Repository navigation
0.69 verb set V: every one of the 111 registered apr verbs is receipted or refuses by name on Qwen3.5 #3597
Description
owner: aprender-a7 (re-owned 2026-10-09 by clerk aprender-3e for cop aprender-13: no open children)
Every verb apr exposes is in V (passes on the blessed model with a receipt, both CUDA host classes), in V2 (passes or refuses by name), or is an explicit refusal carrying removed_by. Nothing silent. Operator ruling 2026-09-20: 0.69 is verbs that are true; 0.70 is verbs that are fast.
The universe is bound — use these numbers, do not re-derive them loosely
Measured on apr 0.68.2 (crates.io) 2026-09-20:
| fact | value |
|---|---|
verbs in apr --help |
112 |
commands in contracts/apr-cli-commands-v1.yaml (SSOT) |
111 |
| difference | exactly one: clap's builtin help. Zero registry verbs missing. |
of the 111: *-lint family |
32 |
| of the 111: everything else | 79 |
So the denominator for "verbs not classified" is 111, and FALSIFY-CLI-001/002 is holding — the registry is trustworthy as the universe. Use the registry, not --help.
apr agent does not exist. The proposed refusal table lists "apr code / apr agent on Qwen 3.5". code is real; agent is not in the binary. Per the operator's own rule 2 read in the other direction, that is a list defect — drop agent rather than dogfood it.
The work
- Diff the registry against the V / V2 / refusal tables. Every one of the 111 lands in exactly one bucket. A verb in none is a list defect, filed before the cut.
- Dogfood the
[U]rows at m=1 on the blessed model (Qwen3.5-4B-Q4_K_M.gguf, sha25600fe7986…, a validated ladder rung), on intel + gx10:chat,code, tool-call round-trip throughserve. - Each becomes PASS with a receipt or a refusal with
removed_byand a named exit code. No third outcome. - Release-notes rows are generated from the receipts, not written as prose.
Known-RED going in — these are inputs, not discoveries
apr devicesreportsNotCompiledon a CUDA build (apr devices reports 'cuda unavailable reason=NotCompiled' on a binary that demonstrably runs CUDA — the first screen a user sees is wrong #3545)apr runprints noBackend:line on the--no-gpuarm (apr run: the --no-gpu arm prints no Backend: line, so the CPU arm cannot be proved (post-publish 0.68.2) #3541) and no tok/s (apr run emits no tok/s — every throughput claim from it is wall time including model load (post-publish 0.68.2) #3542)apr benchrefusesqwen35outright — the benchmark subcommand cannot measure the flagship architecture. Today that refusal is honest; it stays a refusal withremoved_by: v0.70apr chatprints[qwen35: … the GPU backend does not implement it yet (#3090)]and then, one line later,Backend: GPU (CUDA …). Both cite GPU: implement Gated DeltaNet / SSM inference for Qwen3.5 / Qwen3.8 hybrid GGUFs #3090; the second is true (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 #3595)
done_when
- 0 of the 111 registry verbs is unclassified. The
*-lintfamily (32) may take one blanket disposition rather than 32 rows — propose it, do not assume it. - Every V row has a receipt on both CUDA host classes (intel + gx10), or has been moved to a refusal with
removed_by. Partial coverage is a refusal, not a pass. - Every refusal states one line, an exit code, and
removed_by. A refusal whose text names the wrong defect is a fail-open — today's The autonomous-merge arming gate has six assertions that are inert on jq 1.6 (the majority of the pool) — a zero-byte receipt is stopped by one unrelated line #3594 refuses an empty receipt while sayingdelta_sweep.status is '', which a test asserting only "it refused" would score as a pass. Backend:and other diagnostics go to stderr;Completed in …goes to stdout. Any receipt-capturing harness reads both, and says which stream each field came from.- The classification is committed as data the release notes are generated from, not as prose in a PR body.
Blessed model, both host classes, m=1. Refs #3080, #3545, #3541, #3542, #3595, #3596.
Activity
noahgift commentedon Sep 20, 2026
BLOCKED on #3605 for the refusal bucket.
removed_byhas no shape, no schema and no validator — 0 occurrences tree-wide onorigin/main. Operator ruling 2026-09-20: no refusal is written anywhere untilremoved_byhas a shape, settled as apvcontract (refusal-receipt-v1, or a field onparity-receipt-v1), decided by this lane at Phase 0 from Σ at HEAD.That inverts the order I assumed when minting this ticket. The interim
removed_by: v0.70I ruled earlier stands only until #3605 lands, and any refusal written under it gets re-checked before the cut.The V and V2 classification work is not blocked — only the refusal bucket is. Start there.
Also added to this ticket's scope by the instrument lane's finding, for item 3: the computed but unexposed class has its first confirmed entry for free —
PhaseTimings { prefill_ms, decode_ms }is measured on the CUDA path and consumed only byserve;apr runcannot reach it. Not missing, unreachable. That is a different defect from "not implemented" and nothing currently looks for it, so item 3's question for every verb is "does it expose what the codebase already computes?" alongside "does it work?"fix(verbs): the bench refusal carried no exit code — done_when 3 was …
noahgift commentedon Sep 21, 2026
done_when 1 and the data form of 5 are done (PR #3642). done_when 2 is the row that decides 0.69, and it is a handoff.
Derived from
contracts/apr-cli-commands-v1.yaml, not hand-listed;scripts/derive_verb_classification.py --checkfails if the committed classification is not what the registry produces today, falsified both ways.The number that changes the budget: the dogfood denominator is 41, not 111
requires_modelin the registry is the discriminator, and it is a structural fact rather than a judgement:requires_model: true— model-bound, so it can carry a receipt on the blessed model, and owes one on both host classesrequires_model: false— takes no model, so "receipted on Qwen3.5" is not a statement that can be made about itremoved_byand now a measured exit codeMost of the registry cannot be receipted on a model at all. Anyone sizing done_when 2 from the headline 111 would be budgeting nearly three times the work that exists.
The
*-lintblanket disposition, proposed as askedAll 32 go to V2, because all 32 carry
requires_model: false— not 31, not "mostly". That is a disposition from a property they share rather than an exemption because counting to 32 is tedious. If one ever gainsrequires_model: trueit leaves V2 automatically and the check says so.The one refusal, now measured rather than cited
bench, measured onapr 0.68.2 (e6f77c98c)againstQwen3.5-0.8B-Q4_K_M.gguf:blk.0.ssm_a) … Load it withapr run/apr chat, which dispatch this architecture to the hybrid forward."It names the right defect and the right alternative, so it is not the fail-open done_when 3 warns about.
removed_by: v0.70.A quorum caught that my first revision quoted done_when 3 in a comment and shipped a refusal with no exit code — 3/3 unanimous. The script now refuses to emit the file at all when a refusal row is missing any of
exit_code/line/removed_by/reason/stream/measured_on.HANDOFF — done_when 2 is compute-bound and needs both host classes
41 V rows each need a receipt on intel AND gx10. done_when 2: "Partial coverage is a refusal, not a pass." Every V row is currently
dogfood: U, which records that a receipt is owed and absent. AUis not a pass and nothing in #3642 infers one.This row is not analysis-bound, it is host-bound, and I do not have both classes. A session with intel + gx10 time can take it by selector — the denominator is 41, the blessed model is
Qwen3.5-4B-Q4_K_M.gguf(sha25600fe7986…, a validated ladder rung), m=1, and the classification file is the worklist: filterbucket: V.If nobody has host time before 2026-09-22 18:00Z, this issue slips at freeze on done_when 2 alone, and that is the honest reason to record — not a scope problem, a host-availability one. done_when 3 (refusal text quality) and done_when 4 (stream discipline) also remain open, though both are much smaller than 2.
chore(audits): AD-04 quorum receipt for PMAT-3597 — AGREED 3/3 (round 2)
noahgift commentedon Sep 21, 2026
slipped_from: 0.69.0
§4.1 freeze (06x-release-schedule.md §1: "scope that is not on the platform rides the next train"). Operator, 2026-09-21, verbatim: "just by these optimization you should be able to release 0.69 today, ensure this happens". The 0.69 platform is #3669 plus the bump.
Why this row rides 0.70: done_when 1+5 are in #3642, which is red and not on the platform. Per the 2026-09-21T00:22Z comment, done_when 2 "is the row that decides 0.69, and it is a handoff". It is not done at the freeze.
— aprender-04 (cop)
noahgift commentedon Sep 21, 2026
Cop: moved to 0.69.1 and absorbed into #3745 (cells DERIVED from apr's clap surface, SHACL-enforced). Every command without a model arg owes one cell (runs, or refuses by name). The 111 come from the binary's surface, not a list.
21 remaining items
noahgift commentedon Oct 14, 2026
P0 to P1 (2026-10-14 P0 triage): P0 now means it blocks the next release or carries the operator's own words on it; this issue does neither, so it stays on the 0.71.0 milestone at P1. The operator quote in its history is a milestone-wide triage note, not words about this issue.
noahgift commentedon Oct 14, 2026
merged into #5312 (master ticket for epic #3994; triage rule 7b, 2026-10-14). It is a checklist row there; reopen this issue when work on it starts or its PR opens.
noahgift commentedon Oct 14, 2026
Moved: this sub-ticket is now a row in #5332 (Release receipts: every verb receipted, version-exact receipt keys, a working install.sh), split out of #5312 by theme.