id-377 trial A — id-292 bid-literal liveness re-verification
Trial A — bid→procurement rename residual sweep (id-292 re-verification)
Section titled “Trial A — bid→procurement rename residual sweep (id-292 re-verification)”Date: 2026-07-29. Corpus: canonical @ ast-dataflow-efficacy-trials (clean, head 8b397be1).
Protocol: for each question — tool answer, then independent rg/Read ground truth, then verdict.
Tool run as a user (CLI cold path only; MCP warm server not registered — see G7).
No canonical edits were made; no trial-blocking tool bug was found (every miss below is
by-design or a detector gap, not a defect in what the tool claims to do).
Protocol rows
Section titled “Protocol rows”| # | question | command | wall clock (durationMs) | answer | ground truth | verdict | gap_class |
|---|---|---|---|---|---|---|---|
| R1 | Class 1: TS sites value-comparing primary_focus vs 'bid_writing' | bun run ast-dataflow string-literal-uses --value bid_writing | 7.9s (5790) | 1 site: __tests__/hooks/use-primary-focus.test.ts:50 (kind argument) | rg: ~12 sites. Misses ALL prod sites: lib/user-focus-constants.ts:1 (type union), :4 (CV object value), hooks/use-primary-focus.ts:9 (array element), components/dashboard/organisation-profile-nudge.tsx:18 (property key), test property values. No caveat in output states the corpus limit or the kind filter — an Auth-user_metadata surface note is likewise absent | gap | detector-missing + output-shape |
| R2 | Class 2: files value-comparing 'bid_discovered' | bun run ast-dataflow string-literal-uses --value bid_discovered | 9.4s (7088) | 0 results | rg: lib/freshness.ts:103 (=== comparison, load-bearing), :19 (type union), test property values, 2 migration SQL sites | gap | detector-missing |
| R3 | Class 2: who reads/writes record_lifecycle.lifecycle_type (TS) | column-reads / column-writes --table record_lifecycle --column lifecycle_type | 5.4s + 4.4s (2289/1715) | 5 reads (app/api/cron/freshness-transitions/route.ts:160, app/api/freshness/calculate/route.ts:57, + 3 wildcard) / 5 writes (app/api/governance/review/route.ts:231, e2e/fixtures/test-data-fixture.ts:305, lib/mcp/tools/content.ts:1226, lib/mcp/tools/governance.ts:606,1257) | READS clean: freshness/calculate:57 + freshness-transitions:160 are real .select(...lifecycle_type...) strings, the other 3 are honestly-labelled wildcard. WRITES over-report at the COLUMN level: only test-data-fixture.ts:305 (literal key) and content.ts:1226 (...facetUpdate, FACET_FIELDS-gated) actually write lifecycle_type. governance.ts:606 upserts governance_review_status only; governance.ts:1257 and governance/review/route.ts:231 pass a record_lifecycle['Update']-typed updateData whose every branch is governance-only — 3 of 5 are table-level writes reported under an exact columnPath (see G8) | sufficient (reads) / gap (writes) | detector-precision |
| R4 | Class 2 cross-language: does the pipeline touch lifecycle_type? | bun run ast-dataflow-py column-reads --table record_lifecycle --column lifecycle_type | 2.5s (2315) | 1 exact read: scripts/cocoindex_pipeline/sources/l_records.py:1194 (raw SQL, method: select) | rg agrees; a surface the TS tool cannot see, caught via sqlglot | sufficient | — |
| R5 | Class 3: confirm ZERO TS refs for prior_bid_response; can anything see the q_a_extractions CHECK? | string-literal-uses --value prior_bid_response; column-reads --table q_a_extractions --column extractor_kind; schema-coverage --table q_a_extractions | 12.9s + 8.5s + 5.2s | All zero/empty for the literal; schema-coverage enumerates generated-type columns only — the CHECK constraint values (squash L951) appear in NO query | rg: only supabase/migrations/20260617130000_squash_baseline.sql:951. ZERO TS refs claim CONFIRMED. CHECK invisible as expected — {377.4}-tail (pg_proc/migrations blind spot), logged as known, not novel | sufficient (claim) / known gap (CHECK) | corpus-boundary |
| R6 | Class 4: all bid_detail sites | string-literal-uses --value bid_detail | 32.0s outlier (5534 on rerun) | 20 sites, ALL test argument positions; zero prod | rg prod: lib/layer-inference.ts:48 (const init), lib/client-config.ts:167 (property value), supabase/seed.sql:378 (CV seed, SQL), migration comment. Both TS prod sites invisible | gap | detector-missing |
| R7 | Class 4: does any query connect LAYER_BID_DETAIL ↔ 'bid_detail'? | references --symbol 'lib/layer-inference.ts:LAYER_BID_DETAIL'; enum-uses --enum LAYER_BID_DETAIL | 2.9s (672) / 2.8s (35) | references: 8 exact sites, all in-file (inferLayer rule arms — the const is module-private). enum-uses: out_of_corpus (plain consts unsupported). No query surfaces the const’s literal value | Correct as far as it goes; the const→value link stays manual (rg the initializer) | opportunity | detector-missing |
| R8 | Class 4: all bid_library sites | string-literal-uses --value bid_library | 8.6s (5988) | 0 results | rg: lib/layer-inference.ts:94 (=== 'bid_library' — the LOAD-BEARING inference rule), :21 (union), test property values | gap | detector-missing |
| R9 | Class 5: from_bid zero production refs (S485 claim) | string-literal-uses --value from_bid | 8.2s (6220) | 0 results — correct zero | rg: survivors are comments only (app/procurement/[id]/session/page.tsx:413-415, e2e/tests/bid-session.spec.ts:322-390 — all {135.32} tombstone commentary). Even the page.tsx:412 literal named in id-292’s PR#121 note is now a comment. S485 resolution CONFIRMED and complete | sufficient | — |
| R10 | Class 6: all kb-bid-view localStorage sites | string-literal-uses --value kb-bid-view | 8.2s (5855) | 1 site: app/procurement/page.tsx:71 (useViewMode('kb-bid-view','grid'), kind argument, enclosing fn:FormsPage) | rg: exactly 1 — perfect match | sufficient | — |
| R11 | Class 7: load-bearing workspaces.type === 'bid' comparisons | column-reads --table workspaces --column type; string-literal-uses --value bid | 3.7s (1958) / 9.5s | column-reads: silent [] — but workspaces.type no longer EXISTS (generated types show application_type_id; a garbage-column probe also returns silent [], no unknown_column error). Literal sweep: 8 sites (components/provenance/audit-tab.tsx:70 jsxProp, lib/validation/schemas.ts:1185 z.literal, scripts/mcp-eval/functional-correctness.ts:1096) | Premise CHANGED: the type text column was dropped post-T2; the legacy 'bid' alias now lives at the INPUT layer — lib/mcp/tools/workspaces.ts:76 (args.type === 'bid', load-bearing back-compat, MISSED: comparison), :36 (enum list, MISSED: array element), app/api/workspaces/route.ts:140 (STALE COMMENT ONLY — no mapping code; WorkspaceCreateBodySchema.type is z.enum(getValidTypeValues()) and lib/workspace-types.ts:23-30 lists 6 keys without 'bid', so the REST surface rejects the alias at validation), components/dashboard/activity-feed.tsx:117,25 (MISSED: return + union). lib/queue/handlers/batch-reclassify.ts and app/api/items/route.ts no longer contain 'bid'. Load-bearing-vs-stale stays human judgment — the tool contributes enclosing context only | gap ×2 | detector-missing + ergonomics (silent unknown column) |
| R12 | Class 8: source_bid_* GONE (TS + Python) | string-literal-uses --value source_bid_id (+_name); ast-dataflow-py schema-uses --exclude-tests | 10.7s / 0.6s | 0 TS; py evidence sidecar (765 rows) contains no source_bid_*; the only “bid” match in it is the FILENAME scripts/bid_worker.py | rg repo-wide: zero. GONE confirmed both languages | sufficient | — |
| R13 | KEEP list still live? | enum-uses --enum VALID_BID_STATUSES; --enum FINAL_AWARD_FORM_TYPES; --enum VALID_PUBLICATION_STATUSES; string-literal-uses --value bid_response | ~3s each | All three enum probes: out_of_corpus. bid_response: 3 test-arg sites only | KEEP list is stale: VALID_BID_STATUSES / TERMINAL_BID_STATUSES have ZERO repo-wide hits — retired with the bid-status vocabulary (types/bid.ts is gone too; no bid-named successor). bid_response reorient tag IS live (types/reorient.ts:55 union + emit network across 7 prod files — all invisible to the literal sweep, same detector hole). 'bid' form_types CV live (schemas.ts:1140,1185). Separately: enum-uses cannot see as-const arrays — FINAL_AWARD_FORM_TYPES and VALID_PUBLICATION_STATUSES are both LIVE yet error out_of_corpus; the KH CV convention is arrays, so the documented “as const idiom” support misses the dominant idiom | gap | detector-missing |
| R14 | Corpus boundary: which class literals sit out-of-corpus? | contrast R11 sweep vs rg; fixture-uses --needle bid_library then --needle 'scripts/import_bid_library.py' | 9.1s / 0.4s | fixture-uses bid_library: 0. Exact full value: 1 hit (__tests__/fixtures/reference-doc-paths.json:36, requiredPaths[27]) — needle is whole-token exact-match, embedded substrings invisible | Out-of-corpus class literals, named: scripts/seed-id145-w1f-exemplar.ts:129,141 (.eq('form_type','bid') — call-arg kind that WOULD match, proving script exclusion, not kind exclusion); supabase/seed.sql:378 (bid_detail CV seed row); squash L951 CHECK; migration SQL bid_discovered sites. In-corpus surprises: e2e/fixtures/test-data-fixture.ts IS in (R3 hit line 305), scripts/mcp-eval/functional-correctness.ts IS in (R11 hit). No output field states corpus membership either way | gap | corpus-boundary + ergonomics |
Refreshed per-class liveness table (id-292, re-verified 2026-07-29)
Section titled “Refreshed per-class liveness table (id-292, re-verified 2026-07-29)”| class | literal(s) | live sites (file:line) | disposition |
|---|---|---|---|
| 1 | bid_writing | lib/user-focus-constants.ts:1,4 (union + CV value, label already ‘Procurement writing’); hooks/use-primary-focus.ts:9; components/dashboard/organisation-profile-nudge.tsx:18 (key); tests ×4 files | unchanged — Auth user_metadata backfill still the blocker |
| 2 | bid_discovered | lib/freshness.ts:19,103 (union + load-bearing compare); supabase/migrations/20260702130000_id131_freshness_rpcs.sql:95 (RPC body!); squash L4460; tests | premise-changed — lifecycle_type now lives on the record_lifecycle facet (content_items eliminated, id-131). Class SURVIVES but grew a new coupled surface: the id-131 freshness RPC compares the literal in SQL, so the “backfill UPDATE + TS literals atomically” plan must now also patch compute_freshness-family RPCs. TS read surface: 5 readers (2 exact — app/api/freshness/calculate/route.ts:57, app/api/cron/freshness-transitions/route.ts:160 — + 3 wildcard). TS write surface: 2 real writers, lib/mcp/tools/content.ts:1226 and e2e/fixtures/test-data-fixture.ts:305 — the other 3 the tool returned (governance.ts:606,1257, governance/review/route.ts:231) write governance columns only, see G8; pipeline reads it at l_records.py:1194 |
| 3 | prior_bid_response | supabase/migrations/20260617130000_squash_baseline.sql:951 (CHECK) only; ZERO TS refs re-confirmed | unchanged — leave-with-rationale |
| 4 | bid_detail / bid_library | lib/layer-inference.ts:48 (LAYER_BID_DETAIL const + 7 in-file uses), :21,94 (bid_library union + load-bearing rule); lib/client-config.ts:124,167; supabase/seed.sql:378 (CV seed); tests | unchanged |
| 5 | from_bid + derived | comments only (app/procurement/[id]/session/page.tsx:413-415; e2e/tests/bid-session.spec.ts tombstone block) | resolved (S485/{135.32} confirmed; last literal now a comment) |
| 6 | kb-bid-view | app/procurement/page.tsx:71 (sole localStorage site) | unchanged |
| 7 | workspaces.type==='bid' | lib/mcp/tools/workspaces.ts:36,76 (input-alias enum + load-bearing compare — the ONLY live alias surface); app/api/workspaces/route.ts:140 (stale comment only — no mapping code, and the route’s zod enum has no 'bid' member); components/dashboard/activity-feed.tsx:25,117 (activity-category vocab, arguably separate surface); out-of-corpus: scripts/seed-id145-w1f-exemplar.ts:129,141 (form_type='bid', different column) | premise-changed — the workspaces.type TEXT COLUMN IS DROPPED (post-T2; discriminator = application_type_id). “DB still emits the alias” is no longer true; what survives is the CLIENT-INPUT alias ('bid' accepted by the MCP list_workspaces tool, which answers it with a redirect-to-form-tools message). Retirement is now an MCP-tool-deprecation decision, not a DB data migration — and narrower than first written: the REST route carries no alias, only a comment describing one. batch-reclassify.ts no longer carries the literal and app/api/items/route.ts no longer exists |
| 8 | source_bid_id/_name | none (zero repo-wide, TS + Python) | GONE (re-confirmed) |
| KEEP | VALID_BID_STATUSES / TERMINAL_BID_STATUSES | zero repo-wide hits — retired with the bid-status vocabulary (types/bid.ts gone; no bid-named successor) | KEEP entry now moot — nothing left to protect |
| KEEP | bid_response reorient tag | types/reorient.ts:52,55,67 + emit/validator network (lib/activity/team-changes.ts, app/api/reorient/route.ts, components/dashboard/{reorient-section,activity-feed}.tsx, mcp-apps/reorient-me/*) | live — keep protecting |
| KEEP | bid form_types CV | lib/validation/schemas.ts:1140 (FINAL_AWARD_FORM_TYPES), :1185 (z.literal('bid')) | live — keep protecting |
Net: 5 live classes (1, 2, 3, 4, 6), one premise-changed toward cheaper retirement (7), one resolved (5), one gone (8). Two of three KEEP entries live; one moot.
Gaps & opportunities
Section titled “Gaps & opportunities”| id | gap_class | what | repro | proposed fix |
|---|---|---|---|---|
| G1 | detector-missing | string-literal-uses classifies only 5 call-site contexts (viMock/jsxProp/sqlTag/envKey/argument) and silently DROPS comparisons (=== 'x'), object-property values, array elements, type-position literals, return statements, const initializers — i.e. exactly the shapes CV/rename sweeps need. Confirmed intentional (queries/string-literal-uses.ts:118-120 “call-site context search, not raw text search”), but 6 of 8 id-292 classes under-report, three to zero | bun run ast-dataflow string-literal-uses --value bid_discovered → 0 vs freshness.ts:103 | Add kinds comparison, caseClause, propertyValue, arrayElement, typeLiteral, initializer (or an --all-contexts flag defaulting on), keeping the current set as a filter |
| G2 | output-shape | Zero results carry no caveat — indistinguishable from “no sites exist”. Neither the kind-filter (G1) nor corpus membership is stated in any response | R2/R8 outputs | Add a caveats block to every query response (schema-coverage already has one): kinds searched, corpus summary, excluded-surface note |
| G3 | ergonomics | column-reads/column-writes on a nonexistent column return silent [] — no unknown_column (which schema-coverage does emit). “0 readers” and “column was dropped” are indistinguishable; R11 hit this live on the dropped workspaces.type | bun run ast-dataflow column-reads --table workspaces --column zzz_not_real | Validate table+column against database.types.ts in column-reads/writes and reuse the existing unknown_column error kind |
| G4 | detector-missing | enum-uses supports enums and as-const objects but not as-const arrays — the actual KH CV convention. Live FINAL_AWARD_FORM_TYPES and VALID_PUBLICATION_STATUSES both error out_of_corpus (a misleading kind for “declared but unsupported idiom”) | bun run ast-dataflow enum-uses --enum VALID_PUBLICATION_STATUSES | Support as const array declarations (members = element literals); distinguish “unsupported idiom” from out_of_corpus |
| G5 | ergonomics | fixture-uses needle is whole-token exact-match; embedded occurrences (paths, compound keys — bid_library inside "scripts/import_bid_library.py") invisible with no flag to widen | fixture-uses --needle bid_library → 0 vs reference-doc-paths.json:36 | --substring flag (or substring default with a matched field showing the containing token) |
| G6 | corpus-boundary | Known {377.4} tail, live-confirmed here: out-of-corpus surfaces holding class literals — scripts/seed-id145-w1f-exemplar.ts (tsconfig-excluded script; its .eq(...,'bid') args are the kind the tool WOULD catch), supabase/seed.sql, migration bodies, the squash CHECK. No query states membership | R11/R14 | Short term: per-response corpus caveat (G2) + a CLI corpus-info command (exists on MCP only); long term: {377.4} declarative/SQL detectors |
| G7 | performance / mcp-surface | Cold CLI pays ~3-6s project load per query (one 32s outlier under load); this 20-query trial spent ~2.5 min on redundant loads. Warm MCP server exists but is unregistered by design until extraction | any two consecutive queries | For sweep workflows, accept multiple --value args per invocation (amortise one load across a literal set) — cheaper than registering the MCP server early |
| G8 | detector-precision | (added by the verification pass — not found by the trial author.) column-writes reports table-level writes under an EXACT columnPath. A .update(updateData) / .upsert({...}) whose payload never mentions the queried column still returns columnPath: "<queried column>", confidence: "indirect" — the only signal separating it from a real write is that indirect label, which column-reads also uses for genuine exact-column hits. 3 of 5 lifecycle_type writers are false: governance.ts:606 (upserts governance_review_status), governance.ts:1257 + governance/review/route.ts:231 (governance-only updateData branches). Mirror-risk: any rename sweep trusting column-writes will patch files that never touched the column | bun run ast-dataflow column-writes --table record_lifecycle --column lifecycle_type → 5 hits vs 2 real (content.ts:1226, test-data-fixture.ts:305) | Resolve the payload object/variable and emit columnPath: "*" + confidence: "wildcard" when the queried column is not provably a key — i.e. give writes the same wildcard honesty reads already have |
| O1 | opportunity | No query connects a const to its literal value (LAYER_BID_DETAIL ↔ 'bid_detail'): references tracks the symbol, string-literal-uses the string, nothing joins them | R7 | references result rows for string-const declarations could carry literalValue; or extend enum-uses to plain string consts |
| O2 | opportunity | Load-bearing-vs-stale classification (R11) stays human judgment. enclosing + kind help; a comparison kind (G1) with the compared-expression text (args.type, lifecycle_type) would get most of the way | R11 | In a future comparison kind, include the LHS expression text so a human can bucket compat-shim vs dead comparisons quickly |
Tool scorecard (this task’s shape: CV-literal rename-residual sweep)
Section titled “Tool scorecard (this task’s shape: CV-literal rename-residual sweep)”- column-reads / py schema-uses: the stars. Zero over-reports across spot-checks; found live
lifecycle_typesites the id-292 inventory never listed; the py sidecar caught the raw-SQL pipeline read the TS tool cannot see. column-writes is the weaker sibling — same shape, but 3 of its 5lifecycle_typehits are table-level writes dressed in an exactcolumnPath(G8). - string-literal-uses: right tool name, wrong default scope for this job. For 6 of 8 classes rg was strictly better; the tool’s exact-match + AST kinds would BEAT rg (no comment/substring noise — its correct-zero on
from_bidcomments is the proof) if G1’s kinds existed. - references: precise where a symbol exists to hang it on.
- enum-uses: missed every probe in this trial (plain const, as-const arrays ×2).
- Verdict pattern (post-verification): 5 clean sufficient / 8 rows carrying a gap / 1 opportunity across 14 rows. (R3 was logged
sufficient (strong); the verification pass split it — reads sufficient, writes a gap.)
Verification pass (2026-07-29)
Section titled “Verification pass (2026-07-29)”Independent audit by a second agent (the trial author died on a usage limit before self-checking).
Read-only against canonical @ ast-dataflow-efficacy-trials, head 8b397be1, working tree clean.
Every gap repro re-run; premise claims re-derived from source, not from the trial’s own tool output.
1. Gap register — 7 confirmed / 0 refuted
Section titled “1. Gap register — 7 confirmed / 0 refuted”| id | result | evidence from this pass |
|---|---|---|
| G1 | ✅ PASS | string-literal-uses --value bid_discovered → "results":[] (6295ms). Ground truth rg: lib/freshness.ts:103 if (lifecycle_type === 'bid_discovered'), :19 union. Comparison kind genuinely absent |
| G2 | ✅ PASS | No caveats key in ANY response observed this pass (7 distinct queries). Zero-result and populated payloads are structurally identical |
| G3 | ✅ PASS — stronger than logged | column-reads --table workspaces --column zzz_not_real → silent []. Also --table zzz_not_a_table --column id → silent []: the unknown-table case is equally silent, so the fix in G3 must validate both axes, not just the column |
| G4 | ✅ PASS | Both probes error out_of_corpus. Both symbols are live as-const arrays: lib/validation/schemas.ts:1140 (FINAL_AWARD_FORM_TYPES), lib/governance/publication-transitions.ts:31 (VALID_PUBLICATION_STATUSES, consumed at lib/mcp/tools/governance.ts:960 + components/shared/publication-status-badge.tsx:78) |
| G5 | ✅ PASS | fixture-uses --needle bid_library → []; --needle scripts/import_bid_library.py → 1 hit, reference-doc-paths.json:36, context: requiredPaths[27]. Whole-token semantics confirmed |
| G6 | ✅ PASS | tsconfig.json exclude contains scripts, supabase — hence seed-id145-w1f-exemplar.ts:129,141 (.eq('form_type','bid')) and seed.sql:378 are out. The trial’s own “in-corpus surprise” holds and is worth keeping: scripts/mcp-eval/functional-correctness.ts:1096 DID return, so scripts/ exclusion is not uniform — membership is genuinely unpredictable from the config alone. No corpus-info in the CLI’s Valid queries: list |
| G7 | ✅ PASS | Cold-load spread this pass: 3938 / 4871 / 5272 / 5370 / 6295 / 7146 / 7461 / 8794 / 13510 ms. The 32s outlier did not recur, consistent with the trial’s own “under load” note |
| O1, O2 | ✅ consistent | Both restate evidence already carried by R7/R11; no independent claim to falsify |
2. Premise changes
Section titled “2. Premise changes”Class 2 — CONFIRMED, with one over-stated number (corrected in place above).
supabase/migrations/20260702130000_id131_freshness_rpcs.sql:95 reads
AND rl.lifecycle_type = 'bid_discovered' — a real SQL value-compare at the stated line, so the
“atomic backfill must also patch the RPC body” conclusion stands.
scripts/cocoindex_pipeline/sources/l_records.py:1194 is await self._pool.fetch(_SQL_RECORD_LIFECYCLE_FOR_OWNERS, ...),
and that constant (l_records.py:456-463) selects lifecycle_type — pipeline read confirmed.
The facet move is confirmed by the writers themselves (.from('record_lifecycle') everywhere).
But “5 readers + 5 writers” was half wrong: reads are honest, writes are not — 3 of 5 do not
touch the column. See G8. The class-2 disposition is unaffected; only the surface count shrank.
Class 7 — headline CONFIRMED, one sub-claim REFUTED (corrected in place above).
Confirmed: Tables<'workspaces'> (sed-range read of the generated types, Read-tool deny respected)
has NO type key in Row/Insert/Update on either the table or the view block; it carries
application_type_id with an FK to application_types. The column is gone.
Refuted: app/api/workspaces/route.ts contains no alias mapping. Its sole 'bid' occurrence is
the comment at :140 (“Map the legacy ‘bid’ input alias to the ‘procurement’ application_types
row”) — the code below it does const appTypeKey = rawTypeKey and looks the key up verbatim.
WorkspaceCreateBodySchema.type is z.enum(getValidTypeValues()) and lib/workspace-types.ts:23-30
returns exactly six keys, none of them 'bid', so a 'bid' body is rejected at validation and never
reaches the lookup. The comment describes intent that was never implemented (or was later removed).
Net effect on the disposition: class 7 is cheaper still than the trial concluded — the surviving
alias is one MCP tool (lib/mcp/tools/workspaces.ts:36,76), not an MCP tool plus a REST route.
Minor: app/api/items/route.ts does not merely lack 'bid', it does not exist.
3. KEEP-list correction — CONFIRMED
Section titled “3. KEEP-list correction — CONFIRMED”rg -n "VALID_BID_STATUSES|TERMINAL_BID_STATUSES" repo-wide → zero hits.
ls types/bid.ts → No such file or directory. The KEEP entry is genuinely moot.
The other two KEEP entries re-confirmed live: types/reorient.ts:52,55,67 plus a 16-file
bid_response network including components/dashboard/reorient-section.tsx:81,94,115 and
activity-feed.tsx:116; schemas.ts:1140,1185 for the 'bid' form_types CV value.
4. Protocol-row sampling — 4 of 5 sampled rows clean, 1 refuted
Section titled “4. Protocol-row sampling — 4 of 5 sampled rows clean, 1 refuted”| row | result |
|---|---|
| R6 | ✅ answer exact — 20 results, every one under __tests__/, every one kind:"argument". Prod sites layer-inference.ts:48, client-config.ts:167, seed.sql:378 all absent. gap justified by its own evidence |
| R9 | ✅ answer exact — []. Survivors are comment text only, so the correct-zero reading is right and sufficient is earned, not asserted |
| R10 | ✅ answer exact — 1 hit, app/procurement/page.tsx:71, kind:"argument", enclosing:"fn:FormsPage", matching rg 1:1 |
| R13 | ✅ answer exact — both enum probes out_of_corpus while both symbols are live; the as-const-array conclusion follows from the evidence shown |
| R3 | ❌ REFUTED — the row claimed “zero over-reports” on the strength of spot-checking governance.ts:606. That upsert is real, but its payload is owner_kind + owner FK + governance_review_status: null; it never writes lifecycle_type. “Real upsert to record_lifecycle” was mistaken for “real write of lifecycle_type”. Row and scorecard corrected; new gap G8 filed |
5. Hygiene — PASS
Section titled “5. Hygiene — PASS”git status --short in canonical: empty. The trial was read-only as declared; no tools/ast-dataflow*
edits exist, consistent with “no fix declared”.
Docs-site attributable to Trial A: tasks/id-292.md (one appended Notes line — frontmatter, status and
all prior Notes lines untouched) plus the untracked trials/ dir. tasks/id-396.md, tasks/id-399.md
and specs/id-396-corpus-model/ are the parallel lane and were not touched by this pass.
Verdict
Section titled “Verdict”Safe for the synthesis wave to consume, with the corrections above applied. All seven proposed
tool-work items are real and reproduce, so none of the synthesis effort is wasted; G8 adds an eighth
that the trial missed and that matters more than most, because column-writes was the query the
scorecard told readers to trust. Both premise rewrites survive — class 2 as written, class 7 with its
scope reduced to a single MCP tool.