[MODEL] Claude Code repeatedly violates documented design contracts, destroys user work across multiple sessions

Resolved 💬 2 comments Opened Apr 1, 2026 by aviadr1 Closed May 9, 2026

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

  1. Read the design contract in CLAUDE.md and the docstrings (Claude did read them — multiple times)
  2. Actually follow the contract — update only frontmatter, never touch the body
  3. Use the python-frontmatter library that's already imported in the codebase
  4. Edit the source repo, not the installed package
  5. When corrected, internalize the correction and not repeat the same mistake

The entire fix is ~20 lines:

  • In enrich.py: when file exists, use python-frontmatter to 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

  1. Have a codebase with a clear design contract documented in CLAUDE.md, module docstrings, and a dedicated design doc
  2. The contract: "frontmatter is code-writable, body is LLM-only, never parse or overwrite the body"
  3. Ask Claude to fix a bug where code overwrites the body
  4. Claude will read all the docs, acknowledge the contract, then write code that parses/overwrites the body
  5. Correct Claude. It will apologize, then do it again.
  6. 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:

  1. Read the constraint — Claude reads docstrings, CLAUDE.md, design docs that say "don't do X"
  2. Acknowledge the constraint — Claude says "I understand, body is LLM-only"
  3. Immediately violate it — Claude writes code that parses/overwrites the body
  4. Get corrected — User says "WHY ARE YOU DOING X"
  5. Apologize and claim understanding — Claude says "you're right, I violated the contract"
  6. 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

View original on GitHub ↗

This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗