Repository navigation
Revert the split release admission change from the 1.11.1 train - #823
Conversation
There was a problem hiding this comment.
Graphify reviewed this change.
Code graph out of date: Health delta baseline: last indexed commit f5e929d, 56 commit(s) behind this PR's base. Impact and hotspot numbers below may be wrong.
Worth a look — the grounded gate found no coupling regressions or blocking issues, but 2 advisory finding(s) below merit a look before merge.
Not checked: tests were not run; formal verification proved 0 of 23 changed function(s) (5 sampled, not proven, 18 not verified).
Formal verification. PR-changed functions: 5/23 verified (0 proven, 5 may-equivalent, 0 distinguished) · 18 not verified (7 vacuous, 11 unsupported).
Not verified on this run: \_release\_split\_job\_findings (vacuous: never exercised), \_release\_split\_steps (vacuous: never exercised), runner\_findings (vacuous: never exercised), \_ci\_post\_jobs (unsupported), \_ci\_post\_proof (unsupported), \_ci\_post\_runs (unsupported), \_phase\_one (unsupported), \_read\_json (unsupported), \_read\_text (unsupported), \_release\_bump (unsupported), and 8 more.
Graphify review — findings
Reverts the two-phase release (bump, then tag) to a single workflow_dispatch run that computes the version, stamps and resets the run-failure catalog diff, and pushes the VERSION commit and tag in one atomic push before cutting the release. The gate drops the exact-SHA full ci-post requirement and the receipt artifact, and now requires only green pineforge/verify and pineforge/parity plus the App-pushed two-file bump exemption, with version planning moving back to release_version.py next. A failure after the push leaves a tag with no release, and a re-run stops at "tag already exists", so recovery is rebuilding the assets from git and running gh release create by hand.
Worth a look
- Release bump commit is not pushed to main —
.github/workflows/release.yml· Escalate · high- unverified hypothesis — survived the adversarial refute pass; needs human review
- Retrying after the atomic push can skip the unpublished release —
.github/workflows/release.yml:142· Escalate · medium- unverified hypothesis — survived the adversarial refute pass; needs human review
Review partial — this diff was larger than one review pass covers, so later files were not reviewed; some findings may be missing.
Analysis details — impact, health, verification
Impact & health
Graphify review
Impact — 1714 functions depend on the 1656 functions this change touches.
Health — grade C; 10 existing hotspot(s) in the area this change touches (pre-existing, not introduced here):
ci_workflow_findings()— 89 callers, 25 callees (high)gke_admit_workflow_findings()— 18 callers, 14 callees (high)check_commands()— 22 callers, 5 callees (high)native_workflow_findings()— 9 callers, 12 callees (high)_job_values()— 33 callers, 3 callees (high)release_prebuilt_workflow_findings()— 8 callers, 10 callees (high)admit_rule_findings()— 8 callers, 9 callees (high)_job_block()— 20 callers, 3 callees (high)- …and 2 more
Verification — 1714 functions in the blast radius were not formally verified this run (proofs are advisory here).
Health delta baseline: last indexed commit f5e929d, 56 commit(s) behind this PR's base.
Gate & verification
graphify gate
PASS — objectively clean (no health regressions, tests not run — proofs not run this pass (advisory)). Grounded, not self-assessed.
Advisory (not blocking):
- verification_scope: 1682 function(s) in the blast radius were not formally verified this run
Test selection
Test selection
1420 of 1420 test file(s) selected (100%) via static blast radius.
Escalated to a full run for safety (
noncode-change,uncovered-code) — the selection is not trustworthy on its own (see below). CI should run the whole suite.
benchmarks/tests/test_aggregate.py— full-run-safetybenchmarks/tests/test_check_provenance.py— full-run-safetybenchmarks/tests/test_compare.py— full-run-safetybenchmarks/tests/test_public_names.py— full-run-safetybenchmarks/tests/test_run_all.py— full-run-safetybenchmarks/tests/test_run_strategy_feeds.py— full-run-safetydocker/pineforge_sink_finalize_test.py— full-run-safetydocker/pineforge_sink_replay_rq_test.py— full-run-safetydocker/pineforge_sink_replay_test.py— full-run-safetydocker/pineforge_sink_to_json_test.py— full-run-safetydocker/quota_columns_test.py— full-run-safetydocker/quota_convert_test.py— full-run-safetydocker/quota_finalize_test.py— full-run-safetydocker/replay_rq_engine_test.py— full-run-safetydocker/run_json_artifact_window_test.py— full-run-safetydocker/run_json_bin_test.py— full-run-safetydocker/run_json_bounded_transport_test.py— full-run-safetydocker/run_json_bulk_equity_fuzz_test.py— full-run-safetydocker/run_json_bulk_equity_test.py— full-run-safetydocker/run_json_codes_test.py— full-run-safetydocker/run_json_converter_metadata_test.py— full-run-safetydocker/run_json_converter_session_test.py— full-run-safetydocker/run_json_diagnostics_test.py— full-run-safetydocker/run_json_equity_scan_test.py— full-run-safetydocker/run_json_fused_test.py— full-run-safetydocker/run_json_harnesses_test.py— full-run-safetydocker/run_json_metrics_only_test.py— full-run-safetydocker/run_json_misc2_test.py— full-run-safetydocker/run_json_misc_test.py— full-run-safetydocker/run_json_pfbar_test.py— full-run-safetydocker/run_json_provenance_test.py— full-run-safetydocker/run_json_quota_supervisor_test.py— full-run-safetydocker/run_json_replay_test.py— full-run-safetydocker/run_json_selected_sink_test.py— full-run-safetydocker/run_json_sink_lexical_test.py— full-run-safetydocker/run_json_sink_summary_test.py— full-run-safetydocker/run_json_sink_test.py— full-run-safetydocker/run_json_sink_vectors_test.py— full-run-safetydocker/run_json_spool_work_test.py— full-run-safetydocker/run_json_stringio_test.py— full-run-safetydocker/run_json_symbol_feeds_test.py— full-run-safetydocker/run_json_syminfo_test.py— full-run-safetydocker/run_json_trade_scan_test.py— full-run-safetydocker/run_json_window_budget_test.py— full-run-safetydocker/run_json_wrapper_work_test.py— full-run-safetyinclude/pineforge/native_run_spec.hpp— full-run-safetyscripts/derive_corpus_feeds_self_test.py— full-run-safetyscripts/fingerprint_self_test.py— full-run-safetyscripts/run_corpus_self_test.py— full-run-safetyscripts/test_abi_receipt_skips.py— full-run-safety- … and 1370 more
non-code file(s) changed (
.github/workflows/release.yml,docs/ci.md,docs/reference/merge-gate-and-promotion.md,scripts/fixtures/ci_preflight/release_split_phase_planned.yml) → running the full suite for safety (a code graph can't see config/fixture/data deps)
changed code file(s) with no mapped test (
.github/workflows/release.yml,docs/ci.md,docs/reference/merge-gate-and-promotion.md) — a coverage gap or a missing link — running the full suite rather than only the selected tests
Selection is safe under the controlled-regression assumption; always-run tests + a periodic full run are the backstops. Advisory — it never changes the check verdict.
Docs that may be stale (advisory)
AGENTS.md§ Build (lines 12-25): references changed symbolsreceiptAGENTS.md§ What CI runs, per trigger (lines 46-70): references changed symbolsdiagnosticCHANGELOG.md§ Unreleased (lines 8-224): references changed symbolsinventoryCHANGELOG.md§ Report sink and scratch spill (lines 932-1143): references changed symbolsreceiptCHANGELOG.md§ run_json and CLI (lines 1144-1236): references changed symbolsreceiptCHANGELOG.md§ Run-failure codes ([#351]) (lines 2385-2475): references changed symbolsinputsCHANGELOG.md§ Migration (lines 2639-2675): references changed symbolsinputsCHANGELOG.md§ 1.3.0 — 2026-10-06 (lines 2676-2837): references changed symbolsreceiptCHANGELOG.md§ State hashes (lines 2838-2873): references changed symbolstagsCHANGELOG.md§ State hashes (lines 3116-3148): references changed symbolstags
…and 10 more.
Formal verification
Could not verify: Could not verify \_release\_split\_job\_findings.
The verifier did not have enough to check \_release\_split\_job\_findings, so it is saying so rather than guessing. No false assurance is the whole point.
Guarantee: No guarantee either way, this is an honest abstention, not a pass.
Note: Reason: not verifiable: all 63 sampled inputs raised on both versions — the function never executed, so 'no divergence' would be vacuous (mostly KeyError — names the real obstacle, not a sampling gap)
Could not verify: Could not verify \_release\_split\_steps.
The verifier did not have enough to check \_release\_split\_steps, so it is saying so rather than guessing. No false assurance is the whole point.
Guarantee: No guarantee either way, this is an honest abstention, not a pass.
Note: Reason: not verifiable: all 40 sampled inputs raised on both versions — the function never executed, so 'no divergence' would be vacuous (mostly KeyError — names the real obstacle, not a sampling gap)
No difference found (not proven): No behavior difference found in \_release\_split\_toolchain\_reader\_is\_pinned (not a proof).
The verifier ran both versions of \_release\_split\_toolchain\_reader\_is\_pinned on many inputs and saw identical behavior every time. Strong evidence the change is safe, but evidence, not a proof.
Guarantee: Empirical: differential testing (both versions run on many generated inputs). A divergence on an untested input remains possible, so this is 'no counterexample found', not 'proven equivalent'.
Note: An input the sampler did not try could still differ.
No difference found (not proven): No behavior difference found in \_release\_split\_workflow\_findings (not a proof).
The verifier ran both versions of \_release\_split\_workflow\_findings on many inputs and saw identical behavior every time. Strong evidence the change is safe, but evidence, not a proof.
Guarantee: Empirical: differential testing (both versions run on many generated inputs). A divergence on an untested input remains possible, so this is 'no counterexample found', not 'proven equivalent'.
Note: An input the sampler did not try could still differ.
No difference found (not proven): No behavior difference found in release\_bump\_workflow\_findings (not a proof).
The verifier ran both versions of release\_bump\_workflow\_findings on many inputs and saw identical behavior every time. Strong evidence the change is safe, but evidence, not a proof.
Guarantee: Empirical: differential testing (both versions run on many generated inputs). A divergence on an untested input remains possible, so this is 'no counterexample found', not 'proven equivalent'.
Note: An input the sampler did not try could still differ.
Could not verify: Could not verify runner\_findings.
The verifier did not have enough to check runner\_findings, so it is saying so rather than guessing. No false assurance is the whole point.
Guarantee: No guarantee either way, this is an honest abstention, not a pass.
Note: Reason: non-vacuity: domain too small (only 2 distinct inputs exercised, need 3) — 'no divergence' would be near-vacuous
Could not verify: Could not verify \_ci\_post\_jobs.
The verifier did not have enough to check \_ci\_post\_jobs, so it is saying so rather than guessing. No false assurance is the whole point.
Guarantee: No guarantee either way, this is an honest abstention, not a pass.
Note: Reason: parameter `api` is annotated `API` — outside the synthesizable primitive/collection set
Could not verify: Could not verify \_ci\_post\_proof.
The verifier did not have enough to check \_ci\_post\_proof, so it is saying so rather than guessing. No false assurance is the whole point.
Guarantee: No guarantee either way, this is an honest abstention, not a pass.
Note: Reason: parameter `history` is annotated `History` — outside the synthesizable primitive/collection set
Could not verify: Could not verify \_ci\_post\_runs.
The verifier did not have enough to check \_ci\_post\_runs, so it is saying so rather than guessing. No false assurance is the whole point.
Guarantee: No guarantee either way, this is an honest abstention, not a pass.
Note: Reason: parameter `api` is annotated `API` — outside the synthesizable primitive/collection set
Could not verify: Could not verify \_phase\_one.
The verifier did not have enough to check \_phase\_one, so it is saying so rather than guessing. No false assurance is the whole point.
Guarantee: No guarantee either way, this is an honest abstention, not a pass.
Note: Reason: parameter `api` is annotated `API` — outside the synthesizable primitive/collection set
Could not verify: Could not verify \_read\_json.
The verifier did not have enough to check \_read\_json, so it is saying so rather than guessing. No false assurance is the whole point.
Guarantee: No guarantee either way, this is an honest abstention, not a pass.
Note: Reason: parameter `api` is annotated `API` — outside the synthesizable primitive/collection set
Could not verify: Could not verify \_read\_text.
The verifier did not have enough to check \_read\_text, so it is saying so rather than guessing. No false assurance is the whole point.
Guarantee: No guarantee either way, this is an honest abstention, not a pass.
Note: Reason: parameter `api` is annotated `API` — outside the synthesizable primitive/collection set
Could not verify: Could not verify \_release\_bump.
The verifier did not have enough to check \_release\_bump, so it is saying so rather than guessing. No false assurance is the whole point.
Guarantee: No guarantee either way, this is an honest abstention, not a pass.
Note: Reason: parameter `api` is annotated `API` — outside the synthesizable primitive/collection set
Could not verify: Could not verify \_require\_ci\_post.
The verifier did not have enough to check \_require\_ci\_post, so it is saying so rather than guessing. No false assurance is the whole point.
Guarantee: No guarantee either way, this is an honest abstention, not a pass.
Note: Reason: parameter `api` is annotated `API` — outside the synthesizable primitive/collection set
Could not verify: Could not verify \_require\_release\_push.
The verifier did not have enough to check \_require\_release\_push, so it is saying so rather than guessing. No false assurance is the whole point.
Guarantee: No guarantee either way, this is an honest abstention, not a pass.
Note: Reason: parameter `api` is annotated `API` — outside the synthesizable primitive/collection set
Could not verify: Could not verify gate.
The verifier did not have enough to check gate, so it is saying so rather than guessing. No false assurance is the whole point.
Guarantee: No guarantee either way, this is an honest abstention, not a pass.
Note: Reason: not verifiable: all 83 sampled inputs raised on both versions — the function never executed, so 'no divergence' would be vacuous (mostly TypeError — names the real obstacle, not a sampling gap)
Could not verify: Could not verify gh\_api.
The verifier did not have enough to check gh\_api, so it is saying so rather than guessing. No false assurance is the whole point.
Guarantee: No guarantee either way, this is an honest abstention, not a pass.
Note: Reason: not verifiable: all 41 sampled inputs raised on both versions — the function never executed, so 'no divergence' would be vacuous (mostly FileNotFoundError — names the real obstacle, not a sampling gap)
Could not verify: Could not verify main.
The verifier did not have enough to check main, so it is saying so rather than guessing. No false assurance is the whole point.
Guarantee: No guarantee either way, this is an honest abstention, not a pass.
Note: Reason: not verifiable: all 73 sampled inputs raised on both versions — the function never executed, so 'no divergence' would be vacuous (mostly TypeError — names the real obstacle, not a sampling gap)
No difference found (not proven): No behavior difference found in \_\_init\_\_ (not a proof).
The verifier ran both versions of \_\_init\_\_ on many inputs and saw identical behavior every time. Strong evidence the change is safe, but evidence, not a proof.
Guarantee: Empirical: differential testing (both versions run on many generated inputs). A divergence on an untested input remains possible, so this is 'no counterexample found', not 'proven equivalent'.
Note: An input the sampler did not try could still differ.
No difference found (not proven): No behavior difference found in \_run (not a proof).
The verifier ran both versions of \_run on many inputs and saw identical behavior every time. Strong evidence the change is safe, but evidence, not a proof.
Guarantee: Empirical: differential testing (both versions run on many generated inputs). A divergence on an untested input remains possible, so this is 'no counterexample found', not 'proven equivalent'.
Note: An input the sampler did not try could still differ.
Could not verify: Could not verify do\_check.
The verifier did not have enough to check do\_check, so it is saying so rather than guessing. No false assurance is the whole point.
Guarantee: No guarantee either way, this is an honest abstention, not a pass.
Note: Reason: parameter `cfg` is annotated `Config` — outside the synthesizable primitive/collection set
Could not verify: Could not verify do\_stamp.
The verifier did not have enough to check do\_stamp, so it is saying so rather than guessing. No false assurance is the whole point.
Guarantee: No guarantee either way, this is an honest abstention, not a pass.
Note: Reason: parameter `cfg` is annotated `Config` — outside the synthesizable primitive/collection set
Could not verify: Could not verify newest\_tag.
The verifier did not have enough to check newest\_tag, so it is saying so rather than guessing. No false assurance is the whole point.
Guarantee: No guarantee either way, this is an honest abstention, not a pass.
Note: Reason: not verifiable: all 3 sampled inputs raised on both versions — the function never executed, so 'no divergence' would be vacuous (mostly AttributeError — names the real obstacle, not a sampling gap)
Takes the split release admission change (#818) out of this train. It changes the reviewed release workflow, and main's admission rules must be updated for its new shape before it can merge. It returns in the next batch together with that rule update.
This is a plain revert of the #818 merge: the release workflow and every other workflow file are byte-equal to main's, and source, include and test files are unchanged from the previous train head.
🤖 Generated with Claude Code