[arch(at="doc.md#anchor")]: code cites its architecture doc, lint keeps it true - #3887
Conversation
…keeps it true
An inert builtin function annotation in the hot_path family's mold:
declaring a citation costs nothing and requires nothing; the compiler
owns the argument's shape. LINT026 owns resolution, both ways. Forward,
always on: every citation's path resolves against the citing file's
folder, the anchor heading exists exactly once - a struct's citation,
which the compiler cannot validate (one annotation per name per
module), is shape-checked here too. Reverse, behind .lint_config
[docs] enforce_arch: every {#anchor} in the folder's .md files is
cited by that folder's code - a dead anchor is re-cited or stripped.
Line comments are skipped by the scan.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014fKJGuUL8tP58Y6NvoVeSn
arch_of returns a file's [arch] citations with the cited section's text; arch_sites returns the census - every citation of a doc, grouped by anchor in document order, dead anchors and dangling citations included. Both ride utils/common/arch_citations.das, the single scanner LINT026 also uses, so the citation grammar and its four failure spellings cannot fork between the checker and the tools. The cpp-mcp bundle now carries utils/common in full - the helper's require target shipped short before. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014fKJGuUL8tP58Y6NvoVeSn
176 comments: 6 renames applied usage-swept (dwrite_h, chunk_base, chunk_cap, DWRITE_STAGING_BAND, vk_tag), 4 rules landed in REVIEW.md (image-version bump, meta-field tripwire, decline-never-fails-load, wrap-free bounds form - the last two tightened after a dragon pass over the rule diff), 8 facts landed as anchored ARCHITECTURE.md sections cited by 20 [arch] annotations across 15 functions, 35 comments compressed, 42 drained into their surviving copies. The module is armed: enforce_arch holds every anchor cited, negative- controlled. CLAUDE.md carries the citation practice. The archivist agent joins the roster; harvester KEEP one-liners are //! contract comments now. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014fKJGuUL8tP58Y6NvoVeSn
…ines A private //! block is a contract comment - same 3-line cap public docs get; plain // in privates keeps its one WHY line, and the "private symbols don't get public docs" doctrine retires. The style015 fixture was a dead test (nothing asserted it) - now expect-armed and negative-controlled against pristine style_lint. LINT027: a REVIEW*.md or ARCHITECTURE*.md past 300 lines in a tagged folder is a finding (LAWS.md uncapped) - armed knowing three documents fire today; the archivist splits land next. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014fKJGuUL8tP58Y6NvoVeSn
daslib/ARCHITECTURE.md: 779 lines into a 185-line parent plus LINT / EMIT / LINQ companions, every section byte-verbatim, two modal clauses routed into the checklists. dasLLAMA/ARCHITECTURE.md: 1063 lines into a 48-line index over seven companions - ENGINE, MEDIA, IMAGE, RUNTIME, GPU, MEASUREMENT, INVARIANTS - twelve restatement passages deleted, four dated passages archived, all eight anchors alive with their twenty [arch] citations retargeted and LINT026 green both directions. REVIEW.md sheds its image rail into routed REVIEW_IMAGE.md and lands the three routed rules; every sec-cite across both modules resolves against the file that now holds the section. LINT027 green everywhere. The style014 fixture is expect-armed (it had asserted nothing); CLAUDE.md names the split doctrine and the archivist. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014fKJGuUL8tP58Y6NvoVeSn
Both rescue agents are archived under history/agents - the harvester absorbed the PR-gate rescue (RENAME first) and harvest-on-first-touch replaces the legacy sweeps. make_pr's comment-drain row is now the diff-scoped harvest row, its format row states that no folder strips comments any more, and the preflight paragraph gains the tree-frozen rule this session paid for. The dormant strip advisory names the harvester as its successor wherever it still prints. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014fKJGuUL8tP58Y6NvoVeSn
The routing line defines mint and flavor in place; the f32-matmul and charter-edit rules name all three companion homes (the retarget had dropped the GPU one); the rope rule names the function class instead of coinages; "harness" becomes this checklist's own noun, instrument; daslib's ARCHITECTURE*.md globs read "the architecture doc"; the sql alias rule bans the base-table fallback outright and joins its sql_linq siblings; CLAUDE.md's [arch] paragraph is three modal rules, the implementation-folder list admits companions, and the comment-hygiene headline states the harvest regime. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014fKJGuUL8tP58Y6NvoVeSn
…nstallers The five [arch] argument-guard disjuncts get their expect fixtures (a rejection guard covered only by its neighbours can vanish green); the LINT027-alone arming branch gets its --enable arm. detect-dupe's scan filter generalizes the debugger/profiler name-skip: any file whose compilation installs a thread-local debug agent leaves the corpus, counted and logged - das2rst.das entering scope was crashing worker shards at the second install. Checklist repairs from the audits: the bind and emit terms defined in place, the stale shipped-exe WHY dropped, utils/mcp names its ROADMAP ledger and the roadmap lists the two arch tools. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014fKJGuUL8tP58Y6NvoVeSn
There was a problem hiding this comment.
Pull request overview
This PR introduces the new [arch(at="<doc>.md#<anchor>")] annotation as an inert builtin marker, plus supporting infrastructure (shared citation scanner, lint enforcement, MCP tools, docs, and fixtures) so code can cite the architecture sections it is governed by and lint can keep those citations/anchors consistent.
Changes:
- Add builtin
[arch]function annotation (shape-validated by the compiler) and source-based citation resolution shared by LINT026 and MCP tools (arch_of,arch_sites). - Extend the lint runner with folder/document passes (LINT025–LINT027) and add/refresh fixtures to assert the new behavior.
- Update docs, checklists, and dasLLAMA/daslib references to companion architecture documents and the new harvesting workflow.
Reviewed changes
Copilot reviewed 94 out of 96 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| utils/mcp/tools/format_file.das | Update strip advisory text to point to harvester agent |
| utils/mcp/tools/arch_sites.das | New MCP tool: document → code citation census |
| utils/mcp/tools/arch_of.das | New MCP tool: code → cited architecture section text |
| utils/mcp/tools/arch_common.das | Shared helpers for arch MCP tools (section extraction, symbol attribution, tree scan) |
| utils/mcp/test_tools.das | Register arch tools and add MCP tool tests/fixtures |
| utils/mcp/ROADMAP.md | Document new planned tools (arch_of, arch_sites) |
| utils/mcp/REVIEW.md | Clarify MCP docs and add roadmap pointer |
| utils/mcp/registry_das.das | Register arch_of/arch_sites; update format_file description |
| utils/mcp/README.md | Document new MCP tools |
| utils/mcp/cpp-mcp-setup.md | Update bundle layout doc for utils/common shared modules |
| utils/lint/tests/style015_long_comment_private.das | Update STYLE015 fixture to new private //! contract-doc cap behavior |
| utils/lint/tests/style014_long_comment.das | Strengthen STYLE014 fixture with explicit expectations |
| utils/lint/tests/lint027_rule_doc_lines.das | New LINT027 fixture (planted-tree CLI test) |
| utils/lint/REVIEW.md | Clarify checklist wording around gate/module ownership |
| utils/lint/README.md | Document LINT025/026/027 as runner folder rules |
| utils/lint/main.das | Add LINT026 (forward+reverse) + LINT027 + shared folder-walk plumbing |
| utils/detect-dupe/pipeline.das | Add debug-agent installer detection to skip problematic files |
| utils/detect-dupe/main.das | Skip debug-agent-installer files and log skip count |
| utils/das-fmt/dasfmt.das | Update strip advisory text to point to harvester agent |
| utils/common/arch_citations.das | New shared citation scanner + resolution/failure wording (lint + MCP) |
| tests/typer_errors/test_arch_annotation_errors.das | New compile-time shape-error tests for [arch] |
| tests/typer_errors/_arch_wrong_type.das | [arch] error fixture |
| tests/typer_errors/_arch_wrong_name.das | [arch] error fixture |
| tests/typer_errors/_arch_two_args.das | [arch] error fixture |
| tests/typer_errors/_arch_no_hash.das | [arch] error fixture |
| tests/typer_errors/_arch_no_doc_half.das | [arch] error fixture |
| tests/typer_errors/_arch_no_argument.das | [arch] error fixture |
| tests/typer_errors/_arch_no_anchor_half.das | [arch] error fixture |
| tests/typer_errors/_arch_empty_citation.das | [arch] error fixture |
| tests/language/arch_annotation.das | Positive-runtime test: [arch] is inert and composes |
| tests/language/_arch_annotation_doc.md | Anchor doc fixture for [arch] tests |
| tests/dasPUGIXML/parity_xml_order_distinct_group.das | Update architecture doc reference after split |
| src/builtin/REVIEW.md | Clarify what counts as a “bind” in builtin review checklist |
| src/builtin/module_builtin_runtime.cpp | Implement [arch] builtin function annotation + registration |
| skills/mcp_tools.md | Document new MCP tools and [arch] semantics |
| skills/internal/make_pr.md | Update make_pr flow (harvest replaces rescue-bot; tree frozen rule) |
| skills/comment_style_hygiene.md | Clarify allowed C/C++ docs scope and contract-doc intent |
| modules/dasPUGIXML/daslib/linq_fold_xml.das | Update architecture doc reference after split |
| modules/dasLLAMA/tests/test_dlim_wipe.das | Update architecture doc reference after split |
| modules/dasLLAMA/REVIEW.md | Add/adjust routed checklist pointers and new rules |
| modules/dasLLAMA/REVIEW.das | Update doc references in gate messages/comments |
| modules/dasLLAMA/REVIEW_VISION.md | Point to new companion architecture doc |
| modules/dasLLAMA/REVIEW_IMAGE.md | New routed checklist for image rail |
| modules/dasLLAMA/REVIEW_GPU.md | Point to new companion architecture doc |
| modules/dasLLAMA/REVIEW_AUDIO.md | Point to new companion architecture doc |
| modules/dasLLAMA/README.md | List new companion architecture docs |
| modules/dasLLAMA/LAWS.md | Record ruling/provenance for harvested changes and enforce_arch |
| modules/dasLLAMA/harness/residency_ramp_probe.das | Update architecture doc reference after split |
| modules/dasLLAMA/followup_general.md | Update architecture doc reference after split; add follow-up note |
| modules/dasLLAMA/ENVIRONMENT.md | Update architecture doc reference after split |
| modules/dasLLAMA/dasllama/dasllama_tower.das | Update architecture doc reference after split |
| modules/dasLLAMA/dasllama/dasllama_metal_common.das | Update architecture doc reference after split |
| modules/dasLLAMA/dasllama/dasllama_gemma3v.das | Update architecture doc reference after split |
| modules/dasLLAMA/dasllama/dasllama_env.das | Update clarg docs to new companion architecture doc |
| modules/dasLLAMA/benchmarks/REVIEW.md | Point to measurement companion doc; add benchmark policy rule |
| modules/dasLLAMA/ARCHITECTURE_RUNTIME.md | New companion architecture doc (runtime mechanisms) |
| modules/dasLLAMA/ARCHITECTURE_MEDIA.md | New companion architecture doc (tower/audio/vision charters) |
| modules/dasLLAMA/ARCHITECTURE_MEASUREMENT.md | New companion architecture doc (rig + instrumentation rails) |
| modules/dasLLAMA/ARCHITECTURE_INVARIANTS.md | New companion architecture doc (inherited invariants) |
| modules/dasLLAMA/ARCHITECTURE_IMAGE.md | New companion architecture doc (prepared-image rail) |
| modules/dasLLAMA/.lint_config | Enable [docs] enforce_arch = true for the module |
| LAWS.md | Add repo-level ruling entries for [arch] system and harvest workflow |
| history/README.md | Document new history/agents/ and updated archived references |
| history/linq_fold/linq_fold.md | Update archived doc pointer to new companion architecture doc |
| history/dasLLAMA/architecture_retired_notes.md | New archive of removed past-tense passages |
| history/agents/rescue-sweep-bot.md | Archive retired agent charter |
| history/agents/rescue-bot.md | Archive retired agent charter |
| doc/source/stdlib/handmade/function_annotation-builtin-arch.rst | New stdlib doc for builtin [arch] annotation |
| doc/source/reference/language/lint.rst | Add LINT026/LINT027 docs; update STYLE015 docs |
| doc/reflections/das2rst.das | Include enforce_arch_at in lint_config doc grouping |
| daslib/style_lint.das | Update STYLE015 logic/messages; update architecture doc reference |
| daslib/REVIEW.md | Update architecture doc pointers; add new review rule |
| daslib/REVIEW_LINQ.md | Update architecture doc reference; add new SQL alias rule |
| daslib/perf_lint.das | Update architecture doc reference |
| daslib/lint_config.das | Add enforce_arch_at and shared [docs] key reader |
| daslib/linq_fold_table.das | Update architecture doc reference after split |
| daslib/linq_fold_sql.das | Update architecture doc reference after split |
| daslib/linq_fold_json.das | Update architecture doc reference after split |
| daslib/linq_fold_decs.das | Update architecture doc reference after split |
| daslib/linq_fold_common.das | Update architecture doc reference after split |
| daslib/linq_fold_array.das | Update architecture doc reference after split |
| daslib/ARCHITECTURE_LINT.md | New companion architecture doc (lint family internals) |
| daslib/ARCHITECTURE_EMIT.md | New companion architecture doc (emit/standalone/shader notes) |
| CMakeLists.txt | Install all utils/common/*.das to keep shipped MCP server startable |
| CLAUDE.md | Document [arch] + LINT027 + comment-harvest workflow updates |
| ci/make_cpp_mcp_bundle.sh | Copy all utils/common/*.das into cpp-mcp bundle |
| .claude/hooks/README.md | Update comment workflow references to harvester |
| .claude/agents/harvester.md | Update KEEP behavior (private //! contract comment) |
| .claude/agents/archivist.md | New agent charter for architecture grooming/splitting |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
One em-dash in the test document - the gate's own fixer applied; citations still resolve and the language test stays green. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014fKJGuUL8tP58Y6NvoVeSn
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 94 out of 96 changed files in this pull request and generated no new comments.
Suppressed comments (1)
Previously missed (1) — in code that hasn't changed since the last review.
.claude/hooks/README.md:12
- The hook README still describes a “comment drain” where the formatter strips comments per
.lint_config. In this PRmake_pr.mdswitches the gate to comment harvest (diff-scoped) rather than formatter-driven stripping, so this README should be updated to match the new workflow and terminology.
scaffolding - write them freely during a PR. The gate is `make_pr`'s comment
drain: the formatter strips them per the folder's `.lint_config` policy, and a
non-empty strip goes through the `harvester` agent (proposal ledger; the
session rules on every entry). Policy: `skills/comment_style_hygiene.md`;
mechanics: `skills/internal/make_pr.md`.
New language surface: the
[arch(at="<doc>.md#<anchor>")]function annotation - inert at runtime, validated by lint - plus three new lint rules (LINT025-027 complete the set) and two MCP tools.Code can now cite the architecture-doc section that governs it. The annotation is a builtin marker in the
hot_pathfamily's mold: declaring a citation costs nothing and requires nothing; the compiler validates only the argument's shape. LINT026 owns resolution, both directions - every citation's path resolves against the citing file's folder and names a unique{#anchor}heading (always on), and in a folder whose.lint_configsets[docs] enforce_arch = true, every anchor is cited by code (opt-in, so a mid-migration doc is legal). LINT027 caps rule documents at 300 lines in tagged folders. The MCP tools ride the same scanner as the lint, from one shared module:arch_ofreturns a file's citations with the cited section text;arch_sitesreturns a document's census - every citing symbol, dead anchors and dangling citations included.The system was proven on real engine code.
dasllama/dasllama_image.daswent through the full comment-harvest pipeline: six renames, four new review rules (one of which exposed a wrong "law" the old comment had taught for months - the bare bounds form it prescribed itself wraps), eight architecture sections minted with anchors, twenty citations, and the module armed. Both oversized architecture docs then split under the new cap - daslib into three concern companions, dasLLAMA into seven plus a routedREVIEW_IMAGE.md- with every anchor, citation, and section cite carried through, proven by the lint. A private//!block is now a contract comment (STYLE015 caps it at three lines like a public doc), the comment-strip machinery is retired in favor of the harvest flow, and the two rescue agents are archived underhistory/agents/.Where to look:
src/builtin/module_builtin_runtime.cpp(the annotation),utils/common/arch_citations.das(the one scanner),utils/lint/main.das(the three folder passes),utils/mcp/tools/arch_*.das,modules/dasLLAMA/ARCHITECTURE_IMAGE.md+dasllama_image.das(the binding in the wild).Validation, claims, ledger
Validation
preflight --full: 21 passed, 0 failed, 0 skipped - build, interp/JIT/AOT suites, docs, sequence.//!cap against pristinestyle_lint, all five[arch]argument-guard disjuncts. Two pre-existing dead tests were found and revived with exact-countexpectheaders (style014, style015 - neither had asserted anything since creation).arch_sitespost-split agrees with the lint census (19 + 1 citations, 8 anchors, zero dangling).[arch]argument grammar was probe-verified: bare-string annotation arguments do not parse (the grammar has name / name=literal only), soat=is the language's shape.Claims - stated, not tested
utils/common/arch_citations.dasrests on the existing utils/common install glob, verified against the regenerated install script; CI's bundle smoke re-proves it on a full build.Not done
modules/dasLLAMA, image rail). The sweep doctrine is harvest-on-first-touch during the coming perf arcs; re-anchoring daslib's already-swept documentation from its strip-diff provenance is ledgered.REVIEW.dascell for the wrap-free bounds form) stay ledgered.[arch]on structs/classes compiles inert but is compile-unvalidated (one annotation per name per module; a Function/Structure pair under one name is an ABI-breaking diamond) - LINT026'smalformed citationreason covers the gap, tested.🤖 Generated with Claude Code