Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
55 changes: 54 additions & 1 deletion dag/gunbc/ci_layer_roots.dag
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module gunbc.ci_layer_roots

import std.realization_schedule { ScheduleWitnessEntry, ExecutionWitnessKind }
import std.realization_schedule { ScheduleWitnessEntry, ExecutionWitnessKind, CorpusWitnessKind }
import gunbc.cli_invoke {
source_roots_shell_flags,
SourceRootBare,
Expand Down Expand Up @@ -60,6 +60,7 @@ data witness_exclusion_substrings: List<String> = [
"test/claim/diagnostics_test.dag",
"effects_rest_transport_parse_witness_test.dag",
"floor_skip_discovery_witness_test.dag",
"synthetic_orphan_admission_witness_test.dag",
"interp_recorded_fixture_witness_test.dag",
"test/claim/parse_test.dag",
"v1_dag_parse_witness_test.dag",
Expand All @@ -79,6 +80,56 @@ data witness_exclusion_substrings: List<String> = [
"host_build_cache_provision_real_execution_witness_test.dag"
]

data witness_admission_offline_exclusion_substrings: List<String> = [
"test/claim/execution/",
"claim/complexity/accumulator_copy_roster_gate",
"claim/identity_captured_navigation/roster_gate",
"test/claim/enforcement/",
"enforcement_live_witness_test.dag",
"lever_a_local_receipt_witness",
"host_effect_apply_witness_test.dag",
"deploy_access_privilege_witness_test.dag",
"ci_deploy_observed_wet_test.dag",
"random_bytes_csprng_witness_test.dag",
"test/manual/",
"test/claim/manual/",
"test/claim/long/",
"behavioral_witness_test.dag",
"ci_exclusion_proof_test.dag",
"impossible_bug",
"artifact_store_fs_witness_test.dag",
"emit_source_store_test.dag",
"glob_discovery",
"host_discovered_owned_data_manifest.dag",
"host_source_root_ingest_manifest.dag",
"program_assembly/real_ingest_test.dag",
"self_host/compiler_closure_emit_from_ingest_test.dag",
"unified_test_claim_substrate_equivalence.dag"
]

data witness_admission_fixture_exclusion_substrings: List<String> = [
"test/fixture/floor_skip/"
]

data witness_admission_offline_note: String = "Phase 0(b) admission invariant (module-identity-storage-binding): operator-ruled OFFLINE exclusion substrings whose witness rows carry OfflineLocalRecipe consumers — documented local recipes in the paired exclusion notes (wet_integration_offline_note, enforcement_coverage_exclusion_note, accumulator_copy_roster_gate_exclusion_note, identity_captured_navigation_roster_gate_exclusion_note, lever_a_local_receipt_witness_exclusion_note, long_lane_exclusion_note). Dissolves when each row graduates to a scheduled CI consumer or deletes."

data witness_admission_fixture_note: String = "Phase 0(b): floor_skip control fixtures excluded at dir grain — consumers are explicit rosters in floor_skip_discovery_witness, not the discovery corpus. Dissolves when fixture-home policy changes."

fn probe_red(entry: String, f: String) -> ScheduleWitnessEntry {
ScheduleWitnessEntry { entry: entry, function: f, kind: CorpusWitnessKind }
}

data known_red_probe_note: String = "Phase 0(b) quarantine probe cadence (module-identity-storage-binding): known-red frontier witnesses excluded from per-PR discovery that EXPECT RED on main — the falsifier probe batch runs them SelectionApplied; greening is a counted un-quarantine event (dissolve-on in known_red_frontier_note per row). Distinct from falsifier_self_host_wet (green-only SelfEmitted receipts)."

data known_red_probe_entries: List<ScheduleWitnessEntry> = [
probe_red(entry: "src/v2/test/claim/emit/logic_ground_truth_test.dag", f: "logic_complement_truth_table"),
probe_red(entry: "src/v2/test/claim/emit/logic_ground_truth_test.dag", f: "logic_meet_truth_table"),
probe_red(entry: "src/v2/test/claim/emit/logic_ground_truth_test.dag", f: "logic_join_truth_table"),
probe_red(entry: "src/v2/test/claim/emit/logic_ground_truth_test.dag", f: "logic_truth_tables_all"),
probe_red(entry: "src/v2/test/claim/manual/english_emit_add_test.dag", f: "english_emit_add_emit_ingest_round_trip_holds"),
probe_red(entry: "src/v2/test/claim/manual/english_emit_add_test.dag", f: "english_emit_add_prose_holds")
]

data long_lane_exclusion_note: String = "test/claim/long/ is the LONG-test home (operator 5-second rule, 2026-07-12; authority + enforcement: gunbc_ci_fast_lane_rule_note / gunbc_ci_fast_lane_witness_eval_budget in v2.workflow.ci_floor_plan): a witness whose own eval reaches 5s does not run in per-PR discovery — the executor's cooperative eval deadline REDs it by name (EvalBudgetExceeded), and the fix is moving its file here (dag/test/claim/long/, src/v2/test/claim/long/), where discovery excludes it at dir grain and it runs via the local recipe (claim_batch --source-root dag --source-root src/v2 --entry <file> --functions <csv>) or the scheduled lane's future enrollment. First residents (receipted): s1_closure_receipt_test (whole-closure re-parse through the interpreted v2 frontend, 90+min eval, the run-29183446733 wedge class) and self_host_module_emit_derisk_test (~31s/witness). Unlike the roster exclusions above, membership here is a HOME, not a per-file ruling: the 5s deadline makes an over-budget fast-lane witness unwritable-in-place, so the roster cannot silently grow stale (§5 construction over validation). Dissolve-on: per-witness declared cost envelopes (witness-cost-locality admission law) subsume the dir grain."

data wet_integration_offline_note: String = "Four wet-integration entries above (host_effect_apply, deploy_access_privilege, ci_deploy_observed_wet, random_bytes_csprng) are OFFLINE per the hermetic-floor posture (operator 2026-07-11: integration-style witnesses must not run regularly; CI runs hermetic/mocked behavior checks). Each performs genuinely live host effects the hermetic envelope refuses by construction: host_effect_apply drives real LocalShell/SSH host effects (the 133s row atop the slow-witness census), deploy_access_privilege applies privileged shell mutations through fixture actors, ci_deploy_observed_wet shells whoami + sudo -n, random_bytes_csprng reads host entropy. Hermetic duals stay discovered where they exist (the ci_deploy split keeps the pure half; deploy_access_check(access, actor) is the mock-shaped dual). Local recipe: claim_batch --wet --source-root dag --source-root src/v2 --entry <entry> per file. Dissolve-on: the scheduled (nightly) lane un-darkens and admits wet integration rows under its own budget — then these four enroll there as declared execution rows and the exclusion rows delete."
Expand Down Expand Up @@ -124,6 +175,8 @@ data bin_witness_wet_entries: List<ScheduleWitnessEntry> = [
bin_wet(entry: "dag/test/claim/typed_witness_invocation_test.dag", f: "typed_run_witness_bin_unbuildable_red_control_holds"),
bin_wet(entry: "dag/test/claim/typed_witness_invocation_test.dag", f: "typed_is_nonempty_positive_holds"),
bin_wet(entry: "dag/test/claim/typed_witness_invocation_test.dag", f: "typed_is_nonempty_zero_byte_red_control_holds"),
bin_wet(entry: "dag/test/claim/typed_witness_invocation_test.dag", f: "typed_gunbc_cli_run_claim_holds"),
bin_wet(entry: "dag/test/claim/typed_witness_invocation_test.dag", f: "typed_claim_executor_verify_build_artifacts_red_control_holds"),
bin_wet(entry: "dag/test/claim/v1_dag_parse_witness_test.dag", f: "v1_dag_parse_witnesses"),
bin_wet(entry: "src/v2/test/claim/auth_declared_but_unwired_witness_test.dag", f: "auth_declared_but_unwired_witness_keystone_holds"),
bin_wet(entry: "src/v2/test/claim/bootstrap_test.dag", f: "bootstrap_witness_keystone_holds"),
Expand Down
218 changes: 218 additions & 0 deletions src/v1/stage0/src/cli_run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1010,6 +1010,12 @@ const CI_LAYER_ROOTS_AUTHORITY_REL: &str = "dag/gunbc/ci_layer_roots.dag";
const WITNESS_LAYER_ROOTS_DATA_NAME: &str = "witness_layer_roots";
const WITNESS_DISCOVERY_SCAN_DIRS_DATA_NAME: &str = "witness_discovery_scan_dirs";
const WITNESS_EXCLUSION_SUBSTRINGS_DATA_NAME: &str = "witness_exclusion_substrings";
const WITNESS_ADMISSION_OFFLINE_EXCLUSION_SUBSTRINGS_DATA_NAME: &str =
"witness_admission_offline_exclusion_substrings";
const WITNESS_ADMISSION_FIXTURE_EXCLUSION_SUBSTRINGS_DATA_NAME: &str =
"witness_admission_fixture_exclusion_substrings";
const WET_RECEIPT_ENROLLMENT_AUTHORITY_REL: &str =
"src/v2/compiler/self_host/wet_receipt_enrollment.dag";
const WHOLE_TREE_STRICT_RESOLVE_EXCLUSION_SUBSTRINGS_DATA_NAME: &str =
"whole_tree_strict_resolve_exclusion_substrings";

Expand Down Expand Up @@ -7328,6 +7334,13 @@ pub struct DeferredDiscoveryRow {
pub reads_live_tree: bool,
}

/// Phase 0(b) admission invariant refusal — an excluded witness row with zero executing consumers.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct UnexecutedDeferredWitness {
pub entry: String,
pub function: String,
}

#[derive(Debug)]
pub struct DiscoverySummary {
pub total: usize,
Expand Down Expand Up @@ -7706,6 +7719,170 @@ pub fn collect_deferred_discovery_rows(
Ok(out)
}

fn witness_admission_offline_exclusion_substrings() -> Vec<String> {
static PATTERNS: OnceLock<Vec<String>> = OnceLock::new();
PATTERNS
.get_or_init(|| {
string_list_data_from_ci_layer_roots_source(
ci_layer_roots_authority_content(),
WITNESS_ADMISSION_OFFLINE_EXCLUSION_SUBSTRINGS_DATA_NAME,
)
})
.clone()
}

fn witness_admission_fixture_exclusion_substrings() -> Vec<String> {
static PATTERNS: OnceLock<Vec<String>> = OnceLock::new();
PATTERNS
.get_or_init(|| {
string_list_data_from_ci_layer_roots_source(
ci_layer_roots_authority_content(),
WITNESS_ADMISSION_FIXTURE_EXCLUSION_SUBSTRINGS_DATA_NAME,
)
})
.clone()
}

fn path_matches_any_substring(path: &str, subs: &[String]) -> bool {
subs.iter().any(|sub| path.contains(sub.as_str()))
}

fn witness_admission_manifest_key(entry: &str, function: &str) -> String {
format!("{entry}::{function}")
}

// 🟡 dissolve-on: witness_admission_explicit_consumer_manifest — replace this hand-rolled
// entry/function literal scan with the `.dag`-authoritative manifest from
// v2.workflow.witness_admission (or a Node-tree builtin over the roster
// ScheduleWitnessEntry rows). False-positive matches widen the orphan gate (excuse orphans),
// never refuse — interim seed debt, same class as string_list_data_from_ci_layer_roots_source.
fn witness_admission_entry_function_keys_from_source(content: &str) -> Vec<String> {
let mut keys = Vec::new();
let mut push_pair = |entry: &str, function: &str| {
let key = witness_admission_manifest_key(entry, function);
if !keys.iter().any(|k| k == &key) {
keys.push(key);
}
};
let mut scan_call_style = |prefix: &str| {
let mut search_from = 0;
while let Some(rel) = content[search_from..].find(prefix) {
let start = search_from + rel + prefix.len();
let Some((entry, after_entry)) = content[start..].split_once('"') else {
break;
};
let fn_marker = if let Some(pos) = after_entry.find("f: \"") {
("f: \"", pos)
} else if let Some(pos) = after_entry.find("function: \"") {
("function: \"", pos)
} else {
search_from = start + entry.len() + 1;
continue;
};
let fn_start = fn_marker.1 + fn_marker.0.len();
if let Some((function, _)) = after_entry[fn_start..].split_once('"') {
push_pair(entry, function);
}
search_from = start + entry.len() + 1;
}
};
scan_call_style("bin_wet(entry: \"");
scan_call_style("probe_red(entry: \"");
scan_call_style("self_host_wet_entry(\n entry: \"");
scan_call_style("self_host_wet_entry(entry: \"");
let mut search_from = 0;
while let Some(rel) = content[search_from..].find("entry: \"") {
let start = search_from + rel + "entry: \"".len();
let Some((entry, after_entry)) = content[start..].split_once('"') else {
break;
};
if let Some(fn_rel) = after_entry.find("function: \"") {
let fn_start = fn_rel + "function: \"".len();
if let Some((function, _)) = after_entry[fn_start..].split_once('"') {
push_pair(entry, function);
}
}
search_from = start + entry.len() + 1;
}
keys.sort();
keys
}

fn witness_admission_explicit_consumer_keys() -> Vec<String> {
static KEYS: OnceLock<Vec<String>> = OnceLock::new();
KEYS.get_or_init(|| {
let mut keys =
witness_admission_entry_function_keys_from_source(ci_layer_roots_authority_content());
let wet =
std::fs::read_to_string(workspace_root().join(WET_RECEIPT_ENROLLMENT_AUTHORITY_REL))
.unwrap_or_else(|e| {
panic!(
"witness admission: failed to read {}: {e}",
WET_RECEIPT_ENROLLMENT_AUTHORITY_REL
)
});
for key in witness_admission_entry_function_keys_from_source(&wet) {
if !keys.iter().any(|k| k == &key) {
keys.push(key);
}
}
keys.sort();
keys
})
.clone()
}

/// Phase 0(b): every deferred witness row must name an executing consumer (explicit roster,
/// offline local recipe, or fixture explicit roster). Returns orphans — enrolled, zero consumers.
pub fn collect_unexecuted_deferred_witnesses(
deferred_rows: &[DeferredDiscoveryRow],
) -> Vec<UnexecutedDeferredWitness> {
let explicit = witness_admission_explicit_consumer_keys();
let offline = witness_admission_offline_exclusion_substrings();
let fixture = witness_admission_fixture_exclusion_substrings();
let mut orphans = Vec::new();
for row in deferred_rows {
let key = witness_admission_manifest_key(&row.entry, &row.function);
if explicit.iter().any(|k| k == &key) {
continue;
}
if path_matches_any_substring(&row.entry, &offline)
|| path_matches_any_substring(&row.entry, &fixture)
{
continue;
}
orphans.push(UnexecutedDeferredWitness {
entry: row.entry.clone(),
function: row.function.clone(),
});
}
orphans
}

fn refuse_unexecuted_deferred_witnesses(
orphans: &[UnexecutedDeferredWitness],
) -> Result<(), String> {
if orphans.is_empty() {
return Ok(());
}
let mut lines: Vec<String> = orphans
.iter()
.take(8)
.map(|o| format!("{} ({})", o.function, o.entry))
.collect();
if orphans.len() > 8 {
lines.push(format!("… and {} more orphan row(s)", orphans.len() - 8));
}
Err(format!(
"WITNESS ADMISSION REFUSAL cause=UnexecutedDeferredWitness count={} — enrolled \
witness row(s) excluded from discovery name zero executing consumers (Phase 0(b) \
admission invariant); each excluded row must be on falsifier_self_host_wet, \
bin_witness_wet, known_red_probe, offline, or fixture explicit roster: {}",
orphans.len(),
lines.join("; ")
))
}

fn eprintln_deferred_discovery_rows(rows: &[DeferredDiscoveryRow]) {
if rows.is_empty() {
return;
Expand Down Expand Up @@ -9927,6 +10104,8 @@ pub fn run_discovery_corpus_with_options(
} else {
collect_deferred_discovery_rows(source_roots, &options.exclude_substrings)?
};
let admission_orphans = collect_unexecuted_deferred_witnesses(&deferred_rows);
refuse_unexecuted_deferred_witnesses(&admission_orphans)?;
eprintln_deferred_discovery_rows(&deferred_rows);
set_phase(FloorPhase::Discovery, "discovery-roster");
let selection_enabled = options.node_frontier_selection != NodeFrontierSelectionMode::Off;
Expand Down Expand Up @@ -12573,6 +12752,45 @@ mod node_frontier_plumbing_controls {
);
}

// Phase 0(b) admission invariant: every deferred witness row names an executing consumer.
#[test]
fn witness_admission_deferred_rows_have_consumers() {
let ws = workspace_root();
std::env::set_current_dir(&ws).expect("chdir workspace");
let roots = setup_roots(&ws);
let excludes = super::witness_exclusion_substrings();
let deferred =
super::collect_deferred_discovery_rows(&roots, &excludes).expect("deferred scan");
let orphans = super::collect_unexecuted_deferred_witnesses(&deferred);
super::refuse_unexecuted_deferred_witnesses(&orphans)
.unwrap_or_else(|e| panic!("live deferred corpus must admit every row: {e}"));
let normalize = deferred
.iter()
.find(|r| r.function == "self_host_03_normalize_behavioral_receipt_holds")
.expect("03_normalize behavioral receipt must be deferred from discovery");
assert!(
normalize
.entry
.contains("self_host_03_normalize_behavioral_witness_test"),
"03_normalize receipt entry: got {}",
normalize.entry
);
}

#[test]
fn witness_admission_orphan_synthetic_row_refuses() {
let orphan = super::DeferredDiscoveryRow {
entry: "dag/test/claim/synthetic_orphan_admission_witness_test.dag".to_string(),
function: "synthetic_orphan_no_consumer_holds".to_string(),
exclude_reason: "synthetic_orphan_admission_witness_test.dag".to_string(),
reads_live_tree: false,
};
let orphans = super::collect_unexecuted_deferred_witnesses(&[orphan]);
assert_eq!(orphans.len(), 1);
let err = super::refuse_unexecuted_deferred_witnesses(&orphans).expect_err("orphan");
assert!(err.contains("UnexecutedDeferredWitness"));
}

// Phase 0 receipt (module-identity-storage-binding): the 03_normalize behavioral
// witness declares a hermetic import closure but carries string-carried path deps via
// tools.self_host_03_normalize_behavioral_transport — derived host-reading must fire.
Expand Down
39 changes: 39 additions & 0 deletions src/v2/std/witness_admission.dag
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
module v2.std.witness_admission

import v2.std.collection { List }
import v2.std.logic { Bool }
import v2.std.text { String }

data witness_admission_authority_note: String = "Phase 0(b) admission invariant (docs/plans/module-identity-storage-binding-design.md): every enrolled witness row names an executing consumer — discovery rows run per selection; SelfEmitted receipts run on the falsifier wet cadence; known-red quarantined rows run on a probe cadence expecting red (greening is a counted un-quarantine event); operator-ruled OFFLINE rows carry an explicit local-recipe consumer. Enrolled-with-zero-consumers is a typed refusal, never silent. Dissolves when witness_exclusion_substrings rows are replaced by derived consumer classification."

type WitnessConsumerCadence
= DiscoverySelection
| FalsifierSelfHostWet
| BinWitnessWet
| QuarantineProbeExpectRed
| OfflineLocalRecipe
| FixtureExplicitRoster
| NoConsumer

type WitnessAdmissionRefusal
= WitnessAdmissionHolds
| UnexecutedDeferredWitness { entry: String, function: String }

fn witness_consumer_cadence_is_live(cadence: WitnessConsumerCadence) -> Bool {
match cadence {
NoConsumer => false
DiscoverySelection => true
FalsifierSelfHostWet => true
BinWitnessWet => true
QuarantineProbeExpectRed => true
OfflineLocalRecipe => true
FixtureExplicitRoster => true
}
}

fn witness_admission_refusal_is_holds(refusal: WitnessAdmissionRefusal) -> Bool {
match refusal {
WitnessAdmissionHolds => true
UnexecutedDeferredWitness { entry: _, function: _ } => false
}
}
Loading
Loading