Repository navigation
feat(apr-cli): derived-cell coverage for release surfaces, LAB checks and zero-cell refusal (#3745) - #5417
Conversation
…lexity caps Behaviour-neutral. The pre-commit complexity check judges lib.rs with everything it include!s, so pre-existing debt in help_producer_truth.rs and dispatch.rs refused any lib.rs edit. Measured (pmat analyze complexity, cyclomatic/cognitive), before -> after: - help_producer_truth::resolve 73 cognitive -> 8/22; split into long_flag_takes_value (6/7), short_flag_takes_value, bare_word (6/12). - dispatch_runtime_commands 34 cognitive -> 3/7; the Run arm moved to dispatch_run_command (10/17), the trace save-tensor block to trace_save_tensor (2/1). - dispatch_diagnostic_commands 30 cognitive -> 7/20; the Diff arm moved to dispatch_diff_command (4/5), same resolution order (file1, then file2). lib.rs now reports no violation at --max-cyclomatic 30 --max-cognitive 25. Checks: cargo check, fmt, clippy -p apr-cli --lib -D warnings clean. apr-cli lib tests: 7501 passed; 2 not measured (qa golden_output_tests that load real models were killed by the host memory cap, code not touched here). Refs #5227 keep-open: branch only; S3 of #3745 stacks on this commit Agent: aprender-a7 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… check (#3745 S3) Release surfaces may not hand-list apr's verbs or flags; they derive them from the emitted surface (S1, crates/apr-cli/src/surface.rs). The guard is a test-only module of apr-cli: - Case tables (RED and GREEN rows) run with apr-cli's lib tests: 3 passed. - The tree scan is #[ignore] and runs nightly in guards-nightly.yml with --ignored. Under the GATE/LAB rule it never runs on a PR, merge-queue or release path. One ticket, one owner (#3745); a red updates it. - The vocabulary is the release cell universe: non-foreign commands that generate or take a model-role arg. Measured on main with every command as vocabulary, the scan had 5 hits, 3 of them false positives (dogfood row names, release stage names, a cargo option-parser case arm). Restricting the vocabulary and skipping option-parser case arms removes those without editing any release script. The tree scan is RED on this commit with exactly 2 real hand lists, the migration this ticket still owes: - contracts/model-capability-ladder-v1.yaml ladder.cells.verbs - scripts/check_model_ladder.sh (the verb loop in its checker) Checks: hand_list_guard 3/0 (+1 ignored, RED as above), guards-nightly manifest ok + self-test 7/0, guards_are_wired PASS, no_timing_in_required PASS, clippy -p apr-cli --lib clean, fmt clean, roadmap/readme checks ok. Refs #3745 keep-open: S3 guard is LAB; hand-list migration (ladder cells.verbs, check_model_ladder.sh) pending Agent: aprender-a7 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…d, as a LAB check (#3745) A planted two-lane review round chose to derive the ladder's verbs from the release cell universe (the surface's own commands that take a model-role argument or generate), not from what the ladder producer happens to run: a producer that names its own verbs judges itself. - hand_list_guard.rs: ladder_gap() reads the universe from the surface and returns the command keys `ladder.cells.verbs` does not name; ladder_verbs() reads that sequence from the contract. - ladder_gap_case_table (unit): a typed subset leaves a gap, the surface's own keys close it, a contract without the sequence is refused. - the_ladder_owes_every_model_cell_command: #[ignore], LAB. It runs in the existing guards-nightly step (`hand_list_guard -- --ignored`). RED today: the ladder owes no cell to 63 commands. Unchanged on purpose: the release path still judges the ladder's own verbs (check_model_ladder.sh) and the anti-shrink floor as before. Widening that judgment is a gate change and needs its own sign-off round. The two hand lists the tree scan reports stay where they are. Refs #3745 keep-open: ladder-gap and hand-list scans are LAB reds; release-path widening needs its own gate round Agent: aprender-a7 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Under the GATE/LAB rule a LAB red opens one ticket with one owner. The ladder-gap requirement added in 7bf710a had none: it now cites #5231 (owner aprender-a7; RED, 63 commands owed). - guards-nightly.yml: the step is renamed to name both checks and both tickets; its comment gives one ticket per check. - guards_nightly_manifest.txt: the same name (the join key), and the header comment. - hand_list_guard.rs: the #[ignore] reason and doc cite #5231. Checks: check_guards_nightly_manifest.sh ok (9 entries), self-test 7/0; hand_list_guard tests 4/0, 2 ignored; fmt clean. Refs #5231 Refs #3745 keep-open: LAB reds; release-path widening needs its own gate round Agent: aprender-a7 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…n's constraint plan Refs #3745 Agent: rex Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…d a pass over zero cells is no pass (#3745) pv's shapes gate already reports release.cells and release.refusal_cells. The wrapper dropped them, so the tag and the publish could not show how many derived cells were judged, and a Pass that derived none (an empty surface) read the same as a full one. The Pass row and the #3715 ENFORCE PASS line now carry cells=N refusals=R. A Pass with 0 or no derived cells is a decline (rc 2) and prints no ENFORCE line, so cut_tag and preflight R8 refuse it. Selftest: 3 new rows plus 2 new stub bodies; removing the zero-cell check turns 3 rows red. Refs #3745 Agent: rex Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…hes its one ticket (#3745, #5231) One step ran both #[ignore]d checks, and a red went nowhere: the GATE/LAB rule says a LAB red opens or updates ONE ticket with ONE owner, and the step had no opener. It is now two steps (ids lab_hand_list, lab_ladder_gap), each logging to its own file, and each red calls scripts/lab_ticket.sh with its own label and owner. Neither id is in the #5182 ratchet opener's condition, so these reds never write the ratchet ticket. Refs #3745 Refs #5231 Agent: rex Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
# Conflicts: # crates/apr-cli/src/dispatch.rs # docs/roadmaps/roadmap.yaml
noahgift
left a comment
There was a problem hiding this comment.
seat 2, aprender-seat-s12 @3ef54fb4f2 APPROVE (no blocking finding)
Read the non-Rust surfaces in full (guards-nightly.yml, manifest, release_readiness.sh, Cargo files, the new-test wiring). I skimmed the Rust (hand_list_guard.rs, help_producer_truth.rs, dispatch.rs split) for the #[ignore] wiring and test names only, not line by line. Commit trailers: only b0a01d5, 277e654 and 6775876 carry an Opus 5.5 trailer. The other five commits show no Co-Authored-By, so I treated the PR as a whole.
- LAB, not GATE: the two new checks run only in guards-nightly.yml, as
--ignored --exactcargo tests. Both tests carry#[ignore = "LAB ..."], and the case tables stay in the normal lib tests. The openers areif: failure() && steps.<id>.outcome == 'failure'and callscripts/lab_ticket.shwith--label/--title/--owner/--log/--event/--run-url, which that script parses. One ticket with one owner each. Nothing lands on the PR, merge-queue or release path, so there is no third state. - Manifest: the two new lines match the step names exactly. The 1s figures are a local warm run and are labelled as such in the header comment.
- release_readiness.sh (this is on the release path): a Pass over zero or absent derived cells now returns rc 2 with a FAIL line, and the ENFORCE PASS line gains
cells=N refusals=M. Self-test rows cover pass, zero cells, absent release stats and no ENFORCE line on a decline. pv on main already emitsrelease.cells/refusal_cells(ReleaseStats in release_evidence.rs), so a current pv will not trip the new refusal. A stale pinned pv would now decline, which is the intended fail-closed behaviour. The perl extraction relies oncells/refusal_cellspreceding any nested object insiderelease, which the comment states. - Cargo: toml is added as a dev-dependency only, via the workspace alias, and Cargo.lock shows only that one line.
Not run: I did not build or run the tests; CI shards were pending when I read them. Non-blocking.
noahgift
left a comment
There was a problem hiding this comment.
seat 1, aprender-seat-s11 @3ef54fb4f2 APPROVE (no blocking finding; read-only diff review, CI was still pending when I read it; I did not build or run the tests and did not open the C314 receipt)
workflow sign-off (.github/workflows/guards-nightly.yml): YES. Two C324 conditions hold.
- Nothing is added to a PR, merge-queue or release path. The job's triggers are
schedule(cron 47 21) andworkflow_dispatchonly. The four new steps sit inside that nightly job, so they cannot reach a PR/MQ/release job. - They are LAB, with one ticket and one owner each. The hand-list and ladder-gap steps run the two
#[ignore]d tests with--ignored --exact, underif: !cancelled(), so a red one cannot hide the others. Each red opens or updates its single ticket through the existingscripts/lab_ticket.sh(labels lab-hand-list and lab-ladder-gap, owners rex and aprender-a7,--eventpassed, so only a scheduled night writes). The new steps have nocontinue-on-error. scripts/guards_nightly_manifest.txtgains the two lines, and its comment says the 1 s figure is a warm local run, not a CI run.
Code:
hand_list_guard.rsis#[cfg(test)]and so adds no shipped code. The case tables run in the ordinary lib tests; only the two tree scans are#[ignore]d, so nothing new that can block runs on a PR beyond the case tables.- The
dispatch.rsandhelp_producer_truth.rschanges are behaviour-preserving extractions for complexity (#5227): the diff match arm becomesdispatch_diff_command, with the samejson || cli.jsonhandling and the same quant-roundtrip branch. The flag, short-flag and bare-word logic is moved, not changed. release_readiness.sh: a pv Pass with zero or absentrelease.cellsnow declines (rc 2) and prints no ENFORCE PASS line. That is stricter, not looser. The fixtures add pass, passnocells and passnorelease rows, andrefusal_cellsexists inReleaseStatson main, so the field read is real.
Non-blocking:
derived_cellsgreps pv's JSON with a perl regex and so depends oncellscoming before any nested object inrelease. The comment says so, and the passnorelease/passnocells rows cover the two failure shapes, but a pv JSON field-order change would decline closed, not open.- A bare
tomlworkspace dep is added to apr-cli, and Cargo.lock updates to match.
|
§13.11 rung 1 — quorum shadow verdict Shadow mode: this records a verdict and merges nothing. A refusal |
…_guard tests (#3745) Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
noahgift
left a comment
There was a problem hiding this comment.
seat 1, aprender-seat-s11 @957a4f19e6 APPROVE (re-post; the previous review at 3ef54fb stands, including the workflow sign-off, YES)
I diffed 3ef54fb..957a4f1 myself: one file, one added line, apr-cli --lib hand_list_guard in scripts/tree_reader_tests.txt. It registers the new #[cfg(test)] module in the tree-reader list. The line keeps the list's sort order (after commands::tokenize) and its tab-separated form. It does not touch .github/workflows/, so the guards-nightly.yml sign-off is unchanged: schedule and dispatch only, LAB, nothing on a PR, merge-queue or release path. I did not build or run anything.
noahgift
left a comment
There was a problem hiding this comment.
seat 2, aprender-seat-s12 @957a4f19e6 APPROVE (no blocking finding)
Delta from my earlier approval at 3ef54fb: git diff 3ef54fb4f2 957a4f19e6 is one added line in scripts/tree_reader_tests.txt, apr-cli --lib hand_list_guard. It registers the new module's lib tests, sorted in place among the other apr-cli --lib entries and in the same tab-separated shape. Nothing else changed, so my earlier findings and caveats (Rust skimmed, tests not run) carry over unchanged.
…#3745) The job runs --ignored tests on the shared X64 clean-room host, so check_perf_concurrency_groups.sh needs a job-level perf-<host> group. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
noahgift
left a comment
There was a problem hiding this comment.
seat 1, aprender-seat-s11 @33ef503a4c APPROVE (re-post; earlier reviews stand)
workflow sign-off (guards-nightly.yml): YES, unchanged in substance. The only workflow delta since 957a4f1 is a 7-line job-level concurrency: {group: perf-intel, cancel-in-progress: false} block. It adds nothing to a PR, merge-queue or release path: the triggers are still schedule and workflow_dispatch only. With cancel-in-progress: false the nightly queues behind the other perf-intel jobs and nothing is cancelled. That is the only effect, and it matters only when two nightlies overlap. The PR's file set is the same 13 files as at 957a4f1; the rest of the head is the main merge. I did not build or run anything and did not open the C314 receipt.
noahgift
left a comment
There was a problem hiding this comment.
seat 2, aprender-seat-s12 @33ef503a4c APPROVE (no blocking finding)
Delta from 957a4f1: commit 1b7adbb plus a main merge (79d2b05 is #5415 and other main content; the ollama.rs, ladder and surface_audit changes in the compare are main's, not this PR's).
- The PR's own change is the 7-line
concurrency:block on the guards-nightly job:group: perf-intel,cancel-in-progress: false. The group name is character-identical to the ones in nightly-bench.yml and beat-speed-nightly.yml, so the job serialises against them on the shared host rather than racing or cancelling.cancel-in-progress: falsequeues, never kills a running bench.scripts/check_perf_concurrency_groups.shexists on the head, as the comment says. - It is a nightly-only job, so there is no PR, merge-queue or release path effect, and the GATE/LAB split is intact.
- My earlier findings and caveats (Rust skimmed, tests not run) carry over unchanged.
|
Pace scan: 11 commits, 2 main-merges (10-16 07:20, 08:48) and a regen of tree_reader_tests.txt and a concurrency-group fix landing within an hour of each other on 10-16. Rule: one push per fix round (#5430 countermeasures 2-3): push after local green, no main-merge/update-branch push onto a head with CI running or seats pending unless BEHIND blocks arming, batch fixups into one push. Commit counts are a proxy for pushes (GitHub does not expose pushes per PR). No action needed on merges; this is a pace note (PACE-8). Agent: la-0.74 |
What
Derived-cell coverage for the release surfaces (#3745), as LAB checks plus one release-readiness hardening:
hand_list_guard(apr-cli): scans release surfaces for hand-maintained command lists, as a LAB nightly check.scripts/lab_ticket.sh(two steps, two log files; neither writes the ratchet ticket).release_readiness.sh: the Pass row and the 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 #3715 ENFORCE PASS line carrycells=N refusals=R, and a Pass over zero derived cells is a decline (rc 2), so cut_tag and preflight R8 refuse it. Selftest: 3 new rows, removing the zero-cell check turns 3 red.resolveand the dispatch arms are split under the complexity caps (apr-cli: lib.rs include!d functions exceed complexity thresholds (resolve, dispatch_*) #5227).Notes
LAB checks run nightly only, never in a PR, merge-queue or release job.
Merged main in twice (no force); latest merge resolved
dispatch.rs(main'sdispatch_run_commandkept, the older duplicate dropped) and regeneratedroadmap.yamlfrom its fragments.Verification
cargo test -p apr-cli --libfor hand_list_guard, help_producer_truth and dispatch: 83 passedcargo clippy -p apr-cli --lib -- -D warningsandcargo fmt --all -- --check: cleanmake roadmap-aggregate-check,make readme-sync: okRefs #3745
Refs #5231
Refs #5227
keep-open: #3745, #5231 and #5227 stay open; this is one step of each.
🤖 Generated with Claude Code