From cded0794b7eb58ee4b5523bad874dfb40d8584b0 Mon Sep 17 00:00:00 2001 From: t Date: Sat, 24 Oct 2026 09:48:59 +0200 Subject: [PATCH 1/2] chore(roadmap): introduce the frozen roadmap-base.yaml snapshot (S1b data, Refs #6185) A byte copy of docs/roadmaps/roadmap.yaml at main dd6d507250; rule 3 and aggregate --check pass. PMAT-Ticket: PMAT-6185 Co-Authored-By: Claude Sonnet 5.5 --- docs/roadmaps/roadmap-base.yaml | 26013 ++++++++++++++++++++++++++++++ 1 file changed, 26013 insertions(+) create mode 100644 docs/roadmaps/roadmap-base.yaml diff --git a/docs/roadmaps/roadmap-base.yaml b/docs/roadmaps/roadmap-base.yaml new file mode 100644 index 0000000000..a048c1551d --- /dev/null +++ b/docs/roadmaps/roadmap-base.yaml @@ -0,0 +1,26013 @@ +roadmap_version: '1.0' +github_enabled: true +github_repo: paiml/aprender +roadmap: +- id: PMAT-081 + github_issue: null + item_type: task + title: 'FORMAT-PARITY-001: Implement SafeTensors and APR inference' + status: completed + priority: high + assigned_to: null + created: 2026-01-20 11:24:51+00:00 + updated: 2026-01-20 20:00:00+00:00 + spec: null + acceptance_criteria: + - Implement PAR-301 (SafeTensors) and PAR-302 (APR) format inference in realizar + - 'PAR-301: SafeTensors /v1/chat/completions with SSE streaming' + - 'PAR-302: APR format /v1/chat/completions with SSE streaming (CPU and GPU)' + phases: [] + subtasks: [] + estimated_effort: 2h + labels: + - inference + - api + - streaming + notes: 'Resolved 2026-01-20: + + - PAR-301: SafeTensors server now has /v1/chat/completions and /generate endpoints + + - PAR-302: APR server (CPU and GPU) now has /v1/chat/completions endpoint + + - Both support OpenAI-compatible API with SSE streaming + + - ChatML prompt template formatting implemented + + ' +- id: PMAT-082 + github_issue: null + item_type: task + title: 'APR-CLI-RELEASE-029: Release apr-cli v0.2.10 to crates.io' + status: completed + priority: high + assigned_to: null + created: 2026-01-20 16:57:43+00:00 + updated: 2026-01-20 17:01:00+00:00 + spec: null + acceptance_criteria: + - 'Version bump: 0.2.9 -> 0.2.10' + - Published to crates.io + - Verified installation from crates.io + - apr --version reports 0.2.10 + - apr run works with 1.5B model + phases: [] + subtasks: [] + estimated_effort: 30m + labels: + - release + - crates-io + notes: 'Released 2026-01-20: apr-cli v0.2.10 published to crates.io + + Verified: cargo install apr-cli installs and runs correctly + + ' +- id: PMAT-083 + github_issue: null + item_type: task + title: PMAT-COMPLY-001 + status: completed + priority: high + assigned_to: null + created: 2026-01-21 16:38:40+00:00 + updated: 2026-01-21 16:41:40.297300+00:00 + spec: null + acceptance_criteria: + - 'Fix all PMAT compliance warnings: missing .pmat-metrics.toml, O(1) hooks cache, file health analysis' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - compliance + - pmat + notes: null +- id: PMAT-084 + github_issue: null + item_type: task + title: 'FILE-HEALTH-001: Refactor large files to improve code health' + status: completed + priority: critical + assigned_to: null + created: 2026-01-21 16:42:33+00:00 + updated: 2026-01-21 16:47:22.466235+00:00 + spec: null + acceptance_criteria: + - 'Split 20 files >2000 lines into smaller modules. Target: all files <2000 lines, avg health >85%' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - refactoring + - file-health + - pmat + notes: null +- id: PMAT-085 + github_issue: null + item_type: task + title: 'FILE-HEALTH-002: Split optim/mod.rs into submodules' + status: completed + priority: critical + assigned_to: null + created: 2026-01-21 16:49:43+00:00 + updated: 2026-02-04 12:47:27+00:00 + spec: null + acceptance_criteria: + - Extract optimizers into separate files to reduce optim/mod.rs from 7090 to <2000 lines + phases: [] + subtasks: [] + estimated_effort: null + labels: + - refactoring + - file-health + notes: null +- id: PMAT-086 + github_issue: null + item_type: task + title: 'SERVE-TRACE-001: Implement X-Trace-Level header in apr serve' + status: completed + priority: medium + assigned_to: null + created: 2026-01-21 18:30:00+00:00 + updated: 2026-01-26 09:50:00+00:00 + spec: null + acceptance_criteria: + - Parse X-Trace-Level header (brick/step/layer) + - Include brick_trace, step_trace, or layer_trace in response when header present + - No trace fields in response when header absent (F-TRACE-004b) + - QA serve script passes F-TRACE-001, F-TRACE-002, F-TRACE-003 + phases: [] + subtasks: [] + estimated_effort: 4h + labels: + - serving + - tracing + - feature + notes: 'Discovered 2026-01-21: X-Trace-Level header documented in examples/serve_with_tracing.rs + + but not implemented in commands/serve.rs. QA script fails F-TRACE-001/002/003. + + + COMPLETED 2026-01-26: All tracing features implemented and working: + + - X-Trace-Level header parsing in serve.rs + + - --trace, --trace-level, --profile CLI flags + + - --trace-output JSON file writing + + - QA tests all pass (qa_serve 35/35, qa_chat 20/20, qa_verify 20/20) + + ' +- id: APR-ANTIGRAVITY-PARITY-001 + github_issue: null + item_type: epic + title: 'Pillar-5 either-harness parity: apr code drivable by Claude Code OR Google Antigravity with + prompt parity' + status: planned + priority: high + assigned_to: null + created: 2026-07-04 00:00:00+00:00 + updated: 2026-07-04 00:00:00+00:00 + spec: docs/specifications/apr-mcp-server-spec.md + acceptance_criteria: + - apr code's CODE model is drivable by EITHER Claude Code (Anthropic Messages wire) OR Google Antigravity + (Gemini generateContent wire) — one agent loop, two wire formats. + - A fixed prompt corpus produces the SAME canonical tool-call trace through both surfaces (FALSIFY-AGY-PARITY-002), + at temperature 0. + - Anthropic input_schema <-> Gemini functionDeclarations.parameters is a lossless map (FALSIFY-AGY-PARITY-003). + - Both HTTP handlers dispatch into the identical apr-code-v1 agent loop (FALSIFY-AGY-PARITY-004) — no + forked per-wire agent. + - contracts/apr-antigravity-parity-v1.yaml promotes DRAFT -> ENFORCED when the two wire surfaces ship + and all four gates pass. + phases: [] + subtasks: [] + estimated_effort: null + labels: + - pillar-5 + - apr-code + - antigravity + - parity + notes: 'Extends the apr-code pillar from Claude-Code-only to EITHER Claude Code OR Google Antigravity, + with prompt parity. Antigravity (Google''''s agent-first IDE) is Gemini-native (generateContent -> + Vertex Model Garden) and also Anthropic-key capable; apr''''s existing apr-claude-proxy-v1 covers + the Anthropic path, and the new apr-gemini-proxy-v1 covers the Gemini path. The invariant that makes + a prompt portable across both is apr-antigravity-parity-v1 (kind: pattern, 4 gates, DRAFT). NOT a + "beat Antigravity" benchmark — Antigravity is a harness apr plugs INTO, not a fourth-pillar incumbent + (the beat framing stays Claude-Code-only in beat-claude-code-parity-v1). Authored 2026-07-04.' +- id: APR-GEMINI-PROXY-001 + github_issue: null + item_type: task + title: apr serve gemini — Gemini generateContent provable-contract proxy (the Antigravity wire surface) + status: planned + priority: high + assigned_to: null + created: 2026-07-04 00:00:00+00:00 + updated: 2026-07-04 00:00:00+00:00 + spec: docs/specifications/apr-mcp-server-spec.md + acceptance_criteria: + - crates/aprender-serve/src/gemini/ translation layer consumes contracts/apr-gemini-proxy-v1.yaml (YAML + authoritative; hand-edited wire shapes rejected). + - POST /v1beta/models/{model}:generateContent + :streamGenerateContent (SSE) implemented; contents/parts/systemInstruction/functionDeclarations/generationConfig + parsed. + - functionCall/functionResponse round-trip to the SAME agent loop as apr serve anthropic (FALSIFY-GEMINI-PROXY-003). + - 'Sovereignty: no egress to *.googleapis.com (FALSIFY-GEMINI-PROXY-006).' + - All six FALSIFY-GEMINI-PROXY-00x gates green -> contract DRAFT -> ENFORCED. + phases: [] + subtasks: [] + estimated_effort: null + labels: + - pillar-5 + - apr-code + - antigravity + - serve + notes: 'Sibling to apr-claude-proxy-v1 (Anthropic). Same default CODE model (Qwen3-Coder-30B-A3B-Instruct + Q4_K_M), same agent loop; only the wire format differs. Key translation asymmetry: Gemini signals + tool use via a functionCall PART + finishReason=STOP, whereas Anthropic uses stop_reason=tool_use + — both must decode to canonical stop_signal=tool_use. Contract: contracts/apr-gemini-proxy-v1.yaml + (validated 2026-07-04).' +- id: APR-ANTIGRAVITY-INTEGRATION-001 + github_issue: null + item_type: task + title: Track & document Antigravity integration paths (Anthropic-key base URL, Gemini endpoint, community + gateways) + status: planned + priority: medium + assigned_to: null + created: 2026-07-04 00:00:00+00:00 + updated: 2026-07-04 00:00:00+00:00 + spec: docs/specifications/apr-mcp-server-spec.md + acceptance_criteria: + - Document, per Antigravity release, whether it accepts a custom base URL on the Anthropic-key path + (apr serve anthropic drop-in) and/or a custom Gemini endpoint. + - 'A runbook: point Antigravity at a local apr instance via whichever path its current version allows + (incl. community gateway if that is the only route).' + - The wire contracts stay a drop-in so apr is ready the instant an official endpoint override lands. + phases: [] + subtasks: [] + estimated_effort: null + labels: + - pillar-5 + - antigravity + - integration + - tracking + notes: HONEST tracking task. As of 2026-Q1 Antigravity has no official "add a custom endpoint" button; + the Gemini path targets Vertex Model Garden and the Claude path uses a user Anthropic key. apr targets + WIRE PARITY (be a drop-in) rather than claiming shipped Antigravity support. This task follows Antigravity''s + evolving BYOK/endpoint story and keeps a working integration runbook. Pairs with APR-GEMINI-PROXY-001. +- id: ROADMAP-RECONCILE-2026-07-04 + github_issue: null + item_type: documentation + title: 'Reconciliation note (2026-07-04): status drift corrected + beats pivot recorded' + status: completed + priority: high + assigned_to: null + created: 2026-07-04 00:00:00+00:00 + updated: 2026-07-04 00:00:00+00:00 + spec: null + acceptance_criteria: + - Stale pre-pivot inprogress epics reclassified to planned (deferred, not actively worked). + - Session-completed items PMAT-730/733/735 marked completed. + - The 2026-06-12 beats-as-CI-artifacts pivot is recorded as the reason APR-BOOK-* and CRUX-L*/CRUX-M* + are deferred. + phases: [] + subtasks: [] + estimated_effort: null + labels: + - housekeeping + notes: 'The GitHub-synced backlog had drifted: 43 items were labelled `inprogress` but none had been + touched since 2026-05-17 — they are the PRE-PIVOT epics (APR-BOOK-* book-completeness, PMAT-497..514; + CRUX-L*/CRUX-M* kernel+gate parity, PMAT-655..678; and the KD/distillation items PMAT-679/680/687/691). + The 2026-06-12 pivot to BEATS-as-CI-artifacts (PMAT-741+) superseded those lanes. To stop the backlog + implying 43 phantom active tasks WITHOUT fabricating completion, all 43 are reclassified `inprogress` + -> `planned` (deferred backlog). Items genuinely finished this session (PMAT-730 roc/pr curves, PMAT-733 + encoder Pipeline gate, PMAT-735 poly+multiclass SVC) are marked `completed`. The live queue is the + June-11 PMAT-72x/73x/74x beat backlog. See SVC-SMO-WSS-001 for a solver follow-up surfaced this session.' +- id: BEAT-OLLAMA-DECODE-CI-001 + github_issue: null + item_type: task + title: Wire beat_ollama_decode_throughput_speed into a GPU-nightly (developer-verified -> CI-enforced) + status: completed + priority: medium + assigned_to: null + created: 2026-07-04 00:00:00+00:00 + updated: 2026-07-04 00:00:00+00:00 + spec: null + acceptance_criteria: + - beat_ollama_decode_throughput_speed (Pillar-4 decode 1.2-1.37x vs ollama) runs on a scheduled GPU + workflow, not just developer-side. + - The runner has (or gets) the required GGUF (qwen2.5-coder-1.5b-instruct-q4_k_m.gguf) + an apr binary + built --features cuda. + phases: [] + subtasks: [] + estimated_effort: null + labels: + - pillar-4 + - ci + - gates-or-theater + notes: 'Surfaced by the 2026-07-04 beat-wiring audit (see feedback_workspace_test_lib_only_beats_ungated). + beat_ollama_decode_throughput_speed is #[ignore]-gated and its docstring says "ENFORCED manual/GPU + gate", but it is in NO scheduled workflow (not ci/gate, not beat-speed-nightly, not cuda-nightly) + — so it is developer-verified only, a softer version of the closed QLoRA doctrine gap. The natural + home is the cuda-nightly lane (has GPU runners), but that needs the q4_k_m GGUF present on the runner + (the QLoRA lane uses a .apr, not a GGUF). Deferred from v0.59 to keep the release free of runner-infra + dependencies.' +- id: SVC-SMO-WSS-001 + github_issue: null + item_type: task + title: 'SVCRbf: upgrade simplified SMO to libsvm 2nd-order working-set selection (WSS)' + status: planned + priority: low + assigned_to: null + created: 2026-07-04 00:00:00+00:00 + updated: 2026-07-04 00:00:00+00:00 + spec: null + acceptance_criteria: + - MultiClassSVC(rbf) reaches sklearn-parity accuracy on the i%3 Iris split at the DEFAULT C=1 (currently + needs C=10 to reach 0.98; at C=1 the pair 1v2 under-converges to train 0.806). + - The existing svc-rbf-v1 sklearn-parity falsifiers stay green. + phases: [] + subtasks: [] + estimated_effort: null + labels: + - pillar-1 + - svm + - follow-up + notes: Surfaced by beat_sklearn_svc_accuracy (PMAT-735). apr's SVCRbf uses a simplified Platt/CS229 + SMO whose working-set selection maximises |E_i - E_j| (first-order). On the overlapping versicolor/virginica + Iris pair at C=1 it stalls short of the max-margin solution (train 0.806 vs sklearn 1.0); a larger + box constraint C=10 lets it reach 0.98 (ties sklearn). Upgrading to the libsvm 2nd-order WSS heuristic + (+ shrinking) should close the gap at the default C=1. Purely a convergence-quality improvement; the + RBF kernel math and existing parity contract are unchanged. +- id: CUDA-CI-NIGHTLY-001 + github_issue: null + item_type: task + title: CUDA nightly CI lane — enforce the GPU QLoRA training-correctness falsifiers + status: completed + priority: high + assigned_to: null + created: 2026-07-03 00:00:00+00:00 + updated: 2026-07-03 00:00:00+00:00 + spec: null + acceptance_criteria: + - A cuda-labeled self-hosted runner is registered on lambda-vector (RTX 4090, sm_89, CUDA 12.8). + - 'A scheduled workflow runs the #[ignore]-gated GPU falsifier suite with APR_PARITY_MODEL set: FALSIFY-CUDA-FUSED-RMSNORM-DEADLOCK-001, + FALSIFY-CUDA-NF4-FORWARD-NAN-001, FALSIFY-CUDA-NF4-TRAIN-LOSS-PARITY-001, FALSIFY-CUDA-EVAL-ADAPTER-SYNC-001, + FALSIFY-CUDA-EVAL-GPU-FORWARD-001, plus the loss-window suite.' + - The lane is GREEN on main and its result is surfaced (nightly first; promote to a blocking gate on + training-path PRs once stable). + - Each formerly developer-verified GPU win is re-annotated as CI-enforced in ROADMAP.md P3 + the relevant + contract qa_gate. + phases: [] + subtasks: [] + estimated_effort: null + labels: + - cuda + - ci + - pillar-3 + - doctrine-gap + notes: 'Closes the biggest "gates or theater" hole surfaced 2026-07-03: the entire v0.55-v0.57 QLoRA + training-correctness wave is falsified only developer-side because the CI fleet has no CUDA runner. + Prereq is purely operational (register the runner); the falsifiers already exist and pass on the 4090.' +- id: GH-9 + github_issue: 9 + item_type: task + title: Implement graph algorithms and descriptive statistics + status: completed + priority: medium + assigned_to: null + created: 2025-11-19 11:43:09.463886+00:00 + updated: 2025-11-19 11:43:09.463886+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: GH-10 + github_issue: 10 + item_type: task + title: Add Graph and Statistics Examples (cargo examples + book chapters) + status: completed + priority: medium + assigned_to: null + created: 2025-11-19 11:51:12.022014+00:00 + updated: 2025-11-20 22:15:00+00:00 + spec: null + acceptance_criteria: + - '`examples/graph_social_network.rs` implemented and tested' + - '`examples/descriptive_statistics.rs` implemented and tested' + - '`book/src/ml-fundamentals/graph-algorithms.md` written' + - '`book/src/ml-fundamentals/descriptive-statistics.md` written' + - '`book/src/examples/graph-social-network.md` written' + - '`book/src/examples/descriptive-statistics.md` written' + - '`book/src/SUMMARY.md` updated' + - '`cargo run --example graph_social_network` works' + - '`cargo run --example descriptive_statistics` works' + - '`mdbook test` passes' + - All examples in CI + - Zero clippy warnings + phases: [] + subtasks: [] + estimated_effort: null + labels: + - documentation + - enhancement + notes: null +- id: GH-11 + github_issue: 11 + item_type: task + title: Add Graph and Statistics Book Chapters + status: completed + priority: medium + assigned_to: null + created: 2025-11-19 11:58:39.815125+00:00 + updated: 2025-11-20 22:15:00+00:00 + spec: null + acceptance_criteria: + - book/src/ml-fundamentals/graph-algorithms.md written + - book/src/ml-fundamentals/descriptive-statistics.md written + - book/src/examples/graph-social-network.md written + - book/src/examples/descriptive-statistics.md written + - book/src/SUMMARY.md updated + - '`mdbook test` passes' + - Zero clippy warnings + phases: [] + subtasks: [] + estimated_effort: null + labels: + - documentation + notes: null +- id: GH-13 + github_issue: 13 + item_type: task + title: Implement PCA (Principal Component Analysis) for Dimensionality Reduction + status: completed + priority: medium + assigned_to: null + created: 2025-11-19 13:44:12.333717+00:00 + updated: 2025-11-20 21:05:00+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - enhancement + notes: null +- id: GH-15 + github_issue: null + item_type: task + title: 'New task: GH-15' + status: completed + priority: medium + assigned_to: null + created: 2025-11-21 07:03:43.949171+00:00 + updated: 2025-11-21 07:12:09.670302+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: GH-16 + github_issue: null + item_type: task + title: 'New task: GH-16' + status: completed + priority: medium + assigned_to: null + created: 2025-11-21 07:17:59.807813+00:00 + updated: 2025-11-21 07:28:00.029018+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: Sovereign AI Integration Specification v1.1 - Complete architecture document with 10 peer-reviewed + references, Toyota Way principles, and Rust safety improvements + github_issue: null + item_type: task + title: 'New task: Sovereign AI Integration Specification v1.1 - Complete architecture document with + 10 peer-reviewed references, Toyota Way principles, and Rust safety improvements' + status: completed + priority: medium + assigned_to: null + created: 2025-11-20 19:29:36.580632+00:00 + updated: 2025-11-20 19:29:42.227136+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: 'Apply code review safety fixes: Add AprenderError enum and bounds checking to SIMD intrinsics' + github_issue: null + item_type: task + title: 'New task: Apply code review safety fixes: Add AprenderError enum and bounds checking to SIMD + intrinsics' + status: completed + priority: medium + assigned_to: null + created: 2025-11-20 20:42:39.109330+00:00 + updated: 2025-11-20 20:44:14.615018+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: Update trait signatures to use AprenderError instead of static str + github_issue: null + item_type: task + title: 'New task: Update trait signatures to use AprenderError instead of static str' + status: completed + priority: medium + assigned_to: null + created: 2025-11-20 20:46:40.295933+00:00 + updated: 2025-11-20 21:00:09.527059+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: Commit integration specification and proptest configuration + github_issue: null + item_type: task + title: 'New task: Commit integration specification and proptest configuration' + status: completed + priority: medium + assigned_to: null + created: 2025-11-20 21:03:37.876707+00:00 + updated: 2025-11-20 21:04:09.930853+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: Update roadmap status for completed TOP 10 algorithms (KNN, GBM, PCA) + github_issue: null + item_type: task + title: 'New task: Update roadmap status for completed TOP 10 algorithms (KNN, GBM, PCA)' + status: completed + priority: medium + assigned_to: null + created: 2025-11-20 21:04:35.044773+00:00 + updated: 2025-11-20 21:05:13.323191+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: Push completed work to origin/main (5 commits) + github_issue: null + item_type: task + title: 'New task: Push completed work to origin/main (5 commits)' + status: completed + priority: medium + assigned_to: null + created: 2025-11-20 21:17:27.397448+00:00 + updated: 2025-11-20 21:17:51.956065+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: Fix remaining mdbook test failures - Phase 3 (21 chapters remaining) + github_issue: null + item_type: task + title: 'New task: Fix remaining mdbook test failures - Phase 3 (21 chapters remaining)' + status: completed + priority: medium + assigned_to: null + created: 2025-11-20 21:39:39.730580+00:00 + updated: 2025-11-20 21:41:50.464473+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: Fix mdbook test failures - Phase 4 (20 chapters remaining) + github_issue: null + item_type: task + title: 'New task: Fix mdbook test failures - Phase 4 (20 chapters remaining)' + status: completed + priority: medium + assigned_to: null + created: 2025-11-20 21:44:50.318332+00:00 + updated: 2025-11-20 21:46:50.712543+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: Fix mdbook test failures - Phase 5 (~17 chapters remaining) + github_issue: null + item_type: task + title: 'New task: Fix mdbook test failures - Phase 5 (~17 chapters remaining)' + status: completed + priority: medium + assigned_to: null + created: 2025-11-20 21:48:29.672555+00:00 + updated: 2025-11-20 21:50:13.463967+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: Fix mdbook test failures - Phase 6 (~15 chapters remaining) + github_issue: null + item_type: task + title: 'New task: Fix mdbook test failures - Phase 6 (~15 chapters remaining)' + status: completed + priority: medium + assigned_to: null + created: 2025-11-20 21:52:06.527576+00:00 + updated: 2025-11-20 21:54:35.813015+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: Fix mdbook test failures - Phase 7 (pca.md + classification-metrics.md) + github_issue: null + item_type: task + title: 'New task: Fix mdbook test failures - Phase 7 (pca.md + classification-metrics.md)' + status: completed + priority: medium + assigned_to: null + created: 2025-11-20 21:58:39.173370+00:00 + updated: 2025-11-20 22:02:26.233402+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: Fix mdbook test failures - Phase 8 (cross-validation.md + graph-algorithms.md) + github_issue: null + item_type: task + title: 'New task: Fix mdbook test failures - Phase 8 (cross-validation.md + graph-algorithms.md)' + status: completed + priority: medium + assigned_to: null + created: 2025-11-20 22:02:58.867836+00:00 + updated: 2025-11-20 22:04:15.869386+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: Fix mdbook test failures - Phase 9 (descriptive-statistics.md + gradient-descent.md) + github_issue: null + item_type: task + title: 'New task: Fix mdbook test failures - Phase 9 (descriptive-statistics.md + gradient-descent.md)' + status: completed + priority: medium + assigned_to: null + created: 2025-11-20 22:04:47.052534+00:00 + updated: 2025-11-20 22:06:24.550064+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: Fix mdbook test failures - Phase 10 (remaining example chapters) + github_issue: null + item_type: task + title: 'New task: Fix mdbook test failures - Phase 10 (remaining example chapters)' + status: completed + priority: medium + assigned_to: null + created: 2025-11-20 22:07:00.816335+00:00 + updated: 2025-11-20 22:08:13.348266+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: Fix mdbook test failures - Phase 11 (pca-iris.md remaining failures) + github_issue: null + item_type: task + title: 'New task: Fix mdbook test failures - Phase 11 (pca-iris.md remaining failures)' + status: completed + priority: medium + assigned_to: null + created: 2025-11-20 22:11:09.621505+00:00 + updated: 2025-11-20 22:15:09.640635+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: GH-17 + github_issue: null + item_type: task + title: 'New task: GH-17' + status: completed + priority: medium + assigned_to: null + created: 2025-11-21 07:40:31.818413+00:00 + updated: 2025-11-21 12:13:31.151843+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: GH-18 + github_issue: null + item_type: task + title: 'New task: GH-18' + status: completed + priority: medium + assigned_to: null + created: 2025-11-21 11:17:52.675519+00:00 + updated: 2025-11-21 12:14:04.777014+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: GH-19 + github_issue: null + item_type: task + title: 'New task: GH-19' + status: completed + priority: medium + assigned_to: null + created: 2025-11-21 10:59:12.766837+00:00 + updated: 2025-11-21 12:11:44.082761+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: GH-20 + github_issue: null + item_type: task + title: 'New task: GH-20' + status: completed + priority: medium + assigned_to: null + created: 2025-11-21 07:52:04.630299+00:00 + updated: 2025-11-21 12:10:25.405809+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: GH-21 + github_issue: null + item_type: task + title: 'New task: GH-21' + status: completed + priority: medium + assigned_to: null + created: 2025-11-21 11:30:25.181964+00:00 + updated: 2025-11-21 12:07:22.866631+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: GH-22 + github_issue: null + item_type: task + title: 'New task: GH-22' + status: completed + priority: medium + assigned_to: null + created: 2025-11-21 11:49:10.771678+00:00 + updated: 2025-11-21 11:59:43.592344+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: GH-23 + github_issue: 23 + item_type: task + title: '[TOP 10] Implement K-Nearest Neighbors (kNN) Classifier' + status: completed + priority: medium + assigned_to: null + created: 2025-11-19 14:08:23.937219+00:00 + updated: 2025-11-20 21:05:00+00:00 + spec: null + acceptance_criteria: + - KNN struct with fit/predict + - Distance metric selection + - Weighted voting option + - Comprehensive tests (EXTREME TDD) + - 'Example: knn_iris.rs' + - 'Book chapter: ml-fundamentals/knn.md' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - enhancement + notes: null +- id: GH-26 + github_issue: 26 + item_type: task + title: '[TOP 10] Implement Gradient Boosting Machine (GBM)' + status: completed + priority: medium + assigned_to: null + created: 2025-11-19 14:56:44.525541+00:00 + updated: 2025-11-20 21:05:00+00:00 + spec: null + acceptance_criteria: + - GradientBoostingClassifier struct + - GradientBoostingRegressor struct + - fit/predict/staged_predict + - Feature importance + - Early stopping + - Comprehensive tests (EXTREME TDD) + - 'Example: gbm_boston_housing.rs' + - 'Book chapter: ml-fundamentals/gradient-boosting.md' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - enhancement + notes: null +- id: GH-28 + github_issue: null + item_type: task + title: 'New task: GH-28' + status: completed + priority: medium + assigned_to: null + created: 2025-11-21 12:42:05.362403+00:00 + updated: 2025-11-21 12:46:42.641483+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: GH-29 + github_issue: null + item_type: task + title: 'New task: GH-29' + status: completed + priority: medium + assigned_to: null + created: 2025-11-21 12:49:45.703737+00:00 + updated: 2025-11-21 13:11:53.462171+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: GH-30 + github_issue: null + item_type: task + title: 'New task: GH-30' + status: completed + priority: medium + assigned_to: null + created: 2025-11-21 13:16:18.584051+00:00 + updated: 2025-11-21 13:29:44.157674+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: GH-31 + github_issue: null + item_type: task + title: 'New task: GH-31' + status: completed + priority: medium + assigned_to: null + created: 2025-11-21 13:33:21.749313+00:00 + updated: 2025-11-21 13:48:32.660770+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: GH-32 + github_issue: null + item_type: task + title: 'New task: GH-32' + status: completed + priority: medium + assigned_to: null + created: 2025-11-21 13:55:00.544325+00:00 + updated: 2025-11-21 14:08:59.586296+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: GH-33 + github_issue: null + item_type: task + title: 'New task: GH-33' + status: completed + priority: medium + assigned_to: null + created: 2025-11-21 14:17:30.771076+00:00 + updated: 2025-11-21 14:17:57.608899+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: GH-34 + github_issue: null + item_type: task + title: 'New task: GH-34' + status: completed + priority: medium + assigned_to: null + created: 2025-11-21 14:23:06.530519+00:00 + updated: 2025-11-21 14:31:20.029584+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: GH-35 + github_issue: null + item_type: task + title: 'New task: GH-35' + status: completed + priority: medium + assigned_to: null + created: 2025-11-21 14:34:14.673583+00:00 + updated: 2025-11-21 14:38:41.793960+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: GH-36 + github_issue: null + item_type: task + title: 'New task: GH-36' + status: completed + priority: medium + assigned_to: null + created: 2025-11-21 14:42:41.019533+00:00 + updated: 2025-11-21 14:51:05.174993+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: GH-37 + github_issue: null + item_type: task + title: 'New task: GH-37' + status: completed + priority: medium + assigned_to: null + created: 2025-11-21 14:55:09.364756+00:00 + updated: 2025-11-21 15:01:01.611666+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: GH-38 + github_issue: null + item_type: task + title: 'New task: GH-38' + status: completed + priority: medium + assigned_to: null + created: 2025-11-21 15:03:31.978891+00:00 + updated: 2025-11-21 16:12:51.743937+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: GH-39 + github_issue: null + item_type: task + title: 'New task: GH-39' + status: completed + priority: medium + assigned_to: null + created: 2025-11-21 16:16:55.158861+00:00 + updated: 2025-11-21 16:22:12.459727+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: GH-40 + github_issue: null + item_type: task + title: 'New task: GH-40' + status: completed + priority: medium + assigned_to: null + created: 2025-11-21 16:34:18.816174+00:00 + updated: 2025-11-21 16:40:15.070800+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: GH-41 + github_issue: null + item_type: task + title: 'New task: GH-41' + status: completed + priority: medium + assigned_to: null + created: 2025-11-21 16:41:38.188482+00:00 + updated: 2025-11-21 17:36:21.927026+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: GH-42 + github_issue: null + item_type: task + title: 'New task: GH-42' + status: completed + priority: medium + assigned_to: null + created: 2025-11-21 17:41:19.984865+00:00 + updated: 2025-11-21 22:08:41.304854+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: GH-43 + github_issue: null + item_type: task + title: 'New task: GH-43' + status: completed + priority: medium + assigned_to: null + created: 2025-11-21 17:50:56.372225+00:00 + updated: 2025-11-21 22:57:34.454368+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: GH-44 + github_issue: null + item_type: task + title: 'New task: GH-44' + status: completed + priority: medium + assigned_to: null + created: 2025-11-21 18:42:10.066174+00:00 + updated: 2025-11-21 18:56:13.410426+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: GH-45 + github_issue: null + item_type: task + title: 'New task: GH-45' + status: completed + priority: medium + assigned_to: null + created: 2025-11-21 18:57:42.654906+00:00 + updated: 2025-11-21 19:02:44.219926+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: GH-55 + github_issue: null + item_type: task + title: 'New task: GH-55' + status: completed + priority: medium + assigned_to: null + created: 2025-11-21 19:18:55.587113+00:00 + updated: 2025-11-21 22:01:46.951089+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: 'Phase 1: Graph Pathfinding Algorithms (Dijkstra, A*, APSP, shortest_path)' + github_issue: null + item_type: task + title: 'New task: Phase 1: Graph Pathfinding Algorithms (Dijkstra, A*, APSP, shortest_path)' + status: completed + priority: medium + assigned_to: null + created: 2025-11-22 11:21:26.608035+00:00 + updated: 2025-11-22 12:01:38.044632+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: 'Phase 2: Components & Traversal (DFS, connected_components, SCCs, topological_sort)' + github_issue: null + item_type: task + title: 'New task: Phase 2: Components & Traversal (DFS, connected_components, SCCs, topological_sort)' + status: completed + priority: medium + assigned_to: null + created: 2025-11-22 12:02:23.982829+00:00 + updated: 2025-11-22 12:13:40.616541+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: 'Phase 3: Community & Link Analysis (label_propagation, common_neighbors, adamic_adar)' + github_issue: null + item_type: task + title: 'New task: Phase 3: Community & Link Analysis (label_propagation, common_neighbors, adamic_adar)' + status: completed + priority: medium + assigned_to: null + created: 2025-11-22 12:14:44.002528+00:00 + updated: 2025-11-22 12:24:00+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: 'Phase 4: Graph Benchmarks & Spec Update' + github_issue: null + item_type: task + title: 'New task: Phase 4: Graph Benchmarks & Spec Update' + status: completed + priority: medium + assigned_to: null + created: 2025-11-22 12:30:00+00:00 + updated: 2025-11-22 12:42:00+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: 'Phase 1: Classical Bayesian Inference - Conjugate Priors (Gamma-Poisson, Normal-InverseGamma, Dirichlet-Multinomial)' + github_issue: null + item_type: task + title: 'New task: Phase 1: Classical Bayesian Inference - Conjugate Priors (Gamma-Poisson, Normal-InverseGamma, + Dirichlet-Multinomial)' + status: completed + priority: medium + assigned_to: null + created: 2025-11-22 14:14:32.956638+00:00 + updated: 2025-11-22 14:39:39.086233+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: 'Phase 2: Bayesian Examples & Documentation - Create cargo examples and book chapters for Gamma-Poisson, + Normal-InverseGamma, and Dirichlet-Multinomial conjugate priors' + github_issue: null + item_type: task + title: 'New task: Phase 2: Bayesian Examples & Documentation - Create cargo examples and book chapters + for Gamma-Poisson, Normal-InverseGamma, and Dirichlet-Multinomial conjugate priors' + status: completed + priority: medium + assigned_to: null + created: 2025-11-22 14:41:15.060857+00:00 + updated: 2025-11-22 14:55:52.231115+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: Fix mdbook test failures in Bayesian inference chapters + github_issue: null + item_type: task + title: 'New task: Fix mdbook test failures in Bayesian inference chapters' + status: completed + priority: medium + assigned_to: null + created: 2025-11-22 15:33:54.554385+00:00 + updated: 2025-11-22 15:40:56.449462+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: Fix 4 failing Bayesian doctests + github_issue: null + item_type: task + title: 'New task: Fix 4 failing Bayesian doctests' + status: completed + priority: medium + assigned_to: null + created: 2025-11-22 15:45:02.954748+00:00 + updated: 2025-11-22 15:48:16.753235+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: Push 4 commits to origin/main (Bayesian documentation and doctest fixes) + github_issue: null + item_type: task + title: 'New task: Push 4 commits to origin/main (Bayesian documentation and doctest fixes)' + status: completed + priority: medium + assigned_to: null + created: 2025-11-22 15:55:11.609457+00:00 + updated: 2025-11-22 15:56:02.775467+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: Implement Bayesian Linear Regression (analytical posterior) + github_issue: null + item_type: task + title: 'New task: Implement Bayesian Linear Regression (analytical posterior)' + status: completed + priority: medium + assigned_to: null + created: 2025-11-22 16:01:33.865842+00:00 + updated: 2025-11-22 16:57:12.367914+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: Implement Bayesian Model Selection (Bayes Factors, DIC, WAIC) + github_issue: null + item_type: task + title: 'New task: Implement Bayesian Model Selection (Bayes Factors, DIC, WAIC)' + status: completed + priority: medium + assigned_to: null + created: 2025-11-22 16:58:14.002509+00:00 + updated: 2025-11-22 17:07:12.377508+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: Implement Bayesian Logistic Regression (Laplace approximation) + github_issue: null + item_type: task + title: 'New task: Implement Bayesian Logistic Regression (Laplace approximation)' + status: completed + priority: medium + assigned_to: null + created: 2025-11-22 17:08:26.938091+00:00 + updated: 2025-11-22 17:28:20.766867+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: Implement Generalized Linear Models (GLM) - Poisson, Gamma, Binomial families + github_issue: null + item_type: task + title: 'New task: Implement Generalized Linear Models (GLM) - Poisson, Gamma, Binomial families' + status: completed + priority: medium + assigned_to: null + created: 2025-11-22 17:31:10.952421+00:00 + updated: 2025-11-22 18:19:13.275008+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: Implement Statistical Hypothesis Tests (t-test, chi-square, ANOVA) + github_issue: null + item_type: task + title: 'New task: Implement Statistical Hypothesis Tests (t-test, chi-square, ANOVA)' + status: completed + priority: medium + assigned_to: null + created: 2025-11-22 17:57:31.042254+00:00 + updated: 2025-11-22 18:08:46.664578+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: Implement Covariance and Correlation Matrices + github_issue: null + item_type: task + title: 'New task: Implement Covariance and Correlation Matrices' + status: completed + priority: medium + assigned_to: null + created: 2025-11-22 18:21:14.036353+00:00 + updated: 2025-11-22 18:26:45.985389+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: Implement Independent Component Analysis (ICA) + github_issue: null + item_type: task + title: 'New task: Implement Independent Component Analysis (ICA)' + status: completed + priority: medium + assigned_to: null + created: 2025-11-22 18:28:43.837291+00:00 + updated: 2025-11-22 18:35:57.909396+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: Implement ARIMA (Auto-Regressive Integrated Moving Average) + github_issue: null + item_type: task + title: 'New task: Implement ARIMA (Auto-Regressive Integrated Moving Average)' + status: completed + priority: medium + assigned_to: null + created: 2025-11-22 18:37:35.339187+00:00 + updated: 2025-11-24 20:42:07.198350+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: nlp-text-preprocessing + github_issue: null + item_type: task + title: 'New task: nlp-text-preprocessing' + status: completed + priority: medium + assigned_to: null + created: 2025-11-24 20:09:32.343204+00:00 + updated: 2025-11-24 20:29:28.403844+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: Implement document similarity (cosine, Jaccard, edit distance) + github_issue: null + item_type: task + title: 'New task: Implement document similarity (cosine, Jaccard, edit distance)' + status: completed + priority: medium + assigned_to: null + created: 2025-11-24 21:22:04.356333+00:00 + updated: 2025-11-24 21:41:35.169137+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: Implement pattern-based entity extraction (emails, URLs, keywords) + github_issue: null + item_type: task + title: 'New task: Implement pattern-based entity extraction (emails, URLs, keywords)' + status: completed + priority: medium + assigned_to: null + created: 2025-11-24 21:22:15.633104+00:00 + updated: 2025-11-24 21:41:43.155607+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: Implement extractive summarization (TextRank, TF-IDF) + github_issue: null + item_type: task + title: 'New task: Implement extractive summarization (TextRank, TF-IDF)' + status: completed + priority: medium + assigned_to: null + created: 2025-11-24 21:22:17.774131+00:00 + updated: 2025-11-24 21:41:50.085071+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: GH-71 + github_issue: 71 + item_type: task + title: Implement Content-Based Recommender with HNSW (Phase 1) + status: completed + priority: medium + assigned_to: null + created: 2025-11-24 22:36:39.711447+00:00 + updated: 2025-11-24 23:13:58.525879+00:00 + spec: null + acceptance_criteria: + - HNSW index implemented with property tests + - Incremental IDF tracker with decay mechanism + - Content-Based Recommender with <100ms latency benchmark + - Example code demonstrating movie/article recommendations + - Book chapter with usage tutorial + - All quality gates pass (`make tier3`) + - Test coverage ≥95% + phases: [] + subtasks: [] + estimated_effort: null + labels: + - enhancement + notes: null +- id: GH-73 + github_issue: 73 + item_type: task + title: 'feat: Model evaluation framework for .apr models with retraining support' + status: completed + priority: medium + assigned_to: null + created: 2025-11-26 13:45:00.888174+00:00 + updated: 2025-11-26 15:30:00+00:00 + spec: null + acceptance_criteria: + - Add classification metrics to `src/metrics/mod.rs` + - Add `src/eval/mod.rs` evaluation framework + - Add drift detection (`src/eval/drift.rs`) + - Integration with entrenar + phases: [] + subtasks: [] + estimated_effort: null + labels: + - enhancement + notes: null +- id: aprender-tsp-v0.1.0 + github_issue: null + item_type: task + title: 'release: aprender-tsp v0.1.0 - TSP solver with ACO, Tabu, GA, Hybrid and HuggingFace POC models' + status: completed + priority: high + assigned_to: null + created: 2025-11-29 12:00:00+00:00 + updated: 2025-11-29 18:00:00+00:00 + spec: null + acceptance_criteria: + - ACO solver using core aprender::metaheuristics::AntColony + - Tabu Search with 2-opt moves + - Genetic Algorithm with order crossover + - Hybrid solver combining GA + Tabu + ACO + - TSPLIB parser with ATT distance formula fix + - Model persistence with .apr binary format + - CLI with train/solve/benchmark/info commands + - POC models published to HuggingFace (paiml/aprender-tsp-poc) + - 142 tests (105 unit + 22 integration + 15 property) + - Published to crates.io + phases: [] + subtasks: [] + estimated_effort: null + labels: + - release + - metaheuristics + notes: null +- id: GH-80 + github_issue: 80 + item_type: epic + title: 'feat(metaheuristics): Implement derivative-free global optimization for aprender-contrib' + status: completed + priority: medium + assigned_to: null + created: 2025-11-27 08:53:16.807707+00:00 + updated: 2026-02-04 12:49:49+00:00 + spec: null + acceptance_criteria: + - '`SearchSpace` enum (Continuous, Mixed, Binary, Permutation, Graph)' + - '`PerturbativeMetaheuristic` trait' + - Differential Evolution (DE/rand/1/bin, JADE, SHADE) + - Particle Swarm Optimization (standard, constriction, SPSO 2011) + - Simulated Annealing (geometric, adaptive cooling) + - Genetic Algorithm (SBX, polynomial mutation) + - Harmony Search + - CEC 2013 benchmark suite + - CMA-ES with eigendecomposition, boundary handling, IPOP restart + - Binary GA with BitVec solution type + - Feature selection utilities + - '`ConstructiveMetaheuristic` trait' + - '`NeighborhoodSearch` trait' + - Ant Colony Optimization (AS, MMAS, ACS) + - Tabu Search + - HyperoptSearch wrapper + - Neural architecture search primitives + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: APR-FORMAT-002 + github_issue: null + item_type: task + title: 'New task: APR-FORMAT-002' + status: completed + priority: medium + assigned_to: null + created: 2025-12-16 00:03:27.193222+00:00 + updated: 2025-12-16 00:05:56.309890+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: Add APR-SPEC to book and verify examples + github_issue: null + item_type: task + title: 'New task: Add APR-SPEC to book and verify examples' + status: completed + priority: medium + assigned_to: null + created: 2025-12-16 09:20:59.016120+00:00 + updated: 2026-02-04 12:51:06+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: WAPR-CLI-STUBS + github_issue: null + item_type: task + title: 'New task: WAPR-CLI-STUBS' + status: cancelled + priority: medium + assigned_to: null + created: 2025-12-16 09:48:19.113691+00:00 + updated: 2026-02-20 11:05:32+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: Implement apr-cli TUI command + github_issue: null + item_type: task + title: 'New task: Implement apr-cli TUI command' + status: completed + priority: medium + assigned_to: null + created: 2025-12-16 10:23:26.469253+00:00 + updated: 2025-12-16 10:31:28.031659+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: APR-VERIFY-001 + github_issue: null + item_type: task + title: 'New task: APR-VERIFY-001' + status: completed + priority: medium + assigned_to: null + created: 2025-12-16 18:46:36.901960+00:00 + updated: 2026-02-04 12:50:14+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: APR-POKA-001 + github_issue: null + item_type: task + title: 'New task: APR-POKA-001' + status: completed + priority: medium + assigned_to: null + created: 2025-12-16 19:25:20.831662+00:00 + updated: 2026-02-04 12:55:50+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: APRENDER-METAL-001 + github_issue: null + item_type: task + title: 'Metal Backend Integration: AMD GPU Tensor Ops via Intel Mac' + status: cancelled + priority: medium + assigned_to: null + created: 2026-01-02 12:00:00+00:00 + updated: 2026-02-20 11:21:17+00:00 + spec: null + acceptance_criteria: + - trueno Metal backend available for tensor operations + - Neural network forward pass works on AMD GPU (Metal) + - Training backward pass validated on Metal + - Cross-platform model inference (CUDA/Metal) produces identical results + - Performance within 30% of CUDA for common ML workloads + - CI integration via self-hosted Intel Mac runner + phases: [] + subtasks: [] + estimated_effort: 1 week + labels: + - metal + - amd-gpu + - cross-platform + - intel-mac + - depends-on-trueno + notes: 'Depends on TRUENO-METAL-001 completion. + + Uses lambda-lab-rust-development Intel Mac integration: + + - Host: mac (Intel Mac Pro with AMD Radeon Pro W5700X, 16GB VRAM) + + - Metal 3 support, 60 Compute Units + + - Run health check: make mac-health (from lambda-lab-rust-development) + + ' +- id: PMAT-PERF-009-CUDA + github_issue: null + item_type: task + title: 'New task: PMAT-PERF-009-CUDA' + status: completed + priority: medium + assigned_to: null + created: 2026-01-11 23:07:13.191160+00:00 + updated: 2026-02-20 11:05:16+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-PERF-009-WIRE + github_issue: null + item_type: task + title: 'New task: PMAT-PERF-009-WIRE' + status: cancelled + priority: medium + assigned_to: null + created: 2026-01-12 09:15:48.332874+00:00 + updated: 2026-02-20 11:05:32+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-SHOWCASE-NEXT + github_issue: null + item_type: task + title: 'New task: PMAT-SHOWCASE-NEXT' + status: completed + priority: medium + assigned_to: null + created: 2026-01-12 09:30:13.183954+00:00 + updated: 2026-01-27 18:42:19.759905+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-PERF-OPTIMIZE + github_issue: null + item_type: task + title: 'New task: PMAT-PERF-OPTIMIZE' + status: cancelled + priority: medium + assigned_to: null + created: 2026-01-12 09:38:13.765147+00:00 + updated: 2026-02-20 11:05:32+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-PERF-2X-TARGET + github_issue: null + item_type: task + title: 'New task: PMAT-PERF-2X-TARGET' + status: cancelled + priority: medium + assigned_to: null + created: 2026-01-12 09:46:30.149149+00:00 + updated: 2026-02-20 11:05:32+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: SHOWCASE-BRICK-001 + github_issue: null + item_type: task + title: 'New task: SHOWCASE-BRICK-001' + status: completed + priority: medium + assigned_to: null + created: 2026-01-12 23:02:11.425753+00:00 + updated: 2026-01-20 10:39:55.357397+00:00 + spec: null + acceptance_criteria: + - PAR-201 regressions fixed (F-GPU-134b, F-PIPE-166b, F-UX-40). Dead code documented. 32B model added. + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: 'APR-TOK-001: Fix tokenizer decoding for coherent text output' + github_issue: null + item_type: task + title: 'New task: APR-TOK-001: Fix tokenizer decoding for coherent text output' + status: completed + priority: medium + assigned_to: null + created: 2026-01-15 14:15:28.015657+00:00 + updated: 2026-01-20 20:00:00+00:00 + spec: null + acceptance_criteria: + - 95/95 QA tests pass for all GGUF model sizes + - Tokenizer decoding produces coherent text + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: 'Resolved 2026-01-20: Verified through GGUF-SERVE-001 validation. + + All 95 QA tests pass with coherent output across 0.5B, 1B, 1.5B, 7B, 32B models. + + ' +- id: PMAT-087 + github_issue: null + item_type: task + title: 'SERVE-STREAM-001: Fix SSE streaming not visible to OpenAI SDK clients' + status: completed + priority: high + assigned_to: null + created: 2026-01-21 18:31:33+00:00 + updated: 2026-01-21 20:00:00+00:00 + spec: null + acceptance_criteria: + - '**Root Cause**: CPU streaming in realizar''s api.rs is ''fake streaming'' - it generates ALL tokens + first via generate_with_cache (blocking), THEN streams them one-by-one. True streaming only exists + in CUDA path (generate_gpu_resident_streaming). + + + **Fix Required**: Add streaming callback support to CPU OwnedQuantizedModel.generate_with_cache() + similar to the CUDA path, or implement generate_streaming() method that yields tokens as they''re + generated. + + + **Files**: + + - /home/noah/src/realizar/src/api.rs:3622-3679 (CPU quantized streaming) + + - /home/noah/src/realizar/src/gguf/mod.rs (add generate_streaming)' + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: 'GGUF-SERVE-001: Validate apr serve works for all GGUF model sizes (0.5B, 1B, 1.5B, 7B, 32B)' + github_issue: null + item_type: task + title: 'GGUF-SERVE-001: Validate apr serve works for all GGUF model sizes' + status: completed + priority: medium + assigned_to: null + created: 2026-01-20 14:48:04.165836+00:00 + updated: 2026-01-20 18:30:00+00:00 + spec: docs/specifications/qwen2.5-coder-showcase-demo.md + acceptance_criteria: + - '0.5B GGUF: 19/19 tests pass' + - '1B GGUF: 19/19 tests pass' + - '1.5B GGUF: 19/19 tests pass' + - '7B GGUF: 19/19 tests pass' + - '32B GGUF: 19/19 tests pass' + - PAR-303 (0.5B coherency) resolved + - qa-serve.sh bashrs lint compliant + - OpenAI-compatible API /v1/chat/completions verified + - SSE streaming with [DONE] termination verified + - X-Trace-Level header (brick/step/layer) verified + phases: [] + subtasks: [] + estimated_effort: 4h + labels: + - qa + - gguf + - serving + - validation + notes: 'Validated 2026-01-20: All 5 GGUF model sizes pass QA (95/95 tests total). + + PAR-303 (0.5B coherency) resolved - all model sizes now produce coherent output. + + Showcase spec updated to v7.6.0 (100% GGUF, 71% Overall). + + Remaining gaps: PAR-301 (SafeTensors), PAR-302 (APR format). + + ' +- id: PMAT-088 + github_issue: null + item_type: task + title: 'SERVE-CHAT-001: Fix prompt injection in chat completions (extra Human/Assistant turns)' + status: completed + priority: high + assigned_to: null + created: 2026-01-21 18:31:34+00:00 + updated: 2026-01-21 20:00:00+00:00 + spec: null + acceptance_criteria: + - '**Root Cause**: Model generates ''Human:''/''Assistant:'' turns because: + + 1. Empty stop_tokens (Vec::new()) passed to QuantizedGenerateConfig - should include EOS token + + 2. Model may not match ChatML template - some models use ''Human:''/''Assistant:'' format + + 3. Output not cleaned of extra turns after generation + + + **Evidence**: + + - api.rs:3619 has stop_tokens: Vec::new() + + - User typed ''hey'', got ''Human: Hi there...'' in response + + + **Fix Required**: + + 1. Pass proper stop tokens (EOS token ID 151645 for ChatML) + + 2. Clean output text after <|im_end|> or stop sequence + + 3. Consider auto-detecting model format from GGUF metadata + + + **Files**: + + - /home/noah/src/realizar/src/api.rs:3615-3620 (QuantizedGenerateConfig) + + - /home/noah/src/realizar/src/chat_template.rs (template detection)' + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-089 + github_issue: null + item_type: task + title: 'F-CLI-006-REGRESSION: apr check subcommand missing from binary' + status: completed + priority: critical + assigned_to: null + created: 2026-01-21 19:01:41+00:00 + updated: 2026-01-21 20:30:00+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: 'Resolution: NOT A REGRESSION - stale binary issue. + + Fresh build: `apr check --help` works, 10/10 stages pass. + + QA artifact was from outdated binary. + + ' +- id: PMAT-090 + github_issue: null + item_type: task + title: 'PAR-303-REGRESSION: 0.5B model produces incoherent gibberish output' + status: completed + priority: critical + assigned_to: null + created: 2026-01-21 19:02:15+00:00 + updated: 2026-01-21 20:30:00+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: 'Resolution: MODEL CAPACITY ISSUE, NOT CODE BUG. + + Root cause: 0.5B model lacks sufficient parameters for coherent generation. + + Control test: 1B model produces perfect output on same code path. + + Evidence: 1B output "The answer to 2+2 is 4. Let''s break it down..." + + Action: 0.5B marked as stress-test/latency benchmark only. + + ' +- id: PMAT-091 + github_issue: null + item_type: task + title: 'REALIZE-TRACE-001: X-Trace-Level header not working with apr serve delegation' + status: completed + priority: medium + assigned_to: realizar-team + created: 2026-01-21 19:18:42+00:00 + updated: 2026-01-22 20:30:00+00:00 + spec: null + acceptance_criteria: + - F-TRACE-001/002/003 pass when using `apr serve` (not just `realizar serve`) + - brick_trace, step_trace, layer_trace fields populated in response JSON + phases: [] + subtasks: [] + estimated_effort: 2h + labels: + - realizar + - tracing + notes: 'RESOLVED: Trace functionality was already implemented correctly in realizar api.rs + + lines 3797-3897. Original failures were due to: + + 1. Server startup issues (stale binary, wrong port) + + 2. Testing before server fully initialized + + + Verification: 2026-01-22 + + - `apr serve model.gguf --port 8082`: All F-TRACE-001/002/003 PASS + + - brick_trace, step_trace, layer_trace fields correctly populated + + - All 21 QA tests pass including trace tests + + + Root cause likely in realizar''s API - the trace data may require specific + + AppState configuration that apr serve''s delegation doesn''t set up correctly. + + + Note: This is a REALIZAR issue, not APRENDER. apr serve correctly delegates + + to realizar::api::create_router() but traces don''t appear in responses. + + ' +- id: PMAT-092 + github_issue: null + item_type: task + title: 'PMAT-092: Fix empty stop_tokens in GPU chat completions path causing multi-turn loop' + status: completed + priority: critical + assigned_to: null + created: 2026-01-21 22:44:48+00:00 + updated: 2026-01-21 22:50:00+00:00 + spec: null + acceptance_criteria: + - Model stops at EOS token instead of generating fake Human/Assistant turns + - No multi-turn conversation loops in chat completions + phases: [] + subtasks: [] + estimated_effort: 30m + labels: + - realizar + - bug + notes: 'Fixed in realizar commit 95bff6d. + + Root cause: GPU path had `stop_tokens: Vec::new()` causing model to generate + + beyond EOS, creating fake "Human:" and "Assistant:" turns. + + Fix: Added EOS token lookup (<|im_end|> or <|endoftext|>, fallback 151645). + + ' +- id: PMAT-093 + github_issue: null + item_type: task + title: 'PAR-301: Expand apr serve to support APR and SafeTensors formats' + status: completed + priority: high + assigned_to: null + created: 2026-01-22 09:45:17+00:00 + updated: 2026-02-20 11:07:30+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-094 + github_issue: null + item_type: task + title: 'FIVE-WHYS-ST-001: SafeTensors inference produces garbage output' + status: completed + priority: medium + assigned_to: null + created: 2026-01-22 10:09:34+00:00 + updated: 2026-02-04 12:49:05+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-095 + github_issue: null + item_type: task + title: 'PERF-ST-001: SafeTensors performance parity with GGUF' + status: completed + priority: high + assigned_to: null + created: 2026-01-22 10:29:50+00:00 + updated: 2026-02-20 11:07:30+00:00 + spec: null + acceptance_criteria: + - SafeTensors inference is 0.4 tok/s vs GGUF 30+ tok/s - need five-whys analysis + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-096 + github_issue: null + item_type: task + title: 'PMAT-098: APR format performance parity with GGUF and SafeTensors' + status: completed + priority: high + assigned_to: null + created: 2026-01-22 12:49:19+00:00 + updated: 2026-02-20 11:07:30+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-097 + github_issue: null + item_type: task + title: 'REALIZAR-SEND-001: GpuModel Send/Sync bounds fix for apr-cli cuda feature' + status: completed + priority: high + assigned_to: null + created: 2026-01-25 15:05:27+00:00 + updated: 2026-01-25 15:12:19+00:00 + spec: null + acceptance_criteria: + - 'Fix Send/Sync bounds on GpuModel.test_executor trait object. See GitHub #158.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - realizar + - cuda + - bug + notes: null +- id: PMAT-098 + github_issue: null + item_type: task + title: 'PMAT-QA-PROTOCOL-001: Implement comprehensive QA testing protocol' + status: completed + priority: critical + assigned_to: null + created: 2026-01-26 15:03:49+00:00 + updated: 2026-02-04 12:47:42+00:00 + spec: null + acceptance_criteria: + - Implement 27-test modality × format × tracing matrix with ModelFixture, timeouts, and output verification. + See spec §7. + phases: [] + subtasks: [] + estimated_effort: null + labels: + - qa + - testing + - showcase + notes: null +- id: PMAT-099 + github_issue: null + item_type: task + title: 'PMAT-110: APR CUDA KV Cache - Implement proper KV cache for AprV2ModelCuda generation' + status: completed + priority: high + assigned_to: null + created: 2026-01-26 19:17:34+00:00 + updated: 2026-02-20 11:07:30+00:00 + spec: null + acceptance_criteria: + - 'Root cause: realizar''s AprV2ModelCuda::forward_single_cuda has NO KV cache - it just calls forward_cuda(&[token]) + with no context. This makes generation impossible (logits all -inf). + + + Fix: Implement proper KV cache in realizar similar to GGUF CUDA path (OwnedQuantizedKVCache). + + + Acceptance criteria: + + - [ ] APR CUDA generates correct output (not empty/garbage) + + - [ ] Temperature sampling works + + - [ ] Performance: >50 tok/s on RTX 4090 + + - [ ] Test: apr chat with APR model uses GPU' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - cuda + - apr + - kv-cache + - realizar + notes: null +- id: 'PMAT-099: APR format parity - fix AprTransformer config reading' + github_issue: null + item_type: task + title: 'New task: PMAT-099: APR format parity - fix AprTransformer config reading' + status: completed + priority: medium + assigned_to: null + created: 2026-01-22 14:11:54.074583+00:00 + updated: 2026-02-04 12:49:26+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: 'PMAT-103-SIMD: AVX2 SIMD optimization for Q4K matmul to achieve 5+ tok/s' + github_issue: null + item_type: task + title: 'New task: PMAT-103-SIMD: AVX2 SIMD optimization for Q4K matmul to achieve 5+ tok/s' + status: completed + priority: medium + assigned_to: null + created: 2026-01-23 12:13:30.786974+00:00 + updated: 2026-02-20 11:05:16+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-110 + github_issue: null + item_type: task + title: 'New task: PMAT-110' + status: cancelled + priority: medium + assigned_to: null + created: 2026-01-26 19:17:40.490094+00:00 + updated: 2026-02-20 11:05:32+00:00 + spec: null + acceptance_criteria: + - "Root cause: realizar's AprV2ModelCuda::forward_single_cuda has NO KV cache - it just calls forward_cuda(&[token])\ + \ with no context. This makes generation impossible (logits all -inf).\n\nFix: Implement proper KV\ + \ cache in realizar similar to GGUF CUDA path (OwnedQuantizedKVCache).\n\nSCOPE: Both APR AND SafeTensors\ + \ formats must work with GPU for:\n- apr chat (interactive)\n- apr serve (REST API)\n- apr run (single\ + \ prompt)\n\nAcceptance criteria:\n- [ ] APR CUDA generates correct output (not empty/garbage)\n-\ + \ [ ] SafeTensors CUDA generates correct output\n- [ ] Temperature sampling works for both formats\n\ + - [ ] Performance: >50 tok/s on RTX 4090 for both\n- [ ] Test: apr chat with APR model uses GPU\n\ + - [ ] Test: apr chat with SafeTensors model uses GPU\n- [ ] Test: apr serve works with APR format\n\ + - [ ] Test: apr serve works with SafeTensors format\n- [ ] Test: apr run works with APR format \n\ + - [ ] Test: apr run works with SafeTensors format" + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-111 + github_issue: null + item_type: task + title: 'PMAT-114: SafeTensors→APR inference fix' + status: completed + priority: high + assigned_to: null + created: 2026-01-27 17:43:06+00:00 + updated: 2026-01-27 18:33:52.975501+00:00 + spec: null + acceptance_criteria: + - 'Fix fused QKV bias loading in APR transformer. Root cause: APR converter fuses Q/K/V biases into + qkv_proj.bias but loader only looked for separate biases.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - apr + - inference + - fix + notes: null +- id: PMAT-112 + github_issue: null + item_type: task + title: 'FALSIFY-100: Run 100-point Popperian falsification checklist' + status: completed + priority: high + assigned_to: null + created: 2026-01-27 20:10:46+00:00 + updated: 2026-01-27 20:24:47+00:00 + spec: null + acceptance_criteria: + - Execute docs/qa/popperian_falsification_checklist.md against Qwen2.5 showcase. Track pass/fail for + all 100 tests. + phases: [] + subtasks: [] + estimated_effort: null + labels: + - qa + - falsification + - showcase + notes: null +- id: 'APR-PARITY-001: APR/SafeTensors GGUF parity - all QA scripts pass' + github_issue: null + item_type: task + title: 'New task: APR-PARITY-001: APR/SafeTensors GGUF parity - all QA scripts pass' + status: completed + priority: medium + assigned_to: null + created: 2026-01-22 15:35:30.231896+00:00 + updated: 2026-02-04 13:08:15+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: APR-PUB-001 + github_issue: null + item_type: task + title: 'New task: APR-PUB-001' + status: completed + priority: medium + assigned_to: null + created: 2026-01-23 10:19:57.986146+00:00 + updated: 2026-02-20 11:05:16+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: 'APR-TRACE-001: Implement tracing features for APR serve path (5 failing tests)' + github_issue: null + item_type: task + title: 'New task: APR-TRACE-001: Implement tracing features for APR serve path (5 failing tests)' + status: completed + priority: medium + assigned_to: null + created: 2026-01-23 12:44:42.307541+00:00 + updated: 2026-01-23 12:56:13.838059+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: 'LAYOUT-001: Fix Q4K kernel layout mismatch - use row-major kernel for APR/GGUF' + github_issue: null + item_type: task + title: 'New task: LAYOUT-001: Fix Q4K kernel layout mismatch - use row-major kernel for APR/GGUF' + status: completed + priority: medium + assigned_to: null + created: 2026-01-23 14:32:25.102949+00:00 + updated: 2026-01-23 14:39:07.951711+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-113 + github_issue: null + item_type: task + title: 'PMAT-115: Fix SafeTensors GPU silent fallback (Jidoka violation)' + status: completed + priority: critical + assigned_to: null + created: 2026-01-27 21:09:47+00:00 + updated: 2026-01-27 21:14:24+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - jidoka + - safetensors + - gpu + notes: null +- id: PMAT-114 + github_issue: null + item_type: task + title: 'PMAT-116: Implement SafeTensors GPU inference' + status: completed + priority: critical + assigned_to: null + created: 2026-01-28 07:19:40+00:00 + updated: 2026-01-28 07:23:21+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - safetensors + - gpu + - cuda + - spec + notes: null +- id: PMAT-115 + github_issue: null + item_type: task + title: 'PMAT-117: Implement SafeTensors GPU inference (from spec)' + status: completed + priority: critical + assigned_to: null + created: 2026-01-28 07:44:31+00:00 + updated: 2026-02-04 12:48:02+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - safetensors + - gpu + - cuda + - implementation + notes: null +- id: PMAT-116 + github_issue: null + item_type: task + title: 'New task: PMAT-116' + status: completed + priority: medium + assigned_to: null + created: 2026-01-28 08:06:27.533748+00:00 + updated: 2026-02-04 12:48:04+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-117 + github_issue: null + item_type: task + title: Fix SATD violations in apr-cli (Toyota Way compliance) + status: completed + priority: high + assigned_to: null + created: 2026-01-28 08:58:23+00:00 + updated: 2026-02-04 12:41:51+00:00 + spec: null + acceptance_criteria: + - Fix 4 TODO/FIXME/HACK markers in apr-cli per Toyota Way zero-SATD policy + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-118 + github_issue: null + item_type: task + title: 'F-PERF-042: GPU > 2x CPU throughput verification' + status: completed + priority: high + assigned_to: null + created: 2026-01-28 09:08:38+00:00 + updated: 2026-02-04 12:48:53+00:00 + spec: null + acceptance_criteria: + - Implement automated verification that GPU inference achieves >2x CPU throughput. Add to CI quality + gates. + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-119 + github_issue: null + item_type: task + title: 'F-QUAL-032: Argmax parity GGUF vs SafeTensors QA gate' + status: completed + priority: medium + assigned_to: null + created: 2026-01-28 09:19:57+00:00 + updated: 2026-02-04 12:48:37+00:00 + spec: null + acceptance_criteria: + - 'Implement QA gate to verify argmax parity between GGUF and SafeTensors formats for the same model. + The invariant is: argmax(forward_gguf(M, tokens)) == argmax(forward_safetensors(M, tokens)). This + prevents drift where one format produces subtle errors.' + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-120 + github_issue: null + item_type: task + title: 'DEFECT: SafeTensors GPU chat produces garbage (Andon)' + status: completed + priority: medium + assigned_to: null + created: 2026-01-28 10:38:39+00:00 + updated: 2026-02-04 12:48:37+00:00 + spec: null + acceptance_criteria: + - 'Observed: SafeTensors GPU chat produces garbage output despite spec claiming CORROBORATED. This is + a STOP THE LINE defect requiring five-whys analysis. Evidence: ''apr chat model.safetensors --gpu'' + produced garbage Chinese characters instead of ''2+2=4''.' + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-121 + github_issue: null + item_type: task + title: 'FALSIFY-SPEC-001: Systematic falsification of qwen2.5-coder-showcase-demo.md claims' + status: completed + priority: high + assigned_to: null + created: 2026-01-28 17:42:30+00:00 + updated: 2026-02-04 12:48:24+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-122 + github_issue: null + item_type: task + title: 'PMAT-123: Continue systematic falsification testing' + status: completed + priority: high + assigned_to: null + created: 2026-01-28 20:38:31+00:00 + updated: 2026-02-04 12:48:24+00:00 + spec: null + acceptance_criteria: + - Continue falsification of qwen2.5-coder-showcase-demo.md spec claims + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-124 + github_issue: null + item_type: task + title: 'New task: PMAT-124' + status: completed + priority: medium + assigned_to: null + created: 2026-01-28 20:53:22.329521+00:00 + updated: 2026-02-04 12:48:45+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: 'PMAT-127: Fix F-APR-GGUF - APR from GGUF produces garbage' + github_issue: 186 + item_type: task + title: 'FIXED: PMAT-127 APR from GGUF produces garbage (dtype mismatch)' + status: completed + priority: medium + assigned_to: null + created: 2026-01-28 23:40:09.296872+00:00 + updated: 2026-01-30 19:20:00+00:00 + spec: null + acceptance_criteria: + - '[x] apr check /tmp/test.apr passes 10/10 stages' + - '[x] apr trace --payload shows valid logits (L2=1311.75, not NaN)' + - '[x] Root cause identified: dtype byte mismatch (APR 12=Q4K, realizar expected 8)' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - bugfix + - p0-resolved + notes: 'Root Cause: DType byte mapping mismatch between aprender and realizar. + + - APR format uses dtype 12 for Q4K, 14 for Q6K (per aprender/src/format/v2.rs) + + - realizar read dtype 12 as fallback "F32" causing NaN logits + + Fix: Updated realizar/src/apr/mod.rs from_binary() dtype mapping. + + Commits: aaa0f9a3, 734a076f + + ' +- id: 'PMAT-129: Fix F-SAFETENSORS-GPU - apr run should support SafeTensors GPU' + github_issue: null + item_type: task + title: 'New task: PMAT-129: Fix F-SAFETENSORS-GPU - apr run should support SafeTensors GPU' + status: completed + priority: medium + assigned_to: null + created: 2026-01-29 07:44:56.916841+00:00 + updated: 2026-02-04 12:48:45+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: 'PMAT-130: Fix F-Q4_0 - GGUF Q4_0 dequantization produces garbage' + github_issue: null + item_type: task + title: 'New task: PMAT-130: Fix F-Q4_0 - GGUF Q4_0 dequantization produces garbage' + status: completed + priority: medium + assigned_to: null + created: 2026-01-29 07:51:38.043099+00:00 + updated: 2026-02-04 12:48:45+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: 'PMAT-131: Fix F-UX-033 - SafeTensors CPU should display backend type' + github_issue: null + item_type: task + title: 'New task: PMAT-131: Fix F-UX-033 - SafeTensors CPU should display backend type' + status: completed + priority: medium + assigned_to: null + created: 2026-01-29 08:06:40.076272+00:00 + updated: 2026-02-04 12:43:49+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-190 + github_issue: null + item_type: task + title: 'GH-201: Eliminate hot-path unwrap() calls' + status: completed + priority: critical + assigned_to: null + created: 2026-01-31 09:33:53+00:00 + updated: 2026-01-31 09:42:05+00:00 + spec: null + acceptance_criteria: + - 'Remove panic-inducing unwrap()/expect() from inference hot paths (nn/dropout.rs, nn/transformer.rs, + nn/generation.rs). Ref: Popperian Audit Round 12, Test 1. Root cause: Missing CI enforcement of panic-free + policy.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - p0 + - panic-free + - round-12 + notes: null +- id: PMAT-191 + github_issue: null + item_type: task + title: 'GH-202: Remove Unknown Error from explain.rs' + status: completed + priority: critical + assigned_to: null + created: 2026-01-31 09:33:55+00:00 + updated: 2026-01-31 09:42:07+00:00 + spec: null + acceptance_criteria: + - 'Replace ''Unknown Error'' output with structured error message. Ref: Popperian Audit Round 12, Test + 20. Root cause: Stringly-typed error codes without exhaustive match.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - p0 + - error-handling + - round-12 + notes: null +- id: PMAT-192 + github_issue: null + item_type: task + title: 'GH-203: Cross-architecture determinism validation' + status: completed + priority: high + assigned_to: null + created: 2026-01-31 09:33:56+00:00 + updated: 2026-02-04 12:44:28+00:00 + spec: null + acceptance_criteria: + - 'Add cross-machine determinism tests for zero-temperature inference. Ref: Popperian Audit Round 12, + Test 4. Root cause: Incorrect FMA reproducibility assumption.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - p1 + - determinism + - round-12 + notes: null +- id: PMAT-193 + github_issue: null + item_type: task + title: 'GH-204: Prompt injection sanitization' + status: completed + priority: high + assigned_to: null + created: 2026-01-31 09:33:57+00:00 + updated: 2026-02-04 12:46:02+00:00 + spec: null + acceptance_criteria: + - 'Add sanitization for control tokens in user input. Ref: Popperian Audit Round 12, Test 17. Root cause: + Missing security threat model.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - p1 + - security + - round-12 + notes: null +- id: PMAT-194 + github_issue: null + item_type: task + title: 'GH-205: Load testing infrastructure' + status: completed + priority: high + assigned_to: null + created: 2026-01-31 09:33:59+00:00 + updated: 2026-02-04 12:47:13+00:00 + spec: null + acceptance_criteria: + - 'Add 50-concurrent request tests and disconnect cleanup tests. Ref: Popperian Audit Round 12, Tests + 9-10. Root cause: Spec evolution from CLI to server.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - p1 + - testing + - round-12 + notes: null +- id: PMAT-195 + github_issue: null + item_type: task + title: 'GH-198: apr pull SafeTensors missing companion files (tokenizer.json, config.json)' + status: completed + priority: critical + assigned_to: null + created: 2026-02-01 22:14:01+00:00 + updated: 2026-02-04 12:42:26+00:00 + spec: null + acceptance_criteria: + - apr pull for SafeTensors only downloads weight file, missing tokenizer.json and config.json. Causes + apr run to fail with PMAT-172. + phases: [] + subtasks: [] + estimated_effort: null + labels: + - bug + - safetensors + - cli + notes: null +- id: GH-189 + github_issue: null + item_type: task + title: APR chat special tokens fix (BpeTokenizer) + status: completed + priority: medium + assigned_to: null + created: 2026-01-31 06:24:21.819716+00:00 + updated: 2026-01-31 06:24:56+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-196 + github_issue: null + item_type: task + title: GGUF-EXPORT-001 + status: completed + priority: critical + assigned_to: null + created: 2026-02-01 23:21:56+00:00 + updated: 2026-02-20 11:05:16+00:00 + spec: null + acceptance_criteria: + - 'P0: GGUF exporter writes zero metadata keys and HF-style tensor names' + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-197 + github_issue: null + item_type: task + title: 'PMAT-210: Fix BUG-1 GGUF Export from SafeTensors (CRASH)' + status: completed + priority: critical + assigned_to: null + created: 2026-02-03 17:51:49+00:00 + updated: 2026-02-03 17:59:00+00:00 + spec: null + acceptance_criteria: + - 'GGUF export from SafeTensors crashes with zero metadata and wrong tensor names. SafeTensors → GGUF + conversion path completely broken. Falsification: apr export model.apr --format gguf produces valid + GGUF with correct metadata and tensor names.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - P0 + - falsification + - gguf + - export + notes: null +- id: PMAT-198 + github_issue: null + item_type: task + title: 'PMAT-201: Complete Per-Tensor Statistical Fingerprints' + status: completed + priority: high + assigned_to: null + created: 2026-02-03 17:51:55+00:00 + updated: 2026-02-03 18:01:01+00:00 + spec: null + acceptance_criteria: + - 'Implement apr rosetta fingerprint command with JSON output, fingerprint comparison (--diff), and + CI integration. Falsification: apr rosetta fingerprint model.gguf --output fp.json produces valid + JSON with mean, std, min, max, nan_count, checksum for each tensor.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - P1 + - falsification + - fingerprint + - rosetta + notes: null +- id: PMAT-199 + github_issue: null + item_type: task + title: 'PMAT-202: Tensor Statistics Validation' + status: completed + priority: high + assigned_to: null + created: 2026-02-03 17:52:02+00:00 + updated: 2026-02-03 18:04:24+00:00 + spec: null + acceptance_criteria: + - 'Implement apr rosetta validate-stats with role-specific thresholds (LayerNorm, Attention, MLP). Falsification: + apr rosetta validate-stats model.apr --reference model.gguf returns E020 error for corrupted tensors.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - P1 + - falsification + - validation + - rosetta + notes: null +- id: PMAT-200 + github_issue: null + item_type: task + title: 'PMAT-203: Golden Output Embedding' + status: completed + priority: medium + assigned_to: null + created: 2026-02-03 17:52:02+00:00 + updated: 2026-02-03 18:01:01+00:00 + spec: null + acceptance_criteria: + - 'Embed golden test cases in APR metadata. Implement apr validate --golden for self-validating artifacts. + Falsification: Model metadata contains golden_tests array and inference matches expected within tolerance.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - P2 + - falsification + - golden + - validation + notes: null +- id: PMAT-ROSETTA-001 + github_issue: null + item_type: task + title: 'New task: PMAT-ROSETTA-001' + status: completed + priority: medium + assigned_to: null + created: 2026-02-01 18:33:22.303949+00:00 + updated: 2026-02-04 12:46:49+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-201 + github_issue: null + item_type: task + title: 'PMAT-204: Tensor Distribution Tags' + status: completed + priority: medium + assigned_to: null + created: 2026-02-03 18:24:00+00:00 + updated: 2026-02-04 12:46:50+00:00 + spec: null + acceptance_criteria: + - 'Tag tensors with semantic role (Embedding, LayerNorm, etc.) for role-specific validation and quantization + guidance. Falsification: TensorRole enum with from_name() method correctly identifies all tensor types.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - P2 + - falsification + - validation + notes: null +- id: PMAT-202 + github_issue: null + item_type: task + title: 'PMAT-205: Sharding-Aware Placement' + status: cancelled + priority: low + assigned_to: null + created: 2026-02-03 18:24:00+00:00 + updated: 2026-02-20 11:42:51+00:00 + spec: null + acceptance_criteria: + - 'Sharding-aware placement (JAX-inspired PartitionSpec) is aspirational multi-GPU work requiring 4-6 + weeks. Foundation exists (repartir crate, sharded_index.rs, PartitionSpec types) but no runtime implementation. + Single-GPU inference is the priority; multi-GPU sharding is a Phase 3+ concern. Cancelled: premature + — single-GPU perf targets not yet met.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - P3 + - falsification + - sharding + notes: null +- id: PMAT-203 + github_issue: null + item_type: task + title: 'BUG-RUN-001: Fix benchmark token count mismatch in apr run' + status: completed + priority: medium + assigned_to: null + created: 2026-02-04 10:00:33+00:00 + updated: 2026-02-04 14:12:16+00:00 + spec: null + acceptance_criteria: + - 'The apr run --benchmark command shows inconsistent token counts: + + - Header shows actual count from inference engine: ''Generated 10 tokens in 5920.0ms (1.7 tok/s)'' + + - Benchmark section shows word approximation: ''tok/s: 0.3, tokens: 5'' + + + Root cause: execute_inference() returns only text, discarding result.generated_token_count. + + run_model() then approximates with text.split_whitespace().count(). + + + Fix: Return actual token count from execute_inference() and use it in benchmark output.' + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-204 + github_issue: null + item_type: task + title: 'STACK-DRIFT-001: Update downstream crates for aprender 0.25.1' + status: completed + priority: medium + assigned_to: null + created: 2026-02-04 13:19:13+00:00 + updated: 2026-02-20 11:07:30+00:00 + spec: null + acceptance_criteria: + - 'Stack drift detected by batuta bug-hunter. Crates needing update: aprender-shell, aprender-tsp, realizar, + whisper-apr, pmat. Run ''batuta stack drift --fix'' after publish.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - stack + - dependencies + notes: null +- id: PMAT-205 + github_issue: null + item_type: task + title: 'GH-202-FIX-002: Debug realizar APR loader tensor shapes' + status: completed + priority: critical + assigned_to: null + created: 2026-02-04 14:13:49+00:00 + updated: 2026-02-04 14:25:14+00:00 + spec: null + acceptance_criteria: + - Add debug logging to realizar AprTransformer::from_apr_v2() to compare tensor shapes and first N values + between GGUF and APR inference paths. Root cause is in realizar, not aprender. + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-206 + github_issue: null + item_type: task + title: 'GH-202-FIX-003: E2E tensor comparison test for GGUF vs APR' + status: completed + priority: critical + assigned_to: null + created: 2026-02-04 14:25:49+00:00 + updated: 2026-02-04 14:27:58+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-207 + github_issue: null + item_type: task + title: 'GH-202-FIX-004: realizar E2E test comparing GGUF vs APR inference' + status: completed + priority: critical + assigned_to: null + created: 2026-02-04 14:28:04+00:00 + updated: 2026-02-04 14:37:50.775554+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-208 + github_issue: null + item_type: task + title: 'GH-202: LAYOUT-002 conversion fidelity fix' + status: completed + priority: critical + assigned_to: null + created: 2026-02-04 17:25:51+00:00 + updated: 2026-02-04 19:23:00+00:00 + spec: null + acceptance_criteria: + - 'Fix quantized tensor transpose during GGUF→APR import causing 58-90% diff. Blocks #200, #192, #199.' + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-209 + github_issue: null + item_type: task + title: 'GH-200: Qwen2.5-Coder dev-tier QA qualification' + status: completed + priority: critical + assigned_to: null + created: 2026-02-04 17:25:52+00:00 + updated: 2026-02-20 11:07:30+00:00 + spec: null + acceptance_criteria: + - '0/6 models pass QA gates. Blocked by #202 LAYOUT-002 fix.' + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: GH-202 + github_issue: null + item_type: task + title: 'New task: GH-202' + status: completed + priority: medium + assigned_to: null + created: 2026-02-04 12:40:00.035130+00:00 + updated: 2026-02-04 12:41:13+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-210 + github_issue: null + item_type: task + title: 'GH-199: APR 1.5B dequantize and GPU issues' + status: completed + priority: high + assigned_to: null + created: 2026-02-04 17:25:54+00:00 + updated: 2026-02-20 11:12:16+00:00 + spec: null + acceptance_criteria: + - lm_head.weight dequantize fails, APR 8x slower than GGUF, GPU output garbage. + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-211 + github_issue: null + item_type: task + title: 'GH-192: APR inference performance (0.5 vs 270 tok/s)' + status: completed + priority: high + assigned_to: null + created: 2026-02-04 17:25:55+00:00 + updated: 2026-02-20 11:12:16+00:00 + spec: null + acceptance_criteria: + - APR format inference too slow. Dequant path not using fused kernels. + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-212 + github_issue: null + item_type: task + title: 'LAYOUT-CONTRACT-001: Implement tensor layout contract validation tests' + status: completed + priority: critical + assigned_to: null + created: 2026-02-04 18:13:49+00:00 + updated: 2026-02-04 18:23:56+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-213 + github_issue: null + item_type: task + title: 'LAYOUT-CONTRACT-002: Finalize spec documentation and playbook integration' + status: completed + priority: high + assigned_to: null + created: 2026-02-04 18:26:00+00:00 + updated: 2026-02-04 18:26:39+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: 'PMAT-PHASE6: Re-run Phase 6 (marathon + throughput) with self-converted GGUF' + github_issue: null + item_type: task + title: 'New task: PMAT-PHASE6: Re-run Phase 6 (marathon + throughput) with self-converted GGUF' + status: completed + priority: medium + assigned_to: null + created: 2026-02-04 14:50:34.685386+00:00 + updated: 2026-02-20 11:05:16+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-214 + github_issue: null + item_type: task + title: 'SPEC-FINAL-001: Complete tensor layout contract specification' + status: completed + priority: high + assigned_to: null + created: 2026-02-04 18:27:18+00:00 + updated: 2026-02-04 18:28:14+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-215 + github_issue: null + item_type: task + title: 'GH-208: APR Inference - Layer Weight Investigation' + status: cancelled + priority: high + assigned_to: null + created: 2026-02-05 12:13:27+00:00 + updated: 2026-02-20 11:05:32+00:00 + spec: null + acceptance_criteria: + - Embedding correlation fixed (1.0), but APR inference still produces garbage. Need to investigate layer + weights and GPU kernels. + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-216 + github_issue: null + item_type: task + title: 'GH-208-GPU: Fix GPU inference garbage output (Five Whys root cause analysis)' + status: cancelled + priority: critical + assigned_to: null + created: 2026-02-05 12:35:13+00:00 + updated: 2026-02-20 11:05:32+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-217 + github_issue: null + item_type: task + title: 'GH-205: F16 SafeTensors Passthrough Fix' + status: completed + priority: high + assigned_to: null + created: 2026-02-05 14:33:31+00:00 + updated: 2026-02-05 14:35:21.316402+00:00 + spec: null + acceptance_criteria: + - Fixed F16 SafeTensors→APR 95% diff caused by F16→F32→F16 precision loss. Implemented F16 passthrough + that preserves raw bytes. Also fixed F16→F32 conversion arithmetic overflow. + phases: [] + subtasks: [] + estimated_effort: null + labels: + - bug + - converter + - f16 + notes: null +- id: PMAT-218 + github_issue: null + item_type: task + title: 'PMAT-240: Create model family YAMLs (qwen2, llama, whisper, bert)' + status: completed + priority: high + assigned_to: null + created: 2026-02-06 11:05:49+00:00 + updated: 2026-02-20 11:05:16+00:00 + spec: null + acceptance_criteria: + - Write contracts/model-families/qwen2.yaml, llama.yaml, whisper.yaml, bert.yaml following the schema + in Section 4.2 of the model oracle spec. Each YAML declares size variants, constraints, tensor templates, + shape templates, and chat template configurations. + phases: [] + subtasks: [] + estimated_effort: null + labels: + - model-oracle + - phase-1 + notes: null +- id: PMAT-219 + github_issue: null + item_type: task + title: 'PMAT-241: ModelFamily trait + ModelFamilyConfig' + status: completed + priority: high + assigned_to: null + created: 2026-02-06 11:05:53+00:00 + updated: 2026-02-20 11:05:16+00:00 + spec: null + acceptance_criteria: + - Create src/format/model_family.rs with ModelFamily trait, ModelFamilyConfig, ModelSizeConfig, ModelConstraints, + and associated enums (AttentionType, Activation, NormType, PositionalEncoding, MlpType). Include detect_family() + function that takes tensor names and returns matching ModelFamily impl. + phases: [] + subtasks: [] + estimated_effort: null + labels: + - model-oracle + - phase-1 + notes: null +- id: PMAT-220 + github_issue: null + item_type: task + title: 'PMAT-242: YAML contract loader' + status: completed + priority: high + assigned_to: null + created: 2026-02-06 11:05:55+00:00 + updated: 2026-02-20 11:05:16+00:00 + spec: null + acceptance_criteria: + - Create src/format/model_family_loader.rs that parses model family YAML files at runtime. Uses minimal + YAML parsing (no serde_yaml dependency). Returns ModelFamilyConfig structs. Runtime fallback for build.rs + codegen. + phases: [] + subtasks: [] + estimated_effort: null + labels: + - model-oracle + - phase-1 + notes: null +- id: GH-205 + github_issue: null + item_type: task + title: 'New task: GH-205' + status: completed + priority: medium + assigned_to: null + created: 2026-02-05 11:20:38.193678+00:00 + updated: 2026-02-20 11:05:16+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: GH-207 + github_issue: null + item_type: task + title: 'New task: GH-207' + status: completed + priority: medium + assigned_to: null + created: 2026-02-05 11:27:20.280899+00:00 + updated: 2026-02-20 11:05:16+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: GH-208 + github_issue: null + item_type: task + title: 'New task: GH-208' + status: completed + priority: medium + assigned_to: null + created: 2026-02-05 11:29:43.574421+00:00 + updated: 2026-02-20 11:05:16+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-221 + github_issue: null + item_type: task + title: 'PMAT-243: Clippy column-major bans' + status: completed + priority: high + assigned_to: null + created: 2026-02-06 11:05:58+00:00 + updated: 2026-02-20 11:05:16+00:00 + spec: null + acceptance_criteria: + - Add disallowed-methods entries to .clippy.toml for all column-major matmul kernel functions. Verify + cargo clippy -- -D warnings catches column-major imports. + phases: [] + subtasks: [] + estimated_effort: null + labels: + - model-oracle + - phase-1 + notes: null +- id: PMAT-222 + github_issue: null + item_type: task + title: 'PMAT-244: apr oracle local file mode' + status: completed + priority: high + assigned_to: null + created: 2026-02-06 11:06:05+00:00 + updated: 2026-02-20 11:12:22+00:00 + spec: null + acceptance_criteria: + - Add Commands::Oracle to crates/apr-cli/src/lib.rs. Implement local file analysis via RosettaStone::inspect(), + match tensor names against family contracts, detect size variant, output ModelOracleReport in text + and JSON. Include --compliance and --tensors flags. + phases: [] + subtasks: [] + estimated_effort: null + labels: + - model-oracle + - phase-2 + notes: null +- id: PMAT-223 + github_issue: null + item_type: task + title: 'PMAT-245: apr oracle HuggingFace API mode' + status: completed + priority: medium + assigned_to: null + created: 2026-02-06 11:06:07+00:00 + updated: 2026-02-20 11:12:22+00:00 + spec: null + acceptance_criteria: + - Implement HF API query for config.json. Parse model_type, hidden_size, num_hidden_layers from config. + Match against family contracts. Handle gated models (401), rate limits (429), offline mode. + phases: [] + subtasks: [] + estimated_effort: null + labels: + - model-oracle + - phase-2 + notes: null +- id: PMAT-224 + github_issue: null + item_type: task + title: 'PMAT-246: apr oracle --family contract mode' + status: completed + priority: medium + assigned_to: null + created: 2026-02-06 11:06:09+00:00 + updated: 2026-02-20 11:12:22+00:00 + spec: null + acceptance_criteria: + - Implement contract description rendering. Load YAML, display all size variants or filter with --size. + Show constraints, tensor templates with evaluated shapes, chat template. Text and JSON output. + phases: [] + subtasks: [] + estimated_effort: null + labels: + - model-oracle + - phase-2 + notes: null +- id: PMAT-225 + github_issue: null + item_type: task + title: 'PMAT-247: Playbook certification cross-reference' + status: completed + priority: medium + assigned_to: null + created: 2026-02-06 11:06:12+00:00 + updated: 2026-02-20 11:12:22+00:00 + spec: null + acceptance_criteria: + - Parse ../apr-model-qa-playbook/docs/certifications/models.csv. Map detected model to certification + entry using csv_family_key and size variant. Populate CertificationInfo in ModelOracleReport. Handle + missing playbook repo. + phases: [] + subtasks: [] + estimated_effort: null + labels: + - model-oracle + - phase-2 + notes: null +- id: PMAT-226 + github_issue: null + item_type: task + title: 'PMAT-248: PhantomData on Validated* types' + status: completed + priority: medium + assigned_to: null + created: 2026-02-06 11:06:18+00:00 + updated: 2026-02-20 11:17:14+00:00 + spec: null + acceptance_criteria: + - 'Add RowMajor marker type. Make ValidatedWeight generic: ValidatedWeight. Existing code + uses default and compiles unchanged. Add PhantomData field. Update ValidatedEmbedding similarly.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - model-oracle + - phase-3 + notes: null +- id: PMAT-227 + github_issue: null + item_type: task + title: 'PMAT-249: AprTransformer migration to Validated* fields' + status: completed + priority: medium + assigned_to: null + created: 2026-02-06 11:06:20+00:00 + updated: 2026-02-20 11:42:38+00:00 + spec: null + acceptance_criteria: + - 'Covered by GH-279: ValidatedLayerWeights (cuda/types.rs) seals GPU weights with architecture-validated + constructor. ValidatedAprTransformer (safetensors/validation_embedding.rs) seals CPU weights. Both + enforce architecture requirements at construction time via required_roles(). Import/export completeness + gates in aprender refuse incomplete models. The original intent — preventing unvalidated weights from + reaching inference — is fully implemented.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - model-oracle + - phase-3 + notes: null +- id: PMAT-228 + github_issue: null + item_type: task + title: 'PMAT-250: build.rs YAML-to-Rust code generation' + status: completed + priority: medium + assigned_to: null + created: 2026-02-06 11:06:22+00:00 + updated: 2026-02-20 11:26:35+00:00 + spec: null + acceptance_criteria: + - Write build.rs that reads contracts/model-families/*.yaml, generates ModelFamily trait implementations, + writes to OUT_DIR/model_families_generated.rs. Include cargo:rerun-if-changed directives. + phases: [] + subtasks: [] + estimated_effort: null + labels: + - model-oracle + - phase-4 + notes: null +- id: PMAT-229 + github_issue: null + item_type: task + title: 'PMAT-251: Generic AprTransformer' + status: cancelled + priority: medium + assigned_to: null + created: 2026-02-06 11:06:25+00:00 + updated: 2026-02-20 11:42:44+00:00 + spec: null + acceptance_criteria: + - 'Depended on PMAT-227 (now completed via GH-279). Generic AprTransformer would parameterize + by model family — but the actual problem (compile-time architecture enforcement) is solved by ValidatedLayerWeights + and ValidatedAprTransformer. Parameterizing by ModelFamily (different struct fields per arch) is aspirational + and conflicts with the existing approach of using ArchConstraints + runtime validation at construction. + The current sealed-constructor pattern is more practical: one struct, validated at construction. Cancelled: + superseded by GH-279 design.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - model-oracle + - phase-4 + notes: null +- id: PMAT-230 + github_issue: null + item_type: task + title: 'PMAT-253: Additional model family YAMLs' + status: completed + priority: low + assigned_to: null + created: 2026-02-06 11:06:26+00:00 + updated: 2026-02-20 11:21:04+00:00 + spec: null + acceptance_criteria: + - Create contracts/model-families/mistral.yaml, phi.yaml, gemma.yaml, deepseek.yaml. Follow schema established + in PMAT-240. Source config values from HuggingFace model cards and config.json files. + phases: [] + subtasks: [] + estimated_effort: null + labels: + - model-oracle + - phase-5 + notes: null +- id: PMAT-231 + github_issue: null + item_type: task + title: 'GH-254: Verify F2-VALIDATION BOS fix and update showcase spec FALSIFIED gates' + status: completed + priority: critical + assigned_to: null + created: 2026-02-08 10:59:25+00:00 + updated: 2026-02-20 11:05:16+00:00 + spec: null + acceptance_criteria: + - 'BOS fix pushed to realizar (3670abb). Need to: 1) Verify GPU actually accelerates (>100 tok/s vs + 33), 2) Update FALSIFIED gates in showcase spec, 3) Re-measure 1.5B and 7B GPU performance' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - showcase + - gpu + - kaizen + notes: null +- id: PMAT-232 + github_issue: null + item_type: task + title: 'GH-255: 7B GGUF GPU produces garbage output (CPU correct)' + status: completed + priority: critical + assigned_to: null + created: 2026-02-08 11:09:56+00:00 + updated: 2026-02-20 11:05:16+00:00 + spec: null + acceptance_criteria: + - '7B GPU: garbage (''2? son the -"'') vs CPU correct (''2+2 is 4''). 1.5B works on both. apr qa golden + test uses CPU only — QA gap. Root cause: likely CUDA kernel dimension issue (7B: hidden=3584 vs 1.5B: + hidden=1536). Five Whys needed.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - gpu + - inference + - defect + notes: null +- id: PMAT-233 + github_issue: null + item_type: task + title: 'PMAT-260: Investigate 23.7 GB RSS for 7B Q4K (4 GB on disk) — 6x model size' + status: completed + priority: high + assigned_to: null + created: 2026-02-08 14:54:39+00:00 + updated: 2026-02-20 11:05:16+00:00 + spec: null + acceptance_criteria: + - 'Falsified: F-PERF GPU/CPU memory <6 GB shows 23.7 GB. 4 GB Q4K model using 6x memory suggests unnecessary + copies or leaks. Similar pattern to GH-199 where model was cloned twice.' + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-234 + github_issue: null + item_type: task + title: 'PMAT-234: F-GT-001 enforce-provenance flag + F-GT-002 mixed quant warning' + status: completed + priority: medium + assigned_to: null + created: 2026-02-08 15:09:13+00:00 + updated: 2026-02-20 11:05:16+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-235 + github_issue: null + item_type: task + title: 'PMAT-PROFILE-A: Formal verification + code quality for A score' + status: completed + priority: critical + assigned_to: null + created: 2026-02-10 08:37:32+00:00 + updated: 2026-02-20 11:05:16+00:00 + spec: null + acceptance_criteria: + - Improve Formal Verification 0.9->8+, Code Quality 11->20+, Rust Tooling 69.5->100+ + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-243 + github_issue: null + item_type: task + title: Fix 16 showcase spec falsification bugs (Round 51) + status: completed + priority: medium + assigned_to: null + created: 2026-02-14 15:33:00+00:00 + updated: 2026-02-20 11:05:16+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-244 + github_issue: null + item_type: task + title: Split 3 files >2000 lines for File Health compliance + status: completed + priority: high + assigned_to: null + created: 2026-02-14 18:13:10+00:00 + updated: 2026-02-14 19:17:19+00:00 + spec: null + acceptance_criteria: + - rosetta.rs (7202), lib.rs (7148), oracle.rs (6114) need splitting + phases: [] + subtasks: [] + estimated_effort: null + labels: + - comply + - file-health + notes: null +- id: PMAT-245 + github_issue: null + item_type: task + title: Fix CB-500 string byte indexing warnings + status: completed + priority: medium + assigned_to: null + created: 2026-02-14 18:13:12+00:00 + updated: 2026-02-20 11:07:30+00:00 + spec: null + acceptance_criteria: + - 319 CB-506 warnings for &str[n..m] byte indexing that can panic on non-ASCII + phases: [] + subtasks: [] + estimated_effort: null + labels: + - comply + - cb-500 + notes: null +- id: PMAT-246 + github_issue: null + item_type: task + title: Fix CB-900 broken markdown links in book + status: completed + priority: medium + assigned_to: null + created: 2026-02-14 18:13:13+00:00 + updated: 2026-02-20 11:07:30+00:00 + spec: null + acceptance_criteria: + - 24 broken internal links in book/ and docs/ + phases: [] + subtasks: [] + estimated_effort: null + labels: + - comply + - cb-900 + notes: null +- id: PMAT-257 + github_issue: null + item_type: task + title: 'GH-259: apr flow — add GGUF/SafeTensors support via Rosetta dispatch' + status: completed + priority: high + assigned_to: null + created: 2026-02-15 08:14:25+00:00 + updated: 2026-02-15 08:36:11+00:00 + spec: null + acceptance_criteria: + - apr flow only works with APR format, fails on GGUF with 'Invalid magic'. Should use Rosetta Stone + dispatch like tree/hex/debug. + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: GH-219 + github_issue: null + item_type: task + title: 'New task: GH-219' + status: completed + priority: medium + assigned_to: null + created: 2026-02-09 15:48:15.332094+00:00 + updated: 2026-02-20 11:05:16+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-258 + github_issue: null + item_type: task + title: 'GH-260: apr diff — fix cross-format APR parse failure' + status: completed + priority: high + assigned_to: null + created: 2026-02-15 08:14:26+00:00 + updated: 2026-02-15 08:36:12+00:00 + spec: null + acceptance_criteria: + - 'apr diff GGUF vs APR fails with ''Invalid tensor index: invalid dtype''. Rosetta Stone diff should + handle cross-format comparison.' + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: Round-49-falsification + github_issue: null + item_type: task + title: 'New task: Round-49-falsification' + status: cancelled + priority: medium + assigned_to: null + created: 2026-02-12 22:56:33.321235+00:00 + updated: 2026-02-20 11:05:32+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: 'GH-234/235/236: lm_head quantization skip, GPT-2 hidden_dim metadata, GGUF export architecture' + github_issue: null + item_type: task + title: 'New task: GH-234/235/236: lm_head quantization skip, GPT-2 hidden_dim metadata, GGUF export + architecture' + status: completed + priority: medium + assigned_to: null + created: 2026-02-13 16:11:43.916543+00:00 + updated: 2026-02-13 16:31:40.698212+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: GH-237 + github_issue: null + item_type: task + title: 'New task: GH-237' + status: completed + priority: medium + assigned_to: null + created: 2026-02-13 16:38:26.474586+00:00 + updated: 2026-02-20 11:05:16+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: qwen2.5-coder-showcase-demo + github_issue: null + item_type: task + title: 'New task: qwen2.5-coder-showcase-demo' + status: completed + priority: medium + assigned_to: null + created: 2026-02-14 12:06:18.262210+00:00 + updated: 2026-02-20 11:05:16+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: docs/specifications/qwen2.5-coder-showcase.md + github_issue: null + item_type: task + title: 'New task: docs/specifications/qwen2.5-coder-showcase.md' + status: completed + priority: medium + assigned_to: null + created: 2026-02-14 14:19:31.830927+00:00 + updated: 2026-02-20 11:05:16+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: GH-242 + github_issue: 242 + item_type: task + title: apr eval rejects APR format + GGUF fused_matmul type error + status: completed + priority: medium + assigned_to: null + created: 2026-02-14 14:28:36.727595+00:00 + updated: 2026-02-14 14:45:21.597632+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-259 + github_issue: null + item_type: task + title: apr hex --stats silently drops stats for BF16 tensors + status: completed + priority: high + assigned_to: null + created: 2026-02-16 14:40:10+00:00 + updated: 2026-02-20 11:07:30+00:00 + spec: null + acceptance_criteria: + - 'apr hex --tensor --stats on a BF16 safetensors file (e.g. Qwen2-0.5B) shows the tensor header + but skips the Statistics: line entirely. No error, no warning — just silent omission. F32 tensors + work fine. Discovered via tiny-model-ground-truth safetensors parity tests comparing apr hex against + Python safetensors + torch stats.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - hex + - bf16 + - safetensors + - parity + notes: null +- id: PMAT-260 + github_issue: null + item_type: task + title: 'GH-279/280/281: Entrenar delegation API gaps (Loss Send+Sync, cross_entropy_loss, per-class + metrics)' + status: completed + priority: medium + assigned_to: null + created: 2026-02-17 11:24:45+00:00 + updated: 2026-02-20 11:05:16+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-261 + github_issue: null + item_type: task + title: 'Qwen3-8B: Performance Parity Pipeline' + status: completed + priority: high + assigned_to: null + created: 2026-02-17 14:37:33+00:00 + updated: 2026-02-20 11:05:16+00:00 + spec: null + acceptance_criteria: + - 'GH-280 complete: PerHeadRmsNormKernel in trueno-gpu v0.4.18, capability gate flipped, 20/21 falsification + checks pass. Remaining: throughput optimization (3.9 tok/s → 40+ target), GPU golden output verification + (unblocked), format parity.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - qwen3 + - performance + - pipeline + notes: null +- id: PMAT-262 + github_issue: null + item_type: task + title: 'GH-277/278: Fix GGUF export compatibility with llama.cpp' + status: completed + priority: medium + assigned_to: null + created: 2026-02-17 17:14:20+00:00 + updated: 2026-02-17 17:14:23.890164+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: GH-243 + github_issue: 243 + item_type: task + title: 'feat: apr quantize — unified quantization pipeline with GGUF/AWQ/GPTQ output' + status: completed + priority: medium + assigned_to: null + created: 2026-02-15 10:52:15.943055+00:00 + updated: 2026-02-20 11:05:16+00:00 + spec: null + acceptance_criteria: + - '`apr quantize model.apr --scheme int4` works end-to-end' + - '`apr quantize model.apr --scheme gptq --calibration data.jsonl` works' + - '`apr quantize --plan --json` returns memory/time estimates' + - '`--batch` mode produces multiple output files' + - JSON output for all modes + - Testable in tiny-model-ground-truth parity checker + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: GH-244 + github_issue: 244 + item_type: task + title: 'feat: apr finetune — LoRA/QLoRA fine-tuning with adapter upload to Hub' + status: completed + priority: medium + assigned_to: null + created: 2026-02-15 11:12:10.414158+00:00 + updated: 2026-02-20 11:05:16+00:00 + spec: null + acceptance_criteria: + - '`apr finetune model.apr --method lora --data train.jsonl` trains and saves adapter' + - '`apr finetune merge` produces valid APR model' + - Adapter format compatible with PEFT (`adapter_config.json`) + - '`--plan --json` returns VRAM/time estimates (existing behavior preserved)' + - Testable with tiny models (SmolLM-135M fine-tune should complete in <5min) + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: GH-246 + github_issue: 246 + item_type: task + title: 'feat: apr export — MLX, CoreML, and OpenVINO format support' + status: completed + priority: medium + assigned_to: null + created: 2026-02-15 11:30:26.378754+00:00 + updated: 2026-02-20 11:05:16+00:00 + spec: null + acceptance_criteria: + - '`apr export --format mlx` produces loadable MLX model' + - '`apr export --format onnx` produces valid ONNX model' + - '`apr export --list-formats --json` lists all supported formats' + - '`--batch` mode produces multiple output directories' + - Round-trip validation via `apr rosetta` for each format + - Testable in tiny-model-ground-truth parity checker + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: GH-247 + github_issue: 247 + item_type: task + title: 'feat: apr prune + apr distill — structured pruning and knowledge distillation pipeline' + status: completed + priority: medium + assigned_to: null + created: 2026-02-15 11:12:51.494148+00:00 + updated: 2026-02-20 11:05:16+00:00 + spec: null + acceptance_criteria: + - '`apr prune model.apr --method structured --target-ratio 0.5` produces smaller model' + - '`apr distill teacher.apr --student pruned.apr --data train.jsonl` trains student' + - '`apr prune --analyze --json` returns layer importance scores' + - '`apr prune --plan --json` returns time/memory/quality estimates' + - Combined `--distill` flag works for Minitron-style pipeline + - Pruned model passes `apr validate` and `apr check` + - Testable with tiny models (SmolLM-135M → ~70M should complete in <10min) + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: GH-248 + github_issue: 248 + item_type: task + title: 'bug: --json flag ignored on list, eval, tree, debug subcommands' + status: completed + priority: medium + assigned_to: null + created: 2026-02-14 21:33:19.572210+00:00 + updated: 2026-02-20 11:05:16+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - bug + notes: null +- id: GH-249 + github_issue: 249 + item_type: task + title: 'bug: apr inspect --json returns empty architecture field' + status: completed + priority: medium + assigned_to: null + created: 2026-02-14 21:32:59.143242+00:00 + updated: 2026-02-20 11:05:16+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - bug + notes: null +- id: GH-250 + github_issue: 250 + item_type: task + title: 'bug: apr run --json produces completely wrong tokens (32/32 mismatch)' + status: completed + priority: medium + assigned_to: null + created: 2026-02-14 21:32:59.917777+00:00 + updated: 2026-02-20 11:05:16+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - bug + notes: null +- id: GH-251 + github_issue: 251 + item_type: task + title: 'bug: apr validate output format changed — dict with top-level keys instead of checks list' + status: completed + priority: medium + assigned_to: null + created: 2026-02-14 21:33:00.732997+00:00 + updated: 2026-02-20 11:05:16+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - bug + notes: null +- id: PMAT-283 + github_issue: null + item_type: task + title: 'GH-279-SEAL-001: Seal OwnedQuantizedModel fields pub(crate)' + status: completed + priority: medium + assigned_to: null + created: 2026-02-19 09:29:42+00:00 + updated: 2026-02-20 11:05:16+00:00 + spec: null + acceptance_criteria: + - Make OwnedQuantizedModel fields pub(crate) with accessor methods. Currently all fields are pub — anyone + can construct garbage bypassing contract_gate. 18+ consumer files need updating. + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-284 + github_issue: null + item_type: task + title: 'GH-279-SEAL-002: Validated input wrapper for GpuModel::from_apr_weights' + status: completed + priority: medium + assigned_to: null + created: 2026-02-19 09:29:44+00:00 + updated: 2026-02-20 11:12:35+00:00 + spec: null + acceptance_criteria: + - from_apr_weights takes raw Vec. Add a ValidatedAprWeights wrapper that proves dimensions were + checked. Prevents callers from passing wrong-sized vectors. + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: GH-252 + github_issue: 252 + item_type: task + title: 'bug: apr lint exits 5 on warnings-only (0 errors)' + status: completed + priority: medium + assigned_to: null + created: 2026-02-14 21:33:01.473463+00:00 + updated: 2026-02-20 11:05:16+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - bug + notes: null +- id: GH-253 + github_issue: 253 + item_type: task + title: 'bug: apr check (selftest) fails with GH-187 embedding warning' + status: completed + priority: medium + assigned_to: null + created: 2026-02-14 21:33:02.228863+00:00 + updated: 2026-02-20 11:05:16+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - bug + notes: null +- id: GH-254 + github_issue: 254 + item_type: task + title: 'bug: apr bench reports 0.0 tok/s throughput on all models' + status: completed + priority: medium + assigned_to: null + created: 2026-02-14 21:33:03.102874+00:00 + updated: 2026-02-20 11:05:16+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - bug + notes: null +- id: GH-256 + github_issue: 256 + item_type: task + title: 'bug: apr diff reports structural diffs between int4 and int8 variants of same model' + status: completed + priority: medium + assigned_to: null + created: 2026-02-14 21:33:03.820306+00:00 + updated: 2026-02-20 11:05:16+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - bug + notes: null +- id: GH-279-4 + github_issue: null + item_type: task + title: 'GH-279: Wire QkNorm into GPU forward path + fix format_parity sharded SafeTensors' + status: completed + priority: high + assigned_to: null + created: 2026-02-17 19:03:09.771720+00:00 + updated: 2026-02-18 21:00:00+00:00 + spec: null + acceptance_criteria: + - golden_output QA gate passes (GPU QkNorm matches CPU path) + - format_parity QA gate passes (sharded SafeTensors loads all shards) + - performance_regression QA gate passes (GPU speedup restored to baseline) + phases: [] + subtasks: [] + estimated_effort: 4h + labels: + - cuda + - qwen3 + - qa-gates + notes: Wired per-head RMSNorm (QkNorm) into GPU forward path for Qwen3 models. Added attn_q/k_norm_ptr/len + fields to IndexedLayerWeights + BoundLayerWeights. Used existing per_head_rmsnorm_into CUDA kernel + and cache_rmsnorm_gamma upload. Fixed format_parity gate to detect sharded models via model.safetensors.index.json. + Extensive complexity refactoring to pass pre-commit quality gates. +- id: PMAT-285 + github_issue: null + item_type: task + title: 'GH-279-SEAL-003: Consolidate transpose to trueno-quant single source' + status: completed + priority: low + assigned_to: null + created: 2026-02-19 09:29:47+00:00 + updated: 2026-02-20 11:12:35+00:00 + spec: null + acceptance_criteria: + - Both aprender format/converter/mod.rs and realizar have transpose logic. trueno-quant already has + transpose_q4k/q5k/q6k_for_matmul. Remove duplicates, ensure single source of truth. + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-286 + github_issue: null + item_type: task + title: 'UCBD-001: Create provable-contracts-macros proc macro crate' + status: completed + priority: high + assigned_to: null + created: 2026-02-19 10:23:09+00:00 + updated: 2026-02-20 11:15:12+00:00 + spec: null + acceptance_criteria: + - 'Phase 1A from unified-contract-by-design.md. Create #[contract] attribute macro.' + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-287 + github_issue: null + item_type: task + title: 'UCBD-002: Add build.rs binding verification to realizar' + status: completed + priority: high + assigned_to: null + created: 2026-02-19 10:23:09+00:00 + updated: 2026-02-20 11:05:16+00:00 + spec: null + acceptance_criteria: + - 'Phase 1B: build.rs reads binding.yaml, verifies all bindings implemented.' + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-288 + github_issue: null + item_type: task + title: 'UCBD-003: Delete aprender GGUF reader/dequant dead code' + status: completed + priority: high + assigned_to: null + created: 2026-02-19 10:23:10+00:00 + updated: 2026-02-20 11:05:16+00:00 + spec: null + acceptance_criteria: + - 'REVISED: Aprender GGUF reader is NOT dead code — it''s the conversion pipeline reader for ''apr import''. + Only realizar''s inference loading replaces aprender''s inference loading. Updated to: consolidate + dequant functions to use trueno''s implementations where possible.' + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: GH-280 + github_issue: null + item_type: task + title: 'GH-280: Kernel capability gate — contract-driven GPU admission control' + status: completed + priority: medium + assigned_to: null + created: 2026-02-17 18:43:44.982621+00:00 + updated: 2026-02-18 11:51:41+00:00 + spec: null + acceptance_criteria: + - PerHeadRmsNormKernel added to trueno-gpu v0.4.18. Capability gate flipped in realizar. Qwen3 GPU inference + unblocked. 9 new kernel tests, 10 capability tests pass. + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: Add contract-driven property tests from provable-contracts + github_issue: null + item_type: task + title: 'New task: Add contract-driven property tests from provable-contracts' + status: completed + priority: medium + assigned_to: null + created: 2026-02-18 14:48:42.940650+00:00 + updated: 2026-02-18 14:50:17.905535+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: GH-282 + github_issue: 282 + item_type: bug + title: 'fix: apr serve GPU failures — missing make_current() in APR CUDA path' + status: completed + priority: high + assigned_to: null + created: 2026-02-18 22:00:00+00:00 + updated: 2026-02-18 22:00:00+00:00 + spec: null + acceptance_criteria: + - APR CUDA forward path calls make_current() before all GPU operations + - GEMM kernel param types match .param .u32 declarations (u32, not i32) + - CUDA error code 201 (INVALID_CONTEXT) mapped in trueno-gpu diagnostics + - All 14802 realizar unit tests pass + phases: [] + subtasks: [] + estimated_effort: 2h + labels: + - cuda + - apr-serve + - bug-fix + notes: 'Root cause: AprV2ModelCuda never called make_current() before CUDA ops. GGUF path had make_current() + in 4+ places. When tokio worker threads (apr serve) called forward_cuda, the CUDA context was not + current, causing cuModuleLoadData to fail with error 201 (CUDA_ERROR_INVALID_CONTEXT). Also fixed + i32→u32 type mismatch in GEMM parameter passing and added 5 missing CUDA error codes to trueno-gpu + mapping. GH-284 (HTTP perf regression) is a cascade from this — GPU falls back to CPU.' +- id: PMAT-289 + github_issue: null + item_type: task + title: 'UCBD-004: Delete aprender SafeTensors loader dead code' + status: cancelled + priority: medium + assigned_to: null + created: 2026-02-19 10:23:10+00:00 + updated: 2026-02-20 11:15:12+00:00 + spec: null + acceptance_criteria: + - 'Phase 3B: ~300 lines. Realizar owns loading.' + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-290 + github_issue: null + item_type: task + title: 'UCBD-005: Delete realizar duplicate helpers' + status: cancelled + priority: medium + assigned_to: null + created: 2026-02-19 10:23:10+00:00 + updated: 2026-02-20 11:05:32+00:00 + spec: null + acceptance_criteria: + - 'REVISED: apr/helpers.rs functions are not true duplicates — different APIs (no bias, transposed matmul). + Requires API unification, not simple deletion. Deprioritized.' + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-291 + github_issue: null + item_type: task + title: 'UCBD-006: Wire entrenar to use realizar for model loading' + status: cancelled + priority: high + assigned_to: null + created: 2026-02-19 10:23:10+00:00 + updated: 2026-02-20 11:42:32+00:00 + spec: null + acceptance_criteria: + - 'Weight loading already uses canonical stack (aprender GgufReader for GGUF, safetensors for ST). Teacher + inference needs realizar logits-level forward API which doesn''t exist yet — run_inference() returns + text not logits. TeacherModel trait requires forward()->logits, hidden_states(), attention_weights() + — none exposed by realizar. Cancelled: needs API design in realizar first.' + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-292 + github_issue: null + item_type: task + title: 'UCBD-007: Implement all 49 not_implemented bindings' + status: cancelled + priority: medium + assigned_to: null + created: 2026-02-19 10:23:10+00:00 + updated: 2026-02-20 11:15:12+00:00 + spec: null + acceptance_criteria: + - 'Phase 4: All binding.yaml entries must be implemented.' + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-293 + github_issue: null + item_type: task + title: 'New task: PMAT-293' + status: completed + priority: medium + assigned_to: null + created: 2026-02-19 11:01:57.089836+00:00 + updated: 2026-02-20 11:05:16+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-295 + github_issue: null + item_type: task + title: 'New task: PMAT-295' + status: completed + priority: medium + assigned_to: null + created: 2026-02-19 14:03:56.591443+00:00 + updated: 2026-02-20 11:05:16+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-296 + github_issue: null + item_type: task + title: 'GH-279 GAP-1: SafeTensors import completeness gate is conditional' + status: completed + priority: critical + assigned_to: null + created: 2026-02-20 10:29:00+00:00 + updated: 2026-02-20 10:47:50+00:00 + spec: null + acceptance_criteria: + - 'src/format/converter/import.rs:107 — if let Some(config) guard means SafeTensors without model_config + silently skips the architecture completeness gate. Fix: make the gate unconditional, derive arch from + tensor names when config is missing.' + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-297 + github_issue: null + item_type: task + title: 'GH-279 GAP-2: Export path has zero architecture completeness checking' + status: completed + priority: critical + assigned_to: null + created: 2026-02-20 10:29:02+00:00 + updated: 2026-02-20 10:47:50+00:00 + spec: null + acceptance_criteria: + - 'src/format/converter/export.rs — enforce_architecture_completeness is never called. A Qwen3 model + missing QK norm weights can be exported to GGUF without error. Fix: add enforce_architecture_completeness + call before writing output file.' + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-298 + github_issue: null + item_type: task + title: 'GH-279 GAP-3: validate_model_load_basic skips role checking on CPU paths' + status: completed + priority: critical + assigned_to: null + created: 2026-02-20 10:29:06+00:00 + updated: 2026-02-20 10:47:50+00:00 + spec: null + acceptance_criteria: + - 'realizar/src/contract_gate.rs:186 — passes present_roles: Vec::new() which skips completeness. Called + from 9 loader paths. GPU paths are saved by ValidatedLayerWeights::validate() at build_indexed_weights + time, but CPU paths never hit that gate. Fix: have loaders enumerate present roles and call full validate_model_load.' + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-299 + github_issue: null + item_type: task + title: 'GH-279 GAP-4: CPU AprTransformer has no architecture completeness gate' + status: completed + priority: high + assigned_to: null + created: 2026-02-20 10:29:09+00:00 + updated: 2026-02-20 10:47:50+00:00 + spec: null + acceptance_criteria: + - 'ValidatedAprTransformer::validate() checks tensor shapes but NOT architecture-level role requirements. + A Qwen3 APR file missing QK norm passes CPU validation. Fix: add architecture completeness check to + ValidatedAprTransformer::validate() using metadata arch field.' + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-325 + github_issue: null + item_type: task + title: 'FALSIFY-E6: realizar GPU/GGUF embedding path skips ValidatedEmbedding data quality gates' + status: blocked + priority: critical + assigned_to: null + created: 2026-02-23 19:09:46+00:00 + updated: 2026-03-31 16:19:47+00:00 + spec: null + acceptance_criteria: + - 'GPU/GGUF load path (gpu/scheduler/loading.rs) only validates embedding shape (len == vocab*hidden), + but SKIPS density check (<50% zeros), NaN/Inf check, L2 norm, and spot-check gates that the SafeTensors/APR + path enforces via ValidatedEmbedding::new(). A GGUF file with correct shape but 94.5% zeros (PMAT-234 + scenario) would pass GPU loading silently. Five-Whys root: F-DATA-QUALITY-001 enforcement only wired + for APR path, not GGUF.' + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-326 + github_issue: null + item_type: task + title: 'FALSIFY-E7: entrenar saves/loads embeddings without any data quality validation' + status: blocked + priority: critical + assigned_to: null + created: 2026-02-23 19:09:49+00:00 + updated: 2026-03-31 16:19:47+00:00 + spec: null + acceptance_criteria: + - 'entrenar::transformer::Embedding uses raw Tensor (not ValidatedEmbedding). No NaN/Inf check during + training, no density check on save (merge_export.rs:29-63), no statistical validation on load (weights/mod.rs:130-182). + If training diverges and embedding becomes NaN-poisoned or degenerate, the model is saved to disk + without any gate catching it. Five-Whys root: entrenar predates the ValidatedEmbedding contract and + was never retrofitted.' + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-327 + github_issue: null + item_type: task + title: 'FALSIFY-E8: realizar OOB token_id bounds check is insufficient in GPU forward paths' + status: blocked + priority: high + assigned_to: null + created: 2026-02-23 19:09:53+00:00 + updated: 2026-03-31 16:19:47+00:00 + spec: null + acceptance_criteria: + - GPU forward paths (gpu_forward_pass.rs, batch.rs, kv.rs) check token_id >= vocab_size but do NOT check + offset+hidden_dim <= embedding_weights.len(). If embedding_weights is truncated (corrupt GGUF) but + vocab_size in config is stale, Rust panics with slice OOB instead of returning an error. 8+ call sites + affected across gpu/scheduler/. + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-328 + github_issue: null + item_type: task + title: 'FALSIFY-L1: lm_head matmul dimension validation at call sites (§2.1.2)' + status: completed + priority: high + assigned_to: null + created: 2026-02-23 20:45:46+00:00 + updated: 2026-03-31 16:19:41+00:00 + spec: null + acceptance_criteria: + - 'enforce_matmul_contract exists but is only called at import boundary. If config.vocab_size or config.hidden_dim + is corrupted after load (e.g., by a malformed merge), lm_head matmul at GPU forward sites (matmul.rs:304,366) + would silently compute wrong dimensions. Five-Whys: GH-202 was dimension swap; protection at boundary + but not at use site.' + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-329 + github_issue: null + item_type: task + title: 'FALSIFY-L2: entrenar lm_head save/load has no shape or quality validation (§2.1.2)' + status: blocked + priority: high + assigned_to: null + created: 2026-02-23 20:45:49+00:00 + updated: 2026-03-31 16:19:47+00:00 + spec: null + acceptance_criteria: + - entrenar writes lm_head.weight as raw tensor during merge_export (merge_export.rs:29-63). No validation + that shape matches [vocab_size, hidden_dim]. No NaN/Inf check on lm_head before save. Parallels PMAT-326 + for embeddings. + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-330 + github_issue: null + item_type: task + title: 'PMAT-332: ValidatedVector accepts zero-length norm vectors — no minimum length gate. Zero-length + norm weight produces NaN in LayerNorm division. Gate 1 only checks data.len()==expected_len, needs + data.len()>0 guard.' + status: completed + priority: medium + assigned_to: null + created: 2026-02-23 21:21:09+00:00 + updated: 2026-03-31 16:19:41+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: GH-306 + github_issue: null + item_type: task + title: 'New task: GH-306' + status: completed + priority: medium + assigned_to: null + created: 2026-02-22 21:14:55.545255+00:00 + updated: 2026-03-31 16:59:03+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: C-04-hardcoded-eos-chat + github_issue: null + item_type: task + title: 'New task: C-04-hardcoded-eos-chat' + status: completed + priority: medium + assigned_to: null + created: 2026-02-23 12:58:12.438665+00:00 + updated: 2026-03-31 16:59:03+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: GH-324 + github_issue: null + item_type: task + title: 'New task: GH-324' + status: completed + priority: medium + assigned_to: null + created: 2026-02-23 15:11:27.494301+00:00 + updated: 2026-03-31 16:59:03+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-331 + github_issue: null + item_type: task + title: 'PMAT-333: FFN gate_proj/up_proj shape symmetry not enforced — ValidatedWeight accepts any [out,in] + without verifying gate==up shape or down==[hidden,intermediate] reversal. SwiGLU requires gate_proj.shape==up_proj.shape.' + status: completed + priority: medium + assigned_to: null + created: 2026-02-23 21:21:16+00:00 + updated: 2026-03-31 16:19:41+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-332 + github_issue: null + item_type: task + title: 'PMAT-334: FALSIFY-007 dispatch exhaustiveness test only scans 2 of 6 dispatch sites listed in + tensor-layout-v1.yaml. Missing: brick/dispatch.rs, quantize/dispatch.rs, layers/attention.rs, gpu/scheduler.rs. + A catch-all in any unscanned file would go undetected.' + status: completed + priority: medium + assigned_to: null + created: 2026-02-23 21:29:10+00:00 + updated: 2026-03-31 16:19:41+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-333 + github_issue: null + item_type: task + title: 'PMAT-335: Q4_1 and Q5_0 formats in GPU dispatch (gemv_dispatch.rs) but missing from ALL_FORMAT_IDS + registry and FALSIFY-QDOT contract tests. Orphaned formats could silently dispatch to wrong kernel + without contract coverage.' + status: completed + priority: medium + assigned_to: null + created: 2026-02-23 21:31:31+00:00 + updated: 2026-03-31 16:19:41+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-334 + github_issue: null + item_type: task + title: 'PMAT-336: FALSIFY-QDOT-006 missing — gap in numbering between QDOT-005 and QDOT-007. No test + verifies row-major-only constraint from quantized-dot-product-v1.yaml enforcement.row_major_only.' + status: completed + priority: medium + assigned_to: null + created: 2026-02-23 21:31:35+00:00 + updated: 2026-03-31 16:19:41+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-335 + github_issue: null + item_type: task + title: 'PMAT-337: Model-family YAML contract falsification tests (FALSIFY-MF-001..013)' + status: completed + priority: medium + assigned_to: null + created: 2026-02-24 07:36:34+00:00 + updated: 2026-03-31 16:19:41+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-336 + github_issue: null + item_type: task + title: 'PMAT-338: Create special-tokens-registry-v1.yaml + FALSIFY-ST-001..006' + status: completed + priority: medium + assigned_to: null + created: 2026-02-24 07:43:29+00:00 + updated: 2026-03-31 16:19:41+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-337 + github_issue: null + item_type: task + title: 'FT-DBC-001: Fine-tuning provable Design by Contract parity' + status: completed + priority: high + assigned_to: null + created: 2026-02-25 15:43:08+00:00 + updated: 2026-03-31 16:59:03+00:00 + spec: null + acceptance_criteria: + - 'Implement docs/specifications/fine-tune-provable-design-by-contract.md: Kani harnesses for classification + types, PTX kernels for CE and AdamW, binding.yaml updates, apr qa fine-tuning gate' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - fine-tuning + - contracts + - parity + notes: null +- id: PMAT-342 + github_issue: null + item_type: task + title: APR checkpoint spec v1.2.0 — full command matrix and falsification + status: completed + priority: medium + assigned_to: null + created: 2026-03-01 11:47:17+00:00 + updated: 2026-03-31 16:19:41+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-367 + github_issue: null + item_type: task + title: 'fix: TensorDType::from_u8 missing GGML Q4_0/Q5_0/Q5_1 dtype mappings (GH-375)' + status: completed + priority: medium + assigned_to: null + created: 2026-03-04 17:37:08+00:00 + updated: 2026-03-04 17:48:18.366251+00:00 + spec: null + acceptance_criteria: + - Five-whys RCA + fix missing/wrong GGML quant type mappings in tensor_index_impl.rs + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-368 + github_issue: null + item_type: task + title: 'fix: apr-qa dim-smoke G0 config.json resolution from HF cache (GH-360)' + status: completed + priority: medium + assigned_to: null + created: 2026-03-04 17:48:30+00:00 + updated: 2026-03-04 17:50:33.356431+00:00 + spec: null + acceptance_criteria: + - 'Five-whys: dim-smoke scenarios look in workspace dir but config.json lives in HF cache. Fix: resolve + config.json from HF cache path.' + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-369 + github_issue: null + item_type: task + title: 'fix: sharded SafeTensors symlink resolution (GH-363)' + status: completed + priority: medium + assigned_to: null + created: 2026-03-04 17:51:36+00:00 + updated: 2026-03-04 17:55:21.184156+00:00 + spec: null + acceptance_criteria: + - base_dir must canonicalize to resolve symlinks before joining shard filenames + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-370 + github_issue: null + item_type: task + title: 'fix: BPE tokenizer O(n²) greedy rescan → priority queue (GH-378)' + status: completed + priority: medium + assigned_to: null + created: 2026-03-04 17:58:20+00:00 + updated: 2026-03-04 17:59:03.610305+00:00 + spec: null + acceptance_criteria: + - 'Port HF tokenizers word.rs algorithm: doubly-linked symbol list + BinaryHeap, integer pair keys' + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-371 + github_issue: null + item_type: task + title: 'Fix nightly CI: patch alimentar path deps for standalone build' + status: completed + priority: medium + assigned_to: null + created: 2026-03-10 12:56:10+00:00 + updated: 2026-03-31 16:59:03+00:00 + spec: null + acceptance_criteria: + - Nightly workflow fails because Cargo.toml has path dependency on ../alimentar which doesn't exist + in CI. Add sed/pwsh step to patch path deps before build. + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: GH-336 + github_issue: 336 + item_type: task + title: 'fix(P2): benchmark silently swallows generate() errors, reports 0 tok/s' + status: completed + priority: medium + assigned_to: null + created: 2026-02-26 18:14:12.757672+00:00 + updated: 2026-03-31 16:59:03+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - bug + notes: null +- id: GH-337 + github_issue: 337 + item_type: task + title: 'fix(P2): chat server silently degrades to byte-level decode on tokenizer error' + status: completed + priority: medium + assigned_to: null + created: 2026-02-26 18:17:17.543326+00:00 + updated: 2026-03-31 16:59:03+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - bug + notes: null +- id: GH-338 + github_issue: 338 + item_type: task + title: 'fix(P2): probar silently ignores corrupted msgpack metadata' + status: completed + priority: medium + assigned_to: null + created: 2026-02-26 18:25:24.218479+00:00 + updated: 2026-03-31 16:59:03+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - bug + notes: null +- id: GH-339 + github_issue: 339 + item_type: task + title: 'fix(P2): chat template failure silently falls back to raw prompt' + status: completed + priority: medium + assigned_to: null + created: 2026-02-26 18:26:49.640389+00:00 + updated: 2026-03-31 16:59:03+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - bug + notes: null +- id: GH-340 + github_issue: 340 + item_type: task + title: 'fix(P3): safetensors.rs placeholder generation produces fake tokens' + status: completed + priority: medium + assigned_to: null + created: 2026-02-26 18:28:00.080317+00:00 + updated: 2026-03-31 16:59:03+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - bug + notes: null +- id: GH-341 + github_issue: 341 + item_type: task + title: 'chore: publish safety gate + package bloat cleanup (28MB savings)' + status: completed + priority: medium + assigned_to: null + created: 2026-02-26 18:12:34.145741+00:00 + updated: 2026-03-31 16:59:03+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - enhancement + notes: null +- id: PMAT-480 + github_issue: null + item_type: task + title: 'SPEC-CLI: Implement --trace and --profile global flags on apr run/chat/serve' + status: completed + priority: high + assigned_to: null + created: 2026-03-31 12:59:31+00:00 + updated: 2026-03-31 16:59:03+00:00 + spec: null + acceptance_criteria: + - 'Wire renacer layer tracing (8-step state machine) and trueno BrickProfiler as global flags on all + runtime commands. When --trace: emit TensorStats per layer. When --profile: emit per-brick µs timing. + Ref: aprender-spec.md §4, components/tracing.md' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - spec + - cli + - tracing + notes: null +- id: GH-366 + github_issue: null + item_type: task + title: 'New task: GH-366' + status: completed + priority: medium + assigned_to: null + created: 2026-03-01 11:50:50.562288+00:00 + updated: 2026-03-31 16:59:03+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-481 + github_issue: null + item_type: task + title: 'SPEC-PROBAR: Implement apr probar golden snapshot command' + status: completed + priority: high + assigned_to: null + created: 2026-03-31 12:59:34+00:00 + updated: 2026-03-31 16:19:41+00:00 + spec: null + acceptance_criteria: + - 'Add apr probar command for visual regression testing of model activations. Flags: --golden DIR, --assert, + --format json|png, --layer PATTERN, --tolerance FLOAT. Compare per-layer activation stats against + golden reference. Exit non-zero on divergence. Ref: aprender-spec.md §13, components/testing.md' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - spec + - cli + - probar + notes: null +- id: PMAT-482 + github_issue: null + item_type: task + title: 'SPEC-BRICK: Implement BrickTracer auto-escalation in apr cbtop' + status: completed + priority: medium + assigned_to: null + created: 2026-03-31 12:59:38+00:00 + updated: 2026-03-31 16:19:41+00:00 + spec: null + acceptance_criteria: + - 'Wire BrickTracer from renacer into apr cbtop command. Auto-escalate from measurement to full syscall + tracing when CV>15% or efficiency<25%. Emit SyscallBreakdown (mmap_us, futex_us, ioctl_us, compute_us). + Rate limit 100 traces/sec. Ref: components/tracing.md §3' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - spec + - cli + - tracing + - brick + notes: null +- id: PMAT-483 + github_issue: null + item_type: task + title: 'SPEC-CONTRACT: Add provable-contracts equivalence obligations for all 5 compute backends' + status: completed + priority: high + assigned_to: null + created: 2026-03-31 12:59:43+00:00 + updated: 2026-03-31 16:19:41+00:00 + spec: null + acceptance_criteria: + - 'Write YAML contracts with equivalence proof obligations for each kernel across SIMD/wgpu/CUDA PTX/cuBLAS/WASM + backends. Required: RMSNorm, Q4K GEMV, RoPE, SwiGLU, Attention, LM Head. Each contract: scalar reference + + cosine>=0.98 for GPU backends + max_ulp<=2 for SIMD. Ref: components/provable-contracts.md §6, components/compute-backends.md' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - spec + - contracts + - backends + notes: null +- id: PMAT-484 + github_issue: null + item_type: task + title: 'SPEC-PROBAR-CI: Wire apr probar into tier2/tier3 quality gates' + status: completed + priority: medium + assigned_to: null + created: 2026-03-31 12:59:52+00:00 + updated: 2026-03-31 16:19:41+00:00 + spec: null + acceptance_criteria: + - 'Add probar golden regression to Makefile tier2 gate (fast: --assert only) and tier3 gate (full: --profile + --assert). Golden snapshots stored in tests/golden/. Any weight-modifying PR (merge/finetune/prune/quantize) + must pass probar. Ref: components/testing.md §6.2' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - spec + - ci + - probar + notes: null +- id: PMAT-485 + github_issue: null + item_type: task + title: 'SPEC-TRACE-OTLP: Add OTLP export to apr serve for distributed tracing' + status: completed + priority: medium + assigned_to: null + created: 2026-03-31 12:59:56+00:00 + updated: 2026-03-31 16:19:42+00:00 + spec: null + acceptance_criteria: + - 'Add --otlp-endpoint flag to apr serve. Export W3C Trace Context spans (renacer-core SpanRecord) to + Jaeger/Tempo. Each inference request = parent span, each layer = child span with TensorStats. Ref: + components/tracing.md §3.5' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - spec + - cli + - tracing + - serve + notes: null +- id: GH-479 + github_issue: null + item_type: task + title: 'New task: GH-479' + status: completed + priority: medium + assigned_to: null + created: 2026-03-12 10:27:35.676295+00:00 + updated: 2026-03-31 16:59:03+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-486 + github_issue: null + item_type: task + title: 'SPEC-TRAIN-PROFILE: Add --profile and --trace flags to apr train/finetune' + status: completed + priority: high + assigned_to: null + created: 2026-03-31 16:23:56+00:00 + updated: 2026-03-31 16:59:03+00:00 + spec: null + acceptance_criteria: + - 'The tracing spec (§8 gaps table) identifies that apr train and apr finetune have NO --profile or + --trace flags. Users must edit YAML config to enable StepProfiler. Add CLI flags: --profile (enable + StepProfiler), --profile-interval N (report every N steps), --trace (enable layer tracing for forward + pass). Wire to entrenar config.profile_interval.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - spec + - cli + - training + notes: null +- id: PMAT-487 + github_issue: null + item_type: task + title: 'SPEC-DIRTY: Commit pre-existing dirty files with fixes' + status: completed + priority: medium + assigned_to: null + created: 2026-03-31 16:24:03+00:00 + updated: 2026-03-31 16:59:03+00:00 + spec: null + acceptance_criteria: + - '11 pre-existing dirty files in working tree: distill.rs, finetune.rs, probar.rs, handlers.rs, train.rs, + error.rs, ssm/mod.rs, contract_traits.rs, build.rs, Cargo.lock, roadmap.yaml. Review each, fix any + issues, commit.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - cleanup + notes: null +- id: PMAT-488 + github_issue: null + item_type: task + title: 'SPEC-LAYER2-DISPATCH: Add apr backend select/list commands for Layer 2 GPU dispatch' + status: completed + priority: medium + assigned_to: null + created: 2026-03-31 16:24:15+00:00 + updated: 2026-03-31 16:59:03+00:00 + spec: null + acceptance_criteria: + - 'The compute-backends spec describes Layer 2 GPU dispatch (PTX vs cuBLAS vs cuBLASLt vs wgpu) but + there''s no CLI command to inspect or override which GPU path is active. Add: apr gpu info (show detected + backend, SM version, cuBLAS availability), wire existing --backend flag on serve to also work on run/chat.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - spec + - cli + - gpu + notes: null +- id: PMAT-489 + github_issue: null + item_type: task + title: 'BOOK: Add 7 missing chapters to SUMMARY.md' + status: completed + priority: medium + assigned_to: null + created: 2026-03-31 17:03:57+00:00 + updated: 2026-03-31 17:06:04+00:00 + spec: null + acceptance_criteria: + - '7 book chapters exist but are not listed in SUMMARY.md: logic-family-tree, mem-test-full, mem-test, + phi-hf-import, qwen-apr-native, qwen-chat, whisper-transcribe' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - docs + - book + notes: null +- id: PMAT-490 + github_issue: null + item_type: task + title: 'TEST: Un-ignore 5 time-based tests with fake clock' + status: completed + priority: medium + assigned_to: null + created: 2026-03-31 17:03:57+00:00 + updated: 2026-03-31 17:13:02+00:00 + spec: null + acceptance_criteria: + - '5 tests ignored because they use thread::sleep: test_time_budget, test_time_budget_elapsed_remaining, + test_cache_entry_is_valid_expired, test_cache_metadata_age, test_cache_metadata_expiration. Replace + thread::sleep with deterministic time injection.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - test + - quality + notes: null +- id: PMAT-491 + github_issue: null + item_type: task + title: 'TEST: Fix ignored ADMM consensus test' + status: completed + priority: low + assigned_to: null + created: 2026-03-31 17:03:57+00:00 + updated: 2026-03-31 17:18:48+00:00 + spec: null + acceptance_criteria: + - test_admm_box_constraints_via_consensus is ignored with note 'Consensus form for box constraints needs + algorithm refinement'. Investigate and fix the algorithm or remove the test. + phases: [] + subtasks: [] + estimated_effort: null + labels: + - test + - algorithm + notes: null +- id: PMAT-492 + github_issue: null + item_type: task + title: 'FIX: cargo install apr-cli — entrenar xa_t compile error' + status: completed + priority: high + assigned_to: null + created: 2026-03-31 17:36:57+00:00 + updated: 2026-03-31 17:37:05+00:00 + spec: null + acceptance_criteria: + - 'entrenar wgpu_pipeline.rs:655 referenced undefined variable xa_t in debug logging. Plus forward_hidden_gpu_then_cpu_lmhead + needed #[cfg(feature=cuda)]. Both blocked cargo install --path crates/apr-cli with training-gpu feature.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - fix + - install + - entrenar + notes: null +- id: PMAT-493 + github_issue: null + item_type: task + title: 'CONTRACT-GAP: Create 5 highest-priority missing YAML contracts for orphan annotations' + status: completed + priority: high + assigned_to: null + created: 2026-03-31 17:47:44+00:00 + updated: 2026-03-31 18:01:23+00:00 + spec: null + acceptance_criteria: + - '23 of 25 #[contract] annotations reference non-existent YAML files. Top 5 by impact: softmax-kernel-v1 + (EXISTS), rope-kernel-v1 (EXISTS), rmsnorm-kernel-v1, matmul-kernel-v1, cross-entropy-kernel-v1. Create + YAML contracts with equations, proof obligations, and falsification tests.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - contracts + - quality + notes: null +- id: PMAT-494 + github_issue: null + item_type: task + title: 'CONTRACT-GAP: Implement FALSIFY-BE-001..003 for compute-backend-equivalence' + status: completed + priority: high + assigned_to: null + created: 2026-03-31 17:47:44+00:00 + updated: 2026-03-31 18:01:23+00:00 + spec: null + acceptance_criteria: + - compute-backend-equivalence-v1.yaml defines 6 falsification tests (FALSIFY-BE-001..006) but zero are + implemented in Rust. Implement at least BE-001 (SIMD RMSNorm), BE-002 (wgpu forward), BE-003 (PTX + forward pre-Blackwell) as proptest-based tests. + phases: [] + subtasks: [] + estimated_effort: null + labels: + - contracts + - test + notes: null +- id: PMAT-495 + github_issue: null + item_type: task + title: 'CONTRACT-GAP: Implement FALSIFY-NORM-001..003 for normalization-kernel' + status: completed + priority: medium + assigned_to: null + created: 2026-03-31 17:47:44+00:00 + updated: 2026-03-31 20:33:16+00:00 + spec: null + acceptance_criteria: + - normalization-kernel-v1.yaml has 6 FALSIFY-NORM tests defined but zero implemented. Implement NORM-001 + (RMSNorm invariant sum), NORM-002 (LayerNorm zero-mean), NORM-003 (NaN propagation). + phases: [] + subtasks: [] + estimated_effort: null + labels: + - contracts + - test + notes: null +- id: PMAT-496 + github_issue: null + item_type: task + title: 'SF-002: Thread 7 sampling params through apr run dispatch chain' + status: completed + priority: critical + assigned_to: null + created: 2026-04-04 11:25:05+00:00 + updated: 2026-04-04 11:41:45.927792+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-497 + github_issue: null + item_type: task + title: 'APR-BOOK-001: Scaffold 20 chapter examples' + status: planned + priority: critical + assigned_to: null + created: 2026-04-08 08:04:17+00:00 + updated: 2026-04-08 08:04:25.947172+00:00 + spec: null + acceptance_criteria: + - Create examples/ch01_hello_apr.rs through examples/ch20_rag.rs. Each must compile, contain assert!(), + use only aprender-* namespace. + phases: [] + subtasks: [] + estimated_effort: null + labels: + - book + - examples + notes: null +- id: PMAT-498 + github_issue: null + item_type: task + title: 'APR-BOOK-002: Create 20 chapter contract YAMLs' + status: planned + priority: critical + assigned_to: null + created: 2026-04-08 08:04:19+00:00 + updated: 2026-04-08 08:22:21.049932+00:00 + spec: null + acceptance_criteria: + - Create contracts/apr-book-ch01-v1.yaml through contracts/apr-book-ch20-v1.yaml. Each with 5 falsification + conditions, P0 severity. + phases: [] + subtasks: [] + estimated_effort: null + labels: + - book + - contracts + notes: null +- id: PMAT-499 + github_issue: null + item_type: task + title: 'APR-BOOK-003: Create book_contracts integration test' + status: planned + priority: critical + assigned_to: null + created: 2026-04-08 08:04:21+00:00 + updated: 2026-04-08 08:04:21+00:00 + spec: null + acceptance_criteria: + - 'Create tests/book_contracts.rs: verifies all 20 examples exist, all 20 contracts exist, namespace + discipline (zero legacy names).' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - book + - tests + notes: null +- id: PMAT-500 + github_issue: null + item_type: task + title: 'APR-BOOK-004: Falsify all chapters end-to-end' + status: planned + priority: critical + assigned_to: null + created: 2026-04-08 08:04:23+00:00 + updated: 2026-04-08 08:24:24.512282+00:00 + spec: null + acceptance_criteria: + - Run cargo run --example for all 20 chapters, validate all contracts, run namespace grep gate, verify + oracle consultation. + phases: [] + subtasks: [] + estimated_effort: null + labels: + - book + - falsification + notes: null +- id: PMAT-501 + github_issue: null + item_type: task + title: 'APR-BOOK-005: Archive 6 SHOULD-MERGE repos with redirects' + status: planned + priority: critical + assigned_to: null + created: 2026-04-08 08:43:26+00:00 + updated: 2026-04-08 08:43:36.972348+00:00 + spec: null + acceptance_criteria: + - Archive alimentar, batuta-common, trueno-viz, trueno-zram, renacer, pacha with MOVED redirect descriptions + pointing to aprender monorepo crates. + phases: [] + subtasks: [] + estimated_effort: null + labels: + - book + - org-taxonomy + notes: null +- id: PMAT-502 + github_issue: null + item_type: task + title: 'APR-BOOK-006: Archive 24 STALE repos' + status: planned + priority: high + assigned_to: null + created: 2026-04-08 08:43:31+00:00 + updated: 2026-04-08 08:43:31+00:00 + spec: null + acceptance_criteria: + - Archive ds500-subscription-deleted, hello, hello-github, discord-bot, model-serving-survey, socialpower, + software-language-popularity-2025, osx-perf-tune, ubuntu-config-scripts, cost-optimize-aws, eu-currency, + dom-intelligence, labs-code, data, ropub, archived-emlop-book-material, Flask-Elastic-Beanstalk, awsbigdata, + pbjbi, apr-leaderboard, engman, faro, rurl, minimal-pyqt. + phases: [] + subtasks: [] + estimated_effort: null + labels: + - book + - org-taxonomy + notes: null +- id: PMAT-503 + github_issue: null + item_type: task + title: 'APR-BOOK-007: Tag all 205 repos with category topics' + status: planned + priority: medium + assigned_to: null + created: 2026-04-08 08:43:33+00:00 + updated: 2026-04-08 08:45:03.468719+00:00 + spec: null + acceptance_criteria: + - 'Add GitHub topics to all 205 paiml repos matching their category: monorepo, merged, active-tool, + model-training, poc-benchmark, course-demo, legacy-book, legacy-library, ground-truth, transpiler, + lang-ruchy, infra, platform, pmat, stale.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - book + - org-taxonomy + notes: null +- id: PMAT-504 + github_issue: null + item_type: task + title: 'APR-BOOK-008: Archive 18 LEGACY-LIBRARY repos' + status: planned + priority: high + assigned_to: null + created: 2026-04-08 08:53:20+00:00 + updated: 2026-04-08 08:53:28.767394+00:00 + spec: null + acceptance_criteria: + - Archive batuta-cookbook, batuta-ground-truth-mlops-corpus, forjar-cookbook, apr-cookbook, ald-cookbook, + prs-cookbook, apr-model-qa-playbook, reaper, rustysquid, mp4convertor, rclean, universal-bot, discord-intelligence, + ov, assetgen, assetsearch, pacha-run, wos. + phases: [] + subtasks: [] + estimated_effort: null + labels: + - book + - org-taxonomy + notes: null +- id: PMAT-505 + github_issue: null + item_type: task + title: 'APR-BOOK-009: Provable contracts for 21 ACTIVE-TOOL repos' + status: planned + priority: critical + assigned_to: null + created: 2026-04-08 08:53:22+00:00 + updated: 2026-04-08 08:54:18.361385+00:00 + spec: null + acceptance_criteria: + - 'Create contracts/apr-tool-{name}-v1.yaml for each ACTIVE-TOOL repo. Each contract defines: purpose, + inputs, outputs, 5 falsification conditions. Provable-contracts-first documentation.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - book + - contracts + notes: null +- id: PMAT-506 + github_issue: null + item_type: task + title: 'APR-BOOK-010: Provable contracts for 13 GROUND-TRUTH corpora' + status: planned + priority: high + assigned_to: null + created: 2026-04-08 08:53:24+00:00 + updated: 2026-04-08 08:54:59.641361+00:00 + spec: null + acceptance_criteria: + - 'Create contracts/apr-corpus-{name}-v1.yaml for each ground-truth corpus. Defines: domain, language, + file count, coverage target, freshness gate.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - book + - contracts + - ground-truth + notes: null +- id: PMAT-507 + github_issue: null + item_type: task + title: 'APR-BOOK-011: Convert 7 hollow examples to real API exercises' + status: planned + priority: critical + assigned_to: null + created: 2026-04-08 09:04:18+00:00 + updated: 2026-04-08 09:04:24.245970+00:00 + spec: null + acceptance_criteria: + - 'Provable-contract FIRST: update contract YAML with API-level falsification, THEN rewrite example + to use real aprender APIs. Order: ch16 (ARIMA), ch17 (Bayesian), ch18 (Graph), ch19 (Text), ch07 (ModelSelection), + ch10 (Training/Autograd), ch03 (Format). Each example must call fit/predict/transform — not just println.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - book + - examples + - provable-contracts + notes: null +- id: PMAT-508 + github_issue: null + item_type: task + title: 'APR-BOOK-012: Write Part I chapters (1-3) as markdown prose' + status: planned + priority: critical + assigned_to: null + created: 2026-04-08 10:58:08+00:00 + updated: 2026-04-08 10:58:11.421672+00:00 + spec: null + acceptance_criteria: + - 'Create docs/book/ch01.md, ch02.md, ch03.md. Each embeds example code, explains arXiv citations, shows + cargo run output. Provable-contract-first: contract defines what prose MUST cover.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - book + - chapters + - prose + notes: null +- id: PMAT-509 + github_issue: null + item_type: task + title: 'APR-BOOK-013: Provable-contract-only book schema — eliminate all muda' + status: planned + priority: critical + assigned_to: null + created: 2026-04-08 11:01:19+00:00 + updated: 2026-04-08 11:01:23.745921+00:00 + spec: null + acceptance_criteria: + - Redesign book so ZERO content exists without a contract. Every page = contract YAML + example + prose. + Pages without contracts are deleted. SUMMARY.md only lists contracted pages. Update spec with new + schema. + phases: [] + subtasks: [] + estimated_effort: null + labels: + - book + - schema + - contracts + - muda + notes: null +- id: PMAT-510 + github_issue: null + item_type: task + title: 'APR-BOOK-014: PCU contracts for 229 remaining pages — iterative falsification' + status: planned + priority: critical + assigned_to: null + created: 2026-04-08 11:08:15+00:00 + updated: 2026-04-08 11:08:18.946654+00:00 + spec: null + acceptance_criteria: + - 'For each page: 1) create contract YAML, 2) add PCU frontmatter, 3) run book-gate.sh, 4) update spec. + Start with examples/ (highest value), then ml-fundamentals/, then reference sections.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - book + - pcu + - contracts + - zero-muda + notes: null +- id: PMAT-511 + github_issue: null + item_type: task + title: 'APR-BOOK-015: POC benchmark chapters — contract-first vs candle/llama.cpp/ollama/vllm' + status: planned + priority: critical + assigned_to: null + created: 2026-04-08 11:50:13+00:00 + updated: 2026-04-08 11:50:18.376661+00:00 + spec: null + acceptance_criteria: + - 'Part VI: Benchmarks. Ch21 vs Candle (candle-vs-apr repo data), Ch22 vs llama.cpp, Ch23 Training: + pytorch/unsloth/cuBLAS (qwen-train-canary data). Contract YAML first, then examples, then book pages.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - book + - benchmarks + - poc + - contracts + notes: null +- id: PMAT-512 + github_issue: null + item_type: task + title: 'APR-BOOK-016: Switch-from chapters — PyTorch/Ollama/unsloth/ndarray migration guides' + status: planned + priority: critical + assigned_to: null + created: 2026-04-08 11:50:13+00:00 + updated: 2026-04-08 11:50:13+00:00 + spec: null + acceptance_criteria: + - 'Part VII: Switch From. Ch24 PyTorch, Ch25 Ollama, Ch26 ndarray/nalgebra/linfa, Ch27 unsloth. Each + with contract, cargo run --example, API equivalence tables.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - book + - migration + - switch-from + - contracts + notes: null +- id: PMAT-513 + github_issue: null + item_type: task + title: 'APR-BOOK-017: Close proof chain leaks L2-L7, add CI enforcement' + status: planned + priority: critical + assigned_to: null + created: 2026-04-08 12:45:03+00:00 + updated: 2026-04-08 12:45:08.841175+00:00 + spec: null + acceptance_criteria: + - 1) Upgrade book-gate.sh with G8-G12 for section cross-check, prose minimum, executable falsification, + arXiv validation. 2) Create .github/workflows/book-contracts.yml CI. 3) Update spec with leak findings. + 4) Falsify. + phases: [] + subtasks: [] + estimated_effort: null + labels: + - book + - leaks + - ci + - contracts + notes: null +- id: PMAT-514 + github_issue: null + item_type: task + title: 'APR-MCP-KAIZEN: Continuous drift sweep on apr-mcp-server-spec.md' + status: planned + priority: medium + assigned_to: null + created: 2026-04-18 13:33:02+00:00 + updated: 2026-04-18 13:33:05.351120+00:00 + spec: null + acceptance_criteria: + - Ongoing kaizen sweeps on docs/specifications/apr-mcp-server-spec.md + crates/aprender-mcp + book/src/tools/mcp-server.md + + contracts/apr-mcp-tool-schemas-v1.yaml. Each sweep fixes stale counts, stale roadmap tense (Mx→shipped), + stale tool descriptions, and cross-spec inconsistencies. + - 'DISCHARGED 2026-04-18: FALSIFY-MCP-008 extended to cover tool-level `description` at both the live-wiring + layer (`tool_descriptions_match_yaml_contract`) and the codegen-constant layer (`codegen_description_constants_match_yaml`); + build.rs now emits `APR__DESCRIPTION` alongside `APR__SCHEMA`. Neither field can be hand-edited + in Rust source.' + - 'DISCHARGED 2026-04-18: Spec §"Relationship to `apr code`" added — bidirectional MCP scope (consumer + + producer + future apr.code tool) + feature-flag caveat + 9-of-58 coverage table + Phase-2 priority + batch. Closes the gap where the spec treated Claude Code as an external-client-only concern and never + referenced the sibling `apr code` agent (PMAT-182).' + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-515 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-A-08 — Custom mirror / HF_ENDPOINT' + status: planned + priority: medium + assigned_to: null + created: 2026-04-18 14:44:17+00:00 + updated: 2026-04-18 14:44:17+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-A-08-v1.yaml | Competitor: huggingface | Demand: 3/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-A + - competitor-huggingface + - crux-a-08 + notes: null +- id: PMAT-516 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-A-10 — VRAM-aware quant auto-select' + status: planned + priority: high + assigned_to: null + created: 2026-04-18 14:44:17+00:00 + updated: 2026-04-18 14:44:17+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-A-10-v1.yaml | Competitor: ollama | Demand: 4/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-A + - competitor-ollama + - crux-a-10 + notes: null +- id: PMAT-517 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-A-11 — apr cp copy model with new tag' + status: planned + priority: medium + assigned_to: null + created: 2026-04-18 14:44:17+00:00 + updated: 2026-04-18 14:44:17+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-A-11-v1.yaml | Competitor: ollama | Demand: 3/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-A + - competitor-ollama + - crux-a-11 + notes: null +- id: PMAT-518 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-A-12 — apr ps list running models' + status: planned + priority: high + assigned_to: null + created: 2026-04-18 14:44:17+00:00 + updated: 2026-04-18 14:44:17+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-A-12-v1.yaml | Competitor: ollama | Demand: 4/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-A + - competitor-ollama + - crux-a-12 + notes: null +- id: PMAT-519 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-A-13 — apr stop unload model from VRAM' + status: planned + priority: high + assigned_to: null + created: 2026-04-18 14:44:17+00:00 + updated: 2026-04-18 14:44:17+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-A-13-v1.yaml | Competitor: ollama | Demand: 4/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-A + - competitor-ollama + - crux-a-13 + notes: null +- id: PMAT-520 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-A-14 — Pull from S3/GCS/Azure URL' + status: planned + priority: medium + assigned_to: null + created: 2026-04-18 14:44:17+00:00 + updated: 2026-04-18 14:44:17+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-A-14-v1.yaml | Competitor: ecosystem | Demand: 3/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-A + - competitor-ecosystem + - crux-a-14 + notes: null +- id: PMAT-MCP-PARITY-001 + github_issue: null + item_type: task + title: 'APR-MCP-PARITY: Expand aprender-mcp coverage from 9 → full 58-command apr surface' + status: planned + priority: high + assigned_to: null + created: 2026-04-18 15:00:00+00:00 + updated: 2026-04-18 15:00:00+00:00 + spec: docs/specifications/apr-mcp-server-spec.md + acceptance_criteria: + - 'Wave 1 (JSON-clean, model-triage analogues): add apr.inspect, apr.lint, apr.diff — all have existing + --json output and complement the M1-M3 apr.validate/apr.qa/apr.trace workflow-triage surface.' + - 'Wave 2 (format pipeline): apr.convert, apr.export, apr.import, apr.quantize — already JSON-clean; + needed for external agents doing model-format work remotely.' + - 'Wave 3 (model-management + analysis): apr.pull (download), apr.profile (roofline), apr.explain (nat-lang + description), apr.tokenize (debug tokenization).' + - 'Wave 4 (evaluation): apr.eval, apr.probar (behaviour-test pipeline).' + - 'Each wave: extend contracts/apr-mcp-tool-schemas-v1.yaml, update build.rs codegen coverage tests, + extend FALSIFY-MCP-008 CODEGEN_CONSTANTS + CODEGEN_DESCRIPTIONS arrays, add integration tests mirroring + each tool.' + - Interactive-only commands (apr chat, apr tui, apr cbtop, apr monitor) and meta-commands (apr mcp itself) + are EXPLICITLY out of scope — MCP tools must be one-shot request/response. + - 'Falsification gate FALSIFY-MCP-COVERAGE-001: `apr-cli-commands-v1.yaml` commands with `side_effects: + none` OR `category: readonly`/`analysis` MUST appear in the MCP tool set or be explicitly listed as + deferred — enforced by a new test that diffs the two contracts.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - mcp + - parity + - claude-code + notes: null +- id: PMAT-CODE-MCP-CLIENT-001 + github_issue: null + item_type: task + title: 'APR-CODE-MCP-CLIENT: Wire apr code to load external MCP servers via .mcp.json' + status: planned + priority: high + assigned_to: null + created: 2026-04-18 15:00:00+00:00 + updated: 2026-04-18 15:00:00+00:00 + spec: docs/specifications/aprender-orchestrate/components/apr-code.md + acceptance_criteria: + - Add .mcp.json loader at `$CWD/.mcp.json` and `~/.config/apr/mcp.json` — mirrors Claude Code / Cursor + / Cline precedence. Existing TOML AgentManifest.mcp_servers path remains supported. + - Wire `register_mcp_tools` (today in crates/aprender-orchestrate/src/cli/agent_helpers.rs:219, feature-gated + behind `agents-mcp`) into `build_code_tools` at crates/aprender-orchestrate/src/agent/code.rs:360. + Today the call site is missing — external MCP servers declared in manifest are silently ignored by + `apr code`. + - 'Falsification: spawn a stdio MCP server (e.g. the aprender-mcp binary itself), declare it in `.mcp.json`, + launch `apr code --print`, prompt it to call one of the exposed tools (e.g. apr.version), assert the + tool appears in agent logs and the returned content is in the final transcript.' + - 'Privacy-tier guard: Sovereign tier must allow only stdio transport (McpTransport::Stdio); SSE/HTTP + rejected with user-visible error. Existing PrivacyTier logic in mcp_client.rs already expresses this + — verify at wire-up.' + - 'Feature flag: keep behind `agents-mcp`. No changes to default install story (apr code only appears + with `--features code`).' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - mcp + - parity + - claude-code + - apr-code + notes: null +- id: PMAT-CLAUDE-PROXY-001 + github_issue: null + item_type: feature + title: 'APR-CLAUDE-PROXY: `apr serve anthropic` — sovereign Messages-API drop-in backed by apr code + + Qwen3-MoE' + status: planned + priority: high + assigned_to: null + created: 2026-04-18 16:00:00+00:00 + updated: 2026-04-18 16:00:00+00:00 + spec: docs/specifications/apr-mcp-server-spec.md + acceptance_criteria: + - 'Contract committed: contracts/apr-claude-proxy-v1.yaml (DRAFT → ENFORCED when all 6 gates PASS).' + - 'Spec section committed: docs/specifications/apr-mcp-server-spec.md § "Claude Messages-API Provable-Contract + Proxy (PLANNED M6)".' + - 'Default-model resolver implements the fallback chain: unsloth/Qwen3-Coder-30B-A3B-Instruct-GGUF:Q4_K_M + → Qwen/Qwen3-30B-A3B-GGUF:Q4_K_M → APR_CODE_MODEL env → manifest.default_model.' + - 'HTTP surface lives in `crates/aprender-serve/src/anthropic/` (new module). CLI entry: `apr serve + anthropic` — new `ServeCommands::Anthropic` variant in `crates/apr-cli/src/serve_commands.rs` alongside + existing `Plan` and `Run`.' + - FALSIFY-CLAUDE-PROXY-001..006 all ENFORCED before promotion from PLANNED → ACTIVE (see contract for + details). + - 'Sovereignty gate (FALSIFY-CLAUDE-PROXY-006): zero outbound sockets to api.anthropic.com under any + combination of headers/env/config. Asserted by network-sandboxed CI container.' + - Translation semantics are a pure function of (request_body, resolved_model, server_config) — no client-identity + leakage, property-tested round-trip via `apr serve anthropic --dump-translation`. + - 'Streaming (SSE) event sequence validates against Anthropic v2026-02-01 schedule: message_start → + (content_block_start → N × content_block_delta → content_block_stop)⁺ → message_delta → message_stop.' + phases: + - name: Request-shape parser + status: planned + estimated_effort: null + completion: 0 + - name: Non-streaming response generation + status: planned + estimated_effort: null + completion: 0 + - name: SSE streaming + status: planned + estimated_effort: null + completion: 0 + - name: Default-model autoselect + sovereignty + status: planned + estimated_effort: null + completion: 0 + subtasks: [] + estimated_effort: null + labels: + - mcp + - parity + - claude-code + - apr-code + - anthropic + - sovereign + notes: 'Sibling to PMAT-MCP-PARITY-001 (MCP server surface) and PMAT-CODE-MCP- CLIENT-001 (apr code + MCP-client wiring). The three together close the triangle of Claude-Code parity: (1) apr mcp exposes + apr as MCP tools; (2) apr code consumes external MCP servers; (3) apr serve --compat anthropic exposes + the full agent loop via Anthropic''s Messages API. PMAT-CLAUDE-PROXY-001 unlocks the largest category + of IDE integrations (everything speaking `anthropic-sdk-*`) without any MCP dependency. + + ' +- id: PMAT-CODE-PARITY-MATRIX-001 + github_issue: null + item_type: epic + title: 'APR-CODE-PARITY: close the 20-feature gap vs Claude Code surfaced by the 2026-04-18 audit' + status: planned + priority: high + assigned_to: null + created: 2026-04-18 17:00:00+00:00 + updated: 2026-04-18 17:00:00+00:00 + spec: docs/specifications/apr-mcp-server-spec.md + acceptance_criteria: + - P0 tickets (PMAT-CODE-{MCP-CLIENT,SLASH-PARITY,HOOKS,SPAWN-PARITY}-001) each promote from planned + to in-progress with first acceptance criterion landed. + - Audit re-runs after P0 completion (via the six pmat query / grep cross-checks listed in the spec matrix) + and each of the four P0 rows flips from PARTIAL/NONE to SHIPPED with updated evidence path. + - Headline count rebalances from 5/7/8 to at minimum 9/7/4 before this epic closes. + phases: [] + subtasks: [] + estimated_effort: null + labels: + - apr-code + - parity + - claude-code + - epic + notes: 'The matrix is falsifiable, not aspirational — every row cites a specific file path or a specific + zero-hit grep, and can be re-run to verify the gap has closed. This is the key advantage of the audit + approach: parity progress is mechanically checkable, not "does it feel like Claude Code". Re-run the + six falsification cross-checks listed at the bottom of the spec matrix section after each ticket closes. + + ' +- id: PMAT-521 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-A-16 — Modelfile recipe custom system prompt' + status: planned + priority: high + assigned_to: null + created: 2026-04-18 14:44:17+00:00 + updated: 2026-04-18 14:44:17+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-A-16-v1.yaml | Competitor: ollama | Demand: 4/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-A + - competitor-ollama + - crux-a-16 + notes: null +- id: PMAT-522 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-A-17 — Manifest signing cosign/sigstore' + status: planned + priority: low + assigned_to: null + created: 2026-04-18 14:44:17+00:00 + updated: 2026-04-18 14:44:17+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-A-17-v1.yaml | Competitor: ecosystem | Demand: 2/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-A + - competitor-ecosystem + - crux-a-17 + notes: null +- id: PMAT-523 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-A-21 — Shared model cache across users' + status: planned + priority: medium + assigned_to: null + created: 2026-04-18 14:44:17+00:00 + updated: 2026-04-18 14:44:17+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-A-21-v1.yaml | Competitor: ollama | Demand: 3/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-A + - competitor-ollama + - crux-a-21 + notes: null +- id: PMAT-524 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-A-22 — Disk-quota enforcement on registry' + status: planned + priority: low + assigned_to: null + created: 2026-04-18 14:44:17+00:00 + updated: 2026-04-18 14:44:17+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-A-22-v1.yaml | Competitor: ollama | Demand: 2/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-A + - competitor-ollama + - crux-a-22 + notes: null +- id: PMAT-525 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-A-23 — Model search Hub + local cache' + status: planned + priority: medium + assigned_to: null + created: 2026-04-18 14:44:17+00:00 + updated: 2026-04-18 14:44:17+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-A-23-v1.yaml | Competitor: huggingface | Demand: 3/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-A + - competitor-huggingface + - crux-a-23 + notes: null +- id: PMAT-526 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-A-25 — Garbage-collect unused models' + status: planned + priority: medium + assigned_to: null + created: 2026-04-18 14:44:17+00:00 + updated: 2026-04-18 14:44:17+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-A-25-v1.yaml | Competitor: ollama | Demand: 3/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-A + - competitor-ollama + - crux-a-25 + notes: null +- id: PMAT-527 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-B-02 — GGUF → Safetensors for PEFT' + status: planned + priority: high + assigned_to: null + created: 2026-04-18 14:44:17+00:00 + updated: 2026-04-18 14:44:17+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-B-02-v1.yaml | Competitor: llama_cpp | Demand: 4/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-B + - competitor-llama_cpp + - crux-b-02 + notes: null +- id: PMAT-528 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-B-07 — imatrix calibration' + status: planned + priority: critical + assigned_to: null + created: 2026-04-18 14:44:17+00:00 + updated: 2026-04-18 14:44:17+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-B-07-v1.yaml | Competitor: llama_cpp | Demand: 5/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-B + - competitor-llama_cpp + - crux-b-07 + notes: null +- id: PMAT-529 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-B-08 — AWQ quantization' + status: planned + priority: critical + assigned_to: null + created: 2026-04-18 14:44:17+00:00 + updated: 2026-04-18 14:44:17+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-B-08-v1.yaml | Competitor: vllm | Demand: 5/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-B + - competitor-vllm + - crux-b-08 + notes: null +- id: PMAT-530 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-B-09 — GPTQ quantization' + status: planned + priority: critical + assigned_to: null + created: 2026-04-18 14:44:17+00:00 + updated: 2026-04-18 14:44:17+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-B-09-v1.yaml | Competitor: vllm | Demand: 5/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-B + - competitor-vllm + - crux-b-09 + notes: null +- id: PMAT-531 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-B-10 — BitsAndBytes NF4 4-bit' + status: planned + priority: high + assigned_to: null + created: 2026-04-18 14:44:17+00:00 + updated: 2026-04-18 14:44:17+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-B-10-v1.yaml | Competitor: huggingface | Demand: 4/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-B + - competitor-huggingface + - crux-b-10 + notes: null +- id: PMAT-532 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-B-11 — FP8 quantization H100+' + status: planned + priority: medium + assigned_to: null + created: 2026-04-18 14:44:17+00:00 + updated: 2026-04-18 14:44:17+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-B-11-v1.yaml | Competitor: vllm | Demand: 3/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-B + - competitor-vllm + - crux-b-11 + notes: null +- id: PMAT-533 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-B-15 — IQ-quants IQ3_XXS / IQ2_S' + status: planned + priority: medium + assigned_to: null + created: 2026-04-18 14:44:17+00:00 + updated: 2026-04-18 14:44:17+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-B-15-v1.yaml | Competitor: llama_cpp | Demand: 3/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-B + - competitor-llama_cpp + - crux-b-15 + notes: null +- id: PMAT-534 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-B-16 — Per-tensor layer-quant override' + status: planned + priority: medium + assigned_to: null + created: 2026-04-18 14:44:17+00:00 + updated: 2026-04-18 14:44:17+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-B-16-v1.yaml | Competitor: llama_cpp | Demand: 3/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-B + - competitor-llama_cpp + - crux-b-16 + notes: null +- id: PMAT-535 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-B-17 — Quantization-aware training (QAT)' + status: planned + priority: low + assigned_to: null + created: 2026-04-18 14:44:17+00:00 + updated: 2026-04-18 14:44:17+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-B-17-v1.yaml | Competitor: pytorch | Demand: 2/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-B + - competitor-pytorch + - crux-b-17 + notes: null +- id: PMAT-536 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-B-18 — Calibration dataset loader' + status: planned + priority: high + assigned_to: null + created: 2026-04-18 14:44:17+00:00 + updated: 2026-04-18 14:44:17+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-B-18-v1.yaml | Competitor: llama_cpp | Demand: 4/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-B + - competitor-llama_cpp + - crux-b-18 + notes: null +- id: PMAT-537 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-C-04 — Ollama /api/chat' + status: planned + priority: critical + assigned_to: null + created: 2026-04-18 14:44:17+00:00 + updated: 2026-04-18 14:44:17+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-C-04-v1.yaml | Competitor: ollama | Demand: 5/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-C + - competitor-ollama + - crux-c-04 + notes: null +- id: PMAT-538 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-C-09 — Speculative decoding draft model' + status: planned + priority: high + assigned_to: null + created: 2026-04-18 14:44:17+00:00 + updated: 2026-04-18 14:44:17+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-C-09-v1.yaml | Competitor: vllm | Demand: 4/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-C + - competitor-vllm + - crux-c-09 + notes: null +- id: PMAT-539 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-C-11 — OpenAI tool-use function calling' + status: planned + priority: critical + assigned_to: null + created: 2026-04-18 14:44:17+00:00 + updated: 2026-04-18 14:44:17+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-C-11-v1.yaml | Competitor: vllm | Demand: 5/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-C + - competitor-vllm + - crux-c-11 + notes: null +- id: PMAT-540 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-C-12 — Multi-modal vision input LLaVA' + status: planned + priority: high + assigned_to: null + created: 2026-04-18 14:44:17+00:00 + updated: 2026-04-18 14:44:17+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-C-12-v1.yaml | Competitor: llama_cpp | Demand: 4/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-C + - competitor-llama_cpp + - crux-c-12 + notes: null +- id: PMAT-541 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-C-13 — /v1/embeddings endpoint' + status: planned + priority: critical + assigned_to: null + created: 2026-04-18 14:44:17+00:00 + updated: 2026-04-18 14:44:17+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-C-13-v1.yaml | Competitor: llama_cpp | Demand: 5/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-C + - competitor-llama_cpp + - crux-c-13 + notes: null +- id: PMAT-542 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-C-15 — Tensor + pipeline parallelism' + status: planned + priority: high + assigned_to: null + created: 2026-04-18 14:44:17+00:00 + updated: 2026-04-18 14:44:17+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-C-15-v1.yaml | Competitor: vllm | Demand: 4/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-C + - competitor-vllm + - crux-c-15 + notes: null +- id: PMAT-543 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-C-16 — LoRA hotswap at runtime' + status: planned + priority: high + assigned_to: null + created: 2026-04-18 14:44:17+00:00 + updated: 2026-04-18 14:44:17+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-C-16-v1.yaml | Competitor: vllm | Demand: 4/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-C + - competitor-vllm + - crux-c-16 + notes: null +- id: PMAT-544 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-C-17 — Multi-LoRA serving N adapters' + status: planned + priority: high + assigned_to: null + created: 2026-04-18 14:44:17+00:00 + updated: 2026-04-18 14:44:17+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-C-17-v1.yaml | Competitor: vllm | Demand: 4/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-C + - competitor-vllm + - crux-c-17 + notes: null +- id: PMAT-545 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-C-21 — Mirostat sampling' + status: planned + priority: medium + assigned_to: null + created: 2026-04-18 14:44:18+00:00 + updated: 2026-04-18 14:44:18+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-C-21-v1.yaml | Competitor: llama_cpp | Demand: 3/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-C + - competitor-llama_cpp + - crux-c-21 + notes: null +- id: PMAT-546 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-C-22 — Typical sampling' + status: planned + priority: medium + assigned_to: null + created: 2026-04-18 14:44:18+00:00 + updated: 2026-04-18 14:44:18+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-C-22-v1.yaml | Competitor: llama_cpp | Demand: 3/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-C + - competitor-llama_cpp + - crux-c-22 + notes: null +- id: PMAT-547 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-C-23 — DRY sampling' + status: planned + priority: medium + assigned_to: null + created: 2026-04-18 14:44:18+00:00 + updated: 2026-04-18 14:44:18+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-C-23-v1.yaml | Competitor: llama_cpp | Demand: 3/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-C + - competitor-llama_cpp + - crux-c-23 + notes: null +- id: PMAT-548 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-C-24 — Beam search decoding' + status: planned + priority: medium + assigned_to: null + created: 2026-04-18 14:44:18+00:00 + updated: 2026-04-18 14:44:18+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-C-24-v1.yaml | Competitor: pytorch | Demand: 3/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-C + - competitor-pytorch + - crux-c-24 + notes: null +- id: PMAT-549 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-C-29 — NUMA-aware memory placement' + status: planned + priority: medium + assigned_to: null + created: 2026-04-18 14:44:18+00:00 + updated: 2026-04-18 14:44:18+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-C-29-v1.yaml | Competitor: llama_cpp | Demand: 3/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-C + - competitor-llama_cpp + - crux-c-29 + notes: null +- id: PMAT-550 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-C-30 — KV cache quantization Q8_0/Q4_0' + status: planned + priority: high + assigned_to: null + created: 2026-04-18 14:44:18+00:00 + updated: 2026-04-18 14:44:18+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-C-30-v1.yaml | Competitor: llama_cpp | Demand: 4/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-C + - competitor-llama_cpp + - crux-c-30 + notes: null +- id: PMAT-551 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-D-03 — QLoRA 4-bit + LoRA' + status: planned + priority: critical + assigned_to: null + created: 2026-04-18 14:44:18+00:00 + updated: 2026-04-18 14:44:18+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-D-03-v1.yaml | Competitor: huggingface | Demand: 5/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-D + - competitor-huggingface + - crux-d-03 + notes: null +- id: PMAT-552 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-D-04 — DPO preference training' + status: planned + priority: critical + assigned_to: null + created: 2026-04-18 14:44:18+00:00 + updated: 2026-04-18 14:44:18+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-D-04-v1.yaml | Competitor: huggingface | Demand: 5/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-D + - competitor-huggingface + - crux-d-04 + notes: null +- id: PMAT-553 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-D-11 — DDP multi-GPU single node' + status: planned + priority: critical + assigned_to: null + created: 2026-04-18 14:44:18+00:00 + updated: 2026-04-18 14:44:18+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-D-11-v1.yaml | Competitor: pytorch | Demand: 5/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-D + - competitor-pytorch + - crux-d-11 + notes: null +- id: PMAT-554 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-D-12 — FSDP / ZeRO sharding' + status: planned + priority: critical + assigned_to: null + created: 2026-04-18 14:44:18+00:00 + updated: 2026-04-18 14:44:18+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-D-12-v1.yaml | Competitor: pytorch | Demand: 5/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-D + - competitor-pytorch + - crux-d-12 + notes: null +- id: PMAT-555 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-D-17 — ORPO / KTO / IPO alignment' + status: planned + priority: medium + assigned_to: null + created: 2026-04-18 14:44:18+00:00 + updated: 2026-04-18 14:44:18+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-D-17-v1.yaml | Competitor: huggingface | Demand: 3/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-D + - competitor-huggingface + - crux-d-17 + notes: null +- id: PMAT-556 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-D-18 — Reward-model training' + status: planned + priority: medium + assigned_to: null + created: 2026-04-18 14:44:18+00:00 + updated: 2026-04-18 14:44:18+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-D-18-v1.yaml | Competitor: huggingface | Demand: 3/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-D + - competitor-huggingface + - crux-d-18 + notes: null +- id: PMAT-557 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-D-19 — PPO reinforcement learning' + status: planned + priority: medium + assigned_to: null + created: 2026-04-18 14:44:18+00:00 + updated: 2026-04-18 14:44:18+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-D-19-v1.yaml | Competitor: huggingface | Demand: 3/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-D + - competitor-huggingface + - crux-d-19 + notes: null +- id: PMAT-558 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-D-20 — RoPE frequency scaling during SFT' + status: planned + priority: medium + assigned_to: null + created: 2026-04-18 14:44:18+00:00 + updated: 2026-04-18 14:44:18+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-D-20-v1.yaml | Competitor: huggingface | Demand: 3/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-D + - competitor-huggingface + - crux-d-20 + notes: null +- id: PMAT-559 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-D-24 — Activation checkpointing tags' + status: planned + priority: medium + assigned_to: null + created: 2026-04-18 14:44:18+00:00 + updated: 2026-04-18 14:44:18+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-D-24-v1.yaml | Competitor: pytorch | Demand: 3/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-D + - competitor-pytorch + - crux-d-24 + notes: null +- id: PMAT-560 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-D-26 — LR finder range test' + status: planned + priority: medium + assigned_to: null + created: 2026-04-18 14:44:18+00:00 + updated: 2026-04-18 14:44:18+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-D-26-v1.yaml | Competitor: pytorch | Demand: 3/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-D + - competitor-pytorch + - crux-d-26 + notes: null +- id: PMAT-561 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-D-27 — Hyperparameter sweep ray/optuna' + status: planned + priority: medium + assigned_to: null + created: 2026-04-18 14:44:18+00:00 + updated: 2026-04-18 14:44:18+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-D-27-v1.yaml | Competitor: pytorch | Demand: 3/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-D + - competitor-pytorch + - crux-d-27 + notes: null +- id: PMAT-562 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-D-28 — Adapter fusion combine N LoRAs' + status: planned + priority: medium + assigned_to: null + created: 2026-04-18 14:44:18+00:00 + updated: 2026-04-18 14:44:18+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-D-28-v1.yaml | Competitor: huggingface | Demand: 3/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-D + - competitor-huggingface + - crux-d-28 + notes: null +- id: PMAT-563 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-D-29 — Pre-compiled dataset cache' + status: planned + priority: medium + assigned_to: null + created: 2026-04-18 14:44:18+00:00 + updated: 2026-04-18 14:44:18+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-D-29-v1.yaml | Competitor: huggingface | Demand: 3/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-D + - competitor-huggingface + - crux-d-29 + notes: null +- id: PMAT-564 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-D-30 — Multi-task training loop' + status: planned + priority: medium + assigned_to: null + created: 2026-04-18 14:44:18+00:00 + updated: 2026-04-18 14:44:18+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-D-30-v1.yaml | Competitor: huggingface | Demand: 3/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-D + - competitor-huggingface + - crux-d-30 + notes: null +- id: PMAT-565 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-D-31 — TensorBoard / wandb integration' + status: planned + priority: high + assigned_to: null + created: 2026-04-18 14:44:18+00:00 + updated: 2026-04-18 14:44:18+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-D-31-v1.yaml | Competitor: pytorch | Demand: 4/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-D + - competitor-pytorch + - crux-d-31 + notes: null +- id: PMAT-566 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-D-33 — Distributed optimizer ZeRO-1' + status: planned + priority: high + assigned_to: null + created: 2026-04-18 14:44:18+00:00 + updated: 2026-04-18 14:44:18+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-D-33-v1.yaml | Competitor: pytorch | Demand: 4/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-D + - competitor-pytorch + - crux-d-33 + notes: null +- id: PMAT-567 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-D-34 — Deepspeed config loader' + status: planned + priority: medium + assigned_to: null + created: 2026-04-18 14:44:18+00:00 + updated: 2026-04-18 14:44:18+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-D-34-v1.yaml | Competitor: huggingface | Demand: 3/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-D + - competitor-huggingface + - crux-d-34 + notes: null +- id: PMAT-568 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-D-35 — accelerate launch wrapper' + status: planned + priority: high + assigned_to: null + created: 2026-04-18 14:44:18+00:00 + updated: 2026-04-18 14:44:18+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-D-35-v1.yaml | Competitor: huggingface | Demand: 4/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-D + - competitor-huggingface + - crux-d-35 + notes: null +- id: PMAT-569 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-E-02 — Perplexity on held-out corpus' + status: planned + priority: critical + assigned_to: null + created: 2026-04-18 14:44:18+00:00 + updated: 2026-04-18 14:44:18+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-E-02-v1.yaml | Competitor: llama_cpp | Demand: 5/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-E + - competitor-llama_cpp + - crux-e-02 + notes: null +- id: PMAT-570 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-E-03 — lm-eval-harness tasks' + status: planned + priority: critical + assigned_to: null + created: 2026-04-18 14:44:18+00:00 + updated: 2026-04-18 14:44:18+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-E-03-v1.yaml | Competitor: huggingface | Demand: 5/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-E + - competitor-huggingface + - crux-e-03 + notes: null +- id: PMAT-571 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-E-07 — Latency P50/P95/P99 under load' + status: planned + priority: critical + assigned_to: null + created: 2026-04-18 14:44:18+00:00 + updated: 2026-04-18 14:44:18+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-E-07-v1.yaml | Competitor: vllm | Demand: 5/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-E + - competitor-vllm + - crux-e-07 + notes: null +- id: PMAT-572 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-E-10 — Hallucination / drift detector' + status: planned + priority: medium + assigned_to: null + created: 2026-04-18 14:44:18+00:00 + updated: 2026-04-18 14:44:18+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-E-10-v1.yaml | Competitor: huggingface | Demand: 3/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-E + - competitor-huggingface + - crux-e-10 + notes: null +- id: PMAT-573 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-E-11 — MT-Bench / arena judge eval' + status: planned + priority: high + assigned_to: null + created: 2026-04-18 14:44:18+00:00 + updated: 2026-04-18 14:44:18+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-E-11-v1.yaml | Competitor: huggingface | Demand: 4/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-E + - competitor-huggingface + - crux-e-11 + notes: null +- id: PMAT-574 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-E-12 — BBH/MMLU/HellaSwag per-task' + status: planned + priority: high + assigned_to: null + created: 2026-04-18 14:44:18+00:00 + updated: 2026-04-18 14:44:18+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-E-12-v1.yaml | Competitor: huggingface | Demand: 4/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-E + - competitor-huggingface + - crux-e-12 + notes: null +- id: PMAT-575 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-E-13 — RULER long-context eval' + status: planned + priority: medium + assigned_to: null + created: 2026-04-18 14:44:18+00:00 + updated: 2026-04-18 14:44:18+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-E-13-v1.yaml | Competitor: huggingface | Demand: 3/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-E + - competitor-huggingface + - crux-e-13 + notes: null +- id: PMAT-576 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-E-14 — Needle-in-haystack recall' + status: planned + priority: high + assigned_to: null + created: 2026-04-18 14:44:18+00:00 + updated: 2026-04-18 14:44:18+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-E-14-v1.yaml | Competitor: vllm | Demand: 4/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-E + - competitor-vllm + - crux-e-14 + notes: null +- id: PMAT-577 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-E-19 — Perplexity per quant bit-budget' + status: planned + priority: high + assigned_to: null + created: 2026-04-18 14:44:18+00:00 + updated: 2026-04-18 14:44:18+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-E-19-v1.yaml | Competitor: llama_cpp | Demand: 4/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-E + - competitor-llama_cpp + - crux-e-19 + notes: null +- id: PMAT-578 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-E-20 — KL divergence vs FP16 baseline' + status: planned + priority: high + assigned_to: null + created: 2026-04-18 14:44:18+00:00 + updated: 2026-04-18 14:44:18+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-E-20-v1.yaml | Competitor: llama_cpp | Demand: 4/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-E + - competitor-llama_cpp + - crux-e-20 + notes: null +- id: PMAT-579 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-E-21 — Bias/toxicity eval harness' + status: planned + priority: medium + assigned_to: null + created: 2026-04-18 14:44:18+00:00 + updated: 2026-04-18 14:44:18+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-E-21-v1.yaml | Competitor: huggingface | Demand: 3/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-E + - competitor-huggingface + - crux-e-21 + notes: null +- id: PMAT-580 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-E-22 — Code-eval sandbox Docker runner' + status: planned + priority: high + assigned_to: null + created: 2026-04-18 14:44:18+00:00 + updated: 2026-04-18 14:44:18+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-E-22-v1.yaml | Competitor: huggingface | Demand: 4/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-E + - competitor-huggingface + - crux-e-22 + notes: null +- id: PMAT-581 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-E-23 — Tool-use benchmark BFCL' + status: planned + priority: medium + assigned_to: null + created: 2026-04-18 14:44:18+00:00 + updated: 2026-04-18 14:44:18+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-E-23-v1.yaml | Competitor: ecosystem | Demand: 3/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-E + - competitor-ecosystem + - crux-e-23 + notes: null +- id: PMAT-582 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-E-24 — RAG eval RAGAS/TruLens' + status: planned + priority: medium + assigned_to: null + created: 2026-04-18 14:44:18+00:00 + updated: 2026-04-18 14:44:18+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-E-24-v1.yaml | Competitor: ecosystem | Demand: 3/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-E + - competitor-ecosystem + - crux-e-24 + notes: null +- id: PMAT-583 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-E-25 — Vision-language benchmark harness' + status: planned + priority: low + assigned_to: null + created: 2026-04-18 14:44:18+00:00 + updated: 2026-04-18 14:44:18+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-E-25-v1.yaml | Competitor: openclip | Demand: 2/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-E + - competitor-openclip + - crux-e-25 + notes: null +- id: PMAT-584 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-F-06 — KV-cache utilization timeline' + status: planned + priority: high + assigned_to: null + created: 2026-04-18 14:44:18+00:00 + updated: 2026-04-18 14:44:18+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-F-06-v1.yaml | Competitor: vllm | Demand: 4/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-F + - competitor-vllm + - crux-f-06 + notes: null +- id: PMAT-585 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-F-07 — GPU memory timeline Chrome trace' + status: planned + priority: high + assigned_to: null + created: 2026-04-18 14:44:18+00:00 + updated: 2026-04-18 14:44:18+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-F-07-v1.yaml | Competitor: pytorch | Demand: 4/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-F + - competitor-pytorch + - crux-f-07 + notes: null +- id: PMAT-586 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-F-09 — Gradient-norm telemetry per step' + status: planned + priority: critical + assigned_to: null + created: 2026-04-18 14:44:18+00:00 + updated: 2026-04-18 14:44:18+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-F-09-v1.yaml | Competitor: pytorch | Demand: 5/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-F + - competitor-pytorch + - crux-f-09 + notes: null +- id: PMAT-587 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-F-11 — NaN/Inf detector in activations' + status: planned + priority: high + assigned_to: null + created: 2026-04-18 14:44:18+00:00 + updated: 2026-04-18 14:44:18+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-F-11-v1.yaml | Competitor: pytorch | Demand: 4/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-F + - competitor-pytorch + - crux-f-11 + notes: null +- id: PMAT-588 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-F-13 — CUDA OOM postmortem report' + status: planned + priority: critical + assigned_to: null + created: 2026-04-18 14:44:18+00:00 + updated: 2026-04-18 14:44:18+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-F-13-v1.yaml | Competitor: pytorch | Demand: 5/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-F + - competitor-pytorch + - crux-f-13 + notes: null +- id: PMAT-589 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-F-14 — Deadlock/hang detector stack dump' + status: planned + priority: medium + assigned_to: null + created: 2026-04-18 14:44:18+00:00 + updated: 2026-04-18 14:44:18+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-F-14-v1.yaml | Competitor: pytorch | Demand: 3/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-F + - competitor-pytorch + - crux-f-14 + notes: null +- id: PMAT-590 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-F-15 — NCCL failure diagnostics' + status: planned + priority: medium + assigned_to: null + created: 2026-04-18 14:44:19+00:00 + updated: 2026-04-18 14:44:19+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-F-15-v1.yaml | Competitor: pytorch | Demand: 3/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-F + - competitor-pytorch + - crux-f-15 + notes: null +- id: PMAT-591 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-F-17 — Attention pattern visualization' + status: planned + priority: medium + assigned_to: null + created: 2026-04-18 14:44:19+00:00 + updated: 2026-04-18 14:44:19+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-F-17-v1.yaml | Competitor: pytorch | Demand: 3/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-F + - competitor-pytorch + - crux-f-17 + notes: null +- id: PMAT-592 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-F-18 — Token embedding UMAP 2D' + status: planned + priority: low + assigned_to: null + created: 2026-04-18 14:44:19+00:00 + updated: 2026-04-18 14:44:19+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-F-18-v1.yaml | Competitor: pytorch | Demand: 2/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-F + - competitor-pytorch + - crux-f-18 + notes: null +- id: PMAT-593 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-F-19 — apr explain token selection' + status: planned + priority: medium + assigned_to: null + created: 2026-04-18 14:44:19+00:00 + updated: 2026-04-18 14:44:19+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-F-19-v1.yaml | Competitor: llama_cpp | Demand: 3/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-F + - competitor-llama_cpp + - crux-f-19 + notes: null +- id: PMAT-594 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-G-04 — Auto-generate README with examples' + status: planned + priority: medium + assigned_to: null + created: 2026-04-18 14:44:19+00:00 + updated: 2026-04-18 14:44:19+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-G-04-v1.yaml | Competitor: huggingface | Demand: 3/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-G + - competitor-huggingface + - crux-g-04 + notes: null +- id: PMAT-595 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-G-07 — SemVer tag on apr publish' + status: planned + priority: medium + assigned_to: null + created: 2026-04-18 14:44:19+00:00 + updated: 2026-04-18 14:44:19+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-G-07-v1.yaml | Competitor: huggingface | Demand: 3/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-G + - competitor-huggingface + - crux-g-07 + notes: null +- id: PMAT-596 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-G-11 — Ollama push to remote registry' + status: planned + priority: high + assigned_to: null + created: 2026-04-18 14:44:19+00:00 + updated: 2026-04-18 14:44:19+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-G-11-v1.yaml | Competitor: ollama | Demand: 4/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-G + - competitor-ollama + - crux-g-11 + notes: null +- id: PMAT-597 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-G-14 — License metadata validator' + status: planned + priority: medium + assigned_to: null + created: 2026-04-18 14:44:19+00:00 + updated: 2026-04-18 14:44:19+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-G-14-v1.yaml | Competitor: huggingface | Demand: 3/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-G + - competitor-huggingface + - crux-g-14 + notes: null +- id: PMAT-598 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-G-15 — Duplicate-artifact detector pre-push' + status: planned + priority: medium + assigned_to: null + created: 2026-04-18 14:44:19+00:00 + updated: 2026-04-18 14:44:19+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-G-15-v1.yaml | Competitor: huggingface | Demand: 3/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-G + - competitor-huggingface + - crux-g-15 + notes: null +- id: PMAT-599 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-H-03 — Packing for efficient SFT' + status: planned + priority: critical + assigned_to: null + created: 2026-04-18 14:44:19+00:00 + updated: 2026-04-18 14:44:19+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-H-03-v1.yaml | Competitor: huggingface | Demand: 5/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-H + - competitor-huggingface + - crux-h-03 + notes: null +- id: PMAT-600 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-H-06 — Streaming datasets no RAM mat' + status: planned + priority: high + assigned_to: null + created: 2026-04-18 14:44:19+00:00 + updated: 2026-04-18 14:44:19+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-H-06-v1.yaml | Competitor: huggingface | Demand: 4/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-H + - competitor-huggingface + - crux-h-06 + notes: null +- id: PMAT-601 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-H-12 — ImageFolder loader' + status: planned + priority: medium + assigned_to: null + created: 2026-04-18 14:44:19+00:00 + updated: 2026-04-18 14:44:19+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-H-12-v1.yaml | Competitor: pytorch | Demand: 3/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-H + - competitor-pytorch + - crux-h-12 + notes: null +- id: PMAT-602 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-H-13 — Audio dataset loader WAV/FLAC' + status: planned + priority: low + assigned_to: null + created: 2026-04-18 14:44:19+00:00 + updated: 2026-04-18 14:44:19+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-H-13-v1.yaml | Competitor: pytorch | Demand: 2/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-H + - competitor-pytorch + - crux-h-13 + notes: null +- id: PMAT-603 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-H-14 — Dataset mixing per-source weights' + status: planned + priority: medium + assigned_to: null + created: 2026-04-18 14:44:19+00:00 + updated: 2026-04-18 14:44:19+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-H-14-v1.yaml | Competitor: huggingface | Demand: 3/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-H + - competitor-huggingface + - crux-h-14 + notes: null +- id: PMAT-604 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-H-16 — Tokenizer-aware length bucketing' + status: planned + priority: medium + assigned_to: null + created: 2026-04-18 14:44:19+00:00 + updated: 2026-04-18 14:44:19+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-H-16-v1.yaml | Competitor: huggingface | Demand: 3/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-H + - competitor-huggingface + - crux-h-16 + notes: null +- id: PMAT-605 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-H-17 — Contrastive pair sampler for CLIP' + status: planned + priority: medium + assigned_to: null + created: 2026-04-18 14:44:19+00:00 + updated: 2026-04-18 14:44:19+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-H-17-v1.yaml | Competitor: openclip | Demand: 3/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-H + - competitor-openclip + - crux-h-17 + notes: null +- id: PMAT-606 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-H-18 — Negative sampling for ranking' + status: planned + priority: low + assigned_to: null + created: 2026-04-18 14:44:19+00:00 + updated: 2026-04-18 14:44:19+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-H-18-v1.yaml | Competitor: pytorch | Demand: 2/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-H + - competitor-pytorch + - crux-h-18 + notes: null +- id: PMAT-607 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-H-19 — Synthetic data generation via LLM' + status: planned + priority: medium + assigned_to: null + created: 2026-04-18 14:44:19+00:00 + updated: 2026-04-18 14:44:19+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-H-19-v1.yaml | Competitor: huggingface | Demand: 3/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-H + - competitor-huggingface + - crux-h-19 + notes: null +- id: PMAT-608 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-H-20 — PII redaction in datasets' + status: planned + priority: low + assigned_to: null + created: 2026-04-18 14:44:19+00:00 + updated: 2026-04-18 14:44:19+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-H-20-v1.yaml | Competitor: ecosystem | Demand: 2/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-H + - competitor-ecosystem + - crux-h-20 + notes: null +- id: PMAT-609 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-H-21 — Row-level dedup MinHash' + status: planned + priority: medium + assigned_to: null + created: 2026-04-18 14:44:19+00:00 + updated: 2026-04-18 14:44:19+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-H-21-v1.yaml | Competitor: huggingface | Demand: 3/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-H + - competitor-huggingface + - crux-h-21 + notes: null +- id: PMAT-610 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-I-04 — Ollama function calling' + status: planned + priority: critical + assigned_to: null + created: 2026-04-18 14:44:19+00:00 + updated: 2026-04-18 14:44:19+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-I-04-v1.yaml | Competitor: ollama | Demand: 5/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-I + - competitor-ollama + - crux-i-04 + notes: null +- id: PMAT-611 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-I-06 — ReAct agent loop + stop conditions' + status: planned + priority: high + assigned_to: null + created: 2026-04-18 14:44:19+00:00 + updated: 2026-04-18 14:44:19+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-I-06-v1.yaml | Competitor: ecosystem | Demand: 4/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-I + - competitor-ecosystem + - crux-i-06 + notes: null +- id: PMAT-612 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-I-07 — Claude Agent SDK compatibility' + status: planned + priority: medium + assigned_to: null + created: 2026-04-18 14:44:19+00:00 + updated: 2026-04-18 14:44:19+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-I-07-v1.yaml | Competitor: ecosystem | Demand: 3/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-I + - competitor-ecosystem + - crux-i-07 + notes: null +- id: PMAT-613 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-I-09 — Parallel tool-calls one turn' + status: planned + priority: high + assigned_to: null + created: 2026-04-18 14:44:19+00:00 + updated: 2026-04-18 14:44:19+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-I-09-v1.yaml | Competitor: vllm | Demand: 4/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-I + - competitor-vllm + - crux-i-09 + notes: null +- id: PMAT-614 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-I-12 — GBNF grammar from JSON-schema' + status: planned + priority: high + assigned_to: null + created: 2026-04-18 14:44:19+00:00 + updated: 2026-04-18 14:44:19+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-I-12-v1.yaml | Competitor: llama_cpp | Demand: 4/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-I + - competitor-llama_cpp + - crux-i-12 + notes: null +- id: PMAT-615 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-I-13 — MCP resource provider' + status: planned + priority: medium + assigned_to: null + created: 2026-04-18 14:44:19+00:00 + updated: 2026-04-18 14:44:19+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-I-13-v1.yaml | Competitor: ecosystem | Demand: 3/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-I + - competitor-ecosystem + - crux-i-13 + notes: null +- id: PMAT-616 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-I-14 — MCP prompt provider' + status: planned + priority: medium + assigned_to: null + created: 2026-04-18 14:44:19+00:00 + updated: 2026-04-18 14:44:19+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-I-14-v1.yaml | Competitor: ecosystem | Demand: 3/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-I + - competitor-ecosystem + - crux-i-14 + notes: null +- id: PMAT-617 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-I-15 — Agent memory plugin interface' + status: planned + priority: medium + assigned_to: null + created: 2026-04-18 14:44:19+00:00 + updated: 2026-04-18 14:44:19+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-I-15-v1.yaml | Competitor: ecosystem | Demand: 3/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-I + - competitor-ecosystem + - crux-i-15 + notes: null +- id: PMAT-618 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-I-16 — Guardrails output filter pipeline' + status: planned + priority: medium + assigned_to: null + created: 2026-04-18 14:44:19+00:00 + updated: 2026-04-18 14:44:19+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-I-16-v1.yaml | Competitor: ecosystem | Demand: 3/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-I + - competitor-ecosystem + - crux-i-16 + notes: null +- id: PMAT-619 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-J-01 — CLIP zero-shot classification' + status: planned + priority: critical + assigned_to: null + created: 2026-04-18 14:44:19+00:00 + updated: 2026-04-18 14:44:19+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-J-01-v1.yaml | Competitor: openclip | Demand: 5/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-J + - competitor-openclip + - crux-j-01 + notes: null +- id: PMAT-620 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-J-02 — Joint text+image embedding' + status: planned + priority: critical + assigned_to: null + created: 2026-04-18 14:44:19+00:00 + updated: 2026-04-18 14:44:19+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-J-02-v1.yaml | Competitor: openclip | Demand: 5/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-J + - competitor-openclip + - crux-j-02 + notes: null +- id: PMAT-621 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-J-03 — CLIP retrieval cosine search' + status: planned + priority: high + assigned_to: null + created: 2026-04-18 14:44:19+00:00 + updated: 2026-04-18 14:44:19+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-J-03-v1.yaml | Competitor: openclip | Demand: 4/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-J + - competitor-openclip + - crux-j-03 + notes: null +- id: PMAT-622 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-J-04 — Visual feature extraction' + status: planned + priority: high + assigned_to: null + created: 2026-04-18 14:44:19+00:00 + updated: 2026-04-18 14:44:19+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-J-04-v1.yaml | Competitor: openclip | Demand: 4/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-J + - competitor-openclip + - crux-j-04 + notes: null +- id: PMAT-623 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-J-05 — LAION WebDataset tar loading' + status: planned + priority: medium + assigned_to: null + created: 2026-04-18 14:44:19+00:00 + updated: 2026-04-18 14:44:19+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-J-05-v1.yaml | Competitor: openclip | Demand: 3/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-J + - competitor-openclip + - crux-j-05 + notes: null +- id: PMAT-624 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-J-06 — SigLIP model support' + status: planned + priority: high + assigned_to: null + created: 2026-04-18 14:44:19+00:00 + updated: 2026-04-18 14:44:19+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-J-06-v1.yaml | Competitor: openclip | Demand: 4/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-J + - competitor-openclip + - crux-j-06 + notes: null +- id: PMAT-625 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-J-07 — EVA-CLIP model support' + status: planned + priority: medium + assigned_to: null + created: 2026-04-18 14:44:19+00:00 + updated: 2026-04-18 14:44:19+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-J-07-v1.yaml | Competitor: openclip | Demand: 3/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-J + - competitor-openclip + - crux-j-07 + notes: null +- id: PMAT-626 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-J-08 — CLIP contrastive training loop' + status: planned + priority: medium + assigned_to: null + created: 2026-04-18 14:44:19+00:00 + updated: 2026-04-18 14:44:19+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-J-08-v1.yaml | Competitor: openclip | Demand: 3/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-J + - competitor-openclip + - crux-j-08 + notes: null +- id: PMAT-627 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-J-09 — Image preprocessing resize/normalize' + status: planned + priority: critical + assigned_to: null + created: 2026-04-18 14:44:19+00:00 + updated: 2026-04-18 14:44:19+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-J-09-v1.yaml | Competitor: openclip | Demand: 5/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-J + - competitor-openclip + - crux-j-09 + notes: null +- id: PMAT-628 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-J-10 — Text tokenizer for CLIP BPE' + status: planned + priority: high + assigned_to: null + created: 2026-04-18 14:44:19+00:00 + updated: 2026-04-18 14:44:19+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-J-10-v1.yaml | Competitor: openclip | Demand: 4/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-J + - competitor-openclip + - crux-j-10 + notes: null +- id: PMAT-629 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-J-11 — OpenCLIP checkpoint loader' + status: planned + priority: high + assigned_to: null + created: 2026-04-18 14:44:19+00:00 + updated: 2026-04-18 14:44:19+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-J-11-v1.yaml | Competitor: openclip | Demand: 4/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-J + - competitor-openclip + - crux-j-11 + notes: null +- id: PMAT-630 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-J-12 — Image-text pair dataloader' + status: planned + priority: medium + assigned_to: null + created: 2026-04-18 14:44:19+00:00 + updated: 2026-04-18 14:44:19+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-J-12-v1.yaml | Competitor: openclip | Demand: 3/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-J + - competitor-openclip + - crux-j-12 + notes: null +- id: PMAT-631 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-J-13 — Video-CLIP temporal pooling' + status: planned + priority: low + assigned_to: null + created: 2026-04-18 14:44:19+00:00 + updated: 2026-04-18 14:44:19+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-J-13-v1.yaml | Competitor: openclip | Demand: 2/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-J + - competitor-openclip + - crux-j-13 + notes: null +- id: PMAT-632 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-J-14 — Audio-CLIP encoder' + status: planned + priority: low + assigned_to: null + created: 2026-04-18 14:44:20+00:00 + updated: 2026-04-18 14:44:20+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-J-14-v1.yaml | Competitor: openclip | Demand: 2/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-J + - competitor-openclip + - crux-j-14 + notes: null +- id: PMAT-633 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-J-15 — CLIP fine-tune on new concept' + status: planned + priority: medium + assigned_to: null + created: 2026-04-18 14:44:20+00:00 + updated: 2026-04-18 14:44:20+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-J-15-v1.yaml | Competitor: openclip | Demand: 3/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-J + - competitor-openclip + - crux-j-15 + notes: null +- id: PMAT-634 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-J-16 — Distill large-CLIP → small-CLIP' + status: planned + priority: low + assigned_to: null + created: 2026-04-18 14:44:20+00:00 + updated: 2026-04-18 14:44:20+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-J-16-v1.yaml | Competitor: openclip | Demand: 2/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-J + - competitor-openclip + - crux-j-16 + notes: null +- id: PMAT-635 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-J-17 — Zero-shot detection OWL-ViT' + status: planned + priority: medium + assigned_to: null + created: 2026-04-18 14:44:20+00:00 + updated: 2026-04-18 14:44:20+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-J-17-v1.yaml | Competitor: openclip | Demand: 3/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-J + - competitor-openclip + - crux-j-17 + notes: null +- id: PMAT-636 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-J-18 — Multilingual CLIP' + status: planned + priority: medium + assigned_to: null + created: 2026-04-18 14:44:20+00:00 + updated: 2026-04-18 14:44:20+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-J-18-v1.yaml | Competitor: openclip | Demand: 3/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-J + - competitor-openclip + - crux-j-18 + notes: null +- id: PMAT-637 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-J-19 — Export CLIP → ONNX / GGUF' + status: planned + priority: low + assigned_to: null + created: 2026-04-18 14:44:20+00:00 + updated: 2026-04-18 14:44:20+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-J-19-v1.yaml | Competitor: openclip | Demand: 2/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-J + - competitor-openclip + - crux-j-19 + notes: null +- id: PMAT-638 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-J-20 — CLIP eval ImageNet zero-shot' + status: planned + priority: high + assigned_to: null + created: 2026-04-18 14:44:20+00:00 + updated: 2026-04-18 14:44:20+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-J-20-v1.yaml | Competitor: openclip | Demand: 4/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-J + - competitor-openclip + - crux-j-20 + notes: null +- id: PMAT-639 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-K-02 — Ollama Python SDK test suite' + status: planned + priority: critical + assigned_to: null + created: 2026-04-18 14:44:20+00:00 + updated: 2026-04-18 14:44:20+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-K-02-v1.yaml | Competitor: ecosystem | Demand: 5/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-K + - competitor-ecosystem + - crux-k-02 + notes: null +- id: PMAT-640 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-K-05 — apr ui Gradio web UI' + status: planned + priority: medium + assigned_to: null + created: 2026-04-18 14:44:20+00:00 + updated: 2026-04-18 14:44:20+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-K-05-v1.yaml | Competitor: ecosystem | Demand: 3/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-K + - competitor-ecosystem + - crux-k-05 + notes: null +- id: PMAT-641 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-K-07 — Prometheus /metrics endpoint' + status: planned + priority: high + assigned_to: null + created: 2026-04-18 14:44:20+00:00 + updated: 2026-04-18 14:44:20+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-K-07-v1.yaml | Competitor: vllm | Demand: 4/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-K + - competitor-vllm + - crux-k-07 + notes: null +- id: PMAT-642 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-K-08 — OpenTelemetry traces' + status: planned + priority: high + assigned_to: null + created: 2026-04-18 14:44:20+00:00 + updated: 2026-04-18 14:44:20+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-K-08-v1.yaml | Competitor: ecosystem | Demand: 4/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-K + - competitor-ecosystem + - crux-k-08 + notes: null +- id: PMAT-643 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-K-11 — Modelfile DSL parser (Ollama)' + status: planned + priority: medium + assigned_to: null + created: 2026-04-18 14:44:20+00:00 + updated: 2026-04-18 14:44:20+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-K-11-v1.yaml | Competitor: ollama | Demand: 3/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-K + - competitor-ollama + - crux-k-11 + notes: null +- id: PMAT-644 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-K-12 — VSCode extension for apr' + status: planned + priority: medium + assigned_to: null + created: 2026-04-18 14:44:20+00:00 + updated: 2026-04-18 14:44:20+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-K-12-v1.yaml | Competitor: ecosystem | Demand: 3/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-K + - competitor-ecosystem + - crux-k-12 + notes: null +- id: PMAT-645 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-K-13 — Docker image apr-serve:latest' + status: planned + priority: high + assigned_to: null + created: 2026-04-18 14:44:20+00:00 + updated: 2026-04-18 14:44:20+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-K-13-v1.yaml | Competitor: ecosystem | Demand: 4/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-K + - competitor-ecosystem + - crux-k-13 + notes: null +- id: PMAT-646 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-K-14 — systemd unit for apr serve' + status: planned + priority: medium + assigned_to: null + created: 2026-04-18 14:44:20+00:00 + updated: 2026-04-18 14:44:20+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-K-14-v1.yaml | Competitor: ecosystem | Demand: 3/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-K + - competitor-ecosystem + - crux-k-14 + notes: null +- id: PMAT-647 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-K-15 — Kubernetes Helm chart' + status: planned + priority: medium + assigned_to: null + created: 2026-04-18 14:44:20+00:00 + updated: 2026-04-18 14:44:20+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-K-15-v1.yaml | Competitor: ecosystem | Demand: 3/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-K + - competitor-ecosystem + - crux-k-15 + notes: null +- id: PMAT-648 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-K-16 — Triton Inference Server backend' + status: planned + priority: low + assigned_to: null + created: 2026-04-18 14:44:20+00:00 + updated: 2026-04-18 14:44:20+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-K-16-v1.yaml | Competitor: ecosystem | Demand: 2/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-K + - competitor-ecosystem + - crux-k-16 + notes: null +- id: PMAT-649 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-K-17 — NVIDIA Dynamo integration' + status: planned + priority: low + assigned_to: null + created: 2026-04-18 14:44:20+00:00 + updated: 2026-04-18 14:44:20+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-K-17-v1.yaml | Competitor: ecosystem | Demand: 2/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-K + - competitor-ecosystem + - crux-k-17 + notes: null +- id: PMAT-650 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-K-18 — ONNX Runtime backend' + status: planned + priority: medium + assigned_to: null + created: 2026-04-18 14:44:20+00:00 + updated: 2026-04-18 14:44:20+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-K-18-v1.yaml | Competitor: ecosystem | Demand: 3/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-K + - competitor-ecosystem + - crux-k-18 + notes: null +- id: PMAT-651 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-K-19 — CoreML export (Apple Silicon)' + status: planned + priority: medium + assigned_to: null + created: 2026-04-18 14:44:20+00:00 + updated: 2026-04-18 14:44:20+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-K-19-v1.yaml | Competitor: ecosystem | Demand: 3/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-K + - competitor-ecosystem + - crux-k-19 + notes: null +- id: PMAT-652 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-K-20 — TensorRT-LLM export' + status: planned + priority: medium + assigned_to: null + created: 2026-04-18 14:44:20+00:00 + updated: 2026-04-18 14:44:20+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-K-20-v1.yaml | Competitor: ecosystem | Demand: 3/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-K + - competitor-ecosystem + - crux-k-20 + notes: null +- id: PMAT-653 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-K-21 — MLX backend (Apple Silicon native)' + status: planned + priority: medium + assigned_to: null + created: 2026-04-18 14:44:20+00:00 + updated: 2026-04-18 14:44:20+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-K-21-v1.yaml | Competitor: ecosystem | Demand: 3/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-K + - competitor-ecosystem + - crux-k-21 + notes: null +- id: PMAT-654 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-A-04 — Include/exclude file globs' + status: planned + priority: high + assigned_to: null + created: 2026-04-18 14:44:17+00:00 + updated: 2026-04-18 14:44:17+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-A-04-v1.yaml | Competitor: huggingface | Demand: 4/5 | Parent: crux-competitive-research-ux-v1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-A + - competitor-huggingface + - crux-a-04 + notes: null +- id: PMAT-655 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-L-01 — Load pre-built HF kernel by hf://kernels-community/' + status: planned + priority: high + assigned_to: null + created: 2026-04-21 17:14:13+00:00 + updated: 2026-04-21 17:33:02.612716+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-l-01-v1.yaml | Competitor: hf-kernels | Demand: 4/5 | Subspec: docs/specifications/crux-competitive-research-ux-workflows.md + §5.l + §13' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-l + - competitor-hf-kernels + - crux-l-01 + notes: null +- id: PMAT-656 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-L-02 — Drop-in flash-attn2 HF kernel behind aprender FA trait' + status: planned + priority: high + assigned_to: null + created: 2026-04-21 17:14:13+00:00 + updated: 2026-04-21 17:33:06.129257+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-l-02-v1.yaml | Competitor: hf-kernels | Demand: 4/5 | Subspec: docs/specifications/crux-competitive-research-ux-workflows.md + §5.l + §13' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-l + - competitor-hf-kernels + - crux-l-02 + notes: null +- id: PMAT-657 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-L-03 — Drop-in flash-attn3 HF kernel (sm_90a / sm_100)' + status: planned + priority: high + assigned_to: null + created: 2026-04-21 17:14:13+00:00 + updated: 2026-04-21 17:33:08.064157+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-l-03-v1.yaml | Competitor: hf-kernels | Demand: 4/5 | Subspec: docs/specifications/crux-competitive-research-ux-workflows.md + §5.l + §13' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-l + - competitor-hf-kernels + - crux-l-03 + notes: null +- id: PMAT-658 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-L-04 — rmsnorm fused kernel behind LayerNorm trait' + status: planned + priority: medium + assigned_to: null + created: 2026-04-21 17:14:13+00:00 + updated: 2026-04-21 17:40:24.866055+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-l-04-v1.yaml | Competitor: hf-kernels | Demand: 3/5 | Subspec: docs/specifications/crux-competitive-research-ux-workflows.md + §5.l + §13' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-l + - competitor-hf-kernels + - crux-l-04 + notes: null +- id: PMAT-659 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-L-05 — rotary fused RoPE-apply kernel' + status: planned + priority: medium + assigned_to: null + created: 2026-04-21 17:14:14+00:00 + updated: 2026-04-21 17:40:30.201327+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-l-05-v1.yaml | Competitor: hf-kernels | Demand: 3/5 | Subspec: docs/specifications/crux-competitive-research-ux-workflows.md + §5.l + §13' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-l + - competitor-hf-kernels + - crux-l-05 + notes: null +- id: PMAT-660 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-L-06 — paged-attention KV-cache kernel (vLLM-compat)' + status: planned + priority: high + assigned_to: null + created: 2026-04-21 17:14:14+00:00 + updated: 2026-04-21 17:33:09.987621+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-l-06-v1.yaml | Competitor: hf-kernels | Demand: 4/5 | Subspec: docs/specifications/crux-competitive-research-ux-workflows.md + §5.l + §13' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-l + - competitor-hf-kernels + - crux-l-06 + notes: null +- id: PMAT-661 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-L-07 — fp8-fbgemm matmul path for H100+' + status: planned + priority: medium + assigned_to: null + created: 2026-04-21 17:14:14+00:00 + updated: 2026-04-21 17:40:32.230207+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-l-07-v1.yaml | Competitor: hf-kernels | Demand: 3/5 | Subspec: docs/specifications/crux-competitive-research-ux-workflows.md + §5.l + §13' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-l + - competitor-hf-kernels + - crux-l-07 + notes: null +- id: PMAT-662 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-L-08 — quantization-bitsandbytes NF4 via HF kernel' + status: planned + priority: medium + assigned_to: null + created: 2026-04-21 17:14:14+00:00 + updated: 2026-04-21 17:40:34.193033+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-l-08-v1.yaml | Competitor: hf-kernels | Demand: 3/5 | Subspec: docs/specifications/crux-competitive-research-ux-workflows.md + §5.l + §13' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-l + - competitor-hf-kernels + - crux-l-08 + notes: null +- id: PMAT-663 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-L-09 — quantization-gptq fused dequant+matmul' + status: planned + priority: medium + assigned_to: null + created: 2026-04-21 17:14:14+00:00 + updated: 2026-04-21 17:40:36.166173+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-l-09-v1.yaml | Competitor: hf-kernels | Demand: 3/5 | Subspec: docs/specifications/crux-competitive-research-ux-workflows.md + §5.l + §13' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-l + - competitor-hf-kernels + - crux-l-09 + notes: null +- id: PMAT-664 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-L-10 — liger-kernels fused CE-loss for training' + status: planned + priority: high + assigned_to: null + created: 2026-04-21 17:14:14+00:00 + updated: 2026-04-21 17:33:11.883491+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-l-10-v1.yaml | Competitor: hf-kernels | Demand: 4/5 | Subspec: docs/specifications/crux-competitive-research-ux-workflows.md + §5.l + §13' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-l + - competitor-hf-kernels + - crux-l-10 + notes: null +- id: PMAT-665 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-L-11 — megablocks MoE routing kernel' + status: planned + priority: medium + assigned_to: null + created: 2026-04-21 17:14:14+00:00 + updated: 2026-04-21 17:40:38.151284+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-l-11-v1.yaml | Competitor: hf-kernels | Demand: 3/5 | Subspec: docs/specifications/crux-competitive-research-ux-workflows.md + §5.l + §13' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-l + - competitor-hf-kernels + - crux-l-11 + notes: null +- id: PMAT-666 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-L-12 — punica-sgmv multi-LoRA fused SGMV' + status: planned + priority: medium + assigned_to: null + created: 2026-04-21 17:14:14+00:00 + updated: 2026-04-21 17:40:40.127745+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-l-12-v1.yaml | Competitor: hf-kernels | Demand: 3/5 | Subspec: docs/specifications/crux-competitive-research-ux-workflows.md + §5.l + §13' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-l + - competitor-hf-kernels + - crux-l-12 + notes: null +- id: PMAT-667 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-L-13 — activation fused SwiGLU/GeGLU kernel' + status: planned + priority: medium + assigned_to: null + created: 2026-04-21 17:14:14+00:00 + updated: 2026-04-21 17:40:42.178009+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-l-13-v1.yaml | Competitor: hf-kernels | Demand: 3/5 | Subspec: docs/specifications/crux-competitive-research-ux-workflows.md + §5.l + §13' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-l + - competitor-hf-kernels + - crux-l-13 + notes: null +- id: PMAT-668 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-L-14 — mamba-ssm state-space kernel' + status: planned + priority: low + assigned_to: null + created: 2026-04-21 17:14:14+00:00 + updated: 2026-04-21 17:50:35.218351+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-l-14-v1.yaml | Competitor: hf-kernels | Demand: 2/5 | Subspec: docs/specifications/crux-competitive-research-ux-workflows.md + §5.l + §13' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-l + - competitor-hf-kernels + - crux-l-14 + notes: null +- id: PMAT-669 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-L-15 — Kernel version-pinning + SHA-verified load' + status: planned + priority: high + assigned_to: null + created: 2026-04-21 17:14:14+00:00 + updated: 2026-04-21 17:33:13.764545+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-l-15-v1.yaml | Competitor: hf-kernels | Demand: 4/5 | Subspec: docs/specifications/crux-competitive-research-ux-workflows.md + §5.l + §13' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-l + - competitor-hf-kernels + - crux-l-15 + notes: null +- id: PMAT-670 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-M-01 — Gate-1 byte-identical vs safetensors ground truth' + status: planned + priority: critical + assigned_to: null + created: 2026-04-21 17:14:14+00:00 + updated: 2026-04-21 17:15:28.724749+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-m-01-v1.yaml | Competitor: apr-qa-playbook | Demand: 5/5 | Subspec: docs/specifications/crux-competitive-research-ux-workflows.md + §5.m + §13' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-m + - competitor-apr-qa-playbook + - crux-m-01 + notes: null +- id: PMAT-671 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-M-02 — Gate-2 tensor-stats parity (min/max/mean/std, per-tensor)' + status: planned + priority: critical + assigned_to: null + created: 2026-04-21 17:14:14+00:00 + updated: 2026-04-21 17:17:55.283180+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-m-02-v1.yaml | Competitor: apr-qa-playbook | Demand: 5/5 | Subspec: docs/specifications/crux-competitive-research-ux-workflows.md + §5.m + §13' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-m + - competitor-apr-qa-playbook + - crux-m-02 + notes: null +- id: PMAT-672 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-M-04 — Gate-4 cross-format parity APR ↔ GGUF ↔ safetensors' + status: planned + priority: critical + assigned_to: null + created: 2026-04-21 17:14:14+00:00 + updated: 2026-04-21 17:17:57.869191+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-m-04-v1.yaml | Competitor: apr-qa-playbook | Demand: 5/5 | Subspec: docs/specifications/crux-competitive-research-ux-workflows.md + §5.m + §13' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-m + - competitor-apr-qa-playbook + - crux-m-04 + notes: null +- id: PMAT-673 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-M-05 — Gate-5 tokenizer round-trip with NFC normalization' + status: planned + priority: high + assigned_to: null + created: 2026-04-21 17:14:14+00:00 + updated: 2026-04-21 17:26:37.956162+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-m-05-v1.yaml | Competitor: apr-qa-playbook | Demand: 4/5 | Subspec: docs/specifications/crux-competitive-research-ux-workflows.md + §5.m + §13' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-m + - competitor-apr-qa-playbook + - crux-m-05 + notes: null +- id: PMAT-674 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-M-06 — Gate-6 chat-template rendering equivalence' + status: planned + priority: high + assigned_to: null + created: 2026-04-21 17:14:14+00:00 + updated: 2026-04-21 17:26:42.477286+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-m-06-v1.yaml | Competitor: apr-qa-playbook | Demand: 4/5 | Subspec: docs/specifications/crux-competitive-research-ux-workflows.md + §5.m + §13' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-m + - competitor-apr-qa-playbook + - crux-m-06 + notes: null +- id: PMAT-675 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-M-07 — Gate-7 pass@1 on canary suite with confidence interval' + status: planned + priority: critical + assigned_to: null + created: 2026-04-21 17:14:14+00:00 + updated: 2026-04-21 17:17:59.816988+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-m-07-v1.yaml | Competitor: apr-qa-playbook | Demand: 5/5 | Subspec: docs/specifications/crux-competitive-research-ux-workflows.md + §5.m + §13' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-m + - competitor-apr-qa-playbook + - crux-m-07 + notes: null +- id: PMAT-676 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-M-08 — Gate-8 5-Whys root-cause generator on failure' + status: planned + priority: high + assigned_to: null + created: 2026-04-21 17:14:14+00:00 + updated: 2026-04-21 17:26:44.416035+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-m-08-v1.yaml | Competitor: apr-qa-playbook | Demand: 4/5 | Subspec: docs/specifications/crux-competitive-research-ux-workflows.md + §5.m + §13' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-m + - competitor-apr-qa-playbook + - crux-m-08 + notes: null +- id: PMAT-677 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-M-09 — Property-based falsifier ≥ 1000 fuzz cases per gate' + status: planned + priority: high + assigned_to: null + created: 2026-04-21 17:14:14+00:00 + updated: 2026-04-21 17:26:46.354228+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-m-09-v1.yaml | Competitor: apr-qa-playbook | Demand: 4/5 | Subspec: docs/specifications/crux-competitive-research-ux-workflows.md + §5.m + §13' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-m + - competitor-apr-qa-playbook + - crux-m-09 + notes: null +- id: PMAT-678 + github_issue: null + item_type: task + title: 'CRUX gap: CRUX-M-10 — Upstream-fix enforcement (reject workarounds)' + status: planned + priority: high + assigned_to: null + created: 2026-04-21 17:14:14+00:00 + updated: 2026-04-21 17:26:48.292544+00:00 + spec: null + acceptance_criteria: + - 'Contract: contracts/crux-m-10-v1.yaml | Competitor: apr-qa-playbook | Demand: 4/5 | Subspec: docs/specifications/crux-competitive-research-ux-workflows.md + §5.m + §13' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux + - gap + - crux-m + - competitor-apr-qa-playbook + - crux-m-10 + notes: null +- id: PMAT-679 + github_issue: null + item_type: task + title: 'P0-I: Verify P0-G+P0-H end-to-end on fresh checkpoint' + status: planned + priority: critical + assigned_to: null + created: 2026-05-16 07:14:53+00:00 + updated: 2026-05-16 07:23:25+00:00 + spec: null + acceptance_criteria: + - 'PARTIAL discharge (2026-05-16): P0-G verified LIVE via pad-on-export message [P0-G] Padding APR-fallback + tokenizer.ggml.tokens: 151643 + 293 placeholders = 151936; GGUF metadata + tensor shapes all align + at 151936. P0-H NOT verified on epoch-020 checkpoint (it was trained BEFORE P0-H landed; arch metadata + still LlamaForCausalLM → Qwen2 biases leak with passthrough names → llama-cli expected 291 got 219). + P0-H verification deferred to PMAT-681 (P2-C) since exercising it requires a freshly-emitted checkpoint. + Build was blocked by memory pressure (3GB free / 127GB swap exhausted). See evidence/p0-i-2026-05-16/findings.md.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - albor-370m + - p0 + - roadmap-v2 + - ship-model-2 + notes: null +- id: PMAT-680 + github_issue: null + item_type: task + title: 'P0-J: Chinchilla gate — warning → hard blocker' + status: planned + priority: critical + assigned_to: null + created: 2026-05-16 07:15:09+00:00 + updated: 2026-05-16 13:22:20.550551+00:00 + spec: null + acceptance_criteria: + - 'Convert PR #1708 stderr warning to fail-fast error when D/N < 10× in apr pretrain; add --force-under-provisioned + bypass flag. Author contracts/chinchilla-gate-v1.yaml with FALSIFY tests. Audit Rec #2 (audits/albor-370.md). + Effort: 1-2h. Δship +1 (prevention). P=95%. See §83.2.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - albor-370m + - p0 + - roadmap-v2 + - ship-model-2 + - audit-rec + notes: null +- id: PMAT-681 + github_issue: null + item_type: task + title: 'P2-C: Widen corpus to >2B tokens (highest EV)' + status: completed + priority: critical + assigned_to: null + created: 2026-05-16 07:15:09+00:00 + updated: 2026-05-17 08:16:22+00:00 + spec: null + acceptance_criteria: + - 'P2-C 50K-step training COMPLETED via lambda-vector dispatch 2026-05-17. Multi-source corpus assembly + succeeded (49.6B tokens, 18.3M docs, 17 min tokenize at 22.5K docs/s). Training EARLY_STOP at 27 epochs + / 2700 steps with val_loss=4.91 best. AUDIT HYPOTHESIS FALSIFIED: corpus diversity was NOT the binding + constraint — identical termination shape to §82 (which had 1.24B-token single-source corpus). Root + cause discovered (NEW P0-K): apr convert import-from-HF doesn''t stamp hf_architecture / embedded + tokenizer / merges, so all downstream P0-D/E/F/G/H/J machinery has nothing to propagate. Ship % stays + at 79. See evidence/p2c-2026-05-17/findings.md for full Five-Whys + methodology lesson #33 (upstream + metadata defects masquerade as downstream packaging defects). Next: PMAT-690 NEW P0-K apr convert + metadata stamping.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - albor-370m + - p2 + - roadmap-v2 + - ship-model-2 + - audit-rec + - binding-constraint + notes: null +- id: PMAT-682 + github_issue: null + item_type: task + title: 'P2-A2: Same-corpus longer run (DOWNGRADED — fallback only)' + status: planned + priority: low + assigned_to: null + created: 2026-05-16 07:15:09+00:00 + updated: 2026-05-16 07:15:09+00:00 + spec: null + acceptance_criteria: + - 'FALLBACK ONLY if P2-C is blocked on infrastructure. Pre-falsified by audit via Chinchilla math (D/N + = 0.04×). Running more steps on a 22M-token consumed / 1.24B available corpus cannot break the val_loss + plateau (binding constraint is data, not compute). If dispatched: --num-steps 20000 --init qwen-0.5b + --dataset qwen-v2. Effort: 3-8h GPU. Δship +1 best case. P=15%. See §83.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - albor-370m + - p2 + - roadmap-v2 + - ship-model-2 + - fallback + - pre-falsified + notes: null +- id: PMAT-683 + github_issue: null + item_type: task + title: 'P2-D: True distillation from MODEL-1 (apr distill)' + status: planned + priority: medium + assigned_to: null + created: 2026-05-16 07:15:09+00:00 + updated: 2026-05-16 07:15:09+00:00 + spec: null + acceptance_criteria: + - 'Ship apr distill per §35 (currently STUB). Architectural change; defer until P2-C exhausted. Multi-week + scope. Effort: 16-40h. Δship +10. P=25%.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - albor-370m + - p2 + - roadmap-v2 + - ship-model-2 + - distillation + - multi-week + notes: null +- id: PMAT-684 + github_issue: null + item_type: task + title: 'P1-B: HumanEval pass@1 on best checkpoint (DEFERRED)' + status: planned + priority: medium + assigned_to: null + created: 2026-05-16 07:15:26+00:00 + updated: 2026-05-16 07:15:26+00:00 + spec: null + acceptance_criteria: + - 'BLOCKED on val_loss < 3.0 per audit Rec #3 (was < 4.0). At current val_loss=4.71 (perplexity ~111) + zero-shot reasoning is mathematically impossible. apr eval humaneval. Effort: 5-8h gx10. Δship +3 + if pass>5%. P=3%. Run AFTER P2-C lands a better checkpoint.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - albor-370m + - p1 + - roadmap-v2 + - ship-model-2 + - deferred + - blocked-on-p2c + notes: null +- id: PMAT-685 + github_issue: null + item_type: task + title: 'P1-C: Python validity 100 prompts (DEFERRED)' + status: planned + priority: medium + assigned_to: null + created: 2026-05-16 07:15:26+00:00 + updated: 2026-05-16 07:15:26+00:00 + spec: null + acceptance_criteria: + - 'BLOCKED on val_loss < 3.0 per audit Rec #3. Generate from 100 prompts, parse with ast.parse, count + zero-error. Effort: 2h. Δship +3 if pass>30%. P=5% at current val_loss. Run AFTER P2-C.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - albor-370m + - p1 + - roadmap-v2 + - ship-model-2 + - deferred + - blocked-on-p2c + notes: null +- id: PMAT-686 + github_issue: null + item_type: task + title: 'P3-A: apr inspect --quality ≥ 90 on best checkpoint' + status: planned + priority: medium + assigned_to: null + created: 2026-05-16 07:15:26+00:00 + updated: 2026-05-16 07:15:26+00:00 + spec: null + acceptance_criteria: + - 'Discharges AC-SHIP2-007. Run apr inspect --quality against best ckpt. Effort: 1h. Δship +1. P=80%. + DEFERRED until val_loss < 3.0 (audit Rec #3).' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - albor-370m + - p3 + - roadmap-v2 + - ship-model-2 + - deferred + notes: null +- id: PMAT-687 + github_issue: null + item_type: task + title: 'P3-B: apr lint zero High severity on best checkpoint' + status: planned + priority: medium + assigned_to: null + created: 2026-05-16 07:15:26+00:00 + updated: 2026-05-16 07:24:18+00:00 + spec: null + acceptance_criteria: + - 'PARTIAL discharge (2026-05-16): apr lint on epoch-020.apr returns 0 errors / 3 warnings / 1 info + → meets ''zero High severity'' criterion (AC-SHIP2-008 component). Warnings: missing license + model_card + + provenance metadata fields. Info: 122 uncompressed tensors >1MB. Fixing the warnings requires a + model-card author step and metadata stamping in the pretrain pipeline (related to AC-SHIP2-022 provenance). + See evidence/p3-b-2026-05-16-lint.txt.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - albor-370m + - p3 + - roadmap-v2 + - ship-model-2 + notes: null +- id: PMAT-688 + github_issue: null + item_type: task + title: 'P3-C: Publish to HuggingFace as paiml/albor-370m-v1' + status: planned + priority: medium + assigned_to: null + created: 2026-05-16 07:15:26+00:00 + updated: 2026-05-16 07:15:26+00:00 + spec: null + acceptance_criteria: + - 'Once val_loss < 3 + smoke OK: apr publish paiml/albor-370m-v1 --formats apr,safetensors,gguf. Final + ship gate. Effort: 1-2h. Δship +5. P=95%. BLOCKED on P2-C + P1-B + P3-A/B.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - albor-370m + - p3 + - roadmap-v2 + - ship-model-2 + - publish + - blocked-on-p2c + notes: null +- id: PMAT-689 + github_issue: null + item_type: task + title: 'P3-D: Post-publish QA + /dogfood verdict' + status: planned + priority: medium + assigned_to: null + created: 2026-05-16 07:15:26+00:00 + updated: 2026-05-16 07:15:26+00:00 + spec: null + acceptance_criteria: + - 'Per feedback_post_publish_qa_required.md — mandatory after every publish. cargo install + /dogfood + GO. Effort: 1h. Gating (Δship 0). P=99%.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - albor-370m + - p3 + - roadmap-v2 + - ship-model-2 + - publish + - blocked-on-p3c + notes: null +- id: PMAT-690 + github_issue: null + item_type: task + title: 'P0-K NEW: apr convert must stamp hf_architecture + tokenizer + merges into imported APRs' + status: planned + priority: critical + assigned_to: null + created: 2026-05-17 08:16:22+00:00 + updated: 2026-05-17 08:16:22+00:00 + spec: null + acceptance_criteria: + - 'P2-C live falsification (2026-05-17) revealed that PMAT-679..683''s Class 3 packaging cascade (P0-D/E/F/G/H/J) + was treating symptoms of a single upstream defect. apr convert from-HF-safetensors doesn''t stamp + hf_architecture, tokenizer.vocabulary, or tokenizer.merges into the imported APR. apr pretrain --init + then reads None for those fields and downstream P0-* machinery has nothing to propagate. Fix: apr + convert reads source config.json architectures[0] + tokenizer.json + writes them into apr_metadata.hf_architecture + + custom.tokenizer.{vocabulary,merges}. Scope ~100 LOC. Unblocks PMAT-679 P0-H half + AC-SHIP2-010 + llama-cli interop. See evidence/p2c-2026-05-17/findings.md.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - albor-370m + - p0 + - roadmap-v3 + - ship-model-2 + - upstream-fix + notes: null +- id: PMAT-691 + github_issue: null + item_type: task + title: Distillation Phase 2 — KD-wired student forward+backward + status: planned + priority: high + assigned_to: null + created: 2026-05-18 10:58:38+00:00 + updated: 2026-05-18 10:58:47.974418+00:00 + spec: null + acceptance_criteria: + - SPEC-DISTILL-001 Phase 2. Wire CudaTransformerTrainer's KD-loss backward into pipeline.rs::train(). + Add forward_backward_kd_batch(batch, teacher_logits) on the trainer. Replace remaining build_synthetic_logits + stub for student path. Falsifier F-DISTILL-KD-001 — loss monotone over 100 steps. + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-692 + github_issue: 1915 + item_type: task + title: Per-position (full-sequence) knowledge distillation for aprender-train-distill + status: completed + priority: high + assigned_to: null + created: 2026-06-11 06:00:06+00:00 + updated: 2026-06-11 06:00:06+00:00 + spec: null + acceptance_criteria: + - 'Shipped v0.36.0 (PR #1915). Contract: contracts/distill-per-position-kd-v1.yaml. Additive/opt-in + (APR_DISTILL_PER_POSITION); CUDA path unchanged via trait defaults. Falsifiers FT-PERPOS-001..005.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - distill + - shipped + notes: Roadmap-traceability backfill 2026-06-11 (was untracked). +- id: PMAT-693 + github_issue: 1893 + item_type: task + title: 'Sharded GGUF pull + auto-merge — run multi-part GGUFs end-to-end (closes #1893)' + status: completed + priority: high + assigned_to: null + created: 2026-06-11 06:00:06+00:00 + updated: 2026-06-11 06:00:06+00:00 + spec: null + acceptance_criteria: + - 'Shipped v0.37.0 (pull, #1917, contract sharded-gguf-pull-v1) + v0.38.0 (auto-merge, #1918, contract + sharded-gguf-merge-v1). Type-agnostic, lossless-metadata, bounded-memory merge. Advances CRUX-A acquisition.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux-a + - gguf + - shipped + notes: Roadmap-traceability backfill 2026-06-11. +- id: PMAT-694 + github_issue: 1919 + item_type: task + title: BF16 (ggml type 30) GGUF loader support + status: completed + priority: medium + assigned_to: null + created: 2026-06-11 06:00:06+00:00 + updated: 2026-06-11 06:00:06+00:00 + spec: null + acceptance_criteria: + - 'Shipped v0.39.0 (PR #1919). Contract: contracts/bf16-dequant-v1.yaml. get_tensor_f32 + tensor_byte_size + BF16 arms; FT-BF16-001/002.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - quant + - gguf + - shipped + notes: Roadmap-traceability backfill 2026-06-11. +- id: PMAT-695 + github_issue: 1922 + item_type: task + title: APR->GGUF export rejects AprQ8 instead of corrupt-relabeling as Q8_0 (import/export symmetry) + status: completed + priority: high + assigned_to: null + created: 2026-06-11 06:00:06+00:00 + updated: 2026-06-11 06:00:06+00:00 + spec: null + acceptance_criteria: + - 'Shipped v0.40.0 (PR #1922). Contract: contracts/apr-gguf-export-symmetry-v1.yaml. Silent-corruption + fix; FT-APRQ8-001/002. Gated a-priori by CRUX-M-04 (PMAT-672).' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux-m + - format-integrity + - shipped + notes: Roadmap-traceability backfill 2026-06-11. Corruption class to be walled by PMAT-671/672. +- id: PMAT-696 + github_issue: 1924 + item_type: task + title: Fix corrupt Q2_K dequantization (185/256 elements wrong) — format + inference paths + status: completed + priority: critical + assigned_to: null + created: 2026-06-11 06:00:06+00:00 + updated: 2026-06-11 06:00:06+00:00 + spec: null + acceptance_criteria: + - 'Shipped v0.41.0 (PR #1924). Contract: contracts/q2k-dequant-parity-v1.yaml. Both aprender-core + + aprender-serve dequant matched to ggml dequantize_row_q2_K; FT-Q2K-001/002. Directly motivates the + PMAT-671 standing gate.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux-m + - quant-integrity + - shipped + notes: Roadmap-traceability backfill 2026-06-11. Strategic discharge = PMAT-671 (CRUX-M-02 stat-parity + gate would have caught this a priori). +- id: PMAT-697 + github_issue: 1925 + item_type: task + title: Correct ggml dtype names 26-30 (BF16 was reported as IQ1_M in apr tensors/inspect) + status: completed + priority: medium + assigned_to: null + created: 2026-06-11 06:00:06+00:00 + updated: 2026-06-11 06:00:06+00:00 + spec: null + acceptance_criteria: + - 'Shipped v0.41.1 (PR #1925). ggml_dtype_name table reordered to ggml.h (I32=26..BF16=30); exhaustive + test pinned. Advances CRUX-F inspect correctness.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux-f + - inspect + - shipped + notes: Roadmap-traceability backfill 2026-06-11. +- id: PMAT-698 + github_issue: null + item_type: task + title: Hard-refuse unsupported architectures instead of silent llama fallback (replace FALSIFY-TNAME-005) + status: planned + priority: critical + assigned_to: null + created: 2026-06-11 06:00:06+00:00 + updated: 2026-06-11 06:00:06+00:00 + spec: null + acceptance_criteria: + - 'normalize_architecture (tensor_names_fallback.rs:73, tensor_names.rs:282) silently maps unknown arch->llama + and FALSIFY-TNAME-005 PINS that garbage-producing behavior; Gemma/Phi3/Falcon run the wrong forward + path. Make it return Result/Option + actionable error; INVERT the falsifier to assert clean refusal. + Autonomous + CPU-verifiable. Roadmap-aligned target #2.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - arch-breadth + - integrity + - roadmap-aligned + notes: Added 2026-06-11 from roadmap evaluation (refuse-don't-corrupt theme). +- id: PMAT-710 + github_issue: null + item_type: epic + title: 'Unsloth parity: compete with Unsloth on small-model LoRA/QLoRA fine-tune + distillation (pure + Rust)' + status: planned + priority: high + assigned_to: null + created: 2026-06-11 06:10:08+00:00 + updated: 2026-06-11 06:10:08+00:00 + spec: null + acceptance_criteria: + - 'STRATEGIC (user directive 2026-06-11): the PEFT/QLoRA fine-tune + distillation lane is an EXPLICIT + competitor target vs Unsloth. Parity = end-to-end load -> QLoRA(4-bit) -> train -> merge adapter -> + export GGUF/safetensors -> publish HF, in pure safe-Rust, CPU-or-single-GPU (lambda-vector). Unsloth + already a benchmark in-tree (score.rs TRAINING_TOK_S=6000 unsloth-level; ch23_training_bench). Children: + PMAT-711..715. Advances CRUX-D.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux-d + - unsloth + - finetune + - roadmap-aligned + notes: New competitive epic 2026-06-11. Corrects earlier "not an Unsloth replacement" framing — this + is the ONE training lane winnable in pure Rust. +- id: PMAT-711 + github_issue: null + item_type: task + title: QLoRA 4-bit + LoRA fine-tune (apr finetune --qlora --bits 4) — CRUX-D QLoRA (currently MISSING) + status: planned + priority: high + assigned_to: null + created: 2026-06-11 06:10:08+00:00 + updated: 2026-06-11 06:10:08+00:00 + spec: null + acceptance_criteria: + - 'Core Unsloth feature. qlora/qlora_default exist in aprender-train; wire the 4-bit NF4 base + LoRA + adapter path into apr finetune. Falsifier: loss-monotone over N steps on a tiny fixture; 4-bit base + footprint vs f16. CPU-falsifiable math + single-GPU run (lambda-vector).' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux-d + - unsloth + - qlora + notes: null +- id: PMAT-712 + github_issue: null + item_type: task + title: Complete LoRA-merge + export-to-GGUF (Unsloth save_pretrained_merged equivalent) — CRUX-D partial->supported + status: planned + priority: high + assigned_to: null + created: 2026-06-11 06:10:08+00:00 + updated: 2026-06-11 06:10:08+00:00 + spec: null + acceptance_criteria: + - 'aprender-train/src/lora/adapter/merge_export.rs + hf_pipeline/export/exporter.rs exist (partial). + Complete: merge LoRA into base, export merged GGUF + safetensors. Falsifier: merged GGUF loads AND + forward matches the LoRA-applied base within tol (golden). Fully CPU-verifiable.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux-d + - unsloth + - export + notes: null +- id: PMAT-713 + github_issue: null + item_type: task + title: End-to-end apr finetune Unsloth-parity single-command UX (load -> QLoRA -> train -> merge -> + export -> publish) + status: planned + priority: high + assigned_to: null + created: 2026-06-11 06:10:08+00:00 + updated: 2026-06-11 06:10:08+00:00 + spec: null + acceptance_criteria: + - 'The headline competitive story: one command from base model + dataset to a merged, exported, HF-published + fine-tuned model. apr finetune (commands/finetune.rs) exists; wire QLoRA + merge + export + apr publish. + Falsifier: e2e on a tiny fixture model produces a loadable merged artifact + the HF-commit dry-run + succeeds.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux-d + - unsloth + - ux + notes: null +- id: PMAT-714 + github_issue: null + item_type: task + title: Gradient checkpointing for memory (CRUX-D partial) — Unsloth low-VRAM wedge + status: planned + priority: medium + assigned_to: null + created: 2026-06-11 06:10:08+00:00 + updated: 2026-06-11 06:10:08+00:00 + spec: null + acceptance_criteria: + - 'Activation/gradient checkpointing to trade compute for memory, enabling larger context/batch on a + single GPU. Falsifier: identical loss with vs without checkpointing on a fixture (numerical equivalence) + + reduced peak activation memory.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux-d + - unsloth + - memory + notes: null +- id: PMAT-715 + github_issue: null + item_type: task + title: Adapter fusion (combine N LoRAs) + promote Unsloth to tracked training-throughput competitor + (>=6000 tok/s bar) + status: planned + priority: medium + assigned_to: null + created: 2026-06-11 06:10:08+00:00 + updated: 2026-06-11 06:10:08+00:00 + spec: null + acceptance_criteria: + - 'CRUX-D adapter-fusion (missing): merge N LoRA adapters with weights. AND formalize Unsloth as a tracked + competitor in the training benchmark (aprender-test-lib/src/llm/score.rs + ch23_training_bench) with + the >=6000 tok/s (yoga-RTX) / >=13000 (A100) bar. Falsifier: fused adapter forward == weighted sum + of individual; bench reports the unsloth-relative ratio.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - crux-d + - unsloth + - benchmark + notes: null +- id: PMAT-716 + github_issue: null + item_type: epic + title: 'MISSION: one pure-Rust binary that REPLACES + BEATS sklearn + PyTorch + Unsloth + Ollama/llama.cpp + at what each does best' + status: planned + priority: critical + assigned_to: null + created: 2026-06-11 06:18:26+00:00 + updated: 2026-06-11 06:18:26+00:00 + spec: null + acceptance_criteria: + - 'North-star (user directive 2026-06-11). Whole ML lifecycle (classical -> DL -> fine-tune -> quantize + -> serve) in one safe-Rust binary, each stage beating the Python/C++ incumbent at its signature strength. + BEAT = a FALSIFIABLE benchmark (apr >= incumbent on its canonical task), not parity. Cross-cutting + differentiator: provable contract-gated correctness (none of the 4 have it). Pillars: PMAT-717 (sklearn), + PMAT-718 (PyTorch), PMAT-710 (Unsloth), PMAT-719 (Ollama/llama.cpp). Each pillar ships FALSIFY-BEAT-* + gates.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - mission + - four-pillars + - beat + notes: See memory project_mission_four_pillars. Detailed beat-targets land from the four-pillar beat-analysis + (in flight). +- id: PMAT-717 + github_issue: null + item_type: epic + title: 'Pillar 1: BEAT scikit-learn at classical ML (pure Rust) — fit/predict faster, same accuracy, + provably correct' + status: planned + priority: high + assigned_to: null + created: 2026-06-11 06:18:26+00:00 + updated: 2026-06-11 06:18:26+00:00 + spec: null + acceptance_criteria: + - 'aprender-core already has the TOP-10 classical-ML surface (Estimator/Transformer; LinearRegression/LogisticRegression/DecisionTree/RandomForest/GBM/NaiveBayes/KNN/SVM/KMeans/PCA + + model_selection + metrics). MOST-BUILT + MOST-WINNABLE pillar. Beat-benchmark FALSIFY-BEAT-SKLEARN: + fit+predict wall-clock <= sklearn AND accuracy within tol on standard datasets (iris/digits/california). + ROADMAP GAP: sklearn is NOT a tracked CRUX competitor — this pillar likely needs a new classical-ML + category. Mostly CPU-autonomous. Sub-targets from the beat-analysis.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - pillar-sklearn + - classical-ml + - beat + notes: null +- id: PMAT-718 + github_issue: null + item_type: epic + title: 'Pillar 2: BEAT PyTorch at tensors + autograd + training (bounded task: train-to-loss faster + / less memory)' + status: planned + priority: high + assigned_to: null + created: 2026-06-11 06:18:26+00:00 + updated: 2026-06-11 06:18:26+00:00 + spec: null + acceptance_criteria: + - 'HARDEST pillar (PyTorch moat = flexibility + ecosystem). Compute substrate = aprender-compute (trueno + SIMD/GPU) + aprender-train. Beat on the BOUNDED canonical task, not research flexibility: FALSIFY-BEAT-PYTORCH + = train a fixed small model to a target loss with apr <= time and/or <= peak memory. CPU-side pieces + (autograd correctness, op coverage, a CPU training benchmark) are loop-buildable; the perf run is + GPU (lambda-vector). Sub-targets from the beat-analysis.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - pillar-pytorch + - autograd + - beat + notes: null +- id: PMAT-719 + github_issue: null + item_type: epic + title: 'Pillar 4: BEAT Ollama/llama.cpp at local quantized inference — 1.5x decode tok/s AND provable + output-correctness' + status: planned + priority: high + assigned_to: null + created: 2026-06-11 06:18:26+00:00 + updated: 2026-06-11 06:18:26+00:00 + spec: null + acceptance_criteria: + - 'Their best: fast GGUF decode + simple pull/run UX. aprender perf-path already 440 tok/s vs ollama + 307 on 1.5B Q4_K_M (~1.43x; 1.5x = 460 tok/s target). TWO beat-benchmarks: (a) FALSIFY-BEAT-OLLAMA-PERF + = decode tok/s >= ollama at fixed quant (target 1.5x); (b) FALSIFY-BEAT-OLLAMA-CORRECT = provable + output/dequant correctness (the CRUX-M verify wall / Q2_K-class) that ollama+llama.cpp LACK. CRUX-M-02 + (PMAT-671, active) is the correctness leg. Sub-targets from the beat-analysis.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - pillar-ollama + - inference + - beat + notes: null +- id: PMAT-720 + github_issue: null + item_type: task + title: Add aprender::datasets module (load_iris, load_digits, load_california_housing via include_str! + + make_classification/make_blobs/make_regression/make… + status: planned + priority: critical + assigned_to: null + created: 2026-06-11 06:26:41+00:00 + updated: 2026-06-11 06:26:41+00:00 + spec: null + acceptance_criteria: + - 'Parent PMAT-717. Falsifier: datasets::load_digits() returns (1797,64) Matrix + 1797 labels in {0..9}; + load_iris() returns (150,4)+3 classes; checksums/shapes asserted in unit tests.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - pillar-sklearn + - beat + - cpu-autonomous + notes: four-pillar beat-analysis rank 1 +- id: PMAT-721 + github_issue: null + item_type: task + title: 'Falsify the LogisticRegression train_acc=0.505 observation: contract-gated test that LogReg + reaches >=0.95 train-acc on a margin-separable 2-class se…' + status: planned + priority: critical + assigned_to: null + created: 2026-06-11 06:26:41+00:00 + updated: 2026-06-11 06:26:41+00:00 + spec: null + acceptance_criteria: + - 'Parent PMAT-717. Falsifier: LogisticRegression on margin-separable synthetic reaches train_acc >= + 0.95 within 200 iters; currently observed 0.505 on overlapping data — confirm separable case passes + or fix converges.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - pillar-sklearn + - beat + - cpu-autonomous + notes: four-pillar beat-analysis rank 2 +- id: PMAT-722 + github_issue: null + item_type: task + title: Commit the head-to-head sklearn-beat bench harness (apr vs sklearn) on digits classification + + california regression, CSV/JSON out, CI-failing if apr… + status: planned + priority: critical + assigned_to: null + created: 2026-06-11 06:26:41+00:00 + updated: 2026-06-11 06:26:41+00:00 + spec: null + acceptance_criteria: + - 'Parent PMAT-717. Falsifier: apr RandomForestClassifier test_acc >= 0.96 on digits AND apr_walltime_ms + <= sklearn_walltime_ms; RandomForestRegressor R2 >= 0.78 on california. Fails CI otherwise.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - pillar-sklearn + - beat + - cpu-autonomous + notes: four-pillar beat-analysis rank 3 +- id: PMAT-723 + github_issue: null + item_type: task + title: 'Ship `apr qa --falsify` adversarial-corpus mode: bundle N>=5 deliberately-broken GGUF/APR artifacts + (corrupt quant block, NaN weights, transposed lm_…' + status: planned + priority: high + assigned_to: null + created: 2026-06-11 06:26:41+00:00 + updated: 2026-06-11 06:26:41+00:00 + spec: null + acceptance_criteria: + - 'Parent PMAT-719. Falsifier: On the 5-artifact corpus `apr qa --json` flags >=1 gate / exits + non-zero on 5/5; llama-cli/ollama exit 0 with garbage on 5/5. Differentiator FALSIFIED if apr false-passes + any OR an incumbent catches one.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - pillar-ollama + - beat + - cpu-autonomous + notes: four-pillar beat-analysis rank 4 +- id: PMAT-724 + github_issue: null + item_type: task + title: Add finite-difference gradient-correctness gate to core autograd as a proptest (perturb eps=1e-5, + assert max|analytic-numeric|<1e-3 over matmul/relu/… + status: planned + priority: high + assigned_to: null + created: 2026-06-11 06:26:41+00:00 + updated: 2026-06-11 06:26:41+00:00 + spec: null + acceptance_criteria: + - 'Parent PMAT-718. Falsifier: Any op whose analytic gradient deviates from numeric by >1e-3 fails the + gate; passing gate is the machine-checked correctness claim on the training benchmark.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - pillar-pytorch + - beat + - cpu-autonomous + notes: four-pillar beat-analysis rank 5 +- id: PMAT-725 + github_issue: null + item_type: task + title: 'Build the CPU training-time beat-benchmark harness: fixed 2-layer MLP + fixed N=1024 synthetic + regression, single-thread CPU, measure wall-clock-to-t…' + status: planned + priority: high + assigned_to: null + created: 2026-06-11 06:26:41+00:00 + updated: 2026-06-11 06:26:41+00:00 + spec: null + acceptance_criteria: + - 'Parent PMAT-718. Falsifier: apr reaches MSE<=0.05 on the fixed dataset within the fixed step budget + single-thread CPU; if it cannot converge the beat-claim is dead on arrival.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - pillar-pytorch + - beat + - cpu-autonomous + notes: four-pillar beat-analysis rank 6 +- id: PMAT-726 + github_issue: null + item_type: task + title: 'PMAT-711: wire QLoRALayer (4-bit NF4 base) into the InstructPipeline CPU train loop (currently + Vec f32 base, mod.rs:176); reuse the EXISTI…' + status: planned + priority: high + assigned_to: null + created: 2026-06-11 06:26:41+00:00 + updated: 2026-06-11 06:26:41+00:00 + spec: null + acceptance_criteria: + - 'Parent PMAT-710. Falsifier: Qwen2-0.5B q_proj block: NF4 round-trip mean-abs-error <= 1e-3 vs bitsandbytes + per 64-block; QLoRALayer 4-bit footprint <= 0.30x f16; loss monotone-decreasing over 20 CPU steps + on 16-sample fixture; cargo test -p aprender-train --lib lora:…' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - pillar-unsloth + - beat + - cpu-autonomous + notes: four-pillar beat-analysis rank 7 +- id: PMAT-727 + github_issue: null + item_type: task + title: 'PMAT-712: merge->GGUF as a contract-gated golden test — extend run_merge to optionally emit + GGUF, add #[contract] obligation that merged-GGUF forward…' + status: planned + priority: high + assigned_to: null + created: 2026-06-11 06:26:41+00:00 + updated: 2026-06-11 06:26:41+00:00 + spec: null + acceptance_criteria: + - 'Parent PMAT-710. Falsifier: Load merged GGUF in realizar, forward on 8 fixed inputs; max abs diff + vs in-memory base+scale*B@A < 1e-2; pv validate the new merge-export contract; fails if any tensor + diverges.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - pillar-unsloth + - beat + - cpu-autonomous + notes: four-pillar beat-analysis rank 8 +- id: PMAT-728 + github_issue: null + item_type: task + title: Run pinned PyTorch-CPU baseline (single OMP thread) on the IDENTICAL fixed MLP task; record wall-clock-to-target-loss + + peak RSS via /usr/bin/time -v… + status: planned + priority: high + assigned_to: null + created: 2026-06-11 06:26:41+00:00 + updated: 2026-06-11 06:26:41+00:00 + spec: null + acceptance_criteria: + - 'Parent PMAT-718. Falsifier: If apr wall-clock > PyTorch-CPU OR apr peak-RSS > PyTorch peak-RSS, the + beat is FALSIFIED and reported as such — no vibes.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - pillar-pytorch + - beat + - cpu-autonomous + notes: four-pillar beat-analysis rank 9 +- id: PMAT-729 + github_issue: null + item_type: task + title: Unify classifier API onto Estimator (or add a Classifier trait with y:&[usize]) so cross_validate/grid_search + work generically over LogReg/RF/GBM/SVM… + status: planned + priority: medium + assigned_to: null + created: 2026-06-11 06:26:41+00:00 + updated: 2026-06-11 06:26:41+00:00 + spec: null + acceptance_criteria: + - 'Parent PMAT-717. Falsifier: cross_validate::(...) compiles and returns 5-fold + CV accuracy on digits matching a manual KFold loop within 1e-4.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - pillar-sklearn + - beat + - cpu-autonomous + notes: four-pillar beat-analysis rank 10 +- id: PMAT-730 + github_issue: null + item_type: task + title: Add missing metrics roc_auc_score, log_loss, roc_curve, precision_recall_curve (VERIFIED ABSENT + everywhere) + GradientBoostingRegressor to complete t… + status: completed + priority: medium + assigned_to: null + created: 2026-06-11 06:26:41+00:00 + updated: 2026-06-11 06:26:41+00:00 + spec: null + acceptance_criteria: + - 'Parent PMAT-717. Falsifier: roc_auc_score on a known scored set matches sklearn within 1e-4; GradientBoostingRegressor + R2 on california >= 0.80.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - pillar-sklearn + - beat + - cpu-autonomous + notes: four-pillar beat-analysis rank 11 +- id: PMAT-731 + github_issue: null + item_type: task + title: 'PMAT-713: one-command `apr finetune --qlora --bits 4 --export gguf -o out.gguf` doing load->NF4-QLoRA->CPU-train->merge->export + on a tiny fixture (no…' + status: planned + priority: medium + assigned_to: null + created: 2026-06-11 06:26:41+00:00 + updated: 2026-06-11 06:26:41+00:00 + spec: null + acceptance_criteria: + - 'Parent PMAT-710. Falsifier: Single CLI call on 2-layer fixture .apr + 16-line JSONL produces a loadable + merged GGUF; apr qa out.gguf passes; final_loss < initial_loss; e2e integration test in apr-cli.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - pillar-unsloth + - beat + - cpu-autonomous + notes: four-pillar beat-analysis rank 12 +- id: PMAT-732 + github_issue: null + item_type: task + title: 'Wire apr-qa-differential-v1 ollama_parity into a real harness: `apr qa --differential --reference + llama.cpp` reporting top-1 agreement >=95% + ppl-ga…' + status: planned + priority: medium + assigned_to: null + created: 2026-06-11 06:26:41+00:00 + updated: 2026-06-11 06:26:41+00:00 + spec: null + acceptance_criteria: + - 'Parent PMAT-719. Falsifier: `apr qa model.apr --differential` reports top1-agreement + ppl-gap vs + llama.cpp on identical prompts, reproducible across 3 runs (CV<5%); falsified if agreement<95% (apr + decode wrong) or harness needs GPU.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - pillar-ollama + - beat + - cpu-autonomous + notes: four-pillar beat-analysis rank 13 +- id: PMAT-733 + github_issue: null + item_type: task + title: 'Add preprocessing encoders + sklearn-style Pipeline: OneHotEncoder, LabelEncoder, OrdinalEncoder, + PolynomialFeatures, SimpleImputer, Normalizer + Pip…' + status: completed + priority: medium + assigned_to: null + created: 2026-06-11 06:26:41+00:00 + updated: 2026-06-11 06:26:41+00:00 + spec: null + acceptance_criteria: + - 'Parent PMAT-717. Falsifier: Pipeline::new([StandardScaler, PCA(10)], LogisticRegression).fit(digits).score() + >= 0.92; OneHotEncoder on a 3-category column yields a 3-col one-hot matrix asserted element-wise.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - pillar-sklearn + - beat + - cpu-autonomous + notes: four-pillar beat-analysis rank 14 +- id: PMAT-734 + github_issue: null + item_type: task + title: 'PMAT-715: promote Unsloth from static const (score.rs:777) to a tracked competitor ROW in compute_training_step_scorecard + reporting apr/unsloth tok/s…' + status: planned + priority: low + assigned_to: null + created: 2026-06-11 06:26:41+00:00 + updated: 2026-06-11 06:26:41+00:00 + spec: null + acceptance_criteria: + - 'Parent PMAT-710. Falsifier: Fused-adapter forward == sum_i w_i*(scale_i*B_i@A_i@x) within 1e-5 (CPU); + scorecard JSON emits unsloth row + ratio (honest concession that ratio <1.0 on throughput).' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - pillar-unsloth + - beat + - cpu-autonomous + notes: four-pillar beat-analysis rank 15 +- id: PMAT-735 + github_issue: null + item_type: task + title: Add non-linear SVM (RBF/poly kernel SVC) — sklearn SVC's signature strength; current LinearSVM + cannot separate non-linear data. VERIFIED ABSENT (no … + status: completed + priority: low + assigned_to: null + created: 2026-06-11 06:26:41+00:00 + updated: 2026-06-11 06:26:41+00:00 + spec: null + acceptance_criteria: + - 'Parent PMAT-717. Falsifier: RBF-SVC on make_circles (non-linearly-separable) test_acc >= 0.95 where + LinearSVM scores ~0.50.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - pillar-sklearn + - beat + - cpu-autonomous + notes: four-pillar beat-analysis rank 16 +- id: PMAT-736 + github_issue: null + item_type: task + title: Publish a curated `apr registry` short-name catalog (`apr run qwen2.5-coder-1.5b` no URL) with + each entry carrying its `apr qa` verdict as a trust ba… + status: planned + priority: low + assigned_to: null + created: 2026-06-11 06:26:41+00:00 + updated: 2026-06-11 06:26:41+00:00 + spec: null + acceptance_criteria: + - 'Parent PMAT-719. Falsifier: `apr run qwen2.5-coder-1.5b` (bare short name, cold cache) downloads+runs+emits + coherent output AND `apr list` shows each entry''s qa-gate verdict; falsified if a short name doesn''t + resolve or catalog has no per-model correctness badge.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - pillar-ollama + - beat + - cpu-autonomous + notes: four-pillar beat-analysis rank 17 +- id: PMAT-737 + github_issue: null + item_type: task + title: '[GPU-GATED — flag] CPU Q4_K decode parity: implement ggml-style pre-interleaved Q4_K weight + layout at APR import (documented root cause, five-whys-16…' + status: completed + priority: low + assigned_to: null + created: 2026-06-11 06:26:41+00:00 + updated: 2026-07-05 10:43:56.195384+00:00 + spec: null + acceptance_criteria: + - 'Parent PMAT-719. Falsifier: `apr bench model.apr --device cpu` 5-iter median >= `llama-cli -n 128 + -t ` on SAME host, 1.5B Q4_K_M. Currently 9.9 vs 81 = 8.2x slower; clearing it is parity, + not superiority.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - pillar-ollama + - beat + - cpu-autonomous + notes: four-pillar beat-analysis rank 18 +- id: PMAT-738 + github_issue: null + item_type: task + title: '[GPU-GATED — NOT loop-buildable] Single-GPU QLoRA throughput run on lambda-vector to populate + apr-vs-unsloth tok/s bar (6715.7/13659.7) — measurement…' + status: planned + priority: low + assigned_to: null + created: 2026-06-11 06:26:41+00:00 + updated: 2026-06-11 06:26:41+00:00 + spec: null + acceptance_criteria: + - 'Parent PMAT-710. Falsifier: apr finetune --qlora --gpu-backend cuda reports tok/s + peak VRAM into + scorecard; expectation apr --json` 5-run median 128-tok decode >= 460.7 tok/s + (1.5x Ollama) vs current flat ~396; requires RTX-4090-class GPU.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - pillar-ollama + - beat + - gpu-gated + notes: four-pillar beat-analysis rank 20 +- id: PMAT-740 + github_issue: null + item_type: task + title: 'ROADMAP GAP: add a classical-ML (scikit-learn) competitor category (CRUX-S-*) to the CRUX matrix' + status: planned + priority: high + assigned_to: null + created: 2026-06-11 06:26:41+00:00 + updated: 2026-06-11 06:26:41+00:00 + spec: null + acceptance_criteria: + - sklearn is NOT in the CRUX competitor set (Ollama/llama.cpp/PyTorch/HF/vLLM/OpenCLAW). Add a CRUX-S + classical-ML story class so datasets/encoders/RBF-SVM/roc_auc/Pipeline gaps are tracked. Unblocks + Pillar 1 (PMAT-717). + phases: [] + subtasks: [] + estimated_effort: null + labels: + - pillar-sklearn + - roadmap-structure + notes: 'four-pillar beat-analysis roadmap gap #1' +- id: PMAT-741 + github_issue: null + item_type: task + title: 'ROADMAP GAP: add a beat-benchmark contract kind (committed head-to-head, CI-failing, baseline + pinned)' + status: planned + priority: high + assigned_to: null + created: 2026-06-11 06:26:41+00:00 + updated: 2026-06-11 06:26:41+00:00 + spec: null + acceptance_criteria: + - No contract schema for FALSIFY-BEAT-* (apr >= incumbent on canonical task, fails CI on regression, + incumbent baseline committed). Add the kind so every pillar beat-claim is a machine-checked artifact. + Core mission infra. + phases: [] + subtasks: [] + estimated_effort: null + labels: + - mission + - roadmap-structure + - beat + notes: 'four-pillar beat-analysis roadmap gap #2' +- id: PMAT-742 + github_issue: 2851 + item_type: task + title: 'PP-LLAMA-001 v3.1: land #2851 and cut 0.65.0 under the spec (batch fixes, #2849, publish + gate, dogfood GO, receipt)' + status: inprogress + priority: high + assigned_to: null + created: 2026-09-02 16:45:00+00:00 + updated: 2026-09-02 17:30:00+00:00 + spec: docs/specifications/PP-LLAMA-001-MASTER.md + acceptance_criteria: + - '#2851 merged green on ci / gate + workspace-test; release batch merged; #2849 merged' + - 'v0.65.0 tagged and released with the parity guide attached; crates.io cascade drained; post-publish + verification via the crates.io API' + - 'docs/audits/impl-PMAT-742-receipt.md written; transcript-gate PASS' + notes: 'paiml-implement run; jidoka entries in .pmat/jidoka.jsonl' +- id: PMAT-743 + github_issue: 2851 + item_type: bug + title: 'PMAT-742 jidoka: contract corpus integrity ratchet rose 444->445 on #2851 (pp-llama-001-spec-conformance-v1 test id 007A)' + status: completed + priority: high + assigned_to: null + created: 2026-09-02 17:05:00+00:00 + updated: 2026-09-02 17:20:00+00:00 + spec: null + acceptance_criteria: + - cargo test -p aprender-contracts --test validate_contracts green (integrity 444); ids 001..008 contiguous and unique (653f277d6) + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: five-whys in .pmat/jidoka.jsonl; proof:PR#2851 (653f277d6 renumbered the ids; the corpus-integrity test is green on main) +- id: PMAT-744 + github_issue: null + item_type: bug + title: 'perf_gate.sh --phase release cannot PASS while the reference cell is UNMEASURED: ArmC-sig and ArmD + fail the pre-v3 lambda receipt that the matrix already marks SPENT' + status: inprogress + priority: high + assigned_to: null + created: 2026-09-03 04:30:00+00:00 + updated: 2026-09-03 04:50:00+00:00 + spec: docs/specifications/PP-LLAMA-001-MASTER.md + acceptance_criteria: + - 'perf_gate.sh --host lambda --phase release --workload W1 --receipt evidence/perf-gate-001-w1-lambda/receipt.r1.json + --commit
is VERDICT PASS with ArmC-sig and ArmD as REPORT lines naming the UNMEASURED cell' + - 'four --selftest rows, both polarities; each condition of historical_for_unmeasured has a row that goes RED + without it; FALSIFY-PP-LLAMA-001-PERF-GATE-011; spec §6 names the cases' + notes: 'PMAT-742 jidoka entry 10; first run of the release phase (0.65.0 cut)' +- id: PMAT-745 + github_issue: null + item_type: bug + title: 'F-9: the crates.io cascade ran cargo publish --allow-dirty with no precondition; publishing must go only + through a preflight gate (clean tree, version from cargo metadata, tag at HEAD, HEAD on main, dogfood GO)' + status: inprogress + priority: high + assigned_to: null + created: 2026-09-03 07:10:00+00:00 + updated: 2026-09-03 07:20:00+00:00 + spec: docs/specifications/PP-LLAMA-001-MASTER.md + acceptance_criteria: + - 'scripts/check_publish_preflight.sh --selftest 16/16, both polarities of R1-R5; five must-fire mutations RED + (R1 dropped, GO check dropped, deferral whitelist shrunk, phase check dropped, grep -F removed); cascade-publish.sh + refuses on a non-zero gate, carries no dirty-tree override, and keeps its config backup outside the tree; + scripts/dogfood.sh --phase pre-publish records the two registry-bound rows as DEFER with their obligation, so R5 + is satisfiable before a cascade; ci.yml runs the case table; FALSIFY-PUB-CLI contract entry' + notes: 'PMAT-742 release rule F-9 (operator); a GitHub publish workflow is owed separately: no CARGO_REGISTRY_TOKEN + secret exists for the fleet, only PR_REVIEW_SIGNING_KEY_B64. Measured 2026-09-03: the full dogfood is NO-GO before + its own cascade by construction (publish-dry-run of a workspace root, cargo install of the unpublished version on + four hosts), which made the first R5 unsatisfiable; the pre-publish phase is the recorded, whitelisted answer' +- id: PMAT-750 + github_issue: null + item_type: task + title: 'SATD debt: crates/apr-cli/src/commands/finetune.rs:492 — export trained weights from the pipeline; for now the checkpoint dir is saved.' + status: planned + priority: medium + assigned_to: null + created: 2026-09-04 00:10:00+00:00 + updated: 2026-09-04 00:10:00+00:00 + spec: null + acceptance_criteria: + - 'the deferral at crates/apr-cli/src/commands/finetune.rs:492 is resolved and the comment removed' + notes: 'Minted by the PMAT-938 sweep (PR #2860); the marker text is kept in the comment, keyword-free' +- id: PMAT-751 + github_issue: null + item_type: task + title: 'SATD debt: crates/aprender-compute/src/backends/gpu/device/linalg/wgsl_forward.rs:774 — add upload_weight_transposed() for GPU-accelerated LM head.' + status: planned + priority: medium + assigned_to: null + created: 2026-09-04 00:10:00+00:00 + updated: 2026-09-04 00:10:00+00:00 + spec: null + acceptance_criteria: + - 'the deferral at crates/aprender-compute/src/backends/gpu/device/linalg/wgsl_forward.rs:774 is resolved and the comment removed' + notes: 'Minted by the PMAT-938 sweep (PR #2860); the marker text is kept in the comment, keyword-free' +- id: PILLAR1-001 + github_issue: null + item_type: task + title: cross_val_score (model_selection) + status: planned + priority: high + assigned_to: null + created: 2026-06-11 21:40:00+00:00 + updated: 2026-06-11 21:40:00+00:00 + spec: null + acceptance_criteria: + - 'Falsifier: cross_val_score(LinearRegression, X, y, cv=5) returns a Vec of 5 scores matching + cross_validate().scores within 1e-5' + phases: [] + subtasks: [] + estimated_effort: S + labels: + - mission + - pillar-1 + - sklearn-parity + - metric + notes: 'gap-map rank #1 (value 4, effort S); falsified vs sklearn' +- id: PILLAR1-002 + github_issue: null + item_type: task + title: KNeighborsRegressor (neighbors) + status: planned + priority: high + assigned_to: null + created: 2026-06-11 21:40:00+00:00 + updated: 2026-06-11 21:40:00+00:00 + spec: null + acceptance_criteria: + - 'Falsifier: apr KNeighborsRegressor.fit/predict match sklearn.neighbors.KNeighborsRegressor within + 1e-5 MSE on iris/boston test sets' + phases: [] + subtasks: [] + estimated_effort: S + labels: + - mission + - pillar-1 + - sklearn-parity + - estimator_impl + notes: 'gap-map rank #2 (value 4, effort S); falsified vs sklearn' +- id: PILLAR1-003 + github_issue: null + item_type: task + title: GaussianNB Estimator trait impl (naive_bayes) + status: planned + priority: high + assigned_to: null + created: 2026-06-11 21:40:00+00:00 + updated: 2026-06-11 21:40:00+00:00 + spec: null + acceptance_criteria: + - 'Falsifier: impl Estimator for GaussianNB (fit(&Matrix,&Vector), predict()->Vector, + score()->accuracy); cross_validate::(...) compiles and matches direct-call predictions + on iris' + phases: [] + subtasks: [] + estimated_effort: S + labels: + - mission + - pillar-1 + - sklearn-parity + - estimator_impl + notes: 'gap-map rank #3 (value 4, effort S); falsified vs sklearn' +- id: PILLAR1-004 + github_issue: null + item_type: task + title: KNearestNeighbors Estimator trait impl (neighbors) + status: planned + priority: high + assigned_to: null + created: 2026-06-11 21:40:00+00:00 + updated: 2026-06-11 21:40:00+00:00 + spec: null + acceptance_criteria: + - 'Falsifier: impl Estimator for KNearestNeighbors (fit(&Matrix,&Vector) not &[usize]); cross_validate::(...) + compiles and runs on iris' + phases: [] + subtasks: [] + estimated_effort: S + labels: + - mission + - pillar-1 + - sklearn-parity + - estimator_impl + notes: 'gap-map rank #4 (value 4, effort S); falsified vs sklearn' +- id: PILLAR1-005 + github_issue: null + item_type: task + title: LogisticRegression Estimator trait impl (linear_model) + status: completed + priority: high + assigned_to: null + created: 2026-06-11 21:40:00+00:00 + updated: 2026-06-11 21:40:00+00:00 + spec: null + acceptance_criteria: + - 'Falsifier: impl Estimator for LogisticRegression with &Vector signatures; cross_validate/grid_search + on iris binary classification compiles and yields >0.95 accuracy matching sklearn' + phases: [] + subtasks: [] + estimated_effort: S + labels: + - mission + - pillar-1 + - sklearn-parity + - estimator_impl + notes: 'gap-map rank #5 (value 3, effort S); falsified vs sklearn' +- id: PILLAR1-006 + github_issue: null + item_type: task + title: DecisionTreeClassifier Estimator trait impl (tree) + status: completed + priority: high + assigned_to: null + created: 2026-06-11 21:40:00+00:00 + updated: 2026-06-11 21:40:00+00:00 + spec: null + acceptance_criteria: + - 'Falsifier: impl Estimator for DecisionTreeClassifier; cross_validate::(...) + compiles and runs on iris with accuracy parity to sklearn.tree.DecisionTreeClassifier' + phases: [] + subtasks: [] + estimated_effort: S + labels: + - mission + - pillar-1 + - sklearn-parity + - estimator_impl + notes: 'gap-map rank #6 (value 3, effort S); falsified vs sklearn' +- id: PILLAR1-007 + github_issue: null + item_type: task + title: DecisionTreeRegressor Estimator trait impl (tree) + status: planned + priority: high + assigned_to: null + created: 2026-06-11 21:40:00+00:00 + updated: 2026-06-11 21:40:00+00:00 + spec: null + acceptance_criteria: + - 'Falsifier: impl Estimator for DecisionTreeRegressor; cross_validate::(...) + compiles and runs, R² within 1e-3 of sklearn on california_housing' + phases: [] + subtasks: [] + estimated_effort: S + labels: + - mission + - pillar-1 + - sklearn-parity + - estimator_impl + notes: 'gap-map rank #7 (value 3, effort S); falsified vs sklearn' +- id: PILLAR1-008 + github_issue: null + item_type: task + title: RandomForestRegressor Estimator trait impl (ensemble) + status: planned + priority: high + assigned_to: null + created: 2026-06-11 21:40:00+00:00 + updated: 2026-06-11 21:40:00+00:00 + spec: null + acceptance_criteria: + - 'Falsifier: impl Estimator for RandomForestRegressor (like RFC); cross_validate compiles, R² within + 1e-3 of sklearn on wine dataset' + phases: [] + subtasks: [] + estimated_effort: S + labels: + - mission + - pillar-1 + - sklearn-parity + - estimator_impl + notes: 'gap-map rank #8 (value 3, effort S); falsified vs sklearn' +- id: PILLAR1-009 + github_issue: null + item_type: task + title: GradientBoostingClassifier Estimator trait impl (ensemble) + status: planned + priority: high + assigned_to: null + created: 2026-06-11 21:40:00+00:00 + updated: 2026-06-11 21:40:00+00:00 + spec: null + acceptance_criteria: + - 'Falsifier: impl Estimator for GradientBoostingClassifier; cross_validate::(...) + compiles, accuracy parity on iris 3-class' + phases: [] + subtasks: [] + estimated_effort: S + labels: + - mission + - pillar-1 + - sklearn-parity + - estimator_impl + notes: 'gap-map rank #9 (value 3, effort S); falsified vs sklearn' +- id: PILLAR1-010 + github_issue: null + item_type: task + title: LinearSVM Estimator trait impl (classification.svm) + status: planned + priority: high + assigned_to: null + created: 2026-06-11 21:40:00+00:00 + updated: 2026-06-11 21:40:00+00:00 + spec: null + acceptance_criteria: + - 'Falsifier: impl Estimator for LinearSVM; cross_validate(LinearSVM, X, y, kfold) runs without error + and score() matches np.mean(pred==y)' + phases: [] + subtasks: [] + estimated_effort: S + labels: + - mission + - pillar-1 + - sklearn-parity + - estimator_impl + notes: 'gap-map rank #10 (value 3, effort S); falsified vs sklearn' +- id: PILLAR1-011 + github_issue: null + item_type: task + title: score() method on LinearSVM (classification.svm) + status: planned + priority: medium + assigned_to: null + created: 2026-06-11 21:40:00+00:00 + updated: 2026-06-11 21:40:00+00:00 + spec: null + acceptance_criteria: + - 'Falsifier: svm.score(X_test, y_test) == np.mean(predictions == y_test) within 1e-6' + phases: [] + subtasks: [] + estimated_effort: S + labels: + - mission + - pillar-1 + - sklearn-parity + - metric + notes: 'gap-map rank #11 (value 2, effort S); falsified vs sklearn' +- id: PILLAR1-012 + github_issue: null + item_type: task + title: predict_proba for DecisionTreeClassifier (tree) + status: planned + priority: high + assigned_to: null + created: 2026-06-11 21:40:00+00:00 + updated: 2026-06-11 21:40:00+00:00 + spec: null + acceptance_criteria: + - 'Falsifier: apr DecisionTreeClassifier.predict_proba() sums to 1.0 and matches sklearn leaf class + proportions on iris within 1e-5' + phases: [] + subtasks: [] + estimated_effort: S + labels: + - mission + - pillar-1 + - sklearn-parity + - estimator_impl + notes: 'gap-map rank #12 (value 3, effort S); falsified vs sklearn' +- id: PILLAR1-013 + github_issue: null + item_type: task + title: min_samples_split for DecisionTreeClassifier (tree) + status: planned + priority: high + assigned_to: null + created: 2026-06-11 21:40:00+00:00 + updated: 2026-06-11 21:40:00+00:00 + spec: null + acceptance_criteria: + - 'Falsifier: apr DecisionTreeClassifier.with_min_samples_split(N) matches sklearn output (splits/leaves) + on iris dataset' + phases: [] + subtasks: [] + estimated_effort: S + labels: + - mission + - pillar-1 + - sklearn-parity + - estimator_impl + notes: 'gap-map rank #13 (value 3, effort S); falsified vs sklearn' +- id: PILLAR1-014 + github_issue: null + item_type: task + title: min_samples_leaf for DecisionTreeClassifier (tree) + status: planned + priority: high + assigned_to: null + created: 2026-06-11 21:40:00+00:00 + updated: 2026-06-11 21:40:00+00:00 + spec: null + acceptance_criteria: + - 'Falsifier: apr DecisionTreeClassifier.with_min_samples_leaf(N) prevents overfitting on synthetic + 10-sample dataset matching sklearn' + phases: [] + subtasks: [] + estimated_effort: S + labels: + - mission + - pillar-1 + - sklearn-parity + - estimator_impl + notes: 'gap-map rank #14 (value 3, effort S); falsified vs sklearn' +- id: PILLAR1-015 + github_issue: null + item_type: task + title: PCA explained_variance attributes (decomposition) + status: planned + priority: medium + assigned_to: null + created: 2026-06-11 21:40:00+00:00 + updated: 2026-06-11 21:40:00+00:00 + spec: null + acceptance_criteria: + - 'Falsifier: PCA.explained_variance() and explained_variance_ratio() publicly accessible and match + sklearn within 1e-4 across multiple test datasets' + phases: [] + subtasks: [] + estimated_effort: S + labels: + - mission + - pillar-1 + - sklearn-parity + - estimator_impl + notes: 'gap-map rank #15 (value 2, effort S); falsified vs sklearn' +- id: PILLAR1-016 + github_issue: null + item_type: task + title: ICA Transformer trait impl (decomposition) + status: planned + priority: medium + assigned_to: null + created: 2026-06-11 21:40:00+00:00 + updated: 2026-06-11 21:40:00+00:00 + spec: null + acceptance_criteria: + - 'Falsifier: impl Transformer for ICA in decomposition/ica.rs; enables use in generic cross_validate/grid_search + pipelines' + phases: [] + subtasks: [] + estimated_effort: S + labels: + - mission + - pillar-1 + - sklearn-parity + - estimator_impl + notes: 'gap-map rank #16 (value 2, effort S); falsified vs sklearn' +- id: PILLAR1-017 + github_issue: null + item_type: task + title: LocalOutlierFactor UnsupervisedEstimator trait (cluster) + status: planned + priority: medium + assigned_to: null + created: 2026-06-11 21:40:00+00:00 + updated: 2026-06-11 21:40:00+00:00 + spec: null + acceptance_criteria: + - 'Falsifier: impl UnsupervisedEstimator (Labels=Vec) for LocalOutlierFactor; cross_validate_unsupervised + accepts it' + phases: [] + subtasks: [] + estimated_effort: S + labels: + - mission + - pillar-1 + - sklearn-parity + - estimator_impl + notes: 'gap-map rank #17 (value 2, effort S); falsified vs sklearn' +- id: PILLAR1-018 + github_issue: null + item_type: task + title: IsolationForest UnsupervisedEstimator trait (cluster) + status: planned + priority: medium + assigned_to: null + created: 2026-06-11 21:40:00+00:00 + updated: 2026-06-11 21:40:00+00:00 + spec: null + acceptance_criteria: + - 'Falsifier: impl UnsupervisedEstimator (Labels=Vec) for IsolationForest; cross_validate_unsupervised + accepts it' + phases: [] + subtasks: [] + estimated_effort: S + labels: + - mission + - pillar-1 + - sklearn-parity + - estimator_impl + notes: 'gap-map rank #18 (value 2, effort S); falsified vs sklearn' +- id: PILLAR1-019 + github_issue: null + item_type: task + title: MaxAbsScaler (preprocessing) + status: planned + priority: medium + assigned_to: null + created: 2026-06-11 21:40:00+00:00 + updated: 2026-06-11 21:40:00+00:00 + spec: null + acceptance_criteria: + - 'Falsifier: apr MaxAbsScaler.fit_transform(data) output matches sklearn.preprocessing.MaxAbsScaler + within 1e-5 on random test matrix' + phases: [] + subtasks: [] + estimated_effort: S + labels: + - mission + - pillar-1 + - sklearn-parity + - preprocessing + notes: 'gap-map rank #19 (value 2, effort S); falsified vs sklearn' +- id: PILLAR1-020 + github_issue: null + item_type: task + title: Normalizer (preprocessing) + status: planned + priority: medium + assigned_to: null + created: 2026-06-11 21:40:00+00:00 + updated: 2026-06-11 21:40:00+00:00 + spec: null + acceptance_criteria: + - 'Falsifier: apr Normalizer(norm=l2).fit_transform output matches sklearn.preprocessing.Normalizer + within 1e-5' + phases: [] + subtasks: [] + estimated_effort: S + labels: + - mission + - pillar-1 + - sklearn-parity + - preprocessing + notes: 'gap-map rank #20 (value 2, effort S); falsified vs sklearn' +- id: PILLAR1-021 + github_issue: null + item_type: task + title: LabelEncoder (preprocessing) + status: planned + priority: high + assigned_to: null + created: 2026-06-11 21:40:00+00:00 + updated: 2026-06-11 21:40:00+00:00 + spec: null + acceptance_criteria: + - 'Falsifier: apr LabelEncoder.fit_transform([A,B,C,A]) returns [0,1,2,0] matching sklearn.preprocessing.LabelEncoder' + phases: [] + subtasks: [] + estimated_effort: S + labels: + - mission + - pillar-1 + - sklearn-parity + - preprocessing + notes: 'gap-map rank #21 (value 3, effort S); falsified vs sklearn' +- id: PILLAR1-022 + github_issue: null + item_type: task + title: cohen_kappa_score (metrics) + status: planned + priority: medium + assigned_to: null + created: 2026-06-11 21:40:00+00:00 + updated: 2026-06-11 21:40:00+00:00 + spec: null + acceptance_criteria: + - 'Falsifier: match sklearn.metrics.cohen_kappa_score within 1e-4 on multiclass confusion matrix' + phases: [] + subtasks: [] + estimated_effort: S + labels: + - mission + - pillar-1 + - sklearn-parity + - metric + notes: 'gap-map rank #22 (value 2, effort S); falsified vs sklearn' +- id: PILLAR1-023 + github_issue: null + item_type: task + title: hamming_loss (metrics) + status: planned + priority: medium + assigned_to: null + created: 2026-06-11 21:40:00+00:00 + updated: 2026-06-11 21:40:00+00:00 + spec: null + acceptance_criteria: + - 'Falsifier: match sklearn.metrics.hamming_loss as (n_mismatches / n_samples) within 1e-6' + phases: [] + subtasks: [] + estimated_effort: S + labels: + - mission + - pillar-1 + - sklearn-parity + - metric + notes: 'gap-map rank #23 (value 2, effort S); falsified vs sklearn' +- id: PILLAR1-024 + github_issue: null + item_type: task + title: jaccard_score (metrics) + status: planned + priority: medium + assigned_to: null + created: 2026-06-11 21:40:00+00:00 + updated: 2026-06-11 21:40:00+00:00 + spec: null + acceptance_criteria: + - 'Falsifier: match sklearn.metrics.jaccard_score(average=macro/micro/weighted) within 1e-4' + phases: [] + subtasks: [] + estimated_effort: S + labels: + - mission + - pillar-1 + - sklearn-parity + - metric + notes: 'gap-map rank #24 (value 2, effort S); falsified vs sklearn' +- id: PILLAR1-025 + github_issue: null + item_type: task + title: fbeta_score (metrics) + status: planned + priority: medium + assigned_to: null + created: 2026-06-11 21:40:00+00:00 + updated: 2026-06-11 21:40:00+00:00 + spec: null + acceptance_criteria: + - 'Falsifier: match sklearn.metrics.fbeta_score(beta in [0.5,1.0,2.0], average=...) within 1e-4' + phases: [] + subtasks: [] + estimated_effort: S + labels: + - mission + - pillar-1 + - sklearn-parity + - metric + notes: 'gap-map rank #25 (value 2, effort S); falsified vs sklearn' +- id: PILLAR1-026 + github_issue: null + item_type: task + title: explained_variance_score (metrics) + status: planned + priority: medium + assigned_to: null + created: 2026-06-11 21:40:00+00:00 + updated: 2026-06-11 21:40:00+00:00 + spec: null + acceptance_criteria: + - 'Falsifier: match sklearn.metrics.explained_variance_score(y_true, y_pred) within 1e-4 (lift from + PCA module into metrics)' + phases: [] + subtasks: [] + estimated_effort: S + labels: + - mission + - pillar-1 + - sklearn-parity + - metric + notes: 'gap-map rank #26 (value 2, effort S); falsified vs sklearn' +- id: PILLAR1-027 + github_issue: null + item_type: task + title: max_error (metrics) + status: planned + priority: medium + assigned_to: null + created: 2026-06-11 21:40:00+00:00 + updated: 2026-06-11 21:40:00+00:00 + spec: null + acceptance_criteria: + - 'Falsifier: match sklearn.metrics.max_error as max(|y_true - y_pred|) within 1e-5' + phases: [] + subtasks: [] + estimated_effort: S + labels: + - mission + - pillar-1 + - sklearn-parity + - metric + notes: 'gap-map rank #27 (value 1, effort S); falsified vs sklearn' +- id: PILLAR1-028 + github_issue: null + item_type: task + title: median_absolute_error (metrics) + status: planned + priority: medium + assigned_to: null + created: 2026-06-11 21:40:00+00:00 + updated: 2026-06-11 21:40:00+00:00 + spec: null + acceptance_criteria: + - 'Falsifier: match sklearn.metrics.median_absolute_error as median(|y_true - y_pred|) within 1e-4' + phases: [] + subtasks: [] + estimated_effort: S + labels: + - mission + - pillar-1 + - sklearn-parity + - metric + notes: 'gap-map rank #28 (value 1, effort S); falsified vs sklearn' +- id: PILLAR1-029 + github_issue: null + item_type: task + title: mean_squared_log_error (metrics) + status: planned + priority: medium + assigned_to: null + created: 2026-06-11 21:40:00+00:00 + updated: 2026-06-11 21:40:00+00:00 + spec: null + acceptance_criteria: + - 'Falsifier: match sklearn.metrics.mean_squared_log_error within 1e-4 on positive-valued regression + oracle' + phases: [] + subtasks: [] + estimated_effort: S + labels: + - mission + - pillar-1 + - sklearn-parity + - metric + notes: 'gap-map rank #29 (value 1, effort S); falsified vs sklearn' +- id: PILLAR1-030 + github_issue: null + item_type: task + title: mean_absolute_percentage_error (metrics) + status: planned + priority: medium + assigned_to: null + created: 2026-06-11 21:40:00+00:00 + updated: 2026-06-11 21:40:00+00:00 + spec: null + acceptance_criteria: + - 'Falsifier: match sklearn.metrics.mean_absolute_percentage_error within 1e-4 on non-zero y_true' + phases: [] + subtasks: [] + estimated_effort: S + labels: + - mission + - pillar-1 + - sklearn-parity + - metric + notes: 'gap-map rank #30 (value 1, effort S); falsified vs sklearn' +- id: PILLAR1-031 + github_issue: null + item_type: task + title: davies_bouldin_score (metrics) + status: planned + priority: medium + assigned_to: null + created: 2026-06-11 21:40:00+00:00 + updated: 2026-06-11 21:40:00+00:00 + spec: null + acceptance_criteria: + - 'Falsifier: apr davies_bouldin_score(X, labels) within 1e-3 of sklearn.metrics.davies_bouldin_score + on pinned iris dataset' + phases: [] + subtasks: [] + estimated_effort: S + labels: + - mission + - pillar-1 + - sklearn-parity + - metric + notes: 'gap-map rank #31 (value 2, effort S); falsified vs sklearn' +- id: PILLAR1-032 + github_issue: null + item_type: task + title: calinski_harabasz_score (cluster) + status: planned + priority: medium + assigned_to: null + created: 2026-06-11 21:40:00+00:00 + updated: 2026-06-11 21:40:00+00:00 + spec: null + acceptance_criteria: + - 'Falsifier: apr calinski_harabasz_score(X, labels) within 1e-4 of sklearn.metrics.calinski_harabasz_score + on pinned iris dataset' + phases: [] + subtasks: [] + estimated_effort: S + labels: + - mission + - pillar-1 + - sklearn-parity + - metric + notes: 'gap-map rank #32 (value 2, effort S); falsified vs sklearn' +- id: PILLAR1-033 + github_issue: null + item_type: task + title: adjusted_rand_score (metrics) + status: planned + priority: medium + assigned_to: null + created: 2026-06-11 21:40:00+00:00 + updated: 2026-06-11 21:40:00+00:00 + spec: null + acceptance_criteria: + - 'Falsifier: apr adjusted_rand_score(y_true, y_pred) matches sklearn.metrics.adjusted_rand_score exactly + on synthetic test cases' + phases: [] + subtasks: [] + estimated_effort: S + labels: + - mission + - pillar-1 + - sklearn-parity + - metric + notes: 'gap-map rank #33 (value 2, effort S); falsified vs sklearn' +- id: PILLAR1-034 + github_issue: null + item_type: task + title: silhouette_samples (cluster) + status: planned + priority: medium + assigned_to: null + created: 2026-06-11 21:40:00+00:00 + updated: 2026-06-11 21:40:00+00:00 + spec: null + acceptance_criteria: + - 'Falsifier: apr silhouette_samples(X, labels) returns Vec of len(X), mean equals silhouette_score() + within 1e-5' + phases: [] + subtasks: [] + estimated_effort: S + labels: + - mission + - pillar-1 + - sklearn-parity + - metric + notes: 'gap-map rank #34 (value 1, effort S); falsified vs sklearn' +- id: PILLAR1-035 + github_issue: null + item_type: task + title: min_impurity_decrease parameter (tree) + status: planned + priority: medium + assigned_to: null + created: 2026-06-11 21:40:00+00:00 + updated: 2026-06-11 21:40:00+00:00 + spec: null + acceptance_criteria: + - 'Falsifier: apr tree.with_min_impurity_decrease(0.01) produces fewer splits than sklearn baseline + on noisy data' + phases: [] + subtasks: [] + estimated_effort: S + labels: + - mission + - pillar-1 + - sklearn-parity + - estimator_impl + notes: 'gap-map rank #35 (value 2, effort S); falsified vs sklearn' +- id: PILLAR1-036 + github_issue: null + item_type: task + title: KNN weights=distance parameter (neighbors) + status: planned + priority: medium + assigned_to: null + created: 2026-06-11 21:40:00+00:00 + updated: 2026-06-11 21:40:00+00:00 + spec: null + acceptance_criteria: + - 'Falsifier: apr KNN with weights=distance matches sklearn output within 1e-5 on separable test data' + phases: [] + subtasks: [] + estimated_effort: S + labels: + - mission + - pillar-1 + - sklearn-parity + - preprocessing + notes: 'gap-map rank #36 (value 2, effort S); falsified vs sklearn' +- id: PILLAR1-037 + github_issue: null + item_type: task + title: make_pipeline (pipeline_compose) + status: planned + priority: medium + assigned_to: null + created: 2026-06-11 21:40:00+00:00 + updated: 2026-06-11 21:40:00+00:00 + spec: null + acceptance_criteria: + - 'Falsifier: make_pipeline(StandardScaler(), LinearRegression()) produces identical results to manual + Pipeline construction' + phases: [] + subtasks: [] + estimated_effort: S + labels: + - mission + - pillar-1 + - sklearn-parity + - algorithm + notes: 'gap-map rank #37 (value 2, effort S); falsified vs sklearn' +- id: PILLAR1-038 + github_issue: null + item_type: task + title: ShuffleSplit (model_selection) + status: planned + priority: high + assigned_to: null + created: 2026-06-11 21:40:00+00:00 + updated: 2026-06-11 21:40:00+00:00 + spec: null + acceptance_criteria: + - 'Falsifier: ShuffleSplit(n_splits=5, test_size=0.2).split(100) returns 5 folds with 20 test/80 train + each, distinct random indices per fold' + phases: [] + subtasks: [] + estimated_effort: S + labels: + - mission + - pillar-1 + - sklearn-parity + - algorithm + notes: 'gap-map rank #38 (value 3, effort S); falsified vs sklearn' +- id: PILLAR1-039 + github_issue: null + item_type: task + title: LeaveOneOut (model_selection) + status: planned + priority: medium + assigned_to: null + created: 2026-06-11 21:40:00+00:00 + updated: 2026-06-11 21:40:00+00:00 + spec: null + acceptance_criteria: + - 'Falsifier: LeaveOneOut.split(n_samples=5) returns 5 folds, each with 1 test sample and n-1 train + samples' + phases: [] + subtasks: [] + estimated_effort: S + labels: + - mission + - pillar-1 + - sklearn-parity + - algorithm + notes: 'gap-map rank #39 (value 2, effort S); falsified vs sklearn' +- id: PILLAR1-040 + github_issue: null + item_type: task + title: Naive Bayes alpha (Laplace smoothing) parameter (naive_bayes) + status: planned + priority: medium + assigned_to: null + created: 2026-06-11 21:40:00+00:00 + updated: 2026-06-11 21:40:00+00:00 + spec: null + acceptance_criteria: + - 'Falsifier: expose alpha in GaussianNB/MultinomialNB/BernoulliNB; alpha=0 unsmoothed, alpha=1.0 matches + sklearn default on text classification' + phases: [] + subtasks: [] + estimated_effort: S + labels: + - mission + - pillar-1 + - sklearn-parity + - algorithm + notes: 'gap-map rank #40 (value 2, effort S); falsified vs sklearn' +- id: PILLAR1-041 + github_issue: null + item_type: task + title: GridSearchCV (model_selection) + status: planned + priority: high + assigned_to: null + created: 2026-06-11 21:40:00+00:00 + updated: 2026-06-11 21:40:00+00:00 + spec: null + acceptance_criteria: + - 'Falsifier: GridSearchCV on Ridge alpha=[0.01,0.1,1.0,10.0] matches sklearn.GridSearchCV best_alpha + and best_score within 1e-3 on synthetic data; generic param_grid + step__param naming' + phases: [] + subtasks: [] + estimated_effort: M + labels: + - mission + - pillar-1 + - sklearn-parity + - model_selection + notes: 'gap-map rank #41 (value 5, effort M); falsified vs sklearn' +- id: PILLAR1-042 + github_issue: null + item_type: task + title: GradientBoostingRegressor (ensemble) + status: planned + priority: high + assigned_to: null + created: 2026-06-11 21:40:00+00:00 + updated: 2026-06-11 21:40:00+00:00 + spec: null + acceptance_criteria: + - 'Falsifier: fit on boston housing, MSE within 5% of sklearn.ensemble.GradientBoostingRegressor (n_estimators=100, + lr=0.1); fit time < sklearn on same CPU' + phases: [] + subtasks: [] + estimated_effort: M + labels: + - mission + - pillar-1 + - sklearn-parity + - algorithm + notes: 'gap-map rank #42 (value 4, effort M); falsified vs sklearn' +- id: PILLAR1-043 + github_issue: null + item_type: task + title: OneHotEncoder (preprocessing) + status: planned + priority: high + assigned_to: null + created: 2026-06-11 21:40:00+00:00 + updated: 2026-06-11 21:40:00+00:00 + spec: null + acceptance_criteria: + - 'Falsifier: apr OneHotEncoder.fit_transform(categorical_data) output shape and sparsity matches sklearn.preprocessing.OneHotEncoder + on iris.target' + phases: [] + subtasks: [] + estimated_effort: M + labels: + - mission + - pillar-1 + - sklearn-parity + - preprocessing + notes: 'gap-map rank #43 (value 4, effort M); falsified vs sklearn' +- id: PILLAR1-044 + github_issue: null + item_type: task + title: TruncatedSVD (decomposition) + status: planned + priority: high + assigned_to: null + created: 2026-06-11 21:40:00+00:00 + updated: 2026-06-11 21:40:00+00:00 + spec: null + acceptance_criteria: + - 'Falsifier: apr TruncatedSVD(k) fit/transform match sklearn.decomposition.TruncatedSVD within 1e-3 + L2 error on pinned (200,100) matrix with known singular values' + phases: [] + subtasks: [] + estimated_effort: M + labels: + - mission + - pillar-1 + - sklearn-parity + - algorithm + notes: 'gap-map rank #44 (value 4, effort M); falsified vs sklearn' +- id: PILLAR1-045 + github_issue: null + item_type: task + title: NMF (decomposition) + status: planned + priority: high + assigned_to: null + created: 2026-06-11 21:40:00+00:00 + updated: 2026-06-11 21:40:00+00:00 + spec: null + acceptance_criteria: + - 'Falsifier: apr NMF reconstruction error within 1e-2 of sklearn.decomposition.NMF after 200 iterations + on same (n_samples,n_features) with n_components=rank' + phases: [] + subtasks: [] + estimated_effort: M + labels: + - mission + - pillar-1 + - sklearn-parity + - algorithm + notes: 'gap-map rank #45 (value 4, effort M); falsified vs sklearn' +- id: PILLAR1-046 + github_issue: null + item_type: task + title: MultinomialNB (naive_bayes) + status: planned + priority: high + assigned_to: null + created: 2026-06-11 21:40:00+00:00 + updated: 2026-06-11 21:40:00+00:00 + spec: null + acceptance_criteria: + - 'Falsifier: fit/predict on count matrices; match sklearn.naive_bayes.MultinomialNB on 20-newsgroups-subset + TF data within 2% accuracy; <100ms on 1000x100 sparse' + phases: [] + subtasks: [] + estimated_effort: M + labels: + - mission + - pillar-1 + - sklearn-parity + - estimator_impl + notes: 'gap-map rank #46 (value 4, effort M); falsified vs sklearn' +- id: PILLAR1-047 + github_issue: null + item_type: task + title: Pipeline (ML composition) (pipeline_compose) + status: planned + priority: high + assigned_to: null + created: 2026-06-11 21:40:00+00:00 + updated: 2026-06-11 21:40:00+00:00 + spec: null + acceptance_criteria: + - 'Falsifier: Pipeline([(scaler,StandardScaler()),(model,LinearRegression())]) on iris_regression matches + sklearn Pipeline predictions within 1e-4 MSE' + phases: [] + subtasks: [] + estimated_effort: M + labels: + - mission + - pillar-1 + - sklearn-parity + - algorithm + notes: 'gap-map rank #47 (value 4, effort M); falsified vs sklearn' +- id: PILLAR1-048 + github_issue: null + item_type: task + title: learning_curve (model_selection) + status: planned + priority: high + assigned_to: null + created: 2026-06-11 21:40:00+00:00 + updated: 2026-06-11 21:40:00+00:00 + spec: null + acceptance_criteria: + - 'Falsifier: learning_curve(LinearRegression, X, y, train_sizes=[0.1,0.3,0.5,0.7,0.9]) train_scores/val_scores + match sklearn.learning_curve within 1e-2 on boston' + phases: [] + subtasks: [] + estimated_effort: M + labels: + - mission + - pillar-1 + - sklearn-parity + - metric + notes: 'gap-map rank #48 (value 4, effort M); falsified vs sklearn' +- id: PILLAR1-049 + github_issue: null + item_type: task + title: validation_curve (model_selection) + status: planned + priority: high + assigned_to: null + created: 2026-06-11 21:40:00+00:00 + updated: 2026-06-11 21:40:00+00:00 + spec: null + acceptance_criteria: + - 'Falsifier: validation_curve(Ridge, X, y, param_name=alpha, param_range=[0.01,0.1,1.0,10.0]) matches + sklearn.validation_curve output within 1e-2' + phases: [] + subtasks: [] + estimated_effort: M + labels: + - mission + - pillar-1 + - sklearn-parity + - metric + notes: 'gap-map rank #49 (value 4, effort M); falsified vs sklearn' +- id: PILLAR1-050 + github_issue: null + item_type: task + title: RandomizedSearchCV (model_selection) + status: planned + priority: high + assigned_to: null + created: 2026-06-11 21:40:00+00:00 + updated: 2026-06-11 21:40:00+00:00 + spec: null + acceptance_criteria: + - 'Falsifier: RandomizedSearchCV on LogisticRegression {C:[0.1,1,10], solver:[lbfgs,saga]} finds score + within 0.01 of grid search on digits dataset' + phases: [] + subtasks: [] + estimated_effort: M + labels: + - mission + - pillar-1 + - sklearn-parity + - model_selection + notes: 'gap-map rank #50 (value 4, effort M); falsified vs sklearn' +- id: PILLAR1-051 + github_issue: null + item_type: task + title: SGDClassifier (linear_model) + status: planned + priority: high + assigned_to: null + created: 2026-06-11 21:40:00+00:00 + updated: 2026-06-11 21:40:00+00:00 + spec: null + acceptance_criteria: + - 'Falsifier: apr SGDClassifier matches sklearn.linear_model.SGDClassifier accuracy within 1% on MNIST + binary subset, 10k samples' + phases: [] + subtasks: [] + estimated_effort: M + labels: + - mission + - pillar-1 + - sklearn-parity + - estimator_impl + notes: 'gap-map rank #51 (value 4, effort M); falsified vs sklearn' +- id: PILLAR1-052 + github_issue: null + item_type: task + title: SGDRegressor (linear_model) + status: planned + priority: high + assigned_to: null + created: 2026-06-11 21:40:00+00:00 + updated: 2026-06-11 21:40:00+00:00 + spec: null + acceptance_criteria: + - 'Falsifier: apr SGDRegressor matches sklearn.linear_model.SGDRegressor R² within 0.05 on California + housing subset' + phases: [] + subtasks: [] + estimated_effort: M + labels: + - mission + - pillar-1 + - sklearn-parity + - estimator_impl + notes: 'gap-map rank #52 (value 4, effort M); falsified vs sklearn' +- id: PILLAR1-053 + github_issue: null + item_type: task + title: Kernel classes (RBF, Poly, Sigmoid, Linear) (classification.svm) + status: planned + priority: high + assigned_to: null + created: 2026-06-11 21:40:00+00:00 + updated: 2026-06-11 21:40:00+00:00 + spec: null + acceptance_criteria: + - 'Falsifier: kernel(x1,x2) matches sklearn.metrics.pairwise_kernels(X,Y,metric=rbf) within 1e-5; reusable + for kernel SVMs' + phases: [] + subtasks: [] + estimated_effort: M + labels: + - mission + - pillar-1 + - sklearn-parity + - preprocessing + notes: 'gap-map rank #53 (value 4, effort M); falsified vs sklearn' +- id: PILLAR1-054 + github_issue: null + item_type: task + title: Multi-class SVM (OneVsRest) (classification.svm) + status: planned + priority: high + assigned_to: null + created: 2026-06-11 21:40:00+00:00 + updated: 2026-06-11 21:40:00+00:00 + spec: null + acceptance_criteria: + - 'Falsifier: SVM OvR on 4-class iris matches sklearn.svm.SVC accuracy within 1%' + phases: [] + subtasks: [] + estimated_effort: M + labels: + - mission + - pillar-1 + - sklearn-parity + - model_selection + notes: 'gap-map rank #54 (value 4, effort M); falsified vs sklearn' +- id: PILLAR1-055 + github_issue: null + item_type: task + title: MiniBatchKMeans (cluster) + status: planned + priority: medium + assigned_to: null + created: 2026-06-11 21:40:00+00:00 + updated: 2026-06-11 21:40:00+00:00 + spec: null + acceptance_criteria: + - 'Falsifier: apr MiniBatchKMeans 50% faster than sklearn on same hardware; inertia within 1e-3 of sklearn + on pinned iris-scale data' + phases: [] + subtasks: [] + estimated_effort: M + labels: + - mission + - pillar-1 + - sklearn-parity + - estimator_impl + notes: 'gap-map rank #55 (value 3, effort M); falsified vs sklearn' +- id: PILLAR1-056 + github_issue: null + item_type: task + title: max_features parameter for RandomForest (tree) + status: planned + priority: medium + assigned_to: null + created: 2026-06-11 21:40:00+00:00 + updated: 2026-06-11 21:40:00+00:00 + spec: null + acceptance_criteria: + - 'Falsifier: apr RandomForestClassifier.with_max_features(sqrt) uses sqrt(n_features) per split vs + sklearn on wine dataset' + phases: [] + subtasks: [] + estimated_effort: M + labels: + - mission + - pillar-1 + - sklearn-parity + - estimator_impl + notes: 'gap-map rank #56 (value 3, effort M); falsified vs sklearn' +- id: PILLAR1-057 + github_issue: null + item_type: task + title: class_weight=balanced parameter (tree) + status: planned + priority: medium + assigned_to: null + created: 2026-06-11 21:40:00+00:00 + updated: 2026-06-11 21:40:00+00:00 + spec: null + acceptance_criteria: + - 'Falsifier: apr DecisionTreeClassifier.with_class_weight(balanced) achieves >5% higher F1 on imbalanced + dataset vs uniform' + phases: [] + subtasks: [] + estimated_effort: M + labels: + - mission + - pillar-1 + - sklearn-parity + - estimator_impl + notes: 'gap-map rank #57 (value 3, effort M); falsified vs sklearn' +- id: PILLAR1-058 + github_issue: null + item_type: task + title: AdaBoostClassifier (ensemble) + status: planned + priority: medium + assigned_to: null + created: 2026-06-11 21:40:00+00:00 + updated: 2026-06-11 21:40:00+00:00 + spec: null + acceptance_criteria: + - 'Falsifier: binary classification on synthetic data, accuracy within 1% of sklearn.ensemble.AdaBoostClassifier + (n_estimators=50, lr=1.0)' + phases: [] + subtasks: [] + estimated_effort: M + labels: + - mission + - pillar-1 + - sklearn-parity + - algorithm + notes: 'gap-map rank #58 (value 3, effort M); falsified vs sklearn' +- id: PILLAR1-059 + github_issue: null + item_type: task + title: VotingClassifier (ensemble) + status: planned + priority: medium + assigned_to: null + created: 2026-06-11 21:40:00+00:00 + updated: 2026-06-11 21:40:00+00:00 + spec: null + acceptance_criteria: + - 'Falsifier: hard & soft voting, accuracy within 0.5% of sklearn.ensemble.VotingClassifier on iris + with (LogReg, RFC, SVC)' + phases: [] + subtasks: [] + estimated_effort: M + labels: + - mission + - pillar-1 + - sklearn-parity + - algorithm + notes: 'gap-map rank #59 (value 3, effort M); falsified vs sklearn' +- id: PILLAR1-060 + github_issue: null + item_type: task + title: OrdinalEncoder (preprocessing) + status: planned + priority: medium + assigned_to: null + created: 2026-06-11 21:40:00+00:00 + updated: 2026-06-11 21:40:00+00:00 + spec: null + acceptance_criteria: + - 'Falsifier: apr OrdinalEncoder.fit_transform(mixed_categorical) produces integer labels matching sklearn.preprocessing.OrdinalEncoder' + phases: [] + subtasks: [] + estimated_effort: M + labels: + - mission + - pillar-1 + - sklearn-parity + - preprocessing + notes: 'gap-map rank #60 (value 3, effort M); falsified vs sklearn' +- id: PILLAR1-061 + github_issue: null + item_type: task + title: PolynomialFeatures (preprocessing) + status: planned + priority: medium + assigned_to: null + created: 2026-06-11 21:40:00+00:00 + updated: 2026-06-11 21:40:00+00:00 + spec: null + acceptance_criteria: + - 'Falsifier: apr PolynomialFeatures(degree=2).fit_transform(X) produces same number and order of columns + as sklearn.preprocessing.PolynomialFeatures' + phases: [] + subtasks: [] + estimated_effort: M + labels: + - mission + - pillar-1 + - sklearn-parity + - feature + notes: 'gap-map rank #61 (value 3, effort M); falsified vs sklearn' +- id: PILLAR1-062 + github_issue: null + item_type: task + title: FactorAnalysis (decomposition) + status: planned + priority: medium + assigned_to: null + created: 2026-06-11 21:40:00+00:00 + updated: 2026-06-11 21:40:00+00:00 + spec: null + acceptance_criteria: + - 'Falsifier: apr FactorAnalysis likelihood match sklearn within 1e-2 on pinned synthetic data; loadings_/noise_variance + parity within 1e-3' + phases: [] + subtasks: [] + estimated_effort: M + labels: + - mission + - pillar-1 + - sklearn-parity + - algorithm + notes: 'gap-map rank #62 (value 3, effort M); falsified vs sklearn' +- id: PILLAR1-063 + github_issue: null + item_type: task + title: BernoulliNB (naive_bayes) + status: planned + priority: medium + assigned_to: null + created: 2026-06-11 21:40:00+00:00 + updated: 2026-06-11 21:40:00+00:00 + spec: null + acceptance_criteria: + - 'Falsifier: fit/predict on binary feature matrices; match sklearn.naive_bayes.BernoulliNB within 1% + accuracy; support binarize parameter' + phases: [] + subtasks: [] + estimated_effort: M + labels: + - mission + - pillar-1 + - sklearn-parity + - estimator_impl + notes: 'gap-map rank #63 (value 3, effort M); falsified vs sklearn' +- id: PILLAR1-064 + github_issue: null + item_type: task + title: ComplementNB (naive_bayes) + status: planned + priority: medium + assigned_to: null + created: 2026-06-11 21:40:00+00:00 + updated: 2026-06-11 21:40:00+00:00 + spec: null + acceptance_criteria: + - 'Falsifier: match sklearn.naive_bayes.ComplementNB on imbalanced multiclass (20-newsgroups) within + 2% accuracy' + phases: [] + subtasks: [] + estimated_effort: M + labels: + - mission + - pillar-1 + - sklearn-parity + - estimator_impl + notes: 'gap-map rank #64 (value 3, effort M); falsified vs sklearn' +- id: PILLAR1-065 + github_issue: null + item_type: task + title: roc_curve (metrics) + status: planned + priority: medium + assigned_to: null + created: 2026-06-11 21:40:00+00:00 + updated: 2026-06-11 21:40:00+00:00 + spec: null + acceptance_criteria: + - 'Falsifier: match sklearn.metrics.roc_curve FPR/TPR arrays within 1e-4 on pinned binary classification + oracle' + phases: [] + subtasks: [] + estimated_effort: M + labels: + - mission + - pillar-1 + - sklearn-parity + - metric + notes: 'gap-map rank #65 (value 3, effort M); falsified vs sklearn' +- id: PILLAR1-066 + github_issue: null + item_type: task + title: precision_recall_curve (metrics) + status: planned + priority: medium + assigned_to: null + created: 2026-06-11 21:40:00+00:00 + updated: 2026-06-11 21:40:00+00:00 + spec: null + acceptance_criteria: + - 'Falsifier: match sklearn.metrics.precision_recall_curve arrays within 1e-4 on pinned oracle' + phases: [] + subtasks: [] + estimated_effort: M + labels: + - mission + - pillar-1 + - sklearn-parity + - metric + notes: 'gap-map rank #66 (value 3, effort M); falsified vs sklearn' +- id: PILLAR1-067 + github_issue: null + item_type: task + title: cross_validate_unsupervised (cluster) + status: planned + priority: medium + assigned_to: null + created: 2026-06-11 21:40:00+00:00 + updated: 2026-06-11 21:40:00+00:00 + spec: null + acceptance_criteria: + - 'Falsifier: apr::model_selection::cross_validate_unsupervised(kmeans, X, cv) compiles and returns + scores on clustered data' + phases: [] + subtasks: [] + estimated_effort: M + labels: + - mission + - pillar-1 + - sklearn-parity + - model_selection + notes: 'gap-map rank #67 (value 3, effort M); falsified vs sklearn' +- id: PILLAR1-068 + github_issue: null + item_type: task + title: NearestNeighbors (generic query interface) (neighbors) + status: planned + priority: medium + assigned_to: null + created: 2026-06-11 21:40:00+00:00 + updated: 2026-06-11 21:40:00+00:00 + spec: null + acceptance_criteria: + - 'Falsifier: apr NearestNeighbors.kneighbors(X, k) match sklearn.neighbors.NearestNeighbors (indices, + distances) within machine precision' + phases: [] + subtasks: [] + estimated_effort: M + labels: + - mission + - pillar-1 + - sklearn-parity + - estimator_impl + notes: 'gap-map rank #68 (value 3, effort M); falsified vs sklearn' +- id: PILLAR1-069 + github_issue: null + item_type: task + title: RadiusNeighborsClassifier (neighbors) + status: planned + priority: medium + assigned_to: null + created: 2026-06-11 21:40:00+00:00 + updated: 2026-06-11 21:40:00+00:00 + spec: null + acceptance_criteria: + - 'Falsifier: apr RadiusNeighborsClassifier.predict matches sklearn on fixed-radius query; all neighbors + within eps contribute to vote' + phases: [] + subtasks: [] + estimated_effort: M + labels: + - mission + - pillar-1 + - sklearn-parity + - algorithm + notes: 'gap-map rank #69 (value 3, effort M); falsified vs sklearn' +- id: PILLAR1-070 + github_issue: null + item_type: task + title: ColumnTransformer (pipeline_compose) + status: planned + priority: medium + assigned_to: null + created: 2026-06-11 21:40:00+00:00 + updated: 2026-06-11 21:40:00+00:00 + spec: null + acceptance_criteria: + - 'Falsifier: ColumnTransformer([(num,StandardScaler(),[0,1,2]),(cat,OneHotEncoder(),[3,4])]) on mixed-type + data matches sklearn within 1e-4' + phases: [] + subtasks: [] + estimated_effort: M + labels: + - mission + - pillar-1 + - sklearn-parity + - preprocessing + notes: 'gap-map rank #70 (value 3, effort M); falsified vs sklearn' +- id: PMAT-CI-PASSGREP-001 + github_issue: null + item_type: task + title: Anchor the ci.yml compute-step pass check (kill the '10 failed' substring bypass) + status: completed + priority: critical + assigned_to: null + created: 2026-07-05 00:00:00+00:00 + updated: 2026-07-05 00:00:00+00:00 + spec: docs/specifications/fable-architectural-review.md + acceptance_criteria: + - 'ci.yml compute step pass check is anchored (e.g. grep -q ''; 0 failed;'' AND requires a ''test result: + ok.'' line) so a partial-failure run cannot merge green.' + - 'RED-turning mutation: add 10 `assert!(false)` tests to aprender-compute --lib on a scratch branch + — workspace-test MUST fail (today it exits 0 because grep ''test result.*0 failed'' substring-matches + ''10 failed'').' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - infra + - gate + - fable-review-2026-07-05 + - ev-rank-01 + - gates-or-theater + notes: 'The per-PR enforcement backbone is bypassable — every other gate''s credibility transits this + compute-step pass check; one-line fix. Workflow: ticket -> fix/ci-compute-pass-grep -> PR -> ci/gate + (small-CI-edit class, pre-authorized). Source: docs/specifications/fable-architectural-review.md §7b + ev_rank 1.' +- id: PMAT-F2-DECODE-PHASE-001 + github_issue: null + item_type: task + title: Extend the GPU first-token probe to multi-step decode through the production prefill mode + status: planned + priority: high + assigned_to: null + created: 2026-07-05 00:00:00+00:00 + updated: 2026-07-05 00:00:00+00:00 + spec: docs/specifications/fable-architectural-review.md + acceptance_criteria: + - validate_gpu_first_token is extended with >=8 greedy decode steps executed through the SAME prefill + mode production selects, per-step argmax + cosine>=0.95 vs CPU; new FALSIFY-CPU-GPU-012 in apr-cpu-vs-gpu-output-parity-v1.yaml + (NOT 007 - ids 001-011 are all taken and 007 is PMAT-742, the no-false-positive falsifier for this + very function; total_obligations must go 11 -> 12). + - 'RED-turning mutation: corrupt the batched-prefill KV scatter (or truncate the cache at decode step + 4) — the probe MUST reject; today it accepts because it validates only serial prefill (BATCHED_PREFILL + still default on sm_89).' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - pillar-4 + - gate + - fable-review-2026-07-05 + - ev-rank-03 + - gates-or-theater + notes: 'PREREQ FINDINGS (2026-07-29 recon, verified in-tree - read before starting): (1) validate_gpu_first_token + executes ZERO decode steps AND never calls run_prefill, so it exercises neither batched-prefill kernels + nor any cached decode - the in-code comment at generate_2.rs claiming it -only checks the FIRST token- + was itself stale (since PMAT-919 it checks every PROMPT position) and is corrected in this tree. (2) + run_prefill is a PRIVATE method on OwnedQuantizedModelCuda in gguf::cuda while the probe lives in + infer::inference_result - the probe physically cannot call production prefill today; raising it to + pub(crate) or adding a probe entry point inside gguf/cuda is a design decision, not a mechanical edit. + (3) No public API returns per-step LOGITS from the production path - generate_gpu_resident returns + Vec only; generate_gpu_resident_logprobs is the nearest precedent to model a logits-capturing + helper on. (4) The probe resets the GPU KV cache before AND after its loop so validation does not + consume the model; running real prefill will allocate the prefill workspace and arm flash decoding, + so that teardown discipline must be re-derived. (5) The RED-turning mutation is NOT reachable by default + on both legs: batched prefill is default only on non-Blackwell (run_prefill: Err(_) => !is_blackwell), + so the gb10 leg needs an explicit BATCHED_PREFILL=1 matrix entry to be honest. (6) TRAP, not yet a + live bug: cuda/gpu_profile.rs detect_batched_prefill() returns unwrap_or(true) and ignores the Blackwell + carve-out that run_prefill applies, so GpuProfile.batched_prefill disagrees with the real decision + on Blackwell. It currently has ZERO readers (verified), so nothing is misreported today - but any + -the SAME prefill mode production selects- assertion must read the run_prefill decision, never that + field. (7) The probe fails OPEN when the CPU reference forward errors and when BOS is unknown; a decode + extension inherits both holes. (8) No workflow runs cargo test -p aprender-serve --features cuda --lib, + so cuda-nightly needs a new step. ORIGINAL: The #1864 remediation probe validates only serial prefill; + generate_2.rs:246-268 documents in-code that batched-prefill decode corruption (PMAT-810 ''CertainlyCertainly'') + ships through it silently. Workflow: ticket -> branch -> PR -> ci/gate; verify on cuda-nightly both + silicon legs. Source: docs/specifications/fable-architectural-review.md §7b ev_rank 3.' +- id: PMAT-QA-FMTPARITY-DECODE-001 + github_issue: null + item_type: task + title: 'Give apr qa format_parity a real decode path (it is currently a #1864 clone)' + status: completed + priority: high + assigned_to: null + created: 2026-07-05 00:00:00+00:00 + updated: 2026-07-05 00:00:00+00:00 + spec: docs/specifications/fable-architectural-review.md + acceptance_criteria: + - The format_parity gate greedy-decodes >=64 tokens per format via the cache path with per-step argmax + equality (near-tie cosine >=0.98 exemption); qwen-story B2 gains a GGUF leg so the gate actually executes + daily. + - 'RED-turning mutation: zero the SafeTensors-side KV write at decode step 32 — apr qa MUST exit 5; + today it stays green because the gate is one prefill forward + single final-position argmax, zero + decode steps.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - pillar-4 + - gate + - fable-review-2026-07-05 + - ev-rank-04 + - gates-or-theater + notes: 'apr qa''s format_parity gate (the tool the doctrine says to reach for FIRST) is a literal #1864 + clone; cross-format cached-decode drift is invisible to it. Workflow: ticket -> branch -> PR -> ci/gate. + Source: docs/specifications/fable-architectural-review.md §7b ev_rank 4.' +- id: FALSIFY-CUDA-NF4-TRAIN-TRAJECTORY-001 + github_issue: null + item_type: task + title: GPU NF4 training trajectory gate (>=20 optimizer steps vs CPU oracle) — kill the step-0-only + asymmetry + status: planned + priority: high + assigned_to: null + created: 2026-07-05 00:00:00+00:00 + updated: 2026-07-05 00:00:00+00:00 + spec: docs/specifications/fable-architectural-review.md + acceptance_criteria: + - '>=20 real optimizer steps GPU vs NF4-matched CPU oracle (identical data/lr); per-step |dLoss| within + band AND total decrease >= X nats by step 20; wired into cuda-nightly.yml.' + - 'RED-turning mutation: freeze the CUDA Adam t counter at 1 — red by step 3; the current step-0 gate + (parity_probe.rs:186, no optimizer step ever taken) stays green forever while CPU has an enforced + 400-step trajectory (train_to_loss_tests.rs).' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - pillar-3 + - gate + - fable-review-2026-07-05 + - ev-rank-05 + - gates-or-theater + notes: 'GPU training is gated at step 0 only; #2251-class backward/stream bugs are structurally invisible. + GROUNDED 2026-07-05: CONFIRMED still actionable (parity_probe.rs is forward-only, no backward/optimizer; + 400-step CPU trajectory exists; no GPU trajectory test). Workflow: ticket -> branch -> PR -> ci/gate; + nightly proof on both silicon. Source: docs/specifications/fable-architectural-review.md §7b ev_rank + 5.' +- id: PMAT-SERVE-MULTITURN-001 + github_issue: null + item_type: task + title: Genuine multi-turn serve gates (3-turn /api/chat + streaming + real template engine) + status: planned + priority: high + assigned_to: null + created: 2026-07-05 00:00:00+00:00 + updated: 2026-07-05 00:00:00+00:00 + spec: docs/specifications/fable-architectural-review.md + acceptance_criteria: + - '(a) ollama_http_compat gains a 3-turn /api/chat sequence + a stream:true request asserting >=2 chunks + then done:true (per-PR at ci.yml:317); (b) FALSIFY-CHAT-008 rewritten to invoke the real chat_template + engine; (c) qwen-story B6b: 2 follow-up requests to the same server.' + - 'RED-turning mutation: handler drops all-but-last message -> (a) red; swap two turns pre-render -> + (b) red; kill KV reset between requests -> (c) red. Today every serve gate samples one request/one + turn and FALSIFY-CHAT-008 is a string tautology that never calls the template engine.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - pillar-4 + - gate + - fable-review-2026-07-05 + - ev-rank-06 + - gates-or-theater + notes: 'PARTIALLY LANDED 2026-07-29: (a) ollama_http_compat gained a 3-turn /api/chat test asserting + on prompt_eval_count growth (NOT shape - the handler answers 200 + done:true even when generation + fails, so every pre-existing assertion there is satisfied by total failure); RED-verified by making + the handler keep only the last message (3-turn then consumed 26 prompt tokens == last-turn-alone 26). + (b) FALSIFY-CHAT-008 rewritten to call ChatMLTemplate::format_conversation - it was a tautology (producer + and verifier were the same format! over the same vector) and VERIFIED so: swapping two turns left + the OLD test passing. CHAT-006/007/008 were orphan test-only ids never declared in apr-chat-session-v1.yaml, + whose qa_gate still read -All 5 falsification tests pass-; now declared, gate says 8. (c) STILL OPEN: + qwen-story B6b two-follow-up-requests. ALSO: the streaming half was satisfied by GATING existing tests + rather than writing new ones - crates/apr-cli/tests/ollama_ndjson_streaming.rs (PMAT-928) already + has 4 real NDJSON multi-chunk/done:true tests and ran in ZERO workflows; both it and falsification_chat_http_cli + are now on ci.yml:317. NOTE the aprender-serve router CANNOT stream at all - to_chat_request hard-forces + stream:false (ollama_handlers.rs:184-186) and OllamaChatRequest.stream defaults to false, contradicting + Ollama-s wire default of true (apr-cli-s copy gets it right via default_stream); a stream:true assertion + in aprender-serve would need a handler change, which is why the existing apr-cli tests were gated + instead. ORIGINAL: Multi-turn KV/template accumulation is the #1864 gibberish vector and has no genuine + gate. Workflow: (a)/(b) per-PR; (c) rides qwen-story-daily; ci.yml:317 is ONE physical line — consolidate + edits in one PR. Source: docs/specifications/fable-architectural-review.md §7b ev_rank 6.' +- id: PMAT-DRIFT-GATES-001 + github_issue: null + item_type: task + title: Make the claims-as-contract layer actually enforce (README/book/CLI drift caught on the offending + PR) + status: planned + priority: high + assigned_to: null + created: 2026-07-05 00:00:00+00:00 + updated: 2026-07-05 00:00:00+00:00 + spec: docs/specifications/fable-architectural-review.md + acceptance_criteria: + - check_readme_claims.sh (or an extended readme_contract test) runs per-PR; book.yml + book-contracts.yml + triggers extended to crates/apr-cli/src/**; README/CLAUDE.md counts corrected (contracts, ~83.5k tests, + 82 crates). + - 'RED-turning mutation: PR changing the crates/ dir count without a README edit -> red; PR adding a + clap subcommand without a book chapter -> red on THAT PR, not the next book PR. Today the readme-claims + checker is in zero workflows despite status:''enforced'', and README 1331 != tree 1460.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - infra + - contract + - fable-review-2026-07-05 + - ev-rank-07 + - gates-or-theater + notes: 'The claims-as-contract layer is live-proven theater; the book/CLI parity path is filtered so + exactly the drift it exists to catch bypasses it. Workflow: ticket -> branch -> PR -> ci/gate; small-CI-edit + class. Source: docs/specifications/fable-architectural-review.md §7b ev_rank 7.' +- id: APR-ANTHROPIC-MSGS-INTEGRITY-001 + github_issue: null + item_type: task + title: Ship Anthropic-compatible /v1/messages WITH a falsification-gated tool-call-integrity contract + status: planned + priority: medium + assigned_to: null + created: 2026-07-05 00:00:00+00:00 + updated: 2026-07-05 00:00:00+00:00 + spec: docs/specifications/fable-architectural-review.md + acceptance_criteria: + - 'apr serve exposes an Anthropic-compatible /v1/messages (+ count_tokens); contract apr-anthropic-messages-v1.yaml + with a falsifier: tool_call id/structure preserved byte-exact across >=3 turns incl. the #2245 salvage-parser + path.' + - 'RED-turning mutation: drop the tool_call id remapping on turn 2 -> the falsifier MUST reject.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - pillar-5 + - beat + - fable-review-2026-07-05 + - ev-rank-09 + - gates-or-theater + notes: 'mistral.rs ships /v1/messages + agent loop with ZERO correctness contracts; P5''s defensible + ground is provable tool-call integrity — a beat nobody claims. Feeds APR-ANTIGRAVITY-PARITY-001 already + atop the planned queue. Workflow: ticket -> branch -> PR -> ci/gate. Source: docs/specifications/fable-architectural-review.md + §7b ev_rank 9.' +- id: PMAT-GNB-SPEED-DEFENSE-001 + github_issue: null + item_type: task + title: Defend the GaussianNB speed beat (decaying 4.9x -> 2.12x toward its 2.0x gate) + status: planned + priority: medium + assigned_to: null + created: 2026-07-05 00:00:00+00:00 + updated: 2026-07-05 00:00:00+00:00 + spec: docs/specifications/fable-architectural-review.md + acceptance_criteria: + - Regression bisected to a commit or attributed to environment (sklearn 1.9 speedup / allocator / ln-hoist + erosion); margin restored to >=3x measured OR the contract honestly re-pinned with a dated measurement; + then 5 consecutive green nightlies. + - 'RED-turning mutation: (defensive) the beat-speed-nightly GaussianNB leg must return to a durable + green margin; red 07-03/07-04 nightlies are the current RED signal.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - pillar-1 + - beat + - fable-review-2026-07-05 + - ev-rank-10 + - gates-or-theater + notes: 'A LIVE beat decaying toward its own gate; an untriaged decay becomes a flake, then a deleted + gate — five-whys before it flips. Workflow: ticket -> branch -> PR -> ci/gate. Source: docs/specifications/fable-architectural-review.md + §7b ev_rank 10.' +- id: PMAT-CUDA-NIGHTLY-PROBATIVE-001 + github_issue: null + item_type: task + title: Make cuda-nightly greens probative (distinct skip conclusion + GQA-64/AdamW/NF4 falsifiers) + status: planned + priority: medium + assigned_to: null + created: 2026-07-05 00:00:00+00:00 + updated: 2026-07-05 00:00:00+00:00 + spec: docs/specifications/fable-architectural-review.md + acceptance_criteria: + - Skip nights emit a distinct conclusion (neutral/skipped + weekly skip-rate report, alert >50%); the + lane adopts gqa_attention_parity extended to >=64 cached positions, >=10-step AdamW parity, and NF4 + double-roundtrip idempotence. + - 'RED-turning mutation: stride the GPU cache by q_dim (the PMAT-749 bug) -> red by step 8; freeze bias + correction -> red by step 3; perturb absmax on roundtrip 2 -> red. Today gqa horizon=2 positions, + gpu_cpu_parity.rs is assertion-free, both unwired.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - pillar-3 + - gate + - fable-review-2026-07-05 + - ev-rank-11 + - gates-or-theater + notes: 'Yield-to-training turns busy-GPU nights into green no-ops (non-probative greens). GROUNDED 2026-07-05: + CONFIRMED — 2-position horizon, assertion-free _cuda_model parity test, neither wired into any workflow. + Workflow: small-CI-edit class; verify a real (non-skip) run on both legs. Source: docs/specifications/fable-architectural-review.md + §7b ev_rank 11.' +- id: PMAT-CASEFILE-MECH-001 + github_issue: null + item_type: task + title: 'Mechanize the unmechanized case files (#153 format-detection bytes, #1599 apr-cli optional dep)' + status: planned + priority: medium + assigned_to: null + created: 2026-07-05 00:00:00+00:00 + updated: 2026-07-05 00:00:00+00:00 + spec: docs/specifications/fable-architectural-review.md + acceptance_criteria: + - '#153: a regression test asserting format detection reads <=8 bytes + a bind-before-ready ordering + test; #1599: a CI step asserting `cargo tree -p aprender --no-default-features -e normal` contains + no apr-cli.' + - 'RED-turning mutation: swap the 8-byte read for std::fs::read -> #153 test red; make apr-cli non-optional + -> #1599 step red. Today a refactor reintroducing either bug passes every gate.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - cross-cutting + - contract + - fable-review-2026-07-05 + - ev-rank-12 + - gates-or-theater + notes: 'Doctrine 7''s corpus claim is overstated: #153 and #1599 are CLOSED-BUT-UNMECHANIZED (zero regression + artifacts). Workflow: ticket -> branch -> PR -> ci/gate. Source: docs/specifications/fable-architectural-review.md + §7b ev_rank 12.' +- id: PMAT-MACOS-WGPU-NIGHTLY-001 + github_issue: null + item_type: task + title: Execute macOS/Metal tests in the nightly (currently build-only, T5 competitive gap) + status: planned + priority: medium + assigned_to: null + created: 2026-07-05 00:00:00+00:00 + updated: 2026-07-05 00:00:00+00:00 + spec: docs/specifications/fable-architectural-review.md + acceptance_criteria: + - nightly.yml macOS aarch64 leg adds a --features wgpu build + `cargo test -p aprender-compute --lib + --features gpu`; the macOS METAL assertion (device/mod.rs:500) executes. + - 'RED-turning mutation: cfg-gate out Metal backend registration -> the macOS test leg fails.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - infra + - gate + - fable-review-2026-07-05 + - ev-rank-13 + - gates-or-theater + notes: 'T5: the incumbent''s fastest 2026 platform (Ollama MLX ~2x decode, Gemma4 +90%) vs zero macOS + test execution here; the Metal/wgpu path is never compiled on Apple hardware. The nightly macOS lane + already exists. Workflow: small-CI-edit class; GitHub-hosted macos-latest, no fleet dependency. Source: + docs/specifications/fable-architectural-review.md §7b ev_rank 13.' +- id: PMAT-MSRV-GATE-001 + github_issue: null + item_type: task + title: Add an MSRV (rust-version=1.89) PR-blocking gate — CI currently builds on stable/1.93 + status: planned + priority: medium + assigned_to: null + created: 2026-07-05 00:00:00+00:00 + updated: 2026-07-05 00:00:00+00:00 + spec: docs/specifications/fable-architectural-review.md + acceptance_criteria: + - 'A PR-blocking job: dtolnay/rust-toolchain@1.89 + `cargo check --workspace`; per-crate overrides reconciled + (aprender-train 1.87, aprender-graph 1.75).' + - 'RED-turning mutation: use a 1.93-only std API -> the MSRV job fails. Today it merges green and breaks + `cargo install aprender` for 1.89 users.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - infra + - gate + - fable-review-2026-07-05 + - ev-rank-14 + - gates-or-theater + notes: 'rust-version=1.89 is a published contract cargo enforces on every downstream install, but CI + never verifies it; 4-line job. Workflow: small-CI-edit class. Source: docs/specifications/fable-architectural-review.md + §7b ev_rank 14.' +- id: PMAT-PUBLISH-POLICY-001 + github_issue: null + item_type: task + title: Reconverge publish doctrine and practice (crates.io 8 versions/14 days behind, release.yml deleted) + status: blocked + priority: medium + assigned_to: null + created: 2026-07-05 00:00:00+00:00 + updated: 2026-07-05 00:00:00+00:00 + spec: docs/specifications/fable-architectural-review.md + acceptance_criteria: + - 'CLEAN-ROOM GATE FIRST: a `cargo publish --dry-run --no-verify` cascade preflight (per the dev-dep-cycle + rules) recorded green; THEN either cascade v0.59.x to crates.io OR a written policy in ROADMAP.md + designating GH releases as the channel; CLAUDE.md''s stale ''release.yml: automated releases'' claim + fixed either way.' + - 'RED-turning mutation: (policy) the preflight artifact must exist before any publish; a publish without + it is the RED condition.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - infra + - infra + - fable-review-2026-07-05 + - ev-rank-15 + - gates-or-theater + notes: 'BLOCKED_BY: operator decision (publish authorization). T7 fired: doctrine 5 declares clean-room + publishability a HARD release gate while crates.io is 8 versions/14 days behind with zero automation. + NOTE: publish skipped since v0.51 by operator choice; this item is the deliberately operator-gated + one. Workflow: preflight -> operator GO/NO-GO -> cascade; never publish without the preflight artifact. + Source: docs/specifications/fable-architectural-review.md §7b ev_rank 15.' +- id: PMAT-MUTANTS-FULLTREE-001 + github_issue: null + item_type: task + title: Weekly full-tree mutation sweep (mutation is currently diff-scoped PR-only) + status: planned + priority: low + assigned_to: null + created: 2026-07-05 00:00:00+00:00 + updated: 2026-07-05 00:00:00+00:00 + spec: docs/specifications/fable-architectural-review.md + acceptance_criteria: + - A weekly scheduled sharded `cargo mutants -- --lib` (round-robin N crates/night within a time budget) + auto-filing an issue listing surviving mutants; first report produced. + - 'RED-turning mutation: the surviving-mutant list IS the RED signal; a week with new survivors outside + any diff is the failure the sweep exists to surface.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - infra + - gate + - fable-review-2026-07-05 + - ev-rank-16 + - gates-or-theater + notes: 'Mutation is diff-scoped PR-only; full-tree has never been re-sampled since the push-to-main + run was removed — mutation debt outside diffs compounds silently. Workflow: small-CI-edit class; clean-room + runners. Source: docs/specifications/fable-architectural-review.md §7b ev_rank 16.' +- id: PMAT-THEATER-TRIAGE-001 + github_issue: null + item_type: task + title: Triage the ~595 unexecuted integration-test files (wire / lib-twin-verify / archive-label) + status: planned + priority: low + assigned_to: null + created: 2026-07-05 00:00:00+00:00 + updated: 2026-07-05 00:00:00+00:00 + spec: docs/specifications/fable-architectural-review.md + acceptance_criteria: + - A committed classification manifest (wire / lib-twin-verified / archive-labeled) for all crates/*/tests + files; assertion-free tests completed or deleted (gpu_cpu_parity.rs _cuda_model never compared); top-10 + falsifiers wired into cuda-nightly or ci.yml:317 in ONE consolidated PR. + - 'RED-turning mutation: the manifest itself is the artifact; a crates/*/tests file that is neither + wired, lib-twin-verified, nor archive-labeled is the RED item.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - infra + - gate + - fable-review-2026-07-05 + - ev-rank-17 + - gates-or-theater + notes: 'BLOCKED_BY: PMAT-CUDA-NIGHTLY-PROBATIVE-001 (shares the lane). ~595 unexecuted integration-test + files (incl. the falsify_*/parity corpus and the assertion-free gpu_cpu_parity.rs) read as coverage + but enforce nothing. Workflow: consolidate ALL ci.yml:317 edits into one PR to avoid merge-queue conflicts + (single-physical-line constraint). Source: docs/specifications/fable-architectural-review.md §7b ev_rank + 17.' +- id: PMAT-COVERAGE-FLOOR-001 + github_issue: null + item_type: task + title: Enforce the >=95% coverage floor (currently enforced nowhere) + status: blocked + priority: low + assigned_to: null + created: 2026-07-05 00:00:00+00:00 + updated: 2026-07-05 00:00:00+00:00 + spec: docs/specifications/fable-architectural-review.md + acceptance_criteria: + - sovereign-ci coverage_min + test_workspace set for aprender (or coverage-nightly promoted to fail + below a committed baseline). + - 'RED-turning mutation: delete a tested module''s tests -> the coverage job goes red.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - infra + - gate + - fable-review-2026-07-05 + - ev-rank-18 + - gates-or-theater + notes: 'BLOCKED_BY: paiml/.github sovereign-ci reusable workflow (cross-repo change). The >=95% standard + is enforced nowhere (vacuous root-facade coverage job, coverage_min unset, coverage-nightly report-mode) + — ranked last because the coverage+contracts co-evolution rule makes a naive floor counterproductive + without scoped work. Workflow: cross-repo — coordinate with the sovereign-ci owner before edit. Source: + docs/specifications/fable-architectural-review.md §7b ev_rank 18.' +- id: SPEC-DIST-393-GPU-BACKEND + github_issue: 393 + item_type: task + title: Heterogeneous distributed training — wire wgpu/CUDA worker backend (Phase-2 CLI landed) + status: planned + priority: medium + assigned_to: null + created: 2026-07-05 00:00:00+00:00 + updated: 2026-07-05 00:00:00+00:00 + spec: docs/specifications/roadmap-next-wave-2026-07-05.md + acceptance_criteria: + - Distributed worker gradients are computed on the wgpu/CUDA backend, not the current CPU stub (classify_trainer.rs:1483 + `let backend = "cpu"`); --gpu-backend actually dispatches GPU matmul in the data-parallel path. + - 'RED-turning mutation: run a distributed worker with --gpu-backend cuda and assert the gradient tensors + originate from the GPU path — today they come from the hardcoded CPU stub regardless of the flag.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - pillar-2 + - gpu + - distributed + - github-393 + - from-issue-triage-2026-07-05 + notes: 'Phase-2 distributed CLI wiring (--role/--bind/--coordinator/--expect-workers -> DistributedConfig, + TCP AllReduce coordinator/worker) landed via PR #2294 (in #2286). The heterogeneous CUDA+wgpu GPU + worker execution and Phase-3 DiLoCo remain. Tracks GitHub #393.' +- id: M-GPU-MOE-2-WGPU-FORWARD + github_issue: 1582 + item_type: task + title: M-GPU-MOE-2.x — wgpu helpers + qwen3-moe forward parity (portable GPU MoE) + status: planned + priority: low + assigned_to: null + created: 2026-07-05 00:00:00+00:00 + updated: 2026-07-05 00:00:00+00:00 + spec: docs/specifications/roadmap-next-wave-2026-07-05.md + acceptance_criteria: + - qwen3-moe forward runs on the wgpu backend with per-layer cosine >=0.99 vs the CPU oracle; trueno-gpu + wgpu QuantizeKernel + GemmKernel authored. + - 'RED-turning mutation: run qwen3-moe forward --backend wgpu and assert per-layer cosine >=0.99 vs + CPU — today the wgpu MoE path does not exist.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - pillar-3 + - gpu + - wgpu + - moe + - github-1582 + - from-issue-triage-2026-07-05 + notes: 'Blocked on trueno-gpu wgpu kernel authoring (large 3-part item). Portable-GPU counterpart to + the CUDA qwen3-moe path. Tracks GitHub #1582.' +- id: M-GPU-MOE-3-Q8K-THROUGHPUT + github_issue: 1583 + item_type: task + title: M-GPU-MOE-3 — qwen3-moe GPU throughput >=150 tok/s via CUDA f32->Q8K activation quant + status: planned + priority: medium + assigned_to: null + created: 2026-07-05 00:00:00+00:00 + updated: 2026-07-05 00:00:00+00:00 + spec: docs/specifications/roadmap-next-wave-2026-07-05.md + acceptance_criteria: + - 'CUDA f32->Q8_K activation-quant kernel wired into the expert path + DP4A dispatch; >=150 tok/s on + RTX 4090 at VRAM <=95%; flips qwen3-moe-forward-gpu-v1 to ACTIVE_RUNTIME. (Requires the #1749 MoE-aware + `apr bench` dispatch fix first.)' + - 'RED-turning mutation: `apr bench qwen3-coder-30b-a3b.gguf --device cuda` must report >=150 tok/s + (currently the bench path panics on MoE GGUFs, #1749, and the fp32-activation path is below target).' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - pillar-3 + - gpu + - cuda + - moe + - github-1583 + - github-1838 + - from-issue-triage-2026-07-05 + notes: 'Consolidates #1583 (>=150 tok/s throughput target) + #1838 (the CUDA f32->Q8K activation-quant + approach to close v1.8.0). The L47 expert-routing argmax-divergence cascade (47/48 layers >=0.99, + documented in the #1583 thread) is parked separately as a precision-uplift item. Tracks GitHub #1583 + and #1838.' +- id: APR-PERF-GATE-001 + github_issue: 2706 + item_type: epic + title: The receipt rule — a performance number is evidence only if something can prove how it was measured + status: inprogress + priority: critical + assigned_to: null + created: &id001 2026-08-27 00:00:00+00:00 + updated: 2026-08-29 00:00:00+00:00 + spec: docs/specifications/PP-LLAMA-001-MASTER.md + acceptance_criteria: + - The epic closes when docs/specifications/PP-LLAMA-001-MASTER.md reaches ARMED. Its section 7.5 states the conditions, and they are the acceptance criteria of this epic verbatim. + - PP-6, PP-26, PP-27, PP-28, PP-29 and PP-33 are ARMED (both selftest cases present under the exact names in section 6 of the master). + - PP-2, PP-13, PP-24 and PP-30 are ARMED, which requires the GET /v1/effective-config endpoint (master section 12 row 6). + - 'PP-29: scripts/spec_conformance.sh is GREEN inside the guard-runner-labels job, which the bare required check gate needs at .github/workflows/ci.yml. It replaces the retired mutation registry.' + - The JOIN (master section 12 row 7) reproduces the committed zero-GPU fixture to four decimals. + - One MEASURED reference-cell receipt exists at n >= 5 interleaved replicates (master section 12 row 18), and armed_by is set in scripts/perf-matrix.yaml for every band that PASSES P-5. + - scripts/perf-matrix.yaml carries a delta row with a named author for every gated metric, replacing the legacy B1/B2 floors, in the same commit. + - F-BATCH-001 passes at every c > 1 (measured 2.45 on lambda, 2.85 on gx10, postcondition < 2) + - 'Child tickets (41 as of 2026-08-29), linked by github_issue 2706: BENCH-003, PERF-000 .. PERF-037, PERF-039, PERF-040. PERF-038 was never issued: no commit, branch, PR or issue in any repo mentions it (searched 2026-08-29), so the sequence is deliberately left with a hole rather than filled with an invented ticket.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - perf + - gate + - receipt-rule + - epic + notes: 'Governed by docs/specifications/PP-LLAMA-001-MASTER.md since 2026-09-02; the superseded v2.2 spec is at docs/archive/perf-2026-09-01/ and the reviewed draft it replaced at docs/archive/perf-2026-09-02/. Status reconciled against origin/main by PERF-040 on 2026-08-29 at 50d2bc2bb: 0 of 8 scripts/perf-matrix.yaml cells carry a baseline (all UNMEASURED); perf_gate.sh IS invoked, but only as --selftest at .github/workflows/ci.yml, because nothing on main can write the receipt its real mode reads (PERF-024/PERF-025, open PR #2744); F-BATCH-001 is RED at c=2 per contracts/batch-admission-v1.yaml. NO CELL EXPIRES BY DATE ANY MORE. The fixed calendar expiry is replaced by the derived-expiry rule of the master sections 8 and 12: a cell inherits the latest expiry among the section 12 obligation rows that block it, computed by scripts/spec_conformance.sh into evidence/parity/derived_expiries.json, and an expiry moves only by an amendment recorded in the master Appendix D. On expiry an instrument row makes every cell it blocks FAIL: INSTRUMENT.' +- id: BENCH-003 + github_issue: 2706 + item_type: task + title: Characterize variance idle + loaded, n>=10; derive dispersion thresholds + status: completed + priority: high + assigned_to: null + created: *id001 + updated: 2026-08-29 00:00:00+00:00 + spec: docs/specifications/PP-LLAMA-001-MASTER.md + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - perf + - receipt-rule + notes: 'VERIFIED on origin/main 2026-08-29: scripts/lib/bench_threshold.py bootstrap_median_floor() + derives the per-host floor by resampling raw samples (landed ce712eae0 / PR #2705). The RFC + 3x-pooled-stddev rule is recorded there as falsified against this repo own data.' +- id: PERF-000 + github_issue: 2706 + item_type: task + title: 'Falsify the single-lock hypothesis; is #2 the same defect as #3' + status: completed + priority: high + assigned_to: null + created: *id001 + updated: 2026-08-29 00:00:00+00:00 + spec: docs/specifications/PP-LLAMA-001-MASTER.md + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - perf + - receipt-rule + notes: 'VERIFIED on origin/main 2026-08-29: scripts/perf000_serialization_probe.sh (landed ce712eae0 / + PR #2705) carries the pre-recorded prediction; the answer is written into + contracts/batch-admission-v1.yaml F-BATCH-001 measured block.' +- id: PERF-001 + github_issue: 2706 + item_type: task + title: Iteration-level scheduling (Orca design) — REAL BUT PARTIAL, F-BATCH-001 red at c=2 + status: inprogress + priority: high + assigned_to: null + created: 2026-08-27 00:00:00+00:00 + updated: 2026-08-29 00:00:00+00:00 + spec: docs/specifications/PP-LLAMA-001-MASTER.md + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - perf + - receipt-rule + notes: 'VERIFIED on origin/main 2026-08-29: crates/aprender-serve/src/api/iteration_scheduler.rs implements the Orca (OSDI 2022) design. PARTIAL BY ITS OWN CONTRACT: contracts/batch-admission-v1.yaml F-BATCH-001 records verdict RED AT c=2 (serialization_index 2.45 >= 2), so the epic F-BATCH-001 acceptance criterion is NOT met. DOWNGRADED from completed 2026-08-29 by PERF-041: the credited 3.32x aggregate at N=8 is throughput of GARBAGE tokens. Batched CUDA decode emits a constant token to the max_tokens cap for every m>1 and never emits a stop token (#2753); the m=1 fast path in the same run returns coherent English with finish=stop. Aggregate at c=2 is honestly 0.82x of a SINGLE client. F-BATCH-001 stays RED and the mechanism, not just the margin, is unfinished. PP cross-ref (master Appendix A): PP-26 (batch-invariance witness) and section 9 defects 2 and 5. Master section 12 row 1 is the discharging row; no c>1 aggregate may be published while this is red.' +- id: PERF-002 + github_issue: 2706 + item_type: task + title: --batch bounded-time regression test and fix + status: completed + priority: high + assigned_to: null + created: *id001 + updated: 2026-08-29 00:00:00+00:00 + spec: docs/specifications/PP-LLAMA-001-MASTER.md + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - perf + - receipt-rule + notes: 'VERIFIED on origin/main 2026-08-29: contracts/batch-admission-v1.yaml (F-BATCH-002 fast-path + admission, F-BATCH-003 mid-generation join, F-BATCH-004 c=1 latency) cites APR-PERF-GATE-001 s10.1 + step 6 PERF-001/PERF-002. PERF-000 falsified the hang framing: it is a latency regression, not a + deadlock.' +- id: PERF-003 + github_issue: 2706 + item_type: task + title: 'Jidoka: --gpu on a build with no GPU backend FAILS (exit 9)' + status: completed + priority: high + assigned_to: null + created: *id001 + updated: 2026-08-29 00:00:00+00:00 + spec: docs/specifications/PP-LLAMA-001-MASTER.md + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - perf + - receipt-rule + notes: 'VERIFIED on origin/main 2026-08-29: ensure_accelerator_available() in + crates/apr-cli/src/commands/serve/mod.rs returns CliError::FeatureDisabled when an accelerator is + requested and no cuda/wgpu feature is compiled in; contracts/accelerator-request-v1.yaml carries + F-ACCEL-001..007.' +- id: PERF-004 + github_issue: 2706 + item_type: task + title: Receipt schema v2.2 — all metrics, workload, tokenization, scheduler block, drain + status: inprogress + priority: high + assigned_to: null + created: 2026-08-27 00:00:00+00:00 + updated: 2026-08-29 00:00:00+00:00 + spec: docs/specifications/PP-LLAMA-001-MASTER.md + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - perf + - receipt-rule + notes: 'CORRECTED from completed 2026-08-29. Schema half IS on origin/main (scripts/lib/bench_receipt.py plus its 14-case discrimination table; perf_gate.sh arm_c_integrity requires tokenization.method and drain_ms; crates/aprender-test-lib/src/perf_gate/receipt.rs names the s4.4.9 scheduler block). Producer-mapping half is NOT: scripts/perf-receipt-fields.yaml, scripts/lib/perf_receipt.py and check_perf_receipt_fields_have_producers.sh are ABSENT from origin/main, PR #2716 was CLOSED unmerged, and PR #2711 held PERF-004-SCHEMA back after adversarial verification found its claimed end-to-end run could not have executed. Branch feat/perf-004-schema pushed. PP cross-ref (master Appendix A): PP-2, PP-13 and PP-30 (server-reported config, no inferred field, started_utc plus clock_source); also PP-4, PP-10 and PP-11. Master section 12 row 6.' +- id: PERF-005 + github_issue: 2706 + item_type: task + title: ollama-style GPU-less device test, merge phase + status: completed + priority: high + assigned_to: null + created: *id001 + updated: 2026-08-29 00:00:00+00:00 + spec: docs/specifications/PP-LLAMA-001-MASTER.md + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - perf + - receipt-rule + notes: 'VERIFIED on origin/main 2026-08-29: the GPU-less device test is the pair in + crates/apr-cli/src/commands/serve/mod.rs tests: the_refusal_is_total_over_every_input (exhaustive + over all 16 input cells, Err exactly when a request cannot be honoured) and + the_guard_is_actually_wired_into_run (fails if run() stops calling the check).' +- id: PERF-006 + github_issue: 2706 + item_type: task + title: One compute_class() and max_in_flight -> banner, /health, receipt (andon) + status: inprogress + priority: high + assigned_to: null + created: 2026-08-27 00:00:00+00:00 + updated: 2026-08-29 00:00:00+00:00 + spec: docs/specifications/PP-LLAMA-001-MASTER.md + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - perf + - receipt-rule + notes: 'CORRECTED from planned 2026-08-29. NOT on origin/main: crates/aprender-test-lib/src/perf_gate/mod.rs:310 asserts max_in_flight is neither emitted nor classified, and the only compute_class() is the bench-local one in crates/apr-cli/src/commands/bench.rs:283, not one function feeding banner + /health + receipt. Open PR #2711 (branch feat/receipt-rule-b2, pushed) carries the andon commit. PP cross-ref (master Appendix A): PP-2, PP-13 and PP-16. compute_class must be the dispatch path taken, read from the process, and max_in_flight must be server-reported. Master section 12 row 6.' +- id: PERF-007 + github_issue: 2706 + item_type: task + title: Signed receipt push via forjar cron; staleness arm + status: planned + priority: high + assigned_to: null + created: *id001 + updated: 2026-08-29 00:00:00+00:00 + spec: docs/specifications/PP-LLAMA-001-MASTER.md + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - perf + - receipt-rule + notes: 'CONFIRMED planned 2026-08-29. Searched origin/main (scripts/, .github/, contracts/, docs/) for + a signed receipt push or a staleness arm: no artifact. gh search issues/prs --repo paiml/infra + PERF-007 returns []. No aprender branch or open PR references it. PP cross-ref (master Appendix A): PP-21 + (signature valid and covering the commit under test), with PP-20 for the pin staleness half. Master section + 12 rows 0c and 12.' +- id: PERF-008 + github_issue: 2706 + item_type: task + title: Harden fabricated-baseline guard (shape not literal); commit true count + status: completed + priority: high + assigned_to: null + created: *id001 + updated: 2026-08-29 00:00:00+00:00 + spec: docs/specifications/PP-LLAMA-001-MASTER.md + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - perf + - receipt-rule + notes: 'CORRECTED from planned 2026-08-29. On origin/main: scripts/check_no_fabricated_baselines.sh + (+545 lines, shape matching not literals) and scripts/fabricated_baseline_rust_sites.txt (73 lines, + the committed true count), landed de8fbc407 / PR #2710. The shrink-only claim it printed but did not + enforce was armed in 50d2bc2bb / PR #2733 via scripts/check_baseline_ratchets.sh. proof:scripts/check_no_fabricated_baselines.sh' +- id: PERF-009 + github_issue: 2706 + item_type: task + title: One benchmarking entrypoint, enforced by a shrink-only guard + status: completed + priority: high + assigned_to: null + created: *id001 + updated: 2026-08-29 00:00:00+00:00 + spec: docs/specifications/PP-LLAMA-001-MASTER.md + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - perf + - receipt-rule + notes: 'VERIFIED on origin/main 2026-08-29: scripts/check_no_competing_harnesses.sh (landed ce712eae0 / + PR #2705) names apr test llm bench canonical at BASELINE=0 and the shrink-only baseline is enforced + by check_baseline_ratchets.sh.' +- id: PERF-010 + github_issue: 2706 + item_type: task + title: check_perf_claims_cite_receipts.sh + [X]-figure guard; delete comparator claims from book/ + status: completed + priority: high + assigned_to: null + created: *id001 + updated: 2026-08-29 00:00:00+00:00 + spec: docs/specifications/PP-LLAMA-001-MASTER.md + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - perf + - receipt-rule + notes: 'CORRECTED from planned 2026-08-29. On origin/main: scripts/check_perf_claims_cite_receipts.sh + (339 lines), scripts/perf_claim_citation_baseline.txt (156 lines), the widened + scripts/check_no_claim_literals.sh and the book/ edits, all landed de8fbc407 / PR #2710. RESIDUAL, + open in PR #2742: the [X]-figure detector caught 1 of 6 shapes and missed the U+00D7 form the epic + own headline fabrication is written in. proof:scripts/check_perf_claims_cite_receipts.sh' +- id: PERF-011 + github_issue: 2706 + item_type: task + title: Prove gx10 llama.cpp buildable (-DGGML_CUDA_ARCHITECTURES=121) + status: planned + priority: high + assigned_to: null + created: *id001 + updated: 2026-08-29 00:00:00+00:00 + spec: docs/specifications/PP-LLAMA-001-MASTER.md + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - perf + - receipt-rule + notes: 'CONFIRMED planned 2026-08-29. -DGGML_CUDA_ARCHITECTURES=121 appears on origin/main only as + prose (the spec at lines 509 and 690, and .claude/skills/apr-dogfood/SKILL.md) - no build script, no + receipt, no proof. gh search issues/prs --repo paiml/infra PERF-011 returns []. Blocks the gx10 + comparator cells. PP cross-ref (master Appendix A): PP-20 (the comparator pin carries commit, cmake line, + template and expiry) and master section 12 row 15, the gx10 shakedown cell.' +- id: PERF-012 + github_issue: 2706 + item_type: task + title: mini c=8/c=16 — measure or re-decide NOT_APPLICABLE + status: inprogress + priority: high + assigned_to: null + created: 2026-08-27 00:00:00+00:00 + updated: 2026-08-29 00:00:00+00:00 + spec: docs/specifications/PP-LLAMA-001-MASTER.md + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - perf + - receipt-rule + notes: 'CORRECTED from planned 2026-08-29. Branch evidence/perf-012-mini is PUSHED (9aae2e13f, evidence/perf-012-mini/findings.md plus 8 raw band JSONs) and concludes mini serializes on arm64 too and its Metal path does not exist. NOT on origin/main and NO PR is open, so the finding is currently unreviewable and uncitable by the gate. PP cross-ref (master Appendix A): PP-16 and PP-24. The master decides mini as NA with decided_by rather than a permanent UNMEASURED; master section 12 row 5.' +- id: PERF-013 + github_issue: 2706 + item_type: task + title: Dedicated single-agent intel label; forjar apply + deploy + verify + status: inprogress + priority: high + assigned_to: null + created: 2026-08-27 00:00:00+00:00 + updated: 2026-08-29 00:00:00+00:00 + spec: docs/specifications/PP-LLAMA-001-MASTER.md + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - perf + - receipt-rule + notes: 'CORRECTED from planned 2026-08-29. paiml/infra#338 is MERGED - the perf-solo label ships at cardinality 1 on intel-clean-room-16 - but it closed with one item explicitly unproven: no job has ever run on the label. Open PR #2720 (branch perf/perf-solo-lane-receipt, pushed) puts perf-solo on the BEAT speed lane runs-on and records RUNNER_NAME. PP cross-ref (master Appendix A): PP-19 (one global concurrency group per host, cancel-in-progress false, no foreign compute PID). Master section 12 row 12.' +- id: PERF-014 + github_issue: 2706 + item_type: task + title: Delete hardcoded causal string, profile_print_hotspot.rs + status: completed + priority: high + assigned_to: null + created: *id001 + updated: 2026-08-29 00:00:00+00:00 + spec: docs/specifications/PP-LLAMA-001-MASTER.md + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - perf + - receipt-rule + notes: 'VERIFIED on origin/main 2026-08-29: crates/apr-cli/src/commands/profile_print_hotspot.rs was + rewritten in ce712eae0 / PR #2705 and again in de8fbc407 / PR #2710; profile.rs:389 now names the + PERF-014 shape as the pattern to refuse.' +- id: PERF-015 + github_issue: 2706 + item_type: task + title: Fix invalid arithmetic, kernel.rs + status: completed + priority: high + assigned_to: null + created: *id001 + updated: 2026-08-29 00:00:00+00:00 + spec: docs/specifications/PP-LLAMA-001-MASTER.md + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - perf + - receipt-rule + notes: 'VERIFIED on origin/main 2026-08-29: crates/apr-cli/src/commands/kernel.rs:348 - PERF-015: + returns (hotspots, wall_us, tokens), the pass now times ITSELF - and kernel.rs:200 records that both + terms of the ratio come from the SAME pass (landed ce712eae0 / PR #2705).' +- id: PERF-016 + github_issue: 2706 + item_type: task + title: Audit apr profile whole for further fabricated causal claims + status: completed + priority: high + assigned_to: null + created: *id001 + updated: 2026-08-29 00:00:00+00:00 + spec: docs/specifications/PP-LLAMA-001-MASTER.md + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - perf + - receipt-rule + notes: 'CORRECTED from planned 2026-08-29. On origin/main: + crates/apr-cli/src/commands/profile_perf016_tests.rs (198 lines) plus the annotated call sites in + profile_ollama.rs:224/347/437 and profile.rs:380, landed de8fbc407 / PR #2710. The audit found a + third fabricated causal claim and a guard that was GREEN on it. proof:crates/apr-cli/src/commands/profile_perf016_tests.rs' +- id: PERF-017 + github_issue: 2706 + item_type: task + title: Chunked prefill; ratchets Arm E + status: planned + priority: high + assigned_to: null + created: *id001 + updated: 2026-08-29 00:00:00+00:00 + spec: docs/specifications/PP-LLAMA-001-MASTER.md + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - perf + - receipt-rule + notes: 'CONFIRMED planned 2026-08-29. scripts/perf_gate.sh has arm_e_interference() but it is REPORTING + only (W2, and W2 has no injector - see PERF-020); nothing on origin/main ratchets Arm E. Depends on + PERF-001, whose F-BATCH-001 is still RED at c=2. No branch, no PR. PP cross-ref (master Appendix A): PP-4 + (prefill is first-class and present on every band) and PP-31 (per-band ratchets seeded at the last MEASURED + receipt). Arm E becomes itl_p95, REPORTING.' +- id: PERF-018 + github_issue: 2706 + item_type: task + title: Paged KV cache (PagedAttention design); ratchets Arm D + status: planned + priority: high + assigned_to: null + created: *id001 + updated: 2026-08-29 00:00:00+00:00 + spec: docs/specifications/PP-LLAMA-001-MASTER.md + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - perf + - receipt-rule + notes: 'CONFIRMED planned 2026-08-29. scripts/perf_gate.sh has arm_d_memory() in REPORTING mode; no + block table or paged KV allocator exists under crates/aprender-serve/src on origin/main. Depends on + PERF-001. No branch, no PR. PP cross-ref (master Appendix A): PP-24 (slots_admitted and the derived ladder) + and PP-2 (kv_per_slot, kv_bytes_reserved and vram_peak reported by the server). Arm D becomes REPORTING + fields in PP-2.' +- id: PERF-019 + github_issue: 2706 + item_type: task + title: One client, both servers; retire llama-bench from the comparator path + status: inprogress + priority: high + assigned_to: null + created: 2026-08-27 00:00:00+00:00 + updated: 2026-08-29 00:00:00+00:00 + spec: docs/specifications/PP-LLAMA-001-MASTER.md + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - perf + - receipt-rule + notes: 'CORRECTED from planned 2026-08-29. scripts/check_comparator_one_client.sh is ABSENT from origin/main. PR #2713 was CLOSED unmerged; PR #2711 explicitly held PERF-019 back because its guard has a vacuous pass one level below where it believed it closed one (the sentinel proves the filter engaged, nothing proves the walker did). Branch feat/perf-019-oneclient pushed; carried in open PR #2742. PP cross-ref (master Appendix A): PP-25 (one client binary drives both lanes, its sha256 in the receipt) and master section 5.3, which retires llama-bench from the comparator path entirely. Master section 12 row 7.' +- id: PERF-020 + github_issue: 2706 + item_type: task + title: Workload W2 corpus + injector; Arms D and E, REPORTING + status: inprogress + priority: high + assigned_to: null + created: 2026-08-27 00:00:00+00:00 + updated: 2026-08-29 00:00:00+00:00 + spec: docs/specifications/PP-LLAMA-001-MASTER.md + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - perf + - receipt-rule + notes: 'CORRECTED from planned 2026-08-29. Arms D and E exist in scripts/perf_gate.sh on origin/main in REPORTING mode, and crates/aprender-serve/benchmarks/qwen-coder/prompts-w2.jsonl is committed - but crates/aprender-test-lib/src/perf_gate/mod.rs:134 declares the Arm E out-of-band injector unproduced, and PR #2746 (PERF-039) shows the corpus was unreadable by the only loader in the tree, so nothing had ever parsed that file. PP cross-ref (master Appendix A): master section 5.1 workload W2, REPORTING, and PP-4 (agg, dec and prefill on every band).' +- id: PERF-021 + github_issue: 2706 + item_type: task + title: Accelerator contract — retire boolean --gpu for a quantity, resolved-quantity reporting + status: inprogress + priority: high + assigned_to: null + created: 2026-08-27 00:00:00+00:00 + updated: 2026-08-29 00:00:00+00:00 + spec: docs/specifications/PP-LLAMA-001-MASTER.md + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - perf + - receipt-rule + notes: 'VERIFIED PARTIAL on origin/main 2026-08-29: GpuLayerRequest (crates/apr-cli/src/commands/serve/types.rs:504), --gpu-layers, --device and --list-devices (serve_commands.rs, dispatch_run.rs:184) all ship, and explicit-wins is enforced at serve/mod.rs:83-95. Open PR #2707 (branch feat/perf-021-landing, pushed, 9 commits) reports that two of three surfaces verified nothing, so in_progress is correct. PP cross-ref (master Appendix A): PP-15 (no boolean accelerator flag on any surface; a quantity with a server-reported resolved value). Master section 12 row 0d, section 9 defect 9.' +- id: PERF-022 + github_issue: 2706 + item_type: task + title: Five-whys and cost the three O-1 distribution options (ESCALATION, not a default) + status: planned + priority: high + assigned_to: null + created: *id001 + updated: 2026-08-29 00:00:00+00:00 + spec: docs/specifications/PP-LLAMA-001-MASTER.md + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - perf + - receipt-rule + notes: 'CONFIRMED planned 2026-08-29. The O-1 three-way choice is recorded only as a spec question + (APR-PERF-GATE-001-v2.2.md line 1098); no five-whys and no costing exists on origin/main. PR #2707 + states plainly that none of its work ships CUDA in the published artifact and that no code change + substitutes for this decision. Operator-owned escalation. PP cross-ref (master Appendix A): PP-19. Any + distribution option that puts two runs on one device breaks the isolation rule, so the cost of each option + is a cost against PP-19. Master section 12 row 12.' +- id: PERF-023 + github_issue: 2706 + item_type: task + title: Partial GPU offload — needs a free-VRAM query no apr build currently reaches + status: planned + priority: high + assigned_to: null + created: *id001 + updated: 2026-08-29 00:00:00+00:00 + spec: docs/specifications/PP-LLAMA-001-MASTER.md + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - perf + - receipt-rule + notes: 'CONFIRMED planned 2026-08-29. Filed by PR #2707, which REFUSES a partial --gpu-layers request + rather than rounding it, because OwnedQuantizedModelCuda takes no layer count and uploads every + layer. The free-VRAM query that would let a partial request be honoured does not exist in any apr + build. No branch, no PR of its own. PP cross-ref (master Appendix A): PP-2 and PP-24. The free-VRAM query is + the unrecorded input of master section 9 defect 7 and of the registered max_batch prediction in section 10. + Master section 12 row 6.' +- id: PERF-024 + github_issue: 2706 + item_type: task + title: Conformant s4.4 measurement protocol for the load test - termination rule, drain_ms, tokenization block + status: inprogress + priority: high + assigned_to: null + created: 2026-08-29 00:00:00+00:00 + updated: 2026-08-29 00:00:00+00:00 + spec: docs/specifications/PP-LLAMA-001-MASTER.md + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - perf + - receipt-rule + notes: 'Filed after the roadmap was last written; added by PERF-040 on 2026-08-29. NOT on origin/main: crates/aprender-test-lib/src/llm/band.rs and perf_gate/{bootstrap,metrics}.rs are absent, and main own perf_gate/mod.rs names the integration work as a separate ticket. PR #2717 CLOSED unmerged; branch feat/perf-024-conformant-client pushed; carried in open PR #2744 (stacked on #2742). PP cross-ref (master Appendix A): PP-27 and PP-28 (streaming with a dual witness; temperature, seed, ignore_eos and max_tokens on the wire; completion_tokens equal to n_predict), with PP-10 and PP-11 for drain and tokenization. Master section 5.1 and section 12 row 0b.' +- id: PERF-025 + github_issue: 2706 + item_type: task + title: apr test llm bench --band - give the s4.4 protocol a caller and perf_gate.sh real mode an input + status: inprogress + priority: high + assigned_to: null + created: 2026-08-29 00:00:00+00:00 + updated: 2026-08-29 00:00:00+00:00 + spec: docs/specifications/PP-LLAMA-001-MASTER.md + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - perf + - receipt-rule + notes: 'Filed after the roadmap was last written; added by PERF-040 on 2026-08-29. This is the ticket the operator note calls the band CLI. On 50d2bc2bb a grep for ReceiptInput/BandInput/DerivedBand/perf_gate:: outside the module returns rc=1 - nothing calls the protocol or the receipt producer, and perf_gate.sh real mode is invoked nowhere (only --selftest, ci.yml:1011). Open PR #2744; abandoned branch feat/n1-band-cli contributed the shape only. PP cross-ref (master Appendix A): PP-4 and PP-7 (all three metrics per band; raw per-request samples retained). Master section 12 rows 0b and 7.' +- id: PERF-026 + github_issue: 2706 + item_type: task + title: 'drain_ms producer and receipt emitter - the gate demanded a field nothing in the repo could write' + status: completed + priority: high + assigned_to: null + created: 2026-08-29 00:00:00+00:00 + updated: 2026-08-29 00:00:00+00:00 + spec: docs/specifications/PP-LLAMA-001-MASTER.md + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - perf + - receipt-rule + notes: 'Filed after the roadmap was last written; added by PERF-040 on 2026-08-29. VERIFIED on + origin/main: crates/aprender-test-lib/src/perf_gate/drain.rs (778 lines) and perf_gate/receipt.rs + (537 lines), landed 50d2bc2bb / PR #2733. receipt.rs refuses to synthesise what it cannot measure and + names every absent field in unproduced_fields with its reason. PR #2724 was CLOSED unmerged; the + batch is what landed. proof:crates/aprender-test-lib/src/perf_gate/drain.rs' +- id: PERF-027 + github_issue: 2706 + item_type: task + title: 'Six guards named the CODE for failures that were the HOST - one classifier, eleven decision points' + status: completed + priority: high + assigned_to: null + created: 2026-08-29 00:00:00+00:00 + updated: 2026-08-29 00:00:00+00:00 + spec: docs/specifications/PP-LLAMA-001-MASTER.md + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - perf + - receipt-rule + notes: 'Filed after the roadmap was last written; added by PERF-040 on 2026-08-29. VERIFIED on + origin/main: scripts/cargo_classify.sh (265 lines, sourceable and option-neutral) applied at 11 + decision points across check_facade_compat.sh, check_book_examples_compile.sh, + check_format_sovereignty.sh, check_wasm32_core_builds.sh, check_lockfile_current.sh and + check_readme_claims.sh, plus scripts/lib/cargo_failure_cases/ - landed 50d2bc2bb / PR #2733. proof:scripts/cargo_classify.sh' +- id: PERF-028 + github_issue: 2706 + item_type: task + title: 'Twelve baselines said SHRINK-ONLY and compared against nothing' + status: completed + priority: high + assigned_to: null + created: 2026-08-29 00:00:00+00:00 + updated: 2026-08-29 00:00:00+00:00 + spec: docs/specifications/PP-LLAMA-001-MASTER.md + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - perf + - receipt-rule + notes: 'Filed after the roadmap was last written; added by PERF-040 on 2026-08-29. VERIFIED on + origin/main: scripts/check_baseline_ratchets.sh (358 lines) and scripts/lib_baseline_ratchet.sh (284 + lines), landed 50d2bc2bb / PR #2733. Open PR #2742 extends it to tell a detector WIDENING from + LAUNDERING, which PERF-010 needed. proof:scripts/lib_baseline_ratchet.sh' +- id: PERF-029 + github_issue: 2706 + item_type: task + title: 'A dead byte-identical benchmark client, and 169 tests that ran only by feature-unification accident' + status: completed + priority: high + assigned_to: null + created: 2026-08-29 00:00:00+00:00 + updated: 2026-08-29 00:00:00+00:00 + spec: docs/specifications/PP-LLAMA-001-MASTER.md + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - perf + - receipt-rule + notes: 'Filed after the roadmap was last written; added by PERF-040 on 2026-08-29. VERIFIED on + origin/main: crates/aprender-serve/src/http_client/preflight.rs (370 lines, same sha256 as its + sibling benchmark_runner.rs) no longer exists in the tree; deleted in 50d2bc2bb / PR #2733. proof:PR#2733' +- id: PERF-030 + github_issue: 2706 + item_type: task + title: 'The receipt producer recorded accel_absent for every accelerator - SIGPIPE under pipefail' + status: completed + priority: high + assigned_to: null + created: 2026-08-29 00:00:00+00:00 + updated: 2026-08-29 00:00:00+00:00 + spec: docs/specifications/PP-LLAMA-001-MASTER.md + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - perf + - receipt-rule + notes: 'Filed after the roadmap was last written; added by PERF-040 on 2026-08-29. VERIFIED on + origin/main: scripts/parity_host_receipt.sh now reads both accelerator probes from herestrings, never + a pipe, with the measurement in the comment (141 on 10/10 repeats with pipefail, 0 without, pattern + matches 5 times). Found on gx10, reproduced on lambda, landed 50d2bc2bb / PR #2733. proof:scripts/parity_host_receipt.sh' +- id: PERF-031 + github_issue: 2706 + item_type: task + title: Run the BEAT speed lane on perf-solo and make the job name its own runner + status: inprogress + priority: high + assigned_to: null + created: 2026-08-29 00:00:00+00:00 + updated: 2026-08-29 00:00:00+00:00 + spec: docs/specifications/PP-LLAMA-001-MASTER.md + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - perf + - receipt-rule + notes: 'Filed after the roadmap was last written; added by PERF-040 on 2026-08-29. Open PR #2720 (branch perf/perf-solo-lane-receipt, pushed). It is the half PERF-013 left unproven: all 16 agents on intel report hostname mac-server, so RUNNER_NAME is the only field that can say which agent served a job. PP cross-ref (master Appendix A): PP-19. A speed lane that shares a host with any other job is the confound PP-19 exists to remove. Master section 12 row 12.' +- id: PERF-032 + github_issue: 2706 + item_type: task + title: 'check_hardcoded_paths --full has never gated anything; 20 shipped paths landed behind it' + status: completed + priority: high + assigned_to: null + created: 2026-08-29 00:00:00+00:00 + updated: 2026-08-29 00:00:00+00:00 + spec: docs/specifications/PP-LLAMA-001-MASTER.md + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - perf + - receipt-rule + notes: 'Filed after the roadmap was last written; added by PERF-040 on 2026-08-29. VERIFIED on + origin/main: scripts/check_hardcoded_paths.sh (+158 lines) and + scripts/hardcoded_path_shipped_baseline.txt, with the --full mode now invoked from + .github/workflows/ci.yml; landed 50d2bc2bb / PR #2733. proof:scripts/check_hardcoded_paths.sh' +- id: PERF-033 + github_issue: 2706 + item_type: task + title: The comparator pin was global while its builds are per-host, and it accepted a bare prefix + status: inprogress + priority: high + assigned_to: null + created: 2026-08-29 00:00:00+00:00 + updated: 2026-08-29 00:00:00+00:00 + spec: docs/specifications/PP-LLAMA-001-MASTER.md + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - perf + - receipt-rule + notes: 'Filed after the roadmap was last written; added by PERF-040 on 2026-08-29. Open PR #2738 (branch feat/p1-batch2, pushed; merged from feat/m1-pin). gx10 was pointed at one of four llama.cpp trees, and a pin of 23b8cc4 accepted two different trees at rc=0. Not on origin/main. PP cross-ref (master Appendix A): PP-20, and master section 5.3, which makes the pin a per-band template with pinned_on and pin_expiry. Master section 12 row 3.' +- id: PERF-034 + github_issue: 2706 + item_type: task + title: The decode sampler full-sorted 152,064 logits per token to keep 40 + status: inprogress + priority: high + assigned_to: null + created: 2026-08-29 00:00:00+00:00 + updated: 2026-08-29 00:00:00+00:00 + spec: docs/specifications/PP-LLAMA-001-MASTER.md + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - perf + - receipt-rule + notes: 'Filed after the roadmap was last written; added by PERF-040 on 2026-08-29. Open PR #2738 (branch feat/p1-batch2, pushed; merged from feat/m2-alloc). Reported 4.00 allocs/token and 5,474,948 B -> 0.00 and 0, about 10.4x; its allocation harness is only correct under --test-threads=1, fixed in the same branch. Not on origin/main. PP cross-ref (master Appendix A): master section 9 defect 4 (decode at c=1 is a gated metric under P-3) and PP-28, since the sampler is pinned on the wire for both lanes.' +- id: PERF-035 + github_issue: 2706 + item_type: task + title: CUDA was built by no required check, and a 4,545-line CUDA path had never compiled once + status: inprogress + priority: high + assigned_to: null + created: 2026-08-29 00:00:00+00:00 + updated: 2026-08-29 00:00:00+00:00 + spec: docs/specifications/PP-LLAMA-001-MASTER.md + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - perf + - receipt-rule + notes: 'Filed after the roadmap was last written; added by PERF-040 on 2026-08-29. Open PR #2738 (branch feat/p1-batch2, pushed; merged from feat/m3-cuda-ci). A type error in aprender-serve/src/cuda/mod.rs left the required scope green. Not on origin/main. PP cross-ref (master Appendix A): master section 9 defect 8, whose lever is now server_config.build_features_cli from GET /v1/effective-config (PP-2) rather than a harness flag (PP-13); PP-18 for the ancestor check on the measuring binaries.' +- id: PERF-036 + github_issue: 2706 + item_type: task + title: 215 hardcoded machine paths in aprender-serve, across 185 files + status: inprogress + priority: high + assigned_to: null + created: 2026-08-29 00:00:00+00:00 + updated: 2026-08-29 00:00:00+00:00 + spec: docs/specifications/PP-LLAMA-001-MASTER.md + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - perf + - receipt-rule + notes: 'Filed after the roadmap was last written; added by PERF-040 on 2026-08-29. Open PR #2738 (branch feat/p1-batch2, pushed; merged from feat/m5-serve-paths). The population PERF-032 ratchet now refuses to grow. Not on origin/main. PP cross-ref (master Appendix A): no invariant maps directly. It is a precondition of master section 12 row 15, the gx10 shakedown cell: a receipt is reproducible only if the paths it names exist on a host other than the author machine (PP-18 is the provenance half of the same requirement).' +- id: PERF-037 + github_issue: 2706 + item_type: task + title: The chain only two harness invocations were swallowed, and the harness wrote its receipt before validating + status: inprogress + priority: high + assigned_to: null + created: 2026-08-29 00:00:00+00:00 + updated: 2026-08-29 00:00:00+00:00 + spec: docs/specifications/PP-LLAMA-001-MASTER.md + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - perf + - receipt-rule + notes: 'Filed after the roadmap was last written; added by PERF-040 on 2026-08-29. Open PR #2741 (branch feat/r3-batch3, pushed). A fabricated PASS, not a late diagnosis: test_llm.rs:118 writes --output before :139 validates, so a swallowed refusal left a well-formed report the producer read as a sample - measured rc=0 and lane PASS on a run where 3 of 10 requests died. Not on origin/main. PP cross-ref (master Appendix A): PP-10 (nothing issued at or after window close; drained requests recorded with drain_ms) and PP-21 (the receipt is signed after it is complete, never before). Master section 12 rows 0b and 0c.' +- id: PERF-039 + github_issue: 2706 + item_type: task + title: W1 corpus had three formats and no file, and seed/ignore_eos had no wire representation + status: inprogress + priority: high + assigned_to: null + created: 2026-08-29 00:00:00+00:00 + updated: 2026-08-29 00:00:00+00:00 + spec: docs/specifications/PP-LLAMA-001-MASTER.md + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - perf + - receipt-rule + notes: 'Filed after the roadmap was last written; added by PERF-040 on 2026-08-29. Open PR #2746 (branch feat/t2-batch4, pushed). The spec said prompts-w1.jsonl, the only loader parsed YAML, the CLI help promised a JSON array, and ignore_eos appeared nowhere in the tree. prompts-w2.jsonl was already committed and unreadable by that loader, which is why PERF-020 is not complete. Not on origin/main. PP cross-ref (master Appendix A): PP-28. Master section 5.1 records that adding ignore_eos to prompts-w1.jsonl rotates the corpus sha256, which is a component of the PP-22 join key and the PP-9 cell key. Master section 12 row 0b.' +- id: PERF-040 + github_issue: 2706 + item_type: task + title: Reconcile docs/roadmaps/roadmap.yaml with origin/main - the record said planned for shipped work + status: inprogress + priority: high + assigned_to: null + created: 2026-08-29 00:00:00+00:00 + updated: 2026-08-29 00:00:00+00:00 + spec: docs/specifications/PP-LLAMA-001-MASTER.md + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - perf + - receipt-rule + notes: 'This ticket. Added 2026-08-29. Every one of the 26 pre-existing github_issue 2706 entries was re-decided against origin/main at 50d2bc2bb by naming a merge commit or a file that does exist there, never by trusting a report. Three planned entries were in fact shipped (PERF-008, PERF-010, PERF-016, all in PR #2710); three more were under way rather than untouched (PERF-012, PERF-013, PERF-019); one entry marked completed was not (PERF-004); and 16 tickets filed after the file was last written were absent from it entirely. PERF-038 was searched for and does not exist anywhere. Branch feat/u1-roadmap. PP cross-ref (master Appendix A): master section 13. All 42 spec fields in this file now name docs/specifications/PP-LLAMA-001-MASTER.md; the superseded documents and their local paths are in evidence/parity/LEDGER.md section 13.' +- id: PMAT-753 + github_issue: null + item_type: task + title: 'SATD debt: crates/aprender-contracts/src/probar_gen/wired.rs:251 — wire up struct constructor ' + status: planned + priority: medium + assigned_to: null + created: 2026-09-04 00:10:00+00:00 + updated: 2026-09-04 00:10:00+00:00 + spec: null + acceptance_criteria: + - 'the deferral at crates/aprender-contracts/src/probar_gen/wired.rs:251 is resolved and the comment removed' + notes: 'Minted by the PMAT-938 sweep (PR #2860); the marker text is kept in the comment, keyword-free' +- id: PMAT-754 + github_issue: null + item_type: task + title: 'SATD debt: crates/aprender-data/src/tui/adapter.rs:462 — Replace with lazy loading' + status: planned + priority: medium + assigned_to: null + created: 2026-09-04 00:10:00+00:00 + updated: 2026-09-04 00:10:00+00:00 + spec: null + acceptance_criteria: + - 'the deferral at crates/aprender-data/src/tui/adapter.rs:462 is resolved and the comment removed' + notes: 'Minted by the PMAT-938 sweep (PR #2860); the marker text is kept in the comment, keyword-free' +- id: PMAT-755 + github_issue: null + item_type: task + title: 'SATD debt: crates/aprender-db/src/wasm/streaming_parquet.rs:129 — Full Thrift deserialization' + status: planned + priority: medium + assigned_to: null + created: 2026-09-04 00:10:00+00:00 + updated: 2026-09-04 00:10:00+00:00 + spec: null + acceptance_criteria: + - 'the deferral at crates/aprender-db/src/wasm/streaming_parquet.rs:129 is resolved and the comment removed' + notes: 'Minted by the PMAT-938 sweep (PR #2860); the marker text is kept in the comment, keyword-free' +- id: PMAT-756 + github_issue: null + item_type: task + title: 'SATD debt: crates/aprender-graph/benchmarks/compare_networkx.py:77 — Implement actual CLI benchmark runner' + status: planned + priority: medium + assigned_to: null + created: 2026-09-04 00:10:00+00:00 + updated: 2026-09-04 00:10:00+00:00 + spec: null + acceptance_criteria: + - 'the deferral at crates/aprender-graph/benchmarks/compare_networkx.py:77 is resolved and the comment removed' + notes: 'Minted by the PMAT-938 sweep (PR #2860); the marker text is kept in the comment, keyword-free' +- id: PMAT-757 + github_issue: null + item_type: task + title: 'SATD debt: crates/aprender-graph/benchmarks/compare_networkx.py:85 — Implement actual CLI benchmark runner' + status: planned + priority: medium + assigned_to: null + created: 2026-09-04 00:10:00+00:00 + updated: 2026-09-04 00:10:00+00:00 + spec: null + acceptance_criteria: + - 'the deferral at crates/aprender-graph/benchmarks/compare_networkx.py:85 is resolved and the comment removed' + notes: 'Minted by the PMAT-938 sweep (PR #2860); the marker text is kept in the comment, keyword-free' +- id: PMAT-758 + github_issue: null + item_type: task + title: 'SATD debt: crates/aprender-serve/benches/external_matrix.rs:138 — GGUFTransformer no longer has forward() - use OwnedQuantizedModel' + status: planned + priority: medium + assigned_to: null + created: 2026-09-04 00:10:00+00:00 + updated: 2026-09-04 00:10:00+00:00 + spec: null + acceptance_criteria: + - 'the deferral at crates/aprender-serve/benches/external_matrix.rs:138 is resolved and the comment removed' + notes: 'Minted by the PMAT-938 sweep (PR #2860); the marker text is kept in the comment, keyword-free' +- id: PMAT-759 + github_issue: null + item_type: task + title: 'SATD debt: crates/aprender-serve/src/cuda/executor/layers/cublas_prefill/mod.rs:34 — Add M=4 multi-warp kernel, then raise threshold to 8+.' + status: planned + priority: medium + assigned_to: null + created: 2026-09-04 00:10:00+00:00 + updated: 2026-09-04 00:10:00+00:00 + spec: null + acceptance_criteria: + - 'the deferral at crates/aprender-serve/src/cuda/executor/layers/cublas_prefill/mod.rs:34 is resolved and the comment removed' + notes: 'Minted by the PMAT-938 sweep (PR #2860); the marker text is kept in the comment, keyword-free' +- id: PMAT-760 + github_issue: null + item_type: task + title: 'SATD debt: crates/aprender-test-lib/src/playbook/runner.rs:185 — Execute WASM action via executor' + status: planned + priority: medium + assigned_to: null + created: 2026-09-04 00:10:00+00:00 + updated: 2026-09-04 00:10:00+00:00 + spec: null + acceptance_criteria: + - 'the deferral at crates/aprender-test-lib/src/playbook/runner.rs:185 is resolved and the comment removed' + notes: 'Minted by the PMAT-938 sweep (PR #2860); the marker text is kept in the comment, keyword-free' +- id: PMAT-761 + github_issue: null + item_type: task + title: 'SATD debt: crates/aprender-test-lib/src/playbook/runner.rs:223 — Actually evaluate the expression' + status: planned + priority: medium + assigned_to: null + created: 2026-09-04 00:10:00+00:00 + updated: 2026-09-04 00:10:00+00:00 + spec: null + acceptance_criteria: + - 'the deferral at crates/aprender-test-lib/src/playbook/runner.rs:223 is resolved and the comment removed' + notes: 'Minted by the PMAT-938 sweep (PR #2860); the marker text is kept in the comment, keyword-free' +- id: PMAT-762 + github_issue: null + item_type: task + title: 'SATD debt: crates/aprender-train/src/autograd/wgpu_backward.rs:111 — proper SiLU backward via SILU_BACKWARD_SHADER' + status: planned + priority: medium + assigned_to: null + created: 2026-09-04 00:10:00+00:00 + updated: 2026-09-04 00:10:00+00:00 + spec: null + acceptance_criteria: + - 'the deferral at crates/aprender-train/src/autograd/wgpu_backward.rs:111 is resolved and the comment removed' + notes: 'Minted by the PMAT-938 sweep (PR #2860); the marker text is kept in the comment, keyword-free' +- id: PMAT-763 + github_issue: null + item_type: task + title: 'SATD debt: crates/aprender-train/src/autograd/wgpu_backward.rs:142 — WGSL elementwise add shader. For now, download-add-upload.' + status: planned + priority: medium + assigned_to: null + created: 2026-09-04 00:10:00+00:00 + updated: 2026-09-04 00:10:00+00:00 + spec: null + acceptance_criteria: + - 'the deferral at crates/aprender-train/src/autograd/wgpu_backward.rs:142 is resolved and the comment removed' + notes: 'Minted by the PMAT-938 sweep (PR #2860); the marker text is kept in the comment, keyword-free' +- id: PMAT-764 + github_issue: null + item_type: task + title: 'SATD debt: crates/aprender-train/src/autograd/wgpu_backward.rs:149 — RMSNORM_BACKWARD_SHADER' + status: planned + priority: medium + assigned_to: null + created: 2026-09-04 00:10:00+00:00 + updated: 2026-09-04 00:10:00+00:00 + spec: null + acceptance_criteria: + - 'the deferral at crates/aprender-train/src/autograd/wgpu_backward.rs:149 is resolved and the comment removed' + notes: 'Minted by the PMAT-938 sweep (PR #2860); the marker text is kept in the comment, keyword-free' +- id: PMAT-765 + github_issue: null + item_type: task + title: 'SATD debt: crates/aprender-train/src/autograd/wgpu_backward.rs:179 — proper RMSNorm backward + accumulation' + status: planned + priority: medium + assigned_to: null + created: 2026-09-04 00:10:00+00:00 + updated: 2026-09-04 00:10:00+00:00 + spec: null + acceptance_criteria: + - 'the deferral at crates/aprender-train/src/autograd/wgpu_backward.rs:179 is resolved and the comment removed' + notes: 'Minted by the PMAT-938 sweep (PR #2860); the marker text is kept in the comment, keyword-free' +- id: PMAT-766 + github_issue: null + item_type: task + title: 'SATD debt: crates/aprender-train/src/autograd/wgpu_backward.rs:251 — accumulate gradients across layers, then step once per training step' + status: planned + priority: medium + assigned_to: null + created: 2026-09-04 00:10:00+00:00 + updated: 2026-09-04 00:10:00+00:00 + spec: null + acceptance_criteria: + - 'the deferral at crates/aprender-train/src/autograd/wgpu_backward.rs:251 is resolved and the comment removed' + notes: 'Minted by the PMAT-938 sweep (PR #2860); the marker text is kept in the comment, keyword-free' +- id: PMAT-767 + github_issue: null + item_type: task + title: 'SATD debt: crates/aprender-train/src/autograd/wgpu_training.rs:379 — WGSL transpose shader for zero-copy backward.' + status: planned + priority: medium + assigned_to: null + created: 2026-09-04 00:10:00+00:00 + updated: 2026-09-04 00:10:00+00:00 + spec: null + acceptance_criteria: + - 'the deferral at crates/aprender-train/src/autograd/wgpu_training.rs:379 is resolved and the comment removed' + notes: 'Minted by the PMAT-938 sweep (PR #2860); the marker text is kept in the comment, keyword-free' +- id: PMAT-929 + github_issue: null + item_type: task + title: '0.65.0 release under PP-LLAMA-001 v3.1: verify every LANDED §12 row on main, land the open rows, cut through the F-9 gate (paiml-implement run, receipt docs/audits/impl-PMAT-929-receipt.md)' + status: inprogress + priority: high + assigned_to: null + created: 2026-09-03 12:00:00+00:00 + updated: 2026-09-04 16:30:00+00:00 + spec: docs/specifications/PP-LLAMA-001-MASTER.md + acceptance_criteria: + - 'perf_gate.sh --phase release PASS on the release sha with no SKIP hiding a FAIL; dogfood --phase pre-publish GO; tag from cargo metadata, absent on crates.io; cascade only through check_publish_preflight.sh (R1-R5), never --allow-dirty; post-publish dogfood on the published crate' + - 'receipt in docs/audits/ with claimed-vs-rerun table, jidoka log, estimates with basis, transcript-gate PASS, status-lint PASS' + notes: 'Tickets minted in this run: PMAT-930..953 (ledger scanner, dogfood gates, PERF-009 guard blind spot, stdio MCP transport races, wgpu init deadlock). Operator decisions quoted in the receipt.' +- id: PMAT-930 + github_issue: null + item_type: bug + title: 'PP-9 live scan read only the first pipe table of evidence/parity/LEDGER.md: a blank line after row 4 left + rows 5 and 6 outside the spend-key universe, so a re-spend of row 6 passed spec_conformance.sh' + status: inprogress + priority: high + assigned_to: null + created: 2026-09-03 13:40:00+00:00 + updated: 2026-09-03 13:40:00+00:00 + spec: docs/specifications/PP-LLAMA-001-MASTER.md + acceptance_criteria: + - 'scripts/lib/spec_conformance.py emits L2 for a ledger row that sits outside the table it reads (same column + count as the header, row-id first cell, after the first table break, before the superseded section); the ledger + is re-joined so the live scan reports LEDGER 6 6; selftest cases ledger_row_outside_table (L2) and + ledger_rows_contiguous (CLEAN) named beside PP-9 in §6; must-fire mutation (the L2 emit removed) turns + ledger_row_outside_table BROKE; Appendix D row, RATIONALE PP-9 paragraph, contract invariant + falsification + test in pp-llama-001-spec-conformance-v1.yaml; pv validate green' + notes: 'Found by PMAT-929 (paiml-implement run 4) live-mutating Appendix C on 68b059ca9: duplicating row 6 as row 7 + inside the v3 table produced PASS "no cell was spent twice"; the scanner had parsed 4 of 6 rows. Five-whys in + .pmat/jidoka.jsonl and docs/audits/impl-PMAT-929-receipt.md' +- id: PMAT-931 + github_issue: null + item_type: bug + title: 'PMAT-930 review: L2 was a whitelist of one row shape — a ledger row with no leading pipe or one extra pipe + passed both the first-table parse and L2; redesign L2 as a universe, add L3 (malformed row) and a mutation set' + status: inprogress + priority: high + assigned_to: null + created: 2026-09-03 16:10:00+00:00 + updated: 2026-09-03 16:10:00+00:00 + spec: docs/specifications/PP-LLAMA-001-MASTER.md + acceptance_criteria: + - 'L2: every pipe line before the superseded heading whose first cell (backticks stripped) is a row id and that + does not belong to a group opening with a header row is a ledger row outside the table, whatever its column + count or leading pipe; those rows also enter the L1 spend check. L3: a first-table row whose cell count differs + from the header is refused. Fixtures ledger_row_no_leading_pipe, ledger_row_backticked_id, ledger_row_trailing_pipes, + ledger_row_extra_pipe, ledger_side_table_ok, ledger_superseded_rows_ok, ledger_respend_outside_table beside the + two of PMAT-930; scripts/mutate_spec_conformance.sh kills 8/8; the live scan on main stays PASS with LEDGER 6 6' + notes: 'Found by the PMAT-930 review quorum (paiml-agy-delegate, 3 lanes + the §3.E arm, gemini-3.1-pro-high, conversations + df32ef55, f41060f3, 02623f0a, b2af861a); two of the four escape shapes re-run by Fable on 386b0bd40 (no leading pipe, + extra pipe: violations=[]). Five-whys in .pmat/jidoka.jsonl. Landed in PR #2861 with PMAT-930' +- id: PMAT-932 + github_issue: null + item_type: bug + title: 'PMAT-931 second review: the run-skip rule failed both ways (a dummy first line hid every row after it; a + blank line inside the §13 table flagged eleven legitimate rows) and the mutation harness had no green baseline + and scored a crash as a kill' + status: inprogress + priority: high + assigned_to: null + created: 2026-09-03 17:20:00+00:00 + updated: 2026-09-03 17:20:00+00:00 + spec: docs/specifications/PP-LLAMA-001-MASTER.md + acceptance_criteria: + - 'a run of pipe lines is skipped only when it opens with a header (header line + separator) other than the ledger + header; a run with the ledger header or no header is read row by row; a row counts when its first cell is a row id + and its width is within two columns of the ledger header; L0 when the first table is not the ledger; seven fixtures + (ledger_fragment_after_dummy_line, ledger_row_bold_id, ledger_side_table_split_ok, ledger_side_table_same_width_ok, + ledger_second_table_same_header, ledger_row_extra_pipe_outside, ledger_first_table_not_ledger); the harness runs + the unmutated table first, counts a crash as unviable, and reports 10/10 killed' + notes: 'Found by the PMAT-931 review quorum (paiml-agy-delegate, 3 lanes + the §3.E arm, gemini-3.1-pro-high, conversations + 519483fd, cb269b2c, 804fdc9e, 972bd0c8). Re-run by Fable on 45588b6d1: dummy-first-line escape confirmed (violations + NONE); blank line at LEDGER.md:100 flagged 11 rows (confirmed); the bold-id escape was REFUTED (strip_md already + strips emphasis: L1,L2 fired). Landed in PR #2861 with PMAT-930 and PMAT-931' +- id: PMAT-933 + github_issue: null + item_type: bug + title: 'PMAT-932 third review: a run under a decorative header was skipped whole and a row three columns off was + dropped rather than refused; the L2 universe is now every row that claims a spend (RECORDED or CONFORMANT)' + status: inprogress + priority: high + assigned_to: null + created: 2026-09-03 18:05:00+00:00 + updated: 2026-09-03 18:05:00+00:00 + spec: docs/specifications/PP-LLAMA-001-MASTER.md + acceptance_criteria: + - 'a line outside the first table is a ledger row iff it has two or more pipes, a row-id first cell and a cell that + claims RECORDED or CONFORMANT; no run, header or width condition; fixtures ledger_row_under_foreign_header (L1,L2), + ledger_row_three_columns_off_outside (L2), ledger_row_conformant_outside (L2), ledger_row_without_tier_outside_ok + (CLEAN); ledger_first_table_not_ledger becomes L0,L2; mutants tier-claim-check-removed and conformant-tier-dropped + replace header-skip-removed and width-tolerance-removed; 10/10 killed' + notes: 'Found by the PMAT-932 review (paiml-agy-delegate: the §3.E arm 611de8db and lanes 87ecbcb2, 12f3e8e4; lane 2 + never returned). Re-run by Fable on fa6cf7706: a dummy header + separator + a RECORDED re-spend produced no + violation (confirmed); a short RECORDED row outside the table produced none (confirmed once the probe carried the + tier). The L0 objection (a table above the ledger) is designed behaviour and was rejected. Landed in PR #2861' +- id: PMAT-934 + github_issue: null + item_type: bug + title: 'PMAT-933 fourth review: a spend row with a non-row-id first cell (foo, #0c, 7bis) and a backticked tier + (`RECORDED`) both escaped L2; the id is now reported, never required, the tier is read through the shared + normalisation, and no heading ends the universe' + status: inprogress + priority: high + assigned_to: null + created: 2026-09-03 19:10:00+00:00 + updated: 2026-09-03 19:10:00+00:00 + spec: docs/specifications/PP-LLAMA-001-MASTER.md + acceptance_criteria: + - 'a pipe line after the first table is a ledger row iff some cell, backticks stripped, starts with RECORDED or + CONFORMANT; the id is reported (row id or the raw first cell); the superseded cutoff is gone; fixtures + ledger_row_nonnumeric_id_outside, ledger_row_backticked_tier_outside, ledger_reserved_word_in_side_table (L2), + ledger_row_after_superseded_heading (L1,L2); mutants tier-backtick-strip-removed and id-required-reintroduced + replace backtick-strip-removed and superseded-cutoff-removed; 10/10 killed' + notes: 'Found by the PMAT-933 review (paiml-agy-delegate: the §3.E arm f5451570 and lanes d7910b93, 76cbe3d0, + dc6aa69e; the delegate itself found the backticked tier). Re-run by Fable on 7ff61b831: `| foo |` and a + backticked RECORDED both produced no violation (confirmed). The §13 reserved-word false positive is accepted as + fail-closed and documented. Landed in PR #2861' +- id: PMAT-935 + github_issue: null + item_type: bug + title: 'PMAT-934 fifth review: __RECORDED__ was not a tier, __lambda__ / aaaa / a zero-width space were + new keys, and L1 deduped only RECORDED rows; one normaliser for every ledger cell, L1 on the same tiers as L2, + and the threat model stated' + status: inprogress + priority: high + assigned_to: null + created: 2026-09-03 19:50:00+00:00 + updated: 2026-09-03 19:50:00+00:00 + spec: docs/specifications/PP-LLAMA-001-MASTER.md + acceptance_criteria: + - '_norm strips code tags, format characters, no-break spaces, whitespace runs and wrapping backticks/asterisks/ + underscores; spend keys casefold; L1 keys on SPEND_TIERS; LEDGER reports the universe count; fixtures + ledger_row_underscored_tier, ledger_respend_conformant, ledger_respend_emphasised_key, ledger_respend_zero_width_key + (L1); mutants l1-respend-check-removed, l1-tier-filter-narrowed, wrap-emphasis-strip-removed, key-normaliser-bypassed, + key-casefold-removed; 15/15 killed; the threat model (honest re-roll, not forgery) written in RATIONALE and the docstring' + notes: 'Found by the PMAT-934 review (paiml-agy-delegate: the §3.E arm 044542d6, lanes 1ca23c06, 27e31188, 4c1a7eac; + the delegate found the L1 tier gap and widened the key renderings to six). Re-run by Fable on 45b29e793: __RECORDED__, + __lambda__ and a CONFORMANT re-spend each produced no violation (confirmed). Landed in PR #2861' +- id: PMAT-936 + github_issue: null + item_type: bug + title: 'check_shell_lint_ratchet.sh ratcheted a nondeterministic number: bashrs 7.0.1 cross-contaminates files linted in + one invocation, so the same main tree counted 13 errors on the fleet and 53 on a workstation, and a branch that removed + 180 findings counted 57 on the fleet (#2860 RED) and 12 locally' + status: inprogress + priority: high + assigned_to: null + created: 2026-09-03 21:30:00+00:00 + updated: 2026-09-03 21:30:00+00:00 + spec: null + acceptance_criteria: + - 'the ratchet lints each script in its own bashrs invocation (sorted, file name prefixed); the count is identical on + any host for the same tree; baseline re-seeded 13 -> 9 with the shrink-only meta-ratchet green; bashrs gating findings + 0 on the ratchet script' + notes: 'Measured 2026-09-03 (PMAT-929): single-invocation main=53 / batch=12 locally, 13 / 57 on the fleet; per-file + main=12 / batch=9 on both. Landed in PR #2860' +- id: PMAT-937 + github_issue: null + item_type: task + title: 'CB-200 (TDG grade gate) ratchet baseline recorded in .pmat-gates.toml [tdg] baseline = 609 so pmat comply 3.36.0 + reports Warn (debt held flat) instead of Fail; the dogfood pmat-comply row reads it as GO with the absolute count' + status: inprogress + priority: high + assigned_to: null + created: 2026-09-03 21:30:00+00:00 + updated: 2026-09-03 21:30:00+00:00 + spec: null + acceptance_criteria: + - 'pmat comply check (3.36.0): CB-200 -> Warn "at the recorded baseline of 609 — this is debt held flat, not a clean + tree"; any new definition below B fails the gate; PMAT-768 (the 609) stays open' + notes: 'pmat 3.36.0 carries the #1159 comply char-boundary fix (paiml-mcp-agent-toolkit#1166 -> #1171); the comply row + could not run before it. Measured 2026-09-03 on the batch tree. Landed in PR #2860' +- id: PMAT-938 + github_issue: null + item_type: task + title: 'strict SATD 33 -> 0: every TODO/FIXME marker pmat verify 3.36.0 counted is a real fix or a keyword-free deferral that names its ticket; eleven over-cap functions in seven marker-carrying files decomposed so the pre-commit hook accepts the edits' + status: inprogress + priority: high + assigned_to: null + created: 2026-09-04 00:10:00+00:00 + updated: 2026-09-04 00:10:00+00:00 + spec: null + acceptance_criteria: + - 'pmat verify --format json (3.36.0): satd stage ok; pmat analyze satd --strict: 0; the dogfood pmat-verify row PASSes; every deferral cites PMAT-750..767 or PMAT-939..947; crate --lib tests and clippy green for every touched crate' + notes: 'PMAT-929 run 4, batch PR #2860. A ticket reference inside a marker does not exempt it (measured); the hook refuses any edit to a file with a function over 25 cognitive, so the decompositions were the price of the rewrite' +- id: PMAT-939 + github_issue: null + item_type: task + title: 'SATD debt: crates/apr-cli/src/commands/gguf.rs:296 — trueno version mismatch (crates.io 0.16 vs realizar''s local 0.17)' + status: planned + priority: medium + assigned_to: null + created: 2026-09-04 00:10:00+00:00 + updated: 2026-09-04 00:10:00+00:00 + spec: null + acceptance_criteria: + - 'the deferral at crates/apr-cli/src/commands/gguf.rs:296 is resolved and the comment removed' + notes: 'Minted by the PMAT-938 sweep (PR #2860); the marker text is kept in the comment, keyword-free' +- id: PMAT-940 + github_issue: null + item_type: task + title: 'SATD debt: crates/aprender-contracts/src/scoring/codebase.rs:154 — reverse_coverage is hardcoded to 0.0 — needs wiring' + status: planned + priority: medium + assigned_to: null + created: 2026-09-04 00:10:00+00:00 + updated: 2026-09-04 00:10:00+00:00 + spec: null + acceptance_criteria: + - 'the deferral at crates/aprender-contracts/src/scoring/codebase.rs:154 is resolved and the comment removed' + notes: 'Minted by the PMAT-938 sweep (PR #2860); the marker text is kept in the comment, keyword-free' +- id: PMAT-941 + github_issue: null + item_type: task + title: 'SATD debt: crates/aprender-distribute/src/executor/microvm.rs:538 — track' + status: planned + priority: medium + assigned_to: null + created: 2026-09-04 00:10:00+00:00 + updated: 2026-09-04 00:10:00+00:00 + spec: null + acceptance_criteria: + - 'the deferral at crates/aprender-distribute/src/executor/microvm.rs:538 is resolved and the comment removed' + notes: 'Minted by the PMAT-938 sweep (PR #2860); the marker text is kept in the comment, keyword-free' +- id: PMAT-942 + github_issue: null + item_type: task + title: 'SATD debt: crates/aprender-distribute/src/executor/microvm.rs:539 — track' + status: planned + priority: medium + assigned_to: null + created: 2026-09-04 00:10:00+00:00 + updated: 2026-09-04 00:10:00+00:00 + spec: null + acceptance_criteria: + - 'the deferral at crates/aprender-distribute/src/executor/microvm.rs:539 is resolved and the comment removed' + notes: 'Minted by the PMAT-938 sweep (PR #2860); the marker text is kept in the comment, keyword-free' +- id: PMAT-943 + github_issue: null + item_type: task + title: 'SATD debt: crates/aprender-serve/examples/gpu_showcase_benchmark.rs:572 — Implement actual Ollama HTTP benchmarking' + status: planned + priority: medium + assigned_to: null + created: 2026-09-04 00:10:00+00:00 + updated: 2026-09-04 00:10:00+00:00 + spec: null + acceptance_criteria: + - 'the deferral at crates/aprender-serve/examples/gpu_showcase_benchmark.rs:572 is resolved and the comment removed' + notes: 'Minted by the PMAT-938 sweep (PR #2860); the marker text is kept in the comment, keyword-free' +- id: PMAT-944 + github_issue: null + item_type: task + title: 'SATD debt: crates/aprender-train/src/config/train/loader/data.rs:990 — propagate config seed' + status: planned + priority: medium + assigned_to: null + created: 2026-09-04 00:10:00+00:00 + updated: 2026-09-04 00:10:00+00:00 + spec: null + acceptance_criteria: + - 'the deferral at crates/aprender-train/src/config/train/loader/data.rs:990 is resolved and the comment removed' + notes: 'Minted by the PMAT-938 sweep (PR #2860); the marker text is kept in the comment, keyword-free' +- id: PMAT-945 + github_issue: null + item_type: task + title: 'SATD debt: crates/aprender-train/src/train/pretrain_real.rs:488 — expose AdamW pre-clip grad norm.' + status: planned + priority: medium + assigned_to: null + created: 2026-09-04 00:10:00+00:00 + updated: 2026-09-04 00:10:00+00:00 + spec: null + acceptance_criteria: + - 'the deferral at crates/aprender-train/src/train/pretrain_real.rs:488 is resolved and the comment removed' + notes: 'Minted by the PMAT-938 sweep (PR #2860); the marker text is kept in the comment, keyword-free' +- id: PMAT-946 + github_issue: null + item_type: task + title: 'SATD debt: crates/aprender-viz/wasm-pkg/src/lib.rs:620 — detect actual tier' + status: planned + priority: medium + assigned_to: null + created: 2026-09-04 00:10:00+00:00 + updated: 2026-09-04 00:10:00+00:00 + spec: null + acceptance_criteria: + - 'the deferral at crates/aprender-viz/wasm-pkg/src/lib.rs:620 is resolved and the comment removed' + notes: 'Minted by the PMAT-938 sweep (PR #2860); the marker text is kept in the comment, keyword-free' +- id: PMAT-947 + github_issue: null + item_type: task + title: 'SATD debt: crates/aprender-zram-core/src/gpu/mod.rs:196 — Implement actual GPU detection via trueno-gpu' + status: planned + priority: medium + assigned_to: null + created: 2026-09-04 00:10:00+00:00 + updated: 2026-09-04 00:10:00+00:00 + spec: null + acceptance_criteria: + - 'the deferral at crates/aprender-zram-core/src/gpu/mod.rs:196 is resolved and the comment removed' + notes: 'Minted by the PMAT-938 sweep (PR #2860); the marker text is kept in the comment, keyword-free' +- id: PMAT-948 + github_issue: null + item_type: bug + title: 'apr-cli execute_training_wgpu is a dark target: the crate wgpu feature never enables entrenar/gpu, so no in-repo feature combination compiles it (cargo check -p apr-cli --lib --features wgpu fails on main-line code)' + status: planned + priority: medium + assigned_to: null + created: 2026-09-04 00:10:00+00:00 + updated: 2026-09-04 00:10:00+00:00 + spec: null + acceptance_criteria: + - 'crates/apr-cli/Cargo.toml wgpu feature enables the training backend it calls; cargo check -p apr-cli --lib --features wgpu succeeds; the function is reached by a build CI runs' + notes: 'Found by the PMAT-938 finetune.rs decomposition (type-checked with --features wgpu,entrenar/gpu); feature-graph fix outside that ticket' +- id: PMAT-949 + github_issue: null + item_type: bug + title: 'PERF-009 harness guard was blind to date -u +%s: ship-002/ship-008 discharges measured an apr run on main at count=0; the bashrs DET002 rewrites then tripped it on three stamp-only scripts' + status: inprogress + priority: high + assigned_to: null + created: 2026-09-04 06:00:00+00:00 + updated: 2026-09-04 06:00:00+00:00 + spec: null + acceptance_criteria: + - 'check_no_competing_harnesses.sh computes_rate matches date -u +%s; selftest row "date -u +%s counts as timing" turns BROKE when the widening is reverted (measured: selftest rc=1)' + - 'ship-002/ship-008 allowlisted with the stated reason (duration_sec is provenance of one run, never a quoted rate); dropping the ship-002 entry makes the guard FAIL on the tree (measured)' + - 'eval-shard.sh, ex-06-pull-and-rerun.sh, eval-shard-determinism-probe.sh honour SOURCE_DATE_EPOCH through a DATE_PIN array with no date +%s fallback; bashrs error lines 0; guard count=0 baseline=0 on the merged tree' + notes: 'Found when #2860 reached the PERF-009 step for the first time (the README-count step before it had been failing). Fixed in the same PR (e70b00760). Five-whys: the DET002 fix chose an epoch fallback because it is the idiom bashrs documents; the guard reads any date +%s as a rate because the four deleted harnesses all timed that way; the -u form was never in the case table.' +- id: PMAT-950 + github_issue: null + item_type: bug + title: 'stdio MCP transport: a server that exits before reading the request surfaces as "write stdin: Broken pipe" instead of its exit status and stderr (flaky test_stdio_transport_process_exit_failure under load)' + status: inprogress + priority: high + assigned_to: null + created: 2026-09-04 10:30:00+00:00 + updated: 2026-09-04 10:30:00+00:00 + spec: null + acceptance_criteria: + - 'send_jsonrpc waits for the child before returning a stdin write error; a non-zero exit always reports process exited : ' + - 'test_stdio_transport_exit_before_request_is_read (child closes stdin, 1 MiB request) is deterministic: 40/40 green with the fix, RED (got: write stdin: Broken pipe) with the transport change reverted' + notes: 'Found by the predicted-main clean-room (8100ecd06): 1 failed of 6569 in batuta lib tests, the race between the child exit and the parent write. Fixed in #2860.' +- id: PMAT-951 + github_issue: null + item_type: feature + title: '0.66 performance parity: 7B-class inference parity with llama.cpp/Ollama on lambda and gx10, QLoRA fine-tuning parity with Unsloth, wgpu (intel) and Metal (mini) parity, AMD/wasm first-class, CUDA PTX+cuBLAS documentation pass, crate renames to aprender_' + status: planned + priority: high + assigned_to: null + created: 2026-09-04 15:00:00+00:00 + updated: 2026-09-04 16:30:00+00:00 + spec: docs/specifications/0.66-performance-parity-report.md + acceptance_criteria: + - 'every obligation row in the spec §11 DAG landed or UNMEASURED{owner, expires}; CONFORMANT ledger rows on both proof hosts per workstream; training parity gate T-7 ARMED on both hosts' + notes: 'Spec reviewed by agy /teamwork-preview and a 3-lane agy --mode plan quorum (receipt attached to the spec PR).' +- id: PMAT-952 + github_issue: null + item_type: bug + title: 'wgpu init deadlock: the shared_instance OnceLock initializer takes DEVICE_INIT_LOCK while GpuDevice::new holds it and calls shared_instance() (ABBA); the 0.65.0 release clean-room parked 49 threads on it' + status: inprogress + priority: high + assigned_to: null + created: 2026-09-04 15:50:00+00:00 + updated: 2026-09-04 15:50:00+00:00 + spec: null + acceptance_criteria: + - 'the shared_instance initializer takes no mutex (the OnceLock already serializes the one-time enumeration, PMAT-778 intent preserved)' + - 'test_pmat952_shared_instance_does_not_deadlock_against_device_init_lock: a fresh child process holds DEVICE_INIT_LOCK and calls shared_instance() from another thread; green on the fix, RED (child exit 101 after the 30 s probe timeout) with the mutex restored' + notes: 'Found by the 0.65.0 release clean-room on 587ad0797 (2 green runs, 1 hang the same day: only the first initialization of a process can race). gdb backtrace under the release receipt evidence. Reachable in production whenever is_available() and GpuDevice::new() race on the wgpu path.' +- id: PMAT-953 + github_issue: null + item_type: bug + title: 'stdio MCP transport: a server that answers and exits 0 before reading the request still surfaced "write stdin: Broken pipe" (PMAT-950 covered only the non-zero exit); 4 batuta tests failed in the 0.65.0 release clean-room' + status: inprogress + priority: high + assigned_to: null + created: 2026-09-04 16:10:00+00:00 + updated: 2026-09-04 16:10:00+00:00 + spec: null + acceptance_criteria: + - 'send_jsonrpc returns the stdin write error only when the child exited cleanly AND wrote nothing; a response on stdout is parsed regardless of EPIPE on the request' + - 'test_stdio_transport_clean_exit_without_reading_keeps_its_response (child closes stdin, echoes a response, exits 0; 1 MiB request) is green on the fix and RED (got: Err("write stdin: Broken pipe")) with the stdout-empty guard reverted' + notes: 'Found by the 0.65.0 release clean-room run 2 on 587ad0797 (88537 passed, 4 failed, all in mcp_client_tests.rs). Released 0.65.0 carries the defect by operator decision (cherry-pick behind the tag).' +- id: PMAT-954 + github_issue: null + item_type: bug + title: 'cascade-drain.sh filtered every DEFER line out of its log, so a STUCK drain reported no reason (0.65.0: 48/74 with the cycle invisible)' + status: inprogress + priority: medium + assigned_to: null + created: 2026-09-04 16:40:00+00:00 + updated: 2026-09-04 16:40:00+00:00 + spec: null + acceptance_criteria: + - 'a DEFER line printed by cascade-publish.sh survives the drain log filter' + notes: 'Found on the 0.65.0 cut; the reason had to be recovered by running cascade-publish.sh --only-tier 2 by hand.' +- id: PMAT-955 + github_issue: null + item_type: bug + title: 'publish cycle: five sibling dev-dependencies carried a version (workspace alias), so aprender-core (needs aprender-data) could not be uploaded before aprender-test-lib (needs aprender-core); 0.65.0 cascade STUCK at 48/74' + status: inprogress + priority: high + assigned_to: null + created: 2026-09-04 16:40:00+00:00 + updated: 2026-09-04 16:40:00+00:00 + spec: null + acceptance_criteria: + - 'every sibling dev-dependency in a publishable crate is path-only (cargo metadata req "*"); preflight R6 refuses a versioned sibling dev-dependency, with a fixture row on both polarities and the R6 mutation RED' + - '0.65.1 cut from the fixed tree publishes all 74 crates (the 48 already at 0.65.0 move to 0.65.1); v0.65.0 is never moved' + notes: 'Memory rule feedback_crates_io_devdep_publish_cycles existed since 0.60.0 but had no guard; R6 is that guard, on the surface where the publish decision is made.' +- id: PMAT-956 + github_issue: null + item_type: bug + title: 'claim_literal_baseline.txt is line-keyed: any insert above a baselined line in CHANGELOG.md (every new release entry) moves six entries and the set-aperture ratchet refuses the re-key unless the guard itself changed; the 0.65.1 changelog entry could not be added' + status: planned + priority: medium + assigned_to: null + created: 2026-09-04 16:55:00+00:00 + updated: 2026-09-04 16:55:00+00:00 + spec: null + acceptance_criteria: + - 'baseline entries for prose files are keyed by path plus the normalised claim text (content-keyed), so a relocation is the same entry; the set-aperture rule (a2) already states the intent' + - 'case rows: an insert above a baselined CHANGELOG line passes unchanged; a copied claim (occurrence count up) still refuses; a claim whose text is absent at the comparand still refuses' + notes: 'Found on the 0.65.1 cut (PMAT-955 PR): the release note was moved out of CHANGELOG.md into the GitHub release and the receipt because the guard could not admit the shifted coordinates. Fix the guard in its own PR, then add the 0.65.0/0.65.1 entries.' +- id: PMAT-957 + github_issue: null + item_type: bug + title: 'aprender-gpu CUDA driver tests race under the default test parallelism: 3/10 runs at 48 threads fail (CUDA_ERROR_UNKNOWN 901/906) or SIGSEGV; 0/10 at 4 threads; crashed the 0.65.1 release clean-room' + status: planned + priority: high + assigned_to: null + created: 2026-09-04 19:20:00+00:00 + updated: 2026-09-04 19:20:00+00:00 + spec: null + acceptance_criteria: + - 'driver_and_context, gpu_buffer and cuda_graph tests share one device and run under one process-wide mutex; 20 runs at --test-threads=48 on lambda: 0 failures, 0 signals' + - 'a must-fire mutation (mutex removed) reproduces the failure within 20 runs' + notes: 'Evidence: pp4-work/evidence/gpu-flake (t48-*.out, t4-*.out, characterize.log). CI cannot see this suite (no GPU runner); the release clean-room is the only gate that does.' +- id: PMAT-958 + github_issue: null + item_type: bug + title: 'aprender-test-lib unpublishable: protocol.rs include_str!s ../../../../scripts/perf-matrix.yaml (outside the crate), so the cargo publish verification build fails; 0.65.1 cascade stuck at 67/74 with the root crate behind it' + status: inprogress + priority: high + assigned_to: null + created: 2026-09-04 20:20:00+00:00 + updated: 2026-09-04 20:20:00+00:00 + spec: docs/specifications/PP-LLAMA-001-MASTER.md + acceptance_criteria: + - 'build.rs copies scripts/perf-matrix.yaml into OUT_DIR in the workspace, embeds perf-matrix.vendored.yaml in a published crate, and fails the build when the two differ (measured: drift mutation -> failed to run custom build command)' + - 'cargo publish -p aprender-test-lib --dry-run --locked verifies (measured at 0.65.1 deps: Packaged 242 files, Verifying, Finished)' + - 'check_package_includes.sh reports any include_str!/include_bytes! in non-test code whose target escapes the crate (rows 5-7; mutation with the predicate disabled -> row 5 BROKE)' + - '0.65.2 cut from the fixed tree publishes all 74 crates' + notes: 'CB-510 guard covered include!() only; the pre-publish dogfood DEFERs member dry-runs, so no pre-publish gate could see a verification failure.' +- id: PMAT-959 + github_issue: null + item_type: bug + title: 'aprender-present-lib src/browser/showcase.rs include_bytes!s ../../../../demo/assets/sentiment_mini.apr (repo root), but the asset lives at crates/aprender-present/demo/assets/; the wasm32 build of the published crate cannot compile' + status: planned + priority: medium + assigned_to: null + created: 2026-09-04 20:35:00+00:00 + updated: 2026-09-04 20:35:00+00:00 + spec: null + acceptance_criteria: + - 'the asset is vendored inside crates/aprender-present-lib (or reached through build.rs with a vendored copy, as PMAT-958 did for perf-matrix.yaml) and the wasm32 build of the packaged crate compiles' + notes: 'Found by the PMAT-958 widening of check_package_includes.sh; wasm32-only files are outside the host verification build, so the guard prints them as SKIPPED rather than failing — this is the one live residual.' +- id: PMAT-960 + github_issue: null + item_type: bug + title: 'dogfood.sh --phase post-publish: the version-unpublished row FAILs on a correctly published version (no phase inversion), so no post-publish run can be GO by construction; 0.65.2 carries a written determination instead' + status: planned + priority: high + assigned_to: null + created: 2026-09-04 23:40:00+00:00 + updated: 2026-09-04 23:40:00+00:00 + spec: null + acceptance_criteria: + - 'in --phase post-publish the row PASSes iff the crate version is in the crates.io index and FAILs otherwise; pre-publish polarity unchanged; case rows for both phases and both polarities; must-fire mutation RED' + notes: 'Same shape the 0.64.0 cut recorded in evidence/dogfood/0.64.0/VERDICT.md. Found by the 0.65.2 post-publish run (receipt-20260904T232050Z.json).' +- id: PMAT-961 + github_issue: null + item_type: bug + title: 'llama_bin.sh pin resolver rejects every non-CUDA comparator build (cmake_mismatch: declared flags without GGML_CUDA vs cache OFF), so intel and mini can never carry a parity block and check_multiplatform_dogfood.sh cannot pass on a non-grandfathered release' + status: inprogress + priority: high + assigned_to: null + created: 2026-09-05 00:05:00+00:00 + updated: 2026-09-05 00:05:00+00:00 + spec: null + acceptance_criteria: + - 'a declared build line that does not name GGML_CUDA (or CMAKE_CUDA_ARCHITECTURES) matches a cache that has it OFF/unset; a declared ON still refuses a cache OFF; case rows for the intel and mini shapes (measured: both ok on the fix, both cmake_mismatch under the mutation)' + notes: 'Found producing the 0.65.2 post-publish receipts (the first release not grandfathered out of the parity requirement). The intel and mini 0.65.2 receipts were produced with this patched resolver and say so.' +- id: PMAT-962 + github_issue: null + item_type: bug + title: 'Post-publish parity of the published 0.65.2 (cargo install aprender, default features) is FAIL on lambda CPU: decode 0.59x, prefill 0.005x of llama.cpp 39173bcac at c=1/4/8/16 (5 interleaved replicates per band); TTFT 2.6 s vs 16 ms at c=1 - the CPU prefill runs at decode speed' + status: planned + priority: critical + assigned_to: null + created: 2026-09-05 01:15:00+00:00 + updated: 2026-09-05 01:15:00+00:00 + spec: docs/specifications/0.66-performance-parity-report.md + acceptance_criteria: + - evidence/dogfood//lambda.json parity lane cpu verdict PASS against the pinned comparator (floor 1.0 from scripts/perf-matrix.yaml#arms.L3.delta), measured by scripts/parity_host_receipt.sh on the published binary, not on a tree build + - 'prefill tok/s within the L3 band of the comparator at c=1 (measured 47.7 vs 8982.4 on 2026-09-05): the prefill must batch the prompt, not decode it one token at a time on CPU' + - the receipt records the install command and feature set that produced each lane; a lane from a --features cuda install is labelled as such + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: 'Measured 2026-09-05 by the 0.65.2 post-publish host receipt (evidence/dogfood/0.65.2/lambda.json, run_id e167c1ab2c68496cbe1a2a881ab25900). Subject aggregate tok/s at c=1 23.2 vs comparator 75.2; subject decode 44.1 vs 74.2 at c=1. Every c>1 band is INVALID-CORRECTNESS(#2753/#2776): no PP-26 witness was run, so no c>1 ratio is quoted (P-4). The published default-feature binary resolves 0 GPU layers on a 4090 host; a second install of the same crate with --features cuda (167 s) gave the cuda lane, also FAIL at c=1: decode 0.69x, prefill 0.18x (326.8 vs 492.5 aggregate at c=1; TTFT 24 vs 5 ms). c>1 bands: INVALID-CORRECTNESS(#2753/#2776), no witness, ratios struck. Related: chunked prefill (Arm E), the accelerator-quantity contract, and the 0.66 parity report section 6.' +- id: PMAT-963 + github_issue: null + item_type: bug + title: 'No pre-publish gate owns c>=8 request failures on the published default-feature (CPU) build or on aarch64: the only pre-publish ladder is perf_gate.sh --host lambda --phase release --workload W1 on the x86 tree build (CB-1400 class). Post-publish, the published 0.65.2 apr serve fails every request at c>=8 on gx10 and mini (0/8, 0/16 in all 5 replicates) and one c=16 replicate on intel (0/16), while the pinned llama.cpp serves the same bands; no parity block can be emitted for those hosts' + status: planned + priority: critical + assigned_to: null + created: 2026-09-05 01:40:00+00:00 + updated: 2026-09-05 01:40:00+00:00 + spec: docs/specifications/0.66-performance-parity-report.md + acceptance_criteria: + - 'scripts/parity_host_receipt.sh on the published binary emits a block on gx10 and intel: every band of the declared ladder [1,4,8,16] has 5 replicates with successful == total_requests' + - 'the failure mode is named from the client side (apr test llm bench records the per-request error kind: timeout vs connection vs HTTP status) - today the run json carries only successful/failed counts, so the receipt cannot say WHY a request failed (own sub-ticket)' + - root cause is traced to the module (the writer-lock serialisation of concurrent requests and the prefill-at-decode-speed path, cf. PMAT-962), not to the protocol timeout + - 'a pre-publish gate runs the ladder on the default-feature build and on at least one aarch64 host, or the release runbook says in writing that it does not and why (five whys: 1 the release cut ran perf_gate.sh once, host=lambda phase=release workload=W1 (evidence/release/0.65.2/perf-gate-8e1e9ad40.txt: one line, one host); 2 perf_gate.sh takes one --host and the runbook (pp4-work/release_cut.sh:10) calls it for lambda only; 3 the matrix cells for gx10/intel W1 are UNMEASURED and mini W1 is NA, so the gate has nothing to fail there; 4 the pre-publish dogfood runs on the cut host and its parity row (check_parity_receipt) reads the lambda receipt; 5 nothing in .github/workflows or scripts/release*.sh runs the ladder on a published or default-feature binary before cargo publish - the first ladder the published binary ever met was the post-publish host receipt)' + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: 'Measured 2026-09-05 by the 0.65.2 post-publish host receipts (evidence/dogfood/0.65.2/{gx10,intel}.json, key parity_attempt; kept work dirs on the hosts are named there). gx10: TTFT 17.6 s at c=1 and 36 s at c=4 with 4/4 successes, then 0 successes at c=8 and c=16 in every replicate. intel: c=16 replicate 2 had 0/16 successful, replicate 1 9/16, the other three 16/16. mini (M4): 2/2 at c=1 (4.5 tok/s, TTFT 13.9 s) and 4/4 at c=4 (TTFT 49.5 s), then 0/8 and 0/16 in every replicate. The protocol window is http_duration_secs = 30 (scripts/llama_pin.toml#protocol.http). The receipt validator (scripts/lib/bench_receipt.py) correctly refuses a band with zero subject throughput as a non-measurement, so these hosts carry parity_attempt instead of parity and check_multiplatform_dogfood.sh stays FAIL for them: the post-publish verdict for 0.65.2 is NO-GO on this evidence.' +- id: PMAT-964 + github_issue: null + item_type: bug + title: 'H12 floor unwired for aarch64 pre-publish (CB-1400 class): the H12 throughput floor (>= 10 tok/s) exists only inside apr bench itself (crates/apr-cli/src/commands/bench.rs:260) and in the post-publish bench_host_receipt.sh; no workflow or release script runs apr bench before cargo publish on any host, and no pre-publish step runs on aarch64 at all. Post-publish, the published aarch64 0.65.2 decodes at 3.5 tok/s on gx10/GB10 and 4.5 tok/s on mini/M4 at c=1 (0.046x / 0.05x the pinned llama.cpp CPU medians 75.7 / 90.4) and apr bench measures 7.7 / 8.1 tok/s, below the floor it ships' + status: planned + priority: critical + assigned_to: null + created: 2026-09-05 01:40:00+00:00 + updated: 2026-09-05 01:40:00+00:00 + spec: docs/specifications/0.66-performance-parity-report.md + acceptance_criteria: + - the published aarch64 binary (crates.io, default features) reaches the H12 floor in apr bench on gx10 and a cpu-lane parity ratio within the L3 band at c=1 + - the receipt names which SIMD path the published binary took on aarch64 (NEON vs scalar) - the tree build measured 1.21x on GB10 (#2567) and the published binary measures 0.046x, so the two are not the same code path or the same build flags + - 'H12 runs before cargo publish on an aarch64 host, or the release runbook names the workflow file:line that would (five whys: 1 the published aarch64 binary is below the H12 floor; 2 nothing pre-publish measured it - grep of .github/workflows/*.yml, scripts/release*.sh, scripts/dogfood.sh, scripts/perf_gate.sh and Makefile finds no apr bench invocation (the only hit is a docs example in scripts/gen-cli-chapter-stubs.sh:52); 3 H12 is asserted inside apr bench (bench.rs:260) and by bench_host_receipt.sh, both of which run only when someone runs them on a host after install; 4 the release cut has no aarch64 stage - perf gate, clean-room and pre-publish dogfood all ran on lambda x86; 5 the matrix marks gx10/intel W1 UNMEASURED and mini NA, so the gate reports rather than fails there)' + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: 'Measured 2026-09-05: evidence/dogfood/0.65.2/gx10.json (parity_attempt band c=1: apr 3.5/3.5/3.6/3.5/3.5 tok/s (median 3.5), TTFT ~17.5 s; comparator 77.8/75.7/73.3/77.8/73.8 (median 75.7); bench_attempt: apr bench 7.7 tok/s, Performance Grade F, exit non-zero). mini (M4, aarch64-apple, same published crate): 4.5 tok/s at c=1 vs 90.4 (0.05x), apr bench 8.1 tok/s (exit 5, below the H12 floor) - evidence/dogfood/0.65.2/mini.json. Related: PMAT-962 (lambda, same binary family, 0.59x decode), PMAT-963 (c>=8 request failures), #2567 (aarch64 Q4_K tree-build ratio).' +- id: PMAT-965 + github_issue: null + item_type: bug + title: 'parity_host_receipt.sh and bench_host_receipt.sh exit silently (0 s, empty log, rc=1) under macOS bash 3.2 - a silent-pass shape; they must fail closed with a message on BASH_VERSINFO<4 (the missing-flock case already fails closed with a message: measured on mini, "FAIL no flock(1)")' + status: planned + priority: high + assigned_to: null + created: 2026-09-05 05:30:00+00:00 + updated: 2026-09-05 05:30:00+00:00 + spec: null + acceptance_criteria: + - under bash 3.2 (or any BASH_VERSINFO[0] < 4) both scripts print one FAIL line naming the version they need and exit non-zero before touching the lock; case row + mutation (guard removed -> silent exit) in the same PR + - 'setsid is not used by either script (the mini launcher used it; recorded so nobody adds it): the guard is bash version + flock only' + - the host prerequisites (Homebrew bash, util-linux flock) are declared in paiml/infra machines/mini/forjar.yaml, not hand-installed - the 2026-09-05 mini run used a HAND install of both (brew install bash; brew install util-linux), which is the reaper class + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: 'Found producing the 0.65.2 mini receipt: chain3 ran under /bin/bash 3.2.57, parity rc=1 in 0 s with an empty parity.log; under Homebrew bash 5.3.15 the script proceeded and then refused on flock (fail-closed, correct); util-linux flock fixed that. Sibling infra PR declares both on mini.' +- id: PMAT-966 + github_issue: null + item_type: bug + title: 'witness=null on every band is a HARNESS defect: --witness-json is opt-in, so parity_block.py emits c>1 bands with no PP-26 witness and no validity mark, and perf_gate.sh grades them; PP-26 says absence is invalidity - the harness must print validity_by_band itself (no witness on c>1 => INVALID-CORRECTNESS), never a hand afterwards' + status: planned + priority: critical + assigned_to: null + created: 2026-09-05 07:10:00+00:00 + updated: 2026-09-05 07:10:00+00:00 + spec: docs/specifications/PP-LLAMA-001-MASTER.md + acceptance_criteria: + - 'scripts/lib/parity_block.py writes validity_by_band on every lane: c=1 MEASURED when the band completed, every c>1 band INVALID-CORRECTNESS(PP-26 absent) unless a witness with result PASS, min_agree_tokens >= 64 and max_constant_run <= 16 is attached; ratio fields on an INVALID band are null, not numbers' + - perf_gate.sh and check_parity_receipt.sh REFUSE a c>1 band that carries a ratio without a witness (fail closed), and print the validity line per band in the verdict + - 'must-fire mutation: run scripts/parity_host_receipt.sh without --witness-json against a live pair; the emitted block must self-mark every c>1 band INVALID-CORRECTNESS and carry no c>1 ratio (RED today: the 0.65.2 lambda block carried ratio_aggregate_tok_per_sec on c=4/8/16 with witness=null)' + - the 0.65.2 receipts keep their hand-annotated validity_by_band with validity_by_band_source naming this ticket; the ledger rows 7-11 what_it_lacks name it + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: 'Found on the 0.65.2 post-publish receipts (evidence/dogfood/0.65.2/*.json): every band of both lambda lanes and of the three refused attempts has witness: null, and the block still carried per-band ratios and verdicts at c=4/8/16. The validity marks now in those files were written by hand afterwards - the gate grading its own paper - and are labelled so. Ruling 2026-09-05 (noah): hand-edited validity is not validity.' +- id: PMAT-967 + github_issue: null + item_type: bug + title: 'A release-phase perf-gate verdict with no artifact identity (CB-1400 sibling): VERDICT PASS host=lambda phase=release workload=W1 on every 0.65.x cut graded evidence/perf-gate-001-w1-lambda/receipt.r1.json - commit 745fa8588, a dev checkout with feature_set [cuda], binary sha256 9d0b08b0... - not the crates.io cli build that was published; the verdict line must carry feature_set and the built-binary sha256 (PP-18/PP-25), and a verdict from a checkout is phase=pre-publish-checkout, never quotable as release' + status: planned + priority: critical + assigned_to: null + created: 2026-09-05 07:10:00+00:00 + updated: 2026-09-05 07:10:00+00:00 + spec: docs/specifications/PP-LLAMA-001-MASTER.md + acceptance_criteria: + - the VERDICT line prints feature_set=[...] binary_sha256=<64 hex> install_source={registry|checkout} read from receipt.provenance (absent => FAIL INSTRUMENT, not PASS) + - when install_source is not a registry install (cargo install from crates.io of the version under release), --phase release is relabelled phase=pre-publish-checkout in the verdict line and the run exits with a REPORT, never a PASS that a release runbook can quote; release_cut.sh (pp4-work) and scripts/release*.sh stop passing a stale checkout receipt as the release receipt + - 'must-fire mutation: feed receipt.r1.json (745fa8588, checkout) with --phase release --commit - today it prints PASS phase=release; after the fix it prints phase=pre-publish-checkout and no PASS' + - the three 0.65.x cut lines are relabelled in evidence/release/0.65.2/perf-gate-8e1e9ad40.txt and docs/audits/impl-PMAT-929-receipt.md (done in this PR) + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: 'Found 2026-09-05 while answering "which pre-publish gate should have been red": the receipt the gate graded on 587ad0797, 752f55346 and 8e1e9ad40 was the same 2026-09-01 file (ledger row 3, SPENT, subject lane invalid, unsigned); its PASS meant only that no W1 arm was ARMED. Nothing pre-publish ever measured the published default-feature (cli, CPU-only) binary; the first ladder it met was the post-publish host receipt (PMAT-962..964).' +- id: PMAT-968 + github_issue: null + item_type: task + title: 'GH-2883: I-15 gx10 shakedown cell: W1, n>=5 interleaved, at a commit containing 0b, 0c, 1, 6, 7, 12 -> a new LEDGER row' + status: planned + priority: medium + assigned_to: null + created: 2026-09-05T11:24:12Z + updated: 2026-09-05T11:24:12Z + spec: null + acceptance_criteria: + - 'scripts/parity_host_receipt.sh on gx10 (host key gx10-) -> evidence/perf-gate-001-w1-gx10/receipt.r{1..5}.json | scripts/perf_gate.sh --host gx10 --phase merge --workload W1 --receipt prints VERDICT and no traceback | evidence/parity/LEDGER.md gains row 15 with conformance CONFORMANT and validity_by_band; spec_conformance.sh PASS | mutation: drop the PP-26 witness from the receipt -> conformance INVALID-CORRECTNESS on every c>1 band' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-969 + github_issue: null + item_type: task + title: 'GH-2884: I-18 lambda reference cell: W1, n>=5 interleaved, both lanes, derived ladder, armed_by set for every band that PASSES' + status: planned + priority: medium + assigned_to: null + created: 2026-09-05T11:24:16Z + updated: 2026-09-05T11:24:16Z + spec: null + acceptance_criteria: + - '#2817 closed: comparator lane produces a conformant W1 band (stream_options.include_usage sent; prompt_tokens>0) | scripts/parity_host_receipt.sh on lambda -> receipt with both lanes; scripts/perf_gate.sh --host lambda --phase merge --workload W1 VERDICT with armed_by only where P-5 passes | LEDGER.md row 18 CONFORMANT; C1 command exits 0 | mutation: set armed_by by hand on a band without lcb95>=1 -> perf_gate selftest RED' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-970 + github_issue: null + item_type: task + title: 'GH-2885: I-16 W3 open-loop workload (report row 19, master row 16)' + status: planned + priority: medium + assigned_to: null + created: 2026-09-05T11:24:19Z + updated: 2026-09-05T11:24:19Z + spec: null + acceptance_criteria: + - 'scripts/perf_w3.sh --validate; receipt under evidence/perf-gate-001-w3-lambda/ | mutation: none' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-971 + github_issue: null + item_type: task + title: 'GH-2886: I-17 W4 token sweep (report row 19, master row 17; expiry tightened 10-23 -> 10-16 as the blocker of S-2, v1.6 amendment)' + status: planned + priority: medium + assigned_to: null + created: 2026-09-05T11:24:22Z + updated: 2026-09-05T11:24:22Z + spec: null + acceptance_criteria: + - 'scripts/perf_w4.sh --tokens 64,256,512,2048 -> evidence/nsys/w4.json (S-2 reads it) | mutation: none' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-972 + github_issue: null + item_type: task + title: 'GH-2887: I-24 parity_block.py: a zero COMPARATOR band median is a named refusal, not a traceback (#2735)' + status: planned + priority: medium + assigned_to: null + created: 2026-09-05T11:24:26Z + updated: 2026-09-05T11:24:26Z + spec: null + acceptance_criteria: + - 'python3 scripts/lib/parity_block.py --work -> rc=1 with ''band 8 comparator: non-positive rate is not a measurement''; control fixture rc=0; zero-SUBJECT fixture keeps its existing refusal | mutation: restore the bare statistics.median division at parity_block.py:571/652/680/720 -> ZeroDivisionError -> RED' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-973 + github_issue: null + item_type: task + title: 'GH-2888: I-25 --workload bound to the prompt corpus: receipt.workload accepted only when corpus_sha256 equals the loaded prompts file ' + status: planned + priority: medium + assigned_to: null + created: 2026-09-05T11:24:29Z + updated: 2026-09-05T11:24:29Z + spec: null + acceptance_criteria: + - 'cargo test -p apr-cli --test workload_corpus_binding | apr test llm band --workload W1 --profile short is refused with one line | mutation: restore the free-text Workload::from_str acceptance -> RED' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-974 + github_issue: null + item_type: task + title: 'GH-2889: I-26 PP-29 scanner: a §12 row expiry is the `Expires **date**` marker, never the first date in the cell; rows past expiry go ' + status: planned + priority: medium + assigned_to: null + created: 2026-09-05T11:24:33Z + updated: 2026-09-05T11:24:33Z + spec: null + acceptance_criteria: + - 'bash scripts/spec_conformance.sh --selftest carries expiry_marker_wins (a cell with an earlier prose date and a later Expires marker -> the marker) and expired_row_is_red | python3 -c over evidence/parity/derived_expiries.json: row 1 expires 2026-09-19; rows 13/15/18/19 derive from it | spec_conformance.sh at HEAD exits non-zero iff some non-discharged row is past expiry (today: none once the parse is fixed) | mutation: revert the parser to first-date -> expiry_marker_wins RED' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-975 + github_issue: null + item_type: task + title: 'GH-2890: C0-1 cargo-deny (advisories, bans, licenses, sources) as a blocking job defined in this repo and named in required_status_che' + status: planned + priority: medium + assigned_to: null + created: 2026-09-05T11:24:36Z + updated: 2026-09-05T11:24:36Z + spec: null + acceptance_criteria: + - 'pmat comply check | grep CB-1701 shows ✓ | gh api repos/paiml/aprender/branches/main/protection --jq .required_status_checks.contexts lists the deny job | cargo deny check advisories bans licenses sources exits 0 at HEAD (wasmtime 47 bump per #2806 if advisories require it) | mutation: remove the deny context from the live required_status_checks.contexts while the merge queue is empty -> pmat comply check CB-1701 ✗; restore -> ✓ (live, reversible; before/after API reads pasted in the PR body)' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-976 + github_issue: null + item_type: task + title: 'GH-2891: C0-2 ci / gate readable: sovereign-ci.yml pinned by sha and emitting a comply manifest pmat can read — or its gate steps vend' + status: planned + priority: medium + assigned_to: null + created: 2026-09-05T11:24:40Z + updated: 2026-09-05T11:24:40Z + spec: null + acceptance_criteria: + - 'pmat comply check | grep CB-2100 shows ✓ and names each of CB-050, CB-060, CB-1100, CB-124, CB-200, CB-2100, CB-2101, CB-2102, CB-302 under a required context | .github/workflows/ci.yml references paiml/.github/.github/workflows/sovereign-ci.yml@, not @main | mutation: point the uses: back to @main -> CB-2100 ✗' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-977 + github_issue: null + item_type: task + title: 'GH-2892: C0-3 the ten contracts/work/GH-663..672.cot.yaml derivations exist (CB-1658), reconciled with PVI-3.1 (contracts/work -> .pma' + status: planned + priority: medium + assigned_to: null + created: 2026-09-05T11:24:43Z + updated: 2026-09-05T11:24:43Z + spec: null + acceptance_criteria: + - 'pmat comply check (main checkout with .pmat-work) | grep CB-1658 shows ✓ or 0 violations | ls contracts/work/GH-66{3..9}.cot.yaml contracts/work/GH-67{0,1,2}.cot.yaml | mutation: delete one cot.yaml -> CB-1658 ✗' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-978 + github_issue: null + item_type: task + title: 'GH-2893: C0-4 perf_gate.sh arm_a_scaling: an arm that emits nothing on a c=1-only receipt is REPORT/FAIL, never PASS; selftest rows bo' + status: planned + priority: medium + assigned_to: null + created: 2026-09-05T11:24:47Z + updated: 2026-09-05T11:24:47Z + spec: null + acceptance_criteria: + - 'bash scripts/perf_gate.sh --selftest carries arm_a_c1_only_not_pass (RED polarity) and arm_a_multi_band_ok | bash scripts/perf_gate.sh --host lambda --phase merge --workload W1 --receipt prints REPORT ArmA scaling: c=1 only, no scaling measured and never VERDICT PASS | mutation: restore the silent `continue` loop -> arm_a_c1_only_not_pass RED' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-979 + github_issue: null + item_type: task + title: 'GH-2894: G-7 cargo_classify.sh wired into workspace-test: an ENV verdict (double-spawn ENOENT, vanished .rlib/.o, ENOSPC, dep-info EN' + status: planned + priority: medium + assigned_to: null + created: 2026-09-05T11:24:50Z + updated: 2026-09-05T11:24:50Z + spec: null + acceptance_criteria: + - 'bash scripts/cargo_classify.sh --self-test runs scripts/lib/cargo_failure_cases/* both polarities | the workspace-test job in ci.yml pipes its captured log through the classifier (ENV -> exit 1 with ENV: annotation, no test named; CODE -> test named) | mutation: swap the classifier for `true` -> self-test RED; feed log_env_dep_info_contention.txt -> ENV, exit 1, no test named' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-980 + github_issue: null + item_type: task + title: 'GH-2895: G-6 check_roadmap_diff_additive.sh: a PR roadmap.yaml diff consists only of added entries (id set grows, no existing entry l' + status: completed + priority: medium + assigned_to: null + created: 2026-09-05T11:24:54Z + updated: 2026-09-06T02:37:35Z + spec: null + acceptance_criteria: + - 'bash scripts/check_roadmap_diff_additive.sh exit 0 on a trimmed pmat work add hunk; exit 1 on the un-trimmed 2,531-line re-serialisation of 6d9ba274a (fixture) | bash scripts/check_guards_are_wired.sh | mutation: commit an un-trimmed pmat work add output -> RED' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + - pp-066 + notes: 'complete: proof:PR#2987 (merged 65680cdf8 2026-09-06T02:37:35Z); proof:docs/audits/impl-PMAT-980-receipt.md' +- id: PMAT-981 + github_issue: null + item_type: task + title: 'GH-2896: G-5 check_target_universe.sh: for every workspace member (cargo metadata, root ∪ crates/facades) and every cargo target unde' + status: planned + priority: medium + assigned_to: null + created: 2026-09-05T11:24:57Z + updated: 2026-09-05T11:24:57Z + spec: null + acceptance_criteria: + - 'bash scripts/check_target_universe.sh exit 0 and prints members=82 targets= dark=0 | bash scripts/check_guards_are_wired.sh | mutation: drop one named --test from ci.yml while it exists in cargo metadata -> RED; add "# CI only" to a make target no workflow calls -> RED; restore the query_pre_attn_scalar omission in driver_cuda_gguf.rs -> the cuda lane RED' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-982 + github_issue: null + item_type: task + title: 'GH-2897: G-1 check_crate_names.sh: [lib] name == directory (- -> _) over the cargo-metadata member set (root 79 + facades 3); every o' + status: planned + priority: medium + assigned_to: null + created: 2026-09-05T11:25:01Z + updated: 2026-09-05T11:25:01Z + spec: null + acceptance_criteria: + - 'bash scripts/check_crate_names.sh exit 0 printing remaining=51 depkeys_remaining= features_remaining=21 | bash tests/guards/crate_names_cases.sh (case table incl. stray manifest, commented name, absent [lib], [[bin]] ignored, workspace shell skipped, D-5 row, facades workspace, duplicate [lib] name) | bash scripts/check_guards_are_wired.sh | mutation: untracked crates/zz-probe/Cargo.toml with [package] and [lib] name = "probe" -> RED (unregistered stray); delete one allow-list line -> RED; add zz-probe to workspace.members with a bad name -> RED' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-983 + github_issue: null + item_type: task + title: 'GH-2898: G-8 ratchets block regressions, not edits (class #2879): the claim-literal ratchet admits a PAIRED MOVE without a guard edit' + status: planned + priority: medium + assigned_to: null + created: 2026-09-05T11:25:04Z + updated: 2026-09-05T11:25:04Z + spec: null + acceptance_criteria: + - 'bash scripts/check_baseline_ratchets.sh --selftest carries paired_move_admitted and re_admission_refused | a CHANGELOG edit above line 1121 with no guard change passes the ratchet | the pre-commit hook selftest: a merge commit bringing a debt-carrying file from main is not re-gated; a new edit to it still is | the G2.3 ratchet case table: recording a newly found defect in the ledger is GREEN; a regression is RED | mutation: drop the removed-partner condition -> re_admission_refused RED' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-984 + github_issue: null + item_type: task + title: 'GH-2899: G-9 cbtop verdict polarity: status PASS / ci_result green over its own grade F (or a profiler that returned nothing) is a na' + status: planned + priority: medium + assigned_to: null + created: 2026-09-05T11:25:08Z + updated: 2026-09-05T11:25:08Z + spec: null + acceptance_criteria: + - 'cargo test -p aprender-cbtop --test verdict_polarity: grade F => status FAIL; profiler empty => named refusal, exit non-zero | bash scripts/check_pass_grep_anchored.sh stays GREEN | mutation: restore the unconditional PASS -> RED' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-985 + github_issue: null + item_type: task + title: 'GH-2900: G-2 DECISION D-5: [lib] name = aprender declared by root Cargo.toml and crates/aprender-core — keep the front door or rename' + status: completed + priority: medium + assigned_to: null + created: 2026-09-05T11:25:11Z + updated: 2026-09-06T12:10:00Z + spec: null + acceptance_criteria: + - 'one line in spec §0 with decided_by and date | mutation: none' + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: 'complete: decided at https://github.com/paiml/aprender/issues/2873#issuecomment-5558718271 (decided_by: noahgift via driver prompt 2026-09-06); proof:docs/audits/impl-PMAT-985-receipt.md' +- id: PMAT-986 + github_issue: null + item_type: task + title: 'GH-2901: G-3 rename cost measured at HEAD: use-site count (review said 4,097 [A]) by the committed regex, pmat query as second estima' + status: planned + priority: medium + assigned_to: null + created: 2026-09-05T11:25:15Z + updated: 2026-09-05T11:25:15Z + spec: null + acceptance_criteria: + - 'bash scripts/crate_rename_cost.sh reproduces the per-name totals and prints both estimators with their disagreement | docs/audits/crate-rename-cost.md exists with basis= on every figure | mutation: none' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-987 + github_issue: null + item_type: task + title: 'GH-2902: G-4 the obligation DAG as data with invariants in CI: scripts/check_dag_invariants.sh + scripts/lib/dag_invariants.py over d' + status: completed + priority: medium + assigned_to: null + created: 2026-09-05T11:25:18Z + updated: 2026-09-06T02:37:35Z + spec: null + acceptance_criteria: + - 'bash scripts/check_dag_invariants.sh docs/specifications/pp-066-dag.yaml --min-slack-days 6 exit 0 | bash scripts/check_dag_invariants.sh --selftest 5/5 both polarities | python3 scripts/render_dag.py --check exit 0 (spec tables match the yaml) | bash scripts/check_guards_are_wired.sh | mutation: set W-H''s expiry equal to C1''s -> RED (slack); swap two gx10 queue positions -> RED (order); add a self-edge -> RED (cycle)' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + - pp-066 + notes: 'complete: proof:PR#2987 (merged 65680cdf8 2026-09-06T02:37:35Z); proof:docs/audits/impl-PMAT-987-receipt.md' +- id: PMAT-988 + github_issue: null + item_type: task + title: 'GH-2903: SPEC-1.6 spec v1.6: the 14 defects recorded by the S0 ledger and the #2872 review; S0-3/S0-12/S0-19 consequences (D-6 yes; B-M1 f' + status: completed + priority: medium + assigned_to: null + created: 2026-09-05T11:25:22Z + updated: 2026-09-06T02:37:35Z + spec: null + acceptance_criteria: + - 'bash tests/spec/pp066_v16_defects.sh — a case table of the 14 ledger defects: each asserts the corrected text is present (RED at v1.5, GREEN at v1.6; the RED-first test of this docs row) | bash scripts/check_no_claim_literals.sh && bash scripts/check_perf_claims_cite_receipts.sh | python3 scripts/render_dag.py --check (after G-4) or a byte-diff against the DAG-rendered tables | mutation: revert one of the 14 corrections -> its case-table row RED' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:docs + - pp-066 + notes: 'complete: proof:PR#2987 (merged 65680cdf8 2026-09-06T02:37:35Z); proof:docs/audits/impl-PMAT-988-receipt.md' +- id: PMAT-989 + github_issue: null + item_type: task + title: 'GH-2904: R-0 [premises discharged: S0-7 CONFIRMED, S0-14 CONFIRMED] BackendRegistry: enumerate cpu/cuda/wgpu at startup from the mach' + status: planned + priority: medium + assigned_to: null + created: 2026-09-05T11:25:26Z + updated: 2026-09-05T11:25:26Z + spec: null + acceptance_criteria: + - 'cargo test -p apr-cli --test registry_failure_catalogue (FX-1..FX-14, each with a must-RED twin under tests/fixtures/registry/defective/; FX-4b, REG-9 and REG-10 run against the real mixed host intel — two AMD W5700X + llvmpipe, S0-3 — not only against stubs) | scripts/pv_bin.sh validate contracts/apr-devices-schema-v1.yaml and every apr devices --json output validates against it on all four hosts | apr devices --json | jq -e ''[.[]|select(.status=="ready")]|length>=1'' on all four hosts | cargo test -p apr-cli --test backend_refusal_case_table (rows generated from {build features} x {host facts} x BACKEND_VALUES; refuse <=> request ∉ Ready) | git grep -c ''cfg!(any(feature = "cuda"'' crates/apr-cli/src prints 0 | S0-21 half: on gx10, apr devices --json read beside free -g under a 40 GB stress-ng --vm load, twice, and mem_free differs (REG-6 basis for mem_kind: Unified); on mini the adapter ' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-990 + github_issue: null + item_type: task + title: 'GH-2905: R-2 [premises discharged: S0-14 CONFIRMED, S0-15 measured] W-I: cuda joins default features iff S0-14 passed on all four hos' + status: planned + priority: medium + assigned_to: null + created: 2026-09-05T11:25:29Z + updated: 2026-09-05T11:25:29Z + spec: null + acceptance_criteria: + - 'make -C machines/clean-room clean-room-p1 exit 0 (infra checkout; publish-path hard gate) | scripts/check_multiplatform_dogfood.sh --require-resolved-backend cuda exit 0 on lambda and gx10; --require-resolved-backend cpu exit 0 on intel and mini with the cuda entry printed as unavailable reason=DriverNotFound | apr serve run --gpu on a build/host with no Ready GPU exits with the refusal code (error.rs) and the reason line | docs/audits/wi-cost.md carries S0-15 numbers with basis=cold-build-under-CI-load | mutation: make the dogfood record the request instead of the registry -> --require-resolved-backend RED on intel/mini' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-991 + github_issue: null + item_type: task + title: 'GH-2906: R-3 T-6 honest training banner: -m lora --gpu-backend cuda refuses or trains on the GPU; the cuBLAS-backward line prints onl' + status: planned + priority: medium + assigned_to: null + created: 2026-09-05T11:25:32Z + updated: 2026-09-05T11:25:32Z + spec: null + acceptance_criteria: + - 'cargo test -p aprender-train --test banner_truth (banner emitted iff a device-side backward kernel launched, counter from the executor; --gpu-backend cuda on a CPU-only build exits with the refusal code read from error.rs) | mutation: print the banner unconditionally -> RED on the CPU-only arm' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-992 + github_issue: null + item_type: task + title: 'GH-2907: R-4 W5 CLI wall-clock workload, cold arm: apr run / ollama run / llama-cli for a 32-token completion; replicate count from m' + status: planned + priority: medium + assigned_to: null + created: 2026-09-05T11:25:36Z + updated: 2026-09-05T11:25:36Z + spec: null + acceptance_criteria: + - 'scripts/perf_w5.sh --arm cold --pilot 5 prints CV per engine; n = ceil((1.96*CV/0.05)^2) written with basis=pilot | scripts/perf_w5.sh --arm cold --n $n -> evidence/w5//receipt.json naming all three binaries by sha256 and the Ollama daemon build | mutation: drop basis from the receipt -> validator RED' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-993 + github_issue: 2908 + item_type: task + title: 'GH-2908: R-5 apr-* assets for the 5 nightly.yml targets attached to every tagged release, built per D-10; sha256 + minisign-signed ma' + status: planned + priority: medium + assigned_to: null + created: 2026-09-05T11:25:40Z + updated: 2026-09-05T11:25:40Z + spec: null + acceptance_criteria: + - 'make -C machines/clean-room clean-room-p1 exit 0 first | gh release view v0.66.0-rc1 --json assets --jq ''[.assets[].name]'' lists apr-{x86_64,aarch64}-unknown-linux-gnu, apr-{x86_64,aarch64}-apple-darwin, apr-x86_64-pc-windows-msvc tarballs + .sha256 + one signed manifest | on each host scripts/check_multiplatform_dogfood.sh --from-release v0.66.0-rc1 verifies and records asset_sha256 | bench_host_receipt.sh H12 on the aarch64 asset on gx10 and mini before promotion | the promotion job refuses with one host receipt missing | mutation: promote with one host receipt missing -> the promotion job refuses; tamper one byte of the aarch64 tarball after signing -> the host --from-release verify step RED, no receipt written' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + - pp-066 + notes: 'R-5 delta 2026-09-08 (driver v6.1): build != test — the clean-room recipe with the forjar pin builds, the fleet-verify receipt verifies; x86_64-cuda on a JIT ephemeral lambda runner in the gpu-release group at refs/tags/v*; base-owned promotion over four receipts (C14 PASS, parity != skipped); publish_cascade.sh derived and fail-closed; no workflow runs cargo publish. blocked_by KEY (#3045, PMAT-1079) and RUNNER-GROUP; blockers += G-11b. The acceptance set is the DAG row R-5 and issue #2908 (acceptance_criteria here is not a lifecycle field the additive guard admits). Authored on agent/R-5 at 19c015ff9 with three divergences the row PR closes.' +- id: PMAT-994 + github_issue: null + item_type: task + title: 'GH-2909: R-6 one-line installer served at /releases/latest/download/install.sh: detect OS/arch, download the matching asset from the ' + status: planned + priority: medium + assigned_to: null + created: 2026-09-05T11:25:43Z + updated: 2026-09-05T11:25:43Z + spec: null + acceptance_criteria: + - 'bash tests/install/cases.sh (5 targets resolve; bad sha256 -> non-zero and nothing on PATH; bad signature -> non-zero; prerelease-only tag skipped for latest; no curl -> one line; --version pins; never writes outside $PREFIX; shellcheck -S error clean; POSIX sh, bash 3.2 safe) | on each host the C4 run uses the script and its stdout ends with the apr devices block | mutation: flip one hex digit of the pinned public key -> every install RED' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'R-5 delta 2026-09-08: blockers += KEY (#3045, PMAT-1079) — the installer pins the fingerprint of keys/apr-release-minisign.pub; DONE-IF the file is present on main.' +- id: PMAT-995 + github_issue: null + item_type: task + title: 'GH-2910: R-7 README leads with the installer one-liner; cargo install aprender second; the backend line generated from the registry k' + status: planned + priority: medium + assigned_to: null + created: 2026-09-05T11:25:47Z + updated: 2026-09-05T11:25:47Z + spec: null + acceptance_criteria: + - 'bash scripts/check_readme_claims.sh exit 0 | bash scripts/check_no_claim_literals.sh exit 0 | a test greps README for the exact one-liner tests/install/cases.sh exercises | mutation: change the README one-liner''s URL -> the grep test RED' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-996 + github_issue: null + item_type: task + title: 'GH-2911: P-0.3 proof credit from evidence only: l3_kani_proved/l4_lean_proved integers ignored; Kani credit = resolving #[kani::proof] ' + status: planned + priority: medium + assigned_to: null + created: 2026-09-05T11:25:50Z + updated: 2026-09-05T11:25:50Z + spec: null + acceptance_criteria: + - '. scripts/pv_bin.sh && "$PV" proof-status contracts/ --binding contracts/aprender/binding.yaml prints discharged Lean 8 / Kani 47 beside declared 181 / 1,257 | cargo test -p aprender-contracts --lib proof_credit (a contract with hand-typed l4_lean_proved: 7 and no resolving theorem scores 0) | mutation: re-trust the verification_summary integer in gates_extended.rs:401 / explain_render.rs:133 -> fixture RED' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-997 + github_issue: null + item_type: task + title: 'GH-2912: P-0.6 pv lint as its own CI step with --min-score 0.48 (basis=measured mean score 0.48 Grade D at b1a6324b8, #2870 ledger — a ' + status: planned + priority: medium + assigned_to: null + created: 2026-09-05T11:25:53Z + updated: 2026-09-05T11:25:53Z + spec: null + acceptance_criteria: + - 'the ci.yml step (via scripts/pv_bin.sh) exits 0 at HEAD and prints warnings=1082 score>=0.48 | bash scripts/check_pv_lint_step.sh --selftest (a contract adding one warning -> RED) | bash scripts/check_baseline_ratchets.sh PASS with the new baseline classified | mutation: add a hollow contract carrying one new warning -> RED' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-998 + github_issue: null + item_type: task + title: 'GH-2913: P-0.2 derived verification_summary (#2648 b): pv validate errors on drift; the 17 known drifts fixed (FALSIFY-PVI-002)' + status: planned + priority: medium + assigned_to: null + created: 2026-09-05T11:25:57Z + updated: 2026-09-05T11:25:57Z + spec: null + acceptance_criteria: + - '. scripts/pv_bin.sh && "$PV" validate contracts/ exits non-zero on a fixture whose total_obligations != len(proof_obligations) | the 17 drifted contracts validate | mutation: re-accept a drifted summary -> RED' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-999 + github_issue: null + item_type: task + title: 'GH-2914: P-0.4 honest headline: kernel · descriptive · fleet figures derived by pv status --headline; README checked as a floor (#2630)' + status: planned + priority: medium + assigned_to: null + created: 2026-09-05T11:26:02Z + updated: 2026-09-05T11:26:02Z + spec: null + acceptance_criteria: + - '. scripts/pv_bin.sh && "$PV" status --headline prints the three figures; crates/aprender-core/tests/readme_contract.rs checks README as a floor | mutation: type a headline number by hand -> readme_contract RED' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-1000 + github_issue: null + item_type: task + title: 'GH-2915: P-0.5 freeze the archived upstream: port the two stranded commits + the dirty manzana binding; remove the ../provable-contract' + status: planned + priority: medium + assigned_to: null + created: 2026-09-05T11:26:06Z + updated: 2026-09-05T11:26:06Z + spec: null + acceptance_criteria: + - 'git ls-files | grep -c "\.pv/" prints 0 | grep -rn "../provable-contracts" crates/aprender-contracts/src prints nothing | ARCHIVED-UPSTREAM.md exists | mutation: re-add the fallback path -> the no-fallback test RED' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-1001 + github_issue: null + item_type: task + title: 'GH-2916: P-0.1 one proof ladder (upstream numbering: L4 Kani, L5 Lean; PVI-D-1) in proof_status.rs and the three docs; ladder_consisten' + status: planned + priority: medium + assigned_to: null + created: 2026-09-05T11:26:10Z + updated: 2026-09-05T11:26:10Z + spec: null + acceptance_criteria: + - 'cargo test -p aprender-contracts --lib ladder_consistency | mutation: change one doc ladder -> RED' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-1002 + github_issue: null + item_type: task + title: 'GH-2917: P-1.1 #[contract] fails closed (#2699 in full): generated registry, compile_error! on missing name/equation/unparseable predic' + status: planned + priority: medium + assigned_to: null + created: 2026-09-05T11:26:13Z + updated: 2026-09-05T11:26:13Z + spec: null + acceptance_criteria: + - 'cargo test -p aprender-contracts-macros --test trybuild (missing contract -> compile error; optional -> warns) | cargo build -p aprender-contracts-macros succeeds; the 10 dangling call sites are P-1.2, which ships in the same PR | mutation: restore the option_env! None => nothing path -> trybuild RED' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-1003 + github_issue: null + item_type: task + title: 'GH-2918: P-1.2 repoint or author the 10 dangling #[contract] sites (compile errors once P-1.1 lands; ships in the same PR as P-1.1 by c' + status: planned + priority: medium + assigned_to: null + created: 2026-09-05T11:26:17Z + updated: 2026-09-05T11:26:17Z + spec: null + acceptance_criteria: + - 'cargo build --workspace succeeds with all 10 #[contract] sites resolving to an existing contract YAML | cargo test -p aprender-contracts-macros --test trybuild carries a dangling-site row that is a compile error | mutation: re-dangle one site -> compile error -> RED' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-1004 + github_issue: null + item_type: task + title: 'GH-2919: S-3 W-B bench: cargo bench batched Q4_K GEMV at M in {1,4,8} vs M in {16,32} cuBLAS GEMM; per-token time table; no kernel ch' + status: planned + priority: medium + assigned_to: null + created: 2026-09-05T11:26:21Z + updated: 2026-09-05T11:26:21Z + spec: null + acceptance_criteria: + - 'cargo bench -p aprender-serve --bench q4k_gemv -- --save-baseline wb0 -> evidence/bench/wb0.json with per-M medians and MADs (>=5 samples per M) | mutation: run 1 sample per M -> RED' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-1005 + github_issue: null + item_type: task + title: 'GH-2920: S-3g S-3 on gx10 (queue slot after T-0)' + status: planned + priority: medium + assigned_to: null + created: 2026-09-05T11:26:24Z + updated: 2026-09-05T11:26:24Z + spec: null + acceptance_criteria: + - 'same as S-3 on gx10 -> evidence/bench/wb0-gx10.json | mutation: none' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-1006 + github_issue: null + item_type: task + title: 'GH-2921: S-1 [premises discharged: master rows 6 and 9 LANDED per S0-2] W-A per-token host work out of the decode loop: one model.wri' + status: planned + priority: medium + assigned_to: null + created: 2026-09-05T11:26:28Z + updated: 2026-09-05T11:26:28Z + spec: null + acceptance_criteria: + - 'scripts/perf_ab.sh --subject wa --delta code --interleave 5 -> AbRecord with pred_ms_per_tok <= 3.5 recorded before the run and measured.lcb95_ms_per_tok <= 3.5 after | PP-26 witness unchanged at m=1 (greedy stream byte-identical) | mutation: reintroduce the per-token write() -> counter invariant RED' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-1007 + github_issue: null + item_type: task + title: 'GH-2922: S-2 W-C prefill without synchronous copies: pinned pre-allocated activation/KV staging, one async copy per layer, allocation' + status: planned + priority: medium + assigned_to: null + created: 2026-09-05T11:26:31Z + updated: 2026-09-05T11:26:31Z + spec: null + acceptance_criteria: + - 'nsys profile ... scripts/perf_w4.sh --tokens 64,256,512,2048 -> evidence/nsys/wc.json with api_share.copies_allocs < 0.10 | AbRecord with prefill_tok_s > 5700 registered before the run; golden output identical to pre-change | mutation: allocate per layer per token -> allocation-count invariant RED' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-1008 + github_issue: null + item_type: task + title: 'GH-2923: T-0h training-parity harness: train_parity.sh + receipt schema in evidence/train-parity/; recipe extended to Qwen2.5-7B-Instr' + status: planned + priority: medium + assigned_to: null + created: 2026-09-05T11:26:35Z + updated: 2026-09-05T11:26:35Z + spec: null + acceptance_criteria: + - 'scripts/train_parity.sh --validate tests/fixtures/train-parity/*.json exit 0 | scripts/train_parity.sh --dry-run --model Qwen2.5-7B-Instruct --seq 2048 --mb 4 --rank 16 --alpha 16 --targets q,k,v,o,gate,up,down --steps 200 --seed 42 --n 5 --interleave prints the 20-run plan with a time budget basis=pilot | mutation: drop interleaved from a receipt -> validator RED' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-1009 + github_issue: null + item_type: task + title: 'GH-2924: T-2 apr finetune --max-seq-len honoured or refused with one line and the refusal code on every path; the effective value pri' + status: planned + priority: medium + assigned_to: null + created: 2026-09-05T11:26:39Z + updated: 2026-09-05T11:26:39Z + spec: null + acceptance_criteria: + - 'cargo test -p apr-cli --test finetune_seq_len_truth over {256, 512, 1024, 2048} on instruct and wgpu paths: effective == requested or the command refuses | mutation: restore the 512 literal at finetune.rs:717 -> the 1024 and 2048 rows RED' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-1010 + github_issue: null + item_type: task + title: 'GH-2925: T-1 tau_loss for the canary dataset from Unsloth-vs-Unsloth seed variance (seeds 42,43,44), 200 steps; tau = 3 x MAD of fina' + status: planned + priority: medium + assigned_to: null + created: 2026-09-05T11:26:42Z + updated: 2026-09-05T11:26:42Z + spec: null + acceptance_criteria: + - 'scripts/train_parity.sh --tau-derive --seeds 42,43,44 -> evidence/train-parity/tau_loss.json with the three losses, MAD, tau and basis | mutation: hand-type tau -> validator RED (no sha)' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-1011 + github_issue: null + item_type: task + title: 'GH-2926: T-0 the four WT receipts: Unsloth QLoRA and apr finetune -m qlora on Qwen2.5-7B-Instruct, both hosts, n=5 interleaved, paire' + status: planned + priority: medium + assigned_to: null + created: 2026-09-05T11:26:46Z + updated: 2026-09-05T11:26:46Z + spec: null + acceptance_criteria: + - 'scripts/train_parity.sh --validate evidence/train-parity exit 0 with four receipts | evidence/train-parity/LEDGER.md rows 1-2 appended with validity_by_engine | mutation: a receipt with partial=true -> validate RED' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-1012 + github_issue: null + item_type: task + title: 'GH-2927: T-3 training gate REPORTING + self-ratchet: train_tok_per_sec, peak_vram, |dloss|<=tau as WT cells in perf-matrix.yaml; ratc' + status: planned + priority: medium + assigned_to: null + created: 2026-09-05T11:26:50Z + updated: 2026-09-05T11:26:50Z + spec: null + acceptance_criteria: + - 'scripts/perf_gate.sh --phase merge --workload WT prints REPORTING with the ratio and ratchet: seeded@ | scripts/perf_gate.sh --selftest wt_ratchet_fire and wt_ratchet_hold both present | mutation: set armed_by by hand -> selftest RED' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-1013 + github_issue: null + item_type: task + title: 'GH-2928: B-A1 hosts.intel.wgpu cell in perf-matrix.yaml: compute_class wgpu, status UNMEASURED with owner, expiry anchored on D-3 (S0-' + status: planned + priority: medium + assigned_to: null + created: 2026-09-05T11:26:53Z + updated: 2026-09-05T11:26:53Z + spec: null + acceptance_criteria: + - 'bash scripts/check_backend_firstclass.sh --matrix-only exit 0 (after B-G1) or bash scripts/check_perf_matrix_schema.sh exit 0 today; the cell has an owner and exactly one expiry form and its anchor exists in expiry_anchors | mutation: type a date instead of the anchor -> RED' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-1014 + github_issue: null + item_type: task + title: 'GH-2929: B-G1 check_backend_firstclass.sh: clauses 1-7 per backend computed from the tree (workflows, BACKEND_VALUES, perf-matrix.yaml' + status: planned + priority: medium + assigned_to: null + created: 2026-09-05T11:26:56Z + updated: 2026-09-05T11:26:56Z + spec: null + acceptance_criteria: + - 'bash scripts/check_backend_firstclass.sh exit 0 at HEAD printing cuda 6/7 or lower (derived); wired into ci / gate | case table tests/fixtures/firstclass/*.yaml must-match and must-not-match per clause | mutation: add "wgpu is a first-class backend" to README.md -> RED (and check_no_claim_literals.sh stays GREEN under it)' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-1015 + github_issue: null + item_type: task + title: 'GH-2930: D-2doc qwen-train-canary README: the summary figure ("Gap vs unsloth: 2.5x") is derived from the table or deleted; the in-tree ' + status: planned + priority: medium + assigned_to: null + created: 2026-09-05T11:27:00Z + updated: 2026-09-05T11:27:00Z + spec: null + acceptance_criteria: + - 'grep -n "2.5x" ../qwen-train-canary/README.md prints nothing, or the line cites the table cell it divides | crates/aprender-train-canary/README.md and the sibling README carry the same throughput table (diff -q) | mutation: restore the 2.5x summary line -> the README check RED' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-1016 + github_issue: null + item_type: task + title: 'GH-2931: D-1doc [spec id D-1 in §5 Track D; keyed D-1doc here because D-1 is also a §0 decision id] docs/specifications/cuda-backend-arc' + status: planned + priority: medium + assigned_to: null + created: 2026-09-05T11:27:03Z + updated: 2026-09-05T11:27:03Z + spec: null + acceptance_criteria: + - 'the claims-cite check over the doc: every API: sentence cites {artifact sha256, page} or UNVERIFIED{...}; exit 0 iff the UNVERIFIED count <= the receipt header count (down-only) | mutation: strip one citation -> RED' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-1017 + github_issue: null + item_type: task + title: 'GH-2932: TAG-0.66.0 the release cut: v0.66.0-rc1 as prerelease, promotion from four host receipts (R-5), crates.io cascade from the release ' + status: planned + priority: medium + assigned_to: null + created: 2026-09-05T11:27:06Z + updated: 2026-09-05T11:27:06Z + spec: null + acceptance_criteria: + - 'make -C machines/clean-room clean-room-p1 exit 0 (infra checkout) | every §4 C0..C13 command exits 0 on the release commit | gh release view v0.66.0 --json isPrerelease --jq .isPrerelease prints false only after the promotion job | mutation: promote with one host receipt missing -> the promotion job refuses' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:docs + notes: null +- id: PMAT-1018 + github_issue: null + item_type: task + title: 'GH-2933: DEC-D-2 DECISION D-2: Unsloth throughput concession not assumed revoked; T-3 ships REPORTING' + status: completed + priority: medium + assigned_to: null + created: 2026-09-05T11:27:10Z + updated: 2026-09-06T12:10:00Z + spec: null + acceptance_criteria: + - 'one line in spec §0 with decided_by and date | mutation: none' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:docs + notes: 'complete: decided at https://github.com/paiml/aprender/issues/2873#issuecomment-5558717537 (decided_by: noahgift via driver prompt 2026-09-06); proof:docs/audits/impl-PMAT-1018-receipt.md' +- id: PMAT-1019 + github_issue: null + item_type: task + title: 'GH-2934: DEC-D-3 DECISION D-3 (escalate): CI home for non-CUDA lanes — may intel host a wgpu lane and a wasm harness; may mini host night' + status: completed + priority: medium + assigned_to: null + created: 2026-09-05T11:27:14Z + updated: 2026-09-06T12:10:00Z + spec: null + acceptance_criteria: + - 'one line in spec §0 with decided_by and date | mutation: none' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:docs + notes: 'complete: decided at https://github.com/paiml/aprender/issues/2873#issuecomment-5558717787 (decided_by: noahgift via driver prompt 2026-09-06); proof:docs/audits/impl-PMAT-1019-receipt.md' +- id: PMAT-1020 + github_issue: null + item_type: task + title: 'GH-2935: DEC-D-8 DECISION D-8 (escalate): rename sequencing for 0.67 — one PR per crate vs batched leaves' + status: completed + priority: medium + assigned_to: null + created: 2026-09-05T11:27:18Z + updated: 2026-09-06T12:10:00Z + spec: null + acceptance_criteria: + - 'one line in spec §0 with decided_by and date | mutation: none' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:docs + notes: 'complete: decided at https://github.com/paiml/aprender/issues/2873#issuecomment-5558719034 (decided_by: noahgift via driver prompt 2026-09-06); proof:docs/audits/impl-PMAT-1020-receipt.md' +- id: PMAT-1021 + github_issue: null + item_type: task + title: 'GH-2936: DEC-D-9 DECISION D-9: cuda in the published crate default features — yes iff S0-14 (held on intel/mini), R-0 merged, clean-room ' + status: completed + priority: medium + assigned_to: null + created: 2026-09-05T11:27:21Z + updated: 2026-09-06T12:10:00Z + spec: null + acceptance_criteria: + - 'one line in spec §0 with decided_by and date | mutation: none' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:docs + notes: 'complete: decided at https://github.com/paiml/aprender/issues/2873#issuecomment-5558719666 (decided_by: noahgift via driver prompt 2026-09-06); proof:docs/audits/impl-PMAT-1021-receipt.md' +- id: PMAT-1022 + github_issue: null + item_type: task + title: 'GH-2937: DEC-D-10 DECISION D-10: per-target feature set of the release binaries (R-5 runs S0-14 per target)' + status: completed + priority: medium + assigned_to: null + created: 2026-09-05T11:27:25Z + updated: 2026-09-06T12:10:00Z + spec: null + acceptance_criteria: + - 'one line in spec §0 with decided_by and date | mutation: none' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:docs + notes: 'complete: decided at https://github.com/paiml/aprender/issues/2873#issuecomment-5558719920 (decided_by: noahgift via driver prompt 2026-09-06); proof:docs/audits/impl-PMAT-1022-receipt.md' +- id: PMAT-1023 + github_issue: null + item_type: task + title: 'GH-2938: DEC-D-11 DECISION D-11: PV-IMPROVE-001 phase 0 + 1.1/1.2 ride 0.66 as C12 blockers' + status: completed + priority: medium + assigned_to: null + created: 2026-09-05T11:27:28Z + updated: 2026-09-06T12:10:00Z + spec: null + acceptance_criteria: + - 'one line in spec §0 with decided_by and date | mutation: none' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:docs + notes: 'complete: decided at https://github.com/paiml/aprender/issues/2873#issuecomment-5558720148 (decided_by: noahgift via driver prompt 2026-09-06); proof:docs/audits/impl-PMAT-1023-receipt.md' +- id: PMAT-1024 + github_issue: null + item_type: task + title: 'GH-2939: W-B-kernel multi-warp Q4_K GEMV, M in {1,4,8}' + status: planned + priority: medium + assigned_to: null + created: 2026-09-05T11:27:32Z + updated: 2026-09-05T11:27:32Z + spec: null + acceptance_criteria: + - 'kill if: no gain at M<=8, or per-layer cosine witness fails | mutation: none' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-1025 + github_issue: null + item_type: task + title: 'GH-2940: W-D f16 KV + per-layer cosine witness; reserve from measured peak' + status: planned + priority: medium + assigned_to: null + created: 2026-09-05T11:27:35Z + updated: 2026-09-05T11:27:35Z + spec: null + acceptance_criteria: + - 'kill if: any layer cosine < 0.999 at 4096 ctx, or PP-26 regression | mutation: none' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-1026 + github_issue: null + item_type: task + title: 'GH-2941: W-E scheduler: slots_admitted concurrent decodes under captured graphs, one graph per M-bucket or padding' + status: planned + priority: medium + assigned_to: null + created: 2026-09-05T11:27:38Z + updated: 2026-09-05T11:27:38Z + spec: null + acceptance_criteria: + - 'kill if: agg(4)/dec(1) < 2.5x; frozen slot; intra-batch divergence | mutation: none' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-1027 + github_issue: null + item_type: task + title: 'GH-2942: W-G GB10: NEON Q4_K GEMV; batched prefill default on sm_121 after master 21; pre-compiled kernels (trueno#203)' + status: planned + priority: medium + assigned_to: null + created: 2026-09-05T11:27:42Z + updated: 2026-09-05T11:27:42Z + spec: null + acceptance_criteria: + - 'kill if: prefill not linear in prompt tokens; collapse under batched prefill | mutation: none' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-1028 + github_issue: null + item_type: task + title: 'GH-2943: W-H batch-invariant reduction; logprob margin on the wire (master row 22)' + status: planned + priority: medium + assigned_to: null + created: 2026-09-05T11:27:46Z + updated: 2026-09-05T11:27:46Z + spec: null + acceptance_criteria: + - 'kill if: c=16 witness < 64 after the epilogue change | mutation: none' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-1029 + github_issue: null + item_type: task + title: 'GH-2944: W-F-attach apr run attaches to a running apr serve; W5 resident arm' + status: planned + priority: medium + assigned_to: null + created: 2026-09-05T11:27:49Z + updated: 2026-09-05T11:27:49Z + spec: null + acceptance_criteria: + - 'kill if: resident completion slower than Ollama | mutation: none' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-1030 + github_issue: null + item_type: task + title: 'GH-2945: T67-1 pre-compiled sm_121 kernels for training (trueno#203)' + status: planned + priority: medium + assigned_to: null + created: 2026-09-05T11:27:53Z + updated: 2026-09-05T11:27:53Z + spec: null + acceptance_criteria: + - 'kill if: JIT still on the training path | mutation: none' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-1031 + github_issue: null + item_type: task + title: 'GH-2946: T67-2 fused RMSNorm/RoPE/SwiGLU/chunked CE with their backward kernels (review 2.5)' + status: planned + priority: medium + assigned_to: null + created: 2026-09-05T11:27:57Z + updated: 2026-09-05T11:27:57Z + spec: null + acceptance_criteria: + - 'kill if: forward launches counted, backward not | mutation: none' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-1032 + github_issue: null + item_type: task + title: 'GH-2947: T67-3 NF4-in-the-matmul: kernel design + registered per-kernel prediction (mma.sync + register dequant) before code; cuBLAS ha' + status: planned + priority: medium + assigned_to: null + created: 2026-09-05T11:28:00Z + updated: 2026-09-05T11:28:00Z + spec: null + acceptance_criteria: + - 'kill if: code before the registered prediction | mutation: none' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-1033 + github_issue: null + item_type: task + title: 'GH-2948: T67-4 bf16 + activation checkpointing; offload double-buffered and overlapped' + status: planned + priority: medium + assigned_to: null + created: 2026-09-05T11:28:03Z + updated: 2026-09-05T11:28:03Z + spec: null + acceptance_criteria: + - 'kill if: offload not overlapped | mutation: none' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-1034 + github_issue: null + item_type: task + title: 'GH-2949: T67-5 sequence packing (T-2 already covers --max-seq-len)' + status: planned + priority: medium + assigned_to: null + created: 2026-09-05T11:28:07Z + updated: 2026-09-05T11:28:07Z + spec: null + acceptance_criteria: + - 'kill if: packing changes the loss trajectory | mutation: none' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-1035 + github_issue: null + item_type: task + title: 'GH-2950: T-7-arm first P-5 PASS on WT arms the training gate' + status: planned + priority: medium + assigned_to: null + created: 2026-09-05T11:28:11Z + updated: 2026-09-05T11:28:11Z + spec: null + acceptance_criteria: + - 'kill if: passes on a mutated (unfused) build | mutation: none' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-1036 + github_issue: null + item_type: task + title: 'GH-2951: B-W0 quantized-weight upload path in serve: Q4K_GEMV_SHADER (already consumed by compute wgsl_forward.rs:424) wired into Owne' + status: planned + priority: medium + assigned_to: null + created: 2026-09-05T11:28:15Z + updated: 2026-09-05T11:28:15Z + spec: null + acceptance_criteria: + - 'kill if: device bytes > 1.3x model bytes; adapter not hardware; SUBGROUPS denial unrecorded | mutation: none' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-1037 + github_issue: null + item_type: task + title: 'GH-2952: B-W1 wgpu lane on intel: the job, adapter selected by name/type and printed (two AMD W5700X, RADV; llvmpipe present so the ra' + status: planned + priority: medium + assigned_to: null + created: 2026-09-05T11:28:19Z + updated: 2026-09-05T11:28:19Z + spec: null + acceptance_criteria: + - 'kill if: adapter deviceType != DISCRETE_GPU or lavapipe|llvmpipe in driverName = FAIL | mutation: none' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-1038 + github_issue: null + item_type: task + title: 'GH-2953: B-W2 Vulkan comparator pin (llama.cpp Vulkan build) in llama_pin.toml for the intel lane' + status: planned + priority: medium + assigned_to: null + created: 2026-09-05T11:28:22Z + updated: 2026-09-05T11:28:22Z + spec: null + acceptance_criteria: + - 'kill if: pin missing or expired | mutation: none' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-1039 + github_issue: null + item_type: task + title: 'GH-2954: B-W3 PP-26 witnesses on the wgpu lane (m=1 vs m=c)' + status: planned + priority: medium + assigned_to: null + created: 2026-09-05T11:28:25Z + updated: 2026-09-05T11:28:25Z + spec: null + acceptance_criteria: + - 'kill if: witness fails at c>1 | mutation: none' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-1040 + github_issue: null + item_type: task + title: 'GH-2955: B-W4 W1 receipt on the wgpu lane; "wgpu loses to CPU" is a recorded outcome' + status: planned + priority: medium + assigned_to: null + created: 2026-09-05T11:28:29Z + updated: 2026-09-05T11:28:29Z + spec: null + acceptance_criteria: + - 'kill if: no conformant receipt | mutation: none' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-1041 + github_issue: null + item_type: task + title: 'GH-2956: B-W5 clauses 5-6 for wgpu in check_backend_firstclass.sh (dogfood + formats)' + status: planned + priority: medium + assigned_to: null + created: 2026-09-05T11:28:33Z + updated: 2026-09-05T11:28:33Z + spec: null + acceptance_criteria: + - 'kill if: score printed without a receipt | mutation: none' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-1042 + github_issue: null + item_type: task + title: 'GH-2957: B-M1 metal as a Ready registry entry on mini via the wgpu-Metal adapter (no MSL dispatcher exists — S0-12); NA -> UNMEASURED ' + status: planned + priority: medium + assigned_to: null + created: 2026-09-05T11:28:37Z + updated: 2026-09-05T11:28:37Z + spec: null + acceptance_criteria: + - 'kill if: registry prints Ready before a build on mini took the class | mutation: none' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-1043 + github_issue: null + item_type: task + title: 'GH-2958: B-M2 llama.cpp-Metal + Ollama comparator pins on mini' + status: planned + priority: medium + assigned_to: null + created: 2026-09-05T11:28:40Z + updated: 2026-09-05T11:28:40Z + spec: null + acceptance_criteria: + - 'kill if: pin missing or expired | mutation: none' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-1044 + github_issue: null + item_type: task + title: 'GH-2959: B-M3 PP-26 witnesses and the W1 receipt on mini (#2826: the f32 wgpu path is 0.123 tok/s; needs B-W0)' + status: planned + priority: medium + assigned_to: null + created: 2026-09-05T11:34:02Z + updated: 2026-09-05T11:34:02Z + spec: null + acceptance_criteria: + - 'kill if: no conformant receipt | mutation: none' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-1045 + github_issue: null + item_type: task + title: 'GH-2972: B-M4 clauses 5-6 for metal in check_backend_firstclass.sh' + status: planned + priority: medium + assigned_to: null + created: 2026-09-05T11:34:05Z + updated: 2026-09-05T11:34:05Z + spec: null + acceptance_criteria: + - 'kill if: score printed without a receipt | mutation: none' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-1046 + github_issue: null + item_type: task + title: 'GH-2973: B-S1 0.5B GGUF+APR decode under wasmtime (wasm bound computed from bytes per receipt; W1 excluded by address space)' + status: planned + priority: medium + assigned_to: null + created: 2026-09-05T11:34:08Z + updated: 2026-09-05T11:34:08Z + spec: null + acceptance_criteria: + - 'kill if: a size line typed instead of computed | mutation: none' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-1047 + github_issue: null + item_type: task + title: 'GH-2974: B-S2 browser harness for the wasm32 build' + status: planned + priority: medium + assigned_to: null + created: 2026-09-05T11:34:12Z + updated: 2026-09-05T11:34:12Z + spec: null + acceptance_criteria: + - 'kill if: harness not deterministic | mutation: none' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-1048 + github_issue: null + item_type: task + title: 'GH-2975: B-S3 wasm size budget + self-ratchet' + status: planned + priority: medium + assigned_to: null + created: 2026-09-05T11:34:16Z + updated: 2026-09-05T11:34:16Z + spec: null + acceptance_criteria: + - 'kill if: ratchet seeded by hand | mutation: none' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-1049 + github_issue: null + item_type: task + title: 'GH-2976: B-S4 clauses 5-6 for wasm32 in check_backend_firstclass.sh (clause 4 N/A at m=1, printed)' + status: planned + priority: medium + assigned_to: null + created: 2026-09-05T11:34:20Z + updated: 2026-09-05T11:34:20Z + spec: null + acceptance_criteria: + - 'kill if: N/A printed as a pass | mutation: none' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-1050 + github_issue: null + item_type: task + title: 'GH-2977: B-A2 vendor-neutral Vulkan lane receipt on AMD silicon (intel W5700X); ROCm/HIP row with its blocker' + status: planned + priority: medium + assigned_to: null + created: 2026-09-05T11:34:24Z + updated: 2026-09-05T11:34:24Z + spec: null + acceptance_criteria: + - 'kill if: NVIDIA-specific assumption in the wgpu lane | mutation: none' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-1051 + github_issue: null + item_type: task + title: 'GH-2978: PVI-1.3-4.3 PV-IMPROVE phases 1.3-4.3 under #2556: empty macro arm, scoped codegen, PV-ENF-003, one binding registry, Kani/Lean nigh' + status: planned + priority: medium + assigned_to: null + created: 2026-09-05T11:34:27Z + updated: 2026-09-05T11:34:27Z + spec: null + acceptance_criteria: + - 'kill if: per #2870 | mutation: none' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-1052 + github_issue: null + item_type: task + title: 'GH-2979: renames §6.7: 51 [lib]/package renames phased per D-8; shim package only; dep keys and feature strings updated per PR (G-1 count' + status: planned + priority: medium + assigned_to: null + created: 2026-09-05T11:34:31Z + updated: 2026-09-05T11:34:31Z + spec: null + acceptance_criteria: + - 'kill if: check_crate_names.sh remaining does not shrink by exactly the PR count | mutation: none' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-1053 + github_issue: null + item_type: task + title: 'GH-2980: bar-gating qwen-coder-deploy TTFT/ITL/agg(4) bar GATED after re-derivation per F-14' + status: planned + priority: medium + assigned_to: null + created: 2026-09-05T11:34:35Z + updated: 2026-09-05T11:34:35Z + spec: null + acceptance_criteria: + - 'kill if: the comparator fails its own bar | mutation: none' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-1054 + github_issue: null + item_type: task + title: 'GH-2982: C0-5 PRQ-013 single base-owned quorum workflow (pull_request_target/merge_group)' + status: completed + priority: medium + assigned_to: null + created: 2026-09-05T11:54:37Z + updated: 2026-09-05T16:44:33Z + spec: null + acceptance_criteria: + - 'see #2982 (A + mutation)' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + - pp-066 + notes: 'complete: proof:PR#2985 (merged cdc0acb99 2026-09-05T16:44:33Z); proof:docs/audits/impl-PMAT-1054-receipt.md' +- id: PMAT-1055 + github_issue: null + item_type: task + title: 'GH-2983: C0-6 mutation step exceeds job timeout (134 mutants, #2872 receipt run) — basis= run 33953736119: 5,767 s step, 9,017 s job vs 9,000 s timeout' + status: planned + priority: medium + assigned_to: null + created: 2026-09-05T11:54:37Z + updated: 2026-09-05T11:54:37Z + spec: null + acceptance_criteria: + - 'see #2983 (A + mutation)' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-1056 + github_issue: null + item_type: task + title: 'GH-2984: C0-7 receipt terminal marker + check_receipt_complete.sh' + status: completed + priority: medium + assigned_to: null + created: 2026-09-05T11:54:37Z + updated: 2026-09-06T02:37:35Z + spec: null + acceptance_criteria: + - 'see #2984 (A + mutation)' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + - pp-066 + notes: 'complete: proof:PR#2987 (merged 65680cdf8 2026-09-06T02:37:35Z); proof:docs/audits/impl-PMAT-1056-receipt.md' +- id: PMAT-1057 + github_issue: null + item_type: task + title: 'GH-2882: I-1 master row 1: land #2809; Blackwell guard on prefill_multi_prompt (gpu_profile.rs::multi_prompt_prefill_allowed); perf04' + status: planned + priority: medium + assigned_to: null + created: 2026-09-05T11:23:55Z + updated: 2026-09-05T11:23:55Z + spec: null + acceptance_criteria: + - 'gh pr view 2809 --json state,mergedAt shows merged | bash scripts/check_perf041_marker.sh exit 0 (marker present in cuda-nightly.yml; absent marker = RED in its selftest) | the first wired gx10 night writes evidence/perf041/gx10/witness.json (EXPECTED RED per master §9 #1a is a finding to file, not a rerun) | mutation: remove the perf041 step from cuda-nightly.yml -> check_perf041_marker.sh RED' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-1058 + github_issue: null + item_type: task + title: 'PP-066: land the 0.66 release spec (docs only)' + status: planned + priority: medium + assigned_to: null + created: 2026-09-05T07:00:53Z + updated: 2026-09-05T07:00:53Z + spec: docs/specifications/PP-066-release-spec.md + acceptance_criteria: + - Source of truth for the 0.66 obligation set + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: 'first minted as PMAT-966 (#2872, 2026-09-05 07:00Z); #2871 minted PMAT-966 for a harness defect in another session at 07:10Z and both landed — re-minted to PMAT-1058 on 2026-09-06 (the later copy in the file; the harness ticket keeps PMAT-966 because signed evidence under evidence/ cites it)' +- id: PMAT-1059 + github_issue: null + item_type: task + title: 'GH-2999: G-10 check_hardcoded_paths.sh arms at pmat >= 3.32 while the fleet runs 3.31; under 3.37 main is 317 vs baseline 277 — every PR goes red on the fleet upgrade' + status: completed + priority: medium + assigned_to: null + created: 2026-09-06T02:37:57Z + updated: 2026-09-06T14:00:00Z + spec: null + acceptance_criteria: + - 'see #2999 (A + mutation)' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + - pp-066 + notes: 'complete: proof:PR#3011 (merged b0a0a51b2 2026-09-06T13:51:59Z); proof:docs/audits/impl-PMAT-1059-receipt.md' +- id: PMAT-1060 + github_issue: null + item_type: bug + title: 'README claims cargo install aprender is CPU-only, but the plain install compiles the wgpu/Vulkan + backend by default (0.65.2 post-publish dogfood NO-GO) — fix for 0.65.3' + status: planned + priority: high + assigned_to: null + created: 2026-09-06T16:59:05Z + updated: 2026-09-06T16:59:05Z + spec: null + acceptance_criteria: + - 'Either README.md''s CPU-only claim is made true (crates/aprender-serve default features no longer + inherited through apr-cli''s inference feature without default-features = false) or the README states + what the plain install ships.' + - 'The 0.65.3 post-publish dogfood''s banner probe is GREEN.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + - release-0.65.3 + - dogfood + notes: 'Found by docs/audits/dogfood-aprender-0.65.2-post-publish.md (aprender#3010). Freeze rule (BSE-001 + spec v1.3 §3): dogfood run and recorded satisfies the freeze; this ticket carries the defect.' +- id: PMAT-1061 + github_issue: null + item_type: task + title: 'BSE-16 fail-closed gate: target — pmat verify stage_tests root-crate-only in a workspace, SATD pre-existing (§13 F-09)' + status: planned + priority: high + assigned_to: null + created: 2026-09-07T01:23:54Z + updated: 2026-09-07T01:23:54Z + spec: docs/specifications/build-system-enhancement.md (paiml/infra) + acceptance_criteria: + - 'The A_i command of the matching §4 item in the spec exits 0 on the branch and its named mutation goes RED; Fable re-runs both.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + - bse-001 + - m2 + notes: null +- id: PMAT-1062 + github_issue: null + item_type: task + title: 'BSE-01 guard job runs all, reports all; CARGO_TARGET_DIR per container step; aprender timeout-minutes' + status: completed + priority: high + assigned_to: null + created: 2026-09-07T01:23:54Z + updated: 2026-09-07T01:23:54Z + spec: docs/specifications/build-system-enhancement.md (paiml/infra) + acceptance_criteria: + - 'The A_i command of the matching §4 item in the spec exits 0 on the branch and its named mutation goes RED; Fable re-runs both.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + - bse-001 + - m2 + notes: 'BSE-01 landed in three parts, all on main: guard_tree.sh runs every guard + and reports every failure rather than stopping at the first, wired as the guard-tree + job with per-job timeout-minutes (90/90/22); the six container steps each carry + -e CARGO_TARGET_DIR=/workspace/target. proof:PR#3037 proof:scripts/guard_tree.sh' +- id: PMAT-1063 + github_issue: null + item_type: task + title: 'BSE-14 scripts/predict_merge.sh — merge(origin/main, HEAD) in a temp worktree, guard_tree --list guards, freshness tuple, --check refuses on movement' + status: planned + priority: high + assigned_to: null + created: 2026-09-07T01:23:54Z + updated: 2026-09-07T01:23:54Z + spec: docs/specifications/build-system-enhancement.md (paiml/infra) + acceptance_criteria: + - 'The A_i command of the matching §4 item in the spec exits 0 on the branch and its named mutation goes RED; Fable re-runs both.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + - bse-001 + - m2 + notes: null +- id: PMAT-1064 + github_issue: null + item_type: task + title: 'BSE-02 guard-tree job first (the cargo-free guards), parallel to the builds' + status: planned + priority: high + assigned_to: null + created: 2026-09-07T01:23:54Z + updated: 2026-09-07T01:23:54Z + spec: docs/specifications/build-system-enhancement.md (paiml/infra) + acceptance_criteria: + - 'The A_i command of the matching §4 item in the spec exits 0 on the branch and its named mutation goes RED; Fable re-runs both.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + - bse-001 + - m2 + notes: null +- id: PMAT-1065 + github_issue: null + item_type: task + title: 'BSE-09b merge=union on GitHub''s merge engine (goal lane); BSE-09a sorted-insert only if union CONFLICTS' + status: planned + priority: medium + assigned_to: null + created: 2026-09-07T01:23:54Z + updated: 2026-09-07T01:23:54Z + spec: docs/specifications/build-system-enhancement.md (paiml/infra) + acceptance_criteria: + - 'The A_i command of the matching §4 item in the spec exits 0 on the branch and its named mutation goes RED; Fable re-runs both.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + - bse-001 + - m2 + notes: null +- id: PMAT-1066 + github_issue: null + item_type: task + title: 'BSE-10a CI tool pins + baseline tool_version — assert, never install (tools.toml, check_tool_versions.sh)' + status: planned + priority: medium + assigned_to: null + created: 2026-09-07T01:23:54Z + updated: 2026-09-07T01:23:54Z + spec: docs/specifications/build-system-enhancement.md (paiml/infra) + acceptance_criteria: + - 'The A_i command of the matching §4 item in the spec exits 0 on the branch and its named mutation goes RED; Fable re-runs both.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + - bse-001 + - m2 + notes: null +- id: PMAT-1067 + github_issue: null + item_type: task + title: 'BSE-11 nightly witness byte-compare (witness_diff.sh: UNCHANGED/CHANGED, never a status colour)' + status: planned + priority: medium + assigned_to: null + created: 2026-09-07T01:23:54Z + updated: 2026-09-07T01:23:54Z + spec: docs/specifications/build-system-enhancement.md (paiml/infra) + acceptance_criteria: + - 'The A_i command of the matching §4 item in the spec exits 0 on the branch and its named mutation goes RED; Fable re-runs both.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + - bse-001 + - m2 + notes: null +- id: PMAT-1068 + github_issue: null + item_type: task + title: 'BSE-03 three ratchet classes → D2 comparand diff measured on origin/main@SHA in-run; README count derived; threat model first (PR-B)' + status: planned + priority: high + assigned_to: null + created: 2026-09-07T01:23:54Z + updated: 2026-09-07T01:23:54Z + spec: docs/specifications/build-system-enhancement.md (paiml/infra) + acceptance_criteria: + - 'The A_i command of the matching §4 item in the spec exits 0 on the branch and its named mutation goes RED; Fable re-runs both.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + - bse-001 + - m2 + notes: null +- id: PMAT-1069 + github_issue: 3015 + item_type: task + title: 'U-1: pmat#1200: `pmat work cot derive` emits hollow obligations (empty statement/hypothesis for v5.0 contract.json steps; CB-1658 passes the hollow file) — fix upstr' + status: planned + priority: medium + assigned_to: null + created: 2026-09-06T14:10:00Z + updated: 2026-09-06T14:10:00Z + spec: null + acceptance_criteria: + - 'see issue #3015 (A + mutation)' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + - pp-066 + notes: null +- id: PMAT-1070 + github_issue: null + item_type: task + title: 'L0-1b: [P0, unbounded] five whys by apr parity SPC to the OP; the fix; revert → 1.5B RED, 7B GREEN; m=1 str (PP-066 #2873, issue #2971)' + status: planned + priority: medium + assigned_to: null + created: 2026-09-06T16:33:26Z + updated: 2026-09-06T16:33:26Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-1071 + github_issue: null + item_type: task + title: 'SPEC-2.0: spec v2.0 (driver v5): the 18-row scope with each cut row naming the claim it protected; the claims (PP-066 #2873, issue #3023)' + status: planned + priority: medium + assigned_to: null + created: 2026-09-06T16:33:26Z + updated: 2026-09-06T16:33:26Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-1072 + github_issue: 3028 + item_type: bug + title: 'GH-3028: main RED — upstream roadmap-valid (PATH pmat 3.39.0) rejected 12 legacy nested subtask + records as duplicate ids; dropped them, in-repo pin-independent id-uniqueness guard through the parsed + tree (scripts/check_roadmap_ids_unique.sh), G-6 treats a parent''s subtasks list as lifecycle (PR #3030)' + status: completed + priority: high + assigned_to: null + created: 2026-09-06T18:05:00Z + updated: 2026-09-07T07:55:00Z + spec: null + acceptance_criteria: + - 'bash scripts/check_roadmap_ids_unique.sh --self-test && bash scripts/check_roadmap_ids_unique.sh' + - 'pmat 3.39.0 and the 3.37.0 pin both print Validation passed on docs/roadmaps/roadmap.yaml' + - 'mutation: main push run 34049248452 (RED, roadmap-valid) vs PR #3030 run (GREEN, same step)' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + - pp-066 + notes: 'see #3028; fleet pin drift paiml/infra#468; the identical dedup also rides #3027 (BSE-001 H4). Merged as #3030 on 2026-09-07 (main e4b423790, push run green). proof:PR#3030' +- id: PMAT-1073 + github_issue: 3002 + item_type: task + title: 'GH-3002: R-0b backend resolution reads the registry (split of R-0 per the design quorum 2026-09-06)' + status: planned + priority: medium + assigned_to: null + created: 2026-09-06T04:40:00Z + updated: 2026-09-06T04:40:00Z + spec: null + acceptance_criteria: + - 'see #3002 (A + mutation)' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + - pp-066 + notes: null +- id: PMAT-1074 + github_issue: null + item_type: task + title: 'guard_tree.sh cargo classifier is textual: 25 of 170 guards flip when comments and quoted strings are ignored (measured 2026-09-07); replace with an execution oracle or a declared universe' + status: planned + priority: medium + assigned_to: null + created: 2026-09-07T08:44:10Z + updated: 2026-09-07T08:44:10Z + spec: null + acceptance_criteria: + - 'guard_tree.sh --no-cargo decides by a bare ''cargo '' token in the guard''s own text (BSE-01/BSE-02 design). Measured on bse-m2-pr-a: 25 guards carry the token only in comments or printf strings (check_apr_bin_pinned, check_beats_gated, check_tool_versions, both ratchets, ...), so the cargo-free universe — the one predict_merge.sh runs — omitted tree-property guards, and #3037 was predicted PASS on a tree the fleet lint ratchet rejected. Some of the 25 reach cargo through sourced helpers (apr_bin.sh), so stripping strings alone has false negatives. Oracle candidates: run each guard with cargo hidden from PATH (execution), or a declared universe checked against CI wiring. Two ratchets were fixed by rewording their messages in the same PR.' + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-1077 + github_issue: null + item_type: task + title: 'BSE-17 two-tier tests: quick on pull_request (touched crates + reverse dependents + derived tree-reader targets), full on push-to-main/merge_group/nightly/pre-release; tree-identity reuse on the queue ref' + status: planned + priority: medium + assigned_to: null + created: 2026-09-07T15:00:58Z + updated: 2026-09-07T15:00:58Z + spec: null + acceptance_criteria: + - 'Ruling 2026-09-07 (Noah): ''quick test for aprender PR, then full test pre-release — implement ASAP''. Measured 2026-09-07: 22 workspace-test jobs in 33 CI runs, 8 green at 95 min avg, 6 cancelled by a newer push, 4 merge-queue rebuilds of a tree byte-identical to the PR head; both PR-B workspace-test reds came from tree-reader tests (contracts baseline reader, readme_contract.rs) that a crate selection alone would have skipped. Quick tier = gate_touched_crates.sh selection (cap -> full) + every test target that reads the tree, DERIVED by scripts/check_tree_reader_tests.sh from the test sources (include_str!, fs::read*, Path::new, project_root/workspace_root, CARGO_MANIFEST_DIR) into scripts/tree_reader_tests.txt and diffed on every run. Full tier unchanged on push to main, merge_group, workflow_dispatch, nightly, pre-release. Queue ref: when HEAD^{tree} equals the PR head''s tree and that head''s workspace-test check-run succeeded, the job cites it and skips the suite; any doubt runs it.' + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-1078 + github_issue: 3046 + item_type: task + title: 'pr-review-receipt is DELETED: 326.8 h of PR runner-time (floor, measured) for a job nothing needs, reads or requires' + status: inprogress + priority: medium + assigned_to: null + created: 2026-09-08T07:28:32Z + updated: 2026-09-08T11:20:00Z + spec: null + acceptance_criteria: + - 'RESCOPED 2026-09-08 by operator ruling, after a 3/3 FAIL quorum on the dispatch-only attempt: the job is DELETED outright, not moved to workflow_dispatch. The dispatch-only diff gave PR_HEAD_SHA a `|| github.sha` fallback and left PR_NUMBER bound to the pull_request context, which is empty on a dispatch, while check_pr_review_arm4.sh:372 refuses on empty - the job would have been reachable and non-functional, which is worse than absent.' + - 'DONE-IF the deletion is gated on a recorded query: no `needs:` names the job (grep over .github/workflows -> no match); it uploads no artifact and the only download-artifact in the tree is nightly.yml:141 for its own build assets; it is not a required context (branch protection -> ["ci / gate", "workspace-test"]).' + - 'check_pr_review_wiring.sh INVERTS rather than dying with its subject: R4 (the if: polarity table) and its evaluator are deleted with the job; R1 becomes the standing falsifier - no ci.yml job may invoke the receipt guard, with the old `if: github.event_name == ''pull_request''` wiring carried VERBATIM in the case table and asserted FAIL, and a dispatch-only job refused too; R3 is new - the guard must stay a tracked scripts/check_*.sh or R1 holds vacuously. bash scripts/check_pr_review_wiring.sh --self-test -> 10/10, both polarities on every rule.' + - 'scripts/ci_job_minutes.sh makes the figure re-derivable: per-JOB (completed_at - started_at) from the jobs API, started_at not created_at so queue wait is excluded, skipped jobs contribute nothing, and a run count equal to --limit is exit 2 TRUNCATED rather than a silent floor. bash scripts/ci_job_minutes.sh --self-test -> 6/6. Measured 2026-08-08..2026-09-07 on pull_request: pr-review-receipt 326.8 h of a 850.6 h total (a floor; the 96 h this ticket opened with understated it by 3.4x).' + - 'STATED LOSS: the two mutation sweeps (scripts/mutate-guard.sh, scripts/mutate_quorum_arm.sh) and the 43-row bats fixture table no longer run in CI - no other workflow invokes them and they are not check_*.sh, so guard_tree.sh does not reach them. check_pr_review_receipt.sh, check_pr_review_counts.sh and check_pr_review_arm4.sh DO still run, through guard_tree.sh''s derived universe; the PR''s own receipt is judged from the base by pr-review-quorum.yml.' + - 'roadmap.yaml carries ONE addition (this entry) and no other change: check_roadmap_diff_additive.sh -> added=1 lifecycle=0 reserialised=0 deleted=0.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + - pp-066 + notes: 'BSE-15, BSE-001 §4 wave 5. Rescoped from dispatch-only to deletion; the ticket text is the standard the quorum judges the diff against, so it moved with the policy rather than leaving the diff contradicting it.' + +- id: PMAT-1079 + github_issue: 3045 + item_type: task + title: 'KEY: keys/apr-release-minisign.pub on main — the one public key the R-5 release-assets manifest job signs against and the R-6 installer pins; until present the manifest job and the C13 gate refuse and R-5 stays blocked_by KEY (PP-066 #2873, R-5 delta 2026-09-08)' + status: planned + priority: high + assigned_to: null + created: 2026-09-08T07:08:00Z + updated: 2026-09-08T07:08:00Z + spec: null + acceptance_criteria: + - 'see issue #3045 (A + mutation)' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + - pp-066 + notes: 'minted by hand (pmat#1169); DAG row KEY, owner noahgift, expiry 2026-10-02. PMAT-1078 was not free: agent/R-5 contracts/apr-publish-cascade-v1.yaml:4 stamps it for the cascade (unminted in any roadmap), so KEY took the next id.' +- id: PMAT-1080 + github_issue: 3022 + item_type: task + title: 'F-1: the model you named is the model that answers — apr chat silently loaded its built-in Demo model for a sharded SafeTensors index (exit 0, zero tokens, the real path in the banner); resolve_chat_format is ONE decision (suffix before extension, then magic bytes, then a refusal from error.rs), Demo is not an outcome for a path that exists, and .safetensors.index.json reaches the transformer through the same three calls apr run makes (PP-066 #2873, #3022, #3024)' + status: planned + priority: high + assigned_to: null + created: 2026-09-08T12:00:00Z + updated: 2026-09-08T12:00:00Z + spec: null + acceptance_criteria: + - 'see issue #3022 and DAG row F-1 (A + mutations); PR #3050; receipt docs/audits/impl-PMAT-1080-receipt.md' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + - pp-066 + notes: 'minted by hand (pmat#1169); DAG row F-1, owner perf-gate, expiry 2026-09-19. Closes #3024 asks 1, 2 and 4; ask 3 is PMAT-1081.' +- id: PMAT-1081 + github_issue: 3024 + item_type: task + title: 'F-2: the live format x command matrix runs nightly against real models, and the two axes still uncovered are named rather than dropped — an apr serve column and a sharded-GGUF row (merge_gguf_shards) (PP-066 #2873, #3024 ask 3)' + status: planned + priority: medium + assigned_to: null + created: 2026-09-08T12:00:00Z + updated: 2026-09-08T12:00:00Z + spec: null + acceptance_criteria: + - 'see issue #3024 and DAG row F-2 (A + mutation); F-1 ships the runner and its case tables, so this row is a wiring change and nothing else' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + - pp-066 + notes: 'minted by hand (pmat#1169); DAG row F-2, owner bse, expiry 2026-09-26.' +- id: PMAT-1082 + github_issue: 2971 + item_type: task + title: 'L0-1b [P0, unbounded]: five whys by apr parity SPC to the OP — a crushed Q8_K activation block (max/second >= 8, one element setting the scale of 255 others) routes that matmul to the f32-activation kernel; the CPU reference was the inaccurate side, not the GPU; revert -> 1.5B RED / 7B GREEN; m=1 stream byte-identical on every other manifest model (PP-066 #2873, #2971)' + status: planned + priority: high + assigned_to: null + created: 2026-09-08T12:30:00Z + updated: 2026-09-08T12:30:00Z + spec: null + acceptance_criteria: + - 'see issue #2971 and DAG row L0-1b (A + mutations); PR #3032; arms table docs/audits/l0-1b-arms.md; receipt docs/audits/impl-PMAT-1070-receipt.md' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + - pp-066 + notes: 'minted by hand (pmat#1169); DAG row L0-1b, owner perf-gate, expiry 2026-09-26. The gx10 twin was measured 2026-09-08: 1.5B 0.950611 -> 0.999583, 7B 0.998465 -> 0.999782, first_divergence none on both.' +- id: PMAT-1083 + github_issue: 3023 + item_type: task + title: 'SPEC-2.0: PP-066 spec v2.0 — the 18-row 0.66 scope with each cut row naming the claim it protected, the claims ratchet, and scripts/release_criteria.sh (C0 C4 C5 C6 C7 C8 C9 C11 C13 C14, one exit-coded command each)' + status: planned + priority: high + assigned_to: null + created: 2026-09-08T12:30:00Z + updated: 2026-09-08T12:30:00Z + spec: null + acceptance_criteria: + - 'see issue #3023 and DAG row SPEC-2.0 (A + mutations); PR #3025' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:docs + - pp-066 + notes: 'minted by hand (pmat#1169); DAG row SPEC-2.0, owner spec-owner, expiry 2026-09-19.' +- id: PMAT-1090 + github_issue: 3047 + item_type: task + title: 'B4: scripts/roadmap_trim.py had ZERO callers, and .githooks/pre-commit exits 2 on its own line 4 under dash' + status: inprogress + priority: high + assigned_to: null + created: 2026-09-08T12:08:28Z + updated: 2026-09-08T12:08:28Z + spec: null + acceptance_criteria: + - 'D1: pmat work add / work complete re-serialise all of docs/roadmaps/roadmap.yaml on every call. check_roadmap_diff_additive.sh detects it and names scripts/roadmap_trim.py as the remedy - and that remedy had ZERO call sites. Every git grep -n roadmap_trim origin/main hit was prose: a contract remedy: field, an implementation receipt, the guard''s own RED footer, and its own docstring. No hook, no Makefile target, no workflow. So the only detector ran in guard-tree, ~11 minutes after push, and the only actuator was a human reading a footer. Measured live on PR #3026/#3025: VIOLATION reserialised id=PMAT-1077, reserialised=1, base=818 head=824 added=6 lifecycle=36 - one entry, and it turned the required gate red.' + - 'D2: .githooks/pre-commit was #!/bin/sh with set -euo pipefail. pipefail is not POSIX and /bin/sh is dash on this fleet, so following the install line printed in the hook''s OWN header (git config core.hooksPath .githooks) refused EVERY commit before cargo fmt ran: "4: set: Illegal option -o pipefail", exit 2. An unpassable gate trains --no-verify and is why core.hooksPath on this box points at a hand-installed chain instead. D2 is a PREREQUISITE for D1''s fix, not scope creep: a roadmap check added to a hook that dies on line 4 is unreachable, which is the same defect one layer up.' + - 'FIX: 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 :, so it is the IDENTICAL rule set CI applies 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, because resolve_base''s push-shape branch exists to stop a COMMIT being judged against itself, 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. Case table 18 -> 22 rows, hermetic (scratch repos set core.hooksPath=/dev/null so the table judges the guard, not the developer''s hook install). Row 22 asserts the PASS AND the printed base sha, so it cannot pass for the wrong reason. Mutations: base <- resolve_base caught by row 22 (rc 0->1); run_check || true caught by row 20 (rc 1->0). Verified on the thing it fixes: guard-tree and guard-cargo and workspace-test all green on PR #3048.' + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: 'BSE-001 B4. PR #3048. Id reserved at 1090 rather than minted: pmat work add allocates from the roadmap it can see and would have collided with concurrent PP-066 minting (max across origin/main and the open pp-066 heads was 1079), and it re-serialises the whole file - the very defect this ticket fixes. Gap 1080-1089 is deliberate headroom. NOT delivered here: scripts/session_docs_commit.sh, the other half of B4''s DONE-IF, which belongs to G-11b (#3018, inst:A).' +- id: PMAT-1092 + github_issue: null + item_type: task + title: 'release-process-aprender.md v0.1 review: grill the draft against the measured fleet, close the Appendix A S0 ledger, and land what the review admits' + status: planned + priority: high + assigned_to: null + created: 2026-09-08T00:00:00Z + updated: 2026-09-08T00:00:00Z + spec: docs/specifications/release-process-aprender.md + acceptance_criteria: + - 'The draft names 21 scripts/workflows/contracts/keys/manifests as the release process of record. Measured on origin/main c04eda87d and re-audited in full by the AD-04 quorum: 1 exists (scripts/check_readme_claims.sh), 1 is correctly marked new (contracts/apr-dogfood-models-v1.yaml), and 19 of the 20 non-new paths are ABSENT under any path (find over the tree, not just the named location). An earlier revision of this criterion said 12 paths and 11 absent, taken from a partial first sweep before workflows, contracts, install.sh, the signing key and the model manifest were counted; a criterion satisfiable by fixing 11 would have silently dropped 8. The review must state which sections are executable today and which describe artifacts that do not exist.' + - 'Appendix A S0 rows are measured on the physical hosts (ssh, nvidia-smi, uname) and written back into the spec, closing every [U] in section 2 and RD-9. A row transcribed rather than measured is RED.' + - 'Every finding carries the command that produced it; a finding with no command is [U] with a named owner.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-1093 + github_issue: null + item_type: task + title: 'kind labels are DERIVED from the DAG row, never typed: paiml-implement''s kind-gate refused 84 of 105 PP-066 tickets (Phase 0, AUTO-IMPL-SKILL-001 T-1); scripts/check_kind_labels_derived.sh derives and refuses drift both ways, reports the undecidable rather than guessing' + status: completed + priority: medium + assigned_to: null + created: 2026-09-08T14:00:00Z + updated: 2026-09-08T14:00:00Z + spec: null + acceptance_criteria: + - 'bash scripts/check_kind_labels_derived.sh --self-test exits 0 (7 rows, both polarities); bash scripts/check_kind_labels_derived.sh exits 0 with derived=103 missing=0 wrong=0' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + - pp-066 + notes: 'minted by hand (pmat#1169, and now pmat#1240 — parallel agents mint the same id and the merge deletes one). proof:scripts/check_kind_labels_derived.sh' +- id: PMAT-1094 + github_issue: 3055 + item_type: task + title: 'apr *-lint --json emits an outcome in THREE shapes, one of them a Rust Debug string ("Ok { code: 134 }"): pick the structured object and emit it everywhere, so a consumer can write one parser' + status: planned + priority: medium + assigned_to: null + created: 2026-09-08T14:00:00Z + updated: 2026-09-08T14:00:00Z + spec: null + acceptance_criteria: + - 'cargo test -p apr-cli --tests -E "test(json_output_contains_outcomes)" passes with assert_outcome_ok''s two STRING arms deleted — their deletion is the falsifier that the migration is complete' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + - pp-066 + notes: 'minted by hand (pmat#1169). Found sweeping #3051: prometheus-lint emits two of the three shapes in ONE response (text_format an object, required_metrics the string "Ok"); nccl-diag-lint exit_code is "Ok { code: 134 }", a Debug string in a JSON API. Lane 0.67.' +- id: PMAT-1095 + github_issue: 3067 + item_type: task + title: '0.67 CUDA Rust fleet readiness: fix the two wrong-host GPU tests (adversarial.rs:36 hard-codes RTX 4090, cublas_tests.rs:174 asserts >50 TFLOP/s wall-clock) and add scripts/cuda_rust_fleet_check.sh emitting a per-host receipt for gx10 / yoga / lambda-vector' + status: planned + priority: high + assigned_to: null + created: 2026-09-09T15:00:00Z + updated: 2026-09-09T15:00:00Z + spec: docs/specifications/nvidia-cuda-rust-library-integration.md + acceptance_criteria: + - 'cargo test -p aprender-gpu --features cuda --lib test_alloc_oversize_100gb passes on gx10 (GB10, unified memory) AND on an RTX 4090 host: the test asserts the DEVICE-REPORTED total, not a hard-coded 24 GB card' + - 'cargo test -p aprender-gpu --features cuda --lib test_cublas_gemm_f16_training_shape has NO wall-clock TFLOP/s assertion; it asserts numerical parity vs a CPU reference and REPORTS throughput' + - 'bash scripts/cuda_rust_fleet_check.sh --self-test exits 0, and its case table shows a seeded failing probe turns the receipt verdict to FAIL' + - 'bash scripts/cuda_rust_fleet_check.sh --host gx10 writes evidence/cuda-rust-fleet/gx10.json with verdict PASS: cuda-core probe, launch_budget + determinism tests under --features cuda, cutile probe (CUDA >= 13.1)' + - 'bash scripts/cuda_rust_fleet_check.sh --host yoga writes evidence/cuda-rust-fleet/yoga.json with verdict PASS' + - 'evidence/cuda-rust-fleet/noah-Lambda-Vector.json is PASS, OR is INCOMPLETE with driver_floor as the ONLY skipped prerequisite and blocked_on naming the reboot that activates the staged 580 driver — an INCOMPLETE that names its blocker is the truthful artifact; a PASS reached by skipping it is not' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + - orch:fable + - cuda-check + notes: 'minted by hand (pmat#1169). orch-basis:release — this is the 0.67 crates.io readiness lane for NVIDIA CUDA Rust (cuda-core / cutile / cuda-oxide) across the three GPU hosts, per EPIC #3062 and docs/specifications/nvidia-cuda-rust-library-integration.md. Both wrong-host tests were found by the post-upgrade regression run on gx10 (2568 passed / 2 failed) and shown NOT to be caused by CUDA 13.3 via a 13.0 control. The fleet runner is the falsifiable form of "0.67 works flawlessly on gx10, yoga, lambda-vector".' + +- id: PMAT-1096 + github_issue: null + item_type: task + title: '0.66.0 release cut: milestone 0.66.0 drained (#3022 F-1 via #3050, #2971 L0-1 via #3026/#3032, #3063 T0), version bump, tag v0.66.0, GitHub release, crates.io cascade, post-publish QA' + status: planned + priority: critical + assigned_to: null + created: 2026-09-09T16:43:42Z + updated: 2026-09-09T16:43:42Z + spec: null + acceptance_criteria: + - 'orch-basis:release. Scope = the operator-curated 0.66.0 milestone as of 2026-09-09 (PP-066 rows R-0..R-8/C0/G/KEY moved to 0.68.0 by the operator 2026-09-09T12:06Z). Phases: P1 drain #3050 and #3063 through the fleet; P2 close #2971 with citation after a ledger quorum; P3 bump with scripts/bump-version.sh 0.66.0 + release notes + dogfood --phase pre-publish receipt; P4 merge bump, tag, gh release create; P5 cascade-drain to crates.io behind check_publish_preflight.sh; P6 post-publish QA + receipt.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + - orch:fable + - pp-066 + - release + - 0.66.0 + notes: 'orch-basis:release — the 0.66.0 cut is a release-state ticket (AUTO-IMPL-SKILL-003 §2.1 basis=release); push, tag, gh release and the crates.io cascade are orchestration phases (route=self).' +- id: PMAT-1097 + github_issue: null + item_type: task + title: '06x release schedule spec: 0.67.0/0.68.0/0.69.0/0.70.0 at a 2-3 day 24/7 cadence, one GitHub epic per release, priorities A-G (four binaries per tag, NVIDIA CUDA Rust default, gx10 never idle, yoga CUDA tests, 20-minute PR gate, Qwen2.5-Coder-7B parity, declarative fine-tune) + release-schedule contract + docs drift gate' + status: planned + priority: high + assigned_to: null + created: 2026-09-10T09:12:19Z + updated: 2026-09-10T09:12:19Z + spec: docs/specifications/06x-release-schedule.md + acceptance_criteria: + - 'orch-basis:release — a release-schedule spec is a release-state ticket (AUTO-IMPL-SKILL-003 §2.1 basis=release). Operator 2026-09-10 verbatim: ''override "kind:docs" block if needed'' — kind:code because the ticket ships contracts/release-schedule-06x-v1.yaml (pv-validated) and extends FALSIFY-DOCS-CLAUDE-001 to the spec (mutation-verified), alongside the spec and four epics.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + - orch:fable + - release + - 06x-schedule + notes: 'orch-basis:release — a release-schedule spec is a release-state ticket (AUTO-IMPL-SKILL-003 §2.1 basis=release); the spec, its contract, the drift-gate extension and the four epics are one PR; epic creation, push and PR are orchestration phases (route=self).' +- id: PMAT-1098 + github_issue: null + item_type: task + title: '0.67.0 release train (epic #3078, spec docs/specifications/06x-release-schedule.md §3): P0-1 67-A1 four apr assets + verify-apr-assets + check_release_assets.sh, P0-2 67-C2 self-hosted preflight + fleet toolset, P0-3 67-E1/E2 one build graph for tree-reader targets + queue mirrors the PR, 67-E3 guards under 20 min, 67-D0 yoga group restriction + smoke, 67-C1/D1 gpu-quick + cuda-unit, 67-B1 #3061/#3068/#3066 merged + cuda suites green, 67-E0 nightly FULL green, 67-R bump/tag/release/cascade by 2026-09-12T18:00Z' + status: planned + priority: critical + assigned_to: null + created: 2026-09-10T10:27:17Z + updated: 2026-09-10T10:27:17Z + spec: null + acceptance_criteria: + - 'orch-basis:release. Rows and acceptance commands are the spec''s §2/§3 (PR #3087); C3/D2/F1/F2 slip first per §1.2.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + - orch:fable + - release + - 0.67.0 + - epic-3078 + notes: 'orch-basis:release — the 0.67.0 train (epic #3078) is a release-state ticket; orchestration phases (push, PR, tag, cascade) route=self' +- id: PMAT-1099 + github_issue: null + item_type: task + title: 'PVL-1: pv lint/proof-status refuse zero contracts' + status: inprogress + priority: high + assigned_to: null + created: 2026-09-10T11:52:02Z + updated: 2026-09-10T11:55:16.365550162+00:00 + spec: null + acceptance_criteria: + - 'PVL-001 EV-1 (spec: infra docs/specifications/PVL-001-pv-lean-gate.md). RED: integration test spawning $PV lint on a nonexistent path and on an empty dir, asserting exit!=0; same for proof-status on an empty dir. Change: 0 contracts -> exit 2 with ''decline: 0 contracts under ''; applies to lint, proof-status, coverage, graph, and also to lean-status, verify-pipeline and validate — every subcommand that walks a corpus, because a guard that covers four of seven leaves three ways to be told PASS over nothing. Mutation: revert the guard -> test RED. done_when: cd ~/src/aprender && . scripts/pv_bin.sh && "$PV" lint /nonexistent-pvl-path; test $? -ne 0' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + - orch:fable + - pvl-001 + notes: 'orch-basis:M>=3 - footprint measured by pmat query (contract_walk callers) and read at HEAD: crates/aprender-contracts-cli/src/{contract_walk.rs,lib.rs,commands/lint.rs,commands/coverage.rs,commands/graph.rs,commands/proof_status.rs} = 6 modules. Spec: paiml/infra docs/specifications/PVL-001-pv-lean-gate.md row EV-1. This session is the aprender driver instance for PVL rows (PVL-001 section 0).' + +- id: PMAT-1100 + github_issue: null + item_type: task + title: 'Triage: file every open issue and PR without a milestone into a release train, link duplicates, Alfredo first' + status: planned + priority: medium + assigned_to: null + created: 2026-09-10T14:03:43Z + updated: 2026-09-10T14:03:43Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:triage + - orch:fable + notes: null +- id: PMAT-1101 + github_issue: null + item_type: task + title: Q5_K dequant + fused dot read a non-ggml bit layout — every Q5_K tensor on the CPU path (realizar) and in apr import (aprender-quant) is wrong + status: planned + priority: critical + assigned_to: null + created: 2026-09-11T03:40:49Z + updated: 2026-09-11T03:40:49Z + spec: null + acceptance_criteria: + - 'Measured on Qwen3.5-0.8B-Q4_K_M blk.0.attn_qkv (Q5_K, 6144x1024): realizar dequantize_q5_k mismatches gguf-py on 5,959,751/6,291,456 values; matvec sum +26.64 vs llama.cpp -17.06. A literal transcription of ggml dequantize_row_q5_K is bit-exact vs gguf-py. Blocks #3091 CPU parity.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + - 0.67.0 + notes: null +- id: PMAT-1102 + github_issue: null + item_type: task + title: 'gx10 cannot run ci / lint: 14 aarch64-only clippy errors in aprender-compute + present-terminal, and #2567''s aarch64 parallel Q4_K path was never called' + status: planned + priority: high + assigned_to: null + created: 2026-09-11T04:06:14Z + updated: 2026-09-11T04:06:14Z + spec: null + acceptance_criteria: + - 'gx10-pool1 canary: ci / lint failed on #3089 (job 103137079500). x86 lint is clean; aarch64 has unreachable tails after unconditional NEON returns, x86-only helpers compiled dead on arm, and matmul_q4k_f32_parallel (non-x86, #2567) whose only caller is inside the x86_64 block.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + - 0.67.0 + notes: null +- id: PMAT-1104 + github_issue: null + item_type: task + title: CUDA Q5_K GEMV reads the fifth bit from a sequential bitmask instead of ggml's qh[l] bit s (#3111) + status: planned + priority: critical + assigned_to: null + created: 2026-09-11T04:56:39Z + updated: 2026-09-11T04:56:39Z + spec: null + acceptance_criteria: + - 'Q5KGemvKernel: qh byte val_idx/8, bit val_idx%8; ggml: byte val_idx%32, bit val_idx/32. Golden GPU test from the FALSIFY-QDOT-009 fixture; Q5KKernel (gemm) is unreachable from inference and tracked separately in #3111.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + - 0.67.0 + notes: null +- id: PMAT-1105 + github_issue: null + item_type: task + title: 'CI target dirs leak: per-run targets/aprender-ci//run- and queue-ref dirs are never removed — 629 GB filled yoga (ENOSPC evicted #3089), 374 GB on intel; add a sweeper + the end-of-job GC' + status: planned + priority: medium + assigned_to: null + created: 2026-09-11T06:31:20Z + updated: 2026-09-11T06:31:20Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + - orch:fable + - ci + notes: null +- id: PMAT-1106 + github_issue: null + item_type: task + title: 'coverage nightly RED 6 days: GPU-conditional tests panic without an adapter (compute backward.rs x9, cgp x2) — skip, never expect' + status: planned + priority: medium + assigned_to: null + created: 2026-09-11T09:00:10Z + updated: 2026-09-11T09:00:10Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + - orch:fable + - ci + notes: null +- id: PMAT-3076 + github_issue: 3076 + item_type: task + title: 'F16/BF16 GGUF CPU matmul has no SIMD path — unquantized models appear to hang' + status: planned + priority: high + assigned_to: null + created: 2026-09-21T07:52:58Z + updated: 2026-09-21T07:52:58Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'ACCEPTANCE (hand-entered; #3076 has no done_when section, so this quotes its last plan comment verbatim, minted on the PR branch so the AD-04 quorum can run). "(1) the GGUF CPU path gets a SIMD f16/bf16 matvec (dequant-to-f32 tiles through the existing fused dispatcher) with a greedy-parity gate against llama.cpp on an unquantized ≤1B GGUF, so an F16/BF16 model decodes at a measured tok/s instead of appearing to hang; (2) until that lands the loader prints a one-line notice that the F16/BF16 path is scalar and slow rather than silently crawling." Since (1) lands here, (2) is moot. DEVIATION from the issue body: it suggests an integration test "with a wall-clock assertion"; the project bans wall-clock assertions in required checks, so the regression guard is behavioural (kernel parity against an f64 reference at lengths hitting every loop and tail, and float16_matmul against a transcription of the pre-fix loop including a truncated buffer), and tok/s is measured and reported rather than asserted. Not in scope: prefill running one position at a time at decode rate (#2787 / #2801). EVIDENCE (added after the round-1 quorum found the llama.cpp gate missing): scripts/float16_greedy_parity.sh is the greedy-parity gate against the pinned llama.cpp (llama_pin.toml build_commit), on template-free copies of an unquantized ≤1B F16 and BF16 GGUF, because apr double-templates instruct prompts (#3672); --baseline separates divergences this change introduces from ones that predate it. Receipts, the negative control (a deliberately broken binary FAILs 12/12) and the measured before/after decode tok/s with model sha256, host and binaries are in evidence/pmat-3076-f16-bf16-matvec/. WIRING (cop ruling, no workflow edit): the model-backed run is declared in Cargo.toml [package.metadata.dogfood] and runs bare (release mode: the committed receipts are the baseline and pin each model sha256; a model absent from the host is a FAIL) in scripts/dogfood.sh --phase pre-publish; the comparison helpers live in scripts/float16_parity_lib.sh and their case table runs on every PR as scripts/check_float16_greedy_parity.sh through guard_tree.sh.' +- id: PMAT-3118 + github_issue: 3118 + item_type: task + title: 'roadmap.yaml 3-way merge by ticket id: merge driver + steward resolve-dirty so a queue squash never makes stacked PRs DIRTY' + status: planned + priority: medium + assigned_to: null + created: 2026-09-11T11:34:41Z + updated: 2026-09-11T11:34:41Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-3119 + github_issue: 3119 + item_type: task + title: '80/20 test tier as a nextest filterset: ci_test_tier.sh --tier-of-record for PR runs; full suite on merge_group/nightly/pre-release' + status: planned + priority: medium + assigned_to: null + created: 2026-09-11T11:34:55Z + updated: 2026-09-11T11:34:55Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-3120 + github_issue: 3120 + item_type: task + title: 'tree-reader registry at MODULE granularity: 18 whole --lib crates = 88% of all test-seconds in every PR quick tier (E1 costs 93% of full)' + status: planned + priority: medium + assigned_to: null + created: 2026-09-11T12:32:19Z + updated: 2026-09-11T12:32:19Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-3121 + github_issue: 3121 + item_type: task + title: 'pre-release dogfood: every workspace example builds AND runs, apr-cookbook updated, release notes written — three rows on every tagged release (operator 2026-09-11)' + status: planned + priority: medium + assigned_to: null + created: 2026-09-11T12:32:25Z + updated: 2026-09-11T12:32:25Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-3124 + github_issue: 3124 + item_type: task + title: 'Triage pass: label the 72 open issues that carry no label' + status: planned + priority: medium + assigned_to: null + created: 2026-09-11T15:07:05Z + updated: 2026-09-11T15:07:05Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:triage + notes: null +- id: PMAT-3138 + github_issue: 3138 + item_type: task + title: 'workspace-test on ARM64: route arch-neutral after the four aarch64-only reds; scope the tree-reader step to its packages' + status: planned + priority: high + assigned_to: null + created: 2026-09-12T08:54:56Z + updated: 2026-09-12T08:54:56Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - ci + - fleet + - gx10 + notes: null + +- id: PMAT-3146 + github_issue: 3146 + item_type: task + title: 'EPIC: Pareto gap-closure vs linfa 0.8.1 and Burn 0.21.0 — 4 substrates, 4 breadth, 5 completions' + status: planned + priority: critical + assigned_to: null + created: 2026-09-12T11:44:58Z + updated: 2026-09-12T11:44:58Z + spec: null + acceptance_criteria: + - 13 children in 3 tiers across 0.68.0/0.69.0/0.70.0. Gap set derived 2026-09-12 by enumerating both sides. P0 = substrates (SVD, PCA-on-SVD, neighbor index, rank-typed tensor); P1 = breadth (autodiff conv ops, ONNX import, AdaBoost/Bagging, FTRL/SGD); P2 = completions gated on the P0s. CUT list recorded on the issue. + phases: [] + subtasks: [] + estimated_effort: null + labels: + - epic + - enhancement + notes: null +- id: PMAT-3147 + github_issue: 3147 + item_type: task + title: 'P0: SVD substrate in aprender-compute (Golub-Reinsch + randomized)' + status: planned + priority: critical + assigned_to: null + created: 2026-09-12T11:45:15Z + updated: 2026-09-12T11:45:15Z + spec: null + acceptance_criteria: + - 'No SVD exists repo-wide (only SymmetricEigen, crates/aprender-compute/src/eigen/mod.rs:72). Lands thin SVD + randomized (Halko) + deterministic sign convention. FALSIFIABLE: reconstruction ||A-USV^T||_F/||A||_F <= 1e-10 over 200 random f64 matrices spanning mn, rank-deficient, cond>=1e8; U/V orthonormality proptest <= 1e-10; singular values match scipy.linalg.svd within 1e-9 relative on pinned fixtures; randomized path with p=10,q=2 recovers top-k within 1%; reverting the bidiagonalization step must turn the reconstruction test RED. Unlocks #3148 #3156 #3158. Milestone 0.68.0.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - P0 + - enhancement + - pareto-linfa-burn + notes: null +- id: PMAT-3148 + github_issue: 3148 + item_type: task + title: 'P0: rewire PCA onto SVD + add TruncatedSVD' + status: planned + priority: critical + assigned_to: null + created: 2026-09-12T11:45:15Z + updated: 2026-09-12T11:45:15Z + spec: null + acceptance_criteria: + - 'preprocessing/pca.rs:334 forms the covariance matrix then eigendecomposes — squares the condition number and is O(d^3) in FEATURES. docs/BEATS.md records the only measured sklearn loss: PCA fit_transform 18.6x slower. FALSIFIABLE: a guard asserts no d-x-d covariance is constructed in pca.rs; on singular values spanning 1e0..1e-9 the new path matches SVD-exact within 1e-7 where the covariance path is asserted to FAIL the same tolerance; explained_variance_ratio_ sums to 1.0 within 1e-12; sklearn component parity within 1e-8 up to sign; beat-sklearn-pca-speed-v1.yaml lands with the RE-MEASURED ratio and BEATS.md''s loss row is retired by measurement, not deletion — a still-losing number closes this honestly. Depends on #3147. Milestone 0.68.0.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - P0 + - enhancement + - pareto-linfa-burn + notes: null +- id: PMAT-3149 + github_issue: 3149 + item_type: task + title: 'P0: spatial neighbor index substrate (kd-tree + ball-tree + brute)' + status: planned + priority: critical + assigned_to: null + created: 2026-09-12T11:45:15Z + updated: 2026-09-12T11:45:15Z + spec: null + acceptance_criteria: + - 'KdTree/BallTree absent repo-wide; KNearestNeighbors is a linear scan. ASYMPTOTIC gap, not constant-factor. Six consumers pay O(n) today: KNN (classification/mod.rs), DBSCAN (cluster/dbscan.rs), LOF (cluster/lof.rs), TSNE (preprocessing/tsne.rs), SpectralClustering (cluster/spectral.rs), OPTICS (#3155). FALSIFIABLE: proptest over n in 10..2000, d in 1..30 asserts kd-tree and ball-tree return the IDENTICAL k-nearest set as brute force including tie handling; node-visit counts (not wall-clock) grow sub-linearly across n=1e3/1e4/1e5; DBSCAN/LOF/KNN produce identical labels before and after the rewire; perturbing the splitting plane turns the exactness proptest RED. Rewiring the consumers is IN scope — a substrate nobody calls is dead code. Milestone 0.68.0.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - P0 + - enhancement + - pareto-linfa-burn + notes: null +- id: PMAT-3150 + github_issue: 3150 + item_type: task + title: 'P0: const-generic rank-checked tensor — make LAYOUT-001 a compile error' + status: planned + priority: critical + assigned_to: null + created: 2026-09-12T11:45:15Z + updated: 2026-09-12T11:45:15Z + spec: null + acceptance_criteria: + - 'aprender-tensor/src/tensor.rs:10 is shape: Vec — rank is runtime-only. CLAUDE.md records LAYOUT-001 as having occurred 100+ times, defended only by runtime contracts and a hand-maintained FORBIDDEN IMPORTS list. Burn''s Tensor makes rank mismatch a compile error. SCOPE IS NARROW ON PURPOSE: land the type + a RowMajor/ColMajor marker + trybuild proof + migrate exactly ONE hot path; whole-tree migration is the expensive 80% and is explicitly out. FALSIFIABLE: >= 8 trybuild compile-fail cases with committed expected stderr, plus a pass-suite so the type is not merely rejecting everything; zero runtime cost shown on the migrated path; byte-identical output before/after; a deliberate rank error in the migrated path must turn the build RED. Closing this as CUT with the trybuild evidence is a legitimate outcome if ergonomics are bad — record it, do not silently abandon. Milestone 0.68.0.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - P0 + - enhancement + - pareto-linfa-burn + notes: null +- id: PMAT-3151 + github_issue: 3151 + item_type: task + title: 'P1: autodiff op coverage — conv/pool/embedding/gather' + status: planned + priority: high + assigned_to: null + created: 2026-09-12T11:45:15Z + updated: 2026-09-12T11:45:15Z + spec: null + acceptance_criteria: + - 'The 21 autograd fns are all transformer-path (add, matmul, gelu, layer_norm, attention, softmax, ...). conv1d, conv2d, max_pool, avg_pool, gather, scatter are ABSENT; embedding exists only inside wgpu_block.rs, not as a differentiable op. Consequence: aprender cannot train a CNN, or anything that is not a transformer. FALSIFIABLE: finite-difference gradcheck at h=1e-5 on f64 with relative error <= 1e-6 for every new op across stride/padding/dilation/groups combinations; PyTorch autograd parity on pinned fixtures per the existing beat_pytorch_autograd_grad.rs pattern; embedding backward ACCUMULATES correctly for repeated indices (asserts the summed gradient, not merely non-zero); max-tie subgradient convention documented AND tested; an end-to-end CNN trains to an asserted loss floor; CUDA/WGPU paths implement each op or fail loudly naming it — never silent CPU fallback while reporting a GPU device. Milestone 0.69.0.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - P1 + - enhancement + - pareto-linfa-burn + notes: null +- id: PMAT-3152 + github_issue: 3152 + item_type: task + title: 'P1: ONNX import — and resolve the advertised-but-stubbed export' + status: planned + priority: high + assigned_to: null + created: 2026-09-12T11:45:15Z + updated: 2026-09-12T11:45:15Z + spec: null + acceptance_criteria: + - 'apr-cli/src/commands/export.rs:7 marks ONNX export ''(planned)'' while ExportFormat::Onnx is reachable and the error string offers onnx as valid — an advertised surface that does not work, the 0.63.0 dogfood defect class. Import is entirely absent; Burn ships burn-onnx. FALSIFIABLE: unsupported operators FAIL LOUDLY naming the op (fail-closed test — silent partial import is the defect this excludes); per-op numerical parity vs onnxruntime within 1e-5 on pinned fixtures; a real small model imports and matches onnxruntime top-1 on 20 pinned inputs; unsupported opset refused with the version in the message; the supported-op list lives in a contract YAML so it cannot drift from the implementation; apr-cli-commands-v1.yaml and registered_commands updated with FALSIFY-CLI-001/002 green. Export is either implemented or removed from the reachable format list — reachable-and-stubbed is not an option. Milestone 0.69.0.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - P1 + - enhancement + - pareto-linfa-burn + notes: null +- id: PMAT-3153 + github_issue: 3153 + item_type: task + title: 'P1: AdaBoost + generic Bagging/Voting meta-estimators' + status: planned + priority: high + assigned_to: null + created: 2026-09-12T11:45:15Z + updated: 2026-09-12T11:45:15Z + spec: null + acceptance_criteria: + - 'AdaBoost absent repo-wide. aprender''s ensembles (RandomForestClassifier/Regressor, GradientBoostingClassifier) are all concrete and hard-wired — there is no generic meta-estimator over an arbitrary base. THE MISSING PIECE IS THE WRAPPER, not AdaBoost: BaggingClassifier makes all ~55 fittable types ensembleable in one change. FALSIFIABLE: on a fixture where a depth-1 tree scores below 0.70, the 50-estimator AdaBoost must exceed an asserted threshold — a test checking only fit().is_ok() locks the defect in and does not satisfy this; sample weights asserted to CHANGE between rounds with misclassified samples gaining weight; BaggingClassifier instantiated over three different base estimators (tree, KNN, GaussianNB) to prove genericity; OOB score within tolerance of held-out; sklearn AdaBoost accuracy parity within 2 points on iris/wine with pinned seed; soft voting fails at construction for bases lacking predict_proba. Milestone 0.69.0.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - P1 + - enhancement + - pareto-linfa-burn + notes: null +- id: PMAT-3154 + github_issue: 3154 + item_type: task + title: 'P1: FTRL-Proximal + SGDClassifier/SGDRegressor' + status: planned + priority: high + assigned_to: null + created: 2026-09-12T11:45:15Z + updated: 2026-09-12T11:45:15Z + spec: null + acceptance_criteria: + - 'linfa-ftrl exists (Tested/Benchmarked); aprender has no FTRL and no classical SGD linear learner. CHEAP because the seam exists: online/mod.rs:61 already declares partial_fit with two implementors, so this adds learners to an existing trait rather than designing an architecture. Note online/ is otherwise aimed at LLM post-training (DPO, RLVR, distillation) — classical streaming linear models are a different use case the directory name over-promises. FALSIFIABLE: windowed running loss decreases monotonically on a separable stream; SPARSITY IS THE POINT — with lambda1>0 on 10,000 features where only 50 are informative, >= 90% of weights must be EXACTLY zero (a test that skips this tests the wrong thing); two shuffles converge within a documented tolerance; chunked partial_fit comparable to one batch fit; sklearn SGDClassifier parity within 2 points; every loss gradient finite-difference-checked; both compose inside the existing Pipeline. Milestone 0.69.0.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - P1 + - enhancement + - pareto-linfa-burn + notes: null +- id: PMAT-3155 + github_issue: 3155 + item_type: task + title: 'P2: OPTICS clustering' + status: planned + priority: medium + assigned_to: null + created: 2026-09-12T11:45:25Z + updated: 2026-09-12T11:45:25Z + spec: null + acceptance_criteria: + - 'OPTICS absent repo-wide; linfa-clustering ships it. Generalizes DBSCAN: one reachability ordering yields clusterings at EVERY density, fixing DBSCAN''s single real weakness (a global eps cannot find clusters of differing density). FALSIFIABLE: extract_dbscan(eps) must produce labels IDENTICAL to DBSCAN(eps) for >= 5 eps values on 3 fixtures — this is what proves the ordering correct; a varying-density fixture that DBSCAN provably cannot separate at ANY eps (asserted by sweeping eps and showing every result wrong) must be separated by extract_xi, otherwise the ticket has not demonstrated why OPTICS exists; noise gets reachability infinity and label -1; sklearn OPTICS ARI >= 0.95 on pinned fixtures; a test asserts the brute-force path is NOT taken above the auto-select threshold. DEPENDS ON #3149 — started early it grows its own O(n^2) scan. Milestone 0.70.0.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - P2 + - enhancement + - pareto-linfa-burn + notes: null +- id: PMAT-3156 + github_issue: 3156 + item_type: task + title: 'P2: PLSRegression / PLSCanonical' + status: planned + priority: medium + assigned_to: null + created: 2026-09-12T11:45:25Z + updated: 2026-09-12T11:45:25Z + spec: null + acceptance_criteria: + - 'PLS absent repo-wide; linfa-pls ships it. Standard method wherever predictors are many, collinear, and fewer samples than features (chemometrics, spectroscopy, genomics) — its absence is a hard no for that whole audience. PCA cannot substitute: PCA maximizes variance in X, PLS maximizes covariance with y. FALSIFIABLE: THE DIFFERENTIATING TEST is a synthetic dataset whose predictive signal lies in a LOW-variance direction of X — PCA-then-regression asserted BELOW a threshold and PLS above it on the same data; if both pass the fixture is wrong and does not demonstrate PLS. Also: successive components orthogonal within 1e-10; n_components=rank(X) reproduces OLS within 1e-8; duplicated columns fit where naive OLS is asserted to fail; sklearn PLSRegression coefficient parity within 1e-6 up to sign; multi-output y (PLS2) tested with a 3-column y. DEPENDS ON #3147. Milestone 0.70.0.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - P2 + - enhancement + - pareto-linfa-burn + notes: null +- id: PMAT-3157 + github_issue: 3157 + item_type: task + title: 'P2: LARS / LassoLars / lars_path' + status: planned + priority: medium + assigned_to: null + created: 2026-09-12T11:45:25Z + updated: 2026-09-12T11:45:25Z + spec: null + acceptance_criteria: + - 'LARS absent; linfa ships it. The value is the REGULARIZATION PATH, not another sparse regressor: lars_path computes every Lasso solution for all alphas in roughly one OLS fit, where today alpha selection for the existing coordinate-descent Lasso means refitting per candidate (model_selection/alpha.rs suggests that cost is already being paid). Makes an existing feature cheaper rather than only adding surface. FALSIFIABLE: for 20 alphas spanning the path, LassoLars coefficients match the existing coordinate-descent Lasso within 1e-8 — two independent implementations cross-checking each other is the load-bearing test; coefficients asserted piecewise-linear between knots; variables enter the active set in order of decreasing absolute residual correlation, asserted at each knot; THE EFFICIENCY CLAIM IS COUNTED IN FLOPS, NOT TIMED (repo rule: no wall-clock in required checks); LassoLarsIC picks the same alpha as an exhaustive AIC/BIC sweep; sklearn lars_path parity within 1e-8; n= 5 n_components values; Nystroem+LinearSVM within 3 points of SVCRbf where LinearSVM alone is asserted worse by more than that margin; sklearn KernelPCA/Nystroem parity on pinned fixtures; the Kernel trait proven genuinely shared by asserting SVCRbf and KernelPCA produce identical kernel matrix values at the same gamma. DEPENDS ON #3147. Milestone 0.70.0.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - P2 + - enhancement + - pareto-linfa-burn + notes: null +- id: PMAT-3159 + github_issue: 3159 + item_type: task + title: 'P2: Gaussian + Sparse random projection with the JL bound' + status: planned + priority: medium + assigned_to: null + created: 2026-09-12T11:45:25Z + updated: 2026-09-12T11:45:25Z + spec: null + acceptance_criteria: + - 'RandomProjection absent; linfa-reduction ships it. Cheapest item in the epic, and the only reduction method with a DATA-INDEPENDENT guarantee: Johnson-Lindenstrauss preserves all pairwise distances within (1 +/- eps) at O(log n / eps^2) dimensions with no fit pass. Directly useful to work already here — the #3149 neighbour index degrades in high dimension as every kd-tree does, and citl/pattern/mod.rs:25 already carries a ''simplified linear scan for now'' comment. FALSIFIABLE: the JL guarantee is tested AS A GUARANTEE — for 1000 points in 5000 dims projected to johnson_lindenstrauss_min_dim(1000, 0.1), the FRACTION OF PAIRWISE DISTANCES distorted beyond 10% must be below a documented failure probability; checking a mean distortion would not test the lemma. Also: distortion tightens monotonically across >= 3 eps values; sparse variant meets the same bound at asserted density < 1/3; identical seed gives an identical projection matrix; the sparse matrix is never materialized densely, asserted by an allocation-count check (sparse-that-allocates-dense is the defect here); exact integer agreement with sklearn on johnson_lindenstrauss_min_dim; composes with #3149 — project then k-NN, asserting recall against exact search in the ORIGINAL space. Milestone 0.70.0.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - P2 + - enhancement + - pareto-linfa-burn + notes: null + +- id: PMAT-3161 + github_issue: 3161 + item_type: task + title: 'P1: three license states across 79 crates — 14 publishable crates offer Apache-2.0 with no LICENSE-APACHE' + status: planned + priority: high + assigned_to: null + created: 2026-09-12T11:50:05Z + updated: 2026-09-12T11:50:05Z + spec: null + acceptance_criteria: + - 'cargo metadata 2026-09-12: 62 crates MIT, 14 ''MIT OR Apache-2.0'' (all PUBLISHABLE), 3 absent (all publish=false, so hygiene only). Root ships only LICENSE (MIT); there is NO root LICENSE-APACHE — the only Apache text is crates/aprender-zram/LICENSE-APACHE, and that crate is not among the 14. Apache-2.0 §4(a) requires recipients get the License text, so the Apache arm (and its §3 patent grant, the whole reason to offer it) is asserted but unsupported in the published tarball. OPERATOR DECISION NEEDED: MIT-only (fix 14 down) vs dual (fix 62 up + add LICENSE-APACHE). Both linfa 0.8.1 and Burn 0.21.0 are dual; recommendation is dual because it costs one file today and cannot be added later without every contributor''s consent. deny.toml:59 already allows both. FALSIFIABLE: guard asserts exactly one license expression across publishable crates, with its universe from cargo metadata filtered by publish!=false — NOT a hand-list, which free-passes every crate added after it; the 3 exempt BY publish status, not by name; every named license file verified present in ''cargo package --list'' output, not just the working tree (CB-510 lesson); aprender-zram/LICENSE-APACHE reconciled or removed; readme_contract.rs stays green; flipping one crate''s license field must turn the guard RED. Milestone 0.68.0.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - P1 + - bug + - documentation + notes: null + +- id: PMAT-3165 + github_issue: 3165 + item_type: task + title: 'P1: graph intermediate representation (IR) — CRUX-N-14' + status: planned + priority: high + assigned_to: null + created: 2026-09-12T12:16:04Z + updated: 2026-09-12T12:16:04Z + spec: null + acceptance_criteria: + - 'CRUX-N-14, competitor burn, demand 4. burn ships burn-ir; aprender has NO ir/ module in any of 79 crates (verified 2026-09-12). Substrate under ONNX import (#3152), kernel fusion (CUT on the epic largely BECAUSE there is no IR), and multi-backend routing. FALSIFIABLE (contracts/crux-N-14-v1.yaml): lowering an IR graph is BYTE-IDENTICAL to the direct execution path on pinned fixtures (the IR is a refactor, not a rewrite); a graph mixing row-major and column-major edges without an explicit transpose node is REJECTED at validation — this is where LAYOUT-001 becomes checkable at graph level rather than per call site; constant folding strictly reduces node count on a foldable graph AND dead-node elimination removes an unreachable node while retaining every reachable one (both halves, since removing everything also shrinks the count). Milestone 0.69.0.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - P1 + - enhancement + - crux + - pareto-linfa-burn + notes: null +- id: PMAT-3166 + github_issue: 3166 + item_type: task + title: 'P2: general RL algorithms (PPO/DQN/A2C) — CRUX-N-15' + status: planned + priority: medium + assigned_to: null + created: 2026-09-12T12:16:04Z + updated: 2026-09-12T12:16:04Z + spec: null + acceptance_criteria: + - 'CRUX-N-15, competitor burn, demand 2. burn ships burn-rl. aprender has RL only in the RLHF sense (online/dpo.rs, online/rlvr.rs); PPO, DQN, A2C, SAC and Q-learning are absent — the single apparent PPO hit is a comment at online/dpo.rs:7 naming PPO to say it is NOT doing PPO. Demand 2 is honest: general RL is not on the four-pillar mission and nothing else in the epic depends on it. FALSIFIABLE (contracts/crux-N-15-v1.yaml): PPO exceeds a return threshold on CartPole-equivalent within a bounded episode budget AND a random policy is asserted below it (both halves — a threshold only the agent is measured against proves nothing); a ratio outside [1-eps,1+eps] selects the CLIPPED branch of the surrogate; the DQN target network is asserted to LAG (differs between syncs, matches right after). Milestone 0.70.0.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - P2 + - enhancement + - crux + - pareto-linfa-burn + notes: null +- id: PMAT-3167 + github_issue: 3167 + item_type: task + title: 'P2: Barnes-Hut t-SNE (O(n log n)) — CRUX-N-16' + status: planned + priority: medium + assigned_to: null + created: 2026-09-12T12:16:04Z + updated: 2026-09-12T12:16:04Z + spec: null + acceptance_criteria: + - 'CRUX-N-16, competitor linfa, demand 3. linfa-tsne is explicitly Barnes-Hut; aprender''s preprocessing/tsne.rs has no barnes/quadtree/octree markers — naive O(n^2). SAME DEFECT CLASS as the neighbour index (#3149): an algorithm that is PRESENT but asymptotically worse than the comparator''s. Presence is not parity — the first sweep marked t-SNE present and never examined it. FALSIFIABLE (contracts/crux-N-16-v1.yaml): at theta=0.0 Barnes-Hut must DEGENERATE to the naive path within 1e-9 (this is what proves the quadtree correct); quadtree node-visit counts across n=1e3,1e4,1e5 grow O(n log n) where naive is asserted O(n^2) — COUNTED, not timed, per the repo rule against wall-clock in required checks; the dense O(n^2) P-matrix is asserted NOT materialized on the Barnes-Hut path. Milestone 0.70.0.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - P2 + - enhancement + - crux + - pareto-linfa-burn + notes: null +- id: PMAT-3168 + github_issue: 3168 + item_type: task + title: 'P2: vision ops — NMS, GPU connected components, tensor integration — CRUX-N-17' + status: planned + priority: medium + assigned_to: null + created: 2026-09-12T12:16:04Z + updated: 2026-09-12T12:16:04Z + spec: null + acceptance_criteria: + - 'CRUX-N-17, competitor burn, demand 2. burn-vision ships NMS, GPU connected components (Spaghetti/Spaghetti4C plus a cube backend with prefix sum), VGG19 gram-matrix perceptual loss and 2D transforms, all on burn tensors. aprender-image has real coverage burn does not emphasise (canny, morphology, histogram equalization, gradient magnitude) but is CPU-only, has no NMS, and operates on its own buf.rs type rather than aprender-tensor — so vision ops cannot join an autodiff graph or a GPU pipeline. The tensor integration is the piece with cross-cutting value. Demand 2: vision is not a pillar. FALSIFIABLE (contracts/crux-N-17-v1.yaml): NMS kept-index sets identical to a pinned torchvision.ops.nms fixture including the IoU-at-boundary case; the GPU connected-components path labels IDENTICALLY to CPU (a faster path that labels differently is a defect); migrated ops are byte-identical to the buf.rs path. Milestone 0.70.0.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - P2 + - enhancement + - crux + - pareto-linfa-burn + notes: null + +- id: PMAT-3170 + github_issue: 3170 + item_type: task + title: apr-agent accepts any flag as a task slug + status: planned + priority: high + assigned_to: null + created: 2026-09-12T12:28:29Z + updated: 2026-09-12T12:28:29Z + spec: null + acceptance_criteria: + - 'VERIFIED 2026-09-12: ''apr-agent --help'' created worktree /home/noah/src/aprender-worktrees/--help, branch agent/--help, and claim ~/.config/apr-agent/claims/--help.lock, then tried to launch claude. ROOT CAUSE: the slug guard is ''case $slug in *[!a-zA-Z0-9._-]*) die'' — it rejects characters OUTSIDE that class, and ''-'' is INSIDE it, so --help, -h, --version all pass. No --help handler, no leading-dash check. Same class as the repo''s no-hand-rolled-arg-parsers rule (simular''s match args[1] dropped --seed). SECOND DEFECT: apr-agent is NOT tracked (git ls-files returns 0) and nothing in scripts/ or the Makefile installs it, yet .git/hooks/pre-commit refuses every commit in the main checkout and directs the user to it — a required workflow step enforced by an untracked hook naming an untracked tool. FALSIFIABLE: --help/-h print usage, exit 0, and create NO worktree/branch/claim (all three asserted absent); a committed case table of must-reject flags and must-accept slugs is RE-RUN not re-read; a forced launch failure rolls back the worktree, branch and claim; apr-agent is committed to the repo and the hook installed from a tracked source. Milestone 0.68.0.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - P1 + - bug + notes: null +- id: PMAT-3171 + github_issue: 3171 + item_type: task + title: .claude/ holds 58 stray worktrees, 25 GB, 571,815 .rs files in the repo root + status: planned + priority: high + assigned_to: null + created: 2026-09-12T12:28:29Z + updated: 2026-09-12T12:28:29Z + spec: null + acceptance_criteria: + - 'VERIFIED 2026-09-12: a tree-wide line count returned 222,601,319 lines across 581,978 .rs files; the true figure is 3,947,294 across 10,274 — wrong by ~56x. Cause: .claude/ inside the repo root holds 58 agent worktrees, each a full checkout plus build artifacts. du -sh .claude/ = 25G; 571,815 .rs files; only 6 files tracked. NOT just disk: it silently corrupts any tree-wide tool that does not special-case it (line counters, find-based guards, grep sweeps, embedding indexers) and the wrong answer looks plausible — the guard-universe-from-the-wrong-side class. WORSE: the exclusion lives in .git/info/exclude:5, which is PER-CLONE and never committed, so every other clone and every CI runner has no such protection. FALSIFIABLE: the exclusion moves to a TRACKED .gitignore and a test asserts git check-ignore resolves to .gitignore NOT .git/info/exclude (asserting merely that it is ignored passes today and proves nothing); lanes create worktrees outside the repo root or remove them on exit; a reaper that does NOT date dirs by newest file (a sweeper already deleted a live empty mountpoint on that heuristic); a guard fails on >N worktrees in the repo root, mutation-verified by planting one. Milestone 0.68.0.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - P1 + - bug + notes: null +- id: PMAT-3172 + github_issue: 3172 + item_type: task + title: 'CRUX master registry drift: 250 stories vs 275 contracts' + status: planned + priority: medium + assigned_to: null + created: 2026-09-12T12:28:29Z + updated: 2026-09-12T12:28:29Z + spec: null + acceptance_criteria: + - 'VERIFIED 2026-09-12 on main: contracts/crux-competitive-research-ux-v1.yaml declares 250 stories in categories A-K, while contracts/ holds 275 crux-[A-Z]-*.yaml files. Category L (HF kernels-community) has 15 contracts and 0 story rows; category M (APR-QA Playbook) has 9 and 0 — 24 contracts absent from the registry that is supposed to enumerate them. coverage_intake declares total: 250, so any report derived from it under-counts by 24, and nothing validates the two against each other. The scaffolder''s round-trip is broken for L and M: it emits contracts FROM stories, so stories that do not exist cannot regenerate contracts that do. Category N (#3146) deliberately did not repeat this — all 17 registered, coverage_intake asserted against the histogram — but that was a choice, not something the tooling enforced. RELATED, fixed in #3169: scripts/crux_scaffold_contracts.py CATEGORY_NAMES stopped at K, so L and M would have scaffolded with a bare letter as their category name; nothing detected it for months, same root cause. FALSIFIABLE: a BIJECTION test failing in BOTH directions (orphan contract and orphan story are each an error); the 24 orphans registered or explicitly recorded out-of-registry with a reason (silently baselining all 24 does not satisfy this); coverage_intake asserted equal to the status histogram; CATEGORY_NAMES asserted to cover every letter present in contracts/; mutation-verified by deleting a story row. Milestone 0.69.0.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - P2 + - bug + notes: null +- id: PMAT-3173 + github_issue: 3173 + item_type: task + title: verify gate reads descriptive prose as a test citation + status: planned + priority: medium + assigned_to: null + created: 2026-09-12T12:28:29Z + updated: 2026-09-12T12:28:29Z + spec: null + acceptance_criteria: + - 'VERIFIED 2026-09-12: crates/aprender-contracts/src/lint/gates_extended.rs:81 does ''let name = raw.rsplit("::").next()'' over the ENTIRE test: string and treats a tail starting with test_/prop_ as a citation of a Rust test that must exist. It cannot distinguish a CITATION from a DESCRIPTION. A LIVE-PENDING body — the repo''s own sanctioned state for a gate that cannot bind yet (strict_test_binding.rs:119) — that names the test it will one day bind to is reported as PV-VER-001 Unfalsifiable. The garbled name in the message, running from prop_orthonormal_factors to the end of the sentence, is itself the tell that prose was parsed as an identifier. TWO CLASSIFIERS DISAGREE: classify_binding has a considered taxonomy (CargoTest/ShellHarness/BareRustFn/Unbindable) handling LIVE-PENDING and ''pv '' explicitly; the verify gate re-implements detection with a weaker rule and never consults it. It is an ERROR not a warning, so it fails pv lint and lint_passes_on_real_contracts — blocking a build over a sentence — and it penalises exactly the honest LIVE-PENDING form that names its promotion path. Workaround used in #3169 was to write module paths with / instead of :: — changing DOCUMENTATION wording to satisfy a CODE heuristic, the wrong direction. FALSIFIABLE: verify calls classify_binding and skips Unbindable; a genuine bare citation still raises PV-VER-001 (both directions — a fix that just stops reporting passes the first half alone); the extracted name must be a valid Rust identifier, with a must-match/must-not-match case table; mutation-verified by reverting to rsplit over the raw string. Milestone 0.69.0.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - P2 + - bug + notes: null +- id: PMAT-3174 + github_issue: 3174 + item_type: task + title: aprender-train-canary is dark — no measured trueno-vs-Burn number exists + status: planned + priority: medium + assigned_to: null + created: 2026-09-12T12:28:29Z + updated: 2026-09-12T12:28:29Z + spec: null + acceptance_criteria: + - 'VERIFIED 2026-09-12: crates/aprender-train-canary is the ONLY thing in the tree measuring aprender against Burn (trueno WGPU matmul vs burn::tensor matmul across five LLM-shaped sizes, printing a ratio). It never runs, for three independent reasons: (1) excluded from the workspace at Cargo.toml:114 for a sqlite3/burn link conflict, so it has its own [workspace] and is invisible to cargo metadata and every workspace-wide CI job; (2) named in no .github/workflows/*.yml; (3) pinned to burn 0.21.0-pre.2 while 0.21.0 released 2026-05-07 and 0.22.0-pre.3 on 2026-08-25. CONSEQUENCE: there is NO current measured trueno-vs-Burn number — the comparison is asserted by the file''s existence and nothing else. Same dark-target class as benches (CI builds --examples, never benches) and new tests/*.rs (dark until added to the one explicit ci.yml line), via a third mechanism: workspace exclusion. Cargo.toml:143 says the exclusion is intentional; being UNRUNNABLE is a different decision and the two have been conflated. FALSIFIABLE: the pin moves to a released version with a guard asserting it is not a pre-release; a CI job BUILDS AND RUNS it (compiling is not enough — a canary that never executes is the same defect in a new place); the ratio is COMPARED against a floor or a prior run and fails on collapse (a number was once recorded 18,292 times and never compared); or the crate is DELETED and the claim withdrawn — leaving it dark closes nothing; a guard enumerates excluded members from the exclude list itself and asserts each is exercised or recorded as deliberately unbuilt. Milestone 0.69.0.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - P2 + - bug + notes: null + +- id: PMAT-3177 + github_issue: 3177 + item_type: task + title: 'ci: workspace-test shards wait on guard-tree, so a RED guard stops burning shard runner time (#3177)' + status: in_progress + priority: high + assigned_to: aprender-36 + created: 2026-09-24T00:00:00Z + updated: 2026-09-24T00:00:00Z + spec: .github/workflows/ci.yml + acceptance_criteria: + - 'workspace-test-shard declares needs: [guard-tree]; a failed guard-tree skips every shard' + - 'the required check workspace-test still REPORTS (red) when the shards are skipped, so the merge queue never waits on a missing check' + - 'case table: guard red -> shards skipped, workspace-test red; guard green -> shards run; planted mutants go RED' + - 'green-path cost recorded from measured guard-tree and shard durations' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-3186 + github_issue: 3186 + item_type: task + title: 'guard: resolve_base refuses every stacked merge-group entry (#3186, packing P0)' + status: planned + priority: medium + assigned_to: null + created: 2026-09-12T16:34:18Z + updated: 2026-09-12T16:34:18Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-3205 + github_issue: 3205 + item_type: task + title: mini-m4 PR job-set probe workflow (MINI doctrine, APR-RELEASE-001) + status: planned + priority: medium + assigned_to: null + created: 2026-09-16T16:16:04Z + updated: 2026-09-16T16:16:04Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-3222 + github_issue: 3222 + item_type: task + title: 'ONT-2a: andon — L4/L5 print self-declared until grounded' + status: planned + priority: medium + assigned_to: null + created: 2026-09-13T13:59:08Z + updated: 2026-09-13T13:59:08Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-3226 + github_issue: null + item_type: task + title: 'check_roadmap_completion_is_cited: lane scratch under .claude/worktrees is scanned as if it were the tree' + status: planned + priority: medium + assigned_to: null + created: 2026-09-14T14:10:24Z + updated: 2026-09-14T14:10:24Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-3228 + github_issue: null + item_type: task + title: 'ALWAYS LATEST: move the aprender pin to bashrs 7.4.1 + pmat 3.40.0 once the fleet is converged' + status: planned + priority: medium + assigned_to: null + created: 2026-09-14T15:11:46Z + updated: 2026-09-14T15:11:46Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-3229 + github_issue: null + item_type: task + title: 'RUSTSEC-2026-0285: rustls 0.23.40 accepts TLS 1.3 handshake messages across encryption-level boundaries' + status: planned + priority: medium + assigned_to: null + created: 2026-09-14T16:24:32Z + updated: 2026-09-14T16:24:32Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-3231 + github_issue: null + item_type: task + title: 'Branch triage: 35 branches that never had a PR, classified by path residue against main' + status: inprogress + priority: medium + assigned_to: null + created: 2026-09-14T17:40:00Z + updated: 2026-09-14T17:40:00Z + spec: docs/specifications/APR-RELEASE-001-train-and-build-kaizen.md + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:triage + notes: 'docs/audits/branch-triage-2026-09-14.md — 24 DELETE, 11 REVIEW; commit count + is the wrong instrument under squash-merge, path residue is the right one' +- id: PMAT-3232 + github_issue: null + item_type: task + title: 'APR-RELEASE-001 §11.2: the five ontology counters, measured, with an anchor-without-a-consumer refusal' + status: inprogress + priority: medium + assigned_to: null + created: 2026-09-14T18:05:00Z + updated: 2026-09-14T18:05:00Z + spec: docs/specifications/APR-RELEASE-001-train-and-build-kaizen.md + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'unanchored_but_bindable moves from [U] to 297; contracts_anchored may not + rise while pv census is absent, because pv validate accepts entity: by ignoring it' +- id: PMAT-3233 + github_issue: null + item_type: task + title: 'ONT-1: pv census — one cardinality over the corpus (by_anchoring, by_entity_type), census.json tracked + regenerated by `make contracts`, README count read from it, and R-10 provenance marks linted by scripts/lint-provenance.sh' + status: inprogress + priority: high + assigned_to: null + created: 2026-09-14T20:10:00Z + updated: 2026-09-16T10:27:10Z + spec: docs/specifications/paiml-ontology.md + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: the consumer PMAT-3232 proved missing; reads RAW yaml because Contract is not deny_unknown_fields and serde drops entity:. ONT-001 v4.3 says every figure in its §1 is quote-frozen until ONT-1 emits one census +- id: PMAT-3234 + github_issue: null + item_type: task + title: 'guards-nightly has been RED on a matcher that cannot see a YAML-quoted step name' + status: inprogress + priority: high + assigned_to: null + created: 2026-09-14T19:45:00Z + updated: 2026-09-14T19:45:00Z + spec: docs/specifications/APR-RELEASE-001-train-and-build-kaizen.md + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'a step name containing a colon-space must be quoted in YAML; the inline + grep -F matched only the bare spelling, so the lane named a step that runs every + night as one the workflow does not run' +- id: PMAT-3235 + github_issue: null + item_type: task + title: 'examples-nightly: 6 of 22 red rows are an example built without its feature, not a broken example' + status: inprogress + priority: medium + assigned_to: null + created: 2026-09-14T20:05:00Z + updated: 2026-09-14T20:05:00Z + spec: docs/specifications/APR-RELEASE-001-train-and-build-kaizen.md + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'adds needs-feature beside needs-args/needs-hardware/needs-data; like + needs-hardware it is a SKIP that must be re-run with the feature before a release + verdict, never read as the example working' +- id: PMAT-3236 + github_issue: null + item_type: task + title: 'Silicon Nightly reported a vanished dep-info file as a SIMD failure — route its cargo through the ENV/CODE classifier' + status: inprogress + priority: medium + assigned_to: null + created: 2026-09-14T20:25:00Z + updated: 2026-09-14T20:25:00Z + spec: docs/specifications/APR-RELEASE-001-train-and-build-kaizen.md + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'cargo_step.sh (#3241) classifies dep-info ENOENT as ENV and was wired to + book.yml only; 5 of 75 cargo invocation lines across all workflows were covered' +- id: PMAT-3237 + github_issue: null + item_type: task + title: 'Coverage Nightly red every night on a same-process ratio that is load-immune but not instrumentation-immune' + status: inprogress + priority: medium + assigned_to: null + created: 2026-09-14T20:45:00Z + updated: 2026-09-14T20:45:00Z + spec: docs/specifications/APR-RELEASE-001-train-and-build-kaizen.md + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'llvm-cov overhead scales with instrumented branches EXECUTED, which differs + between the compress and decompress paths; the ratio had already been widened once + to 0.25 for this and failed anyway' +- id: PMAT-3259 + github_issue: 3259 + item_type: task + title: 'APEX-2b: extended-Wilkinson tick placement (Talbot, Lin & Hanrahan 2010) — breaks::{extended, extended_loose, Q_DEFAULT, W_DEFAULT}, 36 CRAN goldens + 6 properties + W_DEFAULT-swap mutation (paiml/aprender#3233 half 1 of 2; apex APEX-001 row EV-2b, bound in paiml/apex#71)' + status: planned + priority: medium + assigned_to: null + created: 2026-09-16T14:09:06Z + updated: 2026-09-17T00:00:00Z + spec: null + acceptance_criteria: + - 'The first of the two capabilities #3233 owes apex''s EV-14. NEW crates/aprender-viz/src/breaks.rs, tests/breaks_golden.rs, fixtures/breaks/{manifest.json,README.md,generate.py}; EDITS Cargo.toml (+libm), src/lib.rs (+pub mod breaks), Cargo.lock. W_DEFAULT follows the reference code, not the paper''s prose. Landed through paiml/aprender#3259.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + - apex + - APEX-001 + - EV-2b + - orch:fable + - orch-basis:state + notes: 'id is the PR number (#3259), the EV-2a precedent (PMAT-3273). The first id, PMAT-3233 from issue #3233, collided with ONT-1 PMAT-3233 landed by #3281: add/add on the fragment and the verdict artifact.' +- id: PMAT-3273 + github_issue: null + item_type: task + title: 'APEX-2a: deterministic render primitive — SVG byte-identical across clean-room X64 and ARM64 hosts (svg_identical ASSERTED from SVG bytes; PNG identity RECORDED as png_identical and never asserted, because its verdict decides EV-15''s manifest shape — APEX-001 v4.7): libm-only transcendentals (clippy disallowed-methods, proved live by scripts/ci/libm-ban-live.sh), every emitted coordinate on COORD_GRID=1e-3 via format_coord, text-to-path, sha256 manifest, ci.yml determinism matrix + determinism-compare.sh deciding svg_identical from SVG bytes with a self-test and a manifest_root mutant (apex APEX-001 row EV-2a, bound in paiml/apex#71; depends on EV-2b #3259)' + status: planned + priority: medium + assigned_to: null + created: 2026-09-16T14:10:22Z + updated: 2026-09-16T14:10:22Z + spec: null + acceptance_criteria: + - Id allocated from the PR number (paiml/aprender#3273), GitHub's central sequence, so it cannot collide. NEW crates/aprender-viz/src/{manifest.rs,text.rs}, tests/render_determinism.rs, scripts/ci/{libm-ban-live.sh,determinism-compare.sh}; EDITS crates/aprender-viz/.clippy.toml (existing file; gains the 12-entry libm disallowed-methods list), .github/workflows/ci.yml (NEW determinism X64+ARM64 matrix job and NEW determinism-compare job which needs it; gate.needs names determinism-compare, so a failed matrix leg skips the compare and gate reads its non-success), Cargo.toml (features text-path/raster; libm non-optional), src/lib.rs (deny + quantise + format_coord), src/breaks.rs (EV-2b's four .powi(2) -> sq(x)=x*x, bit-identical, because this crate's .clippy.toml bans f64::powi), src/output/{svg.rs,png_encoder.rs}, src/error.rs, src/scale.rs, src/plots/{histogram,boxplot,force_graph}.rs, examples/{roc_pr_curves,loss_training}.rs, scripts/tree_reader_tests.txt, Cargo.lock; docs/roadmaps/roadmap.yaml regenerated from this fragment. tests/render_determinism.rs has 10 tests; its SVG fixture sits on a LogScale with EV-2b breaks::extended as the axis ticks (receipt ticks:{x:5,y:4}). Publishing aprender-viz stays operator-only. + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + - orch:fable + - 'orch-basis:M>=3' + - apex + - APEX-001 + - EV-2a + notes: null +- id: PMAT-3292 + github_issue: 3292 + item_type: task + title: a run cannot hold a concurrency group while capacity sits idle + status: in_progress + priority: high + assigned_to: null + created: 2026-09-16 11:28:34+00:00 + updated: 2026-09-16 11:28:34+00:00 + spec: null + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-3294 + github_issue: 3294 + item_type: task + title: a roadmap edit without its fragment is refused + status: planned + priority: medium + assigned_to: null + created: 2026-09-16T08:42:17Z + updated: 2026-09-16T08:42:17Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-3296 + github_issue: 3296 + item_type: task + title: 'roadmap fragments: one file per ticket, roadmap.yaml generated on main' + status: in_progress + priority: high + assigned_to: null + created: 2026-09-15 06:00:00+00:00 + updated: 2026-09-15 06:00:00+00:00 + spec: null + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-3300 + github_issue: 3300 + item_type: task + title: 'tools.toml pmat 3.40.1: the fleet converged 2026-09-14 and every intel-hosted PR is red' + status: planned + priority: medium + assigned_to: null + created: 2026-09-15T07:58:08Z + updated: 2026-09-15T07:58:08Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-3318 + github_issue: 3318 + item_type: task + title: the cascade gate reads the structured tested-sha + status: planned + priority: medium + assigned_to: null + created: 2026-09-16T09:36:36Z + updated: 2026-09-16T09:36:36Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-3337 + github_issue: 3337 + item_type: task + title: check_silicon_coverage reads the evidence per axis workflow + status: planned + priority: medium + assigned_to: null + created: 2026-09-15T22:18:29Z + updated: 2026-09-15T22:18:29Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-3338 + github_issue: 3338 + item_type: task + title: 'pv proof-status --table panics on the real corpus: a byte slice lands inside a multi-byte character (#3338)' + status: in_progress + priority: high + assigned_to: null + created: 2026-09-21T00:32:08Z + updated: 2026-09-21T00:32:08Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'Transcribed from issue #3338. Repro: `pv proof-status contracts --table` on origin/main''s contracts, rc=101, panicked at crates/aprender-contracts/src/obligation_matrix.rs:169:11: "byte index 40 is not a char boundary; it is inside ''∈'' (bytes 39..42) of `for Q4_K_M Qwen2.5-Coder, quantization ∈ {Q4_K, Q6_K}`". Plain `pv proof-status` (no --table) does not panic; only the table renderer does. Cause as the issue states it: `truncate(s, max)` returns `&s[..max]`, a byte slice, which panics when `max` falls inside a multi-byte character. Done when the table renderer no longer panics on that input — truncation cuts on a char boundary, not a byte index — and `pv proof-status contracts --table` runs on the real corpus. This fix rides in PR #3351 because that PR''s L2-column change is exercised through `--table` on the real corpus, which panicked before it.' +- id: PMAT-3341 + github_issue: 3341 + item_type: task + title: MoE load-time expert-qtype contract — refuse at load, not at first token (#3341) + status: planned + priority: medium + assigned_to: null + created: 2026-09-16T19:22:19Z + updated: 2026-09-16T19:22:19Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-3346 + github_issue: 3346 + item_type: task + title: 'QE2E-INV-001: ModelConstraints dropped the gated-DeltaNet shape, so 18 of every 24 Qwen3.5 layers were counted as if their tensors did not exist (#3346)' + status: in_progress + priority: high + assigned_to: null + created: 2026-09-20T22:54:24Z + updated: 2026-09-20T22:54:24Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'ACCEPTANCE, from issue #3346 ("decide which side is wrong, with a measurement") as PR #3350 answers it — the answer is neither the range nor the descriptor but the TYPE that reads the descriptor: (1) ModelConstraints carries inner_size, state_size, conv_kernel, group_count and full_attention_interval from contracts/model-families/qwen3_5.yaml, which it previously dropped; (2) the config-derived model_parameter_count equals the measured GGUF tensor sum of a REAL file — ~/models/Qwen3.5-0.8B-Q4_K_M.gguf, 320 tensors, 752,393,024 parameters, delta 0 — with the gated-DeltaNet layer (21,555,360) and the full-attention layer (18,352,640) each matching the measured blk; (3) the two shapes that contradict dense accounting are modelled from the tensors, not assumed: attn_q is [d, 2*n_h*d_k] (the q projection emits the output gate) and the DeltaNet mixer projections/conv/state norm are counted for the 18-of-24 linear layers; (4) the 9B range instantiation is NOT asserted in this PR — the repo 9b descriptor disagrees with itself (inner_size 2048 at hidden 4096; group_count 8 fails group_count*state_size == inner_size) so P(9B) computes to 8.345B, and settling it needs a real Qwen3.5-9B GGUF, recorded in the QE2E-INV-001 binding note; (5) the note edit leaves contracts/binding.yaml valid YAML (156 entries, same as main) and the tracked contracts.nt equals a fresh extraction. Out of scope: acquiring the 9B GGUF; widening the range.' +- id: PMAT-3347 + github_issue: 3347 + item_type: task + title: bind the six qwen35-e2e equations to implementations + status: planned + priority: medium + assigned_to: null + created: 2026-09-16T06:52:28Z + updated: 2026-09-16T06:52:28Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: GH-4045 + github_issue: 4045 + item_type: task + kind: code + title: 'Release process for 0.70+: CRUX-smoke gate on the release binary; full ladder + full CRUX move to nightly; #4033 levers wired into the workflow' + status: inprogress + priority: medium + assigned_to: aprender-e6 + created: 2026-09-23T20:30:19.864488525+00:00 + updated: 2026-09-23T20:30:19.864488525+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: GH-4086 + github_issue: 4086 + item_type: task + title: '0.70.0: dogfood''s declared check_model_ladder gate ignores a recorded emergency scope (no seam) — known-red at 0.69.1' + status: inprogress + priority: medium + assigned_to: null + created: 2026-09-23T23:52:18.558504381+00:00 + updated: 2026-09-23T23:52:18.558504381+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - P2 + notes: null +- id: GH-4110 + github_issue: 4110 + item_type: task + title: 'apr --version prints +no-git on BOTH published surfaces (crates.io install, release binaries)' + status: inprogress + priority: medium + assigned_to: null + created: 2026-09-23T23:59:54.621480081+00:00 + updated: 2026-09-23T23:59:54.621480081+00:00 + spec: null + acceptance_criteria: + - 'a packaged apr-cli (.cargo_vcs_info.json, no .git) emits APR_GIT_SHA = the 9-hex vcs sha, never +no-git (must-RED: the vcs rung removed)' + - 'an unpacked crate inside an UNRELATED repository still names its own vcs sha, not that repo HEAD (must-RED: vcs rung behind git rev-parse)' + - 'a checkout owned by another user (the root build container of binary-release.yml) still yields git rev-parse HEAD (must-RED: the safe.directory retry removed)' + - 'dev checkouts, the override, the malformed-sha and no-vcs fallbacks are unchanged' + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: 'Cop rows (aprender-cf, 2026-09-23/24): (1) build.rs reads the sha1 from .cargo_vcs_info.json with a must-RED fixture; scope widened after aprender-70 found the release binaries print +no-git too: cover both surfaces, each with its own must-RED, and keep any binary-release.yml edit a separate commit. ROOT CAUSE (b), measured: git inside rust:1.93.0-bookworm running as root refuses the runner-owned checkout (fatal: detected dubious ownership); main build.rs printed v0.69.1+no-git there, this one prints the HEAD. The retry marks ONLY the enclosing checkout safe.directory through a private GIT_CONFIG_GLOBAL under OUT_DIR (-c safe.directory is ignored before git 2.39, measured on 2.34.1), so NO workflow edit is needed. Tests: crates/aprender-build-sha/src/emit_tests.rs (8 rows, 3 plants; moved from apr-cli when the resolution became shared, 4219), run by workspace-test. Also Cargo.lock chacha20 0.10.0 (yanked) -> 0.10.2, lock-only.' +- id: GH-4114 + github_issue: 4114 + item_type: task + kind: code + title: check_package_includes.sh skips cfg(test) modules — it passed a crate whose published-tarball cargo test cannot compile (3 includes); the gate must build the real .crate + status: inprogress + priority: medium + assigned_to: null + created: 2026-09-24T01:04:44.436321582+00:00 + updated: 2026-09-24T01:04:44.436321582+00:00 + spec: null + acceptance_criteria: + - 'the gate builds the REAL .crate: cargo package every publishable crate, unpack outside the tree, siblings patched to their tarballs (printed), cargo build --workspace --tests --keep-going; errors named by crate and file:line' + - 'RED on the published aprender-serve 0.69.1 .crate (sha256 22a710f0...), naming the 3 includes (--negative-control)' + - 'aprender-serve GREEN from its tarball on 4eb21dbac (the #4048 fix)' + - 'a planted include_bytes of an excluded tests/ file inside a new #[cfg(test)] module is RED; the source reader does not list it' + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: 'Cop row (aprender-cf, 2026-09-24), filed by aprender-70. Release-time gate scripts/package_tarball_build.sh, declared in [package.metadata.dogfood].gates (no workflow edit; cargo-free guard_tree cannot run it). The PR-time half is rows 14-16 of check_package_includes.sh --self-test, which ci.yml guard-cargo already runs. MEASURED on lambda (compile only): main 49fe19c28 RED in 9 crates in 275 s with a warm target -> filed #4129 (include! outside the .crate) and #4130 (shipped integration tests with stripped path-only dev-deps). Negative control OK in 288 s. On 4eb21dbac aprender-serve is absent from the RED rows (582 s). A defect in the gate''s own first draft: tar restores archived mtimes and cargo decides freshness by mtime, so a warm target dir reused a DIFFERENT build of the same name and version (a false green, caught by row 15). Unpacking with tar -m fixes it.' +- id: GH-4129 + github_issue: 4129 + item_type: task + kind: code + title: 'Published tarballs of aprender-train, aprender-contracts, aprender-contracts-cli, aprender-present-terminal cannot compile their tests: include! of files outside the .crate' + status: inprogress + priority: medium + assigned_to: null + created: 2026-09-24T01:44:20.650601111+00:00 + updated: 2026-09-24T01:44:20.650601111+00:00 + spec: null + acceptance_criteria: + - 'aprender-train, aprender-contracts, aprender-contracts-cli, aprender-present-terminal: the #4114 tarball gate no longer lists them RED (their published tarballs compile their tests)' + - 'in tree every converted test RUNS (no SKIP) and a missing file FAILS it (panic), never skips; out of tree it SKIPs by name' + - 'one pattern with #4048/#4130: run-time read, SKIP : out of tree ... on stderr, *_or_skip helper name (counted by the #4114 shrink report)' + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: 'Cop row (aprender-cf, 2026-09-24). Pattern agreed with aprender-dd (#4130). MEASURED: the #4114 gate at 556994b7f on this tree (cdff936d2), lambda, compile-only, 404 s: the four crates are absent from the RED rows. Remaining RED: aprender-serve (#4048, fixed on the merge-back lineage) and the #4130 class. Shrink report: 43 run-time skip sites across 6 crates. gx10, in tree, per converted test (6 cases), with --nocapture: baseline 1 ok, 0 SKIP lines; the file moved -> rc 101, 0 SKIP, and the in-tree panic in 5 of 6. The 6th (contracts-cli validator.rs) cannot be measured by moving the file: validator.rs is a MODULE of the sibling crate, so moving it is a compile error (E0583). Its baseline shows the test runs in tree. NOT IN SCOPE on main: apr-cli golden_output.rs / thinking_budgets_mirror.rs and the aprender-orchestrate chat_template.rs include chat_template_3990 fixtures and thinking-budgets-v1.yaml; those files exist only on the 0.69.1 lineage (chore/0.69.1-merge-back), so they are fixed there.' +- id: GH-4140 + github_issue: 4140 + item_type: task + kind: code + title: '#4129 on the 0.69.1 lineage: apr-cli and aprender-orchestrate tests include #3990 fixtures / thinking-budgets source from outside their crate' + status: inprogress + priority: medium + assigned_to: null + created: 2026-09-24T04:53:51.420416768+00:00 + updated: 2026-09-24T04:53:51.420416768+00:00 + spec: null + acceptance_criteria: + - 'apr-cli and aprender-orchestrate are absent from the #4114 tarball gate RED rows on this lineage' + - 'in tree each converted test RUNS (no out-of-tree SKIP) and a moved fixture FAILS it; out of tree it SKIPs by name' + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: 'Cop row (aprender-cf, 2026-09-24): the 0.69.1-lineage instances of #4129, branched off chore/0.69.1-merge-back @ f1b09d4d6, NOT part of #4046 single push; folds in the 0.70 batch after #4046. Same pattern as #4048/#4129/#4130.' +- id: GH-4151 + github_issue: 4151 + item_type: task + kind: code + title: cargo fmt --check never sees include!d .rs files — CI's fmt gate is blind to them (two 140-col lines passed) + status: inprogress + priority: medium + assigned_to: null + created: 2026-09-24T06:10:40.669338522+00:00 + updated: 2026-09-24T06:10:40.669338522+00:00 + spec: null + acceptance_criteria: + - 'include!d .rs files are enumerated from source and checked with the pinned rustfmt (the owning crate edition)' + - 'a NEW misformatted include!d file (not in scripts/include_fmt_baseline.txt) is RED, named' + - 'the baseline growing is RED (shrink-only against merge-base with origin/main, lib_baseline_ratchet.sh set mode)' + - 'wired through check_package_includes.sh (ci.yml guard-cargo), with no workflow edit' + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: 'Cop ruling (aprender-cf, 2026-09-24): option B, a shrink-only ratchet. The mass reformat (A) and touched=clean (C) are deferred to a quiet window after the 0.70 fold. MEASURED on main 49fe19c28 with rustfmt 1.8.0-stable (254b59607d): 1778 include!d .rs files, 1584 misformatted (baselined). A full pass over them changes 1783 files, +135611/-128345. 163 remain misformatted after one pass (non-convergent, listed in the receipt separately). The instrument is pinned exactly in the baseline header, and a different rustfmt is "cannot check" (2).' +- id: GH-4162 + github_issue: 4162 + item_type: task + kind: code + title: 'P0: measured token usage for the fleet -- Claude Code + agy, by project / model / lane / hour, with the top levers' + status: inprogress + priority: medium + assigned_to: pvl-b + created: 2026-09-24T06:55:50.906231018+00:00 + updated: 2026-09-24T20:20:00+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - P0 + notes: null +- id: GH-4175 + github_issue: 4175 + item_type: task + title: 'clean-room B2: packaged-tarball test gate, all crates' + status: inprogress + priority: medium + assigned_to: null + created: 2026-09-24T07:51:58.558709285+00:00 + updated: 2026-09-24T07:51:58.558709285+00:00 + spec: null + acceptance_criteria: + - '[ ] `scripts/package_tarball_build.sh` gains the run step. Its case table covers a planted run-time panic (RED) and a clean crate (GREEN).' + - '[ ] `mode_b_tarball` in infra is wired nightly.' + - '[ ] RED measured on v0.69.1. The receipt lists the failing crates and tests, wall time and peak RSS.' + - '[ ] GREEN measured on the fix stack.' + - '[ ] Both-directions proof for the shared helper: out of tree it skips; in tree with the file removed it FAILs.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: GH-4190 + github_issue: 4190 + item_type: task + kind: code + title: 'apr-format: golden_v2_f32_writer_is_byte_identical fails in tree (516 vs 1092 bytes) — a dark CI target' + status: inprogress + priority: medium + assigned_to: null + created: 2026-09-24T12:00:00+00:00 + updated: 2026-09-24T12:00:00+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - P2 + notes: null +- id: GH-4191 + github_issue: 4191 + item_type: task + kind: code + title: 'aprender-orchestrate: test_resolve_project_root_nonexistent_falls_back is host-dependent (stray /tmp/Cargo.toml)' + status: inprogress + priority: medium + assigned_to: null + created: 2026-09-24T12:00:00+00:00 + updated: 2026-09-24T12:00:00+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - P2 + notes: null +- id: GH-4197 + github_issue: 4197 + item_type: task + title: 'PVL-001 EV-6c pt1: kani_assume.rs per-file kani::assume token count (use-import refused, fails closed) + rises + Baseline check; 14 tests; proc-macro2 dep; DELETE dead tests_12b.rs. NO CLI flag, baseline, Makefile, workflow' + status: inprogress + priority: medium + assigned_to: null + created: 2026-09-24T08:24:32.273397348+00:00 + updated: 2026-09-24T08:24:32.273397348+00:00 + spec: null + acceptance_criteria: + - 'cargo test -p aprender-contracts --lib kani_assume: 14 passed. Mutations, each planted alone, restored sha-identical: group markers dropped reds a_group_boundary_breaks_the_sequence; rise as >= reds a_fall_or_a_removed_file_is_not_a_rise; import refusal off reds a_use_import_of_assume_is_refused_in_every_shape; consistency off reds an_inconsistent_baseline_is_refused; string literals counted reds comments_and_strings_never_count; target/ not skipped reds count_tree_keys_relative_paths_and_skips_target_and_hidden.' + - 'count_tree(crates/) on this tree: 177 in 26 files, fails closed on nothing. grep -c gives 187 in 28; the 10 extra are string literals in kani_gen/strategies.rs (9) and invariant_gen.rs (1), code generators whose output is counted.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - ont-0.70 + notes: 'Part 1 of PVL-001 EV-6c (Refs #4197, not Closes). The row probe runs pv discharge check --kani, a subcommand that exists only on EV-6a''s unmerged branch (#4139); part 2 adds the flag, contracts/kani-assume-baseline.json and make kani-ratchet after it lands. The spec''s baseline 254 [C v2] is stale; the measured count is 177. tests_12b.rs was deleted because fail-closed must hold on the real tree: it is not compiled (no mod/#[path]/include! names it) and has an unbalanced } at :35.' +- id: GH-4198 + github_issue: 4198 + item_type: task + title: 'PVL-001 EV-10: pv obligations [ROOT] --gate (commands/obligations.rs, cli/lib/mod wiring) = pv-obligation-gate.py; 11 golden tests, fixtures, ci fragment 462; tree_reader registry +2, surface_audit pv cites +11 lines. NO ci.yml/Makefile/pmat edit' + status: inprogress + priority: medium + assigned_to: null + created: 2026-09-24T08:50:11.471932980+00:00 + updated: 2026-09-24T08:50:11.471932980+00:00 + spec: null + acceptance_criteria: + - 'cargo test -p aprender-contracts-cli --test pvl_obligations_golden: 11 passed. Goldens (pmat, broken, edge .stdout/.rc) were written by running pmat''s scripts/pv-obligation-gate.py (sha256 e4fa9719, pmat d70a78f67, PyYAML 6.0.3) over each fixture, never by pv; pv matches stdout byte for byte and the exit code (pmat 0 over 35 rc 0; broken 6 over 4 rc 1; edge 3 over 4 rc 1: merge keys incl. a chained merge, falsy applies_to/proved_type/document). A duplicate-key and a >64-bit-integer contract match the script''s measured output: the validate line only, 1 over 1 rc 1.' + - 'Mutations in obligations.rs, each planted alone, restored sha-identical, 17/17 red, each naming the test it reds: validate-always-passes, falsification-counts-every-entry, fn/type word boundary (3), binding-yaml-included, gate-flag-ignored, empty-corpus-reported-as-pass, equation-targets-not-skipped, merge-keys-not-resolved, merge-single-pass, everything-truthy, falsy-document-rejected, unused-bad-type-reported-eagerly (edge_fixture_follows_pyyaml_and_python_truthiness_as_the_script_does), symlinked-contracts-skipped (a_symlinked_contract_is_checked_like_its_target), reached-bad-type-silent (a_non_string_proved_type_is_named_where_a_bound_fn_reaches_it), parse-line-after-validate (a_document_serde_yaml_refuses_fails_validate_so_the_verdict_agrees).' + - 'Deliberate differences from the script, documented in the module doc: zero contracts is decline rc 2 (PVL-1), non-YAML/non-mapping/non-string input is a named problem not a traceback, src/ walked on disk, YAML 1.2 vs PyYAML 1.1 plain booleans, checks 2-3 not run on a document serde_yaml refuses (it fails validate on both sides, so the verdict agrees), word chars next to non-ASCII. Largest function cog 17 / cyc 6.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - ont-0.70 + notes: The PVL-001 EV-10 probe greps .github/workflows/ci.yml and uses repo-root tests/ paths; aprender wires integration tests via ci/explicit-test-commands.d fragments and the test lives under crates/aprender-contracts-cli/tests/. Reported to the PVL-001 owner (infra) as a stale probe. The src/ fixture files end .rs.txt because ten aprender gates scan tracked .rs files. +- id: GH-4377 + github_issue: 4377 + item_type: task + title: Adopt dogfood-receipt-v1 in apr-dogfood, and remove python3 from it (ARB-SELF-001 ASL-05) + status: inprogress + priority: medium + assigned_to: null + created: 2026-10-10T13:24:25.785855612+00:00 + updated: 2026-10-10T13:24:25.785855612+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - P0 + - size:M + - owner:aprender-a7 + notes: null +- id: GH-4688 + github_issue: 4688 + item_type: task + title: '0.70.2 T13: BLD-002 R9 one list in code of what merge, tag and publish require' + status: inprogress + priority: medium + assigned_to: null + created: 2026-10-04T11:03:30.893042328+00:00 + updated: 2026-10-04T11:03:30.893042328+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - P0 + - size:L + - owner:aprender-a7 + notes: null +- id: GH-4691 + github_issue: 4691 + item_type: task + title: 'tag_coverage_gate.sh waits for a CI job that no longer exists: resolve it before the tag or refuse' + status: inprogress + priority: high + assigned_to: null + created: 2026-10-04T00:00:00+00:00 + updated: 2026-10-04T00:00:00+00:00 + spec: null + acceptance_criteria: + - 'the coverage job name lives in one function and is resolved against the jobs of .github/workflows/ci.yml at the release commit before any tag step' + - 'absent or renamed job = FAIL naming the job and the file, with 0 GitHub calls (must-RED: origin/main waited for the run, then refused after the tag)' + - 'unreadable/empty ci.yml, no jobs, or a reusable-workflow caller = NOT_MEASURED, which refuses' + - 'present + green passes; present + red refuses; gh failing refuses' + - 'autopilot cut_tag calls --resolve before must-carry/carry/strict; check_tag_step_gated.sh order row and two plants (call removed, die neutered) go RED' + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: 'Before: v0.70.1 tag run completed 25 min after start with no ci / coverage job; the gate refused only at preflight, after the tag and the GitHub release were public (up to 90 tries x 60 s, 2 gh calls/try). After: refused at cut_tag, 0 gh calls, 0 s. NOTE: ci.yml today declares no ci / coverage job (coverage runs inside x86-main), so every release refuses at cut_tag until one is declared or the gate is retargeted.' +- id: GH-4718 + github_issue: 4718 + item_type: task + title: '0702-P1: nightly producers for the deep lanes (deep-doctests, deep-nodefault, deep-bins-smoke)' + status: inprogress + priority: critical + assigned_to: null + created: 2026-10-04T09:17:34.904751550+00:00 + updated: 2026-10-04T09:17:34.904751550+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - P0 + notes: null +- id: GH-4915 + github_issue: 4915 + item_type: task + kind: code + title: 'Release: standing CRUX-smoke release policy in the ladder, read by autopilot, readiness and bump' + status: inprogress + priority: high + assigned_to: aprender-la71 + created: 2026-10-08T01:34:09.000000000+00:00 + updated: 2026-10-08T01:34:09.000000000+00:00 + spec: null + acceptance_criteria: + - 'ladder.release_policy in contracts/model-capability-ladder-v1.yaml records the standing CRUX-smoke policy' + - 'scripts/release/autopilot.sh, scripts/release_readiness.sh and scripts/prepare_bump.sh read it through the strict awk reader' + - 'the models nightly opens or updates one ticket per red row, naming release_policy.ticket_owner; a search it cannot trust opens nothing (NOT-MEASURED)' + - 'the release notes of a covered release list known failures: ladder known_red rungs and open models-nightly red-row tickets' + - 'out of scope: the #4033 levers' + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: GH-5081 + github_issue: 5081 + item_type: task + title: 'nightly train: a red night opens a ticket with an owner within 60 min' + status: inprogress + priority: medium + assigned_to: null + created: 2026-10-10T17:56:26.522678124+00:00 + updated: 2026-10-10T17:56:26.522678124+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: GH-5426 + github_issue: 5426 + item_type: task + kind: code + title: 'pr-review: update stale agy/Claude model ids to current quorum lanes (gemini-4-argon-high, claude-sonnet-5-5, claude-haiku-5-5)' + status: inprogress + priority: medium + assigned_to: null + created: 2026-10-16T10:38:47.453979621+00:00 + updated: 2026-10-16T10:38:47.453979621+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-3351 + github_issue: 3347 + item_type: task + title: pv's L2 column reads an obligation-to-test link, not an index + status: in_progress + priority: medium + assigned_to: null + created: 2026-09-16 07:53:27+00:00 + updated: 2026-09-16 07:53:27+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'SCOPE, transcribed from issue #3347 "Ask" — this row is the second and third bullets; the first bullet (write the six implementation bindings) was #3348 / roadmap PMAT-3347 and is out of scope here. Verbatim from the issue: (2) "Make the --table L2 column read the actual obligation<->test link rather than an index comparison" — the issue states the defect as: obligation_matrix.rs computes l2_tested as idx < falsification_tests.len(), so obligations showed an L2 tick before any test existed; a column that ticks on a count, not on a link, cannot report coverage. (3) "Make single-file pv lint --strict-test-binding resolve its scan root to the repo, or refuse the single-file form instead of reporting a false negative" — the issue states the defect as: it sets the scan root to the contract''s parent, contracts/, which contains no crates/, so no ref can resolve and an already-bound control contract fails identically. Either resolution named in the issue satisfies (3). No count of obligations, tests or contracts is a criterion.' +- id: PMAT-3359 + github_issue: 3359 + item_type: task + title: H1 SIMD dot speedup assertion is a wall-clock check in a required gate + status: planned + priority: medium + assigned_to: null + created: 2026-09-16T12:10:03Z + updated: 2026-09-16T12:10:03Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-3365 + github_issue: 3365 + item_type: task + title: apr install.sh — curl one-liner installer with path-scoped CI test (#3365) + status: planned + priority: medium + assigned_to: null + created: 2026-09-16T15:03:48Z + updated: 2026-09-16T15:03:48Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-3367 + github_issue: 3367 + item_type: task + title: apr chat exits 0 after a generate failure (#3367) + status: planned + priority: medium + assigned_to: null + created: 2026-09-16T14:53:17Z + updated: 2026-09-16T14:53:17Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-3370 + github_issue: 3370 + item_type: task + title: 'EPIC: CRUX category O — AutoML parity vs AutoGluon 1.6.3 — 9 P0, 9 P1, 6 P2 (24 stories)' + status: planned + priority: critical + assigned_to: null + created: 2026-09-16T12:00:00Z + updated: 2026-09-16T12:00:00Z + spec: docs/specifications/crux-competitive-research-ux-workflows.md + acceptance_criteria: + - 'All 24 children (#3371-#3394) closed or explicitly re-cut; apr automl fit/predict on iris and apr forecast fit on a 5-item panel run end to end; each child lands with a contract and mutation-RED evidence.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - P0 + - epic + - enhancement + - crux + - pareto-autogluon + notes: null +- id: PMAT-3371 + github_issue: 3371 + item_type: task + title: 'P0: One-call tabular AutoML: fit(label) -> predict on a CSV — CRUX-O-01' + status: planned + priority: critical + assigned_to: null + created: 2026-09-16T12:00:00Z + updated: 2026-09-16T12:00:00Z + spec: null + acceptance_criteria: + - 'CRUX-O-01, competitor autogluon, demand 5. No predictor-level AutoML entry point exists. crates/aprender-core/src/automl/ is a hyperparameter TUNER (AutoTuner, TPE, GridSearch, RandomSearch, DESearch, TimeBudget) that tunes ONE estimator the caller already chose; nothing takes a labelled table and returns a fitted model. `apr train` is causal-LM pre-training only (crates/apr-cli/src/commands/train.rs:1-5) and `apr finetune --task classify` is text classification. FALSIFIABLE (contracts/crux-O-01-v1.yaml): fit on a labelled CSV returns a predictor whose predictions score above the majority-class baseline — on the iris fixture (crates/aprender-core/src/datasets/iris.csv) accuracy >= 0.90 AND the majority-class baseline is asserted at 0.333 in the same test; the same call works for a regression label without a problem_type argument — a numeric label column yields a regressor whose R^2 on a held-out split exceeds 0.5 AND the mean-predictor baseline is asserted at ~0.0; apr automl fit is reachable from the CLI — `apr automl fit --label class train.csv --out model.apr` exits 0 and writes a loadable artifact; a missing --label exits 2 with a message naming the flag. Epic #3370.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - P0 + - enhancement + - crux + - pareto-autogluon + notes: null +- id: PMAT-3372 + github_issue: 3372 + item_type: task + title: 'P0: Problem-type inference: binary / multiclass / regression / quantile from the label column — CRUX-O-02' + status: planned + priority: critical + assigned_to: null + created: 2026-09-16T12:00:00Z + updated: 2026-09-16T12:00:00Z + spec: null + acceptance_criteria: + - 'CRUX-O-02, competitor autogluon, demand 5. No function infers a task from a label column. Estimators are chosen by type name (LogisticRegression vs LinearRegression); DataFrame in crates/aprender-core/src/data/mod.rs carries ColumnStats but no label-kind classifier. FALSIFIABLE (contracts/crux-O-02-v1.yaml): two unique label values infer binary, 3..=N small-cardinality infer multiclass, many-unique numeric infers regression — a table of (label column, expected kind) fixtures including the ambiguous cases {0,1} as int, {0.0,1.0} as float, and 30 unique floats over 1000 rows all classify as documented; the override wins and a contradictory override is rejected — problem_type=regression on a string label column is an Err naming the column, not a silent cast. Epic #3370.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - P0 + - enhancement + - crux + - pareto-autogluon + notes: null +- id: PMAT-3373 + github_issue: 3373 + item_type: task + title: 'P0: Quality presets (medium / good / high / best / extreme) that name a model portfolio and a time budget — CRUX-O-03' + status: planned + priority: critical + assigned_to: null + created: 2026-09-16T12:00:00Z + updated: 2026-09-16T12:00:00Z + spec: null + acceptance_criteria: + - 'CRUX-O-03, competitor autogluon, demand 5. No preset vocabulary. AutoTuner takes a SearchSpace the caller hand-builds (crates/aprender-core/src/automl/params.rs); there is no named bundle of {models, bagging, stacking, time_limit}. FALSIFIABLE (contracts/crux-O-03-v1.yaml): every preset name resolves to a portfolio and unknown names are rejected with the valid list — the five quality presets each yield a non-empty ordered model list; `presets="bestest"` is an Err whose message contains all five valid names; presets are ordered: a higher preset never fits FEWER model families than the one below it — for medium < good < high < best the family count is monotone non-decreasing, asserted pairwise. Epic #3370.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - P0 + - enhancement + - crux + - pareto-autogluon + notes: null +- id: PMAT-3374 + github_issue: 3374 + item_type: task + title: 'P0: Leaderboard: per-model validation/test score, fit time, predict time and stack level — CRUX-O-04' + status: planned + priority: critical + assigned_to: null + created: 2026-09-16T12:00:00Z + updated: 2026-09-16T12:00:00Z + spec: null + acceptance_criteria: + - 'CRUX-O-04, competitor autogluon, demand 5. No leaderboard type. GridSearchCVResult in model_selection/ ranks parameter settings of one estimator; TuneResult in automl/tuner.rs is a single best trial. Nothing tabulates several fitted models with timings. FALSIFIABLE (contracts/crux-O-04-v1.yaml): the leaderboard is sorted by validation score descending and its columns are fixed — columns == [model, score_val, score_test?, pred_time_val, fit_time, stack_level, fit_order] and score_val is non-increasing row to row; timings are measured, not defaulted — every fit_time and pred_time_val is > 0 after a real fit; a leaderboard built with no fit has zero rows, not zero timings; apr automl leaderboard prints the same table from a saved artifact — `apr automl leaderboard model.apr --json` emits the rows byte-equal to the in-process leaderboard. Epic #3370.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - P0 + - enhancement + - crux + - pareto-autogluon + notes: null +- id: PMAT-3375 + github_issue: 3375 + item_type: task + title: 'P0: Automatic feature-type inference and the AutoML feature pipeline (numeric, categorical, datetime, text n-gram, drop-unique, drop-duplicate) — CRUX-O-05' + status: planned + priority: critical + assigned_to: null + created: 2026-09-16T12:00:00Z + updated: 2026-09-16T12:00:00Z + spec: null + acceptance_criteria: + - 'CRUX-O-05, competitor autogluon, demand 5. Encoders exist (LabelEncoder, OneHotEncoder, OrdinalEncoder, StandardScaler, PolynomialFeatures in crates/aprender-core/src/preprocessing/) but every one is applied by hand to a column the caller already typed. There is no pass that reads a raw DataFrame, infers each column''s kind, and emits a fitted transform. Datetime expansion and text n-gram features do not exist. TfidfVectorizer exists in text/ but is not wired to a tabular pipeline. FALSIFIABLE (contracts/crux-O-05-v1.yaml): column kinds are inferred from raw values — a fixture CSV with int, float, low-cardinality string, high-cardinality string, ISO datetime and free-text columns is typed as {numeric, numeric, categorical, text, datetime, text} exactly; constant and duplicate columns are dropped and the drop is reported — a column with one unique value and an exact duplicate of another column are both absent from the transformed output AND named in the fit report; the fitted pipeline is deterministic under transform — transform(train) then transform(train) are byte-identical and transform(test) never sees a category unseen at fit as anything but the reserved unknown code. Epic #3370.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - P0 + - enhancement + - crux + - pareto-autogluon + notes: null +- id: PMAT-3376 + github_issue: 3376 + item_type: task + title: 'P1: K-fold bagging with out-of-fold predictions (num_bag_folds, predict_oof) — CRUX-O-06' + status: planned + priority: high + assigned_to: null + created: 2026-09-16T12:00:00Z + updated: 2026-09-16T12:00:00Z + spec: null + acceptance_criteria: + - 'CRUX-O-06, competitor autogluon, demand 4. KFold and StratifiedKFold exist (model_selection/) and cross_validate scores them, but no wrapper trains one child per fold, keeps all children, averages them at predict time and exposes the out-of-fold matrix. RandomForest bags trees internally and is not reusable for other estimators. FALSIFIABLE (contracts/crux-O-06-v1.yaml): OOF predictions cover every training row exactly once — for n rows and k folds the OOF matrix has n rows, no NaN, and each row was predicted by the one child that did not see it (asserted through a fold-id trace); bagged prediction is the mean of the children — predict_proba of the bag equals the elementwise mean of the k children''s predict_proba within 1e-12. Epic #3370.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - P1 + - enhancement + - crux + - pareto-autogluon + notes: null +- id: PMAT-3377 + github_issue: 3377 + item_type: task + title: 'P1: Multi-layer stack ensembling with a leakage guard (num_stack_levels, auto_stack, dynamic_stacking) — CRUX-O-07' + status: planned + priority: high + assigned_to: null + created: 2026-09-16T12:00:00Z + updated: 2026-09-16T12:00:00Z + spec: null + acceptance_criteria: + - 'CRUX-O-07, competitor autogluon, demand 4. No stacking. crates/aprender-core/src/stack/ is a deployment-health module (StackHealth, InferenceConfig), not a model stacker. ensemble/ holds MixtureOfExperts gating only. FALSIFIABLE (contracts/crux-O-07-v1.yaml): level-2 features are OOF, never in-sample — a mutation that feeds in-sample level-1 predictions to level 2 is detected by the leak test: the L2 holdout score on a pure-noise label rises above chance (asserted RED) while the OOF path stays at chance; dynamic stacking falls back when stacking hurts — on a fixture where L2 holdout score < L1 holdout score, the final model is the L1 ensemble and the decision is recorded in the fit summary. Epic #3370.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - P1 + - enhancement + - crux + - pareto-autogluon + notes: null +- id: PMAT-3378 + github_issue: 3378 + item_type: task + title: 'P0: Greedy weighted-ensemble selection over fitted models (Caruana ensemble selection) — CRUX-O-08' + status: planned + priority: critical + assigned_to: null + created: 2026-09-16T12:00:00Z + updated: 2026-09-16T12:00:00Z + spec: null + acceptance_criteria: + - 'CRUX-O-08, competitor autogluon, demand 5. No ensemble-selection algorithm. MixtureOfExperts learns a gating network (ensemble/moe.rs); nothing performs the forward greedy selection with replacement over base-model validation predictions that yields non-negative weights summing to 1. FALSIFIABLE (contracts/crux-O-08-v1.yaml): weights are a probability vector and the ensemble never scores below its best member — sum(w)=1, all w>=0, and validation metric(ensemble) >= max over members within 1e-9, on 3 fixtures; selection is greedy with replacement and reproducible — with ensemble_size=25 the weight of a member equals its selection count / 25; two runs on the same inputs produce identical weights. Epic #3370.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - P0 + - enhancement + - crux + - pareto-autogluon + notes: null +- id: PMAT-3379 + github_issue: 3379 + item_type: task + title: 'P0: Time-budgeted portfolio fit: time_limit split across models, each model early-stopped on its share — CRUX-O-09' + status: planned + priority: critical + assigned_to: null + created: 2026-09-16T12:00:00Z + updated: 2026-09-16T12:00:00Z + spec: null + acceptance_criteria: + - 'CRUX-O-09, competitor autogluon, demand 5. TimeBudget and EarlyStopping exist in automl/tuner.rs but budget ONE tuner. There is no allocation of a global limit across an ordered portfolio, no per-model time share, and no ''skip the rest'' when the budget is exhausted. FALSIFIABLE (contracts/crux-O-09-v1.yaml): the wall-clock of fit never exceeds time_limit by more than the tolerance — with time_limit=5s on a portfolio that would take >60s unconstrained, elapsed <= 5s + 1s AND at least one model was skipped with reason=budget in the summary; the budget is redistributed when a model finishes early — a model that uses 10% of its share returns the remainder to the pool; the next model''s share is asserted larger than the naive equal split. Epic #3370.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - P0 + - enhancement + - crux + - pareto-autogluon + notes: null +- id: PMAT-3380 + github_issue: 3380 + item_type: task + title: 'P1: Predictor-level permutation feature importance with p-values and confidence intervals — CRUX-O-10' + status: planned + priority: high + assigned_to: null + created: 2026-09-16T12:00:00Z + updated: 2026-09-16T12:00:00Z + spec: null + acceptance_criteria: + - 'CRUX-O-10, competitor autogluon, demand 4. PermutationImportance exists in crates/aprender-core/src/interpret/ for a single estimator. Missing: the predictor-level call on raw (pre-pipeline) columns, num_shuffle_sets repeats, stddev / p-value / p99 columns, and subsampling. AutoGluon 1.6 also cut this call''s memory 25x (#5645). FALSIFIABLE (contracts/crux-O-10-v1.yaml): importance is reported per raw input column — on a fixture whose datetime column expands to 4 features, the importance table has one row for the datetime column, not four; a pure-noise column has importance statistically indistinguishable from zero — with num_shuffle_sets=10 the noise column''s p-value > 0.05 AND the signal column''s p-value < 0.01 on the same run. Epic #3370.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - P1 + - enhancement + - crux + - pareto-autogluon + notes: null +- id: PMAT-3381 + github_issue: 3381 + item_type: task + title: 'P1: Decision-threshold calibration for binary metrics (calibrate_decision_threshold) — CRUX-O-11' + status: planned + priority: high + assigned_to: null + created: 2026-09-16T12:00:00Z + updated: 2026-09-16T12:00:00Z + spec: null + acceptance_criteria: + - 'CRUX-O-11, competitor autogluon, demand 4. Probability calibration exists (PlattScaling, IsotonicRegression, TemperatureScaling in calibration.rs) but nothing searches the decision threshold that maximises f1 / balanced_accuracy / mcc on validation data and stores it on the predictor (`decision_threshold`, `set_decision_threshold`). FALSIFIABLE (contracts/crux-O-11-v1.yaml): the calibrated threshold beats 0.5 on the calibration metric and the gain is asserted, not the search — on an imbalanced fixture (5% positives) f1 at the calibrated threshold > f1 at 0.5 by >= 0.05 absolute; the threshold is persisted with the model — save then load reproduces predict() bit-identically including the threshold; a mutation that resets the threshold to 0.5 on load turns this RED. Epic #3370.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - P1 + - enhancement + - crux + - pareto-autogluon + notes: null +- id: PMAT-3382 + github_issue: 3382 + item_type: task + title: 'P2: refit_full: retrain the selected models on train+validation after model selection — CRUX-O-12' + status: planned + priority: medium + assigned_to: null + created: 2026-09-16T12:00:00Z + updated: 2026-09-16T12:00:00Z + spec: null + acceptance_criteria: + - 'CRUX-O-12, competitor autogluon, demand 3. No refit-on-full-data step. cross_validate and grid_search return scores; the model returned is the one fitted on a fold, not on all rows. FALSIFIABLE (contracts/crux-O-12-v1.yaml): the refit model saw every row — the refit estimator''s training-row count equals n_train + n_val, asserted through the fitted row count it reports; refit keeps the selected hyperparameters and drops the bag children — the artifact after refit has one child per selected model and its hyperparameters are byte-equal to the pre-refit winner''s. Epic #3370.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - P2 + - enhancement + - crux + - pareto-autogluon + notes: null +- id: PMAT-3383 + github_issue: 3383 + item_type: task + title: 'P2: Model distillation: compress the ensemble into one fast student — CRUX-O-13' + status: planned + priority: medium + assigned_to: null + created: 2026-09-16T12:00:00Z + updated: 2026-09-16T12:00:00Z + spec: null + acceptance_criteria: + - 'CRUX-O-13, competitor autogluon, demand 3. Distillation exists only for LLMs in the training crate (knowledge distillation of transformers); nothing trains a single tabular student on the teacher ensemble''s soft labels with data augmentation. FALSIFIABLE (contracts/crux-O-13-v1.yaml): the student is faster and within tolerance of the teacher — student pred_time < 0.25 x teacher pred_time AND student validation score >= teacher score - 0.02 on a fixture; augmentation produces rows the training set does not contain — with augment_method=spunge the student''s training set has > n_train rows and the added rows are not row-equal to any original. Epic #3370.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - P2 + - enhancement + - crux + - pareto-autogluon + notes: null +- id: PMAT-3384 + github_issue: 3384 + item_type: task + title: 'P1: Deployment artifact: clone_for_deployment / keep_only_best / save_space / persist into one loadable file — CRUX-O-14' + status: planned + priority: high + assigned_to: null + created: 2026-09-16T12:00:00Z + updated: 2026-09-16T12:00:00Z + spec: null + acceptance_criteria: + - 'CRUX-O-14, competitor autogluon, demand 4. Single estimators serialize to .apr (bundle/, serialization/). No artifact holds a fitted feature pipeline (O-05) plus several models plus ensemble weights plus a decision threshold and loads them as one predictor. Nothing prunes non-selected models from disk. FALSIFIABLE (contracts/crux-O-14-v1.yaml): a deployment clone is smaller and predicts identically — clone_for_deployment artifact bytes < 0.5 x full artifact bytes AND predict() on the clone is bit-identical to predict() on the original for the test fixture; the artifact is self-describing and refuses a schema drift — load() on an artifact whose feature schema disagrees with the input columns is an Err naming the first mismatched column, not a wrong prediction. Epic #3370.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - P1 + - enhancement + - crux + - pareto-autogluon + notes: null +- id: PMAT-3385 + github_issue: 3385 + item_type: task + title: 'P2: Inference-latency constraint during model selection (infer_limit, infer_limit_batch_size) — CRUX-O-15' + status: planned + priority: medium + assigned_to: null + created: 2026-09-16T12:00:00Z + updated: 2026-09-16T12:00:00Z + spec: null + acceptance_criteria: + - 'CRUX-O-15, competitor autogluon, demand 3. No model or ensemble is ever excluded for being slow at predict time; leaderboard timings (O-04) do not exist to compare against. FALSIFIABLE (contracts/crux-O-15-v1.yaml): the selected ensemble respects the per-row latency limit — with infer_limit=L the measured pred_time per row of the final model <= L AND at least one faster-but-worse model was preferred over a slower-but-better one (asserted on a fixture built to force the trade). Epic #3370.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - P2 + - enhancement + - crux + - pareto-autogluon + notes: null +- id: PMAT-3386 + github_issue: 3386 + item_type: task + title: 'P2: Fit diagnostics: fit_summary, model_failures and learning curves — CRUX-O-16' + status: planned + priority: medium + assigned_to: null + created: 2026-09-16T12:00:00Z + updated: 2026-09-16T12:00:00Z + spec: null + acceptance_criteria: + - 'CRUX-O-16, competitor autogluon, demand 3. ProgressCallback in automl/tuner.rs streams trial results; there is no post-fit summary object listing models trained, models failed with their error, per-model hyperparameters and per-iteration validation curves. FALSIFIABLE (contracts/crux-O-16-v1.yaml): a model that raises during fit is recorded, not swallowed and not fatal — a portfolio containing a deliberately failing model finishes; model_failures() has exactly one row naming the model and the error string; the leaderboard omits it; learning curves have one point per boosting/epoch iteration — for a GBM with n_estimators=50 and learning_curves=true the curve has 50 validation points, monotone non-increasing after early-stopping''s best iteration is asserted absent. Epic #3370.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - P2 + - enhancement + - crux + - pareto-autogluon + notes: null +- id: PMAT-3387 + github_issue: 3387 + item_type: task + title: 'P1: Tabular foundation model: in-context prediction with a pretrained transformer (TabPFN / TabICL / Mitra class) — CRUX-O-17' + status: planned + priority: high + assigned_to: null + created: 2026-09-16T12:00:00Z + updated: 2026-09-16T12:00:00Z + spec: null + acceptance_criteria: + - 'CRUX-O-17, competitor autogluon, demand 4. No tabular in-context learner. nn/ and the inference crates run causal LMs; nothing consumes (X_train, y_train, X_test) as one context and predicts without gradient steps. AutoGluon 1.4-1.6 added TabPFNv2/2.5/2.6/3, TabICL/v2, Mitra, TabDPT, Nori and made them the extreme preset. FALSIFIABLE (contracts/crux-O-17-v1.yaml): zero-gradient prediction matches a pinned reference within tolerance — loading a pinned small checkpoint via apr pull and predicting a 100-row fixture matches the committed reference probabilities within 1e-4; the context limit is enforced, not silently truncated — a context of rows > the model''s documented max is an Err naming the limit; a mutation that truncates instead turns this RED. Epic #3370.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - P1 + - enhancement + - crux + - pareto-autogluon + notes: null +- id: PMAT-3388 + github_issue: 3388 + item_type: task + title: 'P2: Memory-aware fit: per-model memory estimate and a memory_limit that skips models that would not fit — CRUX-O-18' + status: planned + priority: medium + assigned_to: null + created: 2026-09-16T12:00:00Z + updated: 2026-09-16T12:00:00Z + spec: null + acceptance_criteria: + - 'CRUX-O-18, competitor autogluon, demand 3. No estimator reports an expected peak memory before fitting and nothing checks a limit. AutoGluon 1.6 spent 4 PRs on this (#5757, #5768, #5791, GPU budgeting for parallel folds). FALSIFIABLE (contracts/crux-O-18-v1.yaml): a model whose estimate exceeds the limit is skipped with reason=memory — with memory_limit=64MiB on a fixture where the estimate for the largest model is > 64MiB, that model is absent from the leaderboard and present in the skip list with its estimate; the estimate is not a constant — the estimate for a 10x larger fixture is asserted larger than for the base fixture; a mutation returning a constant turns this RED. Epic #3370.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - P2 + - enhancement + - crux + - pareto-autogluon + notes: null +- id: PMAT-3389 + github_issue: 3389 + item_type: task + title: 'P0: Multi-series forecasting predictor: (item_id, timestamp) panel data, prediction_length, freq — CRUX-O-19' + status: planned + priority: critical + assigned_to: null + created: 2026-09-16T12:00:00Z + updated: 2026-09-16T12:00:00Z + spec: null + acceptance_criteria: + - 'CRUX-O-19, competitor autogluon, demand 5. crates/aprender-core/src/time_series/mod.rs is one struct, ARIMA, on one f32 series (fit/forecast/order). There is no panel container keyed by item and timestamp, no frequency, no horizon-first API and no per-item forecast. FALSIFIABLE (contracts/crux-O-19-v1.yaml): a panel of N items forecasts N x prediction_length rows — on a fixture of 5 items with 200 hourly points each and prediction_length=24 the output has exactly 120 rows, each (item_id, timestamp) unique, timestamps continuing each item''s last stamp at freq=h; irregular timestamps are rejected or regularised, never silently misaligned — an item with a missing hour is an Err naming the item and gap unless fill=forward is passed, in which case the filled row is flagged. Epic #3370.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - P0 + - enhancement + - crux + - pareto-autogluon + notes: null +- id: PMAT-3390 + github_issue: 3390 + item_type: task + title: 'P0: Probabilistic forecasts: quantile_levels and the forecasting metric family (WQL, MQL, MASE, SMAPE, RMSSE, WAPE) — CRUX-O-20' + status: planned + priority: critical + assigned_to: null + created: 2026-09-16T12:00:00Z + updated: 2026-09-16T12:00:00Z + spec: null + acceptance_criteria: + - 'CRUX-O-20, competitor autogluon, demand 5. ARIMA.forecast returns a point path; metrics/probabilistic.rs holds classification-probability metrics, and metrics/regression.rs has no seasonal-scaled (MASE/RMSSE) or quantile (WQL/MQL) losses. FALSIFIABLE (contracts/crux-O-20-v1.yaml): quantile forecasts are monotone in the quantile level — for every (item, step) q0.1 <= q0.5 <= q0.9, asserted over the whole fixture; a mutation that shuffles the quantile columns turns this RED; each metric matches the AutoGluon reference value on a pinned fixture — WQL, MASE, SMAPE, RMSSE, WAPE and MQL computed on a committed (y_true, y_pred, quantiles) fixture equal the reference values produced by autogluon.timeseries.metrics within 1e-9. Epic #3370.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - P0 + - enhancement + - crux + - pareto-autogluon + notes: null +- id: PMAT-3391 + github_issue: 3391 + item_type: task + title: 'P1: Rolling-window backtesting: num_val_windows, refit_every_n_windows, backtest_predictions — CRUX-O-21' + status: planned + priority: high + assigned_to: null + created: 2026-09-16T12:00:00Z + updated: 2026-09-16T12:00:00Z + spec: null + acceptance_criteria: + - 'CRUX-O-21, competitor autogluon, demand 4. No time-aware validation. KFold shuffles rows; nothing cuts the last k horizons of each item as expanding-window validation sets, and there is no API that returns the validation forecasts for inspection. FALSIFIABLE (contracts/crux-O-21-v1.yaml): validation windows never contain a timestamp later than the training cut for that window — for num_val_windows=3 and val_step_size=h, each window''s max training timestamp < min validation timestamp per item, asserted for every item and window; backtest_predictions rows align with backtest_targets — the two frames have identical (window, item_id, timestamp) index sets and no NaN targets. Epic #3370.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - P1 + - enhancement + - crux + - pareto-autogluon + notes: null +- id: PMAT-3392 + github_issue: 3392 + item_type: task + title: 'P2: Known covariates, past covariates and static features in forecasting — CRUX-O-22' + status: planned + priority: medium + assigned_to: null + created: 2026-09-16T12:00:00Z + updated: 2026-09-16T12:00:00Z + spec: null + acceptance_criteria: + - 'CRUX-O-22, competitor autogluon, demand 3. ARIMA is univariate. No container carries per-item static features or time-varying covariates, and no model consumes them. FALSIFIABLE (contracts/crux-O-22-v1.yaml): a known covariate that fully determines the target is used — on a fixture where y = 10*holiday + noise, a model given known_covariates has MASE < 0.5 x the same model without them; future covariates missing for the horizon is an error — predict() without known_covariates for all prediction_length steps is an Err naming the first missing timestamp. Epic #3370.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - P2 + - enhancement + - crux + - pareto-autogluon + notes: null +- id: PMAT-3393 + github_issue: 3393 + item_type: task + title: 'P1: Local statistical baselines: SeasonalNaive, ETS, Theta, AutoARIMA, Croston — CRUX-O-23' + status: planned + priority: high + assigned_to: null + created: 2026-09-16T12:00:00Z + updated: 2026-09-16T12:00:00Z + spec: null + acceptance_criteria: + - 'CRUX-O-23, competitor autogluon, demand 4. ARIMA exists (fixed order; no auto-order search). SeasonalNaive, ETS, Theta and the intermittent-demand family (Croston, ADIDA, IMAPA) are absent. AutoGluon runs these as its ''local'' tier (timeseries/models/local/) and they anchor every leaderboard. FALSIFIABLE (contracts/crux-O-23-v1.yaml): SeasonalNaive is exactly the lag-m copy — forecast[t] == y[t - m] for the whole horizon on a fixture with m=24, byte-equal; AutoARIMA selects the planted order — on a fixture generated from ARIMA(2,1,1) the selected (p,d,q) equals (2,1,1) in >= 9 of 10 seeds; ETS and Theta match the statsforecast reference — point forecasts on the AirPassengers fixture equal the statsforecast reference within 1e-6. Epic #3370.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - P1 + - enhancement + - crux + - pareto-autogluon + notes: null +- id: PMAT-3394 + github_issue: 3394 + item_type: task + title: 'P1: Zero-shot pretrained forecaster (Chronos-2 / Toto-2 class) loaded by apr pull, with optional fine-tuning — CRUX-O-24' + status: planned + priority: high + assigned_to: null + created: 2026-09-16T12:00:00Z + updated: 2026-09-16T12:00:00Z + spec: null + acceptance_criteria: + - 'CRUX-O-24, competitor autogluon, demand 4. apr pull fetches LLM checkpoints (Category A) and the inference crates run decoder transformers, but no forecasting head exists: nothing tokenises a numeric series into the model''s input, samples a horizon, and maps it back to quantiles. FALSIFIABLE (contracts/crux-O-24-v1.yaml): zero-shot output matches a pinned reference — a pinned small checkpoint pulled by `apr pull` forecasts the committed fixture within 1e-3 of the reference quantiles; fine-tuning changes the weights and improves the in-domain metric — after fine_tune on the fixture the WQL improves by >= 5% relative AND at least one weight tensor differs from the pulled checkpoint. Epic #3370.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - P1 + - enhancement + - crux + - pareto-autogluon + notes: null +- id: PMAT-3401 + github_issue: 3401 + item_type: task + title: 'Admit AutoGluon 1.6.3 to CRUX as category O: 24 DRAFT contracts crux-O-01..24 with LIVE-PENDING gates (no implementation, no CLI, no tests), CRUX_COMPETITORS 14->15 in validator.rs + both crux_intake_tests.rs lists, CATEGORY_NAMES[O] in scripts/crux_scaffold_contracts.py, 24 master-registry rows + evidence_sources.autogluon, spec v2.3 §3/§5/§6, evidence/crux/autogluon/ (4 files), 26 roadmap fragments (PMAT-3370 epic, PMAT-3371..3394 stories, PMAT-3401 this ticket) + regenerated roadmap.yaml, and the three corpus derivatives (census, contracts.nt, README CONTRACT_COUNT) regenerated to the merged tree — child of #3370' + status: in_progress + priority: critical + assigned_to: null + created: 2026-09-16T16:30:00Z + updated: 2026-09-16T16:30:00Z + spec: docs/specifications/crux-competitive-research-ux-workflows.md + acceptance_criteria: + - 'Exactly this inventory, nothing more: contracts/crux-O-01..24-v1.yaml (24 files, registry: false, every gate LIVE-PENDING); crates/aprender-contracts/src/schema/validator.rs (CRUX_COMPETITORS 14->15, + autogluon with rationale) and crux_intake_tests.rs (autogluon in the corpus-vocabulary list and in the not-a-BEAT-pillar list); scripts/crux_scaffold_contracts.py (CATEGORY_NAMES O); contracts/crux-competitive-research-ux-v1.yaml (24 stories rows, coverage_intake 43/77/171/291, evidence_sources.autogluon, autogluon reference); docs/specifications/crux-competitive-research-ux-workflows.md (v2.3 header, §3 rows for N and O, §5 Category O table, §6 note); evidence/crux/autogluon/{README.md,api-surface.md,hello.sh,readme-verbs.txt}; docs/roadmaps/entries/PMAT-3370.yaml + PMAT-3371..3394.yaml + PMAT-3401.yaml (26 fragments) and docs/roadmaps/roadmap.yaml regenerated by the aggregator; README.md CONTRACT_COUNT 1842->1866. Absent on purpose: library code, apr CLI wiring, test bodies — those are the 24 children of #3370.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - P0 + - enhancement + - crux + - pareto-autogluon + notes: 'ACCEPTANCE, stated as invariants and not as counts (the first version of this row pinned "README CONTRACT_COUNT 1842->1866" and "coverage_intake 267->291" from the 2026-09-16 tree; main moved and the numbers described a tree that no longer existed, which is what the AD-04 quorum on #3395 round 0 correctly refused): (1) 24 new contract files contracts/crux-O-01-v1.yaml .. crux-O-24-v1.yaml, each metadata.category O, competitor AutoGluon, status draft, intake_status missing, registry false, and each passing pv validate; (2) CRUX_COMPETITORS grows by exactly one entry (autogluon) in crates/aprender-contracts/src/schema/validator.rs and in both crux_intake_tests.rs lists; (3) CATEGORY_NAMES gains O in scripts/crux_scaffold_contracts.py; (4) the master registry gains one row per new contract and evidence_sources.autogluon; (5) 26 roadmap fragments exist (PMAT-3370, PMAT-3371..PMAT-3394, PMAT-3401) and docs/roadmaps/roadmap.yaml equals aggregate(entries/), additive vs origin/main (deleted=0, reserialised=0); (6) contracts/census.json n_files equals origin/main''s n_files at merge time plus 24, contracts/contracts.nt equals a fresh pv extract of the merged tree, and README''s CONTRACT_COUNT blocks equal census n_files — the three derivatives ride in this PR because adding a contract stales all three (#3569). Known and NOT in scope: the census files these 24 under kind kernel because they carry no metadata.kind and registry:false (main''s crux contracts carry registry:true and file under registry); a draft/intake bucket for the census is a census question (#3640-class), not this PR''s.' +- id: PMAT-3427 + github_issue: 3427 + item_type: task + title: 'docs(plan): PP-QUANT-001 research + 0.69 must-carry slice M — measured tables, fix-diff Pareto, implementation' + status: planned + priority: medium + assigned_to: null + created: 2026-09-17T11:33:02Z + updated: 2026-09-17T11:33:02Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:docs + notes: null +- id: PMAT-3428 + github_issue: 3428 + item_type: task + title: 'EPIC: PP-TENSOR-001 — a tensor that has no bytes is a different type from one that does (MoE / tied-embedding ' + status: planned + priority: medium + assigned_to: null + created: 2026-09-17T11:33:03Z + updated: 2026-09-17T11:33:03Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:docs + notes: null +- id: PMAT-3429 + github_issue: 3429 + item_type: task + title: 'PP-QUANT-001 M3: regression fixtures — #1749 #1789 #2535 #3341 (+ #3091 reopen) on tiny synthetic GGUFs, obser' + status: planned + priority: medium + assigned_to: null + created: 2026-09-17T11:33:03Z + updated: 2026-09-17T11:33:03Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-3430 + github_issue: 3430 + item_type: task + title: 'PP-QUANT-001 M1: one `#[repr(u32)] GgmlType` (43 rows: 35 live + 8 Removed) + `TRAITS[43]` below core/compute/' + status: planned + priority: medium + assigned_to: null + created: 2026-09-17T11:33:04Z + updated: 2026-09-17T11:33:04Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + - orch:fable + notes: 'orch-basis:M>=3 — owning modules measured in the PMAT-3427 receipt: aprender-core, aprender-compute, aprender-serve (+ a leaf crate); plan quorum before code' +- id: PMAT-3431 + github_issue: 3431 + item_type: task + title: 'PP-QUANT-001 M2: reconciliation gate — `GgmlType` vs the vendored `ggml.h` id list at a pinned sha; exhaustive' + status: planned + priority: medium + assigned_to: null + created: 2026-09-17T11:33:04Z + updated: 2026-09-17T11:33:04Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-3432 + github_issue: 3432 + item_type: task + title: 'PP-QUANT-001 M4: `tensor_byte_size` and ONE refusal site read `TRAITS` — closes the #3091-reopen / #3341 class' + status: planned + priority: medium + assigned_to: null + created: 2026-09-17T11:33:05Z + updated: 2026-09-17T11:33:05Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-3433 + github_issue: 3433 + item_type: task + title: 'PP-TENSOR-001 T1: typed `TensorStorage` — a dense consumer cannot receive an MoE placeholder' + status: planned + priority: medium + assigned_to: null + created: 2026-09-17T11:33:05Z + updated: 2026-09-17T11:33:05Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + - orch:fable + notes: 'orch-basis:M>=3 — owning modules measured in the PMAT-3427 receipt: aprender-core, aprender-compute, aprender-serve (+ a leaf crate); plan quorum before code' +- id: PMAT-3434 + github_issue: 3434 + item_type: task + title: 'PP-TENSOR-001 T2: sentinel ban — `qtype: 0` + `byte_size: 0` may not be constructed; 0 is F32' + status: planned + priority: medium + assigned_to: null + created: 2026-09-17T11:33:06Z + updated: 2026-09-17T11:33:06Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-3435 + github_issue: 3435 + item_type: task + title: 'PP-TENSOR-001 T3: diagnostic contract — an absent tensor is reported as absent, never as truncated, corrupt, o' + status: planned + priority: medium + assigned_to: null + created: 2026-09-17T11:33:06Z + updated: 2026-09-17T11:33:06Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-3441 + github_issue: 3441 + item_type: task + title: 'PP-QUANT-001 Q3: tier-0 scalar dequant for 35/35 live ggml types — every unsupported-type refusal becomes a sl' + status: planned + priority: medium + assigned_to: null + created: 2026-09-17T11:33:07Z + updated: 2026-09-17T11:33:07Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-3442 + github_issue: 3442 + item_type: task + title: 'PP-QUANT-001 Q5: upstream drift job — a new `ggml_type` id upstream opens an issue here the day it lands' + status: planned + priority: medium + assigned_to: null + created: 2026-09-17T11:33:07Z + updated: 2026-09-17T11:33:07Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-3443 + github_issue: 3443 + item_type: task + title: 'PP-QUANT-001 P4: #3077 support table GENERATED from `TRAITS` (type × backend × tier)' + status: planned + priority: medium + assigned_to: null + created: 2026-09-17T11:33:08Z + updated: 2026-09-17T11:33:08Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:docs + notes: null +- id: PMAT-3445 + github_issue: 3445 + item_type: task + title: 'release train: a tag was cut while its milestone had open issues — 0.68.0 shipped with 2 open, one a user-faci' + status: planned + priority: medium + assigned_to: null + created: 2026-09-17T11:33:08Z + updated: 2026-09-17T11:33:08Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-3446 + github_issue: 3446 + item_type: task + title: 'docs(release): APR-RELEASE-001 has no must-carry section on `main` — land §1.5 (must-carry rows; T-0 waits; > ' + status: planned + priority: medium + assigned_to: null + created: 2026-09-17T11:33:09Z + updated: 2026-09-17T11:33:09Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:docs + notes: null +- id: PMAT-3451 + github_issue: 3451 + item_type: task + title: 'ONT-6: one Verdict lattice, Kani-proved; per-repo arming; exit-vocabulary mapping' + status: planned + priority: high + assigned_to: null + created: 2026-09-17T13:19:20Z + updated: 2026-09-17T13:19:20Z + spec: docs/specifications/paiml-ontology.md + acceptance_criteria: + - 'verdict.rs: Verdict {Fail, Unknown(Reason), Pass}, 15 reasons in §3.4 order, meet = min, arm only on Pass, exit 0/1/2 with `decline: `; unit tests over all 17 elements; cargo kani --harness kani_ont_6_1/2/3 VERIFICATION SUCCESSFUL' + - 'arming.rs: armed_gates from /lint-baseline.json (absent file or key -> the default 8, reverse-coverage unarmed by ruling); explicit [] -> Unknown(NotArmed) (R-2); check_monotone -> ArmedGatesShrank; arming is the declaration alone: a gate a flag ran but the declaration does not arm prints Unknown(NotArmed) and stays out of the meet' + - 'pv lint: every GateResult carries verdict; LintReport carries verdict, armed_gates, not_armed, armed_monotone; exit is the armed meet (Pass 0, Fail 1 reject:, Unknown 2 decline:); a dropped committed gate exits 3 error: armed_gates shrank; --armed-baseline-ref fails closed, the default comparand with nothing to compare prints NOT CHECKED (no comparand)' + - 'contracts/lint-baseline.json arms the 8; check_ont_ratchet.sh --write preserves armed_gates in place; contracts/ont-verdict-lattice-v1.yaml validates with KANI-ONT-6-1/2/3' + - 'operator ruling "Refactor the offenders": run_verify_gate, collect_test_fns and print_findings_grouped below cyclomatic 30 / cognitive 25 with pv lint contracts/ JSON unchanged; their three complexity_baseline.txt rows removed' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + - orch:fable + - orch-basis:state + notes: 'ONT-001 v4.4 row ONT-6. RAH-005 binding filed in paiml/paiml-implement. Receipt: docs/audits/impl-PMAT-3451-receipt.md' +- id: PMAT-3459 + github_issue: 3459 + item_type: task + title: 'release train: move the release autopilot''s tag path into the repo; tag step calls check_milestone_cut.sh (#3459)' + status: planned + priority: critical + assigned_to: null + created: 2026-09-17T15:29:02Z + updated: 2026-09-17T15:29:02Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + - P0 + - must-carry:0.69.0 + notes: null +- id: PMAT-3460 + github_issue: 3460 + item_type: task + title: 'check_milestone_cut.sh: exempt the release epic by issue number from 06x §5, not title match (#3460)' + status: planned + priority: medium + assigned_to: null + created: 2026-09-17T15:29:02Z + updated: 2026-09-17T15:29:02Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-3461 + github_issue: 3459 + item_type: task + title: 'Register PMAT-3459 and PMAT-3460 in the roadmap so the AD-04 quorum for PR #3461 can run (registration only; the tag-path implementation is #3599, the epic-by-number follow-up is #3460)' + status: planned + priority: high + assigned_to: null + created: 2026-09-20T22:53:14Z + updated: 2026-09-20T22:53:14Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:triage + notes: 'ACCEPTANCE (this row is PR #3461 itself, a roadmap-only registration): (1) docs/roadmaps/entries/PMAT-3459.yaml exists with id PMAT-3459, github_issue 3459, priority critical, and a title that transcribes issue #3459 — the release autopilot''s tag path moves into the repo and the tag step calls check_milestone_cut.sh; (2) docs/roadmaps/entries/PMAT-3460.yaml exists with id PMAT-3460, github_issue 3460, and a title that transcribes issue #3460 — check_milestone_cut.sh exempts the release epic by issue number, not title match; (3) docs/roadmaps/roadmap.yaml equals aggregate(entries/) and the diff vs origin/main is additive only (deleted=0, reserialised=0) after the merge of origin/main that picked up PMAT-3539; (4) the PR body carries keep-open for #3459, #3460 and #3080 and no sentence in it is parsed by GitHub as closing #3459 (the must-carry whose criterion is the tag, which this PR does not deliver). NOT in scope: any code, script or measurement for PMAT-3459 or PMAT-3460 — the tag path itself is PR #3599 and is judged there. A lane that finds an entry mis-transcribed, missing or invented FAILs this row.' +- id: PMAT-3465 + github_issue: 3465 + item_type: task + title: 'b2-gpu: aprender-gpu lib tests on hardware at the tag (rule 14)' + status: planned + priority: medium + assigned_to: null + created: 2026-09-17T18:12:33Z + updated: 2026-09-17T18:12:33Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-3468 + github_issue: 3468 + item_type: task + title: preflight R6 judges the cycle, not the shape + status: planned + priority: medium + assigned_to: null + created: 2026-09-17T20:26:51Z + updated: 2026-09-17T20:26:51Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-3471 + github_issue: 3471 + item_type: task + title: 'ONT-2b: Σ — contracts/ontology.yaml with entity_types and extractors; symbol-level check on formal:' + status: planned + priority: medium + assigned_to: null + created: 2026-09-17T20:39:42Z + updated: 2026-09-17T20:39:42Z + spec: docs/specifications/paiml-ontology.md + acceptance_criteria: + - 'Σ: contracts/ontology.yaml declares concepts, roles, 66 symbols, worlds, agents, 7 entity_types each naming a declared extractor, not_expressible, and a readers map claiming every populated key; ontology/sigma.rs loads it and refuses the four malformed-Σ classes at exit 3' + - '`pv lint --gate ` runs ONE gate and reports only it, mapping the verdict through ONT-6''s lattice: Pass 0, corpus violation 1 reject, no Σ 2 decline, malformed Σ 3 error; unknown gate names are refused' + - 'the sigma gate: PV-ONT-001 entity.type not in Σ, PV-ONT-002 undeclared role, PV-ONT-003 undeclared operator glyph without an explicit `prose: true`, PV-ONT-004 a rise in the formal_prose debt; both rules the real corpus cannot exercise carry fixture corpora' + - 'symbol-level means operator glyphs only — applied identifiers are code (ONT-3a), and grammar, arity, types and truth are not checked' + - 'sigma runs inside every pv lint (R-8) as the 10th gate and is armed in contracts/lint-baseline.json (nine armed); formal_prose recorded at the measured 1464 and enforced by the gate that measures it' + - 'contracts/ont-sigma-v1.yaml validates; census 1793; pv lint contracts/ rc 0; the ONT-2b probe passes every conjunct except `merged`' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + - orch:fable + - orch-basis:state + notes: null +- id: PMAT-3477 + github_issue: 3477 + item_type: task + title: '0.68.2 interrupt train (#3477): Qwen3 CUDA QK-norm in graph+batched prefill (#3413), TRAITS refusal collapse (#3432/#3091), #3090 disposition, T-4 publish' + status: planned + priority: medium + assigned_to: null + created: 2026-09-18T10:25:51Z + updated: 2026-09-18T10:25:51Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + - orch:fable + - orch-basis:release + - P0 + notes: null +- id: PMAT-3487 + github_issue: 3487 + item_type: task + title: 'ONT-4: typed relations — a contract''s relations: block (refines · supersedes · contradicts · depends_on) is a gate: role in Σ with Contract→Contract domain/range, every target resolves, acyclic roles have no cycle, contradicts is symmetric; pv lint --gate relations, armed; Σ gains supersedes and contradicts naming this gate as reader (R-11); legacy metadata.depends_on measured as legacy_unresolved_depends_on and ratcheted, never rewritten (R-5); relations_n==0 → Unknown{NoRelations} (R-2)' + status: planned + priority: medium + assigned_to: null + created: 2026-09-18T15:04:36Z + updated: 2026-09-18T15:04:36Z + spec: null + acceptance_criteria: + - '`pv lint contracts/ --gate relations --format json` is Pass at exit 0 on the real corpus with relations_n=3 (the ONT-001 §5 ONT-4 probe''s predicate); `pv lint contracts/` (all gates, relations armed) is Pass at exit 0.' + - 'Σ declares supersedes (acyclic) and contradicts (symmetric), both Contract→Contract, and readers.roles names lint/relations_gate.rs.' + - 'tests/fixtures/ont/relations-{ok,dangling,cycle,domain,malformed,legacy,legacy-rise} each witness one rule: 4 relations accepted with contradicts read both ways (relations_n=5); dangling → PV-ONT-008 naming contract, role, target; a→b→c→a → PV-ONT-009 naming the path; binds in relations → PV-ONT-006; undeclared role + non-list → PV-ONT-005 + 007; legacy hold passes, rise → PV-ONT-010; sigma-ok (no typed relation) → exit 2 decline.' + - 'metadata.depends_on is NOT rewritten: 354 legacy edges counted, 8 unresolved recorded as ont.legacy_unresolved_depends_on in lint-baseline.json and ratcheted shrink-only.' + - 'Two mutations each turn a test RED: the acyclic check skipped (the cycle test), the symmetric closure dropped (the four-relations test).' + - 'cargo test -p aprender-contracts --lib (1588) and -p aprender-contracts-cli (260) pass; clippy -D warnings clean on both crates; make contracts green; census regenerated (1795) and the README count synced.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + - orch:fable + - orch-basis:state + notes: null +- id: PMAT-3490 + github_issue: 3490 + item_type: task + title: 'CB-200 ratchet 601 -> 599 and the complexity shrink under pmat 3.41.1 — the pin itself landed in #3484, not here' + status: planned + priority: medium + assigned_to: null + created: 2026-09-18T15:52:47Z + updated: 2026-09-18T15:52:47Z + spec: null + acceptance_criteria: + - 'THE PIN IS ALREADY IN AND THIS ROW NO LONGER BUMPS IT. `[pmat] version = "3.41.1"` landed on main in `f4c0daa37` (09-18 17:07) inside the 0.68.2 PR #3484, not here. Verified on `origin/main:tools.toml:56`. The row was written before that and its original title said otherwise; two humans AND a review lane then read `tools.toml:7` — a COMMENT reading `version: "3.40.1"` — as the pin, which is paiml/infra#816.' + - 'WHAT THIS ROW ACTUALLY LANDS: the **CB-200 ratchet 601 -> 599** and the stale comment on `tools.toml:7` — and NOTHING ELSE. The complexity-baseline shrink (8 functions) that an earlier version of this criterion claimed ALSO landed in #3484: `scripts/complexity_baseline.txt` is absent from the diff against origin/main, which quorum r3 lane 1 caught. The r2 ratchet output "8 removed" was measured against the MERGE-BASE, not against main. The rebase against main surfaced 601-vs-599 as a genuine conflict — BOTH sides already carried `tool_version=pmat 3.41.1`, so it was never a version disagreement — and 599 is kept because the file is shrink-only against origin/main and taking 601 would surrender the ratchet.' + - 'VERIFIED ON THE MERGED TREE rather than carried, because 10 commits of new code could have made 599 unreachable: `ok CB-200 baseline 599 ([tdg] baseline == scripts/cb200_baseline.txt)`, `ok ratchet cb200_baseline.txt did not grow (2 removed)`, `ok ratchet complexity_baseline.txt did not grow (8 removed)`, `PASS (D2): 3409b29d2 vs 674da069e measured by pmat 3.41.1 — none new, none grown.`' + - '3.41.1 RE-CONFIRMED AS CONVERGED before the rebase, on the RUNNER denominator rather than the host set: intel HOST, `gx10-pool1`, `yoga-build3`, and the gx10/mini/lambda-labs hosts all report 3.41.1, and infra declares 3.41.1 on all five machines. `pforge-clean-room` (`rust:1.95-slim`) carries no pmat at all — paiml/infra#813. A pin measured two days earlier asserts nothing if the fleet moved under it; it had not.' + - 'THE PR-REVIEW RECEIPT UNDER `evidence/pr-review/3491/0fd8deb79.../` IS NOT REGENERATED, deliberately. It is scoped to the sha it names and correct for it. `pr_review_quorum_arm.sh:612` already refuses this case with the true reason — `0fd8deb79` IS an ancestor of the rebased head, so Q3 reaches the late-diff arm and refuses because commits after the reviewed sha touch `tools.toml` and the baselines, outside `evidence/pr-review/3491/**`. Regenerating a signed receipt for a head it never reviewed would be the real defect; a fresh signed round writes to its own directory and the old one stays as the historical artifact it is.' + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-3495 + github_issue: 3495 + item_type: task + title: 'VERIFY-001: run the 132 Kani harnesses in CI (proof credit from runs, not declarations) and pilot Verus on one dequant/parser function' + status: planned + priority: medium + assigned_to: null + created: 2026-09-18T16:43:48Z + updated: 2026-09-18T16:43:48Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-3496 + github_issue: 3495 + item_type: task + title: 'Register PMAT-3495 (VERIFY-001 on 0.71.0) in the roadmap so the AD-04 quorum for PR #3496 can run (registration only)' + status: planned + priority: medium + assigned_to: null + created: 2026-09-21T01:39:59Z + updated: 2026-09-21T01:39:59Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:triage + notes: 'ACCEPTANCE (this row is PR #3496 itself, a roadmap-only registration): (1) docs/roadmaps/entries/PMAT-3495.yaml exists with id PMAT-3495, github_issue 3495, and a title that transcribes issue #3495''s title VERBATIM, character for character: "VERIFY-001: run the 132 Kani harnesses in CI (proof credit from runs, not declarations) and pilot Verus on one dequant/parser function" (read from `gh issue view 3495 --json title` on 2026-09-21; the issue has no rename events); (2) docs/roadmaps/roadmap.yaml equals aggregate(entries/) and the diff vs origin/main is additive only (deleted=0, reserialised=0) after the merges of origin/main; (3) the PR touches nothing outside docs/roadmaps/ and docs/audits/. NOT in scope: any Kani harness, CI wiring or proof — those are PMAT-3495''s own work and are judged when it lands. A lane that finds the entry mis-transcribed, missing or invented FAILs this row.' +- id: PMAT-3500 + github_issue: 3500 + item_type: task + title: 'ONT-4b: pv extract (pv-contract) → contracts/contracts.nt (deterministic N-Triples, no blank nodes, R-15); in-house shapes validator over the SHACL-Core subset of §3.6 exactly (unsupported component → exit 3); shape: block on contracts; pv lint --gate shapes with pc_shape planted every run, shapes_n/focus_nodes_n declines (R-2), a corpus violation naming focus node and shape; contracts/shapes.ttl exported; the first shape targets ont:Contract from the ONT contracts so the whole corpus is focus nodes; shapes armed' + status: planned + priority: medium + assigned_to: null + created: 2026-09-18T20:17:28Z + updated: 2026-09-18T20:17:28Z + spec: docs/specifications/paiml-ontology.md + acceptance_criteria: + - 'The spec''s ONT-4b probe text passes verbatim minus `merged`: contracts.nt tracked with no `_:`, shapes.ttl tracked, `pv lint contracts/ --gate shapes --format json` → Pass with shapes_n>0, focus_nodes_n>0 (1731 at acab2e754) and pc_shape=fired at the top level of the report.' + - 'ontology/shapes.rs implements §3.6''s subset exactly and refuses every other component at parse by name (targetNode, qualifiedValueShape, languageIn, a sequence path, or/and/not, a second node level): `cargo test -p aprender-contracts --lib ontology::shapes` 10/10.' + - 'Two extractions are byte-identical and carry no blank node; `pv extract --check` exits 1 on drift and `make contracts` runs it (R-18).' + - 'The exit vocabulary holds on fixtures: Pass 0; a corpus violation 1 naming focus node and shape (PV-ONT-011); NoShapes, NoFocus, PositiveControlFailed and Warn each 2 with the reason; an unsupported component 3: `cargo test -p aprender-contracts-cli --test ont4b_shapes_gate` 11/11.' + - 'Two mutations from the spec: minCount removed from ont:id → exit 2 decline: PositiveControlFailed; a kind outside the list on one contract → exit 1 naming that contract and the shape.' + - 'shapes is armed (11 armed gates), Σ marks pv-contract/pv_contract implemented, contracts_shaped=1, census 1796 with the README synced; lib 1610 and cli 271 tests pass; clippy -D warnings clean.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + - orch:fable + - orch-basis:state + notes: null +- id: PMAT-3508 + github_issue: 3508 + item_type: task + title: 'ONT-4c1: model receipts as focus nodes — extract:gguf + extract:apr-model over the model:* vocabulary; the ladder rungs as model:Model; resolves: receipt over the tracked ladder receipts (apr-model-ladder-receipt/v1, a row without sha256 is not a witness); per-shape arming (armed_shapes[] in lint-baseline.json, absent = all armed, monotone); shapes ladder-measured (armed) and ladder-green (computed and reported, armed by the 0.68.2 bump)' + status: planned + priority: medium + assigned_to: null + created: 2026-09-19T09:19:25Z + updated: 2026-09-19T09:19:25Z + spec: docs/specifications/paiml-ontology.md (paiml/infra, v4.6 §5 ONT-4c1) + acceptance_criteria: + - '`pv lint contracts/ --gate shapes --format json` on this tree reports the ladder rungs as focus nodes (`by_entity_type.gguf` = the rung count), `pc_extract.gguf` and `pc_extract["apr-model"]` fired, `armed_shapes` ⊇ [ont-shapes-v1, ladder-measured], `not_armed_shapes` = [ladder-green], and `by_shape` names all three; verdict Pass once the re-measured 0.68.1 receipts (sha256 per rung, both hosts) are tracked, Fail naming every rung without a witness until then — measured, not assumed.' + - 'ontology/extract/{gguf,apr_model}.rs: a corrupt GGUF magic and an .apr header whose tensor count disagrees with its index (crates/apr-format/tests/fixtures/golden_v2.apr, 2 tensors, checksum recomputed) are each refused naming the file; both run in memory every gate run as the positive controls.' + - 'ontology/receipts.rs: one reader, schema apr-model-ladder-receipt/v1 refused by name on any other; a rung row with sha256 equal to the contract''s is a witness (model:parityReceipt), a row without sha256 is not (model:unmeasuredRow), a different hex is model:receiptHexMismatch naming file and hex; greenOn / missingGreenHost per (rung, host) with hosts: optional (absent = every host with a receipt), capability passed ∧ ¬skipped, every claimed backend ran ∧ ¬fallback.' + - 'Per-shape arming (v4.6 §3.9): lint-baseline.json armed_shapes[] (absent = all armed), a shape not listed is computed and reported and never in the meet; the plant must fire from an armed shape; `armed_shapes shrank` → exit 3 through the same comparand as armed_gates (an All comparand = the shapes declared in files that existed at it); check_ont_ratchet.sh carries armed_shapes through --write and records ont.shapes_unarmed.' + - 'tests/fixtures/ont/ladder-{green,fallback,fallback-armed,wronghex,nosha,noreceipts,badschema,lyingapr,plantunarmed}: exit 0 / 0 / 1 / 1 / 1 / 2 (decline NoCheckable naming evidence/dogfood/models) / 3 (naming lambda.json) / 1 (PV-ONT-012 naming lying.apr) / 2 (PositiveControlFailed); crates/aprender-contracts-cli/tests/ont4c1_model_receipts.rs 12 legs, wired in ci/explicit-test-commands.d/339.' + - 'Mutations, each RED on its own test: hosts: ignored in resolve() → hosts_scope_the_green_requirement RED; the GGUF magic check removed → PositiveControlFailed pc_extract.gguf; one sha256 changed in a tracked receipt row → ladder-measured rejects naming rung and file (measured on a copy of the real corpus with re-measured receipts); ladder-green armed on the fallback fixture → rejects naming rung and host.' + - 'contracts/ont-model-receipts-v1.yaml holds both shapes (shapes: list, ids ladder-measured / ladder-green); the ladder contract gains entity: {type: gguf}; Σ gguf and apr-model implemented: true; contracts.nt (model nodes, no blank node, pv extract --check 0) and shapes.ttl regenerated. No ci.yml change.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + - orch:fable + - orch-basis:state + notes: null +- id: PMAT-3509 + github_issue: 3509 + item_type: task + title: 'ONT-4b2: extract:code (syn module-tree walk over the bound symbols) and extract:lean (the in-tree theorems) into contracts.nt under the symbol/ and world/ roots; the ONT-0 table''s 32 W3C SHACL-Core cases accounted for one by one — 16 vendored and run by the shapes gate (w3c_cases_passed), 16 NOT vendored because their FORM (a constraint on the node shape itself) is outside the subset, each with its reason; tests/oracle/ scratch crate + make oracle writing tests/oracle/differential.json (release gate only, R-13); Unknown{Differential} on disagreement' + status: planned + priority: medium + assigned_to: null + created: 2026-09-19T11:07:51Z + updated: 2026-09-19T11:07:51Z + spec: null + acceptance_criteria: + - 'extract:code walks the syn module tree of every crate a binding registry names and emits ont:Symbol focus nodes under the symbol/ root (resolved and unresolved counted separately: symbols_resolved / symbols_unresolved in the shapes report); extract:lean emits ont:Statement nodes under the world/ root for the in-tree theorems whose names the ONT-2a camel-case rule accepts; both run inside the one walk extract::all (R-18) and both have a positive control (pc_extract.code / pc_extract.lean) that must fire or the gate declines PositiveControlFailed.' + - 'crates/aprender-contracts/src/ontology/w3c.rs vendors 16 W3C SHACL-Core cases as YAML translations under crates/aprender-contracts/w3c/ and the shapes gate runs them (w3c_cases_passed / w3c_cases_n in the report, 16/16); NOT_VENDORED lists the other 16 of ONT-0''s 32 with the excluding form each (a constraint on the node shape itself, which the subset attaches only to property shapes); the_table_of_ont_0_is_accounted_for_case_by_case asserts CASES + NOT_VENDORED == 32 with no id twice. The CLI leg asserts n >= 16 because 16 is what is vendored — not 32.' + - 'sh:in is TERM equality (InEntry{lexical, datatype}; "1"^^xsd:integer and "1" are different entries; typed export in shapes.ttl); rdfs:subClassOf closes instance sets for targetClass; sh:datatype checks the lexical form is well-formed for the datatype; one sh:node result per failing value; the sh:in message reads `: is not one of []` (the path from #3530, the terms from this row).' + - 'tests/oracle/ is a workspace-DETACHED crate (its own [workspace]; shacl = "=0.3.21" default-features off) run only by `make oracle` / `make oracle-check` (release gate, R-13: no third-party SHACL crate in the gate path; the workspace Cargo.lock has no rudof/oxigraph/horned/sophia/whelk); it writes tests/oracle/differential.json (TRACKED) and oracle-check diffs it; the Makefile target uses --manifest-path, never cd, because the Makefile is .ONESHELL.' + - 'contracts/ont-code-symbols-v1.yaml ships two shapes UNARMED (bound-symbols-resolve, lean-statements-grounded) — reported in not_armed_shapes, armed later by their own PR (§3.9 reported-first); FALSIFY-SYM-001..005 in the contract; scripts/check_ont_ratchet.sh reads entity types and extractors from Σ and preserves foreign keys; fixtures tests/fixtures/ont/{code-bound,code-ghost,lean-sorry}/; CLI test ont4b2_code_lean_w3c (8 legs) wired at ci/explicit-test-commands.d/343-….' + - 'Rebased onto 45decafb5 (ONT-4c1 + #3530 + #3523 + #3516): pv extract contracts --check 0; sigma / relations / shapes Pass on the tree (shapes_n=5, focus_nodes_n=2318, symbols 169 resolved / 101 unresolved, W3C 16/16); the 4c1 corpus test asserts ladder-green is computed and reported (a by_shape entry, listed in armed ∪ not_armed) without pinning which side, so it holds on the 0.68.2 bump tree that arms it; crates/facades/Cargo.lock regenerated for the syn edge; clippy 1.93 -D warnings clean on both crates; lib 1665 + the seven ONT CLI test files green.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + - orch:fable + - orch-basis:state + notes: null +- id: PMAT-3515 + github_issue: 3515 + item_type: task + title: ONT-001 §3.7 extract:json — JSON/JSONL + vocabulary map → RDF, so a tool's --json output is a shaped entity (ARBITER I1-0) + status: inprogress + priority: high + assigned_to: null + created: 2026-09-19T07:20:01Z + updated: 2026-09-19T07:55:00Z + spec: null + acceptance_criteria: + - '(1) crates/aprender-contracts/src/ontology/extract/json.rs (new): `applies(doc)` (entity.type == json); `extract_into(g, stem, doc, root)` reads `entity.ref` relative to `root` and the contract''s `vocabulary: {prefix, root_class, nested}` — root node `iri(prefix, stem)` typed `expand(root_class)` + prov:Entity, scalar keys as `expand(":")` literals (bool → xsd:boolean, integer → xsd:integer via u64/i64, other numbers → xsd:double, string → xsd:string), nested objects and arrays of objects as nodes `.[.]` typed by `nested`, arrays of scalars as repeated predicates, null absent; `.jsonl` = one root per non-empty line with leading NULs trimmed, a line that does not parse is a `Warning{contract,path,line,why}`, no parsable line is `NotJson`. `ExtractError` = RefUnreadable | NotJson | VocabularyIncomplete | Unmapped, each Display naming the contract and the thing. 8 unit tests. (2) extract/mod.rs: `Extraction{graph, warnings, entities_extracted}` and `all(contract_dir)` = pv_contract::extract + every json entity, the ONE walk. (3) rdf.rs: XSD_BOOLEAN, XSD_DOUBLE, Term::boolean/double/signed. (4) lint/shapes_gate.rs: `ShapesOutcome::ExtractFailed(ExtractError)`; the gate uses `extract::all`, and each extraction warning is a Severity::Warning ValidationResult (component "extract:json") so warnings-only is Unknown{Warn}. lint/mod.rs maps ExtractFailed to a skipped gate; cli commands/lint.rs maps it to exit 3 (SigmaMalformed path); commands/extract_rdf.rs uses `extract::all`, prints warnings, exits 3 on an error. (5) contracts/ontology.yaml: entity type `json` → extractor `json`, both implemented: true; contracts/ont-extract-json-v1.yaml (pattern; EXJ-INV-001..005, FALSIFY-EXJ-001..005, qa_gate F-EXJ-001); contracts/contracts.nt refreshed by `pv extract` (9243 triples, --check exit 0). (6) tests/fixtures/ont/json-{ok,violation,unmapped,missing-ref,torn-jsonl}/ (contracts/ + data/) and crates/aprender-contracts-cli/tests/ont_extract_json.rs: 7 tests — Pass exit 0 focus 1 plant fired; Fail exit 1 two violations naming ont:tool/tool-status, shape `tool-status`, `(closed)` + ont:tool/surprise and `broken is not one of`; exit 3 naming `findings`; exit 3 naming `data/does-not-exist.json`; exit 2 Unknown(Warn) focus 3 warnings 1 `line 3 unparsable`; `pv extract` byte-identical twice with the tool/Status class and the nested node and no `_:`, --check exit 0; `pv extract` on json-unmapped exit 3. Measured on paiml/infra contracts/arbiter-status-v1.yaml: Pass, 172 triples, plant_violations 8, 0.05 s; both infra plants rejected. sigma/shapes/relations gates Pass on the corpus; clippy -D warnings clean; 1618 lib tests + all cli suites green. Refs paiml/aprender#3515, paiml/infra#704, paiml/infra#701 (§14 I1-0)' + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-3529 + github_issue: 3529 + item_type: task + title: 'pv contradicts itself about metadata: (validate requires it, the sigma gate refuses it); entity.properties is read by nothing; and a lexical violation does not name its path — Σ accepts an opaque metadata block, extract:pv-contract emits entity.properties. as :, and in/pattern/minLength/maxLength name the property they fired on, with apex''s two EV-21 falsifiers as fixtures' + status: planned + priority: medium + assigned_to: null + created: 2026-09-19T12:20:38Z + updated: 2026-09-19T12:36:52Z + spec: null + acceptance_criteria: + - 'The SAME contracts/ontology.yaml passes `pv validate` AND `pv lint --gate sigma`: Σ carries `metadata` as opaque YAML (no Σ rule reads a field of it), it joins READABLE_KEYS so `readers:` must claim it, and removing that claim brings exit 3 back naming the key — measured by a CLI leg that runs both subcommands on one fixture.' + - 'entity.properties. becomes the predicate : (IRI: ONT_BASE + /) on the contract node, so a shape over the entity''s own properties has focus predicates: apex''s EV-21 falsifiers through the CLI — entity-props-ok Pass, entity-props-bad-value Fail (in) naming the property and the value, entity-props-undeclared-key Fail (closed) naming the undeclared property.' + - 'The predicate IRI carries the entity type as its vocabulary segment: entity.properties.scale of an entity typed `study` is https://ont.paiml.dev/v1alpha1/study/scale — which is what `study:scale` expands to — and NEVER the bare https://ont.paiml.dev/v1alpha1/scale, so a shape over one entity type cannot constrain another type''s `scale`. Both directions asserted in a unit test. (Rendering is unchanged and separate: `short()` prints every ONT_BASE IRI with the `ont:` prefix, so messages read `ont:study/scale`, exactly as they already read `ont:model/parityReceipt`.)' + - 'No entity.type means no property triples — there is no vocabulary segment and inventing one would be an inference; nested mappings and sequences are not emitted at v1alpha1, because the subset has no path expressions and a predicate no shape can reach is decoration. One unit test each.' + - 'A lexical violation names its PATH in the message (in, pattern, minLength, maxLength), not only in the result''s path field. Without it the two falsifiers above cannot name the property at all, and a shape with nine properties emits nine lines a reader cannot tell apart.' + - 'No regression on the real corpus: pv lint contracts --gate sigma Pass, --gate shapes Pass over 1731 focus nodes, pv extract contracts --check 0, aprender-contracts lib green, ont2b_sigma_gate / ont4_relations_gate / ont4b_shapes_gate green, clippy -D warnings clean.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + - orch:fable + - orch-basis:state + notes: null +- id: PMAT-3535 + github_issue: 3535 + item_type: task + title: '§11.1 + check_pr_ont_delta: the docs/specifications sink is the release spec, not every design spec — three maintainer PRs red for a delta that does not exist; predicate self-test with the falsifying design-spec row (Refs aprender#3535)' + status: planned + priority: medium + assigned_to: null + created: 2026-09-19T18:35:25Z + updated: 2026-09-19T18:35:25Z + spec: null + acceptance_criteria: + - 'APR-RELEASE-001 §11.1 names docs/specifications/APR-RELEASE-001-train-and-build-kaizen.md (the release spec, where the train writes its findings) as the docs/specifications sink and says a *-MASTER.md design spec is the finding''s home, not a sink; scripts/check_pr_ont_delta.sh ONT_SWEEP_SINKS carries that exact path in place of the docs/specifications/ prefix — the spec sentence and the guard list name the same bytes.' + - 'predicate_self_test (10 rows) chains into --self-test: crate source, a contract yaml and ci.yml are not sweeps; night.yml, README.md, CLAUDE.md, the apr-cli-commands registry, a derived baseline and the release spec are; the row "a DESIGN spec is not a sweep" (docs/specifications/PP-QUANT-001-MASTER.md) is want=1 and goes RED (got=0) when the directory-wide sink is restored. --self-test 15 + 10 passed; bashrs lint 0 errors; this PR''s own body passes check_pr_ont_delta.sh (ont-delta: none) and check_pr_closes_issue.sh.' + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-3537 + github_issue: 3537 + item_type: task + title: 'ONT-6b: a kind-less contract that fails a kernel-only rule says ''no metadata.kind, judged kernel by default'' on the first error the default caused' + status: planned + priority: medium + assigned_to: null + created: 2026-09-20T07:01:14Z + updated: 2026-09-20T07:01:14Z + spec: docs/specifications/paiml-ontology.md + acceptance_criteria: + - 'crates/aprender-contracts/src/schema/types.rs: `Contract` gains `#[serde(skip)] pub kind_declared: bool` — a parse artifact beside `unknown_top_level_keys`, recording whether `metadata.kind:` was WRITTEN, because `ContractKind` derives `Default = Kernel` and `#[serde(default)]` erases the difference before anything can read `Contract::kind()`' + - 'crates/aprender-contracts/src/schema/parser.rs: `parse_contract_str` sets it from a new `kind_is_declared(yaml)` — a `KindProbe` struct whose only field is `metadata: BTreeMap`, so every other top-level value is DRAINED rather than built (a whole-document `serde_yaml::Value` parse fails on contracts/apr-cli-commands-v1.yaml and would report a declared kind as absent); an absent or non-mapping `metadata` answers false; a unit test carries the duplicate-nested-key shape with an anti-vacuity assertion that a `Value` parse really refuses it' + - 'crates/aprender-contracts/src/schema/validator.rs: `validate_contract` records `violations.len()` before the kernel-only branch and, when `!contract.kind_declared`, calls the new `explain_kind_default` on exactly that slice — which appends ` (no metadata.kind, judged kernel by default)` to the FIRST `Severity::Error` in it, once. New `pub const KIND_DEFAULT_EXPLANATION`. No rule id is matched anywhere and the printer is untouched' + - 'four fixtures under tests/fixtures/ont/kind-default/ — kindless-failing.yaml (has `references` so the first error is the kernel-only one), declared-kernel-failing.yaml (the same content plus `kind: kernel`), kindless-passing.yaml (no kind, all four kernel blocks), pattern.yaml (`kind: pattern`)' + - 'crates/aprender-contracts-cli/tests/ont6b_kind_default.rs: six legs — first-error, exactly-once (with an anti-vacuity assertion that the fixture yields >1 error), declared-kernel-silent, kindless-passing-silent, pattern-silent, and a differential asserting that stripping the explanation from the kind-less output reproduces the declared-kernel output BYTE-FOR-BYTE; ci/explicit-test-commands.d/344-aprender-contracts-cli-ont6b-kind-default.cmd. No ci.yml change' + - 'measured: the four fixtures give rc 1/1/0/0 with the explanation count 1/0/0/0; `cargo test -p aprender-contracts --lib` 1666 passed 0 failed; `cargo fmt --all -- --check` clean and clippy `-D warnings` clean on both crates' + - 'four planted mutations, each asserting its own perl match count BEFORE the tests run (an unapplied edit is indistinguishable from an uncaught mutant), each RED on a DIFFERENT set of legs: drop the text → first-error + once; decorate even when declared → declared-kernel + differential; decorate the LAST error → first-error; decorate warnings too → kindless-passing-silent. Tree restored and green afterwards in the same run' + - 'R-23: over all 1300 tracked contracts this pv and main''s pv (built at daad9f7c5, named) differ on ZERO and ZERO carry the explanation — the change is inert on the corpus; rmedia''s kind-less crates/rmedia-core/contracts/dialogue-v1.yaml (read-only git archive export at 3ff2f4d) goes from `PROVABILITY-001: Kernel contract has no kani_harnesses` to the same line plus the explanation, exit 1 on both' + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-3539 + github_issue: 3539 + item_type: task + title: 'book-contracts.yml: delete the three rust-cache steps — their save step deletes the shared registry/src; cache-bin false was never the fix' + status: planned + priority: medium + assigned_to: null + created: 2026-09-20T07:19:32Z + updated: 2026-09-20T07:19:32Z + spec: null + acceptance_criteria: + - '.github/workflows/book-contracts.yml: the three `Swatinem/rust-cache@v2` steps (jobs chapter-examples-compile, chapter-examples-run, book-integration-tests — all `[self-hosted, Linux, X64, clean-room]`), each with `workspaces: "."` and `cache-bin: "false"`, are DELETED. `grep -c "uses: Swatinem/rust-cache"` goes 3 → 0' + - 'each is replaced by a comment naming the mechanism rather than the old mitigation: cache-bin skips cleanBin alone, the save step also runs cleanRegistry unconditionally and deletes ${CARGO_HOME}/registry/src, and only a job-private CARGO_HOME would make the action safe (--target-dir, --root and a fresh $HOME do not, since cargo reads sources from $CARGO_HOME whatever the target dir is)' + - 'each comment states in those words that THE CI-REAPER IS NOT THE ONLY CAUSE OF THAT MESSAGE — aprender#2822 attributes it to the reaper; in the measured case the reaper had last run 27 minutes earlier and its next run logged swept=0 — and names the two commands that check the clock (`journalctl -u ci-reaper.service`, and a grep for `Post Run Swatinem/rust-cache` over the runners'' _diag/Worker_*.log)' + - 'measured: paiml/infra main''s machines/clean-room/shared-home-guard/check.sh over the changed file prints no VIOLATION (it printed three before), and no other aprender workflow produces a BLOCK under that guard' + - 'FOUR files change and two of them are structural, not scope creep. The two this row authors: `.github/workflows/book-contracts.yml` and this fragment (`docs/roadmaps/entries/PMAT-3539.yaml`). The two the repository requires alongside them: `docs/roadmaps/roadmap.yaml`, GENERATED by `make roadmap-aggregate` and impossible to omit when a fragment is added, and `docs/audits/quorum-PMAT-3539.json`, the committed quorum receipt. An earlier version said "exactly two files change" and quorum r1 correctly FAILED the diff against it, twice.' + - 'THE INVARIANT, stated instead of a line count: **every deletion in this diff is inside `.github/workflows/book-contracts.yml`**, and the three doc files are purely additive. NO source, NO test, NO ci.yml. A round-4 lane refused an earlier version of this criterion for citing `+118/+21/+21` when the receipt had become 84 lines — correctly, and the lesson is that the number was UNCITABLE rather than merely wrong: `docs/audits/quorum-PMAT-3539.json` is REWRITTEN BY EACH QUORUM ROUND, so any criterion quoting its line count is false again the moment the next round runs. An acceptance criterion may not cite a measurement of an artifact the review process itself rewrites. The deletions-are-confined invariant is stable across rounds and is what the criterion was actually protecting.' + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-3543 + github_issue: 3543 + item_type: task + title: 'The post-publish dogfood CANNOT pass: version-unpublished is not phase-aware and the banner still says pre-release' + status: in_progress + priority: high + assigned_to: aprender-f0 + created: 2026-09-20T08:17:54Z + updated: 2026-09-21T16:50:00Z + spec: null + acceptance_criteria: + - 'Issue #3543 defect 1 (the issue has no done_when list; its defects and its falsifier are the acceptance), verbatim: "1. **`version-unpublished` is not phase-aware.** It is a pre-publish gate ("this version must be absent from the index"). In the post-publish phase its precondition is inverted by construction: a successful publish makes it RED forever. `--phase` is parsed and validated (dogfood.sh:42-53) and 13 sites read `DOGFOOD_PHASE`, but this row is not one of them. Post-publish it should assert the opposite — the version IS on the index, resolvable, and `cargo install` of it works — which is the receipt the train actually wants."' + - 'defect 2, verbatim: "2. **The banner lies about which phase ran** (dogfood.sh:269 prints `dogfood pre-release:` unconditionally). Anyone reading the log believes they are looking at the pre-release gate set."' + - 'the issue''s falsifier, verbatim: "**Falsifier for the fix:** run `--phase post-publish` at a version that IS published and require GO; run it at a version that is NOT published and require RED on the new post-publish assertion. Both directions, or the row is decoration again."' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'Release-tooling lane (cop, aprender-04), on the 0.69.1 release path. Its own branch off main 225b2a9ab: dogfood.sh is in none of the #3699/#3708/#3717 stack. SCOPE: scripts/dogfood.sh, the new scripts/check_dogfood_version_row.sh, and this fragment. SUPERSEDES open PR #3202 (PMAT-1098-dogfood-post-publish-phase, 2026-09-13), which the cop will close with these reasons. It does NOT meet this issue: (a) it patches only the dry-run branch, while main has since moved pre-publish onto a direct index.crates.io lookup (dogfood.sh:387-441 at 225b2a9ab); (b) it makes post-publish PASS unconditionally, so the falsifier''s second direction (a version NOT published must be RED) would read "not yet published" and PASS; (c) it leaves the banner. HOW IT IS MET. DEFECT 1: the sparse-index lookup is ONE function, index_version_state CRATE VERSION, which prints "present", "absent", "crate-absent" or "unknown ". Its body is the pre-publish code moved verbatim: the lowercased shard path, HTTP status read apart from the body, and a body that is not the index being UNKNOWN, never absent. version_row PHASE CRATE VERSION STATE decides the row. pre-publish gives version-unpublished, PASS only when absent or crate-absent (unchanged). post-publish gives a NEW row, version-published, PASS only when present AND installable (next), FAIL when absent ("… is NOT in the crates.io index — this phase runs after the cascade, so the version was not published"), crate-absent, or unknown. mark_version_row PHASE marks whichever row version_row decides. POST-PUBLISH ALSO INSTALLS (round 2): defect 1''s own text says post-publish must assert "the version IS on the index, resolvable, and `cargo install` of it works". Round 1''s lanes 1 and 2 FAILed an index-only row on that clause, and they were right. When the index carries the version, published_install_check runs `cargo install --version = --locked --root --target-dir ` with the registry token unset, exactly as a user installs. Every binary that lands must report the version in `--version`. A failed install (which is also where "resolvable" is decided: a version cargo cannot resolve, e.g. a yanked one, fails it), a binary reporting another version, or no binary at all turns version-published FAIL: "… is in the crates.io index but is NOT installable: …". No install is attempted for a version the index does not carry. The pre-publish branch calls it as before. The post-publish phase still runs the publish dry-run, because row 10 (publish-dry-run) reads its exit code and is what discharges the pre-publish DEFER. Its version row is then mark_version_row post-publish, and the pre-publish row is NOT emitted in that phase. The full phase is unchanged: the dry-run path, already exists -> FAIL. DEFECT 2: `phase_banner "$DOGFOOD_PHASE" "$CRATE" "$VERSION"` prints "══ dogfood : v ══". The only other mention of "dogfood pre-release" in scripts/ is a comment in dogfood-use.sh, which nothing parses. FALSIFIER, as a wired table: scripts/check_dogfood_version_row.sh, a scripts/check_*.sh with no bare cargo token, so guard_tree''s --no-cargo set runs it. It runs the REAL "2 + 10" section of dogfood.sh, extracted from its header to the next section header, so the call sites run as well as the helpers. It stubs `mark` (records rows), the publish dry-run, and curl (serving a fixture sparse index: present / absent / 404 / an HTML 200 / down). ROWS: pre-present FAIL; pre-absent PASS; pre-404 PASS; pre-down FAIL UNKNOWN; post-present version-published PASS (in the index, installed with `--version =9.9.9 --locked`, the binary reports 9.9.9) with NO version-unpublished row; post-install-fails FAIL; post-install-wrongver FAIL; post-install-nobin FAIL; post-absent FAIL with no install attempted; post-404 FAIL; post-html FAIL UNKNOWN; post-dry-run (the dry-run still runs, DRC 0); full-unchanged (already exists -> version-unpublished FAIL, no index call); banner ("══ dogfood post-publish: aprender v9.9.9 ══", printed from DOGFOOD_PHASE); index-path (crate "Aprender" is looked up at index.crates.io/ap/re/aprender). That is both directions in both phases, as the falsifier asks. MUTANTS, one per row, each killed: pre-present-pass, pre-absent-fail, pre-404-fail, down-is-absent, post-phase-blind (post-publish emitting the pre-publish row), post-absent-pass (#3202''s shape), post-404-pass, html-is-absent, no-post-call (the `mark_version_row post-publish` call deleted), post-skips-dry-run, full-uses-index, banner-fixed ("pre-release"), index-case (no lowercasing -> "looked up: curl https://index.crates.io/Ap/re/Aprender"); install-ignored, version-unchecked, nobin-ok, install-on-absent, unlocked (the install without --locked). The table''s first full run caught a fixture bug of mine: CRATE was exported before the per-row env, so index-path never saw the uppercase name and passed for the wrong reason until its mutant survived. MEASURED at this commit: `bash scripts/check_dogfood_version_row.sh` rc 0, "PASS 33 row(s)" (15 rows, 18 mutants); bashrs on dogfood.sh and the table, 0 errors (an `eval` in the banner row was replaced by sourcing the extracted line, after check_bashrs_gate''s SEC001); check_bashrs_gate, check_guards_are_wired and check_no_pipe_into_grep_q all rc 0. NOT RUN: a real `dogfood.sh --phase post-publish` against crates.io, which would include a real `cargo install aprender --version = --locked`, a full release build. The next train''s post-publish step is that measurement, hence Refs #3543.' +- id: PMAT-3545 + github_issue: 3545 + item_type: task + title: 'apr devices told every user CUDA was unavailable on a cuda build: trueno/cuda missing from the feature' + status: in_progress + priority: high + assigned_to: null + created: 2026-09-21T00:00:00Z + updated: 2026-09-21T00:00:00Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'ACCEPTANCE (hand-entered from gh#3545 done_when; see paiml-mcp-agent-toolkit#1414). The shipped -cuda asset ran CUDA correctly and told every new user cuda unavailable reason=NotCompiled on the first screen they saw. Two flags decided one fact: apr-cli/cuda enabled realizar/cuda (so inference ran on the GPU) but NOT trueno/cuda — and trueno s backend registry is what devices reads, so default_factories() had no CudaFactory and the registry emitted missing_entry(Cuda) = Source::NotCompiled. Done when: the cuda feature includes trueno/cuda, and a test RED-turns if it is removed again. Falsifier is two-sided: a cuda build must not report not-compiled, AND a non-cuda build must STILL report not-compiled even where a GPU is physically present — a fix that made devices optimistic fails the second arm. NOTE: the issue s own query asks for compiled-in, which would be false even after a correct fix — Source::CompiledIn means linked into the binary, while the CUDA driver is reached via Source::Dlopen(path). The test asserts != not-compiled and the issue s query needs correcting rather than satisfying. Measured on lambda RTX 4090: before = unavailable/not-compiled, after = ready/dlopen.' +- id: PMAT-3546 + github_issue: 3546 + item_type: task + title: 'install.sh: clean-container curl|bash e2e for stable+rc (sha256, version==tag+sha) as release gate + nightly' + status: inprogress + priority: medium + assigned_to: aprender-59 + created: 2026-09-24T18:08:23Z + updated: 2026-09-24T18:08:23Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-3556 + github_issue: 3556 + item_type: task + title: 'PP-LLAMA-001 row 2: perf002 prefill-path probe + decompose() with mandatory refusals — discharges the 2026-09-19 expiry' + status: planned + priority: medium + assigned_to: null + created: 2026-09-20T08:40:15Z + updated: 2026-09-20T08:40:15Z + spec: docs/specifications/PP-LLAMA-001-MASTER.md + acceptance_criteria: + - 'scripts/perf002_prefill_path_probe.sh (new, bash driver) + scripts/perf002_prefill_path_probe.py (new, decider), matching the perf041 idiom: apr_bin.sh-resolved binary, marker written on EVERY exit path carrying host/cc/commit/binary-sha256/started_utc/slope/refused_rule, exit 0 MECHANISM_CONFIRMED / 1 PREDICTION_KILLED / 2 UNMEASURABLE. Nothing under crates/aprender-serve/** or .github/workflows/cuda-nightly.yml (row 1 owns those)' + - 'decompose() carries the four MANDATORY refusals of the row — too_few_distinct_x, negative_slope, r2_below_bound, and bimodal (which REPORTS per-mode fits rather than rejecting) — plus a fifth, implausibly_fast, that guards the harness; every refusal names itself in the output and maps to exit 2, never to a defect claim' + - '`python3 scripts/perf002_prefill_path_probe.py --selftest` is OK on 8 cases: a fixture per refusal, a "bimodal emits two fits" assertion, an anti-vacuity leg proving the floor (not another rule) catches the harness fixture, a CONTROL proving a clean linear sweep is NOT refused, and a check that the control recovers its planted 32.650 ms/token. The driver runs the selftest BEFORE measuring and refuses to report a verdict if it fails' + - 'measure() reads TTFT off the SSE stream (first chunk carrying content) with max_tokens=1, issues and DISCARDS one warm-up per arm, and gives every sample a unique nonce prefix; --repeat-prompt reproduces the prefix-cache bimodality on demand' + - 'measured on gx10 (GB10, cc 121) at commit 338f1d49, qwen2.5-coder-1.5b-instruct-q4_k_m, ladder 64/128/256/384/513 x3: verdict MECHANISM_CONFIRMED, default arm linear at 9.042 ms/token r2 0.999947 n=15 (513 tok -> 4713/4717/4719 ms), BATCHED_PREFILL=1 measured 0.099 s at ~512 tokens (513 tok -> 123/99/98 ms) — a 48x collapse and 3.5x better than §10''s predicted 0.35 s. Slope reproduced at 9.054 and 9.042 across independent runs' + - 'docs/specifications/PP-LLAMA-001-MASTER.md row 2''s status cell goes from `**OPEN**, 2026-09-19` to `**LANDED** (this PR)` with the measurement — this is what DISCHARGES the row: spec_conformance.py:803 sets `discharged = "LANDED" in cell.upper()`, so the §4 andon clears only when the status cell says so, and row 1 proved the cost of the converse (its work had been on main since 2026-09-04 while its cell read OPEN)' + - 'THIS PR ALSO CARRIES ROW 1''S CELL, and that is a deliberate change of scope from the original split. `gate: needs: [... guard-tree ...]` (ci.yml:3040) with `ci / gate` REQUIRED, and guard-tree failing while ANY row disagrees, means row 1''s PR and row 2''s PR are green only TOGETHER: each leaves the other''s rows red, so both sit BLOCKED forever rather than merging in some order (prior art in this repo: 10.1 h, 14 queue entries, zero merges). aprender-bf''s commit `fe593abfc` is cherry-picked here with their authorship preserved, they closed #3565 pointing at this PR, and #3564 waits behind the same gate' + - 'row 21 is dated 2026-09-30 in the same PR: it inherited row 2''s expiry and had none of its own, so discharging row 2 raises `D2 21 — blocked only by rows that have LANDED, so nothing derives its expiry any more` plus a `D5` on the derived file. Basis matches aprender-bf''s for 13/15/19 — blocked until 2026-09-20, one full train past the 0.69.0 cut, owner may move it with a stated basis. Nothing inherits from 21' + - 'evidence/parity/derived_expiries.json is regenerated with `spec_conformance.sh --write` AFTER the cherry-pick is resolved, so it derives from the merged §12 rather than from either half. Measured on the combined tree: `spec_conformance.sh` exits 0, `33 row(s), 33 ARMED, 114 named case(s), 0 missing`, down from 7 rows disagreeing this morning and 5 after row 2 alone' + - 'the marker really is written on every exit path: OUT/MARKER and a python-free `bail_marker` are established BEFORE the `cd` and before sourcing apr_bin.sh, because both of those bail early and the first draft produced SILENCE there while the header claimed otherwise. Measured: running the script from a directory that is not the repo exits 2 and writes a marker with `status: UNMEASURABLE` and `reason: apr_bin.sh could not attribute an apr binary to this tree`' + - 'ONE clock for the run: `date -u` is captured to the append-only `started_utc.log` and read back BEFORE `bail_marker` is defined, so the bail path and the full writer stamp the same instant and neither calls `date` inline — a bare `date` inside `bail_marker` was DET002 in guard-cargo (`bashrs-gate: FAIL 1 … over 345 file(s)`), which is bashrs enforcing the append-only-sink guidance the sibling probe already documents' + - 'the marker vocabulary matches the documented exit codes: exit 2 writes `UNMEASURABLE`, not `UNMEASURED` (the sibling perf041 writes UNMEASURED; this row''s own text says UNMEASURABLE and the file is now internally consistent)' + - 'the probe''s header records the four harness defects that each produced a confident WRONG answer rather than an error (time_starttransfer times headers not tokens; first-request CUDA warm-up gives a negative slope; a repeated prompt measures the prefix cache; the r2 floor wrongly applied to the batched arm). §9 #1''s SIZE is deliberately NOT re-measured here — see aprender#3553' + - 'quorum r8 found the diff tripping the parser with its OWN explanatory prose, and the five citations are reworded rather than the parser changed. `discharged = "LANDED" in cell.upper()` is a SUBSTRING test over the whole cell, so rows 13, 15, 18, 19 and 21 saying "unblocked when row 1 LANDED" / "because row 2 LANDED" all regenerated as `discharged=true expires=null` — five LIVE obligations with no deadline, the exact state D2 exists to refuse, produced by rows citing a discharge rather than claiming one. Verified in derived_expiries.json before fixing. Now "was discharged": 5 occurrences of the scanned word to 0, and the four OPEN rows are back to `discharged=false expires=2026-09-30`' + - 'row 18 carries NO date literal and derives its expiry from row 15. D3 fired on the date inside "unblocked 2026-09-20 when row 1 was discharged" (narration, not a deadline) and row 18 had ALSO typed a literal 2026-10-07 while blocked by a live row 15, which is a D3 violation on its own account. The cell was wrong and the check was right: the committed must-fire `dag_nonroot_with_date_is_red` asserts a blocked row bearing a bare date is RED. Measured: 0 date literals in the cell, `expires=2026-09-30 derived_from=[15]`' + - 'the parser is DELIBERATELY not narrowed in this PR, and the reason is recorded rather than left implicit. Root cause is one COLUMN, not either regex: `status / expires` holds the status sentence and the expiry declaration together, so the parser must pick a declaration out of free prose and a scan cannot tell a citation from a claim. I-26 (PMAT-974, S0-2) already moved ROOT rows off that scan — EXPIRES_MARKER beats the first date, because a root row narrates work before its expiry — and left `_typed_on_blocked` reading the bare DATE fallback: one form variant fixed, its sibling left. Marker-only D3 would contradict `dag_nonroot_with_date_is_red`; dropping the bare fallback fires D2 on every LANDED root row whose date lives in its status sentence. The fix is splitting the column, a §12 change that does not belong in a release-blocking PR. Named as a follow-up in docs/audits/impl-PMAT-3556-receipt.md, Round 8' + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-3563 + github_issue: 3563 + item_type: task + title: 'Two llama.cpp comparator pins are live in-tree at once — 216 refs to d1d3c3396, 124 to 39173bcac; some committed artifacts measure against a superseded oracle' + status: in_progress + priority: critical + assigned_to: aprender-f0 + created: 2026-09-20T08:51:31Z + updated: 2026-09-21T17:00:00Z + spec: null + acceptance_criteria: + - 'Issue #3563 done_when, as the cop added it (comment 2026-09-21T16:35:16Z), verbatim: "done_when (added): exactly one pin in-tree; `llama_bin.sh` resolves and PROVES it on lambda and gx10 (a version+sha line) or fails naming why; every comparator consumer reads it"' + - 'THE SPLIT, recorded on the issue (comment 2026-09-21T16:49:53Z, "Split (cop ruling, aprender-04, 2026-09-21, order A → C → B). This issue now delivers (A) only"): this PR delivers clause 2 only, verbatim: "- **(A), this issue:** "`llama_bin.sh` resolves and PROVES it on lambda and gx10 (a version+sha line) or fails naming why". With nothing named, the resolver takes the pinned build at its CANONICAL location, `${LLAMA_PIN_SRC_ROOT:-$HOME/src}/llama.cpp-`. That path is derived from the pin, not searched for and not a host literal, and the build found there is verified by the same oracle-version, commit and cmake-cache checks as a named one. When it is absent the resolver FAILs naming the path and the declared build line. d1d3c3396 is built at that path on lambda (llama-bench and llama-tokenize added to the existing build) and on gx10 (a fresh build with `build_flags_gx10`)."; clause 3 is #3740 and clause 1 is #3741' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'P0 for the 0.69.1 path (cop, aprender-04): four 0.69.1 rows need ONE resolvable pinned comparator (#3726 tokenizer parity, #3725, #3596, #3693). SPLIT (cop ruling, recorded on the issue, comment 5764188590): this issue delivers (A) only, "llama_bin.sh resolves and PROVES it on lambda and gx10 (a version+sha line) or fails naming why". (C) "every comparator consumer reads it" is #3740; (B) "exactly one pin in-tree" (classify the 142 refs to 39173bcac and the 3 to 60b06ab9a, plus the citation guard) is #3741. Its own branch off main 52f43da71 (the merge-base; used as the quorum base). SCOPE: scripts/llama_bin.sh, scripts/check_llama_pin.sh, two evidence files under evidence/parity/pin-bump-d1d3c3396/, and this fragment. MEASURED BEFORE THE CHANGE: the tree has ONE pin, d1d3c3396 (scripts/llama_pin.toml build_commit). gx10''''s "39173bcac" was only its stale ~/src/aprender checkout (de0e3e182, 2026-08-28). On lambda, `bash scripts/llama_bin.sh` printed "FAIL … (no_binary_named) … reported: ": the resolver never searches (NEVER PATH), $LLAMA_BENCH_PATH was unset, and the pinned build sat unnamed at ~/src/llama.cpp-d1d3c3396, with llama-cli and llama-server but NO llama-bench (the resolver''''s candidate) and no llama-tokenize. ~/src/llama.cpp there is 60b06ab9a, whose llama-cli dies "undefined symbol: llama_memory_breakdown_print". gx10 had NO d1d3c3396 build (~/src/llama.cpp-pin is the old 39173bcac). HOW (A) IS MET. (1) THE CANONICAL LOCATION: with nothing named, llama_bin.sh takes ${LLAMA_PIN_SRC_ROOT:-$HOME/src}/llama.cpp-/build/bin/llama-bench. That path is DERIVED FROM THE PIN, not a PATH search and not a host literal, and the build found there passes the same oracle-version, commit and cmake-cache checks as a named one. A named $LLAMA_BENCH_PATH always wins. When it is absent, the executable mode FAILs naming the canonical path and the pinned commit to build ("fails naming why"). (2) THE ABBREVIATION LENGTH, found by running the resolver on gx10: gx10''''s correct build prints "commit d1d3c339" (8 hex digits; git abbreviates to what is unique in THAT clone), lambda''''s "commit d1d3c3396". The old test (the 9-digit pin as a substring of the version line) refused gx10''''s correct build as wrong_build. The commit token is now read out of either --version shape ("commit " or "()") and matched when one abbreviates the other at git''''s minimum of 7 hex digits (llama_commit_match). Like the build number, which llama_pin.toml already says is not an identity, the length is not. (3) THE BUILDS: on lambda, `cmake --build build --target llama-bench llama-tokenize` in ~/src/llama.cpp-d1d3c3396 (incremental, BUILD_EXIT=0; cache GGML_CUDA=ON with no CMAKE_CUDA_ARCHITECTURES, matching build_flags_lambda). On gx10, a fresh clone of ~/src/llama.cpp detached at d1d3c3396aa13a5f239109a822666c4870490ad5 into ~/src/llama.cpp-d1d3c3396, `cmake -B build -DGGML_CUDA=ON -DCMAKE_CUDA_ARCHITECTURES=121` (build_flags_gx10 verbatim), `cmake --build build -j 16`: BUILD_EXIT=0, 285M, llama-bench/cli/server/tokenize/completion, cache GGML_CUDA=ON CMAKE_CUDA_ARCHITECTURES=121. The disk was checked first (174G free, 81%). No GPU lock was needed for a build. PROOF, committed as evidence/parity/pin-bump-d1d3c3396/RESOLVE-lambda.txt and RESOLVE-gx10.txt: `env -u LLAMA_BENCH_PATH bash scripts/llama_bin.sh` rc 0 on BOTH hosts. lambda: "ok llama.cpp pinned: …/llama.cpp-d1d3c3396/build/bin/llama-bench / build: version: 0.4.1-dev (build 10987, commit d1d3c3396) / cmake: GGML_CUDA=ON CMAKE_CUDA_ARCHITECTURES=unset / pin expires 2026-12-01". gx10: "… build: version: 0.4.1-dev (build 2423, commit d1d3c339) / cmake: GGML_CUDA=ON CMAKE_CUDA_ARCHITECTURES=121 …" (run from a scratch copy of this branch''''s llama_bin.sh + llama_pin.toml, since gx10''''s own checkout is stale). CASE TABLE, scripts/check_llama_pin.sh (ci-wired as before). Every row now runs against a FIXTURE canonical root, never the operator''''s $HOME. New rows: nothing named with the canonical build present -> rc 0; the canonical build at the WRONG commit -> wrong_build; the canonical build''''s cmake disagrees -> cmake_mismatch; a NAMED path wins over the canonical build -> wrong_build; UNPINNED never falls back to a canonical build -> unpinned; an oracle abbreviating SHORTER (7) and LONGER (10) than an 8-digit pin -> rc 0; 6 hex digits (below git''''s minimum) -> wrong_build; a different commit of the same length -> wrong_build. MUTANTS, each killed: canonical-lookup (the path pointed nowhere, as before) -> "expected rc=0, got rc=1 (no_binary_named)"; substring-match (the pre-#3563 test) -> "oracle abbreviates SHORTER than the pin expected rc=0, got rc=1 (wrong_build)". MEASURED at this commit: `bash scripts/check_llama_pin.sh` rc 0. #3726''''s owner (aprender-c3) was told to use the pinned llama-tokenize at the canonical path on both hosts, not ~/src/llama.cpp.' +- id: PMAT-3567 + github_issue: 3567 + item_type: task + title: The fleet-pinned pv is 0.65.2 and has no 'extract' subcommand and no ' + status: planned + priority: medium + assigned_to: null + created: 2026-09-20T10:27:59Z + updated: 2026-09-20T10:27:59Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-3568 + github_issue: 3568 + item_type: task + title: Schema-constrained decoding in apr (--json-schema or grammar) — thre + status: in_progress + priority: medium + assigned_to: null + created: 2026-09-20T10:27:59Z + updated: 2026-10-10T00:55:00Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'Refs #3568, #3826. Schema-constrained decoding (--json-schema, --grammar, response_format) runs through one engine: Session::generate_constrained masks host logits before the repetition penalty and the sampler, so the constraint applies identically on the CPU and on CUDA. A constrained run takes CUDA where an unconstrained one does (dense and hybrid), and reports gpu_attempted, used_gpu and fell_back as an unconstrained run does (#3826). apr serve''s /v1/chat/completions response_format (json_schema, json_object) goes through the same engine on the GGUF CPU and CUDA routes; every other route refuses it by name (ASOC-INV-020, FALSIFY-RESPONSE-FORMAT-3568). Evidence (tests, plants, RTX 4090 and GB10 runs) is in the pull request.' +- id: PMAT-3569 + github_issue: 3569 + item_type: task + title: 'Decision 8: census.json becomes derived (CI computes, guard refuses PR' + status: inprogress + priority: medium + assigned_to: aprender-tarball + created: 2026-09-20T10:27:58Z + updated: 2026-09-24T20:00:00Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-3571 + github_issue: 3571 + item_type: task + title: apr serve routes the Qwen3.5 hybrid to Qwen35Model instead of the dense path + status: in_progress + priority: medium + assigned_to: aprender-c7 + created: 2026-09-21 00:00:00+00:00 + updated: 2026-09-21 00:00:00+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'ACCEPTANCE (cop rulings, moved from acceptance_criteria at the 0.69.1 fold: check_roadmap_diff_additive + forbids editing an existing entry''s acceptance_criteria, and notes is a lifecycle field): Cop ruling + (aprender-04, 2026-09-21, after an external user hit #3571 on main), unit (1), verbatim: "FIRST, the + smallest safe unit: no serve request handler may serve a model whose transformer stack resolved to + 0 layers, on any arch and both routes. Refuse at load, naming the arch and #3571, with a case row + plus a mutant. Stop at its receipt; I fold it with priority." | Cop condition (a), verbatim: "Siblings. + List every other `apr serve` load entry point (APR and SafeTensors starts, and any CLI-side serve + path in aprender-serve `cli`). In the body, say for each one whether it can reach a 0-layer model: + guarded, or unreachable and why. A fix to one copy makes the other copies look reviewed." | Cop condition + (b), verbatim: "(1) must not block (2). Qwen3.5''s generic stack is legitimately 0 layers, so when + (2) lands, qwen35 must route to Qwen35Session BEFORE the check, or the check must test the stack the + chosen route actually executes. Add a row to (2) proving qwen35 serve passes the refusal. (1) alone + refuses qwen35 on main, which is correct until (2)." || ACCEPTANCE (hand-entered from gh#3571 done_when; + see paiml-mcp-agent-toolkit#1414). Layer 1 of a surface no test had ever traversed: apr serve could + not load the flagship architecture at all, and each assumption was visible only once the one above + it cleared. Done when: handler_gpu_completion.rs branches on is_qwen35 and calls Qwen35Model::create_base_model + rather than falling through to the dense OwnedQuantizedModel path, which is the wrong architecture + for a Gated DeltaNet hybrid. Scope is deliberately ONE LAYER: land what works rather than hold the + whole stack behind the last unknown. STOP: do not claim the serve path is end-to-end green on Qwen3.5 + from this row alone — the layers above it are separate rows. + + + UNIT (1), the zero-layer refusal (aprender-c7). Measured on #3571 (issuecomment-5763718338) at release/0.70-batch-1 + 262dfb2f6, which has the fix of #3678: the qwen35 base reached the dense servers with 0 layers + — CPU route HTTP 200, content "", 1024 tokens of "\n" in 6.0 s; GPU route HTTP 500. On main it stops + earlier at the refusal, so this unit is what keeps main honest when batch-1 lands. THE CHECK: + `zero_layer_refusal(arch, layers)` (pure; ModelLoadFailed, exit 6, naming the arch, the 0 and #3571; + the apr run/apr chat hint only for qwen35) inside `build_serve_model`, the one GGUF loader of apr + serve. EVERY apr serve LOAD ENTRY POINT (condition a) — found by sweeping crates/apr-cli/src/commands/serve + for from_mapped / from_apr / from_apr_file / SafetensorsToAprConverter / spawn_apr_q4k_inference_thread; + ALL GUARDED: [1] GGUF --gpu, [2] GGUF --gpu --batch, [3] GGUF CPU — start_gguf_server takes its model + from build_serve_model BEFORE the route is chosen. [4] GGUF --backend wgpu (try_start_wgpu_backend) + and [5] the CPU fallback start_gguf_server_cuda rebuilds when CUDA init fails — both built their own + with from_mapped; both now load through build_serve_model (one GGUF loader, one check). [6] APR CPU + transformer (AprTransformer::from_apr_file), [7] SafeTensors single-file and [8] sharded (SafetensorsToAprConverter::convert + / convert_sharded): the helper on t.config.num_layers where the transformer is in hand. [9] APR GPU + (start_apr_server_gpu), [10] APR CPU quantized (try_apr_quantized_cpu), [11] SafeTensors GPU (start_safetensors_server_gpu), + [12] SafeTensors CPU quantized (start_safetensors_server_cpu_quantized): the helper on the OwnedQuantizedModel + before its Model ready line. [13] APR Q4K pool GPU (start_apr_q4k_server_gpu) parses its layer count + on the scheduler thread after the upload begins, so the count the file DECLARES is read first (AprV2Model::load + is mmap-based) and 0 is refused before the spawn; a file declaring none is refused by name inside + the pool path (parse_apr_q4k_config: APR metadata missing num_layers). [14] aprender-serve cli (serve_model + / prepare_serve_state): UNREACHABLE from apr — `git grep realizar::cli:: -- crates/apr-cli/src` has + no hit — and it builds GGUF models with from_mapped, which refuses the qwen35 hybrid by name. REPO-LAYOUT + FACTS a reviewer needs (round 1 lanes 1-3 misread them as compile errors; each checked at the head): + handlers.rs:1642 is `include!("handler_gpu_completion.rs")`, handlers.rs:1643 `include!("server.rs")`, + and handler_apr_cpu_completion.rs:869 `include!("handlers_include_01.rs")` — so build_serve_model + and zero_layer_refusal, defined in handler_gpu_completion.rs, ARE items of the `handlers` module, + callable unqualified from handlers.rs and handlers_include_01.rs, and reachable from the sibling module + as `super::handlers::zero_layer_refusal` (pub(super)). Proof it compiles: `cargo test -p apr-cli --lib + --features cuda zero_layer_refusal` builds apr-cli and passes both tests. CONDITION (b): on main this + refuses qwen35 serve outright (correct until unit 2). Unit 2 (branch PMAT-3571-serve-qwen35-session) + returns to the resident Qwen35Session BEFORE build_serve_model is called and adds the row proving + qwen35 serve passes. TESTS: zero_layers_is_refused_by_name_and_any_layer_is_admitted (the case table: + qwen35/0 and llama/0 refused, 1/28/24 admitted); serve_refuses_the_qwen35_base_at_load (real Qwen3.5-0.8B + through build_serve_model; SKIPs where the file is absent — lambda/gx10 carry it, CI does not). MUTANT: + deleting the check in build_serve_model turns serve_refuses_the_qwen35_base_at_load RED ("a 0-layer + stack reached the serve routes"), measured. + + + UNIT (2), the hybrid route (aprender-c7), stacked on #3595 (Qwen35Session) and on unit (1). apr serve + routes a hybrid GGUF to start_qwen35_server BEFORE build_serve_model, so the zero-layer refusal never + sees the hybrid base (condition b); the row qwen35_serve_passes_the_zero_layer_refusal_through_its_session + proves it on the real file (hybrid branch taken; build_serve_model refuses the base naming #3571; + the hybrid state serves every layer from the session). realizar: AppState::with_qwen35_session holds + the resident session and deliberately NO quantized_model, so no dense endpoint can decode through + the base (a_dense_endpoint_no_longer_decodes_through_the_zero_layer_base: /v1/completions is no longer + HTTP 200). /v1/chat/completions tries the hybrid first (try_qwen35_backend): the template is the one + the MODEL''s architecture selects (format_messages -> detect_format_from_name), encoded with the GGUF''s + own tokenizer so serve hands the model the tokens apr run and apr chat do; the session runs on the + blocking pool, one request at a time, a request extending the previous one''s tokens reuses its state; + the declared context length sits beside the mutex so an over-context prompt is a 400 naming both numbers + without waiting on a running generation; a reply the context cut short is finish_reason length. TESTS + (real Qwen3.5-0.8B; SKIP where absent): a_chat_request_answers_what_apr_run_answers and a_streamed_chat_request_answers_what_apr_run_answers + (byte-equal to the one-shot run_qwen35_generate_dispatch on the same route), a_dense_endpoint_no_longer_decodes_through_the_zero_layer_base, + a_prompt_past_the_declared_context_is_a_400_naming_both_numbers, gpu_a_chat_request_answers_from_the_gpu_session + (and stays on the GPU — this test found the cross-thread CUDA_ERROR_INVALID_CONTEXT fixed in #3595 + 5d372ca7e). OUT OF SCOPE here: the apr serve ladder rung and its positive control (issue acceptance + 3 and 4) live in scripts/model_ladder.sh / contracts/model-capability-ladder-v1.yaml, owned by aprender-62 + under #3712 — handed over, not edited here; so this unit says Refs #3571, not Closes. The thinking + toggle is #3723 (aprender-fd); the startup line reports the DEFAULT template. CI ROW FOR THE CALL + SITE (cop, non-blocking): serve_refuses_a_synthetic_zero_layer_hybrid_base_at_load writes a synthetic + qwen35 header with aprender-core''s GGUF writer (config declares one block; only token_embd, output_norm + and output tensors) and needs no model file; the call-site mutant (check deleted from build_serve_model) + turns it RED — measured. It has to be the hybrid: the dense loader already refuses block_count 0 at + config validation ("Invalid shape: num_layers must be > 0", measured with a llama fixture), so the + hybrid base — config declares N, layers empty — is the one zero-layer stack this tree can build. STARTUP + LINE (f8, #3719): `chat template: (thinking off|on|the model''s + choice)`, the mode read off the RENDERED assistant prefix (closed = off, open = on), + never off a template name — #3755 replaces the template qwen35 selects today and the line then reports + the new one with no edit here. HEALTH (found by the serve e2e on lambda at 5d09a6885): a Qwen3.5 server + answered /health and /health/ready with 503 "loading" forever — AppState::model_loaded() counted every + dense model type and the qwen35 state holds none, deliberately. model_loaded() now counts the session; + /health compute_mode reads an AtomicBool beside the session mutex (never waits on a running generation), + refreshed after every generation so a fallback is reported. Row: a_qwen35_server_reports_healthy_and_ready + (200 on both, model_loaded true); mutant (the session dropped from model_loaded) RED with the production + symptom, measured.' +- id: PMAT-3574 + github_issue: 3574 + item_type: task + title: ARB-APR-3 parity receipt for the decide lane cell on lambda-labs + status: planned + priority: high + assigned_to: null + created: 2026-09-20T11:20:51Z + updated: 2026-09-20T11:27:22Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-3577 + github_issue: 3577 + item_type: task + title: 'Receipts under contract: parity-receipt-v1 shape, extract:parity-receipt, back-fill 7 receipts (ONT-4c3 re-scoped)' + status: planned + priority: critical + assigned_to: null + created: 2026-09-20T11:34:01Z + updated: 2026-09-20T11:34:17Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'ACCEPTANCE (transcribed from gh#3577, incl. the dated AMENDMENT of 2026-09-21 02:00Z which supersedes the original item 1; §6 1e — the fragment transcribes the issue, it does not edit it). Spec: docs/specifications/ruling-receipts-under-contract.md (operator ruling 2026-09-20). ITEM 1 AS AMENDED, verbatim: "contracts/parity-receipt-v2.yaml carries the shape (the constraints table below, unchanged) in its shape: block, exported to contracts/shapes.ttl. contracts/parity-receipt-v1.yaml is the SHAPELESS superseded form and says why in its own text: no v1 instance exists after the back-fill, and a shape over zero instances is a vacuous pass. A v1 record is refused BY NAME by the extractor (extract:parity-receipt) and, independently, by scripts/parity_receipt_denominator.sh — two readers, both wired (#3600 ci.yml step). A future v1 instance is therefore a refusal, not a silent pass." WHY AMENDED: the original item 1 said "parity-receipt-v1.yaml with its shape" and predates the migration — all 7 records went to v2 in the same commit, so v1 has ZERO instances, and a shape over a class nothing instantiates passes vacuously, which is the defect #3610 names and #3622 makes the shapes gate DECLINE on. Following it literally would add in one PR the thing the other PR exists to refuse. Both pro lanes read the original correctly and failed the PR on it; the ruling is on the acceptance, not the lanes. ONT-4c3 LEDGER BINDING: that ledger lives in paiml/infra (ONT-001 v4.10, infra#831) and CANNOT be done from this repository. The aprender-side deliverable is extractor + shape + denominator + receipts; the ledger row is infra s. The acceptance reads "bound in the ONT-001 ledger" as infra s row, CITED, not as a change here. REMAINING done_when, unchanged: extract:parity-receipt implemented; pv lint --gate shapes --path evidence/ in the required check; PR body shows 7 older receipts RED before back-fill and 0 after, plant violation = 1, mutation RED, pc_shape fired; check_parity_receipt.sh folded into the shape or its remainder listed under not_expressible; verdict rendered on a fleet host once the pv pin lands, else checkout-only: true. Sigma parent bound: json. Back-fill denominator: 7. STOP: subset-insufficient; shared-file-touched without the guard label; any threshold typed into the shape instead of resolved from thresholds.yaml; and do NOT add a v1 shape — see the amendment.' +- id: PMAT-3587 + github_issue: 3587 + item_type: task + title: 'nextest fail-fast discards verdicts: one failure hid 15 unmeasured commands and the shard read as ''1 failure'', not ''1 failure + 15 Unknown''' + status: planned + priority: critical + assigned_to: null + created: 2026-09-20T12:37:48Z + updated: 2026-09-20T12:37:48Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'ACCEPTANCE (hand-entered from issue #3587 "What lands"; minted on the PR branch so the AD-04 quorum can run -- pmat work status refuses a missing item). Two halves: the explicit-command runner (#3616, merged) and the nextest [profile.ci] key (#3626). Lands: 1. **--no-fail-fast on the shard.** The cost is runner minutes on an already-red shard; the benefit is that a red run still measures everything else it was going to measure — which is exactly when you most want the data. 2. **The reducer reports ran / skipped / total** in the shard receipt. The skipped count is a **number**, never an absence. 3. **A receipt with skipped > 0 is Unknown, not Fail and not Pass** — it names what was not measured, per doctrine 4. ' +- id: PMAT-3595 + github_issue: 3595 + item_type: task + title: 'apr chat hard-skips CUDA for every qwen35 model and prints a banner citing #3090 as unimplemented — #3090 shipped a day earlier, and the corrected replacement has zero callers' + status: in_progress + priority: high + assigned_to: aprender-c7 + created: 2026-09-21T16:09:46Z + updated: 2026-09-21T16:09:46Z + spec: null + acceptance_criteria: + - 'Issue #3595 done_when 1, verbatim: "`chat_load_tokenizers.rs` calls `qwen35_route_notice` and **attempts CUDA for `qwen35`** like any other architecture; the unconditional early return goes."' + - 'Issue #3595 done_when 2, verbatim: "A test asserts the two cannot drift again: a `qwen35` model on a CUDA-capable binary must reach the upload path. The current shape passes every test precisely because nothing asserts the GPU is tried." Strengthened by the issue''s own correction comment (2026-09-20T14:10Z), verbatim: "the test must assert the **printed banner** against the **actual route**, not merely that the GPU is reached. Today''s behaviour reaches the GPU *and* prints that it cannot, so any test asserting only \"the GPU was used\" passes on the broken state."' + - 'Issue #3595 done_when 3, verbatim: "**One message per outcome, naming the actionable half** — which tensor, which dtype, and that a `Q4_K_M` build is GPU-eligible. Not two messages with different reasons."' + - 'Cop ruling (aprender-04, 2026-09-21), the 0.69.1 bar for this row, verbatim: "done_when: chat runs on CUDA with no fallback for every Qwen3.5 Q4_K_M size (0.8B–27B) on lambda AND gx10, multi-turn, correct answers."' + - 'Cop ruling (aprender-04, 2026-09-21) on the root cause measured on this issue, verbatim: "The fix keeps the qwen35 CUDA model and its KV resident across turns (extend the GH-224 session cache to Qwen35CudaModel), with the F2 guard once per session. Put it on #3595, with measured per-turn time and memory before and after on both hosts."' + - 'Cop ruling (aprender-04, 2026-09-21) on the raised bar, verbatim: "Your part is that chat and serve accept and handle long prompts without truncating silently." — a conversation longer than the resident state grows the state; one longer than the model''s declared context length is REFUSED by name, never cut.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'Gap measured at 0.69.0 (225b2a9ab) on lambda (RTX 4090, sm_89) and gx10 (GB10, sm_121) before any code, posted on #3595 (issuecomment-5763540923). ROOT: the GH-224 session cache holds only the DENSE OwnedQuantizedModelCuda; try_init_gguf_cuda returns (None, false) for qwen35, so every chat turn falls through to generate_gguf_cpu_tokens, which calls Qwen35Model::create_base_model + run_qwen35_generate_dispatch — a fresh Qwen35CudaModel upload, an F2 sha256 of the whole file (27B: 7.5-8.3 s), a token-by-token re-prefill of the whole conversation, and on sm_121 a PTX re-JIT, all PER TURN. nvidia-smi on lambda 9B: 1187 → 6772 → 6936 → 1576 → 6772 → 6936 → 1576 MiB. Under contention the 9B turn-2 re-allocation hit CUDA_ERROR_OUT_OF_MEMORY and fell back to the CPU (99.7 s). + + Shape of the fix: realizar gains `Qwen35Session` (gguf/inference/forward/qwen35_session.rs) — the hybrid built ONCE, F2-validated once on the first turn''s real prompt (the file hashed once, at load), and a decode state that outlives the turn. A prompt that extends the tokens the state already holds prefills only the new suffix; any other prompt resets the state in place (conv + recurrent state zeroed on the device, KV marked empty) and prefills it whole, on the SAME resident model. The state grows by doubling up to the GGUF''s declared context length; a prompt that cannot fit is refused by name, and a generation budget cut by the context is reported, never silent. The GPU fallback stays loud and keeps QWEN35_GPU_FALLBACK_PREFIX. The same type is what #3571 routes `apr serve` to. + + OUT OF SCOPE here, and why: issue done_when 4 (a tree-wide guard for "a pub fn whose doc says live behaviour elsewhere is wrong, with zero callers") is a guard with its own universe and falsifier, filed as a follow-up rather than bundled; so the PR says Refs #3595, not Closes. The --thinking on|off switch is #3723 (aprender-fd); chat consumes it once it lands. aprender-fd''s qwen3-8b chat-template change (f46063527) touches chat_load_tokenizers.rs and chat_session_02.rs in hunks disjoint from this row''s.' +- id: PMAT-3596 + github_issue: 3596 + item_type: task + title: 'Qwen3.5 hybrid has NO batched CUDA prefill — qwen35_gpu_decode loops forward_single over every prompt token (9B: 235 s for one output token on an ~5.7k-token brief, ~24 tok/s prefill); batched/chunked prefill usable to the declared context' + status: in_progress + priority: critical + assigned_to: aprender-3e + created: 2026-09-21 16:20:00+00:00 + updated: '2026-09-21T17:20:00Z' + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'ACCEPTANCE — transcribed VERBATIM from issue #3596 "## done_when (added)" (comment 2026-09-21T15:57:35Z, the 0.69.1 P0 move): "- [ ] a batched (chunked) CUDA prefill for the Qwen3.5 hybrid (attention layers batched; the Gated DeltaNet recurrence in chunked form) on lambda and gx10, parity-checked against the per-token path at ≥ 64 positions and at 20k" · "- [ ] TTFT for a 20k-token prompt on the 9B measured on both hosts and recorded in the receipt, against llama.cpp at the pinned comparator on the same prompt (the ratio is reported, never claimed as a target)" · "- [ ] `apr run --json` reports `prefill_ms` and `prompt_tokens` (with #3718)". AMENDMENTS — VERBATIM from the cop''s comment on #3596 (2026-09-21T16:12:21Z): "**Amendments (cop, 2026-09-21), for the quorum to judge against:** 1. **"chunked form" is defined:** a chunk-resident scan of the Gated DeltaNet recurrence (state held on-chip across the chunk) that is **bitwise-identical to the per-token recurrence**, measured, is acceptable. The WY/UT chunkwise-parallel form is required only if the scan''s measured share of prefill exceeds 15 %. (aprender-3e''s design note §3, issuecomment-5763674795.) 2. **Context rungs** (operator, verbatim: "lets ensure this release has MORE than enough tokens for our needs (overdo it)"): TTFT is recorded and output is correct at **4k · 8k · 20k · 60k · 148k · 262,144** (every Qwen3.5 GGUF declares `context_length = 262144`, measured) on lambda AND gx10. Where a host''s memory can''t hold a rung (3e''s arithmetic: the 27B on a 24 GB 4090 tops out ≈98k with f16 KV; the 9B at 262k needs f16 KV), apr **refuses before loading, naming the arithmetic**, never OOMs mid-run. Whether that cell may be waived is the operator''s decision (below), not this row''s. 3. **KV precision:** f16 KV is allowed where parity against the f32 path holds (measured at each rung). The choice is printed in `--json`. 4. Decode speed at long context (split-K for the 16-block decode kernel) is a **separate row**, filed next." · F16 SPLIT — VERBATIM from #3596 (2026-09-21T16:20:40Z): "**f16 KV split (agreed with aprender-3e, 2026-09-21):** f16 KV is a storage format touched at four sites: (1) prefill K/V row writes, (2) prefill attention reads, (3) per-token decode row writes, (4) decode attention reads. **#3596** owns the storage type (the f32|f16 tag on `Qwen35CudaState`) plus sites 1–3 and the capacity check that picks f32 / f16 / refuse. **#3725** owns site 4 (the split-K decode kernel reads f16 as well as f32). Until #3725 lands, #3596 ships the f16 branch wired but REFUSING, with the reason "f16 KV decode read not available (#3725)"; no path serves f16 half-done. f16 vs f32 parity is measured on gx10 once both land." · OPERATOR DECISION (relayed by the cop 2026-09-21; verbatim choice "a"): the 27B rungs above what the 4090 holds are owed on gx10 at 262,144; on lambda apr REFUSES before loading, naming the arithmetic; KV quantization (q8/q4) is NOT in 0.69.1. The ORIGINAL done_when items 1–6 of #3596 (TTFT in BEATS.md, apr bench accepting hybrids, the (cached) suffix, the pinned comparator, root-causing the 14 s) belong to #3598/#3604/#3606 rows and are NOT claimed here; this row uses `Refs #3596` unless the issue owner rules the whole issue closable. File boundaries agreed with aprender-c3 (#3693): new kernel files under aprender-gpu/src/kernels/gdn/, new gguf/cuda/forward_qwen35_cuda_prefill.rs, edits limited to forward_qwen35.rs (qwen35_gpu_decode + F2 GPU probe) and forward_qwen35_cuda.rs (state sizing); decode_attention.rs untouched. prefill_ms definition agreed with aprender-a8 (#3718, #3606 StageTimings): forward over post-template prompt tokens up to the first generated token logits, excluding load/h2d/validate/tokenization; null never 0.' +- id: PMAT-3601 + github_issue: 3601 + item_type: task + title: 'apr inspect has no byte-size entry for any IQ-family ggml type — aprender-core sizes and names ggml types from trueno_quant::TRAITS' + status: planned + priority: high + assigned_to: null + created: 2026-09-21T05:47:55Z + updated: 2026-09-21T05:47:55Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'ACCEPTANCE (hand-entered from issue #3601 done_when, verbatim; minted on the PR branch so the AD-04 quorum can run). Done when: (1) apr inspect succeeds on a GGUF containing any of the 10 listed ids (repro: Qwen3.5-4B-UD-Q4_K_XL.gguf, dtype 23). (2) A regression test pins all 10 ids against shape.rs''s byte_size, analogous to ggml_type_table.rs''s spot_checks_against_ggml_sizes, so a future edit can''t silently drop one back out. (3) The error message, if a truly unknown id is ever hit, names the id and points at contracts/apr-cli-commands-v1.yaml''s inspect docs or similar — not a bare "Unsupported dtype N". DEVIATION FROM THE ISSUE''S FIX PROSE (not its done_when): the issue proposed porting rows from aprender-serve''s GGML_TYPES because "the unified TRAITS crate #3430 proposes doesn''t exist yet"; #3581 has since landed it (aprender-quant ggml_type.rs TRAITS[43], upstream-extracted, fixture-checked) and aprender-core already depends on it, so shape.rs reads TRAITS instead of becoming a fifth hand copy. ALSO IN THIS DIFF (same defect class, measured on apr 0.68.2 00e5d2dde): (a) apr tensors sized tensors from a second hand-typed table in aprender-core (safetensors.rs ggml_dtype_element_size SIZES) with seven IQ rows wrong and the 26-30 tail misordered (BF16 0.375 bytes/elem) — it refused the valid Qwen3.5-0.8B-UD-IQ2_XXS.gguf as "Truncated GGUF … 167936 bytes too short"; now type_size/blck_size from TRAITS. (b) ggml_dtype_name (a third copy, ids 0-30) reads TRAITS so TQ1_0/TQ2_0 are named rather than "unknown"; contracts/apr-inspect-dtype-naming-v1.yaml GGML_NAMES + KANI bound amended to match. Behaviour preservation: every id sized before keeps its exact byte count (floor arithmetic kept; characterization test over non-block-multiple counts), ids 0-30 keep their names. The IQ fabrication this sizing exposes is PMAT-3656 (#3656), fixed in the same diff.' +- id: PMAT-3602 + github_issue: 3602 + item_type: task + title: 'apr run --gpu reported a CPU fallback as success: registry::after_generation had no production caller' + status: in_progress + priority: high + assigned_to: null + created: 2026-09-21T00:00:00Z + updated: 2026-09-21T00:00:00Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'ACCEPTANCE (hand-entered from gh#3602 done_when; pmat work add derives neither spec: nor acceptance_criteria: — paiml-mcp-agent-toolkit#1414). Item 1: the GPU rejection is surfaced on a stream a user reads AND in --json. Item 2: SATISFIED BY #3606 — validate_ms instruments validate_gpu_first_token, measured 15.1s on qwen2.5-coder-0.5b; not owed again here. Item 3: root cause named for the dense path — ANSWERED, it is FP8 PREFILL, established by a 2x2 over FP8_PREFILL x FP8_DECODE with both flags named in every cell (divergence tracks FP8_PREFILL exactly, independent of FP8_DECODE; 34.3s used_gpu=false vs 16.9s used_gpu=true); a single-knob bisect could not separate them because detect_fp8_decode falls through to fp8_prefill. Item 4: the fail-vs-fall-back decision RECORDED — it already was, in registry::after_generation (R-0b, gh#3002/#3042): forced accelerator that fell to CPU = refusal exit 14, default selection = corrective line. The defect was that it had NO PRODUCTION CALLER; nor do registry::announce or registry::parity_line, which is why a real run prints zero selected: and zero parity: lines. Item 5: falsifier both ways — 6 cases in run_tests_accel_reconcile.rs; planting the pre-fix behaviour turns the two defect tests RED while the healthy-GPU control stays green. Measured on lambda RTX 4090 sm_89, apr 0.68.2 (e6f77c98c). NOT IN SCOPE, deliberately: the rejection REASON (cosine, position) is not plumbed into --json — it is produced inside realizar F2 and no channel carries it to the CLI; that is a #3606-shaped follow-up, not a value to approximate. STOP: do not widen f2_should_retry_without_fp8 here — that band belongs to gh#3483, reopened with the contradicting measurement. BLAST RADIUS: exit code changes on a shipped surface; 14 files under scripts/ and .github/workflows/ pass --gpu, incl. perf_gate.sh, parity_host_receipt.sh, model_ladder.sh — CI going red on one is the measurement, and its fix belongs on that gate.' +- id: PMAT-3604 + github_issue: 3604 + item_type: task + title: 'f2_validate_qwen35 runs a full CPU reference forward on EVERY call (67% of a 14s TTFT) — run it once per (model sha256, apr version, device) and receipt it' + status: planned + priority: critical + assigned_to: null + created: 2026-09-20T22:25:52Z + updated: 2026-09-20T22:25:52Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'ACCEPTANCE — transcribed from issue #3604 done_when (minted by the cop so the AD-04 quorum for PR #3634 can run; pmat work status refused on a missing item). (1) Validation runs once per (model sha256, apr version, device); subsequent runs of the same triple read the receipt. (2) --revalidate forces a fresh validation and rewrites the receipt. (3) Falsifier: a planted receipt carrying the wrong model sha256 must cause re-validation, not a skip. Same for a receipt written by a different apr version, and one written for a different device. Three planted-receipt cases, each asserted to re-validate. (4) A missing or unreadable receipt validates — absence is never consent. (Unknown/skip is not an option here; the fallback is to do the work.) (5) validate_ms in apr run --json (#3598) reports the cached case distinguishably from the fresh case, so the saving is readable from the receipt rather than inferred from a stopwatch. (6) Measured before/after TTFT on the 144-word row, on the same box with GPU occupancy recorded at start. ADMISSION: 0.69 if it is green by the cut, 0.70 otherwise — readiness rule, not date pressure. EXPLICITLY OUT OF SCOPE (three questions the instrument lane raised and did not answer; none block this row and none should be folded in): whether the CPU reference or the GPU probe dominates the 9.5 s (timed as one unit); whether a cheaper equivalent guard exists; the flat ~1.18 s unattributed_ms residual — recorded rather than absorbed into a neighbour, and the next stage to name. Refs #3596, #3598, #3080.' +- id: PMAT-3605 + github_issue: 3605 + item_type: task + title: 'removed_by gets a shape: refusal-receipt-v1 with a closed escape set' + status: in_progress + priority: medium + assigned_to: null + created: 2026-09-21T00:00:00Z + updated: 2026-09-21T00:00:00Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'ACCEPTANCE (hand-entered from gh#3605 done_when; see paiml-mcp-agent-toolkit#1414). Done when: contracts/refusal-receipt-v1.yaml exists with a shape over removed_by, and the value space is a CLOSED SET rather than free text: pattern ^(v[0-9]+\\.[0-9]+|never|unscheduled)$. The point of the closed set is that legitimately-nothing stays SAYABLE and CHECKABLE — never and unscheduled are honest answers with a shape behind them, instead of a required field manufacturing a fake version. Fixtures cover each arm of the alternation plus a rejecting case. STOP: do not admit free text; do not make the field optional, which would make absence indistinguishable from a deliberate never.' +- id: PMAT-3609 + github_issue: 3609 + item_type: task + title: 'The BPE tokenizer requires a '''' token that Qwen3.5 does not have — a universal unknown-token is an assumption, not a fact' + status: in_progress + priority: high + assigned_to: aprender-62 + created: 2026-09-21T09:00:00Z + updated: 2026-09-21T09:00:00Z + spec: null + acceptance_criteria: + - 'Operator ruling on #3609 (2026-09-20), constraint 1, verbatim: "`unk` becomes `Option`; absent means absent. No synthesis in either direction. That is stronger than the original framing and deliberately so: the `vocab[0] = ""` placeholder for an absent vocabulary goes too. A GGUF with no vocabulary refuses by name — it does not load. Today it loads, which is the inversion this ticket is about; removing only the refusal on the present-but-lacking side would leave the permissive fallback intact and simply move the asymmetry. The two-direction falsifier already proposed covers both: a model with an unknown token still resolves it (so the fix is not \"ignore unk\"), and a model with no vocabulary now refuses (so the fix is not \"synthesise one\")."' + - 'Constraint 2, verbatim: "Prose changes in the same PR, or the belief is reproduced. `book/src/examples/api-server.md` and `examples/model_cache.rs` both repeat \"vocabulary must include ``\" — a property of our constructor stated as a property of the data. Run `pmat query` for `` and `unknown_token`; every hit is either fixed or listed in the PR body as intentionally kept. A hit that is neither is the defect''s next copy."' + - 'Constraint 3, verbatim: "Mutation: reintroduce the `ok_or_else` → the Qwen3.5 fixture goes RED. A fix with no red-turning mutation is a claim. The fixture must be a real Qwen3.5 GGUF header — the family declares `tokenizer.ggml.eos_token_id` and no `unknown_token_id` key at all, which is the actual input, not a synthetic one."' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'Taken by aprender-62, sequenced ahead by the cop (aprender-04). Two interpretation decisions, sent to the cop before implementation: (1) THE FIXTURE. The real Qwen3.5-0.8B header is 10.9 MB (248,320 tokens, 247,587 merges), too large to commit. The fixture is a header-only GGUF generated from the real file: every one of its 46 keys and every scalar value verbatim (eos 248046, padding 248055, model gpt2, pre qwen35, the chat template; no unknown_token_id and no bos key, exactly as in the real file), with only the three arrays (tokens, token_type, merges) cut to a leading slice. Qwen''s first 256 tokens are its byte-level glyphs, so the slice still covers every byte. The generator is committed next to it and records the source header''s sha256. (2) WHERE THE UNKNOWN TOKEN COMES FROM at the vocabulary-only constructors, which receive a Vec and nothing else: the vocabulary''s own `` entry when it has one, otherwise none. Nothing is synthesised, and every model that loads today keeps its unknown token. Threading `tokenizer.ggml.unknown_token_id` through every loader is a filed follow-up, not a silent gap. + + The cop ruled both decisions YES on 2026-09-21. It also added a guard, verbatim: "When the glyph for a byte is ALSO absent, encode must refuse with an error naming the byte. It must never drop the input or emit nothing. Put a row for it in the case table (a vocab without that glyph and without unk → error). Absent means absent at encode time too." How it is met: `encode` returns an infallible Vec and has dozens of callers, so the refusal happens at CONSTRUCTION. With no unknown token, `BPETokenizer::new` refuses, naming the first byte that has neither a `<0xNN>` token nor a byte-level glyph token. `with_merges` also requires every glyph, because the merge path maps bytes to glyphs only. `encode` therefore cannot meet an unencodable byte, and the no-drop guarantee holds on every path. Case row: `no_unknown_token_and_a_byte_with_no_token_is_refused_by_name` (a 256-glyph vocabulary minus byte 0xA9''s glyph → error naming 0xA9). With the unknown token present, encode is unchanged: `<0xNN>`, then the unknown token. The glyph fallback applies only when there is no unknown token. Follow-up filed before the PR: #3675 (thread the DECLARED unknown token through every loader; by-name `vocabulary_unk_token` is the interim, and `apr serve`''s chat path already uses tokenizer.json''s declared `model.unk_token`). Found while testing, filed separately because it is independent of the unknown token: #3677 (the greedy path matches Latin-1 characters such as `é` as byte-level glyph tokens, so `é` decodes to U+FFFD). The Qwen round-trip rows therefore use ASCII, CJK and newline, not `é`. Same class but outside the query''s hits, so not in this PR: `apr showcase`''s pipeline substitutes token ids [1,2,3,4,5] when a model has no vocabulary (commands/showcase/pipeline.rs:165). + + Repo-layout facts a reviewer needs, each checked at the PR head (round 2 lane 1 misread all three, and every one is refuted by `cargo check -p apr-cli` rc=0 and `cargo test -p apr-cli --lib` 7283 passed at e5b2e7541). (1) `realizar` IS aprender-serve: crates/aprender-serve/Cargo.toml:42-43 is `[lib] name = "realizar"`, so `realizar::tokenizer::BPETokenizer` in apr-cli and `crate::tokenizer::BPETokenizer` in aprender-serve are the SAME type, and `realizar::tokenizer::vocabulary_unk_token` (the book, api-server.md) is the function this PR adds. (2) `no_vocabulary` in apr-cli is defined ONCE, at crates/apr-cli/src/commands/serve/handler_gpu_completion.rs:482, and is visible to every serve site because these files are one module: handlers.rs:1618 is `include!("handler_apr_cpu_completion.rs")`, handlers.rs:1619 is `include!("handler_gpu_completion.rs")`, and handler_apr_cpu_completion.rs:869 is `include!("handlers_include_01.rs")`. (3) aprender-serve''s cli has its own `no_vocabulary` (cli/mod_server_commands.rs:13, returning RealizarError), inside the same `mod server_commands` as its six call sites.' +- id: PMAT-3610 + github_issue: 3610 + item_type: task + title: 'shapes gate reported Pass over ZERO focus nodes: per-shape vacuity, not a global total' + status: in_progress + priority: medium + assigned_to: aprender-pvl-a + created: 2026-09-21T00:00:00Z + updated: 2026-09-24T00:00:00Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'ACCEPTANCE (hand-entered from gh#3610 done_when; see paiml-mcp-agent-toolkit#1414). The defect: NoFocus asked the question GLOBALLY (report.focus_nodes_n == 0), which is only ever true for a lone contract. In a DIRECTORY one empty shape is invisible — the others carry the total above zero, the empty one contributes no violations, and the aggregate reports Pass WHILE LISTING IT IN armed_shapes, which is the tool s claim about what it measured. Done when: vacuity is computed per-shape before any verdict is formed; an ARMED shape at zero declines (exit 2, Unknown(NoFocus), named in declines[]); an UNARMED shape at zero is REPORTED in declines[] and does not refuse; a vacuous shape appears in NEITHER armed_shapes NOR not_armed_shapes, because filing a vacuity as a policy choice is how it hid. BOTH VENUES: the lone-contract case already declined correctly, so a fix proved only there proves nothing. pass/fail/decline must stay distinct (0/1/2) and all three must still emit a parseable report with by_shape, since downstream captures stdout regardless of exit code. STOP: do not refuse whenever anything is empty — that breaks the unarmed direction. PRECEDENCE (#3622 re-review, cop ruling B, 2026-09-23): a measured violation outranks a vacuity — an armed zero-focus shape beside a violating armed shape is Fail/exit 1, with the vacuity still named in declines[]. The global NoFocus path (every shape at zero) declines with exit 2 but prints no report yet: #4100.' +- id: PMAT-3611 + github_issue: 3611 + item_type: task + kind: code + title: 'pv: implement sh:lessThan / sh:lessThanOrEquals (SHACL Core property pairs)' + status: inprogress + priority: medium + assigned_to: pvl-b + created: 2026-09-24T18:24:24Z + updated: 2026-09-24T18:24:24Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-3618 + github_issue: 3618 + item_type: task + title: 'Release scripts still carry 0.68.2''s V/T/MS/EPIC and AP=/mnt/... — and the hardcoded-path ratchet does not match /mnt, so nothing catches it' + status: planned + priority: high + assigned_to: null + created: 2026-09-21T05:36:49Z + updated: 2026-09-21T05:36:49Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'ACCEPTANCE (quoted from issue #3618 "done_when"): 1. V/T/MS/EPIC are derived or passed, never literals. 2. AP is derived from the repository, not from a path under /mnt. The scripts are in-tree now; an out-of-tree bundle path is a leftover of where they used to live. 3. Either the /mnt blind spot closes (#3592) or this row ships its own assertion that no release script references a path outside the repo. Prefer the first — the blind spot affects every script, not these. 4. Falsifier: reintroduce a literal /mnt/... in a release script and require a gate to go RED. If nothing can be made to go red, item 3 is unsatisfied regardless of what was edited. SCOPE NOTE (author): this row ships its own assertion (item 3, second branch); #3592 stays open for the analyser itself.' +- id: PMAT-3627 + github_issue: 3627 + item_type: task + title: 'rmsnorm_contract::prop_scale_invariance asserts the ε=0 theorem against the ε=1e-6 implementation — fails whenever α²·mean(x²) ≈ ε (killed #3621 shard 1/3)' + status: planned + priority: critical + assigned_to: null + created: 2026-09-20T21:27:27Z + updated: 2026-09-20T21:27:27Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'ACCEPTANCE (hand-entered from issue #3627 done_when; minted on the PR branch so the AD-04 quorum can run -- pmat work status refuses a missing item). Done when: contracts/rmsnorm-kernel-v1.yaml Scale invariance obligation carries either the ε>0 formal or the α²·mean(x²) ≫ ε precondition; pv validate passes ~~regenerated with pv probar --binding~~ **WITHDRAWN 21:40Z** — b3 measured that pv probar --binding emits 7 #[ignore = "no binding available"] stubs for this contract; the tracked file''s 5 real tests were produced by the pre-monorepo external generator (20dda945b, 2026-02-18) and the header is false (class row: #3630). Instead: the tracked test is edited **directly**, the commit says so, and the file''s header is replaced by a true one (hand-maintained, contract-bound) the minimal input above ([0.0, -0.15964308], α=0.012254778) is a committed regression case that PASSES under the new assertion (i.e. the fixed test is exercised on the exact input that killed #3621), and a mutation that restores the ε=0 assertion turns it RED cargo' +- id: PMAT-3629 + github_issue: 3629 + item_type: task + title: 'fleet_utilization.sh --selftest: printf | grep -q under pipefail reads a MATCH as FAIL when grep closes the pipe first — red main''s guard-tree on gx10-pool3; 55 sibling sites in 31 scripts' + status: planned + priority: critical + assigned_to: null + created: 2026-09-20T21:34:44Z + updated: 2026-09-20T21:34:44Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'ACCEPTANCE (hand-entered from issue #3629 done_when; minted on the PR branch so the AD-04 quorum can run -- pmat work status refuses a missing item). Done when: scripts/fleet_utilization.sh --selftest has no pipe into grep -q; a mutation that restores the pipe AND forces EPIPE (out padded to >64 KiB so the write cannot complete before grep exits) turns the self-test RED deterministically — the positive control for the race, in the PR body the 55-site count is in the PR body from the command that produced it, and a guard refuses a new site (check_guards_are_wired.sh names it; ratchet baseline committed) main''s guard-tree green on the merge commit without rerun ' +- id: PMAT-3637 + github_issue: 3604 + item_type: task + title: 'Register PMAT-3604 in the roadmap so the AD-04 quorum for PR #3634 can run (registration only; the implementation is PR #3634)' + status: planned + priority: high + assigned_to: null + created: 2026-09-20T22:39:43Z + updated: 2026-09-20T22:39:43Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:triage + notes: 'ACCEPTANCE (this row is PR #3637 itself, a roadmap-only registration): (1) docs/roadmaps/entries/PMAT-3604.yaml exists with id PMAT-3604, github_issue 3604, kind:code, and its notes transcribe issue #3604 done_when items 1-6 faithfully — every criterion present, none added, the admission rule and the out-of-scope list as the issue states them; (2) docs/roadmaps/roadmap.yaml equals aggregate(entries/) and the diff vs origin/main is additive only (deleted=0, reserialised=0); (3) the PR body carries keep-open for #3604 and the diff touches nothing outside docs/roadmaps/ except this row''s own quorum receipt(s) at docs/audits/quorum-PMAT-3637*.json. NOT in scope: any code, test or measurement of PMAT-3604 — those are PR #3634 and are judged there. A lane that finds a done_when item mis-transcribed, missing or invented FAILs this row.' +- id: PMAT-3644 + github_issue: 3644 + item_type: task + title: 'check_guards_are_wired.sh reads a step NAME as a bare guard_tree.sh dispatch: 4 guards dark, incl. the #3305 publish-strip guard (which also dies on intel''s python 3.10)' + status: planned + priority: critical + assigned_to: null + created: 2026-09-21T01:39:50Z + updated: 2026-09-21T01:39:50Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'ACCEPTANCE (hand-entered from issue #3644 "What lands"; minted on the PR branch so the AD-04 quorum can run). 1. check_guards_are_wired.sh drops name: lines before the invocation match, in dispatcher_wired() and the per-guard scan; rows 8-10 (the exact ci.yml step-name fixture must NOT count as a dispatch; a quoted run: line still does; a step named after a guard wires nothing); the mutation (remove the drop) turns rows 8 and 10 RED. 2. check_pathonly_devdeps_unused_in_src.sh: tomllib -> tomli -> ENV rc=2 naming interpreter and runner; the scanner ends with a SCAN-DONE trailer the shell REQUIRES; five death rows incl. the whole guard under the intel shape; comments reworded so CARGO_RE no longer classifies it out of --no-cargo, so guard-tree runs it (bare run on the tree: rc 0, 3 s). 3. unwired_guards_baseline.txt records the other three dark guards as APERTURE REVEALS (set-aperture gains a NAME-entry admission: a file the comparand carries, in a diff that changes the owning guard; six case rows, each admission beside its refusal) with the reason each may only leave; #3646 owns the pr_review pair. No workflow file is edited.' +- id: PMAT-3646 + github_issue: 3646 + item_type: task + title: check_pr_review_counts.sh is RED on main (6 rows disagree) and check_pr_review_receipt.sh has no caller — both dark since PRQ-013 moved the receipt job, classified out of --no-cargo by a comment + status: planned + priority: high + assigned_to: null + created: 2026-09-21T06:00:51Z + updated: 2026-09-21T06:00:51Z + spec: null + acceptance_criteria: + - 'Issue #3646 "What lands" item 1, verbatim: "Fix the 6 disagreeing rows in PR-REVIEW-SKILL-002''s files (or the derivation), then reword the one comment so the guard leaves the cargo population and `guard-tree` runs it; delete its ledger line in the same commit (shrink-only)."' + - 'Issue #3646 "What lands" item 2, verbatim: "Decide `check_pr_review_receipt.sh`''s caller: either `pr-review-quorum.yml` invokes it on the PR''s receipt (a workflow edit — operator''s call), or it is folded into `check_pr_review_arm4.sh`, which is already wired with args. Delete its ledger line with whichever lands."' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'SCOPE OF THIS PR: item 1 only. The PR says `Refs #3646`, not a closing keyword, and carries a `keep-open:` line for item 2. check_pr_review_receipt.sh keeps its line in scripts/unwired_guards_baseline.txt on purpose: neither of item 2''s two options lands here. The workflow edit is the operator''s call, and the fold is moot because check_pr_review_arm4.sh already invokes it with a receipt (see Item 2 below). The ledger entry''s own comment says so ("NOT dark: check_pr_review_arm4.sh runs it … Ledgered only because this meta-guard counts a DIRECT workflow invocation"). A reviewer should judge item 2 as OPEN BY DESIGN, not as missed. Handed over by aprender-b3 (2026-09-21); claimed on the issue. Measured on origin/main @ 237fbc32f per the issue: `bash scripts/check_pr_review_counts.sh` rc=1 "--- 6 row(s) disagree with the tree ---"; `bash scripts/check_pr_review_receipt.sh` rc=1 "A run over zero receipts is not a pass (S6.3: a missing receipt is RED)." The ledger line for each guard is added by #3647 (scripts/unwired_guards_baseline.txt, shrink-only); it is deleted in the commit that wires that guard, after #3647 merges. Item 1 lands first; item 2 lands here only if it folds into check_pr_review_arm4.sh with no workflow edit, otherwise the ticket stays open for the operator''s call and the PR says Refs, not Closes. + + What the item-1 PR does. (a) The 6 RED rows were ci.yml sites whose sentences PRQ-013 deleted along with the receipt job (roadmap: "STATED LOSS"), so the rows go. The bats_tests derivation goes too, because no file states that count any more; ci.yml''s fixture_rows site goes from 2 to 1; and scripts/check_pr_review_wiring.sh''s "43-row" joins the table with a self-test row of its own. (b) The :196 comment is reworded so CARGO_RE stops matching: `guard_tree.sh --dry-run --no-cargo` prints `run: scripts/check_pr_review_counts.sh`, and restoring the old wording moves it back to --cargo-only (mutation-verified). (c) The --list mode of mutate-guard.sh and mutate_quorum_arm.sh requires only awk. Before this it demanded bats/jq/minisign/check-jsonschema, so wiring the counts guard into guard-tree, which runs on clean-room HOSTS including the gx10/yoga docker runners, would have turned a dark guard into an ENV-red job (reproduced: rc=2 under a PATH without those four). Sweeps still refuse without them (rc=1). + + Item 2, measured: check_pr_review_receipt.sh HAS a caller with a receipt. check_pr_review_arm4.sh runs `bash "$guard" "$scratch"` (A3) and `bash "$guard" "$best_dir"` (A4) with guard defaulting to it, and pr-review-quorum.yml:141 runs arm4. So there is nothing to fold. What remains is whether guard_tree.sh and the unwired ledger should treat a guard reachable only through another wired guard as wired. That is recorded on the issue and not changed here. LEDGER LINE (added after the 0.69 batch landed): check_pr_review_counts.sh entered scripts/unwired_guards_baseline.txt through #3644 in batch #3669 (squash a877fa056), after this branch was cut, so the deletion criterion 1 names could only be made once main carried the line. Main is merged into this branch (the only conflict was the generated roadmap.yaml, regenerated from entries/), and the entry and its four comment lines are deleted. On the squash-merge this is one commit with the fix. Measured on the merged tree: `bash scripts/check_guards_are_wired.sh` rc 0, "did not grow (1 removed) vs a877fa056", 149 scanned, 5 named by no workflow; `bash scripts/check_pr_review_counts.sh` rc 0, "PASS every stated count equals the derived one"; `--self-test` 16/16; `bash scripts/guard_tree.sh --no-cargo` 78 checks, 0 failed (76 before this branch), including "PASS scripts/check_pr_review_counts.sh [self-test]" and "[run]".' +- id: PMAT-3651 + github_issue: 3651 + item_type: task + title: 'guard_tree.sh drops a passing guard''s output — an UNMEASURED exit-0 reads as PASS in every CI log, so #3567''s verdict can never be observed' + status: planned + priority: critical + assigned_to: null + created: 2026-09-21T05:28:51Z + updated: 2026-09-21T05:28:51Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'ACCEPTANCE (quoted from issue #3651 "What lands"): 1. guard_tree.sh: under a PASS row, surface every captured line whose first token is UNMEASURED or SUMMARY (indented " ~ ", capped at 5 lines + a "(+N more)" count so a chatty guard cannot flood the log). Lines where the word is not the first token are not surfaced. A guard opts a pass-summary in by printing SUMMARY …; an UNMEASURED line is surfaced whether or not the guard opted in. 2. check_fleet_pv_shapes_gate.sh: its pass row is printed as SUMMARY PASS verdict=… so the measured row reaches the log. 3. scripts/tests/guard_tree_test.sh rows: UNMEASURED surfaced; SUMMARY surfaced; the word mid-line not surfaced; a silent pass prints only its PASS row; the cap; and a mutant with the surfacing removed goes RED. NOT in scope: closing #3567 (that needs one guard-tree run on an intel runner after this lands), and the fleet pv''s own verdict.' +- id: PMAT-3656 + github_issue: 3656 + item_type: task + title: 'apr convert/import invent IQ-quant weights: get_tensor_f32 approximated IQ2..IQ4 from raw bytes and exited 0' + status: planned + priority: high + assigned_to: null + created: 2026-09-21T05:47:55Z + updated: 2026-09-21T05:47:55Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'ACCEPTANCE (hand-entered from issue #3656 done_when, verbatim; minted on the PR branch so the AD-04 quorum can run). Done when: (1) get_tensor_f32 on any IQ tensor returns Err naming the tensor and its type; no path in aprender-core returns approximated IQ values; dequantize_iq_approximate is deleted. (2) apr convert … --quantize q4k and apr import on Qwen3.5-0.8B-IQ4_XS.gguf exit non-zero and write no output file. (3) A unit test fails if an approximation arm is restored (mutation: restore the 16..=23 arm → RED). Not in scope: real IQ dequantization in aprender-core (aprender-serve has dequantize_iq*, core cannot depend on serve; the route is PP-QUANT-001 #3421). Why it rides with PMAT-3601: once IQ tensors are sized, raw apr import reaches map_gguf_dtype, whose Q8_0/Q5_K refusal says "cannot represent exactly" — a GH-375 fallback trigger — so without this fix an IQ file could import invented weights where it used to be refused.' +- id: PMAT-3657 + github_issue: 3657 + item_type: task + title: 'publish_strict.sh hardcodes the publish universe size (74) — derive it from the cargo metadata that builds publish-order.txt' + status: in_progress + priority: medium + assigned_to: aprender-62 + created: 2026-09-21T10:40:00Z + updated: 2026-09-21T10:40:00Z + spec: null + acceptance_criteria: + - 'Issue #3657 "What lands" 1, verbatim: "Derive the expected size from the same source that builds `publish-order.txt` (`cargo metadata` at the tag + the facade list), and assert `ORDER == universe` as **sets** (no missing, no extra, no duplicate). The script already checks membership one way."' + - '"What lands" 2, verbatim: "Extend `scripts/check_release_scripts_derive_identity.sh` (or its case table) so a bare crate-count literal in an assertion is refused, with a planted-literal row."' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'Assigned to aprender-62 by the cop (aprender-04). Not a T-4 blocker for 0.69, per the issue. THE SOURCE. publish-order.txt is a committed file with no generator in the tree (ported in #3582); the universe it must equal is scripts/lib/cascade_universe.py, which runs `cargo metadata --no-deps` over EVERY workspace this repo publishes from (`.` and `crates/facades`) at the tag checkout ($WT) and drops `publish = false`. publish_strict.sh already read that universe into EXPECT; this change makes N=${#EXPECT[@]} the size, so the size comes from the same cargo metadata, and the facade names in ORDER are checked against the facade workspace''s own packages. HOW IT IS MET, publish_strict.sh: the three 74 assertions (lines 39, 41, 90 at d0771c5c5) are replaced by `N=${#EXPECT[@]}`, a non-empty check, and three SET checks, each naming the crates: duplicates in ORDER (`sort | uniq -d`), ORDER entries not in the universe, and universe entries not in ORDER ("so never uploaded"). The progress and final strings print $N ("$i/$N", "$n/$N live", "$N/$N"). The final verification is `[ "$n" -eq "$N" ]`. The dependency-order proof and the publish loop are unchanged. check_release_scripts_derive_identity.sh gets rule R3: on a non-comment line, no numeric test (-eq -ne -lt -le -gt -ge == !=) against an integer literal of two or more digits, on either side. Case rows 12-20 are new: the PLANTED row is publish_strict.sh''s own 0.68.2 line 39 verbatim; five more RED shapes (a wc -l count, an unquoted counter, the literal on the left, (( n == 74 )), a quoted "74"); three clean shapes (a count against the derived $N plus `-lt 3` and `-eq 0`; sleep/seq/cut numbers; a comment). The one-digit exemption is deliberate: a retry bound or an exit code is one digit, a crate universe is not. `--help` printed a hardcoded `sed -n 2,24p`; it now prints the leading comment block. MEASURED at this commit: `bash scripts/check_release_scripts_derive_identity.sh --self-test` 23/23 ok (was 14). The guard over the PRE-FIX scripts/release (d0771c5c5) exits 1 with R3 naming lines 39, 41 and 90; over this tree it exits 0 ("8 file(s) … no literal count"). MUTANT with R3''s hits forced empty: rows 12-17 go RED ("rc=0 (wanted 1)"), and no other row changes. END TO END in a private clone (its own refs, tag v9.9.9 in the clone only, RELEASE_AP in scratch, `--plan` reads the sparse index and uploads nothing): the fixed script plans 74 rows, rc 0. NEGATIVE CONTROLS, each committed and re-tagged in the clone, each rc 1: aprender-tsp removed from the order gives "in the universe but not in the publish order, so never uploaded: aprender-tsp"; apr-format appended gives "crate(s) twice in the publish order: apr-format"; not-a-crate appended gives "in the publish order but not in the universe: not-a-crate". THE DEFECT ITSELF: aprender-tsp set `publish = false` AND dropped from the order, a legitimate universe of 73. The pre-fix script (d0771c5c5) stops with "STOP publish: order=73 universe=73, expected 74/74", rc 1. The fixed script plans 73 rows, rc 0. bashrs: 0 errors on the guard (baseline 0). publish_strict.sh has 4 errors before and after, all pre-existing (the change adds none).' +- id: PMAT-3658 + github_issue: 3658 + item_type: task + title: 'Every merge-group run is tier=full: ci_test_tier.sh requires HEAD^2 but the queue is SQUASH (one parent) — a text-only PR runs ~2 runner-hours of unit tests; HEAD^1..HEAD is already the PR diff' + status: planned + priority: critical + assigned_to: null + created: 2026-09-21T06:03:14Z + updated: 2026-09-21T06:03:14Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'ACCEPTANCE — issue #3658 done_when as AMENDED 2026-09-21 06:10Z (the amendment supersedes the original list; operator instruction quoted there: "you will fix ASAP this is P0, and NO roadmap shouldn''t even have 10 minutes testing"). (1) A squash-shaped merge-group fixture (one parent, main moved, a leaf crate touched) gives tier=quick with that crate, not full. The same fixture with a roadmap entry only gives tier=none. Both are case-table rows. (2) Mutation: restoring the HEAD^2 gate sends the squash group back to full (a RED row). (3) A failing git diff HEAD^1..HEAD still gives tier=full (the fail-closed row is kept). (4) On a pull_request: roadmap + audit paths only -> tier=none; the same with a deleted docs path -> quick; roadmap plus any non-docs path -> quick; docs/specifications/ only -> quick. (5) A push of a squash landing (one parent, no reflog) -> quick over HEAD^1..HEAD, not full. (6) [AMENDMENT 2, 2026-09-21 06:55Z, supersedes amendment 1 item 6] ci.yml changes in exactly two places, and nothing else in the workflow changes: (a) one step, if: tier == none, that logs the reason through env:; (b) the pull_request touched-list line (git diff ... > "$RUNNER_TEMP/touched.txt" in the tier step) gains --no-renames, so both sides of every rename are touched paths. diff_into in ci_test_tier.sh gains the same flag. Rows: default --name-only on a rename fixture lists only the new path (the trap is real); the rename into docs/audits/ gives quick with the crate it left; a mutant without --no-renames gives none (RED); and a file-shaped row asserts the ci.yml line carries the flag. The other touched-list builder with the same shape (ci.yml:2783, the ci_gpu_touched feed) is pre-existing, has a different consumer, is out of scope, and is #3667. (7) After landing: the next 5 merge-group runs'' shard-1 logs show a tier= other than full for the docs-only and small-crate groups. This is observed after the merge, and the issue stays open until it is. SCOPE ADDITIONS in the amendment: A. docs-only diffs (every path under docs/roadmaps/ or docs/audits/ and present at HEAD; never a delete) and an empty diff get tier=none; B. a push landing a squash uses HEAD^1..HEAD. NOT IN SCOPE: guard-cargo and the reusable ci/* jobs on docs-only changes (the next row). Refs #3650, #3643.' +- id: PMAT-3661 + github_issue: 3661 + item_type: task + title: 'apr inspect/tensors print "Invalid APR format" for GGUF and SafeTensors failures — CliError::InvalidFormat hardcodes the format name' + status: in_progress + priority: medium + assigned_to: aprender-62 + created: 2026-09-21T10:45:00Z + updated: 2026-09-21T10:45:00Z + spec: null + acceptance_criteria: + - 'Issue #3661 done_when 1, verbatim: "`apr inspect` and `apr tensors` on a truncated GGUF and on a random-bytes `.safetensors` do not call the input an APR file unless its magic bytes are APR''s. Exit code stays 4 (same failure class; `lint_exit_convention_tests` unchanged)." Amended 2026-09-21 by the filer, before implementation, verbatim: "this previously read \"print no \\\"APR\\\" in the error\". Core''s unknown-magic message ends with \"Supported formats: APR (.apr), GGUF (.gguf), SafeTensors (.safetensors)\", which names APR without calling the file one. The criterion is about the claim, not the substring."' + - 'done_when 2, verbatim: "A case-table test drives each of the four inputs above through the real CLI error path and asserts the message names the detected format, or \"model\" when detection failed. It must fail on today''s Display (mutation: restore `\"Invalid APR format: {0}\"`, and the test goes RED)."' + - 'done_when 3, verbatim: "A truncated `.apr` still says APR, so the fix doesn''t just delete the word."' + - 'done_when 4, verbatim: "No double prefix (\"Invalid model format: … Invalid model format: …\") in any of the four messages."' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'Claimed on the issue by aprender-62 (2026-09-21 08:17Z). HOW IT IS MET. New variant `CliError::InvalidModelFile { format, message }`, Display "Invalid {format} file: {message}", exit code 4 (the same arm as InvalidFormat and InvalidInput). It is built only by `CliError::invalid_model_file(path, context, &e)`, which (a) reads the format from the file''s magic bytes through `commands::hex::detected_model_format`, a new 9-byte wrapper over hex.rs''s existing `detect_format`/`format_display_name` that returns "APR", "GGUF", "SafeTensors", or "model" when the bytes match none or the file cannot be read; and (b) takes a core `FormatError`''s message, not its Display, so the core "Invalid model format:" prefix does not appear under the CLI''s own. Three call sites move to it: inspect.rs `run_rosetta_inspect`, tensors.rs `run`, and profile_safetensors.rs (the same `Inspection failed` wrap). `CliError::InvalidFormat` is unchanged, so every other site and the tests that pin "Invalid APR format" (lint_exit_convention_tests, lint_family_guard, beat_run, grad_norm) are untouched. The core double prefix is fixed at its source: aprender-core format/safetensors.rs (include!d into format/tensors.rs) wrapped `GgufReader::from_bytes`''s error as `Failed to parse GGUF: {e}`, and `e` is itself a FormatError whose Display is "Invalid model format: …"; it now takes the inner message. WHAT THE FOUR MESSAGES SAY NOW (the case table renders `error: {e}` exactly as main.rs prints it): inspect truncated GGUF "error: Invalid GGUF file: Inspection failed: Unexpected EOF reading u64 at offset 24"; tensors truncated GGUF "error: Invalid GGUF file: Failed to list tensors: Failed to parse GGUF: Unexpected EOF reading u64 at offset 24"; inspect random .safetensors "error: Invalid model file: Inspection failed: SafeTensors open failed: Invalid SafeTensors file: metadata length 12928470711364830350 exceeds file size"; tensors random .safetensors "error: Invalid model file: Failed to list tensors: Unknown model format: magic bytes 8e44f12f. Supported formats: APR (.apr), GGUF (.gguf), SafeTensors (.safetensors)". A truncated .apr: inspect "error: Invalid APR format: File too small to contain valid APR header (need 64 bytes)" (inspect''s native APR path, unchanged); tensors "error: Invalid APR file: Failed to list tensors: Failed to parse APR v2: Invalid header: file too small". FIXTURES, all built in the test: a GGUF written by aprender''s own `export_tensors_to_gguf`, cut to 28 bytes (4 bytes into the first key''s u64 length, so the reader hits the issue''s own "Unexpected EOF reading u64"); 4 KiB of deterministic noise named .safetensors, opening with the issue''s magic `8e44f12f`; and an `AprV2Writer` file cut to 32 bytes, under its 64-byte header. The case table is `commands/model_file_error_tests_3661.rs`, with 6 rows. It calls the real `inspect::run` / `tensors::run`. For each row it asserts: the rendered prefix; no "Invalid APR" unless the magic is APR''s; no "Invalid model format" anywhere, which is stronger than "not twice"; and `exit_code_value() == 4`. MUTANTS, each RED: M1, the three call sites restored to `CliError::InvalidFormat(format!(…: {e}))` (the pre-fix code at d0771c5c5), fails 14 checks and reproduces the issue''s strings, e.g. "error: Invalid APR format: Failed to list tensors: Invalid model format: Failed to parse GGUF: Unexpected EOF reading u64 at offset 24". M2, the new variant''s Display restored to "Invalid APR format: {message}", fails 9 checks: every non-APR row. M3, the core wrap restored to `Failed to parse GGUF: {e}`, fails 1 check: the tensors-GGUF row''s "Failed to parse GGUF: Invalid model format: …". With all restored: 1 passed. MEASURED at this commit: `cargo test -p apr-cli --lib` 7294 passed, 0 failed, 12 ignored; `cargo test -p aprender-core --lib format::tensors` 131 passed; `cargo clippy -p apr-cli --lib -- -D warnings` rc 0 and `cargo clippy -p aprender-core --lib -- -D warnings` rc 0 (`--tests` on apr-cli fails only in pre-existing tests/falsification_crux_*.rs and nf4_classifier.rs, none in a touched file); `cargo fmt --all -- --check` rc 0; `scripts/check_complexity_ratchet.sh` "none new, none grown"; `bash scripts/guard_tree.sh --no-cargo` 76 checks, 0 failed. NOT DONE: a run of a freshly built `apr` binary. The host was at load 57 on 48 cores and a release build of the facade would have added to it; the table renders the same `error: {e}` line main.rs prints and asserts the exit-code mapping directly. FOLLOW-UP, filed before the PR as #3691: six more sites name GGUF or SafeTensors in their own message and still wrap it in `InvalidFormat` (hex.rs:323/350, safe_tensors_header.rs:180/182, trace_likely_has_repeated.rs:267/332). They are outside this issue''s done_when, which names inspect and tensors.' +- id: PMAT-3662 + github_issue: 3662 + item_type: task + title: 'Hand-typed ggml id→name tables outside aprender-core: sliding_window_entropy.rs, validate_manifest.rs, aprender-serve model_source.rs name 11 of 35 live types; route through trueno_quant::GgmlType' + status: in_progress + priority: medium + assigned_to: aprender-62 + created: 2026-09-21T06:40:00Z + updated: 2026-09-21T06:40:00Z + spec: null + acceptance_criteria: + - 'Issue #3662 done_when 1, verbatim: "Every non-example id→name mapping in `apr-cli` and `aprender-serve` resolves through `trueno_quant::GgmlType::from_id(id).map_or(, GgmlType::as_str)`, or through one shared helper that does. No `12 => "Q4_K"`-shaped match arm remains outside `aprender-quant` in those two crates'' `src/`."' + - 'Issue #3662 done_when 2, verbatim (as amended by the filer 2026-09-21 after measuring): "A test per site feeds ids 10 (Q2_K), 16 (IQ2_XXS), 23 (IQ4_XS) and 30 (BF16) and gets the upstream names. It is RED on today''s tables where they are incomplete (sliding_window_entropy.rs, model_source.rs). validate_manifest.rs was complete when measured (amended 2026-09-21 by the filer), so its row is a parity row and passes before and after."' + - 'Issue #3662 done_when 3, verbatim: "Unknown ids (e.g. 4, 5, 999) still print the site''s existing unknown token, so output stays stable for ids ggml removed."' + - 'Issue #3662 done_when 4, verbatim: "`apr-cli` depends on the quant crate via `{ workspace = true }` (no crates.io copy)."' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'Found by aprender-7a (sliding_window_entropy.rs:295); the other two sites found by aprender-62 at origin/main c0ab699b0 with a scan of crates/apr-cli/src and crates/aprender-serve/src for ` => "Q4_K"`-shaped arms, which returns exactly three: apr-cli commands/sliding_window_entropy.rs `ggml_dtype_name` (unknown token "Unknown"; knows 11 ids), apr-cli commands/validate_manifest.rs `ggml_type_name` (unknown token "UNKNOWN"; knows ids 0-3,6-30, so it is complete today but hand-typed), aprender-serve api/model_source.rs `gguf_qtype_name` (returns None; knows 15 ids, so every IQ*, I8-I64 and F64 is None). "RED on today''s tables" is per site. validate_manifest.rs already names 10/16/23/30 correctly, so its row (ids 10/16/23/30 plus unknown ids 4/5/999, the same ids as the other two sites) is a parity row and is not expected to be RED. The two tables that are wrong today (sliding_window_entropy, model_source) carry the RED rows. validate_manifest.rs''s reverse name→id parser (`"iq4_xs" => Some(23)`) has case-insensitive aliases ("bfloat16") and is not an id→name mapping. It is out of scope and stays. Examples under crates/aprender-serve/examples/ are out of scope per the issue. + + Facts a reviewer needs, each checked at the PR head (round 1 of the quorum misread all three). (1) WHERE sliding_window_entropy.rs IS TESTED: it is not a module. crates/apr-cli/src/commands/hex.rs:442 is `include!("sliding_window_entropy.rs")`, and hex.rs:444 includes hex_06.rs, whose :11 is `include!("hex_options_detect.rs")`. So `ggml_dtype_name` and its tests share one module, `commands::hex`. The pre-existing tests for this function (test_ggml_dtype_name_known/_unknown) already live in hex_options_detect.rs, and the new test_ggml_dtype_name_names_every_family sits beside them. It ran as commands::hex::tests::test_ggml_dtype_name_names_every_family: RED on the old table (left "Unknown", right "Q2_K"), GREEN after. (2) THE CRATE NAME: the workspace dependency is `trueno-quant = { path = "crates/aprender-quant", ..., package = "aprender-quant" }` (root Cargo.toml:262), and Cargo.lock records PACKAGE names. So `aprender-quant` in apr-cli''s Cargo.lock dependency list is what cargo wrote for `trueno-quant = { workspace = true }`. It was generated by cargo, not hand-edited. (3) GgmlType IS EXPORTED: crates/aprender-quant/src/lib.rs has an unconditional `pub mod ggml_type;` and `pub use ggml_type::{GgmlFamily, GgmlType, ...}`. The type was added by #3581 AFTER the v0.68.2 tag (`git cat-file -e v0.68.2:crates/aprender-quant/src/ggml_type.rs` fails), so a tree at or before v0.68.2, or the crates.io aprender-quant 0.68.2, does not have it and fails with E0433. At the PR head, `cargo check -p aprender-serve` and `cargo check -p apr-cli` both exit 0. Verified at the PR head: cargo test -p aprender-serve --lib model_source 19 passed; cargo test -p apr-cli --lib -- commands::hex commands::validate_manifest 174 passed; clippy -D warnings clean on both crates.' +- id: PMAT-3666 + github_issue: 3666 + item_type: task + title: 'APEX-2d: raster — NEW crates/aprender-viz/src/raster.rs svg_to_png behind `raster` (resvg default-features OFF, so no font database is compiled in; a roxmltree pre-scan refuses text/tspan/textPath/tref/altGlyph/textArea/font/font-face/foreignObject/image/feImage in the SVG namespace OR none; href resolver reads nothing; resvg render; row-wise demultiply into Framebuffer; pinned PngEncoder, never encode_png); error.rs Error::SvgElementRefused; lib.rs pub mod raster; NEW tests/raster_determinism.rs (11 tests + per-host raster-.json); NEW scripts/ci/raster-compare.sh (12-case self-test, 2 mutants; asserts resvg AND os match across the two hosts before computing png_identical, beside the existing svg_sha256/width/height/scale guards) in ci.yml determinism-compare, raster step + upload path in determinism; svg_to_png split into the scale check + prescan_refuse + a PRIVATE render_unscanned, with ONE #[cfg(test)] unit test a_text_element_paints_nothing_because_no_font_database_is_compiled_in (no public API growth, no repo path so the tree-reader registry is unchanged); NEW scripts/ci/raster-fontdb-ban.sh (cargo-tree ban on fontdb/rustybuzz/ttf-parser/font*, 6-arm self-test incl. the as-shipped control and a contains-not-prefix arm) + its ci.yml step and a --lib raster:: step, both in determinism; tree_reader_tests.txt; Cargo.lock drops zune-jpeg 0.4 + fontdb/rustybuzz edges; png_identical RECORDED not asserted; NO publish (apex APEX-001 row EV-2d)' + status: planned + priority: medium + assigned_to: null + created: 2026-09-21T15:54:31Z + updated: 2026-09-21T15:54:31Z + spec: null + acceptance_criteria: + - 'comparability (added 2026-09-23): raster-compare.sh asserts [.[].resvg]|unique|length==1 and [.[].os]|unique|length==1 before it computes png_identical, because the producer recorded both and the consumer previously copied them into hosts[] without reading them. MEASURED by deleting each guard in turn (plant and restore sha256-verified): without the resvg guard case resvg-differs gives rc=0 png=true, failed: 1; without the os guard case os-differs gives rc=0 png=true, failed: 1 — so the missing guard did not merely skip a refusal, it produced the FALSE cross-architecture claim. Each deletion reds exactly its own arm. Self-test 10 -> 12 cases, 0 failed.' + - 'KNOWN LIMITATION, recorded rather than fixed unilaterally: the per-host receipt records "resvg": "0.45.1" as a hand-written literal in tests/raster_determinism.rs, under a comment that says the receipt is a measurement rather than the constants the fixture was built with — true of width/height, not of that field. It is accurate today (cargo tree -p aprender-viz --features raster resolves resvg v0.45.1; the second Cargo.lock entry, 0.47.0, is pre-existing on main and absent from the normal graph), and the comparability guard above makes a DISAGREEMENT between hosts fail, but two hosts writing the same stale literal would still agree. Deriving or externally checking that value is a design choice with three plausible mechanisms and belongs to a quorum, not to one session.' + - 'accept (APEX-001 EV-2d): tests_at_least 3 -p aprender-viz --features raster --test raster_determinism; the two-host raster-receipt.json has (.hosts|length)==2 and (.png_identical|type)=="boolean" (recorded, not asserted). Each mutation names the arm it turns RED, because the two mutations are observable in different places: M1 (replace the prescan_refuse call) turns EXACTLY the 4 refusal tests in tests/raster_determinism.rs RED and leaves the other 7 green (measured 2026-09-22: 7 passed, 4 failed; plant and restore both sha256-verified). M2 (resvg default-features back ON plus opt.fontdb_mut().load_system_fonts()) turns raster::tests::a_text_element_paints_nothing_because_no_font_database_is_compiled_in RED and scripts/ci/raster-fontdb-ban.sh RED, and leaves all 11 integration tests GREEN (measured 2026-09-22). M2 is unobservable through svg_to_png BY DESIGN — the pre-scan refuses before usvg builds a tree — which is why the unit test calls render_unscanned and the ban reads the dependency graph instead; behaviour alone cannot pin the flag, since an EMPTY font database renders the same as a missing one. The earlier wording, that M2 turns the 4 refusal tests RED, was MEASURED FALSE (11 passed, 0 failed) and is superseded. Publishing aprender-viz stays operator-only (STOP(PUBLISH)).' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-3670 + github_issue: 3670 + item_type: task + title: 'check_fleet_pv_shapes_gate.sh FAILs guard-tree on fleet state (intel pin rewritten to 0.65.2 by another repo''s CI) — fleet state must be UNMEASURED, never FAIL' + status: planned + priority: critical + assigned_to: null + created: 2026-09-21T07:33:19Z + updated: 2026-09-21T07:33:19Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'ACCEPTANCE — issue #3670 done_when, verbatim in substance. (1) Each fleet-state branch prints UNMEASURED runner=... reason= ..., exits 0, and never prints PASS or SUMMARY PASS. (2) A mutant restoring FAIL on pin-mismatch exits 1, and a mutant restoring the ENV exit on pv-env exits 2; each mutant row refuses to pass if its edit did not apply. (3) A planted violation from a matching pinned binary is still RED, and a control that does not fire is still RED. (4) Real runs: pin forced to 0.65.2 under a 0.68.2 binary gives UNMEASURED reason=pin-mismatch (rc 0); the fleet pv on a tree with migrated parity records gives PASS verdict=Pass. RULING: PASS/FAIL only from a verdict produced by a binary that matches its pin; fleet state is UNMEASURED with a named reason and exit 0. Scope: scripts/check_fleet_pv_shapes_gate.sh only, one commit on top of #3653 (053992448).' +- id: PMAT-3671 + github_issue: 3671 + item_type: task + title: 'check_fleet_pv_shapes_gate.sh: reason=pv-env (exit 0) covers a pinned pv that PANICS — only pv rc 2 is fleet state; any other no-JSON rc must stay RED' + status: in_progress + priority: high + assigned_to: aprender-62 + created: 2026-09-21T10:15:00Z + updated: 2026-09-21T10:15:00Z + spec: null + acceptance_criteria: + - 'Issue #3671 done_when 1, verbatim: "pv''s own exit code is captured before the parser runs. `reason=pv-env`, exit 0, applies **only** when pv''s rc is 2 and it produced no JSON."' + - 'done_when 2, verbatim: "A pinned pv that produces no JSON with any other rc (101 panic, 134/139 signal, 1 with no output) goes RED, not `UNMEASURED`. It exits non-zero, and the row names pv''s rc and its first stderr line."' + - 'done_when 3, verbatim: "Case-table rows: a panic stub (101, no JSON) → RED. The existing rc-2-no-JSON stub stays `UNMEASURED reason=pv-env`. A mutant that removes the pv-rc check sends the panic row back to `UNMEASURED` (the row discriminates)."' + - 'done_when 4, verbatim: "The other fleet-state branches (`no-pin`, `no-binary`, `pin-mismatch`, `incapable`, `judge-env`) are unchanged."' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'Found by aprender-62 cross-inspecting the andon commit 984fc76a9 (PMAT-3670) in the 0.69 batch #3669; the cop ruled it a separate ticket for after the batch. HOW IT IS MET. `judge` captures pv''s own exit as `pvrc` (the parser still receives it, for its message) and the verdict `case` is keyed on the PAIR `:`: `2:2` is `UNMEASURED reason=pv-env` exit 0, unchanged; `2:*` is `FAIL runner=… reason=pv-no-verdict … pv exited … pv stderr: ` to stderr, exit 1. The arms for parser rc 0 (PASS), 1 (FAIL) and other (judge-env) are unchanged, and the no-pin / no-binary / pin-mismatch / incapable branches return before pv runs, so they are untouched. RED is FAIL (exit 1), not ENV (exit 2): a panic caused by a contract in the tree is tree state. SIGNAL ROW. The case table uses SIGKILL (rc 137, `kill -KILL $$` in the stub), a real signal death that writes no core file on a runner; 134/139 are the same `2:*` arm, since the arm matches any pv rc but 2. MEASURED at this commit: `bash scripts/check_fleet_pv_shapes_gate.sh --self-test` 19/19 ok (was 15). The new rows are 13-15 (panic 101, SIGKILL 137, rc 1 with no output: each RED naming pv''s rc and stderr, never UNMEASURED) and 16 (mutant `2:2)` -> `2:*)`, i.e. pv-env keyed on the parser alone: the panic stub goes back to `UNMEASURED reason=pv-env`, exit 0, so the panic row discriminates). BEFORE THE FIX, the same self-test with the new rows: rows 13-15 FAIL with "UNMEASURED runner=probe-runner reason=pv-env … ENV no JSON verdict (rc=101) … panicked", rc 0, reproducing the issue''s table. ALSO FIXED, same rows: the existing pv-env mutant (row 12) was VACUOUS. Its sed replaced the arm''s opening single quote with a double quote, so the mutant script was a bash syntax error (`bash -n` rc 2 at "line 146: syntax error near unexpected token `(`") and "exited non-zero" without reaching the arm it claimed to test. Both mutants now keep the arm''s text through a sed backreference, are refused unless `bash -n` passes, and assert the specific outcome (row 12: exit 2 and `ENV (rc=2)`; row 16: exit 0 and `UNMEASURED … reason=pv-env`). `--help` printed a hardcoded `sed -n 2,44p`, which cut the header off once it grew; it now prints the leading comment block, found by awk. `bashrs lint`: 0 errors (baseline 0). `bash scripts/guard_tree.sh --no-cargo`: 76 checks, 0 failed.' +- id: PMAT-3672 + github_issue: 3672 + item_type: task + title: 'apr run applies the chat template TWICE: the prompt reaches the model as an escaped user turn inside a user turn' + status: planned + priority: high + assigned_to: null + created: 2026-09-21T11:00:21Z + updated: 2026-09-21T11:00:21Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'ACCEPTANCE (hand-entered from issue #3672 done_when, verbatim; minted on the PR branch so the AD-04 quorum can run). (1) apr run -v on Qwen2.5-0.5B-Instruct-f16.gguf with a plain prompt shows exactly one template application and no \u{200B} in formatted_prompt. (2) The prompt token count equals llama.cpp''s for the same rendered conversation (21 for the prompt above, with no system turn). (3) A test fails if the prompt is templated twice (mutation: restore the upstream wrap → RED). ROOT CAUSE (issue comment): crates/apr-cli/src/dispatch_run.rs (GH-638) pre-wrapped the prompt in hard-coded ChatML, and realizar prepare_tokens (GH-278) then applied the model''s own template again. Fix: the prompt stays raw; --chat (or the GH-638 instruct/chat source-name heuristic) reaches realizar as InferenceConfig::force_chat_template, which prepare_tokens_{gguf,safetensors,apr} OR into its single template decision.' +- id: PMAT-3673 + github_issue: 3673 + item_type: task + title: 'Batching is the default merge path: scripts/batch_fold.sh + APR-RELEASE-001 §13 (operator 2026-09-21)' + status: planned + priority: critical + assigned_to: null + created: 2026-09-21T08:23:21Z + updated: 2026-09-21T08:23:21Z + spec: docs/specifications/APR-RELEASE-001-train-and-build-kaizen.md + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'ACCEPTANCE (quoted from issue #3673 "What lands"): 1. scripts/batch_fold.sh — fold receipted PR branches into one release/-batch branch, git merge --no-ff in the given order: a conflict ONLY in the generated set {docs/roadmaps/roadmap.yaml, contracts/census.json, contracts/contracts.nt, contracts/shapes.ttl, the CONTRACT_COUNT blocks of README.md} is taken and marked for regeneration; a conflict ANYWHERE else — including README prose outside a count block — aborts that branch''s merge and reports SKIP with the paths, never resolved by picking a side; --regen regenerates the generated set ONCE with the tree-built pv (scripts/pv_bin.sh), asserts the fixed points (aggregate --check, pv extract --check, readme_sync.sh --check), and commits the regeneration; exit 0 all folded; 1 any SKIP; 2 usage/git/regeneration failure; a folded-but-unregenerated generated set is never silent; --self-test case table, wired into CI. 2. APR-RELEASE-001 §13 — the batching procedure as the default path (cop prompt §7): assembly, generated-set regeneration, left-out rules, what needs a new quorum (only content new to the batch), constituent disarm/close, a red batch, and the review-lane VOID rule while paiml-implement#317 is open. AUTHOR NOTES (not criteria): the case table lives in scripts/check_batch_fold.sh (guard-tree runs it) because a --self-test case inside batch_fold.sh made check_guards_are_wired.sh RED; §13 required amending hard rule 9 ("No hand-squash of batches") and the matching §8 stop, which the new default contradicts.' +- id: PMAT-3676 + github_issue: 3676 + item_type: task + title: 'CI diet: aprender itself burns 99 intel runner-hours/day — coverage on tag/nightly only, path-filter book jobs, perf/model suites nightly, mutants only on .rs diffs' + status: planned + priority: critical + assigned_to: null + created: 2026-09-21T09:50:38Z + updated: 2026-09-21T09:50:38Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'ACCEPTANCE (quoted from issue #3676 "Proposal" + "done_when"; operator 08:38Z: "YES, coverage on tags release only"; Noah approved all five workflow items directly to aprender-b3): 1. Coverage (ci / coverage) on the release tag and the nightly only, never on pull_request or merge_group. COV_FLOOR enforcement moves to the tag gate (T-2) and the nightly, where a regression still blocks the release. 2. Book Chapter Examples and mdBook: path-filtered. They run when book/** or the crates a chapter imports change, and nightly always. 3. The perf gate case table and the model-tests falsification suites move to nightly. The PR path keeps a smoke row. 4. mutants runs only when the diff has .rs. 5. Every moved job still runs on the tag. check_workflow_path_filters.sh and the gate aggregator are updated so a skipped job is a pass only when the skip reason is the documented filter. done_when: intel runner-minutes per 24 h drop by >= 40% at equal PR throughput (measured after merge); the tag gate still runs coverage with COV_FLOOR, and a planted coverage drop fails the tag (control); a book-only PR runs the book jobs, a crate-only PR not imported by a chapter does not (both rows); gate accepts skipped only for jobs whose filter says skip, any other skipped state fails (mutation). COP ADDENDUM (aprender-04, relaying rmedia-88): before removing coverage from ci.yml, enumerate every consumer of the coverage number and prove each still has a producer, with a guard asserting the chain. (A), THE ci / gate FIX (cop ruling 2026-09-21 ~15:00Z; batch-1 #3707 left this row out): the first spelling, `skip_coverage: true` on sovereign-ci@70e51ec, made `ci / gate` RED on every PR: that reusable''s gate counts a skipped coverage job as a mandatory failure ("coverage did not succeed (result: skipped)"). This PR''s own CI was red on it (run 35585906113, cancelled unread) and so was batch-1. The fix: pin sovereign-ci to paiml/.github f713290c86fcd70d6f26a0faab14e67e6713586f (#74 `coverage_on` + #77), pass `coverage_on: tag`, add `push: tags: [v*]` to ci.yml (the reusable''s second required edit), and remove coverage-nightly''s v* tag trigger so each tag is measured once, by ci.yml. The same pin also brings #73''s roadmap-fragment-parity, which would have refused every aprender PR (aprender still commits roadmap.yaml). #77 keys it on the BASE tree: NOT-ACTIVE while roadmap.yaml is tracked, and it arms by itself when #3709 migrates. scripts/check_coverage_has_producers.sh now asserts R3 (the nightly runs on schedule, NOT on v* tags) and R5 (ci.yml has coverage_on: tag, no live skip_coverage: true, and on: push tags [v*]), with 16/16 self-test rows including "skip_coverage: true instead of coverage_on -> RED". On f7b25a6c6 the guard reports R3 and R5 RED; after the change it PASSES. Also in this change (cop, found by aprender-f0): ci.yml runs `check_pr_closes_issue.sh --self-test` beside `--body`, because guard_tree skips it as wired-with-args and its case table ran in no job, and the ci.yml comment that claimed otherwise is corrected. PROOF REQUIRED before re-folding: this PR''s own CI green, with the gate logging `coverage: NOT MEASURED` and `roadmap-fragment-parity: NOT-ACTIVE`.' +- id: PMAT-3681 + github_issue: 3681 + item_type: task + title: '#3669 batch: two functions over the complexity ratchet (run_shapes_gate NEW 13/28, dispatch_runtime_commands GROWN 41->43) — extract helpers, no behaviour change' + status: planned + priority: critical + assigned_to: null + created: 2026-09-21T09:12:54Z + updated: 2026-09-21T09:12:54Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'ACCEPTANCE (quoted from issue #3681): 1. run_shapes_gate is under the threshold (cyclomatic < 30, cognitive <= 25) and dispatch_runtime_commands is back to main''s 15/41 — bash scripts/check_complexity_ratchet.sh reports none new, none grown. 2. No behaviour change: each extraction moves code verbatim into a helper (same order, same outcomes); cargo test -p aprender-contracts --lib passes the same count as before (1684); cargo test -p apr-cli --lib dispatch/registry pass; clippy -D warnings clean on both crates. 3. Nothing else in the diff: only shapes_gate.rs and dispatch.rs, plus this row''s roadmap fragment. CONTEXT: the base of this diff is the batch head 01abbca6d (release/0.69-batch); the functions'' prior shapes come from #3600 (run_shapes_gate) and #3604 + #3638/#3602 (dispatch_runtime_commands), which are already in the batch with their own receipts and are NOT judged here.' +- id: PMAT-3682 + github_issue: 3682 + item_type: task + title: 'parity_receipt_denominator.sh reads git''s refusal as 0 receipts on container runners — a git failure must be ENV exit 2, never a count' + status: in_progress + priority: critical + assigned_to: aprender-62 + created: 2026-09-21T09:19:00Z + updated: 2026-09-21T09:19:00Z + spec: null + acceptance_criteria: + - 'Issue #3682 done_when 1, verbatim: "The listing is `git -c safe.directory="$root" -C "$root" ls-files …`, and git''s stderr is no longer discarded."' + - 'done_when 2, verbatim: "A git failure makes the script exit **2 (ENV)** with a message naming git. It is never a count of 0. `verify` propagates that status instead of collapsing it to 1."' + - 'done_when 3, verbatim: "A self-test row puts a `git` stub on PATH that exits 128 with the dubious-ownership message. It requires exit 2 and a message naming git, and it requires that the output NOT contain \"holds 0\"."' + - 'done_when 4, verbatim: "Mutation: with the pre-fix `count_and_check` restored, that row goes RED."' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'The judged diff is this ONE commit, scripts/parity_receipt_denominator.sh plus this fragment, with --base at its parent. The three commits under it on the 0.69 batch branch (the dogfood ledger re-audit, the ONT ratchet restamp, the ont4b 6->9 raise) are data/ratchet restamps that carry their proofs in their commit bodies and are outside this ticket. Found in batch #3669, workspace-test shard 3/3 on gx10-pool1 (job 106269529629): "EXPECTED_RECEIPTS says 7; the tree holds 0". On the docker runners git refuses the bind-mounted tree ("detected dubious ownership", exit 128), and the old `(cd "$root" && git ls-files … 2>/dev/null | sort -u)` inside a process substitution discarded both the message and the exit status. Measured at this commit: `bash scripts/parity_receipt_denominator.sh --self-test` 5/5 ok (the new row: "git refusing the tree is ENV exit 2 naming git, never a count of 0"); `bash scripts/parity_receipt_denominator.sh` "PASS 7 receipt(s) … says 7"; MUTANT with the pre-fix count_and_check from 55b123f2f: self-test rc=1, "FAIL git refused and the result was exit 1: FAIL evidence/parity/EXPECTED_RECEIPTS says 2; the tree holds 0."; `cargo test -p aprender-contracts-cli --test ont4c3_parity_receipts` 9 passed. Sibling sweep, on lines the batch ADDED in scripts/ and crates/*/tests/: ci_test_tier.sh:180 and :252 fail closed (not docs-only / tier=full); lib_baseline_ratchet.sh:300/302 fail closed but misattribute the cause ("this branch WROTE it"). No other zero-count site. Outside test paths: release/lib_release_params.sh:39 silently falls back to the tree root. Those are filed, not fixed here.' +- id: PMAT-3685 + github_issue: 3685 + item_type: task + title: 'apr parity exits 5 ("parity disproven") when CUDA init REFUSES the model quant type (F16/IQ*, PMAT-785): a tool limit read as a model defect; turns pre-publish dogfood C14 NO-GO' + status: planned + priority: critical + assigned_to: null + created: 2026-09-21T09:50:31Z + updated: 2026-09-21T09:50:31Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'ACCEPTANCE (hand-entered from issue #3685 done_when, verbatim; minted on the PR branch so the AD-04 quorum can run). (1) apr parity whose quant type the CUDA capability gate refuses (PMAT-785) prints ONE stderr line parity: REFUSED architecture= quant= reason= and exits 12, never 5; exit 5 stays reserved for a comparison that ran and failed. (2) a RED-turning test: a refused quant type gives 12 plus the mark; a supported one never takes that path; mutation-proved (map the refusal back to 5 and the test fails). (3) bash scripts/check_model_parity.sh --manifest --apr on this host: the qwen2.5-0.5b-instruct row is UNMEASURED-TOOL (report), every Q4_K_M row still PASS, and the must-RED twin still turns C14 RED. (4) scripts/dogfood.sh --phase pre-publish model-parity row is not FAIL on this host. Blocks the 0.69.0 T-2 preflight and the release-commit dogfood; own small PR, not folded into #3669.' +- id: PMAT-3690 + github_issue: 3690 + item_type: task + kind: code + title: Release T-4 waits for the tag's own coverage run + status: planned + priority: medium + assigned_to: aprender-4285 + created: 2026-09-24T16:25:58Z + updated: 2026-09-24T16:25:58Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-3691 + github_issue: 3691 + item_type: task + title: 'apr hex / apr trace still say "Invalid APR format" for GGUF and SafeTensors failures — 6 more InvalidFormat sites after #3661' + status: in_progress + priority: medium + assigned_to: aprender-37 + created: 2026-09-21T14:25:00Z + updated: 2026-09-21T14:25:00Z + spec: null + acceptance_criteria: + - 'Issue #3691 done_when 1, verbatim: "Each of the six sites uses `CliError::invalid_model_file(path, context, &e)` (added by #3661), or a variant naming the format it already knows. Exit code stays 4."' + - 'done_when 2, verbatim: "A row per command (`hex`, `trace`, and the SafeTensors header reader) on a truncated GGUF / malformed SafeTensors asserts that the message names the format and does not say "Invalid APR"."' + - 'done_when 3, verbatim: "The remaining `CliError::InvalidFormat(` sites (130 at `d0771c5c5`, including these six) are classified: APR-only input (keep) versus possibly-non-APR (move). The classification goes in the PR body."' + - 'The six sites, verbatim from the issue (line numbers at `d0771c5c5`): hex.rs:323 and hex.rs:350 `InvalidFormat(format!("Failed to parse GGUF: {e}"))`; safe_tensors_header.rs:180 `InvalidFormat(format!("Invalid SafeTensors header UTF-8: {e}"))`; safe_tensors_header.rs:182 `InvalidFormat(format!("Invalid SafeTensors JSON: {e}"))`; trace_likely_has_repeated.rs:267 `InvalidFormat(format!("Failed to parse GGUF: {e}"))`; trace_likely_has_repeated.rs:332 `InvalidFormat(format!("Failed to inspect SafeTensors: {e}"))`.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'Dispatched by the cop, aprender-04, to aprender-37 (2026-09-21 ~14:25Z). BASE: `0517e75a7` (PMAT-3661), not origin/main. #3691 reuses `CliError::invalid_model_file`, which #3661 added, and #3661 is not on main yet: it is folded into the unpushed `release/0.70-batch-1`. This branch is one commit on top of it, so the batch folds only this delta. HOW EACH done_when IS MET. (1) The six sites use `CliError::invalid_model_file(path, context, &e)`: hex.rs `parse_gguf` and `get_gguf_tensor_f32` (context "Failed to parse GGUF"), and trace_likely_has_repeated.rs `trace_gguf` ("Failed to parse GGUF") and `trace_safetensors` ("Failed to inspect SafeTensors"). Each has a path and an `AprenderError`, so the helper names the format from the file''s magic bytes and strips the core FormatError prefix. The two SafeTensors header-reader sites (UTF-8, JSON) have neither a path nor an `AprenderError`: `parse_safetensors_header(bytes)` gets the whole file, which `hex::run` already read, and a `Utf8Error` / `serde_json::Error`. They use a new sibling constructor, `CliError::invalid_model_bytes(bytes, message)`. It follows the same rule, reading the format from the bytes'' magic and never assuming it, through a new `hex::detected_format_of(bytes)`; `detected_model_format(path)` now calls that function after reading its 9 bytes. That is the done_when''s "variant naming the format it already knows". Every moved site keeps exit code 4: `InvalidModelFile` is on the same arm as `InvalidFormat`, and each row asserts `exit_code_value() == 4`. SCOPE, with one rule and its exclusions named. Besides the six, four more sites move: the rest of "the SafeTensors header reader", the unit done_when 2 names. Those are `parse_safetensors_header`''s size check ("SafeTensors file too small") and length check ("SafeTensors header length exceeds file size"), plus the "SafeTensors header is not a JSON object" check in each of its two callers (`run_safetensors`, `slice_safetensors`). The issue''s grep matched `format!(` calls only, so it missed these four string literals. Leaving them would keep printing "Invalid APR format: SafeTensors …" from the same reader. That makes 10 sites in 4 files. NOT moved, deliberately: hex.rs:353, `get_gguf_tensor_f32`''s tensor read. It also fires on `apr hex --slice … --tensor NAME` with a NAME that is not in the file (core says "Tensor ''NAME'' not found in GGUF"), so moving it would call a healthy file "Invalid GGUF file". It needs a split, not a move, and is classified below. The other 116 sites are classified, not changed. `CliError::InvalidFormat` itself is unchanged. TESTS (done_when 2). New `commands/model_file_error_tests_3691.rs`, declared as a `#[cfg(test)]` child of `hex` so it can call the private reader. It has one row per moved site, plus a second-caller row and an APR control. Each row renders `error: {e}` exactly as main.rs prints it and checks four things, the same as #3661''s table: the expected prefix; no "Invalid APR" unless the file is APR; no core "Invalid model format" anywhere; and exit 4. Rows that a file can reach call the real `hex::run` / `trace::run`: a truncated GGUF (hex, `hex --slice`, trace); SafeTensors with an overrunning header length, a non-UTF-8 header, and a cut-off header `{"a":` (hex, `hex --slice`, trace); and #3661''s 4 KiB noise named `.safetensors` (trace, by extension). Three sites cannot be reached through `hex::run`, because its `detect_format` picks SafeTensors only for 9+ bytes with `{` at byte 8: the 4-byte size check, and "not a JSON object" in both callers (a header starting with `{` is an object or not JSON at all). Their rows call the private function directly with the bytes that would reach them: 4 bytes, and a `[1]` header. The expected messages are: GGUF rows "Invalid GGUF file: Failed to parse GGUF: Unexpected EOF reading u64 at offset 24"; hex SafeTensors rows "Invalid SafeTensors file: "; the 4-byte and array rows "Invalid model file: …", because their magic matches no format; trace on the cut-off header "Invalid SafeTensors file: Failed to inspect SafeTensors: …"; trace on noise "Invalid model file: Failed to inspect SafeTensors: …"; and the APR control (a truncated .apr through `run_apr`, unchanged) "Invalid APR format: Failed to read APR: …". The fixtures are #3661''s, made `pub(super)` in model_file_error_tests_3661.rs instead of copied; that file''s own test is unchanged and still passes. CLASSIFICATION (done_when 3). It is in the commit message and goes in the PR body. There are 126 sites at `0517e75a7`: 125 `CliError::InvalidFormat(` lines plus one function-pointer use (dispatch_run.rs:242 `.map_err(CliError::InvalidFormat)`, which the `(` grep misses). The issue''s 130 was `git grep ''InvalidFormat(''` at `d0771c5c5`: 128 sites, the variant declaration, and its exit-code arm. #3661 moved 3. Classes, decided by the input that reaches each site: MOVED here, 10; MOVE, model file (may be GGUF, SafeTensors, or unrecognised, so "Invalid APR format" can be false), 33; MOVE, not a model file (CLI arguments, JSON/CSV/corpus inputs, HF responses, serialising our own reports, IO), 58; KEEP, APR-only input, 15; TEST, asserting on the variant, 10. A script checked that every one of the 126 appears in exactly one class. STOP LIST: no change to `InvalidFormat`''s Display or to any of the 116 unmoved sites; no new error variant; no edit outside apr-cli except this fragment and the regenerated roadmap.yaml; no push and no arm, because the cop folds this into the batch. MEASURED at this commit: `cargo test -p apr-cli --lib`: 7295 passed, 0 failed, 12 ignored (#3661''s 7294 plus this table). `cargo test -p apr-cli --lib model_file_error_tests`: 2 passed, this table and #3661''s, whose fixtures it now shares. `cargo clippy -p apr-cli --lib -- -D warnings`: rc 0. `--tests` fails only on 2 findings in the untouched pre-existing `commands/nf4_classifier.rs`, the same state #3661 recorded; none are in a touched file. `cargo fmt --all -- --check`: rc 0. Rustfmt does not reach safe_tensors_header.rs through its `include!`, so its changed lines were formatted by hand, and a whole-file rustfmt was not applied because it rewrites untouched lines. `scripts/check_complexity_ratchet.sh`: "a877fa056 vs … none new, none grown". `bash scripts/guard_tree.sh --no-cargo`: 76 checks, 0 failed. `check_roadmap_fragment_required.sh`, `roadmap_fragments.py aggregate --check`, `check_roadmap_sorted.sh` and `check_roadmap_ids_unique.sh`: all PASS. MUTANTS, run one at a time against this table, each RED: S01–S10, each moved site reverted alone to its pre-fix `CliError::InvalidFormat(…)`, fails exactly its own row. For example, S01 renders "error: Invalid APR format: Failed to parse GGUF: Invalid model format: Unexpected EOF reading u64 at offset 24", the issue''s string. With all 10 reverted, the 12 non-control rows fail (29 checks) and the APR control still passes. H1, `invalid_model_bytes` hardcoded to "SafeTensors" (the assumed format), fails the 3 "Invalid model file" rows (4 bytes, array header ×2). H2, `detected_format_of` always returning "model", fails the 8 rows that expect GGUF or SafeTensors. Sources were restored and checked by md5 before the full runs. NOT DONE: a run of a freshly built `apr` binary. The host was at load 55–64 on 48 cores, and a release build of the facade would have added to it. The table renders the same `error: {e}` line main.rs prints and asserts the exit-code mapping directly.' +- id: PMAT-3692 + github_issue: 3692 + item_type: task + title: 'guard-tree is RED on every intel runner since the 0.69 batch: check_pathonly_devdeps_unused_in_src.sh exits ENV for a missing TOML reader — fleet state must be UNMEASURED' + status: in_progress + priority: critical + assigned_to: aprender-62 + created: 2026-09-21T11:32:00Z + updated: 2026-09-21T11:32:00Z + spec: null + acceptance_criteria: + - 'Issue #3692 done_when 1, verbatim: "A missing TOML reader (neither `tomllib` nor `tomli`) and a missing interpreter print `UNMEASURED runner= reason=no-toml-reader|no-interpreter …` and exit **0**. guard_tree surfaces the line under PASS (#3651). Neither is ever a verdict line."' + - 'done_when 2, verbatim: "Anything else that stops the scan (the interpreter crashes, exits non-zero without the `SCAN-DONE` trailer, or exits 3 without the no-reader line) stays ENV rc 2, RED. Only the missing *tool* is fleet state, the #3671 line."' + - 'done_when 3, verbatim: "Case rows: `PATHONLY_GUARD_FORCE_NO_TOML=1` gives UNMEASURED rc 0; a missing interpreter gives UNMEASURED rc 0; `/bin/false` gives ENV rc 2. A mutant that maps every ENV to UNMEASURED turns the `/bin/false` row RED."' + - 'done_when 4, verbatim: "Proof on a real Python 3.10 with no TOML reader: the whole guard, and guard_tree around it, go UNMEASURED/PASS where the pre-fix guard went ENV/FAIL."' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'ANDON, found by aprender-62 as first responder on #3689: its guard-tree (job 106309701767, intel-clean-room-3) failed "76 checks, 1 failed" on this guard alone, "ENV: no TOML reader on this interpreter (python 3.10 …)". #3644 (batch #3669, a877fa056) put the guard in guard-tree''s --no-cargo population while its own header said the intel hosts have python 3.10.12 and no reader. The batch''s guard-tree passed only because it ran on gx10-pool1. The fleet fix is OUT: infra declared the fleet python-free for automation (infra#708, 02:05Z, "do not propose installing tomli"). So the cop ruled (~11:28Z) that the fix is the guard, folded onto #3689 for one CI cycle. SCOPE: this commit touches only scripts/check_pathonly_devdeps_unused_in_src.sh plus this fragment. #3689''s PMAT-3685 parity change is judged by its own receipt. HOW IT IS MET. scan() returns a third code, 3, for fleet state, in exactly two ways: `command -v` finds no interpreter (reason=no-interpreter), or the scanner prints its own "ENV: no TOML reader on this interpreter" line AND exits 3 (reason=no-toml-reader; the scanner''s sys.exit changed 2 -> 3). The pattern is keyed on the PAIR, so either one alone stays ENV. In both cases scan() prints `UNMEASURED runner=… reason=… … fleet state, not a pass (#3692)` to stderr, where it survives the callers'' command substitution; guard_tree captures both streams. selftest() passes 3 through; main() returns 0 on 3 from the case table or the tree scan, before any verdict or OK line. Every other failure path is unchanged: ENV rc 2. `--selftest` in fleet state also exits 0. DEATH ROWS, 5 -> 7: FORCE_NO_TOML -> 3; no interpreter -> 3 (was 2); /bin/false -> 2; an interpreter that exits 3 printing a traceback but NOT the no-reader line -> 2 (new: the exit code alone does not buy an UNMEASURED); the working interpreter -> 0; the WHOLE guard under FORCE_NO_TOML -> rc 0 with "UNMEASURED runner=intel-probe reason=no-toml-reader" and no "missed hit_", "false positive" or "OK: no NEW" line (was: rc 2); the WHOLE guard under /bin/false -> rc 2 (new). MEASURED at this commit: `bash scripts/check_pathonly_devdeps_unused_in_src.sh --selftest` rc 0, "PASS: case table (4 must-match, 7 must-not-match, 7 death rows)"; a bare run on this box''s python3 (which has a reader) rc 0, "OK: no NEW src/ reference to a publish-stripped dev-dep (3 baselined pair(s), #3306)", so the real verdict is unchanged where a reader exists. REAL PYTHON 3.10: /usr/bin/python3.10 is 3.10.12; run with -S (no site-packages) it cannot import tomli and has no tomllib, which is the intel host''s shape with a real interpreter. The whole guard under it gives rc 0, "UNMEASURED runner=py310-probe reason=no-toml-reader -- no TOML reader on this interpreter (python 3.10, need tomllib >= 3.11 or tomli) …". The PRE-FIX guard (main) under the same interpreter gives rc 2, "ENV: the scanner did not finish … ENV: the case table could not be measured (scan rc=2)", which is #3689''s failure reproduced. MUTANT, every ENV mapped to UNMEASURED (scan''s ENV branch `return 2` -> `return 3`): selftest rc 1 with three death rows RED, "rc=3 (wanted 2) interpreter exits 1 with no output", "rc=3 (wanted 2) interpreter exits 3 without the no-reader line", "rc=0 (wanted 2) the whole guard under a dead interpreter". GUARD_TREE UNDER THE SAME REAL PYTHON 3.10 (PATHONLY_GUARD_PYTHON=<3.10 -S stub> bash scripts/guard_tree.sh --no-cargo): rc 0, "76 checks, 0 failed", with "PASS scripts/check_pathonly_devdeps_unused_in_src.sh [run]" and beneath it "~ UNMEASURED runner=py310-probe reason=no-toml-reader -- …", surfaced by #3651. That is the job #3689 lost on intel-clean-room-3.' +- id: PMAT-3693 + github_issue: 3693 + item_type: task + title: 'Qwen3.5-9B Q4_K_M on CUDA at ~12k-token context corrupts identifiers it quotes from the prompt and runs at 1.0 tok/s: discriminate model weakness from long-context CUDA divergence' + status: in_progress + priority: critical + assigned_to: aprender-c3 + created: 2026-09-21T15:55:00Z + updated: 2026-09-21T15:55:00Z + spec: null + acceptance_criteria: + - 'Issue #3693 done_when 1, verbatim: "**discriminate first, then fix.** The same prompt, same seed, temperature 0: CPU (`--no-gpu`) vs CUDA, token by token. Identical corruption means model/quant weakness (document it, then compare a Q8_0/F16 9B); divergence means a CUDA path defect."' + - 'done_when 2, verbatim: "`apr parity` (or `--per-op`) at ≥ 8k positions, CPU vs CUDA, with the first position where cosine drops below the C14 floor named. C14''s corpus gains a long-context row, so the gate covers the context length the product is used at."' + - 'done_when 3, verbatim: "decode rate at 12k context measured separately from prefill, with `--json` timing fields. 1.0 tok/s end-to-end has to be attributed (prefill vs decode, and KV-cache growth)."' + - 'done_when 4, verbatim: "if CUDA diverges: the fix plus a falsifier that goes RED on the 12k-position corpus"' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'Routed by the cop (aprender-04) at 2026-09-21 ~15:45Z onto the 0.69.1 path (#3710 bar, context row: "each of the four at the largest prompt the three consumers actually send, derived from their measured traffic, never picked here", with RAH''s review lane measured at ~44 KB, about 12k tokens). The input is paiml-implement-c9''s prompt at /mnt/nvme-raid0/agent-wt/gtmp-318/apr-lane/lane.json.prompt.txt on lambda (44667 bytes, sha256 ed8b3007…). Model /home/noah/models/Qwen3.5-9B-Q4_K_M.gguf, sha256 03b74727…, identical on lambda and gx10. Binary: the 0.69.0 release build, `apr 0.69.0 (225b2a9ab)`, at /mnt/nvme-raid0/targets/ladder-069/release/apr on each host. Measurements are recorded on the issue as they land. DISCRIMINATION RESULT (aprender-c3, 2026-09-21): not a CUDA defect and not model weakness. (a) The gdn_decode_attention multi-pass path (>4096 positions) is correct: a new device test at the default cap, seq_len up to 12,288, passes against the CPU port. (b) RoPE is ruled out: rope.dimension_sections [11,11,10,0] make IMROPE equal NeoX for text. (c) On arbiter''s r891 prompt, apr CPU and apr CUDA BOTH lose to the pinned llama.cpp at copy positions from about 250 tokens (pos 252: llama.cpp 17114 `maps` at logprob -0.001, apr 2117 `map`). (d) The cause both share is the tokenizer: apr''s GGUF encoder is greedy longest-match, so the prompt reaches the model as ids it never saw. That is #3726, which carries the fix. This row closes as #3726 if the re-measure after the fix shows no corruption; any remainder stays here. The 1.0 tok/s is serial prefill (qwen35 CUDA has no batched prefill), owned by #3596.' +- id: PMAT-3694 + github_issue: 3694 + item_type: task + title: 'parity_receipt_denominator.sh needs a python-free classify() — then drop its UNMEASURED path' + status: in_progress + priority: high + assigned_to: aprender-0e + created: 2026-09-21T14:52:00Z + updated: 2026-09-21T14:52:00Z + spec: null + acceptance_criteria: + - 'Issue #3694 done_when 1, verbatim: "`parity_receipt_denominator.sh` classifies record / legacy / other with no python3 on PATH, by a real parse, and its self-test runs every row on a python-free runner."' + - 'done_when 2, verbatim: "The exit-3 UNMEASURED path and `ont4c3_parity_receipts`''s acceptance of exit 3 are removed, so a runner without the tool can no longer pass the test unmeasured."' + - 'Issue body, verbatim: "The predicate stays an independent implementation, deliberately not the Rust extractor''s, and it must still PARSE the JSON rather than substring-match it (a substring test standing in for a parse is refused). One option is a tiny parse in a tool the runners do carry."' + - 'Cop dispatch (aprender-04 to aprender-0e, 2026-09-21), verbatim: "done_when: the real corpus still gives `PASS 7 receipt(s)`; a stub PATH with NO python3 gives the same PASS; the git-refusal row (#3682) is unchanged; a mutant goes RED. No jq either unless you prove the runner has it (clean-rooms have none, and yoga''s is jq 1.6)."' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'Follow-up to #3695 (the stop-gap that made a python-free runner UNMEASURED exit 3) under the cop ruling on #3689. SCOPE: scripts/parity_receipt_denominator.sh, crates/aprender-contracts-cli/tests/ont4c3_parity_receipts.rs, and this fragment. HOW IT IS MET. classify() is POSIX awk, run under LC_ALL=C: a strict RFC 8259 parser, iterative (an explicit container stack, so no recursion limit), that validates UTF-8 inside strings (no overlongs, no surrogates, nothing past U+10FFFF) and keeps only the ROOT object''s keys, each value''s kind and the decoded text of a string value. The rule is unchanged: record iff the root is an object whose schema is the string apr-parity-receipt/v2; legacy iff not, and metrics is an array or parity is present; anything else, including any syntax error, is other. A later duplicate key wins, as in json.load and serde_json. A raw NUL byte is decided in bash (other), because busybox awk holds C strings and would truncate the document. It is still an independent implementation: no code shared with extract:parity-receipt. The one deliberate difference from the python it replaces: NaN / Infinity are not JSON (RFC 8259), and serde_json refuses them too, so they are other. REMOVED: PY_BIN / PARITY_PYTHON, the command -v check and its UNMEASURED return 3, the --self-test UNMEASURED early exit, and the Rust test''s exit-3 acceptance. There is no exit 3 any more. A missing awk, or one that answers nothing, is ENV exit 2, RED (seam PARITY_AWK). SELF-TEST, 9 rows (was 7): the 5 original rows unchanged, including the #3682 git-refusal row; NEW "a PATH with no python3 (only git awk sort grep head tr wc) measures the same PASS", which also lists the script''s dependencies; NEW "a missing classifier is ENV exit 2 naming it, never a count of 0 or UNMEASURED", replacing the #3695 no-interpreter row; "a classifier that answers nothing is ENV exit 2" (#3695, kept); NEW a 35-row classification table (escaped slash, a \u-escaped key, quotes and brackets inside strings, schema nested or only in prose, a root array, a truncated document, trailing content, a trailing comma, single quotes, NaN, a leading zero, a raw tab, a bad escape, latin-1, a UTF-8 surrogate, a NUL, a BOM, duplicate keys in both orders, and legacy metrics[] / parity / an escaped metrics key). MEASURED at this commit. `bash scripts/parity_receipt_denominator.sh` rc 0 "PASS 7 receipt(s) under evidence/parity/**, and evidence/parity/EXPECTED_RECEIPTS says 7." --self-test rc 0, 9 ok, under gawk 5.1, mawk 1.3.4-20200120 and busybox awk (PARITY_AWK). THE YOGA SHAPE, a PATH of every /usr/bin and /bin executable except python* (2832 tools, command -v python3 finds nothing): the real corpus gives the same rc 0 PASS 7, --print gives 7, and --self-test gives 9 ok. THE RUNNER IMAGE: sovereign-ci is FROM rust:1.95-slim-bookworm (infra machines/intel/sovereign-ci/Dockerfile). In debian:bookworm-slim plus git (mawk 1.3.4.20200120-3.1, python3 NONE, jq NONE) the self-test gives 9 ok and the real corpus gives PASS 7 rc 0; in rust:1.95-slim (trixie, mawk 1.3.4.20250131-1, python3 NONE, jq NONE) the same. awk is Priority: required in Debian, and 52 of 131 scripts/check_*.sh already run it on every runner. DIFFERENTIAL against the old python classify(), over all 118 tracked files under evidence/parity/** plus 55 adversarial documents including a 3000-deep nesting: identical under gawk and mawk except NaN and -Infinity (the deliberate difference above); 7 records in both. The 35 table rows agree with the python rule on 34; the 35th is the NaN row. MUTANTS, each run against --self-test, all RED: a substring classifier (grep for the schema) gives rc 1 with 23 FAIL rows; the python classify() restored gives rc 1 ("a python-free PATH gave exit 2 … python3: command not found"); the first duplicate key wins gives rc 1 on both duplicate rows; UTF-8 validation removed gives rc 1 (latin-1, surrogate); trailing content accepted gives rc 1; the schema-kind check removed gives rc 1 ({"schema":"","schema":2} -> record); the silent-classifier arm restored to fall through as other (#3695) gives rc 1, "the tree holds 0"; the NUL pre-check removed gives rc 1 under busybox awk and rc 0 under gawk, so that guard is load-bearing only for C-string awks. THE RUST TEST: `cargo test -p aprender-contracts-cli --test ont4c3_parity_receipts` 9 passed with python3 on PATH, and 9 passed on the yoga-shape PATH plus ~/.cargo/bin (no python3). PARITY_AWK=/bin/true fails it, "exit Some(2)" plus the ENV line. MUTANT: the pre-fix script (225b2a9ab) on the python-free PATH fails the new test with "exit Some(3)" and the UNMEASURED line, so the exit-3 acceptance is gone. bashrs lint 0 errors; check_shell_lint_ratchet.sh PASS (ratcheted); cargo fmt --all -- --check rc 0. Not in scope: #3697 (the other guards that need python3), which is the next row in this lane.' +- id: PMAT-3695 + github_issue: 3695 + item_type: task + title: 'workspace-test RED on python-free runners: parity_receipt_denominator.sh scores a missing python3 as "the tree holds 0"' + status: in_progress + priority: critical + assigned_to: aprender-62 + created: 2026-09-21T11:36:00Z + updated: 2026-09-21T11:36:00Z + spec: null + acceptance_criteria: + - 'Issue #3695 done_when 1, verbatim: "No python3 on the runner prints `UNMEASURED runner= reason=no-interpreter interpreter= …` and exits **3**, never a count. A python3 that exists but gives no classification (crashes, prints nothing) is ENV rc 2, RED. Exit 1 (disagree) is unchanged."' + - 'done_when 2, verbatim: "The Rust test accepts exit 3 ONLY with that line (naming the interpreter) on stderr. Exits 1 and 2 still fail it."' + - 'done_when 3, verbatim: "Self-test rows for all three: no interpreter → 3 plus the line; an interpreter that answers nothing → 2; the working interpreter → the existing rows. Plus a mutant."' + - 'done_when 4, verbatim: "It stays MEASURED wherever python3 exists. The cop requires `PASS 7 receipt(s)` from `bash scripts/parity_receipt_denominator.sh` at the release commit in the T-2 ledger."' + - 'done_when 5, verbatim: "The root fix, `classify()` without python, after which the UNMEASURED path disappears, is its own 0.70 row: #3694."' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'ANDON 2, found by aprender-62 as first responder on #3689: workspace-test-shard 1/3 (job 106309701273, runner yoga-build3) failed ont4c3_parity_receipts::the_committed_tree_agrees_with_its_own_denominator with "scripts/parity_receipt_denominator.sh: line 61: python3: command not found" for every receipt. classify() then printed nothing, the loop read that as "other", and the script said "the tree holds 0", exit 1. That is a missing interpreter scored as a count, the class of the git refusal in #3682. The cop ruled (~11:40Z) to fold it into #3689''s push under four conditions, which are done_when 1-5 above. SCOPE: scripts/parity_receipt_denominator.sh, crates/aprender-contracts-cli/tests/ont4c3_parity_receipts.rs, and this fragment. HOW IT IS MET. PY_BIN (seam PARITY_PYTHON, default python3). count_and_check checks `command -v "$PY_BIN"` after listing the tree and before any file: absent -> UNMEASURED line to stderr, return 3, which verify and --print propagate. Each file''s class must now be exactly record|legacy|other; anything else, including nothing, is "ENV the classifier () gave no answer for ", return 2 (the old `*) :` fall-through was the defect). --self-test on a runner with no interpreter prints an UNMEASURED line and exits 0: the classification rows cannot run there. The Rust test accepts exit 3 only when stderr carries both "UNMEASURED runner=" and "reason=no-interpreter interpreter="; any other non-success still fails. MEASURED at this commit: `--self-test` rc 0 with 7 rows, the 5 existing plus "no interpreter is UNMEASURED exit 3 naming it, never a count of 0" and "an interpreter that answers nothing is ENV exit 2, never a count of 0"; a bare run with python3 gives rc 0, "PASS 7 receipt(s) under evidence/parity/**, and evidence/parity/EXPECTED_RECEIPTS says 7." (the T-2 requirement, measured); PARITY_PYTHON=/nonexistent gives rc 3 "UNMEASURED runner=nopy-probe reason=no-interpreter interpreter=/nonexistent/python3 …"; PARITY_PYTHON=/bin/true gives rc 2 "ENV the classifier (/bin/true) gave no answer for evidence/parity/derived_expiries.json". THE YOGA SHAPE, a PATH made of every /usr/bin and /bin executable except python*: the PRE-FIX script (25d2ee264) prints "python3: command not found" 118 times, then "FAIL evidence/parity/EXPECTED_RECEIPTS says 7; the tree holds 0.", rc 1, which is #3689''s failure reproduced; the fix prints "UNMEASURED runner=yoga-shape reason=no-interpreter interpreter=python3 …", rc 3. MUTANT, the silent-classifier arm restored to the old `*) :` fall-through: self-test rc 1, "FAIL a silent interpreter gave exit 1: FAIL evidence/parity/EXPECTED_RECEIPTS says 2; the tree holds 0." THE RUST TEST: `cargo test -p aprender-contracts-cli --test ont4c3_parity_receipts` gives 9 passed with python3; PARITY_PYTHON=/nonexistent/python3 gives 1 passed, printing the UNMEASURED line; PARITY_PYTHON=/bin/true gives FAILED, "exit Some(2)" plus the ENV line, so a crash is still RED and only the named UNMEASURED line buys exit 3. `cargo fmt --all -- --check` rc 0.' +- id: PMAT-3696 + github_issue: 3696 + item_type: task + title: 'publish_strict.sh: a blank line in publish-order.txt stops the cascade naming an EMPTY crate — refuse it by line number' + status: in_progress + priority: low + assigned_to: aprender-62 + created: 2026-09-21T11:39:00Z + updated: 2026-09-21T11:39:00Z + spec: null + acceptance_criteria: + - 'Issue #3696 done_when 1, verbatim: "An empty crate name is refused **by name**, before any set check: `STOP publish: blank line N in publish-order.txt` (every blank or whitespace-only line, each by its number), rc 1, and no `bad array subscript`."' + - 'done_when 2, verbatim: "Measured in a private clone: a blank line at line 36 gives exactly that message; the clean file still plans 74 rows, rc 0."' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'Found by aprender-7a seat-filling #3657; the cop ruled it a small 0.70 row stacked on #3657''s 6fd241645, which is not touched (this commit is its child). SCOPE: scripts/release/publish_strict.sh (4 lines before the mapfile) and this fragment. HOW IT IS MET: awk lists every line of publish-order.txt that is empty or whitespace-only, by number; any hit stops with `die "blank line in publish-order.txt: an empty crate name is not a crate"` before ORDER is built, so no empty string reaches the set checks or bash''s associative-array subscript. publish_strict.sh has no --self-test on purpose (one would make it a guard that must be workflow-invoked), so the proof is end to end. MEASURED in a private clone (its own refs; tag v9.9.9 in the clone only; RELEASE_AP in scratch; --plan reads the sparse index and uploads nothing). BEFORE, at 6fd241645, a blank line at line 36: rc 1, "scripts/release/publish_strict.sh: line 47: EXPECT: bad array subscript" and "STOP publish: in the publish order but not in the universe: " (an empty name). AFTER, at this commit: the clean file gives rc 0 and 74 rows; a blank line at 36 gives rc 1, "STOP publish: blank line 36 in publish-order.txt: an empty crate name is not a crate", with 0 subscript errors; a whitespace-only line at 3 plus a blank line (now at 37) gives rc 1, "STOP publish: blank line 3, 37 in publish-order.txt: an empty crate name is not a crate". `bash scripts/check_release_scripts_derive_identity.sh`: PASS (no literal count, no identity literal).' +- id: PMAT-3697 + github_issue: 3697 + item_type: task + title: 'guard-tree python dependence, batch 1 of #3697: 4 guards python-free or UNMEASURED (t2_preflight_verdict, no_hosted_runners, nextest_ci_profile_no_fail_fast, roadmap_ids_unique) + scripts/lib/python_fleet_state.sh' + status: in_progress + priority: high + assigned_to: aprender-0e + created: 2026-09-21T15:20:00Z + updated: 2026-09-21T16:40:00Z + spec: null + acceptance_criteria: + - 'Issue #3697, verbatim: "**What lands (0.70):** per guard, one of: - (a) remove the python dependency (the root fix, the direction of #3694: no python in automation). For YAML reads, prefer `pv`/bashrs/Rust readers the repo already builds. - (b) where a python reader stays, classify its absence as fleet state: `UNMEASURED … reason=`, exit 0, surfaced by guard_tree (#3651), never red. That is the ruling applied to fleet-pv (#3669''s andon) and to pathonly (#3692)."' + - 'Issue #3697, verbatim: "My own `check_nextest_ci_profile_no_fail_fast.sh` (#3626) is on the no-python3 list. It reads TOML through a purpose-built fallback on 3.10, but with no interpreter at all it reports ENV rc 2, which guard_tree counts as FAIL: same class, (b) applies."' + - 'Cop dispatch (aprender-04 to aprender-0e, 2026-09-21), verbatim: "Each guard becomes python-free, or UNMEASURED per the #3692 ruling. One PR per 3–4 guards so the reviews stay small." and "same proof shape (no-python3 PATH + debian:bookworm-slim)".' + - 'NOT in this batch (it lands with the last batch, when it can be green): the issue''s "one guard-tree row: `guard_tree.sh --no-cargo` under a `python3 -S` stub and a no-python3 stub. It must end `0 failed`". Today 18 other guards still fail it.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'SCOPE: scripts/lib/python_fleet_state.sh (new, sourced), scripts/check_t2_preflight_verdict.sh, scripts/check_no_hosted_runners.sh, scripts/check_nextest_ci_profile_no_fail_fast.sh, scripts/check_roadmap_ids_unique.sh, and this fragment. The rest of #3697 (18 guards, and the stub-shaped guard-tree row) is later batches. (a) PYTHON-FREE. t2_preflight_verdict: the self-test''s mutant splice (replace decide() with the pre-#3561 absence-as-consent body) is awk over a quoted-heredoc mutant, cut from the `decide() {` line through the first line that is exactly `}`; a subject with no such close is ENV. The spliced file is BYTE-IDENTICAL to the python splice''s output under gawk 5.1, mawk 1.3.4 and busybox awk. no_hosted_runners: the scan is awk; POSIX ERE has no \b, so the token''s boundaries are spelled `(^|[^A-Za-z0-9_])…([^A-Za-z0-9_]|$)`. DIFFERENTIAL vs the python scan (cwd-relative paths, same baseline semantics, sorted stale list): identical stdout+rc on the real 21 workflows (with and without a baseline), on a 611-violation adversarial corpus (every token shape x 11 prefixes x 12 suffixes), and on two baseline corpora, under all three awks, EXCEPT a token touching a non-ASCII letter (e.g. ubuntu-latesté): python (Unicode \w) passed it, awk (ASCII word chars) flags it. 0 violations lost, 111 added, all with é. Rows 13-15 pin both boundaries and the ASCII choice (rows 13/14 agree with python; row 15 is the deliberate difference). (b) UNMEASURED. scripts/lib/python_fleet_state.sh: py_fleet_state [module...] probes the interpreter (PY_FLEET_PYTHON, default python3) by importing each module; only ModuleNotFoundError is `not installed`. rc 0 ok; rc 3 fleet state with ONE stderr line `UNMEASURED runner= reason=no-interpreter interpreter= guard=` (absent, or exec 126/127) or `reason=no-module module=`; rc 2 ENV for an interpreter that exists and dies or answers nothing. Reason names: the tree already says `no-interpreter` (#3692 pathonly, #3695 denominator), so that is kept over the issue''s example `no-python`, and `no-module module=yaml` names the module rather than coining one reason per module. Sourced, option-neutral (check_sourced_libs_option_neutral.sh OK: 9 libraries). Its case table py_fleet_state_self_test (5 stub rows + 2 real-interpreter rows that print UNMEASURED where there is none) runs inside each consuming guard''s --self-test, because a scripts/tests file would be dark without a workflow edit. nextest_ci_profile_no_fail_fast: judge() probes first; no interpreter -> rc 3 -> the run exits 0 with the UNMEASURED line and no PASS line; /bin/false still ENV rc 2; the old row `no interpreter at all -> ENV rc=2` is now `-> UNMEASURED rc=3` plus a run-level row; the reader table (both readers) is UNMEASURED where python is absent. roadmap_ids_unique: scan() needs python3 + PyYAML; either missing -> UNMEASURED exit 0; a dying python3 -> ENV; the 5 YAML rows are UNMEASURED where there is no reader; the missing-file row and two new fleet-state rows run everywhere. MEASURED, guard_tree.sh --no-cargo on 225b2a9ab + this batch, each shape a python3 stub first on PATH: normal python3 76 checks, 0 failed (unchanged); python3.10 -S 14 -> 12 FAIL rows (roadmap_ids_unique s+r gone); no python3 (stub exits 127) 29 -> 22 FAIL rows (all 7 rows of these 4 guards gone), and under PASS guard_tree surfaces the UNMEASURED lines (#3651). debian:bookworm-slim (sovereign-ci''s FROM base) + git, python3 NONE, jq NONE, mawk 1.3.4.20200120-3.1: t2_preflight_verdict self-test rc 0 (2 ok) run rc 0; no_hosted_runners self-test rc 0 (15 ok) run rc 0 `OK: 21 workflow files`; nextest self-test rc 0 (9 ok, 3 UNMEASURED) run rc 0; roadmap_ids_unique self-test rc 0 (8 ok, 3 UNMEASURED) run rc 0 with the UNMEASURED line. MUTANTS, each against a scratch copy, all RED: py_fleet_state mapping every failure to UNMEASURED -> roadmap_ids_unique self-test rc 1 (`a python3 that dies -> ENV exit 2, never UNMEASURED`, plus the helper''s crash rows); no_hosted_runners leading boundary dropped -> rc 1 (row 13 xubuntu-latest); t2 splice made a no-op -> rc 1 (`the pre-#3561 mutant PASSED the case table`). bashrs: check_shell_lint_ratchet.sh PASS (errors only may not rise).' +- id: PMAT-3699 + github_issue: 3699 + item_type: task + title: 'prepare_bump.sh --ship opens a bump PR whose body fails §6 R-2 (check_pr_closes_issue): the CHANGELOG''s context refs (#EPIC, ''refs #N'') have no keep-open line — hit on 0.68.2 (#3498) and 0.69.0 (#3698)' + status: in_progress + priority: high + assigned_to: aprender-f0 + created: 2026-09-21T13:03:24Z + updated: 2026-09-21T15:20:00Z + spec: null + acceptance_criteria: + - 'Issue #3699 done_when 1 AS AMENDED on the issue by its author (comment 2026-09-21T15:17:48Z, "done_when 1 amended (issue author, cop, 2026-09-21), replacing the original wording"), verbatim: "`prepare_bump.sh --ship` derives every `#N` the §6 R-2 guard owes a reason for (`check_pr_closes_issue.sh --list-owed`: not under a closing keyword, not proven a PR or a closed issue; an unresolvable ref counts) and writes ONE `keep-open:` line naming them (\"cited by the CHANGELOG for context; each closes via its own PR; the release EPIC closes at T-4\")"' + - 'done_when 2, verbatim: "before `gh pr create` it runs `scripts/check_pr_closes_issue.sh --body ` and refuses to open the PR on rc != 0"' + - 'done_when 3, verbatim: "a case-table row: a CHANGELOG with an EPIC ref and a `refs #N` produces a body the guard PASSes; a mutant that drops the keep-open line goes RED"' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'Assigned by the cop (aprender-04) as the first item of the release-tooling lane, to land before the 0.70 bump. Fixtures and stubs only: nothing here ran against the live 0.69 train, its state dir, or a publish token. SCOPE: scripts/release/prepare_bump.sh, scripts/check_pr_closes_issue.sh, the new scripts/check_release_bump_pr_body.sh, and this fragment. HOW IT IS MET. (1) --ship builds the body BEFORE the cargo checks, the commit and the push (it used to be built after the push). It asks the guard for the refs that owe a reason through a new `check_pr_closes_issue.sh --list-owed --body FILE`, which prints the output of the SAME classify_refs() the judge uses (refactored out of check_body_text, behaviour unchanged), and appends ONE line `keep-open: #A #B -- cited by the CHANGELOG for context; each closes via its own PR; the release EPIC closes at T-4`, whose reason is done_when 1''s parenthetical, verbatim. The epic-and-refs row pins the whole line. When nothing is owed there is no line. WHICH REFS (done_when 1 as amended; the ORIGINAL read "derives every `#N` in the generated body that isn''t under a closing keyword", and quorum round 2''s lane 1 FAILed on that literal reading, which is why the issue author amended it): the guard''s own set, so references PROVEN to be pull requests or closed issues are left out, exactly as the judge leaves them out, and an unresolvable ref is kept (fails closed). Measured on the real 0.69.0 body: 61 distinct #N, of which the guard owes 5 (#3080 #3545 #3571 #3602 #3658), which is the same 5 the CI step flagged and aprender-62 named by hand. Naming all 61 would list merged PRs in a keep-open line. THE REASON TEXT is the ticket''s own. Quorum round 1 FAILed an earlier wording that described the close MECHANISM instead (lane 1, gemini-3.1-pro-high: the reason must be done_when 1''s text), and the ticket''s text wins. Its last clause is a statement about WHEN, and it holds today: the epic is closed at T-4, by hand (0.68.2''s #3477, closer=null, 2026-09-20T08:23Z; the cop is closing 0.69.0''s #3080 right after the crates.io publish). #3708, same owner and queued before the 0.70 bump that first emits this line, makes the close step do it mechanically: autopilot.sh close (lines 301-307) comments on the epic, then requires 0 open milestone items, and closes nothing. The reason carries no `#`, so the line cannot add a closing reference (a line that closed the epic on the bump''s merge would be the #3400 landmine). (2) `bash check_pr_closes_issue.sh --body pr_body.md || die "the bump PR body fails §6 R-2; nothing committed, pushed or opened"` runs before the cargo checks, the commit, the push and `gh pr create`. (3) scripts/check_release_bump_pr_body.sh is a scripts/check_*.sh, so guard_tree.sh runs it bare in guard-tree with no workflow edit (the check_t2_preflight_verdict.sh pattern). It runs the REAL prepare_bump.sh --ship end to end in a throwaway fixture: a local bare origin, a bump clone on release-9.9.9 with the CHANGELOG section uncommitted, a T-2 GO receipt, stubs for gh (records calls, captures --body-file), cargo and the arm helper, and ref kinds from the guard''s PR_CLOSES_REF_KIND_CMD seam. ROWS: guard-case-table (runs check_pr_closes_issue.sh --self-test, see DARK TABLE below); epic-and-refs (EPIC #9002 + `refs #9005` + PR #9001 + `closes #9006` -> PR opened, body PASSes the guard, ONE keep-open line naming exactly #9002 #9005, not the PR and not the closed-by-keyword ref); no-keep-open (that body minus its keep-open line -> guard rc 1); adds-no-close (the keep-open line alone -> --list-owed lists every ref it names); prs-only (no line, still PASS); landmine (`no-close: #9005` -> non-zero, no `gh pr create`, no branch on origin). COMMITTED MUTANTS, run on every bare run: drop-keep-open (the printf line removed) is killed by epic-and-refs, "exited 1: STOP the bump PR body fails §6 R-2"; drop-refusal is killed by landmine, "exited 0 on a landmine body". A missing subject or mutation anchor is ENV rc 2, never a pass. The guard table gains list-owed (#9001 pr, #9002 open, #9003 unresolvable, #9004 closed, #9005 under Closes -> exactly "#9002 #9003") and list-owed-empty-body (rc 2). MEASURED at this commit: `bash scripts/check_release_bump_pr_body.sh` rc 0, "PASS 8 row(s)"; `bash scripts/check_pr_closes_issue.sh` rc 0, "self-test OK: 21 case(s)". The first run of the new table caught a real bug in this change: the keep-open line read "#9005-- cited", because $(...) strips the trailing newline. LIVE REPLAY: the real CHANGELOG [0.69.0] section through the real prepare_bump.sh --ship, with gh `api` passed to the real gh and only `pr create` stubbed. rc 0, 122 api calls (two passes over 61 refs), 1 pr create. Keep-open line "keep-open: #3080 #3545 #3571 #3602 #3658 -- cited by the CHANGELOG for context; each closes via its own PR; the release EPIC closes at T-4". The unmodified guard with LIVE resolution on the opened body: "PASS: non-closing ref(s) #3080 #3545 #3571 #3602 #3658 allowed by a keep-open reason." Zero closing references in the body. AD HOC MUTANTS, not committed, each RED: a reason ending "the release EPIC closes #9002" turns 2 rows RED (epic-and-refs, adds-no-close: "names '#9002 #9005 #9002 ' but only '#9005 ' are still owed"); naming every #N instead of --list-owed turns 3 rows RED (epic-and-refs, adds-no-close, prs-only); moving the refusal after the push turns landmine RED, "the branch was pushed before the refusal"; a --list-owed that prints every ref turns 3 rows of the WIRED table RED (guard-case-table, epic-and-refs naming #9006, prs-only). DARK TABLE, pre-existing and found here: `bash scripts/guard_tree.sh --no-cargo` prints `skipped: scripts/check_pr_closes_issue.sh -- wired-with-args in ci.yml`, and ci.yml line 1398 runs that guard only with --body. So its case table ran in NO CI job, even though the ci.yml comment at lines 1368-1373 still says guard_tree runs it bare. Its new list-owed rows would have been dark too. The guard-case-table row gives that table a caller inside guard-tree with no workflow edit. The stale ci.yml comment is left for a workflow-authorized change. GUARD_TREE: `bash scripts/guard_tree.sh --no-cargo` at fc5fdee22 (7 rows then): "77 checks, 0 failed", with "PASS scripts/check_release_bump_pr_body.sh [run]". OUT OF SCOPE, observed: a CHANGELOG bullet whose PR title carries a closing keyword ("fix: closes #N") would still close #N when the bump merges. The guard PASSes that, correctly by its own rule, and nothing here changes it.' +- id: PMAT-3703 + github_issue: 3703 + item_type: task + title: 'aprender-verify-ml test_pipeline_generate_small asserts wall-clock (generation_time_ms > 0) — failed v0.69.0''s clean-room B2 on a fast gx10 runner' + status: in_progress + priority: critical + assigned_to: aprender-fd + created: 2026-09-21T14:20:00Z + updated: 2026-09-21T15:22:00Z + spec: null + acceptance_criteria: + - 'Issue #3703 done_when 1, verbatim: "the assertion tests what the code promises (the stat is populated and monotone), never elapsed wall time. E.g. drop the timing clause, or record µs and assert `generation_time_us` is set, not `> 0`"' + - 'done_when 2, verbatim: "a sweep of every test in the crates clean-room B2 runs (`--lib` of the published crates) for `as_millis() > 0` / `elapsed ... > ` / `Instant`-based assertions, with each hit fixed or listed with its reason. `scripts/check_no_timing_in_required.sh` extended to see this form (it passed while this sat in a required gate)"' + - 'done_when 3, verbatim: "mutation proof: a test build with an instantaneous generator must still PASS"' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'Handed to aprender-62 by the cop after infra-c8 was redirected by the operator (#3703 was unstarted). #3702, filed a minute earlier for the same defect, was closed as a duplicate. THE FAILURE: v0.69.0 clean-room (paiml/infra run 35608872676, gx10-pool1, "Run clean-room gates") GATE B2: aprender-verify-ml data::pipeline::tests::test_pipeline_generate_small, "assertion failed: stats.generation_time_ms > 0 || stats.total_generated < 10". `generation_time_ms` is `elapsed.as_millis() as u64` and the test asks for count(10), so a host that generates 10 programs in under 1 ms reads 0. It did not reproduce on lambda''s debug build (0/40 runs failed there), which is why PR CI and the merge group were green. DONE_WHEN 1: the timing clause is replaced by what generate() promises, `assert_eq!(stats.total_generated, programs.len())`, which holds by construction (`total_generated: all_programs.len()`). No clock is asserted. DONE_WHEN 3, measured: with the generator made instantaneous (`generation_time_ms` forced to 0), the fixed test PASSES ("1 passed"), and the OLD clause under the same mutant FAILS with exactly the clean-room message, "assertion failed: stats.generation_time_ms > 0 || stats.total_generated < 10". So #3703 reproduces deterministically on any host. DONE_WHEN 2, the sweep. Scope: every `crates/*/src/**.rs` (the `--lib` surface). The #3703 shape is an INTEGER duration (`.as_millis()`, `.as_micros()`, `.as_secs()`, or a name ending _ms/_us/_secs) asserted `> 0`, `>= 1` or `!= 0`, which truncates to 0 on a fast host. A float `> 0.0` on `as_secs_f64()` does not truncate. 104 hits. FIXED, 3, each a measured duration with nothing guaranteeing it is positive: pipeline.rs:438 (above), aprender-orchestrate bug_hunter/tests_patterns.rs `hunt_result.duration_ms > 0` (dropped; result.is_ok() and the parsed claims already prove the hunt ran) and aprender-train finetune/instruct_trainer.rs `result.total_time_ms > 0` (dropped; the epoch count is asserted). LISTED WITH ITS REASON, 101, in the new scripts/wallclock_assert_baseline.txt, each line read and classified: 76 declared render budgets (`budget()` returns BrickBudget::uniform(16) and similar; constants), 9 configured values (timeouts, windows, intervals, chunk sizes, options), 7 epoch timestamps (`timestamp_ms` from SystemTime), 1 cost-model estimate, 4 fixture inputs (health_tests Duration::from_millis(100), process_tracer from_micros(100), stats u64::MAX/2, format_chat latency_us=5000), and 4 real measurements taken AFTER a sleep of at least the truncation unit (cache/tests.rs sleeps 2 ms; falsification/types.rs sleeps 1 ms; brick_tracer sleeps 10 us and 100 us). THE GUARD: check_no_timing_in_required.sh PART 4 scans with that pattern (comment lines excluded by the same matcher) and ships a 15-row case table (7 must-match, including the exact pipeline line; 8 must-not-match, including `> 0.0`, `as_secs_f64() > 0.0`, `>= 10`, a comment, and a name that only contains `_ms`). A pattern that disagrees with its table is refused before any scan result is trusted. THE LEDGER IS KEYED ON THE ASSERTION TEXT, not on `path:line`: each line is ``, so the 101 hits are 32 recorded texts. A coordinate key was the first version (handed over at 0221c7c1b) and was measured to be a trap. With the ledger at a comparand (BASELINE_RATCHET_BASE_REF=HEAD), one unrelated comment line inserted at the top of widgets/border.rs made PART 4 report border.rs:755 NEW and :754 stale. Re-pointing the entry, which is the remedy it printed, was then REFUSED by the set-aperture ratchet ("the owning guard is unchanged in this diff"), so any unrelated edit above any of the 101 lines in ~50 files would have turned guard-tree red with no in-branch fix. The ratchet is now `keyed` (classified in check_baseline_ratchets.sh): no text may appear and no count may rise. PART 4 fails on NEW (a text the tree holds more often than recorded, so a COPY of a recorded line fails too), on STALE (a recorded count above the tree''s: lower it in the commit that fixed the line, which the ratchet allows), on a malformed ledger line, and on a scan of 0 files. GUARD MUTANTS, measured on this tree with BASELINE_RATCHET_BASE_REF=HEAD: M0 unmutated rc 0; M1 the #3703 line restored rc 1 (NEW, pipeline.rs:442); M2 the trap above, an unrelated insertion over a recorded line, rc 0; M3 a copy of `assert!(budget.total_ms > 0);` added in a new place rc 1 (count rises); M4 every data line removed from the ledger with the hits still in the tree rc 1; M5 a recorded count raised rc 1 (stale, and the ratchet reports RAISED); M6 a new key appended rc 1 (NEW KEY); M7 a malformed ledger line rc 1; M8 the `_ms` alternative dropped from the pattern rc 1 (4 case-table rows flip, scan not trusted); M9 the scan made to answer 0 files rc 1; M10 M4 under `NR == FNR` instead of `FILENAME == ARGV[1]` rc 0. M10 is the proof that the awk file test is load-bearing: with an emptied ledger `NR == FNR` reads every hit as a recorded entry and passes them all, so the guard uses FILENAME. ONE MORE HIT, OUTSIDE THE INTEGER SHAPE AND FIXED: aprender-train monitor/inference/tests/inference_monitor_tests.rs test_monotonic_ns_non_zero asserted `monotonic_ns() > 0` where monotonic_ns() is `START.get_or_init(Instant::now).elapsed().as_nanos()`. When that test is the first caller in the process, the call initializes the epoch and reads the gap between two back-to-back clock reads, which is 0 on a coarse timer. Its sleep ran BEFORE that first call, so it guarded nothing. The test now initializes, sleeps 1 us, and asserts the second read is greater than the first; the sleep, not host speed, carries the assertion. bashrs on the guard: 0 errors (the shell lint ratchet counts errors). The added warnings are the parser reading awk array syntax, `$''\t''` and `[![:space:]]` as shell. SCOPE AMENDMENT, the issue author (cop) on #3703, 2026-09-21T14:49:28Z, verbatim: "done_when 2''s sweep is satisfied by *listing* each remaining hit with its reason. The slow-host `elapsed < N` upper-bound class is the named remainder, tracked in **#3705**, and #3703''s ledger may list those hits with reason `#3705`. The PR for #3703 may therefore say `Closes #3703` + `Refs #3705`." THE LISTING: docs/audits/pmat-3703-timing-sweep.md, a snapshot at 8c08dd8dd with the commands that regenerate it (they print 58 + 45 = 103 lines). 58 upper bounds carry reason `#3705`. The 45 other lower bounds on a duration each carry a reason: 10 are sleep-guarded, 8 are tautologies, 8 are not clock readings, 17 are nanosecond or float readings over real work (0 only inside one clock tick; the closest is trueno-ublk adaptive_batch.rs:494, which times two add_items calls), 1 is a hidden upper bound routed to #3705 (tuner_tests_callbacks.rs:191, `remaining >= 999 s`), and 1 is `#[ignore]`d. It is listed rather than put in the PART 4 ledger because the ledger''s data lines are ENFORCED by text and count, and a coordinate list there would read as enforced while drifting. OUT OF THIS ROW, and stated rather than stretched: the SLOW-host twin, an upper bound on elapsed time (`elapsed < N`), with 59 candidate lines in the same sweep, is filed as #3705 (0.70). done_when 2''s "`Instant`-based assertions" reads that class in; this row covers the fast-host truncation class that failed the release, and a reviewer should judge #3705 as the named remainder.' +- id: PMAT-3704 + github_issue: 3704 + item_type: task + title: 'ONT-4c3: pc_extract draws the parity-receipt positive control every gate run, and every extractor the gate runs has a control' + status: planned + priority: high + assigned_to: null + created: 2026-09-21T14:16:17Z + updated: 2026-09-21T14:16:17Z + spec: null + acceptance_criteria: + - "cargo test -p aprender-contracts --lib lint::shapes_gate::tests::every_implemented_entity_type_in_sigma_has_an_extract_control_and_it_fires passes: the pc_extract key set EQUALS contracts/ontology.yaml's implemented entity types (7) and every control is fired — red on main (4 vs 7)" + - "cargo test -p aprender-contracts-cli --test ont4c3_parity_receipts the_parity_extractor_control_is_drawn_by_the_gate_every_run passes: top-level pc_extract[\"parity-receipt\"] == \"fired\" on aprender's contracts/, the ONT-001 v4.10 ONT-4c3 probe's question" + - "pv lint contracts/ --gate shapes --format json: verdict Pass, pc_extract 7/7 fired, by_entity_type[\"parity-receipt\"] == 7" + - "Mutation: each of the three new controls goes not-fired when its extractor regresses the way it watches (parity drops the comparator edge; json infers a class for an unmapped nested key; pv-contract infers metadata.kind) and the gate declines exit 2 naming pc_extract.; dropping a control key turns the \u03a3-tie test red" + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: "Refs #3577 (ONT-4c3; its ledger binding is infra's row, bound after this merges) and #3624 (the by_entity_type sibling, not closed here). R-3 of ONT-001: pc_extract is one planted defect per registered extractor, every run." +- id: PMAT-3708 + github_issue: 3708 + item_type: task + title: 'autopilot''s INHERITED dogfood GO writes no receipt that check_publish_preflight.sh R5 accepts — v0.69.0 stopped at the publish preflight 43 min after tagging' + status: in_progress + priority: critical + assigned_to: aprender-f0 + created: 2026-09-21T14:42:13Z + updated: 2026-09-21T15:45:00Z + spec: null + acceptance_criteria: + - 'Issue #3708 done_when 1, verbatim: "ONE rule, enforced at both ends. EITHER autopilot never inherits and runs the real dogfood at T-1 in `$AP/wt` (pre-tag, where a NO-GO costs no public tag), OR R5 accepts the inherited receipt under exactly the conditions autopilot checked (parent GO receipt present, bump diff = version surface only, parent is the release commit''s first parent), and both read the same file. Pick one; don''t keep both."' + - 'done_when 2 AS AMENDED on the issue by its author (comment 2026-09-21T15:37:51Z, "done_when 2 amended (issue author, cop, 2026-09-21), replacing the original, which assumed the inherit option. The option picked is: NEVER inherit."), verbatim: "a case table, wired as a scripts/check_*.sh so guard-tree runs it (the check_t2_preflight_verdict.sh pattern), that drives the real scripts/release/autopilot.sh dogfood step with stubs: a parent GO receipt plus a version-only bump diff still runs dogfood.sh (never inherits); a receipt R5 refuses (NO-GO, other commit, other version, absent) STOPs at T-1 before any tag; a GO receipt passes R5 at T-1, and `check_publish_preflight.sh` R5 at T-4 reads the same receipt file with the same function. Plus the close step: the epic as the milestone''s only open item is closed, then the milestone; any other open item refuses both. A mutant for each."' + - 'done_when 3, verbatim (measured at the NEXT train; this PR says Refs #3708, not Closes): "measured on the 0.70 train: no STOP between TAGGED and CASCADE for this reason"' + - 'The issue body''s close-step finding, verbatim: "Also found the same day (aprender-f0): the `close` step requires the milestone to have 0 open items, but nothing closes the release EPIC, so `close` dies on its own epic. 0.68.2''s was closed by hand. Same fix owner."' + - 'Obligation ADDED on the issue by its author (comment 2026-09-21T15:24:47Z, "Obligation added (issue author, cop, 2026-09-21)"), verbatim: "`prepare_bump.sh --ship` refuses to open the bump PR unless per-host model-ladder receipts for the NEW version are committed on the bump branch: `evidence/dogfood/models//{lambda,gx10}.json`, written by `scripts/model_ladder.sh` with an apr built from the bump tree. 0.68.2 did this by hand (#3498); 0.69.0 missed it, and that made `check_model_ladder` unmeasurable until after the tag. The script may REQUIRE the receipts without producing them; gx10''s is measured over the operator-authorized lambda→gx10 SSH. Case row: missing gx10.json refuses, naming the file; mutant."' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'P0 on the 0.69.1 critical path (cop, aprender-04). Fixtures and stubs only: nothing ran against the live 0.69 train, its state dir, GitHub writes or a publish token. STACKED on PMAT-3699 (branch PMAT-3699-bump-pr-body-keep-open, 0cb1e4bd6), because both change scripts/release/prepare_bump.sh. The judged diff is base 0cb1e4bd6 to this head. SCOPE: scripts/release/autopilot.sh, scripts/check_publish_preflight.sh, scripts/release/prepare_bump.sh, scripts/check_release_bump_pr_body.sh (extended), the new scripts/check_release_autopilot_dogfood_close.sh, and this fragment. PICK (done_when 1 says pick one): autopilot NEVER inherits. The parent''s T-2 GO is at the OLD version, so rows keyed on the version (check_model_ladder) were never measured at the release version. And the T-4 recovery ran the same ~35 min dogfood anyway, after the tag was public. The inherit branch is DELETED, not flagged off, so there is no second rule to keep in sync. HOW EACH IS MET. (1) The dogfood step runs `scripts/dogfood.sh --phase pre-publish` in $AP/wt (the release worktree), then `check_publish_preflight.sh --receipt-only`. That is a new mode running R2 plus R5 only (R3 cannot hold before the tag). R5 is now ONE function, rule_r5(), which the full gate calls at T-4 and --receipt-only calls at T-1, both on the newest $AP/wt/.dogfood/receipt-*.json: the same file and the same function. A refusal is `STOP T-1 R5 refused …`, before the tag step. (2) The case table is scripts/check_release_autopilot_dogfood_close.sh. It is a scripts/check_*.sh because guard_tree.sh''s universe is the flat `git ls-files ''scripts/check_*.sh''`, so a table living only in scripts/release/ would run nowhere (the check_t2_preflight_verdict.sh pattern). It drives the REAL autopilot.sh through its own from/to steps (`dogfood dogfood`, `close close`). The fixture: a local bare origin whose main holds a parent (9.9.8) and a bump touching only Cargo.toml and CHANGELOG.md (9.9.9), a T-2 GO receipt for the parent (exactly the shape the old code inherited on), a real copy of check_publish_preflight.sh, and stubs for gh, cargo metadata and dogfood.sh. ROWS: never-inherits (dogfood.sh RUNS, no dogfood-inherited.receipt, "DOGFOOD GO at (R5 holds at T-1)"); t4-agrees-go (after tagging, the FULL gate prints "ok R5 dogfood receipt receipt-….json: GO for at 9.9.9" for the receipt T-1 accepted); nogo-stops; t1-r5-version (a receipt for 9.9.8 on a 9.9.9 cut STOPs at T-1, and the T-4 gate''s R5 refuses the same receipt, so the two ends agree on refusal too); t1-r5-commit (a receipt naming the parent STOPs at T-1); t1-r5-absent (the dogfood exits 0 and writes no receipt: STOPs at T-1); close-epic-last; close-other-open. MUTANTS, one per claim ("A mutant for each"), run on every bare run, each killed: inherit (the pre-#3708 step verbatim) -> "dogfood.sh never ran: the parent GO was inherited"; drop-nogo-stop -> "it stopped, but not on the NO-GO" (T-1 R5 caught it instead: defence in depth, but the NO-GO row still names the line); drop-t1-r5, run against each of t1-r5-version/-commit/-absent -> "autopilot passed T-1 with a receipt R5 refuses (version|commit|absent)"; t1-reads-another-file (--receipt-only pointed at a receipt dir the T-4 gate does not read) -> never-inherits "STOP T-1 R5 refused", so "the same file" is load-bearing; t1-skips-rule-r5 (--receipt-only no longer calls rule_r5) -> t1-r5-version passes a 9.9.8 receipt, so "the same function" is load-bearing; drop-epic-close -> "STOP milestone 9.9.9 still has 1 open item(s) after the epic"; drop-others-check -> "the epic was closed while #9010 is open". check_publish_preflight.sh --selftest (run by ci.yml:1978) gains 6 --receipt-only rows: an untagged tree with a GO receipt passes (the full gate refuses that tree on R3); NO-GO, stale commit, other version, absent, and a disallowed deferral each refuse with "FAIL R5". (3) is measured at the next train; it cannot be met by this PR, hence Refs. CLOSE STEP: it lists the milestone''s open items EXCEPT the epic. Any remaining one is a STOP naming them, closing neither. Otherwise it closes the epic if it is OPEN, so a re-run after a failure is idempotent, then requires open_issues == 0 and PATCHes the milestone closed. OBLIGATION: `prepare_bump.sh --ship` runs `bash scripts/check_model_ladder.sh --version "$V"` in the bump tree. That is the same judge the dogfood''s check_model_ladder row runs. Its FAIL lines go to stderr, and it refuses before the cargo checks, the commit, the push and `gh pr create`. It also refuses receipts that are present but gitignored (`git ls-files --others --ignored --exclude-standard -- evidence/dogfood/models/$V`), which `git add -A` would silently leave out. check_release_bump_pr_body.sh gives every fixture green receipts, a real copy of check_model_ladder.sh and a MINIMAL fixture ladder (the two required hosts, lambda and gx10, and one rung), so a rung added to the real ladder cannot break this table. New rows: ladder-missing-gx10 (refuses, naming "evidence/dogfood/models/9.9.9/gx10.json"; no push, no PR) and ladder-ignored. New mutants: drop-ladder (judge replaced by `true`) -> "exited 0 (ladder=no-gx10)"; drop-ignored -> "exited 0 (ladder=ignored)". MEASURED at this commit: `bash scripts/check_release_autopilot_dogfood_close.sh` rc 0, "PASS 17 row(s)" (8 behaviours, 9 mutants); `bash scripts/check_release_bump_pr_body.sh` rc 0, "PASS 12 row(s)"; `bash scripts/check_publish_preflight.sh --selftest` rc 0, "25/25 rows"; `bash scripts/check_model_ladder.sh --version 0.68.2` rc 0 on the real ladder and receipts (the judge the gate calls is live); bashrs lint on the 5 changed scripts: 0 errors each; check_release_scripts_derive_identity.sh PASS. GUARD_TREE (`bash scripts/guard_tree.sh --no-cargo`) at the first cut of this commit: "77 checks, 2 failed". check_guards_are_wired: the new table was UNWIRED, because a comment said "cargo metadata" and guard_tree''s textual `(^|[^a-z_-])cargo ` test moved it out of the --no-cargo set; the table never runs cargo (it stubs the metadata call), so the comment was reworded. check_no_pipe_into_grep_q: two `printf | grep -q` sites in the new table (76 vs ceiling 74), now here-strings. Both guards pass after the fix (grep-q "measured 74", guards_are_wired "PASS (ratcheted)"), and `guard_tree.sh --list --no-cargo` lists the table. Full re-run at 3a0513d35 (11-row table): "78 checks, 0 failed", with "PASS scripts/check_release_autopilot_dogfood_close.sh [run]". After the table grew to 17 rows: check_no_pipe_into_grep_q, check_guards_are_wired, and check_bashrs_gate ("PASS 363 file(s) linted … 0 SEC/DET/IDEM errors") re-run, all rc 0. PyYAML (needed by check_model_ladder.sh) is present in guard-tree: check_roadmap_ids_unique.sh and check_roadmap_completion_is_cited.sh already hard-fail without it, and they are green there.' +- id: PMAT-3711 + github_issue: 3711 + item_type: task + title: 'apr qa golden_output: a GPU golden-generation ERROR is reported as a SKIP (note_gpu_golden_skip) — ''GPU broken'' passes the gate; the Q4_K CUDA rule can''t be proven while it does' + status: in_progress + priority: critical + assigned_to: aprender-0e + created: 2026-09-21T15:55:00Z + updated: 2026-09-21T15:55:00Z + spec: null + acceptance_criteria: + - 'Issue #3711 done_when 1, verbatim: "a GPU golden generation error on a host that HAS a CUDA device and a `--features cuda` build is a **FAIL** naming the error, never a skip. SKIP stays only for \"no GPU on this host / no cuda feature\", and it names which."' + - 'done_when 2, verbatim: "case rows: GPU error gives FAIL; no-device gives SKIP-with-reason; GPU wrong answer gives FAIL; GPU right answer gives PASS. Plus a mutant (route the error back to skip and it goes RED)"' + - 'done_when 3, verbatim: "the Q4_K sweep and `scripts/model_ladder.sh` read the new verdict. Re-measure lambda + gx10 with the 0.69.1 binary, and no model is GREEN whose GPU leg errored"' + - 'Cop ruling (aprender-04 to aprender-0e, 2026-09-21), verbatim: "FOLD the sibling in: `run_golden_output_gate_runtime` saying \"GPU hybrid forward\" on a host with no device is the same gate labelling a run by intent. The pass message must name the backend that actually ran (a measured signal, e.g. the device the dispatch reported), plus a case row for cuda-feature-no-device. Same PR, same receipt."' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'SCOPE: crates/apr-cli/src/commands/output_verification.rs, golden_output.rs, qa_gguf.rs (one line: golden_gate_for passes cpu_only), and this fragment. THE DEFECT IS WORSE THAN THE TITLE. On main, a CUDA init or GPU generation error in validate_gpu_golden_output went to note_gpu_golden_skip (a verbose-only println) and returned Ok(None); the case then judged only the CPU answer and the gate said PASSED, "3 golden test cases passed", not SKIP. Sibling (cop ruling, folded in): run_golden_output_gate_runtime labelled every cuda build "GPU hybrid forward, #3090" and ignored InferenceResult::used_gpu, and the qwen35 GPU dispatch falls back to the CPU on ANY GPU failure (forward_qwen35::run_qwen35_generate_dispatch), so a broken GPU passed on the CPU''s answer with a GPU label. HOW IT IS MET. GpuGoldenLeg {Passed, WrongAnswer, Errored, NotRun(why)}: judge() maps an Err (CUDA init on device 0, or GPU generation) to Errored, and failure() makes Errored a gate FAIL naming the error ("... a broken GPU, not a skip (#3711): "); WrongAnswer is the existing "GPU output failed (CPU passed)" FAIL. gpu_golden_not_run(cuda_feature, device, gguf) is the ONLY source of a skip and names which: "this build has no cuda feature" / "no CUDA device on this host" / "the dense GPU leg judges GGUF only"; the hybrid fail-safe arm is NotRun naming the runtime rung. The pass message names the leg: "(GPU leg judged on CUDA device 0)" or "(GPU leg SKIPPED: )". Runtime rung: golden_output_runtime returns (text, used_gpu); runtime_golden_backend(used_gpu, gpu_not_run) names the backend the dispatch REPORTED, and fails when the GPU should have served (cuda build + device + an architecture the GPU runs, i.e. not cpu_only) and the dispatch reported CPU. cuda_device_present() is one probe for both rungs. CASE ROWS (crates/apr-cli golden_output_tests, cargo test -p apr-cli --lib golden_output_tests: 14 passed, 10 new): GPU generation error -> FAIL naming CUDA_ERROR_ILLEGAL_ADDRESS; CUDA init error -> FAIL naming CUDA_ERROR_OUT_OF_MEMORY; GPU wrong answer -> FAIL; GPU right answer (plain and with a think block) -> PASS, judged; no device -> SKIP naming it, not a failure; each skip names which and a cuda host+GGUF starts the leg; runtime: cuda build + no device -> labelled CPU, never GPU; runtime GPU fallback on a cuda host -> FAIL; runtime GPU served -> labelled GPU from the dispatch; architecture the GPU declines -> CPU pass saying why. MUTANTS, each RED: the error routed back to skip (Err -> NotRun) fails 2 rows (generation error, init error); Errored mapped to no failure fails the same 2; the runtime fallback labelled by intent ("GPU hybrid forward, #3090") fails runtime_gpu_fallback_on_a_cuda_host_fails_the_gate; a no-device run labelled GPU fails 2 runtime rows. LIVE, RTX 4090 sm_89, apr 0.69.0 built from this branch with --features cuda, apr qa --json --offline with the perf/parity gates skipped (the ladder''s flags): qwen2.5-1.5b-instruct-q4_k_m rc 0 "3 golden test cases passed (GPU leg judged on CUDA device 0)"; the same with CUDA_VISIBLE_DEVICES= rc 0 "... (GPU leg SKIPPED: no CUDA device on this host)" [main said "3 golden test cases passed"]; Qwen3.5-0.8B-Q4_K_M rc 0 "... through the runtime entry point (served by GPU: the dispatch reported used_gpu=true)"; the same with no device rc 0 "served by CPU: the dispatch reported used_gpu=false, and the GPU was not expected (no CUDA device on this host)" [main, same run: "(GPU hybrid forward, #3090)" -- the label-by-intent, measured]; and ONE RUN under GPU memory contention from another session: Qwen3.5-0.8B rc 5 FAIL "the GPU should have served this model ... fell back ... A broken GPU, not a pass (#3711)" with stderr "GPU (CUDA) qwen35 path rejected, falling back to CPU: ... CUDA_ERROR_OUT_OF_MEMORY" -- exactly the run main would have passed as GPU. FOUND, NOT CAUSED HERE: qwen2.5-coder-0.5b-instruct-q4_k_m on the RTX 4090 fails the golden gate on BOTH main and this branch, identically: "GPU output failed (CPU passed): golden_output_gpu: gibberish (fragment \"```\\n\" repeats 3+ times)". Reported to the cop for the 0.69.1 Q4_K CUDA rule. DONE_WHEN 3: scripts/model_ladder.sh (qa_row gate()) and scripts/check_model_ladder.sh both require golden_output passed and not skipped, so an Errored GPU leg (passed:false) turns the rung RED with no ladder change; the red-golden case fixture already pins that path. The re-measure of lambda + gx10 with the 0.69.1 binary is the train''s T-2 step and is NOT done here -- this PR is Refs #3711, not Closes. clippy -p apr-cli --lib -D warnings (default features) rc 0; --features cuda: apr-cli has no clippy findings (the -D warnings run stops in aprender-compute on a pre-existing unused GemmOp import, same on main). cargo fmt --all -- --check rc 0.' +- id: PMAT-3712 + github_issue: 3712 + item_type: task + title: Model gate universe = each host's measured Q4_K inventory; the gate refuses an optional Q4_K rung (the contract's last one flips in the 0.69.1 fold, per the done_when 1 amendment); skip/fallback/rc!=0 RED; cells = verb x thinking x context rung + status: in_progress + priority: critical + assigned_to: null + created: '2026-09-21T00:00:00Z' + updated: '2026-09-21T00:00:00Z' + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'ISSUE AMENDMENT (#3712 comment by the issue author, quoted verbatim): "done_when 1 amended (issue author, cop aprender-04, 2026-09-21 16:56Z): the guard that refuses `required: false` on a Q4_K rung (case row + mutant) is met by #3721. The contract''s own `qwen3-8b-q4km` rung flips to `required: true` in the 0.69.1 fold, together with aprender-fd''s qwen3-8b fix and a committed green lambda receipt. Flipping it earlier would turn `pv lint contracts/` red on every PR, because the armed ladder-green shape reads the committed 0.68.2 lambda receipt, in which qwen3-8b is red. This changes only the order of the work, not the bar: 0.69.1 does not tag until qwen3-8b is `required: true` and green on both lambda and gx10." ISSUE AMENDMENT 2 (#3712 comment 5764495191 by the issue author, quoted verbatim; lanes judge the cells scope against it): "done_when 5 added (issue author, cop aprender-04, 2026-09-21 17:12Z). Operator, verbatim, 2026-09-21: "lets ensure this release has MORE than enough tokens for our needs (overdo it), and our verbs are dogfooded, i.e chat with and without thinking, ditto run, ditto code, etc," - [ ] The cells matrix. A cell is (Q4_K model, required host, verb ∈ {run, chat, serve, code}, thinking mode derived from the model''s chat template, context rung). Rungs come from `evidence/release/context-rungs.json` up to the model''s declared `context_length`, which is read from the GGUF. The long rungs are owed by qwen35 (always the full set through the declared length) plus one representative per other arch, named in the ladder contract and echoed in the receipt (issue author''s ruling). - [ ] What each cell must do. Where the cell fits the host''s total GPU memory by the declared arithmetic, it must pass on CUDA. Where it doesn''t fit, it must be an honest pre-load refusal naming the arithmetic, never a CPU fallback (operator "a", #3710). - [ ] Coverage. Every rung must pass on at least one required host. The operator''s sentence is the requirement. The cell definition above is the issue author''s reading of it, so a lane judging scope judges against this comment. This is not unrequested scope." ACCEPTANCE (hand-entered from gh#3712; this row = done_when 1 + 2, the GATE side; cop assignment 2026-09-21: worker B). Issue done_when 1, verbatim: "Universe = measured inventory, not a list. The release gate derives the model set from what''s ON each required host (every `*Q4_K*` GGUF/APR under the declared models dir on lambda AND gx10), unioned with the ladder. A model present on a host but missing from the gate''s run is a FAIL naming it. The ladder has no `required: false` for any Q4_K rung; a guard refuses the key on a Q4_K rung (case row + mutant)." Issue done_when 2, verbatim: "Every (model, host) cell is GREEN on CUDA: capability_match passed (not skipped), golden_output passed (not skipped; #3711), `apr run --gpu` rc 0 with no fallback line. One red cell = NO-GO. There is no known, optional or pre-existing exemption, and no threshold like >= N%." WHAT THIS ROW DOES: (a) contracts/model-capability-ladder-v1.yaml gains `ladder.inventory` {dirs, patterns (case-insensitive *q4_k*/*q4k* .gguf/.apr), backends [cuda]}; (b) scripts/model_ladder.sh measures ladder UNION the host''s inventory (every match, depth 1), judges each inventory model on cuda with the SAME measure() as a rung, and writes receipt schema apr-model-ladder-receipt/v2 carrying `inventory` [{file, sha256, bytes}], `file` per row, and `apr_sha` (full 40-hex, for #3715); (c) scripts/check_model_ladder.sh FAILs: `required` not true on a Q4_K rung; a Q4_K rung that does not claim cuda; a ladder with no inventory; a receipt that is not v2 or has no inventory; an EMPTY inventory; an inventory file with no present row (MISSING from the run, named); an inventory-only model not green on cuda (skip, fallback, rc != 0 are RED); (d) case table grows 18 -> 26 (every case red for exactly its own reason, one FAIL line each except the two-host cases), plus 3 self-mutants each killed by its case (q4k-required-false, q4k-without-cuda, inventory-missing); --case with no such case is now RED, and the root is derived from the script path, not git rev-parse (#3581). WHAT IT DOES NOT DO (cop ruling 2026-09-21): qwen3-8b-q4km stays `required: false` in the contract, and the gate refuses that key at T-2, so the release cannot ship on it. Flipping it here would turn pv lint red on EVERY PR: the armed ladder-green shape reads the committed 0.68.2 lambda receipt (golden_output: Empty output), measured rc 0 -> 1 with only that flip. The flip folds into the 0.69.1 batch with the qwen3-8b fix and a committed green lambda receipt. So done_when 1''s `no required: false` clause is NOT met by this row: Refs, not Closes. Done_when 2''s cells turn green only through the model fixes under EPIC #3710; done_when 3 and 4 are aprender-f0''s (#3708). cells[] per verb x context (the widened bar, #3715 proposal) ships with the cop''s widened-bar delta, not here. WHERE THE GATE RUNS (so its rc=1 on the real contract is the release NO-GO, not a PR red): check_model_ladder.sh is declared ONLY in Cargo.toml [package.metadata.dogfood] gates (line 612, the T-2 pre-publish dogfood) and is listed in scripts/unwired_guards_baseline.txt (line 12): no PR workflow runs it, and guard_tree skips it (unwired-baseline). pv lint is a different tool that never runs this script; it reads the contract and PASSES with qwen3-8b at required: false. Measured on this head: guard_tree --no-cargo 0 failed, pv lint contracts/ PASS, cargo test -p aprender-contracts --lib 0 failed. THE GPU LOCK (cop ruling 2026-09-21, after a gx10 global OOM at 15:56:08Z killed CI containers): every apr call in model_ladder.sh goes through apr_locked = flock -E 75 -w ${MODEL_LADDER_LOCK_WAIT:-1800} /tmp/apr-gpu.lock choom -n 1000 --; a lock still held after the wait is an ENV decline (exit 2) naming the holder pid from /proc/locks, never a hang and never a model verdict. T-1 wraps the script in choom only (a second flock outside would deadlock). check_model_ladder.sh audits it statically in the REAL run (a raw "$APR" call is RED) and behaviourally in --self-test (fake apr via --lock-probe: lock held + oom 1000; a held lock declines naming the pid), with four producer mutants each killed: raw-apr-call, no-lock, no-choom, unbounded. FALSIFY-MCL-015. ROW B1 (the judge side of cells; stacked on row A; operator bar raise 2026-09-21: "lets ensure this release has MORE than enough tokens for our needs (overdo it), and our verbs are dogfooded, i.e chat with and without thinking, ditto run, ditto code, etc,"). A cell is (model, host, verb, thinking, context rung). contracts/model-capability-ladder-v1.yaml gains `ladder.cells` {verbs [run, chat, serve, code], long_rungs_for {families [qwen35], representatives: one file per other arch}}. The RUNGS are deliberately NOT in the contract: they live in evidence/release/context-rungs.json (apr-release-context-rungs/v1, landing in #3715), one declaration shared with pv; consumer-max = max over consumers[].max_prompt_tokens. The judge (scripts/lib/model_ladder_cells.py, called from check_model_ladder.sh) derives the owed set from the MEASURED inventory: short rungs for every model up to its context_length, long rungs for qwen35 and each arch''s representative; thinking modes from the template evidence (enable_thinking -> both; always-open -> on; else off, #3723), never the producer''s claim; fit := weights + kv_bytes_per_token * tokens + workspace <= gpu_mem_total_bytes (operator ''a'', #3710; an unmeasured term keeps the cell owed in full). A fitting cell must pass (cuda, no fallback, rc 0, prompt_tokens >= rung, answer_chars > 0, think_closed when on); a non-fitting cell must be `refused` with required_bytes > the host TOTAL (a co-tenant refusal is RED); every owed cell must pass on >= 1 required host; every arch in any inventory has a representative some required host holds. A missing context-rungs file, a consumer without a number, a missing context_length (#3733) and a receipt with no cells are each a named FAIL, never an empty owed set. Anti-shrink floors vs origin/main: the cells block (block, verbs, long-rung families and representatives) AND the rung file evidence/release/context-rungs.json (its rung ids and consumers; git show origin/main, absent there = bootstrap), because the rungs live in that file, not in the cells block. A `pass` on a cell the declared arithmetic says cannot fit is RED (MCL-INV-008: not fits => refused): the arithmetic decides what is owed, so a pass beyond it proves the arithmetic wrong (#3596). The module itself keeps only REQUIRED hosts'' receipts. Case table 26 -> 47; 10 module mutants each killed by its case. The PRODUCER side (row B2: measuring the cells) is not in this row: it needs #3723 (thinking toggle), #3733 (inspect keys) and #3596 (capacity::plan, the pre-load refusal). Until it lands, the real T-2 run is RED on ''receipt carries no cells'', which is the operator''s bar, not a PR red: check_model_ladder.sh runs only in the release dogfood (Cargo.toml [package.metadata.dogfood]) and is listed in scripts/unwired_guards_baseline.txt. MEASURED (answers a round-3 lane claim that qwen35-family GGUFs report general.architecture = qwen2): on lambda, Qwen3.5-0.8B-Q4_K_M.gguf and Qwen3.5-4B-Q4_K_M.gguf report general.architecture = qwen35 (apr inspect --json, and a direct GGUF v3 header read whose keys are qwen35.block_count, qwen35.context_length 262144, qwen35.full_attention_interval 4, ...), so `families: [qwen35]` matches them by arch. The fixture''s q.gguf is arch qwen35 and owes 16 cells in green-cells, every long rung included; a mutant deleting the families check (family-long) is killed by red-cells-missing-cell. 11 cells mutants.' +- id: PMAT-3714 + github_issue: 3714 + item_type: task + title: 'qwen3moe (Qwen3-30B-A3B, Qwen3-Coder-30B-A3B, Q4_K_M) has NO working CUDA path: apr run --gpu falls back to CPU (rc 14), apr qa emits no gates — blocks 0.69.1 under the all-Q4_K-CUDA rule' + status: in_progress + priority: critical + assigned_to: aprender-eb + created: 2026-09-21T16:40:00Z + updated: 2026-09-21T16:40:00Z + spec: null + acceptance_criteria: + - 'Issue #3714 done_when 1, verbatim: "`apr run --gpu` on both qwen3moe Q4_K_M files runs on CUDA with no fallback on **lambda AND gx10**, and `apr qa` capability_match plus golden_output PASS (not skipped). The 30B-A3B at Q4_K_M (~18 GB) must fit the 4090''s 24 GB with KV, or the refusal names the memory arithmetic, and the operator rules."' + - 'done_when 2, verbatim: "GPU vs CPU parity on the qwen3moe forward (`apr parity` must no longer refuse it as UNMEASURED-TOOL, #3367''s residual) at ≥ 64 positions"' + - 'done_when 3, verbatim: "`apr qa` on qwen3moe emits its gates, never an empty report (an empty gate list is a FAIL of qa itself)"' + - 'done_when 4, verbatim: "both files added as REQUIRED ladder rungs (#3712)"' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'Operator, verbatim (issue body): "you must ensure all models Q4_K CUDA work; the end. on gx10 and lambda-labs". Cop ruling relayed by aprender-04 (operator "yes, to all"): NEW kernels are cuda-oxide first, each with a CPU twin and a per-kernel differential test on sm_89 and sm_121; if oxide cannot express one, say which and why on #3714 before any hand PTX. Gap list, measured on 225b2a9ab cuda builds on both hosts before any code: https://github.com/paiml/aprender/issues/3714#issuecomment-5763628862. The issue is delivered as four rows, each its own PR, each `Refs #3714` until the last. R1 (this PR) = done_when 1 and 3. It adds NO kernel, so the oxide ruling does not apply to it: a device-resident Qwen3MoeCudaModel (gguf/cuda/forward_qwen3_moe_resident.rs) on the #3090 Qwen35CudaModel pattern, built from existing executor kernels (Q4_K/Q6_K/F32 GEMV, experts at base + e*stride in one stacked allocation, SwiGLU, RMSNorm, per-head RMSNorm, NEOX rope, GQA decode attention, residual add, and elementwise_mul_into, an allocation-free wrapper over the existing ElementwiseMul kernel), routing on the host through route_top_k, the one routing rule shared with the CPU layers; wired where the gap list showed CUDA was never tried (infer/inference_result.rs -> infer/qwen3_moe_dispatch.rs) behind the runtime F2 rule, whose CPU reference runs with FP32 activations (quantize::with_fp32_activations, a dedicated rayon pool); the fit check calls realizar::capacity::plan, lifted byte-identical from #3596 (aprender-3e) so one fit computation serves both paths; and qa: a gate that errors is a FAILED row and the report is always written (qa.rs dispatch_gate), qwen3moe routes golden/throughput through the runtime entry point (qa_gguf.rs), and the dense-instrument gates skip naming the MoE placeholder. Chat/serve --gpu (api/cuda_chat_backend.rs) keep the CPU chain in R1: they need a persistent resident model, a named remainder. R2 = done_when 2 (apr parity for qwen3moe at >= 64 positions, plus per-op rows for #3715). R3 = the v2 kernels (device top-k, fused scaled accumulate, expert gather), oxide first. R4 = done_when 4 with aprender-62 (#3712). Files owned by other sessions and not touched: crates/apr-cli/src/commands/golden_output.rs and output_verification.rs (aprender-0e #3711, aprender-fd), cuda/executor/layers/cublas_prefill* (aprender-37).' +- id: PMAT-3715 + github_issue: 3715 + item_type: task + title: 'pv SHACL release-readiness shape: the tag is REFUSED unless every (Q4_K model in host inventory × {lambda,gx10} × {run,chat,serve,code} × consumer-context) cell has a Pass receipt — a missing cell is a violation, never a skip' + status: in_progress + priority: critical + assigned_to: aprender-97 + created: 2026-09-21T15:55:00Z + updated: 2026-09-21T15:55:00Z + spec: null + acceptance_criteria: + - 'Issue #3715 done_when 1, verbatim: "**the evidence graph**: `pv extract` ingests the release receipts (per-host model inventory, ladder and matrix receipts from #3712/#3708, dogfood receipt) as nodes: `:Model` (sha256, quant, arch), `:Host`, `:Verb` (run/chat/serve/code), `:ContextRung` (token counts DERIVED from the consumer-traffic records on #3710, never invented), `:Receipt` (verdict, backend, fallback, apr version plus sha)"' + - 'done_when 2, verbatim: "**the shape** `release-readiness-v1`: focus = every `:Model` in the inventory of every required `:Host`. For each (verb, context rung) exactly one `:Receipt` with `verdict=Pass`, `backend=cuda`, `fallback=false`, `apr_sha = release commit`. A missing, skipped, stale-sha or fallback receipt is a violation naming the cell."' + - 'done_when 3, verbatim: "**armed with a red-turning falsifier**: fixtures where each single cell is missing, skipped, falls back, or is stale, and each one turns the gate RED (the ONT-001 rule: a shape that has never gone red isn''t armed)"' + - 'done_when 4, verbatim: "**wired where the decision is made**: autopilot''s T-1 step and `check_publish_preflight.sh` both run `pv lint --gate shapes --shape release-readiness-v1` on the release commit''s evidence, and a violation STOPs before the tag and refuses at T-4"' + - 'done_when 5, verbatim: "**proof**: on the v0.69.0 evidence the shape reports the actual leaks (qwen3-8b lambda, qwen2.5-coder lambda, qwen3moe both hosts, chat/serve/code cells absent). On 0.69.1 it passes with N/N cells named."' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'KNOWN REMAINDER (cop ruling, verbatim): release_evidence.rs `VERBS` is a hand-coded list; #3745 S2 replaces it with the derived cell set via `Inputs.cells`. 0.69.1 does not tag while it exists. QUORUM: round 3 AGREED at 84289cb7ba38adf96c0a1c5f836eb84ccb8d0646 (gemini-3.1-pro-high, gemini-3.1-pro-low, gpt-oss-120b-medium all PASS; docs/audits/quorum-PMAT-3715.json). Assigned by the cop (aprender-04) to aprender-97 on the 0.69.1 all-hands (EPIC #3710). The receipt FORMAT is shared and was agreed on #3712 before building: with aprender-62 (measuring side: issuecomment-5763332078, -5763540875, -5763596544, memory fields -5763795158) and aprender-f0 (T-1/T-4 wiring, issuecomment-5763344947); kernel-diff with aprender-37/aprender-eb (-5763412455, -5763633743, -5763653200); tokenizer parity on #3726 (-5763745060). SCOPE ADDED ON THE ISSUE by its author (cop), each built: kernel differential per GPU arch (#3715 issuecomment-5763396082); thinking {on,off} x context rungs {4k,8k,20k,60k,consumer-max,declared} (-5763490841, #3710 -5763489958); tokenizer parity per model (#3726 done_when 3); the memory-fit rule, operator decision "a" (#3710 -5763753907); three-state thinking_modes (#3723). WAIVERS: none, cop ruling (c) - a comment-based waiver is forgeable by every agent session (all post as noahgift); the operator-only surface is #3722. DONE HERE: done_when 1 (pv extract --release-* --out ingests inventory, cells, kernel/tokenizer/dogfood receipts as Release/Host/Model/Verb/ContextRung/Cell/CellReceipt/... nodes); done_when 2 (the nine-shape release-readiness-v1 family, armed by --shape); done_when 3 (34 red-turning CLI cases in crates/aprender-contracts-cli/tests/ont_release_readiness.rs, wired as ci/explicit-test-commands.d/450; two mutants caught: skip-as-pass turns 1 red, always-fresh turns 3 red); the pv side of done_when 4 (the invocation and exit contract f0 calls: 0 Pass, 1 Fail naming cells, 2 decline, 3 caller error); the first half of done_when 5 (evidence/release/proof-0.69.0: RED, 795 findings naming qwen3-8b lambda verdict=fail, qwen2.5-coder lambda and qwen3moe both hosts unmeasured/unkeyed, 752 of 768 cells absent, the NO-GO inherited dogfood). NOT DONE HERE (so the PR carries Refs, not Closes): the autopilot T-1 / check_publish_preflight T-4 call sites (aprender-f0, #3717/#3708), and "on 0.69.1 it passes with N/N cells named", which needs the producer (#3712 cells[]) and the model fixes to land. Also fixes a collision that existed independently: receipts.rs refused every schema but apr-model-ladder-receipt/v1 by name, so the first committed v2 receipt would have turned `pv lint --gate shapes` exit 3 on every PR.' +- id: PMAT-3717 + github_issue: 3717 + item_type: task + title: '#3712 done_when 3 (child): the model-matrix gate runs at T-1 on BOTH hosts before any tag, receipts committed in the bump, re-read at T-4 by the same judge' + status: in_progress + priority: critical + assigned_to: aprender-f0 + created: 2026-09-21T15:46:37Z + updated: 2026-09-21T16:30:00Z + spec: null + acceptance_criteria: + - 'Issue #3717 done_when 3 (verbatim from #3712), verbatim: "**It runs BEFORE the tag**, as a T-1 step in `scripts/release/autopilot.sh` on BOTH hosts (gx10 over the operator-authorized lambda→gx10 SSH). A NO-GO stops the train with no tag cut. The per-host receipts are committed in the bump PR (#3708), and `check_publish_preflight.sh` re-reads the same receipts at T-4."' + - 'cop requirement 1, verbatim: "**red-turning tests**: a case table driving the real autopilot `models` step and the T-4 R7 with stubs. An unreachable host, a failed build, a missing receipt, a red receipt, or a judge decline (exit 2) each STOP before the tag (and FAIL at R7). A green pair passes. A mutant per row."' + - 'cop requirement 2 (instrument isolation; its LOCATION clause is replaced by the amendment below), verbatim: "**instrument isolation on gx10**: build in a PER-RELEASE target dir on gx10''s /mnt/nvme-raid0 (e.g. `targets/rel-`), delete the previous release''s dir first (the disk is at 90%), and NEVER `~/src/aprender/target`, a shared cache under an old checkout (the #3600 class: a stale instrument agrees with itself). Before measuring, prove `apr --version` = ` ()` on each host, and record it in the receipt."' + - 'cop requirement 3, verbatim: "the judge is `check_model_ladder.sh --version V --receipts DIR`, the same function at T-1 and T-4 (the frozen interface with #3712''s measuring side)"' + - 'cop requirement 4 (measured on the 0.69.1 train; this PR says Refs #3717), verbatim: "proof on the 0.69.1 train: the autopilot STATUS shows `MODELS GO` on both hosts before `TAGGED`"' + - 'AMENDMENT on the issue (comment 2026-09-21T15:50:22Z), verbatim: "**Instrument-isolation location amended (cop, 2026-09-21), replacing the location clause:** build in a PER-RELEASE target dir on gx10, derived at run time and never a literal in scripts/release/: `$HOME/.cache/aprender-release/rel-` on the remote; delete every other `rel-*` there first; NEVER `~/src/aprender/target` or any dir under it. The rest of the item stands (fresh target, previous dirs deleted, `apr --version` = " ()" proved on each host, and the receipt''s apr_version checked against it). Why: on gx10 /mnt/nvme-raid0 is the same filesystem as / (measured), and check_release_scripts_derive_identity.sh R1 refuses absolute /mnt paths in scripts/release/. Added: refuse up front with a named ENV reason when the remote free space is below the measured size of a fresh cuda release target."' + - 'GPU-SHARING REQUIREMENT added on the issue (comment 2026-09-21T16:09:54Z, the cop''s ruling relayed verbatim), verbatim: "Ruling, as you recommend: **one owner**. The LOCK lives in model_ladder.sh, per apr call (62''s row B), which protects every caller. Your T-1 wrapper runs the ladder under `choom -n 1000 --` ONLY (oom_score_adj is inherited across fork) and takes NO flock. Builds stay outside any lock. Your table asserts "runs under choom -n 1000 and the wrapper takes no flock"; 62''s asserts "every apr call runs under the lock"."' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'P0 on the 0.69.1 release path (cop, aprender-04). This is #3712''s done_when 3, split out so that aprender-62 (done_when 1+2, the measuring side: scripts/model_ladder.sh, scripts/check_model_ladder.sh, the ladder contract) and aprender-f0 do not mint the same fragment. Fixtures and stubs only in CI; nothing here ran against the live train or a publish token. STACKED on PMAT-3708 (branch PMAT-3708-dogfood-one-rule, 629143eeb): the judged diff is base 629143eeb to this head. SCOPE: the new scripts/release/models_t1.sh; scripts/release/autopilot.sh (a new `models` step); scripts/check_publish_preflight.sh (a new R7); the new scripts/check_release_models_t1.sh; and this fragment. "The per-host receipts are committed in the bump PR (#3708)" is already delivered by #3708: prepare_bump.sh --ship refuses unless check_model_ladder.sh --version is green in the bump tree, and refuses gitignored receipts. HOW IT IS MET. (1) BEFORE THE TAG, ON BOTH HOSTS: autopilot STEPS gains `models` between `dogfood` and `tag`. It runs scripts/release/models_t1.sh $AP/models-t1 and STOPs with "T-1 model matrix NO-GO … nothing is tagged" on any non-zero exit. On GO it says "MODELS GO at on lambda and gx10", which is the STATUS line cop requirement 4 asks for before TAGGED. models_t1.sh runs two legs IN PARALLEL: lambda locally in the release worktree, and gx10 over `ssh -o BatchMode=yes gx10 "bash -s"`, the lambda->gx10 SSH the operator authorized. Each leg builds `cargo build --release -p apr-cli --bin apr --features cuda --locked` (binary-release.yml''s command) from the release commit. It then PROVES the binary before measuring (`apr --version` must equal "apr ()"), runs `scripts/model_ladder.sh --host --out ` (the frozen interface), and brings gx10''s receipt back. Each receipt''s existing apr_version field must equal that same line. Then `scripts/check_model_ladder.sh --version --receipts $AP/models-t1` judges both. An unreachable host (ssh rc 255), a failed build, a binary that is not the release, a missing receipt, a red cell and a judge DECLINE (rc 2) are each NO-GO. Nothing is retried, and there is no exemption. (2) INSTRUMENT ISOLATION ON gx10, per the AMENDMENT: a PER-RELEASE dir `$HOME/.cache/aprender-release/rel-`, derived on the remote at run time. It holds a detached worktree at the release commit, and CARGO_TARGET_DIR is /target. Every other rel-* is deleted first, and ~/src/aprender/target is never used (only `git -C ~/src/aprender fetch origin main` and `worktree add` touch that checkout). No host path is a literal in scripts/release/ (check_release_scripts_derive_identity.sh PASS). The worktree is removed after measuring; the target stays for a same-version re-run and is deleted by the next release. DISK: the leg REFUSES up front, as ENV ("MODELS-LEG gx10 ENV: … refused before building", models_t1.sh exit 2), when the filesystem''s free space plus an existing same-version dir is below NEED_KIB = 5,524,629 KiB. MEASURED 2026-09-21 on lambda at 629143eeb with a fresh CARGO_TARGET_DIR: the target is 5,285,126,283 bytes (244 s, nice 19), the binary printed "apr 0.69.0 (629143eeb)", and a worktree checkout is 363,372 KiB. gx10 is aarch64 and was not measured. A read-only probe of gx10 (bash 5.2.21, git 2.43.0): df -Pk reports 116,078,068 KiB free, so it "would-build". (3) T-4 RE-READ, THE SAME JUDGE: check_publish_preflight.sh gains R7, rule_r7(), called by the full gate. It runs `check_model_ladder.sh --version ` in the tagged tree, over the receipts COMMITTED by the bump. rc 0 -> "ok R7"; rc 2 -> "FAIL R7 the model-matrix judge DECLINED (rc 2), and a decline is not a pass"; any other -> "FAIL R7 model matrix NOT green", quoting the judge''s FAIL lines; a missing judge -> "FAIL R7 no model-matrix judge". The seam is PUBLISH_PREFLIGHT_LADDER_JUDGE. The PASS line now ends "dogfood GO, model matrix green". The self-test gains r7_model_matrix_red_refuses, r7_judge_decline_refuses and r7_judge_absent_refuses. Every fixture commits a judge stub that refuses any version but 1.2.3, so all_rules_hold also proves the argument: 28/28. #3715 (the pv SHACL shape, aprender-97) will become the gate of record behind the same call sites. That design is agreed on #3712 (comments 5763316076 and 5763344947): T-1 passes MC, and T-4 passes the measured sha after a `git diff --quiet HEAD -- . '':!evidence''` proof. It is NOT in this diff. RED-TURNING TABLE (cop requirement 1): scripts/check_release_models_t1.sh, a scripts/check_*.sh with no bare cargo token, so guard_tree''s --no-cargo set runs it. It drives the REAL autopilot `models` step, and so the real models_t1.sh, through `autopilot.sh 9.9.9 99 models models`. The fixture: a local bare origin (parent 9.9.8, release 9.9.9); an ssh stub that runs the gx10 script locally under a fake gx10 HOME whose ~/src/aprender sits at the OLD parent with a stale rel-9.9.7 beside it; a build stub that bakes `apr --version` from the tree it ran in; and committed stubs for model_ladder.sh and the judge. T-1 ROWS: green-pair (MODELS GO; gx10 measured by "apr 9.9.9 ()" although its checkout sat at the parent; built into rel-9.9.9, not ~/src/aprender/target; rel-9.9.7 deleted); gx10-unreachable; build-fails; missing-receipt; red-cell; judge-decline; stale-binary; disk-refusal (exit 2, nothing built). T-4 ROWS: rule_r7 EXTRACTED from check_publish_preflight.sh and run on a tagged tree''s committed receipts (cargo-free): r7-green, r7-red, r7-missing (names gx10.json), r7-decline, r7-no-judge. MUTANTS, one per row, each killed: shared-target -> "gx10 did not build into the per-release dir"; no-255-reason, build-ignored, no-receipt-ok -> the STOP no longer names the cause; red-is-go and decline-is-go -> "autopilot exited 0"; no-version-proof -> the pre-measure NOT-THE-RELEASE is gone (the receipt''s apr_version check still stops it, which is defence in depth); no-disk-check -> "autopilot exited 0"; autopilot-no-die -> "autopilot exited 0"; r7-no-version -> "decline: no --version given"; r7-red-is-go and r7-decline-is-go -> "rc=0, want 1"; r7-no-fail-lines -> the refusal no longer names gx10.json; r7-no-judge-ok -> "rc 127", not the no-judge refusal. That the full gate CALLS rule_r7 is proved by the preflight self-test, which needs a Rust-package fixture and runs at ci.yml:1978. Ad hoc wiring mutant (the gate without its rule_r7 call): "BROKE r7_model_matrix_red_refuses / r7_judge_decline_refuses / r7_judge_absent_refuses", 25/28. The table''s first full run caught a fixture bug of mine: the red receipt was written before its env var was exported, so r7-red was RED and its mutant was "killed" for the wrong reason. It was fixed by passing the red host positionally, and the mutant now dies with "rc=0, want 1". ROUND 2 CHANGE (after the round-1 receipt at d00665a7f), the GPU-SHARING requirement: both legs run `choom -n 1000 -- bash scripts/model_ladder.sh …`. oom_score_adj is inherited across fork, so the ladder and every apr it starts are the OOM victim, never the CI pool (the gx10 15:56Z OOM killed 18 CI containers). The wrapper takes NO flock: the lock is model_ladder.sh''s own, per apr call (#3712 row B), and a second flock on /tmp/apr-gpu.lock here would deadlock it. That is the one-owner ruling. Builds run under neither. New row oom-victim: stubs for choom and flock record what wrapped each process, and the row requires "ladder host= oom=1000 flock=0" on both hosts, "build host= oom=none flock=0", and no flock call at all. New mutants: no-choom (gx10''s ladder without choom) -> "gx10 ladder did not run under choom -n 1000 alone: ladder host=gx10 oom=none flock=0"; wrapper-flock (lambda''s ladder under `flock /tmp/apr-gpu.lock choom …`) -> "… ladder host=lambda oom=1000 flock=1". MEASURED at this commit: `bash scripts/check_release_models_t1.sh` rc 0, "PASS 30 row(s)"; `bash scripts/check_publish_preflight.sh --selftest` "28/28 rows"; `bash scripts/check_release_autopilot_dogfood_close.sh` "PASS 17 row(s)" and `bash scripts/check_release_bump_pr_body.sh` "PASS 12 row(s)", both unchanged by the new step; check_bashrs_gate "PASS 365 file(s) … 0 SEC/DET/IDEM errors", after a SEC010 on a `cd /` in the gx10 heredoc was removed; check_guards_are_wired, check_no_pipe_into_grep_q and check_release_scripts_derive_identity all PASS. `bash scripts/guard_tree.sh --no-cargo` at 38f8b5945: "79 checks, 0 failed", with "PASS scripts/check_release_models_t1.sh [run]". Cop requirement 4 (the real 0.69.1 train, MODELS GO on both hosts before TAGGED) is measured on that train, hence Refs #3717.' +- id: PMAT-3718 + github_issue: 3718 + item_type: task + title: 'apr run --json: prompt_tokens + completion_tokens + finish_reason; serve usage and finish_reason never report a cut as a stop (#3718, RAH #3716)' + status: in_progress + priority: high + assigned_to: aprender-a8 + created: 2026-09-21T16:20:00Z + updated: 2026-09-21T16:20:00Z + spec: null + acceptance_criteria: + - 'Issue #3718 done_when 1, verbatim: "`apr run --json` emits `prompt_tokens` (the post-template token count actually fed to the model) and `completion_tokens`, and the numbers match the tokenizer (a case row checks a fixed prompt''s count)"' + - 'done_when 2, verbatim: "the same fields are in `apr serve`''s `/v1/chat/completions` `usage` object (OpenAI shape)"' + - 'done_when 3, verbatim: "a prompt truncated or refused for length says so in the JSON (`truncated: true` or an error), never a silent cut"' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'SCOPE. The three done_when rows quoted above. `prefill_ms` is deliberately NOT emitted by this row. The cop''s lane message asked for it, but it is not in #3718''s done_when, and it is owned elsewhere: aprender-a8 and aprender-3e agreed one definition (wall-clock over the forward passes on the post-template prompt, up to the first token''s logits; load, h2d, the F2 validate and tokenization excluded; null, never 0, where a path does not split prefill). It rides #3606''s StageTimings and 3e''s #3596 timer (`run_qwen35_generate_dispatch_timed`, not on main). Wiring it into this JSON is a follow-up once those land. RUN (done_when 1, 3). New `realizar::infer::run_inference_report(config) -> (InferenceResult, RunReport)`; `run_inference` is a thin wrapper over it. It is a separate entry point so that none of the ~75 `InferenceResult` literals change. `RunReport { finish_reason, context_length }` is None on a path that does not report it (APR, SafeTensors), never a default. The GGUF path computes it where the stop set and the budget are known. `FinishReason::from_decode(generated, stop, budget)`: a last token in the stop set is Stop; otherwise a run that filled its budget is Length; a shorter run ended on a stop token its loop consumed. This rule holds for both loop shapes, traced: the qwen35 CPU/GPU, MoE and wgpu loops PUSH the stop token, the dense CPU (`generate_with_cache`) and CUDA (`decode_blocking`) loops break BEFORE pushing, and every loop''s only other non-error exit is its budget. `decode_budget` clamps to `context_length - prompt` only on the dense CPU loop, the one loop that does (`effective_max_tokens`). `FinishReason` is declared once, in `infer::run_report` (not behind the `server` feature); `api::types::FinishReason` is now a re-export. apr-cli: `RunUsage { prompt_tokens, completion_tokens, finish_reason, context_length }` on `RunResult`, emitted by `build_final_json`, so it appears in both `--json` and the `--stream` final event. `prompt_tokens` = `input_token_count`, the post-chat-template count including BOS that `prepare_tokens` fed the model. `completion_tokens` is the engine count, never the word-count stand-in `tokens_generated` falls back to. No path truncates a prompt (traced: `prepare_tokens` has no truncation). An over-long prompt is REFUSED (ContextLimitExceeded -> error exit), which is done_when 3''s "or an error"; the completion-side cut is now `finish_reason: length`, where before it was silent. SERVE (done_when 2, 3). `/v1/chat/completions` `usage` was already OpenAI-shaped with the post-template count on the realizar backends (`tokenize_chat_prompt`: template, encode, `len`). Three silent cuts are fixed. (a) The dense CPU backend (`try_quantized_backend`) judged finish against the REQUESTED max_tokens after `effective_max_tokens` had clamped the loop to the context room, so a context-clamped cut said "stop"; it is now judged against the budget the loop ran with, both streaming and not. (b) A prompt that cannot fit was a 500 (non-stream) or a 200 SSE carrying an error event that still ended "stop". It is now a 400 before generation on both, via the existing `generation_error_status`, whose doc already said callers map it to 400. (c) The APR CPU fallback (apr-cli handler_apr_cpu_completion.rs) hardcoded "stop" while capping max_tokens at 4096. It now uses `from_decode` against that cap with the loop''s real stop set (token 0, pushed; `is_eos_token`). Its `run_apr_cpu_inference` also returned the PROMPT as the completion when nothing was generated (`else { &output_tokens[..] }`); that now yields empty. MEASURED on lambda, CPU, Qwen3.5-0.8B-Q4_K_M, pinned `apr 0.69.0 (3fadee114)` via scripts/apr_bin.sh. `apr run -i <"What is 2+2? Answer with one number."> --chat --json`: prompt_tokens 24, context_length 262144. The same templated string through llama.cpp 41fc758 `llama-tokenize --ids` gives 24 ids, identical id-for-id to apr''s `--verbose` encode (with and without llama.cpp''s BOS policy). That is done_when 1''s case row against an independent tokenizer. max-tokens 4 and 1024: completion 2, finish stop (the model ends on EOS). A 20-line-poem prompt at max-tokens 6: completion 6, finish length. DONE_WHEN 1 CASE ROW, automated (added after the round-2 quorum FAIL, which correctly said a manual measurement is not a case row): infer::run_report::a_fixed_text_prompt_counts_the_tokens_the_tokenizer_feeds builds the pygmy GGUF with a SentencePiece vocabulary (` ▁Hello ▁world !` + filler; bos 1, eos 2) through the new `test_factory::build_executable_pygmy_gguf_with` metadata hook, runs the TEXT prompt "Hello world!" through `run_inference_report` (the `apr run --prompt` path: prepare_tokens_gguf, the GGUF tokenizer, BOS policy) and asserts the fed ids are [1, 3, 4, 5] and input_token_count (which becomes prompt_tokens) is 4. The expectation is derived by hand from the vocabulary, not from apr''s encoder. Mutant: prepare_tokens_gguf reports tokens.len()-1 -> the row goes RED. The post-template count on a real model is the llama.cpp row above (24 == 24, id for id). TESTS. infer::run_report: a case table over both loop shapes, the clamped-cut pin, budget arithmetic, and four rows through `run_inference_report` on the pygmy GGUF (context 32): a context-clamped cut is Length with 28 = 32 - 4 tokens, a max_tokens cut is Length, a stop token under budget is Stop (0 tokens, dense loop consumed it), and an over-long prompt is refused naming both lengths. api::tests::usage_finish_3718 runs through the real router on a quantized AppState: clamped cut -> length with usage prompt+completion == context, clamped stream -> terminal chunk length, prompt > context -> 400 on stream and non-stream, stop under budget -> stop (both), unclamped -> cut at the request budget. apr-cli run_tests_usage_3718: JSON carries the four fields, null (not 0 or "stop") when unreported, stream final event carries them. MUTANTS, each run and each RED: serve clamp reverted (2 red), 400 reverted to the old path (1), run-report clamp off (1), from_generation always Length (4), never Length (7). SUITES at 3fadee114 + rustfmt: `cargo test -p aprender-serve --lib` 15913 passed; `cargo test -p apr-cli --lib` 7301 passed; `cargo test -p aprender-contracts --lib` 1684 passed; clippy -D warnings on aprender-serve and apr-cli clean; fmt clean. KNOWN, NOT CHANGED. completion_tokens counts the pushed stop token on the qwen35/MoE/wgpu loops and not on the dense loops, because that is what each loop returns (measured: qwen35 `tokens: [17, 248046]`, completion 2). The CUDA backends were not exercised on hardware in this row: the report logic is backend-agnostic and clamps only on the dense CPU loop. Streaming chat does not apply stop STRINGS on the true-streaming path; that is pre-existing and not a length cut. Found while measuring and routed separately: `--prompt P --chat` double-templates (24 -> 56 prompt_tokens), which is #3743 = #3672 in batch-1.' +- id: PMAT-3724 + github_issue: 3724 + item_type: task + title: 'qwen3-8b-q4km golden_output ''Empty output'' on lambda: the gate ran Qwen3 in thinking mode + no production path uses (0.69.0 stopper)' + status: in_progress + priority: critical + assigned_to: aprender-c7 + created: 2026-09-22 07:05:40+00:00 + updated: 2026-09-22 07:05:40+00:00 + spec: null + acceptance_criteria: + - 'Issue #3724 done_when 1, verbatim: "qwen3-8b-q4km produces correct output on lambda CUDA, and `apr + qa` (ladder flags) passes on **lambda AND gx10**. The five Qwen3.5 Q4_K_M rungs (0.8b/2b/4b/9b/27b) + stay green on both."' + - 'Issue #3724 done_when 2, verbatim: "the golden gate builds its prompts with the SAME detector and + template production uses, keyed on `general.architecture`. Every other architecture keeps byte-identical + ChatML, pinned by a test. No check is relaxed."' + - 'Issue #3724 done_when 3, verbatim: "a thinking-capable model is judged in BOTH modes: OFF (production + no-think prompt, answer correct) and ON (think block closes and the answer after it is correct, with + a budget that overdoes it). A block that doesn''t close is REPORTED by name with the budget ("think + block unclosed within N tokens"), never stripped to an empty answer."' + - 'Issue #3724 done_when 4, verbatim: "`apr chat`, `apr serve` and `apr run --chat` on qwen3-8b on lambda + CUDA are reported."' + - 'Issue #3724 done_when 5, verbatim: "the x86-vs-aarch64 think-length difference (545 vs < 512) is + recorded on the row."' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'ROOT: the gate hardcoded three ChatML prompts, which leaves Qwen3 in thinking mode - a mode + no production path uses, because realizar''s detector gives every qwen3* except qwen3moe the Qwen3NoThink + template (PMAT-181). On x86 the greedy reasoning for "What is 2+2?" ran the whole 512-token budget + (527 tokens, 15 of prompt) and was still inside ; strip_thinking_blocks truncated at the unclosed + tag, so the answer was "" and verify_output reported "Empty output". aarch64 closes the same block + under 512. SAME CODE, DIFFERENT TOKEN COUNTS - which is why a prompt defect presented as a host defect + (done_when 5). FIX, and no budget was raised: (1) golden_prompt_for renders through the SAME detector + production uses, keyed on general.architecture; every ChatML-mapped architecture is byte-identical + to the old hardcoded strings, pinned by chatml_architectures_render_the_legacy_prompt_byte_for_byte, + which classifies by ASKING the detector rather than by a hand-written list. Cop ruled option (A), + the detector for every architecture, 2026-09-22. (2) split_thinking_blocks -> ThinkingSplit{Answer,Unclosed} + replaces the truncating strip on all three legs (CPU, CUDA, runtime); an unclosed block is reported + as "think block unclosed within N tokens" with the chars generated. (3) thinking_on_case judges the + other mode at 2048 tokens, with the suppression detected by READING production''s rendered prompt + (without_thinking_prefill) rather than matching a template name, so #3755''s replacement template + is followed rather than bypassed. MEASURED at 3ebb1c61e on both hosts: model_ladder.sh 8/8 green, + red 0, on lambda (x86_64, RTX 4090 sm_89) and gx10 (aarch64, GB10 cc 12.1); qwen3-8b-q4km green on + the host where it failed. Falsification on a no-cuda build, zero GPU time: reverting the prompt alone + is RED naming the unclosed block; reverting both changes reproduces the issue''s exact "Empty output". + done_when 4 REPORTED, and it is the interesting half: apr serve, apr run --chat and (now) the golden + gate all take realizar''s detector and get Qwen3NoThink; apr chat takes aprender-core''s detector + (crates/apr-cli/src/commands/chat.rs:34), whose TemplateFormat has seven variants and NO Qwen3NoThink + at all, so no-think is unrepresentable there and the model thinks. Measured: apr chat on Qwen3-1.7B + prints "Detected ChatML chat template" and answers "Okay, the user is asking...". Thinking-on + therefore remains a reachable production mode; #3724 does not delete that cell. The unification is + #3801''s remedy, routed separately by the cop.' +- id: PMAT-3726 + github_issue: 3726 + item_type: task + title: 'apr''s byte-level BPE tokenizer is non-canonical (greedy longest-match, no pre-tokenizer, no merge ranks): every GGUF prompt reaches the model as ids it never saw; corrupts copy tasks (#3693) and every non-ASCII user' + status: in_progress + priority: critical + assigned_to: aprender-c3 + created: 2026-09-21T16:20:00Z + updated: 2026-09-21T17:25:00Z + spec: null + acceptance_criteria: + - 'Issue #3726 done_when 1, verbatim: "apr''s token ids are **identical to llama.cpp''s** (the pinned comparator, `llama-tokenize` / `--verbose-prompt`) for every Q4_K model family in the inventory (qwen35, qwen3, qwen2 / qwen2.5, qwen3moe) on a corpus of real consumer briefs (#3716), source code, and non-ASCII sets (CJK, accented Latin, emoji, box-drawing, zero-width chars), and the round-trip decode(encode(x)) == x"' + - 'done_when 2, verbatim: "the byte-level BPE byte→unicode map (GPT-2 bytes_to_unicode) and the pre-tokenizer regex match the model''s `tokenizer.ggml.pre` / HF definition. Root cause named on the issue."' + - 'done_when 3, verbatim: "a **tokenizer-parity gate** (a scripts/check_*.sh, wired) that fails on any id mismatch against the pinned llama.cpp, plus a mutant (reintroduce the id-0 byte fallback and it goes RED). It becomes a required cell per model in the release shape (#3715)."' + - 'done_when 4, verbatim: "re-measure #3693 after the fix: if the corruption disappears, #3693 closes as this; if not, the remainder stays on #3693"' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'Filed by the cop (aprender-04) from infra-c8''s measurement; owner aprender-c3, who reached the same root cause from the forward side (#3693). ROOT CAUSE: `GGUFModel::encode` (crates/aprender-serve/src/gguf/token.rs) was documented and implemented as greedy longest-match over each whole segment, with no pre-tokenizer and no merge ranks. `prepare_tokens_gguf` (the `apr run` path), `apr parity` and serve''s batch path all call it. Measured on apr 0.69.0 (225b2a9ab) against the pinned llama-tokenize (d1d3c3396) for "The quorum forbids it; cited refutes!!!": apr gave `Ġquo|rum Ġforbid|s … Ġrefute|s`, llama.cpp `Ġqu|orum Ġforb|ids … Ġref|utes`. On arbiter''s r891 prefix apr gave 253 ids and llama.cpp 248, with 16 differing spans. The lane''s "quoorum" is `Ġquo` (apr''s odd split of the prompt) joined to the canonical continuation `orum`. FIX (this row): new crates/aprender-serve/src/gguf/byte_level_bpe.rs, a port of llama.cpp''s reference: `unicode_regex_split_custom_qwen2`/`_qwen35` line for line (selected by tokenizer.ggml.pre; the fleet inventory has exactly these two: qwen2 covers qwen2/qwen2.5/qwen3/qwen3moe, qwen35 covers qwen35/qwen35moe), GPT-2 bytes_to_unicode, ranked merges from tokenizer.ggml.merges with a priority queue (lowest rank, then leftmost, as llm_tokenizer_bpe_session), special tokens by token_type CONTROL/USER_DEFINED/UNKNOWN longest first (tokenizer_st_partition). `GGUFModel::encode` routes every byte-level vocabulary through it. A byte-level file with an unimplemented pre-tokenizer keeps the greedy path and says so once on stderr, naming #3726. The old `<|...|>` special-token rule also missed USER_DEFINED ``/``. The gate follows the #3076 shape: scripts/check_tokenizer_parity.sh (PR-time case table, run by guard_tree) and scripts/tokenizer_parity.sh (model-backed, apr vs the pinned llama-tokenize, declared in [package.metadata.dogfood] for the pre-publish phase), reading ids from a new `apr tokenize encode MODEL (-p TEXT | -f FILE)`. That command reads only the GGUF metadata, calls the production GGUFModel::encode, and prints the path taken and decode(encode(x)) == x. Corpus: evidence/tokenizer-parity/corpus/ (public aprender source, a review brief over a public aprender commit, non-ASCII / whitespace / identifier / chat-template sets). MEASURED (receipts in evidence/tokenizer-parity/): lambda, release mode at 9026b70a5, 147/147 (21 GGUFs x the 7 committed files of that time, pinned llama-tokenize d1d3c3396 resolved by the default path); lambda at 9026b70a5 with the 4 real consumer briefs, 210/210 (21 x 10: the 6 committed files after the corpus was trimmed to keep review briefs small, a 25 KB shell script dropped and the review brief cut to 9 KB, plus the 4 briefs); gx10 (aarch64) at 9026b70a5 with the briefs and the 7-file corpus, 132/132 (12 x 11; the pinned build prints d1d3c339 and tp_commit_matches accepts a 7+ hex prefix). Every pair: identical ids, canonical path, decode(encode(x)) == x. MUTANT (done_when 3): bytes >= 0x80 -> id 0 reintroduced; the gate goes RED, 14 of 22 pairs FAIL (the 8 that pass are the pure-ASCII files, as that mutation predicts), first mismatch at the first non-ASCII byte (mutant-id0-lambda.txt). GUARDS: guard_tree --no-cargo 82/82 at 9026b70a5 after three fixes it found: complexity (the splitter is a Splitter with one method per alternative; GGUFModel::encode fell from cognitive 60 to 41), shell lint (SC2075, SEC011), dogfood coverage (surface_audit.csv rows re-mapped through a line diff, one new row, denominator 837 -> 838 in contracts/apr-dogfood-coverage-v1.yaml and the apr-dogfood skill). done_when 4 (#3693 re-measure): an A/B of the fixed binary (9026b70a5) against the control (262dfb2f6, this branch''s parent, which already carries #3672''s template-once fix) on the two lane prompts at temperature 0 on CUDA, queued under the GPU lock on both hosts; recorded on #3693 and #3726 when it lands. OUT OF SCOPE, filed: aprender-core''s BpeTokenizer and realizar''s apr/tokenizer (the APR/HF paths) are #3742; SentencePiece GGUFs keep the greedy path and the gate reports them UNCOVERED, never PASS.' +- id: PMAT-3727 + github_issue: 3727 + item_type: task + title: 'FP8 batched GEMM multiplies a STALE activation on mixed-quant models: the PMAT-084 cache key (ptr, count) aliases across layers — #3602''s cosine 0.4153' + status: in_progress + priority: critical + assigned_to: aprender-37 + created: 2026-09-21T16:20:00Z + updated: 2026-09-21T16:20:00Z + spec: null + acceptance_criteria: + - 'Issue #3727 done_when, verbatim: "A hit is only possible between GEMMs that share an input inside one phase (QKV, gate+up). Every non-FP8 route invalidates the key, and every phase that writes a fresh input opens a new scope, so the `(ptr, count)` aliasing class is closed, not just this instance."' + - 'Issue #3727 done_when, verbatim: "A test drives a mixed-quant layer sequence (6 non-FP8 GEMMs, then an FP8 `ffn_down` on the same buffer, × N layers) and asserts **0** cross-layer hits. Today''s code gives N−1. An all-FP8 sequence still gives 3 hits per layer (K, V, up). A mutant that removes the invalidation turns it RED."' + - 'Issue #3727 done_when, verbatim: "qwen2.5-coder-0.5b Q4_K_M: GPU backend with no fallback, `apr run` correct, `apr qa` golden 3/3, on lambda (default path) AND on gx10 with `BATCHED_PREFILL=1`. `PREFILL_DETAIL_TRACE` shows 0 hits for it and 84 for qwen2.5-coder-7b."' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: '0.69.1 row (#3710), dispatched by the cop, aprender-04. It is #3602''s `cosine 0.4153`, localized in https://github.com/paiml/aprender/issues/3602#issuecomment-5763796065. MECHANISM. `cublas_prefill_fp8_gemm` reused its converted FP8 activation whenever `(packed_input_ptr, m·k)` equalled the last conversion''s key (PMAT-084). The key was cleared only on scratch reallocation, never when the input''s contents changed. On a mixed-quant model, two FP8 GEMMs on the same buffer are separated only by non-FP8 routes, so the second reused the first''s activation. qwen2.5-coder-0.5b''s hidden size of 896 is not a multiple of 256, so Q/K/V/O/gate/up are Q5_0/Q8_0 and only `ffn_down` (Q4_K/Q6_K) takes FP8. With `PREFILL_DETAIL_TRACE=1`, the 0.69.0 binary prints 23 `[PMAT-084] FP8 activation cache HIT ptr=0x71aec6600000 count=238336` (= 49 × 4864) lines: layers 1–23 multiplied layer 0''s SwiGLU output. HOW EACH done_when IS MET. (1) Reuse is now OPT-IN. New `cuda/executor/fp8_activation_cache.rs`: `Fp8ActivationCache { key, share_armed }` replaces the raw `fp8_activation_cache_key` field. `batched_gemv_or_gemm`, the single entry of every batched GEMM whatever its route, starts with `fp8_act_cache.begin_dispatch()`, which drops the held conversion unless the caller armed `fp8_act_cache.share_next()` immediately before the call. The only arming sites are the three shared-input groups: K and V after Q (`batched_qkv.rs`), and up after gate (`batched_ffn.rs`, and `prefill.rs`''s packed prefill). So every non-FP8 route invalidates the key (done_when 1''s first clause). Every dispatch that is not a declared share opens a new scope, and a phase boundary is always one (its second clause, in the stronger form: the scope is the shared-input group, not the phase). A missing `share_next` now costs one extra conversion, never a wrong result. The routes that bypass the dispatcher (the fused DP4A QKV and gate/up kernels) never reach FP8 and never arm. The FP8 GEMM consults `hit(ptr, count)` / `record(ptr, count)`, and a scratch reallocation calls `invalidate()`. (2) The unit tests in `fp8_activation_cache.rs` drive the cache in the executor''s order (begin_dispatch, then hit/record on an FP8 route). A 24-layer mixed-quant sequence (6 non-FP8 GEMMs, then an FP8 `ffn_down` on one buffer and count) must give 0 hits. A 28-layer all-FP8 sequence keeps exactly 84 (K, V, up per layer). Four more rows cover: an unarmed dispatch on the same key misses (gate after RMSNorm rewrote the norm buffer), an armed dispatch on another input misses, the arm is consumed by one dispatch, a non-FP8 group leader still lets K/V share one conversion, and a reallocated scratch holds nothing. MUTANT: `begin_dispatch` never clearing makes the mixed-quant row report 23 hits (the count the hardware trace showed) and fails 2 more rows. RED, 4 passed / 3 failed. (3) On hardware, see MEASURED. `graph_dispatch.rs` (PMAT-291) dispatches one mul_mat per node and does not arm, so if FP8 fires there outside capture, its K/V/up reconvert: a performance cost only, never a correctness one. FP8 routes never fire during capture (`!is_capturing`). The companion row is PMAT-3728 (#3728), which is qwen2.5-coder-7b''s separate FP8 defect, an FP16 overflow of the GEMM''s D. That model''s trace shows the intended 84 hits, so this change does not touch it. STOP LIST: no change to FP8 numerics, to which GEMMs take FP8, or to any route predicate; no default-off workaround (the cop''s ruling). MEASURED: hardware, binaries pinned by `--version` sha, every run under `flock /tmp/apr-gpu.lock choom -n 1000`, sweep prompt "What is the capital of France? Answer briefly." (`apr run --gpu -v`, `--max-tokens 16`) plus the sweep''s `apr qa` golden gate. The hardware binary is `db112cbbf`, this change before the rustfmt pass. The only differences in this commit are in the test module (rustfmt, and one operand hoisted into `let act`). Production code is byte-identical modulo whitespace, checked by stripping whitespace from both. qwen2.5-coder-0.5b on lambda (RTX 4090 sm_89), default path (batched prefill, FP8 prefill on, "[PMAT-053] FP8 weight cache: 24 matrices cached"): `Backend: GPU (NVIDIA GeForce RTX 4090)`, no divergence, rc 0, "The capital of France is Paris.", `apr qa` golden 3/3. `PREFILL_DETAIL_TRACE=1`: 0 PMAT-084 hits (the 0.69.0 binary: 23). qwen2.5-coder-0.5b on gx10 (GB10 sm_121) with `BATCHED_PREFILL=1` (gx10 defaults to serial prefill, so batched must be forced to exercise the path): `Backend: GPU (NVIDIA GB10)`, rc 0, "Paris", `apr qa` golden 3/3 (0.69.0: diverged at pos 1, cos 0.4159). The same 0.5b cells on the stacked PMAT-3728 binary `b47cd0a2d`: rc 0 and qa 3/3 on both hosts. Control: qwen2.5-coder-7b on `db112cbbf` shows 84 hits, the intended K/V/up pattern, and still diverges at pos 1 (lambda cos 0.5668, gx10 0.5724). That is PMAT-3728''s defect, and this change leaves it alone. Tests: `cargo test -p aprender-serve --lib --features cuda fp8_activation_cache` 7 passed; mutant 3 failed (23 hits). `cargo clippy -p aprender-serve --lib --features cuda -- -D warnings` rc 0. `cargo fmt --all -- --check` rc 0. CI does not compile `aprender-serve --features cuda` in the per-PR workspace-test, so these gates were run locally.' +- id: PMAT-3728 + github_issue: 3728 + item_type: task + title: 'FP8 prefill GEMM overflows its FP16 output: D = true × 448/act_absmax exceeds 65,504 on qwen2.5-coder-7b (cosine 0.5668, lambda)' + status: in_progress + priority: critical + assigned_to: aprender-37 + created: 2026-09-21T16:20:00Z + updated: 2026-09-21T16:20:00Z + spec: null + acceptance_criteria: + - 'Issue #3728 done_when, verbatim: "The FP8 prefill GEMM''s intermediate can''t overflow: D in BF16 (or FP32), or `act_absmax/448` applied before the 16-bit store. Its range comes from the output dtype, not from the activation scale."' + - 'Issue #3728 done_when, verbatim: "A GPU test with a small-absmax activation and outputs whose `true × 448/absmax` exceeds 65,504 (the 7b layer-1 QKV numbers). The FP8 result must match the f32 reference within the FP8 tolerance. The pre-fix FP16 D goes RED (inf/NaN or cosine collapse)."' + - 'Issue #3728 done_when, verbatim: "qwen2.5-coder-7b Q4_K_M: GPU backend with no fallback, `apr run` correct, `apr qa` golden 3/3, on lambda AND on gx10 with `BATCHED_PREFILL=1`."' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: '0.69.1 row (#3710), dispatched by the cop, aprender-04. It is stacked on PMAT-3727 (#3727), which it needs: the 7b''s layers are all FP8, and the 0.5b''s defect is the stale key. MECHANISM. `cublas_prefill_fp8_gemm` quantizes the activation with `448/act_absmax` and folds the weight dequant (`w_absmax/448`) into cuBLASLt''s alpha. D is therefore `true_result × 448/act_absmax`, and step 4 multiplies `act_absmax/448` back out. D was FP16, so any GEMM whose input absmax is small relative to its output saturated at 65,504. From the CPU per-op dumps of the 0.69.0 binary (prompt "What is 2+2?"; the dumped QKV is pre-bias: `ffn_block.rs` "Trace QKV BEFORE bias"), qwen2.5-coder-7b''s layer-1 QKV has input absmax 0.0602 and outputs up to 11.54, so D peaks at 85,807 on rows 1–3. That is where the F2 gate saw the first divergence ("position 1, argmax 474 != 198, cosine 0.5668"). qwen2.5-1.5b (green) peaks at 6,822; qwen2.5-coder-0.5b''s FP8 GEMMs peak at 1,436. The 7b''s `PREFILL_DETAIL_TRACE` shows exactly the 84 intended PMAT-084 hits, so this is not the stale-key defect. HOW EACH done_when IS MET. (1) D is BF16, which has FP32''s exponent range, so the range comes from the output dtype, not the activation scale. `aprender-gpu` `cublaslt.rs`: new `Fp8GemmOut { F16, Bf16 }`, and the cached FP8 GEMM''s body moves to a private `gemm_fp8_e4m3_cached(out, …)` whose C/D layouts use `out.cuda_type()` and whose plan cache is keyed `(m, n, k, out)`. `gemm_fp8_e4m3_to_f16_cached` keeps its signature and delegates with F16. New `gemm_fp8_e4m3_to_bf16_cached` delegates with Bf16. `aprender-serve` `cublas_prefill`: the GEMM calls the BF16 variant into the same 2-byte scratch. Step 4 becomes the new `BF16_TO_F32_ACT_SCALED_PTX` / `convert_bf16_to_f32_act_scaled`. bf16 is the upper half of an f32, so the widening is `u16 → u32 << 16`, exact, on the same sm_75 target (no sm_80+ `cvt.f32.bf16`). The FP16 kernel (`F16_TO_F32_ACT_SCALED_PTX`, `convert_f16_to_f32_act_scaled`) had no other caller and is removed. The PMAT-082 JIT warmup now warms the BF16 cached plan the GEMM actually runs. The BF16 significand (8 bits) is still finer than the E4M3 operands'' (4 bits). (2) New GPU row `cublas_prefill/fp8_gemm_range_tests_3728.rs`. It calls the real `cublas_prefill_fp8_gemm` (now `pub(super)` for it), with m=16, n=64, k=256, activations 0.05 with absmax 0.0602 (the 7b''s layer-1 value), and FP8 weights all E4M3 0x7E (448) with scale 1/448. The f32 reference is 12.8 per output. It first asserts it is not vacuous: `peak × 448/act_absmax = 95,256 > 65,504`. It then requires 0 non-finite outputs and every output within 5% of the reference; FP8''s own error here is +3.2%, since 0.05 × 448/0.0602 = 372.1 rounds to the grid point 384. It skips, printing `SKIP`, without a CUDA device. On lambda it ran with no SKIP line: 1 passed. MUTANT: the pre-fix FP16 D (gemm.rs + mod.rs from the PMAT-3727 commit, with only `pub(super)` and the test module added) → RED, "D saturated: 1024 of 1024 outputs are inf/NaN". (3) On hardware, see MEASURED. STOP LIST: no change to activation or weight quantization, to which GEMMs take FP8, or to the FP16 GEMM''s other callers (`gemm_fp8_e4m3_to_f16` and the `_scaled` variant are untouched); no default-off workaround (the cop''s ruling). MEASURED: GPU row on lambda (RTX 4090, sm_89), run with `--nocapture` and no SKIP line: 1 passed. MUTANT (the pre-fix FP16 D): RED, "D saturated: 1024 of 1024 outputs are inf/NaN". Hardware on binary `b47cd0a2d` (this change stacked on PMAT-3727; this commit differs only by the rebase onto PMAT-3727''s final test-only tidy), pinned by `--version` sha, every run under `flock /tmp/apr-gpu.lock choom -n 1000`, sweep prompt, `apr run --gpu -v` + `apr qa` golden. qwen2.5-coder-7b, lambda default path (batched, FP8 on): the pos-1 divergence (0.69.0: argmax 474 != 198, cos 0.5668) is GONE, and the first divergence is now pos 44 (argmax 198 = 198, cos 0.9348); `apr qa` golden 3/3. gx10 (GB10 sm_121) with `BATCHED_PREFILL=1`: pos 1 gone, pos 44 cos 0.9364, qa 3/3. gx10 default (serial prefill): rc 0, `Backend: GPU (NVIDIA GB10)`, "The capital of France is Paris.". The remaining pos-44 rejection is a THIRD defect, PMAT-3759 (#3759): the GPU RMSNorm runs at epsilon 1e-5 instead of the model''s 1e-6. It reproduces on 0.69.0 with FP8 off (pos 44, cos 0.9348) and with serial prefill (0.9359), and float64 ground truth shows the CPU exact and the GPU wrong. So done_when 3 (the 7b green on both hosts) is NOT met by this commit alone; it is met with PMAT-3759 stacked on it, and that commit carries the closing keyword. qwen2.5-coder-0.5b on this binary: lambda default rc 0, GPU, "Paris", qa 3/3; gx10 `BATCHED_PREFILL=1` rc 0, GPU, "Paris", qa 3/3. GATES (`--features cuda`, which the per-PR workspace-test does not compile): `cargo clippy -p aprender-serve --lib --features cuda -- -D warnings` rc 0; `cargo clippy -p aprender-gpu --lib --features cuda -- -D warnings` rc 0; `cargo test -p aprender-gpu --lib --features cuda cublaslt` passed; `cargo fmt --all -- --check` rc 0. §3.B CUDA-docs arm: UNAVAILABLE. The spawn gate refused the cuda-docs-reviewer dispatch because this ticket is filed in the worktree''s roadmap, not the main checkout''s. Record it as not run, never a PASS. The device claims are backed by hardware instead: the BF16-output FP8 cuBLASLt GEMM ran and matched on sm_89 (the GPU row and all lambda cells) and on sm_121 (the gx10 cells).' +- id: PMAT-3731 + github_issue: 3731 + item_type: task + title: '#3544 (d)+(b): the train emits each host''s receipt in the schema the gate reads, and a missing $AP/receipts is an infra fault, never "4 failing hosts"' + status: in_progress + priority: critical + assigned_to: aprender-f0 + created: 2026-09-21T16:24:47Z + updated: 2026-09-22T02:20:00Z + spec: null + acceptance_criteria: + - 'Issue #3731 done_when 1 (verbatim from #3544), verbatim: "**The directory is created before it is written to**, and a redirect failure is reported as an infrastructure fault, never as a host verdict. Falsifier: remove `$AP/receipts/`, run the step, and require an error that names the missing directory rather than four failing hosts."' + - 'done_when 2 (verbatim from #3544), verbatim: "**Emit the receipt in the schema the gate reads**, from the train rather than by hand — `evidence/dogfood//.json`, committed in the ledger PR. The assets lane''s schema is adopted: `provenance ∈ {release-asset, crates.io, local-build}` + exact asset filename, `sha256_published` **and** `sha256_measured` as two fields, the `apr devices --json` entries array verbatim, `generate{model_sha256, backend_line_verbatim, tokens, wall_ms, output_sane}` **or** `generate: null` with a reason, `driver`, `nproc`, and a non-empty `unmeasured[]` naming what that host could not prove."' + - 'the cop''s two requirements in the issue body, verbatim: "stacked on #3717 (it changes autopilot.sh''s hosts step); a red-turning case table driving the real autopilot `hosts` step with stubs, a mutant per row"' + - 'SCOPE WIDENED (comment 5763903861, cop ruling: #3730 merged in), the ordering, verbatim: "**The ordering this issue now delivers, in this order:** +1. **emit the receipts** (#3544 item 2): `evidence/dogfood//.json` in the gate''s schema, from the train; +2. **the post-publish dogfood runs AFTER the hosts step**, so the receipts it judges exist; +3. **fail closed** (#3544 item 1): a post-publish NO-GO, including any DEFER that survives into post-publish, is a STOP, not a log line; +4. **a missing `$AP/receipts` is an infrastructure fault** (#3544 item 4), never "4 failing hosts"; +5. **no `jq -e` over a receipt that may be empty or absent** anywhere in this issue''s acceptance (#3544 item 5, #3554)."' + - 'the same comment''s #3544 items 1 and 5, verbatim: "#3544 item 1, verbatim: "**Fail closed.** A DEFER that survives into the post-publish phase is RED, not a line in a log. Today the pre-publish run DEFERs (correctly — the version is not published yet) and nothing forces the discharge; it happened this train because a person chased it." +#3544 item 5, verbatim: "Note the `jq -e` hazard (#3554) applies directly to acceptance here: on jq 1.6 a receipt that was never produced passes its own gate.""' + - 'THE COP''S RULING ON THE PLAN (comment 5764976186, relayed verbatim), verbatim: "aprender-04 on #3731: no veto. Build it, and #3731 + #3732 fold together. Two corrections/rulings: +1. **mini IS an ssh target.** I measured it just now: `ssh mini ''uname -sm''` → `Darwin arm64`, hostname mini. "Not an ssh target" was a negative claim from one source. HOSTS stays "lambda intel gx10 mini", and the hosts step visits mini for the receipt: `cargo install aprender --version =V --locked` from crates.io, CPU/Metal, no CUDA asset. host_receipt.sh must run under macOS: no /proc, BSD sed/stat, `shasum -a 256` where sha256sum is absent, nproc via `sysctl -n hw.ncpu`. Put a Darwin row in the case table (stubbed uname). +2. **First-green before it blocks** (operator rule 2026-09-17: a gate never green on its own target is not a gate). This row hasn''t been green since 0.65.2, so before it may STOP a train, prove it on a real target: run host_receipt.sh against the PUBLISHED 0.68.2 on all four hosts. Every block that goes green there blocks for 0.69.1. A block that can''t go green on 0.68.2 (e.g. parity refusing on a host) is filed with its measured refusal and runs as REPORT for 0.69.1, named in unmeasured[] and in the release notes, never silently. That''s the standing rule applied, not you softening the gate. +Also: every parity/bench/generate run on lambda or gx10 goes under `flock /tmp/apr-gpu.lock choom -n 1000 -- …`. Stop at the receipt."' + - 'comment 5765122207 (recorded before round 1), verbatim: "**Cop ruling on the implementation and on "committed in the ledger PR" (aprender-04, 2026-09-21T~18:05Z), relayed verbatim by aprender-f0:** + +> aprender-04: the implementation is accepted as described. Blocks that went green BLOCK; the three hand-made historical receipts are exempt by name; PARITY_REPORT_ONLY is version-keyed (0.69.1::#3756) and inert once the host is provisioned; REPORT rows are appended to the release notes once. Your question: **close must OPEN the ledger PR itself**: receipts plus the ledger on a `ledger/` branch, PR opened unarmed, and I fold/arm it. $AP is reclaimable, so receipts that exist only there can be lost, and "hand step" is how 0.68.x ledgers went missing. Record that on the issue. Milestones: #3756 → 0.69.1 and **I take it** (fleet row: build the pin on intel, clone+Metal-build it on mini, then commit the RESOLVE evidence). #3757 → 0.69.1, eb after #3714, likely the same Q8_K-reference asymmetry as #3751. #3758 → 0.70.0 (REPORT for 0.69.1; your #3731 already fixes its dropped-output half). + +"The implementation as described" is aprender-f0''s status to the cop, and its terms are: +- The blocks that went green on the published 0.68.2 now BLOCK in `check_multiplatform_dogfood.sh`: install, a sane `generate`, `.crate` sha256 published = measured, and a non-empty `unmeasured[]`. The exemptions are `TRAIN_RECEIPT_GRANDFATHERED="0.63.0 0.64.0 0.65.2"`. +- `PARITY_REPORT_ONLY` entries are `VERSION:HOST:#ISSUE`, applied only while the block is absent. +- `postpub` appends the gate''s REPORT rows to the release notes, once. + +How the ledger ruling is implemented: a new autopilot step, **`ledger`**, between `postpub` and `close`, so `close` never declares a train done whose receipts exist only in `$AP`. +- It writes the ledger record with `ledger.py`, which moves here from `close`. +- It commits `evidence/dogfood//.json` for every host plus `docs/build-ledger//-lambda-vector-train.json` onto `ledger/`. The base is `origin/main`, or the existing `origin/ledger/` on a re-run, so no push is ever forced. +- It pushes, then opens the PR against main **unarmed** (no `--auto`, no merge), or reuses the open one. +- Anything that fails is a STOP before `close`. + +Correction on #3758, from aprender-f0: #3731 does NOT fix its dropped-output half. `bench_host_receipt.sh` still runs `apr bench … 2>/dev/null`, so the receipt''s `bench_attempt.reason` is the generic "apr bench exited non-zero". #3731 only carries that recorded reason into the gate''s REPORT row and the release notes. The H12 numbers (intel 9.6, mini 7.2 tok/s) are in #3758, not in the receipts."' + - 'comment 5770133655 (recorded before round 1), verbatim: "**Amendment recorded before round 1 (aprender-f0, 2026-09-22 ~02:00Z): REPORT_ONLY also covers a PRESENT, VALID parity block that is not green.** The cop''s ruling above approved `REPORT_ONLY` as "version-keyed … inert once the host is provisioned" and "applies ONLY while the block is ABSENT". The first-green run then measured a case that rule cannot express: lambda''s parity block is COMPLETE and VALID (four cpu bands, the accel probe run under the per-band lock) and still cannot go green — the cpu lane is 0.40× (apr 14.0/32.7/36.2/41.4 vs llama.cpp 66.6/129.8/123.1/165.2 tok/s at c1/4/8/16; #2844''s class), and the gate demands a `cuda` lane the crates.io build cannot emit (#3805). Under absent-only, 0.69.1 would STOP after publishing, on a defect the release cannot fix. + +So, as built and tabled (rows G13/G13b/G14, one mutant), an entry `VERSION:HOST:parity:#ISSUE` REPORTs when the block is ABSENT **or** VALID-but-not-green (a required lane missing, or a lane below its floor), naming the issue and printing the measured lanes; an **INVALID** block still FAILs (row G3), so an entry never excuses a malformed receipt; an unlisted host still FAILs (row G13b). This was put to the cop at 23:55Z and 01:05Z (no answer yet); it stands as the decided recommendation unless vetoed, in which case the three rows and the two `[ -n "$report_only" ]` branches come out and lambda''s parity FAILs 0.69.1''s postpub. + +The 0.69.1 list, from what was measured: `0.69.1:lambda:parity:#3805 0.69.1:gx10:parity:#3805 0.69.1:intel:parity:#2855 0.69.1:mini:parity:#2855 0.69.1:lambda:bench:#3758 0.69.1:intel:bench:#3758 0.69.1:gx10:bench:#3758 0.69.1:mini:bench:#3758`. gx10''s parity entry is provisional until its run reports; its block, if it completes, has the same missing-cuda-lane shape as lambda''s (its crates.io build has no cuda feature either)."' + - 'comment 5770273842 (recorded before round 1), verbatim: "**First-green result on the PUBLISHED 0.68.2 (aprender-f0, 2026-09-21/22)**, per the cop''s ruling above: `scripts/release/host_receipt.sh 0.68.2 ` from a kit on all four hosts. Each host ran `cargo install aprender --version =0.68.2 --locked` into a scratch root, and the `.crate` sha256 published by crates.io equalled the one downloaded, `5dc9e307…44ae85`, on every host. Final kits: +- lambda and gx10: kit6 (per-band GPU lock, `--gpu-prio 8`); +- intel: kit4; +- mini: kit7 (JSON twins). + +| block | lambda | intel | gx10 | mini | for 0.69.1 | +|---|---|---|---|---|---| +| install rc 0, version_tested | green | green | green | green | **BLOCKS** | +| `.crate` sha256 published = measured | green | green | green | green | **BLOCKS** | +| generate sane (2+2 → "4") | green | green | green | green | **BLOCKS**. Every host reported `Backend: wgpu (Vulkan)`, then "path rejected … cosine vs CPU = 0.955", then CPU (#3757) | +| unmeasured[] names what was not proven | green | green | green | green | **BLOCKS** | +| bench (apr bench vs spec H12) | green 1 of 2 runs | refused 2 of 3 (9.6 tok/s) | refused 2 of 2 (+1 not admitted by the queue in 3600 s) | refused 3 of 3 (7.2 tok/s) | REPORT, owed by **#3758** | +| parity | valid block; all 4 cpu bands lock-free, then the accel probe under the lock. The cpu lane is 0.40× (apr 14.0/32.7/36.2/41.4 vs llama.cpp 66.6/129.8/123.1/165.2 tok/s at c1/4/8/16), and the gate demands a cuda lane the crates.io build cannot emit | refused: c16 subject rate 0 (16/16 requests past the 120 s timeout) | refused: the four cpu bands ran lock-free, then the accel probe was NOT admitted by the GPU queue within GPUQ_WAIT=3600 s (release-priority tickets held the lock): "accel lane is UNMEASURED, and that is not the same as no accelerator". The same starvation refused this run''s generate (gpu-q exit 75; gx10''s kit3 run had measured it green, "4") | refused: c8 and c16 subject rates 0 | REPORT: lambda **#3805**, intel **#2855**, mini **#2855**, gx10 **#3805** (it owns gx10''s lane for the same reason as lambda''s) | + +`REPORT_ONLY="0.69.1:lambda:parity:#3805 0.69.1:gx10:parity:#3805 0.69.1:intel:parity:#2855 0.69.1:mini:parity:#2855 0.69.1:lambda:bench:#3758 0.69.1:intel:bench:#3758 0.69.1:gx10:bench:#3758 0.69.1:mini:bench:#3758"` + +What the proof found and fixed in #3731 on the way: +1. **nvidia-smi** prints its failure on stdout (intel), and that text became the accelerator field. Stdout is now used only on rc 0. +2. **tokens=null**: `apr run`''s text output has no count. Generate now uses `--format json`. +3. The **kit''s file list** had drifted (parity died on `scripts/perf_isolation.sh`). The kit is now the whole `scripts/` tree. +4. **The GPU lock was held through CPU bands**: 54+ min at 1% GPU on lambda. The lock is now per accel band (`gpu_band_lock.sh`). +5. **PyYAML is absent on mini.** The kit now carries JSON twins, with no host change. +6. **`parity.parity`**: the producer writes `{"parity": block}`, and host_receipt stored it whole, so the gate saw no lanes. It is unwrapped now, and the stub mirrors the real shape. +7. A **valid-but-failing block** could not be excused by an absent-only REPORT entry. An entry now covers absent OR valid-but-not-green; an INVALID block still FAILs. + +Filed from the proof: #3756 (the pin not provisioned on intel/mini; the cop provisioned it), #3757, #3758, #3805. #2855 is existing."' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'Release-tooling lane (cop, aprender-04), on the 0.69.1 release path, STACKED ON #3717 (branch PMAT-3717-models-t1-both-hosts, receipted head cee1c410f; that is this row''s quorum base, as the issue requires, since it changes autopilot.sh''s hosts step). #3731 and #3732 fold together (cop ruling, quoted above). SCOPE: scripts/release/autopilot.sh (the hosts step, a new postpub step, a new ledger step, install without the dogfood, close without the ledger), scripts/release/host_receipt.sh (new), scripts/check_multiplatform_dogfood.sh (the DOGFOOD_RECEIPTS_DIR seam, the train blocks, REPORT_ONLY, the bench/parity REPORT wording), scripts/parity_host_receipt.sh (the per-band GPU lock only), scripts/lib/gpu_band_lock.sh (new), scripts/lib/yaml_twin.py (new), scripts/lib/bench_receipt.py and scripts/lib/perf_receipt.py (their one YAML read each goes through yaml_twin.load), scripts/check_release_host_receipts.sh (new, the case table), and this fragment. HOW EACH ACCEPTANCE ITEM IS MET. (1) THE RECEIPTS, from the train, in the gate''s schema: scripts/release/host_receipt.sh runs on each host from a KIT = the release commit''s Cargo.toml + its whole scripts/ tree + the JSON twins below (a hand-kept file list had drifted: the first proof''s parity died on gx10 with "scripts/perf_isolation.sh: No such file"). It installs as a user does (`cargo install aprender --version =V --locked` into a scratch root, never PATH), and writes evidence/dogfood//.json: provenance crates.io + asset aprender-.crate, sha256_published (the sparse-index cksum) AND sha256_measured (the downloaded .crate) as two fields, `apr devices --json` verbatim, generate{model_sha256, backend_line_verbatim, fallback_line_verbatim, used_gpu, tokens, wall_ms, output_sane} from `apr run --format json` (stdout JSON, stderr lines verbatim) or generate:null with the reason in unmeasured[], driver, nproc, cpu, os/arch from uname (the Darwin branch is table-driven), and a never-empty unmeasured[]. The bench and parity blocks come from the existing producers; a refusal leaves _attempt{status,rc,reason}. It is bash-3.2 safe (mini), with the clock, hashes and JSON in python3. (2) THE ORDER: autopilot STEPS are now ... cascade install hosts postpub ledger close. `install` no longer runs the dogfood. `hosts` produces the receipts (the gate''s own HOSTS matrix, READ from check_multiplatform_dogfood.sh, never re-listed; the train host locally, the rest over ssh, in parallel) into $AP/receipts/dogfood. `postpub` runs the post-publish dogfood with DOGFOOD_RECEIPTS_DIR=$AP/receipts/dogfood (the tag''s tree cannot hold files made after it). (3) FAIL CLOSED: a post-publish NO-GO is a STOP, and so is a receipt that is not GO, not for this commit, or still DEFERS a row, read from the dogfood''s own receipt, not only its rc. (4) INFRA IS NEVER A HOST VERDICT: $AP/receipts is created before the first write, and every write target is proved writable first, so a missing or vanished dir is ONE STOP naming the dir ("INFRA the receipt dir ... is missing or unwritable"); an ssh that cannot connect (rc 255, named once as SSH_FAILED) and a host that returns no parseable receipt for (V, itself) are INFRA lines, counted apart from host failures. The issue''s falsifier maps to B2 (removed before the step: it is created, green), B3 (removed mid-step: STOP naming the dir, no host count) and B4 (a file in its place: STOP naming it). (5) NO `jq -e`: every receipt read is python3 (S1 asserts neither script carries it). THE COP''S RULINGS AS BUILT (all recorded on the issue): mini is visited like every host, with a Darwin row (A2). First-green on the PUBLISHED 0.68.2 before it blocks: results below. Every block that went green there BLOCKS for 0.69.1 in check_multiplatform_dogfood.sh: install/version as before, plus generate sane, sha256_published = sha256_measured, a non-empty unmeasured[], and the bench block (an ABSENT bench block now FAILs, naming the receipt''s recorded refusal); the hand-made receipts of 0.63.0/0.64.0/0.65.2 are exempt by name (TRAIN_RECEIPT_GRANDFATHERED). A (host, block) that could NOT go green is listed in REPORT_ONLY as VERSION:HOST:BLOCK:#ISSUE and applies only to its version, and only to a block that is ABSENT or VALID-BUT-NOT-GREEN (a required lane missing, or a lane below its floor: what lambda''s complete, valid 0.40x block measured); a block that is INVALID is judged as always, so an entry never excuses a malformed receipt. Its row is still printed as REPORT, and postpub appends the gate''s REPORT rows to the GitHub release notes, once. THE LEDGER (cop ruling): the new `ledger` step commits the receipts (evidence/dogfood//) and the train record (docs/build-ledger//, ledger.py moved here from close) onto ledger/, based on origin/main or on the existing origin/ledger/ so it never force-pushes, pushes, and opens the PR UNARMED (or reuses it); any failure STOPs before close. THE GPU RULE (rev 5): generate and bench queue through `gpu-q --prio N` (the train passes --gpu-prio 1, proofs 8; a host without gpu-q falls back to `flock -w ` + choom and says so in unmeasured[]); --gpu-wait (default 3600 s) bounds every wait. The parity run is NOT wrapped: a first proof held lambda''s lock 54+ min at 1% GPU through its cpu bands. parity_host_receipt.sh now takes the lock PER BAND and ONLY for GPU work (the accel probe and each accel band) through scripts/lib/gpu_band_lock.sh: a holder process queues, writes a ready file INSIDE the lock (a queue that exits without running the holder is therefore never "admitted"), and at GPU_BAND_TIMEOUT_S (<= 1200) kills the band''s registered servers while still holding the lock, so the band FAILs "ran past"; cpu bands never take it; a probe the queue never admits is a refusal ("accel lane UNMEASURED"), never "0 layers". PYYAML ON MINI (cop ruling, no host change): the kit carries JSON twins of scripts/perf-matrix.yaml and scripts/perf-receipt-fields.yaml, written by the release commit''s scripts/lib/yaml_twin.py where PyYAML exists and never committed; the two readers load the twin only when `import yaml` fails. THE CASE TABLE, scripts/check_release_host_receipts.sh (guard_tree-wired, --no-cargo), drives the REAL scripts (host_receipt.sh in a kit; autopilot.sh through its own from/to steps in a throwaway release repo whose kit IS the real host_receipt.sh and whose dogfood stub runs the REAL check_multiplatform_dogfood.sh over the receipts the train wrote; parity_host_receipt.sh''s real run_band() extracted; the real gpu_band_lock.sh on a real flock(1) over scratch locks; the real yaml readers with PyYAML blocked) with stubs for the crates.io install, apr, uname/lscpu/nproc/sysctl/nvidia-smi (its failure text on STDOUT, as intel''s), flock/choom/gpu-q, ssh (each host''s uname and GPU; unreachable; toolchain-less; removing $AP/receipts mid-step), gh (pr list/create, release view/edit) and the crates.io index (a file:// record). ROWS: A1 gpu-linux (every schema field; gpu-q prio 5 around generate and bench only; parity handed the rule), A2 darwin, A3 install-fails (a receipt is still written; unmeasured names install/generate/bench/parity), A4 parity-refuses (parity_attempt), A5 insane-answer, A6 two-hashes, A7 bad-version, A8 nvsmi-fails, A9 gpu-fallback (the wgpu rejection verbatim), A10 legacy-wrap, A11 bad-prio; B1 train-green (HOST-RECEIPT lines BEFORE the post-publish dogfood, which reads $AP/receipts/dogfood; the REAL gate accepts all four incl. the new blocks; mini is Darwin; the kit carries both JSON twins; lambda and gx10 queued at prio 1), B2 dir-removed, B3 dir-vanishes (the issue''s falsifier), B4 dir-blocked, B5 unreachable (ssh 255 = INFRA, 0 host failures), B6 env-no-toolchain, B7 postpub-nogo, B8 postpub-defer, B9 postpub-noreceipt, B10 install-only, B11 postpub-alone, B12 report-notes (once); L1 ledger-pr (receipts + record on ledger/ atop main, PR opened UNARMED), L2 ledger-rerun (fast-forward, no second PR), L3 ledger-empty, L4 ledger-rejected; G1-G14 the gate (a listed absent parity block REPORTs, unlisted FAILs; another version''s entry is inert; a PRESENT invalid block FAILs; the real list''s shape; generate null / insane, hash mismatch, empty unmeasured FAIL; the hand-made versions REPORT; an absent bench block FAILs unless listed; a listed VALID block below floor or missing a required lane REPORTs, unlisted FAILs); T1 twin-equal, T2 twin-missing; P1-P4 the band lock; R1-R4 run_band (cpu free, accel held then freed, refused, bound); S1 no-jq-e. MUTANTS, one per claim, each killed: hr-drop-accel-line, hr-no-gpu-wrap, hr-gpuq-not-preferred, hr-parity-nested, hr-parity-wrapped, hr-os-literal, hr-drop-attempt, hr-sane-always, hr-merge-hashes, hr-no-version-check, hr-nvsmi-any-rc, hr-drop-fallback, hr-version-key; ap-steps-reordered, ap-no-receipts-env, ap-hosts-literal, ap-receipt-prio, ap-drop-mkdir, ap-no-receipt-to, ap-255-is-a-host, ap-drop-nogo-stop, ap-drop-receipt-read, ap-install-dogfood, ap-drop-notes, ap-ledger-no-push, ap-ledger-armed, ap-ledger-from-main, ap-ledger-no-stop, ap-no-twins; gate-any-version, gate-report-present, gate-floor-any, gate-bench-absent-report, gate-gen-any, gate-hash-any, gate-unmeasured-any; lock-release-noop, lock-bound-kills-none, band-lock-any-class; reader-yaml-only, twin-writes-wrong. MEASURED at this commit: `bash scripts/check_release_host_receipts.sh` "PASS 94 row(s) and mutant(s): the train emits, then judges, every host receipt; infra is never a host verdict", rc 0, with the real REPORT_ONLY list in place (row G4 checks its shape). The REAL gate over the four REAL 0.68.2 receipts (a fixture repo at 0.68.2, the list re-keyed to 0.68.2) prints: lambda ok/ok, REPORT bench #3758, REPORT parity "needs lane(s) cuda, receipt has: cpu" #3805; intel ok/ok, ok bench (median 3182 ms), REPORT parity #2855; gx10 ok, FAIL generate (null, the queue refusal quoted), REPORT bench #3758, REPORT parity #3805; mini ok/ok, REPORT bench #3758, REPORT parity #2855.. FIRST-GREEN ON THE PUBLISHED 0.68.2 (host_receipt.sh from the kit, cargo install =0.68.2 --locked, .crate sha256 published = measured = 5dc9e307...44ae85 on every host): committed as evidence/dogfood/0.68.2/{lambda,intel,gx10,mini}.json with a provenance README (the gate never reads that dir for a cut). install rc 0 + version_tested: GREEN on all four. .crate sha256 published = measured: GREEN on all four. generate (2+2 -> "4", output_sane): GREEN on lambda, intel, mini, and on gx10 in its kit3 and kit5 runs (rc 0, "4"); gx10''s committed kit6 receipt has generate:null because gpu-q never admitted the prio-8 call within GPUQ_WAIT=3600 s (release tickets held the lock), recorded verbatim in unmeasured[] -- the gate FAILs that receipt''s generate row, as it should for a non-measurement. On EVERY host the default `apr run` chose wgpu, rejected it (cosine 0.955 vs CPU) and fell back to CPU (#3757). unmeasured[] non-empty: GREEN on all four. So install, sha256, generate and unmeasured BLOCK for 0.69.1. bench (apr bench vs spec H12): lambda green 1 of 2 runs, intel green 1 of 3 (9.6 tok/s refused twice), gx10 refused 2 of 2 measured (+1 not admitted), mini refused 3 of 3 (7.2 tok/s): cannot go green reliably, REPORT owed by #3758 on all four. parity: lambda''s block is VALID (4 cpu bands lock-free, the accel probe under the per-band lock) but the cpu lane is 0.40x (apr 14.0/32.7/36.2/41.4 vs llama.cpp 66.6/129.8/123.1/165.2 tok/s at c1/4/8/16) and the gate demands a cuda lane the crates.io build cannot emit (#3805); intel refused: band[16] subject rate 0, 16/16 requests past the 120 s timeout (#2855); mini refused: band[8] and band[16] subject rates 0 (#2855); gx10 refused: the accel probe was not admitted within 3600 s ("accel lane is UNMEASURED, and that is not the same as no accelerator"), owed by #3805, which owns gx10''s lane for the same reason as lambda''s. THE 0.69.1 REPORT_ONLY LIST, each entry a measured refusal filed where it is owned: 0.69.1:lambda:parity:#3805 0.69.1:gx10:parity:#3805 0.69.1:intel:parity:#2855 0.69.1:mini:parity:#2855 0.69.1:lambda:bench:#3758 0.69.1:intel:bench:#3758 0.69.1:gx10:bench:#3758 0.69.1:mini:bench:#3758. FILED from the proof: #3756 (pinned llama.cpp not provisioned on intel/mini; the cop provisioned both), #3757 (the published binary''s default path picks wgpu and rejects it, cosine 0.955 vs CPU, on all four hosts; macOS says Vulkan), #3758 (apr bench below spec H12 on intel 9.6 / mini 7.2 tok/s, and bench_host_receipt.sh drops the reason), #2855 (existing: the cpu lane at c=16 times out every request). NOT RUN: a real train. The 0.69.1 hosts/postpub/ledger steps are that measurement, hence Refs #3731.' +- id: PMAT-3732 + github_issue: 3732 + item_type: task + title: '#3544 (c): derive the dogfood host matrix from the hosts the train visits (workflow job labels), NA{reason, decided_by, date} for declared absence; fails both ways' + status: in_progress + priority: high + assigned_to: aprender-f0 + created: 2026-09-21T16:24:49Z + updated: 2026-09-22T03:30:00Z + spec: null + acceptance_criteria: + - 'Issue #3732 body, verbatim: "Child of **#3544**, split by the cop (aprender-04, 2026-09-21) into three separately receipted rows so each has its own fragment. Owner **aprender-f0** (release-tooling lane). The items below are quoted **verbatim** from #3544''s "Remaining work". + +## done_when (verbatim from #3544) +- [ ] **Derive the host matrix** from the hosts the train actually visits, with `NA{reason, decided_by, date}` for declared absence — the fleet lane''s ruling, recorded in the comments. Fails in both directions: demanded-but-not-visited, and visited-but-not-demanded. + +The design is the fleet lane''s ruling of 2026-09-20, recorded in #3544''s first comment: the matrix is derived from the labels the train''s jobs select, a host with no job gets an explicit `NA{reason, decided_by, date}` row, and the proposed acceptance is `bash scripts/check_dogfood_matrix_is_visited.sh` (new) plus `check_multiplatform_dogfood.sh` exit 0 against receipts the train itself committed. + +## Also required (cop) +- [ ] a red-turning case table, a mutant per row (demanded-but-not-visited AND visited-but-not-demanded) + +Order: fourth (cop, 2026-09-21). + +Refs #3544"' + - 'THE DESIGN PROPOSED BEFORE CODE (comment 5770601396, recorded before round 1), verbatim: "**Design to rule on before code (aprender-f0, 2026-09-22), because #3731 changed the premise of the fleet ruling.** + +The fleet lane''s ruling in #3544 (2026-09-20) derived the matrix "from the hosts the train actually visits — the labels its jobs select, read from the workflow", with `NA{reason, decided_by, date}` for a host no job targets, and it rejected "a `mini.json` for a host the train never visited". Since then the cop ruled on #3731 that **mini IS visited**: the train''s `hosts` step runs `scripts/release/host_receipt.sh` over ssh on every host of `check_multiplatform_dogfood.sh`''s `HOSTS` (lambda locally; intel, gx10, mini over ssh), and every one of the four produced a real receipt on the published 0.68.2. So "the hosts the train visits" is no longer a set of workflow runner labels; it is what `autopilot.sh` actually reaches, by ssh and by runner. + +**What "fails in both directions" means now:** +- *demanded-but-not-visited*: under #3731 the `hosts` step READS `HOSTS` from the gate, so every demanded host is visited by construction; an unreachable one is an INFRA STOP, never a silent green. This direction is closed by #3731 and needs a guard only against regression: the visited set must still be derived from the gate''s list, never a second literal (row `ap-hosts-literal` in #3731''s table already kills that mutant). +- *visited-but-not-demanded*: REAL today. `autopilot.sh` visits **yoga** (the CUDA release asset, `HOST yoga rc=…`) and runs the installer on intel and gx10, but yoga is in no matrix and has no receipt; its measurement is a `.txt` the gate never reads. Workflow runners also visit hosts (`clean-room.yml` on intel/gx10/yoga, `b2-gpu.yml`, `binary-release.yml`) that the matrix does not name. + +**Proposed:** `scripts/check_dogfood_matrix_is_visited.sh` (new, guard_tree-wired, a case table with a mutant per row): +1. **VISITED** is derived: the ssh targets and local host of `autopilot.sh`''s `hosts` step (parsed from the script, never re-listed) ∪ the `runs-on` host labels of the release-path workflows (`binary-release.yml`, `clean-room.yml` via infra, `b2-gpu.yml`), mapped to host names by the same label table the fleet uses. +2. **DEMANDED** = the gate''s `HOSTS` ∪ an explicit NA table in the gate, `NA="host:reason:decided_by:YYYY-MM-DD"` entries (declared absence). +3. RED when VISITED ⊄ DEMANDED ∪ NA ("visited-but-not-demanded", naming the host, e.g. yoga today), and RED when DEMANDED ⊄ VISITED ("demanded-but-not-visited"). An NA host that becomes visited is RED too (the NA is stale and must leave), which is how mini re-enters the matrix automatically when its job lands. +4. The matrix stays a grow-only set (the gate''s layer-2 floor against origin/main is untouched). + +**Two decisions for the cop:** (a) is **yoga** a matrix host (it then needs a host receipt from `host_receipt.sh`, which today would be its first cargo install there) or an NA row ("yoga: CUDA asset smoke only; decided_by …; date")? (b) do workflow runner labels count as "visited" for the matrix, or only the train''s own ssh/local visits? The fleet ruling says labels; #3731 makes the ssh visits the ones that produce receipts. I recommend: both count as VISITED (a host any release-path job touches must be demanded or declared NA), and yoga gets an NA row now with the reason above, to be lifted when the fleet decides it gets a receipt. + +Stacked on #3731 (they fold together, per the cop). Refs #3544."' + - 'THE FLEET LANE''S RULING this item implements (#3544 comment, 2026-09-20), verbatim: "**Decided (fleet lane + release lane, 2026-09-20): narrow the matrix, and derive the narrowing.** Recording it here so the implementation does not re-litigate it. + +Rejected — *emit a receipt for every host in the current list*: a `mini.json` for a host the train never visited is a receipt for a measurement nobody took. It turns "we do not test on mini" into a green tick. The present red is TRUE; that green would be a lie the gate manufactures — the exact defect class this repo keeps paying for. + +Rejected — *hand-narrow the list*: a constant that drifts from reality and nobody re-reads, which is the same failure one level up. + +**Adopted:** the matrix is **derived from the hosts the train actually visits** — the labels its jobs select, read from the workflow. A host with no job targeting it gets an explicit `NA{reason, decided_by, date}` row: *declared* absence, not silent absence. When #3518 lands and mini gets a job, mini re-enters the matrix automatically, because the derivation sees the new job rather than someone remembering. + +**The gate fails in both directions:** demanded-but-not-visited is today''s bug; visited-but-not-demanded is tomorrow''s. Proposed acceptance: `bash scripts/check_dogfood_matrix_is_visited.sh` (new), plus `check_multiplatform_dogfood.sh` exit 0 against receipts the train itself committed. + +**Do not let mini bury the serious half.** mini is a scoping error. **lambda, intel and gx10 having no receipt across two releases is a gate that has not run at all.** Fix that first — the train''s `hosts` step emitting `{host, arch, version_tested, date, install_rc}` and committing it in the ledger PR — and mini becomes a footnote. + +Ordering note: this is row 69-A1 of the 0.69 train (#3080), so it is scope, not overhead."' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: '#3544 item (c), the fleet lane''s ruling of 2026-09-20 quoted above, STACKED ON #3731 (branch PMAT-3731-host-receipts-fail-closed, head 9b18a6da9; the cop ruled #3731 and #3732 fold together), so the quorum base is 9b18a6da9. THE PREMISE MOVED: the fleet ruling derived "the hosts the train actually visits" from workflow runner labels, at a time when the train visited no matrix host for a receipt. Under #3731 the train''s hosts step VISITS every HOSTS member for a receipt (the train host locally, the rest over ssh, mini included, per the cop''s ruling on #3731), so the visited set is what autopilot.sh reaches, by ssh, locally and by runner. The design comment on the issue (quoted above) records this and the two decisions it leaves the cop; it was written for aprender-04, which was shut down before reading it, and re-put to aprender-3e; the recommendations below stand as decided unless vetoed. SCOPE: scripts/release/autopilot.sh (the hosts it visits declared ONCE -- ASSET_HOSTS, INSTALLER_HOSTS, TRAIN_HOST, matrix_hosts() -- walked by the hosts step and printed by a new `--visited` mode, no gh, no network), scripts/check_multiplatform_dogfood.sh (NA_HOSTS), scripts/check_dogfood_matrix_is_visited.sh (new), scripts/check_release_host_receipts.sh (one mutant anchor moved with the refactor), and this fragment. HOW THE ITEM IS MET. DERIVED, NEVER RE-LISTED: `autopilot.sh --visited` prints one "VISITED " line per (host, how) the hosts step would reach, from the same variables the step walks (release-asset: gx10, yoga; installer: intel, gx10; host-receipt-local: lambda; host-receipt-ssh: intel, gx10, mini). The guard adds the hosts the release-path WORKFLOWS name: binary-release.yml''s matrix `host:` fields (yoga, gx10) and b2-gpu.yml''s runs-on host label (yoga). A POOL label (clean-room, "intel, yoga or gx10") names no host, so it is REPORTed, never demanded: whichever member takes a job is not a matrix visit. DEMANDED is the gate''s HOSTS; DECLARED ABSENCE is the gate''s NA_HOSTS, rows of "host:reason:decided_by:YYYY-MM-DD" (the ruling''s NA{reason, decided_by, date}). FAILS IN BOTH DIRECTIONS: R1 a visited host neither in HOSTS nor in NA_HOSTS is RED (visited-but-not-demanded: yoga today, absent the NA row); R2 a HOSTS member nothing visits is RED (demanded-but-not-visited: closed by construction under #3731, guarded here against regression, and #3731''s `ap-hosts-literal` mutant already kills a re-listed matrix in autopilot); R3 an NA host that is in HOSTS, or that nothing visits any more, is a STALE row and RED (so a host re-enters the matrix by its row LEAVING, which is what makes mini-style absence self-correcting); R4 an NA row without a reason, a decider or a date is RED; R0 an empty HOSTS or an empty visited set is RED. THE TWO DECISIONS, as recommended and built: (a) yoga is an NA row now ("the CUDA release asset is smoke-tested here but no cargo-install receipt is taken; a receipt needs the fleet to decide yoga is a supported-platform row"; decided_by aprender-f0 as a recommendation pending the cop; 2026-09-22), to be lifted by the fleet by deleting the row and adding yoga to HOSTS, at which point host_receipt.sh runs there like everywhere else; (b) workflow host NAMES count as visited beside the train''s own visits, pool labels do not. The ruling''s second acceptance, "check_multiplatform_dogfood.sh exit 0 against receipts the train itself committed", is #3731''s: its B1 row runs the real gate over receipts the real hosts step wrote, and evidence/dogfood/0.68.2/ holds the train''s receipts from the published 0.68.2. THE CASE TABLE, `bash scripts/check_dogfood_matrix_is_visited.sh --self-test`, 15 rows and mutants over a stub autopilot (--visited lines) and a stub gate: S1 the control (a, b demanded and visited; c visited and declared absent -> green with the REPORT line); S2 c visited, undemanded, undeclared -> R1; S3 d demanded, never visited -> R2; S4 c joined HOSTS while still declared absent -> R3; S5 an NA host nothing visits -> R3; S6 an NA row without decider/date -> R4; S7 a workflow-named host nothing demands -> R1 via the workflow; S8 empty HOSTS -> R0; S9 nothing visited -> R0; S10 a pool label is REPORTed, not demanded; mutants dropping R1, R2, R3, R4 and the workflow reader, each killed. MEASURED at this commit: `bash scripts/release/autopilot.sh --visited` prints the 8 lines above, rc 0; the guard on the tree: ok lambda/intel/gx10/mini (each visited and demanded, with how), "REPORT yoga visited (b2-gpu.yml runs-on label, binary-release.yml matrix host, release-asset) and DECLARED absent: ...", three "REPORT pool clean-room" lines, PASS; without the NA row it is "FAIL R1 yoga is VISITED (...) but neither in HOSTS nor declared absent" (the visited-but-not-demanded direction, measured on the real tree); #3731''s table on this tree: PASS 94 rows and mutants; guard_tree --no-cargo: 81 checks, 0 failed. Refs #3732 #3544.' +- id: PMAT-3733 + github_issue: 3733 + item_type: task + title: 'apr inspect --json drops every qwen35.* metadata key: the GGUF reader parsed only an arch-prefix allowlist; every header key now reaches inspect (#3733)' + status: in_progress + priority: critical + assigned_to: aprender-a8 + created: 2026-09-21T17:05:00Z + updated: 2026-09-21T17:05:00Z + spec: null + acceptance_criteria: + - 'Issue #3733 done_when, verbatim: "`apr inspect --json ` emits every KV the header carries (or at least every `.*` key) for any arch, including one inspect has never heard of. A test runs a fixture GGUF with an unknown arch prefix and fails if any header key is missing from `.metadata`."' + - 'Cop comment on #3733 (2026-09-21T16:25:54Z), verbatim: "done_when: `apr inspect --json` emits EVERY GGUF metadata key the file carries, with no arch-prefixed allowlist (the 46 KVs on the 4B). A case row checks the count against the header''s KV count, plus a mutant (drop one prefix and it goes RED). Also trace the RosettaStone path, since 62 didn''t."' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'ROOT CAUSE (traced, the RosettaStone path included): `apr inspect` sends every GGUF to `run_rosetta_inspect` (inspect.rs:162), then `RosettaStone::inspect_gguf` (rosetta/validate_inspect.rs:419) copies `load_gguf_raw(..).raw_metadata` unfiltered, and `load_gguf_raw` (gguf/api.rs) built that map from `GgufReader::metadata`. `GgufReader::from_bytes` parsed a key only if it started with `tokenizer.`, `general.`, `llama.`, `qwen2.`, `qwen3.`, `phi.`, `mistral.` or `gpt2.` (reader_parsing.rs) and length-skipped everything else, so `qwen35.*` (which does not start with `qwen3.`) and `quantize.*` never existed after the parse. No filter was in inspect or rosetta. FIX: nothing is skipped any more. Keys outside the allowlist are decoded into a new `GgufReader::display_only_metadata`, and `raw_metadata` is `metadata` chained with it. DELIBERATELY NOT `keep_all` on this path: the config accessors (`context_length()`, `num_layers()`, `hidden_size()`...) read `metadata`, and `load_gguf_raw` feeds them into the `apr import` model config, so widening `metadata` would give every unlisted architecture a config the import path has never been given. That is a behaviour change outside this row. A test pins it: `reader.context_length()` stays None on the qwen35 fixture while `display_only_metadata` holds the key. `from_file_full` (the shard merge) is unchanged and keeps everything in `metadata`. `skip_metadata_value` lost its only caller and is deleted; its ten builder tests now also assert that the key lands in `display_only_metadata`. HARDENING, which parsing instead of skipping makes necessary: `read_metadata_array` took its element count from the file, called `Vec::with_capacity(count)` and indexed `data[..]` directly for i32/f32 arrays. The span is now checked against the bytes left before any allocation, and the checked `read_i32_le`/`read_f32_le` are used. A hostile count returns FormatError "overruns the file" instead of panicking. The case row covers element types 4, 5, 6 and 8. CLI: `output_rosetta_json` is split into `rosetta_json(path, report) -> Value` plus the print, so the --json document is testable. It emits `report.metadata` unfiltered. MEASURED on lambda. Pre-fix instrument: `apr 0.68.2 (97093d2a5)`. It is a valid baseline because `git log v0.68.2..52f43da71` touches none of reader_parsing.rs, api.rs, validate_inspect.rs or inspect.rs. Qwen3.5-4B-Q4_K_M: .metadata|length = 24, qwen35.* keys = 0, qwen35.context_length = null, which reproduces #3733. Post-fix instrument: `apr 0.69.0 (336b7230b)`, resolved and HEAD-checked by `scripts/apr_bin.sh` under CARGO_TARGET_DIR=/mnt/nvme-raid0/targets/a8-3718. The header KV count comes independently from python `gguf` (GGUFReader.fields minus GGUF.*): 0.8B 46/46, 2B 46/46, 4B 46/46, 9B 46/46, 27B 49/49 (shown/header), each with all 18 qwen35.* keys, context_length 262144, full_attention_interval 4, block_count 24/24/32/32/64, head_count_kv 2/2/4/4/4, key_length 256. Control on an arch that was already on the allowlist: Qwen3-1.7B 32/32, context_length 40960, unchanged. TESTS: api_tests_all_keys_3733.rs covers a fixture whose header carries qwen35.*, quantize.*, an unheard-of prefix `zzz_never_heard_of.*`, general.* and tokenizer.*. It asserts load_gguf_raw and RosettaStone::inspect both show every header key with count == header length, the accessor firewall, and the hostile-count rows. inspect_tests adds rosetta_json_emits_every_metadata_key. Suites: `cargo test -p aprender-core --lib -- format::gguf format::rosetta` 645 passed; `cargo test -p apr-cli --lib -- inspect` 140 passed. MUTANTS, each run and each RED: (1) skip restored (display-only insert removed): 13 red, including both header-count rows and all 10 builder rows; (2) the `.chain(display_only_metadata)` union dropped: both header-count rows red; (3) the cop''s mutant, one prefix dropped (`quantize.*` not kept): both header-count rows red; (4) bounds check removed: the hostile-count row red; (5) a `qwen35.` filter in rosetta_json: rosetta_json_emits_every_metadata_key red. KNOWN, NOT CHANGED: arrays whose element type is 8/16/64-bit (types 0,1,2,3,7,10,11,12) still decode to an empty ArrayUint32 and so display `[len=0]`. This is pre-existing, and the shard merge also depends on that variant, so it is out of scope. Census of all 21 GGUFs in /home/noah/models: array element types are STRING (59) and INT32 (30) only, so no fleet file reaches it.' +- id: PMAT-3739 + github_issue: 3739 + item_type: task + title: 'CRUX inference dogfood slice 1: the SAME GGUF + SAME golden prompts through apr, llama.cpp@pin and ollama on the `run` verb, judged by one rule: a competitor right and apr wrong is RED' + status: in_progress + priority: critical + assigned_to: aprender-76 + created: 2026-09-21T17:10:00Z + updated: 2026-09-21T20:20:00Z + spec: null + acceptance_criteria: + - 'SLICE 1 of #3739, as the design note on the issue lays out (issuecomment-5764437831): the `run` verb, the golden prompts, thinking OFF, lambda. This PR does NOT meet the issue''s done_when in full, and it says `Refs #3739`, never a closing keyword. Every receipt it writes carries a `not_covered` list naming the verbs chat, serve and code, thinking ON, the consumer-brief rungs and max context, and TTFT, so a partial run cannot be read as a full one.' + - 'done_when 1, the part this slice meets, verbatim: "`scripts/crux_inference_dogfood.sh ` runs ... the SAME prompt set (the golden prompts ...) through: run: `apr run` · `llama-cli` · `ollama run`". Measured: `bash scripts/crux_inference_dogfood.sh 0.69.0 --backend cpu --model ~/models/qwen2.5-coder-1.5b-instruct-q4_k_m.gguf` on lambda gives rc 0 with 3 cells GREEN, apr and llama.cpp@d1d3c3396 both correct. It declines (rc 2) when `apr --version` is not , when no --model is given, for a verb other than run, when --engines omits apr, and when no comparator resolves.' + - '"Same model" is recorded, not asserted, verbatim: "ollama IMPORTS the exact GGUF via a Modelfile (`FROM `) and the receipt records sha256 for all three engines". The receipt holds the input sha256 and ollama''s stored blob digest, with `blob_is_input`. An ollama import that carries no chat template (`TEMPLATE {{ .Prompt }}`, what 0.5.7 does on lambda) is REFUSED by name for every cell, never run as a raw completion against two engines that chat. GPU sharing, per the cop''s ruling: on the gpu lane one cell (one prompt through every engine) holds /tmp/apr-gpu.lock (fd 9, closed in every engine) for its engine invocations only. ollama runs with `--keepalive 0`, and the cell stops the model and waits for `ollama ps` to drop it before releasing the lock, recording `vram_released`. The cpu lane takes no lock (the rule''s clause 2); every engine runs under `choom -n 1000`.' + - 'done_when 2, the part this slice meets: per cell the receipt records answer correct (golden), exact-match agreement across engines, token-id parity (apr''s `-v` prompt ids against llama.cpp''s own `/apply-template` + `/tokenize` rendering of the same messages; count plus the id prefix apr prints, labelled `apr_ids_complete`), and prompt/completion tokens and rates as each engine REPORTED them, labelled by engine and never judged. The driver reads no clock and computes no rate (`check_no_competing_harnesses.sh` stays count=0). TTFT and max context belong to later slices and are listed as not covered.' + - 'done_when 3, the gate, verbatim: "a cell where llama.cpp OR ollama answers correctly and apr doesn''t is **RED** (a finding naming the cell)". `bash scripts/check_crux_inference_judge.sh`, which guard_tree runs bare, gives rc 0 and "21 ok, 0 broke". Its row 2 is the #3715 falsifier: llama.cpp right and apr wrong makes the judge exit 1 with the cell RED. Other rows make RED an apr that exits non-zero, falls back off the lane''s backend, or is MISSING. ANY UNJUDGED cell (no comparator answered) declines the run with rc 2, because under the 17:19Z amendment "a missing cell is a NO-GO". ALL_WRONG (every engine wrong) is NAMED and counted per model (`summary.all_wrong_by_model`), never a violation and never a pass, per the cop''s ruling. The prompt set must declare a POSITIVE CONTROL (golden-2plus2, `"control": true`). A control cell that is ALL_WRONG, a model with no measured control cell, and a set that declares none each decline rc 2, with the cause named in `declined_because`. A comparator that exits non-zero or cannot be parsed is no oracle. A drift row pins the prompt set to golden_output.rs::golden_test_cases.' + - 'Mutation, 11 mutants, each turning the table RED: removing the RED rule breaks 6 rows; ignoring apr''s exit code breaks 2; ignoring fallback/backend breaks 1; skipping a missing apr row breaks 14; letting UNJUDGED pass breaks 4; `correct()` ignoring `answered` breaks 4; letting a control ALL_WRONG pass breaks 2; letting an undeclared control pass breaks 1; letting an unmeasured control pass breaks 1; not counting ALL_WRONG per model breaks 1; adding a pattern to the prompt set breaks 4, including the drift row. (An earlier no-GREEN decline was removed, not mutated: the per-model control rule subsumes it, and a mutant of it broke nothing.)' + - 'The first receipts are committed at evidence/crux/0.69.0/lambda-cpu.{json,md} and evidence/crux/0.69.0/lambda-gpu.{json,md}, measured by apr 0.69.0 and the harness at afb05a3de (`apr --version` and `harness.sha` in each receipt). MEASURED: lambda-cpu is PASS, 3 GREEN, with apr and llama.cpp both correct. lambda-gpu is RED, 2 RED + 1 GREEN: on golden-2plus2 (the control) and golden-paris, `apr run --gpu` exits 14 (CUDA diverges from CPU, cosine 0.8795 at position 3; wgpu rejected at 0.955; fell back to CPU and refused) while llama.cpp answers correctly on the same RTX 4090. golden-greeting ran on the GPU with no fallback and is GREEN. The RED cells are an instance of the open #3602 (same model, same host: the GPU result fails its own correctness check and falls back). They are named on #3739 and are not fixed in this PR. The harness''s job is to go RED here, and it did.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'Refs #3739, slice 1 (not a closing keyword; the issue has 6 done_when items and this meets parts of 1, 2 and 3). SCOPE AMENDMENT on the issue (issuecomment-5764587628, cop aprender-04, 17:19Z), verbatim: "Operator, verbatim: \"and CRUX for each verb in pre-release dogfood\". This applies the earlier operator line, \"the way to prevent testing leakage is tests are dervived from surface and SHACL enforced\" (#3745). The verb universe is DERIVED, not listed. It is every command in the surface the release-candidate binary emits (#3745 S1). The run/chat/serve/code list in this issue''s title is superseded as a scope; those four are the first slice, not the set. Every derived verb has a CRUX mapping entry in one committed correspondence file ... A derived verb with NO entry is a SHACL violation. Absence is never \"no comparator\". ... Pre-release, and it gates the tag. CRUX runs in the pre-publish dogfood (T-1), and its receipt is a `:CruxCell` input to `release-readiness-v1` (#3715/#3745). A cell where a comparator is right and apr is wrong is a NO-GO, and so is a missing cell." The cop''s ruling on sequencing, relayed the same minute: "The thin slice (qwen2.5-coder-1.5b `run`, lambda, 3 engines) stays first", and the correspondence file and `:CruxCell` fields are agreed with aprender-97 (#3745 S2, #3715) BEFORE they are coded. So this PR adds no correspondence file. The cop''s rulings of 18:47Z, verbatim: "(1) ALL_WRONG is NAMED, not a violation, since the bar is \"apr right wherever a competitor is right\". Two guards so it can''t become the escape: (i) it''s never scored Pass, and the receipt counts ALL_WRONG per model; (ii) every model''s prompt set includes a positive-control prompt that the smallest model answers right on every engine. If that control comes back ALL_WRONG, the run is DECLINED (rc 2) as a broken harness, never recorded as a model limitation." and "Every CRUX ollama request sets `keep_alive: 0`, runs under the GPU lock, and the cell checks VRAM is released before it drops the lock." Its ruling (2), the lambda ollama upgrade as a binary-only forjar change in paiml/infra, is slice 2 and is not in this PR. Its receipt already keys cells on the release-readiness tuple (model_sha256, host, verb, thinking, rung) plus prompt_id, as aprender-97 asked, and makes an UNJUDGED (unmeasured) cell decline. The issue''s done_when, verbatim: (1) "`scripts/crux_inference_dogfood.sh ` runs, per inventory Q4_K model × {lambda, gx10}, the SAME prompt set (the golden prompts + a consumer brief from #3716 at each declared context rung that fits) through: run: `apr run` · `llama-cli` · `ollama run`; chat (multi-turn): `apr chat` · llama-cli conversation · `ollama run` multi-turn; serve: `apr serve` · `llama-server` · `ollama serve`, all through the SAME OpenAI `/v1/chat/completions` client, streaming + non-streaming; code: `apr code` on a scripted edit-and-verify task, and the same task driven through llama-server and ollama by the same client; thinking ON and OFF where the model supports it (#3723), at temperature 0, same seed" (2) "per cell it records: answer correct (golden), exact-match agreement across engines, token-id parity (apr vs `llama-tokenize`), TTFT, decode tok/s, prompt/completion tokens, and the max context each engine accepts before refusing (or failing silently)" (3) "the gate: a cell where llama.cpp OR ollama answers correctly and apr doesn''t is RED (a finding naming the cell). Performance ratios are REPORTED, never claimed (the withdrawn-headline rule). The receipt feeds the SHACL shape (#3715) as a required cell kind." (4) "ollama is upgraded on lambda through the declared path (forjar) to a version that loads qwen35 and qwen3moe GGUFs; both hosts'' versions are recorded" (5) "runs in the release train (the T-1 `models` step, #3717) and ALSO on demand; the results table is committed per release (`evidence/crux//`)" (6) "depends on: #3563 (A), #3723, #3571". SLICING, ruled by the cop (aprender-04, 2026-09-21: "Start with a design note on #3739 and a first thin slice (qwen2.5-coder-1.5b Q4_K_M, `run` verb, lambda, all 3 engines) to prove the harness, then widen") and laid out in the design note: 1 run (this PR); 2 ollama on lambda via forjar + gx10; 3 chat; 4 serve through one client (perf via `apr test llm bench`, needs #3571); 5 code; 6 thinking ON (needs #3723); 7 consumer rungs + max context; 8 T-1 wiring (#3717). SCOPE: scripts/crux_inference_dogfood.sh (driver), scripts/lib/crux_inference_judge.py (judge), scripts/check_crux_inference_judge.sh (case table), scripts/crux_inference_prompts.json (prompt set), evidence/crux/0.69.0/*, this fragment. ONE DELIBERATE DEVIATION from the letter of done_when 2: token-id parity uses llama.cpp''s server `/tokenize` on its own `/apply-template` rendering, not the `llama-tokenize` binary. lambda''s pinned build dir (the one llama_bin.sh resolves) has no `llama-tokenize`, the server exists on both hosts, and both call the same llama_tokenize on the same vocab. Rendering first also makes parity cover the chat template, which is where #3672 lives. PERF-009: the driver starts engines but contains no rate token and reads no clock, and the judge starts nothing, so the competing-harness count stays 0 without an allowlist entry. The serve slice takes TTFT and decode rate from `apr test llm bench`, not from a new timer. FINDINGS on lambda, apr 0.69.0 @ 52f43da71, qwen2.5-coder-1.5b Q4_K_M sha256 cc324af0…: (a) apr renders the chat template twice (#3672): 46 prompt ids against llama.cpp''s 36, diverging at id 1, and the U+200B escapes encode as id 0 (#3726). The golden answer is still right ("4"), so only the parity field sees it. (b) ollama 0.5.7 imports a GGUF with no chat template; gx10''s 0.33.2 imports the GGUF''s own jinja template but stores blob b9a2f9f3…, not the input''s cc324af0…' +- id: PMAT-3740 + github_issue: 3740 + item_type: task + title: '#3563 (C): every llama.cpp comparator consumer resolves through scripts/llama_bin.sh — no direct binary path, no second resolver' + status: in_progress + priority: high + assigned_to: aprender-f0 + created: 2026-09-21T16:46:26Z + updated: 2026-09-22T00:00:00Z + spec: null + acceptance_criteria: + - 'Issue #3740 done_when (verbatim from #3563''s done_when, added by the cop), verbatim: "done_when (added): exactly one pin in-tree; `llama_bin.sh` resolves and PROVES it on lambda and gx10 (a version+sha line) or fails naming why; every comparator consumer reads it — the clause this issue owns: **every comparator consumer reads it**."' + - 'the cop''s requirement in the issue body, verbatim: "a red-turning case table (a wired scripts/check_*.sh), a mutant per row"' + - 'THE AUDIT (recorded before round 1), comment 5765844943, verbatim: "**Audit (aprender-f0, 2026-09-21), read on `PMAT-3756-llama-pin-intel-mini` @ `88a07cc2a`, which is #3563(A) plus the BSD-sed fix, stacked on main `a9502d992`.** Each hit is classified by whether a llama.cpp binary is EXECUTED from it, and if so how it is located. + +### Shell / Python: every consumer that executes a binary already resolves through `scripts/llama_bin.sh` +| file | how it gets the binary | class | +|---|---|---| +| `scripts/parity_host_receipt.sh` | sources `llama_bin.sh` → `$LLAMA_SERVER` | consumer, **resolves via the pin** | +| `scripts/extract_ggml_traits.sh` | sources `llama_bin.sh` (for `llama_pin_get`) | consumer, **via the pin** | +| `scripts/check_comparator_flags.sh` | sources `llama_bin.sh`, reads `$LLAMA_SERVER` in the harness | guard, **via the pin** | +| `check_no_competing_harnesses.sh`, `check_bench_protocol.sh`, `check_comparator_one_client.sh` | the token appears in grep patterns, messages and case-table fixtures | mention (guards) | +| `perf_gate.sh`, `lib/bench_receipt.py`, `dogfood_examples.sh`, `publish/albor-370m-publish-readiness.sh`, `check_no_fabricated_baselines.sh` (`LLAMA_BIN="$(command -v llama-bench)"` is a **must-not-match fixture line**, not code) | comments, messages, fixtures | mention | +| `lib/perf_receipt.py:1236`, `lib/parity_block_selftest.sh:79` | `/opt/llama-server` and `/usr/bin/llama-server` as self-test fixture strings | mention (fixture) | + +### Rust: three consumers locate llama.cpp OUTSIDE the pin +1. **`crates/apr-cli/src/commands/showcase/benchmark_helpers.rs:39` `run_llama_cpp_bench`**: `which llama-server` (PATH), and then **no measurement at all**: it returns `35.0 + jitter` tok/s, and `apr showcase` turns that into a "speedup vs llama.cpp". Filed separately as **#3773**, because it is a fabricated baseline in a shipped command, not only a resolution defect. +2. **`crates/aprender-serve/tests/qwen3_moe_argmax_parity.rs:102` `locate_llama_cli`**: `which llama-cli` (PATH), then a hard-coded `LLAMA_CLI_CANDIDATE_PATHS` list. That''s a second resolver, with no pin and no version check. It''s a parity test, so its verdict is about whichever llama-cli PATH yields (on lambda, `~/src/llama.cpp` is 60b06ab9a with a broken llama-cli). +3. **`crates/aprender-serve/src/bench/runtime.rs:281` `LlamaCppConfig::default()`**: `binary_path: "llama-cli"` (PATH). It is consumed by `benches/external_matrix.rs` and `examples/pmat_benchmark_matrix.rs` (apr vs llama.cpp). + +Not consumers: `test_llm_band.rs` spawns `bash scripts/perf_receipt_sign.sh`; `apr test llm bench --url` talks HTTP to a server someone else started (in-tree, `parity_host_receipt.sh`, which resolves it via the pin). + +### Proposed shape (for the cop''s ruling before code, because "no second resolver" constrains the Rust side) +- **Rust consumers read ONLY the environment `llama_bin.sh` exports.** They read `LLAMA_CLI`, `LLAMA_SERVER` and `LLAMA_BENCH`, set by `. scripts/llama_bin.sh` after it proves the build. No PATH lookup, no candidate lists, no Rust port of the pin logic, since that would be the second resolver. A test with no such variable SKIPS, naming the command to run (`. scripts/llama_bin.sh && cargo test …`). A bench or example REFUSES. +- `LlamaCppConfig::default()` keeps its public shape, but `binary_path` defaults to `$LLAMA_CLI` when set, and the two in-tree comparator callers (the bench and the example) refuse without it. Whether the LIBRARY default may still say `"llama-cli"` for outside users is part of the ruling. +- The guard, `scripts/check_comparator_consumers_resolve.sh`, is a case table: + - RED for a Rust `Command::new("which").arg("llama-…")`, a `llama-*` literal path default, or a candidate-path const in a comparator consumer; + - RED for a shell command-position `llama-*` invocation that does not come from `$LLAMA_*` (reusing `check_comparator_one_client.sh`''s command-position walker, not a grep); + - a mutant per row. +- The showcase is left to #3773, so this row doesn''t also own the fabrication."' + - 'ITS CORRECTION, comment 5765978075, verbatim: "**Correction to my audit above (aprender-f0).** Item 3 said `LlamaCppConfig::default()` "is consumed by `benches/external_matrix.rs` and `examples/pmat_benchmark_matrix.rs`". I asserted that without checking, and **it is wrong**. `git grep ''LlamaCppConfig\|LlamaCppBackend'' -- ''*.rs''` finds no caller outside `crates/aprender-serve/src/bench/` itself (the type, its backend impl, re-exports, and its own unit tests). +- `benches/external_matrix.rs` does not spawn llama.cpp. It talks HTTP to servers the user starts (`LLAMACPP_GPU_URL`/`CPU_URL`), and `llama-server` appears only in the printed start instructions: a mention. +- `examples/pmat_benchmark_matrix.rs` does not spawn llama.cpp either. It compares apr against **hard-coded** llama.cpp numbers (`llama_cpp_gpu_baseline: 594.10`, `cpu 194.28`, …, "Verified llama-bench baselines (RTX 4090, tg64)"), with no pin, date or receipt. That''s the asserted-baseline class (#3773''s sibling), not a resolution defect; flagged here for the cop to triage. + +So for the in-tree Rust callers, #3740 changes `tests/qwen3_moe_argmax_parity.rs` (env-only, gated as a pre-publish dogfood gate) and the showcase''s `which llama-server` lookup (#3773 owns its fabricated number). For the library default, per ruling (4), it adds only the doc comment "unverified; not what our gates use". Ruling (3) ("the in-tree bench/example REFUSE without the env") has no subject for `LlamaCppConfig`."' + - 'THE COP''S RULINGS (relayed verbatim), comment 5766067680, verbatim: "**Cop rulings on #3740 (aprender-04, 2026-09-21), relayed verbatim by aprender-f0.** + +On the proposed shape (after the audit above): +> aprender-04 rulings for #3740, all approved as proposed with two conditions: +> (1) In-tree Rust comparator callers read ONLY the env llama_bin.sh exports after proving the build (LLAMA_CLI/LLAMA_SERVER/LLAMA_BENCH): no PATH, no candidate lists, no Rust port of the pin logic. +> (2) Tests without that env SKIP and print the exact command to run them (`. scripts/llama_bin.sh && cargo test …`). CONDITION: the pre-publish dogfood runs those tests WITH the env set, so the skip can never be the release path. Wire them as a dogfood gate and say where in the fragment. +> (3) The in-tree bench/example REFUSE without the env. +> (4) The LIBRARY''s public default for outside users may stay "llama-cli" (PATH). CONDITION: its doc comment says it is unverified and not what our gates use. +> (5) The guard case table as described, one mutant per row, reusing check_comparator_one_client.sh''s walker. +> Stack on #3756 (88a07cc2a). #3773 (the fabricated showcase baseline) is triaged into 0.69.1 as release-blocking, owner TBD. Not yours unless you finish #3740 first. + +On the showcase, after the correction above: +> aprender-04: thanks for the correction; that''s the right reflex. On the showcase: NO, don''t touch it in #3740. #3773 is already assigned to aprender-fc (reused, as the operator asked), and its minimum fix is exactly the Err("not measured") you propose. Two owners on one file is the duplicate-fix trap. #3740''s Rust scope = the MoE parity test (env-only, plus the pre-publish dogfood gate where a skip is a FAIL) and the doc comment on the library default. Your new finding (examples/pmat_benchmark_matrix.rs with hard-coded llama.cpp numbers) is folded into #3773 as its sibling; #3773 now owns every asserted competitor baseline. Proceed on #3740 stacked on #3756. + +**How the showcase site is carried.** It is untouched here. The guard''s shrink-only known-violation baseline (`scripts/comparator_consumer_baseline.txt`) lists `R2 crates/apr-cli/src/commands/showcase/benchmark_helpers.rs #3773`. Once #3773 removes the `which llama-server` probe, the entry goes stale, and a stale entry is RED, so whichever PR lands second deletes that line. aprender-fc has been told."' + - 'FOUND BY THE GATE''S FIRST RUN, comment 5768641411 (recorded before round 1), verbatim: "**Found by the gate''s first real run (aprender-f0, 2026-09-22):** the MoE parity test''s comparator must be `llama-completion`, not `llama-cli`. The declared dogfood gate (`scripts/dogfood_comparator_env_tests.sh`) got its GPU slot and ran `f_qw3_moe_parity_002_argmax_vs_llama_cpp` against the pinned build. It FAILED at `qwen3_moe_argmax_parity.rs:231`: `llama-cli exited non-zero`. + +`evidence/parity/pin-bump-d1d3c3396/LOAD.md` already records why. `llama-cli` rejects `-no-cnv` at both pins, and it applies the chat template. Raw completion is `llama-completion`. And `--log-disable` empties `llama-completion`''s stdout. The test passed `-no-cnv --log-disable` to `llama-cli`, so it had never run against any comparator: it only ever skipped, for want of a `llama-cli` on PATH. + +Fix (commit `47b2cb510`): +- `scripts/llama_bin.sh` also exports `LLAMA_COMPLETION`, the `llama-completion` beside the proven build. That adds one variable to ruling (1)''s set, "the env llama_bin.sh exports after proving the build", and it comes from the same proven directory. +- The test reads only `$LLAMA_COMPLETION` and drops `--log-disable`. +- The gate requires `LLAMA_COMPLETION`. + +The gate''s first-green re-run is queued on lambda at `gpu-q --prio 8`."' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: '#3563 part C (split by the cop into A -> C -> B). STACKED ON #3756 (branch PMAT-3756-llama-pin-intel-mini, receipted head 88a07cc2a, itself stacked on #3563(A)''s receipted 8fe36c080), because it needs #3563(A)''s canonical-path resolver and #3756''s BSD-sed fix; the quorum base is 88a07cc2a. SCOPE: crates/aprender-serve/tests/qwen3_moe_argmax_parity.rs, crates/aprender-serve/src/bench/runtime.rs (doc comments only), scripts/llama_bin.sh (one more export, LLAMA_COMPLETION), scripts/dogfood_comparator_env_tests.sh (new), Cargo.toml ([package.metadata.dogfood] gates, one entry), scripts/check_comparator_consumers_resolve.sh (new), scripts/comparator_consumer_baseline.txt (new), scripts/check_baseline_ratchets.sh (one classify() line for the new baseline), and this fragment. THE AUDIT (quoted above, with its correction): every shell consumer that EXECUTES llama.cpp already sources llama_bin.sh; the Rust consumers that locate it outside the pin are the Qwen3-MoE argmax parity test (`which llama-cli` + a hard-coded candidate list) and `apr showcase` (`which llama-server`, and a fabricated baseline: #3773, assigned to aprender-fc by the cop, NOT touched here). LlamaCppConfig has no in-tree caller (the correction). HOW EACH RULING IS MET. (1) The MoE test reads ONLY `$LLAMA_COMPLETION`, which scripts/llama_bin.sh exports from the proven build''s own directory: no PATH, no candidate list, no Rust port of the pin logic. It is llama-completion, not llama-cli: the gate''s first real run failed the llama-cli version at qwen3_moe_argmax_parity.rs:231, because llama-cli rejects -no-cnv at both pins and applies the chat template, and --log-disable empties llama-completion''s stdout (evidence/parity/pin-bump-d1d3c3396/LOAD.md; recorded on the issue). The test had never run against a comparator: it only ever skipped. (2) Without the variable the test SKIPS and prints the exact command (`. scripts/llama_bin.sh && cargo test -p aprender-serve --test qwen3_moe_argmax_parity -- --ignored`). WHERE THE CONDITION IS MET: scripts/dogfood_comparator_env_tests.sh is DECLARED in Cargo.toml''s [package.metadata.dogfood] gates, so scripts/dogfood.sh runs it at pre-publish (and post-publish). It sources llama_bin.sh, requires an executable LLAMA_COMPLETION, builds the test outside the GPU lock, runs it through `gpu-q --prio 1` (DOGFOOD_GPU_PRIO overrides it for a proof run), and FAILS on a skip ("skipped —" in the output), on a filter that matched nothing (no "test ... ok" line), on a failure, or on an unresolved pin: a skip is never the release path. (3) The in-tree bench/example: no in-tree caller uses LlamaCppConfig (the correction), so ruling (3) has no subject. (4) LlamaCppConfig''s Default keeps "llama-cli" for outside users; its doc comment and the binary_path field doc say it is unverified and not what our gates use. (5) THE GUARD, scripts/check_comparator_consumers_resolve.sh (guard_tree-wired, --no-cargo): R1 no llama.cpp binary in shell COMMAND POSITION by bare name or literal path, decided by check_comparator_one_client.sh''s own walker, EXTRACTED from that file at run time with only its predicate swapped (so a walker fix reaches both guards); R1b no shell PATH probe (which / command -v / type -P) of a llama.cpp binary, heredocs and comments being data; R2 no Rust `Command::new("which"|...)` probe of one; R3 no Rust Command::new of one by name or literal path; R4 no Rust const/static list of candidate paths; R5 a SHRINK-ONLY known-violation baseline (scripts/comparator_consumer_baseline.txt, classified `set` in check_baseline_ratchets.sh, with `# tool_version=none`), holding exactly one entry, `R2 crates/apr-cli/src/commands/showcase/benchmark_helpers.rs #3773`: unlisted violations are RED, a stale entry is RED (so whichever of #3773 / #3740 lands second deletes it; aprender-fc has been told), and the list may not grow against origin/main. SELF-TEST, 36 rows and mutants: S1-S14 (shell and Rust shapes, each rule and each clean control), B1-B5 (the ratchet), D1-D7b (the release gate driven with a stub resolver and a stub test runner under a hermetic PATH: pass, skip, did-not-run, failure, unresolved pin, no LLAMA_COMPLETION, gpu-q at release priority), and mutants: the gate without its skip / ran / pin checks and without gpu-q, the one-client walker''s own predicate (flags only llama-bench), the scan without R2 / R4 / R1b, and the ratchet without its stale check. MEASURED: `bash scripts/check_comparator_consumers_resolve.sh --self-test` "SELF-TEST PASSED (36 rows and mutants)"; the real tree: 1 violation, owned by the baseline (#3773), PASS; RED ON THE DEFECT: the same check over the ORIGINAL test file reports R2 at :103 (`Command::new("which").arg("llama-cli")`) and R4 at :75-78 (the four candidate paths). `cargo test -p aprender-serve --test qwen3_moe_argmax_parity`: 4 passed, 1 ignored (the comparator test). FIRST-GREEN OF THE DOGFOOD GATE ON ITS OWN TARGET (lambda, the pinned d1d3c3396 build, the 30B MoE GGUF): GREEN. `CARGO_TARGET_DIR=... DOGFOOD_GPU_PRIO=8 bash scripts/dogfood_comparator_env_tests.sh` on lambda (2026-09-21, finished ~23:50Z after ~1 h in gpu-q at prio 8) printed "ok pinned llama-completion: /home/noah/src/llama.cpp-d1d3c3396/build/bin/llama-completion (version: 0.4.1-dev (build 10987, commit d1d3c3396))", "ok f_qw3_moe_parity_002_argmax_vs_llama_cpp ran against the pinned llama-completion and passed" (the line said llama-cli at the time; corrected since), "PASS 1 comparator-consumer test(s) ran against the pinned llama.cpp", GATE_EXIT=0. Its FIRST run, before the llama-completion fix, FAILED at qwen3_moe_argmax_parity.rs:231 (llama-cli exited non-zero), which is the finding recorded on the issue; an earlier attempt waited 3 h in the queue and timed out without running (GATE_EXIT=124). Related guards: check_llama_pin rc 0, check_comparator_one_client OK, check_baseline_ratchets, check_shell_lint_ratchet, check_bashrs_gate, check_guards_are_wired all PASS.' +- id: PMAT-3741 + github_issue: 3741 + item_type: task + title: '#3563 (B): exactly one llama.cpp comparator pin is cited in-tree — every other sha is historical and dated, or it is RED' + status: in_progress + priority: high + assigned_to: aprender-f0 + created: 2026-09-21T16:46:28Z + updated: 2026-09-22T03:05:00Z + spec: null + acceptance_criteria: + - 'Issue #3741 done_when 1 (verbatim from #3563), verbatim: "Enumerate every committed artifact citing `39173bcac` and classify each: *still valid* (measured before the bump and honestly labelled with the pin it used), or *stale* (claims a current baseline against a superseded comparator)."' + - 'done_when 2, verbatim: "`scripts/llama_bin.sh` is described as "the resolver that refuses anything else" — check whether it refuses a *citation* of a non-pinned sha in a committed receipt, or only refuses resolving a binary. If only the latter, the guard does not cover the surface where the defect lives."' + - 'done_when 3, verbatim: "A guard: no committed artifact may cite a comparator sha other than `llama_pin.toml`''s `build_commit`, unless the citation is explicitly historical and carries the date of the measurement. Falsifier: plant a receipt citing an old pin and require RED."' + - 'the issue''s note, verbatim: "Note the pin''s own rule when resolving this: bumping the comparator invalidates every ratio measured against the old one, so a bump is a decision with a named cost, not a cleanup."' + - 'the mechanism the issue quotes (operator amendment, Clause 2a), verbatim: "## The mechanism (operator''s 2026-09-20 amendment, Clause 2a, quoted in #3563) +> The TRAITS fixture records the sha it was extracted from. A test asserts `fixture.sha == llama_pin.toml build_commit`. A pin bump therefore turns the fixture RED until it is regenerated by the committed extraction command — the bump''s cost is visible in the bump PR, not discovered later."' + - 'the cop''s requirement in the issue body, verbatim: "a red-turning case table, a mutant per row (a planted receipt citing an old pin is RED)"' + - 'THE ENUMERATION AND THE PROPOSED DESIGN (comment 5768382978, recorded before round 1), verbatim: "**First pass of the enumeration (aprender-f0, 2026-09-22), read on `PMAT-3740` @ `bfeed8ced`, which stacks on #3756 → #3563(A).** `git grep -c 39173bca` gives 75 files. They fall into three classes: + +**1. Dated history: honest, keep.** A citation that records when a measurement was made and against which pin: +- CHANGELOG (the re-pin line); +- `llama_pin.toml`''s re-pin notes ("RE-PINNED 2026-09-15 … The previous pin, 39173bcac"); +- PP-LLAMA-001-MASTER''s change-log row and RATIONALE ("both build 39173bcac, 2026-09-02"); +- `contracts/batch-admission-v1.yaml` ("Measured 2026-08-25 … llama.cpp pinned 39173bcac"); +- `contracts/pp-llama-001-comparator-pin-v1.yaml` (props files "at the old template argv"); +- comments recording the OLD build''s measured behaviour in `llama_bin.sh`, `check_llama_pin.sh`, `bench_receipt.py:590` and `perf_receipt.py:61`; +- every file under `evidence/` that is a timestamped record: dogfood 0.65.2 receipts, parity LEDGER rows 0a/5/12 (which `llama_pin.toml` already names as incomparable with the new pin), `parity-http/findings.json`, the props captures, `perf-060/calibration.md`, ship-004 transcripts, and so on; +- `docs/archive/**`. + +**2. Fixtures: not a claim about the comparator, but indistinguishable from one.** +- Rust tests: `test_llm_band.rs`, `extended_commands.rs`, `parity_receipt_tests.rs`, `perf_gate/mod.rs`; +- shell/python self-tests: `perf_gate.sh:1842`, `perf_receipt.py:1237`; +- fixture files: `scripts/lib/parity_receipt_cases/*.json` (22 files) and `tests/fixtures/perf-gate/parity-host-work/*`. + +They use `39173bcac…` as a sample value, often padded with a fake tail (`39173bcac0123456789abcdef…`). + +**3. Stale: claims a CURRENT baseline against a superseded comparator.** +- `evidence/parity/thresholds.yaml:45`: `comparator: ''llama.cpp [X], CPU build, pin 39173bcac (scripts/llama_pin.toml)''`. It is a threshold row that says its comparator is "the pin in llama_pin.toml", and that file now says `d1d3c3396`. +- `evidence/perf-054/campaign-scope.md:379` is a how-to that exports `LLAMA_BENCH_PATH=~/src/llama.cpp-pin/... # 7746 (39173bcac)`, which points readers at the old build. It is dated campaign scope, so it is borderline. + +`60b06ab9a` (3 refs): two Qwen3.5 tests in `crates/aprender-serve` cite it as the reference llama.cpp they were checked against. Classifying those is part of this issue too. + +**Done_when 2:** `llama_bin.sh` refuses to RESOLVE a binary that is not the pin. It does not look at any citation in a committed file, so it does not cover the surface this issue is about. + +**Proposed guard** (for the cop''s ruling before code): +- `llama_pin.toml` declares the superseded pins: `superseded = [{commit = "39173bcac", until = "2026-09-15"}, {commit = "60b06ab9a", ...}]`. +- A new `check_comparator_pin_citations.sh` scans every tracked text file. Each citation of a superseded pin must belong to a file on a SHRINK-ONLY ledger, `scripts/comparator_pin_citations.txt` (` `, class ∈ {historical, fixture}). That ledger is this enumeration, committed. +- A citation in a file NOT on the ledger is RED; that covers the planted-receipt falsifier. A ledger entry whose file no longer cites the sha is RED (stale). +- Fixtures move to an obviously synthetic sha (e.g. `0000000fixture…`), so the fixture class empties and only dated history remains. +- The stale class is fixed in this row: thresholds.yaml''s row names `d1d3c3396` or states that it was measured against the superseded pin, and the perf-054 how-to is marked historical. +- A case table plus a mutant per row."' + - 'WHAT WAS BUILT AND MEASURED (comment 5770588248, recorded before round 1), verbatim: "**Built and measured (aprender-f0, 2026-09-22 ~03:00Z), on `PMAT-3741-one-comparator-pin-cited` @ `96110412e`, stacked on #3740 (`701a959ad`), on the file-ledger design proposed above (the cop has not ruled yet; the ledger data is the same under either design, and this stands as the decided recommendation unless vetoed):** + +- **done_when 1, the enumeration:** `scripts/comparator_pin_citations.txt`, one line per file that cites a superseded pin: ``. 71 files: 40 `historical` (dated records: evidence/, docs/archive, dated spec/contract/CHANGELOG lines, comments beside the pin recording the OLD build''s behaviour) and 31 `fixture` (sample values in self-tests and fixture files). The two STALE citations are fixed in `4f6fd1fc5`: `evidence/parity/thresholds.yaml`''s qwen3.5 cpu row no longer claims "pin 39173bcac (scripts/llama_pin.toml)" (it names the pin of record and dates the basis measured against the previous pin), and `evidence/perf-054/campaign-scope.md`''s how-to that exported the old build is marked historical. +- **done_when 2:** measured: `scripts/llama_bin.sh` refuses only to *resolve* a non-pin binary; it reads no committed file for citations. The surface where the defect lives is covered by the new guard, not by the resolver. +- **done_when 3, the guard:** `scripts/check_comparator_pin_citations.sh` (guard_tree-wired, 78/0 on the branch). `scripts/llama_pin.toml` gains `superseded_commits = "39173bcac 60b06ab9a"` (bumping `build_commit` appends the old value). R1: a file citing a superseded pin (7+ hex digits, so the 8-digit form counts) that is not on the ledger is RED, naming file:line — tracked OR untracked (an untracked planted receipt gets no free pass). R2: a ledger entry whose file no longer cites is RED (stale; the ledger shrinks). R3: a `historical` entry carries a date (YYYY-MM-DD in the file, its path, or the ledger line). R4: the ledger may not grow against origin/main (classified `set` in `check_baseline_ratchets.sh`). R5: `superseded_commits` declared, and never containing `build_commit`. The guard''s own fixtures build the old shas from halves, so it neither exempts nor ledgers itself. +- **The falsifier, on the REAL tree:** a planted `evidence/parity/planted/receipt.json` citing `39173bcac` → `FAIL R1 evidence/parity/planted/receipt.json:1 cites a superseded comparator pin and is not on scripts/comparator_pin_citations.txt`; the same, untracked → RED too; removed → PASS. +- **Case table:** 16 rows and mutants (control; planted receipt; 8-digit abbreviation; stale entry; undated historical; the date on the ledger line; ledger growth vs main; build_commit listed as superseded; no superseded list; malformed line; a citation of the current pin needs no ledger; mutants dropping R1/R2/R3/R4 and a full-sha-only match, each killed). +- Related guards at `96110412e`: check_llama_pin, check_comparator_flags, check_bench_protocol, check_baseline_ratchets, check_guards_are_wired, check_shell_lint_ratchet, check_bashrs_gate, check_model_parity --self-test (26/26): all PASS. + +Not done, pending the ruling: moving the 31 fixture files to an obviously synthetic sha (which would empty the `fixture` class). Ledgering them is the less invasive form; the ledger is shrink-only, so that move can follow as its own delta."' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: '#3563 part B (split by the cop into A -> C -> B), STACKED ON #3740 (branch PMAT-3740-comparator-consumers-resolve, head 701a959ad, itself on #3756 -> #3563(A)); the quorum base is 701a959ad. The design is the file-ledger recommendation recorded on the issue before round 1 (comments quoted above); the cop had not ruled on it when this was built, so it stands as the decided recommendation unless vetoed. SCOPE: scripts/llama_pin.toml (one key, superseded_commits), scripts/check_comparator_pin_citations.sh (new), scripts/comparator_pin_citations.txt (new: the enumeration), scripts/check_baseline_ratchets.sh (one classify() line), scripts/llama_bin.sh (one comment dated), evidence/parity/thresholds.yaml (the stale row), evidence/perf-054/campaign-scope.md (the stale how-to), and this fragment. HOW EACH ITEM IS MET. done_when 1 (enumerate and classify): the ledger IS the enumeration, committed: 71 files, one line each, ` TAB historical|fixture TAB why [sha]`: 40 historical (dated records under evidence/ and docs/archive, dated spec/contract/CHANGELOG lines, comments beside the pin recording the OLD build''s measured behaviour) and 31 fixture (sample values in scripts/lib/parity_receipt_cases/*.json, tests/fixtures, Rust tests and self-tests). The STALE class had two members and both are fixed here: evidence/parity/thresholds.yaml''s qwen3.5 cpu row claimed "pin 39173bcac (scripts/llama_pin.toml)" a week after that file said d1d3c3396; it now names the pin of record and dates the basis measured against the previous pin (2026-09-15). evidence/perf-054/campaign-scope.md''s how-to exported the old build; it is marked historical and points at scripts/llama_bin.sh. done_when 2 (does llama_bin.sh refuse a citation?): measured, no: it refuses only to RESOLVE a non-pin binary and reads no committed artifact, so the guard, not the resolver, covers the surface where the defect lives; this is stated, not fixed in the resolver. done_when 3 (the guard): scripts/llama_pin.toml declares superseded_commits = "39173bcac 60b06ab9a" (a bump appends the old build_commit). scripts/check_comparator_pin_citations.sh, guard_tree-wired (--no-cargo): R1 a file citing a superseded pin (its first 7 hex digits followed by hex, so the 8-, 9- and 40-digit forms all count) that is not on the ledger is RED naming file:line, over tracked UNION untracked text files (an untracked planted receipt gets no free pass); R2 a ledger entry whose file no longer cites any superseded pin is RED (stale: delete it, that is how the ledger shrinks); R3 a historical entry carries a date, YYYY-MM-DD in the file, its path or its ledger line (the "explicitly historical and carries the date" clause, satisfied at the ledger for two undated transcripts); R4 the ledger may not grow against origin/main (a set ratchet, classified in check_baseline_ratchets.sh); R5 superseded_commits is declared and never contains build_commit. The guard''s own fixtures build the old shas from halves, so it neither exempts nor ledgers itself. THE FALSIFIER ON THE REAL TREE: a planted evidence/parity/planted/receipt.json citing 39173bcac -> "FAIL R1 evidence/parity/planted/receipt.json:1 cites a superseded comparator pin and is not on scripts/comparator_pin_citations.txt"; the same file untracked -> RED; removed -> PASS. THE CASE TABLE, `bash scripts/check_comparator_pin_citations.sh --self-test`, 16 rows and mutants: C1 the control (dated history + a fixture, both ledgered, green); C2 a planted receipt unlisted -> R1 naming it; C3 an 8-digit abbreviation is a citation -> R1; C4 a stale entry -> R2; C5 an undated historical entry -> R3; C5b the date on the ledger line satisfies R3; C6 a ledger that grew 1 -> 2 against main -> R4; C7 build_commit listed as superseded -> R5; C8 no superseded list -> R5; C9 a malformed ledger line is RED, never a pass; C10 a citation of the CURRENT pin needs no ledger; mutants drop-r1, drop-r2, drop-r3, drop-r4 and full-sha-only (the 8-digit form no longer matches), each killed by its row. MEASURED at this commit: self-test "SELF-TEST PASSED (16 rows and mutants)"; the tree "ok build_commit d1d3c3396; superseded 39173bcac 60b06ab9a; 71 file(s) cite a superseded pin, every one ledgered (40 historical, 31 fixture); no stale entry", PASS; guard_tree --no-cargo "78 checks, 0 failed"; check_llama_pin rc 0 (the new key does not disturb the resolver''s table), check_comparator_flags, check_bench_protocol, check_baseline_ratchets, check_guards_are_wired, check_shell_lint_ratchet, check_bashrs_gate all PASS; check_model_parity.sh --self-test 26/26 after the thresholds.yaml edit. NOT DONE, pending the ruling: moving the 31 fixture files to an obviously synthetic sha, which would empty the fixture class; ledgering them is the less invasive form and the ledger is shrink-only, so that move can follow as its own delta. RE-BASED ON batch/0.70.0 (2026-09-24): two citations born after the ledger (scripts/check_tokenizer_parity.sh, tests/fixtures/ont/release-green/.../tokenizer/0.69.1/parity.json) are fixture values and are ledgered: 73 files, 40 historical, 33 fixture. QUORUM r1+r2 FINDINGS FIXED (sonnet-5, measured): r1 found the guard skipped all of docs/roadmaps/ and docs/audits/quorum-; r2 found that even an exact-shape exemption (PMAT-*.yaml) passed a planted live claim, being content-blind. The guard now exempts NOTHING but the ledger and the pin file: the four ticket records that quote the old pin (PMAT-3563/3740/3741 fragments and the roadmap.yaml aggregate) are ledgered as dated history like any other file, so the ledger is 77 files (44 historical, 33 fixture). Rows C11 (a PMAT-shaped fragment with a live claim -> R1), C12 (docs/roadmaps/entries/PLANTED.yaml -> R1), C13 (docs/audits/quorum-planted.md -> R1); mutants shape-exempt and prefix-exempt, each killed: SELF-TEST PASSED (21 rows and mutants). QUORUM r3 FINDING FIXED (sonnet-5, measured): the ledger was keyed by FILE, so a live claim appended to an already-ledgered file (roadmap.yaml, thresholds.yaml) passed. Each ledger line now pins the exact number of citing lines as a 4th field; R6 turns a mismatch RED, naming the line numbers (more = a new citation, judged like a new file; fewer = lower the count). 176 lines pinned across 77 files. Rows C14 (a live claim appended to a ledgered file -> R6), C15 (count above the file -> R6), C16 (a line with no count -> RED); mutant drop-r6: SELF-TEST PASSED (25 rows and mutants). QUORUM r4 FINDING FIXED (sonnet-5, measured): a count cannot see a dated line rewritten in place into a live claim. The 4th field is now :, the count AND the sha256 of the citing lines'' text; R6 names count growth, count loss, or an in-place edit (`--pin PATH` prints the value for a deliberate re-pin). Rows C15-C17 (C17: a dated line edited in place, same count, a date elsewhere -> R6); mutants drop-r6 and count-only: SELF-TEST PASSED (27 rows and mutants). QUORUM r5 FINDING FIXED (sonnet-5, measured): the scan skipped any file with a NUL in its first 4 KiB, which git diff also shows as ''Binary files differ'', so a planted receipt behind one NUL byte was invisible to both. There is no binary skip now; a byte-level prefilter keeps it at ~0.9 s. Row C18 plus mutant nul-skip: SELF-TEST PASSED (29 rows and mutants). QUORUM r6 FINDING FIXED (sonnet-5, measured): a receipt saved as UTF-16 hid the pin behind interleaved NULs, invisible to the scan and to git diff. The scan and --pin now prefilter and decode in UTF-8/16/32, keeping the encoding whose decoded text really cites, and R3 reads the decoded text. Rows C19 (a UTF-16 planted receipt -> R1) and C19b (--pin and the judge agree on UTF-16-BE), plus mutant utf8-only: SELF-TEST PASSED (32 rows and mutants). Also: re-merged the moving batch/0.70.0 (r2 found 10 roadmap entries missing from the stale aggregate) and split two swapped classify() comments in check_baseline_ratchets.sh. Refs #3741.' +- id: PMAT-3743 + github_issue: 3743 + item_type: task + title: 'apr run --prompt P --chat templated twice: the three-shape equality test on top of #3672, plus a model-ladder check for escaped specials (#3743)' + status: in_progress + priority: high + assigned_to: aprender-a8 + created: 2026-09-21T21:00:00Z + updated: 2026-09-21T21:00:00Z + spec: null + acceptance_criteria: + - 'Issue #3743 done_when 1, verbatim: "**One templating site.** The prompt is templated exactly once, by the model''s own `tokenizer.chat_template`. `--prompt P --chat`, positional `P --chat` and `-i file --chat` (same text) produce **byte-identical formatted prompts and equal `prompt_tokens`**, asserted by a test that is RED at 0.69.0 (and RED again with the CLI-side wrap restored as a mutant)."' + - 'done_when 2, verbatim: "The thinking toggle (#3723) is honoured through that single site. Neither path may re-wrap or drop `enable_thinking`. Coordinate the seam with #3723''s owner (aprender-fd); this row owns the apr-cli side."' + - 'done_when 3, verbatim: "No escaped special token (`<​|` with a zero-width char) appears in any formatted prompt the model-ladder / CRUX run cells feed a model. That is a check in the dogfood, not only a unit test."' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'SCOPE, as the cop ruled: the FIX already landed as #3672 in batch-1 #3707 (a9502d992). run_prompt_and_chat hands realizar the RAW prompt and `force_chat_template`, and prepare_tokens applies the model''s template once. This row does not re-fix dispatch_run.rs. It adds only what #3672 lacked: the three-shape equality test and the dogfood check. MEASURED (done_when 1) on lambda, CPU, Qwen3.5-0.8B-Q4_K_M, --verbose `[DEBUG] formatted_prompt` + `encoded N tokens`, same text "What is 2+2? Answer with one number.". `apr 0.69.0 (52f43da71)`: `--prompt P --chat` 56 tokens, positional `P --chat` 56, `-i file --chat` 24; the two 56s carry the zero-width escape and their formatted-prompt sha (cbbfe515524c) differs from the file shape (fe8052ef3bac). `apr 0.69.0 (a9502d992)` (batch-1): 24 == 24 == 24, identical formatted-prompt sha fe8052ef3bac on all three, no zero-width. TEST (done_when 1): lib_execute_export_convert.rs test_3743_three_prompt_shapes_build_the_same_realizar_config parses the three argv spellings with clap (on a 16 MB thread), feeds each through run_prompt_and_chat exactly as dispatch_run does, and builds realizar''s config through the new `commands::run::realizar_config` (execute_with_realizar''s config building, extracted unchanged). It asserts every shape reaches realizar as the raw text with force_chat_template set, so the formatted prompt, a pure function of that config and the model, is byte-identical. RED at 0.69.0, whose shape was the CLI-side ChatML wrap. The wrap-restored mutant (run_prompt_and_chat wrapping when chat_template) turns it RED: `left: Some("<|im_start|>user\nWhat is 2+2? ...")`. THINKING TOGGLE (done_when 2): on main neither `apr run` nor realizar''s InferenceConfig has an `enable_thinking`/thinking flag yet (#3723, aprender-fd). The apr-cli side no longer wraps anything, so nothing can re-wrap or drop it. `realizar_config()` is now the single place a thinking flag must be forwarded, and fd was told the seam. This criterion cannot be closed until #3723 adds the flag, so the PR says Refs, not Closes. DOGFOOD (done_when 3): scripts/model_ladder.sh''s per-backend run cell adds --verbose and sets `escaped_special` when realizar''s `formatted_prompt=` line carries `\u{200b}` (Debug-escaped) or the raw U+200B. The rung is then not green, and scripts/check_model_ladder.sh (the [package.metadata.dogfood] gate) fails it: "templated twice (#3743)". Old receipts without the field read as not escaped. New case scripts/lib/model_ladder_cases/red-escaped-special; `check_model_ladder.sh --self-test` 19 cases, 0 bad. Mutant: judge rule removed -> "FAIL case red-escaped-special rc=0 want=1". The ladder''s exact cell and grep on qwen2.5-coder-0.5b-instruct-q4_k_m.gguf (instruct-named, so 0.69.0''s name heuristic wrapped it): 52f43da71 -> escaped_special=true (`<\u{200b}|im_start|>user` visible); a9502d992 -> false. CRUX: this repo holds no CRUX run cell that feeds `apr run` a prompt; the CRUX probes live in the nightly-ux-crux skill, and that check is named for its owner. SUITES at this commit: `cargo test -p apr-cli --lib` 7301 passed; `-p aprender-contracts --lib` 1689 passed; clippy -D warnings apr-cli clean; fmt clean; bashrs lint findings unchanged vs main (model_ladder.sh 45=45, check_model_ladder.sh 18=18).' +- id: PMAT-3745 + github_issue: 3745 + item_type: task + title: '#3745 S3: hand-list guard (LAB nightly) + hand-list migration' + status: planned + priority: medium + assigned_to: null + created: 2026-10-12T16:14:06Z + updated: 2026-10-12T16:14:06Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null + epic: 3863 +- id: PMAT-3747 + github_issue: 3747 + item_type: task + title: '#3568 PR 1/4: the TokenConstraint hook and the llguidance engine behind it — no generation loop wired' + status: in_progress + priority: high + assigned_to: aprender-0e + created: 2026-09-21T17:21:12Z + updated: 2026-09-21T17:25:00Z + spec: null + acceptance_criteria: + - 'Issue #3747 done_when, verbatim: "`constrain::TokenConstraint` {mask, accept, is_complete} exists, and `ConstraintError` names every refusal (SchemaInvalid, SchemaUnsupported, DeadEnd, Rejected, Vocab, NotCompiled), each rendered with its name first"' + - 'verbatim: "`load_schema` takes the schema inline OR as `@path` and refuses non-JSON, non-schema JSON and unreadable paths as SchemaInvalid, before any token"' + - 'verbatim: "llguidance 1.8.0 sits behind the trait, as an optional dependency behind a feature that apr-cli''s `inference` enables; `cargo deny check` (licenses + advisories) stays green with its full dependency tree"' + - 'verbatim: "`GGUFModel::constraint_vocab()` builds each token''s bytes from the SAME per-token decoding `decode()` uses; control/unused tokens are special and can never be constrained text"' + - 'verbatim: "case table: RAH''s quorum-lane schema and rmedia''s three schemas (#3716) compile exactly, accept their real documents, refuse violations at the byte, and allow nothing after one complete value; an approximation is refused; without the feature a constraint is refused (NotCompiled), never ignored"' + - 'verbatim: "mutants: a no-op mask, a dropped special marker, flexible whitespace, allowed approximations and a never-refusing accept each turn the case table RED"' + - 'verbatim: "a measured per-token mask overhead on the Qwen3.5-9B vocabulary (the backend-independent part; the CUDA host-logits download is PR 3''s measurement)"' + - 'NOT THIS PR, verbatim from #3747: "PR 2: apr run''s CPU paths, `--json-schema`/`--grammar`, exit codes + `removed_by`, `SchemaWithThinking`, the independent second reader, `finish_reason`/`prompt_tokens`. PR 3: the CUDA paths and their overhead. PR 4: `apr serve` after #3571. The lenient-extraction removal (§5.0 row 4) is infra''s, after PR 2."' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'Parent #3568 (design note issuecomment-5763921678, ruled by the cop 2026-09-21): PR 1 of 4. Refs #3568 and Closes #3747. WHAT LANDS. crates/aprender-serve/src/constrain/mod.rs: TokenConstraint; ConstraintError with Display `SchemaInvalid: …`, `SchemaUnsupported: …`, `ConstraintDeadEnd: …`, `ConstraintRejected: …`, `ConstraintVocab: …`, `StructuredOutputNotCompiled: …`; load_schema (inline | @path); ConstraintVocab + validate(); ConstraintEnv (index once per model) -> json_schema / lark; doc: cross-field facts no JSON Schema expresses stay the consumer''s to check (rmedia, #3716). constrain/llg.rs (feature structured-output): special tokens carry TokTrie''s marker byte so no grammar can emit them as text. JSON is COMPACT unless the caller set its own x-guidance: llguidance''s default flexible whitespace ran away in this case table ({ then 63 bytes of whitespace). A boolean schema is normalised: `true` -> `{}`, compact; `false` -> SchemaInvalid (it admits no document). An approximation (grammar warnings, reachable only through a caller''s lenient/coerce_one_of x-guidance) is SchemaUnsupported, never used quietly. Engine compile errors map to SchemaUnsupported with the engine''s message verbatim: llguidance''s errors are untyped, and a substring sort would be a text match standing in for a type. A failed compute_mask (NoExtensionBias) and an empty mask are both DeadEnd. crates/aprender-serve/src/gguf/token.rs: GGUFModel::constraint_vocab() and push_token_bytes, which decode() now calls too. control/unused token_type (3, 5) are special, else the GH-320 <|…|> rule; SentencePiece''s ▁ is mapped on BYTES so a lone <0xNN> survives. test_factory gains add_i32_array. examples/constrain_mask_overhead.rs (required-features structured-output). DEPENDENCY. aprender-serve: llguidance 1.8.0 optional, default-features off, [lark, rayon, ahash] (referencing dropped: it duplicated referencing 0.28/0.29; a $ref schema is then refused by name). Feature structured-output = [dep:llguidance]; apr-cli inference adds realizar/structured-output. NOTE for reviewers: `realizar` IS aprender-serve. Root Cargo.toml has `realizar = { path = "crates/aprender-serve", package = "aprender-serve" }`, aprender-serve''s [lib] name is `realizar`, and apr-cli''s existing cuda feature enables `realizar/cuda` the same way. `cargo check -p apr-cli` rc 0 and the example (`use realizar::constrain`) builds rc 0. A round-1 lane read this as a mismatch and was refuted by the build. cargo deny check licenses / advisories / bans / sources: all rc 0; duplicate-crate warnings 64 on main -> 66, the +2 being strum/strum_macros 0.28 via derivre (llguidance''s regex engine). MEASURED at this commit. cargo test -p aprender-serve --lib --features structured-output -- constrain:: constraint_vocab: 24 passed. Without the feature: 12 passed, including StructuredOutputNotCompiled. Consumer schemas (RAH quorum-lane; rmedia quiz, outline, key-terms/reflection) compile exactly, accept real documents byte by byte to completion, allow nothing after one complete value, and refuse 7 violations at the byte (enum, minimum, pattern x2, additionalProperties:false, const, minLength). RAH row: a model intending the 2026-09-21 NULL vote {"verdict":"PASS","summary":"ok","finding":[]} is held until the required `findings` exists; unconstrained it writes the NULL vote. MUTANTS (8, each RED, re-run on this commit): mask a no-op (7 rows), special marker dropped (1, the in-string special row), flexible whitespace (3), approximations allowed (1), accept never refusing (2), token_type ignored (1), gpt2 bytes read as UTF-8 (1), boolean `true` left flexible (1). OVERHEAD, examples/constrain_mask_overhead, release, 3 runs, a real 124-token RAH verdict tokenized by the model''s own tokenizer and accepted end to end: Qwen3.5-9B-Q4_K_M (vocab 248,320) index 559-606 ms once per model, compile 0.67-0.79 ms, mask p50 155-163 us, p95 207-223 us, max 262-291 us per token; Qwen3-1.7B (151,936) p50 104-105 us. Against RAH''s measured decode of 1.0-2.9 tok/s that is under 0.05 percent. cargo fmt --all -- --check rc 0 (the example is formatted; round 1 caught it unformatted); clippy -p aprender-serve --lib --features structured-output -D warnings rc 0.' +- id: PMAT-3749 + github_issue: 3749 + item_type: task + title: '#3745 S1: apr emits its own clap surface as JSON; arg roles come from typed markers; a model loaded through an unmarked arg is RED' + status: inprogress + priority: critical + assigned_to: aprender-fc + created: 2026-09-21T17:27:26Z + updated: 2026-09-21T17:27:26Z + spec: null + acceptance_criteria: + - "S1.1: cargo test -p apr-cli --lib surface:: passes. It includes the_emitter_sees_a_flag_added_to_the_clap_tree: `--zz-dummy` (SetTrue) is injected into `run` via mut_subcommand and appears in the emitted JSON under path [\"run\"] with role mode. It also includes the_surface_is_versioned_and_deterministic: schema == \"apr-cli-surface/v1.1\", and two emissions from one tree are byte-identical." + - "S1.2: in the emitted surface, every model-taking command's model arg has role model. This covers run SOURCE, chat, serve run, code --model, qa, inspect, tensors, trace, diff, merge, distill --teacher/--student, finetune, the rosetta subcommands, pull/rm/import, and pv verify-structure --model and rag transcribe --model (cop ruling below). run --prompt and the run positional PROMPT have role prompt, run --input has role input-file, and run --backend has role backend. Each role is read by TypeId (or by BackendArg's group id), never by name." + - "S1.3: cargo test -p apr-cli --lib surface::guard passes. Every free-form arg (raw PathBuf, or raw String without a finite value set) in a non-foreign subtree is RED, and the guard names ` `. The foreign-subtree list is by Rust type and fails closed both ways. The case table has one row per value-parser class. Mutants, each observed RED then restored GREEN: (a) inspect's `file: ModelPath` reverted to `PathBuf`; (b) a new subcommand with a raw `--model: PathBuf`; (c) a raw `String` prompt." + - "S1.4: `\"$APR\" surface --json` from the built binary exits 0 with a single JSON document on stdout, and under --quiet too. The schema is `apr-cli-surface/v1.1` as agreed on #3745 (issuecomment-5764787123 + amendments 5764810360, 5764962501, and amendment 3 for v1.1). No surface JSON is committed." + - "S1 v1.1 (cop ruling, quoted in notes): every command carries `generates: bool`, true iff it has a PromptText arg or carries the command-level ServesGeneration marker. The marker is on `serve run` (HTTP), `chat` (stdin) and `mcp` (JSON-RPC). cargo test -p apr-cli --lib surface:: covers it with generates_case_table (a PromptText arg; the marker; a model-only command; a look-alike group named ServesGeneration; a raw String arg named prompt), the_generators_are_declared, and mutant_serve_run_without_its_marker_does_not_generate. Live mutant: removing the marker from serve run in source turns the_generators_are_declared RED with `[\"serve\", \"run\"] must be a generator`." + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: | + Part S1 of #3745. Owner aprender-fc, routed by cop aprender-04. Criteria quoted VERBATIM from the cop's per-part comment on #3745 (issuecomment-5764661626): + + "### S1: surface emitter + typed arg markers + marker guard (aprender-fc) + - [ ] S1.1 A hidden `apr` subcommand prints the full clap tree as JSON: every subcommand path; every arg with long/short/positional, num_args, value_enum values, default and **role** ∈ {model, prompt, input-file, backend, mode, other}. A test adds a dummy flag to the clap tree and finds it in the JSON. + - [ ] S1.2 The role is read from the arg's typed constructor, not its name. Every existing model-taking command is migrated onto the markers. + - [ ] S1.3 Marker guard (issue mutant 3): a command that loads a model through a plain `PathBuf` arg is RED, with a case row and a mutant. + - [ ] S1.4 The JSON schema is agreed with S2/S3/#3739 and versioned inside the JSON. It's generated from the binary under test at gate time and never committed." + + Issue mutant 3, VERBATIM from the #3745 body: "**Mutant 3:** a command that loads a model with a plain `PathBuf` arg instead of `ModelArg` → the marker guard is RED." + + Cop rulings on the S1 design note, VERBATIM from aprender-04 (2026-09-21, on #3749's design, #3745 issuecomment-5764787123): + "3. Totality over loader-detection: approved, and better than what I specified. Making an undeclared role inexpressible needs no loader list to rot. It also means "other" roles are typed too (OutputPath, DirPath, FreeText…); no raw PathBuf/String survives in apr-cli subtrees. + 4. KEEP the String half. It closes the #3743 prompt-in-a-String class, and cutting it would re-open a leak we just paid for. The 428-arg migration is the job. Foreign subtrees: they ARE apr's surface, so emit them with `foreign: true`. The two known model gaps (`pv verify-structure --model`, `rag transcribe --model`) are in-tree crates: give them the ModelPath type in S1 itself, not a follow-up, because a model-taking verb with no cells is exactly the leak. Any remaining foreign free-form arg is emitted role `unknown`. S2 gives every `unknown` arg's verb at least the runs-or-refuses cell, and the receipt carries the `unknown` count under a SHRINK-ONLY ratchet (it can only go down). + 5. dispatch_run.rs and the serve handlers untouched, adapting at dispatch.rs: approved." + Cop ruling on the dispatch_run.rs edits the migration forced, VERBATIM from aprender-04 (2026-09-21, after being notified before the edit): "proceed. The 7 conversion edits in dispatch_run.rs are disjoint from #3707's run_prompt_and_chat hunk, and I'll resolve them at the fold if git needs help. No separate note to a8 is needed; #3743 adds a test elsewhere." So ruling 5's "dispatch_run.rs untouched" holds for the `dispatch_run` fn and its `run` args; the 7 edits are in its serve and rosetta arms, and the serve handlers are untouched. + Cop ruling adding `generates` (schema v1.1), VERBATIM from aprender-04 (2026-09-21): "one additive change to S1 BEFORE its slot-3 review (~21:50Z), so the review covers it. aprender-97 (S2) found that the prompt-role rule misses `serve run`, whose prompts arrive over HTTP, which would regress from #3715. Add a surface field `generates: bool` per command, from a TYPED marker: true when the command has a PromptText arg or carries a new `ServesGeneration` marker (put it on `serve run` and any other HTTP/stdin generator), never from the name. Include a case row plus a mutant (drop the marker from serve run → the surface says generates=false → RED), and bump the schema's minor version." + So the role set emitted is {model, prompt, input-file, backend, mode, other, unknown}. `unknown` exists only because of ruling 4, and the marker guard makes it RED outside foreign subtrees. + + Where it runs: the marker guard is a `cargo test -p apr-cli --lib` test, so it runs in CI's workspace-test (nextest --lib over the workspace). The surface JSON is produced by the built binary (`apr surface --json`) at gate time for S2/S3/#3739. That is cargo-side only, and nothing is committed. + Deliberately NOT here: S2 (the cli-surface extractor, derived cells, the release-readiness targets) and S3 (the hand-list guard). Their owners are 97 and 62. + Refs #3745 #3743 #3739 #3715. +- id: PMAT-3750 + github_issue: 3750 + item_type: task + title: 'apr qa''s capability predicates std::fs::read the WHOLE model (twice, plus a to_vec copy) — RSS swings past 30 GB on Qwen3-30B-A3B, an OOM risk on GB10''s unified memory' + status: in_progress + priority: critical + assigned_to: aprender-0e + created: 2026-09-21T18:08:57Z + updated: 2026-09-21T21:45:00Z + spec: null + acceptance_criteria: + - 'THIS PR IS #3750 PR A. Cop ruling (aprender-04 to aprender-0e, 2026-09-21), verbatim: "split approved … PR A = the qa path + the FULL sweep ledger (every one of the 99 production sites with a verdict) + the gx10 before/after. It says **Refs #3750**, not Closes, because done_when 2 wants each site converted or justified, and \"convert later\" is neither. PR B = a sub-issue in **0.69.1**, not later." PR B is #3761.' + - 'Issue #3750 done_when 1, verbatim (PR A carries it in full): "Every qa capability predicate reads the header (mmap, or a bounded read) and never the tensor data. A test with a sparse multi-GB fixture asserts peak RSS stays under a small bound (the bound is measured, not guessed)."' + - 'Issue #3750 done_when 2, verbatim (PR A carries the LISTING; the conversions of the header-only sites are #3761): "Sibling sweep: every `std::fs::read` of a model path in apr-cli / aprender-serve / aprender-core is listed with its caller. Each is converted, or justified as needing the whole file."' + - 'Issue #3750 done_when 3, verbatim (PR A carries it in full): "Measured on gx10: `apr qa` on the 30B, peak RSS before and after, with the binary version + sha."' + - 'Cop dispatch, verbatim: "Header-only (mmap or bounded read) + the sibling sweep of every whole-file `std::fs::read` of a model path + a measured peak-RSS before/after on gx10 (under `flock /tmp/apr-gpu.lock choom -n 1000`). eb''s #3714 has an mmap predicate you can reuse; coordinate so there''s one header reader."' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'Refs #3750 (not Closes: done_when 2 wants each site converted or justified, and the 17 header-only sites outside apr qa are #3761, PR B, 0.69.1). WHAT LANDS. crates/apr-cli/src/commands/model_header.rs: read_prefix, gguf_header (a GGUF header from a growing prefix: 16 MiB first, doubling, 256 MiB cap, refused past it, never read whole), gguf_arch_and_tensors, apr_header_prefix (APR v2 header + metadata + tensor index, bounded by data_offset). The 13 whole-file reads and one to_vec copy on the apr qa path are converted (docs/audits/3750-whole-file-model-reads.md, table 1): capability gate + cpu_only_architecture + hybrid_loader_architecture read the header (extract_gguf_arch_and_tensors and its to_vec are gone); is_gguf_format, the golden/format-parity/throughput/gpu-speedup magic checks read 8 bytes; the tokenizer reads in golden_output, throughput_gguf, format parity, gpu isolation and speedup x2 use the one map those gates already make (mapped.model). CASE ROW (done_when 1). model_header.rs header_reads_of_a_2_gib_gguf_keep_peak_rss_small: a real GGUF extended sparsely to 2 GiB; the probe runs gguf_arch_and_tensors, gguf_header, cpu_only_architecture and hybrid_loader_architecture in a CHILD process (this test binary, re-run on peak_rss_probe) and reads its VmHWM. Bound 256 MiB, measured not guessed: 44.4 MiB on the fixture, 59.5-60.3 MiB on a real 0.5B GGUF, 57.4-59.0 MiB on the real Qwen3-30B-A3B GGUF; with a whole-file read put back into gguf_arch_and_tensors, 2,136,776 KiB (RED). LEDGER (done_when 2, the LISTING). docs/audits/3750-whole-file-model-reads.md: git grep of fs::read( and read_to_end( over apr-cli, aprender-serve and aprender-core: 231 hits, 99 production + 132 test-only, plus the 13 converted. Every production site has a verdict and its use: DOC 9, NOT-MODEL 11, PR-B CONDITIONAL 1, PR-B HEADER-ONLY 11, PR-B MAGIC-ONLY 4, PR-B STREAMED 1 (eval verify_single_file hashes every byte), WHOLE-DATA 62. GX10 (done_when 3), apr qa on Qwen3-Coder-30B-A3B-Instruct-Q4_K_M.gguf (18,556,689,568 bytes), --features cuda builds, under flock /tmp/apr-gpu.lock choom -n 1000, --json --offline and every GPU/network gate skipped: before apr 0.69.0 (52f43da71) max RSS 36,278,440 KiB, after apr 0.69.0 (ff89fb6aa) 19,367,800 KiB, both qa passed rc 0. With --skip-contract (the capability predicates alone): 36,273,092 KiB in 1:10 -> 46,396 KiB in 0.14 s. The 19.36 GB left in the full run is HEAP (sampled RssAnon 19,357,084 KiB, RssFile 11,236 KiB) from the tensor_contract gate: RosettaStone::validate -> GgufReader::from_file, a read_to_end of the whole model. That gate reads every tensor value, so it is WHOLE-DATA in the ledger, marked could stream, and filed as #3790; it is not a capability predicate and this PR does not change it. ff89fb6aa is the measured binary''s commit; the commits after it add docs and the roadmap entry only, so the reviewed code is the code measured.' +- id: PMAT-3754 + github_issue: 3754 + item_type: task + title: 'apr run --temperature T alone is silently greedy (--top-k defaulted to 1): one DEFAULT_TOP_K (40) for run/chat/serve/code (#3754)' + status: in_progress + priority: high + assigned_to: aprender-a8 + created: 2026-09-21T18:10:00Z + updated: 2026-09-21T18:10:00Z + spec: null + acceptance_criteria: + - 'Issue #3754 done_when 1, verbatim: "`--temperature T>0` with no explicit `--top-k` samples: the output differs from greedy for at least one of N fixed seeds. Asserted by a test that is RED at 0.69.0."' + - 'done_when 2, verbatim: "Explicit `--top-k 1` (or `--temperature 0`) stays greedy and byte-deterministic; the determinism tests are unchanged."' + - 'done_when 3, verbatim: "The chosen default is documented in `apr run --help`, derived from the same constant the code uses (no second copy). The same default covers chat / serve / code, or each verb''s difference is named."' + - 'done_when 4, verbatim: "Same-seed sampled output is byte-identical ×2, and a different seed differs (a8''s two controls)."' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'ROOT CAUSE. `apr run --top-k` was declared `default_value = "1"` (commands_enum.rs), `RunOptions::default()` set top_k 1 too, and every decode loop picks greedily when `temperature == 0.0 || top_k == 1` (traced: dense CPU generate_quantized.rs:103/415, dense CUDA generate_1.rs:172, qwen35 CPU/GPU, MoE qwen3_moe_generate.rs:89). So `--temperature 0.8` alone was greedy with no message. `apr chat` and `apr serve` already sampled with 40 (`resolve_chat_top_k` plus five `if temperature == 0.0 { 1 } else { 40 }` copies), which is also the llama.cpp and Ollama default. FIX: one declaration. `realizar::infer::DEFAULT_TOP_K = 40` and `realizar::infer::sampling_top_k(temperature, requested)` (1 at temperature 0, else the request, else DEFAULT_TOP_K). Users: `apr run --top-k` via `default_value_t = crate::commands::run::DEFAULT_TOP_K`, which IS realizar''s constant under the `inference` feature (without it there is no sampler; the flag parses to 1 and nothing reads it). Also RunOptions::default, apr chat (chat_generate_session_02.rs, 3 sites), serve (resolve_chat_top_k now delegates; gpu_completions_handler, realize_handlers_embed_completion x3 and cli/apr_inference use sampling_top_k; cli/gguf_inference_gpu x2 keep their `<= 0.01` greedy threshold and take DEFAULT_TOP_K for the sampled arm), and apr code local driver. LIBRARY DEFAULT DELIBERATELY UNCHANGED: realizar `InferenceConfig::new` keeps top_k 1. PMAT-823 pins that a default config forwards a byte-identical greedy generation config, top_k included (test_pmat823_default_config_is_greedy_no_regression plus 9 default-value rows). `apr run` always forwards its `--top-k` explicitly (`with_top_k(options.top_k)`), so the flag default is where the fix belongs. A scan of all 24 non-test `InferenceConfig::new` call sites found none that sets a temperature without a top-k. A first cut changed the library default too; those 10 rows went RED, and it was reverted. Greedy is unchanged everywhere: the default temperature is 0, and every loop tests `temperature == 0.0` first. dispatch_run.rs is not touched. PER-VERB (done_when 3): run has `--top-k`, default DEFAULT_TOP_K, shown by --help as "[default: 40]" from the constant. chat has no `--top-k`; it samples with DEFAULT_TOP_K at temperature > 0 and 1 at 0. serve takes the request `top_k`, else DEFAULT_TOP_K, and is greedy at temperature 0 (resolve_chat_top_k). code exposes no sampling flag. Its local realizar driver passed top_k 0 (filter disabled, full-vocabulary sampling) while its apr-serve driver sent none and so got serve''s 40; both now get DEFAULT_TOP_K. The apr-serve driver''s `APR_AGENT_TOP_K` override is unchanged. NAMED DIFFERENCES, not fixed here (traced call chains, #3760): `apr run` on .apr samples. It goes run_apr_inference -> run_apr_cpu_inference -> run_apr_quantized_cpu_inference (infer/gguf_gpu_generate.rs:881/894) -> OwnedQuantizedModel::generate_with_cache, the GGUF sampler; APR CUDA builds a QuantizedGenerateConfig (:794), so the #3754 default reaches it. `apr run` on .safetensors NEVER samples: CPU is greedy_decode_with_transformer (infer/mod_log_transformer_eos.rs:76 -> :32) and CUDA is cuda_model.generate(input, max_tokens, eos_id) (gguf_gpu_generate.rs:1109); neither reads temperature/top_k/seed. The AprTransformer sampler (apr_transformer/generation.rs:88) takes the ARGMAX of the top-k/top-p survivors, so it never draws; it is reached by AprTransformer::generate_with_cache[_streaming] callers such as `apr chat` on SafeTensors (chat_generate_safetensors.rs:62/70) and serve''s APR CPU fallback (apr-cli serve/handlers.rs:1121, handler_apr_cpu_completion.rs:151/224). All of these are #3760. The GGUF paths are the ones this row fixes. TESTS. realizar infer::tests_sampling_default_3754, on the pygmy GGUF through `run_inference`: (1) the sampling_top_k table, DEFAULT_TOP_K > 1, and InferenceConfig::new() still top_k 1 / temperature 0; (2) temperature 1.5 with the top-k `apr run` now sends when none is named (DEFAULT_TOP_K) differs from greedy for at least one of seeds 1..=8 (done_when 1); (3) top_k 1 at temperature 1.5, temperature 0, and temperature 0 with top_k 40 all equal greedy for seeds 1..=4 (done_when 2); (4) the same seed twice is byte-identical, and one of seeds 8..=15 differs from seed 7 (done_when 4). apr-cli run_tests_top_k_default_3754, parsed on a 16 MB thread like data.rs: `apr run m.gguf --temperature 0.8` parses top_k == DEFAULT_TOP_K; explicit `--top-k 1` is kept and bare `apr run` has temperature 0; `--help`''s default value for top_k equals DEFAULT_TOP_K and RunOptions::default agrees (done_when 3). MUTANTS, each run and each RED: DEFAULT_TOP_K = 1 (the 0.69.0 value) turns 4 red: temperature-alone, seed-used, the table, and serve''s existing pmat760 defaults_to_40_when_unset (which now reads the shared constant). The `--top-k` clap default restored to the literal "1" turns 2 red: the parse row and the --help row. MEASURED on lambda, CPU, Qwen3.5-2B-Q4_K_M, pinned `apr 0.69.0 (edb5ea058)` via scripts/apr_bin.sh, prompt "Write one sentence about the sea.", 32 tokens: `--temperature 0.8 --seed 1234` != greedy (engaged); the same x2 is identical; seed 99 != seed 1234 (seed used); `--temperature 0.8 --top-k 1` == greedy; `--temperature 0 --top-k 40` == greedy. `apr run --help` prints "[default: 40]". The pre-fix side is the intel column on #3710 (apr 0.69.0 52f43da71): `--temperature 0.8` without --top-k was token-identical to greedy on all four Qwen3.5 sizes. SUITES at this commit''s code: `cargo test -p aprender-serve --lib` 15902 passed, 1 failed: cli::cli_tests_format_size::test_home_dir ("assertion failed: home.is_some()"). That is a pre-existing in-process env race: cli/tests_03.rs:197 `remove_var("HOME")` runs concurrently under `cargo test`. It is 3/3 green in isolation, touches nothing in this diff, and cannot race under CI''s nextest (one process per test). `cargo test -p apr-cli --lib` 7301 passed; `-p aprender-orchestrate --lib` 6535 passed; `-p aprender-contracts --lib` 1689 passed; clippy -D warnings on aprender-serve, apr-cli and aprender-orchestrate clean; fmt clean.' +- id: PMAT-3756 + github_issue: 3756 + item_type: task + title: 'Parity lane refuses on intel and mini: the pinned llama.cpp (d1d3c3396) has no llama-bench/llama-server there' + status: in_progress + priority: high + assigned_to: aprender-04 + created: 2026-09-21T18:00:00Z + updated: 2026-09-21T18:00:00Z + spec: null + acceptance_criteria: + - 'Issue #3756 done_when, verbatim: "done_when: `llama_bin.sh` resolves the pin on intel and mini (evidence committed like `evidence/parity/pin-bump-d1d3c3396/RESOLVE-{lambda,gx10}.txt`), and `host_receipt.sh intel|mini` writes a `parity` block"' + - 'THIS PR delivers the FIRST clause only (llama_bin.sh resolves the pin on intel and mini, with the evidence committed). The second clause (host_receipt.sh writes a parity block) needs #3731, which is not on main; this PR says Refs #3756, not Closes.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'SCOPE: scripts/llama_bin.sh (one line: the commit-token extraction), evidence/parity/pin-bump-d1d3c3396/RESOLVE-{intel,mini}.txt, and this fragment. STACKED on #3563(A) (branch PMAT-3563-llama-pin-resolves-both-hosts @ 8fe36c080, receipt committed), whose canonical-location resolver it uses; fold #3563(A) first. HOST PROVISIONING (the cop''s fleet row; the operator: "you are traffic cop and have ssh, you fix anything you need"; done before the 0.69.1 train starts, not inside it): intel: `cmake --build ~/src/llama.cpp-d1d3c3396/build --target llama-bench llama-server llama-tokenize llama-cli -j 8` under nice 19 / ionice idle (incremental; the existing cache already matched build_flags_intel, GGML_NATIVE=ON, GGML_CUDA=OFF), BUILD_EXIT=0. mini: `git clone https://github.com/ggml-org/llama.cpp ~/src/llama.cpp-d1d3c3396 && git checkout d1d3c3396aa13a5f239109a822666c4870490ad5 && cmake -B build -DGGML_METAL=ON` (build_flags_mini verbatim), then the same four targets, BUILD_EXIT=0. DEFECT FOUND BY THE PROOF (fixed here): on mini, #3563(A)''s resolver refused the correct build as wrong_build. Its commit extraction `sed -nE ''s/…/p;t;s/…/p''` is one expression, and BSD sed (macOS /usr/bin/sed) reads everything after `t` as a LABEL, so it failed with "undefined label" and extracted nothing. Measured pre-fix on mini, rc 1: `sed: 2: "s/.*commit ([0-9a-f]{7, ...": undefined label '';s/.*\(([0-9a-f]{7,40})\).*/\1/p''` then `FAIL llama.cpp named but NOT the declared build (wrong_build)`. FIX: the same three commands as separate -e arguments. PROBE: 4 inputs (commit d1d3c3396, paren abcdef1, a 6-digit commit, no commit) give byte-identical output under GNU sed 4.8 (lambda) and BSD sed (mini): d1d3c3396 / abcdef1 / empty / empty. MEASURED AFTER: `bash scripts/check_llama_pin.sh` rc 0, 43 ok rows, both mutants still killed; live `env -u LLAMA_BENCH_PATH LLAMA_PIN_HOST= bash scripts/llama_bin.sh` rc 0 on intel (`version: 0.4.1-dev (build 2744, commit d1d3c3396)`) and on mini (`version: 0.4.1-dev (build 10987, commit d1d3c3396)`), in the committed RESOLVE files. REMAINDER: the llama.cpp builds live in user-space trees under ~/src on each host; declaring them in forjar (so a re-provisioned host rebuilds them) is not in this PR.' +- id: PMAT-3759 + github_issue: 3759 + item_type: task + title: 'GPU RMSNorm runs with ε = 1e-5, not the model''s 1e-6: the kernel cache key omits ε and preload bakes 1e-5 — special-token positions come out 0.431× (qwen2.5-coder-7b, F2 pos 13/44)' + status: in_progress + priority: critical + assigned_to: aprender-37 + created: 2026-09-21T16:20:00Z + updated: 2026-09-21T16:20:00Z + spec: null + acceptance_criteria: + - 'Issue #3759 done_when, verbatim: "Every RMSNorm module key includes ε (its bits), and preload compiles with the model''s ε, so a cached kernel can never carry a different ε than the launch asked for."' + - 'Issue #3759 done_when, verbatim: "A GPU test with a near-zero-mean-square input (≈1e-6) and ε = 1e-6: the GPU RMSNorm output norm matches the f32 reference within 1e-3 relative. With a 1e-5 kernel preloaded under the old key it goes RED."' + - 'Issue #3759 done_when, verbatim: "qwen2.5-coder-7b Q4_K_M: GPU backend with no fallback, `apr run` correct, `apr qa` golden 3/3, on lambda (default) AND on gx10 with `BATCHED_PREFILL=1`. The `attn_norm` GPU/CPU norm ratio is 1.000 at the special-token positions."' + - 'Issue #3759 done_when, verbatim: "**done_when 4 (Qwen3.5):** a Qwen3.5-9B chat-prompt cell on lambda and gx10, 0.69.0 against the fix."' + - 'Issue #3759 done_when, verbatim: "**done_when 5 (siblings):** every PTX/JIT module-cache key either carries each parameter its kernel bakes in (epsilon, RoPE theta, head dims, scales) or reads it at runtime, shown per key. A guard/test fails when a key omits a baked parameter. Any sibling key the sweep finds incomplete is fixed in this change."' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: '0.69.1 row (#3710), dispatched and widened by the cop, aprender-04. Stacked on PMAT-3728 (#3728), which stacks on PMAT-3727 (#3727). With all three, qwen2.5-coder-7b''s F2 rejections are all gone; this is the third defect in that model''s lambda red. LOCALIZATION. After #3728, the 7b still fell back at pos 44 (0.69.0''s double chat template) / pos 13 (the #3672 clean prompt), with argmax equal and cos ≈0.935 / 0.883. It fails on lambda on BOTH prefill paths and on gx10 only with `BATCHED_PREFILL=1`. `apr parity --per-op` (serial path) on the clean chat prompt `<|im_start|>user\nWhat is the capital of France? Answer briefly.<|im_end|>\n<|im_start|>assistant\n`: layer-0 attention diverges at pos 0 (cos 0.738), 13 and 15, the `<|im_start|>` / `<|im_end|>` positions. Float64 ground truth (layer-0 Q/K/V dequantized from the GGUF with `gguf` 0.17.1, plus bias, on the dumped attn_norm input, at pos 0 where RoPE is the identity): cos(truth, CPU) = 1.000000 for Q, K and V; cos(truth, GPU) = 0.994 / 0.99993 / 0.738. So the CPU reference is exact and the GPU is wrong. The cop''s reference-drift hypothesis (#3751) was ruled out by that, and by `DIRECT_FP32_GEMV=1`, which moved pos 44 only 0.9348→0.9382. The GPU''s W·x has the right direction (cos 1.0000) and 0.431× the magnitude, for Q and V alike, so its input was scaled. The per-position GPU/CPU norm ratio of the attn_norm output fits RMSNorm at epsilon = 1.00e-05 at all 17 positions, against the model''s 1e-6. Ordinary tokens (embedding mean-square ≈3e-4) come out 0.986×; the special tokens (mean-square 1.05e-6) come out 0.431×. MECHANISM. Epsilon is a PTX immediate (`mov_f32_imm`), but the module cache keyed the norm kernels by shape alone (`rmsnorm_vectorized_{h}`, `batched_rmsnorm_vectorized_{h}`, …). The model-load preload in `gguf/cuda/mod.rs` (the "[GH-129] Early kernel preload: N modules compiled" line in every run) compiled those keys at a hardcoded 1e-5, and every later launch passing 1e-6 reused them. At cc ≥ 120 the serial path uses `rmsnorm_simple_{h}`, which is never preloaded, so gx10 serial was green and gx10 batched red. HOW EACH done_when IS MET. (1) Commit 1: `CudaExecutor::f32_bits_tag` (the exact bits, `b{:08x}`) is appended to every norm-kernel key that omitted epsilon: plain/simple/vectorized/precise/batched RMSNorm, per-head and batched per-head, fused-residual (2 sites) and batched fused-residual, LayerNorm, and the fused gate-up-SwiGLU. The fused RMSNorm+Q4K GEMV key used the rounded `{:.0e}` and now uses the bits. `preload_modules_for_capture` / `preload_modules_for_batched_capture` take epsilon, and every caller passes the model''s (`model.config.eps` at model load; the forward''s `epsilon` in the graph-capture paths). `preload_rmsnorm_module` / `preload_batched_prefill_modules` compile with it and key it like the launch. (2) GPU rows `cuda/executor/rmsnorm_eps_tests_3759.rs`, input mean-square ≈1.05e-6 (the special-token value). Row 1: serial and batched RMSNorm at 1e-5, then at 1e-6 in the same process, each within 1e-3 of the f32 reference. Row 2: `preload_modules_for_capture(…, 1e-6)` on a harness, then launch, within 1e-3. Each asserts it is not vacuous: the reference norms at the two epsilons differ by more than 2×. MUTANT A (the key without epsilon, the preload still passing the model''s) and MUTANT B (A plus the preload''s hardcoded 1e-5, i.e. the pre-fix code): see MEASURED. (3) See MEASURED. WIDENED BY THE COP, now done_when 4 and 5 on the issue (quoted verbatim in acceptance_criteria). (a) Qwen3.5 (done_when 4): `forward_qwen35_cuda.rs` calls `rmsnorm_into` and `per_head_rmsnorm_into` with the model''s 1e-6, and both keys omitted epsilon, so the flagship was exposed too. Cells: Qwen3.5-9B on 0.69.0 vs this change, lambda default and gx10 `BATCHED_PREFILL=1`. (b) Siblings (done_when 5), commit 2. `ensure_kernel_module(key, &KernelType)` (new `cuda/executor/module_key_guard.rs`) becomes the compile-on-miss step at 154 of the 203 live module-cache sites (every idiom site, including the preloads), migrated by script. Under `cfg(any(debug_assertions, test))` it records the PTX hash compiled under each key. A later hit whose request differs from every request already proven equivalent is regenerated, and a different hash panics naming both. Grid-only differences have the same PTX and pass. The guard''s own rows: one key asked for 1e-5 then 1e-6 panics; `BatchedVectorizedRmsNorm` with batch_size 1/8/49 under one key passes. The 49 unguarded live sites are classified by reading in `docs/audits/pmat-3759-module-key-audit.md`. That sweep found and fixed two more incomplete keys: every RoPE key omitted theta (baked via `mov_f32_imm(theta.log2())`; masked today by one theta per process, since the model-load preload runs after `set_rope_theta`), and the fused prefill attention used the constant key "fused_prefill_attn" while baking head_dim, heads_per_kv and 1/√head_dim. Both are now keyed. WHERE THE GUARD RUNS: every `cargo test -p aprender-serve --features cuda --lib`, release or debug. In CI that is `ci.yml` job `cuda-unit`, whose `gguf::cuda::` filter does not select the executor rows added here, and they need a GPU. Widening it, or adding `cuda::executor::` to cuda-nightly, is a workflow change left to the release owner. Until then the release-path backstop is the ladder''s F2 fallback cell, and the guard runs wherever this crate''s cuda tests run locally (all of this session''s runs). NOT DONE / LEFT: `layers/loading.rs`, `layers/preload_utilities.rs` and `executor/kernel.rs` are dead copies (nothing `include!`s them) that still hardcode 1e-5; deleting them is its own change. STOP LIST: no change to any kernel''s PTX, to epsilon or theta values, or to which kernel a path selects; no default-off workaround; no workflow edit. MEASURED: all on hardware through `gpu-q --prio 1` (the cop''s ordered GPU queue), binaries pinned by `--version` sha: `c0f4869d2` (commit 1''s code) and `a95681f71` (this change''s code, before one clippy fix in the debug/test-only guard, which a release library does not compile). TESTS on lambda (RTX 4090), no SKIP lines: `rmsnorm_eps_tests_3759` epsilon rows 2/2 pass; the guard rows 4/4 pass, with the guard refusing one key for two epsilons ("module key `guard_probe_3759` is incomplete: … VectorizedRmsNorm { hidden_size: 1536, epsilon: 1e-5 } … now asked for … epsilon: 1e-6"). MUTANT A (the key without epsilon): the two-epsilon row goes RED, "serial/batched eps=1e-6 after 1e-5: output norm 12.0846, reference 28.0525 (56.9% off)", the 0.43x signature. MUTANT B (A plus the preload''s hardcoded 1e-5, i.e. the pre-fix code): both rows RED. GUARD SWEEP: the whole `aprender-serve --features cuda` lib suite matching `cuda`, a debug test build with the guard live: 1439 passed, 0 failed, 7 ignored, 246 s. No exercised key produces two PTX texts. HARDWARE, qwen2.5-coder-7b Q4_K_M, sweep prompt, `apr run --gpu -v` + `apr qa` golden: lambda default path (batched, FP8 on): rc 0, `Backend: GPU (NVIDIA GeForce RTX 4090)`, "The capital of France is Paris.", qa 3/3 on both binaries. 0.69.0 fell back at pos 1 (#3728), and the PMAT-3728 binary at pos 44 (cos 0.9348). gx10 (GB10, sm_121) default (serial): rc 0, GPU, "Paris", qa 3/3 on both binaries. gx10 `BATCHED_PREFILL=1`: pos 1, argmax equal, cos 0.8720. That is issue #3785: FP8 batched prefill on sm_121, not this defect. On this binary `FP8_PREFILL=0` is green, and `DIRECT_FP32_GEMV=1` stays 0.8716, so it is not the CPU reference. The same FP8 batched path is green on lambda. PMAT-3785, stacked on this, turns FP8 prefill off at cc >= 100, and with it the gx10 `BATCHED_PREFILL=1` cell is green (binary `73176dc4c`: rc 0, `Backend: GPU (NVIDIA GB10)`, "Paris", qa 3/3). So done_when 3''s gx10 cell is met by this change plus PMAT-3785; this change alone is green there with `FP8_PREFILL=0`. qwen2.5-coder-0.5b: lambda default rc 0, qa 3/3; gx10 `BATCHED_PREFILL=1` rc 0, qa 3/3. PER-OP on the chat prompt, lambda, serial path, this binary: the GPU/CPU attn_norm norm ratio is 1.0000 at all 17 positions, including `<|im_start|>`/`<|im_end|>` (was 0.4312 at those positions); layer-0 attention cos 1.0000 everywhere; lm_head >= 0.9993. F2 EVIDENCE: the dense qwen2 F2 has no receipt cache (it skips only on `SKIP_PARITY_GATE` or a probe under 2 tokens), so these are real passes. QWEN3.5-9B (the cop''s widening): aprender-c7''s exact `apr chat --gpu` repro with a FRESH `APR_F2_RECEIPT_DIR` fails identically on 0.69.0 and on this change: lambda pos 23 cos 0.8338, gx10 0.8390. It is NOT this defect; gx10''s serial RMSNorm (`rmsnorm_simple`) was never preloaded at 1e-5. It is routed separately. My first Qwen3.5 cells were VACUOUS: F2 skipped them via a cached receipt ("CPU reference forward skipped [source=receipt]"). They are discarded, and that gate-integrity finding went to the cop. GATES: `cargo clippy -p aprender-serve --lib --features cuda -- -D warnings` rc 0; `cargo fmt --all -- --check` rc 0; complexity ratchet "none new, none grown".' +- id: PMAT-3760 + github_issue: 3760 + item_type: task + title: 'One shared seeded sampler: AprTransformer and SafeTensors run draw; GpuModel samplers draw; greedy-only GPU decoders gated (#3760)' + status: in_progress + priority: high + assigned_to: aprender-a8 + created: 2026-09-21T19:00:00Z + updated: 2026-09-21T19:00:00Z + spec: null + acceptance_criteria: + - 'Issue #3760 done_when 1, verbatim: "At T>0 with k>1, the APR/SafeTensors sampler DRAWS from the renormalized survivor distribution using the seeded RNG, the same algorithm as the GGUF path. Better still, ONE shared sampler function for every format, so the two can''t diverge again."' + - 'done_when 2, verbatim: "Controls, measured on an .apr and a .safetensors model: sampled ≠ greedy for some seed; the same seed ×2 is byte-identical; seed A ≠ seed B; `--top-k 1` or T=0 is byte-greedy. The test is RED at 0.69.0."' + - 'done_when 3, verbatim: "Sibling sweep: every `sample*`/`argmax` site in aprender-serve and aprender-core generation paths is listed, and each one either uses the shared sampler or is justified."' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'SCOPE (issue title, amended by the cop from a8''s trace): SafeTensors run and every AprTransformer caller never sampled. `apr run` on .apr already sampled (run_apr_quantized_cpu_inference -> OwnedQuantizedModel::generate_with_cache, the GGUF sampler), which is measured below. ONE SHARED SAMPLER (done_when 1): new `realizar::sampling` with `draw(logits, temperature, top_k, top_p, r)` (the body moved verbatim from OwnedQuantizedModel::sample_topk_with_draw, which now delegates), `draw_seeded(.., &mut StdRng)`, `is_greedy(temperature, top_k)` (temperature 0 or top_k 1; top_k 0 disables the filter) and `DEFAULT_SEED` (42). Greedy stays each loop''s OWN argmax because the loops break ties differently (max_by keeps the last maximum, gguf ops::argmax the first), so greedy output is byte-identical. Routed through it: (a) AprTransformer `sample_from_logits` (apr_transformer/generation.rs), which took the ARGMAX of the top-k/top-p survivors and so could never draw. It is now seeded from a new `GenerateConfig.seed`, and `top_k_top_p_survivors` is deleted (the filter lives in the shared draw, pinned by the GGUF top-k/top-p rows). (b) The SafeTensors `apr run` CPU loop, `greedy_decode_with_transformer` -> `decode_with_transformer(transformer, input, &InferenceConfig)` (plain and sharded). It never read temperature/top_k/top_p/seed. (c) GpuModel `ops::sample_topk` and `kv_forward_block::sample_topk`: both sorted by probability and returned the first entry, the argmax. They are now seeded from a new `GpuGenerateConfig.seed` (chat takes the OpenAI `seed`). GREEDY-ONLY DECODERS: a sampled request no longer silently takes them. The SafeTensors CUDA `generate(input, max_tokens, eos_id)` and both wgpu loops (GGUF `try_wgpu_generate`, `try_apr_wgpu_inference`, each an inline argmax) run only when `is_greedy`; otherwise a notice is printed and the CPU loop that draws runs. The GpuModel `/v1/completions` handler hardcoded `top_k: 1`, so a request temperature did nothing; it now uses the CPU completions handlers'' rule (1 at temperature 0, else 40). #3754''s DEFAULT_TOP_K replaces that literal when both land. DEFAULT CHANGE: `apr_transformer::GenerateConfig::default()` temperature 1.0 -> 0.0. With the old argmax sampler every config, this default included, decoded greedily, so default callers (bench, serve /generate with no temperature) keep their output. A default of 1.0 with a real draw would have randomised them. Five rows that pinned 1.0 were updated with that reason. EXISTING ROWS THAT PINNED THE DEFECT: PMAT-820''s `neutral_params_byte_identical_to_legacy` and `top_k_ge_vocab_is_neutral` asserted that sampling at T>0 returned the argmax. They are replaced by sampler_tests (draws off the argmax; same seed reproduces, another seed changes; T0/top-k 1 is the argmax; top-k 2 bounds the draw). TESTS: sampling::tests (is_greedy table, the CDF walk, seeded reproducibility); apr_transformer::generation::sampler_tests (4); infer::tests_sampling_3760 through `run_inference` on the tiny SafeTensors fixture (sampled != greedy for one of 8 seeds, same seed identical and another seed differs, top-k 1 / T0 greedy on 4 seeds) plus `wgpu_serves_greedy_requests_only`; gpu::scheduler test_sample_topk_draws_off_the_argmax_and_is_seeded. MUTANTS, each run and each RED: AprTransformer sampler back to argmax (3 red); SafeTensors loop always greedy (2); SafeTensors seed ignored (1); GpuModel kv sampler back to argmax (1). MEASURED (done_when 2) on lambda, CPU, qwen2.5-coder-0.5b-instruct .apr and .safetensors, pinned via scripts/apr_bin.sh, 24 tokens. main `apr 0.69.0 (a9502d992)`: .safetensors sampled != greedy NO, seed 99 != 1234 NO (the defect); .apr YES/YES. Branch `(8760145f5)`: both formats sampled != greedy YES, same seed x2 IDENTICAL, seed 99 != 1234 YES, --top-k 1 == greedy YES, and greedy tokens byte-identical to main on both. wgpu: without --no-gpu on lambda (Qwen3-1.7B) main tries wgpu (Vulkan), its parity gate rejects it (cosine 0.870116), and it falls back to CPU. So main already sampled there, and the greedy-wgpu case is traced from code, not measured. On the branch a sampled request prints the notice and goes straight to the CPU. SWEEP (done_when 3): docs/audits/sampler-sweep-PMAT-3760.md lists every site in 4 sections: A routed through the shared sampler, B greedy-only decoders gated, C greedy by construction, D draws but not via the shared seeded draw, each with a named follow-up; the highest-priority follow-up is `sample_with_temperature` (wall-clock hash RNG) on serve''s APR Q4K GPU chat. SUITES at 8760145f5: aprender-serve lib 15920 passed; apr-cli lib 7300 passed; aprender-contracts lib 1689 passed; aprender-serve integration apr_coverage/apr_transformer_coverage/apr_transformer_deep_coverage 258+50+90 passed, and gguf_model_coverage, gguf_transformer_coverage, gpu_coverage, mock_gpu_flow and moe_kv_cache_equivalence 190+38+306+30+0(1 ignored) passed; clippy -D warnings clean on aprender-serve, apr-cli and aprender-serve --features cuda; fmt clean. `cargo check -p aprender-serve --features cuda --tests` fails ONLY on tests/gpu_cpu_trace_compare.rs (`missing field lm_head_tied`). That is pre-existing: this branch does not touch that file or AprTransformer, and gpu/tests/imp_1001d.rs notes that no CI job builds the cuda test profile.' +- id: PMAT-3770 + github_issue: 3770 + item_type: task + title: 'batch-1 combination break: check_release_bump_pr_body.sh fixture ladder receipts meet the current #3712 judge' + status: in_progress + priority: critical + assigned_to: null + created: '2026-09-21T00:00:00Z' + updated: '2026-09-21T00:00:00Z' + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'ISSUE (#3770): folding #3721 + #3738 into release/0.69.1-batch-1 (ded8a932a) turned scripts/check_release_bump_pr_body.sh RED on 4 rows (epic-and-refs, prs-only, ladder-missing-gx10, ladder-ignored) + the drop-refusal mutant, all ''STOP model-ladder receipts for 9.9.9 are not green in the bump tree''. The table runs the REAL scripts/check_model_ladder.sh on fabricated receipts that were the pre-#3712 shape (v1, no inventory; a fixture ladder with no inventory block; a seed tree without the producer the judge''s GPU-lock audit reads and without the cells module the judge imports). done_when (the cop, 2026-09-21): fixtures green under the current judge; the two refusal rows name their intended reasons; every other table that fabricates ladder receipts swept in the same commit; guard_tree --no-cargo on the branch shows only the two known complexity REDs. WHAT THIS DOES: write_receipt writes apr-model-ladder-receipt/v2 (inventory = the fixture rung''s file, candidates = that file read as a Q4_K member, the rung row names its file); the fixture ladder COPIES the real contract''s `inventory` block (never retyped, so it follows the tree''s inventory shape: row A''s patterns today, #3763''s candidates + member_dtype after it folds) and its rung names a file; the seed tree gets real copies of scripts/model_ladder.sh and scripts/lib/model_ladder_cells.py. SWEEP: the other tables that reference the ladder judge were run and need nothing: check_publish_preflight.sh --selftest (R7 rows all ok; it uses a judge STUB) and check_release_models_t1.sh --self-test (rc 0; stubs). MEASURED: check_release_bump_pr_body.sh --self-test PASS 12 rows (all 4 formerly-red rows ok; ladder-missing-gx10 names evidence/dogfood/models/9.9.9/gx10.json and ladder-ignored names ''are gitignored''; mutants drop-keep-open, drop-refusal, drop-ladder, drop-ignored all killed); the same table with #3763''s judge, producer and contract swapped in: PASS 12 rows.' +- id: PMAT-3774 + github_issue: 3774 + item_type: task + title: 'CRUX verb correspondence (#3739 amendments): every leaf of the derived apr surface maps to its llama.cpp / ollama / hf / llamafile counterpart, or `{none: reason}` per engine' + status: in_progress + priority: critical + assigned_to: aprender-76 + created: 2026-09-21T19:20:00Z + updated: 2026-09-21T22:00:00Z + spec: null + acceptance_criteria: + - 'Issue #3774 done_when 1, verbatim: "`evidence/crux/verb-correspondence.yaml` (`schema: crux-verb-correspondence/v1`) has exactly one entry per LEAF `key` of the surface `apr surface --json` emits (#3745 S1, `apr-cli-surface/v1`), hidden and foreign leaves included, with aliases counted as the same verb. It carries `surface: {source, sha256}` binding it to the emitted surface it was derived from." MEASURED: 253 entries = the 253 leaves of the `apr-cli-surface/v1.1` surface emitted by apr 0.69.0 (7ed033b63, branch PMAT-3745-s1-surface-emitter), sha256 207c3297…da2b. The entry key set equals the leaf key set, with no duplicates. Every `generates: true` leaf that maps no engine (embed, rerank, mcp, parity, rosetta compare-inference) has a specific reason; parity and compare-inference compare apr with apr, and their external comparison is the `run` cells.' + - 'done_when 2, verbatim: "Every entry has `comparators` with ALL FOUR engine keys (`llama.cpp: {binary, args}`, `ollama: {subcommand, args}`, `hf: {api, args}`, `llamafile: {binary, args}`), each either that mapping or `{none: }`. An entry with at least one mapping has `judged_by` ∈ golden | greedy_tokens | task." MEASURED: all 253 entries state all 4 engines; 16 verbs map at least one engine (run, chat, serve run, code, bench, quantize, pull, list, rm, tokenize encode-corpus, eval, inspect, tensors, devices, modelfile parse, import); 237 are `none` on every engine, each with a reason.' + - 'done_when 3, verbatim: "Measured at authoring and recorded, each with a negative control that fails: every mapped llama.cpp `binary` exists in the pinned build (d1d3c3396) and every mapped flag appears in its `--help`; every ollama `subcommand` and flag appears in `ollama --help` (0.33.2); every mapped apr flag is an arg of that verb in the surface." MEASURED: 7/7 llama.cpp binaries and 10/10 flags ok on gx10''s pinned build; 7/7 ollama subcommands plus `create --quantize` ok on lambda''s 0.33.2; every mapped apr flag is present in its verb''s surface args. The controls `llama-cli --frobnicate`, bin `llama-frobnicate` and `ollama frobnicate` all FAIL.' + - 'done_when 4, out of scope, verbatim: "the `hf` and `llamafile` mappings are declared here but verified against their pins by the engine worker''s rows, since the pins don''t exist yet; the SHACL reading is aprender-97''s S2; the cells for newly mapped verbs are later #3739 slices."' + - 'Added to #3774 at ~19:30Z (the cop: "You own the correspondence file columns (`hf` and `llamafile`) and the judge side (#3774)"), verbatim: "`scripts/lib/crux_inference_judge.py` treats `hf` and `llamafile` as comparators: RED when either is right and apr is wrong." MEASURED by `bash scripts/check_crux_inference_judge.sh`: 33 ok, 0 broke. New rows cover: hf right with apr wrong is RED; a llamafile refusal is quoted and, beside a right llama.cpp, the cell is GREEN; hf output that is not the contract JSON, or JSON with no `text`, is no oracle.' + - 'Verbatim: "`tok` rows ... and `tmpl` rows ... are byte-equal or RED, with the first differing index or byte named. An engine row with no apr row beside it is RED. A row the reference engine refused is UNJUDGED, and the run declines. `greedy` rows are REPORTED." MEASURED rows: equal tok ids are GREEN; differing ids are RED at index 1; an HF tok row without apr is RED; an HF-refused tok row declines rc 2; an equal tmpl is GREEN; the #3672 double wrap is RED at byte 17; greedy divergence at step 2 is reported with its logit cosine 0.7071 and no verdict.' + - 'Verbatim: "`scripts/crux_inference_dogfood.sh` exports `CRUX_MANIFEST` and `CRUX_WORK`, resolves `scripts/crux_engine_.{sh,py}` ... A missing script, a failing probe, or a `gen` that appends no row becomes a refused row naming why." MEASURED on lambda with a throwaway fake hf driver (never committed): probe recorded verbatim as `hf.probe`; 3 hf gen rows judged correct; the absent llamafile driver refused by name on every cell; the receipt table has 5 engine columns. The driver still reads no clock (0 rate tokens) and check_no_competing_harnesses stays count=0.' + - 'Mutation for the judge side: dropping the tok/tmpl mismatch-or-absent RED breaks 3 rows; not failing the run on a deterministic RED breaks 3; not declining a deterministic UNJUDGED breaks 1; dropping hf as a comparator breaks 1; not requiring the contract `text` field breaks 1; taking the logit cosine at the wrong step breaks 1. The slice-1 mutants still hold.' + - 'Added ~21:15Z, verbatim from #3774: "The GPU lock goes through gpu-q ... Each cell (one prompt, every engine) is written as one script and runs as ONE gpu-q command." MEASURED: the driver has no fd-9 lock left (0 hits for 9>&-/cell_lock/eng_run). On the gpu lane it runs `GPUQ_WAIT=$LOCK_WAIT gpu-q --prio ${CRUX_GPU_PRIO:-3} -- bash ` (the cop''s priority classes: CRUX development = 3, the train''s T-1 run passes 1) when `gpu-q --caps` lists `wait` (it does on lambda and gx10), else the bounded flock; `harness.gpu_lock` records which. On the cpu lane it records "none (cpu lane, the rule''s clause 2)".' + - 'Verbatim: "`evidence/crux/hf-sources.yaml` maps each GGUF (by sha256) to the HF source weights at a PINNED revision." MEASURED: cc324af0… maps to Qwen/Qwen2.5-Coder-1.5B-Instruct@2e1fd397 (bfloat16). Its GGUF provenance was checked through the HF API: the LFS sha256 of qwen2.5-coder-1.5b-instruct-q4_k_m.gguf in Qwen/Qwen2.5-Coder-1.5B-Instruct-GGUF@f86cb2c1 equals the local file''s.' + - 'Verbatim: "A degenerate answer is no answer, from any engine." MEASURED: case rows cover apr''s `!!!!…` as RED where llama.cpp answered, and hf''s `!!!!…` as unable to vouch. The mutant that removes the rule breaks 2 rows. The table is 35 ok, 0 broke.' + - 'Also measured (~21:45Z): a plugin engine is held to its lane as apr is. An hf/llamafile gen row must carry `reported.device` matching its lane (`cpu*` on the cpu lane, anything else on gpu), and a missing device is no answer. This came out of the integration run, where HF on the cpu lane reached the 4090 outside the GPU lock (infra-3c confirmed it and fixed their side in 9c806f008). Rows: hf on the CPU in the gpu lane, and hf with no device, are both UNJUDGED. Each mutant breaks 1. Cells also carry `positive_control` (aprender-97''s additive field for pv). The table is 38 ok, 0 broke.' + - 'INTEGRATION, lambda cpu lane, with infra-3c''s REAL engine drivers (PMAT-3778 @ e719fc11a, copied in untracked for the run and removed after): the hf probe was recorded verbatim (transformers 5.17.0, torch 2.14.0+cu130, lock sha256 be29a4f4…); hf gen rows were appended and judged; the absent llamafile install was refused by name ("probe exit 3: llamafile is not installed at … (forjar resource crux-llamafile, paiml/infra#906)"). It FOUND that the hf engine answered `!` × 64 on all 3 prompts (transformers left lm_head untied; reported to infra-3c), and that the golden greeting pattern scored it correct: #3782 and the degenerate rule above.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'Refs #3774 (child of #3739; the closing keyword goes on this PR only if the quorum passes it). SCOPE: evidence/crux/verb-correspondence.yaml, evidence/crux/hf-sources.yaml, scripts/lib/crux_inference_judge.py, scripts/crux_inference_dogfood.sh (the plugin-engine hook), scripts/check_crux_inference_judge.sh, and this fragment. STACKED on crux-3739-inference-dogfood (PR #3767), so the diff to judge is `origin/crux-3739-inference-dogfood...HEAD`. HOW IT IS MADE: a one-off authoring script, kept out of the tree, reads `apr surface --json` and writes the YAML. The committed file is the declaration, bound to its surface by sha256; the header says to re-derive when that sha changes. Engine-level `none` reasons state a fact about the engine. The mapped set follows the cop''s examples in the 17:19Z amendment (serve ↔ llama-server / ollama serve, tokenize ↔ llama-tokenize, bench ↔ llama-bench, quantize ↔ llama-quantize, pull/list ↔ ollama pull/list) plus the verbs whose counterpart is a real engine verb on the same file. `finetune` is `none`: at the pin, llama-finetune''s `--lora` loads an adapter and does not train one. `tokenize train/plan/apply/import-hf/repair-manifest` are tokenizer training/format verbs and map to none; only `encode-corpus` (text → ids) maps, to llama-tokenize / AutoTokenizer. Each mapped engine becomes a REQUIRED :CruxCell once S2 reads this file, so a mapping is a commitment, not a label.' +- id: PMAT-3775 + github_issue: 3775 + item_type: task + title: apr code -p --output-format json prints NO JSON envelope on a driver error (rc 1, stderr only) — a machine consumer cannot tell failure from nothing + status: in_progress + priority: critical + assigned_to: aprender-f8 + created: '2026-09-21T21:40:00Z' + updated: '2026-09-21T21:40:00Z' + spec: null + acceptance_criteria: + - 'Issue #3775 done_when 1, verbatim: "With `--output-format json`, EVERY exit, success or failure, writes exactly one JSON document to stdout. On failure it carries `{"error": {"kind", "message", "exit_code"}}`, plus `capacity` where #3720 / #3596''s CapacityRefused applies, and the same field names as #3720''s response contract (one schema, not a second copy)."' + - 'Issue #3775 done_when 2, verbatim: "Cases: the serve child fails to load; a model refused (0 layers, capacity); a tool error. Each gives a parseable envelope, rc ≠ 0, and a RED test at 0.69.0."' + - 'Issue #3775 done_when 3, verbatim: "Nothing but the JSON document on stdout (the #3606 "stream declared" rule); diagnostics go to stderr."' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'Minted by aprender-f8. The cop (aprender-04), verbatim: "(a) the JSON envelope missing on a driver error is a new 0.69.1 issue and **yours** (same area). Every exit writes exactly one JSON document to stdout, with the error fields matching fd''s #3720 schema (one schema)." The schema is the #3720 text aprender-f8 proposed (https://github.com/paiml/aprender/issues/3720#issuecomment-5767761121), which aprender-fd accepted (comment 5767765474), verbatim: "Accepted as written on #3720 (comment 5767765474), with one precision: `empty_completion` uses the command''s own inference-failure exit code (apr run 8, apr code 1), so nothing gets re-mapped." Fields: status ok|refused|failed; error {kind, message, exit_code} iff status != ok; capacity iff kind == capacity_refused; existing apr code fields (type/subtype/is_error/result) stay, is_error == (status != ok).' +- id: PMAT-3777 + github_issue: 3777 + item_type: task + title: '#3745 S2: cli-surface extractor + derived release cells (pairwise) — release-readiness-v1 targets the derived set, VERBS deleted' + status: in_progress + priority: critical + assigned_to: aprender-97 + created: 2026-09-21T19:20:00Z + updated: 2026-09-21T19:20:00Z + spec: null + acceptance_criteria: + - 'verbatim (#3745 issuecomment-5764661626 / -5765674584): S2.1 A pv extractor `cli-surface`, registered implemented in `contracts/ontology.yaml`, with its own pc_extract planted control (the #3706 Σ-tie).' + - 'verbatim (#3745 issuecomment-5764661626 / -5765674584): S2.2 The cell set is computed: every model-role command × host-inventory models × input shapes × mode args (a deterministic pairwise covering array) × thinking × rung. Commands without a model owe one runs-or-refuses cell. The derived cell count is printed in the receipt.' + - 'verbatim (#3745 issuecomment-5764661626 / -5765674584): S2.3 `release-readiness-v1` targets the derived set through `Inputs.cells`, and `release_evidence.rs`''s `VERBS` const is **deleted**. Issue mutants 1 and 2 are RED.' + - 'verbatim (#3745 issuecomment-5764661626 / -5765674584): S2.4 `:CruxCell` plus the per-verb CRUX mapping entry (#3739): a derived verb with no mapping entry is a violation.' + - 'verbatim (#3745 issuecomment-5764661626 / -5765674584): S2.5 The flag-effect oracle: for every derived **mode** arg, some cell must exist where toggling it changes the observable output: stdout bytes, the JSON fields, or the token ids. A mode arg with no observable effect on any cell is RED unless its typed marker (S1) declares it a no-op for that model class, with the class named. Sampling args additionally carry a8''s controls: sampled ≠ greedy for some seed; the same seed ×2 byte-identical; seed A ≠ seed B; top-k 1 / T 0 byte-greedy.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'Part S2 of #3745, routed by the cop (aprender-04). Cop rulings on the S2 design note (#3745 issuecomment-5765981405): D1 pairwise over modes ∪ {input shape, thinking, rung} per (command, model, host) (≈35k cells vs ≈280k for the literal product, measured on fc''s surface at 621a47862), plus a PROJECTED WALL TIME per host from measured medians (never guessed), long rungs per #3712 done_when 5 (qwen35 full, other archs one named representative); D2 an additive typed `generates` field on the surface (fc adds it to S1), never inferred from names; D3 one-factor-at-a-time cells for S2.5 per representative model per arch, plus `output_sha256` in cells[] (agreed with 62). Input: `apr surface --json` (apr-cli-surface/v1, fc #3749) from the release candidate, passed to pv as a file. Stdin: undeclared in v1, counted under a shrink-only ratchet with `unknown` (baseline 259, all foreign). Base: release/0.69.1-batch-1 (carries #3715); folds after S1.' +- id: PMAT-3778 + github_issue: 3778 + item_type: task + title: 'CRUX engine drivers for #3739: llamafile and HF transformers — probe/gen/tok/tmpl/greedy rows to row contract v1' + status: planned + priority: high + assigned_to: null + created: 2026-09-21T19:11:28Z + updated: 2026-09-21T19:11:28Z + spec: null + acceptance_criteria: + - "scripts/crux_engine_llamafile.sh probe prints llamafile's --version and the sha256 of the forjar-declared binary; gen appends one row per cell to $CRUX_MANIFEST (row contract v1), a cell llamafile cannot run being a row with rc null and llamafile's own error as refused" + - "scripts/crux_engine_hf.sh runs uv run --frozen over scripts/crux_hf/uv.lock (transformers[serving]==5.17.0, torch==2.14.0 exact); probe prints resolved versions, CUDA state and the lock sha256; gen/tok/tmpl/greedy append one row each, refusals quoting the exception" + - "measured on lambda-labs (receipt docs/audits/impl-PMAT-3778-receipt.md): llamafile loads qwen35; --cli ignores thinking control and -n, the server honours both; HF every path on CPU" + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: "#3739 engine seam, agreed with the cop (aprender-04) and aprender-76 (#3774, correspondence + judge). Stops at the receipt." +- id: PMAT-3785 + github_issue: 3785 + item_type: task + title: 'FP8 batched prefill diverges on sm_121 (GB10): qwen2.5-coder-7b BATCHED_PREFILL=1 fails F2 at pos 1 (cos 0.872) while FP8_PREFILL=0 passes — FP8 prefill off at cc >= 100' + status: in_progress + priority: critical + assigned_to: aprender-37 + created: 2026-09-21T16:20:00Z + updated: 2026-09-21T16:20:00Z + spec: null + acceptance_criteria: + - 'Issue #3785 done_when, verbatim: "**Immediate (cop ruling, correctness over speed):** FP8 prefill is OFF at cc ≥ 100 until this is root-caused, matching the documented intent. A test covers cc 89 → on and cc 100/120/121 → off, with a mutant. The gx10 7b BATCHED_PREFILL=1 cell goes green, and the chosen precision is printed in the trace."' + - 'Issue #3785 done_when, verbatim: "**Root cause:** the first op that diverges on sm_121 under FP8 batched prefill (per-op, as #3759 did), filed with the evidence. Re-enabling FP8 on Blackwell is its own row, gated on the same cell green."' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: '0.69.1 row (#3710). Filed and assigned by the cop, aprender-04, who ruled the policy: "FP8 prefill OFF at cc ≥ 100 until root-caused … correctness beats speed". Stacked on PMAT-3759. FINDING. With PMAT-3727, 3728 and 3759 fixed, qwen2.5-coder-7b Q4_K_M on gx10 (GB10, sm_121) with `BATCHED_PREFILL=1` still failed the F2 gate at pos 1 (argmax 198 = 198, cos 0.8720) and fell back to CPU. On that binary `FP8_PREFILL=0` was green, and `DIRECT_FP32_GEMV=1` stayed at 0.8716 (not the CPU reference). The same FP8 batched path is green on lambda (RTX 4090, sm_89). gx10''s default resolves serial prefill, so this was latent in the default configuration. `detect_fp8_prefill` documented "OFF for Blackwell", but the code enabled it at cc >= 89 (PMAT-410). Contract gpu-context-health-v1 said both: its equation had become `fp8_enabled = (cc >= 89)`, while its own GCH-INV-001 and FT-GPU-CTX-001 require false for every cc >= 100. None of its falsification tests named a test, so nothing ran the prediction. HOW done_when 1 IS MET. New pure `fp8_prefill_policy(cc, FP8_PREFILL)` in `cuda/gpu_profile.rs`: default ON for cc 89..100 (Ada, Hopper), OFF below and at cc >= 100 (`FP8_PREFILL_MAX_CC_EXCLUSIVE = 100`), with `FP8_PREFILL=0/1` still overriding. `detect_fp8_prefill` only reads the env and calls it. FP8 decode follows it through `detect_fp8_decode`''s existing fallthrough. Tests `fp8_prefill_policy_tests_3785`: a 12-row table (cc 75/86 off, 89/90 on, 100/120/121 off, the override forcing on at 121 and off at 89, garbage env values) plus an exhaustive sweep of cc 100..256 (the contract''s Kani bound). MUTANT: restore the PMAT-410 policy `cc >= 89` → both RED, first at `fp8_prefill_policy(cc=100, FP8_PREFILL=None)`. Trace: model init prints `[#3785] prefill GEMM precision: FP16|FP8 (E4M3) (cc=N; FP8 prefill defaults on for cc 89..100 only, FP8_PREFILL=0/1 overrides)`, unconditionally like the `[GH-129]`/`[PMAT-053]` lines beside it (the crate''s `verbose()` is REALIZAR_VERBOSE, not `-v`). Contract: the equation''s formula and invariants now say `89 <= cc < 100 unless FP8_PREFILL overrides`, with the #3785 measurement, and FT-GPU-CTX-001/003 name the test. done_when 2 (root cause: the first op that diverges on sm_121 under FP8 batched prefill) is NOT in this change and stays open on the issue; re-enabling FP8 on Blackwell is its own row, gated on the same cell. STOP LIST: no change to FP8 kernels or GEMM routing; only the default policy, its trace line, the contract and the test. MEASURED (gpu-q prio 1, binaries pinned by `--version`): gx10, binary `b88f96257`, `BATCHED_PREFILL=1`: trace "[#3785] prefill GEMM precision: FP16 (cc=121; …)", rc 0, `Backend: GPU (NVIDIA GB10)`, "The capital of France is Paris.", `apr qa` rc 0. Control, same binary plus `FP8_PREFILL=1`: trace "FP8 (E4M3) (cc=121; …)", pos 1 cos 0.8720 → rc 14. So the policy is the mechanism. (An earlier binary `73176dc4c`, the same policy without the unconditional trace line, gave the same pair: rc 0 with qa 3/3, and 0.8720 forced.) lambda, `b88f96257`, default: trace "FP8 (E4M3) (cc=89; …)", `[PMAT-053] FP8 weight cache: 197 matrices cached`, rc 0, GPU, "Paris", qa 3/3. FP8 is unchanged on Ada. This commit differs from `b88f96257` only by the restack onto PMAT-3759''s final fragment (no code). GATES: `cargo test -p aprender-serve --lib --features cuda fp8_prefill_policy` 2 passed; `cargo clippy -p aprender-serve --lib --features cuda -- -D warnings` rc 0; `cargo fmt --all -- --check` rc 0; `pv validate` and `pv lint contracts/gpu-context-health-v1.yaml` PASS. WITH THE STACK: qwen2.5-coder-7b is green on lambda default and gx10 `BATCHED_PREFILL=1`, which is #3728''s done_when 3.' +- id: PMAT-3786 + github_issue: 3786 + item_type: task + title: 'APR Q4K GPU chat: the request seed reaches a seeded draw through the shared sampler; the wall-clock-hash sampler is deleted (#3786)' + status: in_progress + priority: high + assigned_to: aprender-a8 + created: 2026-09-21T21:45:00Z + updated: 2026-09-21T21:45:00Z + spec: null + acceptance_criteria: + - 'Issue #3786 done_when 1, verbatim: "`sample_with_temperature` is removed, or delegates to `realizar::sampling::draw_seeded` with a `StdRng` seeded from the request''s `seed` (default `sampling::DEFAULT_SEED`). The APR Q4K scheduler threads the seed through."' + - 'done_when 2, verbatim: "The same request and seed twice give byte-identical output on the APR Q4K GPU chat path. A different seed gives different output. Temperature 0 or `top_k` 1 stays greedy. Each is a test that is RED at 0.69.0."' + - 'done_when 3, verbatim: "No wall-clock-derived randomness is left in any token-selection site (`git grep -n ''SystemTime::now().hash''` over the generation paths is empty, or each remaining hit is justified)."' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'STACKED on #3760 (fix/3760-shared-seeded-sampler @ 72db50867), which provides `realizar::sampling::{draw_seeded, DEFAULT_SEED}`. FIX: `AprQ4kRequest` gains `seed: u64`, and the three senders set it: `/generate` (api/batch.rs) and chat (api/cuda_chat_backend.rs) use `request.seed.unwrap_or(sampling::DEFAULT_SEED)`; `/v1/completions` (api/gpu_completions_handler.rs) uses DEFAULT_SEED because its request has no seed field. `generate_q4k` takes the seed and seeds ONE `StdRng` per request, and both sampled sites (first token, decode step) call the new ungated `q4k_sampled_token(logits, temperature, rng)` = `sampling::draw_seeded(logits, temperature, Q4K_TOP_K=40, 1.0, rng)`. Greedy is untouched (`temperature <= 0.01` -> `cli::inference::argmax`), so greedy output is byte-identical. `cli::inference::sample_with_temperature` (cli/apr_inference.rs), whose uniform draw was `hash(SystemTime::now())` and which also indexed `top[0]` of an empty slice at top_k 0, is DELETED; the Q4K scheduler was its only caller. done_when 3 sweep: `git grep -n ''SystemTime::now().hash''` over aprender-serve/src and aprender-core/src now finds only aprender-core/src/preprocessing/tsne.rs:328, t-SNE''s embedding initialisation, which is not token selection. TESTS (done_when 2, the sampler the GPU loop runs): api::apr_q4k_scheduler::sampled_token_3786: the same seed reproduces 32 draws byte for byte; a different seed changes them; the draw is not the argmax in disguise. MUTANT: q4k_sampled_token ignoring the request rng (an unseeded draw, the 0.69.0 behaviour) -> the_same_seed_reproduces_the_sampled_tokens RED. REAL PATH, measured and BLOCKED by a different defect: a `--features cuda` build of this branch (`apr 0.69.0 (2db3f55b2)`), `apr serve run qwen2.5-coder-1.5b-instruct-q4k.apr --gpu` on lambda''s RTX 4090, takes the Q4K path ("[GH-471] Entering Q4K GPU path"), but its forward emits degenerate logits. At temperature 0.8 every seed returns "HHHHHHHHHHHHHHHHHHHHHHHH"; temperature 0 fails `Invalid token ID: 151935` (vocab-1, the argmax of NaN logits). No template is applied (prompt_tokens 7), and GET /health answers 503 while it serves. With identical degenerate logits every seed draws the same token, so the path cannot discriminate the seed; the unit rows are the evidence. Reported to the cop as a separate defect. The cop routed that defect as #3791 (aprender-c7); a follow-up evidence commit re-measures the path once it lands. SUITES at this commit: `cargo test -p aprender-serve --lib` 15923 passed; `-p aprender-contracts --lib` 1689 passed; clippy -D warnings on aprender-serve, with and without `--features cuda`, clean; fmt clean.' +- id: PMAT-3791 + github_issue: 3791 + item_type: task + title: 'APR Q4K GPU serve path (ALB-095) emits garbage: ''HHHH…'' for every seed at T=0.8, Invalid token ID 151935 (vocab-1 = argmax over NaN) at T=0, no chat template (7 prompt tokens), and /health 503 while serving' + status: in_progress + priority: critical + assigned_to: aprender-c7 + created: 2026-09-21T21:54:05Z + updated: 2026-09-21T21:54:05Z + spec: null + acceptance_criteria: + - 'Issue #3791 done_when 1, verbatim: "Bisect: 0.69.0 / main / this branch, CPU vs GPU on the same .apr, and the first op producing NaN (per-op), with the result recorded."' + - 'Issue #3791 done_when 2, verbatim: "The Q4K GPU forward matches the CPU forward on this file (argmax equal, cosine ≥ the F2 floor over 64 positions). The F2 gate runs on this path too; if F2 doesn''t exist here, that''s part of the defect."' + - 'Issue #3791 done_when 3, verbatim: "The chat template is applied on this path through the SAME shared selector as run/chat (#3755''s rendering)."' + - 'Issue #3791 done_when 4, verbatim: "/health and /health/ready report ready on a serving Q4K server (a router test), sharing #3571 unit (2)''s model_loaded() fix, not a second copy."' + - 'Issue #3791 done_when 5, verbatim: "A cell (serve × APR Q4K × GPU) in the derived set is green on lambda and gx10."' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'Stacked on #3571 unit (2) (PMAT-3571-serve-qwen35-session-main @ d2c8a7793) per the cop, so model_loaded() is ONE predicate. BISECT (lambda, qwen2.5-coder-1.5b-instruct-q4k.apr): 0.69.0 (225b2a9ab) already has it — serve --gpu takes the ALB-095 pool path, /health 503 "loading", T=0 chat HTTP 500 `Invalid token ID: 151935`. The CPU forward is right (`apr run --no-gpu`: "The sea is a vast and mysterious body of water that stretches across the globe."). `apr run --gpu` on the same file is a DIFFERENT GPU path (OwnedQuantizedModelCuda, FP8 cuBLASLt prefill): F2 rejects at pos 3, cos 0.8934 — aprender-37''s FP8 row, not this one. ROOT 1 (the NaN): every GEMV in gpu/adapters/apr_q4k.rs launched a Q4_K kernel; the pool upload records each tensor''s type and this Q4_K_M file keeps 29 tensors at Q6_K (14 layers'' attn_v and ffn_down, and output.weight — the lm_head). Fix: quantized_gemv dispatches on the recorded type (Q4_K → q4k, Q6_K → q6k_gemv_cached, anything else REFUSED by name, never decoded as Q4_K); the batched QKV and gate/up launches batch only when every tensor involved is Q4_K. ROOT 2 (after ROOT 1, the text was "helf helf helf…"): the host-weight extraction read QKV biases (and Q/K norms) under HF names only, `.ok()`; this file names them GGUF-style (blk.N.attn_q.bias — 84 of them), so every Qwen2 bias was silently dropped. Fix: optional_f32 looks under both names, and a tensor present but unreadable is an error, not None. TEMPLATE: the Q4K state had cached_architecture None, so the shared selector (tokenize_chat_prompt → format_chat_messages → detect_format_from_name — the path #3755 changes) fell back to raw: 7 prompt tokens. apr-cli now passes the file''s declared architecture (AppState::with_architecture): 18 prompt tokens, "The vast, blue sea stretches across the horizon, reflecting the sun''s warm rays…". HEALTH: model_loaded() counts apr_q4k_tx in the same predicate as #3571''s qwen35 session; compute_mode gpu. TESTS: q4k_gpu_forward_matches_the_cpu_forward_under_the_f2_rule (real file + CUDA; the pool forward vs OwnedQuantizedModel::from_apr''s forward, 64 real positions, crate::infer::f2_multi_position_report: accepted, min cosine 0.9999); a_q4k_state_reports_loaded_and_gpu (no device). MUTANTS, measured: Q6_K decoded as Q4_K → RED "the GPU logits carry NaN/inf"; GGUF bias names removed → RED, accepted=false, min cosine 0.5350, argmax 374 vs 74403 at pos 1. SIBLINGS (cop''s ask): apr/cache.rs dispatch_quantized_gemv matches on qtype (12/13/14) — guarded. The executor''s dense layer paths (cached.rs, layers/ffn.rs, swiglu.rs) select Q4K kernels upstream of these call sites; not audited here beyond the GGUF Q4_K_M ladder rungs (mixed Q4K/Q6K) that pass on them. OPEN in this row, named: a RUNTIME F2 gate on this path at load (the parity test proves the forward; a load-time guard needs the CPU model, and this path exists for 17 GB MoE .apr files — design question to the cop), and the serve × APR Q4K × GPU cells on both hosts.' +- id: PMAT-3792 + github_issue: 3792 + item_type: task + title: 'shapes_gate complexity ratchet: pure refactor of run_shapes_gate_with, no behaviour change' + status: in_progress + priority: critical + assigned_to: aprender-97 + created: 2026-09-21T21:58:00Z + updated: 2026-09-21T21:58:00Z + spec: null + acceptance_criteria: + - 'Issue #3792 done_when 1, verbatim: "`run_shapes_gate_with` is no longer RED in `bash scripts/check_complexity_ratchet.sh`, via a PURE refactor with no behaviour change: the same answers, in the same order."' + - 'done_when 2, verbatim: "`cargo test -p aprender-contracts --lib` is green, and `pv lint contracts --gate shapes` passes with 8/8 pc_extract controls fired."' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'The cop (aprender-04) requested this, verbatim: "Please land a pure-refactor commit on a branch OFF release/0.69.1-batch-1 (not your old branch) that brings it under threshold with no behaviour change. Proof: `bash scripts/check_complexity_ratchet.sh` rc 0, `cargo test -p aprender-contracts --lib` green, and `pv lint contracts --gate shapes` 8/8 controls fired." SCOPE: this ticket IS the refactor. It is NOT #3715''s feature, which was already folded at ded8a932a; the diff against ded8a932a is only this refactor plus this fragment and receipt. The ratchet was RED on release/0.69.1-batch-1 (ded8a932a) vs main a9502d992: run_shapes_gate_with cyclomatic 13 cognitive 28 (the limit is 25). The fix moves the preamble (collect -> empty -> arming -> family, same order), the family ordering, the verdict rule and the two report maps into prepare / order_by_family / needs_receipts / verdict_of / by_shape / by_entity_type. MEASURED at 2a40dda85: the ratchet no longer lists run_shapes_gate_with (rc stays 1 only for crates/aprender-serve/src/constrain/tests.rs::generate_intent, not in this diff and not this ticket''s); cargo test -p aprender-contracts --lib 1701 passed; pv lint contracts --gate shapes Pass, 8/8 pc_extract fired; ont_release_readiness / ont4b / ont4c1 / ont4c3 CLI targets 34/11/12/10 passed; clippy -D warnings clean. A prior round under PMAT-3715 had a lane FAIL on SCOPE because it judged this delta against the #3715 feature ticket; the cop ruled that this refactor gets its own ticket.' +- id: PMAT-3793 + github_issue: 3793 + item_type: task + title: '#3568 PR 2/4: apr run --json-schema / --grammar on the CPU paths (dense GGUF + Qwen3.5) — the named refusals, a second-reader validator, finish_reason + prompt_tokens' + status: in_progress + priority: critical + assigned_to: null + created: 2026-09-21T23:26:26Z + updated: 2026-10-09T12:42:18Z + spec: null + acceptance_criteria: + - 'THIS PR IS #3568 PR 2 of 4 (#3793), per the design note https://github.com/paiml/aprender/issues/3568#issuecomment-5763921678, split item 2 verbatim: "`apr run` on the CPU paths (dense and Qwen3.5), with the flags, the refusals, the second reader and the `--json` fields." CUDA is PR 3; `apr serve` is PR 4.' + - 'Issue #3793 done_when 1, verbatim: **Flags:** "`apr run --json-schema ` and `--grammar ` (Lark). Both are validated **before the first token**. `--format json` is not overloaded."' + - 'Issue #3793 done_when 2, verbatim: **The CPU loops:** "**Dense GGUF, CPU:** apply it in the per-step sampler of `generate_with_cache`." and "**Qwen3.5 hybrid:** apply it in `run_qwen35_generate` on CPU". The mask only removes candidates: "Greedy / temperature 0 stays deterministic".' + - 'Issue #3793 done_when 3, verbatim: **Every path not wired is refused:** "Every other generation path **refuses** the flag by name until it is wired. A constraint that is silently ignored is decoration." In this PR that includes the CUDA paths (PR 3), with the refusal `SchemaUnsupportedPath{path}` and "an exit code and a `removed_by`".' + - 'Issue #3793 done_when 4, verbatim: **The refusals**, "each one line on stderr with a non-zero exit code": `SchemaInvalid`, `SchemaUnsupported{keyword, path}` with a `removed_by`, `SchemaUnsupportedPath{path}`, `SchemaWithThinking`, `SchemaViolation`, `Truncated`. "Per rmedia, a cut or empty completion is an error, never an empty success."' + - 'Issue #3793 done_when 5, verbatim: **Thinking:** the ruling (2): "`--json-schema` + a thinking template: refused by name (SchemaWithThinking) in 0.69.1." The 0.70 follow-up is #3735.' + - 'Issue #3793 done_when 6, verbatim: **A second reader:** "The final text is validated against the schema by a validator independent of the engine … before exit 0. Masking is one reader; this is the other."' + - 'Issue #3793 done_when 7, verbatim: **`--json` fields:** "`apr run --json` gains `finish_reason` (`stop | length | constraint_complete | dead_end`) and `prompt_tokens`."' + - 'Issue #3793 done_when 8, verbatim: **Positive controls:** "A malformed schema gives `SchemaInvalid` and a non-zero exit **before generation**, with no tokens emitted." "A valid schema with a violating prompt still gives conforming output." "A **mutant** that makes the constraint a no-op turns the corpus test RED."' + - 'Issue #3793 done_when 9, verbatim (amended by the author before review): **The corpus is the real consumer schemas:** a review tool''s output schema, and rmedia''s quiz, outline and key-terms schemas from #3716. The prompts include ones that ask the model to violate the schema, run here on the CPU paths. Every sample that exits 0 validates with the second reader, and every sample the budget cuts is refused (`Truncated`, non-zero), never reported as a success. *(Amended by the author before review, 2026-09-22: the design note''s "every sample validates" cannot hold for a sample that never completes. A greedy model can loop inside an unbounded string or number, and no budget completes that document. This was measured: the review schema''s `summary` and rmedia''s `seconds`, details in the comment below. The guarantee that holds, and that this PR tests, is that nothing non-conforming is ever reported as a success.)*' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'Refs #3568 (PR 2 of 4), #3793. apr run --json-schema / --grammar on the CPU paths (dense GGUF and Qwen3.5) through the one engine (#4263): Session::generate_constrained is Session::generate with the constraint masking host logits, never the greedy fast path. The named refusals (SchemaInvalid, SchemaUnsupported, SchemaUnsupportedPath, SchemaWithThinking, SchemaViolation, Truncated) exit non-zero with one stderr line; a second, independent validator checks the final text before exit 0; apr run --json gains finish_reason and prompt_tokens. Evidence is in the pull request.' +- id: PMAT-3795 + github_issue: 3795 + item_type: task + title: 'CRUX slice 3 (#3739): the chat verb — a two-turn conversation through apr chat, llama.cpp and ollama (pty-driven), hf and llamafile; judged on the final turn' + status: in_progress + priority: critical + assigned_to: aprender-76 + created: 2026-09-21T23:00:00Z + updated: 2026-09-21T23:20:00Z + spec: null + acceptance_criteria: + - 'Issue #3795 done_when 1, verbatim: "`scripts/crux_inference_dogfood.sh --verbs run,chat` runs a multi-turn conversation per model through every engine. A `chat` request without `run` declines, because the positive control lives in `run`." The prompt is `chat-arith-2turn`, the user turns "What is 2+2?" then "Now multiply that by 3.", judged on the FINAL reply (`expect_any ["12"]`); every reply is recorded.' + - 'done_when 2, verbatim: apr runs through `apr chat`, one user turn per stdin line; llama.cpp and ollama through `scripts/lib/crux_pty_chat.py`, a stdlib pseudo-terminal driver, because they do not take turns from a pipe. MEASURED before building it: llama-cli fed a pipe loops on empty `> ` prompts until killed; `ollama run` reads the whole pipe as ONE prompt and answers both turns in one reply. Driven through the pty helper, each held the conversation: llama-cli and ollama both gave ["2 + 2 equals 4.", "4 * 3 equals 12."]. hf and llamafile use `gen --verb chat` with the user turns (infra-3c, a3eecfe2d).' + - 'done_when 3, verbatim: "The judge scores the final turn with the same RED rule. `apr chat` reports no backend (#3794), so apr''s chat cells carry `backend_verified: false` and the receipt''s `not_covered` names it. The run-verb token-parity field isn''t reported as measured for chat."' + - 'done_when 4, MEASURED: `bash scripts/check_crux_inference_judge.sh` gives 42 ok, 0 broke. The chat rows: a GREEN chat; apr losing the first turn''s answer ("9") while llama.cpp carries it ("12") is RED; an apr transcript with no `Assistant:` turn is RED; and the record of every turn, `backend_verified: false`, and "not measured for the chat verb". Mutants: judging apr chat on the FIRST turn breaks 1; not recording backend_verified breaks 1; measuring chat as run breaks 1.' + - 'done_when 5, MEASURED on lambda (cpu lane, qwen2.5-coder-1.5b Q4_K_M, `--verbs run,chat`): PASS, 4 cells (3 run + 1 chat), 4 GREEN. In the chat cell apr, llama.cpp@d1d3c3396 and ollama 0.33.2 each gave ["2 + 2 equals 4.", "4 * 3 equals 12."]. hf and llamafile were refused by name (their drivers are on PMAT-3778, not yet merged). `not_covered` names apr chat''s unverified backend (#3794). No ollama import was left behind.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'Refs #3739 (slice 3; not a closing keyword for the parent). Closes #3795 when this merges. STACKED on crux-3774-verb-correspondence (#3789), so the diff to judge is `origin/crux-3774-verb-correspondence...HEAD`. SCOPE: scripts/crux_inference_dogfood.sh (the chat verb), scripts/lib/crux_pty_chat.py (new), scripts/lib/crux_inference_judge.py (chat parsing), scripts/check_crux_inference_judge.sh (chat rows), scripts/crux_inference_prompts.json (the chat prompt; the golden drift check covers only the golden rung), and this fragment. FOUND while building it: #3794, where `apr chat --no-gpu` still uploads the GGUF to CUDA (VRAM held outside the GPU lock; generation honours force_cpu, the load path does not) and apr chat reports no machine-readable backend. The pty helper starts only the argv it is given and reads no clock for a metric (its per-turn timeout is a bound), so the competing-harness count stays 0.' +- id: PMAT-3797 + github_issue: 3797 + item_type: task + title: 'CRUX slice 4 (#3739): the serve verb — apr serve, llama-server and ollama through ONE OpenAI client, streaming + non-streaming, plus hf/llamafile servers' + status: in_progress + priority: critical + assigned_to: aprender-76 + created: 2026-09-21T23:55:00Z + updated: 2026-09-22T00:40:00Z + spec: null + acceptance_criteria: + - 'Issue #3797 done_when 1, verbatim: "`scripts/crux_inference_dogfood.sh --verbs run,serve` runs ONE serve cell per model under one hold of the GPU lock: `apr serve run` and `llama-server` each load the model once, next to the running ollama daemon; every golden prompt goes through `scripts/lib/crux_openai_client.py`, non-streaming and streaming; then the servers stop, and ollama unloads (keep_alive 0, plus the unload wait)." Teardown kills every server before waiting, and waits on those pids only. The first real run hung here: a bare `wait` after the first kill blocked on the other server.' + - 'done_when 2, verbatim: "One client for every server. `crux_openai_client.py` sends the same body (model, messages, max_tokens, temperature, seed, stream) and writes the row-contract JSON `{\"text\", \"reported\": {device, stream, finish_reason, usage, chunks}}`. It reads no clock and computes no rate." MEASURED against the three servers on lambda (cpu): non-stream and stream both answer, and the usage is transcribed (apr serve prompt_tokens 18; llama-server and ollama 36).' + - 'done_when 3/4, verbatim: "Plugin engines (hf, llamafile) run `gen --verb ''serve run''` ... The judge reads every serve row through the client JSON and applies the same RED rule. The key gains an additive `mode` (nonstream | stream) for serve cells only. apr serve''s cells carry `backend_verified: false`." Per aprender-97 (#3715), the correspondence ENTRY for `serve run` declares `modes: [nonstream, stream]`, with per-engine modes (llama.cpp and ollama both, hf and llamafile nonstream), so pv never names a verb.' + - 'done_when 5, MEASURED: `bash scripts/check_crux_inference_judge.sh` gives 44 ok, 0 broke. The serve rows: stream and non-stream are distinct GREEN cells with apr serve''s backend unverified; an apr serve that answered nothing (connection refused) while llama-server answered is RED. Mutants: dropping the mode from the key breaks 1; dropping the serve backend flag breaks 1.' + - 'done_when 6, MEASURED on lambda (cpu lane, qwen2.5-coder-1.5b Q4_K_M, `--verbs run,serve`), rerun after the teardown fix and finishing unaided: PASS, 9 cells (3 run + 6 serve), 9 GREEN. apr serve, llama-server@d1d3c3396 and ollama 0.33.2 each answered every golden prompt in both modes. No server process and no ollama import was left behind. apr serve answers 2+2 with "4" from an 18-token prompt, where llama-server and ollama send 36 and answer "2 + 2 equals 4.": apr serve does not inject the GGUF template''s default system prompt. It is recorded; the byte-equal tmpl rows against HF are what will judge it.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'Refs #3739 (slice 4; not a closing keyword for the parent). Closes #3797 when merged. STACKED on crux-3739-chat (#3796), so the diff to judge is `origin/crux-3739-chat...HEAD`. SCOPE: scripts/crux_inference_dogfood.sh (the serve cell, the `serve` verb token mapped to key `serve run`, emit_gen/cell_result/rows_for carrying verb and mode), scripts/lib/crux_openai_client.py (new), scripts/lib/crux_inference_judge.py (serve parsing, the `mode` key part), scripts/check_crux_inference_judge.sh (serve rows), evidence/crux/verb-correspondence.yaml (`modes` on the serve run entry, regenerated from the same v1.1 surface, sha 207c3297), and this fragment. NOT in this slice and named in `not_covered`: TTFT and decode rate through `apr test llm bench` (the canonical client, PERF-009, the next increment), and max accepted context. The client computes no rate: check_no_competing_harnesses stays count=0.' +- id: PMAT-3801 + github_issue: 3801 + item_type: task + title: apr chat takes the detector every other verb takes (one TemplateFormat) + status: in_progress + priority: critical + assigned_to: aprender-c7 + created: 2026-09-22 08:01:24+00:00 + updated: 2026-09-22 08:01:24+00:00 + spec: null + acceptance_criteria: + - 'Issue #3801 done_when 1, verbatim: "`--thinking on` on run, chat, code and serve always ends in an + answer or a named refusal. A block unclosed at the think budget is closed by the guard and reported + (`reasoning_truncated`). No verb hangs to max_tokens inside ``."' + - 'Issue #3801 done_when 2, verbatim: "Qwen3.5-0.8B/2B/4B/9B/27B Q4_K_M golden, both legs, green on + lambda AND gx10 CUDA; the report names every guard-closed case."' + - 'Issue #3801 done_when 3, verbatim: "Mutants: the guard removed makes the 0.8B golden thinking leg + RED; a guard that fires silently (no `reasoning_truncated`) makes a case row RED."' + - 'Issue #3801 done_when 4, verbatim: "The llama.cpp comparison above is re-run as a case row (same + prompts, pinned d1d3c3396), so "the model does this too" stays measured, not remembered."' + - 'COP RULING (aprender-cop, 2026-09-22), verbatim: "Ruling on the fix: the detector unification IS + #3801''s remedy, and it is yours after #3817. `apr chat` switching to realizar''s `detect_format_from_name` + makes all four paths agree and deletes the blocker at its root, rather than making the non-terminating + mode terminate." and, on this row: "Unify the detector; do not bound the loop."' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'DIVERGES FROM THE ISSUE''S ''Decided design (aprender-fd)'' BY COP RULING, recorded on the issue + before any round: issuecomment-5773096497. The four done_when clauses above describe the think-budget + guard; this row implements the cop''s ruling instead and does NOT claim them. ROOT: apr chat imported + detect_format_from_name from aprender-core, whose TemplateFormat has seven variants (ChatML, Llama2, + Mistral, Alpaca, Phi, Custom, Raw) and NO Qwen3NoThink - so no-think was unrepresentable on that path, + not merely unselected, and chat_load_tokenizers.rs:120''s template_format_name match compiled with + no arm for it because it matched the other crate''s enum. apr serve, apr run --chat and (since #3724) + apr qa''s golden gate all take realizar''s detector. MEASURED BEFORE, apr 0.69.0 (3ebb1c61e), apr + chat Qwen3-1.7B-Q4_K_M --temperature 0: ''Detected ChatML chat template'' then ''Assistant: Okay, + the user is asking...''. MEASURED AFTER, apr 0.69.0 (1f992a5e3), same command: ''Detected Qwen3NoThink + (thinking off) chat template'' then ''Assistant: \n\n2 + 2 = 4.''. The banner''s private copy + of the name match is deleted in favour of the one template_format_name, which gained the two variants + the old enum could not express (Qwen3NoThink, Zephyr) - two copies of a match over an enum are how + a new variant gets handled in one place and not the other, which is this defect. qwen3_moe keeps plain + ChatML (PMAT-181, trained without blocks), pinned by a test. WHAT THIS DOES NOT DO: it does + not implement the think-budget guard and does not make the non-terminating mode terminate; it makes + that mode unreachable from the four verbs at their defaults. The guard remains the remedy for deliberate + --thinking on under #3723, a separate row not in 0.69.1.' +- id: PMAT-3807 + github_issue: 3807 + item_type: task + title: 'FP8 prefill recipe zeroes activations (per-batch E4M3 scale × subnormal flush-to-zero): qwen2.5-coder-7b apr run --chat fails F2 at pos 1 (cos 0.813) on the RTX 4090 default path and exits 14 on CPU' + status: in_progress + priority: critical + assigned_to: aprender-37 + created: 2026-09-22T00:58:00Z + updated: 2026-09-22T01:35:00Z + spec: null + acceptance_criteria: + - 'Issue #3807 done_when, verbatim: "GPU unit rows: every converter matches a CPU E4M3 reference on the subnormal range; an outlier-row FP8 GEMM matches f64 within tolerance. Mutants (restore FTZ; restore per-batch scale) go RED."' + - 'Issue #3807 done_when, verbatim: "#3751''s dense-F2 harness, 4 Qwen2.5 models × 3 prompts, lambda default: all ACCEPT with FP8 on. gx10 `FP8_PREFILL=1 BATCHED_PREFILL=1` coder-7b: ACCEPT."' + - 'Issue #3807 done_when, verbatim: "The cell above: rc 0, `Backend: GPU`, FP8 trace, no retry note."' + - 'Issue #3807 done_when, verbatim: "Prefill speed kept: `apr serve` timings.prompt_ms for a 500-token coder-7b prompt stays within 10% of today''s 45–50 ms."' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: '0.69.1 row, filed by aprender-37 as #3785''s done_when 2 (root cause) and proposed to the cop, aprender-04. Stacked on PMAT-3785. FINDING. With the #3672 single chat template (main a9502d992) plus PMAT-3727/3728/3759/3785, `apr run qwen2.5-coder-7b-instruct-q4_k_m.gguf --prompt "What is the capital of France? Answer briefly." --chat --gpu` on lambda (RTX 4090, cc 89, the DEFAULT batched FP8 path) encoded the same 18 tokens as #3751''s dense-F2 harness. It printed "GPU output diverges from CPU at position 1 (argmax 198 != 198, cosine 0.8134)" and exited 14 on CPU; with `FP8_PREFILL=0` it ran on the GPU. The gx10 `FP8_PREFILL=1 BATCHED_PREFILL=1` pos-1 0.872 (#3785) is the same fingerprint, so this is not sm_121-specific. MECHANISM. `cublas_prefill_fp8_gemm` scaled the whole [m x k] activation batch by ONE 448/absmax, and all three E4M3 converters (`f32_to_e4m3`, `_scaled`, `_device_scaled`) sent a biased exponent < 1 to zero, i.e. flushed subnormals. The down-projection inputs carry massive-activation outliers (7b: absmax 871 at layer 27, 352 at 26, 94 at 3), so every activation below absmax x 3.5e-5, up to 12.4% of a layer''s inputs, was zeroed on every token. A float64 emulation of that exact recipe (GGUF weights via `gguf.quants.dequantize`, per-tensor E4M3, FTZ, BF16 D) tracks the real GPU on 10 of 12 model x prompt rows, including both real REJECTs at the same positions (7b pos 1: 0.794 vs 0.813; qwen2.5-1.5b pos 11: 0.951 + argmax flip vs 0.949 + flip). REJECTED ALTERNATIVES (measured). FP8 prefill default OFF: the FP16 weight cache has no VRAM budget (7b: 13.5 GB vs 6.7 GB FP8); `apr serve --context-length 32768` then OOMs its FP16 warmup and a 1931-token prompt fails with CUDA_ERROR_OUT_OF_MEMORY, while FP8 serves it in 219 ms. Dropping the retry floor ALONE: the FP16 re-measure cached FP16 weights on top of the resident FP8 cache (~25 GB for the 7b on a 24 GB card). CHANGE, commit 1 (the recipe). New `cuda/executor/layers/cublas_prefill/fp8_recipe.rs`: `fp8_absmax_rows` (one 256-thread block per row, shared-memory tree), `fp8_quantize_rows` (per-row scale 448/absmax[row]; round to nearest even; saturates at 448 = 0x7E; below 2^-6 encodes the subnormal rne(|x| x 512) x 2^-9, where q = 8 is exactly the smallest normal''s code 0x08), `fp8_dequant_outer` (Y[t, c] = D[t, c] x act_absmax[t]/448 x w_absmax[c]/448) and `fp8_quantize_weight`. `get_or_cache_fp8_weight` stores a per-output-channel absmax vector (`fp8_weight_row_absmax`); `cublas_prefill_fp8_gemm` keeps a per-token absmax buffer (`fp8_act_row_absmax`, reused by PMAT-084''s K/V and up hits, and growing it invalidates the held activation), runs the GEMM with alpha 1, and applies both outer scales in the BF16 to F32 widening. D stays BF16 (#3728); it is now at most 448^2 x k. The per-tensor helpers (`absmax_reduce`, the three flushing converters, `bf16_to_f32_act_scaled`, `gpu_absmax`, `gpu_absmax_device`) are deleted, so nothing can reach the flushing encoder again. #3728''s range row now inserts a per-channel absmax vector instead of the per-tensor alpha. Commit 2 (the gate). The #3413 C FP16 retry skipped misses below F2_CATASTROPHIC_COSINE (0.90) on the premise that a second measurement cannot turn orthogonal logits into parity, but the retry switches the precision; it is not a second sample. With commit 1 alone, qwen2.5-coder-0.5b chat-zorblat measured 0.894 under FP8 and would have gone to CPU, while FP16 passes it. `f2_should_retry_without_fp8` now retries ANY FP8-batched miss, and `f2_remeasure_without_fp8` frees the FP8 weight cache first (FP8 stays off for that model afterwards). A defect outside FP8 still fails the FP16 re-measure and still rejects; no floor moved. F2_CATASTROPHIC_COSINE becomes test-only. HOW EACH done_when IS MET. (1) New `fp8_recipe_tests_3807.rs`. Quantizer row: every finite E4M3 value, every midpoint (ties), values just off each midpoint, saturation (450, 463.9, 500, 1e6) and sub-2^-10 values, all negated too, against a CPU nearest-with-ties-to-even reference; at least 40 are non-zero subnormal cases. Outlier row: 16 tokens x 256, token 0 carrying 871, the others at 0.01; 64 channels, channel 3 carrying an 8.0 outlier and channel 7 scaled by 3e-5; the weight goes through `fp8_quantize_weight`, the GEMM through `cublas_prefill_fp8_gemm`; the per-token relative L2 error must stay below 8% and the per-channel error (tokens 1..16) below 20%. MUTANTS, each built and run on the GPU: M1 (subnormals flushed in `fp8_quantize_rows`): quantizer row RED ("x=9.785156e-4: got 0x00, want 0x01", …). M2 (one activation scale per batch): outlier row RED, token 1 at 25.26%, channel 14 at 47.59%. M3 (one weight scale per tensor): outlier row RED, channel 7 at 55.11%. The correct recipe: token 4.65%, channel 8.07%, quantizer exact. Commit 2''s mutant (floor restored): `a_deep_fp8_miss_is_retried_on_fp16` RED. (2) PARTLY MET, stated as measured. The harness judges the FP8 logits WITHOUT the production FP16 retry. Lambda, combined tree (eb 5d909dda6 + this stack + commit 1), FP8 on, 12 rows: coder-7b 3/3 ACCEPT (chat-france 0.9977, was REJECT 0.813); coder-1.5b 3/3 ACCEPT; coder-0.5b 2/3 (chat-zorblat REJECT at pos 21, 0.894, argmax equal; was ACCEPT 0.9945 before commit 1); qwen2.5-1.5b 1/3 (chat-france REJECT at pos 11, 0.937, was already REJECT 0.949; chat-zorblat REJECT at pos 23, 0.976 with argmax flip, was ACCEPT 0.958). So "all ACCEPT with FP8 on" is NOT met: on Qwen2.5 at 1.5B and below, E4M3 sits at the F2 gate''s edge under every scaling recipe tried (the emulator''s 12/12 prediction for this recipe did not hold on the small models, which move chaotically between rows). What production does with those rows is commit 2''s measurement below: all 8 prompt cells run on the GPU. gx10 (sm_121), binary 084008f34 (commit 1), coder-7b `FP8_PREFILL=1 BATCHED_PREFILL=1`: trace "FP8 (E4M3)", batched, no retry note, no divergence, `Backend: GPU`, "The capital of France is Paris.", rc 0 (under #3785 this cell was pos 1 0.872, rc 14). coder-1.5b the same. (3) Lambda, binary `apr 0.69.0 (0c907e883)` (main a9502d992 + this stack + both commits), coder-7b chat-france: trace "FP8 (E4M3) (cc=89 …)", no retry note, no divergence, `Backend: GPU`, "The capital of France is Paris.", rc 0. (4) `apr serve` timings.prompt_ms, coder-7b, 499-token prompt, 4 warm requests: 45.8 / 46.2 / 47.7 / 49.8 ms (before: 44.5 to 49.3). PRODUCTION MATRIX, commit 2, same binary, `apr run --chat --gpu`, 4 models x {chat-france, chat-zorblat}: 8/8 rc 0, `Backend: GPU`, correct answers (Paris / Lima). coder-7b and coder-1.5b: FP8 accepted, no retry. coder-0.5b chat-france: FP8 accepted. coder-0.5b chat-zorblat: FP8 0.8938 → "re-measuring on the FP16 prefill path" → "[PMAT-053] Cleared FP8 weight cache: 24 matrices (99.8 MB freed)" → FP16 0.9686 → GPU. qwen2.5-1.5b chat-france: 0.9374 → FP16 0.9941 → GPU; chat-zorblat: 0.9639 → FP16 0.9970 → GPU. GATES: `cargo test -p aprender-serve --features cuda --lib` rows `cublas_prefill` 3 passed (both #3807 rows and #3728''s), `fp8_activation_cache` 7 passed, `pmat3477_f2_fp8_retry_tests` 4 passed, `pmat919` 8 passed; `cargo clippy -p aprender-serve --lib --features cuda -- -D warnings` rc 0 (verbose run shows clippy-driver on `realizar`); `cargo fmt --all -- --check` clean. NOT DONE / LEFT. done_when 2''s harness clause, see (2); a VRAM-driven precision policy (FP16 when its cache fits, FP8 only when it does not) would move the small models off E4M3 entirely, and is a separate row if the cop wants the harness clause. Re-enabling FP8 on cc >= 100 by default is #3785''s policy change, gated on the gx10 cell above, not in this row. STOP LIST: no change to which GEMM path a model takes, to #3785''s policy, to any F2 floor, or to CI workflows.' +- id: PMAT-3809 + github_issue: 3809 + item_type: task + title: 'test(serve): wire the dark FALSIFY-SRV/HTTP suite + guard that every src test file is declared' + status: inprogress + priority: high + assigned_to: aprender-tarball + created: 2026-09-24T19:05:00Z + updated: 2026-09-24T19:05:00Z + spec: null + acceptance_criteria: + - cargo test -p apr-cli --lib -- commands::serve::tests_contract_enforcement runs 25 tests, all pass + - scripts/check_src_test_files_wired.sh (guard_tree) exits 1 on a new undeclared src test file and on a stale baseline entry; --self-test case table passes + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-3810 + github_issue: 3810 + item_type: task + title: 'CI cuda-unit runs every cuda-gated aprender-serve lib test (cuda:: filter, single-threaded, SKIP fails) (#3810)' + status: planned + priority: medium + assigned_to: null + created: 2026-09-23T16:13:45Z + updated: 2026-09-23T16:13:45Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-3817 + github_issue: 3817 + item_type: task + title: apr run --gpu on qwen3moe refuses pre-load by name + status: in_progress + priority: critical + assigned_to: aprender-c7 + created: 2026-09-22 07:05:04+00:00 + updated: 2026-09-22 07:05:04+00:00 + spec: null + acceptance_criteria: + - 'Issue #3817 done_when 1, verbatim: "`apr run --gpu` on both qwen3moe Q4_K_M files **refuses pre-load, + by name**, naming the architecture (`qwen3moe`), citing #3714, and stating that CUDA support is 0.70.0. + It **never** runs on CPU under `--gpu`. Exit code is a refusal code, not 14-after-fallback."' + - 'Issue #3817 done_when 2, verbatim: "`apr run` **without** `--gpu` is unchanged and still works on + CPU (the CPU MoE path shipped in #3367, closed 0.69.0). A refusal that also breaks the working path + is a regression, not a fix."' + - 'Issue #3817 done_when 3, verbatim: "`apr qa` on a qwen3moe file emits its gates **as refusals with + reasons**, not as an empty JSON with `capability_match` and `golden_output` absent. Absence is the + bug; a named refusal is the fix."' + - 'Issue #3817 done_when 4, verbatim: "Every OTHER architecture''s `--gpu` behaviour is byte-identical. + Prove it with a case table, not by inspection: at minimum one dense Q4_K (qwen2.5-coder), one Qwen3.5 + rung, and one non-qwen model."' + - 'Issue #3817 done_when 5, verbatim: "**A planted mutant that removes the refusal turns a test RED**, + and the test names what it caught. Restoring the CPU fallback under `--gpu` must fail."' + - 'Issue #3817 done_when 6, verbatim: "The qwen3moe files are removed from lambda''s and gx10''s 0.69.1 + host inventory, and the release notes plus README state by name that 0.69.1 does not support qwen3moe + on CUDA, with a pointer to #3714. Landing the refusal without the inventory and the note leaves the + gate still owing the cell."' + - 'Issue #3817 done_when 7, verbatim: "Measured and recorded, because it decides how much of the above + is even needed: whether 30B-A3B at Q4_K_M **fits** the 4090 at the short rungs (4k/8k/20k), read from + the host receipt''s measured GPU memory — weights + KV-per-token x rung + workspace. If it does not + fit, those cells become legitimate RefusalCells and the inventory change shrinks accordingly."' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'ONE predicate: realizar::capability::no_cuda_forward_reason(arch) says why this build has no + CUDA forward, normalising every spelling the loader accepts (qwen3moe, qwen3_moe, Qwen3MoeForCausalLM, + Qwen3CoderForCausalLM, qwen3_5_moe). Its only arm is qwen3_moe because infer/inference_result.rs dispatches + that architecture to the CPU-only MoE generator and returns used_gpu=false unconditionally; deleting + the arm when #3714 lands is what turns the refusal off, so refusal and routing cannot drift. apr run + consults it BEFORE any print or load, refusing with NotImplemented = exit 12 (''this build cannot + do that''), deliberately NOT 14 (''it tried and fell back''). Reading a GGUF header is an mmap, so + the refusal does not touch the 18 GB behind it. apr qa: three changes. dispatch_gate turns a gate + that cannot RUN into a FAILED gate carrying the error, so no gate can empty the report again (before: + zero bytes of JSON, rc 5, capability_match and golden_output ABSENT). is_cpu_only_architecture admits + an architecture whose CUDA forward was never built, routing golden and throughput through the same + runtime entry point apr run uses. capability_match refuses by name instead of reporting ''all ops + supported by GPU'', which is true and misleading: no kernel is missing, the path was not built. MEASURED + on lambda, apr 0.69.0 (9f8836c71) BEFORE: apr run --gpu rc 14 after an 18 GB load and a CPU generation; + apr qa rc 5 with an EMPTY json and ''Validation failed: CPU generation failed: matmul weight has EMPTY + data buffer ... a MoE parent FFN tensor''; apr run --no-gpu rc 0, ''2 + 2 = 4.'' in 8.00s.' +- id: PMAT-3828 + github_issue: 3828 + item_type: task + title: 'P0: the release gate''s verb dimension computes over ONE verb — the ladder never runs serve, chat or code, and a live /api/chat defect walked through all three coverage surfaces' + status: planned + priority: critical + assigned_to: null + created: 2026-09-22T08:35:31Z + updated: 2026-09-22T08:35:31Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-3837 + github_issue: 3837 + item_type: task + title: 'The --features cuda lint surface has never been gated: clippy -p apr-cli --lib --features cuda is RED' + status: in_progress + priority: medium + assigned_to: aprender-dd + created: 2026-09-23T00:00:00Z + updated: 2026-09-23T00:00:00Z + spec: null + acceptance_criteria: + - 'cargo clippy -p apr-cli --lib --features cuda -- -D warnings exits 0' + - 'a gate that runs in a workflow lints the cuda axis, with flags passed literally and a planted RED proving it' + - 'other feature axes enumerated; any excluded one is named with a ticket' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-3839 + github_issue: 3839 + item_type: task + title: 'Coverage owes 0.69.1: 87.82% vs floor 88, and COVERAGE_EXCLUDE_REGEX has described a different tree since April' + status: inprogress + priority: high + assigned_to: aprender-9b + created: 2026-09-23T00:00:00Z + updated: 2026-09-23T00:00:00Z + spec: null + acceptance_criteria: + - 'The --skip substring defect is fixed: skips match intent, not substrings (operator ruling 2026-09-23: in scope)' + - 'Measured line coverage >= 88% on the release commit, with COV_FLOOR unchanged' + - 'A coverage gate that cannot measure reports "did not measure", never a coverage verdict' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'This branch covers the skip defect, the global-config mv hazard, and did-not-measure. The COVERAGE_EXCLUDE_REGEX repair is deliberately NOT here: per the ticket, it moves the denominator and must be its own change.' +- id: PMAT-3847 + github_issue: 3847 + item_type: task + title: 'ONT-4c: the first non-code contracts — README.md, CLAUDE.md, one .apr model file, one CSV — with their extractors' + status: planned + priority: medium + assigned_to: null + created: 2026-09-22T13:24:57Z + updated: 2026-09-22T13:24:57Z + spec: docs/specifications/paiml-ontology.md (paiml/infra, v4.11 §5 ONT-4c) + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-3855 + github_issue: 3855 + item_type: task + title: 'ONE GATE FRAMEWORK: one and only one way to build a gate (143 gates, 25 baselines, 39 ratchets)' + status: planned + priority: medium + assigned_to: null + created: 2026-09-22T15:13:29Z + updated: 2026-09-22T15:13:29Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:docs + notes: null +- id: PMAT-3947 + github_issue: 3947 + item_type: task + title: 'aprender-core has no IQ dequantizer, so tensor_contract cannot inspect three release-blocking models — port from the validated aprender-serve decoders' + status: inprogress + priority: high + assigned_to: aprender-9b + created: 2026-09-23T00:00:00Z + updated: 2026-09-23T00:00:00Z + spec: null + acceptance_criteria: + - 'Per-tensor census of the three files, measured before any code' + - 'tensor_contract inspects those tensors, with an external oracle and a positive control that FAILS on a wrong decode' + - 'The three rows go green on their own merits, without weakening tensor_contract or whitelisting a type; #3850 must not regress' + - 'Report as capability cells (model, quant, tensor type, crate) -> number and oracle' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'PR #3958. CPU dequant only; the CUDA IQ4 GEMV kernels are out of scope.' +- id: PMAT-3952 + github_issue: 3952 + item_type: task + title: 'CRUX: vLLM as a pre-release comparator engine; #3971 source-weight cache verification; #3964 ollama loads only inside + the GPU lock' + status: inprogress + priority: critical + assigned_to: aprender-83 + created: '2026-09-23T08:40:00Z' + updated: '2026-09-23T13:10:00Z' + spec: null + acceptance_criteria: + - '#3952 done_when: --engines ...,vllm produces vLLM gen rows on at least one host, judged by the unchanged rule; each host + where it cannot run records a named refusal; a planted mismatch (vLLM right, apr wrong) is RED in the judge case table' + - '#3971: both source-weight drivers (hf, vllm) hash every cached file against the name it promises and refuse by name on + mismatch; CRUX uses its own HF_HOME' + - '#3964 (operator: ''yes you may change ollama''): every CRUX ollama model load runs while the GPU lock is held, proven + by a behavioural check that catches a no-lock mutant' + - 'cop ruling: an unpinned comparator makes the cell RED (''oracle unpinned''), never a third state' + - 'cop (critical path): both source-weight drivers run in BATCH mode — one engine load per gen-batch call, row contract + v1 per item; plus `serve stream` for #3962 (aprender-19)' + - a stopped driver takes its engine children with it (SIGTERM left VLLM::EngineCore on gx10's card, aprender-dd) — including + under a pid namespace with the host's /proc (quorum lane 2) + - 'thinking-ON rows from hf/vllm split correctly when the official template prefills (Qwen3.5, #3990)' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'Fold, per the cop (aprender-6a): #3781 (PMAT-3778 hf+llamafile drivers) + PMAT-3952-crux-vllm (vLLM driver, #3971 + verification, batch mode, serve stream) + PMAT-3952-crux-vllm-judge (vllm comparator, unpinned-oracle RED, #3964 lock + check), on top of aprender-6c''s fix/3957-gate-hardening (F6), which this depends on. Stops at the receipt. | STATUS 2026-09-23: + the original done_when (vLLM gen rows on a host, a named refusal where it cannot run, planted vLLM-right/apr-wrong RED) + and the #3971/#3964/unpinned criteria were MET by fold2 (PMAT-3952-crux-fold2, folded into release/0.69.1-batch-2 at 66c911359; + quorum receipt docs/audits/quorum-PMAT-3952.json, 3/3 PASS). The follow-on branch PMAT-3952-crux-greedy2 carries driver + fixes under this ticket — the Qwen3.5 prefilled- split, the SIGTERM engine orphan, batch/serve-stream hardening, + the keep_alive lock check — and the F9 producer under PMAT-3957.' +- id: PMAT-3954 + github_issue: 3954 + item_type: task + title: 'aprender-mcp: generic McpServer over a caller-supplied ToolSet (blocks infra#917)' + status: planned + priority: medium + assigned_to: null + created: 2026-09-23T07:00:57Z + updated: 2026-09-23T07:00:57Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-3957 + github_issue: 3957 + item_type: task + title: '0.69.1 gate hardening (no GPU): sha-bound receipts, missing-field=FAIL, verb output oracles, CRUX judge strength, + DEFER exits 2 (+F1b, F8, F6 quorum-revised)' + status: in_progress + priority: critical + assigned_to: aprender-6c + created: 2026-09-23 00:00:00+00:00 + updated: '2026-09-23T13:10:00Z' + spec: null + acceptance_criteria: + - 'F9 (RED-MODEL attribution; cop ruling 2026-09-23 that the F9 producer and evidence belong to PMAT-3957): the CRUX producer + writes kind=greedy rows — apr and llama.cpp greedy ids on the identical GGUF, thinking ON and OFF, llama.cpp both on apr''s + own prompt ids (engine parity, prompt_source ''apr'') and on the model''s OFFICIAL template (prompt_source ''official''), + raw {generated_ids, generated_text with special tokens, greedy, special, max_tokens, prompt_ids, template_prompt_ids} + — for Qwen3.5-0.8B-IQ4_XS, 0.8B-Q4_K_M, 2B-Q4_K_M and the 4B control; the judge (aprender-36) reads the model defect off + the official rows only' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-3962 + github_issue: 3962 + item_type: task + title: 'CRUX producer: per-verb prompt sets (incl. hard prompts) + code verb + hf/vllm quorum rows — prompt-certification half (aprender-dd)' + status: in_progress + priority: critical + assigned_to: aprender-dd + created: 2026-09-23T00:00:00Z + updated: 2026-09-23T00:00:00Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-3972 + github_issue: 3972 + item_type: task + title: 'ONT-4c5: capability cells — a required ladder cell is oracle-proven or RED; Unknown{NotRun} on a required cell never arms (#3972, #4047)' + status: in_progress + priority: medium + assigned_to: aprender-pvl-a + created: 2026-09-23T18:17:18Z + updated: 2026-09-24T19:30:00Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-3975 + github_issue: 3975 + item_type: task + title: 'GH-3975: CudaExecutor::gemm m=1 GEMV path reads B as [n,k] against its [k,n] contract' + status: planned + priority: high + assigned_to: null + created: 2026-09-23T08:36:08Z + updated: 2026-09-23T08:36:08Z + spec: null + acceptance_criteria: + - Must-RED tests for every gemm caller at m=1 and m=2. + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-3994 + github_issue: 3994 + item_type: task + title: EPIC 0.71 Don't Leave Behind + MoE plan (#3994) + status: planned + priority: medium + assigned_to: null + created: 2026-09-23T11:00:36Z + updated: 2026-09-23T11:00:36Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:docs + notes: null +- id: PMAT-3997 + github_issue: 3997 + item_type: task + title: Debt ratchet 0.70→0.74 — step 1 quorum research plan (#3997) + status: planned + priority: medium + assigned_to: null + created: 2026-09-23T10:24:54Z + updated: 2026-09-23T10:24:54Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:docs + notes: null +- id: PMAT-3998 + github_issue: 3998 + item_type: task + title: 'EPIC 0.70.0 Fast Train: concrete plan under docs/ + 3-lane quorum deciding the epic''s open questions' + status: in_progress + priority: high + assigned_to: aprender-19 + created: 2026-09-23T12:30:00Z + updated: 2026-09-23T12:30:00Z + spec: docs/specifications/release-0.70-fast-train-plan.md + acceptance_criteria: + - 'A plan under docs/ gives every must-carry row of #3998 an owner-free done_when, the measured baseline with its source, and a first-green proof (a command or artifact that can fail).' + - 'The plan includes 0.70''s debt-ratchet slice (#3997, slice 1 of 5).' + - 'A 3-lane quorum (paiml-implement kind=docs, agy delegate, gpt-oss fallback on quota, never NO-VERDICT-and-park) reviews the plan and decides the epic''s open questions; its receipt is committed beside the plan.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:docs + notes: 'Assigned by aprender-cf (planning/triage cop), 2026-09-23, relaying the operator: "quorum decide. now use quorum and claud plan for each epic". Scope: plan + quorum receipt + one summary comment on #3998. No child issues and no milestone moves until operator review.' +- id: PMAT-3999 + github_issue: 3999 + item_type: task + title: EPIC 0.73 llama.cpp Parity plan (#3999) + status: planned + priority: medium + assigned_to: null + created: 2026-09-23T11:00:41Z + updated: 2026-09-23T11:00:41Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:docs + notes: null +- id: PMAT-4000 + github_issue: 4000 + item_type: task + title: EPIC 0.72 Agent Ready plan (#4000) + status: planned + priority: medium + assigned_to: null + created: 2026-09-23T11:00:38Z + updated: 2026-09-23T11:00:38Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:docs + notes: null +- id: PMAT-4001 + github_issue: 4001 + item_type: task + title: EPIC 0.74 Any Model plan (#4001) + status: planned + priority: medium + assigned_to: null + created: 2026-09-23T11:00:44Z + updated: 2026-09-23T11:00:44Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:docs + notes: null +- id: PMAT-4002 + github_issue: 4002 + item_type: task + title: EPIC 0.75 CRUX fine-tune/distill plan (#4002) + status: planned + priority: medium + assigned_to: null + created: 2026-09-23T11:00:47Z + updated: 2026-09-23T11:00:47Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:docs + notes: null +- id: PMAT-4016 + github_issue: 4016 + item_type: task + title: '#4016: llama.cpp fit is the placement gate for every model certification/test' + status: planned + priority: medium + assigned_to: null + created: 2026-09-24T00:44:37Z + updated: 2026-09-24T00:44:37Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-4023 + github_issue: 4023 + item_type: task + title: 'GH-4023: coverage-nightly produces a number again (port #3839 + killed-binary guard + per-module aprender-serve + scoped reports)' + status: planned + priority: high + assigned_to: null + created: 2026-09-23T21:54:34Z + updated: 2026-09-23T21:54:34Z + spec: null + acceptance_criteria: + - 'PR #4023' + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-4041 + github_issue: 4041 + item_type: task + title: 'apr-cli --no-default-features compiles and lints clean: gate the inference-only sites; add the axis to the feature-matrix lint' + status: in_progress + priority: high + assigned_to: aprender-75 + created: 2026-09-24T00:00:00Z + updated: 2026-09-24T00:00:00Z + spec: null + acceptance_criteria: + - 'cargo clippy -p apr-cli --lib --no-default-features -- -D warnings exits 0 (was 8 compile errors on main@49fe19c28)' + - 'supported, not dark: crates/apr-cli/Cargo.toml documents the minimal crates.io install; a gate runs the axis so it cannot rot again' + - 'the other single-feature axes are measured and each is green or ticketed' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-4059 + github_issue: 4059 + item_type: task + title: 'binary-debt #2: the KEPT binaries'' CLI tests are dark in CI; wire them capped, and refuse a spawning test target no lane runs (#4059)' + status: in_progress + priority: high + assigned_to: aprender-36 + created: 2026-09-24T00:00:00Z + updated: 2026-09-24T00:00:00Z + spec: scripts/check_bin_cli_tests_wired.sh + acceptance_criteria: + - 'every test target that SPAWNS a workspace binary (CARGO_BIN_EXE_, cargo_bin(, cargo_bin_cmd!) is derived from the tree (tests/.rs, tests//main.rs, [[test]], autotests=false) and is either on a --test line with its own -p package, or ledgered in scripts/bin_cli_unwired_baseline.txt; drift either way is RED' + - 'the ledger is a shrink-only set baseline (check_baseline_ratchets.sh)' + - 'the KEPT binaries'' dark targets (apr-cli, the aprender facade, aprender-profile, aprender-orchestrate) are wired as capped per-crate fragments, each wall time measured on lambda first; the one huge target (the MoE live falsifier, 157 s with a model) is ledgered to #4179 for a nightly model-host lane' + - 'check_bin_cli_tests_wired.sh --self-test kills planted mutants: no cargo_bin_cmd!, name-only wiring, no dir targets, no word boundary, no \-continuation join' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'pv (aprender-contracts-cli): all 17 CLI test files were already wired on main@aa7c6ef03; the issue body is stale on that point.' +- id: PMAT-4067 + github_issue: 4067 + item_type: task + title: 'APEX-2e: aprender-viz SvgEncoder::metadata(self, xml) -> Result — one block, first child of , bytes = payload + fixed wrapping (no timestamp/encoder/version), second call replaces; roxmltree well-formedness refusal; error.rs Error::SvgMetadataRefused; Cargo.toml roxmltree 0.20 (+1 Cargo.lock edge, already in the lock via usvg); NEW tests/svg_metadata.rs (6 tests); roadmap entry; NO workflow, NO PNG (#4068), NO publish (apex APEX-001 row EV-2e)' + status: planned + priority: medium + assigned_to: null + created: 2026-09-24T04:55:48Z + updated: 2026-09-24T04:55:48Z + spec: null + acceptance_criteria: + - 'RED (a) one block, placed first, bytes exactly +payload+; (b) two independently built encoders render byte-identical with the block present; (c) malformed payloads refused (unclosed, mismatched, bare & and <, a breakout, DOCTYPE/entity, mid-document XML declaration). cd crates/aprender-viz && cargo test -p aprender-viz --test svg_metadata: 6 passed; RED before the implementation (rc 101, no method metadata, no variant SvgMetadataRefused).' + - 'Mutations, each planted alone and restored sha-identical: timestamp in the rendered block (the spec plant) and timestamp at build time each red exactly_one_metadata_block_placed_first + two_independent_builds_render_byte_identical_with_the_block_present + well_formed_payloads_of_other_shapes_are_accepted_verbatim; parse check removed reds a_malformed_payload_is_refused_not_emitted; block moved after the background reds exactly_one_metadata_block_placed_first. An allow_dtd:false option turned nothing red (the wrapper already makes a payload DTD a parse error) and was removed rather than kept as an untestable defence.' + labels: + - kind:code + - apex-upstream + notes: 'apex APEX-001 row EV-2e (spec v4.23, apex#136). Consumer: apex EV-23b embeds EV-23''s provenance payload through this API. The spec row proposed metadata(self, xml) -> Self; a builder returning Self cannot refuse a malformed payload, so the signature is -> Result, recorded as a row amendment in apex. Ends at STOP(PUBLISH: aprender-viz ); the cop folds it into the 0.70 batch, unarmed.' +- id: PMAT-4070 + github_issue: 4070 + item_type: task + title: 'ONT-4d: subsumption in Σ; shapes inherit down the hierarchy' + status: in_progress + priority: high + assigned_to: aprender-19 + created: 2026-09-23T21:40:00Z + updated: 2026-09-23T22:10:00Z + spec: paiml/infra docs/specifications/paiml-ontology.md@948ae923 (ONT-4d, line 619; R-19) + acceptance_criteria: + - 'Row ONT-4d RED, verbatim: "Σ `subsumes` with a cycle → exit 3 `error: subsumes cycle `; a shape on `Code` rejects a `Kernel` instance that violates it (`focus_nodes_n` for the shape == instances of `Code` ∪ all sub-concepts); a sub-concept shape that *removes* a super-concept constraint → exit 1 `reject: weakens .`; `rdf:type` closure present in `contracts.nt` for every super-concept; export byte-identical across two runs."' + - 'Row ONT-4d change: "Σ `subsumes[]`; `extract:pv-contract` materializes the type closure; `shapes.rs` resolves `targetClass` through it; OWL writer emits `SubClassOf` axioms; `by_concept` in census."' + - 'Row ONT-4d mutation: "drop the closure materialization → the `Kernel`-under-`Code` fixture stops firing → RED."' + - 'Row ONT-4d probe: `present ''^subsumes:'' contracts/ontology.yaml && "$PV" lint contracts/ --gate shapes --format json` with `.inherited_shapes_applied>0 and .verdict=="Pass"`, and `rg -q ''SubClassOf'' contracts/ontology.ofn`.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + - orch:fable + - orch-basis:state + notes: 'Stacked on PMAT-4071 (ONT-2c): the probe greps SubClassOf in contracts/ontology.ofn, which ONT-2c''s writer produces. Real Σ edges are read off the concepts'' own docs: Kernel ⊑ Contract, Symbol ⊑ Code.' +- id: PMAT-4071 + github_issue: 4071 + item_type: task + title: 'ONT-2c: in-house OWL 2 EL writer; TBox check via the oracle, advisory' + status: in_progress + priority: high + assigned_to: aprender-19 + created: 2026-09-23T18:30:00Z + updated: 2026-09-23T20:50:00Z + spec: paiml/infra docs/specifications/paiml-ontology.md@948ae923 (ONT-2c, line 626; §3.8) + acceptance_criteria: + - 'Row ONT-2c RED, verbatim: "writer output re-parsed by the oracle equals the fixture''s axiom set; two writes byte-identical; every Σ key mapped or in `not_expressible`; `acyclic` yields no axiom; `tbox-report.json` has `advisory: true`; gate maps it to `Unknown{Advisory}`; inferred subsumption between distinct Σ concepts → `unintended_subsumptions` non-empty."' + - 'Row ONT-2c mutation: "write `acyclic` as transitive + irreflexive → oracle round-trip RED."' + - 'Cop ruling 2026-09-23 (aprender-cf, refined per infra-83): (B) told-closure in-tree, precondition-guarded, advisory; (A) ELK 0.4.3 via a JVM as the independent oracle, agreement required at the RELEASE gate only; no JVM is a `decline:` NOT MEASURED, RED at release; a planted unintended subsumption must go RED in both.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + - orch:fable + - orch-basis:state + notes: 'ONT-001 R-22: kind:code,orch:fable,orch-basis:state admits Fable or Opus. No Rust EL reasoner exists (infra ont-oracle-ledger [V 2026-09-14]); ELK 0.4.3 pinned (zip 965ad946…, jar de1fffaf…, Apache-2.0), sent to infra-83 for the ledger. The OWL oracle is its own detached crate tests/oracle/owl/: oxigraph (via shacl) enables oxrdf Triple and breaks horned-owl''s horned-pretty-rdf under feature unification (E0004, measured).' +- id: PMAT-4072 + github_issue: 4072 + item_type: task + title: 'ONT-3a: extract:code — bindings resolve fail-closed across the workspace, via syn' + status: completed + priority: high + assigned_to: aprender-ea + created: 2026-09-24T14:05:08Z + updated: 2026-09-24T18:00:00Z + spec: null + acceptance_criteria: + - paiml/infra docs/specifications/paiml-ontology.md row ONT-3a. `pv lint --gate bindings` fail-closed on the repo corpus (PV-ONT-028/029/030), ghosts allowlisted with a ticket (#4319), enforced by a lib test. + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'quorum 3/3 PASS on fe8c9dff7; proof:docs/audits/quorum-PMAT-4072-fe8c9dff7.json' +- id: PMAT-4073 + github_issue: 4073 + item_type: task + title: 'ONT-3b: formalization.yaml gains model_of; no model earns no L4' + status: completed + priority: medium + assigned_to: pvl-b + created: 2026-09-24T17:12:12Z + updated: 2026-09-28T08:40:00Z + spec: infra docs/specifications/PVL-001-pv-lean-gate.md + acceptance_criteria: + - pv lint contracts/ --gate refinement --format json reports verdict Pass, models 3 resolved 3, unrefined_baseline 76 + - proof-status L4 from the discharge requires a resolving extraction/simulation model_of for the theorem's module + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: Ported from feat/4082-4073-ev8b-ont3b@202d5c51d onto B3 (#4317); EV-8b half superseded by B3's 69ed3ac0e. proof:crates/aprender-contracts-staging/lean/formalization.yaml proof:crates/aprender-contracts/src/lint/refinement_gate.rs + evidence: 'Verified 2026-09-28 by aprender-6b on intel at PR-2 head 035b019866: pv lint contracts/ --gate refinement --format json -> verdict Pass, models 3 resolved 3, ghosts 0, unrefined 76 (= acceptance baseline 76). First measured 2026-09-26 by aprender-5d at fold/b3-onto-main @7061eb6dd.' +- id: PMAT-4074 + github_issue: 4074 + item_type: task + title: 'ONT-5: pv-sat offline behind a bin boundary; witness checked in the gate; two positive controls' + status: planned + priority: high + assigned_to: null + created: 2026-09-24T12:00:00Z + updated: 2026-09-24T12:00:00Z + spec: docs/specifications/paiml-ontology.md + acceptance_criteria: + - 'witness.rs: typed relations as propositional Horn (live ids are units, depends_on/refines imply, contradicts conflicts, supersedes withdraws a unit); census_id_set_sha256 + relations_sha256 name the witness; check() refuses any core that is not a derivation in the current graph and any model that falsifies a clause; pc_checker refuses fixtures/unsat-core-corrupt.json every run' + - 'pv lint --gate ont-consistency: PV-ONT-022 names the core, PV-ONT-023 a witness that does not check; exit 2 NoCheckable / WitnessStale (prints make contracts) / PositiveControlFailed; a malformed Σ exits 3; computed and NOT armed' + - 'pv-sat bin, private to its target (F-7: no mod sat in lib.rs): plant pc_reasoner draws [A, B, C] before it writes; every answer over a 500-seed sweep checks; the witness is byte-stable on rerun' + - 'make contracts runs pv-sat then pv lint --gate ont-consistency and fails if contracts/witness/ differs; contracts/ont-consistency-v1.yaml names 7 falsification tests that exist; ci/explicit-test-commands.d 460 (ont5_consistency_gate) and 470 (--bin pv-sat) run what workspace-test --lib cannot' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'ONT-001 §5 row ONT-5. Handed off by rmedia-82 at e4577f7bd. Receipt: docs/audits/impl-PMAT-4074-receipt.md' +- id: PMAT-4075 + github_issue: 4075 + item_type: task + title: 'ONT-4e: requires/ensures as first-class; Liskov rule on refines, witness-checked' + status: planned + priority: medium + assigned_to: null + created: 2026-09-24T12:05:32Z + updated: 2026-09-24T12:05:32Z + spec: docs/specifications/paiml-ontology.md + acceptance_criteria: + - 'schema: requires[] and ensures[] take the {id, statement, formal, formal_status} Clause shape; an invariant counts as a clause only when it carries formal_status; a non-list requires/ensures is PV-ONT-026 naming its file' + - 'liskov.rs: pre (B.requires implies A.requires), post (A.ensures implies B.ensures), inv (A.invariants implies B.invariants) over opaque atoms; check() refuses a chain from a different atom and a counter-model that hides or invents a violation; pc_checker refuses fixtures/liskov-corrupt.json every run' + - 'pv lint --gate refines: exit 1 reject naming "precondition strengthened (PRE-1)" / "postcondition weakened (POST-1)" / "invariant dropped"; prose is Unknown{Prose} naming the clause; legacy is Pass with liskov_pairs_checked 0; WitnessStale names make contracts; liskov_prose baseline ratchets down (PV-ONT-027); computed and NOT armed' + - 'pv-sat writes contracts/witness/liskov/.json after its own pc_liskov_reasoner plant fires; readme_gen prints Requires/Ensures/Invariants counts; contracts/ont-refines-v1.yaml names 6 falsification tests that exist; ci/explicit-test-commands.d 600 runs ont4e_refines_gate' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'ONT-001 §5 row ONT-4e. Stacked on #4248 (ONT-5) and #4137 (ONT-4d). Receipt: docs/audits/impl-PMAT-4075-receipt.md' +- id: PMAT-4076 + github_issue: 4076 + item_type: task + title: 'ONT-7: valid_under — kernel-kind contracts carry a world index' + status: planned + priority: high + assigned_to: null + created: 2026-09-23T20:51:06Z + updated: 2026-09-23T20:51:06Z + spec: null + acceptance_criteria: + - paiml/infra docs/specifications/paiml-ontology.md v4.12 @948ae923 row ONT-7 (:656), probe (:657). depends_on ONT-1, ONT-6. K̂ 60. Cop (aprender-cf) assignment 2026-09-23. + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-4077 + github_issue: 4077 + item_type: task + title: 'ONT-8: one evidence block — PROV-O names, one L-enum, every entity type' + status: planned + priority: high + assigned_to: null + created: 2026-09-24T08:42:58Z + updated: 2026-09-24T08:42:58Z + spec: null + acceptance_criteria: + - paiml/infra docs/specifications/paiml-ontology.md v4.14 row ONT-8, probe (:667). Stacked on PMAT-4076 (ONT-7), gate 16 (EV-11 PMAT-4166 takes 14/15). Cop (aprender-cf) assignment 2026-09-24. + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-4080 + github_issue: 4080 + item_type: task + title: 'PVL-2: proof-status resolves bindings; ghost binding is a reject' + status: planned + priority: medium + assigned_to: null + created: 2026-09-23T18:46:02Z + updated: 2026-09-23T18:46:02Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-4081 + github_issue: 4081 + item_type: task + title: 'PVL-3: one definition of L4/L5' + status: planned + priority: medium + assigned_to: null + created: 2026-09-23T18:28:10Z + updated: 2026-09-23T18:28:10Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-4082 + github_issue: 4082 + item_type: task + title: '#4082: PVL-8b — L4 credit from discharge-summary.json; lean-status discharged column; formalization.yaml validated' + status: in_progress + priority: high + assigned_to: aprender-ont + created: 2026-09-24T18:00:00Z + updated: 2026-09-24T18:00:00Z + spec: infra docs/specifications/PVL-001-pv-lean-gate.md + acceptance_criteria: + - pv discharge check --no-lake --validate-formalization exits 0 on the tracked record, 1 on a stale field + - pv proof-status --format json reports l4_source == discharge + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-4083 + github_issue: 4083 + item_type: task + title: 'PVL-001 EV-9 (part 1 of 2): provable-ladder runs on every PR, advisory; a forced skip is RED' + status: in_progress + priority: high + assigned_to: null + created: 2026-09-29T17:58:00Z + updated: 2026-09-29T17:58:00Z + spec: null + acceptance_criteria: + - Folded into #4588 (PR-2 of #4502), C78 cop ruling (a) 2026-09-29. The provable-ladder section runs ADVISORY (ci/sections.yml), not yet in gate.needs; a forced ladder SKIP must be RED, with a planted mutant proving the check sees it (scripts/ci/ladder_skip_is_red.sh), finding docs/findings/ev9-fat-driver-skip-is-success.jsonl. + - Making it required (ci.yml gate list) is a later step and an operator check-in; out of scope for #4588. + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-4101 + github_issue: 4101 + item_type: task + title: CB-200 back under its baseline, measured on every PR (#4101) + status: in_progress + priority: high + assigned_to: pvl-b + created: 2026-09-24T00:58:10Z + updated: 2026-09-24T00:58:10Z + spec: null + acceptance_criteria: + - 'paiml/aprender#4101: refactor the 0.69.1-cycle below-B definitions (CB-200 603 -> 598 on batch/0.70.0) and gate CB-200 per PR through a guard guard_tree.sh already runs' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + - cb-200 + - ratchet + notes: null +- id: PMAT-4102 + github_issue: 4102 + item_type: task + title: 'ci: a job''s per-run target dir is deleted when its last job ends (last-one-out, flock-guarded); size lever chosen from the measured by-kind split' + status: in_progress + priority: high + assigned_to: aprender-75 + created: 2026-09-24T00:00:00Z + updated: 2026-09-24T00:00:00Z + spec: null + acceptance_criteria: + - 'a CI job on gx10 leaves no run- target behind, pass or fail: du before/after one job AND a planted failing job (always() is the claim)' + - 'never a live sibling: a job that ends while another job of the run still holds the tree keeps it (cop ruling (A), 2026-09-24)' + - 'must-RED: two jobs finishing together delete exactly once, never zero, never twice, under one flock on the host-local fs (scripts/ci_run_target_release.sh --self-test)' + - 'the 64G is split by kind before a size lever is chosen; the lever''s before/after is measured on the same shard' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-4108 + github_issue: 4108 + item_type: task + title: 'guard_tree.sh: 0 executed checks (or fewer than planned) is a failure, never a pass (#4108)' + status: planned + priority: medium + assigned_to: null + created: 2026-09-23T21:56:06Z + updated: 2026-09-23T21:56:06Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-4110 + github_issue: 4110 + item_type: task + title: apr version names rc tag and commit + status: in_progress + priority: medium + assigned_to: aprender-ea + created: 2026-09-24T17:50:47Z + updated: 2026-09-24T17:50:47Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-4112 + github_issue: 4112 + item_type: task + title: 'GH-4112: ci.yml runs guard-tree + guard-cargo on fold pushes to release/** (operator-approved option B)' + status: planned + priority: medium + assigned_to: null + created: 2026-09-24T06:47:28Z + updated: 2026-09-24T06:47:28Z + spec: null + acceptance_criteria: + - 'Refs #4112. push.branches gains ''release/**''; every job but guard-tree/guard-cargo is excluded on a release push; both guard jobs unshallow there so resolve_base.sh can name merge-base(origin/main, HEAD). Guard: scripts/check_ci_release_fold_scope.sh (R1-R3, 8-case self-test; RED on main''s ci.yml with 11 violations).' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-4120 + github_issue: 4120 + item_type: task + title: check_crux_serve_code T2 + crux_cell_teardown signal pid 1 (the runner Listener in CI); guard_tree must isolate guards (#4120) + status: planned + priority: medium + assigned_to: null + created: 2026-09-24T00:32:40Z + updated: 2026-09-24T00:32:40Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-4122 + github_issue: 4122 + item_type: task + title: 'PVL-001 EV-5a: pin Mathlib, scoped Lean warning gate, orphan allowlist' + status: in_progress + priority: high + assigned_to: aprender-6c + created: 2026-09-24T00:00:00Z + updated: 2026-09-24T00:00:00Z + spec: null + acceptance_criteria: + - 'Issue #4122 done_when 1, verbatim: "the pinned build is reproducible from a clean cache"' + - 'done_when 2, verbatim: "the warning gate goes RED on a planted warning inside its scope and ignores one outside it"' + - 'done_when 3, verbatim: "the orphan allowlist goes RED on a new unlisted orphan"' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'Scope, verbatim from #4122: "pin Mathlib; add a scoped Lean warning gate; add an orphan allowlist. The Lean build runs on lambda ... No workflow edit." The branch also fixes the root lake build that is broken on main (a duplicate ProvableContracts.Alibi.alibi_slope_pos in Alibi.Basic and Alibi.Slopes; Slopes renamed alibi_slope_real_pos, contracts.nt regenerated by pv extract), without which no gate over the root build could be green. It also adds `lake exe cache unpack`, because `cache get` decompressed nothing on a fresh checkout. MEASURED on lambda from a fresh checkout at d18e411aa: 0 Mathlib modules elaborated, 16435 jobs, build.sh rc 0 in 804 s; check-orphans 162/103/59/59. A degraded same-family round (Sonnet 5 + Fable 5.1) passed at d18e411aa: docs/audits/quorum-GH-4122-pvl-5a-degraded.json.' +- id: PMAT-4127 + github_issue: 4127 + item_type: task + title: '#4127: drop unmaintained proc-macro-error/-error2 from published aprender (tabled 0.22, validator 0.21)' + status: planned + priority: medium + assigned_to: null + created: 2026-09-24T04:51:52Z + updated: 2026-09-24T04:51:52Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-4130 + github_issue: 4130 + item_type: bug + title: 'Published tarballs of aprender-core, aprender-orchestrate, aprender-cbtop, aprender-test-showcase ship integration tests whose path-only dev-dependencies cargo package strips' + status: in_progress + priority: high + assigned_to: aprender-dd + created: 2026-09-24T00:00:00Z + updated: 2026-09-24T00:00:00Z + spec: null + acceptance_criteria: + - 'scripts/package_tarball_build.sh (#4114) no longer reports aprender-core, aprender-orchestrate, aprender-cbtop or aprender-test-showcase RED' + - 'no sibling dev-dependency is re-versioned (PMAT-955 / preflight R6)' + - 'what a tarball drops is printed and counted, never a silent shrink: excluded targets in the gate NOT SHIPPED list, lib-test reads via the agreed *_or_skip run-time pattern (SKIP by name out of tree, PANIC in tree)' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-4133 + github_issue: 4133 + item_type: task + title: 'CI: direct guard steps run under setsid --wait (#4133)' + status: planned + priority: medium + assigned_to: null + created: 2026-09-24T01:27:53Z + updated: 2026-09-24T01:27:53Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-4139 + github_issue: 4139 + item_type: task + title: 'PVL-001 EV-6a: pv discharge check -- axiom subset pins; compiler-escape allowlist' + status: in_progress + priority: high + assigned_to: aprender-6c + created: 2026-09-24T00:00:00Z + updated: 2026-09-24T00:00:00Z + spec: null + acceptance_criteria: + - 'PVL-001 EV-6a probe (infra spec, amended infra#992): escape-allowlist.yaml and Axioms.lean tracked; `pv discharge gen-axioms $LEAN --check` rc 0; `pv discharge check $LEAN --no-lake` rc 0' + - 'accept: `lake env lean Axioms.lean` passes on the built tree; `pv discharge check $LEAN --strict` rc 1 until the 7 pending entries are confirmed; `cargo test -p aprender-contracts-cli --test pvl_discharge_check`' + - 'infra#992: MISSING-ROOT rc 1 for exact `ProvableContracts.<...>.` refs and capstones naming no theorem; labels rc 1 only when NOT in $LEAN/unresolved-labels.json; the gate never writes that file (make label-ratchet does)' + - 'mutations: `axiom pvl_mutation : False` in a Theorem file -> scan RED and subset pin RED; `@[implemented_by]` on a def -> allowlist RED' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'Stacked on EV-5a (#4122). Scope from #4139 and PVL-001 EV-6a as amended by infra#992 (cop relay, 2026-09-24). Also withdraws a false L4 claim: cooperative-matrix-gemm-v1 cited the AXIOM f16_accumulation_error_bound as its lean_theorem; the reference becomes the `none -- ...` sentinel. MEASURED on lambda: check with lake elaboration rc 0 (164 pinned, 85 ORPHANED-ROOT, 7 PENDING); --strict rc 1; the pvl_mutation mutation turns scan and pin RED.' +- id: PMAT-4142 + github_issue: 4142 + item_type: task + title: 'ci: the mutants gate mutates the WORKSPACE -- it was vacuous for crates/** (0 mutants on every crate diff)' + status: in_progress + priority: high + assigned_to: aprender-6c + created: 2026-09-24T00:00:00Z + updated: 2026-09-24T00:00:00Z + spec: null + acceptance_criteria: + - 'The PR mutants job lists and runs cargo-mutants with --workspace (the fix for #4142: without it every crate diff listed 0 mutants and passed -- measured on #3772/#3737/#3707/#3706)' + - 'OPERATOR ruling via the cop (2026-09-24, verbatim "go with recommended yes"): on-PR --workspace -j N with a RED "too many to judge" cap of ~60 mutants, plus a nightly full run' + - 'The gate refuses rather than passes: a failed list, a run that wrote no outcomes, an unparseable outcomes.json, and a tested count that differs from the listed count are RED' + - 'scripts/mutants_diff_gate.sh --self-test: every rule deleted in a copy breaks the row that names it' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'cargo-mutants 27 refuses `workspace = true` in .cargo/mutants.toml ("unknown field"), so the fix is the --workspace flag, which is a ci.yml edit approved by the operator through the cop. Measured on gx10 with the real tool: the #4139 diff at 820e8523 lists 270 mutants (269 at 9f5fbcc7b, the #4142 issue table) and the gate prints RED "too many to judge: 270 mutants in the diff > cap 60"; a README-only diff prints "0 mutants in the diff". Cost: ~85 s per aprender-contracts mutant, serially.' +- id: PMAT-4160 + github_issue: 4160 + item_type: task + title: 'pv-contract extractor: a class per entity type (ont:entity/), so a SHACL shape can target one entity type (apex EV-19b)' + status: in_progress + priority: high + assigned_to: aprender-75 + created: 2026-09-24T00:00:00Z + updated: 2026-09-24T00:00:00Z + spec: null + acceptance_criteria: + - 'a contract with entity.type T is also typed rdf:type entity/T, and `targetClass: entity:T` expands to exactly that IRI (pinned by a test)' + - 'accept-level (pv lint --gate shapes on a fixture): two entity types, two closed shapes scoped by entity class, Pass with no cross-firing' + - 'must-RED: the same two shapes scoped by ont:Contract cross-fire (the gap, measured); a planted wrong-type contract fails its type''s shape' + - 'apex: the study shape over all apex contracts passes and does not fire on the 18 claim contracts (acceptance run coordinated with apex-4c)' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-4166 + github_issue: 4166 + item_type: task + title: 'PVL-11: pv lint ratchets — theorem pairing and depends_on' + status: planned + priority: high + assigned_to: null + created: 2026-09-24T07:10:50Z + updated: 2026-09-24T07:10:50Z + spec: null + acceptance_criteria: + - paiml/infra PVL-001 EV-11 (00553b0b). Cop (aprender-cf) assignment 2026-09-24. + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-4179 + github_issue: 4179 + item_type: task + title: 'binary-debt: qwen3_moe live falsifier nightly, fail-closed' + status: inprogress + priority: medium + assigned_to: aprender-88 + created: 2026-09-24T16:20:28Z + updated: 2026-09-24T16:20:28Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-4186 + github_issue: 4186 + item_type: task + title: 'P0: dogfood hosts run ONLY the latest green nightly apr/pv — apr_bin.sh + pv_bin.sh refuse anything older (arbiter manifest, fail closed)' + status: in_progress + priority: critical + assigned_to: aprender-49 + created: 2026-09-24T00:00:00Z + updated: 2026-09-24T00:00:00Z + spec: null + acceptance_criteria: + - nightly mode (APR_BIN_REQUIRE / PV_BIN_REQUIRE=nightly) accepts only the manifest's green binary + - 'case table — stale/tagged/missing/malformed/stale-manifest/denylisted refuse; nightly accepts' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - P0 + - kind:code + notes: null +- id: PMAT-4189 + github_issue: 4189 + item_type: task + title: 'P0: nightly publishes every [[bin]] at main head with a SHA manifest (G5)' + status: in_progress + priority: critical + assigned_to: null + created: 2026-09-29T17:58:00Z + updated: 2026-09-29T17:58:00Z + spec: null + acceptance_criteria: + - Folded into #4588 (PR-2 of #4502), C78 cop ruling (a) 2026-09-29. nightly.yml derives the bin list from workspace metadata and builds every [[bin]] at the main head with a SHA manifest; binary-release.yml plus scripts/release/asset_version_check.sh refuse a version-mismatched asset; scripts/check_bin_names_aprender.sh (#4430) keeps shipped names aprender-*. Receipt docs/audits/impl-GH-4189-receipt.md. + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-4199 + github_issue: 4199 + item_type: task + title: 'PVL-001 EV-6b: pv discharge check --leanchecker -- non-fresh kernel re-check, bounded' + status: completed + priority: high + assigned_to: aprender-5d + created: 2026-09-24T00:00:00Z + updated: 2026-09-26T19:10:00Z + spec: null + acceptance_criteria: + - 'PVL-001 EV-6b probe (amended as EV-7b A-7b.1: the target is wired through ci/explicit-test-commands.d, so the literal can never appear in ci.yml): `cd "$WT" && tracked crates/aprender-contracts-cli/tests/pvl_discharge_leanchecker.rs && present -- ''ci_run_explicit_test_commands\.sh --run ci/explicit-test-commands\.d'' .github/workflows/ci.yml && bash scripts/ci_run_explicit_test_commands.sh --list ci/explicit-test-commands.d | present -- ''--test pvl_discharge_leanchecker( |$)'' && merged EV-6b`' + - 'probe arms MEASURED on 4cb4dffd2 (lambda, 2026-09-24): GREEN rc 0; 470-*.cmd removed rc 1; restored rc 0; ci.yml pointed at another directory rc 1; restored rc 0' + - 'RED: a stub `lake` on PATH whose leanchecker returns 1 -> rc 1; no lake -> rc 2; a toolchain without bin/leanchecker -> rc 2 `decline: leanchecker not in toolchain`, never rc 1' + - '`timeout lake env leanchecker ProvableContracts` (--leanchecker-timeout, default 3600 s; --leanchecker-ulimit-v KiB when set); a timeout rejects; timeout/ulimit/lake start failures (rc 125-127) decline' + - 'formalization.yaml `scope` states the non-fresh limitation: --fresh replays Mathlib and is the nightly''s (PVL-F7)' + - 'accept on lambda: `timeout 60m "$PV" discharge check "$LEAN" --leanchecker`' + - 'probe amended A-7b.2 (the runner moved from ci.yml to ci/sections.yml with the five fat jobs, so the A-7b.1 ci.yml arm now reads RED on a wired tree): `present -- ''ci_run_explicit_test_commands\.sh --run ci/explicit-test-commands\.d'' ci/sections.yml`; the .cmd is 471-*, renumbered from 470' + - 'A-7b.2 arms MEASURED on b1cd8c0b08 (lambda, 2026-09-26): GREEN rc 0; 471-*.cmd removed rc 1; sections.yml runner repointed rc 1; restored rc 0' + - 'MEASURED on b1cd8c0b08 (lambda, 2026-09-26): tests/pvl_discharge_leanchecker.rs 6/6 pass (accept, reject, no-lake decline, no-checker decline, --no-lake conflict, non-fresh scope); aprender-contracts --lib discharge 105/105' + - 'accept MEASURED on lambda 2026-09-26, pv built at b1cd8c0b08, after `lake build` (6877 jobs, rc 0, 74 s): `timeout 60m pv discharge check crates/aprender-contracts-staging/lean --leanchecker` from the repo root -> rc 0 in 289 s (ROOTS 250 pinned; leanchecker ok, 8 threads, MemoryMax=24G CPUQuota=800%)' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'proof:crates/aprender-contracts-cli/tests/pvl_discharge_leanchecker.rs. Stacked on EV-6a (#4139). Absent vs failed is decided by probing `lake env printenv LEAN_SYSROOT` for bin/leanchecker, because MEASURED on elan v4.15.0 `lake env leanchecker` exits 1 "does not have the binary" -- the rc alone would read a missing checker as a failed proof.' +- id: PMAT-4200 + github_issue: 4200 + item_type: task + title: 'PVL-001 EV-7a: pv challenge gen/check -- pin each contract-bound statement apart from its proof' + status: in_progress + priority: high + assigned_to: aprender-dd + created: 2026-09-24T00:00:00Z + updated: 2026-09-24T00:00:00Z + spec: null + acceptance_criteria: + - '`pv challenge gen contracts $LEAN` writes $LEAN/Challenge/.lean: every bound root X restated as `theorem _root_.PvlChallenge.X := sorry` inside the scope frames still open at its declaration' + - '`pv challenge check contracts $LEAN` rc 0 when fresh; rc 1 on an extra, missing or differing file or an unrestated root; rc 2 on zero challenges or an unloadable tree' + - 'lint gate 13 `challenge-fresh` = check; skipped when no lean base or no challenge exists' + - 'mutation: a hand-edited challenge statement turns check RED (`cargo test -p aprender-contracts-cli --test pvl_challenge`)' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'Stacked on EV-6a (#4139). Consumed by EV-7b (aprender-98). Frames, not `open`: an opened namespace loses the current-namespace priority (alibi `dist` was ambiguous, Alibi.dist vs Dist.dist); a `_root_.` decl inside the reopened namespace resolves as the source does, and a sibling name reads the solution (lean v4.29.0-rc4 core probe). challenge-fresh is NOT armed in lint-baseline.json; it moves only via make ont-ratchet.' +- id: PMAT-4201 + github_issue: 4201 + item_type: task + title: 'PVL-001 EV-7b: comparator -- the solution closes exactly the pinned statement' + status: in_progress + priority: high + assigned_to: aprender-98 + created: 2026-09-24T00:00:00Z + updated: 2026-09-24T00:00:00Z + spec: null + acceptance_criteria: + - 'PVL-001 EV-7b: $LEAN/scripts/Comparator.lean (run via `lake env lean`) prints NDJSON {name, challenge_type_hash, solution_type_hash, axioms}; `pv discharge check --comparator`: hash mismatch rc 1, solution missing MISSING-ROOT rc 1, zero rows rc 2' + - 'SHA-256 statement hash over canon (binder names dropped, binder info kept), FIPS --self-test; a solution row with no axioms list is MALFORMED (fail closed)' + - '`proved-is-derived` is NOT in this row: per cop ruling option (1) 2026-09-24 it is born armed in EV-8a (#4202), with underived_proved_claims=95 shrink-only (PVL-001 A-7b.2)' + - 'probe (amended per cop ruling 2026-09-24, PVL-001 A-7b.1): crates/aprender-contracts-cli/tests/pvl_comparator.rs wired through ci/explicit-test-commands.d, which ci.yml consumes; removing the .d entry turns the probe RED' + - 'mutation: strengthen a hypothesis of a solution theorem -> hash mismatch RED' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'Stacked on EV-6b (feat/4199-pvl-6b-leanchecker @4cb4dffd2, on EV-6a b536fd686); rebases onto EV-7a (#4200, aprender-dd) when it lands. Cop assignment (aprender-cf, 2026-09-24).' +- id: PMAT-4207 + github_issue: 4207 + item_type: task + title: '#4207: lint tests read the shared /tmp as their project root — nest each corpus in a private tempdir' + status: planned + priority: medium + assigned_to: null + created: 2026-09-24T10:55:00Z + updated: 2026-09-24T10:55:00Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-4215 + github_issue: 4215 + item_type: task + title: 'Qwen3.5 CUDA greedy decode: persistent embedding buffer, GPU argmax, no format!/Vec on the launch path' + status: inprogress + priority: high + assigned_to: null + created: 2026-09-24T08:28:19Z + updated: 2026-09-24T20:45:00Z + spec: null + acceptance_criteria: + - 'A steady-state greedy decode token makes 0 host heap allocations, 0 device allocations and downloads exactly the 4-byte token id (counted, not asserted by reading).' + - 'Greedy on the device is token-identical to the CPU argmax of the downloaded logits at temperature 0.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'Scope is #4215 (a)(b)(c) from /mnt/nvme-raid0/tmp/alt0693/REPORT.md §A. Measured +2% at 850 on 4B (78.3 -> 79.9 tok/s); the 0.58x gap to ollama is NOT closed by this slice.' +- id: PMAT-4219 + github_issue: 4219 + item_type: task + title: every [[bin]] --version prints the build SHA (shared build-sha) + status: inprogress + priority: medium + assigned_to: aprender-88 + created: 2026-09-24T14:05:08Z + updated: 2026-09-24T14:05:08Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-4228 + github_issue: 4228 + item_type: task + title: 'perf(cpu): multi-row K-quant GEMM + batched Qwen3.5 prefill (CRUX #4223 T1)' + status: inprogress + priority: high + assigned_to: aprender-88 + created: 2026-09-24T17:44:32Z + updated: 2026-09-24T21:58:00Z + spec: null + acceptance_criteria: + - 'FALSIFY-4228-001..003: multi-row Q4_K x Q8_K GEMM bit-identical to the per-token matvec; token-major; bad shapes rejected' + - 'FALSIFY-4228-004/005: batched prefill bit-identical (logits, recurrent state, KV) to per-token on Qwen3.5 0.8B and 4B' + - 'FALSIFY-4228-006: Q5_K/Q6_K multi-row GEMMs bit-identical to the per-row matvec (NaN payload canonicalized); FMA mutant goes RED' + - 'CPU prefill tok/s at 850 and 4k, n>=3 with spread, same GGUF as the #4223 row, load1 < cores' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-4233 + github_issue: 4233 + item_type: task + title: Qwen3.5 CUDA decode step as a CUDA graph + status: planned + priority: high + assigned_to: null + created: 2026-09-24T17:12:39Z + updated: 2026-09-24T17:12:39Z + spec: null + acceptance_criteria: + - Indirect rope/attention/KV-scatter kernels + manual graph capture of Qwen35CudaModel::forward_single behind QWEN35_CUDA_GRAPH=1. + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-4242 + github_issue: 4242 + item_type: task + title: 'sovereign-update shared crate: update check + update subcommand' + status: planned + priority: medium + assigned_to: null + created: 2026-09-24T09:28:46Z + updated: 2026-09-24T09:28:46Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-4244 + github_issue: 4244 + item_type: task + kind: code + title: 'PVL-001 EV-6c: 59 Lean modules unreachable from root' + status: planned + priority: medium + assigned_to: aprender-ea + created: 2026-09-24T16:52:28Z + updated: 2026-09-24T16:52:28Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-4250 + github_issue: 4250 + item_type: task + title: '0.69.4 G0: serve-level test fails unless apr serve prefills Qwen3.5 batched (#4250)' + status: planned + priority: medium + assigned_to: aprender-ac + created: 2026-09-24T10:04:37Z + updated: 2026-09-24T10:04:37Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-4252 + github_issue: 4252 + item_type: task + title: 'Mandatory apr dogfood: apr serve Qwen3.5-4B as an advisory 4th quorum lane (gx10 CUDA primary, yields on any need for the box; lambda CPU fallback opt-in and only at load1 < 24) (#4252)' + status: inprogress + priority: high + assigned_to: aprender-6c + created: 2026-09-24T11:30:00Z + updated: 2026-09-25T12:00:00Z + spec: null + acceptance_criteria: + - 'gx10 serve runs --backend cuda --gpu-layers all; an answer is labelled gx10-cuda only with used_gpu true and the server pid holding GPU memory (#4089)' + - 'Any need for the box (gpu lock, queue, foreign GPU app, claim file, disk/mem alarm) stops the gx10 server by recorded pid; the ask records unavailable, or passes to lambda CPU only when opted in and load1 < 24' + - 'AMENDED 2026-09-25 (OPERATOR, verbatim, relayed by the cop aprender-77): "lambda fans are loud. Your 4B CPU apr lane (io-admit-4b, dogfood4252, about 8 cores) moves to gx10 now. Keep lambda CPU runs only when load1 < 24 (infra#1087 row 5). Do not start new lambda-CPU apr runs." So the lambda leg runs only with --allow-lambda/--force-lambda AND load1 < 24; otherwise it is recorded not-tried with its reason' + - 'Mutation proof: planted hold -> watcher YIELD -> the ask is unavailable by default, or lambda answers when opted in at load1 < 24 -> watcher resumes' + - 'The lane never hangs a quorum: one hard budget per ask, verdict unavailable on expiry; advisory, counts=false' + - 'Every serve failure is filed under #4252' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: "Landed on batch/0.70.0 by aprender-60 without scripts/bench_serve_4252.py (PERF-009); #4282 closed." +- id: PMAT-4256 + github_issue: 4256 + item_type: task + title: release assets carry git sha + status: in_progress + priority: medium + assigned_to: aprender-ea + created: 2026-09-24T17:50:48Z + updated: 2026-09-24T17:50:48Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-4258 + github_issue: 4258 + item_type: task + title: 'Qwen3.5 CUDA: q8_activation_valid is never cleared on the qwen35 path, so DP4A reuses a stale Q8_1 activation' + status: inprogress + priority: high + assigned_to: null + created: 2026-09-24T10:25:13Z + updated: 2026-09-24T12:01:41Z + spec: null + acceptance_criteria: + - 'A DP4A GEMV requantizes its input whenever the input buffer differs from the cached Q8_1 activation or a qwen35 writer kernel (rmsnorm_into, per_head_rmsnorm_into, residual_add_into, fused_swiglu_into, gdn_sigmoid_gate_into) rewrote it; a red-first test covers both.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'Found in /mnt/nvme-raid0/tmp/alt0693/REPORT.md "Extra finding". The DP4A-catastrophic falsifier now passes parity at every position on 0.8B; re-measure the #4030 pin on 2B/4B.' +- id: PMAT-4259 + github_issue: 4259 + item_type: task + title: 'GPU argmax kernel keeps the later index on an exact tie; CPU argmax keeps the first — breaks greedy token identity once #4215(b) moves argmax to GPU' + status: inprogress + priority: medium + assigned_to: null + created: 2026-09-24T12:01:41Z + updated: 2026-09-24T12:01:41Z + spec: null + acceptance_criteria: + - 'The GPU argmax returns the FIRST index of an exact maximum, as the CPU argmax does; a red-first tie-break falsifier covers ties within a thread, across threads, and across blocks.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'Ported from c8ce988c3 (perf/4215, based on 0.69.3) onto main; prerequisite for #4215(b), greedy GPU argmax.' +- id: PMAT-4261 + github_issue: 4261 + item_type: task + title: 'Qwen3.5-9B has no temp-0 refs: 0.69.3 G1 shows 9B SKIPPED; refs owed before 0.69.4 acceptance' + status: inprogress + priority: high + assigned_to: null + created: 2026-09-24T16:47:18Z + updated: 2026-09-24T16:47:18Z + spec: null + acceptance_criteria: + - 'Temp-0 refs for Qwen3.5-9B-Q4_K_M (sha256 03b74727…) at 850/4k/32k exist and are receipted: apr rc ids per prompt, compared to base 0.69.1 and to llama.cpp on the official template, every divergence measured as a near-tie or reported.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:docs + notes: 'evidence/release/0.69.4/refs-qwen35-9b/README.md' +- id: PMAT-4263 + github_issue: 4263 + item_type: task + title: "one engine (0.69.3): every Qwen3.5 verb through realizar::session::Session" + status: inprogress + priority: critical + assigned_to: aprender-ac + labels: + - kind:code +- id: PMAT-4268 + github_issue: 4268 + item_type: task + title: 'Workstream D (#4263): dense GGUF (llama, qwen2, qwen3, mistral, ...) CUDA and CPU forwards behind the one engine (realizar::session); apr run, run --batch, chat and serve dense route through it' + status: in_progress + priority: critical + assigned_to: aprender-49 + created: 2026-09-24 14:00:00+00:00 + updated: '2026-09-24T19:00:00Z' + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'D1 (this PR): DenseForward (CPU + CUDA) implements ArchForward in gguf/inference/forward/dense_session.rs; apr run (run_gguf_generate) and apr run --batch (BatchModel) drive DenseSession through dense_turn, which answers token-for-token what generate_with_cache answered (greedy, seeded sampled, stop token dropped, ContextLimitExceeded kept). Witness guards in infer/tests_dense_session_4268.rs turn RED when either route goes back to its own loop (mutation measured). --trace keeps the instrumented loops (the engine has no brick profiler). The wgpu fallback keeps its own greedy loop (out of scope). The CUDA arms are free fns (cuda_reset/cuda_forward/cuda_forward_greedy) for aprender-98''s serve cuda_batch_scheduler (#4280). D2: apr chat (GGUF and APR) holds a DenseSession (CUDA, or a lazily built CPU one) and answers through dense_turn; apr serve''s CPU quantized backend (streaming and not) and CUDA non-scheduler RwLock path run a per-request Session (DenseForward::cpu, or aprender-98''s BorrowedCudaForward under the write lock); dense_stream never streams the stop token. Serve witness guards in api/tests/dense_session_4268.rs turn RED when the CPU route goes back to generate_with_cache (mutation measured). The CUDA paths are not yet run on a GPU.' +- id: PMAT-4269 + github_issue: 4269 + item_type: task + title: 'one-engine workstream M: port qwen3_moe run, ST CUDA run, APR CPU serve, APR Q4K scheduler, ST serve and ST chat onto realizar::session::Session (child of #4263)' + status: in_progress + priority: high + assigned_to: aprender-cb + created: 2026-09-24T11:30:00Z + updated: 2026-09-24T11:30:00Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'Roadmap id authorized by the 0.69.3 captain (aprender-36). Targets release/0.69.3 via the #4263 one-engine branch; #4265 (APR CPU stop/top_p) closed from this workstream.' +- id: PMAT-4270 + github_issue: 4270 + item_type: task + title: 'one-engine 0.69.3 workstream V: tool verbs on the Session trait (bench, qa dense gates, eval perplexity, profile, trace)' + status: in_progress + priority: critical + assigned_to: aprender-36 + created: 2026-09-24 12:35:00+00:00 + updated: '2026-09-24T16:30:00Z' + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'V2b: the dense qa gates (golden CPU, output_verification GPU golden, gpu_isolation, speedup parity and CPU/GPU, golden GGUF throughput) drive realizar::gguf::dense_session::dense_turn through apr-cli commands/qa_dense_session.rs; a GPU gate refuses a turn with used_gpu=false. Witnesses: qa_dense_session_tests (2, release mode; the require_gpu mutant kills one).' +- id: PMAT-4273 + github_issue: 4273 + item_type: task + title: 'qwen35 decode attention: split over sequence + f16 KV (decode collapses 70->7.8 tok/s at 32k)' + status: inprogress + priority: medium + assigned_to: null + created: 2026-09-24T10:58:23Z + updated: 2026-09-24T10:58:28.746720556+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-4275 + github_issue: 4275 + item_type: task + kind: code + title: 'binary-release smoke: strip -rc.N and bind the asset to its commit' + status: planned + priority: medium + assigned_to: null + created: 2026-09-24T14:17:31Z + updated: 2026-09-24T14:17:31Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-4280 + github_issue: 4280 + item_type: task + title: 'Workstream D2b (#4263): apr serve dense CUDA scheduler single-request path through the one engine (realizar::session::Session)' + status: in_progress + priority: critical + assigned_to: aprender-98 + created: 2026-09-24 11:00:00+00:00 + updated: '2026-09-24T12:00:00Z' + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'cuda_batch_scheduler generate_single_request (the m==1 fast path, shared with the iteration scheduler) runs one Session::generate over BorrowedCudaForward, a dense CUDA ArchForward over the scheduler''s borrowed model built on aprender-49''s cuda_reset/cuda_forward/cuda_forward_greedy. Stop tokens are filtered in the callback so none is sent (pre-port semantics). The m>1 batched path (batched_setup_and_prefill/batched_decode_step) is multi-slot and stays as is. Known delta: the per-request prefix cache (establish_prompt_kv/populate_prefix_cache) is not used on the ported path.' +- id: PMAT-4285 + github_issue: 4285 + item_type: task + kind: code + title: 'rc cut: tag vX.Y.Z-rc.N on every green merge to release/X.Y.Z' + status: planned + priority: medium + assigned_to: null + created: 2026-09-24T14:01:18Z + updated: 2026-09-24T14:01:18Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-4286 + github_issue: 4286 + item_type: task + kind: code + title: promote rc to final with no rebuild + status: planned + priority: medium + assigned_to: null + created: 2026-09-24T14:17:31Z + updated: 2026-09-24T14:17:31Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-4287 + github_issue: 4287 + item_type: task + kind: code + title: 'rc gate: run the publish preflight + cargo package cascade at rc cut' + status: planned + priority: medium + assigned_to: null + created: 2026-09-24T14:33:50Z + updated: 2026-09-24T14:33:50Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-4326 + github_issue: 4326 + item_type: task + title: nightly ships a CUDA apr build for x86_64 + aarch64 + status: planned + priority: medium + assigned_to: null + created: 2026-09-25T01:51:01Z + updated: 2026-09-25T01:51:01Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-4327 + github_issue: 4327 + item_type: task + title: rc staged on every fleet host before publish, darwin-arm64 asset + status: in_progress + priority: medium + assigned_to: aprender-ea + created: 2026-09-24T18:11:17Z + updated: 2026-09-24T18:11:17Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-4328 + github_issue: 4328 + item_type: task + title: 'ci(release): cross-repo release-asset contract — RED on missing platform asset or .sha256 (C6)' + status: inprogress + priority: critical + assigned_to: aprender-88 + created: 2026-09-24T18:06:35Z + updated: 2026-09-24T18:06:35Z + spec: null + acceptance_criteria: + - scripts/check_sovereign_release_assets.sh --live exits 10 when any manifest repo's latest release lacks linux-x86_64 (musl or gnu.2.NN<=35), linux-aarch64 or darwin-arm64 for a binary, or an archive lacks its .sha256 + - bare run is an offline 17-case table (guard_tree), each removed platform / missing .sha256 / plain-gnu x86_64 RED; 5 checker mutants killed + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-4336 + github_issue: 4336 + item_type: task + title: 'ci(cuda-unit): the clippy --features cuda step runs on apr-cli-only diffs (cuda_lint output)' + status: inprogress + priority: medium + assigned_to: aprender-x4233 + created: 2026-09-25T00:00:00Z + updated: 2026-09-25T00:00:00Z + spec: null + acceptance_criteria: + - scripts/ci_gpu_touched.sh --self-test answers gpu_touched=0 cuda_lint=1 on an apr-cli-only diff, with a planted mutant that deletes apr-cli from CUDA_LINT_CRATES + - cuda-unit starts on cuda_lint=1; its cargo test steps carry a gpu_touched step if; the clippy step has none (scripts/tests/ci_gpu_touched_test.sh) + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-4342 + github_issue: 4342 + item_type: task + title: 'qwen35 --gpu tok/s counts the CUDA build + F2 guard as generation (inference_ms not generation-only) — sibling of #3714' + status: in_progress + priority: high + assigned_to: aprender-1c + created: 2026-09-25T00:30:00Z + updated: 2026-09-25T00:30:00Z + spec: null + acceptance_criteria: + - 'inference_ms for a qwen35 --gpu run excludes the layer load, the CUDA build and the F2 guard (batch.rs:51 contract), as the qwen3moe path does since #3714' + - 'Measured on lambda: apr run --gpu --json on Qwen3.5-4B-Q4_K_M reports a tok/s consistent with the decode wall time, before (2d1978aad) and after' + - 'apr chat keeps run_qwen35_generate_dispatch with an unchanged signature' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'Found by aprender-1c while measuring #3714 (cop assignment 2026-09-24). Fix: run_qwen35_generate_dispatch_timed returns setup_ms; inference_result subtracts it.' +- id: PMAT-4346 + github_issue: 4346 + item_type: task + title: 'qwen-story-daily builds apr in place instead of cargo-installing into the gx10 host ~/.cargo/bin (fleet-bins clobber) (#4346)' + status: in_progress + priority: high + assigned_to: aprender-e6 + created: 2026-09-25T02:51:16Z + updated: 2026-09-25T02:51:16Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-4347 + github_issue: 4347 + item_type: task + title: 'PVL: prove all 7 escape-allowlist axioms (DPO x3, f16 bound, NF4 x3) instead of confirming them' + status: in_progress + priority: high + assigned_to: pvl-b + created: 2026-09-25T01:30:00Z + updated: 2026-09-25T02:00:00Z + spec: infra docs/specifications/PVL-001-pv-lean-gate.md + acceptance_criteria: + - every escape-allowlist.yaml axiom is a Lean theorem whose #print axioms is [propext, Classical.choice, Quot.sound] + - escape-allowlist.yaml carries no entry for a proved decl; Axioms.lean regenerated (pv discharge gen-axioms --check rc 0) + - pv discharge check --no-lake PENDING count drops by the number proved + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'DPO x3 by pvl-b; NF4 x3 and f16 by aprender-57. The old dpo_gradient_formula axiom was false for beta < 0; now a HasDerivAt theorem plus dpo_gradient_scale_nonpos (0 <= beta).' +- id: PMAT-4354 + github_issue: 4354 + item_type: task + kind: code + title: 'PRM-L: land PRM-001 v3 (PROMETHEUS) + rex/001 to main' + status: in_progress + priority: high + assigned_to: worker + created: 2026-09-25T18:38:33Z + updated: 2026-09-25T18:38:33Z + spec: docs/specifications/PRM-001-prometheus.md + acceptance_criteria: + - Refs paiml/aprender#4354. Spec PRM-001 v3 byte-exact, rex-prereg-v2 lock, v1 lock frozen, superseded banners, v3 figure. + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-4369 + github_issue: 4369 + item_type: task + title: 'Migrate the 12 hand-rolled producer build.rs key builders onto build_helper::env_key (#2699 remainder)' + status: in_progress + priority: high + assigned_to: null + created: 2026-09-25T09:13:07Z + updated: 2026-09-29T17:20:00Z + spec: null + acceptance_criteria: + - Folded into #4587 (PR-1 of #4502), C78. Every binding build.rs keys through build_helper::env_key with its build-dep, and Cargo.lock carries the edges (CI builds --locked). + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-4415 + github_issue: 4415 + item_type: task + title: 'Lever 0: guard-cargo/guard-tree stop at the first red step — run every guard and report every failure in one pass (RC #4318: 1 failure per run, 15–71 steps dark)' + status: inprogress + priority: high + assigned_to: aprender-5d + created: 2026-09-26T12:00:00+00:00 + updated: 2026-09-26T12:00:00+00:00 + spec: null + acceptance_criteria: + - 'each guard section (guard-tree, guard-cargo) in ci/sections.yml runs its guards through ONE step, bash scripts/ci_guards.sh , under if: !cancelled() && steps.guard-setup.outcome == success; every guard step that can run outside a pull_request event lives in the -steps manifest (if: false) and the runner executes all of them past a red step, one ::error per failure and one SUMMARY. The only steps left in the section are the ones that need the pull_request payload (both already !cancelled()) and the always() target-watch report — the same three #4457 kept — and check_guard_steps_run_all.sh refuses any other fail-fast step over the baseline' + - 'make guards-local and .githooks/pre-push run the same script and print the same ci_guards: sha256 line CI prints' + - 'the guard jobs are the guard-* sections the gate in .github/workflows/ci.yml reads; a gate that reads none, or an unreadable file, fails closed (rc 2)' + - 'scripts/guard_fail_fast_baseline.txt (shrink-only) and scripts/ci_guards_uncovered.txt name real car sections; check_guard_steps_run_all.sh --self-test goes RED on each planted mutant and is itself wired into CI' + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: 'Port of #4457 (PMAT-4415-guards-run-all, written against the pre-#4433 ci.yml) onto car/0.70.0 fat-job CI, as fold item from aprender-59. Workflow-surface change: 3/3 non-Claude-author quorum required; no push by the author.' +- id: PMAT-4421 + github_issue: 4421 + item_type: task + title: 'P0: bind the pr-review-sign receipt by diff patch-id (git patch-id --verbatim) so it verifies on the merge-queue sha; fail closed' + status: in_progress + priority: critical + assigned_to: aprender-5d + created: 2026-09-25 14:00:00+00:00 + updated: '2026-09-25T16:00:00Z' + spec: docs/specifications/PR-REVIEW-SKILL-002-v2.md + acceptance_criteria: + - 'the signer stamps predicate.diff_patch_id (git patch-id --verbatim of the pinned base_sha..head_sha diff, evidence/pr-review// excluded) before signing' + - 'Arm 4 recomputes the id from the subject (merge_group: sha^1..sha; else merge-base(origin/main,sha)..sha) and fails closed on empty diff, two parents, missing id, or mismatch' + - 'negative arm: a 1-byte change and a trailing-space change to the squash no longer verify (self-test rows)' + - 'works on git 2.34 (no --verbatim) via a byte-exact port checked against golden ids and native git' + - 'legacy (pre-#4421) receipts are exempt only for PRs < 4427 and only until 2026-09-26T16:00Z (operator ruling via cop, FLOW-04); branch events keep the ancestor rule; each bound has a negative self-test row' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'Merge-queue eval (Y5): head/ancestor binding 0/6, tree 4/6, patch-id 6/6. Root cause shared with ASL-00 (sessions == admin identity); cross-link pi-21 ASL-00a.' +- id: PMAT-4431 + github_issue: 4431 + item_type: task + title: 'fold(B3) onto main: merge origin/main e7a52949d into fold/b3-onto-main and green the target-side guards' + status: in_progress + priority: high + assigned_to: aprender-57 + created: 2026-09-26T12:22:22Z + updated: 2026-09-26T12:22:22Z + spec: null + acceptance_criteria: + - origin/main merged in without rebase or force; conflicts resolved. + - every target-side guard newer than the merge-base is green on the merged tree, or its red is shown identical on main. A change to ANY file (another ticket's fragment included) is in scope when a named guard is RED without it. + - (process, not diff content) a quorum on the merge delta, then pmat-merge re-arms with --match-head-commit; the round judging this diff is that quorum. + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'receipt: docs/audits/impl-PMAT-4431-receipt.md' +- id: PMAT-4433 + github_issue: 4433 + item_type: task + title: 'CI = 5 fat jobs (x86 main, gx10, yoga, mac-refusal, determinism) with a Σ-executed invariant (operator ruling 2026-09-25 16:58, items 1+4)' + status: in_progress + priority: critical + assigned_to: aprender-1c + created: 2026-09-25 17:00:00+00:00 + updated: '2026-09-25T18:00:00Z' + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'Collapse the ~20 ci.yml jobs into 5 fat jobs; each runs every section (ci/sections.yml, verbatim old job bodies; vendored sovereign-ci verified against its upstream sha256) to completion on the biggest runner in its class via scripts/ci/fat_driver.py. Required contexts gate / workspace-test / ci / gate keep their names. scripts/ci/sigma_executed.py enforces the executed test-id set == the universe listed independently (by id, not count); a dropped test turns it RED. Train-active priority hook kept as a floor. Item 3 (rc.N = tag on queue-green main) and the #4434/#4436 release-rule docs are a follow-up PR. Scope of the driver: fat_driver.py collapses the MULTI-section Linux jobs (x86-main, gx10, yoga, determinism); mac-check is the ruling''s mac-refusal job, already ONE section on the one macOS runner (no docker there), so it keeps its steps and its context name, and as on main it is not in gate.needs.' +- id: PMAT-4438 + github_issue: 4438 + item_type: task + title: 'APR-EPIC-001: themed epics and issue cap — A1 epic skeleton, A3 issue-to-epic map, triage-apply' + status: in_progress + priority: high + assigned_to: aprender-d1 + created: 2026-09-25T16:20:00Z + updated: 2026-09-25T16:20:00Z + spec: docs/specifications/APR-EPIC-001-themed-epics-and-issue-cap.md + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:docs + notes: null +- id: PMAT-4445 + github_issue: 4445 + item_type: task + title: 'apr bench (qwen35 --fast) refuses every run with warmup+iterations > 1: one session reuses its own prefix cache' + status: inprogress + priority: high + assigned_to: aprender-bb + created: 2026-09-27T11:13:42+00:00 + updated: 2026-09-27T11:13:42+00:00 + spec: null + acceptance_criteria: + - 'Session::forget_prefix drops every prefix the session can resume from. On main that is the held positions (Session has no checkpoint yet); it destructures Session exhaustively, so a merge that adds the #4214 checkpoint field does not compile until forget_prefix resets it too' + - 'bench_qwen35 calls forget_prefix before every warmup turn and every timed turn, so every timed turn prefills its whole prompt; the reused != 0 guard itself is unchanged' + - 'session::tests::forget_prefix_makes_an_extending_prompt_prefill_whole_again: an extending prompt, which on main would resume (reused == 2), prefills from position 0 after forget_prefix; RED when forget_prefix does not clear (mutant measured 2026-09-27, panics at session_tests.rs:248)' + - 'When this meets car/0.70.0 (#4429), the resolution is the car-side form already reviewed on bb/4445-bench-fresh-prefill @9c34ca648d: forget_prefix also sets checkpoint = None, plus session::tests::forget_prefix_makes_the_same_prompt_prefill_whole_again (identical prompt 3x, reused == 0, no restore; RED on a forget_prefix that keeps the checkpoint, measured)' + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: 'Adopted from aprender-ea orphan fix/4445-bench-fresh-prefill @65fd973170 (09-25, never PRed). The bug exists only with the #4214 checkpoint, i.e. car/0.70.0 (#4429); main before #4429 does not reuse an identical prompt. Cop ruling 2026-09-27: not folded into the car; own PR on main the moment #4429 merges, before the rc.1 tag. Superseded 2026-09-27 ~14:00Z by operator "make it faster" (via cop): open on main NOW, in parallel with the car. Until the car lands this change is inert on main (an identical prompt already prefills whole there); it pre-lands the bench wiring and the API so the car merge needs only the checkpoint line, which the exhaustive destructure forces.' +- id: PMAT-4446 + github_issue: 4446 + item_type: task + title: PRA-001 T12 terms/provider tagging (P-TERMS) + status: planned + priority: medium + assigned_to: null + created: 2026-09-25T17:08:31Z + updated: 2026-09-25T17:08:31Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-4447 + github_issue: 4447 + item_type: task + title: PRM-S1 review-replay-v1 benchmark + runner + status: planned + priority: medium + assigned_to: null + created: 2026-09-25T17:46:46Z + updated: 2026-09-25T17:46:46Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-4453 + github_issue: 4453 + item_type: task + title: 'Arm 4 self-test inherits GITHUB_EVENT_NAME: four rows RED inside the merge_group job (FLOW-04 follow-up)' + status: in_progress + priority: critical + assigned_to: aprender-ont + created: 2026-09-25 20:00:00+00:00 + updated: '2026-09-25T20:00:00Z' + spec: docs/specifications/PR-REVIEW-SKILL-002-v2.md + acceptance_criteria: + - 'every self-test row runs with GITHUB_EVENT_NAME, PR_REVIEW_SUBJECT_KIND, PR_REVIEW_NOW and PR_REVIEW_LEGACY_UNTIL unset; a row that needs an event names it' + - 'self-test is 23/23 with the ambient event empty, merge_group and pull_request_target, and RED under merge_group without the fix' + - 'no change to the verdict logic of Arm 4 itself' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'pr-review-quorum run 36177378373 (merge_group, 00058476c = #4426 queue squash) failed on receipt-reviews-ancestor, legacy-exempt-in-window, legacy-exempt-not-ancestor, legacy-two-last-stale. Parent PMAT-4421.' +- id: PMAT-4455 + github_issue: 4455 + item_type: task + title: 'APR-EPIC-001 A8: findings-ledger-v1 — a findings line is under contract, written and checked by pv' + status: in_progress + priority: high + assigned_to: aprender-wmainred + created: 2026-10-09T00:00:00Z + updated: 2026-10-09T00:00:00Z + spec: docs/specifications/APR-EPIC-001-themed-epics-and-issue-cap.md + acceptance_criteria: + - 'Spec row A8, verbatim: "Findings schema and contract `findings-ledger-v1`."' + - 'Spec rule 17 fields, verbatim: "`{id, title, evidence, repro, suspected_epic, severity, found_at_sha}`".' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'SCOPE: contracts/findings-ledger-v1.yaml (new, kind pattern, closed shape over the seven rule-17 fields), scripts/findings_ledger.sh (new: add and check, both judged by pv lint --gate shapes on the real contract), tests/fixtures/ont/findings-ledger/*.jsonl and crates/aprender-contracts-cli/tests/ont_findings_ledger.rs (the case table, both arms), ci/explicit-test-commands.d (one .cmd), CLAUDE.md (the "surface defects" line). NOT BUILT, with reasons recorded on the issue: the rule-17 author check (every session files as one account), rule 18 (the existing closes-issue guard already covers a cited-but-unclosed ref), rule 19 (a ratchet; C324 rule 6). The contract binds lines written after it lands; the lines already in docs/findings/ are not rewritten, and no PR or release step reads docs/findings/.' +- id: PMAT-4469 + github_issue: 4469 + item_type: task + title: 'yoga CUDA jobs run each test binary under the host GPU lock (infra#1178)' + status: in_progress + priority: high + assigned_to: infra-27 + created: 2026-09-26 12:00:00+00:00 + updated: '2026-09-26T12:00:00Z' + spec: null + acceptance_criteria: + - 'cuda-unit (ci/sections.yml) and cuda-nightly ada-yoga set CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_RUNNER to flock -E 175 -w 600 /run/lock/fleet-gpu/gpu.lock, so test execution holds the lock and compilation does not' + - 'each job first asserts the lock is the host''s (bind mount in the container; root-owned file on the host runner) and fails closed when it is missing, never taking a private lock' + - 'the yoga cuda-unit job is green on a runner that has the infra#1178 mount' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'Operator ruling 2026-09-26 (via the cop): yoga''s GPU is exclusive for CI. Host side paiml/infra#1182 (PMAT-1178 there), applied on yoga. PR #4468.' +- id: PMAT-4478 + github_issue: 4478 + item_type: task + title: 'ci: pr-review-sign receives an empty signing key — secret name misspelled (…_B vs …_B64), every PR''s present check RED' + status: in_progress + priority: critical + assigned_to: aprender-57 + created: 2026-09-26 16:00:00+00:00 + updated: '2026-09-26T16:00:00Z' + spec: docs/specifications/PR-REVIEW-SKILL-002-v2.md + acceptance_criteria: + - 'ci.yml passes FAT_SECRET_PR_REVIEW_SIGNING_KEY_B64 from secrets.PR_REVIEW_SIGNING_KEY_B64, the name ci/sections.yml pr-review-sign reads' + - 'scripts/check_fat_secrets_passed.sh: every secrets.NAME on a non-comment line of ci/sections.yml (except GITHUB_TOKEN) has FAT_SECRET_NAME from secrets.NAME in ci.yml, and every FAT_SECRET_KEY reads secrets.KEY; 6-row case table carrying the #4441 shape verbatim as FAIL; RED on main''s ci.yml, GREEN on this tree' + - 'the guard is wired in ci/sections.yml (case table, then tree) and check_guards_are_wired.sh is GREEN' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'Found on #4431 CI run 36246483181: "carries an UNSIGNED receipt and PR_REVIEW_SIGNING_KEY_B64 is empty". #4441 (fat jobs) hand-wrote the env line with the trailing 64 dropped.' +- id: PMAT-4481 + github_issue: 4481 + item_type: task + title: 'batch(ONT): fold #4480 (contracts gate fails closed, #4475) and #4473 (ONT-4c4 kernel receipts + O-1 gated_rmsnorm receipt, #4069/#3522) onto main as one PR' + status: in_progress + priority: high + assigned_to: aprender-df + created: 2026-09-26T16:51:01Z + updated: 2026-09-26T16:51:01Z + spec: null + acceptance_criteria: + - the three commits of #4480 (c30936d9d3) and #4473 (91969973aa, 09edd15f28) are cherry-picked with -x onto main, content unchanged. Besides the picks, the diff holds this ticket's roadmap entry and receipt, the quorum artifact, and the CI-fix delta in the next criterion. + - bash scripts/contracts_gate.sh on the combined tree runs 6 of 6 steps with 0 failed (the regenerated census.json / contracts.nt / shapes.ttl match), and its --self-test passes. + - 'CI-fix delta (added after the 3/3 at 367ae45bd6): the combined tree broke BINDING-006 (a #[kernel] and its CPU reference on one equation) and bashrs SC2171 in contracts_gate.sh. Both are fixed here because the fold caused them: KernelBinding.kernel keys the kernel entry apart, and the jq program moves into a heredoc. Tests cover a pair passing, two references RED, two kernels RED, and kernel-only resolving to no reference.' + - (process, not diff content) a 3-lane quorum on this diff, then pmat-merge arms with --match-head-commit once CI is green. + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'receipt: docs/audits/impl-PMAT-4481-receipt.md. Replaces #4480 and #4473 (closed as superseded, branches kept).' +- id: PMAT-4502 + github_issue: 4502 + item_type: task + title: 'batch/ont-10: every remaining ONT-10 row for 0.70.0 (one PR, one quorum, one CI)' + status: in_progress + priority: critical + assigned_to: aprender-88 + created: 2026-09-27T10:17:06Z + updated: 2026-09-29T17:40:00Z + spec: null + acceptance_criteria: + - 'every ONT-10 row on the batch lands in this one PR (no per-row PRs); origin/main merged in without rebase or force' + - 'Sigma binary is implemented by extract:binary from the tracked evidence/binary/snapshot.jsonl, one node per cargo bin target keyed binary//; binary-target is NOT in armed_shapes' + - 'scripts/surface_audit_bins_gate.sh is GREEN (every [[bin]] has a docs/audits/surface_audit.csv row) and RED on an empty ledger' + - 'pv validate passes on contracts/binary-surface-v1.yaml and every contracts/bin-*.yaml; the aprender-contracts lib is green' + - 'a gate still RED stays in its contract with the observed value in if_fails, never dropped' + - '#4587 A-prime (operator ruling 2026-09-29 06:36Z via the cop, commit a79535bd51): CI generates the mutants survivor table itself (mutants-table-scope, mutants-shard matrix, verifier scripts/ci/mutants_survivor_table.py); any gap is RED; scope PR-1 and PR-2 of 0.70 only (ci/mutants-table-refs.txt)' + - 'folded tickets carried with their own entries: PMAT-4199, PMAT-4200, PMAT-4347, PMAT-4166 (lint ratchet), PMAT-4139 (Lean label ratchet), PMAT-4604 (pv 0.69.4 set), PMAT-4369 (build_helper::env_key); the quorum --ticket names every one' + - '(process, not diff content) one quorum on the combined head; pmat-merge arms with --match-head-commit' + - 'ratchet block per C188(a), reviewed in #4647: the ci.yml mutants-debt ratchet (scripts/check_mutants_debt_ratchet.sh, ci/mutants-debt.tsv; mutants out of the ci / gate required set) is carried here verbatim from #4647, where quorum q-4647g agreed 3/3; in scope here by operator rulings C188(a) and C192(1) (2026-10-01)' +- id: PMAT-4507 + github_issue: 4507 + item_type: task + title: 'fat_driver setup_workspace: a root-owned leftover section tree makes mkdir raise FileExistsError (runner poisoning)' + status: in_progress + priority: high + assigned_to: aprender-49 + created: 2026-09-27 05:26:00+00:00 + updated: '2026-09-27T05:26:00Z' + spec: null + acceptance_criteria: + - 'a self-test row plants an undeletable leftover ws and setup (make_section_dirs) yields a fresh _temp/home/ws' + - 'the rename-aside is written to the section log; older asides are retried, and past ASIDE_KEEP undeletable ones every setup warns' + - 'the mutant that restores rmtree-and-ignore then mkdir turns the self-test RED (FileExistsError row)' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'Blocked #4479 (ONT-10 chain head) twice on framework16-2. 0.70.0 path; branch 49/4507-fat-ws-aside off car/0.70.0.' +- id: PMAT-4510 + github_issue: 4510 + item_type: task + title: 'ci.yml plumbs the receipt signing secret under a truncated name; a guard ties section secrets to their plumbing' + status: in_progress + priority: high + assigned_to: infra-83 + created: 2026-09-27 07:00:00+00:00 + updated: '2026-09-27T07:00:00Z' + spec: null + acceptance_criteria: + - '.github/workflows/ci.yml plumbs FAT_SECRET_PR_REVIEW_SIGNING_KEY_B64 from secrets.PR_REVIEW_SIGNING_KEY_B64, the name ci/sections.yml reads' + - 'scripts/check_ci_fat_secrets_plumbed.sh is GREEN on this tree, RED with the #4441 line restored, and its self-test carries that line byte for byte' + - 'the pr-review-sign step on a PR with an unsigned receipt signs it instead of reporting an empty key' + - 'the x86-main job of .github/workflows/ci.yml runs scripts/check_ci_fat_secrets_plumbed.sh --self-test and then the guard on the tree, before the sections run, so a future truncation fails ci / gate' + - 'Operator, verbatim (2026-09-28, via the cop): "Fix inside #4512 (same scope: guard/plumbing): exclude the receipt path(s) from the fingerprint input set ... add a test: re-running the stamp on an unchanged diff gives the same fingerprint (idempotent)." scripts/lib/pr_review_patch_id.sh excludes evidence/pr-review/ and docs/audits/quorum-*.json; scripts/check_pr_review_arm4.sh --self-test proves head = +receipt = +quorum = re-stamp, and that a control file (docs/audits/other.json) still moves the fingerprint' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'Found on #4431 run 36297914139 (x86-main pr-review-sign). Regressed in #4441 (a016cee94).' +- id: PMAT-4514 + github_issue: 4514 + item_type: task + title: 'FLOW-003 v1.1: queue/release-cycle model spec with review fixes' + status: inprogress + priority: medium + assigned_to: null + created: 2026-09-27T06:56:07Z + updated: 2026-09-27T06:56:11.885936345+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: null +- id: PMAT-4524 + github_issue: 4524 + item_type: task + title: 'PRM-L land rex/001 C6+C11+C14 on main: merge main, reconcile with #4655 crate snapshot' + status: planned + priority: high + assigned_to: null + created: 2026-10-08T12:49:26Z + updated: 2026-10-08T12:49:26Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null + epic: 4354 +- id: PMAT-4539 + github_issue: 4539 + item_type: task + title: 'KREG-001: SHACL kernel registry, selector refuses unregistered kernels (aprender#4539)' + status: planned + priority: high + assigned_to: null + created: 2026-09-27T11:28:55Z + updated: 2026-09-27T11:28:55Z + spec: null + acceptance_criteria: + - 'Phase 1: registry rows + shape contract + runtime admit gate + coverage test. Refs #4539' + - 'AC-1 (key): the admission key includes arch, isa_features and backend; admit() matches on them (issue #4539 body)' + - 'AC-2 (arch-generic): no field or enum is valid for only one of x86 or CUDA; aarch64, Metal and wgpu rows validate with no schema change (issue #4539 body)' + - 'AC-3 (receipt-gated admission): a row without a parity receipt from a host of its arch is a violation. Every cpu row carries a receipt, and every receipt names its row, once, from a host of its arch, at the row''s tolerance path (FALSIFY-KREG-008, no allowance count). GPU rows may be unmeasured: their receipt coverage is a LAB check, off the merge path (#4574) (issue #4539 body)' + - 'AC-4 (stable id): every row has a stable kernel_id plus shape_class and precision, for OBS-15 kernel_path (issue #4539 body)' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null + epic: 3994 +- id: PMAT-4594 + github_issue: 4594 + item_type: task + title: 'fix(guard): check_silicon_coverage.sh scores a short API run listing as STALE 9d (false RED)' + status: inprogress + priority: high + assigned_to: aprender-57 + created: 2026-09-28T14:00:00Z + updated: 2026-09-28T14:00:00Z + spec: null + acceptance_criteria: + - Every created>= listing is cross-checked against the unfiltered newest run; a listing missing a run inside the lookback is re-read once, and still short is NO-GO (unknown, rc 2), never STALE + - 'Falsifier: stale evidence (newest nightly 9d old, whole listing) stays RED (self-test row h-real-stale, rc 1)' + - 'Falsifier: run 36364433328''s real jobs, fresh, are GREEN (row g-real-green, rc 0)' + - The 11:25Z short "21 of 21" listing (run 36410817478) scores GREEN on a whole re-read and NO-GO when short on every read; main's reader scores both STALE (rows i, j) + - No lookback window, page cap or policy limit changes + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'Operator ruling 2026-09-28 13:53Z (via the cop): own small PR, first in the queue, on main before the #4512 push.' +- id: PMAT-4604 + github_issue: 4604 + item_type: task + title: 'C2: publish pv (aprender-contracts-cli) 0.69.4 + deps for B1 gate tool (L20)' + status: in_progress + priority: high + assigned_to: null + created: 2026-09-28T14:17:01Z + updated: 2026-09-29T17:20:00Z + spec: null + acceptance_criteria: + - Folded into #4587 (PR-1 of #4502), C78. The 6-crate pv set is at 0.69.4, the facade guard allows exactly that set, and binary-release builds pv with --features update-check,build-sha. + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-4616 + github_issue: 4616 + item_type: task + title: 'D5: serve over device KV (4096) returns 500 — refuse with 400 context exceeds N' + status: inprogress + priority: critical + assigned_to: aprender-2e-serve + created: 2026-09-28T20:47:39Z + updated: 2026-09-28T20:47:39Z + spec: null + acceptance_criteria: + - 'lambda RTX 4090, 5432-token chat turn: main returns 500, the branch returns 400 context exceeds 4096 (the --context-length 32768 -> 200 case is #4603, not this ticket)' + - 'api/tests/serve_context_d5.rs: the refusal fires at prompt_tokens >= serving_context, and serving_context = min(model context, device KV)' + - 'Dense GGUF CUDA chat, completions, stream, /generate, /batch/generate and /v1/batch/completions all refuse before generating; every typed generate-error site maps ContextLimitExceeded to 400, never 500 (batch-scheduler channel errors are strings reached only after the pre-flight; the APR Q4K backends are #4625)' + - 'The mutants gate can judge this diff: no build script in the aprender-serve test build watches a missing path (build-sha .git-sha, compute/present-core/serve sibling provable-contracts reads), so the test phase after `cargo test --no-run` recompiles nothing (run 36520343459 spent 4m18s of each 300s mutant budget compiling)' + phases: [] + subtasks: [] + estimated_effort: null + labels: [] + notes: 'OPERATOR ruling D5 (ruling-3715). Child of #3715. The ladder part (--context-length on gate-named rungs) is 0d #4603.' +- id: PMAT-4621 + github_issue: 4621 + item_type: task + title: 'lambda run/chat cells time out: unchunked dense prefill OOM, qk-norm forced serial, chat KV 2048, Qwen3.5 no F16/IQ4_XS dequant' + status: in_progress + priority: critical + assigned_to: aprender-ec + created: 2026-09-29T00:55:00Z + updated: 2026-09-29T09:01:00Z + spec: null + acceptance_criteria: + - 'Root 1: the dense batched CUDA prefill is chunked under a score-buffer budget, so a 20k-token prompt on Qwen2.5-0.5B IQ3_M/IQ4_XS runs on the GPU (no OOM, no CPU fallback) and the lambda run cell passes under the 600 s timeout (no timeout raised).' + - 'Root 2: a QK-norm model (Qwen3) keeps FP8 off but takes the FP16 batched prefill when it fits in free VRAM, and keeps the serial prefill when it does not (Qwen3-8B), with BATCHED_PREFILL=1 still overriding.' + - 'Root 3: the apr chat device KV is sized to the model context when free VRAM allows (2048 floor), so a 26k-token chat turn on Qwen3-1.7B stays on the GPU.' + - 'Root 5: the Qwen3.5 batched prefill dequantizes F16 and IQ4_XS tensors on the device, so Qwen3.5-4B-UD and 0.8B-IQ4_XS pass the F2 CPU-parity guard on the GPU.' + - 'Red/green on lambda with a pinned binary: every cell above rc=124 (or CPU fallback) on base and rc=0 on the GPU on the fix. Serve KV 4096 (D5) and IQ2_XXS/IQ3_S/IQ2_S/Q2_K dequant are out of scope.' + - 'Mutation gate (operator E1; cop ruling 2026-09-29 08:32Z "#4620''s CUDA mutants shard goes INSIDE #4620"): the CPU mutants section lists every cuda-gated mutant of the diff as NOT_MEASURED and defers that sorted set (scripts/mutants_diff_gate.sh --defer-unbuilt); the mutants-cuda section on the yoga GPU runner mutates the feature-gated files at the head sha (--features aprender-serve/cuda --gated-only); the gate job is RED unless both set shas match (GATE-MUTANTS-CUDA-RULE, scripts/check_ci_gate_mutants_cuda_rule.sh). 0 not_measured on changed cuda code.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'Child of #3715 (the release-readiness shape whose lambda cells these roots turned red). Minted by the cop aprender-77, 2026-09-29.' +- id: PMAT-4633 + github_issue: 4633 + item_type: task + title: 'fix(deps): wasmtime 47.0.4 -> 48.0.3 for RUSTSEC-2026-0315/0316 (security job red on main and every PR)' + status: inprogress + priority: critical + assigned_to: aprender-00 + created: 2026-09-29T12:17:38Z + updated: 2026-09-29T12:17:38Z + spec: null + acceptance_criteria: + - The workspace wasmtime pin is 48.0.3 and Cargo.lock resolves wasmtime 48.0.3 (cargo metadata --locked rc=0) + - cargo audit on the branch Cargo.lock reports no RUSTSEC-2026-0315/0316 (rc=0); on origin/main it reports both + - cargo deny check rc=0 (advisories, bans, licenses, sources) + - No audit or deny ignore is added and no gate is relaxed; the diff is Cargo.toml, Cargo.lock, this roadmap entry (with its roadmap.yaml copy) and docs/audits/security-PMAT-4633-wasmtime-48.md, the C45 review input that stands in for the raw Cargo.lock, only + - wasmtime stays optional behind aprender-test-lib's runtime feature (cargo tree -i wasmtime --workspace finds no active path), so the 1.95 MSRV of the 48 line does not reach the 1.93 pin + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'Cop ruling 2026-09-29 12:0xZ: P0 main fix, Cargo bump only, PR open by 13:00Z.' +- id: PMAT-4641 + github_issue: 4641 + item_type: task + title: CB-200 release gate compares head to the last release tag, not a stored limit; clear the 4 findings over v0.69.3 + status: planned + priority: high + assigned_to: null + created: 2026-09-29T22:33:26Z + updated: 2026-09-29T22:33:26Z + spec: null + acceptance_criteria: + - 'dogfood.sh pmat-comply read [tdg] baseline 599 (main 622, FINAL NO-GO). Now scripts/cb200_head_vs_base.sh: one pmat, one run, baseline zeroed, head <= newest final tag. Cop ruling 2026-09-29 21:33Z.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null + epic: 3997 +- id: PMAT-4646 + github_issue: 4646 + item_type: task + title: 'MUT-RATCHET: mutants gate -> ratchet mode (debt file shrink-only), operator C187/C188' + status: inprogress + priority: critical + assigned_to: aprender-ca + created: 2026-10-01T06:50:00Z + updated: 2026-10-01T10:00:00Z + spec: null + acceptance_criteria: + - ci/mutants-debt.tsv lists every known survivor of #4587 run 36725778557 and #4588 run 36703131059 as file, mutant, outcome, sha, run id (5 tab fields; outcome MissedMutant or Timeout) + - 'scripts/check_mutants_debt_ratchet.sh is RED on a grown, swapped, malformed, duplicated or missing debt file and on an unresolvable merge base, and GREEN on a shrink, a shrink to zero rows, or an unchanged file; and RED when no base is nameable (resolve_base refuses); its --self-test passes 16/16 (R1-R16: R14-R16 kill the three surviving guard mutants named by the 1f2e3598ea review)' + - The ci gate job reports the mutants section result but does not fail on it; every other required section (WT, guard-tree, guard-cargo, sov.gate, determinism) still fails the gate exactly as before + - No ruleset change, no timeout raised, no other gate relaxed; the reviewed source diff is ci.yml (one marked block), the debt file, the guard script, this roadmap entry and ONE queue-only fix to .github/workflows/pr-review-quorum.yml (below) only. The PR also carries the generated docs/roadmaps/roadmap.yaml and, once reviewed, its own receipt under evidence/pr-review/4647/ and its quorum verdict; those are outputs of review, not part of the diff under review + - '.github/workflows/pr-review-quorum.yml, queue-only fix, operator 2026-09-28 14:52Z (gate-keeping workflow edits with red/green proof are pre-approved): ARM4_PR_HEAD_SHA = github.event.pull_request.head.sha (empty on merge_group, so Arm 4 reads the PR head from the pulls API) and the job permission pull-requests: read. Before, the queue squash was passed as the head and every queued PR read UNSIGNED (runs 36888741583 and 36890960012; #4632 run 36602609576). No gate loosened: the signature must still verify under the repo key and its trusted comment must still name pr=, head= and pid= (the patch-id of the squash diff Arm 4 computes). Red/green on queue sha 79594c8362: old wiring rc 1 UNSIGNED, new rc 0, A3 corrupted-signature control still rejects' + - A RESTORE PR (#4648) deletes the ratchet block after v0.70.0 is on crates.io + - Out of scope, tracked in #4649 - comparing a PR's own mutants survivors with the debt file (a NEW survivor is RED); until then a new survivor is reported, not blocked + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'Operator C187(a)/C188(a), 2026-10-01: ratchet, not a waiver.' +- id: PMAT-4650 + github_issue: 4650 + item_type: task + title: 'apr serve: pass request tools into the GGUF chat template and parse Qwen3.5 XML tool calls (tool calling was silently dead)' + status: inprogress + priority: critical + assigned_to: aprender-w4650 + created: 2026-10-04T00:00:00Z + updated: 2026-10-04T00:00:00Z + acceptance_criteria: + - With request `tools`, the Qwen2.5, Qwen3 and Qwen3.5 templates render their `` block, and the tool JSON is written as HF tojson writes it (json.dumps with Python separators and no HTML escaping) + - With no tools, the rendered prompt is byte-identical to before, so the 16 #3990 oracle cells do not move + - A Qwen3.5 XML call (`V`) to a declared tool returns tool_calls with schema-typed arguments and finish_reason "tool_calls". A call to an undeclared tool stays content + - The Qwen3.5, CUDA and dense chat paths all pass request.tools to the renderer + - 'Out of scope, follow-ups: streaming tool_calls; replaying assistant tool_calls and tool-role messages into the template; tools on the legacy template path (it warns)' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:bug + notes: 'Filed by alfredodeza. Operator: must hit 0.70.2.' +- id: PMAT-4651 + github_issue: 4651 + item_type: task + title: 'PP-LLAMA-001 §12: re-date rows 13, 15, 18, 19, 21 to 2026-10-15 (operator C197; not delivered for 0.70, carried to 0.71)' + status: inprogress + priority: critical + assigned_to: aprender-ca + created: 2026-10-01T12:45:00Z + updated: 2026-10-01T12:45:00Z + spec: docs/specifications/PP-LLAMA-001-MASTER.md + acceptance_criteria: + - Rows 13, 15, 19 and 21 carry Expires 2026-10-15 (was 2026-09-30) with the operator, ruling and reason in the row; row 18 derives 2026-10-15 from row 15 with no date typed + - An Appendix D row records who moved the expiry (operator Noah, ruling C197) and why ("not delivered for 0.70; carried to 0.71") + - evidence/parity/derived_expiries.json is regenerated by `bash scripts/spec_conformance.sh --write`, and exactly those five rows change + - The D6 andon in scripts/lib/spec_conformance.py is unchanged. `bash scripts/spec_conformance.sh` passes today, and with SPEC_CONFORMANCE_TODAY=2026-10-16 it is RED with D6 for the re-dated rows + - 'At release time, not in this PR: the 0.70 release notes (gh release v0.70.0) carry "NO SPEED DELIVERED: PP-LLAMA-001 rows 13, 15, 18, 19, 21 (re-dated to 2026-10-15)"' + - Out of scope, tracked in #4652 - a 7-day advance warning before any row expires + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:docs + notes: 'Operator C197, 2026-10-01 12:40Z: re-date via the spec''s own procedure; check unchanged; not a waiver.' +- id: PMAT-4687 + github_issue: 4687 + item_type: task + title: 'publish_strict.sh: one door to cargo publish — refuse a clean-room run id that is missing, red, or tested another commit' + status: in_progress + priority: high + assigned_to: aprender-cd + created: 2026-10-06T00:00:00Z + updated: 2026-10-06T00:00:00Z + spec: null + acceptance_criteria: + - 'Issue #4687 row T10, verbatim: "publish_strict.sh must refuse a clean-room run id that is missing, red, or tested another commit (it accepts any non-empty file today, lines 28-30 at v0.70.1). Plant all three."' + - 'Done when, verbatim: "a contract, a planted falsifier that goes red, a first green on a real PR, and before-and-after numbers."' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'SCOPE: scripts/release/publish_strict.sh, scripts/cascade-publish.sh (clean_room_gate gains an optional third argument, a pinned run id), scripts/check_cascade_clean_room_gate.sh (10 pinned rows), scripts/check_publish_strict_cleanroom.sh (new), contracts/publish-workspace-v1.yaml (PW-DOOR-005, FALSIFY-PUB-008). HOW IT IS MET: publish_strict.sh reads the recorded run id and loads clean_room_gate from the cascade script (the same extraction the existing guard uses), then calls it pinned to that one run. Pinned mode reads exactly that run through the runs API, refuses a run of another workflow, and never lists runs, so a green run elsewhere cannot stand in for a red recorded one. A missing, empty, non-numeric, unreadable, red or other-commit id stops the cascade before any upload. --plan is unchanged. MEASURED: check_publish_strict_cleanroom.sh runs the real publish_strict.sh against a fixture tag checkout and a stub gh and cargo. BEFORE (origin/main 645dc34101): 8 of 9 checks FAIL; the non-numeric, red, other-commit and unreadable ids all pass the door and stop later, on the B2-gpu id. AFTER: 9 of 9 hold; check_cascade_clean_room_gate.sh holds every row, including the 10 pinned ones.' +- id: PMAT-4715 + github_issue: 4715 + item_type: task + title: 'B2: root-cause fixes for red nightlies on main' + status: inprogress + priority: critical + assigned_to: aprender-wmainred + created: 2026-10-04T00:00:00Z + updated: 2026-10-04T00:00:00Z + acceptance_criteria: + - Each red or cancelled scheduled workflow on main has a root cause named in its fix PR, one PR per defect, listed on issue #4715 + - Each fix PR changes no gate's acceptance; a threshold or acceptance change goes to the train lead's sign-off batch instead + - After each fix merges, the next scheduled or dispatched run of that workflow on main gets past the step that failed + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:ci + notes: 'Parent #4678 (0.70.2), bar B2: no check red on main for more than 24 h. Proposed by aprender-a7, minted by cop aprender-14.' +- id: PMAT-4719 + github_issue: 4719 + item_type: task + title: '0702-P2: nightly producers for the readiness, milestone and preflight verdict lanes (#4719)' + status: inprogress + priority: critical + assigned_to: null + created: 2026-10-04T09:18:17Z + updated: 2026-10-04T09:18:17Z + spec: null + acceptance_criteria: + - release-gates-nightly.yml runs milestone (--must-carry) and preflight (--graph-only) at main HEAD + - readiness-nightly.yml runs release_readiness.sh on same-commit dogfood-receipt + models-t1, else skipped (not_measured) + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null + epic: 4678 +- id: PMAT-4729 + github_issue: 4729 + item_type: task + title: pr-review-quorum present on its own review-light runner lane + status: planned + priority: critical + assigned_to: null + created: 2026-10-04T11:38:38Z + updated: 2026-10-04T11:38:38Z + spec: null + acceptance_criteria: + - 'C310 item 8: move present to [self-hosted, review-light], steps unchanged.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null + epic: 4678 +- id: PMAT-4741 + github_issue: 4741 + item_type: task + title: 'PY-PORT-2: port publishable_crates / package_include_diff / coverage_report_scope to Rust (C301)' + status: inprogress + priority: high + assigned_to: aprender-w4664 + created: 2026-10-04T17:05:00Z + updated: 2026-10-04T17:05:00Z + spec: null + acceptance_criteria: + - crates/aprender-ci-tools builds with publish = false. It has one clap-derive bin with subcommands publishable-crates, package-include-diff and coverage-report-scope, ported from scripts/lib/publishable_crates.py, scripts/lib/package_include_diff.py and scripts/coverage_report_scope.py + - scripts/tests/ci_tools_py_parity_test.sh runs every case through the .py original (as external validator) and the Rust bin. stdout is byte-identical and success or failure agrees, including on live `cargo metadata`. The argv forms where clap deliberately differs (--help/--version exit 0, --exclude=NAME accepted, extra positionals refused) are listed in the crate README and are out of parity scope. A planted mismatch must be detected, and a run of fewer cases than declared fails + - contracts/binary-debt-v1.yaml has a KEEP row for the bin. The crate has a README linking paiml/aprender, and readme_contract and check_binary_debt.sh are green + - 'FALSIFY-MONO-011: aprender-ci-tools is added to the [[bin]] allowlist with ALLOWLIST_BASELINE 27 -> 28, in its own commit (sign-off row 38: loosens a shrink-only list, so it waits for operator sign-off and can be reverted alone)' + - Out of scope - switching any caller (Makefile, scripts/*.sh) to the bin; CI behaviour is unchanged by this ticket + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:tooling + notes: 'Ruled by aprender-a7 (PY-PORT decision; MONO-011 option A as sign-off row 38). Branch-only, no PR.' +- id: PMAT-4748 + github_issue: 4748 + item_type: task + title: 'T43: push to main reuses the merge queue''s real x86-main + determinism on the same sha' + status: planned + priority: critical + assigned_to: null + created: 2026-10-06T09:28:27Z + updated: 2026-10-06T09:28:27Z + spec: null + acceptance_criteria: + - 'Refs #4748. A push run on main reuses x86-main and determinism from the merge_group run on that sha, only when that run ran them for real (not itself a reuse). Guard: scripts/check_ci_push_reuse.sh.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null + epic: 4678 +- id: PMAT-4756 + github_issue: 4756 + item_type: task + title: 'examples-nightly: 29 examples fail and 7 time out on main (run 37169058144)' + status: inprogress + priority: high + assigned_to: aprender-wmainred + created: 2026-10-04T17:55:00Z + updated: 2026-10-10T07:32:00Z + spec: null + acceptance_criteria: + - The 36 rows that were fail or timeout in run 37169058144 are pass or a skip class (needs-args, needs-hardware, needs-data, needs-feature), with fail 0 and timeout 0, under scripts/dogfood_examples.sh --timeout-secs 180 + - scripts/dogfood_examples.sh and its classifier are unchanged + - Release-build workloads are unchanged, except GPU-018 (#4756), which still runs but reports its own tok/s as an informational line outside the pass counts, and the every-build bug fixes in the receipts README (the Q4_0 and Q8_0 buffer sizes); only debug builds or non-terminal runs take a shorter path + - Out of scope, on build-kaizen/examples-nightly-queue - the workflow's runs-on, concurrency and runner label + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'Receipts: evidence/examples-nightly-4756/. Before (CI run 37169058144): fail 29, timeout 7. After (one debug run of the 36 rows on 22954be7ab, libcuda hidden; the later GPU-018 and include-fmt commits are not in that run): pass 9, needs-args 11, needs-hardware 10, needs-data 5, needs-feature 1, fail 0, timeout 0. Receipt of record: the re-enabled nightly. qa_verify''s own gate failures (every section rc 1, 0 tests from the root facade) are #5026, outside this ticket.' +- id: PMAT-4769 + github_issue: 4769 + item_type: task + title: 'FLAKE-0: StreamingKVCache memory-bound tests commit up to 34 GB and are OOM-killed on smaller runners' + status: inprogress + priority: high + assigned_to: aprender-wmainred + created: 2026-10-04T23:34:00Z + updated: 2026-10-04T23:50:00Z + spec: null + acceptance_criteria: + - 'Step 1: the three long-context memory-bound tests (ultra, super, mega) carry #[ignore = "FLAKE-0 #4769"] and nothing else changes; every other aprender-serve lib test passes' + - 'Step 2: StreamingKVCache and StreamingKVCacheFp16 allocate each layer as its own zeroed buffer, the three tests are un-ignored and pass under a 24 GB memory cap, and decode throughput shows no regression beyond noise' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'Cause: vec![vec![0; n]; layers] clones layer 0 into every layer, writing every byte, so construction commits 8.6 / 17.2 / 34.4 GB; nextest KILLed the tests on a 30 GB runner (run 37241931271, workspace-test shard 1).' +- id: PMAT-4786 + github_issue: 4786 + item_type: task + title: 'PY-PORT R1: port scripts/lib/dag_status.py to aprender-ci-tools dag-status' + status: planned + priority: medium + assigned_to: null + created: 2026-10-05T12:18:07Z + updated: 2026-10-05T12:18:07Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null + epic: 4678 +- id: PMAT-4787 + github_issue: 4787 + item_type: task + title: 'PY-PORT-2c: switch coverage_report_scope callers to aprender-ci-tools, delete the .py (C301)' + status: inprogress + priority: high + assigned_to: aprender-0d + created: 2026-10-05T12:18:37Z + updated: 2026-10-05T12:18:37Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null + epic: 4741 +- id: PMAT-4788 + github_issue: 4788 + item_type: task + title: 'PY-PORT-2b: port tarball_shrink_report.py to aprender-ci-tools' + status: inprogress + priority: medium + assigned_to: aprender-a7f + created: 2026-10-05T12:25:13Z + updated: 2026-10-05T12:25:13Z + spec: null + acceptance_criteria: + - crates/aprender-ci-tools has a tarball-shrink-report subcommand ported from scripts/lib/tarball_shrink_report.py + - scripts/tests/ci_tools_py_parity_test.sh runs every case through the original (the in-tree .py, as external validator) and the Rust bin. stdout is byte-identical and the exit code agrees, covering empty inputs, a full fixture, missing inputs (exit 2), one bad input (a directory named x.rs, exit 1) and the live crates/ tree. A planted defect in the port turns it red + - 'scripts/package_tarball_build.sh, the only caller, stays on the .py: it runs on a CI gate path (check_package_includes.sh --self-test), and gate tools must already be released. The switch and the delete are a follow-up once a released aprender-ci-tools carries the port' + - The crate README lists the deliberate differences (usage error exit 1 under clap; Unicode Other_Alphabetic characters as word characters) + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'Branch-only, no PR. Base is the PMAT-4741 branch.' + epic: 4741 +- id: PMAT-4789 + github_issue: 4789 + item_type: task + title: 'PY-PORT: port tarball_workspace.py to aprender-ci-tools tarball-workspace (C301)' + status: planned + priority: high + assigned_to: null + created: 2026-10-05T12:25:43Z + updated: 2026-10-05T12:25:43Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null + epic: 4741 +- id: PMAT-4797 + github_issue: 4797 + item_type: task + title: 'PY-PORT-2d: port tarball_build_errors.py to aprender-ci-tools tarball-build-errors (C301)' + status: inprogress + priority: high + assigned_to: aprender-0d + created: 2026-10-05T13:47:26Z + updated: 2026-10-05T13:47:26Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null + epic: 4741 +- id: PMAT-4799 + github_issue: 4799 + item_type: task + title: 'PY-PORT-2e: port llama_fit_verdict.py to aprender-ci-tools llama-fit-verdict (C301)' + status: inprogress + priority: high + assigned_to: aprender-0d + created: 2026-10-05T14:32:33Z + updated: 2026-10-05T14:32:33Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null + epic: 4741 +- id: PMAT-4800 + github_issue: 4800 + item_type: task + title: 'PY-PORT: git_patch_id.py -> aprender-ci-tools git-patch-id' + status: planned + priority: medium + assigned_to: null + created: 2026-10-05T14:32:57Z + updated: 2026-10-05T14:32:57Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null + epic: 4741 +- id: PMAT-4802 + github_issue: 4802 + item_type: task + title: 'PY-PORT: crux-judge — retire the Python CRUX judge, oracles and certifier for tools/aprender-crux-judge' + status: inprogress + priority: medium + assigned_to: aprender-wprodmodels + created: 2026-10-05T14:52:00Z + updated: 2026-10-05T14:52:00Z + spec: null + acceptance_criteria: + - 'The binary''s collect, eval, extract, lint, certify and check subcommands replace crux_inference_judge.py, crux_oracles.py and crux_prompt_certify.py, which are deleted; every caller resolves the binary through scripts/lib/crux_judge_bin.sh' + - 'All 11 golden receipts are byte-identical (receipt JSON, Markdown, exit code); scripts/check_crux_oracles.sh and scripts/check_crux_inference_judge.sh are green against the binary, and every F6 mutant is rebuilt from mutated Rust sources and killed' + - 'run_python_cell is the one python3 seam: only the model reply plus the asserts, under unshare -rn, rlimits, python3 -I, a scrubbed env and a sentinel; each property has a planted-failure row; a missing sandbox is sandbox_unavailable, never correct' + - 'Checklist row, done: the crate''s tests carried 48 .unwrap() calls (certify 5, collect 3, judge 20, oracles 9, pyjson 4, pyval 7); the crate is outside the workspace, so the disallowed-methods lint never runs on it; each is now an expect with its reason, and the crate''s clippy.toml carries the disallowed-methods ban, which a planted unwrap proves fires' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'Branch-only, no PR, until a PR slot. Follow-ups: port the python3 fixture harness in the two case tables; the prompt set''s note at the next recertification; stale comments in four Python drivers; remove the run_python_cell seam.' + epic: 4741 +- id: PMAT-4806 + github_issue: 4806 + item_type: task + title: '0702-P3a: nightly assets rehearsal for RR-P03/P04 — build every release asset at main''s head on a schedule, never upload, no secrets (child of #4678)' + status: inprogress + priority: high + assigned_to: aprender-wprodmodels + created: 2026-10-05T15:10:00Z + updated: "2026-10-05T17:45:00Z" + spec: null + acceptance_criteria: + - '`.github/workflows/assets-rehearsal-nightly.yml` is generated from `binary-release.yml` by one script (no hand copy). The build steps are the release''s own; only the trigger, the permissions, the tag source, the checkout ref and the upload steps differ. A drift check (`--check`) regenerates and diffs, and runs first in every rehearsal run, so a release-workflow edit without a regen makes the rehearsal red rather than stale.' + - 'It cannot upload: workflow `permissions: contents: read`, no `secrets.` reference, no `environment:`, no upload or release step. Every job starts with a guard that refuses to run when a registry token (env or cargo credentials file) is present. Each property has a planted row in the case table.' + - 'The `verify` job runs `check_release_assets.sh --assets-from ` over the union of what the build jobs produced. The tag is `v-rc.0` at the run commit, so the rc stamp runs as on a real rc; a missing asset is red; a build job that could not run reads not_measured, never green.' + - 'Fleet-hours per night are stated from measured job durations.' + - 'Red/green proof: a planted upload step, a planted `secrets.` reference, a planted token and a hand edit of the generated file each go red; the clean tree is green.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'Fleet-hours per night (AC 4), measured: the GitHub jobs API durations of the successful build jobs of the last 15 binary-release.yml runs, the same jobs the rehearsal runs. Mean (max) minutes: pv 4 lanes 0.8+1.4+0.9+1.2 (max 2.5 each); all [[bin]]s aarch64 3.9 (5.2), x86_64 4.9 (6.7); apr cpu aarch64 2.9 (5.3), x86_64 4.5 (6.4), darwin 4.5 (4.5); apr cuda aarch64 2.7 (5.4), x86_64 3.8 (5.4). Sum about 32 runner-min mean, about 49 max (the sum of the per-lane maxima), plus about 3 min for the drift check and verify: about 0.6 fleet-hours per night, about 0.87 worst case, on warm caches; a cold-cache night runs longer. The first scheduled nights re-measure it. Split from the assets lane of #4720. Wiring the rehearsal into the train lane table is a gate change and is not part of this ticket: it follows three green scheduled nights. Lands as three stacked parts, each reviewed against its own planted defect: part 1 the verdict (verify, tag); part 2 the no-upload guard and lint, tested on a fixture built from the real step bodies; part 3 the generator, --check and the generated workflow.' + epic: 4678 +- id: PMAT-4862 + github_issue: 4862 + item_type: task + title: 'FLAKE-0: aprender-profile test_decision_span_event_attributes fails with ETXTBSY (Text file busy) exec race' + status: inprogress + priority: high + assigned_to: aprender-wcensus + created: 2026-10-06T08:20:00Z + updated: 2026-10-06T08:20:00Z + spec: null + acceptance_criteria: + - 'Step 1: test_decision_span_event_attributes carries #[ignore = "FLAKE-0 #4862"] and nothing else changes; every other aprender-profile test passes' + - 'Step 2: every script-writing test in sprint31_ruchy_integration_tests.rs is free of the write-fd/fork window (serialised, or the spawn retries on ETXTBSY), the test is un-ignored, and each passes 200 runs of the file under parallel load' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'Cause: the test writes a script then execs it while sibling test threads fork; a child forked in that window holds the write fd, so exec fails with ETXTBSY (run 37403017673, workspace-test shard 3). Passed on the same PR head in run 37408602581.' +- id: PMAT-4899 + github_issue: 4899 + item_type: task + title: 'EG-0: Measure — probe, oracle, contracts, corpus (no engine code)' + status: planned + priority: high + assigned_to: null + created: 2026-10-07T17:53:52Z + updated: 2026-10-07T17:53:52Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:measurement + notes: null + epic: 4898 +- id: PMAT-4900 + github_issue: 4900 + item_type: task + title: 'EG-1: Load — GGUF, tokenizer, kind' + status: planned + priority: high + assigned_to: null + created: 2026-10-07T17:53:58Z + updated: 2026-10-07T17:53:58Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null + epic: 4898 +- id: PMAT-4901 + github_issue: 4901 + item_type: task + title: 'EG-2: Embed on CPU' + status: planned + priority: high + assigned_to: null + created: 2026-10-07T17:54:04Z + updated: 2026-10-07T17:54:04Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null + epic: 4898 +- id: PMAT-4902 + github_issue: 4902 + item_type: task + title: 'EG-3: Serve' + status: planned + priority: high + assigned_to: null + created: 2026-10-07T17:54:09Z + updated: 2026-10-07T17:54:09Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null + epic: 4898 +- id: PMAT-4903 + github_issue: 4903 + item_type: task + title: 'EG-4: CUDA on sm_89 and sm_121' + status: planned + priority: high + assigned_to: null + created: 2026-10-07T17:54:14Z + updated: 2026-10-07T17:54:14Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null + epic: 4898 +- id: PMAT-4904 + github_issue: 4904 + item_type: task + title: 'EG-5: Refusals, apr qa, the ladder' + status: planned + priority: high + assigned_to: null + created: 2026-10-07T17:54:19Z + updated: 2026-10-07T17:54:19Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null + epic: 4898 +- id: PMAT-4905 + github_issue: 4905 + item_type: task + title: 'EG-6: Model ops round trip' + status: planned + priority: high + assigned_to: null + created: 2026-10-07T17:54:23Z + updated: 2026-10-07T17:54:23Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null + epic: 4898 +- id: PMAT-4906 + github_issue: 4906 + item_type: task + title: 'EG-7: Fine-tune' + status: planned + priority: high + assigned_to: null + created: 2026-10-07T17:54:28Z + updated: 2026-10-07T17:54:28Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null + epic: 4898 +- id: PMAT-4907 + github_issue: 4907 + item_type: task + title: 'EG-8: Prune, then distill' + status: planned + priority: high + assigned_to: null + created: 2026-10-07T17:54:33Z + updated: 2026-10-07T17:54:33Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null + epic: 4898 +- id: PMAT-4908 + github_issue: 4908 + item_type: task + title: 'EG-9: Evaluate, measure, dogfood' + status: planned + priority: high + assigned_to: null + created: 2026-10-07T17:54:38Z + updated: 2026-10-07T17:54:38Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null + epic: 4898 +- id: PMAT-4918 + github_issue: 4918 + item_type: task + title: streaming chat emits tool_calls (A3) + status: inprogress + priority: critical + assigned_to: null + created: 2026-10-08T13:32:24Z + updated: 2026-10-08T14:00:00Z + spec: contracts/serve-stream-tool-calls-v1.yaml + acceptance_criteria: + - With tools declared, a streamed reply that holds a tool call ends with one delta.tool_calls chunk and finish_reason tool_calls, on the live and the replayed SSE builder (T1, T2) + - The streamed calls equal the non-streaming calls for the same text, under any split of the deltas (T3) + - With no tools or tool_choice none, the stream is byte-identical to the v0.70.2 golden (T5) + - FALSIFY-SSTC-001..012 pass, each with its mutant recorded red + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null + epic: 4926 +- id: PMAT-4930 + github_issue: 4930 + item_type: task + title: 'D2: T-1 dogfood ladder gate waits for the models lane''s CRUX receipts' + status: in_progress + priority: critical + assigned_to: aprender-clerk + created: 2026-10-08T13:38:42Z + updated: 2026-10-08T13:38:42Z + spec: null + acceptance_criteria: + - 'under the standing release policy the T-1 dogfood lane starts only after the models lane exits GO, with MODEL_LADDER_CRUX_DIR and CRUX_CERT set to the receipts it wrote' + - 'a red in models, or in any lane before models ends, leaves dogfood NOT-RUN' + - 'scripts/check_release_t1_lanes_joined.sh policy cases are red on main and green with the fix; every mutant is killed' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null + epic: 3998 +- id: PMAT-4936 + github_issue: 4936 + item_type: task + title: 'x86-main: fence the fat_driver case-table annotations; section git fetch reads up to 3 times (P6)' + status: inprogress + priority: high + assigned_to: null + created: 2026-10-08T14:17:11Z + updated: 2026-10-08T14:17:16.352731207+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null + epic: 3998 +- id: PMAT-4941 + github_issue: 4941 + item_type: task + title: '#4941 feat(decide): the Laya ModernBERT encoder and decision library (carry)' + status: inprogress + priority: medium + assigned_to: null + created: 2026-10-10T08:24:58Z + updated: 2026-10-10T08:24:58Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null + epic: 4381 +- id: PMAT-4948 + github_issue: 4948 + item_type: task + title: '#4948 ci: fat-job section containers outlive cancelled runs' + status: planned + priority: high + assigned_to: null + created: 2026-10-09T08:14:39Z + updated: 2026-10-09T08:14:39Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null + epic: 3998 +- id: PMAT-4955 + github_issue: 4955 + item_type: task + title: 'Q6: non-blocking PR-path rows to nightly LAB' + status: planned + priority: high + assigned_to: null + created: 2026-10-09T09:05:55Z + updated: 2026-10-09T09:05:55Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null + epic: 3998 +- id: PMAT-4971 + github_issue: 4971 + item_type: task + title: 'V3 serving-shape parity: lambda perf041 witness for Qwen3.5-4B at c in {1,4,8,16}' + status: planned + priority: high + assigned_to: null + created: 2026-10-10T01:35:02Z + updated: 2026-10-10T01:35:02Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null + epic: 3597 +- id: PMAT-4984 + github_issue: 4984 + item_type: task + title: APR wgpu path leaks the EOS id into text and reports no finish_reason + status: planned + priority: high + assigned_to: null + created: 2026-10-09T18:43:36Z + updated: 2026-10-09T18:43:36Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null + epic: 3597 +- id: PMAT-5025 + github_issue: 5025 + item_type: task + title: 'guard: refuse a shallow fetch into the shared common git dir (#5025)' + status: planned + priority: high + assigned_to: null + created: 2026-10-12T12:32:41Z + updated: 2026-10-12T12:32:41Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null + epic: 3998 +- id: PMAT-5034 + github_issue: 5034 + item_type: task + title: 'fleet_cells_gate: wildcard waiver covers only data faults; non-date until expires' + status: planned + priority: high + assigned_to: null + created: 2026-10-12T12:33:33Z + updated: 2026-10-12T12:33:33Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null + epic: 3863 +- id: PMAT-5047 + github_issue: 5047 + item_type: task + title: 'check_roadmap_diff_additive: history row not_measured, self-test row floor (#5047)' + status: planned + priority: high + assigned_to: null + created: 2026-10-12T12:47:51Z + updated: 2026-10-12T12:47:51Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null + epic: 3998 +- id: PMAT-5053 + github_issue: 5053 + item_type: task + title: Nightly ci-pending retry same night, else red + status: planned + priority: high + assigned_to: null + created: 2026-10-10T11:53:27Z + updated: 2026-10-10T11:53:27Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null + epic: 3863 +- id: PMAT-5064 + github_issue: 5064 + item_type: task + title: 'fleet_cells_gate: self-test rows for DEL, locale, day guards; run --self-test nightly' + status: planned + priority: high + assigned_to: null + created: 2026-10-12T12:40:21Z + updated: 2026-10-12T12:40:21Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null + epic: 3863 +- id: PMAT-5080 + github_issue: 5080 + item_type: task + title: nightly_train --producers refuses a registered lane with no producer workflow on the commit + status: planned + priority: high + assigned_to: null + created: 2026-10-10T17:55:34Z + updated: 2026-10-10T17:55:34Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null + epic: 3998 +- id: PMAT-5108 + github_issue: 5108 + item_type: task + title: Scripts kill by name pattern; kill only the pid recorded at spawn + status: inprogress + priority: medium + assigned_to: null + created: 2026-10-11T02:30:22Z + updated: 2026-10-11T02:30:29.175357598+00:00 + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null + epic: 3863 +- id: PMAT-5170 + github_issue: 5170 + item_type: task + title: 'surface ledger: aprender-ci-tools row (0.71.1 P1)' + status: planned + priority: high + assigned_to: null + created: 2026-10-12T02:38:04Z + updated: 2026-10-12T02:38:04Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null + epic: 3998 +- id: PMAT-5174 + github_issue: 5174 + item_type: task + title: 'Release: decide where the R5 dogfood receipt belongs on the publish path' + status: planned + priority: high + assigned_to: null + created: 2026-10-12T02:43:24Z + updated: 2026-10-12T02:43:24Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null + epic: 3998 +- id: PMAT-5225 + github_issue: 5225 + item_type: task + title: 'PY-PORT-2f: port model_ladder_cells_produce.py to aprender-ci-tools (C301), carries #4986' + status: planned + priority: medium + assigned_to: null + created: 2026-10-12T16:14:45Z + updated: 2026-10-12T16:14:45Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null + epic: 4741 +- id: PMAT-5227 + github_issue: 5227 + item_type: task + title: apr-cli lib.rs include!d fns exceed complexity thresholds + status: planned + priority: medium + assigned_to: null + created: 2026-10-12T16:33:54Z + updated: 2026-10-12T16:33:54Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null + epic: 3863 +- id: PMAT-5256 + github_issue: 5256 + item_type: task + title: 'apr --version short sha: one fixed length (9) for build and comparators' + status: planned + priority: high + assigned_to: null + created: 2026-10-13T19:42:15Z + updated: 2026-10-13T19:42:15Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null + epic: 3998 +- id: PMAT-5282 + github_issue: 5282 + item_type: task + title: 'apr code eval E1: ontology contracts + spec' + status: planned + priority: high + assigned_to: null + created: 2026-10-14T09:10:41Z + updated: 2026-10-14T09:10:41Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:docs + notes: null + epic: 5281 +- id: PMAT-5374 + github_issue: 5374 + item_type: task + title: 'FLAKE-0: check_hardcoded_paths self-test pipe into grep -q (GH #5374)' + status: planned + priority: high + assigned_to: null + created: 2026-10-15T06:51:19Z + updated: 2026-10-15T06:51:19Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null + epic: 4780 +- id: PMAT-5463 + github_issue: 5463 + item_type: task + title: refactor 5 apr-cli files under pre-commit complexity limits + status: planned + priority: high + assigned_to: null + created: 2026-10-17T03:17:59Z + updated: 2026-10-17T03:17:59Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null + epic: 3998 +- id: PMAT-5737 + github_issue: 5737 + item_type: task + title: 'T-rollup: rollup bot (aprender-rollup crate + gh layer + bin)' + status: planned + priority: high + assigned_to: null + created: 2026-10-19T07:13:22Z + updated: 2026-10-19T07:13:22Z + spec: null + acceptance_criteria: + - 'INTAKE refs #5394; step 1 on feat/rollup-bot @138d94c28f' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null + epic: 5510 +- id: PMAT-5792 + github_issue: 5792 + item_type: task + title: 'Advisory gate: PR fails only on advisories it introduces; main-resident advisory = andon, not a block (0h stop)' + status: planned + priority: critical + assigned_to: null + created: 2026-10-20T12:27:03Z + updated: 2026-10-20T12:27:03Z + spec: null + acceptance_criteria: + - 'Contract contracts/advisory-gate-diff-v1.yaml. Refs #5791. Gate-accept: solo + non-author sign-off + Noah''s yes; workflows edits go to quorum first.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null + epic: 3863 +- id: PMAT-5817 + github_issue: 5817 + item_type: task + title: 'check_release_models_t1: measure_bogus fixture is hermetic (own CARGO_TARGET_DIR)' + status: planned + priority: high + assigned_to: null + created: 2026-10-20T23:55:53Z + updated: 2026-10-20T23:55:53Z + spec: null + acceptance_criteria: + - measure_bogus runs models_t1.sh directly; the stub cargo build writes apr 9.9.9 into an inherited CARGO_TARGET_DIR. Own target dir per fixture. + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null + epic: 5510 +- id: PMAT-5843 + github_issue: 5843 + item_type: task + title: 'MQ feeder: every 5 min enqueue the oldest green non-draft PR when the merge queue is empty' + status: planned + priority: high + assigned_to: null + created: 2026-10-21T10:55:00Z + updated: 2026-10-21T10:55:00Z + spec: null + acceptance_criteria: + - 'scripts/mq_feeder.sh --self-test green; timer live; kicked PRs re-read at 30s and skipped' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null + epic: 5510 +- id: PMAT-5846 + github_issue: 5846 + item_type: task + title: 'arm_pr_automerge.sh: stale guard-tree check name (default must be x86-main)' + status: planned + priority: high + assigned_to: null + created: 2026-10-21T10:13:29Z + updated: 2026-10-21T10:13:29Z + spec: null + acceptance_criteria: + - 'default GUARD_CHECK_NAME names a check run that exists on PR heads; --self-test fixtures updated' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null + epic: 5510 +- id: PMAT-5847 + github_issue: 5847 + item_type: task + title: 'LAB nightlies: timeout-minutes on every job and end by 05:00Z (falsifier scripts/lab/lab_timeouts_audit.sh)' + status: in_progress + priority: high + assigned_to: null + created: 2026-10-21T11:30:00Z + updated: 2026-10-22T18:30:00Z + spec: null + acceptance_criteria: + - 'scripts/lab/lab_timeouts_audit.sh is RED on the pre-fix tree (22 findings on the merge-base) and GREEN after; --self-test 11 rows' + - 'release-rehearsal-nightly.yml (cron 20 5, 455 min lower bound) is RED in the audit with no exemption by default; one owner, this ticket. Exempting it is pending quorum.' + - 'reaper catching queued + schedule runs is a separate change to the deployed pr-run-reaper.sh' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null + epic: 5510 +- id: PMAT-5873 + github_issue: 5873 + item_type: task + title: 'LAB: check_harness_server_cleanup apr-stub row races; quarantine to guards-nightly, then fix' + status: in_progress + priority: high + assigned_to: aprender-w5382 + created: 2026-10-21T15:20:00Z + updated: 2026-10-21T15:20:00Z + spec: null + acceptance_criteria: + - 'the check runs in guards-nightly (LAB), not in ci/explicit-test-commands.d' + - 'the apr-stub row no longer races (second PR)' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null + epic: 5510 +- id: PMAT-5879 + github_issue: 5879 + item_type: task + title: 'intake: coverage scan updates the #5875 report, never one ticket per function' + status: in_progress + priority: high + assigned_to: aprender-w5382 + created: 2026-10-21T16:00:00Z + updated: 2026-10-21T16:00:00Z + spec: null + acceptance_criteria: + - 'LAB check goes RED on an open "test: cover" issue not named in epic #5875, GREEN today' + - 'it runs in guards-nightly, never in a PR or merge-queue job' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: coverage-nightly.yml already edits one tracking issue by title; the per-function filer is outside the repo, this guard catches it. + epic: 5875 +- id: PMAT-5884 + github_issue: 5884 + item_type: task + title: 'mg-reuse: merge_group skips workspace-test-shard when its tree == a green PR run''s tree (Noah 16:28Z #3)' + status: planned + priority: high + assigned_to: null + created: 2026-10-21T17:05:00Z + updated: 2026-10-21T17:05:00Z + spec: null + acceptance_criteria: + - 'merge_group skips workspace-test-shard only when K1-K5 hold and the PR head run workspace-test succeeded; any difference runs the full shards' + - 'ci_mg_reuse.sh --self-test falsifier: changed main/tree -> wt=0, identical tree -> wt=1, override carries wt only when exactly 1' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null + epic: 5510 +- id: PMAT-5888 + github_issue: 5888 + item_type: task + title: aprender-rollup --version (nightly version-failed) + status: planned + priority: high + assigned_to: null + created: 2026-10-21T17:43:16Z + updated: 2026-10-21T17:43:16Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null + epic: 5510 +- id: PMAT-5889 + github_issue: 5889 + item_type: task + title: 'LAB kfocus-shadow-lab.yml: dispatch-only x86-main shadow on kfocus (OP 17:15Z parity)' + status: planned + priority: high + assigned_to: null + created: 2026-10-21T17:44:17Z + updated: 2026-10-21T17:44:17Z + spec: null + acceptance_criteria: + - 'Dispatch-only LAB workflow (C324) running x86-main at a given sha on kfocus, to compare verdicts with intel. PR #5887.' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:measurement + notes: null + epic: 5510 +- id: PMAT-5914 + github_issue: 5914 + item_type: task + title: 'pv debug-build CPU: tests lint whole contracts tree with debug pv' + status: planned + priority: high + assigned_to: null + created: 2026-10-22T07:04:44Z + updated: 2026-10-22T07:04:44Z + spec: null + acceptance_criteria: + - See handoff/pv-debug-cpu-20261022.md; PV_BIN override + shared release pv + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null + epic: 5510 +- id: PMAT-5920 + github_issue: 5920 + item_type: task + title: 'guard-cargo: parallel cargo-free lane in ci_guards.sh (merge-queue x86-main 29.3 min)' + status: planned + priority: high + assigned_to: null + created: 2026-10-22T10:40:00Z + updated: 2026-10-22T10:40:00Z + spec: null + acceptance_criteria: + - See ci/guard-lane-steps.txt; the lane is off by default (CI_GUARDS_LANE=1 opts in; C324) + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null + epic: 5510 +- id: PMAT-5924 + github_issue: 5924 + item_type: task + title: 'EMG-001 C1: workspace-test-shard single shard, threads 4 to 16' + status: planned + priority: high + assigned_to: null + created: 2026-10-22T10:55:00Z + updated: 2026-10-22T10:55:00Z + spec: null + acceptance_criteria: + - handoff/emg-001/EMG-001.md C1+C2; EMG-9 proof in PR body + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null + epic: 5510 +- id: PMAT-5952 + github_issue: 5952 + item_type: task + title: 'ci: push-to-main tier runs only HEAD^1..HEAD; use the PUSH_BEFORE range' + status: planned + priority: high + assigned_to: null + created: 2026-10-22T15:15:00Z + updated: 2026-10-22T15:15:00Z + spec: null + acceptance_criteria: + - ci_test_tier.sh push arm diffs github.event.before..HEAD with an all-zero-before guard; self-test rows plus a planted mutant + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-5955 + github_issue: 5955 + item_type: task + title: 'ci: heavy X64 jobs run only in merge_group/push; PR runs stay light (Noah 15:09Z)' + status: planned + priority: critical + assigned_to: null + created: 2026-10-22T16:20:00Z + updated: 2026-10-22T16:20:00Z + spec: null + acceptance_criteria: + - on pull_request x86-main, x86-main-advisories and workspace-test-shard do not run; pr-light does; ci / gate, gate and workspace-test pass when pr-light passes + - on merge_group, push, an empty or an unknown event the same aggregators fail when a heavy job is skipped; ci_mg_reuse.sh --self-test runs both directions plus mutants that delete the event check + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-5971 + github_issue: 5971 + item_type: task + title: 'ci: move guard-cargo, guard-tree, vendored-schemas out of x86-main into an MQ "guards" job on the existing mq lane' + status: in_progress + priority: high + assigned_to: null + created: 2026-10-22T16:30:00Z + updated: 2026-10-22T16:30:00Z + spec: null + acceptance_criteria: + - 'merge_group runs a required "guards" job on the existing [self-hosted, Linux, X64, mq] label (no new runner label) holding guard-tree, guard-cargo, vendored-schemas; x86-main drops them on merge_group' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null + epic: 5510 +- id: PMAT-5974 + github_issue: 5974 + item_type: task + title: 'ci: silicon-coverage scores a consistently empty workflow listing MISSING instead of NOT_MEASURED' + status: planned + priority: critical + assigned_to: null + created: 2026-10-22T16:49:18Z + updated: 2026-10-22T16:49:18Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null + epic: 3863 +- id: PMAT-5978 + github_issue: 5978 + item_type: task + title: 'check_silicon_coverage: re-read an all-empty listing once, print request ids' + status: planned + priority: critical + assigned_to: null + created: 2026-10-22T17:32:38Z + updated: 2026-10-22T17:32:38Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null + epic: 3863 +- id: PMAT-6041 + github_issue: 6041 + item_type: task + title: 'ci: guard-cargo#m5 mounts a toolchain that lives outside RUSTUP_HOME and fails loud when the container does not run the pinned rustc' + status: in_progress + priority: high + assigned_to: null + created: 2026-10-23T00:55:00Z + updated: 2026-10-23T00:55:00Z + spec: null + acceptance_criteria: + - 'm5 resolves the pinned toolchain with readlink -f, mounts it when outside RUSTUP_HOME, and the container step fails with FAIL(ENV) naming the resolved rustc if it is not the pinned one' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null + epic: 5510 +- id: PMAT-6042 + github_issue: 6042 + item_type: task + title: 'gate: affected_set.sh narrows docs/contracts/*.md to READERS-only (split out of #6035)' + status: in_progress + priority: high + assigned_to: null + created: 2026-10-23T11:00:00Z + updated: 2026-10-23T11:00:00Z + spec: null + acceptance_criteria: + - docs, contracts, root *.md and .claude/ paths select READERS only, not ALL + - nothing on a PR, merge-queue or release path calls affected_set.sh (dormant) + - the readers case table and self-test run as a nightly LAB step with one owner + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-6068 + github_issue: 6068 + item_type: task + title: repo_flow binding_station is the argmin of the station bounds (flow model eq 2/3/5/6) + status: planned + priority: medium + assigned_to: null + created: 2026-10-23T03:15:38Z + updated: 2026-10-23T03:15:38Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null + epic: 5923 +- id: PMAT-6102 + github_issue: 6102 + item_type: task + title: 'ci: one PR per ticket, enforced (check refuses a duplicate PR per PMAT ticket)' + status: planned + priority: high + assigned_to: null + created: 2026-10-23T07:18:45Z + updated: 2026-10-23T07:18:45Z + spec: null + acceptance_criteria: [] + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null + epic: 5923 +- id: PMAT-6123 + github_issue: 6123 + item_type: task + title: 'guard_lane_stop.sh: no date(1), clock injected (DET002; child of PMAT-5920)' + status: planned + priority: high + assigned_to: null + created: 2026-10-23T09:30:00Z + updated: 2026-10-23T09:30:00Z + spec: null + acceptance_criteria: + - scripts/guard_lane_stop.sh has no date invocation and no bashrs disable-line; bashrs lint --no-ignore reports no DET002 + - the self-test fails when ACTIVE_SINCE_EPOCH and ACTIVE_SINCE disagree + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-6131 + github_issue: 6131 + item_type: task + title: 'pmat_bin.sh reads its pin from tools.toml, one source (m36 FAIL ENV; child of PMAT-1059)' + status: in_progress + priority: high + assigned_to: null + created: 2026-10-23T10:20:00Z + updated: 2026-10-23T10:20:00Z + spec: null + acceptance_criteria: + - scripts/pmat_bin.sh holds no version literal; PMAT_PIN is tools.toml [pmat] version + - an unreadable pin returns 1, never a default + - check_hardcoded_paths.sh --self-test reads the pin from tools.toml + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-6133 + github_issue: 6133 + item_type: task + title: 'move the pmat pin to 3.42.0; re-stamp CB-200 and complexity baselines (child of PMAT-6131)' + status: in_progress + priority: high + assigned_to: null + created: 2026-10-23T10:40:00Z + updated: 2026-10-23T10:40:00Z + spec: null + acceptance_criteria: + - tools.toml [pmat] version is 3.42.0 and check_tool_versions.sh reports no pmat header mismatch + - instrument vs tree separated by measuring 3.41.1 and 3.42.0 on the same tree + - complexity_baseline.txt and cb200_baseline.txt carry tool_version=pmat 3.42.0; no count rises for tree debt + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null +- id: PMAT-6134 + github_issue: 6134 + item_type: task + title: 'EMF G3: receipts keyed by patch-id; a push re-reviews only changed patch-ids' + status: in_progress + priority: high + assigned_to: null + created: 2026-10-23T10:45:00Z + updated: 2026-10-23T10:45:00Z + spec: docs/specifications/EMF-G3-patch-id-receipts.md + acceptance_criteria: + - scripts/pr_patch_ids.sh is the one producer of per-commit patch-ids; an unreadable range or an empty set is a refusal + - mq_feeder.sh needs_seats arms a gate PR only when every head patch-id has 2 distinct seats and a 3/3 receipt, with no request-changes naming a head id + - a no-op rebase and a merge of main void 0 receipts; an amended commit voids only its own id + - the head-sha rules stay accepted; arm_pr_automerge.sh keeps its head_sha rule + - case table F1-F9 in mq_feeder.sh --self-test, each with a planted mutant + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null + epic: 5510 +- id: PMAT-6135 + github_issue: 6135 + item_type: task + title: 'mq-feeder: gate auto-arm with non-author seats + fresh_derived byte-compare (split from #6112)' + status: planned + priority: medium + assigned_to: null + created: 2026-10-23T10:35:00Z + updated: 2026-10-23T10:35:00Z + spec: null + acceptance_criteria: + - 'The mq-feeder arms a gate PR only when every head patch-id has 2 distinct non-author seats and a 3/3 fresh_derived byte-compare receipt (as #6134 needs_seats); a no-op rebase or merge of main voids 0 receipts and an amended commit voids only its own id; a falsifier test shows an author-only seat or a stale byte-compare does not arm' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null + epic: 5510 +- id: PMAT-6185 + github_issue: 6185 + item_type: task + title: 'roadmap: frozen roadmap-base.yaml, generator reads it (S1 of removing the tracked aggregate)' + status: in_progress + priority: high + assigned_to: null + created: 2026-10-23T17:20:00Z + updated: 2026-10-23T17:20:00Z + spec: null + acceptance_criteria: + - 'S1a (this change, scripts only): roadmap_fragments.py aggregate reads roadmap-base.yaml when it sits beside roadmap.yaml, check_roadmap_fragment_required.sh freezes it and judges roadmap.yaml against aggregate(roadmap-base.yaml, entries/); a scratch dir without roadmap-base.yaml behaves as before. S1b (the data-only follow-up PR, stacked on this one) adds docs/roadmaps/roadmap-base.yaml, a snapshot that equals roadmap.yaml, and rule 3 verifies it on introduction. This change deliberately contains no roadmap-base.yaml' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null + epic: null +- id: PMAT-6200 + github_issue: 6200 + item_type: task + title: 'CI: pin ci/gate, gate, mg-reuse-self-test to X64 runners' + status: planned + priority: critical + assigned_to: null + created: 2026-10-23T19:02:47Z + updated: 2026-10-23T19:02:47Z + spec: null + acceptance_criteria: + - 'ci.yml jobs mg-reuse-self-test, ci-gate (ci / gate) and gate carry the X64 label in runs-on, so no gx10 aarch64 runner can take them; a guard fails if any of the three loses it' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null + epic: 5923 +- id: PMAT-6206 + github_issue: 6206 + item_type: task + title: 'CI: fat_driver depth-1 checkout fetches tags first and surfaces git stderr' + status: planned + priority: critical + assigned_to: null + created: 2026-10-24T00:17:40Z + updated: 2026-10-24T00:17:40Z + spec: null + acceptance_criteria: + - 'fat_driver.py uses_checkout (fetch-depth 1) runs git fetch -q origin +refs/tags/*:refs/tags/* (tags only, the + forces a moved tag; no --force flag, no bare --tags) under a 600s timeout before git tag -l, and a failing git tag -l or git tag -d fails the checkout with git stderr and rc in the section log; the self-test rows (missing tag object fetched, unfetchable tag fails with stderr, moved tag does not fail the fetch, undeletable tag fails with why) each turn red under the mutants that drop the fetch, the + of the refspec, the tags-only refspec (bare --tags or a wide refspec), the failure check, the stderr, the rc, the timeout or its 600' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null + epic: 5923 +- id: PMAT-6208 + github_issue: 6208 + item_type: bug + title: 'PP-29 D6: PP-LLAMA-001 §12 rows 16, 17, 20 expired 2026-10-23, main RED' + status: in_progress + priority: high + assigned_to: aprender-w5382 + created: 2026-10-24T00:45:00Z + updated: 2026-10-24T00:45:00Z + spec: null + acceptance_criteria: + - 'scripts/spec_conformance.sh passes on the branch; rows 16, 17, 20 carry 2026-11-06 (the 0.73.0 milestone date rows 13, 15, 19, 21 already use) with the was-date shown; a changelog row names the quorum round, says none of the three has evidence, and carries the NO SPEED DELIVERED consequence for the 0.72 notes; with SPEC_CONFORMANCE_TODAY=2026-11-07 the andon is RED again for exactly these rows; derived_expiries.json is regenerated by --write' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'Re-date is renewal, not discharge; it ships only on a quorum AGREED at the final head. Real discharge needs lambda/CUDA hardware cells.' + epic: 5510 +- id: PMAT-6211 + github_issue: 6211 + item_type: task + title: 'model-ladder: per-cell memory admission so large cells do not swap the host' + status: in_progress + priority: high + assigned_to: null + created: 2026-10-24T01:00:00Z + updated: 2026-10-24T01:00:00Z + spec: null + acceptance_criteria: + - 'with --admit (LADDER_ADMIT=1 in model_ladder.sh), each cell is checked against free memory, swap in use and live runner jobs; a cell the host cannot take is recorded not_measured with the reason and never run; an unreadable host admits nothing' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null + epic: null +- id: PMAT-6212 + github_issue: 6212 + item_type: task + title: 'corpus-ingest: civil_from_days and now_utc_iso8601 tests + FALSIFY-006 (the #5590 delta not on main)' + status: in_progress + priority: low + assigned_to: aprender-w5382 + created: 2026-10-24T01:20:00Z + updated: 2026-10-24T01:20:00Z + spec: null + acceptance_criteria: + - 'cargo test -p apr-cli --bin aprender-corpus-ingest -- civil_from_days now_utc format_utc passes (3 tests); changing the 719_468 epoch offset by one turns civil_from_days_epoch_and_leap_boundaries RED; contracts/bin-apr-cli--aprender-corpus-ingest-v1.yaml carries FALSIFY-BIN-APR_CORPUS_INGEST-006 and pv validate passes' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: 'Re-cut from the EMG-001 return of #5590; its step-profiler half already landed (a743e8c23d).' + epic: 5510 +- id: PMAT-6235 + github_issue: 6235 + item_type: task + title: 'ci/sections.yml: pre-checkout ownership restore chowns to the runner uid, not 1000:1000' + status: in_progress + priority: high + assigned_to: null + created: 2026-10-24T04:30:00Z + updated: 2026-10-24T04:30:00Z + spec: null + acceptance_criteria: + - 'the three Pre-checkout ownership restore steps chown /workspace to the invoking runner uid:gid passed into the container, never a hardcoded 1000:1000' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null + epic: null +- id: PMAT-6239 + github_issue: 6239 + item_type: task + title: 'ci: pr-light runs on an X64 clean-room runner, not gx10-build' + status: in_progress + priority: high + assigned_to: null + created: 2026-10-24T05:05:00Z + updated: 2026-10-24T05:05:00Z + spec: null + acceptance_criteria: + - 'pr-light runs-on is [self-hosted, Linux, X64, clean-room] and the mg-reuse wiring check pins that exact line' + phases: [] + subtasks: [] + estimated_effort: null + labels: + - kind:code + notes: null + epic: null From d8ab4b78b42b94327f5ea31748702357bc25340e Mon Sep 17 00:00:00 2001 From: t Date: Sat, 24 Oct 2026 09:49:28 +0200 Subject: [PATCH 2/2] ci(pin-cites,completion-cited): R7 for roadmap-base.yaml and a content-bound completion exemption (GATE CHANGE, Refs #6185) Two gate changes for the frozen roadmap-base.yaml, declared in the PMAT-6185 notes and docs/audits/quorum-PMAT-6185-R1-pin-cites.md (A/B ruling, not the sign-off): 1. check_comparator_pin_citations.sh R7 loosens R1 for the one pair roadmap.yaml -> roadmap-base.yaml; the copy must carry EXACTLY the historical roadmap.yaml row's pin. Rows C20-C25, mutants drop-copy-rule, any-copy-line, drop-class-filter, widen-scope, membership-only; 43/43. 2. check_roadmap_completion_is_cited.sh leaves the base out of the count only while roadmap.yaml is in scope and holds every id the base holds. 3 case rows plus mutants path-waiver, drop-subset-test, no-live-requirement run inside the self-test (41/41). PMAT-Ticket: PMAT-6185 Co-Authored-By: Claude Sonnet 5.5 --- docs/audits/quorum-PMAT-6185-R1-pin-cites.md | 45 +++++++++++++ docs/roadmaps/entries/PMAT-6185.yaml | 2 +- docs/roadmaps/roadmap.yaml | 2 +- scripts/check_comparator_pin_citations.sh | 43 ++++++++++++- scripts/check_roadmap_completion_is_cited.sh | 68 ++++++++++++++++++++ 5 files changed, 156 insertions(+), 4 deletions(-) create mode 100644 docs/audits/quorum-PMAT-6185-R1-pin-cites.md diff --git a/docs/audits/quorum-PMAT-6185-R1-pin-cites.md b/docs/audits/quorum-PMAT-6185-R1-pin-cites.md new file mode 100644 index 0000000000..8b31ecddc0 --- /dev/null +++ b/docs/audits/quorum-PMAT-6185-R1-pin-cites.md @@ -0,0 +1,45 @@ + +# #6228 R1 comparator_pin_citations: A (rewrite 18 cites) vs B (guard exemption). Opus x3, read-only. Verdict: NOT A (3/3). Lanes: C3 / B / B = a narrow, text-pinned guard rule (not a path exemption): a file whose citing lines are identical (same n:sha12) to an already-ledgered file's is admitted; needs self-test row + mutant + non-author sign-off (gate content). Partial C: freeze base without entries that have their own file -> 1 citing line left (PMAT-962). +Why not A: 17 of 18 lines come from entries/PMAT-3741(14)/3563(2)/3740(1), which are ledgered dated history (2026-09-24); editing roadmap.yaml alone drifts aggregate --check; editing entries rewrites verbatim issue text; PMAT-962:14641 records a measurement at 39173b…. Swap roadmap.yaml->base: R4 in the guard is count-only (passes) but check_baseline_ratchets.sh set class (comm -13) refuses it. Unmeasured by lanes: nightly ratchet run, aggregate --check. +## lane 1 +**C3: change the guard's rules so that a line copied from history already on the ledger is admitted by its text, not by its path. It is not a path exemption (B), not a swap, and not A.** + +- **A is out.** Of the 18 lines, 17 come from entry files: PMAT-3741 (14), PMAT-3563 (2) and PMAT-3740 (1). Only PMAT-962 (:14641) lives in roadmap.yaml alone. `aggregate()` lets an entry file replace the base entry with the same id, so editing roadmap.yaml by itself is undone on regeneration and `aggregate --check` would drift. Editing the entry files as well trips R6, and it rewrites issue text quoted verbatim in records ledgered as dated history. The PMAT-962 title is dated history too. A rewrites history. +- **A swap is out.** The guard's own R4 only compares counts (`len(led) > len(mled)`), so a swap would pass it. But `_br_cmp_set` in `lib_baseline_ratchet.sh` checks that the new ledger is a whole-line subset of main's (`comm -13`). Its own table has a row for this case, "swap, count unchanged", and expects RED. Taking roadmap.yaml off git doesn't help either: its line goes stale under R2, and the replacement line still counts as growth. +- **B is out as worded.** The guard says nothing is exempt by path. A path exemption is a waiver, which is banned. +- **C3 is a real change to what the gate accepts.** A new ledger line is admitted only when its citing lines are text-identical to lines already ledgered at origin/main. That is the same idea as set-aperture's (a2) "moved" proof, but across files. Changing the ratchet class needs a mutant row, the non-author sign-off round and two reviews. Separately, R4's count-only check is weaker than the `set` class it claims, which is a defect worth logging. + +**What I couldn't measure:** +- I ran neither `--self-test` nor `check_baseline_ratchets.sh` on this head. +- I didn't run `aggregate --check`. +- I didn't check whether a base that drops the ids with entry files (shrinking the citations to 1 line) still aggregates byte-identically. +## lane 2 +**B**, but done as a rule change bound to a pin, not as an exemption row. + +- **A is out.** Of the 18 citing lines in `roadmap.yaml`, 16 come from fragments: PMAT-3563 at :19950 and :19965, and PMAT-3741 at :21493–21549. A fragment overrides the base entry with the same id, so editing only `roadmap.yaml` breaks `aggregate --check`. Fixing it means also editing `entries/PMAT-3563.yaml` and `entries/PMAT-3741.yaml`. Both are on the ledger as historical, and 3741 *is* the verbatim list of old-pin citations, so rewriting it falsifies dated history. Only :14641 (PMAT-962) comes from the base alone. +- **R4 swap test:** the PR-path R4 in `check_comparator_pin_citations.sh:137` only compares counts (`len(led) > len(mled)`), so a roadmap.yaml→roadmap-base.yaml swap passes it. The nightly `set` ratchet in `check_baseline_ratchets.sh` checks a whole-line subset (`comm -13`) and refuses the swap. Its own header calls a swap "an append wearing the old total". The swap also needs `roadmap.yaml` to stop citing the pin, but it's byte-identical to the base, so R1 goes red. Every C variant I tried either grows the ledger or changes a path in it. +- **Form of B:** the guard learns one rule. The declared frozen base must pin to the same `n:sha12` as the ledgered `roadmap.yaml` line (today 18:38afc7a5fac9). R6 still applies, the ledger doesn't grow, and there is no third state. Because it changes what the gate accepts, it needs a quorum sign-off from a session that is not the author, two reviews, and a self-test row plus mutant. + +**Not measured:** +- I did not run `aggregate --check` or the nightly ratchet. +- `grep` finds 0 hits in `entries/PMAT-3740.yaml`, but the ledger says 1. The guard accepts it, so it's probably a different encoding. +- A re-pin also fails the nightly whole-line `set` check, which is an existing mismatch. +## lane 3 +**B** (a narrow guard change with sign-off from a session that isn't the author), plus a C clean-up first + +- **A rewrites history and breaks `aggregate --check`.** The 18 lines belong to tickets PMAT-3563, PMAT-3741 and PMAT-3740, plus one line in PMAT-962. The first three are generated from `entries/*.yaml`, and an entry there replaces the matching base entry (`roadmap_fragments.py:91-118`). So editing `roadmap.yaml` alone fails `--check`. Editing the entries too rewrites ledgered historical records dated 2026-09-24. Line `:14641` (PMAT-962) records a measurement taken against 39173b…, so changing that pin makes the record false. +- **The C swap fails.** R4 in the guard only compares counts (`len(led) > len(mled)`, line 137), so swapping the `roadmap.yaml` ledger line for a `roadmap-base.yaml` line would pass R4. But `check_baseline_ratchets.sh` classifies this ledger as `set`, which is subset-based: "counting passes a swap, which is an append wearing the old total". A new path is RED there. The swap also needs `roadmap.yaml` to stop citing, which it can't, because it is generated from the base. Dropping it gives R1 or R2. +- **Partial C, worth doing.** Freeze the base without the entries that already have their own file in `entries/` (they are dropped from the output anyway). That takes it from 18 citing lines to 1, PMAT-962. That one line is still unledgered and still R1 under today's guard. +- **B, done right, is not a waiver.** Change what the gate accepts so that a file whose citing lines exactly match an already-ledgered file's lines (same n:sha12) is accepted. Ship it with self-test cases, a mutant and a non-author sign-off round bound to the final commit. No third state, and nothing is ever exempted by path: mutants line 272 already rejects that. + +**Not measured:** I didn't run `check_baseline_ratchets.sh` on a swapped tree, didn't run `aggregate --check` with a trimmed base, and didn't reconcile the 16 lines my grep found with the guard's 18 (probably 60b06a… citations). + +## Scope of the PR that carries this file (declared here, not in the PMAT-6185 entry) + +That PR is a **GATE CHANGE**, not data-only, and it ADDS `docs/roadmaps/roadmap-base.yaml` (S1b of #6185). The PMAT-6185 acceptance text says S1a "contains no roadmap-base.yaml" and S1b is "data-only"; that wording is superseded by this paragraph, because `check_roadmap_diff_additive` rejects any rewrite of an existing acceptance line. +It adds rule R7 to `scripts/check_comparator_pin_citations.sh`, which loosens R1 for one pair: `roadmap-base.yaml` passes unledgered only if every citing line is a byte-identical copy of a line the HISTORICAL ledger row for `roadmap.yaml` pins (fixture rows are not copyable; the copy must carry exactly the source row's pin, so a duplicated or dropped line is R1). Self-test rows C20-C25; mutants drop-copy-rule, any-copy-line, drop-class-filter, widen-scope, membership-only, all killed. Follow-up for the step that removes the tracked `roadmap.yaml`: move its ledger row onto `roadmap-base.yaml` in the same change (C24). Residual: a copy of a historical line skips R3/R6; a re-pin that drops a citing line needs the base re-cut. +This file is the A/B question ruling, not the sign-off; the review round on the final commit is the sign-off. + +### Second gate change in the same PR: completion-citation guard + +`scripts/check_roadmap_completion_is_cited.sh` counted the ~287 `status: completed` entries of the byte-copy `roadmap-base.yaml` as new uncited claims. It now leaves the base out of the count ONLY while `docs/roadmaps/roadmap.yaml` is in scope and holds every id the base holds (roadmap.yaml judges those entries). This is content-bound, not a path waiver: if roadmap.yaml is removed (the aggregate-removal step) or the base holds an id roadmap.yaml lacks, the base is judged like any roadmap file. Self-test rows cover all three cases; mutants "path waiver" and "drop the subset test" are killed. No follow-up is needed beyond the aggregate-removal step already named above. diff --git a/docs/roadmaps/entries/PMAT-6185.yaml b/docs/roadmaps/entries/PMAT-6185.yaml index aa53182aa5..c7ec035b0f 100644 --- a/docs/roadmaps/entries/PMAT-6185.yaml +++ b/docs/roadmaps/entries/PMAT-6185.yaml @@ -15,5 +15,5 @@ estimated_effort: null labels: - kind:code - notes: null + notes: 'GATE CHANGE (S1b, PR carrying docs/roadmaps/roadmap-base.yaml): S1b is NOT data-only and OVERRIDES the S1a/S1b wording in acceptance_criteria, which cannot be edited in place. It adds rule R7 to scripts/check_comparator_pin_citations.sh, loosening R1 for the one pair roadmap.yaml -> roadmap-base.yaml: the base passes unledgered only if its citing lines carry EXACTLY the pin of the historical roadmap.yaml ledger row and every line is a byte-copy of one of them. Self-test C20-C25; mutants drop-copy-rule, any-copy-line, drop-class-filter, widen-scope, membership-only. Scope and A/B ruling: docs/audits/quorum-PMAT-6185-R1-pin-cites.md. SECOND GATE CHANGE in the same PR: scripts/check_roadmap_completion_is_cited.sh does not count the completed entries of roadmap-base.yaml while docs/roadmaps/roadmap.yaml is in scope and holds EVERY id the base holds (content-bound, not a path waiver); if roadmap.yaml is removed or the base holds an id it lacks, the base is judged like any roadmap file. Self-test rows: ids all present (no records), extra id (judged), roadmap.yaml removed (judged); mutants path-waiver and drop-subset-test are killed. Follow-ups for the step removing the tracked roadmap.yaml: move the ledger row onto roadmap-base.yaml (C24) and let the completion-citation guard judge the base (it does so automatically).' epic: null diff --git a/docs/roadmaps/roadmap.yaml b/docs/roadmaps/roadmap.yaml index a048c1551d..31342f4a65 100644 --- a/docs/roadmaps/roadmap.yaml +++ b/docs/roadmaps/roadmap.yaml @@ -25876,7 +25876,7 @@ Not done, pending the ruling: moving the 31 fixture files to an obviously synthe estimated_effort: null labels: - kind:code - notes: null + notes: 'GATE CHANGE (S1b, PR carrying docs/roadmaps/roadmap-base.yaml): S1b is NOT data-only and OVERRIDES the S1a/S1b wording in acceptance_criteria, which cannot be edited in place. It adds rule R7 to scripts/check_comparator_pin_citations.sh, loosening R1 for the one pair roadmap.yaml -> roadmap-base.yaml: the base passes unledgered only if its citing lines carry EXACTLY the pin of the historical roadmap.yaml ledger row and every line is a byte-copy of one of them. Self-test C20-C25; mutants drop-copy-rule, any-copy-line, drop-class-filter, widen-scope, membership-only. Scope and A/B ruling: docs/audits/quorum-PMAT-6185-R1-pin-cites.md. SECOND GATE CHANGE in the same PR: scripts/check_roadmap_completion_is_cited.sh does not count the completed entries of roadmap-base.yaml while docs/roadmaps/roadmap.yaml is in scope and holds EVERY id the base holds (content-bound, not a path waiver); if roadmap.yaml is removed or the base holds an id it lacks, the base is judged like any roadmap file. Self-test rows: ids all present (no records), extra id (judged), roadmap.yaml removed (judged); mutants path-waiver and drop-subset-test are killed. Follow-ups for the step removing the tracked roadmap.yaml: move the ledger row onto roadmap-base.yaml (C24) and let the completion-citation guard judge the base (it does so automatically).' epic: null - id: PMAT-6200 github_issue: 6200 diff --git a/scripts/check_comparator_pin_citations.sh b/scripts/check_comparator_pin_citations.sh index 9be8962b9a..abcab039df 100755 --- a/scripts/check_comparator_pin_citations.sh +++ b/scripts/check_comparator_pin_citations.sh @@ -27,6 +27,9 @@ # R6 the file's citing lines match their pin: a line APPENDED to a ledgered file, or a dated line # EDITED in place into a live claim, is RED (#3741 quorum r3/r4) -- a ledgered file is not a # blind spot. A deliberate edit re-pins in the same diff: --pin prints the value. +# R7 docs/roadmaps/roadmap-base.yaml (a frozen byte copy of roadmap.yaml) passes unledgered ONLY if every one of its +# citing lines is a byte-identical copy of a line the HISTORICAL ledger row for docs/roadmaps/roadmap.yaml pins +# (never a fixture row). That one pair only: any other file, and one novel line in the copy, is R1. # A citation is the commit's first 7 hex digits followed by hex (git's abbreviation floor), so # the 8-digit, 9-digit and 40-digit forms of the previous pin all count. # @@ -87,7 +90,7 @@ led = entries(ledger) tracked = subprocess.run(["git", "-C", root, "ls-files", "-z", "--cached", "--others", "--exclude-standard"], capture_output=True).stdout.decode(errors="replace").split("\0") tracked = sorted({t for t in tracked if t}) if len(tracked) < 1: print("FAIL the tracked universe is empty"); sys.exit(1) -citing, pinned, decoded = {}, {}, {} +citing, pinned, decoded, ctexts = {}, {}, {}, {} for rel in tracked: if rel in (os.path.relpath(ledger, root), pin_rel): continue # the ledger and the pin file declare the old pins. NOTHING else is exempt by path or shape: a roadmap @@ -106,8 +109,18 @@ for rel in tracked: lines, texts = [], [] for i, line in enumerate(text.splitlines(), 1): if any(pt.search(line) for pt in pats): lines.append(i); texts.append(line) - if lines: citing[rel] = lines; pinned[rel] = pin_of(texts); decoded[rel] = text + if lines: citing[rel] = lines; pinned[rel] = pin_of(texts); decoded[rel] = text; ctexts[rel] = texts +# A byte-identical COPY of a citing line that a HISTORICAL ledgered file already pins (R6) is that same dated history, not a new +# claim: a frozen snapshot of roadmap.yaml (docs/roadmaps/roadmap-base.yaml) repeats its lines. NO path is exempt; one +# novel citing line in the copy is R1 like any other file. +# The copy must carry EXACTLY the source's pin (count + text hash, the row R6 holds), so a duplicated or dropped line is R1, not just a novel one. The pool +# reads the LIVE roadmap.yaml row, so when the epic removes the tracked aggregate the ledger row MOVES to roadmap-base.yaml in the same +# change (same count, so R4 holds; the file is then ledgered and R7 no longer applies; C24). A re-pin of roadmap.yaml that DROPS a +# citing line is R1 on the base until the base is re-cut or its row takes over: recorded in PMAT-6185 as a follow-up. +COPY_SRC, COPY_DST = "docs/roadmaps/roadmap.yaml", "docs/roadmaps/roadmap-base.yaml" # the one pair R7 knows +ledlines = {t for r, v in led.items() if v[0] == "historical" and r == COPY_SRC and r in ctexts for t in ctexts[r]} # NOT fixture rows: a fixture value is a sample, copying it is a claim for rel, lines in sorted(citing.items()): + if rel == COPY_DST and rel not in led and COPY_SRC in led and pinned[rel] == led[COPY_SRC][2] and all(t in ledlines for t in ctexts[rel]): continue # EXACTLY the source's pinned lines if rel not in led: print(f"FAIL R1 {rel}:{lines[0]} cites a superseded comparator pin and is not on {os.path.relpath(ledger, root)} " f"({len(lines)} line(s)). A live claim against a superseded comparator is the defect; dated history or a fixture value is listed by file, with why.") @@ -236,11 +249,32 @@ if [ "${1:-}" = "--self-test" ]; then && printf 'evidence/parity/u16.md\thistorical\ta UTF-16 record\t%s\n' "$(pin_line "$TMP/c19b" evidence/parity/u16.md)" >> "$TMP/c19b/scripts/comparator_pin_citations.txt" && git -C "$TMP/c19b" add -A expect 'C19b --pin and the judge decode UTF-16 the same way: ledgered by --pin -> green' "$TMP/c19b" 0 'every one ledgered' expect 'C17 a dated line EDITED IN PLACE into a live claim (same count, a date elsewhere) -> R6' "$TMP/c17" 1 'a citing line was EDITED in place' + pair() { # NAME CLASS DST: a roadmap.yaml with one dated citing line, ledgered as CLASS, copied byte-for-byte to DST + local d="$TMP/$1"; fixture "$1" || return 2 + mkdir -p "$d/docs/roadmaps" "$d/$(dirname "$3")" || return 2 + printf 'measured 2026-08-24 against llama.cpp %s: 0.59x\n' "$OLD" > "$d/docs/roadmaps/roadmap.yaml" + printf 'docs/roadmaps/roadmap.yaml\t%s\tdated 2026-08-24\t%s\n' "$2" "$(pin_line "$d" docs/roadmaps/roadmap.yaml)" >> "$d/scripts/comparator_pin_citations.txt" + cp "$d/docs/roadmaps/roadmap.yaml" "$d/$3" && git -C "$d" add -A + } + pair c20 historical docs/roadmaps/roadmap-base.yaml + expect 'C20 roadmap-base.yaml, a byte-copy of the historical roadmap.yaml line -> green' "$TMP/c20" 0 'every one ledgered' + pair c21 historical docs/roadmaps/roadmap-base.yaml && printf 'now CURRENT at %s\n' "$OLD" >> "$TMP/c21/docs/roadmaps/roadmap-base.yaml" && git -C "$TMP/c21" add -A + expect 'C21 that copy plus ONE novel citing line -> R1' "$TMP/c21" 1 'R1 docs/roadmaps/roadmap-base.yaml:1' + pair c22 fixture docs/roadmaps/roadmap-base.yaml + expect 'C22 a copy of a FIXTURE-class ledger line -> R1 (only historical lines can be copied)' "$TMP/c22" 1 'R1 docs/roadmaps/roadmap-base.yaml:1' + pair c23 historical evidence/parity/copy.md + expect 'C23 the same historical line copied into any OTHER path -> R1 (R7 knows one pair)' "$TMP/c23" 1 'R1 evidence/parity/copy.md:1' + pair c25 historical docs/roadmaps/roadmap-base.yaml && cat "$TMP/c25/docs/roadmaps/roadmap.yaml" >> "$TMP/c25/docs/roadmaps/roadmap-base.yaml" && git -C "$TMP/c25" add -A + expect 'C25 the copy DUPLICATES a pinned line (membership holds, the pin differs) -> R1' "$TMP/c25" 1 'R1 docs/roadmaps/roadmap-base.yaml:1' + pair c24 historical docs/roadmaps/roadmap-base.yaml && git -C "$TMP/c24" rm -qf docs/roadmaps/roadmap.yaml && sed -i 's|^docs/roadmaps/roadmap.yaml\t|docs/roadmaps/roadmap-base.yaml\t|' "$TMP/c24/scripts/comparator_pin_citations.txt" && git -C "$TMP/c24" add -A + expect 'C24 the aggregate removed and its ledger row moved onto roadmap-base.yaml -> green' "$TMP/c24" 0 'every one ledgered' fixture c16 && printf 'evidence/parity/old-ratio.md\thistorical\tdated in the file\ntests/fx/case.json\tfixture\ta sample value\n' > "$TMP/c16/scripts/comparator_pin_citations.txt" expect 'C16 a ledger line with no pin -> RED, never a pass' "$TMP/c16" 1 'TAB:' # MUTANTS: each must turn its row RED. The judge is re-sourced from a mutated copy of this file. mutant() { # NAME OLD NEW WANT-RC NEEDLE FIXTURE-DIR [MAIN-LEDGER] -- killed iff the row's expectation no longer holds + # WANT-RC/NEEDLE are the UNMUTATED row's expectation (e.g. drop-copy-rule: C20 expects rc 0). The mutant is killed when the + # mutated guard NO LONGER gives that rc+needle (disabling R7 makes C20 fail R1); it survives only if it still does. local name=$1 old=$2 new=$3 want=$4 needle=$5; shift 5 python3 - "$0" "$TMP/mut-$name.sh" "$old" "$new" <<'PY' || { printf 'FAIL mutant %s: anchor not found exactly once\n' "$name"; fails=$((fails + 1)); return; } import sys @@ -270,6 +304,11 @@ PY mutant drop-r4 ' if mled is not None and len(led) > len(mled):' ' if False:' 1 'R4 the ledger GREW' "$TMP/c6" "$TMP/c6/main-ledger.txt" mutant shape-exempt 'pin_rel):' 'pin_rel) or rel.startswith("docs/roadmaps/entries/PMAT-"):' 1 'R1 docs/roadmaps/entries/PMAT-9.yaml:1' "$TMP/c11" mutant prefix-exempt 'pin_rel):' 'pin_rel) or rel.startswith(("docs/roadmaps/", "docs/audits/quorum-")):' 1 'R1 docs/roadmaps/entries/PLANTED.yaml:1' "$TMP/c12" + mutant drop-copy-rule 'if rel == COPY_DST and rel not in led and COPY_SRC in led' 'if False and COPY_SRC in led' 0 'every one ledgered' "$TMP/c20" + mutant any-copy-line 'and pinned[rel] == led[COPY_SRC][2] and all(t in ledlines' 'and any(t in ledlines' 1 'R1 docs/roadmaps/roadmap-base.yaml:1' "$TMP/c21" + mutant drop-class-filter 'if v[0] == "historical" and r == COPY_SRC' 'if r == COPY_SRC' 1 'R1 docs/roadmaps/roadmap-base.yaml:1' "$TMP/c22" + mutant widen-scope 'if rel == COPY_DST and rel not in led and COPY_SRC' 'if rel not in led and COPY_SRC' 1 'R1 evidence/parity/copy.md:1' "$TMP/c23" + mutant membership-only 'and pinned[rel] == led[COPY_SRC][2]' '' 1 'R1 docs/roadmaps/roadmap-base.yaml:1' "$TMP/c25" mutant full-sha-only 'pats = [re.compile(r"(?/dev/null | awk -F: '{t+=$2} END {print t+0}') row 'lane scratch contributes no records' 0 "$n_lane" + # THE FROZEN BASE is judged by roadmap.yaml while roadmap.yaml holds every id it holds, and by itself otherwise. + mk docs/roadmaps/roadmap-base.yaml <<'YAML' +roadmap: +- id: R-ALIAS-DONE + status: completed + notes: null +YAML + scan_roadmaps "$TD" >"$TD/scan4.out" 2>"$TD/scan4.err" || true + row 'frozen base, ids all in roadmap.yaml: no records' 0 "$(grep -c 'roadmap-base.yaml' "$TD/scan4.out" || true)" + mk docs/roadmaps/roadmap-base.yaml <<'YAML' +roadmap: +- id: R-ALIAS-DONE + status: completed + notes: null +- id: R-ONLY-IN-BASE + status: completed + notes: null +YAML + scan_roadmaps "$TD" >"$TD/scan4.out" 2>"$TD/scan4.err" || true + row 'frozen base holding an id roadmap.yaml lacks is judged' 2 "$(grep -c 'roadmap-base.yaml' "$TD/scan4.out" || true)" + mkdir -p "$TD/nolive/docs/roadmaps" + cp "$TD/docs/roadmaps/roadmap-base.yaml" "$TD/nolive/docs/roadmaps/roadmap-base.yaml" + scan_roadmaps "$TD/nolive" >"$TD/scan5.out" 2>"$TD/scan5.err" || true + row 'roadmap.yaml removed: the base is judged' 2 "$(grep -c 'roadmap-base.yaml' "$TD/scan5.out" || true)" + rm -rf "${TD:?}/nolive" + rm -f "${TD:?}/docs/roadmaps/roadmap-base.yaml" + n_out=$(grep -c '^SCOPE out crates/other/roadmap.yaml' "$TD/scan.err" || true) row 'foreign schema is reported out of scope, not skipped' 1 "$n_out" n_rec=$(grep -c 'crates/other/roadmap.yaml' <<< "$SCAN" || true) @@ -673,6 +721,26 @@ YAML fi PR_CACHE_DIR="" + # MUTANTS. Each rewrites the frozen-base exemption in a COPY of this script and re-runs the copy's own case rows; the + # mutant is killed iff that run goes RED. SELFTEST_IN_MUTANT stops the copy from running its own mutants (no recursion). + if [ -z "${SELFTEST_IN_MUTANT:-}" ]; then + printf -- '--- mutants: the exemption must be content-bound ------------------\n' + mutant() { # NAME SED-EXPR -- killed iff the mutated script's self-test fails + mkdir -p "$TD/mut/scripts" + sed "$2" "${BASH_SOURCE[0]}" > "$TD/mut/scripts/m.sh" + if cmp -s "${BASH_SOURCE[0]}" "$TD/mut/scripts/m.sh"; then row "mutant $1 changed the script" changed same; return; fi + if SELFTEST_IN_MUTANT=1 bash "$TD/mut/scripts/m.sh" --self-test >/dev/null 2>&1; then + row "mutant $1 is killed" killed survived + else + row "mutant $1 is killed" killed killed + fi + } + mutant path-waiver 's/if rel == FROZEN_BASE and item_ids(doc) <= item_ids(_live\[0\])/if rel == FROZEN_BASE/' + mutant drop-subset-test 's/item_ids(doc) <= item_ids(_live\[0\])/True/' + mutant no-live-requirement 's/^_live = \[d for r, d in in_scope if r == LIVE_AGGREGATE\]/_live = [d for r, d in in_scope if r == LIVE_AGGREGATE] or [{"roadmap": [{"id": "R-ALIAS-DONE"}, {"id": "R-ONLY-IN-BASE"}]}]/' + rm -rf "${TD:?}/mut" + fi + printf ' %s case(s), %s failure(s)\n' "$t" "$f" if [ "$f" -ne 0 ]; then printf 'SELFTEST FAILED\n'; exit 1; fi printf 'SELFTEST PASSED — no roadmap in this tree was scanned; run with no\n'