feat: corpus baselines + ratchets — metrics JSON per repo, regression fails, --bless carries a reason #45
Labels
No labels
code-review
correctness
dos
performance
security
severity/high
severity/low
severity/medium
tech-debt
Kind/Breaking
Kind/Bug
Kind/Documentation
Kind/Enhancement
Kind/Feature
Kind/Security
Kind/Testing
Priority
Critical
Priority
High
Priority
Low
Priority
Medium
Reviewed
Confirmed
Reviewed
Duplicate
Reviewed
Invalid
Reviewed
Won't Fix
Status
Abandoned
Status
Blocked
Status
Need More Info
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
h-dv/code-index#45
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
P2 — turns corpus runs into a trend rather than a pass/fail. Depends on #40.
From
_prdoc/records/brainstorm-2026-07-28-oss-corpus-test-system.md§4.Three enforcement tiers
Tier A — hard gates:
phantom_count == 0, no panics/hangs,parse_error_files == 0(or a per-repo frozen allowlist with reasons), determinism, cold==incremental, wall-clock budget.Tier B — ratcheted against a committed
baseline.json: resolution metrics, symbol-extraction recall, index wall-clock, peak RSS, DB bytes/source KB, query p50/p99, tokens-per-answer.Tier C — diagnostics, never asserted: the
resolution_gapshistogram by reason code × language × repo. This is the worklist (#47), not a score.Explicitly NOT a gate: raw resolution %
Per the build-vs-buy verdict, the ~20% rate is a denominator artifact — most refs point at stdlib/third-party and the resolver correctly declines them. Gating on it creates direct pressure to mint phantoms, i.e. to destroy the moat to make a dashboard green. It may be recorded; it may never fail a build.
Spike baseline (v0.8.7 @
855710d, tier-1) to seed the file:Anti-gaming
Baselines live in the repo, so a change shows up in the PR diff.
--blessrequires a reason string written into the baseline — blessing must be visible in review, never a silent green-wash. (This project has already seen metrics that "passed" because a derived value was mutated rather than measured — see I030b'simpact_batchesfinding.)Acceptance
baseline.jsonper repo, seeded from the table above--blesswrites a mandatory reason fieldLanded (partially) —
tests/corpus/baseline.json+crates/indexer/tests/corpus_ratchet.rsExact structural counts pinned per tier-1 repo, gated on any drift, wired into the nightly
corpusjob.Why this suite exists
Every other corpus suite asks "is this index self-consistent?" — deterministic, coherent with a cold index, free of phantom rebinds. None of them notices a change that is self-consistent but unintended. A resolver tweak that quietly moves 4,000 refs passes all of them. #52 is the worked example: it changed resolution on real repos and no test could see it.
resolvedis the dimension this exists for.Counts only — timings deliberately excluded
The issue's Tier B listed wall clock, RSS, DB bytes and tokens-per-answer as ratchet candidates. I implemented only the count dimensions, and I think the rest should stay out:
corpus_determinism), so exact equality is a legitimate gate;That is not theoretical: while implementing this,
resolver.rs's existing 10sbounded_workassertion failed under load ~45 and then passed 3/3 in isolation on the same binary. Filed as #55. Timings stay recorded-only intarget/corpus/scale-*.json.Anti-gaming
COSI_CORPUS_BLESS=1requiresCOSI_CORPUS_BLESS_REASON(rejected below 8 chars) and writes the reason into the committed baseline, so an intentional change shows up in review. This project has already shipped a metric that "passed" because a derived value was mutated rather than measured (I030b'simpact_batches), so the escape hatch is deliberately noisy.Verified non-vacuous, not assumed
rust-ripgrep: resolved 13760 -> 13759 (-1)COSI_CORPUS_BLESS=1without a reason → refusedA finding the baseline surfaced immediately
js-expresshasimports: 0. Express is CommonJS and the javascript plugin does not capturerequire()as an import. Recorded in the baseline as a known oddity rather than hidden — adjacent to #31 item 2. If it ever becomes non-zero that is an improvement, and blessing it should cite the cause.Still open on this issue
precision_gate, determinism/coherence incorpus_metamorphic, ceilings incorpus_scale) rather than centralised here — arguably fine, but not what the issue described.resolution_gapshistogram as a diagnostic artifact) is not implemented; it belongs with #47's gap miner.