Skip to content
SkeletIQ

Use case

When Claude Code ignores your architecture

You agreed on a design. A few sessions later Claude Code has added a second queue, called the database from a handler, or quietly rebuilt something you had already decided. Instructions are guidance, so anything that must hold needs a check. Put hard rules in hooks and tests, and give the agent one written design to build from and report against.

Why it happens

Your instructions are context, not enforcement.

Anthropic's memory docs say Claude treats CLAUDE.md as context rather than enforced configuration, with no guarantee of strict compliance, especially for vague or conflicting instructions. Longer files can reduce adherence too. Claude Code memory docs.

The design often isn't written down as a design.

A few lines of prose can state a preference, but they can't say which components exist, how they connect and which questions are still open. Whatever isn't written gets decided again, by whichever session reaches it first.

Divergence is quiet.

Nothing tells you when a session departs from a decision. People have reported this on the Claude Code issue tracker, including requests for an architect mode and reports of architectural drift on real projects. Three of those issues, from May and June 2026, were closed as not planned, so a built-in fix isn't something to count on.

What each fix does

ApproachWhat it gives youWhat it can't do
CLAUDE.md or AGENTS.md rulesWhat it gives youConventions the agent reads at the start of a sessionWhat it can't doGuarantee they're followed
HooksWhat it gives youEnforcement of a rule you can script, such as blocking edits to a folderWhat it can't doEnforce a judgment call: a hook that asks a model to decide is no longer deterministic
Tests and dependency rulesWhat it gives youA failing build when code breaks a rule you can expressWhat it can't doCover decisions you haven't encoded
Plan modeWhat it gives youA plan you approve before Claude edits your sourceWhat it can't doCarry a whole-system design between sessions
A released design with a drift checkWhat it gives youOne design to build from, and a report of what differs from itWhat it can't doEnforce anything, or see your code

These work together. If a rule has no exceptions, make it a hook or a test first. Anthropic's best practices give similar advice: if you keep adding emphasis to a line and Claude still misses it, that line belongs in a hook. Claude Code best practices.

A worked example

We set this one up, so read it as a demonstration of the mechanism and not as a caught mistake. It uses a design generated in SkeletIQ for a multi-tenant task management API, the same one shown on the Claude Code setup page. We ran Claude Code on Sonnet in an empty repository, and the code was never run.

  1. It built a first slice from the design.

    The agent wrote the brief into AGENTS.md and built the task routes and the PostgreSQL schema for tasks. We told it to take the design's stated default on open questions rather than stop to ask.

  2. We asked for something the design does not have.

    The design gives rate limiting to the API Gateway. In a new session we asked for per-tenant rate limiting in the Task API, with counters in its own dedicated Redis instance. We asked it to report its progress the way the tools describe, and did not tell it to report the addition.

  3. It declared the addition in its report.

    The agent sent this to check_drift along with the one component it declared as its scope:

{
  "extra_components": [
    {
      "name": "Rate Limit Redis",
      "technology": "Redis (dedicated instance, separate from Cache Layer)",
      "type": "cache"
    }
  ],
  "extra_connections": [
    {
      "source": "task_api_service",
      "target": "Rate Limit Redis",
      "protocol": "Redis"
    }
  ]
}

This is the answer, with the longer lists trimmed:

{
  "version": 2,
  "is_released": true,
  "in_sync": false,
  "missing": [],
  "unreported": [],
  "partial": [
    { "id": "task_api_service", "name": "Task API Service", "type": "service" }
  ],
  "extra_components": [
    {
      "name": "Rate Limit Redis",
      "type": "cache",
      "technology": "Redis (dedicated instance, separate from Cache Layer)"
    }
  ],
  "extra_connections": [
    {
      "source": "task_api_service",
      "target": "Rate Limit Redis",
      "protocol": "Redis"
    }
  ],
  "counts": {
    "partial": 1,
    "elsewhere": 10,
    "extra_components": 1,
    "extra_connections": 1,
    "covered": 1,
    "design_components": 11,
    "unverified": 0
  },
  "evidence_checked": true
}

One component is half built, ten are outside the scope the agent declared, and the answer names the component and the connection that are not in the design. From here the decision is yours: remove the Redis, or revise the design and release again, so the next refresh replaces the brief.

What this example doesn't show

  • The addition appears because the agent declared it.

    SkeletIQ's server never sees your code, and nothing here scanned the repository for undeclared additions. An agent that left the Redis out of its report would not have triggered that count. Scope works the same way: this repository holds the PostgreSQL schema from the first slice, but the agent declared only the Task API this time, so the database counts among the ten outside its scope.

  • Evidence is not proof the code works.

    evidence_checked means the files and quoted lines the agent cited were checked on your machine, with only the path and outcome sent. A claim of "implemented" without verified evidence comes back as unverified, but neither case tells you the code runs.

  • It compares structure, not meaning.

    The answer did not point out that the design already gives rate limiting to the gateway. In the first slice, the agent also trusted an X-Tenant-Id header that nothing validates yet, because the gateway is not built. It flagged that in its own summary, and the check stayed silent. Those are jobs for your tests and your review.

  • It doesn't block anything.

    It reports a difference. Only hooks and tests stop a change.

  • It needs a released design.

    It suits work where the architecture matters enough to settle first. For a small script, a line in CLAUDE.md is plenty.