Skip to content
Merged
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
19 changes: 19 additions & 0 deletions dag/gunbc/cli_run_workspace_root_scaffold.dag
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,22 @@ data cli_run_workspace_root_discovery_loc_delta_net: Int = 12
data cli_run_workspace_root_discovery_test_discriminator_git_toplevel: String = "from_subdirectory_matches_git_toplevel"

data cli_run_workspace_root_discovery_test_discriminator_cwd_ascent: String = "refuses_path_outside_git_checkout"

data cli_run_source_root_anchor_scaffold: Disposition = Scaffold {
dissolves_to: SingleAuthority,
bind: DeclarationRef {
module_path: "v1_compiler.cli_run",
decl_name: "try_anchor_source_root",
field: WholeDeclaration
}
}

data cli_run_source_root_anchor_dissolve_trigger: String = "🟡 dissolve-on: try_anchor_source_root — declared layer/pool-root anchoring in HAND-Rust: layer roots are DECLARED by the v2.lens.medium_structure_containment roster while dag/compiler is modeled-before-implemented (§6 model-first), so root absence is a legitimate state the walk skips LOUDLY (counted stderr line per root), never a mid-floor panic; CLI-provided roots keep the panicking anchor_source_root contract. DISSOLVES WHEN cli_run.rs Chunk F lands (docs/plans/cli-run-reconcile-defork.md → the roots walk is GENERATED and absence becomes a typed, located, counted diagnostic at the roster layer) OR ROADMAP 5-dissolve-patches cli_run.rs shrink retires HAND path handling entirely"

data cli_run_source_root_anchor_receipt_plan_anchor: String = "docs/plans/cli-run-reconcile-defork.md#interim-workspace-root-scaffold"

data cli_run_source_root_anchor_loc_delta_net: Int = 43

data cli_run_source_root_anchor_test_discriminator_present_root: String = "try_anchor_source_root_resolves_declared_present_root"

data cli_run_source_root_anchor_test_discriminator_absent_root: String = "try_anchor_source_root_skips_declared_absent_root"
4 changes: 2 additions & 2 deletions dag/test/claim/ci_deploy_witness_test.dag
Original file line number Diff line number Diff line change
Expand Up @@ -111,8 +111,8 @@ fn witness_deploy_run_script_invokes_gunbc_wet() -> Bool {
let script = gunbc_ci_deploy_run_script(stage: gunbc_ci_deploy_srv1_stage)
string_contains(s: script, pattern: live_deploy_apply_entry)
&& string_contains(s: script, pattern: live_deploy_apply_srv1_wet_function)
&& string_contains(s: script, pattern: "$ROOT/target/release/gunbc")
&& string_contains(s: script, pattern: "--source-root dag")
&& string_contains(s: script, pattern: "\"$ROOT/target/release/gunbc\" run")
&& string_contains(s: script, pattern: "--source-root \"$ROOT/dag\"")
}

fn witness_workflow_deploy_job_matches_enrollment() -> Bool {
Expand Down
50 changes: 50 additions & 0 deletions dag/test/claim/cli_run_workspace_root_hand_rust_witness_test.dag
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@ import gunbc.cli_run_workspace_root_scaffold {
cli_run_workspace_root_discovery_loc_delta_net,
cli_run_workspace_root_discovery_test_discriminator_git_toplevel,
cli_run_workspace_root_discovery_test_discriminator_cwd_ascent,
cli_run_source_root_anchor_scaffold,
cli_run_source_root_anchor_dissolve_trigger,
cli_run_source_root_anchor_receipt_plan_anchor,
cli_run_source_root_anchor_loc_delta_net,
cli_run_source_root_anchor_test_discriminator_present_root,
cli_run_source_root_anchor_test_discriminator_absent_root,
}
import std.disposition { Scaffold, SingleAuthority }

Expand Down Expand Up @@ -49,3 +55,47 @@ test fn workspace_root_hand_rust_discriminating_tests_named() -> Bool {
pattern: "outside_git"
)
}

test fn source_root_anchor_hand_rust_scaffold_is_seed_retained() -> Bool {
match cli_run_source_root_anchor_scaffold {
Scaffold { dissolves_to: SingleAuthority, bind: _ } => true
_ => false
}
}

test fn source_root_anchor_dissolve_trigger_names_site_and_lane() -> Bool {
string_contains(
s: cli_run_source_root_anchor_dissolve_trigger,
pattern: "try_anchor_source_root"
) &&
string_contains(
s: cli_run_source_root_anchor_dissolve_trigger,
pattern: "medium_structure_containment"
) &&
string_contains(
s: cli_run_source_root_anchor_dissolve_trigger,
pattern: "cli-run-reconcile-defork"
) &&
string_contains(
s: cli_run_source_root_anchor_dissolve_trigger,
pattern: "5-dissolve-patches"
)
}

test fn source_root_anchor_receipt_plan_anchor_is_checkable() -> Bool {
string_contains(
s: cli_run_source_root_anchor_receipt_plan_anchor,
pattern: "cli-run-reconcile-defork.md#interim-workspace-root-scaffold"
) && cli_run_source_root_anchor_loc_delta_net > 0
}

test fn source_root_anchor_discriminating_tests_named() -> Bool {
string_contains(
s: cli_run_source_root_anchor_test_discriminator_present_root,
pattern: "resolves_declared_present"
) &&
string_contains(
s: cli_run_source_root_anchor_test_discriminator_absent_root,
pattern: "skips_declared_absent"
)
}
80 changes: 73 additions & 7 deletions src/v1/stage0/src/cli_run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -329,9 +329,55 @@ fn repo_relative_path_normalized(path: &Path) -> String {
})
}

// SCAFFOLD (§7 seed-retained HAND-RUST — authority: gunbc.cli_run_workspace_root_scaffold
// (cli_run_source_root_anchor_scaffold row);
// receipt: docs/plans/cli-run-reconcile-defork.md#interim-workspace-root-scaffold;
// witness: dag/test/claim/cli_run_workspace_root_hand_rust_witness_test.dag).
// 🟡 dissolve-on: try_anchor_source_root — declared layer/pool roots come from the
// v2.lens.medium_structure_containment roster while `dag/compiler` is modeled-before-implemented,
// so absence is a legitimate state skipped LOUDLY (counted line per root); DISSOLVES WHEN
// cli_run.rs Chunk F lands (roots walk GENERATED; absence becomes a typed, located, counted
// diagnostic at the roster layer) OR ROADMAP 5-dissolve-patches retires HAND path handling.
// Discriminating receipts: try_anchor_source_root_resolves_declared_present_root /
// try_anchor_source_root_skips_declared_absent_root.
/// Resolve a source/pool-root spelling to an absolute directory under
/// [`process_workspace_root`]. Absolute paths baked from the compile-time
/// [`workspace_root`] (sccache cross-runner) are re-anchored when missing on disk.
/// Non-panicking sibling of [`anchor_source_root`] for DECLARED layer/pool roots whose absence is
/// a legitimate state (a modeled-before-implemented location, e.g. `dag/compiler` in the
/// medium-structure roster): `None` when the root does not exist under any anchoring, so the
/// caller can skip it LOUDLY (counted line) instead of panicking mid-floor. CLI-provided roots
/// keep the strict panicking contract - a typo'd argument must refuse, never skip.
fn try_anchor_source_root(root: &str) -> Option<String> {
let p = Path::new(root);
let ws = process_workspace_root();
if p.is_absolute() {
if p.is_dir() {
return Some(root.to_string());
}
let baked = workspace_root();
if let Ok(rel) = p.strip_prefix(&baked) {
let reanchored = ws.join(rel);
if reanchored.is_dir() {
return Some(reanchored.to_string_lossy().into_owned());
}
}
if let Ok(rel) = repo_relative_path(p) {
let reanchored = ws.join(&rel);
if reanchored.is_dir() {
return Some(reanchored.to_string_lossy().into_owned());
}
}
return None;
}
let anchored = ws.join(p);
if anchored.is_dir() {
Some(anchored.to_string_lossy().into_owned())
} else {
None
}
}

fn anchor_source_root(root: &str) -> String {
let p = Path::new(root);
let ws = process_workspace_root();
Expand Down Expand Up @@ -528,7 +574,8 @@ mod cli_path_arg_resolution_tests {
mod process_workspace_root_tests {
use super::{
anchor_source_root, process_workspace_root, repo_relative_path,
repo_relative_path_normalized, workspace_relative_repo_path, workspace_root,
repo_relative_path_normalized, try_anchor_source_root, workspace_relative_repo_path,
workspace_root,
};
use std::path::Path;

Expand Down Expand Up @@ -559,6 +606,22 @@ mod process_workspace_root_tests {
.is_file());
}

#[test]
fn try_anchor_source_root_resolves_declared_present_root() {
let anchored = try_anchor_source_root("dag").expect("dag exists in every checkout");
assert!(Path::new(&anchored)
.join("gunbc/ci_layer_roots.dag")
.is_file());
}

#[test]
fn try_anchor_source_root_skips_declared_absent_root() {
assert_eq!(
try_anchor_source_root("dag/declared-but-not-yet-implemented-root"),
None
);
}

#[test]
fn runtime_workspace_root_scaffold_marker_is_declared() {
assert_eq!(
Expand Down Expand Up @@ -7450,9 +7513,7 @@ fn run_discovery_rows(
for row in rows {
// Applied only: PredictOnly must resolve + run cold and record via the post-resolve
// would_skip path (falsifier semantics — docs/plans/affected-set-differential-falsifier.md).
if selection == NodeFrontierSelectionMode::Applied
&& entry_fast_skip.contains(&row.entry)
{
if selection == NodeFrontierSelectionMode::Applied && entry_fast_skip.contains(&row.entry) {
if current_entry.as_deref() != Some(row.entry.as_str()) {
augment_closure_modules_from_import_facts(
&row.entry,
Expand Down Expand Up @@ -9061,8 +9122,8 @@ mod node_frontier_plumbing_controls {
.map(|i| (i + 1) as i64)
.expect("floor_disc_node_a line");
let diff = diff_at(&fixture_abs, data_line);
let diff_edits =
floor_diff_edits_from_diff_text(&index, &diff).expect("seeds from referenced-node diff");
let diff_edits = floor_diff_edits_from_diff_text(&index, &diff)
.expect("seeds from referenced-node diff");
assert!(
!diff_edits.overlapping_data_items.is_empty(),
"data-item diff must populate overlapping_data_items"
Expand Down Expand Up @@ -10484,7 +10545,12 @@ fn pool_roots_abs(pool_roots: &[String]) -> Vec<String> {
}

fn project_layer_import_root(root: &str, layer: &'static str, out: &mut Vec<LayerImportFactRaw>) {
let abs_root = anchor_source_root(root);
let Some(abs_root) = try_anchor_source_root(root) else {
eprintln!(
"[layer-import] declared root {root} absent on disk (layer={layer}) — skipped, no facts projected"
);
return;
};
let root_path = Path::new(&abs_root);
if !root_path.is_dir() {
return;
Expand Down
5 changes: 4 additions & 1 deletion src/v2/compiler/body_lowering_fold.dag
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import v2.std.diagnostic {
Diagnostics,
ExternalContractUnknown,
Outcome,
Some,
Unavailable,
diagnostics_singleton,
node_locus,
Expand Down Expand Up @@ -97,7 +98,9 @@ fn body_lower_type_atom_node(sym: Symbol) -> Node {
fn body_lower_wrapper_retained_shell(shell: Node) -> Outcome<Node> {
Accepted {
value: shell,
diagnostics: diagnostics_singleton(d: body_lower_wrapper_retained_diagnostic(n: shell))
diagnostics: Some {
diagnostics: diagnostics_singleton(d: body_lower_wrapper_retained_diagnostic(n: shell))
}
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/v2/test/claim/affected_set_universe_test.dag
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import v2.lens.affected_set {
repo_process_universe,
repo_process_universe_from
}
import gunbc.ci_spec { Gate, gunbc_ci_gates }
import gunbc.ci_spec { Gate, gunbc_ci_gates, gunbc_ci_regen_floor_gates, gunbc_ci_emit_determinism_floor_gates }

fn symbol_eq(a: Symbol, b: Symbol) -> Bool {
a == b
Expand All @@ -35,7 +35,7 @@ fn identity_in(ps: List<RepoProcess>, sym: Symbol) -> Bool {
test fn affected_set_universe_gate_processes_match_declared_gates() -> Bool {
bag_eq(
xs: process_identities(ps: ci_gate_processes()),
ys: gate_discriminants(gates: gunbc_ci_gates),
ys: gate_discriminants(gates: concat(concat(gunbc_ci_gates, gunbc_ci_regen_floor_gates), gunbc_ci_emit_determinism_floor_gates)),
eq: symbol_eq
)
}
Expand Down
22 changes: 22 additions & 0 deletions src/v2/test/claim/body_lowering_wrapper_retained_test.dag
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
module v2.test.claim.body_lowering_wrapper_retained

import v2.compiler.body_lowering_fold { body_lower_wrapper_retained_shell }
import v2.std.diagnostic { Accepted, Rejected, Some }
import v2.std.logic { Bool }
import v2.std.node { Conj, TypeNode, node_synthetic }

data wrapper_retained_diagnostics_shape_note: String = "Discriminating witness for the 2026-07-11 s1_closure floor panic: body_lower_wrapper_retained_shell constructed Accepted whose diagnostics field held a RAW NonEmptyDiagnostics where the Diagnostics coproduct (None | Some) is declared - the first downstream match over Diagnostics (diagnostics_merge in the normalize child fold) then panicked non-exhaustive on every file with a wrapper-retained fn body. This witness pins the SHAPE: the wrapper-retained outcome's diagnostics must inhabit the Some arm of Diagnostics and carry the typed wrapper-retained reason. Pre-fix it returns false (the Some pattern cannot match a raw record); post-fix true. Reproduced red/green by execution on dag/std/error_primitives.dag via s1_file_parses."

fn witness_wrapper_retained_diagnostics_inhabit_coproduct() -> Bool {
let shell = node_synthetic(kind: TypeNode { connective: Conj }, children: [])
match body_lower_wrapper_retained_shell(shell: shell) {
Accepted { value: _, diagnostics: Some { diagnostics: ne } } =>
ne.head.reason == ^body_lowering_reason_wrapper_retained_emitted
Accepted { value: _, diagnostics: _ } => false
Rejected { diagnostics: _ } => false
}
}

test fn body_lowering_wrapper_retained_diagnostics_holds() -> Bool {
witness_wrapper_retained_diagnostics_inhabit_coproduct()
}
2 changes: 1 addition & 1 deletion src/v2/test/claim/ci_spec_witness_test.dag
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@ fn witness_floor_disposition_marker_initialized_before_docs_only_branch() -> Boo
string_contains(s: script, pattern: ci_floor_disposition_marker_init_note) &&
string_contains(
s: script,
pattern: concat(concat(stamp, "\n"), "_ci_changed=$(git diff")
pattern: concat(concat(stamp, "\n\n"), "_ci_changed=$(git diff")
)
}

Expand Down
Loading