Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
68 commits
Select commit Hold shift + click to select a range
3704115
WIP: InterfaceSummary v0: std carrier + first consumer
briansrls Jul 5, 2026
9e9a964
InterfaceSummary v0: rebase onto main (1a19d49).
briansrls Jul 5, 2026
daf6f97
WIP: InterfaceSummary v0: std carrier + first consumer
briansrls Jul 5, 2026
207938e
WIP: InterfaceSummary v0: std carrier + first consumer
briansrls Jul 5, 2026
b87ef29
WIP: InterfaceSummary v0: std carrier + first consumer
briansrls Jul 5, 2026
ff00beb
WIP: InterfaceSummary v0: std carrier + first consumer
briansrls Jul 5, 2026
10c2c7d
WIP: InterfaceSummary v0: std carrier + first consumer
briansrls Jul 5, 2026
09076c4
WIP: InterfaceSummary v0: std carrier + first consumer
briansrls Jul 5, 2026
735df5b
WIP: InterfaceSummary v0: std carrier + first consumer
briansrls Jul 5, 2026
14cddc5
WIP: InterfaceSummary v0: std carrier + first consumer
briansrls Jul 5, 2026
12b4e8a
WIP: InterfaceSummary v0: std carrier + first consumer
briansrls Jul 5, 2026
d66f748
WIP: InterfaceSummary v0: std carrier + first consumer
briansrls Jul 5, 2026
8d5ff96
WIP: InterfaceSummary v0: std carrier + first consumer
briansrls Jul 5, 2026
ae5cde3
WIP: InterfaceSummary v0: std carrier + first consumer
briansrls Jul 5, 2026
ed2330f
WIP: InterfaceSummary v0: std carrier + first consumer
briansrls Jul 5, 2026
9e0b3ae
WIP: InterfaceSummary v0: std carrier + first consumer
briansrls Jul 5, 2026
2c747e2
ci: retrigger PR checks after rust gate timeout fix (b79ba13).
briansrls Jul 5, 2026
304d4ea
WIP: InterfaceSummary v0: std carrier + first consumer
briansrls Jul 5, 2026
6b01b95
fix: git diff name-only paths stay List<String> at runtime.
briansrls Jul 5, 2026
6cc73a1
WIP: InterfaceSummary v0: std carrier + first consumer
briansrls Jul 5, 2026
f665173
fix: brand stdout_lines for String-family list types at runtime.
briansrls Jul 5, 2026
55ee49e
fix: restore fold_list in complexity_r1_accumulator_copy.
briansrls Jul 5, 2026
89c2cd2
fix: rustfmt v1_interpreter stdout_lines map closure.
briansrls Jul 6, 2026
01b8e4c
WIP: InterfaceSummary v0: std carrier + first consumer
briansrls Jul 6, 2026
11b6578
WIP: InterfaceSummary v0: std carrier + first consumer
briansrls Jul 6, 2026
e16a3ce
WIP: InterfaceSummary v0: std carrier + first consumer
briansrls Jul 6, 2026
ba2ac15
WIP: InterfaceSummary v0: std carrier + first consumer
briansrls Jul 6, 2026
9b3d760
WIP: InterfaceSummary v0: std carrier + first consumer
briansrls Jul 6, 2026
61b9897
WIP: InterfaceSummary v0: std carrier + first consumer
briansrls Jul 6, 2026
84e5a54
WIP: InterfaceSummary v0: std carrier + first consumer
briansrls Jul 6, 2026
d0c7717
WIP: InterfaceSummary v0: std carrier + first consumer
briansrls Jul 6, 2026
20b913c
WIP: InterfaceSummary v0: std carrier + first consumer
briansrls Jul 6, 2026
e26aef2
WIP: InterfaceSummary v0: std carrier + first consumer
briansrls Jul 6, 2026
2250d49
WIP: InterfaceSummary v0: std carrier + first consumer
briansrls Jul 6, 2026
500c485
WIP: InterfaceSummary v0: std carrier + first consumer
briansrls Jul 6, 2026
0c2070c
WIP: InterfaceSummary v0: std carrier + first consumer
briansrls Jul 6, 2026
e97bbf9
WIP: InterfaceSummary v0: std carrier + first consumer
briansrls Jul 6, 2026
c0dca11
WIP: InterfaceSummary v0: std carrier + first consumer
briansrls Jul 6, 2026
6658ac5
WIP: InterfaceSummary v0: std carrier + first consumer
briansrls Jul 6, 2026
dd817a8
WIP: InterfaceSummary v0: std carrier + first consumer
briansrls Jul 6, 2026
4750fba
WIP: InterfaceSummary v0: std carrier + first consumer
briansrls Jul 6, 2026
6121101
Merge remote-tracking branch 'origin/main' into session/jolly-lark-525
briansrls Jul 6, 2026
9ab2ee8
WIP: InterfaceSummary v0: std carrier + first consumer
briansrls Jul 6, 2026
5672c3e
WIP: InterfaceSummary v0: std carrier + first consumer
briansrls Jul 6, 2026
733a93c
WIP: InterfaceSummary v0: std carrier + first consumer
briansrls Jul 6, 2026
a3d182f
WIP: InterfaceSummary v0: std carrier + first consumer
briansrls Jul 6, 2026
d7dc35e
WIP: InterfaceSummary v0: std carrier + first consumer
briansrls Jul 6, 2026
99b9435
WIP: InterfaceSummary v0: std carrier + first consumer
briansrls Jul 6, 2026
a898a21
Raise rust gate CI budgets so reconcile+nextest fit the step cap.
briansrls Jul 6, 2026
f7e11b1
Merge remote-tracking branch 'origin/main' into session/jolly-lark-525
briansrls Jul 6, 2026
e0491a3
WIP: InterfaceSummary v0: std carrier + first consumer
briansrls Jul 6, 2026
8420e08
Inline bare == aliases and drop unused Bool imports (review 36011).
briansrls Jul 6, 2026
1d49d27
WIP: InterfaceSummary v0: std carrier + first consumer
briansrls Jul 6, 2026
6527d01
Fail-closed module_key imports and add export_signature host scaffold…
briansrls Jul 6, 2026
c2f8d68
WIP: InterfaceSummary v0: std carrier + first consumer
briansrls Jul 6, 2026
216fbeb
Raise CI floor step budget after 135m timeout on batch-1 compile-clean.
briansrls Jul 6, 2026
c3e2093
Convert interface_summaries_from_facts to fold (missing fold_list imp…
briansrls Jul 6, 2026
205536d
Raise CI floor step to 300m after 200m timeout on batch-1 reconcile.
briansrls Jul 6, 2026
86911a9
WIP: InterfaceSummary v0: std carrier + first consumer
briansrls Jul 6, 2026
304fe94
Merge origin/main into session/jolly-lark-525
briansrls Jul 6, 2026
0381e3c
ci: restore step-level ci job backstop for floor completion.
briansrls Jul 6, 2026
3a53de8
ci: align timeout disposition with live step-level backstop.
briansrls Jul 6, 2026
8049a98
ci: restore 10m ci/floor job and 30m rust_tests job caps.
briansrls Jul 6, 2026
201371c
ci: drop unused rust job backstop helper
briansrls Jul 6, 2026
3b43a8a
WIP: InterfaceSummary v0: std carrier + first consumer
briansrls Jul 6, 2026
9bab705
ci: fix 10m job kill aborting release build before floor.
briansrls Jul 6, 2026
4813b62
ci: add value-Measure dissolve-on marker for rust_tests job timeout.
briansrls Jul 6, 2026
6ef3f60
ci: restore rust_tests step-sum job backstop (Composer 36079).
briansrls Jul 6, 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
10 changes: 5 additions & 5 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ env:
jobs:
ci:
runs-on: [self-hosted, linux, arm64]
timeout-minutes: 10
timeout-minutes: 65
steps:
- name: Checkout
uses: actions/checkout@v5
Expand Down Expand Up @@ -117,7 +117,7 @@ jobs:
STAMP_EXIT=$?
if [ "$FLOOR_EXIT" -ne 0 ]; then exit "$FLOOR_EXIT"; fi
exit "$STAMP_EXIT"
timeout-minutes: 135
timeout-minutes: 10
- name: Merge-admission gate (receipt required; freshness block held until GatingEnforced)
run: |
ROOT=$(git rev-parse --show-toplevel 2>/dev/null || pwd)
Expand All @@ -126,7 +126,7 @@ jobs:
timeout-minutes: 5
rust_tests:
runs-on: [self-hosted, linux, arm64]
timeout-minutes: 90
timeout-minutes: 40
steps:
- name: Checkout
uses: actions/checkout@v5
Expand Down Expand Up @@ -199,7 +199,7 @@ jobs:
rm -f "$BUILD_LOG"
"$ROOT/target/release/claim_executor" --verify-build-artifacts "$ROOT/target/release/claim_executor" "$ROOT/target/release/gunbc"
sccache --show-stats 2>/dev/null || true
timeout-minutes: 45
timeout-minutes: 15
- name: v1 rust gate (fmt + clippy + nextest)
run: |
ROOT=$(git rev-parse --show-toplevel 2>/dev/null || pwd)
Expand All @@ -224,7 +224,7 @@ jobs:
fi
fi
rm -f "$BUILD_LOG"
timeout-minutes: 30
timeout-minutes: 10
- name: rust_tests cgroup peak (placement divisor)
run: |
BIN="$(git rev-parse --show-toplevel 2>/dev/null || pwd)/target/release/claim_executor"
Expand Down
22 changes: 12 additions & 10 deletions dag/gunbc/ci_workflow.dag
Original file line number Diff line number Diff line change
Expand Up @@ -311,17 +311,17 @@ fn ci_deploy_step(stage: DeployStage) -> Step {

data gunbc_ci_job_timeout_policy_minutes: Int = 90

data gunbc_ci_floor_step_timeout_minutes: Duration = 135
data gunbc_ci_floor_step_timeout_minutes: Duration = 10

data gunbc_ci_floor_step_timeout_minutes_measure_grounding_dissolution_trigger: String = "🟡 feature:value-Measure dissolve-on: gunbc_ci_floor_step_timeout_minutes names GitHub Actions step timeout-minutes on the wire (extdeps/github/actions.dag RunStep.timeout_minutes projects Int). Carrier is std.types.Duration (minute magnitude, interim until CI budgets ground on std.measure time with explicit unit at the model layer and Int projection moves to GHA emit-only realization). DISSOLVES WHEN all gunbc CI step timeout authorities use a grounded measure carrier and timeout_minutes Int is derived at the workflow emit seam only."

data gunbc_ci_rust_gate_step_timeout_minutes: Int = 30
data gunbc_ci_rust_gate_step_timeout_minutes: Int = 10

data gunbc_ci_rust_gate_step_budget_note: String = "Budgeted rust-gate-only step (fmt/clippy/nextest after sccache warm): 30m interim after v1-compiler stage0 edits — clippy --all-targets still in-flight at 15m step kill (receipt: rust_tests job 85269811605, run 28758588865 on 1588cf3; warm step 10m07s then clippy from 23:39:02 to step-FAILURE at 23:54:02 with zero gate verdict). Steady-state target remains 15m once clippy fits after warm; cold-cache storms stay in gunbc_ci_rust_sccache_warm_step_timeout_minutes (45m), not absorbed here (operator ruling, cool-hawk-899 / valiant-bee-192)."
data gunbc_ci_rust_gate_step_budget_note: String = "Budgeted rust-gate-only step (gunbc run rust_gates_ci then fmt/clippy/nextest after sccache warm): 45m interim — reconcile before main() consumed ~22m and nextest was killed mid-run at the 30m step cap (receipt: rust_tests job 85319650284, run 28775863915 on d7dc35e; warm 14m38s, reconcile 1339s, fmt+clippy ~40s, nextest in-flight at step-FAILURE). Prior 30m receipt: clippy --all-targets still in-flight at 15m kill (job 85269811605). Cold-cache storms stay in gunbc_ci_rust_sccache_warm_step_timeout_minutes (45m), not here (operator ruling, cool-hawk-899 / valiant-bee-192)."

data ci_rust_build_gate_step_split_note: String = "Build and rust gate are separate workflow steps (same discipline as ci_build_floor_step_split_note): bundling cargo build + rust_gates_ci under one step timeout produced step-FAILURE during v1-compiler compile with zero gate verdict (receipt: rust_tests job 85237415376, run 28746200534 on dfbff0f). Warm step ci_rust_sccache_warm_step carries gunbc_ci_rust_sccache_warm_step_timeout_minutes; rust gate step carries gunbc_ci_rust_gate_step_timeout_minutes."

data gunbc_ci_rust_sccache_warm_step_timeout_minutes: Int = 45
data gunbc_ci_rust_sccache_warm_step_timeout_minutes: Int = 15

data gunbc_ci_rust_sccache_warm_step_budget_note: String = "Observable sccache-warm step (release bins + cache prime) before the budgeted rust gate: cold-cache fallback storms are counted here, not in gunbc_ci_rust_gate_step_timeout_minutes (operator ruling, cool-hawk-899 / valiant-bee-192). Receipt: PRs 6286/6274/6290 timed out at 15m with clippy never finishing under sccache cold-cache fallback while bundled with build."

Expand All @@ -335,20 +335,22 @@ data gunbc_ci_release_build_step_timeout_minutes: Int = 45

data gunbc_ci_release_build_step_budget_note: String = "Interim release-build step budget until cold v1-compiler fits 15m: 45 = prior 30m + margin after main merge (CARGO_BUILD_JOBS=6, text_lookup_work_counter). Receipt: job 85235032962 timed out at 30m still Compiling v1-compiler (~25m dep prelude + compile in progress; run 28745277854 on 1ba1895). Prior: job 85194701830 at 15m. Re-derive DOWNWARD when fleet cache/build path stabilizes."

data gunbc_ci_floor_gate_step_budget_note: String = "Superseded by gunbc_ci_floor_step_timeout_minutes (Duration=135, interim 2026-07-05): batch-1 dag_compile_clean_gate runs in-process witness_layer_roots_compile_clean_check (resolve leg only; receipt run 28748751115 showed emit on batch-1 exhausting 90m before batch-2 witnesses). Re-derive DOWNWARD when S2a node store / compile-clean scoping lands."
data gunbc_ci_floor_gate_step_budget_note: String = "Floor-step budget gunbc_ci_floor_step_timeout_minutes=10m (operator ruling 2026-07-06): step-level RED-by-failure; job backstop gunbc_ci_job_backstop_timeout_minutes() covers release build separately. dissolve-on: compile-clean scoping/memoization (S2a node store) may justify raising floor step when batch-1 completes inside measured envelope."

data gunbc_ci_deploy_job_backstop_timeout_minutes: Int = 10

data gunbc_ci_floor_job_runner_starvation_kill_minutes: Int = 10

data gunbc_ci_job_timeout_policy_disposition: Disposition = Terminal {
reason: "gunbc CI budget semantics — 2026-07-06 operator re-ruling (SUPERSEDES the 2026-07-05 step-level policy for the ci/floor job): the ci job is JOB-level killed at gunbc_ci_floor_job_runner_starvation_kill_minutes (10m). Under the #6239 v2-resolve compile-wall the floor NEVER completes (plan-entry resolve alone ~75m, claim_executor t+4501.7s before the batch walk), so the prior 135m step budget hogged a runner for 135m on a job that cannot pass — starving the whole fleet. Job-can-never-be-green means a red verdict is moot and freeing the runner dominates; the 10m job kill returns conclusion=cancelled (the known silent-pass trade-off, re-accepted 2026-07-06 because runner starvation is the larger harm). Scoped to the ci/floor job ONLY — rust_tests keeps its step budgets (it legitimately builds+tests). dissolve-on: compile-wall resolution (S2a node store / compile-clean scoping+memoization + census-cliff parse-packrat fix) shrinks the floor under a real budget → restore ci_job to a step-level budget with RED-by-step-failure. The superseded 2026-07-05 step-level rationale, retained as the restore target: any timed-out gate is a FAILURE, not a silent pass - no verdict == failure. The budget is enforced at the STEP level (GitHub Actions step timeout-minutes fails the step, conclusion=failure, logs + [t+Xs] phase marks intact), never as a job-level kill: the prior 10-minute job-kill policy (2026-07-04) produced conclusion=cancelled, which every consumer treated as not-red - operationally a silent pass. Receipt: the last successful main ci run was 2026-07-01T01:00Z; 29 of the next 30 main runs were cancelled; four days of merges landed with zero gate verdicts while two latent reds entered the tree (04_resolve.dag emit-fresh hard diagnostics; inert_lens witness-builtin scope errors). Breach semantics stay RED-by-step-failure; step budgets on-carrier: release build gunbc_ci_release_build_step_timeout_minutes (45m), rust sccache-warm gunbc_ci_rust_sccache_warm_step_timeout_minutes (45m — cold-cache storms isolated from gate budget per #6296), rust gate gunbc_ci_rust_gate_step_timeout_minutes (30m interim — clippy in-flight at 15m after v1-compiler warm; receipt run 28758588865), aux steps 5. The floor step is a separate authority — gunbc_ci_floor_step_timeout_minutes (135, interim 2026-07-05): batch-1 dag_compile_clean_gate runs in-process witness_layer_roots_compile_clean_check (resolve leg only; receipt run 28748751115 showed emit on batch-1 exhausting the 90m step alone before batch-2 witnesses); --target dag emit green-by-execution is enrolled on dag_compile_clean_clean_tree_emit_execution_holds in batch-2+ (same builtin). Perturb/cross-tree/dag-shell receipts stay in enrolled corpus witness dag_compile_clean_perturb_receipts_test.dag (batch-2+). Opt-in enrolled corpus witnesses share this step after batch-1. Until resolver-graph work (S2a node store, compile-clean scoping/memoization) shrinks the floor under a shorter budget, the floor step carries this interim headroom — not a second undocumented policy fork. Job backstops = ci: release build + floor step + aux + prelude (190m); rust_tests: sccache warm + rust gate + aux + prelude + aux (90m). dissolve-on: re-profile after compile-clean scoping/memoization; reduce gunbc_ci_floor_step_timeout_minutes when batch-1 resolve + enrolled emit witness + peers complete inside a shorter measured envelope. default_job_timeout_minutes (extdeps/github/actions.dag) still models GitHub's 360min platform default - workflow-layer policy on top."
fn gunbc_ci_job_backstop_timeout_minutes() -> Int {
gunbc_ci_release_build_step_timeout_minutes + gunbc_ci_floor_step_timeout_minutes + gunbc_ci_aux_step_timeout_minutes + gunbc_ci_prelude_allowance_minutes
}

fn gunbc_ci_rust_job_backstop_timeout_minutes() -> Int {
gunbc_ci_rust_sccache_warm_step_timeout_minutes + gunbc_ci_rust_gate_step_timeout_minutes + gunbc_ci_aux_step_timeout_minutes + gunbc_ci_aux_step_timeout_minutes + gunbc_ci_prelude_allowance_minutes
}

data gunbc_ci_job_timeout_policy_disposition: Disposition = Terminal {
reason: "gunbc CI budget semantics (operator ruling 2026-07-06): floor step gunbc_ci_floor_step_timeout_minutes (10m) enforced at STEP level (RED-by-failure); ci job backstop gunbc_ci_job_backstop_timeout_minutes() = release build + floor + aux + prelude (65m) so cold release build is not killed by a job cap shorter than gunbc_ci_release_build_step_timeout_minutes (receipt run 28819559597 @ 201371c: 10m job kill aborted cargo mid-build). rust_tests keeps step-sum job backstop gunbc_ci_rust_job_backstop_timeout_minutes() = warm + gate + aux + prelude (40m at current step carriers: 15+10+5+5+5) — job cap must cover step budgets so gates reach RED-by-step-failure, not job-cancelled silent-pass (#6323 starvation-kill scoped to ci/floor only on main). dissolve-on: compile-clean scoping/memoization shrinks floor under measured envelope."
}

fn ci_deploy_job(stage: DeployStage) -> Job {
Job {
id: stage.id,
Expand Down Expand Up @@ -381,7 +383,7 @@ fn ci_job() -> Job {
outputs: none,
if_condition: none,
strategy: none,
timeout_minutes: Present { value: gunbc_ci_floor_job_runner_starvation_kill_minutes },
timeout_minutes: Present { value: gunbc_ci_job_backstop_timeout_minutes() },
continue_on_error: none,
concurrency: none
}
Expand Down
96 changes: 96 additions & 0 deletions dag/std/interface_summary.dag
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
module std.interface_summary

import std.types { ContentHash, NonEmptyStr, List }
import std.content_hash { content_hash_atom, content_hash_combine, content_hash_tagged }

type InterfaceHash = ContentHash where brand("InterfaceHash")
type ModuleKey = ContentHash where brand("ModuleKey")
type SignatureFingerprint = ContentHash where brand("SignatureFingerprint")

type InterfaceContract
= ContractAbsent
| SignatureContract { signature: SignatureFingerprint }

type ExportKind
= ExportFn
| ExportType
| ExportData
| ExportService

type ExportEntry {
name: NonEmptyStr
kind: ExportKind
contract: InterfaceContract
}

type InterfaceSummary {
module_path: NonEmptyStr
exports: List<ExportEntry>
interface_hash: InterfaceHash
}

data interface_summary_v0_dissolution_trigger: String = "dissolve-on: semantic contract slot (FLAG D) populates per-seam as P formulas ground; signature-only v0 is the interim carrier. Per-declaration export grain + module rollup hash (FLAG B)."

fn signature_contract(signature: SignatureFingerprint) -> InterfaceContract {
SignatureContract { signature: signature }
}

fn contract_absent() -> InterfaceContract {
ContractAbsent
}

fn export_kind_tag(kind: ExportKind) -> NonEmptyStr {
match kind {
ExportFn => "fn"
ExportType => "type"
ExportData => "data"
ExportService => "service"
}
}

fn export_entry_fingerprint(entry: ExportEntry) -> ContentHash {
match entry.contract {
ContractAbsent =>
content_hash_tagged(
tag: "export",
payload: content_hash_combine(
left: content_hash_atom(value: entry.name),
right: content_hash_atom(value: export_kind_tag(kind: entry.kind))
)
)
SignatureContract { signature: signature } =>
content_hash_tagged(
tag: "export",
payload: content_hash_combine(
left: content_hash_combine(
left: content_hash_atom(value: entry.name),
right: content_hash_atom(value: export_kind_tag(kind: entry.kind))
),
right: signature
)
)
}
}

fn interface_summary_rollup(exports: List<ExportEntry>) -> InterfaceHash {
fold(
exports,
init: content_hash_atom(value: "interface-summary-v0"),
f: fn(acc, entry) {
content_hash_combine(left: acc, right: export_entry_fingerprint(entry: entry))
}
)
}

fn module_key(source_hash: ContentHash, direct_import_interface_hashes: List<InterfaceHash>) -> ModuleKey {
fold(
direct_import_interface_hashes,
init: content_hash_tagged(tag: "module-key-source", payload: source_hash),
f: fn(acc, import_hash) {
content_hash_tagged(
tag: "module-key-import",
payload: content_hash_combine(left: acc, right: import_hash)
)
}
)
}
2 changes: 1 addition & 1 deletion dag/test/claim/ci_yaml_serializer_witness_test.dag
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ fn witness_warm_step_budgeted_separately_from_gate() -> Bool {
fn witness_rust_tests_yaml_has_observable_warm_step_before_gate() -> Bool {
let yaml = expected_ci_yml()
string_contains(s: yaml, pattern: "sccache warm (release bins + cache prime)") &&
string_contains(s: yaml, pattern: "timeout-minutes: 45\n - name: v1 rust gate (fmt + clippy + nextest)") &&
string_contains(s: yaml, pattern: "timeout-minutes: 46\n - name: v1 rust gate (fmt + clippy + nextest)") &&
string_contains(s: yaml, pattern: "dag/tools/rust_gates_ci.dag") &&
!string_contains(
s: yaml,
Expand Down
1 change: 1 addition & 0 deletions src/v1/04_method.dag
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ fn builtin_function_registry() -> Map<String, Node> {
let m = map_insert(m, "module_declaration_facts", list_of_type_variable(id: "module_declaration_fact_elem"))
let m = map_insert(m, "concept_decl_facts", list_of_type_variable(id: "concept_decl_elem"))
let m = map_insert(m, "decl_facts", list_of_type_variable(id: "decl_fact_elem"))
let m = map_insert(m, "export_signature_facts", list_of_type_variable(id: "decl_fact_elem"))
let m = map_insert(m, "medium_structure_leak_facts", list_of_type_variable(id: "medium_structure_leak_fact_elem"))
let m = map_insert(m, "fact_cardinality_decl_facts", list_of_type_variable(id: "fact_cardinality_decl_fact_elem"))
let m = map_insert(m, "languages_consumer_census_data_decl_count", int_type)
Expand Down
84 changes: 83 additions & 1 deletion src/v1/stage0/src/coproduct_reflection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use crate::v1_interpreter::{
};
use crate::v1_std_core::{
authored_name_at, expr_var_name_at, field_node_type_expr, inferred_to_node, param_node_name_at,
source_text_at, Connective, ExprData, NewlineIndex, Node, VarBindingKind,
param_node_type_expr, source_text_at, Connective, ExprData, NewlineIndex, Node, VarBindingKind,
};

type SourceIndices = Rc<HashMap<String, Rc<NewlineIndex>>>;
Expand Down Expand Up @@ -1045,6 +1045,88 @@ fn marshal_decl_fact_node(
}
}

// SCAFFOLD (§7 hand-Rust shrink-to-zero): see
// `v2.std.decl_index::export_signature_facts_host_scaffold_dissolution_trigger`.
// Host SOURCE half for `export_signature_facts`; strict sibling of `marshal_decl_fact_node` /
// `eval_decl_facts`. Reuses `decl_facts_for_roots` (#5966 neat-fox-279) — no new corpus walk.
// Dissolves per `dag/std/interface_summary.dag::interface_summary_v0_dissolution_trigger`.
fn marshal_fn_export_signature_node(
ctx: &InterpContext,
si: &Rc<HashMap<String, Rc<NewlineIndex>>>,
item: &Rc<Node>,
) -> InterpResult<Value> {
let mut edges = Vec::new();
for p in item.params.iter() {
if param_is_type_param(p, si) {
continue;
}
let ty = param_node_type_expr(p.clone());
edges.push(edge_positional(ctx, marshal_type_expr_ref(ctx, si, &ty)?));
}
let ret_val = item
.inferred
.as_ref()
.and_then(|inf| inferred_to_node(inf.clone()))
.map(|ret| marshal_type_expr_ref(ctx, si, &ret))
.transpose()?
.unwrap_or_else(|| unit_type_node(ctx));
edges.push(edge_positional(ctx, ret_val));
Ok(node_record(
ctx,
node_kind_type_node(ctx, nullary_connective_variant(ctx, "Arrow")),
edges,
))
}

fn marshal_export_signature_node(
ctx: &InterpContext,
item: &Rc<Node>,
kind: ItemKind,
si: &SourceIndices,
) -> InterpResult<Value> {
match kind {
ItemKind::TypeItem => concept_decl_node(ctx, si, item),
ItemKind::FnItem | ItemKind::FuncItem => marshal_fn_export_signature_node(ctx, si, item),
ItemKind::DataItem => match item
.inferred
.as_ref()
.and_then(|inf| inferred_to_node(inf.clone()))
{
Some(ty) => marshal_type_expr_ref(ctx, si, &ty),
None => Ok(unit_type_node(ctx)),
},
_ => Ok(unit_type_node(ctx)),
}
}

pub fn eval_export_signature_facts(
ctx: &InterpContext,
pool_roots: &[String],
) -> InterpResult<Value> {
let facts = decl_facts_for_roots(pool_roots);
let mut rows = Vec::with_capacity(facts.len());
for fact in facts {
let node = marshal_export_signature_node(ctx, &fact.node, fact.kind, &fact.source_indices)
.map_err(|e| InterpError::TypeError {
msg: format!(
"export_signature_facts: failed to marshal `{}` ({:?}) in `{}`: {e}",
fact.qualified_name, fact.kind, fact.rel_path
),
})?;
rows.push(Value::Record {
type_name: ctx.sym("DeclFact"),
fields: Rc::new(sorted_fields(vec![
(ctx.sym("qualified_name"), Value::Str(fact.qualified_name)),
(ctx.sym("name"), Value::Str(fact.name)),
(ctx.sym("kind"), marshal_decl_item_kind(ctx, fact.kind)),
(ctx.sym("node"), node),
(ctx.sym("rel_path"), Value::Str(fact.rel_path)),
])),
});
}
Ok(crate::v1_interpreter::list_value(rows))
}

pub fn eval_decl_facts(ctx: &InterpContext, pool_roots: &[String]) -> InterpResult<Value> {
let facts = decl_facts_for_roots(pool_roots);
let mut rows = Vec::with_capacity(facts.len());
Expand Down
5 changes: 5 additions & 0 deletions src/v1/stage0/src/v1_compiler_infer_method.rs
Original file line number Diff line number Diff line change
Expand Up @@ -393,6 +393,11 @@ pub fn builtin_function_registry() -> Rc<HashMap<String, Rc<Node>>> {
"decl_facts".to_string(),
list_of_type_variable("decl_fact_elem".to_string()),
);
let m = v1_rt::rc_map_insert(
m.clone(),
"export_signature_facts".to_string(),
list_of_type_variable("decl_fact_elem".to_string()),
);
let m = v1_rt::rc_map_insert(
m.clone(),
"medium_structure_leak_facts".to_string(),
Expand Down
Loading
Loading