From ac9f06281c9e021fed559f45caee33ea1ec8bb6b Mon Sep 17 00:00:00 2001 From: gunbc-ci-auto-heal Date: Sun, 27 Sep 2026 01:42:54 +0000 Subject: [PATCH 1/6] Native frontier ratchet: an owned correctness flip is admitted debt growth, per identity; an unowned increase stays lost The ratchet had no disposition for debt that GROWS because a silent wrong acceptance now refuses at a located site. v2.workflow.compile_door_cause_ownership gains CorrectnessFlipDeclaration (cause, grain, pull request, why), joined to the owning CauseOwnership row by cause_correctness_flip_lookup; gunbc.native_frontier_ratchet admits an ADDED identity (agreed at mint, or new to the universe) refused under such a cause as FrontierGrewByOwnedCorrectnessFlip, reusing the guard's PriorAcceptanceWasNeverSound for the agreed->refused half. Unowned, orphan- declared, or wrong-grain causes stay NEW DEBT / ACCEPT-TO-REFUSE; a mixed run loses exactly on its unowned part; a carried row's regression is not excused. Also corrects the claim that the nightly opens the mint PR (it only publishes an artifact) and records first-mint ordering. Co-Authored-By: Claude Opus 5.5 (1M context) --- dag/gunbc/native_frontier_debt.dag | 12 +- dag/gunbc/native_frontier_ratchet.dag | 162 +++++++++++++++++- .../native_frontier_ratchet_witness_test.dag | 139 ++++++++++++++- src/v1/stage0/src/target_invocation_host.rs | 7 +- .../workflow/compile_door_cause_ownership.dag | 57 +++++- 5 files changed, 360 insertions(+), 17 deletions(-) diff --git a/dag/gunbc/native_frontier_debt.dag b/dag/gunbc/native_frontier_debt.dag index 9037749c7ba..2e73a0aa56c 100644 --- a/dag/gunbc/native_frontier_debt.dag +++ b/dag/gunbc/native_frontier_debt.dag @@ -31,7 +31,17 @@ import gunbc.native_route_progress_guard { NativeProgressDispositionRow, NativeC // WHO WRITES IT. Nobody by hand. A row is produced only by `native_frontier_proposal_lines`, // rendered by the emitted binary from its own run, and it lands through a reviewed pull request // that carries the run receipt (host, tested tree, executable, command). The nightly -// `native-frontier` workflow opens that pull request. It is never merged automatically. +// `native-frontier` workflow only PUBLISHES the proposal (a workflow artifact, with `contents: read`); +// it opens no pull request, so every mint and re-mint is a person carrying that artifact into one. +// +// WHEN THE FIRST MINT MAY HAPPEN. A mint makes whatever the run observed the baseline, so a mint +// taken just before a known correctness flip lands records the silently wrong acceptances as +// agreement, and the flip then reads as a loss on every one of them. The first mint is therefore +// taken after the pending flips its minter knows of have landed (2026-09-27: the caret flip, +// gunbc#12392, reason caret_symbol_not_lowered), so their refusals enter as baseline debt. A flip +// landing AFTER a mint is not stranded: gunbc.native_frontier_ratchet admits it per identity as +// `FrontierGrewByOwnedCorrectnessFlip` when its cause is owned and declared in +// v2.workflow.compile_door_cause_ownership known_correctness_flips. // // THE STANDING TODAY IS UNMINTED, AND THAT IS A RED, NOT A PASS. No run has yet produced a roster: // the route's measured wall (gunbc.rung_drop v2_native_route_off_the_merge_path, re-derived by the diff --git a/dag/gunbc/native_frontier_ratchet.dag b/dag/gunbc/native_frontier_ratchet.dag index 1723bfaa10f..b74c786ec18 100644 --- a/dag/gunbc/native_frontier_ratchet.dag +++ b/dag/gunbc/native_frontier_ratchet.dag @@ -37,6 +37,7 @@ import gunbc.native_route_progress_guard { NativeProgressBaselineRow, NativeProgressObservedReading, NativeProgressObservedRow, NativeProgressFinding, NativeProgressDispositionRow, NativeCauseTransitionRow, NativeProgressDisposition, SubjectDeleted, SubjectLeftTheUniverse, SubjectRenamed, + NativeAcceptToRefuseRow, PriorAcceptanceWasNeverSound, native_exclusion_cause_reason, ReachExecutableStarted, native_progress_read_observed, native_progress_observed_rows, native_progress_reading_findings, native_progress_observed_index, native_progress_disposition_index, native_progress_baseline_index, @@ -50,6 +51,10 @@ import gunbc.native_frontier_debt { NativeFrontierRosterStanding, RosterUnminted, RosterMinted } import gunbc.native_frontier_roster { native_frontier_roster } +import v2.workflow.compile_door_cause_ownership { + CauseOwnership, CorrectnessFlipDeclaration, CauseCorrectnessFlip, FatalGrain, + known_frontier_causes, known_correctness_flips, cause_correctness_flip_lookup_over +} // THE NATIVE V2 FRONTIER RATCHET: whether one complete native run over the v2.test.* universe // kept, lost or advanced the debt `gunbc.native_frontier_roster` records. @@ -206,6 +211,117 @@ fn native_frontier_row_advanced( } } +// ═══ debt that grows because a wrong acceptance now refuses ══════════════════════════════════ + +// AN ADDED IDENTITY WHOSE DEBT IS AN OWNED CORRECTNESS FLIP. The roster is closed to growth, and +// this is the one way it grows: a change made a silently wrong acceptance refuse at a located site +// (DESIGN section 5), so the identity was never correct, only accepted. Reading that as a frontier +// loss would punish the correction and invite reverting it. So an added identity (agreed at the +// mint and refusing now, or new to the universe and refusing) is admitted when, and only when, the +// cause it refused with has a fatal-grain row in v2.workflow.compile_door_cause_ownership +// known_frontier_causes AND a known_correctness_flips declaration naming the pull request. The +// disposition carries both, so the proposal pull request shows the owner and the flip it cites. +// +// WHAT IS NEVER ADMITTED THIS WAY. A divergence (it has no cause an owner could declare). A cause +// with no owning row, or an owning row with no flip declaration: that increase stays NEW DEBT or +// ACCEPT-TO-REFUSE and the run is FrontierLost. An EXISTING debt row falling to an earlier stage: +// that is a regression of debt already carried, not an added identity, and the guard's own clauses +// still judge it. The admission is per identity, so a mixed run loses on exactly its unowned part. +type NativeFrontierOwnedCorrectnessFlip { + identity: NativeRouteTestIdentity + debt: NativeFrontierDebt + flip: CauseCorrectnessFlip +} + +// The authority the admission reads, supplied rather than imported at the decision so the witness +// can discriminate at this interface (native_frontier_verdict supplies the committed tables). +type NativeFrontierFlipAuthority { + owners: List + flips: List +} + +fn native_frontier_flip_authority() -> NativeFrontierFlipAuthority { + NativeFrontierFlipAuthority { owners: known_frontier_causes, flips: known_correctness_flips } +} + +fn native_frontier_owned_flip( + identity: NativeRouteTestIdentity, + attained: NativeRouteAttainment, + authority: NativeFrontierFlipAuthority +) -> Optional { + match attained { + AttainRefused { stage: s, cause: c } => + match cause_correctness_flip_lookup_over( + cause: native_exclusion_cause_reason(c: c), grain: FatalGrain, + owners: authority.owners, flips: authority.flips + ) { + Present { value: f } => + optional_present(value: NativeFrontierOwnedCorrectnessFlip { identity: identity, debt: DebtRefused { stage: s, cause: c }, flip: f }) + Absent => optional_absent() + } + AttainAgreed => optional_absent() + AttainDiverged { cause: _ } => optional_absent() + AttainUnreached { blocked_at: _ } => optional_absent() + } +} + +// THE ADDED IDENTITIES THE AUTHORITY OWNS: every observed row whose baseline is agreement (in the +// minted universe, no debt row) or absent (new to the universe), with an owned flip cause. +fn native_frontier_owned_flips( + observed_rows: List, + baseline_index: Map, + authority: NativeFrontierFlipAuthority +) -> List { + list_flat_map(xs: observed_rows, f: fn(o) { + let added = + match map_lookup(m: baseline_index, key: native_route_identity_qualified(identity: o.identity)) { + Absent => true + Present { value: b } => + match b { + BaselineAgreed => true + BaselineRefused { stage: _, cause: _ } => false + BaselineDiverged { cause: _ } => false + } + } + if added { + match native_frontier_owned_flip(identity: o.identity, attained: o.attained, authority: authority) { + Present { value: f } => [f] + Absent => [] + } + } else { + [] + } + }) +} + +// AN AGREED IDENTITY'S FALL, EXPRESSED IN THE GUARD'S OWN VOCABULARY. The guard already has the +// disposition this is (`PriorAcceptanceWasNeverSound`); what it lacked was a source other than a +// hand-authored per-identity row. Here the row is derived from the owned flip, so it cannot drift +// from the run and cannot be written for an identity the run did not observe falling. +fn native_frontier_flip_accept_to_refuse_row(f: NativeFrontierOwnedCorrectnessFlip) -> NativeAcceptToRefuseRow { + NativeAcceptToRefuseRow { + identity: f.identity, + disposition: PriorAcceptanceWasNeverSound { + authority: native_frontier_flip_citation(f: f), + now_refuses_with: native_frontier_debt_text(debt: f.debt) + } + } +} + +fn native_frontier_flip_citation(f: NativeFrontierOwnedCorrectnessFlip) -> String { + join([ + "v2.workflow.compile_door_cause_ownership correctness flip of gunbc#", + integer_int_to_decimal_string(value: f.flip.pull_request), " (", f.flip.why, ")" + ], "") +} + +fn native_frontier_flip_text(f: NativeFrontierOwnedCorrectnessFlip) -> String { + join([ + "OWNED CORRECTNESS FLIP (", native_frontier_debt_text(debt: f.debt), "; ", + native_frontier_flip_citation(f: f), ") ", native_route_identity_qualified(identity: f.identity) + ], "") +} + // ═══ integrity versus debt ═════════════════════════════════════════════════════════════════ // EXHAUSTIVE, NO WILDCARD: a clause added to admission must be classified here before this module @@ -282,6 +398,11 @@ type NativeFrontierProposal { type NativeFrontierVerdict = FrontierHeld | FrontierAdvanced { advanced: List, proposal: NativeFrontierProposal } + | FrontierGrewByOwnedCorrectnessFlip { + flips: List + advanced: List + proposal: NativeFrontierProposal + } | FrontierLost { findings: List } | FrontierUnminted { proposal: NativeFrontierProposal } | FrontierNotAMeasurement { reasons: List } @@ -396,7 +517,8 @@ fn native_frontier_judge_minted( rows: List, dispositions: List, cause_transitions: List, - readings: List + readings: List, + authority: NativeFrontierFlipAuthority ) -> NativeFrontierVerdict { let baseline_rows = native_frontier_baseline_rows(universe: universe, rows: rows) let observed_rows = native_progress_observed_rows(readings: readings) @@ -404,7 +526,13 @@ fn native_frontier_judge_minted( let baseline_index = native_progress_baseline_index(rows: baseline_rows) let disposition_index = native_progress_disposition_index(dispositions: dispositions) let transition_index = native_cause_transition_index(rows: cause_transitions) - let no_accept_to_refuse = native_accept_to_refuse_index(rows: []) + let owned_flips = native_frontier_owned_flips(observed_rows: observed_rows, baseline_index: baseline_index, authority: authority) + let flip_accept_to_refuse = native_accept_to_refuse_index(rows: list_flat_map(xs: owned_flips, f: fn(f) { + match map_lookup(m: baseline_index, key: native_route_identity_qualified(identity: f.identity)) { + Present { value: _ } => [native_frontier_flip_accept_to_refuse_row(f: f)] + Absent => [] + } + })) let rename_targets = native_frontier_rename_targets(dispositions: dispositions) let guard_findings: List = list_flat_map( xs: [ @@ -412,7 +540,7 @@ fn native_frontier_judge_minted( list_flat_map(xs: baseline_rows, f: fn(row) { native_progress_row_findings( row: row, observed: observed, dispositions: disposition_index, - accept_to_refuse: no_accept_to_refuse, cause_transitions: transition_index, + accept_to_refuse: flip_accept_to_refuse, cause_transitions: transition_index, reach: ReachExecutableStarted ) }), @@ -429,7 +557,9 @@ fn native_frontier_judge_minted( let new_debt = filter( xs: native_frontier_new_debt(observed_debt: observed_debt, baseline_index: baseline_index), predicate: fn(n) { - any(xs: rename_targets, predicate: fn(t) { t == native_route_identity_qualified(identity: n.identity) }) == false + let key = native_route_identity_qualified(identity: n.identity) + any(xs: rename_targets, predicate: fn(t) { t == key }) == false + && any(xs: owned_flips, predicate: fn(f) { native_route_identity_qualified(identity: f.identity) == key }) == false } ) let findings = list_append( @@ -443,6 +573,8 @@ fn native_frontier_judge_minted( let proposal = native_frontier_proposal_of(observed: observed_rows) if is_empty(xs: findings) == false { FrontierLost { findings: findings } + } else if is_empty(xs: owned_flips) == false { + FrontierGrewByOwnedCorrectnessFlip { flips: owned_flips, advanced: stale, proposal: proposal } } else if is_empty(xs: stale) { FrontierHeld } else { @@ -466,7 +598,8 @@ fn native_frontier_verdict( standing: native_frontier_roster, readings: native_frontier_readings(receipt: receipt), admission: admission, - pattern: pattern + pattern: pattern, + authority: native_frontier_flip_authority() ) } @@ -477,7 +610,8 @@ fn native_frontier_verdict_over( standing: NativeFrontierRosterStanding, readings: List, admission: NativeRouteAdmission, - pattern: TargetPattern + pattern: TargetPattern, + authority: NativeFrontierFlipAuthority ) -> NativeFrontierVerdict { let integrity = native_frontier_integrity_refusals(admission: admission) if native_frontier_pattern_is_whole(pattern: pattern) == false { @@ -489,7 +623,7 @@ fn native_frontier_verdict_over( RosterUnminted => FrontierUnminted { proposal: native_frontier_proposal_of(observed: native_progress_observed_rows(readings: readings)) } RosterMinted { receipt: _, universe: u, rows: rows, dispositions: ds, cause_transitions: ts } => - native_frontier_judge_minted(universe: u, rows: rows, dispositions: ds, cause_transitions: ts, readings: readings) + native_frontier_judge_minted(universe: u, rows: rows, dispositions: ds, cause_transitions: ts, readings: readings, authority: authority) } } } @@ -501,6 +635,7 @@ fn native_frontier_verdict_word(v: NativeFrontierVerdict) -> String { match v { FrontierHeld => "held" FrontierAdvanced { advanced: _, proposal: _ } => "advanced" + FrontierGrewByOwnedCorrectnessFlip { flips: _, advanced: _, proposal: _ } => "grew-by-owned-correctness-flip" FrontierLost { findings: _ } => "lost" FrontierUnminted { proposal: _ } => "unminted" FrontierNotAMeasurement { reasons: _ } => "not-a-measurement" @@ -519,6 +654,14 @@ fn native_frontier_report_lines(v: NativeFrontierVerdict) -> List { ], "")], right: a ) + FrontierGrewByOwnedCorrectnessFlip { flips: fl, advanced: a, proposal: _ } => + list_append( + left: [join([ + integer_int_to_decimal_string(value: length(xs: fl)), + " added identit(ies) owed debt under an owned correctness flip, NOT YET APPLIED: the committed gunbc.native_frontier_roster stays authoritative until a reviewed pull request replaces it with the proposal below" + ], "")], + right: list_append(left: list_map(xs: fl, f: native_frontier_flip_text), right: a) + ) FrontierLost { findings: fs } => fs FrontierUnminted { proposal: p } => [join(["UNMINTED: gunbc.native_frontier_roster carries no roster; this complete run proposes a universe of ", integer_int_to_decimal_string(value: length(xs: p.universe)), " identities and ", integer_int_to_decimal_string(value: length(xs: p.rows)), " debt row(s) for review"], "")] @@ -528,8 +671,8 @@ fn native_frontier_report_lines(v: NativeFrontierVerdict) -> List { } // THE PROPOSED ROSTER, AS THE `.dag` MODULE IT WOULD BE. Present for every arm except `Held` and -// `NotAMeasurement`. The nightly writes it over `dag/gunbc/native_frontier_roster.dag` and opens a -// pull request. Dispositions and cause transitions are NOT carried forward, because each describes +// `NotAMeasurement`. The nightly publishes it as a workflow artifact; it reaches +// `dag/gunbc/native_frontier_roster.dag` only through a reviewed pull request that carries it. Dispositions and cause transitions are NOT carried forward, because each describes // a transition relative to the rows it was written against: once the roster is re-minted from the // run, a disposition for a subject with no row and a transition whose cause no longer moves are // both findings in their own right (`DisposedSubjectHasNoBaselineRow`, @@ -539,6 +682,7 @@ fn native_frontier_proposal(v: NativeFrontierVerdict) -> Optional optional_absent() FrontierAdvanced { advanced: _, proposal: p } => optional_present(value: p) + FrontierGrewByOwnedCorrectnessFlip { flips: _, advanced: _, proposal: p } => optional_present(value: p) FrontierLost { findings: _ } => optional_absent() FrontierUnminted { proposal: p } => optional_present(value: p) FrontierNotAMeasurement { reasons: _ } => optional_absent() diff --git a/dag/test/claim/native_frontier_ratchet_witness_test.dag b/dag/test/claim/native_frontier_ratchet_witness_test.dag index e9adf0a8437..49f5b610f4a 100644 --- a/dag/test/claim/native_frontier_ratchet_witness_test.dag +++ b/dag/test/claim/native_frontier_ratchet_witness_test.dag @@ -26,8 +26,12 @@ import gunbc.native_frontier_debt { NativeFrontierDebtRow, DebtRefused, NativeFrontierRosterStanding, RosterUnminted, RosterMinted, NativeFrontierMintReceipt } +import v2.workflow.compile_door_cause_ownership { + CauseOwnership, CorrectnessFlipDeclaration, FatalGrain, HeadGrain, MigrationOwned +} import gunbc.native_frontier_ratchet { - NativeFrontierVerdict, FrontierHeld, FrontierAdvanced, FrontierLost, FrontierUnminted, FrontierNotAMeasurement, + NativeFrontierVerdict, FrontierHeld, FrontierAdvanced, FrontierGrewByOwnedCorrectnessFlip, + NativeFrontierFlipAuthority, FrontierLost, FrontierUnminted, FrontierNotAMeasurement, native_frontier_verdict_over, native_frontier_verdict_word, native_frontier_reading, native_frontier_integrity_refusals, native_frontier_row_line, native_frontier_report_lines, native_frontier_proposal } @@ -83,14 +87,21 @@ fn debt_row(identity: NativeRouteTestIdentity, stage: NativeTestStage, cause: Na NativeFrontierDebtRow { identity: identity, debt: DebtRefused { stage: stage, cause: cause } } } +// No owned flips: every claim that does not name the flip authority judges under the empty one, +// so the growth arm cannot be what makes it pass. fn judge(standing: NativeFrontierRosterStanding, readings: List) -> NativeFrontierVerdict { - native_frontier_verdict_over(standing: standing, readings: readings, admission: NativeRouteAdmitted, pattern: whole_pattern()) + judge_under(authority: NativeFrontierFlipAuthority { owners: [], flips: [] }, standing: standing, readings: readings) +} + +fn judge_under(authority: NativeFrontierFlipAuthority, standing: NativeFrontierRosterStanding, readings: List) -> NativeFrontierVerdict { + native_frontier_verdict_over(standing: standing, readings: readings, admission: NativeRouteAdmitted, pattern: whole_pattern(), authority: authority) } fn is_lost(v: NativeFrontierVerdict) -> Bool { match v { FrontierLost { findings: _ } => true FrontierHeld => false + FrontierGrewByOwnedCorrectnessFlip { flips: _, advanced: _, proposal: _ } => false FrontierAdvanced { advanced: _, proposal: _ } => false FrontierUnminted { proposal: _ } => false FrontierNotAMeasurement { reasons: _ } => false @@ -101,6 +112,7 @@ fn lost_with(v: NativeFrontierVerdict, prefix: String) -> Bool { match v { FrontierLost { findings: fs } => any(xs: fs, predicate: fn(f) { starts_with(s: f, prefix: prefix) }) FrontierHeld => false + FrontierGrewByOwnedCorrectnessFlip { flips: _, advanced: _, proposal: _ } => false FrontierAdvanced { advanced: _, proposal: _ } => false FrontierUnminted { proposal: _ } => false FrontierNotAMeasurement { reasons: _ } => false @@ -115,6 +127,7 @@ test fn equality_holds() -> Bool { readings: [refused(identity: subject_a, stage: NativeTestStagePrepare, cause: entry_cause), agreed(identity: subject_b)] ) { FrontierHeld => native_frontier_verdict_word(v: FrontierHeld) == "held" + FrontierGrewByOwnedCorrectnessFlip { flips: _, advanced: _, proposal: _ } => false FrontierAdvanced { advanced: _, proposal: _ } => false FrontierLost { findings: _ } => false FrontierUnminted { proposal: _ } => false @@ -135,6 +148,7 @@ test fn a_cleared_row_advances_and_the_proposal_drops_it() -> Bool { starts_with(s: l, prefix: "1 roster change(s) the run supports, NOT YET APPLIED") }) FrontierHeld => false + FrontierGrewByOwnedCorrectnessFlip { flips: _, advanced: _, proposal: _ } => false FrontierLost { findings: _ } => false FrontierUnminted { proposal: _ } => false FrontierNotAMeasurement { reasons: _ } => false @@ -150,6 +164,7 @@ test fn a_later_stage_refusal_advances_and_keeps_the_row() -> Bool { ) { FrontierAdvanced { advanced: _, proposal: p } => length(xs: p.rows) == 1 FrontierHeld => false + FrontierGrewByOwnedCorrectnessFlip { flips: _, advanced: _, proposal: _ } => false FrontierLost { findings: _ } => false FrontierUnminted { proposal: _ } => false FrontierNotAMeasurement { reasons: _ } => false @@ -168,6 +183,7 @@ test fn a_deleted_subject_with_its_disposition_advances() -> Bool { readings: [agreed(identity: subject_b)] ) { FrontierHeld => false + FrontierGrewByOwnedCorrectnessFlip { flips: _, advanced: _, proposal: _ } => false FrontierAdvanced { advanced: _, proposal: p } => length(xs: p.universe) == 1 && is_empty(xs: p.rows) FrontierLost { findings: _ } => false FrontierUnminted { proposal: _ } => false @@ -231,6 +247,7 @@ test fn w_RED_an_unminted_roster_proposes_and_does_not_pass() -> Bool { match v { FrontierUnminted { proposal: p } => length(xs: p.rows) == 1 && length(xs: p.universe) == 2 && native_frontier_verdict_word(v: v) == "unminted" FrontierHeld => false + FrontierGrewByOwnedCorrectnessFlip { flips: _, advanced: _, proposal: _ } => false FrontierAdvanced { advanced: _, proposal: _ } => false FrontierLost { findings: _ } => false FrontierNotAMeasurement { reasons: _ } => false @@ -242,10 +259,12 @@ test fn w_RED_a_narrower_pattern_is_not_a_measurement() -> Bool { standing: minted(universe: [], rows: [], dispositions: []), readings: [agreed(identity: subject_a)], admission: NativeRouteAdmitted, - pattern: narrow_pattern() + pattern: narrow_pattern(), + authority: NativeFrontierFlipAuthority { owners: [], flips: [] } ) { FrontierNotAMeasurement { reasons: _ } => true FrontierHeld => false + FrontierGrewByOwnedCorrectnessFlip { flips: _, advanced: _, proposal: _ } => false FrontierAdvanced { advanced: _, proposal: _ } => false FrontierLost { findings: _ } => false FrontierUnminted { proposal: _ } => false @@ -257,10 +276,12 @@ test fn w_RED_an_integrity_clause_makes_the_run_not_a_measurement() -> Bool { standing: minted(universe: [], rows: [], dispositions: []), readings: [agreed(identity: subject_a)], admission: NativeRouteRefused { causes: [PopulationOmissionsPresent] }, - pattern: whole_pattern() + pattern: whole_pattern(), + authority: NativeFrontierFlipAuthority { owners: [], flips: [] } ) { FrontierNotAMeasurement { reasons: rs } => length(xs: rs) == 1 FrontierHeld => false + FrontierGrewByOwnedCorrectnessFlip { flips: _, advanced: _, proposal: _ } => false FrontierAdvanced { advanced: _, proposal: _ } => false FrontierLost { findings: _ } => false FrontierUnminted { proposal: _ } => false @@ -305,6 +326,7 @@ test fn a_rename_target_holding_the_bar_is_not_new_debt() -> Bool { ) { FrontierAdvanced { advanced: _, proposal: p } => length(xs: p.rows) == 1 && length(xs: p.universe) == 1 FrontierHeld => false + FrontierGrewByOwnedCorrectnessFlip { flips: _, advanced: _, proposal: _ } => false FrontierLost { findings: _ } => false FrontierUnminted { proposal: _ } => false FrontierNotAMeasurement { reasons: _ } => false @@ -329,6 +351,7 @@ test fn a_new_agreeing_subject_enrols_rather_than_holding() -> Bool { match judge(standing: minted(universe: [subject_a], rows: [], dispositions: []), readings: [agreed(identity: subject_a), agreed(identity: subject_b)]) { FrontierAdvanced { advanced: _, proposal: p } => length(xs: p.universe) == 2 && is_empty(xs: p.rows) FrontierHeld => false + FrontierGrewByOwnedCorrectnessFlip { flips: _, advanced: _, proposal: _ } => false FrontierLost { findings: _ } => false FrontierUnminted { proposal: _ } => false FrontierNotAMeasurement { reasons: _ } => false @@ -410,3 +433,111 @@ test fn a_lost_run_names_every_finding() -> Bool { readings: [refused(identity: subject_a, stage: NativeTestStagePrepare, cause: entry_cause), refused(identity: subject_b, stage: NativeTestStagePrepare, cause: entry_cause)] ))) == 2 } + +// ═══ debt that grows from an owned correctness flip ═══ +// +// The fixture flip is shaped like the caret flip (gunbc#12392): a cause that makes a silently wrong +// acceptance refuse at a located site. The fixture uses its own symbol so these claims do not +// depend on that row landing in v2.workflow.compile_door_cause_ownership. + +data flip_cause: NativeRouteExclusionCause = CompilerFrontierAttributed { reason: ^fixture_correctness_flip_cause } + +data flip_owner: CauseOwnership = CauseOwnership { + cause: ^fixture_correctness_flip_cause, + grain: FatalGrain, + lane: MigrationOwned, + flip_trigger: "fixture: retires when the fixture slice lowers the construct" +} + +data flip_declaration: CorrectnessFlipDeclaration = CorrectnessFlipDeclaration { + cause: ^fixture_correctness_flip_cause, + grain: FatalGrain, + pull_request: 12392, + why: "fixture: a silently wrong acceptance now refuses at the located site" +} + +fn owned_and_declared() -> NativeFrontierFlipAuthority { + NativeFrontierFlipAuthority { owners: [flip_owner], flips: [flip_declaration] } +} + +// A: agreed at the mint and refusing now. B: new to the universe and refusing. Both under the flip. +fn flip_standing() -> NativeFrontierRosterStanding { + minted(universe: [subject_a], rows: [], dispositions: []) +} + +fn flip_readings() -> List { + [refused(identity: subject_a, stage: NativeTestStagePrepare, cause: flip_cause), refused(identity: subject_b, stage: NativeTestStagePrepare, cause: flip_cause)] +} + +// ADMITTED: both added identities are owed debt under an owned, declared flip, so the run does not +// lose. It is not equality either: it proposes the roster with both rows, each carrying its owner +// and pull request, under a word the instrument reads as holding. +test fn an_owned_correctness_flip_increase_is_admitted() -> Bool { + let v = judge_under(authority: owned_and_declared(), standing: flip_standing(), readings: flip_readings()) + match v { + FrontierGrewByOwnedCorrectnessFlip { flips: fl, advanced: _, proposal: p } => + length(xs: fl) == 2 + && any(xs: fl, predicate: fn(f) { (f.flip.pull_request == 12392 && f.flip.owner.cause == ^fixture_correctness_flip_cause) == false }) == false + && length(xs: p.rows) == 2 && length(xs: p.universe) == 2 + && native_frontier_verdict_word(v: v) == "grew-by-owned-correctness-flip" + && (proposes_nothing(v: v) == false) + FrontierHeld => false + FrontierAdvanced { advanced: _, proposal: _ } => false + FrontierLost { findings: _ } => false + FrontierUnminted { proposal: _ } => false + FrontierNotAMeasurement { reasons: _ } => false + } +} + +// THE SAME INCREASE, UNOWNED, IS A LOSS. Three ways to lack the authority, each the same run: no +// declaration, a declaration whose cause has no owning row, and an owning row at the wrong grain. +// Each loses on both identities, under the guard's accept-to-refuse finding and this module's new +// debt, and proposes nothing. +fn loses_both(authority: NativeFrontierFlipAuthority) -> Bool { + let v = judge_under(authority: authority, standing: flip_standing(), readings: flip_readings()) + lost_with(v: v, prefix: "ACCEPT-TO-REFUSE") && lost_with(v: v, prefix: "NEW DEBT") && proposes_nothing(v: v) +} + +test fn w_RED_the_same_increase_with_an_unowned_cause_is_lost() -> Bool { + loses_both(authority: NativeFrontierFlipAuthority { owners: [flip_owner], flips: [] }) + && loses_both(authority: NativeFrontierFlipAuthority { owners: [], flips: [flip_declaration] }) + && loses_both(authority: NativeFrontierFlipAuthority { + owners: [CauseOwnership { cause: ^fixture_correctness_flip_cause, grain: HeadGrain, lane: MigrationOwned, flip_trigger: "fixture" }], + flips: [flip_declaration] + }) +} + +// A MIXED SET REFUSES EXACTLY ITS UNOWNED PART. A falls under the owned flip; B lands refusing with +// a cause nobody declared. The run is lost, a finding names B, and no finding names A: the owned +// identity is not collateral, and the unowned one is not carried in on its neighbour's authority. +test fn w_RED_a_mixed_set_refuses_the_unowned_part() -> Bool { + let v = judge_under( + authority: owned_and_declared(), + standing: flip_standing(), + readings: [refused(identity: subject_a, stage: NativeTestStagePrepare, cause: flip_cause), refused(identity: subject_b, stage: NativeTestStagePrepare, cause: other_cause)] + ) + match v { + FrontierLost { findings: fs } => + any(xs: fs, predicate: fn(f) { starts_with(s: f, prefix: "NEW DEBT") && ends_with(s: f, suffix: "v2.test.beta.holds") }) + && any(xs: fs, predicate: fn(f) { ends_with(s: f, suffix: "v2.test.alpha.holds") }) == false + && proposes_nothing(v: v) + FrontierHeld => false + FrontierGrewByOwnedCorrectnessFlip { flips: _, advanced: _, proposal: _ } => false + FrontierAdvanced { advanced: _, proposal: _ } => false + FrontierUnminted { proposal: _ } => false + FrontierNotAMeasurement { reasons: _ } => false + } +} + +// AN EXISTING DEBT ROW IS NOT AN ADDED IDENTITY. A carried debt at eval and now refuses at prepare +// under the owned flip: that is a regression of debt already carried, and the flip does not excuse it. +test fn w_RED_an_owned_flip_does_not_excuse_a_carried_rows_regression() -> Bool { + lost_with( + v: judge_under( + authority: owned_and_declared(), + standing: minted(universe: [subject_a], rows: [debt_row(identity: subject_a, stage: NativeTestStageEval, cause: entry_cause)], dispositions: []), + readings: [refused(identity: subject_a, stage: NativeTestStagePrepare, cause: flip_cause)] + ), + prefix: "REGRESSED" + ) +} diff --git a/src/v1/stage0/src/target_invocation_host.rs b/src/v1/stage0/src/target_invocation_host.rs index 21988792cec..a2106ef2fa2 100644 --- a/src/v1/stage0/src/target_invocation_host.rs +++ b/src/v1/stage0/src/target_invocation_host.rs @@ -1034,7 +1034,10 @@ fn run_self_host(source_roots: &[String]) -> InvocationOutcome { /// /// `held` and `advanced` are the observation holding: every planned identity reached a terminal /// verdict and every honest failure is rostered debt. An advance also prints a proposed smaller -/// roster, which the nightly turns into a pull request. `lost` and `unminted` are the observation +/// roster, which a reviewed pull request may carry (the nightly only publishes it). An owned +/// correctness flip (`grew-by-owned-correctness-flip`) holds for the same reason: every added +/// identity is owed debt under a declared, owned cause, and it too prints a proposed roster. +/// `lost` and `unminted` are the observation /// not holding. `unminted` is a complete run with nothing to hold it to, and an empty roster read as /// no debt would be a vacuous pass. `not-a-measurement` means the receipt failed an integrity /// clause or the pattern was narrower than the universe, so the subject was not reached. @@ -1043,7 +1046,7 @@ fn run_v2_native_frontier(source_roots: &[String]) -> InvocationOutcome { match cli_run::run_v2_native_frontier(source_roots, &pattern) { Ok(run) => { let termination = match run.frontier.as_str() { - "held" | "advanced" => Termination::ObservationHeld, + "held" | "advanced" | "grew-by-owned-correctness-flip" => Termination::ObservationHeld, "lost" | "unminted" => Termination::ObservationDidNotHold, "not-a-measurement" => Termination::SubjectUnreached, other => { diff --git a/src/v2/workflow/compile_door_cause_ownership.dag b/src/v2/workflow/compile_door_cause_ownership.dag index 839ac2f6a94..fcb4d1532c7 100644 --- a/src/v2/workflow/compile_door_cause_ownership.dag +++ b/src/v2/workflow/compile_door_cause_ownership.dag @@ -2,9 +2,10 @@ module v2.workflow.compile_door_cause_ownership import v2.std.collection { List } import v2.std.node { Symbol } -import v2.std.optional { Optional } +import v2.std.optional { Optional, Present, Absent, optional_present, optional_absent } import v2.std.algebra { list_find_first } import std.types { String } +import v2.std.integer { Int } // THE CAUSE-OWNERSHIP AUTHORITY FOR THE v2 FRONT-END FRONTIER, HOMED BELOW ITS CONSUMERS. // @@ -287,3 +288,57 @@ fn cause_ownership_lookup(cause: Symbol, grain: DiagnosticGrain) -> Optional = [] + +fn cause_correctness_flip_lookup_over( + cause: Symbol, + grain: DiagnosticGrain, + owners: List, + flips: List +) -> Optional { + match list_find_first(xs: owners, predicate: fn(row) { + row.cause == cause && discriminant(v: row.grain) == discriminant(v: grain) + }) { + Absent => optional_absent() + Present { value: owner } => + match list_find_first(xs: flips, predicate: fn(d) { + d.cause == cause && discriminant(v: d.grain) == discriminant(v: grain) + }) { + Absent => optional_absent() + Present { value: d } => optional_present(value: CauseCorrectnessFlip { owner: owner, pull_request: d.pull_request, why: d.why }) + } + } +} + +fn cause_correctness_flip_lookup(cause: Symbol, grain: DiagnosticGrain) -> Optional { + cause_correctness_flip_lookup_over(cause: cause, grain: grain, owners: known_frontier_causes, flips: known_correctness_flips) +} From d330ec0ebd97f74f965d0a1e95341af8fba60236 Mon Sep 17 00:00:00 2001 From: gunbc-ci-auto-heal Date: Sun, 27 Sep 2026 02:14:13 +0000 Subject: [PATCH 2/6] witness: use the string_contains builtin, not a bare ends_with the floor binds to gunbc.rust_item_scan Co-Authored-By: Claude Opus 5.5 (1M context) --- dag/test/claim/native_frontier_ratchet_witness_test.dag | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dag/test/claim/native_frontier_ratchet_witness_test.dag b/dag/test/claim/native_frontier_ratchet_witness_test.dag index 49f5b610f4a..517c0a1e133 100644 --- a/dag/test/claim/native_frontier_ratchet_witness_test.dag +++ b/dag/test/claim/native_frontier_ratchet_witness_test.dag @@ -518,8 +518,8 @@ test fn w_RED_a_mixed_set_refuses_the_unowned_part() -> Bool { ) match v { FrontierLost { findings: fs } => - any(xs: fs, predicate: fn(f) { starts_with(s: f, prefix: "NEW DEBT") && ends_with(s: f, suffix: "v2.test.beta.holds") }) - && any(xs: fs, predicate: fn(f) { ends_with(s: f, suffix: "v2.test.alpha.holds") }) == false + any(xs: fs, predicate: fn(f) { starts_with(s: f, prefix: "NEW DEBT") && string_contains(s: f, pattern: "v2.test.beta.holds") }) + && any(xs: fs, predicate: fn(f) { string_contains(s: f, pattern: "v2.test.alpha.holds") }) == false && proposes_nothing(v: v) FrontierHeld => false FrontierGrewByOwnedCorrectnessFlip { flips: _, advanced: _, proposal: _ } => false From b0439de6692148dca3c81885fd339aabd5dc3cf9 Mon Sep 17 00:00:00 2001 From: gunbc-ci-auto-heal Date: Sun, 27 Sep 2026 02:20:59 +0000 Subject: [PATCH 3/6] Flip declaration names the mint it reconciles; the grant lapses at re-mint. Delete the uncalled lookup wrapper (review 71692) Co-Authored-By: Claude Opus 5.5 (1M context) --- dag/gunbc/native_frontier_ratchet.dag | 17 ++++++++++---- .../native_frontier_ratchet_witness_test.dag | 23 +++++++++++++++++++ .../workflow/compile_door_cause_ownership.dag | 16 ++++++++----- 3 files changed, 46 insertions(+), 10 deletions(-) diff --git a/dag/gunbc/native_frontier_ratchet.dag b/dag/gunbc/native_frontier_ratchet.dag index b74c786ec18..04863237f2e 100644 --- a/dag/gunbc/native_frontier_ratchet.dag +++ b/dag/gunbc/native_frontier_ratchet.dag @@ -221,6 +221,8 @@ fn native_frontier_row_advanced( // cause it refused with has a fatal-grain row in v2.workflow.compile_door_cause_ownership // known_frontier_causes AND a known_correctness_flips declaration naming the pull request. The // disposition carries both, so the proposal pull request shows the owner and the flip it cites. +// The declaration also names the mint it reconciles (`reconciles_tested_tree`); it admits nothing +// against a roster minted from any other tree, so a re-mint ends the grant (review 71692). // // WHAT IS NEVER ADMITTED THIS WAY. A divergence (it has no cause an owner could declare). A cause // with no owning row, or an owning row with no flip declaration: that increase stays NEW DEBT or @@ -247,6 +249,7 @@ fn native_frontier_flip_authority() -> NativeFrontierFlipAuthority { fn native_frontier_owned_flip( identity: NativeRouteTestIdentity, attained: NativeRouteAttainment, + minted_tree: String, authority: NativeFrontierFlipAuthority ) -> Optional { match attained { @@ -256,7 +259,11 @@ fn native_frontier_owned_flip( owners: authority.owners, flips: authority.flips ) { Present { value: f } => + if f.reconciles_tested_tree != minted_tree { + optional_absent() + } else { optional_present(value: NativeFrontierOwnedCorrectnessFlip { identity: identity, debt: DebtRefused { stage: s, cause: c }, flip: f }) + } Absent => optional_absent() } AttainAgreed => optional_absent() @@ -270,6 +277,7 @@ fn native_frontier_owned_flip( fn native_frontier_owned_flips( observed_rows: List, baseline_index: Map, + minted_tree: String, authority: NativeFrontierFlipAuthority ) -> List { list_flat_map(xs: observed_rows, f: fn(o) { @@ -284,7 +292,7 @@ fn native_frontier_owned_flips( } } if added { - match native_frontier_owned_flip(identity: o.identity, attained: o.attained, authority: authority) { + match native_frontier_owned_flip(identity: o.identity, attained: o.attained, minted_tree: minted_tree, authority: authority) { Present { value: f } => [f] Absent => [] } @@ -513,6 +521,7 @@ fn native_frontier_stale( // disposition, per cause transition), from the reading step (malformed readings), and from this // module (new debt, net of admitted rename targets). fn native_frontier_judge_minted( + minted_tree: String, universe: List, rows: List, dispositions: List, @@ -526,7 +535,7 @@ fn native_frontier_judge_minted( let baseline_index = native_progress_baseline_index(rows: baseline_rows) let disposition_index = native_progress_disposition_index(dispositions: dispositions) let transition_index = native_cause_transition_index(rows: cause_transitions) - let owned_flips = native_frontier_owned_flips(observed_rows: observed_rows, baseline_index: baseline_index, authority: authority) + let owned_flips = native_frontier_owned_flips(observed_rows: observed_rows, baseline_index: baseline_index, minted_tree: minted_tree, authority: authority) let flip_accept_to_refuse = native_accept_to_refuse_index(rows: list_flat_map(xs: owned_flips, f: fn(f) { match map_lookup(m: baseline_index, key: native_route_identity_qualified(identity: f.identity)) { Present { value: _ } => [native_frontier_flip_accept_to_refuse_row(f: f)] @@ -622,8 +631,8 @@ fn native_frontier_verdict_over( match standing { RosterUnminted => FrontierUnminted { proposal: native_frontier_proposal_of(observed: native_progress_observed_rows(readings: readings)) } - RosterMinted { receipt: _, universe: u, rows: rows, dispositions: ds, cause_transitions: ts } => - native_frontier_judge_minted(universe: u, rows: rows, dispositions: ds, cause_transitions: ts, readings: readings, authority: authority) + RosterMinted { receipt: mr, universe: u, rows: rows, dispositions: ds, cause_transitions: ts } => + native_frontier_judge_minted(minted_tree: mr.tested_tree, universe: u, rows: rows, dispositions: ds, cause_transitions: ts, readings: readings, authority: authority) } } } diff --git a/dag/test/claim/native_frontier_ratchet_witness_test.dag b/dag/test/claim/native_frontier_ratchet_witness_test.dag index 517c0a1e133..9760d42b3fe 100644 --- a/dag/test/claim/native_frontier_ratchet_witness_test.dag +++ b/dag/test/claim/native_frontier_ratchet_witness_test.dag @@ -453,6 +453,7 @@ data flip_declaration: CorrectnessFlipDeclaration = CorrectnessFlipDeclaration { cause: ^fixture_correctness_flip_cause, grain: FatalGrain, pull_request: 12392, + reconciles_tested_tree: "0123456789abcdef0123456789abcdef01234567", why: "fixture: a silently wrong acceptance now refuses at the located site" } @@ -541,3 +542,25 @@ test fn w_RED_an_owned_flip_does_not_excuse_a_carried_rows_regression() -> Bool prefix: "REGRESSED" ) } + +// THE GRANT ENDS AT THE NEXT MINT (review 71692). The same owned, declared flip, judged against a +// roster minted from a different tree (a re-mint after the flip landed): the declaration reconciles +// a mint that is no longer the baseline, so the same growth is a loss again. +test fn w_RED_a_flip_declared_for_an_earlier_mint_admits_nothing() -> Bool { + loses_after_remint( + standing: RosterMinted { + receipt: NativeFrontierMintReceipt { + tested_tree: "fedcba9876543210fedcba9876543210fedcba98", + preparation_seed_identity: "seed", + emitted_closure_identity: "closure", + executable_identity: "executable" + }, + universe: [subject_a], rows: [], dispositions: [], cause_transitions: [] + } + ) +} + +fn loses_after_remint(standing: NativeFrontierRosterStanding) -> Bool { + let v = judge_under(authority: owned_and_declared(), standing: standing, readings: flip_readings()) + lost_with(v: v, prefix: "ACCEPT-TO-REFUSE") && lost_with(v: v, prefix: "NEW DEBT") && proposes_nothing(v: v) +} diff --git a/src/v2/workflow/compile_door_cause_ownership.dag b/src/v2/workflow/compile_door_cause_ownership.dag index fcb4d1532c7..5cb5e5d2b6b 100644 --- a/src/v2/workflow/compile_door_cause_ownership.dag +++ b/src/v2/workflow/compile_door_cause_ownership.dag @@ -299,12 +299,19 @@ fn cause_ownership_lookup(cause: Symbol, grain: DiagnosticGrain) -> Optional optional_absent() - Present { value: d } => optional_present(value: CauseCorrectnessFlip { owner: owner, pull_request: d.pull_request, why: d.why }) + Present { value: d } => optional_present(value: CauseCorrectnessFlip { owner: owner, pull_request: d.pull_request, reconciles_tested_tree: d.reconciles_tested_tree, why: d.why }) } } } - -fn cause_correctness_flip_lookup(cause: Symbol, grain: DiagnosticGrain) -> Optional { - cause_correctness_flip_lookup_over(cause: cause, grain: grain, owners: known_frontier_causes, flips: known_correctness_flips) -} From ee781b5038bbb2e234134b62953a21d5ff950b24 Mon Sep 17 00:00:00 2001 From: gunbc-ci-auto-heal Date: Sun, 27 Sep 2026 07:51:35 +0000 Subject: [PATCH 4/6] Host: name the v1 PURPOSE admission beside the new frontier word (review 71709) Co-Authored-By: Claude Opus 5.5 (1M context) --- src/v1/stage0/src/target_invocation_host.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/v1/stage0/src/target_invocation_host.rs b/src/v1/stage0/src/target_invocation_host.rs index a2106ef2fa2..c6bf12ebd3f 100644 --- a/src/v1/stage0/src/target_invocation_host.rs +++ b/src/v1/stage0/src/target_invocation_host.rs @@ -1037,6 +1037,8 @@ fn run_self_host(source_roots: &[String]) -> InvocationOutcome { /// roster, which a reviewed pull request may carry (the nightly only publishes it). An owned /// correctness flip (`grew-by-owned-correctness-flip`) holds for the same reason: every added /// identity is owed debt under a declared, owned cause, and it too prints a proposed roster. +/// (v1 PURPOSE admission, `gunbc.v1_maintenance_standing`: this arm only maps a v2 frontier +/// verdict word to its termination; the verdict itself is decided in `.dag`, so no seed growth.) /// `lost` and `unminted` are the observation /// not holding. `unminted` is a complete run with nothing to hold it to, and an empty roster read as /// no debt would be a vacuous pass. `not-a-measurement` means the receipt failed an integrity From 7bcc4c41deaf797af1f2a4d83aeb0351132bb711 Mon Sep 17 00:00:00 2001 From: gunbc-ci-auto-heal Date: Sun, 27 Sep 2026 20:05:37 +0000 Subject: [PATCH 5/6] Delete the native-frontier nightly as an authority change; bind the roster's producer to the required native-route lane Operator ruling 2026-09-27. Deletes gunbc.native_frontier_workflow, its generated-artifact registry arms, provenance row, action-use census entry and claim, and the YAML. The roster stays tracked; its mint/re-mint is taken from the required native-route lane's merge_group run (node://adhoc-11684de4-07b). gunbc.rung_drop v2_native_frontier_nightly_cadence is rewritten honestly: temporary rung OutsideTheLadder (nothing runs the ratchet until the lane lands), reason ReplacementStaged, trigger naming the capability (the lane's run produces a proposal a mint PR carries). Co-Authored-By: Claude Opus 5.5 (1M context) --- .gitattributes | 1 - .github/workflows/native-frontier.yml | 119 ----- dag/gunbc/generated_artifact.dag | 7 +- dag/gunbc/generated_artifact_emit.dag | 8 +- dag/gunbc/generated_workflow_provenance.dag | 5 - dag/gunbc/instrument_targets.dag | 8 +- .../instruments/docs_projection_gate.dag | 2 - dag/gunbc/ledger_row_coherence.dag | 3 +- dag/gunbc/native_frontier_debt.dag | 13 +- dag/gunbc/native_frontier_ratchet.dag | 10 +- dag/gunbc/native_frontier_workflow.dag | 406 ------------------ dag/gunbc/native_route_progress_guard.dag | 3 +- .../v2_native_frontier_nightly_cadence.dag | 45 +- .../v2_native_route_off_the_merge_path.dag | 13 +- .../action_use_admission_witness_test.dag | 12 +- src/v1/stage0/src/target_invocation_host.rs | 2 +- 16 files changed, 58 insertions(+), 599 deletions(-) delete mode 100644 .github/workflows/native-frontier.yml delete mode 100644 dag/gunbc/native_frontier_workflow.dag diff --git a/.gitattributes b/.gitattributes index ec1c213f356..30eed76eed4 100644 --- a/.gitattributes +++ b/.gitattributes @@ -20,7 +20,6 @@ .github/workflows/heal-publish.yml merge=generated-artifact .github/workflows/heal.yml merge=generated-artifact .github/workflows/microvm-shakedown.yml merge=generated-artifact -.github/workflows/native-frontier.yml merge=generated-artifact .github/workflows/witnesses.yml merge=generated-artifact .gitignore merge=generated-artifact DESIGN.md merge=generated-artifact diff --git a/.github/workflows/native-frontier.yml b/.github/workflows/native-frontier.yml deleted file mode 100644 index 3a35731cc16..00000000000 --- a/.github/workflows/native-frontier.yml +++ /dev/null @@ -1,119 +0,0 @@ -# Generated by gunbc.native_frontier_workflow expected_native_frontier_workflow_yml — do not hand-edit. -# Authority: gunbc.native_frontier_workflow native_frontier_workflow; regen via tools.generated_artifact_gate main_wet. -name: native-frontier -on: - schedule: - - cron: 17 3 * * * - workflow_dispatch: -permissions: - contents: read -concurrency: - group: native-frontier - cancel-in-progress: true -env: - CARGO_TERM_COLOR: always - MALLOC_ARENA_MAX: "2" -jobs: - frontier: - runs-on: [self-hosted, linux, arm64] - timeout-minutes: 360 - permissions: - contents: read - steps: - - name: Checkout - uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 - with: - persist-credentials: false - - name: Assert the runner user's systemd manager is reachable (the memory bound needs it) - run: |- - # dissolve-on: native_frontier_preflight_step -- orch-emitted foreign-executor step probing the runner user's systemd manager (systemctl --user show-environment) and refusing with UserManagerUnreachable; the if/echo/exit strings remain until a typed host-manager-reachability probe lands on host_effect_apply (#5828 / shell-to-intent Phase 2), whose refusal arm this step's cause becomes - if ! 'systemctl' '--user' 'show-environment' >/dev/null; then - echo "::error title=environment::UserManagerUnreachable -- systemd-run --user cannot bound this job's memory on $(hostname) for $(id -un) (uid $(id -u)). The host needs a lingering user manager (loginctl enable-linger), an operator host change. This is not a frontier verdict." - exit 1 - fi - - name: Isolate toolchain homes - run: |- - # dissolve-on: ci_toolchain_home_isolation_script -- orch-emitted foreign-executor prelude step wiping and setting HOME/CARGO_HOME/RUSTUP_HOME under RUNNER_TEMP so concurrent runner slots stop sharing one toolchain; leaf rm/echo strings remain until a typed per-job filesystem-and-environment effect lands on host_effect_apply (shell-to-intent Phase 2). This obligation covers THIS carrier and ci_isolate_toolchain_script, which share that terminal construction; ci_pin_rustup_default_script carries its own obligation because it does not - rm -rf "$RUNNER_TEMP/rustup" "$RUNNER_TEMP/cargo" - echo "HOME=$RUNNER_TEMP" >> "$GITHUB_ENV" - echo "CARGO_HOME=$RUNNER_TEMP/cargo" >> "$GITHUB_ENV" - echo "RUSTUP_HOME=$RUNNER_TEMP/rustup" >> "$GITHUB_ENV" - - name: Install Rust toolchain - uses: actions-rust-lang/setup-rust-toolchain@2b1f5e9b395427c92ee4e3331786ca3c37afe2d7 - with: - components: rustfmt - cache: false - rustflags: -D warnings - - name: Pin rustup default (isolated RUSTUP_HOME has no default toolchain) - run: |- - # dissolve-on: ci_pin_rustup_default_script -- orch-emitted foreign-executor step selecting a rustup default toolchain inside an isolated RUSTUP_HOME, which starts with none, and resolving the cargo binary that selection implies. The leaf rustup/command/echo strings remain until a typed TOOLCHAIN-SELECTION effect lands on host_effect_apply -- NOT the filesystem-and-environment effect ci_toolchain_home_isolation_script waits on, which is why this is a separate obligation: that effect landing alone would leave this carrier standing - rustup default "$(rustup show active-toolchain | awk '{print $1; exit}')" - if [ -x "$CARGO_HOME/bin/cargo" ]; then CARGO_BIN="$CARGO_HOME/bin/cargo"; else CARGO_BIN="$(command -v cargo || true)"; fi - if [ -z "$CARGO_BIN" ]; then echo "::error::no cargo binary: neither the isolated $CARGO_HOME/bin/cargo shim nor PATH carries one"; exit 1; fi - echo "CARGO_BIN=$CARGO_BIN" >> "$GITHUB_ENV" - - name: Build the compiler the instrument runs through - id: build_witness_fold - run: |+ - GUNBC_FLOOR_LOG='gunbc-floor-cmd.log' - 'set' '+e' - 'set' '-o' 'pipefail' - ('sh' '-e' '-c' 'cargo build --release -p v1-compiler --bin gunbc') 2>&1 | 'tee' "$GUNBC_FLOOR_LOG" - GUNBC_FLOOR_EXIT="$?" - GUNBC_FLOOR_RECEIPT='gunbc-floor-outcome.txt' - GUNBC_FLOOR_CLASS='structural' - GUNBC_FLOOR_SIGNATURE='' - if '[' "$GUNBC_FLOOR_EXIT" '-eq' '126' ']'; then GUNBC_FLOOR_CLASS='infra'; GUNBC_FLOOR_SIGNATURE='CommandInvokedCannotExecute'; fi - if '[' "$GUNBC_FLOOR_CLASS" '=' 'structural' ']' && '[' "$GUNBC_FLOOR_EXIT" '-eq' '127' ']'; then GUNBC_FLOOR_CLASS='infra'; GUNBC_FLOOR_SIGNATURE='CommandNotFound'; fi - if '[' "$GUNBC_FLOOR_CLASS" '=' 'structural' ']' && '[' "$GUNBC_FLOOR_EXIT" '-eq' '0' ']'; then GUNBC_FLOOR_CLASS='none'; GUNBC_FLOOR_SIGNATURE=''; fi - if '[' "$GUNBC_FLOOR_CLASS" '=' 'structural' ']' && '[' '-f' "$GUNBC_FLOOR_LOG" ']' && 'grep' '-q' 'MemoryStallRefusedPageThrash' "$GUNBC_FLOOR_LOG"; then GUNBC_FLOOR_CLASS='infra'; GUNBC_FLOOR_SIGNATURE='MemoryStallRefusedPageThrash'; fi - if '[' "$GUNBC_FLOOR_CLASS" '=' 'structural' ']' && '[' '-f' "$GUNBC_FLOOR_LOG" ']' && 'grep' '-q' 'The runner has received a shutdown signal' "$GUNBC_FLOOR_LOG"; then GUNBC_FLOOR_CLASS='infra'; GUNBC_FLOOR_SIGNATURE='RunnerLost'; fi - if '[' "$GUNBC_FLOOR_CLASS" '=' 'structural' ']' && '[' '-f' "$GUNBC_FLOOR_LOG" ']' && 'grep' '-q' 'sccache: error: failed to execute compile' "$GUNBC_FLOOR_LOG"; then GUNBC_FLOOR_CLASS='infra'; GUNBC_FLOOR_SIGNATURE='SccacheFailedToExecuteCompile'; fi - if '[' "$GUNBC_FLOOR_CLASS" '=' 'structural' ']' && '[' '-f' "$GUNBC_FLOOR_LOG" ']' && 'grep' '-q' '(exit status: 254)' "$GUNBC_FLOOR_LOG"; then GUNBC_FLOOR_CLASS='infra'; GUNBC_FLOOR_SIGNATURE='SccacheRustcWrapperExit254'; fi - if '[' "$GUNBC_FLOOR_CLASS" '=' 'structural' ']' && '[' '-f' "$GUNBC_FLOOR_LOG" ']' && 'grep' '-q' 'sccache: encountered fatal error' "$GUNBC_FLOOR_LOG"; then GUNBC_FLOOR_CLASS='infra'; GUNBC_FLOOR_SIGNATURE='SccacheFatalError'; fi - if '[' "$GUNBC_FLOOR_CLASS" '=' 'structural' ']' && '[' '-f' "$GUNBC_FLOOR_LOG" ']' && 'grep' '-q' 'failed to spawn' "$GUNBC_FLOOR_LOG"; then GUNBC_FLOOR_CLASS='infra'; GUNBC_FLOOR_SIGNATURE='ProcessSpawnFailure'; fi - if '[' "$GUNBC_FLOOR_CLASS" '=' 'structural' ']' && '[' '-f' "$GUNBC_FLOOR_LOG" ']' && 'grep' '-q' 'Resource temporarily unavailable' "$GUNBC_FLOOR_LOG"; then GUNBC_FLOOR_CLASS='infra'; GUNBC_FLOOR_SIGNATURE='ResourceTemporarilyUnavailable'; fi - if (! '[' '-f' "$GUNBC_FLOOR_RECEIPT" ']') || '[' "$GUNBC_FLOOR_CLASS" '=' 'structural' ']' || ('[' "$GUNBC_FLOOR_CLASS" '=' 'infra' ']' && (! ('[' '-f' "$GUNBC_FLOOR_RECEIPT" ']' && 'grep' '-q' 'class=structural' "$GUNBC_FLOOR_RECEIPT"))) || ('[' "$GUNBC_FLOOR_CLASS" '=' 'none' ']' && (! ('[' '-f' "$GUNBC_FLOOR_RECEIPT" ']' && 'grep' '-q' 'class=structural' "$GUNBC_FLOOR_RECEIPT")) && (! ('[' '-f' "$GUNBC_FLOOR_RECEIPT" ']' && 'grep' '-q' 'class=infra' "$GUNBC_FLOOR_RECEIPT"))); then 'printf' 'class=%s\nsignature=%s\nexit=%s\n' "$GUNBC_FLOOR_CLASS" "$GUNBC_FLOOR_SIGNATURE" "$GUNBC_FLOOR_EXIT" > "$GUNBC_FLOOR_RECEIPT"; if '[' "$GUNBC_FLOOR_CLASS" '=' 'infra' ']'; then 'echo' '::error title=environment::floor_class='"$GUNBC_FLOOR_CLASS"' signature='"$GUNBC_FLOOR_SIGNATURE"' exit='"$GUNBC_FLOOR_EXIT"'; this is not a verdict about the diff. Attempt receipt: '"$GUNBC_FLOOR_RECEIPT"; fi; if '[' "$GUNBC_FLOOR_CLASS" '=' 'structural' ']'; then 'echo' '::error title=subject::floor_class='"$GUNBC_FLOOR_CLASS"' exit='"$GUNBC_FLOOR_EXIT"'; read the step log for the subject defect'; fi; fi - 'exit' "$GUNBC_FLOOR_EXIT" - - - name: Run //gunbc/instruments:v2-native-frontier under a memory bound - id: frontier_run - run: |+ - GUNBC_FLOOR_LOG='gunbc-floor-cmd.log' - 'set' '+e' - 'set' '-o' 'pipefail' - ('sh' '-e' '-c' ''\''systemd-run'\'' '\''--user'\'' '\''--scope'\'' '\''--property=MemoryMax=24G'\'' '\''--'\'' '\''target/release/gunbc'\'' '\''test'\'' '\''//gunbc/instruments:v2-native-frontier'\''') 2>&1 | 'tee' "$GUNBC_FLOOR_LOG" - GUNBC_FLOOR_EXIT="$?" - GUNBC_FLOOR_RECEIPT='gunbc-floor-outcome.txt' - GUNBC_FLOOR_CLASS='structural' - GUNBC_FLOOR_SIGNATURE='' - if '[' "$GUNBC_FLOOR_EXIT" '-eq' '126' ']'; then GUNBC_FLOOR_CLASS='infra'; GUNBC_FLOOR_SIGNATURE='CommandInvokedCannotExecute'; fi - if '[' "$GUNBC_FLOOR_CLASS" '=' 'structural' ']' && '[' "$GUNBC_FLOOR_EXIT" '-eq' '127' ']'; then GUNBC_FLOOR_CLASS='infra'; GUNBC_FLOOR_SIGNATURE='CommandNotFound'; fi - if '[' "$GUNBC_FLOOR_CLASS" '=' 'structural' ']' && '[' "$GUNBC_FLOOR_EXIT" '-eq' '0' ']'; then GUNBC_FLOOR_CLASS='none'; GUNBC_FLOOR_SIGNATURE=''; fi - if '[' "$GUNBC_FLOOR_CLASS" '=' 'structural' ']' && '[' '-f' "$GUNBC_FLOOR_LOG" ']' && 'grep' '-q' 'MemoryStallRefusedPageThrash' "$GUNBC_FLOOR_LOG"; then GUNBC_FLOOR_CLASS='infra'; GUNBC_FLOOR_SIGNATURE='MemoryStallRefusedPageThrash'; fi - if '[' "$GUNBC_FLOOR_CLASS" '=' 'structural' ']' && '[' '-f' "$GUNBC_FLOOR_LOG" ']' && 'grep' '-q' 'The runner has received a shutdown signal' "$GUNBC_FLOOR_LOG"; then GUNBC_FLOOR_CLASS='infra'; GUNBC_FLOOR_SIGNATURE='RunnerLost'; fi - if '[' "$GUNBC_FLOOR_CLASS" '=' 'structural' ']' && '[' '-f' "$GUNBC_FLOOR_LOG" ']' && 'grep' '-q' 'sccache: error: failed to execute compile' "$GUNBC_FLOOR_LOG"; then GUNBC_FLOOR_CLASS='infra'; GUNBC_FLOOR_SIGNATURE='SccacheFailedToExecuteCompile'; fi - if '[' "$GUNBC_FLOOR_CLASS" '=' 'structural' ']' && '[' '-f' "$GUNBC_FLOOR_LOG" ']' && 'grep' '-q' '(exit status: 254)' "$GUNBC_FLOOR_LOG"; then GUNBC_FLOOR_CLASS='infra'; GUNBC_FLOOR_SIGNATURE='SccacheRustcWrapperExit254'; fi - if '[' "$GUNBC_FLOOR_CLASS" '=' 'structural' ']' && '[' '-f' "$GUNBC_FLOOR_LOG" ']' && 'grep' '-q' 'sccache: encountered fatal error' "$GUNBC_FLOOR_LOG"; then GUNBC_FLOOR_CLASS='infra'; GUNBC_FLOOR_SIGNATURE='SccacheFatalError'; fi - if '[' "$GUNBC_FLOOR_CLASS" '=' 'structural' ']' && '[' '-f' "$GUNBC_FLOOR_LOG" ']' && 'grep' '-q' 'failed to spawn' "$GUNBC_FLOOR_LOG"; then GUNBC_FLOOR_CLASS='infra'; GUNBC_FLOOR_SIGNATURE='ProcessSpawnFailure'; fi - if '[' "$GUNBC_FLOOR_CLASS" '=' 'structural' ']' && '[' '-f' "$GUNBC_FLOOR_LOG" ']' && 'grep' '-q' 'Resource temporarily unavailable' "$GUNBC_FLOOR_LOG"; then GUNBC_FLOOR_CLASS='infra'; GUNBC_FLOOR_SIGNATURE='ResourceTemporarilyUnavailable'; fi - if (! '[' '-f' "$GUNBC_FLOOR_RECEIPT" ']') || '[' "$GUNBC_FLOOR_CLASS" '=' 'structural' ']' || ('[' "$GUNBC_FLOOR_CLASS" '=' 'infra' ']' && (! ('[' '-f' "$GUNBC_FLOOR_RECEIPT" ']' && 'grep' '-q' 'class=structural' "$GUNBC_FLOOR_RECEIPT"))) || ('[' "$GUNBC_FLOOR_CLASS" '=' 'none' ']' && (! ('[' '-f' "$GUNBC_FLOOR_RECEIPT" ']' && 'grep' '-q' 'class=structural' "$GUNBC_FLOOR_RECEIPT")) && (! ('[' '-f' "$GUNBC_FLOOR_RECEIPT" ']' && 'grep' '-q' 'class=infra' "$GUNBC_FLOOR_RECEIPT"))); then 'printf' 'class=%s\nsignature=%s\nexit=%s\n' "$GUNBC_FLOOR_CLASS" "$GUNBC_FLOOR_SIGNATURE" "$GUNBC_FLOOR_EXIT" > "$GUNBC_FLOOR_RECEIPT"; if '[' "$GUNBC_FLOOR_CLASS" '=' 'infra' ']'; then 'echo' '::error title=environment::floor_class='"$GUNBC_FLOOR_CLASS"' signature='"$GUNBC_FLOOR_SIGNATURE"' exit='"$GUNBC_FLOOR_EXIT"'; this is not a verdict about the diff. Attempt receipt: '"$GUNBC_FLOOR_RECEIPT"; fi; if '[' "$GUNBC_FLOOR_CLASS" '=' 'structural' ']'; then 'echo' '::error title=subject::floor_class='"$GUNBC_FLOOR_CLASS"' exit='"$GUNBC_FLOOR_EXIT"'; read the step log for the subject defect'; fi; fi - 'exit' "$GUNBC_FLOOR_EXIT" - - - name: Publish the frontier lines and the proposed roster - run: |- - # dissolve-on: native_frontier_publish_step -- orch-emitted foreign-executor step copying the [native-frontier] and [native-frontier-roster] lines the emitted binary already rendered (gunbc.native_frontier_ratchet native_frontier_report_lines, native_frontier_proposal_file_lines) into the job summary and the proposal file; the sed/echo/redirect strings remain until the emitted driver writes those two files itself, which is the capability gunbc.source_root_eval_driver_seed_growth names for its whole rendered main (a .dag driver receiving host effects as values, v2.cli.compile_cli NativeCliDriver). Adding the writes to the rendered main now instead would grow hand-written seed Rust to retire hand-written shell, which the 2026-09-23 seed policy refuses - sed -n 's/^\[native-frontier-roster\] //p' gunbc-floor-cmd.log > native-frontier-roster-proposal.dag - echo '## native frontier' >> "$GITHUB_STEP_SUMMARY" - echo '```' >> "$GITHUB_STEP_SUMMARY" - sed -n 's/^\[native-frontier\] //p' gunbc-floor-cmd.log >> "$GITHUB_STEP_SUMMARY" - echo '```' >> "$GITHUB_STEP_SUMMARY" - if test -s native-frontier-roster-proposal.dag; then echo 'A proposed roster is attached as the native-frontier-roster-proposal artifact. It is NOT applied: the committed gunbc.native_frontier_roster stays authoritative until a reviewed pull request replaces it.' >> "$GITHUB_STEP_SUMMARY"; fi - if: always() - - name: Upload the proposed roster - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f - with: - name: native-frontier-roster-proposal - path: native-frontier-roster-proposal.dag - if-no-files-found: ignore - retention-days: 14 - if: always() diff --git a/dag/gunbc/generated_artifact.dag b/dag/gunbc/generated_artifact.dag index 28a670a76ec..355b0859075 100644 --- a/dag/gunbc/generated_artifact.dag +++ b/dag/gunbc/generated_artifact.dag @@ -22,7 +22,6 @@ type GeneratedArtifact | MicrovmShakedownYamlArtifact | HealWorkflowYamlArtifact | HealPublisherWorkflowYamlArtifact - | NativeFrontierWorkflowYamlArtifact | GitignoreArtifact | GitattributesArtifact | CargoConfigArtifact @@ -57,7 +56,7 @@ type GeneratedArtifact data generated_artifact_registry: List = concat( concat( concat( - [WitnessFloorYamlArtifact, FleetConvergeYamlArtifact, FleetDesiredAdmissionYamlArtifact, MicrovmShakedownYamlArtifact, HealWorkflowYamlArtifact, HealPublisherWorkflowYamlArtifact, NativeFrontierWorkflowYamlArtifact, GitignoreArtifact, GitattributesArtifact, CargoConfigArtifact, RoadmapArtifact, DesignArtifact, DesignFailureModesArtifact, DesignRungDropsArtifact, ContributorOnboardingArtifact, GithooksPrePushArtifact, GithooksPreCommitArtifact, GeneratedArtifactMergeDriverArtifact, RunnerDeployArtifact, Stage0CrateLayoutGeneratedDagArtifact, Stage0CrateLayoutGeneratedRsArtifact, Stage0CratePartitionGeneratedDagArtifact, Stage0ExecutableAssemblyGeneratedDagArtifact, Stage0LinkedPartitionCratesArtifact, SeedRetentionFrontierGeneratedRsArtifact, V1InterpreterDispatchGeneratedRsArtifact, EvaluationBudgetConsequenceGeneratedRsArtifact, ReleaseLocusSeedConstantsGeneratedRsArtifact, CouponCadQueryProgramArtifact, Fci1BoundedExecutionContextArtifact, FileTransportRealizationGeneratedRsArtifact, WholeCorpusCompileMeasuredRootDemandsArtifact, ApprovalDeviceVectorsArtifact, ApproveIosProjectYmlArtifact], + [WitnessFloorYamlArtifact, FleetConvergeYamlArtifact, FleetDesiredAdmissionYamlArtifact, MicrovmShakedownYamlArtifact, HealWorkflowYamlArtifact, HealPublisherWorkflowYamlArtifact, GitignoreArtifact, GitattributesArtifact, CargoConfigArtifact, RoadmapArtifact, DesignArtifact, DesignFailureModesArtifact, DesignRungDropsArtifact, ContributorOnboardingArtifact, GithooksPrePushArtifact, GithooksPreCommitArtifact, GeneratedArtifactMergeDriverArtifact, RunnerDeployArtifact, Stage0CrateLayoutGeneratedDagArtifact, Stage0CrateLayoutGeneratedRsArtifact, Stage0CratePartitionGeneratedDagArtifact, Stage0ExecutableAssemblyGeneratedDagArtifact, Stage0LinkedPartitionCratesArtifact, SeedRetentionFrontierGeneratedRsArtifact, V1InterpreterDispatchGeneratedRsArtifact, EvaluationBudgetConsequenceGeneratedRsArtifact, ReleaseLocusSeedConstantsGeneratedRsArtifact, CouponCadQueryProgramArtifact, Fci1BoundedExecutionContextArtifact, FileTransportRealizationGeneratedRsArtifact, WholeCorpusCompileMeasuredRootDemandsArtifact, ApprovalDeviceVectorsArtifact, ApproveIosProjectYmlArtifact], map(fleet_autoinstall_specs, s => AutoinstallUserDataArtifact { spec: s }) ), map(fleet_intent_known_hosts, h => RunnerHostSudoersArtifact { host: h.identity }) @@ -198,7 +197,6 @@ fn artifact_location(a: GeneratedArtifact) -> ArtifactLocation { MicrovmShakedownYamlArtifact => ArtifactLocation { directory: ".github/workflows", name: "microvm-shakedown.yml" } HealWorkflowYamlArtifact => ArtifactLocation { directory: ".github/workflows", name: "heal.yml" } HealPublisherWorkflowYamlArtifact => ArtifactLocation { directory: ".github/workflows", name: "heal-publish.yml" } - NativeFrontierWorkflowYamlArtifact => ArtifactLocation { directory: ".github/workflows", name: "native-frontier.yml" } GitignoreArtifact => ArtifactLocation { directory: ".", name: ".gitignore" } GitattributesArtifact => ArtifactLocation { directory: ".", name: ".gitattributes" } CargoConfigArtifact => ArtifactLocation { directory: ".cargo", name: "config.toml" } @@ -287,7 +285,6 @@ fn artifact_commit_policy(a: GeneratedArtifact) -> CommitPolicy { MicrovmShakedownYamlArtifact => CommitRequired { consumer: GithubActionsWorkflow } HealWorkflowYamlArtifact => CommitRequired { consumer: GithubActionsWorkflow } HealPublisherWorkflowYamlArtifact => CommitRequired { consumer: GithubActionsWorkflow } - NativeFrontierWorkflowYamlArtifact => CommitRequired { consumer: GithubActionsWorkflow } RoadmapArtifact => CommitRequired { consumer: ProjectDocumentation } DesignArtifact => CommitRequired { consumer: ProjectDocumentation } DesignFailureModesArtifact => NotCommitted @@ -351,7 +348,6 @@ fn artifact_eq(a: GeneratedArtifact, b: GeneratedArtifact) -> Bool { MicrovmShakedownYamlArtifact => match b { MicrovmShakedownYamlArtifact => true _ => false } HealWorkflowYamlArtifact => match b { HealWorkflowYamlArtifact => true _ => false } HealPublisherWorkflowYamlArtifact => match b { HealPublisherWorkflowYamlArtifact => true _ => false } - NativeFrontierWorkflowYamlArtifact => match b { NativeFrontierWorkflowYamlArtifact => true _ => false } GitignoreArtifact => match b { GitignoreArtifact => true _ => false } GitattributesArtifact => match b { GitattributesArtifact => true _ => false } CargoConfigArtifact => match b { CargoConfigArtifact => true _ => false } @@ -428,7 +424,6 @@ fn artifact_producer(a: GeneratedArtifact) -> DeclarationRef { MicrovmShakedownYamlArtifact => decl_ref(module_path: "gunbc.runner_microvm_shakedown_workflow", decl_name: "expected_microvm_shakedown_yml") HealWorkflowYamlArtifact => decl_ref(module_path: "gunbc.heal_workflow", decl_name: "expected_heal_workflow_yml") HealPublisherWorkflowYamlArtifact => decl_ref(module_path: "gunbc.heal_publisher_workflow", decl_name: "expected_heal_publisher_workflow_yml") - NativeFrontierWorkflowYamlArtifact => decl_ref(module_path: "gunbc.native_frontier_workflow", decl_name: "expected_native_frontier_workflow_yml") GitignoreArtifact => decl_ref(module_path: "gunbc.gitignore_emit", decl_name: "expected_gitignore") GitattributesArtifact => decl_ref(module_path: "gunbc.gitattributes_emit", decl_name: "expected_gitattributes") CargoConfigArtifact => decl_ref(module_path: "gunbc.cargo_config_emit", decl_name: "expected_cargo_config_toml") diff --git a/dag/gunbc/generated_artifact_emit.dag b/dag/gunbc/generated_artifact_emit.dag index b916f4e1cae..56b653024cb 100644 --- a/dag/gunbc/generated_artifact_emit.dag +++ b/dag/gunbc/generated_artifact_emit.dag @@ -6,7 +6,7 @@ import gunbc.approve_ios_project { expected_approve_ios_project_yml, ApproveIosP import product.printed_chassis.cadquery_realization { CouponProgramGeneration, CouponProgramGenerated, CouponProgramRefused, expected_coupon_cadquery_program } import gunbc.generated_artifact { GeneratedArtifact, - WitnessFloorYamlArtifact, FleetConvergeYamlArtifact, FleetDesiredAdmissionYamlArtifact, MicrovmShakedownYamlArtifact, HealWorkflowYamlArtifact, HealPublisherWorkflowYamlArtifact, NativeFrontierWorkflowYamlArtifact, GitignoreArtifact, GitattributesArtifact, CargoConfigArtifact, RoadmapArtifact, DesignArtifact, DesignFailureModesArtifact, DesignRungDropsArtifact, ContributorOnboardingArtifact, + WitnessFloorYamlArtifact, FleetConvergeYamlArtifact, FleetDesiredAdmissionYamlArtifact, MicrovmShakedownYamlArtifact, HealWorkflowYamlArtifact, HealPublisherWorkflowYamlArtifact, GitignoreArtifact, GitattributesArtifact, CargoConfigArtifact, RoadmapArtifact, DesignArtifact, DesignFailureModesArtifact, DesignRungDropsArtifact, ContributorOnboardingArtifact, RunnerDeployArtifact, GithooksPrePushArtifact, GithooksPreCommitArtifact, GeneratedArtifactMergeDriverArtifact, AutoinstallUserDataArtifact, RunnerHostSudoersArtifact, PlanArtifact, Stage0CrateLayoutGeneratedDagArtifact, Stage0CrateLayoutGeneratedRsArtifact, @@ -37,7 +37,6 @@ import gunbc.fleet_converge_workflow { expected_fleet_converge_yml, FleetConverg import gunbc.fleet_desired_admission_workflow { expected_fleet_desired_yml, FleetDesiredGenerationOutcome, FleetDesiredGenerated, FleetDesiredGenerationRefused } import gunbc.runner_microvm_shakedown_workflow { expected_microvm_shakedown_yml, MicrovmShakedownWorkflowGenerated, MicrovmShakedownWorkflowGenerationRefused } import gunbc.heal_workflow { expected_heal_workflow_yml, HealWorkflowGenerated, HealWorkflowGenerationRefused } -import gunbc.native_frontier_workflow { expected_native_frontier_workflow_yml, NativeFrontierWorkflowGenerated, NativeFrontierWorkflowGenerationRefused } import gunbc.heal_publisher_workflow { expected_heal_publisher_workflow_yml, HealPublisherWorkflowGenerated, HealPublisherWorkflowGenerationRefused } import gunbc.witness_floor_workflow { WitnessFloorGenerationOutcome, WitnessFloorGenerated, WitnessFloorGenerationRefused } import gunbc.compiler_gate_workflow { expected_compiler_gate_yml } @@ -119,10 +118,6 @@ fn artifact_generate_unadorned(a: GeneratedArtifact) -> ArtifactGenerationOutcom HealWorkflowGenerated { content } => artifact_generated(content: content) HealWorkflowGenerationRefused { reason } => ArtifactGenerationRefused { reason: reason } } - NativeFrontierWorkflowYamlArtifact => match expected_native_frontier_workflow_yml() { - NativeFrontierWorkflowGenerated { content } => artifact_generated(content: content) - NativeFrontierWorkflowGenerationRefused { reason } => ArtifactGenerationRefused { reason: reason } - } HealPublisherWorkflowYamlArtifact => match expected_heal_publisher_workflow_yml() { HealPublisherWorkflowGenerated { content } => artifact_generated(content: content) HealPublisherWorkflowGenerationRefused { reason } => ArtifactGenerationRefused { reason: reason } @@ -266,7 +261,6 @@ fn artifact_extra_valid(a: GeneratedArtifact, generated: ArtifactGenerationOutco MicrovmShakedownYamlArtifact => ci_yml_parses(path: artifact_path(a: a)) HealWorkflowYamlArtifact => ci_yml_parses(path: artifact_path(a: a)) HealPublisherWorkflowYamlArtifact => ci_yml_parses(path: artifact_path(a: a)) - NativeFrontierWorkflowYamlArtifact => ci_yml_parses(path: artifact_path(a: a)) GitignoreArtifact => true GitattributesArtifact => true CargoConfigArtifact => true diff --git a/dag/gunbc/generated_workflow_provenance.dag b/dag/gunbc/generated_workflow_provenance.dag index 6ebf193e533..2b54b95a6d8 100644 --- a/dag/gunbc/generated_workflow_provenance.dag +++ b/dag/gunbc/generated_workflow_provenance.dag @@ -10,7 +10,6 @@ import gunbc.generated_artifact { MicrovmShakedownYamlArtifact, HealWorkflowYamlArtifact, HealPublisherWorkflowYamlArtifact, - NativeFrontierWorkflowYamlArtifact, } import v2.std.optional { Present, Absent } @@ -93,10 +92,6 @@ fn generated_workflow_provenance(a: GeneratedArtifact) -> GeneratedWorkflowProve generator: "gunbc.heal_publisher_workflow expected_heal_publisher_workflow_yml", authority: "gunbc.heal_publisher_workflow heal_publisher_workflow", } } - NativeFrontierWorkflowYamlArtifact => Present { value: GeneratedWorkflowProvenance { - generator: "gunbc.native_frontier_workflow expected_native_frontier_workflow_yml", - authority: "gunbc.native_frontier_workflow native_frontier_workflow", - } } _ => none } } diff --git a/dag/gunbc/instrument_targets.dag b/dag/gunbc/instrument_targets.dag index 16a52049fca..f3b1ddaf65a 100644 --- a/dag/gunbc/instrument_targets.dag +++ b/dag/gunbc/instrument_targets.dag @@ -209,9 +209,11 @@ fn v2_native_cli_label() -> Label { // because its verdict is a separate fact: a regressed identity turns this red, while qualification // counts a classified refusal and stays green. // -// ITS CONSUMER is the nightly `native-frontier` workflow (gunbc.native_frontier_workflow), which runs -// it on the srv self-hosted class under a memory bound and opens the pull request its proposal -// describes. Its subject corpus is the self-host instrument's, because the adjudicating binary is +// ITS CONSUMER is the native route's REQUIRED lane on the merge_group revision (operator ruling +// 2026-09-27). The nightly `native-frontier` workflow that ran it on a schedule was deleted by that +// ruling; the lane is promoted under a separate work item and is a declared frontier until it lands +// (gunbc.rung_drop v2_native_frontier_nightly_cadence). The run's printed proposal is what a mint or +// re-mint pull request carries (gunbc.native_frontier_debt). Its subject corpus is the self-host instrument's, because the adjudicating binary is // that instrument's emitted closure. fn v2_native_frontier_label() -> Label { Label { package: instruments_package() target: TargetName { name: "v2-native-frontier" } } diff --git a/dag/gunbc/instruments/docs_projection_gate.dag b/dag/gunbc/instruments/docs_projection_gate.dag index 7be9583a989..af3380921d6 100644 --- a/dag/gunbc/instruments/docs_projection_gate.dag +++ b/dag/gunbc/instruments/docs_projection_gate.dag @@ -20,7 +20,6 @@ import gunbc.generated_artifact { MicrovmShakedownYamlArtifact, HealWorkflowYamlArtifact, HealPublisherWorkflowYamlArtifact, - NativeFrontierWorkflowYamlArtifact, GitignoreArtifact, GitattributesArtifact, CargoConfigArtifact, RoadmapArtifact, @@ -89,7 +88,6 @@ fn docs_projection_producer(a: GeneratedArtifact) -> Optional { MicrovmShakedownYamlArtifact => Absent HealWorkflowYamlArtifact => Absent HealPublisherWorkflowYamlArtifact => Absent - NativeFrontierWorkflowYamlArtifact => Absent GitignoreArtifact => Absent GitattributesArtifact => Absent CargoConfigArtifact => Absent diff --git a/dag/gunbc/ledger_row_coherence.dag b/dag/gunbc/ledger_row_coherence.dag index b495c0f80bf..e1ac595b785 100644 --- a/dag/gunbc/ledger_row_coherence.dag +++ b/dag/gunbc/ledger_row_coherence.dag @@ -4,7 +4,7 @@ import std.types { String, List, Bool } import gunbc.generated_artifact { GeneratedArtifact, WitnessFloorYamlArtifact, FleetConvergeYamlArtifact, FleetDesiredAdmissionYamlArtifact, MicrovmShakedownYamlArtifact, - HealWorkflowYamlArtifact, HealPublisherWorkflowYamlArtifact, NativeFrontierWorkflowYamlArtifact, + HealWorkflowYamlArtifact, HealPublisherWorkflowYamlArtifact, GitignoreArtifact, GitattributesArtifact, CargoConfigArtifact, RoadmapArtifact, DesignArtifact, DesignFailureModesArtifact, DesignRungDropsArtifact, ContributorOnboardingArtifact, GithooksPrePushArtifact, GithooksPreCommitArtifact, GeneratedArtifactMergeDriverArtifact, @@ -119,7 +119,6 @@ fn ledger_rows(a: GeneratedArtifact) -> List { MicrovmShakedownYamlArtifact => [] HealWorkflowYamlArtifact => [] HealPublisherWorkflowYamlArtifact => [] - NativeFrontierWorkflowYamlArtifact => [] GitignoreArtifact => [] GitattributesArtifact => [] CargoConfigArtifact => [] diff --git a/dag/gunbc/native_frontier_debt.dag b/dag/gunbc/native_frontier_debt.dag index 9037749c7ba..91521a254dc 100644 --- a/dag/gunbc/native_frontier_debt.dag +++ b/dag/gunbc/native_frontier_debt.dag @@ -30,8 +30,17 @@ import gunbc.native_route_progress_guard { NativeProgressDispositionRow, NativeC // // WHO WRITES IT. Nobody by hand. A row is produced only by `native_frontier_proposal_lines`, // rendered by the emitted binary from its own run, and it lands through a reviewed pull request -// that carries the run receipt (host, tested tree, executable, command). The nightly -// `native-frontier` workflow opens that pull request. It is never merged automatically. +// that carries the run receipt (host, tested tree, executable, command). It is never merged +// automatically. +// +// WHICH RUN PROPOSES IT (operator ruling 2026-09-27). The native route's REQUIRED lane: its run on +// the merge_group revision executes `//gunbc/instruments:v2-native-frontier`, the emitted binary +// prints the `[native-frontier-roster]` proposal, and the lane publishes it. A mint or re-mint pull +// request carries that one run's proposal verbatim, with `tested_tree` equal to the merge_group +// sha, so the roster's receipt names a revision that was judged on the landing path. No schedule +// and no hand-run produces it: the nightly `native-frontier` workflow that used to was deleted by +// that ruling, and until the lane is live the roster stays unminted +// (gunbc.rung_drop v2_native_frontier_nightly_cadence). // // THE STANDING TODAY IS UNMINTED, AND THAT IS A RED, NOT A PASS. No run has yet produced a roster: // the route's measured wall (gunbc.rung_drop v2_native_route_off_the_merge_path, re-derived by the diff --git a/dag/gunbc/native_frontier_ratchet.dag b/dag/gunbc/native_frontier_ratchet.dag index 1723bfaa10f..93fd56e8f88 100644 --- a/dag/gunbc/native_frontier_ratchet.dag +++ b/dag/gunbc/native_frontier_ratchet.dag @@ -58,8 +58,10 @@ import gunbc.native_frontier_roster { native_frontier_roster } // `adjudicate` mode, beside `native_route_admission`, over the same receipt value. The per-identity // verdicts are typed values there, so the ratchet reads them as values. Anywhere else they would // first be written out as JSON and read back by a second decoder. The consumer that turns its -// verdict into an exit status is the `//gunbc/instruments:v2-native-frontier` instrument, and the -// nightly `native-frontier` workflow (gunbc.native_frontier_workflow) runs that instrument. +// verdict into an exit status is the `//gunbc/instruments:v2-native-frontier` instrument. Its run +// is bound to the native route's REQUIRED lane on the merge_group revision (operator ruling +// 2026-09-27, which deleted the nightly `native-frontier` workflow that ran it on a schedule). Until +// that lane is live nothing runs it, and gunbc.rung_drop v2_native_frontier_nightly_cadence says so. // // WHAT IT REUSES AND WHAT IT ADDS. The per-row comparison is gunbc#12049's guard, called row by // row: stage and cause regressions, subjects that left without a disposition, rename targets, @@ -528,8 +530,8 @@ fn native_frontier_report_lines(v: NativeFrontierVerdict) -> List { } // THE PROPOSED ROSTER, AS THE `.dag` MODULE IT WOULD BE. Present for every arm except `Held` and -// `NotAMeasurement`. The nightly writes it over `dag/gunbc/native_frontier_roster.dag` and opens a -// pull request. Dispositions and cause transitions are NOT carried forward, because each describes +// `NotAMeasurement`. The required native-route lane publishes it; it reaches +// `dag/gunbc/native_frontier_roster.dag` only through a reviewed pull request that carries it. Dispositions and cause transitions are NOT carried forward, because each describes // a transition relative to the rows it was written against: once the roster is re-minted from the // run, a disposition for a subject with no row and a transition whose cause no longer moves are // both findings in their own right (`DisposedSubjectHasNoBaselineRow`, diff --git a/dag/gunbc/native_frontier_workflow.dag b/dag/gunbc/native_frontier_workflow.dag deleted file mode 100644 index 6e48651279f..00000000000 --- a/dag/gunbc/native_frontier_workflow.dag +++ /dev/null @@ -1,406 +0,0 @@ -module gunbc.native_frontier_workflow - -import std.types { Bool, Int, List, String, NonEmptyStr } -import v2.std.optional { Present, Absent } -import v2.std.algebra { list_map } -import extdeps.languages.yaml.types { yaml_string, yaml_int, yaml_bool, kv } -import extdeps.languages.yaml.emit { emit_yaml, EmittedYaml, YamlEmitRefused, yaml_emit_refusal_text } -import extdeps.languages.yaml.gha_workflow { project_workflow_to_yaml } -import extdeps.github.actions { - Workflow, Job, Step, RunStep, UsesStep, - WorkflowDispatch, Schedule, - WorkflowPermissions, PermRead, - ConcurrencySpec, ConcurrencyMappingQueueNotMax, CancelInProgressBool -} -import extdeps.cron.schedule_model { CronSchedule, Exact, Wildcard } -import extdeps.exec.command { shell_command_render } -import extdeps.systemd { MemoryMax } -import extdeps.systemd.systemd_run { SystemdRunProperty, systemd_run_user_scope_command } -import extdeps.systemd.systemctl { systemctl_user_manager_probe_command } -import gunbc.action_use_admission { checkout_action, upload_artifact_action } -import gunbc.roadmap_execution_contract { CargoCapability, RustcCapability, RustfmtCapability, RustupCapability } -import gunbc.workflow_capability_closure { - CapabilityAnnotatedStep, StepCapabilityRole, capability_neutral, provides_only, consumes_only, - workflow_job_capability_closure, capability_closure_is_closed -} -import gunbc.toolchain_home_standing { - admit_workflow_toolchain_homes, WorkflowToolchainHomesAdmitted, WorkflowToolchainHomeRefused, toolchain_home_refusal_reason -} -import gunbc.toolchain_workflow_steps { toolchain_home_isolation_step, toolchain_pin_rustup_default_step } -import gunbc.witness_floor_workflow { witness_floor_toolchain_step, witness_floor_build_step } -import gunbc.ci_runner_target { gunbc_ci_selected_runner_spec } -import gunbc.ci_failure_class { wrap_command_with_floor_attempt_receipt, floor_attempt_command_log_filename } -import gunbc.repo_self_build { repo_self_build_command } -import gunbc.gunbc_cli_command { gunbc_test_command } -import gunbc.heal_workflow { job_permissions_carry_write } -import std.dissolution { DissolutionCondition, unbound_dissolution, dissolution_description } -import v2.std.orchestration { - Pipeline, PipelineStep, Do, Comment, Exit, If, Run, FailFast, - ExitZero, Not, DiscardOut, ToFile -} -import v2.std.optional { optional_present, optional_absent } -import v2.workflow.ci_workflow_run_emit { ci_workflow_run_emit_pipeline, ci_workflow_do } - -// THE NIGHTLY NATIVE FRONTIER RUN (operator-approved 2026-09-23 as one additional job, on a nightly -// cadence only). It runs `//gunbc/instruments:v2-native-frontier` once a night on the srv -// self-hosted class and publishes what that run proposes. The verdict is -// gunbc.native_frontier_ratchet's; this module decides only the job's realization. -// -// WHY NIGHTLY AND NOT MERGE_GROUP. The adjudicating native run is the route whose measured wall -// retired the `required-v2-native` lane (gunbc.rung_drop v2_native_route_off_the_merge_path, now -// replaced by gunbc.rung_drop v2_native_frontier_nightly_cadence). A per-pull-request or -// merge_group lane needs a further operator decision, and that decision should be made from the -// wall THIS job measures. The job does not restate that wall: the emitted binary prints it on its -// `[native-cost-partition]` line (`parent_span_nanos`, `peak_rss_bytes`), and the step timings -// record it on every run. -// -// WHY THE SRV CLASS, AND WHY THE BOUND. A BuildBuddy runner (7 GiB) is killed by native emission. -// The run's resident set is the reason it cannot share a host unbounded. So the instrument runs in -// a transient user scope with a MemoryMax the kernel enforces -// (extdeps.systemd.systemd_run systemd_run_user_scope_command). An over-budget run is killed inside -// its own cgroup and reported red by the step. It is never allowed to compete for the host. -// `GUNBC_MEMORY_BUDGET_BYTES` would not do here: the seed reads it as a planning ceiling and does -// not enforce it (v1 memory_governor). -// -// NO CREDENTIAL ON THE FLEET. The job is read-only. It uploads the proposed roster file as an -// artifact and writes the frontier lines to the job summary. Opening the shrink pull request is a -// recurring privileged write, which DESIGN section 3b routes through -// gunbc.auth.authorization_pattern_selection. Our self-hosted runners also run pull-request code, -// so a token there would be reachable from it. The publisher is a DECLARED FRONTIER (operator -// ruling via neat-boar-16, 2026-09-23). It must reuse gunbc.heal_publisher_workflow's route (its -// WIF federation and per-secret cell, on a GitHub-hosted runner), extended there if heal-publish -// cannot yet express "open a roster pull request", and never mint a second publisher. TRIGGER: that -// extension lands. Until then an advance is not progress: the ratchet's own report says -// "N roster row(s) cleared or later-staged, NOT YET APPLIED", and the committed roster stays -// authoritative. -// -// `emit-build`'s cancellation ruling does not apply: this is a schedule and a manual dispatch, and a -// newer run of the same subject supersedes an older one (cancel-in-progress), so no head ever holds -// more than one native claimant. - -data native_frontier_workflow_name: String = "native-frontier" - -data native_frontier_job_id: String = "frontier" - -data native_frontier_required_bins: List = ["gunbc"] - -data native_frontier_build_step_name: String = "Build the compiler the instrument runs through" - -data native_frontier_run_step_name: String = "Run //gunbc/instruments:v2-native-frontier under a memory bound" - -data native_frontier_run_step_id: String = "frontier_run" - -data native_frontier_proposal_path: String = "native-frontier-roster-proposal.dag" - -data native_frontier_proposal_artifact_name: String = "native-frontier-roster-proposal" - -data native_frontier_artifact_retention_days: Int = 14 - -// A BOUND, NOT A BUDGET. The one full native run measured on srv2 peaked near 15 GB (the drop row's -// figure, re-derived by this job's own `[native-cost-partition]` line). The bound leaves room above -// that, and stays far enough under an srv host that co-tenant runner slots survive a runaway. -data native_frontier_memory_max: NonEmptyStr = "24G" - -// A BOUND ABOVE THE ONE MEASURED FULL RUN (4h06m on srv2), for the same reason as the memory bound: -// trimming a slow but honest run would turn a verdict into silence. The wall this job measures is -// what a later merge_group decision reads. -data native_frontier_timeout_minutes: Int = 360 - -// 03:17 UTC, off the hour so it does not queue behind every other scheduled workflow on GitHub. -data native_frontier_schedule: CronSchedule = CronSchedule { - minute: Exact { value: 17 }, - hour: Exact { value: 3 }, - day_of_month: Wildcard, - month: Wildcard, - day_of_week: Wildcard -} - -fn native_frontier_instrument_command() -> String { - shell_command_render(command: systemd_run_user_scope_command( - properties: [SystemdRunProperty { property: MemoryMax, value: native_frontier_memory_max }], - command: gunbc_test_command(label: "//gunbc/instruments:v2-native-frontier") - )) -} - -// THE MEMORY BOUND'S PRECONDITION, ASSERTED FIRST AND REFUSED WITH A TYPED CAUSE. `systemd-run --user` -// needs a reachable user manager for the runner user, and that is a host fact, not a repository -// one. Measured by neat-boar-16 on 2026-09-23 for ghrunner (uid 999): srv1 has Linger=yes, but its -// /run/user/999 was absent at the time of reading (the manager may start lazily; unverified), and -// srv2 reports the user neither logged in nor lingering, so it cannot host this job until an -// operator enables linger there. This step runs before the build, so an unfit host refuses in -// seconds, naming `UserManagerUnreachable`, instead of hours into the census. There is no -// unbounded fallback. -// MARKED ON REQUEST (review 70711): both hand-shell steps in this job carry an on-carrier marker, -// as their siblings in the prelude do, and each names the capability that ends it. -data native_frontier_preflight_shell_emit_dissolution_trigger: DissolutionCondition = unbound_dissolution(description: "dissolve-on: native_frontier_preflight_step -- orch-emitted foreign-executor step probing the runner user's systemd manager (systemctl --user show-environment) and refusing with UserManagerUnreachable; the if/echo/exit strings remain until a typed host-manager-reachability probe lands on host_effect_apply (#5828 / shell-to-intent Phase 2), whose refusal arm this step's cause becomes") - -data native_frontier_publish_shell_emit_dissolution_trigger: DissolutionCondition = unbound_dissolution(description: "dissolve-on: native_frontier_publish_step -- orch-emitted foreign-executor step copying the [native-frontier] and [native-frontier-roster] lines the emitted binary already rendered (gunbc.native_frontier_ratchet native_frontier_report_lines, native_frontier_proposal_file_lines) into the job summary and the proposal file; the sed/echo/redirect strings remain until the emitted driver writes those two files itself, which is the capability gunbc.source_root_eval_driver_seed_growth names for its whole rendered main (a .dag driver receiving host effects as values, v2.cli.compile_cli NativeCliDriver). Adding the writes to the rendered main now instead would grow hand-written seed Rust to retire hand-written shell, which the 2026-09-23 seed policy refuses") - -// THE PREFLIGHT AS A PIPELINE, NOT AS SHELL TEXT (review 70721). The branch, the refusal and the -// exit are v2.std.orchestration structure, rendered by the same bash emitter as the prelude steps. -// Only the leaf commands are strings, which is the same level the prelude sits at. -fn native_frontier_preflight_pipeline() -> Pipeline { - Pipeline { - steps: [ - Comment { text: dissolution_description(condition: native_frontier_preflight_shell_emit_dissolution_trigger) }, - If { - cond: Not { inner: ExitZero { run: Run { - command: shell_command_render(command: systemctl_user_manager_probe_command()), - env: [], - redirect: optional_present(value: DiscardOut), - capture: optional_absent() - } } }, - then_: Pipeline { - steps: [ - ci_workflow_do(command: "echo \"::error title=environment::UserManagerUnreachable -- systemd-run --user cannot bound this job's memory on $(hostname) for $(id -un) (uid $(id -u)). The host needs a lingering user manager (loginctl enable-linger), an operator host change. This is not a frontier verdict.\""), - Exit { status: "1" } - ], - on_failure: FailFast - }, - else_: optional_absent() - } - ], - on_failure: FailFast - } -} - -fn native_frontier_preflight_step() -> Step { - RunStep { - name: Present { value: "Assert the runner user's systemd manager is reachable (the memory bound needs it)" }, - id: none, - run: ci_workflow_run_emit_pipeline(p: native_frontier_preflight_pipeline()), - shell: none, - env: none, - working_directory: none, - if_condition: none, - continue_on_error: none, - timeout_minutes: none - } -} - -fn native_frontier_checkout_step() -> Step { - UsesStep { - name: Present { value: "Checkout" }, - id: none, - uses: checkout_action, - with: Present { value: [kv(key: "persist-credentials", value: yaml_bool(b: false))] }, - env: none, - if_condition: none, - continue_on_error: none, - timeout_minutes: none - } -} - -// THE RUN'S LOG IS THE WRAPPER'S OWN (gunbc.ci_failure_class floor_attempt_command_log_filename). -// The wrapper tees the command under pipefail, so the step's status is the instrument's. A second -// tee inside the command would report tee's status instead. The failure-class wrapper is the -// floor's, so a lost runner reads as `infra` rather than as a frontier verdict. -fn native_frontier_run_step() -> Step { - RunStep { - name: Present { value: native_frontier_run_step_name }, - id: Present { value: native_frontier_run_step_id }, - run: concat( - wrap_command_with_floor_attempt_receipt( - command: native_frontier_instrument_command() - ), - "\n" - ), - shell: none, - env: none, - working_directory: none, - if_condition: none, - continue_on_error: none, - timeout_minutes: none - } -} - -// THE READ-BACK IS A PREFIX STRIP AND NOTHING ELSE. Every line it copies was rendered by -// gunbc.native_frontier_ratchet (`native_frontier_report_lines`, `native_frontier_proposal_file_lines`), -// so this step decides no fact. It runs whatever the verdict was, because a lost or unminted run -// is exactly the run whose lines a reader needs. The proposal file is a typed redirect (ToFile). -// The summary appends stay inside leaf commands, as the prelude's `>> "$GITHUB_ENV"` rows do, -// because v2.std.orchestration RedirectSpec has no append arm. -fn native_frontier_prefix_strip_command(prefix: String) -> String { - join(["sed -n 's/^\\[", prefix, "\\] //p' ", floor_attempt_command_log_filename], "") -} - -fn native_frontier_summary_append_command(command: String) -> String { - join([command, " >> \"$GITHUB_STEP_SUMMARY\""], "") -} - -fn native_frontier_publish_pipeline() -> Pipeline { - Pipeline { - steps: [ - Comment { text: dissolution_description(condition: native_frontier_publish_shell_emit_dissolution_trigger) }, - Do { run: Run { - command: native_frontier_prefix_strip_command(prefix: "native-frontier-roster"), - env: [], - redirect: optional_present(value: ToFile { path: native_frontier_proposal_path }), - capture: optional_absent() - } }, - ci_workflow_do(command: native_frontier_summary_append_command(command: "echo '## native frontier'")), - ci_workflow_do(command: native_frontier_summary_append_command(command: "echo '```'")), - ci_workflow_do(command: native_frontier_summary_append_command(command: native_frontier_prefix_strip_command(prefix: "native-frontier"))), - ci_workflow_do(command: native_frontier_summary_append_command(command: "echo '```'")), - If { - cond: ExitZero { run: Run { command: join(["test -s ", native_frontier_proposal_path], ""), env: [], redirect: optional_absent(), capture: optional_absent() } }, - then_: Pipeline { - steps: [ci_workflow_do(command: native_frontier_summary_append_command(command: join(["echo 'A proposed roster is attached as the ", native_frontier_proposal_artifact_name, " artifact. It is NOT applied: the committed gunbc.native_frontier_roster stays authoritative until a reviewed pull request replaces it.'"], "")))], - on_failure: FailFast - }, - else_: optional_absent() - } - ], - on_failure: FailFast - } -} - -fn native_frontier_publish_step() -> Step { - RunStep { - name: Present { value: "Publish the frontier lines and the proposed roster" }, - id: none, - run: ci_workflow_run_emit_pipeline(p: native_frontier_publish_pipeline()), - shell: none, - env: none, - working_directory: none, - if_condition: Present { value: "always()" }, - continue_on_error: none, - timeout_minutes: none - } -} - -fn native_frontier_upload_step() -> Step { - UsesStep { - name: Present { value: "Upload the proposed roster" }, - id: none, - uses: upload_artifact_action, - with: Present { - value: [ - kv(key: "name", value: yaml_string(s: native_frontier_proposal_artifact_name)), - kv(key: "path", value: yaml_string(s: native_frontier_proposal_path)), - kv(key: "if-no-files-found", value: yaml_string(s: "ignore")), - kv(key: "retention-days", value: yaml_int(n: native_frontier_artifact_retention_days)) - ] - }, - env: none, - if_condition: Present { value: "always()" }, - continue_on_error: none, - timeout_minutes: none - } -} - -type NativeFrontierBoundStep { - step: Step - role: StepCapabilityRole - step_name: String -} - -fn native_frontier_bound_steps() -> List { - [ - NativeFrontierBoundStep { step: native_frontier_checkout_step(), role: capability_neutral, step_name: "Checkout" }, - NativeFrontierBoundStep { step: native_frontier_preflight_step(), role: capability_neutral, step_name: "Assert the runner user's systemd manager is reachable (the memory bound needs it)" }, - NativeFrontierBoundStep { step: toolchain_home_isolation_step(), role: capability_neutral, step_name: "Isolate toolchain homes" }, - NativeFrontierBoundStep { - step: witness_floor_toolchain_step(), - role: provides_only(capabilities: [CargoCapability, RustcCapability, RustfmtCapability, RustupCapability]), - step_name: "Install Rust toolchain", - }, - NativeFrontierBoundStep { - step: toolchain_pin_rustup_default_step(), - role: consumes_only(capabilities: [RustupCapability, CargoCapability]), - step_name: "Pin rustup default (isolated RUSTUP_HOME has no default toolchain)", - }, - NativeFrontierBoundStep { - step: witness_floor_build_step(step_name: native_frontier_build_step_name, build_script: repo_self_build_command(bins: native_frontier_required_bins)), - role: consumes_only(capabilities: [CargoCapability]), - step_name: native_frontier_build_step_name, - }, - NativeFrontierBoundStep { step: native_frontier_run_step(), role: consumes_only(capabilities: [CargoCapability]), step_name: native_frontier_run_step_name }, - NativeFrontierBoundStep { step: native_frontier_publish_step(), role: capability_neutral, step_name: "Publish the frontier lines and the proposed roster" }, - NativeFrontierBoundStep { step: native_frontier_upload_step(), role: capability_neutral, step_name: "Upload the proposed roster" }, - ] -} - -fn native_frontier_capability_closure_holds() -> Bool { - capability_closure_is_closed( - v: workflow_job_capability_closure( - steps: list_map( - xs: native_frontier_bound_steps(), - f: fn(b) { CapabilityAnnotatedStep { step_name: b.step_name, role: b.role } }, - ) - ), - ) -} - -data native_frontier_permissions: WorkflowPermissions = WorkflowPermissions { - contents: Present { value: PermRead }, - pull_requests: none, - issues: none, - actions: none, - id_token: none -} - -fn native_frontier_job() -> Job { - Job { - id: native_frontier_job_id, - name: none, - runner: gunbc_ci_selected_runner_spec(), - steps: list_map(xs: native_frontier_bound_steps(), f: fn(b) { b.step }), - needs: [], - env: none, - outputs: none, - if_condition: none, - timeout_minutes: Present { value: native_frontier_timeout_minutes }, - continue_on_error: none, - concurrency: none, - permissions: Present { value: native_frontier_permissions }, - environment: none - } -} - -data native_frontier_concurrency: ConcurrencySpec = ConcurrencyMappingQueueNotMax { - group: "native-frontier", - cancel_in_progress: Present { value: CancelInProgressBool { value: true } }, - explicit_single: none -} - -data native_frontier_workflow: Workflow = Workflow { - name: native_frontier_workflow_name, - run_name: none, - on: [Schedule { cron: native_frontier_schedule }, WorkflowDispatch { inputs: [] }], - concurrency: Present { value: native_frontier_concurrency }, - env: Present { - value: [ - kv(key: "CARGO_TERM_COLOR", value: yaml_string(s: "always")), - kv(key: "MALLOC_ARENA_MAX", value: yaml_string(s: "2")) - ] - }, - permissions: Present { value: native_frontier_permissions }, - jobs: [native_frontier_job()] -} - -type NativeFrontierWorkflowGenerationOutcome - = NativeFrontierWorkflowGenerated { content: String } - | NativeFrontierWorkflowGenerationRefused { reason: String } - -data native_frontier_credential_refusal_reason: String = "REFUSED gunbc.native_frontier_workflow: the frontier job carries a write grant, and it runs on the self-hosted fleet, which also runs pull-request code. The shrink pull request is opened by the declared heal-publish extension, never from this job. No workflow yaml was emitted." - -data native_frontier_capability_refusal_reason: String = "REFUSED gunbc.native_frontier_workflow: the job's capability closure does not hold. No workflow yaml was emitted." - -fn expected_native_frontier_workflow_yml() -> NativeFrontierWorkflowGenerationOutcome { - match admit_workflow_toolchain_homes(workflow: native_frontier_workflow) { - WorkflowToolchainHomeRefused { job_id: j, refusal: r } => - NativeFrontierWorkflowGenerationRefused { reason: toolchain_home_refusal_reason(job_id: j, refusal: r) } - WorkflowToolchainHomesAdmitted => - if job_permissions_carry_write(permissions: native_frontier_job().permissions) { - NativeFrontierWorkflowGenerationRefused { reason: native_frontier_credential_refusal_reason } - } else if !native_frontier_capability_closure_holds() { - NativeFrontierWorkflowGenerationRefused { reason: native_frontier_capability_refusal_reason } - } else { - match emit_yaml(v: project_workflow_to_yaml(workflow: native_frontier_workflow)) { - EmittedYaml { text: t } => NativeFrontierWorkflowGenerated { content: t } - YamlEmitRefused { path: p, reason: r } => NativeFrontierWorkflowGenerationRefused { reason: yaml_emit_refusal_text(module_path: "gunbc.native_frontier_workflow", path: p, reason: r) } - } - } - } -} diff --git a/dag/gunbc/native_route_progress_guard.dag b/dag/gunbc/native_route_progress_guard.dag index 87e21e4eb1a..7c759b6269c 100644 --- a/dag/gunbc/native_route_progress_guard.dag +++ b/dag/gunbc/native_route_progress_guard.dag @@ -70,7 +70,8 @@ import gunbc.witness_v2_native_route { // CONSUMED SINCE 2026-09-23, PER ROW. gunbc.native_frontier_ratchet calls this module's row, disposition // and cause-transition folds (`native_progress_row_findings`, `native_progress_disposition_row_findings`, // `native_cause_transition_row_findings`) and `native_progress_finding_text` from inside the emitted -// binary's adjudicate mode, run nightly by `//gunbc/instruments:v2-native-frontier`. What it does +// binary's adjudicate mode, run by `//gunbc/instruments:v2-native-frontier` (bound to the native +// route's required lane since the nightly's deletion, 2026-09-27). What it does // NOT consume is `native_progress_report` as a whole (its whole-baseline adjudication clause cannot // hold for a roster compiled into the binary that judges it; the ratchet states why), nor the // provenance and advance vocabulary, which stays the frontier described below. The paragraphs diff --git a/dag/gunbc/rung_drop/v2_native_frontier_nightly_cadence.dag b/dag/gunbc/rung_drop/v2_native_frontier_nightly_cadence.dag index b2609b29165..845e1a4677b 100644 --- a/dag/gunbc/rung_drop/v2_native_frontier_nightly_cadence.dag +++ b/dag/gunbc/rung_drop/v2_native_frontier_nightly_cadence.dag @@ -1,36 +1,35 @@ module gunbc.rung_drop.v2_native_frontier_nightly_cadence import std.types { List, NonEmptyStr } -import gunbc.rung_drop { RungDrop, Standing, TypedDeclaration, DeletedWithoutReplacement } -import gunbc.guarantee_rung { Mitigatable, MechanicallyPreventable } - -// DECLARED 2026-09-23 (operator ruling via neat-boar-16). This is the differently-named drop that -// gunbc.rung_drop v2_native_route_off_the_merge_path pre-authorises as its third option: "a job -// that runs on a different cadence with its own row". The job is the nightly `native-frontier` -// workflow (gunbc.native_frontier_workflow). It runs `//gunbc/instruments:v2-native-frontier`, -// and gunbc.native_frontier_ratchet judges that run against the committed roster. +import gunbc.rung_drop { RungDrop, Standing, TypedDeclaration, ReplacementStaged } +import gunbc.guarantee_rung { OutsideTheLadder, MechanicallyPreventable } + +// DECLARED 2026-09-23, REWRITTEN 2026-09-27 (operator rulings via neat-boar-16). The row began as +// the differently-named drop gunbc.rung_drop v2_native_route_off_the_merge_path pre-authorised as +// its third option: a nightly `native-frontier` workflow running `//gunbc/instruments:v2-native-frontier`, +// with gunbc.native_frontier_ratchet judging that run against the committed roster. It claimed +// Mitigatable: caught a day late, not blocking. // -// THE RUNG THE NIGHTLY RESTORES IS RESTORED BY CADENCE, NOT ON THE MERGE PATH, and the row says so -// rather than claiming the previous rung back (DESIGN section 4b(1)). A regression is caught -// mechanically, but a day late and without blocking the change that caused it. So the temporary -// rung stays mitigatable: the frontier cannot silently move backwards, but it can merge backwards. -// -// SEQUENCING WITH THE ROW IT REPLACES. That row retires on an OBSERVED nightly run, never on this -// emission (the gunbc.rung_drop floor_cut_heal precedent: a capability is retired by its -// execution). Until then both rows stand, and the older one is the accurate description of the -// loss. The flip is one edit: that row's standing becomes Retired, with the first run's receipt as -// `trigger_fired`. +// WHY THE RUNG IS NOW OUTSIDE THE LADDER. The nightly never executed the universe: every scheduled +// run refused in preflight (UserManagerUnreachable on the runner host). The 2026-09-27 ruling then +// deleted it and bound the frontier to the native route's REQUIRED lane, which is staged under +// node://adhoc-11684de4-07b and not yet live. Between the two nothing runs the ratchet, so a +// frontier regression is not caught late -- it is not caught. Keeping Mitigatable would be rung +// inflation (DESIGN section 4b(1)); the row states the silent state honestly and names the capability +// whose execution ends it. It keeps its identity, because the subject (the frontier off the merge +// path) is unchanged; only the interim mechanism was withdrawn. data v2_native_frontier_nightly_cadence_population: List = [ - "gunbc.native_frontier_ratchet native_frontier_verdict over the whole v2.test.* universe, on every merge candidate (it runs nightly on main instead)", + "gunbc.native_frontier_ratchet native_frontier_verdict over the whole v2.test.* universe, on every merge candidate (nothing runs it at all until the required native-route lane is live)", "the derived v2.test.* universe executed by the emitted-native compiler, on every merge candidate", + "the [native-frontier-roster] proposal a mint or re-mint pull request carries: with no run there is no proposal, so the roster stays RosterUnminted and the ratchet has no baseline to hold", "what the route cannot see even when it runs, so a shrinking roster bounds the frontier from below and never measures it exactly: (i) every refusal inside a module whose FILE the front end refused; (ii) sites under a refused binder, which resolve marks ObservationIncomplete and never visits; (iii) call arguments, which do not reach resolve (gunbc.recurring_failure_mode call_expression_erased_at_v2_body_lowering); and, per identity, every refusal after the FIRST terminal one", ] data v2_native_frontier_nightly_cadence: RungDrop = RungDrop { identity: "v2_native_frontier_nightly_cadence" as NonEmptyStr, - subject: "The v2 native frontier (the ratchet over the emitted-native route's refusals) runs nightly, not on the merge path", + subject: "The v2 native frontier (the ratchet over the emitted-native route's refusals) runs on no merge candidate and on no schedule until the required native-route lane is live", declared: "2026-09-23", @@ -38,9 +37,9 @@ data v2_native_frontier_nightly_cadence: RungDrop = RungDrop { declaration: TypedDeclaration { previous: MechanicallyPreventable, - temporary: Mitigatable, - reason: DeletedWithoutReplacement, + temporary: OutsideTheLadder, + reason: ReplacementStaged { replacement: "the native route's REQUIRED lane on the merge_group revision (node://adhoc-11684de4-07b), running //gunbc/instruments:v2-native-frontier" }, population: v2_native_frontier_nightly_cadence_population, - restoration_trigger: "A REQUIRED merge_group (or per-pull-request) lane that runs //gunbc/instruments:v2-native-frontier and whose red blocks the landing, admitted by a further operator decision (the job roster is closed to growth). That decision must be made from the wall the nightly measures on the real runner class, not from a cited one, and the lane must supersede an older run of the same subject. The nightly alone does NOT retire this row. Neither does a non-required lane: the merge path is the capability this row lost. The lower-bound population (front-end file refusals, ObservationIncomplete under refused binders, call arguments, per-identity refusals after the first) is NOT restored by that lane either. Each of those retires only when the route observes it, and a row naming one of them must be split out rather than retired with this one", + restoration_trigger: "The required native-route lane's run on the merge_group revision executes //gunbc/instruments:v2-native-frontier over the whole v2.test.* universe, its red blocks the landing, AND that run produces a [native-frontier-roster] proposal that a mint pull request carries into gunbc.native_frontier_roster -- the capability is a ratchet judging every merge candidate against a minted roster, so the lane existing, or running without a mint taken from it, does NOT retire this row. The receipt (run id, merge_group sha as tested_tree, the minting pull request) becomes trigger_fired. The lower-bound population (front-end file refusals, ObservationIncomplete under refused binders, call arguments, per-identity refusals after the first) is NOT restored by that lane either. Each of those retires only when the route observes it, and a row naming one of them must be split out rather than retired with this one", } } diff --git a/dag/gunbc/rung_drop/v2_native_route_off_the_merge_path.dag b/dag/gunbc/rung_drop/v2_native_route_off_the_merge_path.dag index 27d456e8c94..9dbd61e1737 100644 --- a/dag/gunbc/rung_drop/v2_native_route_off_the_merge_path.dag +++ b/dag/gunbc/rung_drop/v2_native_route_off_the_merge_path.dag @@ -27,12 +27,13 @@ import gunbc.guarantee_rung { Mitigatable, MechanicallyPreventable } // be two facts. What is lost is EXECUTION ON THE ACCEPTANCE PATH: nothing runs the native route // on a merge candidate unless a person chooses to. // -// ITS THIRD OPTION IS BUILT, NOT YET OBSERVED (2026-09-23). The nightly `native-frontier` workflow -// (gunbc.native_frontier_workflow) is the "job that runs on a different cadence", and its row is -// gunbc.rung_drop v2_native_frontier_nightly_cadence. This row retires when the first nightly run on -// main is OBSERVED to execute the whole universe and report a frontier verdict. Its receipt (run -// id, tested tree, the `[native-cost-partition]` wall and peak) becomes `trigger_fired`. The -// emission alone does not retire it. +// ITS THIRD OPTION WAS BUILT AND NEVER OBSERVED, THEN DELETED (2026-09-23 / 2026-09-27). The nightly +// `native-frontier` workflow was the "job that runs on a different cadence"; every scheduled run +// refused in preflight (UserManagerUnreachable on the runner host) and none executed the universe. +// The operator ruling of 2026-09-27 deleted it in favour of the native route's REQUIRED lane, +// promoted under a separate work item. This row retires when that lane is OBSERVED to execute the +// whole universe on a merge candidate; its receipt (run id, tested tree, the +// `[native-cost-partition]` wall and peak) becomes `trigger_fired`. The emission alone does not. data v2_native_route_off_the_merge_path_population: List = [ "gunbc.witness_v2_native_route native_route_admission — every receipt clause, on every merge candidate", diff --git a/dag/test/claim/action_use_admission_witness_test.dag b/dag/test/claim/action_use_admission_witness_test.dag index 7e200131891..9e500b04327 100644 --- a/dag/test/claim/action_use_admission_witness_test.dag +++ b/dag/test/claim/action_use_admission_witness_test.dag @@ -280,7 +280,7 @@ fn census_holds(c: RealizedCensus) -> Bool { // eval-step budget. This join is what makes the per-file claims the census: a workflow added without // a claim, or a claim naming a file that is gone, refuses here, by name. data realized_workflow_files: List = [ - "fleet-converge.yml", "fleet-desired.yml", "heal-publish.yml", "heal.yml", "microvm-shakedown.yml", "mtcollins-canary.yml", "native-frontier.yml", "witnesses.yml" + "fleet-converge.yml", "fleet-desired.yml", "heal-publish.yml", "heal.yml", "microvm-shakedown.yml", "mtcollins-canary.yml", "witnesses.yml" ] fn listed_workflow_files() -> List { @@ -356,16 +356,6 @@ test fn census_microvm_shakedown_uses_are_modeled_and_executed_exactly() -> Bool ((c.refused |> count) == 0) && (c.uses == 0) } -// The nightly native frontier run (gunbc.native_frontier_workflow): its checkout and the -// upload-artifact step that publishes the proposed roster are among the admitted uses, so the join -// ran over real structure, not an empty file. -test fn census_native_frontier_uses_are_modeled_and_executed_exactly() -> Bool { - let c = census_file(name: "native-frontier.yml") - census_holds(c: c) - && any(c.admitted_texts, t => t == action_release_uses_text(action_release: checkout_action)) - && any(c.admitted_texts, t => t == action_release_uses_text(action_release: upload_artifact_action)) -} - // The hand-authored canary: its checkout and github-script steps are among the admitted uses, so // the join ran over real structure, not an empty file. test fn census_mtcollins_canary_uses_are_modeled_and_executed_exactly() -> Bool { diff --git a/src/v1/stage0/src/target_invocation_host.rs b/src/v1/stage0/src/target_invocation_host.rs index 21988792cec..dc044415246 100644 --- a/src/v1/stage0/src/target_invocation_host.rs +++ b/src/v1/stage0/src/target_invocation_host.rs @@ -1034,7 +1034,7 @@ fn run_self_host(source_roots: &[String]) -> InvocationOutcome { /// /// `held` and `advanced` are the observation holding: every planned identity reached a terminal /// verdict and every honest failure is rostered debt. An advance also prints a proposed smaller -/// roster, which the nightly turns into a pull request. `lost` and `unminted` are the observation +/// roster, which a reviewed pull request may carry (the required native-route lane publishes it). `lost` and `unminted` are the observation /// not holding. `unminted` is a complete run with nothing to hold it to, and an empty roster read as /// no debt would be a vacuous pass. `not-a-measurement` means the receipt failed an integrity /// clause or the pattern was narrower than the universe, so the subject was not reached. From 2efa5c5c7d8d046670ee8748cfa9eaf8685e424e Mon Sep 17 00:00:00 2001 From: "gunbai-bot[bot]" <289086189+gunbai-bot[bot]@users.noreply.github.com> Date: Sun, 27 Sep 2026 22:07:59 +0000 Subject: [PATCH 6/6] chore: regenerate drifted generated artifacts (ci auto-heal) Ledger-Repair-Judged: docs/design-rung-drops.md Ledger-Rows-Repaired: docs/design-rung-drops.md v2_native_frontier_nightly_cadence Heal-Candidate-Run: 36346816743 --- docs/design-rung-drops.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/design-rung-drops.md b/docs/design-rung-drops.md index b802182a7f7..407b6411dfb 100644 --- a/docs/design-rung-drops.md +++ b/docs/design-rung-drops.md @@ -230,9 +230,9 @@ admission rows on falsifier-family cadences with no scheduled route, awaiting tr The v2 native route (emitted-native compiler over the derived v2.test.* universe) as a required CI lane: RUNG DROP, mechanically preventable -> mitigatable (deleted without replacement). Population: gunbc.witness_v2_native_route native_route_admission — every receipt clause, on every merge candidate, the derived v2.test.* universe executed by the emitted-native compiler (positive population), v2.native_lane_fixture.control native_lane_false_control / native_lane_true_control (live-verdict controls), fixtures/native_lane_malformed/poison.dag.poisoned (malformed-specimen control), the old-route-withdrawn (no-fallback) control. Restored when: A REQUIRED NATIVE-ROUTE JOB WHOSE WALL FITS THE ACCEPTANCE PATH, designed from the ground up against an operator-agreed contract and not re-added into the same envelope: the job must conclude on every merge candidate inside its declared timeout on the real runner class (a measured wall, not a cited one), a newer head of the same subject must supersede the older run so no head holds more than one native claimant, and its red must still discriminate every clause of native_route_admission — universe join, positive population, classified refusals, per-identity agreement with the floor reference, and all four controls -- with the live false/true pair OBSERVED at gunbc.witness_v2_native_route native_route_live_pair_standing = LivePairRequired, not held by the expecting-red enrollment (gunbc.rung_drop.native_lane_live_pair_expected_red must be retired first, or retire in the same change). Whether that is reached by affected-set admission that runs only the universe a change touches, by a native run cheap enough to fit whole, or by a job that runs on a different cadence with its own row, is the design decision this drop waits on; the first two retire this row, the third replaces it with a differently-named drop. Re-adding `required-v2-native` with its 2026-09-10 shape does not retire this row and is refused by test.claim.witness_floor_workflow_consolidation_witness_test w_RED_the_deleted_lanes_do_not_return. -### The v2 native frontier (the ratchet over the emitted-native route's refusals) runs nightly, not on the merge path — declared 2026-09-23 +### The v2 native frontier (the ratchet over the emitted-native route's refusals) runs on no merge candidate and on no schedule until the required native-route lane is live — declared 2026-09-23 -The v2 native frontier (the ratchet over the emitted-native route's refusals) runs nightly, not on the merge path: RUNG DROP, mechanically preventable -> mitigatable (deleted without replacement). Population: gunbc.native_frontier_ratchet native_frontier_verdict over the whole v2.test.* universe, on every merge candidate (it runs nightly on main instead), the derived v2.test.* universe executed by the emitted-native compiler, on every merge candidate, what the route cannot see even when it runs, so a shrinking roster bounds the frontier from below and never measures it exactly: (i) every refusal inside a module whose FILE the front end refused; (ii) sites under a refused binder, which resolve marks ObservationIncomplete and never visits; (iii) call arguments, which do not reach resolve (gunbc.recurring_failure_mode call_expression_erased_at_v2_body_lowering); and, per identity, every refusal after the FIRST terminal one. Restored when: A REQUIRED merge_group (or per-pull-request) lane that runs //gunbc/instruments:v2-native-frontier and whose red blocks the landing, admitted by a further operator decision (the job roster is closed to growth). That decision must be made from the wall the nightly measures on the real runner class, not from a cited one, and the lane must supersede an older run of the same subject. The nightly alone does NOT retire this row. Neither does a non-required lane: the merge path is the capability this row lost. The lower-bound population (front-end file refusals, ObservationIncomplete under refused binders, call arguments, per-identity refusals after the first) is NOT restored by that lane either. Each of those retires only when the route observes it, and a row naming one of them must be split out rather than retired with this one. +The v2 native frontier (the ratchet over the emitted-native route's refusals) runs on no merge candidate and on no schedule until the required native-route lane is live: RUNG DROP, mechanically preventable -> outside the ladder (replacement staged: the native route's REQUIRED lane on the merge_group revision (node://adhoc-11684de4-07b), running //gunbc/instruments:v2-native-frontier). Population: gunbc.native_frontier_ratchet native_frontier_verdict over the whole v2.test.* universe, on every merge candidate (nothing runs it at all until the required native-route lane is live), the derived v2.test.* universe executed by the emitted-native compiler, on every merge candidate, the [native-frontier-roster] proposal a mint or re-mint pull request carries: with no run there is no proposal, so the roster stays RosterUnminted and the ratchet has no baseline to hold, what the route cannot see even when it runs, so a shrinking roster bounds the frontier from below and never measures it exactly: (i) every refusal inside a module whose FILE the front end refused; (ii) sites under a refused binder, which resolve marks ObservationIncomplete and never visits; (iii) call arguments, which do not reach resolve (gunbc.recurring_failure_mode call_expression_erased_at_v2_body_lowering); and, per identity, every refusal after the FIRST terminal one. Restored when: The required native-route lane's run on the merge_group revision executes //gunbc/instruments:v2-native-frontier over the whole v2.test.* universe, its red blocks the landing, AND that run produces a [native-frontier-roster] proposal that a mint pull request carries into gunbc.native_frontier_roster -- the capability is a ratchet judging every merge candidate against a minted roster, so the lane existing, or running without a mint taken from it, does NOT retire this row. The receipt (run id, merge_group sha as tested_tree, the minting pull request) becomes trigger_fired. The lower-bound population (front-end file refusals, ObservationIncomplete under refused binders, call arguments, per-identity refusals after the first) is NOT restored by that lane either. Each of those retires only when the route observes it, and a row naming one of them must be split out rather than retired with this one. ### The native lane's live-verdict control pair as a required admission clause — declared 2026-09-21 · RETIRED