Skip to content

@docs/X.md is an eager import, not on-demand loading — blueprint's templates teach the opposite #14

Description

@j4th

What's wrong

blueprint's foundation-doc templates tell every scaffolded project to wire ARCHITECTURE.md, STANDARDS.md, and the two cascade docs into CLAUDE.md with @docs/... syntax, and describe that as on-demand loading. It isn't. Per Claude Code's memory docs, @path is an eager import — the target is expanded into context at session launch alongside the CLAUDE.md that references it. A CLAUDE.md built from this template therefore pays the full token cost of all four documents on every session, silently, which is the exact cost the same template's own cited ETH Zürich finding says to avoid.

Evidence

The template calls the imports on-demand

.claude/skills/blueprint/references/templates/claude-md.md:12-16:

**Always-loaded vs on-demand**:
- CLAUDE.md = always loaded. Keep it minimal.
- ARCHITECTURE.md = loaded via `@docs/ARCHITECTURE.md` when building subsystems.
- STANDARDS.md = loaded via `@docs/STANDARDS.md` when doing PRs or quality checks.
- CONTRIBUTING.md = read once by humans, not Claude — do not @-reference unless specifically relevant.

…and then emits four bare @-imports inside the fenced template block (lines 37–114) that is copied into the project's actual CLAUDE.md — claude-md.md:108-113:

## References

- @docs/ARCHITECTURE.md — load when building a specific subsystem
- @docs/STANDARDS.md — load when doing PRs or quality checks
- @docs/cbk/blueprint.md — load when context about the initiative or workstreams is needed
- @docs/cbk/problem_brief.md — load when context about the original problem is needed

These four lines are outside backticks in the emitted file, so they import. The kit's own CLAUDE.md:79 confirms this reaches every project: "Templates live in references/templates/ and are quoted verbatim in skill output. Edits to a template change every future cascade artifact — treat them as the contract."

The same file opens by declaring the constraint it then violates (claude-md.md:3): "The agent's session primer. Loaded EVERY session by Claude Code. Must be lean."

Claude Code's memory docs say the opposite

Verified against a live fetch of https://code.claude.com/docs/en/memory:

Imported files are expanded and loaded into context at launch alongside the CLAUDE.md that references them.

You can also split content into imports for organization, though imported files still load and enter the context window at launch.

Splitting into @path imports helps organization but doesn't reduce context, since imported files load at launch.

To mention a path in your CLAUDE.md without importing it, wrap it in backticks: writing `@README` keeps the text literal, while @README outside backticks imports the file.

The templates contradict each other

templates/architecture.md:3 licenses ARCHITECTURE.md to grow without bound on the grounds that it isn't in every session's context, and names the mechanism that puts it there in the same sentence:

On-demand reference doc. NOT loaded every session — loaded via `@docs/ARCHITECTURE.md` when building specific subsystems. Can be comprehensive because it doesn't compete with every session's context.

Scope: 13 occurrences across 4 files

grep -rn "@docs/" --include="*.md" . in this repo returns 13 hits in 4 files — templates/claude-md.md (8: lines 6, 14, 15, 110–113, 118), templates/architecture.md (2: lines 3, 29), templates/standards.md (1: line 29), references/foundation-doc-templates.md (2: lines 11, 66). Four of the 13 (claude-md.md:110–113) become live imports in the emitted CLAUDE.md; the other nine are backticked prose that teach the wrong model and propagate it into other emitted docs. Three further sites use the same @-reference framing without the docs/ prefix: claude-md.md:16, :125, :151.

grep -rni "eager" --include="*.md" . returns only Notion-provisioning and subagent-dispatch uses — the kit warns about the trap nowhere.

The false rationale is recorded as a deliberate design choice

references/foundation-doc-templates.md:66 — the paragraph a future editor would cite to reintroduce this:

**Exception**: README.md's Documentation table uses markdown links because the README's audience is GitHub's rendered view and the links are the whole point of the table. CLAUDE.md's @-references use the `@docs/file.md` syntax because Claude Code parses that specifically for context loading. Both exceptions are about target audience, not preference — only override the inline-code default when there's a real audience reason.

"Claude Code parses that specifically for context loading" is true and is exactly the problem: the parse is an eager import, not a lazy handle.

It shipped into a real cascade run

echosphere (34 commits on main — 31 squash-merged PRs plus 3 pre-cascade commits — and 29 ADRs, 0000–0028) shows the split outcome. Its CLAUDE.md never carried the @docs/ form: the References section has read "Pointers, not imports — read on demand (eager @-imports would inline ~330 lines into every session against the pointer posture)" since the blueprint commit itself (6fe6406, PR #3). The operator overrode the template at authoring time — not post-hoc.

But the same blueprint commit emitted the ARCHITECTURE.md and STANDARDS.md templates' @docs/ blockquote verbatim, and both are still present at HEAD:

docs/ARCHITECTURE.md:3: > On-demand reference. Load via `@docs/ARCHITECTURE.md` when building subsystems. …
docs/STANDARDS.md:3:    > Load via `@docs/STANDARDS.md` for PRs, reviews, and quality gates. …

So an operator who spotted the trap in the file where it costs tokens still shipped the instruction in two others, because the templates say it in four places and the operator only overrode one.

The kit's own verification check mandates the antipattern

.claude/rules/cbk-conventions.md § Verification (line 550-551) contains a positive check (no ! prefix — it must match):

# This file is referenced from CLAUDE.md (or wherever the project's project-instructions live)
grep "@.claude/rules/cbk-conventions.md" CLAUDE.md

Run against this repo's own root CLAUDE.md, it exits 1 — the kit's CLAUDE.md mentions cbk-conventions.md only in backticks (lines 28, 41, 58, 63, 77, 90, 93). This repo's CLAUDE.md:77 instructs that these greps be run when editing that rule file, so the kit currently fails its own mandated check — and a project that adopts the correct backticked form fails it too. Note also that .claude/rules/*.md files without paths: frontmatter already load at launch on their own, so @-importing one double-loads it.

Why it matters

Every project blueprint scaffolds gets a CLAUDE.md that silently front-loads four extra documents into every session — the file the template itself says "Must be lean." The cost compounds: templates/architecture.md explicitly tells the author ARCHITECTURE.md "can be comprehensive because it doesn't compete with every session's context," so the two templates jointly produce a growing document that is in fact loaded every session. Nothing in the cascade artifacts or the templates' prose flags it; the prose asserts the opposite. And because the rationale is written down at foundation-doc-templates.md:66 as an intentional exception, a future editor correcting one site has a documented reason to put it back.

Proposed change

Replace every @docs/... with a backticked path plus prose telling the agent to Read it on demand, and add an explicit warning naming the trap. Because the mistaken rationale is recorded in prose, fixing only the emitted lines is not enough — the reason has to be corrected too. Sites:

  1. .claude/skills/blueprint/references/templates/claude-md.md — 8 @docs/ sites plus 3 @-reference mentions. Rewrite the "Always-loaded vs on-demand" block (lines 12–16) to name the eager-import trap and quote the memory docs; fix the ETH Zürich bullet (line 6); convert the emitted ## References block (lines 110–113) to backticked paths with a note that they are mentions, not imports; fix line 118 (use `@docs/ARCHITECTURE.md` reference instead), line 125, and line 151.
  2. .claude/skills/blueprint/references/templates/architecture.md — lines 3 and 29. Line 3's "can be comprehensive because it doesn't compete with every session's context" is only true once the @-import is gone; keep the claim, fix the mechanism.
  3. .claude/skills/blueprint/references/templates/standards.md — line 29 (the emitted blockquote).
  4. .claude/skills/blueprint/references/foundation-doc-templates.md — line 11 (the doc-order table row) and line 66 (the "Exception" paragraph). Line 66 is the highest-priority single edit: it is the stated rationale, so leaving it makes every other fix look like a style preference.
  5. .claude/rules/cbk-conventions.md § Verification — change grep "@.claude/rules/cbk-conventions.md" CLAUDE.md to match the backticked form (e.g. grep -q "cbk-conventions" CLAUDE.md), with a comment explaining why it is deliberately not an @ import.

All five should land together: fixing the templates while leaving item 5 means a project that adopts the corrected form fails its own mandated verification grep.

Do this as a repo-wide sweep rather than file-by-file edits. A hand-fix pass on a downstream vendored copy of this kit (unmerged branch chore/kit-setup-and-harvest in you-are-hear) corrected claude-md.md, architecture.md, standards.md, and the cbk-conventions.md verification grep, and caught the ARCHITECTURE.md row at foundation-doc-templates.md:10 — but left both @docs/ occurrences in that same file (lines 11 and 66) byte-identical to the kit. The file most in need of the fix is the one a manual pass skipped.


Filed from an adversarially-verified harvest against j4th/echosphere (31 merged PRs, 29 ADRs) and the first github-issues-axis run at j4th/you-are-hear. Every quote in this issue was grep-verified against the repo it is attributed to, and every absence claim independently re-run, across three audit rounds.

No activity

Activity on this issue will appear here.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingdocumentationImprovements or additions to documentationharvestHarvested from a real cascade runsource:echosphereEvidence from the echosphere run (Linear axis)source:you-are-hearEvidence from the you-are-hear run (GitHub axis)

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions