Repository navigation
Substrate T-E-P P1 Slice 6: indirect-call fail-closed cementing tripwire - #2200
Conversation
T-E-P-Producer-Broadening Phase 1, Slice 6. Pure cementing slice — no
producer extension, no termination-prover change, no substrate
introduction.
Indirect-call dispatch (`w.f(x)` over `Wrapper { f: fn(Int) -> Int }`)
currently lowers to a typed Diagnostic::ResolveError naming the X1.b
prerequisite. The substrate types `TransformDispatch::Indirect` and
`ArrowPortRef` named in the brief don't exist at HEAD — only a
forward-looking comment in
`prereq_x_call_on_field_access_ratchet_test.rs:105` describes where
they would land.
So at HEAD, indirect calls never reach a callable Transform node, and
the per-call descent producer correctly emits NO evidence entries for
them. That's fail-closed by structural absence: the audit's
load-bearing concern (don't let indirect calls fabricate
SubValueRelation evidence) is already satisfied by the existing X1.b
diagnostic gate.
This slice cements that invariance with a behavioral tripwire:
1. compile a `Wrapper.f(x)` fixture
2. assert the X1.b ResolveError fires (a)
3. assert per_call_descent_evidence emits NO entries attributed to
`invoke` (b)
When TransformDispatch::Indirect substrate eventually lands (a future
P1 substrate-fact-introduction slice with its own dispatch + DAG-
ancestor / coproduct-vs-coordinate / primitive-vs-lens-extensible
receipts per INVARIANTS.md), this test will fail because:
- the X1.b ResolveError will stop firing, OR
- per_call_descent_evidence will start producing entries
Either failure surfaces the producer-extension obligation atomically
with the substrate landing — same discipline pattern Slice 4's
per-arg cementing established.
Authority: gunbc#828 #issuecomment-4400468778 / Director Ask-3
ratification; gunbc#2068 #issuecomment-4402804374 Mgr-cleared
pure-cementing plan.
Cross-slice invariants preserved: no new CallPattern variant, no
TransformNode widening, no termination-prover changes, no
INVARIANTS.md P1 substrate-fact-introduction trigger.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
Review metadata
Findings
Verdict APPROVE_WITH_COMMENTS. The diff is small and the fail-closed intent is sound, but the new diagnostic assertion is more message-coupled than the testing rubric wants. Everything else in this change looks narrowly scoped and consistent with the current fail-closed boundary. |
briansrls
left a comment
There was a problem hiding this comment.
Review metadata
- Provider / model:
codex/unknown - Commit:
b9cabf3f· Trigger:schedule - Thinking:
207s wall
Non-blocking — Strengths
src/v3/compiler/tests/integration/m2_substrate_inhabitance_test.rsThe added tripwire is implementation-layer test code, documents a bounded X1.b/Indirect trigger, and reinforces P3 fail-closed behavior without adding substrate authority.
✅ No blocking concerns; the test-only change is a tracked cementing ratchet for the current indirect-call absence.
1. Story of the diffThis PR adds one cementing integration test for the current pre-substrate state of indirect calls through function-valued fields. The fixture declares 2. Invariant categories
3. VerdictREQUEST_CHANGES. The production/substrate shape is untouched, and the no-evidence assertion is the right fail-closed tripwire, but the diagnostic assertion is too string-sentinel-shaped for a PR whose only purpose is cementing a fail-closed invariant. Tighten |
… range codex BLOCKING inline finding on (closed) PR #2198 surfaced a PRE-EXISTING parallel-authority issue on main, symmetric to the Slice 5 Div issue but for Sub: `is_strictly_smaller`'s Sub arm accepts any positive integer literal, but the per-call descent producer's `positive_amount_from_i64` only materializes `PositiveDescentAmount` for `1..=MAX_PEANO_MATERIALIZATION` (dag.rs:1031-1032). So `f(n - 257)` would pass termination while the producer fails to materialize and falls back to `SubValueUnknown` — same single-authority discipline violation Slice 3 (#2182) cemented for descent_provable / ClusterDescentChecker. This issue predates Slices 1-5; Sub was the only ArithmeticOp the prover accepted, and its acceptance boundary was never tightened to match the producer. closed PR #2198 was a Div extension; this fix is the symmetric Sub cap. Cap `is_strictly_smaller`'s Sub arm at the same `1..=MAX_PEANO_MATERIALIZATION` range as the producer's materialization. Both authorities now share the same acceptance boundary on `param - k`. New regression `..._constant_descent_termination_matches_producer_acceptance_boundary` pins the boundary by rejecting `n - 257` at compile time. If either authority shifts the range, this test surfaces the divergence — same tripwire shape as the indirect-call cementing test (#2200). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
… range (#2201) codex BLOCKING inline finding on (closed) PR #2198 surfaced a PRE-EXISTING parallel-authority issue on main, symmetric to the Slice 5 Div issue but for Sub: `is_strictly_smaller`'s Sub arm accepts any positive integer literal, but the per-call descent producer's `positive_amount_from_i64` only materializes `PositiveDescentAmount` for `1..=MAX_PEANO_MATERIALIZATION` (dag.rs:1031-1032). So `f(n - 257)` would pass termination while the producer fails to materialize and falls back to `SubValueUnknown` — same single-authority discipline violation Slice 3 (#2182) cemented for descent_provable / ClusterDescentChecker. This issue predates Slices 1-5; Sub was the only ArithmeticOp the prover accepted, and its acceptance boundary was never tightened to match the producer. closed PR #2198 was a Div extension; this fix is the symmetric Sub cap. Cap `is_strictly_smaller`'s Sub arm at the same `1..=MAX_PEANO_MATERIALIZATION` range as the producer's materialization. Both authorities now share the same acceptance boundary on `param - k`. New regression `..._constant_descent_termination_matches_producer_acceptance_boundary` pins the boundary by rejecting `n - 257` at compile time. If either authority shifts the range, this test surfaces the divergence — same tripwire shape as the indirect-call cementing test (#2200). Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…dence partition (openai-pro APPROVE_WITH_COMMENTS) openai-pro review on PR #2358 sha 93f187e → 9c61c4f: 2 valid findings. §0 authority cite: replaced local filesystem path (`/Users/briansrls/.worktrees/gunbc/zesty-bear-812 thread`) with durable GitHub-comment refs: - gunbc#846 #issuecomment-4411924843 (Director's initial relay) - gunbc#846 #issuecomment-4412008376 (subsequent ratification + partner-work delegation) §3.2 evidence partition: prior framing labeled the recent-PR list as "materially reduced entries" but included enabling-only landings (#2281 +1, #2271 net 0, #2200 added entries). Re-partitioned into: - "Census-reducing landings" (only PR #2279) - "Enabling-only landings" (#2281, #2271, #2200) — substrate/scaffold work that does NOT reduce census in-PR - Recomputed rate using only census-reducing landings: ~0.25/day or ~0.5-1/cycle (upper bound) - Added explicit "Why this matters for §3.3" sentence clarifying enabling-only events are prerequisites, not reductions Boundary discipline + Modeling Faithfulness re-grounded; rate calculation now cleanly traceable to evidence. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…2358) * docs(audit): R3 PB-0 velocity walk + SG-0 census trajectory finding Director-greenlit follow-up to PR #2300 cluster analysis. Honest census walk + velocity-to-zero math against gates #8 (sg0_non_test_zero) + #84 (every_rust_test_ports_to_dag_or_generated) — the Pure-Bootstrap-Zero closure gates per THESIS.md:298 + ROADMAP.md:53/88. LOAD-BEARING FINDING: SG-0 census is GROWING, not shrinking. 9-day delta 2026-04-30 → 2026-05-09: +30 entries (119 → 149), at +3.3/day average. R3 close requires gates #8 + #84 reach 0; at current trajectory the gates never close. Per-class partition shows ~80-90 of 101 test entries dissolve via single bulk event when Cluster M (T-Tests-As-Data-Completeness) lands; remaining classes dissolve via PB-Runtime + T-V2-Retirement + T-Tier3-Dissolution + LP-Retirement. Reclassifies Cluster M as critical-path-load-bearing for PB-0 closure thesis (PR #2300 had it as parallel). Without Cluster M COMPLETE, gate #84 cannot close inside 8-12 week R3 window. Surfaces 2 NEW honest-close risks (Risk 5 trajectory + Risk 6 Cluster M dispatch status) for Director cycle absorption + Brian-tier framing question on whether "PB-0 by R3 close" is still load-bearing or has drifted. Cites THESIS.md, ROADMAP.md, r3-program-plan.md §1.8 + §10, prior cluster analysis as parents; does not restate gate Pass-conditions. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(audit): §4 dependency picture — separate substrate-flow vs PB-0-closure edges (codex BLOCKING) Codex review on PR #2358 line 92: §4 dependency diagram had A → B → M (substrate flow) but §5 Risk 4 + PR #2300 §4 Risk 2 reference M → B → E (PB-0-closure sequencing). Inconsistent edge directions violated INVARIANTS P2/P5 single-authority-metadata for sequencing. Resolution: §4 now explicitly carries two edge-classes: - View 1 substrate-flow: A → {B, M} (parallel-post-A) - View 2 PB-0-closure: M → (B-PB-0-honest cementing-in-dag) → E Both views are simultaneously true under different relations (substrate-availability vs closure-readiness). The "M → B → E" sequencing in §5 Risk 4 corresponds to View 2 — closure-honesty sequencing, not substrate flow. PR #2300 §2 had M classified as "parallel" which is correct under View 1 substrate-flow but missed View 2 PB-0-closure-readiness; this audit's reclassification of M as "critical-path" is correct under View 2 closure-flow. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(audit): §0 + §3.2 — durable authority cite + dissolution-rate evidence partition (openai-pro APPROVE_WITH_COMMENTS) openai-pro review on PR #2358 sha 93f187e → 9c61c4f: 2 valid findings. §0 authority cite: replaced local filesystem path (`/Users/briansrls/.worktrees/gunbc/zesty-bear-812 thread`) with durable GitHub-comment refs: - gunbc#846 #issuecomment-4411924843 (Director's initial relay) - gunbc#846 #issuecomment-4412008376 (subsequent ratification + partner-work delegation) §3.2 evidence partition: prior framing labeled the recent-PR list as "materially reduced entries" but included enabling-only landings (#2281 +1, #2271 net 0, #2200 added entries). Re-partitioned into: - "Census-reducing landings" (only PR #2279) - "Enabling-only landings" (#2281, #2271, #2200) — substrate/scaffold work that does NOT reduce census in-PR - Recomputed rate using only census-reducing landings: ~0.25/day or ~0.5-1/cycle (upper bound) - Added explicit "Why this matters for §3.3" sentence clarifying enabling-only events are prerequisites, not reductions Boundary discipline + Modeling Faithfulness re-grounded; rate calculation now cleanly traceable to evidence. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(audit): §8 meta-finding — closure-claims-vs-HEAD drift pattern (Director scope expansion) Director scope expansion at gunbc#846 #issuecomment-4412017502: 6 additional drift findings from parallel Director-tier audit sweep all share root cause "program-plan claims running ahead of HEAD reality." Director recommended folding pattern observation into this audit. §8 captures 9 specific drift instances across PM + 2 Director audits: 1. §1.8 status drift (this audit §1) 2. SG-0 trajectory drift (this audit §0) 3. TC1 #11 plan-language drift (Director ask 6) 4. 10 demonstration gates runtime-path drift (Director ask 7) 5. Substrate-gap-class #61 enumeration drift (Director ask 8) 6. Gate-count canonicalization drift (Director ask 9) 7. Gate #95 carve-doc cross-ref drift (Director ask 10) 8. §10.3 ratification ledger publication drift (Director ask 11) 9. R4-carve hand-Rust drift (PM ask 2026-05-09 at #828 #issuecomment-4412052024) Pattern shape: every instance is "document text asserts a closure-state that HEAD does not satisfy" via 4 sub-shapes (post-R3 substrate dep / trajectory divergence / one-sided conjunctive close / cross-ref drift). Standing recommendation: status-vs-HEAD grep cadence in standing PM/Director cycle (per-Mgr lane self-check + PM weekly §1.8/§10.3 grep). Meta-finding is structural-not-personnel: drift class closes when reconciliation cadence is added explicitly. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(audit): §0 audit-time snapshot disclaimer (codex BLOCKING — staleness vs HEAD) codex BLOCKING inline @ docs/audit/r3-pb0-velocity-walk-2026-05-09.md:23: "HEAD census row is stale against sg0_census_test.rs." Verified: at PR branch sha 5ea313c the census is 49 + 102 + 2 = 153; on origin/main cf1d523 it's 50 + 103 + 2 = 155. Audit cited 48 + 101 + 1 = 149/150. Audit numbers ARE stale relative to HEAD — main has moved 1 commit past the PR branch since audit authored. Fix: add explicit "audit-time snapshot" disclaimer scoping the count cells to the audit window. Live source-of-truth for SG-0 trajectory is `docs/audit/r3-sg0-trajectory-tracker.md` (daily/per-cycle refresh). The trajectory finding (growth ≥ +3.3/day; gates cannot reach zero at observed velocity) is structural and remains valid regardless of point-in-time count drift; specific cells should be read "as of audit window" not "as of HEAD now." Per `r3-sg0-trajectory-tracker.md` §7 + audit §7: methodology durable; specific numbers ephemeral. The codex finding was correct that the audit numbers were presented as if HEAD-current; disclaimer now scopes them properly. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(audit): tracker-file forward-reference (codex BLOCKING — tracker on sibling PR #2361) codex BLOCKING inline @ docs/audit/r3-pb0-velocity-walk-2026-05-09.md:17: cited `docs/audit/r3-sg0-trajectory-tracker.md` is not in PR #2358's tree — it's on sibling PR #2361. If PR #2358 merges first, the reference points to a non-existent file (P1/P2 violation). Verified: tracker file IS on PR #2361 branch (blob `85e072cf`); IS NOT on PR #2358 branch or main. Fix: refactored references to: - Cite `src/v3/compiler/tests/integration/sg0_census_test.rs` directly as the live SG-0 census source-of-truth (file IS on main) - Note tracker artifact lands via sibling PR #2361; cite-once-merged - §8 standing-recommendation updated similarly Snapshot scope disclaimer now self-contained — audit can land independently of PR #2361 merge ordering. No forward-references to non-merged sibling content remain. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(audit): §4 gate #8 partial Cluster M overlap (openai-pro REQUEST_CHANGES) openai-pro review on PR #2358 sha cf89a69: §2.2 row "infer/lower/test_runner" listed Cluster M as part of test_runner's dissolution dependency, but §4 summary claimed gate #8 is "orthogonal to M/B closure flow" — internal contradiction. Fix: amended §4 to acknowledge partial Cluster M overlap for test_runner.rs specifically (test runner retires when Cluster M's TestClaim system can drive testing end-to-end as .dag data — i.e., when #87 cementing-test discipline + bulk-port discipline land). Gate #8 is now correctly characterized: mostly orthogonal to M/B closure flow, but not fully — test_runner.rs is the specific overlap entry per §2.2. Single canonical PB-0 closure dependency picture restored across §2.2 + §4. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(audit): §1 — overclaim "every test entry has dissolution-trigger comment" corrected (codex BLOCKING) codex inline BLOCKING @ docs/audit/r3-pb0-velocity-walk-2026-05-09.md:40: prior framing claimed "every test entry has a header-comment naming a 'dissolution trigger'." Verified at HEAD: only ~32 of 103 test entries have inline header comments. The remaining ~71 are potentially untracked hand-Rust debt under INVARIANTS P1/P5 — option-(c) discipline assumes per-entry dissolution-trigger documentation but these lack it. Fix: §1 corrected to "About 32 of 103 test entries... the remaining ~71 entries lack inline dissolution-trigger comments." Added explicit audit finding: commentless entries are "potentially untracked hand-Rust debt" — they may have implicit dissolution paths (m1/m2 boundary tests via T-V2-Retirement + Tests-As-Data; sg* tests via Tests-As-Data; common/ helpers when downstream consumers retire) but lack the per-entry header comment. PM follow-up (Task 13): per-entry audit of ~71 commentless entries to classify under existing clusters OR flag as untracked debt requiring fresh substrate authoring or comment-attribution PR. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(audit): §2 cluster-level partition scope + §8 per-instance verification table (codex BLOCKING) codex top-level BLOCKING on PR #2358 sha 7a34af5: 2 valid findings. **Finding 1 — §2 trigger partition assumed-shape vs mechanical**: §2 partition was cluster-level estimation, not per-entry mechanical audit. Codex correct that "option-(c) dominance" claim needed grounding. Fix: §2 now explicitly scopes the partition as cluster-level methodology (NOT per-entry attribution) — derived from (a) inspection of header comments where present + (b) inferred classification of commentless entries by filename pattern. Per-entry verification deferred to Task 13 (UNACCOUNTED entries grep). The cluster-level partition supports §3 velocity-math finding without per-entry attribution; both §1 + §3 conclusions reproducible at cluster-level. **Finding 2 — §8 Director-audit bullets transcribed without per-instance verification**: §8 listed 9 drift instances by short reference; each bullet's grounding was implicit (verified in corresponding fix commits but not surfaced inline). Fix: §8 converted to verification table with explicit "Verification (landed authority)" column per instance. Each of the 9 drift instances now cites: - The grep-verified landed authority (e.g., `docs/r3-program-plan.md` §1.8 row #11 + Director disposition `473b99fb...`) - The fix commit / PR where addressed (e.g., PR #2361 sha 6efde88) - Dispositions where applicable (e.g., #7 dissolved by Task 12 PR #2364; #9 resolved by Director (a) ratification + Task 12) Each drift instance now self-grounds the §8 meta-finding without requiring readers to re-derive evidence per-bullet. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(audit): §1 trigger-coverage math reconcile to 101 (codex BLOCKING) codex inline BLOCKING @ docs/audit/r3-pb0-velocity-walk-2026-05-09.md:40: "trigger-coverage math says 32 of 103 test entries while the same audit snapshot and §2 say 101 test entries, so the remaining-debt count is internally inconsistent under INVARIANTS P1/P2." Verified: §1 used "32 of 103" + "remaining ~71" while §0 audit-time snapshot table line 25 + §2.1 line 56 + §2.1 line 69 + §3 line 134 all use 101. The 103 was introduced in commit ebfebae (BLOCKING fix for "every entry" overclaim) — I picked 103 instead of matching the existing 101 framing. Real internal inconsistency. Fix: §1 trigger-coverage reconciled to 101 (matches §0 audit-time snapshot table at sha c25b2d8df + §2.1 + §3 references): - "32 of 103" → "32 of 101" (with explicit cite to §0 snapshot) - "remaining ~71" → "remaining ~69" (101 − 32 = 69, partition-consistent) - §2 methodology cite "(~32 of 103 test entries per §1)" → "(~32 of 101)" Single audit-time-snapshot count (101) used consistently across §0/§1/§2/§3. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(audit): §8 row 1 source pointer — cluster-analysis (openai-pro REQUEST_CHANGES) openai-pro REQUEST_CHANGES on PR #2358 sha 2ba3719: §8 drift instance #1 sourced "9 gates likely promotable to CONSUMER_LANDED" to "this audit §1" but §1 is the SG-0 option-(c) discussion, NOT a 9-gate status audit. The source pointer didn't actually ground the row. Verified: the 9-gate inventory is in docs/audit/r3-cluster-analysis-2026-05-09.md §1 (PR #2300, on main), which says verbatim: "9 gates likely-promotable from DECLARED → CONSUMER_LANDED. 88 → ~79 still-DECLARED if Mgrs refresh ledger." Fix: row 1 source pointer corrected to cluster-analysis doc citation with verbatim quote + retain the existing grep-verification chain (§1.8 + 8 merged PRs). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * fix(audit): THESIS/ROADMAP citations to section anchors (codex non-blocking) codex review on PR #2358 sha c27502c: non-blocking — "THESIS citation says line 298 for the Pure Bootstrap quote, but the quote is at THESIS.md:282 in the current repo; fix the line pointer when touching the authority block." Verified: THESIS:298 IS the Pure Bootstrap quote on origin/main (codex may be reading a stale snapshot). But per `feedback_section_anchors_over_line_numbers`, line numbers drift — should switch to section/symbol anchors regardless. Fix: parent-doc citations switched from line-numbers to structural references: - THESIS.md "Pure Bootstrap to Zero" framing + verbatim quote (section anchor; line-anchor-immune) - ROADMAP.md T-PB-A lane row (`pb_hand_rust_at_shim_floor` predicate named explicitly) + T-PB-B lane row (`pb_rust_tests_outside_residual_zero` predicate named explicitly) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Summary
T-E-P-Producer-Broadening Phase 1, Slice 6. Pure cementing slice — no producer extension, no termination-prover change, no substrate introduction.
Per Substrate Mgr clearance at gunbc#2068 #issuecomment-4402804374 (post-STOP-and-PING substrate-shape question response), this slice pins the fail-closed-on-indirect-call invariance at HEAD with a behavioral tripwire that fires atomically when the substrate eventually lands.
Substrate state at HEAD
TransformDispatch::IndirectandArrowPortRefare comment-only forward-looking references inprereq_x_call_on_field_access_ratchet_test.rs:105. The substrate types do not exist as enum variants.w.f(x)overWrapper { f: fn(Int) -> Int }) lower to a typedDiagnostic::ResolveErrornaming the X1.b prerequisite. They never reach a callable Transform node.That's already the right behavior. The audit's load-bearing concern (don't let indirect calls fabricate
SubValueRelationevidence) is satisfied by the existing X1.b diagnostic gate.What this slice adds
A behavioral regression test that pins both halves of the invariance:
(a) The X1.b
ResolveErrormust fire for the indirect call site.(b)
per_call_descent_evidencemust emit NO entry attributed toinvoke's body.Tripwire shape
When
TransformDispatch::Indirectsubstrate eventually lands — as a separate P1 substrate-fact-introduction slice with its own dispatch + DAG-ancestor / coproduct-vs-coordinate / primitive-vs-lens-extensible receipts perINVARIANTS.md— this test will fail because:per_call_descent_evidencewill start producing entries for the indirect callEither failure surfaces the producer-extension obligation atomically with the substrate landing. Same discipline pattern Slice 4's per-arg cementing established (#2192).
Cross-slice invariants reaffirmed
CallPatternvariantTransformNodewideningINVARIANTS.mdP1 substrate-fact-introduction triggerWhy pure cementing here
After reading substrate at HEAD per Mgr's "your read" delegation (gunbc#2068 #issuecomment-4402786922), the (2a-substrate-introduction) option from the STOP-and-PING (gunbc#2068 #issuecomment-4402746171) was structurally inappropriate for a per-class slice — introducing a new TransformTarget variant would be a P1 substrate-fact-introduction with full procedure receipts, explicitly disallowed by the cross-slice invariants Mgr has been holding the lane to.
The right Slice 6 was the smaller, structurally-honest piece: cement the existing fail-closed behavior so future substrate work can't silently regress it. The substrate-introduction (real "indirect-call coverage" extension) needs its own dispatch when ratified.
Gate progress
e_p_per_call_descent_evidence_full_coverage(gate Lane B tasks #76, P1): partial — Slice 6 cements the fail-closed-on-indirect-call invariance. No additional shapes classified, but the producer's structural correctness on a class previously covered only by absence is now behaviorally pinned.Tests
e_p_per_call_descent_evidence_indirect_call_fail_closed_invariance— compiles theWrapper.f(x)fixture and asserts both halves of the invariance.e_p_per_call_descent_evidence_*tests should remain green.Test plan
invokeassertedAuthority
docs/briefs/r3-t-e-p-producer-broadening-worker.md(PR R3 Substrate #1782, MERGED)🤖 Generated with Claude Code