Repository navigation
test(ArcGate): gate doc path:line citations so evidence cannot rot silently - #166
Conversation
Heads-up: this gate and #161 break each other, in both directions. Measured, not predicted.I ran this branch ( Both failures are real and neither is a defect in either PR — they are a sequencing collision. 1.
|
Code Metrics Report━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Language Files Lines Code Comments Blanks ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ C Header 5 305 210 52 43 CSS 2 1181 1036 34 111 CUDA 73 25129 18043 4319 2767 Dockerfile 1 39 22 8 9 JavaScript 16 3546 2676 482 388 Jinja2 7 694 656 5 33 JSON 74 4600 4597 0 3 Makefile 1 6 5 0 1 Metal Shading Lan| 33 12224 9431 1142 1651 PowerShell 1 300 227 30 43 Python 145 15139 12482 811 1846 Shell 37 8630 5732 2323 575 Plain Text 4 3801 0 2479 1322 TOML 33 1498 1294 54 150 YAML 3 25 23 2 0 ───────────────────────────────────────────────────────────────────────────────── HTML 4 2687 2604 43 40 |- CSS 2 543 479 37 27 |- JavaScript 1 1233 1215 12 6 (Total) 4463 4298 92 73 ───────────────────────────────────────────────────────────────────────────────── Jupyter Notebooks 4 122 83 23 16 |- Markdown 1 60 30 22 8 |- Python 1 122 113 1 8 (Total) 304 226 46 32 ───────────────────────────────────────────────────────────────────────────────── Markdown 203 44777 0 34735 10042 |- BASH 72 1654 1202 331 121 |- C 3 17 17 0 0 |- CUDA 2 84 56 16 12 |- JSON 18 708 708 0 0 |- PowerShell 1 1 1 0 0 |- Python 23 1008 787 113 108 |- Rust 66 2051 1716 77 258 |- TOML 6 207 164 0 43 |- YAML 5 41 36 5 0 (Total) 50548 4687 35277 10584 ───────────────────────────────────────────────────────────────────────────────── Rust 671 324626 280130 15983 28513 |- Markdown 489 27661 471 23865 3325 (Total) 352287 280601 39848 31838 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Total 1317 484719 346246 87004 51469 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ |
…silently Every lane compiles code or runs tests; none checks whether a sentence describing the code is true. The recent ArcMoE/EP docs error — "reachable only via ARC_EP_SIZE" when `ep_size` is also a serde config field — was caught only because an unrelated PR conflicted and forced someone to read `deepseek4.rs`. Absent that accident it would still be on master. Prose is not mechanically checkable, but the load-bearing part of these docs is: the `path/to/file.rs:123` citations a reader is expected to follow. This scans `memory/` and `arc-tools/` and asserts each citation resolves to a real file, at a real line, near the symbol it names. Drift and rot are separated, because they are different defects. A citation a few lines off is churn — 27 of them exist today, some off by hundreds of lines purely because files grew — and is reported, never fatal. A citation into a deleted file, past the end of a file, or naming a symbol that exists nowhere is rot, and fails. Landed as a ratchet: 66 pre-existing violations are pinned in BASELINE with a reason each (64 are citations into sglang/vLLM/candle/cudarc reference trees that are not vendored here, so they can never resolve; 2 are real rot, named rather than hidden). A new violation fails, and `baseline_has_no_stale_entries` fails when a pinned entry starts passing, so the waiver list cannot rot in either direction. SymbolRot is the one class with no waiver path and an empty baseline. Three guards this session passed on unfixed code, so this one carries its own proof that it can fail: `fixtures_prove_each_violation_class_fails` builds a synthetic repo with a wrong line, a deleted file and a renamed symbol and asserts each is reported, and `citation_census_is_not_empty` asserts the scan actually matched something. std only, no GPU, no network, no new dependency; runs in 0.2 s inside the existing `cargo test -p mistralrs-core` lane, alongside `capability_reachability.rs` which it is modelled on. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SpVNMpb13HkUXqSqbN1o9H
SymbolRot is the one verdict with no waiver path, so a *false* rot report is unfixable short of editing this file. The search set it rests on was the same narrow list used for citation targets, which meant a symbol living in any unlisted text format would have been reported as existing nowhere. Widen CODE_EXTS to every textual extension the repo tracks, and cap searched files at 2 MB. It stays an allowlist rather than "everything that is not .md" because the repo tracks 166 PDFs, several 20-30 MB. Re-verified: the renamed-symbol demonstration still goes red. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SpVNMpb13HkUXqSqbN1o9H
Adding "memory/mission" alongside "memory" would otherwise inflate the census and report every finding twice. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SpVNMpb13HkUXqSqbN1o9H
… scans Rebased onto master `c8168a0a1`. #161 mirrored `00_RESUME_HERE.md`, `FACTS.md`, `KERNEL_RULES.md` and `COMPETITIVE_TEARDOWN.md` into `memory/mission/`, which is inside SCAN_ROOTS. The two PRs broke each other in opposite directions; both are fixed here, and neither was a defect in either PR. 1. `baseline_has_no_stale_entries` FAILED — #161 FIXED two waivers. BASELINE waived `FACTS.md` as UNRESOLVED-PATH in `wave29-BD-rung-decision.md` and `wave41-BS-qtip2b-bake.md`, both reasoned "agent memory file, lives outside the repo". #161 puts it *in* the repo, so both citations resolve and the waivers stop waiving anything. Deleted. This is the gate catching its own rot, which is the behaviour it was built for. 2. `doc_citations_do_not_rot` FAILED — 48 new citations into non-vendored trees. The four new docs cite upstream that this repo does not vendor: SGLang and vLLM Python, candle, toktrie, CUTLASS/DeepGEMM headers, and `cuda.h`. These are the case the failure message names — "if it points into an external reference tree that is not vendored here, add a Waiver with a reason". Added as 43 rows, not 48: `Waiver::covers` treats a `cite` with no `:` as matching any citation of that path, so one row covers every line of a given upstream file. Pinning line numbers in someone else's tree would be noise we cannot maintain. Each row says which upstream it is. Verified: `cargo test -p mistralrs-core --test doc_citations` -> 10 passed, 0 failed. Full suite `-p mistralrs-core -p mistralrs-quant -p mistralrs-vision` -> 0 failures. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SpVNMpb13HkUXqSqbN1o9H
7d2c5e1 to
ffa472e
Compare
Reconciled with #161 — I landed that first, so this repair is mine. Pushed
|
…re already wrong Deleting the dead kernel shortens `qtip_gather_gemv.cu` from 441+ to 425 lines, which pushes two citations in `wave28-AZ-moe-token-cap.md` past the end of the file. With #166's citation gate present that is a hard failure: wave28-AZ-moe-token-cap.md:83 [LINE-OUT-OF-RANGE] `qtip_gather_gemv.cu:437-441` — mistralrs-quant/kernels/qtip/qtip_gather_gemv.cu has 425 lines wave28-AZ-moe-token-cap.md:95 [LINE-OUT-OF-RANGE] `qtip_gather_gemv.cu:435-436` Worth noting: both citations were ALREADY wrong before this PR. The doc introduces them as "launch geometry", but on master lines 435-441 are the GEMV accumulate loop, not the launcher. The deletion does not break them — it converts silent drift into a detectable out-of-range, which is exactly what that gate exists to do. Repointed at where the launch geometry actually is: :390-397 packed_smem, stage_packed, SHMEM, `dim3 grid(...)`, and the launch :391-392 the `stage_packed = 0` fall-back to global reads Verified against the post-deletion file, not the pre-deletion one. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SpVNMpb13HkUXqSqbN1o9H
The missing lane
Every lane we run compiles code or runs tests. None verifies that a sentence describing the code is true.
The clearest recent case: a docs change on master claiming ArcMoE/EP is reachable only via
ARC_EP_SIZE, whenep_sizeis a serde config field and the env var merely overrides it. It was caught only because an unrelated PR conflicted and forced someone to read the code.Prose can't be checked mechanically. The citations can. This scans
memory/**andarc-tools/**for everypath/to/file.rs:123andfile.rs:12-34and asserts:pipeline/mod.rsfindsmistralrs-core/src/pipeline/mod.rs);`build_expert_parallel_plan` (`deepseek4.rs:2211`), by far the dominant shape here — that identifier is still near the cited line.Every violation is reported with the doc, the line in the doc, and the citation text. "3 citations are stale" without naming them is nearly useless.
Drift vs rot
Different defects, treated differently:
Failing on drift would make the gate un-landable and teach people to delete citations rather than write them. 27 citations have drifted today, some by hundreds of lines.
The census (this is itself a finding)
798 citations across
memory/+arc-tools/. 98 resolve to more than one file; 52 carry a checkable identifier.BASELINE:server_args.py), which no prefix rule captures.wave64-CP-arcgraph-capture-defects.md:134citesdevice.rs:754-908meaning candle'sdevice.rs; the only one here isarc-profiler/src/device.rs(268 lines), so a reader lands on an unrelated file.wave33-BK-attention-kv.md:205citesact_quant_kv_nopeatdeepseek4.rs:2168-2210. It moved todsv4_kv_fp8.rs(nowreference_act_quant_kv_nope);deepseek4.rs:2168isEpPlacementMode.Fixing the two rot entries is deliberately not in this PR — some of those docs belong to other agents' open PRs.
docs/andresearch/are excluded for now: 212 of their 336 citations point into external reference checkouts, so gating them would add ~90 waiver rows and almost no verification. Adding a root is a one-line change.Mode: ratchet
A new violation fails.
baseline_has_no_stale_entriesfails when a pinned entry starts passing, so the waiver list cannot rot in the other direction either.SymbolRotis the one class with no waiver path and an empty baseline.Proof it can go red
Three guards this session passed on unfixed code, so this one carries its own proof. Both as permanent fixtures and observed live against the real corpus:
viterbi.rs:150→:99999LINE-OUT-OF-RANGE ... viterbi.rs has 2026 lines— redgit rm arc-tools/quality/batch_load_probe.py(really deleted)UNRESOLVED-PATH ... no file in this repo matches— redstage_paged_attnrenamed repo-wideSYMBOL-ROT ... exists nowhere in this repo— redAll three restored; suite green. The third is also the escalation working as designed: that citation is a drift warning today and becomes a hard failure once the symbol stops existing.
fixtures_prove_each_violation_class_failsreproduces all three against a synthetic repo in a temp dir, so the checker cannot lose the ability to fail without going red.fixtures_tolerate_ordinary_churnasserts the other half — a gate that fires on everything is as useless as one that fires on nothing.citation_census_is_not_emptyasserts the scan actually matched something and that everySCAN_ROOTSentry exists.Cost
stdonly — no GPU, no network, no new dependency, no CI edit. It lands in the existingcargo test -p mistralrs-corelane next tocapability_reachability.rs, which it is modelled on. 0.2 s, all three OSes. Paths are normalised so Windows indexes the same keys.One restraint worth calling out: path resolution is exact-suffix, with no progressive stripping. Stripping
candle-core/src/cuda_backend/offmod.rswould resolve an external citation against dozens of in-repomod.rsfiles, one of which is bound to be long enough to pass the line check — laundering rot into a green run.🤖 Generated with Claude Code
https://claude.ai/code/session_01SpVNMpb13HkUXqSqbN1o9H