Skip to content

feat(parity): L0-1b — apr parity --per-op names the first diverging op (1.5B: post_ffn_residual layer 26); the CPU Q8_K reference is the inaccurate side - #3032

Merged
noahgift merged 51 commits into
mainfrom
agent/L0-1b
Sep 9, 2026
Merged

Conversation

@noahgift

@noahgift noahgift commented Sep 6, 2026

Copy link
Copy Markdown
Contributor

Row L0-1b (#2971, PP-066 #2873) — steps 0, 1 and 2. Not armed yet: receipt is status: partial until the gx10 twin is measured (fleet-verify).

Ticket

PMAT-1070 (minted in #3025). Issue #2971 (P0, inst:A).

Claim

apr parity <gguf> --per-op names the first op where the GPU-resident forward stops computing the function the CPU reference computes — per (stage, layer), over every prompt position (78 ≥ 64, I8), exit 0 with the table, the admission gate bypassed internally and recorded (never SKIP_PARITY_GATE). On the 1.5B it names post_ffn_residual layer 26 (min cosine 0.660150 @pos 0) and its lm_head row is the gate's own 0.9508; on the 7B it names nothing.

RED test

Commit 71a25c2: parity_per_op_table unit tests (forward order; downstream red is never the answer) and per_op_tap tests (selected stage only; unarmed writes and computes nothing; bypass thread-local). Live twin (POP-F-003): .pr/L0-1b/accept.sh legs A5/A6 on lambda.

Acceptance

APR=<cuda build> bash .pr/L0-1b/accept.sh → 6/6: table tests · tap tests · pv validate · arms doc · 1.5B names layer 26 with lm_head within 1e-3 of 0.9508 · 7B clean.

Step 1 arms (measured, docs/audits/l0-1b-arms.md)

graph off · FP8 decode off · FP8 all off · flash decode off · fused gate-up off · all off → 0.9508 @pos 0 in every arm; 7B 0.9986. No switchable GPU path is the mechanism.

The finding (measured; the receipt and the arms doc carry the tables)

Layers 0–25 agree at every op. At position 0 the residual carries a massive activation (dim 408 = −3664); the layer-26 FFN cancels it on CPU (ffn_out +3675.7 → residual 11.3) but not on GPU (4084.2 → 407). ffn_norm@26 is identical on both sides; ffn_swigl@26 neurons 2908/7035 differ by +14 %/+7.5 %. A float64 recomputation from the dequantised weights (.pr/L0-1b/step0/probe26.py) gives −1142.0/618.4: the GPU is within 0.5 % of the truth; the CPU (−996.4/573.6) is 13 % off and is reproduced to three decimals by Q8-quantising the activation per 256 elements. The CPU Q8_K reference is the inaccurate side on massive-activation tokens.

Step 2 — the fix (commit 361d685)

quantize::has_crushed_block (per 256-block max/second ≥ 8; basis: the measured criterion table — never on 77 ordinary positions × 28 layers, ≥ 20 on the first token's crushed blocks) sends that one matmul to the f32-activation kernel (quantize::direct_f32) through matvec_into_honest on the reference forward (QKV, o_proj, gate/up, down) and the fused gate+up driver.

before after
1.5B apr parity min cosine 0.950827 (1 < 0.98, 2 argmax≠) 0.999761 (0, 0)
1.5B --per-op first diverging op / lm_head post_ffn_residual L26 / 0.950827 none / 0.999761
7B apr parity min cosine 0.998607 0.999580
GPU dump tree, GPU m=1 greedy streams on 5 local models byte-identical
CPU decode 1.5B 64 tok n=3 (tok/s) 11.6 · 10.8 · 10.8 12.0 · 13.2 · 12.6 (no slowdown resolved; basis [U])

Mutation

  • POP-F-003 revert twin (measured, same tree): has_crushed_block → false → the 1.5B table names post_ffn_residual layer 26 again, lm_head 0.950827, accept.sh A5 RED; the mutant's CPU dump tree is bitwise identical to the pre-fix tree (24,258 files) — the routing refactor changes nothing by itself. Restored → 6/6.
  • Unit-level (in the contract): reverse the forward scan → ordering test RED; ignore should_save → tap test RED; has_crushed_block 4 tests (the layer-26 block, an ordinary block, one-hot, all-zero).
  • CI RED→GREEN pair: no guard step is added by this PR; the falsifier is the live twin above.

Contract

contracts/apr-parity-per-op-v1.yaml (kind: pattern; POP-OB-001..003 ↔ POP-F-001..003) — pv validate through scripts/pv_bin.sh: valid.

Decomposition (hook-clean, verified)

forward_single_with_cache 26/55 → 6/9 and single_cache_ffn_block 21/69 → 6/12 (cyclomatic/cognitive), split into small helpers. Oracle: the per-op CPU dump tree over 78 positions — 24,258 files bitwise identical before/after; GPU tree identical; same first diverging op.

Quorum

.pr/L0-1b/quorum.md — three families (gemini-3.1-pro, claude-sonnet-4-6, gpt-oss-120b): 3/3 endorse fixing the CPU side; lane 2's dissent ("per-32 matches the GPU" is falsified by the probe table) folded; the delegate's zero-code arm DIRECT_FP32_GEMV=1 measured 0.9508 → 0.999896 before the fix was written.

Receipt

docs/audits/impl-PMAT-1070-receipt.mdstatus: partial (step 2 open).

Writes

code: crates/apr-cli/src/commands/{parity_per_op.rs,parity_per_op_table.rs,mod.rs,dispatch_analysis.rs}, crates/apr-cli/src/extended_commands.rs, crates/aprender-serve/src/quantize/{mod.rs,direct_f32.rs,fused_gate_up.rs}, crates/aprender-serve/src/inference_trace/gpu_stage_dump.rs (+gpu_stage_dump/per_op_tap.rs), crates/aprender-serve/src/cuda/executor/{stage_dump.rs,mod.rs,layers/phase_attention.rs,layers/indexed_ffn.rs}, crates/aprender-serve/src/gguf/cuda/{mod.rs,mod_parity_gate.rs}, crates/aprender-serve/src/gguf/inference/forward/ffn_block.rs · contracts: contracts/apr-parity-per-op-v1.yaml · receipt · docs/audits/l0-1b-arms.md · .pr/L0-1b/** (plan, accept.sh, step0 evidence). No shared files.

Fleet pin note: this branch sits on agent/L0-1 (#3026) and carries its cuda-feature fix (gpu_profile_or_none error type).

🤖 Generated with Claude Code

… binary c642576eecb62daa) — apr parity --json over 78 positions: qwen2.5-coder-1.5b min cosine 0.9508 at position 0 (|Δlogit|max 11.97), qwen2.5-coder-7b min 0.9986; under the horizon rule (min over >= 64 positions >= 0.98 [U]) 1.5B RED / 7B GREEN before any kernel edit (#3017)

Pmat-Ticket: PMAT-1065
…est.sh -> evidence/models/supported.yaml, 18 models, every entry cites file:line; --check refuses a hand-typed entry; 6-row case table); C14 scripts/check_model_parity.sh --manifest (apr parity over >= 64 positions per manifest model, min cosine vs evidence/parity/thresholds.yaml — 0.98 [U] until item 5 measures it; UNMEASURED reported, README-cited unmeasured RED; SKIP_PARITY_GATE is an override that prints and refuses; 6-row case table over the lambda records: 1.5B RED, 7B GREEN, must-RED twin, < 64 positions refused) (#3017, PMAT-1065)

Pmat-Ticket: PMAT-1065
…tree already does (cited), the five-whys hypothesis for the N-lane quorum; threshold basis = PARITY_GATE_COSINE_MIN (mod.rs:803), itself [U]

Pmat-Ticket: PMAT-1065
…S (record corrected); the fused Q8_1 FFN is off by default (gpu_profile.rs:238), so the five-whys step 3 is refuted on default config and the 1.5B/7B asymmetry on the unfused path is the open question; the surviving zero-risk fix is REG-15's selected: line; lanes were one family (gap)

Pmat-Ticket: PMAT-1065
…s its duplicate under driver v5.1) — receipt, record, scripts and manifest cite it

Pmat-Ticket: PMAT-1065
…izon gate, the derived manifest, REG-15 admission); ci.yml guard-runner-labels runs the manifest case table + --check and C14's case table; every 0.65.2 (1.5B, cuda) dogfood receipt relabelled INVALID-CORRECTNESS citing #2971 (PMAT-1065)

Pmat-Ticket: PMAT-1065
… a forced backend never downgrades — CliError::ParityFailed with its own code read at test time; unforced prints selected: cpu (reason: parity FAILED …); PASS prints selected: cuda …), override_line() for SKIP_PARITY_GATE, parse_gate_error over the load-time gate's message; 7 hermetic tests (worker-written, orchestrator-verified) (#2971, PMAT-1065)

Pmat-Ticket: PMAT-1065
…oad failure: a parity-gate failure prints selected: cpu (reason: parity FAILED cosine=… threshold=…) when unforced (apr chat today) and refuses when forced (R-0b's --backend); apr compare prints the override line only when the user set SKIP_PARITY_GATE (diff-benchmark's silent set_var waits for its own decomposition — the file is over the complexity gate) (#2971, PMAT-1065)

Pmat-Ticket: PMAT-1065
…pare override), the worker ledger, the cuda type-check on lambda, and the gaps (diff-benchmark decomposition, effective-config block, apr devices --model, dogfood C14, threshold measurement, gx10)

Pmat-Ticket: PMAT-1065
…lsifier (FAILs the run if it ever passes), then check_model_parity.sh --manifest over the built binary: PASS when measured, FAIL on a measured failure or an override, REPORT with the reason on a host that holds no manifest model (the pre-publish proof is make fleet-verify ROW=release on lambda and gx10) (#2971, PMAT-1065)

Pmat-Ticket: PMAT-1065
…e lambda 1.5B record must be RED and the 7B record GREEN under evidence/parity/thresholds.yaml (read by regex, no default), both over >= 64 positions; the full manifest runs only in dogfood, the release and R-8 (#2971, PMAT-1065)

Pmat-Ticket: PMAT-1065
…ambda) sits at min cosine 0.9986 in all five runs and the known-bad pair (1.5B@lambda) at 0.9508 in all five (both deterministic, stdev 0.0); 0.98 lies between; [U] until the gx10 pair (#2971, PMAT-1065)

Pmat-Ticket: PMAT-1065
…ositions,threshold,basis} — the load-time gate returns the cosine it measured, the CUDA model carries a ParityGateRecord (PASS | skipped under the SKIP_PARITY_GATE override | not-run) set by one admission helper, the report is never absent (not-run on cpu residency or a non-cuda build); shape test (#2971, PMAT-1065)

Pmat-Ticket: PMAT-1065
…cs under --features cuda)

Pmat-Ticket: PMAT-1065
…st targets (GREEN on a GPU-less host; the live manifest is the fleet-verify leg); receipt carries the v6 DONE-IF ledger

Pmat-Ticket: PMAT-1065
…itations moved); accept.sh GREEN on this host (10/10 legs)

Pmat-Ticket: PMAT-1065
…rive_model_manifest.sh --check must go RED in guard-runner-labels) and min_cosine 0.90 (the 1.5B sentinel must PASS and sentinel_1p5b_on_lambda_is_red must FAIL in workspace-test). REVERTED after the RED run ids are captured (I3)

Pmat-Ticket: PMAT-1065
… row 7); UNMEASURED is a per-host REPORT and a host that measured nothing is not a pass (the fleet-level rule is R-5's); aliases of one file are measured once (longest name first); the case table judges under its own threshold fixture and writes the tracked twin only when absent; PAR-F-003's test is the admission level (R-0b owns backend_refusal_case_table); the manifest's admission rule is stated (#2971, PMAT-1065)

Pmat-Ticket: PMAT-1065
…one() so the silent SKIP_PARITY_GATE set_var becomes the printed override (the file was over the complexity gate) (#2971, PMAT-1065)

Pmat-Ticket: PMAT-1065
…to R-0b, two documented) in the receipt

Pmat-Ticket: PMAT-1065
…ED line (SC2075); the round-1 guard job stopped at the bashrs step before reaching the manifest mutation

Pmat-Ticket: PMAT-1065
…ade STALE (diff_benchmark_report.rs::run, error.rs::resolve_model_path, gguf/cuda/mod.rs::preload_and_verify are now under both thresholds) — the shrink-only ratchet demands the delete

Pmat-Ticket: PMAT-1065
…t alias only resolves without --features cuda (cuda build of apr-cli was RED: E0107)

Pmat-Ticket: PMAT-1065
…every SaveTensorStage on both forwards, admission bypassed internally), the bisection arms with their switches (FP8_PREFILL/FP8_DECODE, BATCHED_GRAPH, flash_decode_enabled, force_high_precision_ffn), the andon (#2971)

Pmat-Ticket: PMAT-1065
… new I8 sentinel test (thresholds_demand_at_least_sixty_four_positions) must turn workspace-test RED; round-1 mutants (typed manifest entry, min_cosine 0.90) reverted — their RED is run 34049865821 (guard: manifest derivation step; workspace-test: sentinel_1p5b test)

Pmat-Ticket: PMAT-1065
…sis I8); the I8 threshold test stays. Round-2 RED: run 34052968770 (workspace-test: thresholds_demand_at_least_sixty_four_positions, 3/3 tries); round-1 RED: run 34049865821 (guard: manifest derivation step; workspace-test: sentinel_1p5b)

Pmat-Ticket: PMAT-1065
…e over every position (CPU tap on the reference forward, executor stage dump per phase, internal gate bypass recorded as skipped); step 1 arms + the layer-26 finding (docs/audits/l0-1b-arms.md): the CPU Q8_K reference is the inaccurate side on massive-activation tokens; forward_single_with_cache / single_cache_ffn_block decomposed (cognitive 55/69 -> 9/12), CPU dump tree bitwise identical (24,258 files)

Pmat-Ticket: PMAT-1070
…rity-per-op-v1 (pv valid), accept.sh 6/6 on lambda

Pmat-Ticket: PMAT-1070
@noahgift noahgift added pp-066 PP-066 (0.66) DAG row inst:A PP-066 instance claim (I14): inst:A labels Sep 6, 2026
noahgift and others added 6 commits September 7, 2026 09:32
…e, revert falsifier, speed n=3 [U]), gaps (gx10 twin, apr chat line, scratch/traced paths)

Pmat-Ticket: PMAT-1070
…EQUIRED_TOP_LEVEL_KEYS 12 -> 13; the shape test was RED on the GREEN leg (run 34093549220)

Pmat-Ticket: PMAT-1065
…e type is already must_use (clippy double_must_use under deny(clippy::all))

Pmat-Ticket: PMAT-1065
…s into guard-tree

BSE-001 M2 split the old guard-runner-labels job into guard-tree (cargo-free,
dispatched by scripts/guard_tree.sh) and guard-cargo. The four L0-1a steps
(derive_model_manifest.sh --self-test/--check, check_model_parity.sh --self-test)
are cargo-free by `grep -cE '(^|[^a-z_-])cargo '` == 0 on both scripts, so they
re-anchor into guard-tree after check_row_pr_write_set.sh, the same neighbour they
had before the split.

Also drops unfused_test.json — a 0-byte file left at the repo root by the round-2
mutation run (193d626) and committed by accident.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018RouwmUL7vFfJyCx9qLEoH
noahgift and others added 10 commits September 8, 2026 13:13
…hold [U] lifted, the divergence is model-selected not device-selected

Card items (iv) and (vi). `make fleet-verify` does not exist (BSE's G-11b), so the
measurement was taken rather than waited on.

gx10-a5b5, aarch64, NVIDIA GB10 (sm_121), driver 590.48.01, apr 0.65.2 (c04eda8)
sha256 21d182d69505159c. Mechanism engaged, not intended: every run's stderr carries
`[GH-480] Patched N backward branch(es) for sm_121 JIT workaround`, a path lambda's
sm_89 build does not have.

  model                                positions<0.98  min cosine  max|dlogit|@0  verdict
  qwen2.5-coder-1.5b-instruct-q4_k_m         1           0.950611     12.0087       RED
  qwen2.5-coder-7b-instruct-q4_k_m           0           0.998465      0.8032       GREEN

n=5 per cell, stdev 0.0 in all four cells across both hosts.

THE FINDING. Two GPU generations, two ISAs, two host architectures, one running a JIT
workaround the other does not have — and the known-bad pair lands within 2.2e-4 of the
same cosine (lambda 0.950827, gx10 0.950611) while the known-good pair on the same
silicon is 0.9985+. The divergence is selected by the MODEL (hidden 1536/heads 12/kv 2
/GQA 6 vs 3584/28/4/7), not by the device. Every "an sm_89 kernel is wrong" or "the
sm_121 JIT patch corrupts a branch" hypothesis is refuted before L0-1b dispatches a
lane. It is asserted, not merely written down: the_two_hosts_agree_on_each_model_to_
within_a_thousandth goes RED if that stops holding.

The driver's 0.9418 / 5.38 were guessed to be gx10's numbers by all three earlier lanes.
They are not: gx10 measures 0.950611 / 12.0087. The source report's provenance stays [U];
the defect it names is confirmed on both required hosts.

Item (iv) CLOSED, the [U] on evidence/parity/thresholds.yaml lifted: 0.98 now separates
two measured known-good pairs from two measured known-bad pairs with 0.0185 of margin
under the lower good floor, asserted at >= 0.01 on each side, because a gate that passes
with no headroom is a finding (0.63.0 hansei) and a near-tie once inverted a whole
diagnosis (#2359).

Falsifiers added: check_model_parity.sh --self-test 7 -> 9 rows (both polarities on BOTH
hosts); sentinel_tests 4 -> 8 (1.5B RED / 7B GREEN per host, cross-host agreement,
threshold margin on both sides).

Refs #2971, PMAT-1065

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018RouwmUL7vFfJyCx9qLEoH
…ps into guard-tree

Same resolution as agent/L0-1: BSE-001 M2 split guard-runner-labels into guard-tree
and guard-cargo, and the three L0-1a steps are cargo-free, so they re-anchor into
guard-tree after check_row_pr_write_set.sh. Also drops the 0-byte unfused_test.json.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018RouwmUL7vFfJyCx9qLEoH
…ies is one file

check_hardcoded_paths.sh refused +25 shipped machine-specific paths — 24 of them
`"model": "/home/noah/models/…"` inside the apr parity --json output, one a hardcoded
cargo in accept.sh. That guard has no allowlist by design, and its own header sets the
precedent for evidence: redacting a host path "would delete the evidence and fabricate a
cleaner history".

Neither redaction nor an exemption was needed, because the path was never part of the
measurement.

  * Every canonical record RE-TAKEN with the model named relatively (`cd ~/models &&
    apr parity ./<model>.gguf …`), same pinned binaries (lambda c642576eecb62daa, gx10
    21d182d69505159c), same prompt. The metrics array and every other key are
    BYTE-IDENTICAL to the absolute-path run; only `model` differs — compared field by
    field, not asserted.
  * n5/ drops its ten JSONs per host. All five runs of each model were byte-identical to
    each other AND to the canonical record — stdev 0 understates it, the whole file was
    the same file — so five copies carried nothing their sha256 does not. DETERMINISM.md
    records the hashes and the distinct-count; runs.log keeps the ten exit codes.
  * accept.sh: CARGO="${CARGO:-$HOME/.cargo/bin/cargo}" — still never a bare `cargo`
    (a shell function of that name overrides CARGO_TARGET_DIR), no longer a machine path.

Also `make readme-sync`: the CONTRACT_COUNT block stated 1815 and the merge tree carries
1816 (main's contracts/patterns/ratchet-verdict-d2-v1.yaml plus this row's
apr-gpu-cpu-parity-v1.yaml). That block is GENERATED, so it is an equality, not a ratchet.

check_hardcoded_paths.sh --full: delta +0. sentinel_tests 8/8. accept.sh 12/12.

Refs #2971, PMAT-1065

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018RouwmUL7vFfJyCx9qLEoH
…achine path

check_hardcoded_paths.sh refused +25 shipped paths; the resolution was neither a
redaction nor an exemption — the records were re-taken with the model named relatively
(byte-identical metrics, same pinned binaries) and the n=5 series collapsed to its
sha256, because all five runs were byte-identical to the canonical record. delta +0.

Refs #2971, PMAT-1065

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018RouwmUL7vFfJyCx9qLEoH
…refusal proof never ran on main

Found by asking of this row what R-0b's regenerated tree-reader ledger asked of its
sibling: which of this PR's test targets does a workflow actually execute?

  $ grep -rc reg15_admission .github/workflows/   ->  no match

crates/apr-cli/tests/reg15_admission.rs is card item (i)'s falsifier — seven hermetic
tests, among them forced_backend_over_a_failed_parity_gate_refuses_with_the_code_from_
error_rs, which is the whole claim of REG-15: a forced backend never silently downgrades.
BSE-17's quick tier runs it on a PR that touches apr-cli, but the full tier and every push
to main run `--lib` plus ONE explicit list of --test targets, and it was not on that list.
Merged as it stood, nothing on main would ever have executed it again — the exact trap
recorded for the beats line (a new test target is theater until it is added there).

It joins that line beside cli_commands. Note the scale of the standing problem while
passing: apr-cli carries 64 integration targets and the line names 7 of them (#2341).

Refs #2971, PMAT-1065

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018RouwmUL7vFfJyCx9qLEoH
…taken portably from the pre-fix mutant build

check_hardcoded_paths.sh refused 11 shipped machine-specific paths. Seven were real
portability defects in the scripts — accept.sh, probe26.py, probe26b.py and sweep.sh
hardcoded ~/models, and sweep.sh reached into a SIBLING WORKTREE for
check_model_parity.sh's PROMPT. Now ${APR_MODELS_DIR:-$HOME/models} and a $ROOT derived
from the script's own location.

The other four were recorded `apr parity` outputs whose `model` field held the absolute
path, and two of them are the PRE-FIX table — the fix has since landed, so re-running was
not available. They were re-taken from the registered mutant instead (has_crushed_block
returning false, built --features cuda from this branch, sha256 0372f1cc846c0992; the
post-fix build of the same tree is 776cbbdb4306b5d8), with the model named relatively.

All four came back BIT-FOR-BIT identical — 283 rows and every other key, including
first_divergence post_ffn_residual layer 26 at min cosine 0.660150 @0, the row's central
finding. Only `model` differs.

That is worth more than the cleanup that prompted it: the step-0 evidence is not an
artifact a reader must trust, it is a FUNCTION of the committed tree, recoverable by
flipping one predicate. The source was restored immediately; `git status` on
quantize/mod.rs is clean.

check_hardcoded_paths --full: delta +0. check_no_claim_literals: PASS.

Refs #2971, PMAT-1082

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018RouwmUL7vFfJyCx9qLEoH
…ts n=5 series is one file

The same treatment the lambda records already had, applied to the gx10 twin this session
added: check_hardcoded_paths.sh counted 14 more, all `"model": "/home/noah/models/…"`
inside apr parity output.

  * n5/ drops its ten JSONs. All five runs of each model were byte-identical to each other
    AND to the canonical record — stdev 0 understates it, the whole file was the same file
    — so five copies carried nothing their sha256 does not. DETERMINISM.md records the
    hashes and the distinct-count; runs.log keeps the ten exit codes.
  * The two canonical records and the two --per-op summaries were re-taken with the model
    named relatively on the SAME binary (apr 0.65.2 (ecbd8e4), sha256 8cdb7c1a668127db).
    Every metrics/rows array and every other key is byte-identical; only `model` differs,
    compared field by field.

check_hardcoded_paths --full: delta +0 (from +14). sentinel_tests unchanged.

Refs #2971, PMAT-1082

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018RouwmUL7vFfJyCx9qLEoH
…tly extends L0-1a's

Three conflicts, all the same shape and all resolved to ours, because this branch is where
L0-1a's parity-gate API grew rather than a divergent take on it:

  commands/mod.rs         main lacks parity_per_op / parity_per_op_table — L0-1b's modules
  cuda/mod.rs             ParityGateRecord gains skipped_for_diagnosis() and load_time_skip()
                          -> Option<Self>; main carries L0-1a's earlier bool form
  mod_parity_gate.rs      admit_by_parity_gate takes Option<ParityGateRecord>, not bool

"Ours" is a claim until the callers agree, so both crates were compiled after the
resolution rather than eyeballed: `cargo check -p aprender-serve --lib` and
`cargo check -p apr-cli --lib` both clean.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018RouwmUL7vFfJyCx9qLEoH
@noahgift

noahgift commented Sep 8, 2026

Copy link
Copy Markdown
Contributor Author

Rebased onto the new main (L0-1a landed), acceptance re-run 6/6

#3026 merged, so this branch merged origin/main. Three conflicts, all the same shape and all resolved to ours, because this is the branch where L0-1a's parity-gate API grew rather than a divergent take on it:

file main here
commands/mod.rs no parity_per_op* L0-1b's two modules
cuda/mod.rs ParityGateRecord bool form skipped_for_diagnosis(), load_time_skip() -> Option<Self>
mod_parity_gate.rs admit_by_parity_gate(bool) admit_by_parity_gate(Option<ParityGateRecord>)

"Ours" is a claim until the callers agree, so both crates were compiled after the resolution rather than eyeballed: cargo check -p aprender-serve --lib and cargo check -p apr-cli --lib, both clean.

.pr/L0-1b/accept.sh6/6, hardware legs included:

ok A1 cargo test -p apr-cli --lib parity_per_op_table
ok A2 cargo test -p aprender-serve --lib per_op_tap
ok A3 pv validate contracts/apr-parity-per-op-v1.yaml
ok A4 docs/audits/l0-1b-arms.md non-empty
ok A5 apr parity <1.5B> --per-op  → no diverging op, lm_head ≥ 0.98
ok A6 apr parity <7B>   --per-op  → no diverging op

Shared guards run pre-emptively rather than discovered one CI cycle at a time — claims ratchet, hardcoded paths (--full), competing harnesses, baseline ratchets, tree-reader registry: all 0.

Why this is the release

D-14 rescoped 0.66.0 to the CUDA parity fix and nothing else, and this PR is the fix. With it, C14 — the release criterion for 0.66's single claim — runs live and passes on lambda:

PASS qwen2.5-coder-1.5b-instruct: 78 positions, min cosine 0.9998 at position 36 >= 0.98
PASS qwen2.5-coder-0.5b-instruct: 78 positions, min cosine 0.9996 at position 0
PASS qwen2.5-coder-7b-instruct:   78 positions, min cosine 0.9996 at position 22
C14: measured=3 rc=0

Receipt: evidence/release/0.66.0/C14-live-lambda.md. The gx10 twin of the fix (GB10, sm_121, aarch64) is in evidence/parity/l0-1b/gx10/: 1.5B 0.950611 → 0.999583, 7B 0.998465 → 0.999782, first_divergence none on both.

@noahgift
noahgift enabled auto-merge September 8, 2026 19:46
…e T2 denominator

The branch adds --per-op / --out / --threshold to `apr parity`, which is new
CLI surface cited by docs/audits/surface_audit.csv, so check_dogfood_coverage.sh
G2.1 freshness went red. Three rows added; then two things fell out of it.

1. in_dogfood_skill is `no`, not `yes`. The skill's Phase 2b sweep runs
   `"$APR" parity $MODEL` -- the bare subcommand. It does not pass a flag, so
   it does not exercise these three. Marking them `yes` would have moved
   coverage 143/833 (17.2%) -> 146/836 (17.5%) while covering nothing: the
   exact theatre G2.6 exists to stop, in the commit that touches G2.6. The
   column is self-declared and nothing verifies it, which is why it has to be
   declared against what the sweep actually runs.

2. The T2 pairing rule keys on the NUMBER, so growing the ledger invalidated
   the prose. `states_feature_ratio` matches a line only when the live feature
   denominator appears on it (the `feature...N/M` pattern needs the word before
   the digits, and these lines are written "143/833 features"). 833 -> 836 left
   four lines stating a cluster ratio with no feature ratio the guard could
   see. Re-derived in contracts/apr-dogfood-coverage-v1.yaml (references,
   description, baselines block, the T2 invariant, F-DOGCOV-009's prediction)
   and .claude/skills/apr-dogfood/SKILL.md.

The description also mis-stated its own floor -- "Coverage is ALLOWED to be
17.2%. It is not allowed to become 17.1%" reads as a ratio floor. check_floors()
ratchets COUNTS (total up, covered up, per-binary covered up) and never the
ratio, and it has to: honestly adding ungated surface must be allowed to lower
the ratio, because the only ways to hold a ratio while shipping three uncovered
flags are to omit them from the ledger or to mark them gated. Corrected to say
what the code enforces and why.

Dogfood coverage for the three flags is owed and is 0.67 work, not 0.66.

Verified: check_dogfood_coverage.sh rc=0 (G2.1/2.2/2.3/2.4/2.5/2.6 all PASS,
836 rows, 143 covered); --self-test rc=0, every registered mutation still RED;
pv validate 0 errors. README count re-synced 1816 -> 1817 for FALSIFY-README-002.

Refs #3032

Pmat-Ticket: PMAT-1070
…three uncited speed factors

Two guards went red on the merge, both for the same reason -- this branch changed
numbers that other files had recorded.

1. dogfood_baseline.py --check: the contract pins per_binary / per_band /
   per_cluster totals, and the three new `apr parity` flag rows moved four of
   them. Re-derived from the ledger, matching the script's own output exactly:
     per_binary  apr           370 -> 373 (covered 143)
     per_band    q7_8            9 -> 11  (covered 9,  100.0% -> 81.8%)
     per_band    q9_10          20 -> 21  (covered 20, 100.0% -> 95.2%)
     per_cluster apr-lint-diag  68 -> 71  (covered 55,  80.9% -> 77.5%)
   `--check` now prints CHECK PASSED.

2. check_perf_claims_cite_receipts.sh (PERF-010) reported three NEW uncited
   speed comparisons in crates/aprender-serve/src/quantize/mod.rs. They are not
   new: the identical text sits at 179/292/318 on origin/main and this branch's
   +99 lines pushed it to 181/294/320. The baseline is file:line keyed, so a
   pure shift reads as three arrivals and seven stale locations.

   `--update` is the WRONG remedy and the guard says so: the ratchet is
   per-entry, not per-count -- re-running it left the file smaller (243 -> 238)
   and still RED, because an entry may only LEAVE. So the findings are fixed
   instead:
     "~3x faster than half::f16::from_bits().to_f32()"     -> mechanism, no factor
     "provides 2-4x speedup for Q4_K GEMV operations"      -> mechanism, no factor
     "Intel AVX-512 Guide: Contiguous loads 5x faster"     -> vendor guidance, marked as not a measurement of this code
   None of the three had a receipt, on this tree or any other. The op counts
   under `# Performance` are structural and stay; "Expected speedup" stays too,
   because a target needs no receipt.

Verified: dogfood_baseline.py --check PASSED; check_perf_claims_cite_receipts.sh
rc=0 (new: 0, dangling: 0, ratchet did not grow vs d6ed9ac);
check_dogfood_coverage.sh rc=0; cargo check -p aprender-serve --lib rc=0.

Refs #3032

Pmat-Ticket: PMAT-1070
@noahgift
noahgift added this pull request to the merge queue Sep 9, 2026
Merged via the queue into main with commit b0406bc Sep 9, 2026
17 of 19 checks passed
@noahgift
noahgift deleted the agent/L0-1b branch September 9, 2026 09:27
noahgift added a commit that referenced this pull request Sep 9, 2026
…t the root — eight bashrs SEC/DET findings from #3032/BSE scripts, six shifted claim literals deleted (shrink-only ratchet), fresh PP-26 witness on lambda (c=1/4/8/16 PASS), C14 builds its own cuda apr on a GPU host, delegate agent-memory gitignored

Pmat-Ticket: PMAT-1096

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BjhtNUSensCYpQb3mCYLod
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

inst:A PP-066 instance claim (I14): inst:A L0-1b PP-066 DAG row L0-1b (#2971) pp-066 PP-066 (0.66) DAG row

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant