Uh oh!
There was an error while loading. Please reload this page.
test(parity): value-level label parity — catch accept/accept-with-divergent-data (#1009 P0) - #186
Conversation
…ergent-data (#1009 P0) The validator-parity harness only pinned accept/reject verdicts, so the one failure mode RFC-0002 leans hardest on — the CLI previews "N labeled rows" while the ingestor writes null/fewer — passed every gate (data-ingestors #340). This adds a value-level layer on top of the verdict pins. Generator (gen-validator-goldens.py): for cases the manifest flags `value_parity` (and the ingestor accepts), drive the REAL ingestor read path (CSVIngestor.read_data + the #340 label resolution + RecordProcessor) and record the resolved label header, the row count, and the class set it stores. Requires the #340 fix in the target ingestor; fails loudly rather than pin the bug if it's absent. Go preview (preflight.go): factor CheckLabelDiversity's read/resolve/NA/ collapse loop into readLabelColumnValues — one scan that returns the resolved label, sorted class set, and row count — and expose it as ReadLabelValues. CheckLabelDiversity now derives its verdict from that single source (no forked read loop; loses only the multi-class early-exit micro-opt). This also gives RFC-0002's "check your data" preview a real value read to display. Test (parity_golden_test.go): for value_parity cases, assert the Go preview's resolved label + row count + class set equal the ingestor golden. Proven to bite: mutating imgc-label-case's golden to the pre-#340 state (unresolved "label", empty classes) fails the test with "the read paths resolve the label column differently — #340 class"; regenerating against #340 restores green. sync-validator-goldens.sh --check now compares values too (they carry no paths), so a value-only drift can't slip past the verdict-only check. imgc-label-case (header " Label " vs config `label`) is the ` Label `/`label` read-path case #1009 P0 asks for — value parity turns it into a live proof of #340. Scope: string-read labels (image/text always; tabular string-family). Numeric labels stay verdict-only — cross-language float formatting ("1.0" vs "1") makes value comparison unreliable, and the numeric collapse is already verdict-pinned. Depends on data-ingestors #340 (di#352): the value goldens are generated against it. Once #340 lands on data-ingestors develop, a regen is a no-op; the P0.3 CI drift job must pin a data-ingestors SHA that includes #340. Part of backend#1009 (P0 value-level parity). Remaining #1009: money-path seam, CI drift wiring (pin SHA + coverage floor), cross-repo taxonomy contract, one real content-compared e2e. Part of the data-ingest epic backend#1008. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
saadqbal
commented
Jul 8, 2026
bugbot run |
Bugbot couldn't runBugbot is not enabled for your user on this team. Ask your team administrator to increase your team's hard limit for Bugbot seats or add you to the allowlist in the Cursor dashboard. |
LukasWodka
commented
Jul 8, 2026
bugbot run |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit 00f728e. Configure here.
saadqbal
commented
Jul 8, 2026
Nice, careful PR 👍 The single-scan refactor of |
Uh oh!
There was an error while loading. Please reload this page.
…0.3) (#188) * ci: pin the data-ingestors schema ref + add a coverage floor (#1009 P0.3) Two of the three CI drift tripwires from #1009. (The third — a scheduled `sync-validator-goldens.sh --check` against the pinned ingestor — waits for #340 to land on a stable ref, since the value-aware check regenerates against the ingestor read path and needs the #340 fix; the Go-side parity test already enforces the committed goldens on every PR.) (b) Pin the schema-drift check to a data-ingestors SHA, not floating master. sync-schema.sh now builds the fetch URL from scripts/.data-ingestors-ref (a pinned commit SHA), overridable via DATA_INGESTORS_REF. Before, any upstream commit touching the schema reddened every open CLI PR until someone synced; now adopting upstream is a deliberate SHA bump + re-sync in one PR. Pinned to 0de1f148 (current master; the embedded schema matches it — check stays green). (c) Add a per-package coverage floor. `go test -cover` printed numbers and asserted nothing, so the two load-bearing, historically thin-tested packages could silently rot. scripts/coverage-floor.sh fails the build if internal/cli or internal/submit drops below its floor; wired into the Test job after `go test`. Floors are a RATCHET (bump UP only, lowering is a reviewed edit), set just under current develop: internal/cli 68% (now 70.1%), internal/submit 72% (now 74.8%). Bump these up once #186/#187 land (they lift internal/cli to ~72%). The script is bash-3.2-portable (no associative arrays — macOS default). Verified locally: sync-schema.sh --check matches at the pinned SHA; coverage-floor.sh passes and bites (a 99% floor fails, a below-current floor passes); shellcheck clean; build.yml parses; full suite green. Part of backend#1009 (P0 CI drift tripwires). Remaining #1009: the goldens drift job (post-#340), the cross-repo taxonomy contract test, one content-compared ingest e2e. Part of the data-ingest epic backend#1008. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * ci: fail loudly on a malformed coverage-floor entry (#1009 P0.3) A dropped ":floor" in FLOORS left min="$entry" (the whole token); the awk comparison then errored on that as bare source and exited non-zero, which `if awk` read as "not below floor" and printed a bogus "ok" — the ratchet became a silent no-op for that package. Validate each entry has a "package:INT" shape before the awk call. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * ci: validate the data-ingestors ref before it enters the schema URL (#1009 P0.3) The ref (pinned file value, or the DATA_INGESTORS_REF override) is interpolated into a raw.githubusercontent.com URL. An unvalidated ref could inject path traversal ("../..") or extra path segments — the same class scripts/install.sh already guards for its release tag. Restrict the ref to a SHA/branch/tag shape (alnum start; alnum . _ - / ; no "..") and fail with exit 2 otherwise. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Co-authored-by: Asad Iqbal <asad.dsoft@gmail.com>
Summary
The validator-parity harness pinned only accept/reject verdicts. So the one failure mode RFC-0002 leans hardest on — the CLI previews "N labeled rows, K classes" while the ingestor actually writes null/fewer — sailed through every gate. That's the data-ingestors #340 class (a case-/whitespace-mismatched label passes both verdicts, then reads NULL in-cluster). This adds a value-level layer on top of the verdict pins: the resolved label header + row count + class set the real ingestor read path produces must equal the Go preview's.
This is the P0 "value-level parity" keystone of #1009 — "the only thing that catches accept/accept-with-divergent-data."
What changed
gen-validator-goldens.py— for cases flaggedvalue_parity(and accepted), drives the REAL ingestor read path (CSVIngestor.read_data+ the chore: back-merge main → develop (adopt cobra 1.10.2 + reconcile drift) #340 label resolution +RecordProcessor) and records{resolved_label, row_count, classes}. Fails loudly if the target ingestor predates chore: back-merge main → develop (adopt cobra 1.10.2 + reconcile drift) #340 (won't pin the bug).preflight.go— factoredCheckLabelDiversity's read/resolve/NA/collapse loop intoreadLabelColumnValues(one scan → resolved label, class set, row count) and exposedReadLabelValues.CheckLabelDiversitynow derives its verdict from that single source — no forked read loop; also gives RFC-0002's "check your data" preview a real value read to show.parity_golden_test.go— forvalue_paritycases, asserts the Go preview's resolved label + row count + class set equal the ingestor golden.sync-validator-goldens.sh --check— now compares values too (they carry no fixture paths), so a value-only drift can't slip past the verdict-only check.cases.json— flags the 9 accept/accept string-label cases asvalue_parity.Proven to bite
Mutating
imgc-label-case's golden to the pre-#340 state (unresolvedlabel, empty classes) fails the test:Regenerating against #340 restores green.
imgc-label-case(header" Label "vs configlabel) is exactly the`Label`/labelread-path case #1009 P0 names — value parity turns it into a live proof of #340.Scope & dependency
"1.0"vs"1") makes value comparison unreliable, and the numeric collapse is already verdict-pinned.develop, a regen is a no-op; the CI drift job (below) must pin a data-ingestors SHA that includes chore: back-merge main → develop (adopt cobra 1.10.2 + reconcile drift) #340.Type
Test hardening · cli · RFC-0002 foundation. Part ofbackend#1009 (P0 value-level parity) — not the whole ticket.
Remaining #1009: money-path seam (
submitFn/portForwardFn/mintTokenFn+ exit-code/reclaim matrix), CI drift wiring (pin the schema-drift + goldens SHA, per-package coverage floor), cross-repo taxonomy contract test, one real content-compared ingest e2e.Note
Low Risk
Test-hardening and a refactor of label reading that keeps diversity checks on the same scan; production preflight behavior should be equivalent with clearer shared semantics.
Overview
Extends the validator-parity harness beyond accept/reject so the Go CLI preview cannot agree with the ingestor on verdict while reading different label data (data-ingestors #340).
Preflight refactors label diversity into a shared
readLabelColumnValuesscan that returns resolved header, row count, and class set viaReadLabelValues/LabelReadValues;CheckLabelDiversitynow derives its verdict from that same read.Harness & goldens:
cases.jsonmarks nine accept cases withvalue_parity.gen-validator-goldens.pyrecords ingestor value goldens from the realCSVIngestorread path (requires #340_resolve_label_column).parity_golden_test.goasserts Go values match those goldens.sync-validator-goldens.sh --checkcompares verdicts and values so value-only drift fails CI.Numeric-label cases stay verdict-only; string-read paths are what value parity pins.
Reviewed by Cursor Bugbot for commit 00f728e. Bugbot is set up for automated code reviews on this repo. Configure here.