Skip to content

fix(pv): an empty corpus is refused with exit 2, never reported as PASS (PVL-1, PMAT-1099) - #3093

Open
noahgift wants to merge 20 commits into
mainfrom
PMAT-1099-pvl-1-zero-contracts
Open

fix(pv): an empty corpus is refused with exit 2, never reported as PASS (PVL-1, PMAT-1099)#3093
noahgift wants to merge 20 commits into
mainfrom
PMAT-1099-pvl-1-zero-contracts

Conversation

@noahgift

@noahgift noahgift commented Sep 10, 2026

Copy link
Copy Markdown
Contributor

PVL-1 (PMAT-1099): pv refuses to report over ZERO contracts

Spec: paiml/infra docs/specifications/PVL-001-pv-lean-gate.md §2 row EV-1. Ground truth: PV-LEAN-AUDIT-001 (2026-09-10 10:47Z).

Facts re-verified at HEAD 43b8d8e (genchi genbutsu)

cited fact HEAD note
pv lint /nonexistent-path → rc 0, Result: PASS over 0 contracts VERIFIED in-tree pv 0.66.0 built by scripts/pv_bin.sh [V]
pv lint <empty dir> → rc 0 VERIFIED [V]
pv proof-status <empty dir> → rc 0, Proof Status (0 contracts) VERIFIED [V]
pv verify-pipeline <empty dir> → "No contracts found", rc 0 VERIFIED (not in the spec row; plan-grill finding, verify_pipeline.rs:26-29) [V]
`pv lint coverage graph ` → walked nothing, rc 0
contract_walk::collect_contracts used by graph, proof-status, lean-status, verify-pipeline; lint and coverage walk on their own VERIFIED (pmat query --literal "contract_walk::") [V]

Change

  • contract_walk.rs: ZeroContracts { path, filter } (Display 0 contracts under <path>), ZERO_CONTRACTS_EXIT = 2, collect_corpus() (dir walked · single file = one-contract corpus · missing path = empty), require_contracts(), exit_code_for().
  • lib.rs: a ZeroContracts dispatch error exits 2 (nothing was measured — clap's usage-error code); every other error keeps exit 1 (measured, failed).
  • lint.rs: refuse_empty_corpus() reads the gate named validate (count = parsed + parse errors) before any report is printed. A shape-only match was measured refusing every VALID corpus, because duplicate-stems reuses the Validate detail with zeros. lint/gates.rs: a single file is linted as a one-contract corpus (no cache beneath a file).
  • coverage.rs, graph.rs, proof_status.rs (--kind filtering to zero is refused and named), lean_status.rs, verify_pipeline.rs (returns the error instead of process::exit, which had killed the crate's unit-test binary).
  • contracts/work/PMAT-1099.yaml (kind: pattern): 3 equations, 3 obligations, 5 falsifiers — every if_fails carries the mutation actually run.

RED → GREEN (measured)

  • RED at HEAD, implementation stashed: cargo test -p aprender-contracts-cli --test pvl_zero_contractsFAILED. 1 passed; 14 failed (a9db650) [V]
  • GREEN (1ca5d39): same command → ok. 15 passed; 0 failed; cargo test -p aprender-contracts-cli (every target) → 204 passed / 0 failed; cargo test -p aprender-contracts --lib → 1501 passed [V]
  • target/debug/pv lint contracts/Result: PASS, validate contracts: 1766, errors: 0, rc 0 [V]
  • scripts/check_contract_test_binding.sh → PASS, 539 refs resolved, ratchet unchanged [V]
  • make gate (post-commit; touched crates aprender-contracts + aprender-contracts-cli → selection 4 > cap 3 → full cargo check --workspace --tests) → rc 0, 41 checks / 0 failed, 436 s [V]. NOTE: run before the commits it reported no files touched vs origin/main — nothing to select — it reads commits, so a pre-commit gate run measures nothing there.
  • done_when ("$PV" lint /nonexistent-pvl-path; test $? -ne 0) in this worktree → rc 2 [V]. It reads ~/src/aprender's checkout, so it turns green on merge, not before.

Mutations (each applied on 1ca5d39, measured, reverted; git status clean after each) [V]

# mutation prediction measured
001 require_contracts removed from collect_corpus proof-status/graph/lean-status/verify-pipeline RED, lint+coverage GREEN 7 passed; 8 failed — exactly those 8
002 lint guard call removed only lint_* RED 0 passed; 2 failed (filter lint_)
003 exit_code_for → always 1 every *_is_refused RED, controls GREEN 0 passed; 13 failed (filter is_refused)
004 require_contracts → always Err both controls RED 0 passed; 2 failed (filter control_)
005 post---kind guard removed the kind-filter case RED 0 passed; 1 failed
Restore → 15 passed every time.

Jidoka

make gate RED once: pmat complexity, lint::run cognitive 30 > 25 with the guard inline (HEAD was already at 25). Extracted refuse_empty_corpus() and moved the single-file cache rule into build_config()run back to 25. Logged in .pmat/jidoka.jsonl.

Review lanes

  • Plan grill (agy /teamwork-preview, conversation 8006e793-4cdc-4a41-bcc5-d571e5eccd58): PASS-with-changes — keep exit 2; add single-file handling (else pv_surface_gate goes red for the wrong reason); include lean-status + verify-pipeline; no fixture or caller depends on an empty dir passing; the != 2 control was vacuous → controls now require exit 0 AND a printed count of 1. All adopted.
  • Pre-merge 3-lane quorum on this diff: receipt to follow in docs/audits/PVL-1-receipt.md.

Routing

phase class route.sh executed as
1 plan grill plan route=agy-plan w=1.00 basis=absent effort=1[U] paiml-agy-delegate (teamwork, width 1)
2–3 impl impl route=agy-goal w=1.00 basis=absent note=fable-binding effort=1[U] direct — PVL-001 §4.9: subagents read-only, orchestrator is the sole writer
4 review review route=agy-quorum w=1.00 basis=absent effort=1[U] paiml-agy-delegate (quorum, width 3)
4 push/PR/receipt orchestration route=self w=100.00 basis=absent self

Not changed / findings not asked for

Refs PMAT-1099

Pre-merge review quorum (3 agy lanes) → 3/3 FAIL → fixed in cf2967d

lane conversation verdict load-bearing finding
1 ae646ee3-00b3-4364-aaee-76c2f0b68908 FAIL --watch bypasses the guard (run_watch loops run_lint+print_report, lint.rs:344); measured a report over 0 contracts
2 a8b61a5b-2eb6-4215-8bd9-d717dbdead97 FAIL same bypass, measured; contracts: 0, errors: 0 confirmed as the right emptiness signal
3 7ba5404a-cd2b-43a1-8bcd-803612cb8fa5 FAIL --watch (lint.rs:46) AND --diff HEAD <empty> → exit 0 "Nothing to lint" (lint.rs:72)

Verified at HEAD by the orchestrator [V]: lint::run returns into run_watch at :46-65 and into run_diff_check at :72-76, both before refuse_empty_corpus at :101. Fixed in cf2967d — guard after every watch tick; --diff says "nothing changed" only over a non-empty corpus.

RED→GREEN [V] (guard stashed with git stash push -- src/commands/lint.rs, tests present):

cargo test -p aprender-contracts-cli --test pvl_zero_contracts -- lint_watch_empty_dir_is_refused lint_diff_empty_dir_is_refused
→ test result: FAILED. 0 passed; 2 failed   (watch: code -1, killed at 20 s after repeated "Result: PASS" over 0 contracts; diff: exit 0)
git stash pop
cargo test -p aprender-contracts-cli --test pvl_zero_contracts
→ test result: ok. 17 passed; 0 failed

Lane dissent NOT acted on (spec-mandated, escalated in the receipt): all three lanes say exit 2 is ambiguous with clap's usage error. PVL-001 row EV-1 says "0 contracts → exit 2". Kept at 2. Lane models: not recorded by agy [U]. This fix commit has NOT been re-reviewed by a quorum (session budget at andon) — the PR stays unmerged until the next PVL run re-quorums it.

Second review quorum (3 agy lanes on 8bb0c29) → 3/3 FAIL → fixed in 3f573c3

lane conversation verdict load-bearing finding
1 39742bf6-db16-4911-a826-435d2f325b10 FAIL walker drops unparsable files: unparsable-only dir → 0 contracts (exit 2) in --diff, exit 1 in lint; contract lacks watch/diff falsifier; receipt count 1767 vs 1766
2 7a9f134e-3afd-45de-8939-a994ca055898 FAIL same divergence measured for proof-status; --diff nothing-changed path parsed the whole corpus; FALSIFY-002 harness stale (4 tests, not 2)
3 d12f6807-7a19-4b20-b8bb-1fd8daa56b72 FAIL same; lint reports (exit 1) over an unparsable-only dir — that is "measured and failed", kept; receipt line numbers were cited at f99b9b6 (stated in the row)

Verified at HEAD by the orchestrator [V]: collect_contracts skipped Err from parse_contract (contract_walk.rs, pre-fix :128) and every *playbook* stem (:125) — contracts/apr-page-examples-qwen-qa-playbook-v1.yaml and …-state-machine-playbooks-v1.yaml are real contracts lint parses. Fixed in 3f573c3: ONE file rule (provable_contracts::lint::collect_yaml_files, now public) for the walker, coverage and the diff probe; a broken file is ParseErrors (exit 1, named); lint --diff probes without parsing.

Measured [V] (target/debug/pv … contracts/): lint contracts: 1767, errors: 0; proof-status Proof Status (1767 contracts) rc 0; coverage Contracts: 1767; lint --diff HEAD contracts/ rc 0 in 31 ms.

Mutations [V] (contracts/work/PMAT-1099.yaml v1.1.0, exact commands in each if_fails): 006 → FAILED. 2 passed; 2 failed (watch, diff) → ok. 4 passed; 007 → FAILED. 0 passed; 2 failed (unparsable_only, mixed_dir) → ok. 2 passed; 002 re-measured → 2 passed; 2 failedok. 4 passed.

Not acted on: the exit-2/clap ambiguity (spec-mandated, escalated in the receipt). A third 3-lane quorum runs on 3f573c3 before any merge.

Third review quorum (3 agy lanes on 3f573c3) → 3/3 PASS

lane conversation verdict what it measured
1 f9537cc7-f322-4701-8572-0308022c69f2 PASS lint / proof-status / coverage all 1767 over contracts/; broken-only and mixed scratch dirs exit 1 naming the file for every command; --diff over an empty dir exits 2; no caller depends on the old skip
2 a1db2c27-c233-4088-90a8-6465087ece2e PASS same; has_contract_files is the lint engine's rule; 20 s watch deadline sound
3 4adf9381-1862-43a6-bf91-e38f686455e4 PASS same; tests fail without the fixes (checked at a9db650)

lane-reduce.sh --width 3 --not-before <launch>agreed: true; artifact docs/audits/quorum-PMAT-1099.json, session receipt docs/audits/PVL-1-receipt.md (commit a81d1e5, docs only). Non-blocking note from all three lanes: the collect_from_real_contracts_dir unit test cannot see a walker that drops broken files (the corpus has none) — the integration falsifiers (FALSIFY-PVL-1-007) do.

guard-cargo on a81d1e5 → wired in 7bb3ee0STOP(workflow-merge)

BSE-17's self-test (rows 8/9) refused the PR: scripts/tree_reader_unwired_baseline.txt drifted … > aprender-contracts-cli --test pvl_zero_contracts — the falsifier copies contracts/softmax-kernel-v1.yaml, so it is a tree-reader, and the full tier runs --workspace --lib only: no workflow would ever have executed it. Ledgering it as "reads the tree and nothing runs it" would ship PVL-1's gate as a test CI never runs, so it is wired into the same cargo test -p X --test Y chain as pv_surface_gate (ci.yml, one line) and the derived registry is regenerated with scripts/check_tree_reader_tests.sh --update. Local: check_tree_reader_tests.sh rc 0, ci_test_tier.sh --self-test 15/15 [V].

This PR now touches .github/workflows/ci.yml. Per PVL-001 §4.5 it ends in STOP(workflow-merge: aprender PR 3093): operator merge from the web UI once gate and workspace-test are green. The code under review is unchanged since the third quorum's 3/3 PASS (3f573c3); the wiring commit is orchestrator-owned and is verified by CI itself.

🤖 Generated with Claude Code

noahgift and others added 8 commits September 10, 2026 14:41
PVL-001 row EV-1 (PMAT-1099). PV-LEAN-AUDIT-001 measured on 2026-09-10 with the
in-tree pv 0.66.0: `pv lint /nonexistent-path` exit 0 `Result: PASS` over 0
contracts; `pv lint <empty dir>` exit 0; `pv proof-status <empty dir>` exit 0
`Proof Status (0 contracts)`; `pv verify-pipeline <empty dir>` "No contracts
found", exit 0. A gate that measures nothing and reports PASS — the fleet's
signature defect, and the one aprender's Makefile records as its former
release-gate defect.

tests/pvl_zero_contracts.rs, 15 cases: every reporting subcommand (lint,
proof-status, coverage, graph, lean-status, verify-pipeline) must exit 2 with
`error: 0 contracts under <path>` on a missing path, an empty directory, or a
sidecar-only directory; a --kind filter that empties the corpus is refused and
named; two controls require exit 0 AND a printed count of ONE for a real
contract given as a directory and as a single file (lint, coverage and graph
used to read_dir a file path, find nothing, and pass).

Measured at HEAD 43b8d8e with this file and no implementation:
  cargo test -p aprender-contracts-cli --test pvl_zero_contracts
  -> test result: FAILED. 1 passed; 14 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.34s (rc=0)

Refs PMAT-1099

Pmat-Ticket: PMAT-1099
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DkwPBrLHuPJrJeUbaFBu7P
…SS (PVL-1)

contract_walk: ZeroContracts / collect_corpus / require_contracts / exit_code_for
— one definition of "empty" and one exit code: 2 is "nothing was measured"
(clap's usage-error code — the invocation was wrong), 1 stays "measured and
failed". lib.rs maps a ZeroContracts dispatch error to exit 2.

lint: refuse_empty_corpus() reads the gate NAMED `validate` (its count is parsed
+ parse errors) — `duplicate-stems` reuses the Validate detail shape with zeros,
so a shape-only match refused every VALID corpus (measured, then fixed). The lint
loader treats a single file as a one-contract corpus (no cache beneath a file);
coverage and graph do the same. proof-status: --kind filtering to zero is refused
and named. lean-status and verify-pipeline: same walker, same refusal (plan-grill
finding; verify-pipeline printed "No contracts found" and returned 0, and a
process::exit there killed the crate's unit-test binary — it returns the error).

Measured on this commit:
  cargo test -p aprender-contracts-cli (every target)      -> 204 passed, 0 failed
  cargo test -p aprender-contracts --lib                   -> 1501 passed
  target/debug/pv lint contracts/                          -> Result: PASS, 1766 contracts, exit 0
  scripts/check_contract_test_binding.sh                   -> PASS, 539 refs resolved
  make gate                                                -> rc=0
Jidoka (.pmat/jidoka.jsonl): pmat complexity flagged lint::run cognitive 30 > 25
with the guard inline; extracted refuse_empty_corpus() and moved the single-file
cache rule into build_config().

Refs PMAT-1099

Pmat-Ticket: PMAT-1099
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DkwPBrLHuPJrJeUbaFBu7P
…h measured RED then GREEN

kind: pattern. Three equations (empty corpus refused; one file is one contract;
--kind filtering to zero refused), three obligations, five falsification tests
citing tests/pvl_zero_contracts.rs by filter. Every if_fails carries the mutation
actually run on 1ca5d39 (see the file): the walker guard, the lint guard, the exit
code, an always-refusing guard against the controls, and the post-filter guard —
each turned its predicted cases RED and only those, and went GREEN on restore.
pv validate: 0 errors. scripts/check_contract_test_binding.sh: PASS.

Refs PMAT-1099

Pmat-Ticket: PMAT-1099
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DkwPBrLHuPJrJeUbaFBu7P
…MAT-1099)

Refs PMAT-1099

Review quorum on #3093 (3 agy lanes, 3/3 FAIL): `lint::run` returned into
`run_watch` and `run_diff_check` BEFORE `refuse_empty_corpus`, so
`pv lint --watch <empty>` printed "Result: PASS" over 0 contracts every 5 s
and `pv lint --diff HEAD <empty>` said "Nothing to lint" at exit 0.
Both are the vacuous pass PVL-1 exists to end.

- run_watch: the same guard after every run_lint tick (exit 2 at the first
  tick over an empty corpus; a corpus emptied mid-watch ends the watch at 2).
- run_diff_check: "nothing changed" is only said over a non-empty corpus
  (collect_corpus, the one definition of empty; exit 2 otherwise).

RED (guard stashed, tests present):
  cargo test -p aprender-contracts-cli --test pvl_zero_contracts -- lint_watch_empty_dir_is_refused lint_diff_empty_dir_is_refused
  -> FAILED. 0 passed; 2 failed (watch: killed at 20 s after repeated "Result: PASS" over 0 contracts, code -1; diff: exit 0)
GREEN:
  cargo test -p aprender-contracts-cli --test pvl_zero_contracts -> ok. 17 passed; 0 failed

Not changed (recorded for the next run): exit 2 is shared with clap usage
errors - all three lanes call that an ambiguity; PVL-001 row EV-1 mandates 2.
`changed_contracts` diffs the literal `contracts/` path, not <dir> (diff.rs:22).

Pmat-Ticket: PMAT-1099
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DkwPBrLHuPJrJeUbaFBu7P
…, not re-reviewed, STOP(andon)

Refs PMAT-1099

Pmat-Ticket: PMAT-1099
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DkwPBrLHuPJrJeUbaFBu7P
…a broken file is measured not dropped (PVL-1, PMAT-1099)

Refs PMAT-1099

Second review quorum on #3093 (3 agy lanes, 3/3 FAIL): the walker in
contract_walk.rs used a private file rule and silently DROPPED files that
failed to parse, so a directory of only broken YAML was "0 contracts"
(exit 2) to proof-status and `lint --diff` while `lint` measured the same
directory as `contracts: 1, errors: 1` (exit 1). The private rule also
skipped every `*playbook*` stem, and the corpus holds real contracts named
that way (apr-page-examples-*-playbook*-v1.yaml): proof-status counted
fewer contracts than lint over the same tree.

- `provable_contracts::lint::collect_yaml_files` (is_contract_yaml + the
  skipped sidecar dirs) is now public and is THE file rule; the walker,
  coverage (its private duplicate walker deleted) and the diff-mode probe
  all use it. Over contracts/: lint 1767, proof-status 1767, coverage 1767.
- A contract file that fails to parse is ParseErrors (exit 1, every file
  named, "N of M contract files under <path> failed to parse"), never a
  silent skip and never "0 contracts".
- `lint --diff <ref>` with nothing changed probes for contract files
  without parsing (has_contract_files): exit 0 in 31 ms over contracts/
  (the previous fix parsed the whole corpus on that path).
- The sidecar fixture: a `*playbook*` file is not a sidecar (it is a
  contract name in the corpus); the test now uses a dot-prefixed file.

Falsifiers (contracts/work/PMAT-1099.yaml v1.1.0, each measured):
  006 watch guard removed + diff probe neutralised ->
      `cargo test -p aprender-contracts-cli --test pvl_zero_contracts lint_`
      FAILED. 2 passed; 2 failed (lint_watch_…, lint_diff_…) -> restored ok. 4 passed
  007 walker drops parse failures again ->
      `… pvl_zero_contracts -- unparsable_only mixed_dir`
      FAILED. 0 passed; 2 failed -> restored ok. 2 passed
  002 re-measured: guard call in lint::run deleted -> 2 passed; 2 failed -> ok. 4 passed

cargo test -p aprender-contracts-cli: 74+1+64+34+8+19+8 passed, 0 failed;
aprender-contracts lib 1501 passed; make gate rc 0.

Pmat-Ticket: PMAT-1099
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DkwPBrLHuPJrJeUbaFBu7P
… quorum 3 PASS 3/3, artifact

Refs PMAT-1099

Docs only (docs/audits/**): the code reviewed by the third quorum is 3f573c3.

Pmat-Ticket: PMAT-1099
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DkwPBrLHuPJrJeUbaFBu7P
…e-reader no workflow ran (PMAT-1099)

Refs PMAT-1099

guard-cargo on a81d1e5 (BSE-17 self-test rows 8/9): `scripts/tree_reader_unwired_baseline.txt drifted — > aprender-contracts-cli --test pvl_zero_contracts` — the new falsifier reads contracts/softmax-kernel-v1.yaml, so it is a tree-reader, and the full tier runs `--workspace --lib` only: no workflow would ever have executed it. Ledgering it as "reads the tree and nothing runs it" would make PVL-1's gate a test that never runs; it is wired into the same `cargo test -p X --test Y` chain as pv_surface_gate instead, and the derived registry is regenerated with `scripts/check_tree_reader_tests.sh --update` (never hand-edited).

Local: `check_tree_reader_tests.sh` rc 0; `ci_test_tier.sh --self-test` 15 checks, 0 failed.

This PR now touches .github/workflows/ci.yml: STOP(workflow-merge: aprender PR 3093) per PVL-001 §4.5 — operator merge once gate and workspace-test are green.

Pmat-Ticket: PMAT-1099
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DkwPBrLHuPJrJeUbaFBu7P
noahgift and others added 2 commits September 10, 2026 18:03
…rst 'Host layout' step exports CI_TARGETS_ROOT / CI_CARGO_ROOT / SCCACHE_HOST_DIR / CI_REGISTRY / IMAGE with the intel clean-room defaults, 33 hardcoded sites read them; byte-identical on intel (#3100)

Also: check_runner_labels.sh accepts the `build` pool label. No job changes where it runs yet (BP-3).

Pmat-Ticket: PMAT-1098

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
(cherry picked from commit 77038f4)
… box carrying `build` (intel clean-room or yoga-eph); gate on any pool box (operator 2026-09-10: requeue to available capacity; #3100)

Pmat-Ticket: PMAT-1096

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
(cherry picked from commit 3b56d00)
@github-actions

github-actions Bot commented Sep 10, 2026

Copy link
Copy Markdown

§13.11 rung 1 — quorum shadow verdict

S13-SHADOW pr=3093 head=0828696272e5d72e53c2f1af38acd6d44c89850b verdict=REFUSE class=Q1 arm_rc=1

Shadow mode: this records a verdict and merges nothing. A refusal
to arm is not a block (§13 adds zero rows to §7) — the pull request is
exactly as green as it was.

noahgift and others added 7 commits September 10, 2026 18:07
…pool (operator direction 2026-09-10) (PMAT-1099)

Cherry-picked byte-identical from #3098/#3101 (-x); the ci.yml delta to #3098 is the pvl_zero_contracts wiring only. Receipt records the verbatim direction and the local guard results.

Pmat-Ticket: PMAT-1099

Claude-Session: https://claude.ai/code/session_01DkwPBrLHuPJrJeUbaFBu7P

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…ontract, so the generated count moves 1817 -> 1818 (PMAT-1099)

guard-cargo FALSIFY-README-002 is an EQUALITY, not a ratchet: the block is generated by scripts/readme_sync.sh, so a generated number may not lag the merge tree. `make readme-sync` wrote both blocks; check_readme_claims.sh now PASSes (1818 agrees with merge tree). G-11 does not bind: this is not an agent/<row> branch.

Pmat-Ticket: PMAT-1099

Claude-Session: https://claude.ai/code/session_01DkwPBrLHuPJrJeUbaFBu7P

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
… ANY x86 box carrying `build`" on this row (PMAT-1099)

MEASURED, not assumed: every job that landed on a yoga box today died in `actions/checkout` before a single step ran — EACCES rmdir on a root-owned _work/aprender/aprender/target. On this branch that took workspace-test, guard-tree, guard-cargo and pr-review-shadow (yoga-build) and vendored-schemas (yoga-eph); on #3098 it took guard-tree. workspace-test alone burned 10 attempts on yoga-build between 16:35 and 16:45. The pre-checkout EACCES self-heal does not save it: the docker-inspect branch is TAKEN and the chown reaches a different filesystem view than the containerized runner workspace, while `2>/dev/null || true` keeps the step green.

This revert is branch-local and nets to zero against a main that later carries BP-3, so it cannot regress the pool. BP-1 (the host-layout env indirection) is KEPT. Undo this commit once the yoga _work trees are swept.

Pmat-Ticket: PMAT-1099

Claude-Session: https://claude.ai/code/session_01DkwPBrLHuPJrJeUbaFBu7P

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…e yoga checkout EACCES (not mine, escalated) (PMAT-1099)

Pmat-Ticket: PMAT-1099

Claude-Session: https://claude.ai/code/session_01DkwPBrLHuPJrJeUbaFBu7P

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…ox" on this row (PMAT-1099)

BP-1 rewrites GUARD_TARGET_DIR from the literal `run-${{ github.run_id }}-guards` env key into an `echo ... >> $GITHUB_ENV` form, and scripts/tests/guard_tree_test.sh asserts the literal: the case row "guard-cargo has its own target dir suffix (run-<RUN_ID>-guards)" reports `matches=0` and guard-tree goes RED — measured on intel-clean-room-3, so this is BP-1, not the yoga host gaps. The same row will go red on #3101, which carries BP-1 on its own.

With BP-3 already reverted, BP-1 buys this row nothing, so both come off and the ci.yml delta to origin/main is exactly the pvl_zero_contracts wiring.

Pmat-Ticket: PMAT-1099

Claude-Session: https://claude.ai/code/session_01DkwPBrLHuPJrJeUbaFBu7P

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…stderr line (PVL-1, PMAT-1099)

The third review quorum on #3093 (3 lanes, 3 FAIL) found `pv validate` unguarded: it reads one artifact and never went through the walker, so a nonexistent path was exit 1 `No such file or directory` and an empty directory exit 1 `Is a directory (os error 21)` — while the spec row names validate beside lint, proof-status, coverage and graph. Guarded first; a directory now validates every file lint would walk with an accumulator. `pv lint /nonexistent` leaked `cannot create /.pv` ahead of the refusal (two lines, three under --diff): the corpus check moves ahead of the cache dir, the diff probe and the watcher (a helper, so lint::run keeps cognitive 25 — the hook ceiling), and assert_refused asserts exactly one stderr line. The prefix names the verdict class: `decline:` for exit 2, `error:` for exit 1 — the vocabulary in PVL-001 §0 and the row's own RED text. verify_pipeline's unit tests ignored `run`'s Result (this PR made it fallible; clippy --all-targets -D warnings: 3 errors → 0). Mutation FALSIFY-PVL-1-008 measured RED (empty dir → exit 0, the vacuous PASS) then GREEN.

Refs PMAT-1099

Pmat-Ticket: PMAT-1099
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01F6j8JyVRA7yDHTjgDbviW4
…, decline: prefix all re-measured (PMAT-1099)

Second review quorum of this session, three independent agy lanes, writes=false, on the head that carries the validate fix. Every lane re-measured the three findings of the 3/3 FAIL quorum on 77187ac as closed, the directory walk as correct, the decline: prefix as harmless to the other suites, and the ci.yml delta as the one-line wiring. Artifact bound to head + diff_sha256 so pmat-merge can read it; partial=true is only lane 1's benign stderr note ("root agent idle; waiting for 1 background task"). Lane models unreported by agy (EV-17).

Refs PMAT-1099

Pmat-Ticket: PMAT-1099
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01F6j8JyVRA7yDHTjgDbviW4
@noahgift
noahgift enabled auto-merge September 11, 2026 07:31
…contracts

# Conflicts:
#	docs/roadmaps/roadmap.yaml
@noahgift

Copy link
Copy Markdown
Contributor Author

quorum-review (AD-04): three PASS — agreed

{
 "ticket": "PMAT-1099",
 "head": "5f6acd76b376606a8365a770903f462484ce15cb",
 "width": 3,
 "executor": "agy",
 "agreed": true,
 "lanes": [
  {
   "lane": 1,
   "verdict": "PASS",
   "findings": 5
  },
  {
   "lane": 2,
   "verdict": "PASS",
   "findings": 3
  },
  {
   "lane": 3,
   "verdict": "PASS",
   "findings": 5
  }
 ]
}

… after #3089)

Refs PMAT-1099

Pmat-Ticket: PMAT-1099

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…dditive guard read the 0.67.0 train squash as deletions on this branch (PMAT-980 remedy, #2874)

python3 scripts/lib/roadmap_diff.py trim --base origin/main --file docs/roadmaps/roadmap.yaml --write

Pmat-Ticket: PMAT-1098

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
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