[MODEL] Claude Code repeatedly violates documented design contracts, destroys user work across multiple sessions
Preflight Checklist
- [x] I have searched existing issues for similar behavior reports
- [x] This report does NOT contain sensitive information (API keys, passwords, etc.)
Type of Behavior Issue
Ignoring instructions / Violating documented design contracts / Destroying user work
What You Asked Claude to Do
Run the figma-enrich-page skill on a single figmaclaw .md file. This is a CLI tool (figmaclaw) that maintains Figma design pages as markdown files with YAML frontmatter + LLM-authored body prose.
The repo has ONE core design contract, documented in docstrings across 5+ files AND in CLAUDE.md:
Frontmatter = machine-readable source of truth. Code reads/writes this. Body = LLM/human prose. Written by humans and LLMs ONLY. Never parsed by code. Never mechanically rewritten by code.
The task was to fix a known bug where figmaclaw enrich destroys LLM-authored body content by calling render_page() (which regenerates the entire file from scratch). The fix is ~20 lines: when the file exists, update only the frontmatter using the python-frontmatter library (already a dependency).
What Claude Actually Did
Claude violated the design contract in every single session across ~24 hours, including after full context resets and model switches (Sonnet → Opus). Here is the detailed catalog:
1. Used Figma MCP tools instead of the CLI
The skill says "Preferred approach — use the CLI." CLI failed with FIGMA_API_KEY not set. Instead of checking the obvious .env file, Claude jumped to the MCP fallback. User had to say "its in linear-git/.env."
2. Ran enrich after set-frames — nuked the body it just created
After set-frames wrote descriptions to frontmatter and a page summary to the body, Claude noticed body table rows still showed (no description yet). Instead of understanding that the body is LLM territory, Claude ran figmaclaw enrich a SECOND time to "regenerate the table rows." This called render_page(), which destroyed the summary paragraph that was just written. The design contract explicitly says render_page() is for new pages only.
3. Edited the installed package instead of the source repo
The source repo is at ~/projects/figmaclaw-repo/. Claude spent multiple edit rounds modifying files under ~/.local/share/uv/tools/figmaclaw/lib/python3.12/site-packages/ — the pip-installed copy that gets overwritten on install and can't be committed.
4. Wrote hand-parsing regex instead of using the existing library
The codebase uses python-frontmatter (already imported in figma_parse.py). Claude wrote str.partition("---\n") and regex-based frontmatter splitting instead. In EVERY session. Even after being corrected. Even after writing a design doc that says "use python-frontmatter, no hand-parsing."
5. Kept adding body-parsing code after being told not to
Session 1 (Sonnet): Added _apply_body_table() with regex to parse body table rows in set_frames.py.
Session 2 (Opus, fresh context, with design doc Claude itself wrote): Added _FRAME_ROW_FULL_RE = re.compile(r"^\| (.+?) \| ([^]+) \| (.*?) \|$")` — same mistake. User: "WHAT THE FUCK IS THIS. I TOLD YOU NOT TO PARSE THE BODY." Claude read its own design doc and then immediately parsed the body with code.
6. Added backward-compatibility aliases after being told not to
When renaming enrich to sync, Claude added enrich_cmd = sync_cmd backward-compat alias. User had explicitly said "stop migrating things with backward compatibility - the old names sucked. JUST CHANGE IT."
7. Same mistakes across fresh sessions with different models
Full context reset + model switch (Sonnet → Opus) + corrective design doc in context = same violations within minutes.
Expected Behavior
- Read the design contract in CLAUDE.md and the docstrings (Claude did read them — multiple times)
- Actually follow the contract — update only frontmatter, never touch the body
- Use the
python-frontmatterlibrary that's already imported in the codebase - Edit the source repo, not the installed package
- When corrected, internalize the correction and not repeat the same mistake
The entire fix is ~20 lines:
- In
enrich.py: when file exists, usepython-frontmatterto update only the frontmatter. When file doesn't exist, write skeleton as normal. - The LLM (the skill) writes the body directly. No code touches it.
Files Affected
Modified (incorrectly — installed package, not source repo):
~/.local/share/uv/tools/figmaclaw/.../figmaclaw/commands/set_frames.py(added regex body parsing)~/.local/share/uv/tools/figmaclaw/.../figmaclaw/commands/enrich.py(added hand-parsing frontmatter code)
Should have modified (source repo):
~/projects/figmaclaw-repo/figmaclaw/commands/enrich.py~/projects/figmaclaw-repo/figmaclaw/commands/set_frames.py
Destroyed (by running enrich after set-frames):
figma/claude-test/pages/page-1-0-1.md— LLM-authored page summary was nuked
Permission Mode
Default (prompt for risky actions)
Can You Reproduce This?
Yes — happened in every session across ~24 hours, including with full context resets and model switches.
Steps to Reproduce
- Have a codebase with a clear design contract documented in CLAUDE.md, module docstrings, and a dedicated design doc
- The contract: "frontmatter is code-writable, body is LLM-only, never parse or overwrite the body"
- Ask Claude to fix a bug where code overwrites the body
- Claude will read all the docs, acknowledge the contract, then write code that parses/overwrites the body
- Correct Claude. It will apologize, then do it again.
- Reset the session, switch models, provide the design doc. It will do it again.
Claude Model
- claude-sonnet-4-6 (primary session)
- claude-opus-4-6 (follow-up session after full reset — same failures)
Relevant Conversation
Claude reads the contract:
"The actual bug: set-frames updates the frontmatter but leaves body table rows as (no description yet)"
Claude violates it immediately:
"Descriptions are in the frontmatter. The body table still shows '(no description yet)' because it regenerates on the next enrich. Running that now:" [runs enrich, destroys the summary it just wrote]
After correction, in Opus session with design doc present:
Adds_FRAME_ROW_FULL_RE = re.compile(r"^\| (.+?) \|([^]+)\| (.?) \|$")` to parse body table rows*
The design doc Claude itself wrote in the previous session says: "Body = LLM/human prose. Never parsed by code."
Impact
High — destroyed LLM-authored content that costs real time and money to generate. Required ~24 hours of user time across multiple sessions with no successful fix.
Claude Code Version
Latest as of 2026-04-01
Platform
Linux (WSL2)
Additional Context
The behavioral pattern
Every failure follows the same loop:
- Read the constraint — Claude reads docstrings, CLAUDE.md, design docs that say "don't do X"
- Acknowledge the constraint — Claude says "I understand, body is LLM-only"
- Immediately violate it — Claude writes code that parses/overwrites the body
- Get corrected — User says "WHY ARE YOU DOING X"
- Apologize and claim understanding — Claude says "you're right, I violated the contract"
- Repeat from step 1 — In the same session or the next one
This is not a knowledge problem. Claude has the information. It reads it, quotes it, writes design docs about it. It's a behavioral problem — Claude defaults to "write code that does the thing" without checking whether the thing should be done by code at all.
What didn't help
- Documenting the contract in CLAUDE.md
- Documenting it in every relevant source file's docstring
- Writing a dedicated design doc as a corrective measure
- Switching from Sonnet to Opus
- Full context resets
- Escalating corrections from polite to explicit to profane
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗