Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
00b40e9
WIP: HAND lens E: interpreter reads v2/lens/*.dag tables → retire 13 …
Jul 1, 2026
a69e6e7
WIP: HAND lens E: interpreter reads v2/lens/*.dag tables → retire 13 …
Jul 1, 2026
51dd7de
WIP: HAND lens E: interpreter reads v2/lens/*.dag tables → retire 13 …
Jun 30, 2026
4a603f3
WIP: HAND lens E: interpreter reads v2/lens/*.dag tables → retire 13 …
Jun 30, 2026
c905cf1
ci: re-trigger after fleet OOM flake on 9c14c21
Jun 30, 2026
19b1798
fix: GATE 1 loyal-bee — facts readback perturb witness + #5364 scaffo…
Jun 30, 2026
945d178
fix: dedupe Bool import in scaffold watchdog module
Jun 30, 2026
0044dc2
WIP: HAND lens E: interpreter reads v2/lens/*.dag tables → retire 13 …
Jun 30, 2026
72e24ed
fix: single-authority #5364 trigger + floor-level zero-budget witness
Jul 1, 2026
fb0aa66
chore: drop unused scaffold-index import from transport_script lens
Jul 1, 2026
98fa4a9
Merge remote-tracking branch 'origin/main' into session/still-crab-325
Jul 1, 2026
1d2d2a3
Merge origin/main into session/still-crab-325
Jul 1, 2026
7e9dddd
Merge remote-tracking branch 'origin/main' into session/still-crab-325
Jul 1, 2026
1862275
WIP: HAND lens E: interpreter reads v2/lens/*.dag tables → retire 13 …
Jul 1, 2026
13b7ce4
Merge origin/main into session/still-crab-325 to unblock PR #6028.
Jul 1, 2026
3e1f322
Merge remote-tracking branch 'origin/main' into session/still-crab-325
Jul 1, 2026
0f81ed9
WIP: HAND lens E: interpreter reads v2/lens/*.dag tables → retire 13 …
Jul 1, 2026
8b3ec24
Merge remote-tracking branch 'origin/main' into session/still-crab-325
Jul 1, 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
5 changes: 5 additions & 0 deletions dsl/gunbc/hand_lens_host_bridge_scaffold_index.dag
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module gunbc.hand_lens_host_bridge_scaffold_index

import std.types { String }

data transport_script_position_host_bridge_dissolution_trigger: String = "dissolve-on: gunbc#5364 — host-fed transport_script_position_facts_for_path (cli_run.rs TransportScriptArgShape classify_*) folds into pure Node-tree reader; verdict authority is v2.lens.host_language_transport_script.dag"
38 changes: 38 additions & 0 deletions dsl/gunbc/hand_lens_host_bridge_scaffold_watchdog.dag
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
module gunbc.hand_lens_host_bridge_scaffold_watchdog

import gunbc.hand_lens_host_bridge_scaffold_index {
transport_script_position_host_bridge_dissolution_trigger,
}
import std.types { List, String, Bool }

type HostBridgeScaffoldRow {
lens_module: String
host_seam: String
dissolution_trigger: String
}

data transport_script_position_scaffold_row: HostBridgeScaffoldRow = HostBridgeScaffoldRow {
lens_module: "v2.lens.host_language_transport_script"
host_seam: "cli_run.rs::transport_script_position_facts_for_path"
dissolution_trigger: transport_script_position_host_bridge_dissolution_trigger
}

data hand_lens_host_bridge_scaffold_roster: List<HostBridgeScaffoldRow> = [
transport_script_position_scaffold_row
]

fn scaffold_dissolution_trigger_nonempty(row: HostBridgeScaffoldRow) -> Bool {
row.dissolution_trigger != ""
}

fn scaffold_dissolution_trigger_matches_authority(row: HostBridgeScaffoldRow) -> Bool {
row.dissolution_trigger == transport_script_position_host_bridge_dissolution_trigger
}

fn hand_lens_host_bridge_scaffold_roster_tracked() -> Bool {
all(
hand_lens_host_bridge_scaffold_roster,
row => scaffold_dissolution_trigger_nonempty(row: row)
&& scaffold_dissolution_trigger_matches_authority(row: row)
)
}
15 changes: 15 additions & 0 deletions dsl/test/claim/hand_lens_host_bridge_scaffold_watchdog_test.dag
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
module test.claim.hand_lens_host_bridge_scaffold_watchdog

import gunbc.hand_lens_host_bridge_scaffold_watchdog {
hand_lens_host_bridge_scaffold_roster_tracked,
transport_script_position_scaffold_row,
scaffold_dissolution_trigger_matches_authority,
scaffold_dissolution_trigger_nonempty,
}
import std.types { Bool }

test fn hand_lens_host_bridge_scaffold_roster_tracks_5364_dissolution() -> Bool {
hand_lens_host_bridge_scaffold_roster_tracked()
&& scaffold_dissolution_trigger_nonempty(row: transport_script_position_scaffold_row)
&& scaffold_dissolution_trigger_matches_authority(row: transport_script_position_scaffold_row)
}
2 changes: 1 addition & 1 deletion src/v1/04_method.dag
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ fn builtin_function_registry() -> Map<String, Node> {
let m = map_insert(m, "complexity_linearity_syntactic_wildcard_finding_count", int_type)
let m = map_insert(m, "complexity_linearity_syntactic_site_fired", bool_type)
let m = map_insert(m, "census_corpus_roots_follow_layer_authority", bool_type)
let m = map_insert(m, "transport_script_literal_violation_count_for_path", int_type)
let m = map_insert(m, "transport_script_position_facts_for_path", list_of_type_variable(id: "transport_script_position_fact_elem"))
let m = map_insert(m, "layer_import_facts", list_of_type_variable(id: "layer_import_fact_elem"))
let m = map_insert(m, "import_resolution_facts", list_of_type_variable(id: "import_resolution_fact_elem"))
let m = map_insert(m, "module_declaration_facts", list_of_type_variable(id: "module_declaration_fact_elem"))
Expand Down
269 changes: 265 additions & 4 deletions src/v1/stage0/src/cli_run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,14 @@ use crate::v1_compiler_tokenize;
use crate::v1_interpreter;
use crate::v1_rt;
use crate::v1_std_core::{
authored_name_at, build_newline_index, byte_to_line_col, diagnostic_to_message,
diagnostic_to_span, empty_intern_table, expr_var_name_at, field_init_node_name_at,
arg_name_at, arg_value, authored_name_at, block_stmts, build_newline_index, byte_to_line_col,
diagnostic_to_message, diagnostic_to_span, empty_intern_table, expr_method_name_at,
expr_var_name_at, field_access_base, field_access_field_at, field_init_node_name_at,
field_init_node_value, has_child_named, intern,
is_discovery_corpus_advisory_typecheck_diagnostic, is_discovery_corpus_blocking_diagnostic,
is_error_diagnostic, is_interpreter_blocking_diagnostic, CompilerDiagnostic, ErrorNode,
ExprData, InferredNode, InternTable, NewlineIndex, Node,
is_error_diagnostic, is_interpreter_blocking_diagnostic, let_binding_name_at, let_value,
method_arg_nodes, method_receiver, CompilerDiagnostic, ErrorNode, ExprData, InferredNode,
InternTable, NewlineIndex, Node,
};
use serde::Serialize;

Expand Down Expand Up @@ -7552,6 +7554,265 @@ pub fn doc_graph_doc_count() -> i64 {
doc_graph_report().doc_count as i64
}

// Host-fed fact extraction for `v2.lens.host_language_transport_script` — the lens `.dag` table
// owns verdict logic; this bridge only projects `shell.Exec.Run` script-arg shapes from parsed
// modules. DISSOLUTION: node-tree reader at gunbc#5364; until then one shared host seam (Chunk D).
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
enum TransportScriptArgShape {
ComputedApplication = 0,
BareStringLiteral = 1,
LetBoundStringLiteral = 2,
StringInterpLiteralsOnly = 3,
}

impl TransportScriptArgShape {
fn as_symbol(self) -> &'static str {
match self {
Self::ComputedApplication => "ComputedApplication",
Self::BareStringLiteral => "BareStringLiteral",
Self::LetBoundStringLiteral => "LetBoundStringLiteral",
Self::StringInterpLiteralsOnly => "StringInterpLiteralsOnly",
}
}
}

pub struct TransportScriptPositionFactRaw {
pub path: String,
pub function: String,
pub shape: &'static str,
}

fn resolve_dag_path_for_transport_script(path: &str) -> PathBuf {
let candidate = Path::new(path);
if candidate.is_file() {
return candidate.to_path_buf();
}
let rooted = workspace_root().join(path);
if rooted.is_file() {
return rooted;
}
panic!("transport_script_position_facts: file not found: {path}");
}

fn parse_module_items_for_transport_script(
path: &str,
) -> (Rc<Vec<Rc<Node>>>, Rc<HashMap<String, Rc<NewlineIndex>>>) {
let resolved = resolve_dag_path_for_transport_script(path);
let path_str = resolved.to_string_lossy();
let content = std::fs::read_to_string(&resolved).unwrap_or_else(|e| {
panic!("transport_script_position_facts: failed to read {path_str}: {e}")
});
let filename = resolved
.file_name()
.and_then(|s| s.to_str())
.unwrap_or(path);
let tokens = v1_compiler_tokenize::tokenize(content.clone(), filename.to_string());
let source_index = build_newline_index(filename.to_string(), content);
let mut source_indices = HashMap::new();
source_indices.insert(filename.to_string(), source_index);
let source_indices = Rc::new(source_indices);
let result = v1_compiler_parse::parse(tokens, source_indices.clone());
if let Some(err) = result.error.as_ref() {
panic!(
"transport_script_position_facts: parse error in {path}: {}",
diagnostic_to_message(err.diagnostic.clone())
);
}
let module = result
.module
.as_ref()
.expect("transport_script_position_facts: missing module");
(module.children.clone(), source_indices)
}

fn literal_string_value_transport_script(node: &Rc<Node>) -> bool {
matches!(
node.expr_data.as_ref(),
ExprData::ExprLiteral {
value: lit,
..
} if matches!(lit.as_ref(), LiteralValue::LitStr { .. })
)
}

fn classify_transport_script_arg(
node: &Rc<Node>,
let_literal_bindings: &HashMap<String, bool>,
source_indices: &Rc<HashMap<String, Rc<NewlineIndex>>>,
) -> TransportScriptArgShape {
if literal_string_value_transport_script(node) {
return TransportScriptArgShape::BareStringLiteral;
}
match node.expr_data.as_ref() {
ExprData::ExprStringInterp => {
for child in node.children.iter() {
match child.expr_data.as_ref() {
ExprData::ExprLiteral { value, .. } => {
if !matches!(value.as_ref(), LiteralValue::LitStr { .. }) {
return TransportScriptArgShape::ComputedApplication;
}
}
ExprData::ExprVar { .. } => {
let name = expr_var_name_at(child.clone(), source_indices.clone());
if !let_literal_bindings.get(&name).copied().unwrap_or(false) {
return TransportScriptArgShape::ComputedApplication;
}
}
_ => return TransportScriptArgShape::ComputedApplication,
}
}
TransportScriptArgShape::StringInterpLiteralsOnly
}
ExprData::ExprVar { .. } => {
let name = expr_var_name_at(node.clone(), source_indices.clone());
if let_literal_bindings.get(&name).copied().unwrap_or(false) {
TransportScriptArgShape::LetBoundStringLiteral
} else {
TransportScriptArgShape::ComputedApplication
}
}
_ => TransportScriptArgShape::ComputedApplication,
}
}

fn is_shell_exec_run_transport_script(
node: &Rc<Node>,
source_indices: &Rc<HashMap<String, Rc<NewlineIndex>>>,
) -> bool {
match node.expr_data.as_ref() {
ExprData::ExprMethodCall { .. } => {
if expr_method_name_at(node.clone(), source_indices.clone()) != "Run" {
return false;
}
let recv = method_receiver(node.clone());
match recv.expr_data.as_ref() {
ExprData::ExprFieldAccess { .. } => {
if field_access_field_at(recv.clone(), source_indices.clone()) != "Exec" {
return false;
}
let base = field_access_base(recv.clone());
match base.expr_data.as_ref() {
ExprData::ExprVar { .. } => {
expr_var_name_at(base.clone(), source_indices.clone()) == "shell"
}
_ => false,
}
}
_ => false,
}
}
_ => false,
}
}

fn transport_script_arg_node(
node: &Rc<Node>,
source_indices: &Rc<HashMap<String, Rc<NewlineIndex>>>,
) -> Option<Rc<Node>> {
for arg in method_arg_nodes(node.clone()).iter() {
if arg_name_at(arg.clone(), source_indices.clone()).as_deref() == Some("script") {
return Some(arg_value(arg.clone()));
}
}
None
}

fn binding_is_literal_shaped_transport_script(
node: &Rc<Node>,
bindings: &HashMap<String, bool>,
source_indices: &Rc<HashMap<String, Rc<NewlineIndex>>>,
) -> bool {
matches!(
classify_transport_script_arg(node, bindings, source_indices),
TransportScriptArgShape::BareStringLiteral
| TransportScriptArgShape::LetBoundStringLiteral
| TransportScriptArgShape::StringInterpLiteralsOnly
)
}

fn collect_let_bindings_in_block_transport_script(
block: &Rc<Node>,
bindings: &mut HashMap<String, bool>,
source_indices: &Rc<HashMap<String, Rc<NewlineIndex>>>,
) {
for stmt in block_stmts(block.clone()).iter() {
match stmt.expr_data.as_ref() {
ExprData::ExprLet { .. } => {
let name = let_binding_name_at(stmt.clone(), source_indices.clone());
let val = let_value(stmt.clone());
let literal_shaped =
binding_is_literal_shaped_transport_script(&val, bindings, source_indices);
bindings.insert(name, literal_shaped);
}
_ => walk_transport_script_expr(stmt, bindings, source_indices, &mut |_| {}),
}
}
}

fn walk_transport_script_expr(
node: &Rc<Node>,
let_bindings: &HashMap<String, bool>,
source_indices: &Rc<HashMap<String, Rc<NewlineIndex>>>,
on_run: &mut dyn FnMut(TransportScriptArgShape),
) {
if is_shell_exec_run_transport_script(node, source_indices) {
if let Some(script_node) = transport_script_arg_node(node, source_indices) {
on_run(classify_transport_script_arg(
&script_node,
let_bindings,
source_indices,
));
}
}
for child in node.children.iter() {
walk_transport_script_expr(child, let_bindings, source_indices, on_run);
}
}

fn transport_script_facts_for_function_body(
rel_path: &str,
function: &str,
body: &Rc<Node>,
source_indices: &Rc<HashMap<String, Rc<NewlineIndex>>>,
) -> Vec<TransportScriptPositionFactRaw> {
let mut bindings = HashMap::new();
if let ExprData::ExprBlock { .. } = body.expr_data.as_ref() {
collect_let_bindings_in_block_transport_script(body, &mut bindings, source_indices);
}
let mut facts = Vec::new();
walk_transport_script_expr(body, &bindings, source_indices, &mut |shape| {
facts.push(TransportScriptPositionFactRaw {
path: rel_path.to_string(),
function: function.to_string(),
shape: shape.as_symbol(),
});
});
facts
}

pub fn transport_script_position_facts_for_path(
path: String,
) -> Vec<TransportScriptPositionFactRaw> {
let (items, source_indices) = parse_module_items_for_transport_script(&path);
let mut facts = Vec::new();
for item in items.iter() {
let kind = item_kind(item.clone());
if !matches!(kind, ItemKind::FuncItem | ItemKind::FnItem) {
continue;
}
let Some(body) = item.body.as_ref() else {
continue;
};
facts.extend(transport_script_facts_for_function_body(
&path,
&item.name,
body,
&source_indices,
));
}
facts
}

#[cfg(test)]
mod module_path_index_tests {
use super::*;
Expand Down
2 changes: 0 additions & 2 deletions src/v1/stage0/src/module_path_index/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
pub mod fact_cardinality_census;
pub mod medium_structure_census;
pub mod non_fold_residue_census;
pub mod transport_script_position_census;

pub use fact_cardinality_census::{
cross_tree_coexistence_count, cross_tree_diverged_fork_count, cross_tree_is_coexistence,
Expand All @@ -12,4 +11,3 @@ pub use non_fold_residue_census::{
non_fold_residue_coproduct_universe_count, non_fold_residue_count,
non_fold_residue_stale_roster_count, non_fold_residue_unrostered_count,
};
pub use transport_script_position_census::transport_script_literal_violation_count_for_path;
Loading