feat(registry): S3c — the startup Selection reaches GET /v1/effective-config, and a forced accelerator that fell to cpu at RUNTIME is refused - #3349
Open
noahgift wants to merge 5 commits into
Conversation
…registry, and a forced accelerator never downgrades to cpu (#3041) Slice S3a of docs/audits/pr-3041-split-plan.md, cut fresh from origin/main; #3041 is not merged or rebased. apr_cli::registry (declared #[path] from commands_enum.rs, not lib.rs, whose include! tree carries pre-existing over-threshold functions the complexity hook would charge): a Request becomes a Resolved or a refusal over trueno::registry. Not compiled => FeatureDisabled (9); compiled but not Ready on this host => BackendUnavailable (14, new); only the default may fall to cpu. Purely additive: no call site changes behaviour in this slice. Falsifier tests/backend_refusal_case_table.rs 5/5 PASS. Mutation: both not-ready branches of resolve_in returning cpu_resolved instead of Err turns a_forced_accelerator_with_none_ready_refuses_and_never_downgrades and every_backend_value_is_resolvable_on_every_fixture_and_forced_gpu_is_never_cpu RED (observed); restored clean. Contract REG-OB-004 + REG-F-003 + the two resolution bindings; pv validate 0 errors with the in-tree pv 0.67.0. The static-guard half of the original hunk is NOT claimed here: check_backend_registry.sh is S3b and is not in this tree. Wiring: ci/explicit-test-commands.d/400-apr-cli-backend-refusal-case-table.cmd (free ordinal) and the regenerated scripts/tree_reader_tests.txt row. Removing either turns check_tree_reader_tests.sh RED in both directions (observed). Pmat-Ticket: PMAT-3041 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…registry, and a static guard keeps cfg! backend reads at zero (#3041) Slice S3b of docs/audits/pr-3041-split-plan.md, stacked on S3a; #3041 is not merged or rebased. S3a was additive — this is where behaviour moves. Call sites. `apr run` (dispatch.rs run_preflight), `apr chat` (dispatch_analysis.rs), `apr serve` (serve/mod.rs), bench compute_class/provenance, finetune wgpu_available, lib.rs emit_version_json, serve list_devices/cli_build_features and handler_gpu_completion now ask crate::registry instead of cfg!(feature=cuda|wgpu): the decision becomes a fact about the HOST, not about what was compiled. The census under crates/apr-cli/src goes 19 code reads -> 0 (the one survivor is prose in registry.rs). dispatch.rs also carries 99589f9/#3040 decompositions of dispatch_runtime_commands, dispatch_diagnostic_commands and help_producer_truth::resolve (behaviour-preserving; the same tests are the oracle). Guard. scripts/check_backend_registry.sh, 10/10 rows, both polarities. Ported off ripgrep to grep -rnE per plan decision D4b — no scripts/check_*.sh on main invokes rg and guard-runner-labels provisions none, so the rg form would have been an env-death inside guard_tree. NO-ARG IS THE GATE, not --static: guard_tree.sh runs every tracked check_*.sh BARE, so a gate hiding behind a flag would print usage, exit 2, and be a RED row for a guard that never ran. Wiring is therefore guard_tree itself (verified: it is a `run:` row of --dry-run --no-cargo, and check_guards_are_wired PASSes) — no workflow edit. Row 10 is the real mutation: cfg!(any(feature=cuda,wgpu)) back in a COPY of the real crates/apr-cli/src turns --static RED naming accel.rs. bashrs 0 errors. Contract. The static half of REG-OB-004 / REG-F-003 that S3a dropped under decision D2 is restored now that the guard exists, ids unchanged; the effective-config half stays out — it is S3c code and nothing here discharges it. pv validate 0 errors. Tests for the switched paths, which had none on either side of the split: accel::ensure_available_for and request_from_asked (cpu/default never refused in any spelling; --gpu beats --no-gpu and --backend cpu, honoured or refused but never quietly cpu) and dispatch::run_preflight (the effective_no_gpu GH-326 decision). The three-surface scan stopped accepting the needle `accel::ensure_available`, which is a SUBSTRING of `ensure_available_for` and so passed identically before and after the switch; with the needle named per surface, reverting apr chat to the old spelling turns every_accelerator_surface_calls_the_refusal RED (observed, rc 101) and restoring it GREEN. #3041 parked the pre-R-0b refusal text in accel::legacy_refusal, unreferenced, under #[allow(dead_code)] — the lint that would have reported it. Dropped: registry::not_compiled owns that message and is reached. Left for S3c: serve/mod.rs a0269f3 (effective-config set_backend_resolution), chat_generate_session_02 5b5116d (cuda_fallback_or_refuse), run_entry.rs. Pmat-Ticket: PMAT-3041 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…s rows S3b moved S3b carries S3a's 6-line module declaration at the top of commands_enum.rs (+6 for all 42 distinct cited lines, 64 tokens) and, in dispatch_analysis.rs, replaces the 4-line `accel::ensure_available(...)` call in the `apr chat` arm with the 1-line `ensure_available_for(...)` (-3 below line 1676). 13 cited lines in that file: 12 sit above the edit and do not move; one, :1699, sits below it and moves to :1696. Every token is re-pointed through a line-level diff (merge-base 7ee0eca -> branch, difflib.SequenceMatcher over lines) and accepted ONLY where the cited line's TEXT is byte-identical on both sides. No row was re-audited by hand, none was dropped, and the file was not re-serialised: normalising every `commands_enum.rs:NNN` and `dispatch_analysis.rs:NNN` token to a constant makes the before and after byte-identical. 838 lines before and after. HONEST NOTE, for the audit and not for this commit to fix: the row `apr chat ... (ACCELERATOR_GUARD crates/apr-cli/src/dispatch_analysis.rs:1699)` cites a line whose text is ` runs,` -- a field of the bench arm, not an accelerator guard -- and it already did so at the merge base. This commit moves that citation mechanically to the same text at :1696; it does not invent a new target. The guard `apr chat` actually calls now lives at ~:1668. Re-aiming that row is a re-audit, not a re-point, and is left for one. G2.1 freshness PASS 78 cited evidence files, 2 changed by this branch G2.2 PASS (no row lost, 837 comparand rows) G2.3/G2.5/G2.6/G2.4 PASS Pmat-Ticket: PMAT-3041 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…-config, and a forced accelerator that fell to cpu at RUNTIME is refused (#3041) Slice S3c of docs/audits/pr-3041-split-plan.md, stacked on S3b; #3041 is neither merged nor rebased. The plan's S3c row and the list S3b left agree exactly, and this is that list: serve/mod.rs (a0269f3), chat_generate_session_02.rs (5b5116d), run_entry.rs, effective_config.rs + effective_config_route_pp2.rs, and the contract's effective-config half. PUBLISH. realizar::api::effective_config gains a process-wide BackendResolution (OnceLock, first write wins) and the response gains `resolved` {kind, device_index, device_uid, device_name, reason, discovered_at_unix, basis, matches_loaded} beside the residency-MEASURED compute_class; matches_loaded stays null until a model is resident, so nothing is compared that cannot be. REQUIRED_TOP_LEVEL_KEYS 13 -> 14. ensure_accelerator_available/_in return the Resolved instead of dropping it. READ BACK, BOTH HALVES. #3041 published this value and asserted it only from the route side, with the route's own test supplying the value — which cannot witness the serve gate publishing the wrong thing. Adapted: the mapping run() performs is a named seam, serve::publish_backend_resolution, and the_startup_resolution_serve_publishes_is_the_one_effective_config_reports reads it back field for field through realizar's public accessor, the one the route calls. Mutations, observed rc 101: publish a constant `kind: "cpu"` -> that row RED; make resolved_report() return None -> effective_config_reports_the_startup_backend_resolution RED. RUNTIME REFUSAL. registry::after_generation arrived with S3a (registry.rs was taken whole); what S3c adds is the CALLERS — run_entry.rs before any output mode, and apr chat's CUDA-init Err arm through cuda_fallback_or_refuse, which carries the real forced flag instead of the hardcoded `false` that predated --backend. A unit test of the decision cannot see a call site that stopped asking, and that is precisely the defect the review lane measured (apr run --gpu announced `selected: wgpu`, the wgpu path failed on a Q6_K tensor, the run finished on CPU and exited 0). So the surfaces are scanned by name — with every needle assembled by format! from pieces, because this test lives IN one of the files it scans and would otherwise contain its own needle and pass with the call site deleted. Mutations, observed rc 101: delete the run_entry call -> every_generating_surface_reconciles_what_ran_with_what_was_announced RED naming `apr run`; restore chat's silent on_cuda_load_error(..., false) fallback -> the same row RED naming `apr chat`; move the run call below the --stream branch -> the_run_reconciliation_happens_before_the_first_output_branch RED. NOT TAKEN from #3041: its chat_generate_session_02.rs blob also reverts main's ShardedSafeTensors arm, so only the two 5b5116d hunks were applied (git apply -3), per the plan's "stale side, take main". CONTRACT. REG-OB-004 and REG-F-003 keep their ids. The effective-config `resolved` clause and the after_generation clause return, the test command gains its `cargo test -p aprender-serve --lib effective_config_route_pp2` leg, and the non-goal that said the serve half was "NOT claimed here" is replaced by what IS still a non-goal: the PRE-generation refusal (#3042). apr-cli reconciles AFTER generation, so the cpu run is already spent when a forced accelerator is refused — stated rather than hidden. pv validate, built from this worktree because the PATH pv is stale: 0 errors. No CI wiring is owed: both proving targets are `--lib`, which workspace-test already runs, so there is no new --test target, no ci/explicit-test-commands.d fragment and no tree_reader_tests.txt row. No surface_audit.csv row cites any file this slice touches (0 of 838 rows), so no citation moves and the ledger is untouched. apr-cli --lib 7255 passed / 0 failed / 12 ignored; aprender-serve --lib effective_config 29/0; clippy -D warnings clean on both libs; fmt clean; dogfood coverage gate PASS (G2.1 78 cited evidence files). Pmat-Ticket: PMAT-3041 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
noahgift
enabled auto-merge
September 16, 2026 07:18
|
§13.11 rung 1 — quorum shadow verdict Shadow mode: this records a verdict and merges nothing. A refusal |
… adds The registry is derived, so it is regenerated with its own --update rather than hand-merged. S3c's new test modules ride existing --lib targets; the drift the guard reported was the registry being behind the sources, not a missing wiring row. Pmat-Ticket: PMAT-3041 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Third slice of the #3041 split (
docs/audits/pr-3041-split-plan.md, #3334). Stacked on #3344 (S3b), which stacks on #3342 (S3a) — until those merge, this PR's diff shows theirs too.S3a added the library, S3b switched the call sites. S3c closes the loop at both ends: what the process resolved at startup becomes observable, and a forced accelerator that falls back at runtime is refused instead of quietly producing cpu output.
Two adaptations, both to make a claim falsifiable
#3041 published the startup resolution and then asserted it only from the route's own test, which supplied the value itself — that cannot witness the serve gate publishing the wrong thing. So:
run()'s mapping became a named seam,serve::publish_backend_resolution, read back field-for-field throughrealizar::api::effective_config::backend_resolution(). Publishing a constantkind: "cpu"turns that row RED; makingresolved_report()returnNoneturns the route row RED.format!from pieces.Five mutations, each observed RED and restored byte-identically
after_generationcall inrun_entryapr runon_cuda_load_error(…, false)fallbackapr chat--streambranchkind: "cpu"resolved_report() → NoneScope discipline
Only the two
5b5116d6chunks were taken forchat_generate_session_02.rs; #3041's blob for that file also reverts main's laterShardedSafeTensorsarm, which the plan marks "stale side, take main". The contract's effective-config andafter_generationclauses are restored with obligation ids unchanged, and the mutation text was rewritten to the mutations actually observed here rather than the ones #3041 claimed.No CI wiring is owed — both proving targets are
--lib, already inworkspace-test. Nosurface_audit.csvrow cites any file this slice touches (0 of 838), so the ledger is untouched and G2.1 is unchanged.Gate at the head commit, every leg measured with an unpiped exit code:
apr-cli --lib7255 passed / 0 failed,aprender-serve --lib effective_config29 passed, clippy-D warningsclean on both crates, fmt clean, dogfood coverage PASS,pv validate0 errors (built from the worktree — the PATHpvis two minor versions stale).Refs #3041
no-close: #3041 stays open until S4 lands; it is then closed with a pointer, per the plan. The PRE-generation refusal stays a non-goal here and is #3042.
ont-delta: resolves REG-OB-004 — the effective-config half (the served process reports its startup Selection as
resolved, and a forced accelerator that fell to cpu at runtime is refused before any output), discharged by REG-F-003's new effective-config and after_generation legs; obligation ids unchanged.🤖 Generated with Claude Code