Skip to content

fix/ticket 2532 - #2549

Closed
noahgift wants to merge 2 commits into
mainfrom
fix/ticket-2532
Closed

fix/ticket 2532#2549
noahgift wants to merge 2 commits into
mainfrom
fix/ticket-2532

Conversation

@noahgift

Copy link
Copy Markdown
Contributor

noahgift and others added 2 commits August 20, 2026 21:00
…hs (#2532)

pmat analyze hardcoded-paths reports 324 machine-specific paths in SHIPPED
code on origin/main. 46 of them were inside contracts/ -- the tier whose
whole job is to make a defect impossible.

The issue argued "they all resolve on this host, which is the defect".
Measured, it is worse: of 91 distinct shipped paths only 31 still exist
here. /home/<user>/src/aprender-worktrees/crux-spec -- the root of 17 crux
golden-set paths -- is gone. Those 17 falsification tests open with

    GOLD=/home/<user>/src/aprender-worktrees/crux-spec/evidence/crux/...json
    [ -f "$GOLD" ] || { echo "golden set absent"; exit 2; }

so they self-skip on every machine in the world, while pv validate and
pv lint contracts/ both report PASS. A contract that cannot execute
anywhere is not enforcement; it reads like enforcement.

WHAT LANDS

contracts/ 46 -> 0, with no baseline to raise. 27 files repointed at
${APR_CRUX_GOLDENS:-evidence/crux}, ${APR_MODELS:?},
${APR_LEADERBOARD_ROOT:?}, $HOME/... or a repo-relative path. The
:? forms turn "unset" into a loud failure instead of a silent skip.

contracts/machine-specific-paths-v1.yaml (kernel, 2 equations,
5 obligations, 6 falsification tests, 2 kani harnesses).
pv validate: 0 errors, 0 warnings.

scripts/check_hardcoded_paths.sh, wired in ci.yml at guard-runner-labels
next to its sibling check_test_fixture_paths.sh, which gate lists in
needs. Default mode is zero-tolerance over contracts/**/*.{yaml,yml}
with a 1000-file vacuity floor. --full is the whole-tree ratchet over
pmat's shipped tier, seeded at 278.

WHY --full IS NOT WIRED INTO CI

Detection belongs to pmat (pmat#1017) and --full shells out to it rather
than re-detecting. But MEASURED 2026-08-20: the clean-room pool that runs
the blocking guards (16 x intel-clean-room, the only runners carrying the
clean-room label) has pmat 3.31.0, in which analyze hardcoded-paths does
not exist. Wiring it today reds every PR; cargo install pmat || true
would make it a gate that cannot fail. The trigger to promote it is
written into both the script header and ci.yml.

MUTATION-VERIFIED (each shown RED, then GREEN)

  restore crux-A-03 pre-fix           -> rc=1, 1 hit
  restore all 27 pre-fix contracts    -> rc=1, 47 hits
  self-test: 4/4 defect shapes flagged, 0/9 portable shapes flagged
  MIN_CONTRACT_FILES=999999           -> rc=1 (fails closed)
  new /home/... in a tracked example  -> --full rc=1, 278 -> 279
  baseline lowered to 277             -> --full rc=1 (comparison, not constant)
  pmat absent / pmat 3.31.0 stub      -> --full rc=1, never a skip
  control: clean tree                 -> rc=0 both modes

NOT DONE, DELIBERATELY

The remaining 278 (216 in examples, 32 in evidence/, 5 in workflows) are
separate PRs. evidence/*.json should be excluded from remediation, not
rewritten: those are dated records of which command ran where, and
rewriting them falsifies them.

Refs #2532
Two review findings closed, plus the README count.

1. THE WIRING ROW COULD NOT DETECT UNWIRING. It read:

       test: "grep -q 'check_hardcoded_paths.sh' .github/workflows/ci.yml"

   which a COMMENT satisfies — precisely the "reference, not execution" the row
   exists to exclude. A reviewer demonstrated it. Now two anchored predicates:

       grep -qE '^[[:space:]]+run: bash scripts/check_hardcoded_paths\.sh$' ...
    && grep -qE '^[[:space:]]*needs:.*guard-runner-labels' ...

   Mutation-verified in both directions rather than observed green:
     comment out ci.yml:800          -> RED   (restored -> GREEN)
     drop guard-runner-labels from
       gate's needs at ci.yml:808    -> RED   (restored -> GREEN)
   So commenting out the invocation AND detaching the job from `gate` are both
   caught. The second predicate had to be written against the inline
   `needs: [ci, workspace-test, mutants, guard-runner-labels]` form; my first
   attempt assumed a YAML block list and silently never matched — caught by
   running it rather than reading it.

2. evidence/crux GOLDENS DO NOT EXIST, AND DID NOT BEFORE EITHER. A reviewer
   flagged that the purge rewrote e.g.

     -GOLD=/home/noah/src/aprender-worktrees/crux-spec/evidence/crux/huggingface/revision-goldens.json
     +GOLD=${APR_CRUX_GOLDENS:-evidence/crux}/huggingface/revision-goldens.json

   while evidence/crux/{huggingface,llama_cpp} are untracked and absent. True —
   and the ORIGINAL was equally dead: /home/noah/src/aprender-worktrees/crux-spec
   does not exist on this machine either, and no workflow executes crux contract
   tests (`grep -rn crux .github/workflows/` finds only a comment). So this is
   not a regression: the paths were machine-specifically dead and are now
   portably dead, which is exactly what #2532 asks for. Stating it rather than
   implying the default resolves. Set APR_CRUX_GOLDENS to a real goldens tree to
   run them; committing the goldens is separate work.

3. README count 1778 -> 1779 in all three places, which the required
   readme_contract and check_readme_claims.sh gates demand.

SEQUENCING: fix/ticket-2519 also adds exactly one contract and also claims 1779.
Both cannot be right simultaneously — whichever lands second needs 1780. Queue
them one at a time.

Verified: check_hardcoded_paths.sh rc=0 (1779 contract files scanned, 0
machine-specific paths, allowed 0); --self-test rc=0; check_readme_claims.sh
rc=0; pv validate rc=0.

Refs #2532

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@noahgift

Copy link
Copy Markdown
Contributor Author

Superseded by #2613, the 0.64.0 integration batch.

This PR's commits are merged into batch/release-0-64-0 verbatim (--no-ff, never rebased),
and #2613's body carries the full provenance table — PR number, branch, merged head SHA, and
the issues each closes — so the detail survives the squash.

Why batched rather than landed individually: one workspace-test run is ~58 minutes on a
shared box. Thirteen PRs cost thirteen runs whether they go serially or in parallel; one
integration branch costs one. The same approach landed 24 branches previously.

Batching also found four defects that were invisible to every individual PR — most
notably the README contract count: #2548, #2549 and #2587 each add exactly one contract, each
is individually correct at 1779, and three +1s collide on one literal (correct value 1781).
That is the exact class that killed the previous batch.

Closing now, deliberately: an open PR that merges first moves #2613's base and forces
another full run. This is reversible and the branch is untouched — reopen if #2613 is
abandoned.

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.

1 participant