diff --git a/ROADMAP.md b/ROADMAP.md index c70d0aa34b2..71ed597ba24 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -85,7 +85,6 @@ This window = a few days of STABILITY — shrink the fail-open surface, don't "l A flaky or green-but-broken floor means no gate protects anything — so CI is upstream of every §0 claim. CI is also the one workload that flexes *every* substrate layer at once (execution · scheduling · caching · secrets/effects · emission), so it is the forcing function that turns each modeled-but-inert abstraction load-bearing. **Deliverable = shared abstractions proven by CI consuming them** (one Materialization kernel · one Placement authority · one secrets model); faster CI falls *out* of that, it is not the goal (§6 — price the lane in displaced cost, "move with confidence", not elegance). → [charter: causal-chain gap analysis](docs/plans/ci-process-end-to-end.md) — what's on `.dag` today vs not, push→execute. -→ [CI humming](docs/plans/ci-humming.md) — the throughput/wall-clock/reliability operations plan for the **▸ NOW** milestone: un-throttle runner slots from the modeled budget (fix the build-pool double-count), verified-effective caps, the carrier, SessionSliceEnforcement, oomd demoted to backstop. → [CI humming](docs/plans/ci-humming.md) — the throughput/wall-clock/reliability operations plan for the **▸ NOW** milestone: un-throttle runner slots from the modeled budget (fix the build-pool double-count), verified-effective caps, the carrier, SessionSliceEnforcement, oomd demoted to backstop. diff --git a/dsl/gunbc/ci_floor_measurement.dag b/dsl/gunbc/ci_floor_measurement.dag index 9317e4e75cb..e653ea0504f 100644 --- a/dsl/gunbc/ci_floor_measurement.dag +++ b/dsl/gunbc/ci_floor_measurement.dag @@ -6,6 +6,7 @@ import std.realization_measurement { ConcurrentMemoryPeakSample, concurrent_memory_peak_per_share, } +import std.disposition { Disposition, Scaffold, DeclLocator, WholeDeclaration, SingleAuthority } data gunbc_ci_floor_measured_peak: ConcurrentMemoryPeakSample = ConcurrentMemoryPeakSample { peak: byte_size(11592347648) @@ -103,3 +104,30 @@ type HostFixedOverhead | HostFixedOverheadUnmeasured data gunbc_ci_host_fixed_overhead: HostFixedOverhead = HostFixedOverheadMeasured { bytes: byte_size(17179869184) } + +data gunbc_ci_floor_measured_peak_disposition: Disposition = Scaffold { + dissolves_to: SingleAuthority, + bind: DeclLocator { + module_path: "gunbc.ci_floor_measurement", + decl_name: "gunbc_ci_job_peaks", + field: WholeDeclaration + } +} + +data gunbc_ci_host_fixed_overhead_disposition: Disposition = Scaffold { + dissolves_to: SingleAuthority, + bind: DeclLocator { + module_path: "gunbc.ci_floor_measurement", + decl_name: "gunbc_ci_per_service_overhead", + field: WholeDeclaration + } +} + +data gunbc_ci_concurrent_runs_conservative_high_disposition: Disposition = Scaffold { + dissolves_to: SingleAuthority, + bind: DeclLocator { + module_path: "gunbc.ci_runner_placement", + decl_name: "runner_deployment_plan", + field: WholeDeclaration + } +} diff --git a/dsl/std/bytes.dag b/dsl/std/bytes.dag index 62367805e23..d3a18d8c4f5 100644 --- a/dsl/std/bytes.dag +++ b/dsl/std/bytes.dag @@ -2,6 +2,7 @@ module std.bytes import std.types { Bytes } import std.integer { UInt8 } +import std.disposition { Disposition, Scaffold, DeclLocator, WholeDeclaration, SingleAuthority } fn pure_dag_seam_unreachable() -> Int { 1 / 0 @@ -18,3 +19,12 @@ fn octets_bytes(o: List) -> Bytes { fn utf8_encode_bytes(s: String) -> Bytes { s as Bytes } + +data bytes_seam_host_realization_marker: Disposition = Scaffold { + dissolves_to: SingleAuthority, + bind: DeclLocator { + module_path: "std.bytes", + decl_name: "builtin_function_registry", + field: WholeDeclaration + } +} diff --git a/dsl/std/encoding.dag b/dsl/std/encoding.dag index 1bc7b07a994..e85c283f313 100644 --- a/dsl/std/encoding.dag +++ b/dsl/std/encoding.dag @@ -4,6 +4,7 @@ import std.algebra { BoundedLattice } import std.types { Bytes } import std.integer { UInt8 } import std.bytes { pure_dag_seam_unreachable } +import std.disposition { Disposition, Scaffold, Terminal, DeclLocator, WholeDeclaration, SingleAuthority } type Encoding = ASCII @@ -303,3 +304,16 @@ fn base64_decode(s: String, variant: Base64Variant) -> List? { } } } + +data utf8_decode_bytes_host_realization_marker: Disposition = Scaffold { + dissolves_to: SingleAuthority, + bind: DeclLocator { + module_path: "std.bytes", + decl_name: "builtin_function_registry", + field: WholeDeclaration + } +} + +data base64_group_fill_carrier_debt_marker: Disposition = Terminal { + reason: "Base64EncodeBuf = EncEmpty|EncOne|EncTwo and Base64DecodeBuf = DecEmpty|DecOne|DecTwo|DecThree: the hand-rolled Int count accumulator debt is paid; closed sums are declared and all arms are covered by execution in base64_rfc4648_witness_test.dag" +} diff --git a/dsl/tools/rust_stage0_gates.dag b/dsl/tools/rust_stage0_gates.dag index 27294426747..9badc313e2d 100644 --- a/dsl/tools/rust_stage0_gates.dag +++ b/dsl/tools/rust_stage0_gates.dag @@ -1,6 +1,7 @@ module tools.rust_stage0_gates import std.list { List } +import std.disposition { Disposition, Scaffold, Terminal, DeclLocator, WholeDeclaration, SingleAuthority } fn rust_monolith_suffixes() -> List { [".rs", "Cargo.toml", "Cargo.lock", "rust-toolchain.toml", @@ -15,11 +16,27 @@ fn any_rust_monolith(paths: List) -> Bool { fold(paths, false, fn(acc, p) { acc || path_is_rust_monolith(path: p) }) } -data consumed_input_closure_concept_note: String = "ConsumedInputClosure = a unit's declared consumed-.dag inputs (what .dag a unit reads -> what must re-run on change). This is AFFECTED-SET SELECTION, the same underlying concept as (1) v2 affected_set/source_authority (src/v2/lens/affected_set, v2.std.artifact.NodeArtifactProvenance) and (2) the .dag-floor witness selection, at a third layer (rust tests run by the v1 binary). It is NOT NodeArtifactProvenance: that PRODUCES-artifact over v2 Nodes, this CONSUMES-input over opaque unit identities -- different direction, different domain, no coincidence to dedupe (DESIGN 2/3), so FIRST authority for the dsl-layer instance, not a parallel mint. Homed in dsl because the consumer should_run_gates runs in the v1/dsl tree, which cannot import v2 (imports point toward std; v2->dsl legal, dsl->v2 forbidden); dsl is the one layer all three consumers reach. unit is opaque -- a rust test is ONE kind of unit, named general so the .dag-floor selection can converge onto this carrier later without a rename." +data consumed_input_closure_concept_note: Disposition = Terminal { + reason: "ConsumedInputClosure is the first std-layer authority for dsl-layer input-consumption selection; consume-input vs produce-artifact is a permanent §3 distinction (different direction + domain from NodeArtifactProvenance), so this dsl-layer instance is the FIRST authority, not a parallel mint" +} -data consumed_input_closure_convergence_candidate: String = "CONVERGENCE CANDIDATE (accounted, not unified now) with v2 affected_set/source_authority AND the .dag-floor selection -- same concept at different layers. DISSOLUTION TRIGGER: one consumed-input/selection authority at a layer all three consumers reach (the deep (B) work -- relocate provenance/affected_set down, or a shared lower-layer authority)." +data consumed_input_closure_convergence_candidate: Disposition = Scaffold { + dissolves_to: SingleAuthority, + bind: DeclLocator { + module_path: "std.consumed_input", + decl_name: "ConsumedInputClosure", + field: WholeDeclaration + } +} -data consumed_input_closure_slice1_status: String = "SLICE-1 NON-SOUND WIRING-ONLY: consumed_dag_paths is HAND-LISTED. Proves the fire/skip plumbing, NOT the coverage WALL (drift-proof completeness, closure superset of actual-reads). A .dag read added later is NOT captured here -> declaration drift silently re-opens the .dag->rust fail-open for the missing path. DISSOLUTION TRIGGER (soundness): structural closure derivation through the opaque host-read seam (filesystem_read/ws.join) -- the shared blocker. Only coproduct_reflection_conformance_test populated for slice 1." +data consumed_input_closure_slice1_status: Disposition = Scaffold { + dissolves_to: SingleAuthority, + bind: DeclLocator { + module_path: "tools.rust_stage0_gates", + decl_name: "structural_closure_derivation", + field: WholeDeclaration + } +} type ConsumedInputClosure { unit: String @@ -56,9 +73,18 @@ fn any_declared_closure_hit(paths: List) -> Bool { fold(declared_consumed_input_closures, false, fn(acc, c) { acc || closure_hit_by_any(closure: c, paths: paths) }) } -data unit_must_run_failclosed_note: String = "Fail-closed per-unit selection: a unit with NO declared closure must run (absent declaration = run, never skip), keeping the coverage direction sound while declarations are added incrementally. A declared unit runs iff a changed path is in its closure. The fold seeds true (the fail-closed default); the matching declared entry, if any, overrides it with the affected-by-diff verdict." +data unit_must_run_failclosed_note: Disposition = Terminal { + reason: "fail-closed per-unit selection is a permanent §5 invariant: absent declaration = must-run, keeping coverage sound while declarations are added incrementally" +} -data unit_must_run_staged_note: String = "STAGED primitive (DESIGN 6 scaffold-with-dissolution-trigger): unit_must_run is the fail-closed PER-UNIT selector but is NOT YET consumed by the live gate -- should_run_gates fires coarsely via any_declared_closure_hit (all-or-nothing: any declared closure hit runs the whole rust suite). It is exercised only by its discriminating witnesses today (proving the fail-closed (iii) direction by execution). DISSOLUTION / CONSUMER TRIGGER: the per-unit rust-test selection slice (the affordability direction) that replaces all-or-nothing should_run_gates with per-test selection -- at which point unit_must_run becomes the live selector and this staged note dissolves. Until then it is an intentionally-staged primitive, not an inert abstraction." +data unit_must_run_staged_note: Disposition = Scaffold { + dissolves_to: SingleAuthority, + bind: DeclLocator { + module_path: "tools.rust_stage0_gates", + decl_name: "per_unit_test_selector", + field: WholeDeclaration + } +} fn unit_must_run(unit: String, paths: List) -> Bool { fold(declared_consumed_input_closures, true, fn(acc, c) { @@ -66,7 +92,9 @@ fn unit_must_run(unit: String, paths: List) -> Bool { }) } -data should_run_gates_coverage_note: String = "Coverage fire (Edge-(b)): the rust gate ALSO runs when a changed .dag is in the union of declared consumed-input closures -- purely additive to the existing .rs/Cargo fire, so the change only ever ADDS fires, never newly skips (fail-closed for coverage)." +data should_run_gates_coverage_note: Disposition = Terminal { + reason: "Coverage fire (Edge-(b)) is a permanent §5 design invariant: the rust gate ALSO runs when a changed .dag is in the union of declared consumed-input closures, only ever ADDING fires, never newly skipping" +} fn should_run_gates(paths: List, git_success: Bool) -> Bool { if git_success { diff --git a/src/v1/tests/src/disposition_redundancy_lens_test.rs b/src/v1/tests/src/disposition_redundancy_lens_test.rs index d25b6c5c9b9..41653e9e462 100644 --- a/src/v1/tests/src/disposition_redundancy_lens_test.rs +++ b/src/v1/tests/src/disposition_redundancy_lens_test.rs @@ -80,4 +80,22 @@ fn disposition_redundancy_lens_discriminates_by_execution() { test_entry, "redundancy_region1_fires_when_a_real_mark_successor_present", ); + // Slice-2: bytes/encoding markers non-empty and two Scaffolds fire on synthetic present. + assert_witness_true(test_entry, "redundancy_region_bytes_marks_nonempty"); + assert_witness_true( + test_entry, + "redundancy_region_bytes_fires_on_builtin_registry_present", + ); + // Slice-2: budget-tree markers non-empty and fire on job_peaks locator. + assert_witness_true(test_entry, "redundancy_region_budget_marks_nonempty"); + assert_witness_true( + test_entry, + "redundancy_region_budget_fires_on_job_peaks_present", + ); + // Slice-2: rust_stage0_gates markers non-empty and fire on synthetic present. + assert_witness_true(test_entry, "redundancy_region_rust_gates_marks_nonempty"); + assert_witness_true( + test_entry, + "redundancy_region_rust_gates_fires_on_convergence_target_present", + ); } diff --git a/src/v2/lens/disposition_redundancy_test.dag b/src/v2/lens/disposition_redundancy_test.dag index 7d4c533f854..9c4282131ad 100644 --- a/src/v2/lens/disposition_redundancy_test.dag +++ b/src/v2/lens/disposition_redundancy_test.dag @@ -1,8 +1,25 @@ module v2.test.lens_disposition_redundancy.disposition_redundancy_test import v2.lens.disposition_redundancy { disposition_redundancy_violation_count } -import std.disposition { Disposition, Scaffold, DeclLocator, NamedField, SingleAuthority } -import extdeps.llm.anthropic { structural_coverage_gap_anthropic_tool_result_nested_block_wire_payloads } +import std.disposition { Disposition, Scaffold, Terminal, DeclLocator, NamedField, WholeDeclaration, SingleAuthority } +import extdeps.llm.anthropic { + structural_coverage_gap_anthropic_tool_result_nested_block_wire_payloads +} +import std.bytes { bytes_seam_host_realization_marker } +import std.encoding { utf8_decode_bytes_host_realization_marker, base64_group_fill_carrier_debt_marker } +import gunbc.ci_floor_measurement { + gunbc_ci_floor_measured_peak_disposition, + gunbc_ci_host_fixed_overhead_disposition, + gunbc_ci_concurrent_runs_conservative_high_disposition +} +import tools.rust_stage0_gates { + consumed_input_closure_concept_note, + consumed_input_closure_convergence_candidate, + consumed_input_closure_slice1_status, + unit_must_run_failclosed_note, + unit_must_run_staged_note, + should_run_gates_coverage_note +} import v2.std.collection { List } import v2.std.algebra { length } import v2.std.logic { Bool } @@ -65,3 +82,100 @@ test fn redundancy_region1_fires_when_a_real_mark_successor_present() -> Bool { present: redundancy_region1_real_successor_present ) == 1 } + +data redundancy_region_bytes_marks: List = [ + bytes_seam_host_realization_marker, + utf8_decode_bytes_host_realization_marker, + base64_group_fill_carrier_debt_marker +] + +data redundancy_region_bytes_synthetic_present: List = [ + DeclLocator { + module_path: "std.bytes", + decl_name: "builtin_function_registry", + field: WholeDeclaration + } +] + +test fn redundancy_region_bytes_marks_nonempty() -> Bool { + length(xs: redundancy_region_bytes_marks) > 0 +} + +test fn redundancy_region_bytes_green_against_nonmatching() -> Bool { + disposition_redundancy_violation_count( + dispositions: redundancy_region_bytes_marks, + present: redundancy_present_with_successor + ) == 0 +} + +test fn redundancy_region_bytes_fires_on_builtin_registry_present() -> Bool { + disposition_redundancy_violation_count( + dispositions: redundancy_region_bytes_marks, + present: redundancy_region_bytes_synthetic_present + ) == 2 +} + +data redundancy_region_budget_marks: List = [ + gunbc_ci_floor_measured_peak_disposition, + gunbc_ci_host_fixed_overhead_disposition, + gunbc_ci_concurrent_runs_conservative_high_disposition +] + +data redundancy_region_budget_job_peaks_locator: DeclLocator = DeclLocator { + module_path: "gunbc.ci_floor_measurement", + decl_name: "gunbc_ci_job_peaks", + field: WholeDeclaration +} + +test fn redundancy_region_budget_marks_nonempty() -> Bool { + length(xs: redundancy_region_budget_marks) > 0 +} + +test fn redundancy_region_budget_green_against_nonmatching() -> Bool { + disposition_redundancy_violation_count( + dispositions: redundancy_region_budget_marks, + present: redundancy_present_with_successor + ) == 0 +} + +test fn redundancy_region_budget_fires_on_job_peaks_present() -> Bool { + disposition_redundancy_violation_count( + dispositions: redundancy_region_budget_marks, + present: [redundancy_region_budget_job_peaks_locator] + ) == 1 +} + +data redundancy_region_rust_gates_marks: List = [ + consumed_input_closure_concept_note, + consumed_input_closure_convergence_candidate, + consumed_input_closure_slice1_status, + unit_must_run_failclosed_note, + unit_must_run_staged_note, + should_run_gates_coverage_note +] + +data redundancy_region_rust_gates_synthetic_present: List = [ + DeclLocator { + module_path: "std.consumed_input", + decl_name: "ConsumedInputClosure", + field: WholeDeclaration + } +] + +test fn redundancy_region_rust_gates_marks_nonempty() -> Bool { + length(xs: redundancy_region_rust_gates_marks) > 0 +} + +test fn redundancy_region_rust_gates_green_against_nonmatching() -> Bool { + disposition_redundancy_violation_count( + dispositions: redundancy_region_rust_gates_marks, + present: redundancy_present_with_successor + ) == 0 +} + +test fn redundancy_region_rust_gates_fires_on_convergence_target_present() -> Bool { + disposition_redundancy_violation_count( + dispositions: redundancy_region_rust_gates_marks, + present: redundancy_region_rust_gates_synthetic_present + ) == 1 +}