Skip to content

[arch(at="doc.md#anchor")]: code cites its architecture doc, lint keeps it true - #3887

Merged
borisbat merged 9 commits into
masterfrom
bbatkin/arch-annotation
Aug 27, 2026
Merged

[arch(at="doc.md#anchor")]: code cites its architecture doc, lint keeps it true#3887
borisbat merged 9 commits into
masterfrom
bbatkin/arch-annotation

Conversation

@borisbat

Copy link
Copy Markdown
Collaborator

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_path family'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_config sets [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_of returns a file's citations with the cited section text; arch_sites returns a document's census - every citing symbol, dead anchors and dangling citations included.

The system was proven on real engine code. dasllama/dasllama_image.das went 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 routed REVIEW_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 under history/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.
  • The dry run's model-free suite: 71 files, 859 tests, 0 failed (includes the prepared-image rail). LINT026's reverse direction was negative-controlled: a planted dead anchor fired, was removed, re-linted green.
  • The lint fixtures run with negative controls (mutate, observe red, restore): LINT026 forward/reverse arms, LINT027 cap and its --enable-alone arming, STYLE015's new //! cap against pristine style_lint, all five [arch] argument-guard disjuncts. Two pre-existing dead tests were found and revived with exact-count expect headers (style014, style015 - neither had asserted anything since creation).
  • The archivist splits carry byte/word-level verbatim proofs per section; arch_sites post-split agrees with the lint census (19 + 1 citations, 8 anchors, zero dangling).
  • The [arch] argument grammar was probe-verified: bare-string annotation arguments do not parse (the grammar has name / name=literal only), so at= is the language's shape.
  • A detect-dupe latent bug fixed en route: a scanned file whose compilation installs a thread-local debug agent crashed any worker that compiled a second one; such files now leave the corpus, counted and logged (generalizes the existing debugger/profiler name-skip).
  • An external codex round returned zero findings; the TDD audit (67 branches, negative-controlled) drove the fixture additions above; the MCP registry wiring for both tools is exercised live (this PR's tooling was used through the running server during its own review).

Claims - stated, not tested

  • The platform matrix rides this PR's CI; the C++ surface is one inert MarkFunctionAnnotation subclass, expected behavior-identical across tiers.
  • The installed MCP server's reach to utils/common/arch_citations.das rests 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

  • Anchors exist only where the trial minted them (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.
  • The dragon rounds' RECOMMEND-LINT proposals (notably a REVIEW.das cell 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's malformed citation reason covers the gap, tested.
  • The shipped-exe rule family (per-tool flat ban vs the parent's sanctioned-drop duty) surfaced in three audits; one family-wide ruling is ledgered.

🤖 Generated with Claude Code

borisbat and others added 8 commits August 27, 2026 07:10
…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
Copilot AI lite review requested due to automatic review settings August 27, 2026 18:06

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment thread utils/common/arch_citations.das
Comment thread utils/detect-dupe/pipeline.das
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
Copilot AI review requested due to automatic review settings August 27, 2026 19:01

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 PR make_pr.md switches 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`.

@borisbat
borisbat merged commit b128973 into master Aug 27, 2026
38 checks passed
@borisbat
borisbat deleted the bbatkin/arch-annotation branch August 27, 2026 20:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants