Conversation
|
§13.11 rung 1 — quorum shadow verdict Shadow mode: this records a verdict and merges nothing. A refusal |
…ived from launched backward kernels, not from the request Pmat-Ticket: PMAT-991
…launch; training_backend_banner derived from it (PMAT-991, #2906) Pmat-Ticket: PMAT-991
…ent, the cuda request on a cpu-only build is a refusal (exit 9) Pmat-Ticket: PMAT-991
…(exit 9); the cuBLAS backward line is printed after training from entrenar's launch counter, never from the request (PMAT-991, #2906) Pmat-Ticket: PMAT-991
…ne's test module (the lib.rs test seam is blocked by pre-existing complexity debt in lib.rs's include graph: dispatch.rs, help_producer_truth.rs); test_run_training_creates_adapter exercises the CPU path it always ran, and says so — 'cuda' on a cpu-only build is now a refusal (PMAT-991) Pmat-Ticket: PMAT-991
… banner is derived from launches, a gpu request the build cannot honour is FeatureDisabled (PMAT-991, #2906) README.md's contract count was already at 1812 on the rebased base (bumped by the G-11 ratchet process since this branch's original base); no README edit needed or made here (row PRs do not write README.md, driver rule). Pmat-Ticket: PMAT-991
… rows Pmat-Ticket: PMAT-991
…unch snapshot, no reset API; a second fine-tune in one process inherits nothing; race-free tests), four more device-side backward launch sites counted (f16->f32 a, NF4 cuBLAS/PTX/tensor-core a), -m lora --gpu-backend cuda is ValidationFailed exit 5 (refuse or train on the GPU), dead gpu_backend_notice removed (PMAT-991, #2906) Pmat-Ticket: PMAT-991
…able-with-changes, lane 1 right on the f16 site, three more NF4 sites found), mutations re-run at a137ba6 Pmat-Ticket: PMAT-991
|
Rebased onto Re-verified at HEAD (
|
|
Auto-merge armed. Currently |
…dogfood `pmat work add` was not used, for the two reasons this ticket exists: 1. It allocates from the roadmap it can see. Max across origin/main and every open pp-066 head is PMAT-1079, and three instances are minting concurrently, so an auto-mint races. 1090 leaves 1080-1089 as headroom. A gap is opaque; a collision is data loss (and 12 duplicate ids on stale heads is what turned `ci / security` red on #3031 and #3001). 2. It re-serialises the whole file — the defect this ticket fixes. The new `--staged` mode judged its own commit, which is the point: $ bash scripts/check_roadmap_diff_additive.sh --staged === roadmap.yaml STAGED diff is additive: base=c04eda87d (merge-base(origin/main, HEAD)) head=8e4ceee37 (index tree) === roadmap-diff: base=818 head=819 added=1 lifecycle=0 reserialised=0 deleted=0 PASS $ git diff --cached --stat docs/roadmaps/roadmap.yaml | 19 +++++++++++++++++++ added=1, reserialised=0, 0 deletions. That is the diff the rule asks for, and `pmat work add` cannot produce it — which is why the remedy script exists and why nothing calling it made the rule unenforceable in practice. Refs #3047, PMAT-1090. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EeUX4ymyt8XhjXbtTuNH8L
check_roadmap_diff_additive.sh reported base id(s) missing at head: this branch forked before they landed on main, and a plain update takes one side of the file whole. Resolved as main's roadmap plus this branch's own new entries, each at its sorted slot among same-prefix peers. The other three roadmap guards pass on the result. Pmat-Ticket: PMAT-1098 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
check_roadmap_diff_additive.sh reported base id(s) missing at head: this branch forked before they landed on main, and a plain update takes one side of the file whole. Resolved as main's roadmap plus this branch's own new entries, each at its sorted slot among same-prefix peers. The other three roadmap guards pass on the result. Pmat-Ticket: PMAT-1098 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
check_roadmap_diff_additive.sh reported base id(s) missing at head: this branch forked before they landed on main, and a plain update takes one side of the file whole. Resolved as main's roadmap plus this branch's own new entries, each at its sorted slot among same-prefix peers. The other three roadmap guards pass on the result. Pmat-Ticket: PMAT-1098 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…n moved main under this branch Pmat-Ticket: PMAT-1098 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
check_roadmap_diff_additive.sh reported base id(s) missing at head: this branch forked before they landed on main, and a plain update takes one side of the file whole. Resolved as main's roadmap plus this branch's own new entries, each at its sorted slot among same-prefix peers. The other three roadmap guards pass on the result. Pmat-Ticket: PMAT-1098 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
check_roadmap_diff_additive.sh reported base id(s) missing at head: this branch forked before they landed on main, and a plain update takes one side of the file whole. Resolved as main's roadmap plus this branch's own new entries, each at its sorted slot among same-prefix peers. The other three roadmap guards pass on the result. Pmat-Ticket: PMAT-1098 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
… run it exits 2 on its own line 4 (paiml#3048) * fix(B4): the roadmap remedy had zero callers and the hook that would run it exits 2 on its own line 4 (paiml#3047) `guard-tree` is red on PP-066 paiml#3025 — instance A's only MERGEABLE open PR — for one entry: $ bash scripts/check_roadmap_diff_additive.sh $(git merge-base origin/main pr3025) pr3025 VIOLATION reserialised: id=PMAT-1077 (bytes differ, no field actually changed) roadmap-diff: base=818 head=824 added=6 lifecycle=36 reserialised=1 deleted=0 `pmat work add` re-serialises the whole roadmap on every call. This repo already knows that, already detects it, and already ships the remedy — and the remedy had ZERO call sites: every `git grep roadmap_trim` hit was prose (a contract field, a receipt, this guard's own RED footer). Detection lived only in CI, so the loop was commit → push → wait 11 min for guard-tree → read a footer → run trim → push again. The hook that would have closed that loop could not run at all. `.githooks/pre-commit` was `#!/bin/sh` with `set -euo pipefail`; /bin/sh is dash here, so following the install line in its own header refused EVERY commit before a single check ran: $ /bin/sh .githooks/pre-commit ; echo $? .githooks/pre-commit: 4: set: Illegal option -o pipefail 2 An unpassable gate is not a gate. It is why core.hooksPath on this box points somewhere else entirely. WHAT CHANGED - `check_roadmap_diff_additive.sh --staged` judges the INDEX. `git write-tree` makes the staged content a real tree object and roadmap_diff.py already resolves any ref via `git show <ref>:<file>`, so this is the identical rule set CI applies, run against exactly the bytes about to be committed. One implementation, two entry points — a second copy of the rule list is how bashrs#266 happened. - The base is plain merge-base(origin/main, HEAD), NOT resolve_base, and the reason is written at the divergence: resolve_base's push-shape branch exists because a COMMIT judged against itself passes vacuously, which cannot arise when the head is the index tree. On a branch freshly cut from main it would return the tip's PARENT and attribute main's own entries to this commit. - `.githooks/pre-commit`: bash shebang, and the roadmap guard runs FIRST (cheapest check, costliest miss). rc 2 = "this box cannot judge" warns and does not block, because guard-tree still refuses — nothing goes silently green. FALSIFIED, NOT ASSERTED Rows 19-22 of the case table, both polarities, hermetic (the scratch repos set core.hooksPath=/dev/null so the table judges this guard, not the developer's hook install). 22/22. Two mutations, each caught: M1 base <- resolve_base → row 22 rc=0→1 (main's re-serialisation misattributed), rows 19,20 rc→2. SELF-TEST FAILED. M2 `run_check ... || true` → row 20 rc=1→0 (the gate cannot fail). SELF-TEST FAILED. Restored: 22/22 rows. Row 22 is the discriminating one: it asserts the PASS *and* that the printed base is the origin/main tip, so it cannot pass for the wrong reason. Closes paiml#3047. Refs PMAT-980, G-6, #2874, paiml#3025. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EeUX4ymyt8XhjXbtTuNH8L * chore(B4): reserve PMAT-1090 — and the append is the fix's own first dogfood `pmat work add` was not used, for the two reasons this ticket exists: 1. It allocates from the roadmap it can see. Max across origin/main and every open pp-066 head is PMAT-1079, and three instances are minting concurrently, so an auto-mint races. 1090 leaves 1080-1089 as headroom. A gap is opaque; a collision is data loss (and 12 duplicate ids on stale heads is what turned `ci / security` red on paiml#3031 and paiml#3001). 2. It re-serialises the whole file — the defect this ticket fixes. The new `--staged` mode judged its own commit, which is the point: $ bash scripts/check_roadmap_diff_additive.sh --staged === roadmap.yaml STAGED diff is additive: base=c04eda87d (merge-base(origin/main, HEAD)) head=8e4ceee37 (index tree) === roadmap-diff: base=818 head=819 added=1 lifecycle=0 reserialised=0 deleted=0 PASS $ git diff --cached --stat docs/roadmaps/roadmap.yaml | 19 +++++++++++++++++++ added=1, reserialised=0, 0 deletions. That is the diff the rule asks for, and `pmat work add` cannot produce it — which is why the remedy script exists and why nothing calling it made the rule unenforceable in practice. Refs paiml#3047, PMAT-1090. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EeUX4ymyt8XhjXbtTuNH8L * chore(B4): quorum verdict artifact — 3/3 PASS (PMAT-1090, paiml#3048) Three independent agy lanes judged the diff against PMAT-1090 and the receipt. AGREED: lane 1=PASS, lane 2=PASS, lane 3=PASS. No lane raised a finding with cited or measured grounding; the single asserted finding restates the ticket. Refs paiml#3047, PMAT-1090. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EeUX4ymyt8XhjXbtTuNH8L --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
check_roadmap_diff_additive.sh reported base id(s) missing at head: this branch forked before they landed on main, and a plain update takes one side of the file whole. Resolved as main's roadmap plus this branch's own new entries, each at its sorted slot among same-prefix peers. The other three roadmap guards pass on the result. Pmat-Ticket: PMAT-1098 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…enerated (T-5 R-4) Pmat-Ticket: PMAT-1098 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
check_roadmap_diff_additive.sh reported base id(s) missing at head: this branch forked before they landed on main, and a plain update takes one side of the file whole. Resolved as main's roadmap plus this branch's own new entries, each at its sorted slot among same-prefix peers. The other three roadmap guards pass on the result. Pmat-Ticket: PMAT-1098 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…is the answer One conflict, docs/audits/impl-estimates.jsonl. Both sides APPENDED: this branch added four PMAT-991 rows, main added three PMAT-972 rows (via #3006). Taking either side whole deletes measurements nothing else records. Resolved as the union, main's rows first since they are already in main's history. Verified after: 46 rows, every one valid JSON, zero duplicates, no conflict markers. Pmat-Ticket: PMAT-1098 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…is the answer One conflict, docs/audits/impl-estimates.jsonl. Both sides APPENDED different tickets' rows; taking either side whole deletes measurements nothing else records. Resolved as the union, main's rows first since they are already in main's history — the same resolution #3001 needed an hour ago, for the same reason: a squash-merge from the queue makes every branch carrying this file DIRTY on it. Verified after: every row valid JSON, zero duplicates, no conflict markers. Pmat-Ticket: PMAT-1098 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
One conflict, docs/audits/impl-estimates.jsonl, append-only, resolved as the union with main's rows first. #3001 at ~07:05Z, #3093 at ~08:35Z, this at ~08:45Z — three identical resolutions in under two hours. #3256 is the fix: `docs/audits/*.jsonl merge=union` in .gitattributes, with a guard holding the scope (149 goldens and datasets must NOT be union-merged). Once that lands this conflict stops existing. Pmat-Ticket: PMAT-1098 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
… the conflict was right Two conflicts. docs/audits/impl-estimates.jsonl — append-only, resolved as the union with main's rows first. Fourth time today (#3001, #3093, #3005, this); #3256 makes it stop. README.md — the CONTRACT_COUNT block, 1839 on this branch against 1837 on main. Taking either side would have been wrong: the branch ADDS contracts, so the merged tree is neither number. CLAUDE.md's rule for this table is explicit — "the table gives the command, and the value is only a dated sample. If a number here disagrees with its command, the command wins." find contracts -name '*.yaml' | wc -l -> 1840 Set to 1840 at both blocks, and check_readme_claims.sh agrees: PASS FALSIFY-README-002 contract_count: 1840 (CONTRACT_COUNT block, derived by scripts/readme_sync.sh; 1 block(s) agree with the merge tree 259c8f7) A generated value is not a text conflict to pick a side of. It is a question with a command attached. Pmat-Ticket: PMAT-1098 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
PP-066 DAG row R-3 (spec §5 T-6, D-7; epic #2873; ticket PMAT-991; receipt
docs/audits/impl-PMAT-991-receipt.md,status: partialuntil merged).feedback_apr_finetune_lora_cpu_only: the "cuBLAS backward" training banner was printed from the request, before any step, on any build;--gpu-backend cudaon a cpu-only build fell through to the CPU silently. Now the banner is an event and the impossible request is a refusal.What lands
entrenar(crates/aprender-train):backward_kernel_launches()/reset_backward_kernel_launches()— anAtomicU64bumped at every cuBLAS backward launch (cuda_forward/matmul.rsa, a_accumulate, b;matmul_f16.rsa, b);training_backend_banner(requested) -> Option<String>isSomeiffrequested == "cuda"and the counter > 0. RED-first testtests/banner_truth.rs(both feature arms; the cuda arm drives one cuBLAS backward on this box's RTX 4090 and watches the counter move).apr finetune:gpu_backend_decision(requested, build_has_cuda, build_has_wgpu)—cuda/wgpuon a build without the feature isCliError::FeatureDisabled(exit code 9, read fromerror.rs:106);auto/cpunever refuse;pre_training_noticenever says "cuBLAS backward";post_training_bannerprintsentrenar's line after training. Case tablecommands/finetune_gpu_backend_truth_tests.rs(5 tests, both polarities).contracts/apr-train-banner-truth-v1.yaml(kind: pattern, TBT-OB-001..003;pv validatevalid,pv lint0/0). README contract count 1811 → 1812.test_run_training_creates_adapterhard-coded"cuda"and asserted the old silent fallback; it now names the CPU path it always ran.Acceptance, re-run by the orchestrator on eaea476
cargo test -p aprender-train --test banner_truthcargo test -p aprender-train --test banner_truth --features cuda(lambda, sm_89)cargo test -p apr-cli --lib gpu_backend_truthcargo test -p apr-cli --libcargo test -p aprender-train --libprune::snapshot_tests— identical on a pristine origin/main worktree at 65680cd while CI's workspace-test there is green: local insta drift,src/pruneuntouched herecargo fmt --all -- --check·cargo clippy -p {aprender-train,apr-cli} --lib -- -D warningscheck_contract_test_binding.sh·check_contract_enforcement.sh·check_readme_claims.sh·check_no_claim_literals.sh·check_roadmap_diff_additive.shMutations — RED, then restored GREEN
training_backend_bannerreturns Some for "cuda" regardless of the counterbanner_is_none_for_cuda_with_zero_launchesFAILED,cpu_only::cpu_backward_never_increments_the_device_counterFAILED (0 passed, 2 failed) → restored 2 passedgpu_backend_decisionreturnsOk(Cpu)for "cuda" on a build without cudacuda_request_on_cpu_only_build_is_a_refusal_not_a_fallbackFAILED,gpu_backend_decision_case_tableFAILED (3 passed, 2 failed) → restored 5 passedFindings recorded in the receipt
aprender-train, the lib isentrenar(S0-10 class).crates/apr-cli/src/lib.rscannot be committed on this box: the pre-commit complexity hook follows itsinclude!()graph and refuses on pre-existing debt (dispatch.rs:103cognitive 41,dispatch.rs:508cognitive 30,help_producer_truth.rs:51cognitive 73). The integration-test seam was dropped; the case table lives incommands::finetune's own test module. Not discharged with#[allow]or--no-verify.autograd/cuda_backward/— a PTX-only backward would leave the bannerNone(open question for the 3-lane review; the spec names the cuBLAS sites).Review round (3-lane quorum, 2026-09-06 — 3/3 mergeable with changes; applied at a137ba6, re-verified)
training_backend_banner(requested, launches_at_start), snapshot beforetrainer.train(), no reset API); the tests snapshot and compare (race-free under parallel tests).gemm_f16_to_f32_backward_alaunched uncounted; lanes 2/3 said all sites were covered. Lane 1 was right, and three more uncounted device backward launches were found inmatmul.rs(gemm_nf4_backward_a_cublas, the NF4 PTX and tensor-core backward_a — the QLoRA path). Nine launch sites are counted now.-m lora --gpu-backend cudanow REFUSES (ValidationFailed, exit 5) instead of running the CPU path under a GPU flag;auto+ plain LoRA is the CPU path and the notice says so (gpu_backend_decisiongainedmethod_has_cuda_path).gpu_backend_notice/GpuBackendPlan(still holding the request-derived cuBLAS string) and their five tests removed.banner_truth2/2 (default and--features cuda),gpu_backend_truth8/8,cargo test -p apr-cli --lib7211 passed,cargo test -p aprender-train --lib7621 passed + the same three pre-existing prune snapshot failures, clippy/fmt clean,pv validatevalid. Mutations: 1 (banner unconditional) 0/2 passed; 2 (cuda on a cpu-only build → Cpu) 6/8; 3 (plain LoRA + cuda → Cuda, no refusal) 7/8; all restored GREEN.Quorum verdicts and the adjudication are in the receipt. Receipt for this PR itself: advisory, not produced (driver A1).
no-close: #2873 is the epic this row implements one part of; an epic is not closed by one of its rows.