Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
347d735
Namespace wave admission: charge a consumed row's deletion to its own…
Sep 13, 2026
b466304
Merge remote-tracking branch 'origin/main' into session/deep-otter-83…
Sep 13, 2026
48ea9ad
Wave admission: an owned consumed row is a receipt, only an unowned o…
Sep 13, 2026
10c40db
Wave admission: the receipt is observational, and the backstop's subj…
Sep 13, 2026
24fc5e1
Merge main into the consumed-row-owner branch
Sep 13, 2026
3355057
Thread the adjudication event through the explicit-revision seam (mer…
Sep 13, 2026
98b1bc9
Wave admission: the follow-up's forge state is read by nothing here, …
Sep 13, 2026
0b4ae4d
Merge main into the consumed-row-owner branch (DIRTY resolution)
Sep 14, 2026
5b022f7
Cut namespace transition admissions to directory-is-membership rows (…
gunbai-bot[bot] Sep 14, 2026
ceb0cec
Merge main into the consumed-row-owner branch (conflict: namespace_wa…
Sep 14, 2026
90a9193
transition_admission: hoist the expected_candidates annotation to mod…
Sep 14, 2026
1369a21
Merge main into the consumed-row-owner branch (conflict: namespace_wa…
Sep 14, 2026
adafa74
Merge remote-tracking branch 'origin/main' into session/deep-otter-83…
Sep 15, 2026
c59d850
Merge remote-tracking branch 'origin/main' into session/deep-otter-83…
Sep 15, 2026
8102440
Merge remote-tracking branch 'origin/main' into session/deep-otter-83…
Sep 15, 2026
d6a9db5
Merge remote-tracking branch 'origin/main' into session/deep-otter-83…
Sep 16, 2026
63c8cf7
Merge remote-tracking branch 'origin/main' into session/deep-otter-83…
Sep 16, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
96 changes: 93 additions & 3 deletions dag/gunbc/namespace/namespace_wave_admission.dag

Large diffs are not rendered by default.

72 changes: 72 additions & 0 deletions dag/gunbc/namespace/transition_admission.dag
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
module gunbc.namespace.transition_admission

import std.types { NonEmptyStr, List }
import std.decl_ref { DeclarationRef }
import std.integer { UInt32 }
import gunbc.compiler_frontend_program_interlock { NamespaceDeltaDisposition }

// Directory-is-membership roster for namespace transition admissions.
//
// CONSUMERS (§3c): (1) v1_compiler.namespace_wave_admission load_transition_admissions
// folds sibling files under dag/gunbc/namespace/transition_admission/ as the permission
// set for adjudicate -- the production fold, required-ci wave-admission phase only.
// (2) the parse sweep consumes each sibling as an ordinary module. (3)
// admission_roster_path_touched reads the directory prefix on the unfiltered diff.
// There is no committed list: a list would re-create the single-file collision this
// module exists to delete. Recurring_failure_mode's derived roster.dag exists because
// other modules import a List; this fold does not.
//
// EMPTY IS THE RESTING STATE, AND EMPTY IS NOT PERMISSIVE. A missing or empty sibling
// directory admits no extra delta: a run with no unadjudicated motion passes, a real
// TargetChanged without a file refuses. That sentence used to live above a Rust const
// and went stale whenever a dissolution PR edited the array but not the paragraph
// (#11274 left prose asserting seven #11182 rows still stood). THIS MODULE is the
// home for what remains: membership is the directory. Git history of the deleted
// const is quarry for past shrinks (53, 314, …). Do not transcribe a census of
// retired labels here — that is how the paragraph rotted.
//
// #11193 / #11347's const row is CONSUMED on main. Deletion owner is #11356
// (carried on #11214). This cut does not re-home that row as a sibling file:
// a roster touch that keeps a consumed admission is the bystander-red the
// directory exists to stop, and it would duplicate #11356's receipt.
//
// INHERITANCE FROM IN-FLIGHT CONST PRs. #11306 (vivid-stag-90) may land first with
// six TargetChanged rows, label "repository visibility unifies onto its resource
// module (gunbc#11306)", expected declarer extdeps.github.repository, at:
// extdeps.github.actions_token :: ActionsRepositoryPolicyObservation RepositoryVisibility
// extdeps.github.actions_token :: fork_write_tokens_reachable PrivateRepository
// extdeps.github.actions_token :: fork_write_tokens_reachable PublicRepository
// test.claim.actions_job_grant_witness :: fork_policy_allows PrivateRepository
// test.claim.actions_job_grant_witness :: fork_policy_denies PrivateRepository
// test.claim.actions_job_grant_witness :: public_fork_policy_allows PublicRepository
// Those become six sibling files (stem = module_declaration_spelling). They are
// consumed by that merge; #11316 deletes them as files. If this cut merges after
// that pair, the directory is empty again — the designed resting state. Do not
// author those six files onto an unlanded #11345: they would refuse against a
// main that does not yet carry the relocation.

// Binding.expected_candidates: candidate declaring identities, same type as enclosing. The wall
// join is module_path. decl_name must equal Binding.spelling (the relocated leaf); load refuses a
// mismatch so a phantom leaf cannot pass.
type AdmissionSubject
= Binding {
enclosing: DeclarationRef
spelling: NonEmptyStr
expected_candidates: List<DeclarationRef>
}
| Membership {
from_module: NonEmptyStr
target_module: NonEmptyStr
}

type DeletionFollowUp
= NotAuthored
| PullRequest { number: UInt32 }

type TransitionAdmission {
label: NonEmptyStr
subject: AdmissionSubject
disposition: NamespaceDeltaDisposition
deletion_follow_up: DeletionFollowUp
owner_pull_request: UInt32
}
30 changes: 27 additions & 3 deletions src/v1/stage0/src/bin/claim_executor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -812,9 +812,16 @@ fn run() -> Result<ExitCode, ExitCode> {
vocabulary.len()
));
}
match v1_compiler::cli_run::namespace_wave_admission::run_required_wave_admission(
index,
) {
let event_name = std::env::var("GITHUB_EVENT_NAME").ok();
let adjudicated = v1_compiler::cli_run::namespace_wave_admission::adjudication_event_from_name(
event_name.as_deref(),
)
.and_then(|event| {
v1_compiler::cli_run::namespace_wave_admission::run_required_wave_admission(
index, event,
)
});
match adjudicated {
Ok(outcome) => {
if let Some(failure) = report_wave_admission_outcome(&outcome) {
phase_failures.push(failure);
Expand Down Expand Up @@ -1914,6 +1921,7 @@ fn report_wave_admission_outcome(
head,
report,
roster_touched: _,
event: _,
} => {
let p = &report.population;
eprintln!(
Expand Down Expand Up @@ -1941,6 +1949,22 @@ fn report_wave_admission_outcome(
for consumed in &report.consumed_admissions {
eprintln!("required-ci: namespace-wave-admission CONSUMED ADMISSION {consumed}");
}
for owed in &report.used_without_follow_up {
eprintln!("required-ci: namespace-wave-admission FOLLOW-UP ABSENT {owed}");
}
for receipt in &report.owned_consumed_receipts {
eprintln!(
"required-ci: namespace-wave-admission CONSUMED ROW RECEIPT row={:?} \
owner=gunbc#{} follow_up=gunbc#{} -- follow-up number declared; its \
existence, state, and deletion scope are not established by this run, and \
whether this run refuses is wave_admission_refusal's verdict, not this \
receipt's; no executing route in this repository reads the follow-up's forge \
state",
receipt.label,
receipt.owner_pull_request,
receipt.deletion_follow_up_pull_request
);
}
// THE VERDICT IS THE WALL'S, NOT THE PRINTER'S. This function owns the receipts
// because it owns a stderr; `wave_admission_refusal` owns whether the run refuses,
// so the arm that decides it can be exercised by a test on the path CI runs rather
Expand Down
Loading
Loading