diff --git a/dsl/gunbc/auth/credentials.dag b/dsl/gunbc/auth/credentials.dag index 57902a39b90..7c496eeeb9e 100644 --- a/dsl/gunbc/auth/credentials.dag +++ b/dsl/gunbc/auth/credentials.dag @@ -1,9 +1,3 @@ -// gunbc/auth/credentials.dag -- Concrete gunbc credential acquisition bindings. -// -// This module binds provider-neutral credential needs to concrete runtime -// mechanisms. It is intentionally not part of std/: these patterns depend on -// a specific provider and local runtime tooling. - module gunbc.auth.credentials import extdeps.cloud.gcp.gcp @@ -11,11 +5,6 @@ import extdeps.cloud.gcp.secret_manager import std.resources { Network } import std.types { FilePath, NonEmptyStr } -// Acquire a credential from GCP Secret Manager via the canonical REST interface. -// -// Local dev composes shell.GCloud.AuthPrintAccessToken (auth) with -// gcp.SecretManager.AccessVersion (REST) β€” not a forked shell duplicate of the endpoint. - pattern gcp_secret_credential( project_id: NonEmptyStr, secret_name: NonEmptyStr, @@ -33,9 +22,6 @@ pattern gcp_secret_credential( return { token: utf8_secret_from_access_payload(payload: result.payload) } } -// OAuth2 access token via ADC refresh: gcloud.Auth.ReadADC (file) β†’ oauth2.Google.Refresh (REST). -// One interface shape for the token endpoint; ReadADC is a prerequisite handler, not a fork. - pattern gcp_oauth_access_token_via_adc_refresh( adc_path: FilePath = "~/.config/gcloud/application_default_credentials.json" ) -> { token: Secret } @@ -50,18 +36,11 @@ pattern gcp_oauth_access_token_via_adc_refresh( return { token: refresh.access_token } } -// OAuth2 access token via gcloud CLI (shell.GCloud.AuthPrintAccessToken). -// Distinct realization path β€” gcloud's credential store, not a fork of Refresh. -// Shell transport is not yet a declared resource (same as gcp_secret_credential's auth step). - pattern gcp_oauth_access_token_via_gcloud() -> { token: Secret } { auth = shell.GCloud.AuthPrintAccessToken() return { token: auth.access_token } } -// Dispatch entry: GcpOAuth2AccessTokenStrategy β†’ the leaf materializer for that path. -// Network is declared only on the AdcRefresh leaf chain; GcloudCli is shell-only. - pattern gcp_oauth_access_token(strategy: GcpOAuth2AccessTokenStrategy) -> { token: Secret } { node result = match strategy { @@ -71,10 +50,6 @@ pattern gcp_oauth_access_token(strategy: GcpOAuth2AccessTokenStrategy) -> { toke return { token: result.token } } -// ADC path dispatch: Present/Absent for encoded FilePath? values. -// 🟑 SCAFFOLD β€” feature:literal-optional-none-match β€” dissolve-on: literal-built -// `FilePath? = none` encodes as Absent (not raw null) so Present/Absent match is total; -// delete the third arm once the substrate routes literal none into Absent. pattern gcp_oauth_access_token_adc_for_path(path: FilePath?) -> { token: Secret } uses net: Network { diff --git a/dsl/gunbc/auth/patterns.dag b/dsl/gunbc/auth/patterns.dag index 6e9ea2fa631..bf9a8117903 100644 --- a/dsl/gunbc/auth/patterns.dag +++ b/dsl/gunbc/auth/patterns.dag @@ -1,9 +1,3 @@ -// gunbc/auth/patterns.dag -- Gunbc-specific auth composition. -// -// These patterns intentionally live outside std/: they compose concrete -// runtime environments, provider services, and local tooling to materialize -// credentials and auth contexts. - module gunbc.auth.patterns import std.resources { Filesystem, Network, AuthContext } @@ -24,17 +18,11 @@ import extdeps.github.actions { GitHubActionsRuntime } import extdeps.runtime.local { LocalDevRuntime } import extdeps.shell -// 🟒 terminal coproduct: consumer-owned auth runtime choice; each payload lives in its discrete concern home. type AuthRuntime = GitHubActions { runtime: GitHubActionsRuntime } | GcpMetadata { runtime: MetadataRuntime } | LocalDev { runtime: LocalDevRuntime } -// Acquire a subject token based on runtime environment. -// Useful independently for: any workflow that needs a subject token -// without the full credential chain (e.g., direct STS exchange, -// non-GCP federated auth). - pattern acquire_subject_token( runtime: AuthRuntime, audience: NonEmptyStr @@ -42,16 +30,11 @@ pattern acquire_subject_token( node token = match runtime { GitHubActions { runtime: github_actions } => github_oidc(audience: audience, runtime: github_actions) GcpMetadata { runtime: _ } => metadata_oidc(audience: audience) - LocalDev { runtime: _ } => metadata_oidc(audience: audience) // placeholder: local_auth() needs if/else expression support + LocalDev { runtime: _ } => metadata_oidc(audience: audience) } return { token: token.token } } -// Optionally impersonate a service account. -// Passes through the original token when no SA is specified. -// Useful independently for: any workflow that needs conditional -// SA impersonation outside of the credential chain. - pattern optional_impersonation( access_token: Secret, service_account: ServiceAccountEmail?, @@ -73,9 +56,6 @@ fn build_token(payload: Secret, scheme: AuthScheme, header_name: String, source_ { token: payload, scheme: scheme, expires_at: none } } -// OIDC -> STS -> optional impersonation -> secret access -> credential. -// Composes fundamental auth steps with GCP service calls. - pattern credential_chain( runtime: AuthRuntime, audience: NonEmptyStr, @@ -89,7 +69,7 @@ pattern credential_chain( lifetime_seconds: Int where range(min: 1, max: 3600)= 3600 ) -> { token: AccessToken } uses net: Network - // provides auth: AuthContext -- commented: parser doesn't support provides yet + { node subject: acquire_subject_token(runtime: runtime, audience: audience) @@ -121,9 +101,6 @@ pattern credential_chain( } } -// Real implementations replacing stubs. Each acquires a subject token -// from the runtime environment using the appropriate protocol. - func github_oidc(audience: String, runtime: GitHubActionsRuntime) -> { token: Secret } uses net: Network { @@ -144,24 +121,3 @@ func metadata_oidc(audience: String) -> { token: Secret } response = gcp.Metadata.GetIdentityToken(audience: audience) return { token: response.subject_token as String } } - -// ADC check -> OAuth2 refresh -> conditional re-auth via gcloud -> merge. -// Commented: parser doesn't support if/else as inline expression yet. -// Materializers (when enabled): gunbc.auth.credentials.gcp_oauth_access_token(strategy). -// -// func local_auth() -> Secret -// uses fs: Filesystem -// { -// adc_path = shell.Env.Get(name: "GOOGLE_APPLICATION_CREDENTIALS") -// -// adc = gcloud.Auth.ReadADC(path: adc_path.value) [when adc_path.value != none] // parses ADC JSON -> client_id, client_secret, refresh_token -// adc_refresh = oauth2.Google.Refresh( -// client_id: adc.client_id, client_secret: adc.client_secret, refresh_token: adc.refresh_token -// ) [when adc_path.value != none] -// gcloud_auth = shell.GCloud.AuthPrintAccessToken() -// -// let adc_token = adc_refresh.access_token -// let gcloud_token = gcloud_auth.access_token -// let result = if adc_path.value != none { adc_token } else { gcloud_token } -// return result -// } diff --git a/dsl/gunbc/bootstrap.dag b/dsl/gunbc/bootstrap.dag index 4522a895b06..90a16c7998e 100644 --- a/dsl/gunbc/bootstrap.dag +++ b/dsl/gunbc/bootstrap.dag @@ -1,28 +1,7 @@ -// gunbc/bootstrap.dag -- Bootstrap pipeline data model. -// -// The gunbc compiler is self-hosting. The bootstrap pipeline is: -// 1. .dag source files define the compiler -// 2. stage0 .rs files are a frozen compiled version -// 3. stage0 compiles .dag -> produces new .rs -> must match stage0 -// -// This file models the pipeline stages, their inputs/outputs, and the -// strategies for handling structural changes (new Node fields, new types) -// so the pipeline knows what to do automatically instead of requiring -// manual stage0 edits. -// -// These types are gunbc-specific (not std/): they model THIS compiler's -// bootstrap process, not a general-purpose build system. - module gunbc.bootstrap import std.types { ContentHash, FilePath, NonEmptyStr } -// --- Pipeline stages ------------------------------------------------------ - -// The ordered stages of the compiler pipeline. -// Each stage is a pure function: input -> (output, diagnostics). -// Ordering is total: tokenize < parse < resolve < normalize < infer -// < complexity < ownership < emit. type CompilerStage = Tokenize | Parse @@ -33,8 +12,6 @@ type CompilerStage | Ownership | Emit -// What a stage consumes. Every stage after Tokenize consumes the -// previous stage's output. type StageInput = SourceText { files: List } | TokenStream { from_stage: CompilerStage } @@ -44,8 +21,6 @@ type StageInput | TypedGraph { from_stage: CompilerStage } | AnnotatedGraph { from_stage: CompilerStage } -// What a stage produces. Diagnostics thread through every stage -// boundary (DESIGN.md: "Every stage returns { value, diagnostics }"). type StageOutput { stage: CompilerStage artifact_kind: ArtifactKind @@ -62,18 +37,12 @@ type ArtifactKind | OwnershipProofs | RenderedFiles -// --- Source entry ---------------------------------------------------------- - type SourceEntry { path: FilePath content: String module_name: NonEmptyStr? } -// --- Change classification ------------------------------------------------ - -// What kind of structural change is being made to the compiler. -// This drives the BootstrapStrategy selection. type ChangeKind = AddField | RemoveField @@ -84,7 +53,6 @@ type ChangeKind | ModifyVariant | AddStage -// A classified change to the compiler's own structure. type ChangeClassification { kind: ChangeKind target_type: NonEmptyStr @@ -93,23 +61,8 @@ type ChangeClassification { affects_stages: List } -// --- Bootstrap strategy --------------------------------------------------- - -// How to handle a change through the bootstrap pipeline. -// -// SinglePass: the change is backward-compatible (e.g. new field with -// default, new coproduct variant). The current stage0 can compile -// the new .dag source and produce correct output. -// -// TwoPhase: the change is NOT backward-compatible (e.g. new required -// field, removed field). The old compiler must first be taught to -// handle defaults, then the new compiler can take over. -// -// Additive: a special case of SinglePass where the change only adds -// new structure without modifying existing paths. type BootstrapStrategy = SinglePass | TwoPhase | Additive -// The resolved strategy for a specific change. type BootstrapPlan { change: ChangeClassification strategy: BootstrapStrategy @@ -117,11 +70,6 @@ type BootstrapPlan { reason: String } -// --- Fixed-point verification --------------------------------------------- - -// The convergence check: regen(regen(source)) == regen(source). -// If pass1 != pass2, the change is not at fixed point and the -// pipeline must iterate. type FixedPointCheck { pass1_hash: ContentHash pass2_hash: ContentHash @@ -129,21 +77,11 @@ type FixedPointCheck { diff_files: List } -// Overall result of a bootstrap cycle. type BootstrapResult = Converged { check: FixedPointCheck } | Diverged { check: FixedPointCheck, iteration: Int } | CompileError { stage: CompilerStage, message: String } -// --- Field propagation ---------------------------------------------------- - -// Which transforms preserve which fields across pipeline stages. -// This is the structural fact that determines whether a field -// survives a stage boundary or must be recomputed. -// -// Example: map_children preserves ident (it copies the parent node's -// metadata while transforming children). But normalize may discard -// source spans from desugared nodes. type PropagationRule = Preserved | Recomputed @@ -155,7 +93,6 @@ type FieldPropagation { rule: PropagationRule } -// A transform and the fields it guarantees to preserve. type TransformContract { transform_name: NonEmptyStr stage: CompilerStage @@ -163,12 +100,6 @@ type TransformContract { recomputed_fields: List } -// --- Strategy selection --------------------------------------------------- - -// Determine the bootstrap strategy from a change classification. -// Additive: new field with default, or new type. -// SinglePass: new coproduct variant (existing match arms still work). -// TwoPhase: everything else (requires old compiler to handle the gap). fn classify_strategy(change: ChangeClassification) -> BootstrapStrategy { match change.kind { AddField => if change.has_default { Additive } else { TwoPhase } diff --git a/dsl/gunbc/ci_fleet.dag b/dsl/gunbc/ci_fleet.dag index 1ec178dbe7c..24eb643d892 100644 --- a/dsl/gunbc/ci_fleet.dag +++ b/dsl/gunbc/ci_fleet.dag @@ -1,9 +1,3 @@ -// gunbc/ci_fleet.dag β€” gunbc CI runner identity (ComputeOffer β†’ GitHub Actions runs-on labels). -// -// OUR self-hosted runner as compute_fabric data, consumed by ci_workflow / ci_yaml_emit via -// gunbc_ci_runner_spec(). The memory-aware spawn-width modeling was removed (the floor pins a -// flat width); the real per-host fleet inventory lives in gunbc.operator_fleet. - module gunbc.ci_fleet import extdeps.cpu.ampere { altra_q6430_catalog } diff --git a/dsl/gunbc/ci_floor_measurement.dag b/dsl/gunbc/ci_floor_measurement.dag index ae5f60caa55..9d12c155a7e 100644 --- a/dsl/gunbc/ci_floor_measurement.dag +++ b/dsl/gunbc/ci_floor_measurement.dag @@ -1,39 +1,3 @@ -// gunbc/ci_floor_measurement.dag β€” the CI floor's MEASURED per-shard memory peak (Β§1-C). -// -// This is the committed half of the Β§1 measurementβ†’plan loop (realization-measurement-loop.md -// Phase 0/1). The spawn-width derivation (src/v2/workflow/ci_floor_plan.dag) divides the LIVE -// host memory budget by the per-shard peak recorded HERE. Per DESIGN Β§3 (measuredβ‡’peripheral): -// - the per-shard peak is OUR measurement β†’ we COMMIT it, provenance-stamped (this file); -// - the cgroup budget is authored by an EXTERNAL system (the host/scheduler) β†’ the host -// realizer READS it live (claim_executor), never committed. -// This file is the peripheral measured realization; the v2 plan stays pure topology. -// -// NOT a hand-grounded literal: the number below is claim_executor's MEASURED VmHWM emit -// ("[measurement] floor peak RSS: (VmHWM) at spawn_width=N", added in #5431). It -// replaces β€” does not re-add β€” the ~14GB hand-grounded literal #5419 deleted as unwired. -// -// ── PROVENANCE (re-stamp on every re-measure) ──────────────────────────────── -// source emit : "[measurement] floor peak RSS: 8400113664 bytes (VmHWM) at spawn_width=4" -// run : GitHub Actions run 27893441091 (#5431 PR CI, job 82540829121) -// commit : cb71163cf2 (the #5431 merge that landed the VmHWM emit) -// corpus : 616 discovery witnesses (0 skipped) -// date : 2026-06-21 -// Each DiscoveryBatch shard does a WHOLE-TREE resolve, so the per-shard peak β‰ˆ the whole-floor -// VmHWM Γ· the spawn_width it was measured at (the concurrency). It scales with TREE size, not -// witnesses-per-shard β€” which is why a larger tree (the old ~2900-row era) peaked far higher. -// -// 🟑 SCAFFOLD β€” feature:measured-peak-drift-gate β€” -// consumer: ci_floor_plan.gunbc_ci_floor_spawn_width (via std.realization_width). -// RESIDUE (DESIGN Β§6, legit unstructurable-before-execution): the committed peak is stale in -// exactly ONE dangerous direction β€” the tree grows un-re-stamped β†’ committed peak too LOW β†’ -// ⌊budget Γ· peakβŒ‹ too HIGH β†’ OOM. A peak is fundamentally a runtime OUTPUT (you cannot know a -// run's peak before running it), so a committed-prior-measurement + a drift-check is the legit -// Β§6 residue, not a construction wall. The #5431 emit each run is the drift MONITOR but nothing -// GATES on it yet (observe-by-eyeball = validation, not construction). -// dissolve-on: a cheap CI gate compares this committed peak against the live emit's VmHWMΓ·width -// and fails closed when committed is stale-LOW beyond a margin (re-stamp required). Out of scope -// for the Β§1-C width PR; this marker keeps the committed fact from being a silent staleness trap. - module gunbc.ci_floor_measurement import std.measure { ByteSize, byte_size } @@ -43,25 +7,13 @@ import std.realization_measurement { concurrent_memory_peak_per_share, } -// The measured whole-floor concurrent peak (VmHWM) bundled with the concurrency it was sampled -// at β€” ONE fact (a ConcurrentMemoryPeakSample), the single authority for the Β§1-C derivation. -// Peak and concurrency are only meaningful together (per-share = peak Γ· concurrency), so they -// live in one carrier rather than as two loose rows that could drift apart. Re-stamp the pair -// here on every re-measure (provenance above). data gunbc_ci_floor_measured_peak: ConcurrentMemoryPeakSample = ConcurrentMemoryPeakSample { peak: byte_size(8400113664) concurrency: 4 } -// Per-shard peak: each DiscoveryBatch shard does a whole-tree resolve, so the per-shard peak is -// the measured concurrent peak distributed across its sample concurrency. Delegates to the std -// measure-algebra derivation (std.realization_measurement) β€” no inline unwrap/divide/re-ground -// here; the division is a grounded measure operation, not a one-off expression. fn gunbc_ci_floor_per_shard_peak_rss_bytes() -> ByteSize { concurrent_memory_peak_per_share(sample: gunbc_ci_floor_measured_peak) } -// Fail-closed fallback width when the host cannot read a live memory budget: the last -// known-safe MEASURED width (the run above passed at width 4 = 8.40 GB concurrent on the real -// fleet). A bounded, grounded fallback β€” never fabricated, never an unbounded memory-blind width. data gunbc_ci_floor_conservative_fallback_width: Int = 4 diff --git a/dsl/gunbc/ci_layer_roots.dag b/dsl/gunbc/ci_layer_roots.dag index 84560eadfc2..d5a17c7bef1 100644 --- a/dsl/gunbc/ci_layer_roots.dag +++ b/dsl/gunbc/ci_layer_roots.dag @@ -1,18 +1,7 @@ -// gunbc/ci_layer_roots.dag β€” single authority for CI witness layer roots (Β§3). -// -// Intentionally v2-import-free so dsl-only `gunbc compile` and transport scripts -// can read roots without pulling the ci_workflow projection graph. - module gunbc.ci_layer_roots -// Single authority for CI witness layer roots (replaces triple-fork in ci.yml / transport scripts). -// Overlay order: dsl first, then src/v2 β€” v2 rows win on duplicate module paths -// (e.g. extdeps.shell without dsl/std.types) while dsl-only modules remain available. -// TRANSITIONAL (slice 3): dsl-first so the v2 extdeps.shell overlay wins; reverts when dsl/extdeps/shell is deleted (final slice). data witness_layer_roots: List = ["dsl", "src/v2"] -// Satisfies claim_batch --roster-from-discovery scan-dir gate (unified_claim_* in dsl/test/claim; -// find_witness homomorphism kernel anchors in src/v2/compiler/manual). data witness_discovery_scan_dirs: List = ["dsl/test/claim", "src/v2/compiler/manual"] fn witness_layer_source_flags(roots: List) -> String { diff --git a/dsl/gunbc/ci_spec.dag b/dsl/gunbc/ci_spec.dag index 7328dc5e0e5..c31992f39a4 100644 --- a/dsl/gunbc/ci_spec.dag +++ b/dsl/gunbc/ci_spec.dag @@ -1,5 +1,3 @@ -// gunbc/ci_spec.dag β€” CI intent as data (gates, diff policy, transport scripts). - module gunbc.ci_spec import gunbc.ci_layer_roots { @@ -33,9 +31,6 @@ type CiSpec { notice_title: String } -// 🟑 SCAFFOLD β€” feature:gate-coproduct-inhabitant-bridge β€” bind gunbc#4872 β€” -// dissolve-on-arrival: generic Symbolβ†’inhabitant replaces exhaustive match roster; -// roster completeness is witness-checked in src/v2/test/claim/ci_spec_witness_test.dag. data gunbc_ci_gates: List = [ RustMonolithGate, EmitHostGate, @@ -57,9 +52,6 @@ data gunbc_ci_spec: CiSpec = { notice_title: "v2 claim corpus" } -// Unify v1-compiler feature set across CI cargo invocations. v1-compiler-tests enables -// text_lookup_work_counter; building gunbc/claim_executor without it forces a second full -// v1-compiler compile when rust gates run clippy --all-targets (~49% CI wall-time prong). data ci_release_features: String = "text_lookup_work_counter" fn ci_repo_root_shell() -> String { @@ -76,9 +68,6 @@ fn ci_release_build_line() -> String { ) } -// Two-tier cold retry on fleet EAGAIN (#4978 / #5138): first CARGO_BUILD_JOBS=1 with -// sccache (populate daemon when it works); if sccache still cannot spawn rustc, drop -// RUSTC_WRAPPER and compile direct. Workflow policy β€” NOT generic shell transport. fn ci_cargo_eagain_retry_core(command: String) -> String { concat( concat( @@ -120,12 +109,10 @@ fn ci_cargo_eagain_retry_core(command: String) -> String { ) } -// ci.yml workflow step (runs under bash β€” pipefail is available). fn ci_cargo_eagain_retry_script(command: String) -> String { concat("set -o pipefail\n", ci_cargo_eagain_retry_core(command: command)) } -// claim_executor / shell.Exec path (`sh -c` β€” delegate to bash for pipefail). fn ci_cargo_eagain_retry_shell_exec(command: String) -> String { concat( concat("bash -o pipefail <<'__GUNBC_CI_RETRY__'\n", ci_cargo_eagain_retry_core(command: command)), @@ -133,11 +120,6 @@ fn ci_cargo_eagain_retry_shell_exec(command: String) -> String { ) } -// The artifacts the release bootstrap build MUST produce β€” the prebuilt release bins the floor -// then consumes WITHOUT a rebuild: `claim_executor` (the scheduler/executor the floor runs) and -// `gunbc` (the compiler the host gates invoke via tools.host_prelude). `cargo build … --bins` -// (ci_release_build_line) produces both; declaring them here is the single authority the -// verification generator derives the exists+freshness checks from (DESIGN Β§3/Β§5). fn ci_release_artifact(name: String) -> BuildArtifact { BuildArtifact { path: Concat { parts: [var_ref(name: "ROOT"), lit(text: concat("/target/release/", name))] }, @@ -150,12 +132,6 @@ data ci_floor_required_artifacts: List = [ ci_release_artifact(name: "gunbc") ] -// Source packages whose `.rs` files and manifests determine the `claim_executor`/`gunbc` build -// outputs. `stage0` is the binary package; `stage0_core` and `stage0_emit_core` are the generated -// crates it depends on. `src/v1/tests/` (v1-compiler-tests) is intentionally excluded β€” it is a -// test-only workspace member not in `claim_executor`/`gunbc`'s dep graph; touching a test helper -// does not trigger a rebuild, so scanning it produces a freshness false-positive against a -// legitimately-cached binary (DESIGN Β§5: the check must not fire for a correct no-rebuild). fn ci_build_source_roots() -> List { [ Concat { parts: [var_ref(name: "ROOT"), lit(text: "/src/v1/stage0")] }, @@ -164,16 +140,10 @@ fn ci_build_source_roots() -> List { ] } -// Derived verification: existence (primary) then source-relative freshness (secondary) for each -// declared artifact, appended after the build so a non-zero verification exit fails the step. fn ci_floor_build_verify_script() -> String { verifications_script(produces: ci_floor_required_artifacts, roots: ci_build_source_roots(), patterns: ["*.rs", "Cargo.toml", "Cargo.lock"]) } -// Release bootstrap build + declared-artifact verification + sccache stats (ci.yml workflow -// step). Success is DERIVED, not exit-code-only: the build can exit 0 with no/stale artifact -// (sccache false cache-hit) β€” `ci_floor_build_verify_script` makes that fail closed before the -// floor runs a phantom binary (DESIGN Β§5). fn ci_release_build_script() -> String { concat( concat("ROOT=", ci_repo_root_shell(), "\n"), @@ -187,7 +157,6 @@ fn ci_release_build_script() -> String { ) } -// Rust-monolith gate argv lines (workflow policy lives here, not in dispatch_shell). fn ci_rust_gate_fmt_command() -> String { "cargo fmt --all --check" } @@ -197,13 +166,7 @@ fn ci_rust_gate_clippy_command() -> String { } fn ci_rust_gate_test_command() -> String { - // Two name filters passed to libtest after `--` (a test runs if its name - // contains EITHER): the recorded-fixture purity suite + the resolve_expr_types - // redundant-re-traversal structural guard (the #5146-class O(2^depth) regression - // guard). The rest of v1-compiler-tests carries pre-existing reds, so CI pins the - // known-green subset. The `--` is required: `cargo test` accepts a single - // positional TESTNAME, so a second bare filter errors ("unexpected argument"); - // multiple substring filters must follow `--` to reach the test binary. + "cargo test -p v1-compiler-tests -- interp_recorded_fixture wet_hermetic resolve_expr_types_retraversal" } @@ -225,20 +188,6 @@ fn git_fetch_script(policy: DiffPolicy) -> String { ) } -// `claim_executor` takes ONLY `--source-root` (to resolve the plan) β€” it has no -// `--scan-dir` flag and hard-errors on any unknown argument. Scan dirs are carried -// SOLELY by the plan (`ci_floor_plan` discovery batch `scan_dirs` from -// `gunbc.ci_layer_roots.witness_discovery_scan_dirs` β†’ `RunnableDiscoveryBatch. -// scan_dirs`), the single authority for that derivation (DESIGN Β§3); emitting them -// on the argv too would be a redundant, fail-closed mis-wire (DESIGN Β§5). -// -// Layer roots: `gunbc.ci_layer_roots.witness_layer_roots` (Β§3 single authority). - -// The dependency-ordered scheduler plan (the single floor topology, DESIGN Β§3) and -// the host entry the executor evaluates. The scheduler β€” NOT a flat claim_batch + -// gates pair β€” is the default CI runtime: both the discovery corpus and the gates -// are scheduler plan nodes (`src/v2/workflow/ci_floor_plan.dag`), run dependency-ordered -// and parallel-where-independent, fail-closed (DESIGN Β§4/Β§5). data floor_plan_entry: String = "src/v2/workflow/ci_floor_plan.dag" data floor_plan_function: String = "gunbc_ci_floor_batches" diff --git a/dsl/gunbc/ci_workflow.dag b/dsl/gunbc/ci_workflow.dag index dce5671a159..b64aad433f4 100644 --- a/dsl/gunbc/ci_workflow.dag +++ b/dsl/gunbc/ci_workflow.dag @@ -1,12 +1,3 @@ -// gunbc/ci_workflow.dag β€” authoritative GitHub Actions Workflow value for repo CI. -// -// Single authority for `.github/workflows/ci.yml` (DESIGN Β§3). The committed file -// is the literal byte output of `serialize_yaml(project_workflow_to_yaml(ci_workflow))` -// β€” no hash pin, no dual representation. -// -// Job timeout uses `default_job_timeout_minutes` (360): the claim_executor CI floor -// (#5122) exceeds the prior 240m limit on self-hosted runners; not lens-specific cost. - module gunbc.ci_workflow import extdeps.formats.yaml { yaml_string, yaml_int, yaml_bool, kv } @@ -37,8 +28,7 @@ data ci_workflow: Workflow = { ], concurrency: Present { value: ConcurrencyMappingQueueNotMax { - // GitHub Actions `${{ }}` expressions are typed Nodes in `gunbc.ci_workflow_expressions` - // and serialized here (medium-as-Node guard β€” no inline expression strings in this file). + group: ci_concurrency_group(), cancel_in_progress: Present { value: CancelInProgressBool { value: true } }, explicit_single: none @@ -66,8 +56,7 @@ data ci_workflow: Workflow = { RunStep { name: Present { value: "Isolate toolchain dirs" }, id: none, - // CARGO_HOME/RUSTUP_HOME before Setup Rust + Cache Cargo. Fleet sccache is - // host-managed (SCCACHE_SERVER_UDS); enable wrapper only when daemon responds. + run: concat( concat( concat( diff --git a/dsl/gunbc/ci_workflow_expressions.dag b/dsl/gunbc/ci_workflow_expressions.dag index a5359d549fb..e0297050b99 100644 --- a/dsl/gunbc/ci_workflow_expressions.dag +++ b/dsl/gunbc/ci_workflow_expressions.dag @@ -1,14 +1,3 @@ -// gunbc/ci_workflow_expressions.dag β€” the typed GitHub Actions expressions `ci_workflow` emits. -// -// Single authority (DESIGN Β§3) for every `${{ … }}` expression in `.github/workflows/ci.yml`. -// `gunbc.ci_workflow` builds its scalar bytes by `serialize_template`-ing these typed templates -// (never inline `${{ }}` strings); the model-walk witnesses walk this same roster (never grep the -// emitted YAML). Both faces of the medium-as-Node guard close on one definition each. -// -// `ci_workflow_expression_templates` is the complete roster of the workflow's expression sites, so -// a model-walk over it covers the whole CI workflow's expression medium with no blind spot. A new -// `${{ }}` site is added here as a typed template, not as an inline string in `ci_workflow`. - module gunbc.ci_workflow_expressions import extdeps.github.expressions { @@ -18,7 +7,6 @@ import extdeps.github.expressions { serialize_template, runner_os, runner_arch, runner_temp } -// hashFiles('**/Cargo.lock', 'rust-toolchain.toml') fn ci_cache_hash_files() -> Expression { FunctionCall { function: HashFiles, @@ -29,7 +17,6 @@ fn ci_cache_hash_files() -> Expression { } } -// github.event.pull_request.number || github.run_id fn ci_concurrency_discriminator() -> Expression { LogicalOr { left: ContextAccess { context: Github, path: ["event", "pull_request", "number"] }, @@ -37,7 +24,6 @@ fn ci_concurrency_discriminator() -> Expression { } } -// concurrency group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.run_id }} data ci_concurrency_group_template: ExpressionTemplate = { segments: [ Interpolation { expression: ContextAccess { context: Github, path: ["workflow"] } }, @@ -46,14 +32,12 @@ data ci_concurrency_group_template: ExpressionTemplate = { ] } -// Setup Rust step `HOME`: ${{ runner.temp }} data ci_setup_rust_home_template: ExpressionTemplate = { segments: [ Interpolation { expression: runner_temp() } ] } -// Cache Cargo `path:` (block scalar body β€” runner.temp for every cached dir). data ci_cache_path_template: ExpressionTemplate = { segments: [ Interpolation { expression: runner_temp() }, @@ -65,7 +49,6 @@ data ci_cache_path_template: ExpressionTemplate = { ] } -// Cache Cargo `key:`: cargo-ci-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles(...) }} data ci_cache_key_template: ExpressionTemplate = { segments: [ LiteralText { text: "cargo-ci-" }, @@ -77,7 +60,6 @@ data ci_cache_key_template: ExpressionTemplate = { ] } -// Cache Cargo `restore-keys:`: cargo-ci-${{ runner.os }}-${{ runner.arch }}-\n data ci_cache_restore_keys_template: ExpressionTemplate = { segments: [ LiteralText { text: "cargo-ci-" }, @@ -88,7 +70,6 @@ data ci_cache_restore_keys_template: ExpressionTemplate = { ] } -// The complete roster of the workflow's expression sites (what the model-walk witnesses walk). data ci_workflow_expression_templates: List = [ ci_concurrency_group_template, ci_setup_rust_home_template, @@ -97,7 +78,6 @@ data ci_workflow_expression_templates: List = [ ci_cache_restore_keys_template ] -// Serialized-bytes accessors consumed by `gunbc.ci_workflow` (the emit side). fn ci_concurrency_group() -> String { serialize_template(template: ci_concurrency_group_template) } fn ci_setup_rust_home() -> String { serialize_template(template: ci_setup_rust_home_template) } fn ci_cache_path() -> String { serialize_template(template: ci_cache_path_template) } diff --git a/dsl/gunbc/ci_yaml_emit.dag b/dsl/gunbc/ci_yaml_emit.dag index d0572f91a45..70b7cfe8c04 100644 --- a/dsl/gunbc/ci_yaml_emit.dag +++ b/dsl/gunbc/ci_yaml_emit.dag @@ -1,8 +1,3 @@ -// gunbc/ci_yaml_emit.dag β€” composed CI workflow YAML projection. -// -// `runs-on:` is derived from `gunbc_ci_fleet_offer` via `runner_spec_from_offer` -// (Phase 3a seam) β€” see gunbc.ci_fleet + gunbc.runner_spec_from_offer. - module gunbc.ci_yaml_emit import extdeps.formats.yaml { serialize_yaml } @@ -13,7 +8,6 @@ fn expected_ci_yml() -> String { serialize_yaml(v: project_workflow_to_yaml(workflow: ci_workflow)) } -// Drift check shared by the gate and discriminating witnesses (committed == projection). fn ci_yml_drifted(committed: String) -> Bool { !(committed == expected_ci_yml()) } diff --git a/dsl/gunbc/ci_yaml_validate.dag b/dsl/gunbc/ci_yaml_validate.dag index 03f83d9b01f..6f31f9c6e1e 100644 --- a/dsl/gunbc/ci_yaml_validate.dag +++ b/dsl/gunbc/ci_yaml_validate.dag @@ -1,9 +1,3 @@ -// gunbc/ci_yaml_validate.dag β€” host YAML parse check for generated ci.yml bytes. -// -// DESIGN Β§5: drift equality alone is insufficient; the committed file must parse as YAML. -// Tries python3 PyYAML first, then actionlint on PATH, then the hand-written `yaml_check` -// seed bin (SCAFFOLD β€” see `src/v1/stage0/src/bin/yaml_check.rs` dissolution trigger). - module gunbc.ci_yaml_validate import extdeps.shell @@ -16,10 +10,6 @@ import extdeps.languages.bash.program { data yaml_check_release_bin: String = "target/release/yaml_check" -// python3 -c '...' 2>/dev/null -// || actionlint 2>/dev/null -// || (test -x && ) -// || cargo run -q -p v1-compiler --release --bin yaml_check -- fn ci_yml_parse_program(path: String) -> ShellProgram { let p = lit(text: path) let bin = lit(text: yaml_check_release_bin) diff --git a/dsl/gunbc/design_argument.dag b/dsl/gunbc/design_argument.dag index a6deb37bcc1..792fb53f5d9 100644 --- a/dsl/gunbc/design_argument.dag +++ b/dsl/gunbc/design_argument.dag @@ -1,23 +1,3 @@ -// gunbc/design_argument.dag β€” DESIGN.md's own argument, as data (the Β§7 recursion). -// -// The axiom+syllogism lens's first target is DESIGN.md itself (DESIGN open thread #1): -// the document checking that its own serial structure is a real consequence-chain back -// to the axioms, not a circle. This module is the INSTANCE β€” the A1-A3 axioms and the -// Β§1 consequence rows β€” kept OUT of std/ (it is a fact about gunbc's own DESIGN, not a -// universal framework, exactly as doc_reachability homes the doc-graph instance outside -// std/). The framework it runs over is std/syllogism.dag (Β§3 single authority). -// -// SCOPE: Β§1 only β€” the smallest NON-VACUOUS argument (A1-A3 + their immediate -// consequences), per the "DESIGN as the FIRST target" reading. Β§2-Β§7 rows (and the -// independent-peer sections, which root into their OWN licensing axiom) land on top -// incrementally once this slice is green. -// -// These rows are the "map" step of Β§2's decompress -> map -> reduce: DESIGN's prose -// already NAMES each edge ("From A1 and A2 β€”", "From A2 and A3 β€”", "A1-A2 turned on -// grounding itself"), so the model transcribes the stated premises, it does not invent -// them. A1-A3 are NonLogicalAxiom (domain postulates of the gunbc theory; the Β§1 prose -// "assumed, not derived"). - module gunbc.design_argument import std.syllogism { @@ -25,8 +5,6 @@ import std.syllogism { Proposition, Argument } -// DESIGN Β§1 β€” "The objective (the axioms)". Three NON-LOGICAL axioms: assumed, -// not derived; domain postulates about goals / time / agreement, not tautologies. data design_axioms: List = [ Axiom { id: "A1", @@ -45,21 +23,20 @@ data design_axioms: List = [ } ] -// DESIGN Β§1's three stated consequences β€” each names the premises the prose cites. data design_section_1_propositions: List = [ - // "From A1 and A2 β€” the solution is minimal, safe, efficient." + Proposition { id: "s1.minimal-safe-efficient", statement: "the solution is minimal, safe, efficient: a solution is good insofar as it spends less of the only thing valued, time (cost, safety, complexity)", premises: ["A1", "A2"] }, - // "From A2 and A3 β€” grounding is intersubjective." + Proposition { id: "s1.grounding-intersubjective", statement: "grounding is intersubjective: because time is the only assumed-shared value, a fact is grounded only by pointing at a shared, time-stable framework", premises: ["A2", "A3"] }, - // "At the limit β€” reduce intersubjectivity to physics." β€” "A1-A2 turned on grounding itself". + Proposition { id: "s1.reduce-to-physics", statement: "at the limit, reduce intersubjectivity to physics: the efficient, time-bound description of interactions that satisfies a goal β€” A1-A2 turned on grounding itself", @@ -67,7 +44,6 @@ data design_section_1_propositions: List = [ } ] -// The DESIGN Β§1 argument: the non-logical axioms and the consequences they entail. data design_section_1_argument: Argument = Argument { axioms: design_axioms, propositions: design_section_1_propositions diff --git a/dsl/gunbc/digest_render.dag b/dsl/gunbc/digest_render.dag index 4a737ae4e42..ecd072157fa 100644 --- a/dsl/gunbc/digest_render.dag +++ b/dsl/gunbc/digest_render.dag @@ -1,26 +1,9 @@ -// gunbc/digest_render.dag -- PR digest render/projection for ctrl migration catalog #8. -// -// Phase-3 receipt: this module is gunbc-owned rendering/projection over the -// existing GitHub source facts in `dsl/extdeps/github/pulls.dag` plus shared -// structured-text primitives from `dsl/std/render.dag`. -// -// Placement discipline: -// - extdeps.github.pulls owns provider source facts (`PullRequest`, -// `PullReview`, `PullRequestRef`). -// - this module owns repo-specific digest rendering. -// - no field is added to `PullRequest`; derived digest views stay here. -// -// Trio anchor: catalog #8 PR digests, paired with Phase 1.5 -// `dsl/ctrl/pr_digests.dag` modeling and the named parity harness. - module gunbc.digest_render import extdeps.github.pulls { PullRequest, PullReview, PullRequestState, ReviewState, Open } import std.render { kv_pair, list_block } import std.types { Url } -// -- Derived digest projection ----------------------------------------- - type PullRequestDigestSubject { number: Int title: String @@ -35,20 +18,6 @@ type DigestReadinessProjection = DigestOpenForReview | DigestNotReady { first_reason: String, more_reasons: List } -// Practice-4 receipt -- GREEN terminal for the narrowed catalog #8 Phase-3 -// digest-render surface. Ledger: -// - classification: current-PR render projection only, over `PullRequest` -// facts already owned by `extdeps.github.pulls`. -// - dissolution pattern: closed two-arm coproduct (`DigestOpenForReview` vs -// structurally nonempty `DigestNotReady`) because this projection does not -// claim CI/conflict/current-review authority. -// - non-authority receipt: review states remain raw rendered history below -// because `PullReview` is a flat review-event carrier, not an authoritative -// current-review-decision model. -// - extension trigger: a future CI/conflict/mergeability or current-review -// source-fact landing extends this module or a sibling projection, not -// `PullRequest`. - type PullRequestDigestView { subject: PullRequestDigestSubject readiness: DigestReadinessProjection @@ -117,8 +86,6 @@ fn project_pull_request_digest(pr: PullRequest, reviews: List) -> Pu } } -// -- Rendering ---------------------------------------------------------- - fn render_readiness(readiness: DigestReadinessProjection) -> String { match readiness { DigestOpenForReview => "open for review" diff --git a/dsl/gunbc/gunbhub_serve.dag b/dsl/gunbc/gunbhub_serve.dag index 8b013464197..da11b3dae1e 100644 --- a/dsl/gunbc/gunbhub_serve.dag +++ b/dsl/gunbc/gunbhub_serve.dag @@ -1,14 +1,3 @@ -// gunbc/gunbhub_serve.dag β€” gunbhub M2 served render surface. -// -// Consumer-owned ServedStaticRouteTable for the shared http-serve host -// (quick-crane L2). Bodies are serialize_fragment output strings, composed -// and XSS-checked at table-build time (not per-request). Host binds, -// serves GET, returns status_on_hit+body or 404 β€” gunbhub supplies only the table. -// -// Placement: gunbc-owned product surface (ctrl README Β§Conventions). -// HTTP wire facts stay in extdeps.http.server; page composition and -// requestβ†’response binding live here. - module gunbc.gunbhub_serve import std.types { HttpMethod, HttpStatus, GET } @@ -45,8 +34,6 @@ import extdeps.http.server { ServedStaticRouteTable, } -// --- Request / response carriers (dispatch witness) ------------------------ - type GunbhubServeRequest { method: HttpMethod path: String @@ -57,24 +44,18 @@ type GunbhubHttpResponse { body: String } -// 🟒 TERMINAL β€” closed serve outcome for the M2 literal-route surface. -// Extension trigger (M3): forge-backed NotFound when object lookup fails. type GunbhubServeResult = Served { response: GunbhubHttpResponse } | RenderRejectedBeforeServe { reason: String } | RouteNotFound | MethodNotAllowed -// 🟒 TERMINAL β€” React consumer page source (M2 browse route). type GunbhubPageSource = ReactPage { node: MarkupNode } -// 🟒 TERMINAL β€” closed render outcome for per-request page-source serve path. type GunbhubRenderResult = RenderedHtml { html: String } | RenderRejected { reason: String } -// --- Browse page (R1 structural compose; M3 replaces hardcoded entries) ---- - fn gunbhub_browse_entry(name: String) -> MarkupNode { ElementNode { tag: "li", @@ -112,7 +93,6 @@ fn gunbhub_browse_page() -> MarkupNode { } } -// Hostile fixture β€” javascript: href must be rejected before any response body. fn gunbhub_hostile_page() -> MarkupNode { ElementNode { tag: "a", @@ -121,8 +101,6 @@ fn gunbhub_hostile_page() -> MarkupNode { } } -// README doc view β€” M1 placeholder: react-composed body until std.markdown -// consumer merges; swap body builder when M1 lands (table shape unchanged). fn gunbhub_readme_page() -> MarkupNode { ElementNode { tag: "article", @@ -146,7 +124,6 @@ fn gunbhub_readme_page() -> MarkupNode { } } -// 🟒 TERMINAL β€” closed compose outcome for static-table body serialization. type GunbhubComposeResult = ComposedOk { html: String } | ComposeRejected { reason: String } @@ -171,7 +148,6 @@ fn gunbhub_browse_path_template() -> PathTemplate { } } -// BEST-GUESS encoding (sync with quick-crane-803): single-segment /{repo-path}. fn gunbhub_repo_path_template() -> PathTemplate { PathTemplate { tokens: [ParamToken { name: "repo-path" }] } } @@ -235,8 +211,6 @@ fn path_matches_template(template: PathTemplate, path: String) -> Bool { st.ok && st.seg_idx == count(xs: segs) } -// --- Render through canonical consumers ------------------------------------ - fn render_gunbhub_page(source: GunbhubPageSource) -> GunbhubRenderResult { match source { ReactPage { node } => @@ -261,8 +235,6 @@ fn serve_gunbhub_page_source(source: GunbhubPageSource) -> GunbhubServeResult { } } -// --- Route table + host static serve table ----------------------------------- - type GunbhubRouteRow { route: HttpServerRoute page: GunbhubPageSource @@ -307,8 +279,6 @@ fn gunbhub_route_table() -> List { ] } -// ServedStaticRouteTable the shared host consumes. Bodies serialized at compose time. -// ComposeRejected rows are OMITTED (fail-closed: host 404s, not empty 200). fn gunbhub_served_static_route_table() -> ServedStaticRouteTable { let routes = fold( xs: gunbhub_route_table(), @@ -394,8 +364,6 @@ fn serve_gunbhub_request(req: GunbhubServeRequest) -> GunbhubServeResult { } } -// --- route β†’ handler binding (consumer-owned; host attaches at deploy) ----- - fn gunbhub_node_route_bindings() -> List { map( xs: gunbhub_route_table(), diff --git a/dsl/gunbc/gunbhub_serve_html.dag b/dsl/gunbc/gunbhub_serve_html.dag index 7f787b82a02..b44e8472d5b 100644 --- a/dsl/gunbc/gunbhub_serve_html.dag +++ b/dsl/gunbc/gunbhub_serve_html.dag @@ -1,5 +1,3 @@ -// gunbc/gunbhub_serve_html.dag β€” Html consumer arm for gunbhub serve. - module gunbc.gunbhub_serve_html import std.markup { diff --git a/dsl/gunbc/idea_pr_spine.dag b/dsl/gunbc/idea_pr_spine.dag index 3a3fdda746f..5bff108ae11 100644 --- a/dsl/gunbc/idea_pr_spine.dag +++ b/dsl/gunbc/idea_pr_spine.dag @@ -1,13 +1,3 @@ -// gunbc/idea_pr_spine.dag β€” minimal flat spine for workflow_recursive witnesses. -// -// Slice of ctrl plans.idea_pr_spine relocated for gunbc harness re-proof. -// Consumes std.reducible.ReduceVerdict (not re-minted). -// -// Layer direction: gunbc (product/workflow) imports ctrl.review_verdict β€” the -// established review-authority substrate in dsl/ctrl (staged, v2-runnable). -// No dsl/gunbc/*.dag imported ctrl.* before this slice; the direction is -// intentional: review facts live in ctrl, ideaβ†’PR spine consumes them. - module gunbc.idea_pr_spine import std.types { List } diff --git a/dsl/gunbc/operator_fleet.dag b/dsl/gunbc/operator_fleet.dag index e827fa74629..005ce177cd4 100644 --- a/dsl/gunbc/operator_fleet.dag +++ b/dsl/gunbc/operator_fleet.dag @@ -1,14 +1,3 @@ -// gunbc/operator_fleet.dag β€” the operator fleet inventory (srv1 + srv2 as compute-fabric hosts). -// -// srv1 + srv2 as real ComputeOffer values (ASRock Rack ALTRAD8UD-1L2T, Ampere Altra M128-30, -// 128c/128t, 128 GiB DDR4). PUBLIC in gunbc β€” we skip the private ctrl repo. The privacy -// boundary is handled in-repo: rotated BMC credentials are std.credentials handles (never -// committed); operator-private distro left absent. The operator owns the fleet (provider). -// -// Plain inventory β€” the spawn-width/allocator/placement modeling was removed as unwired -// complexity; this is the authority that CI/sessions/placement can derive from when a real -// consumer needs it. - module gunbc.operator_fleet import gunbc.operator_fleet_network { operator_host_srv1, operator_host_srv2 } @@ -36,7 +25,6 @@ import product.compute_fabric { Dram, } -// Shared host facts (the two hosts are identical hardware). data operator_fleet_cpu: CpuFacts = CpuFacts { catalog: altra_max_m12830_catalog, deployment: CpuDeploymentFacts { sustained_per_thread_hz: hertz(3000000000) }, @@ -44,13 +32,12 @@ data operator_fleet_cpu: CpuFacts = CpuFacts { data operator_fleet_os_surface: OperatingSystemSurface = OperatingSystemSurface { kernel: Linux, - distro_or_product: none, // operator-private β€” resolved at runtime, never committed (skip-ctrl) + distro_or_product: none, version: none, filesystem_semantics: Posix, process_semantics: PosixProcess, } -// Baseboards (out-of-band BMC management plane). data srv1_baseboard: ServerBaseboard = ServerBaseboard { catalog: asrock_altrad8ud_1l2t_catalog, bmc: BmcEndpoint { host: "192.168.1.183", protocol: Redfish }, @@ -60,7 +47,6 @@ data srv2_baseboard: ServerBaseboard = ServerBaseboard { bmc: BmcEndpoint { host: "192.168.1.184", protocol: Redfish }, } -// Rotated BMC credentials: HANDLES only, value NEVER committed (the skip-ctrl privacy). data srv1_bmc_credential: CredentialFlow = Stored { secret_name: "bmc-srv1-admin" } data srv2_bmc_credential: CredentialFlow = Stored { secret_name: "bmc-srv2-admin" } @@ -121,5 +107,4 @@ data srv2_offer: ComputeOffer = ComputeOffer { constraints: [], } -// The fleet: the single inventory authority CI / sessions / placement derive from. data operator_fleet_offers: List = [srv1_offer, srv2_offer] diff --git a/dsl/gunbc/operator_fleet_network.dag b/dsl/gunbc/operator_fleet_network.dag index 80f6cbcf378..d9091b1279d 100644 --- a/dsl/gunbc/operator_fleet_network.dag +++ b/dsl/gunbc/operator_fleet_network.dag @@ -1,12 +1,3 @@ -// gunbc/operator_fleet_network.dag β€” measured operator fleet network topology (3a-ours). -// -// Concrete srv1/srv2 attachment points grounded by operator probes 2026-06-20: -// flat LAN 192.168.1.0/24 (gw .1); srv1=.185 / srv2=.188; BMCs .183 / .184; -// tailscale 100.69.18.126 / 100.73.169.40 on tailecbe08.ts.net; -// docker bridges 172.17.0.0/16 (both hosts) + 172.18.0.0/16 (srv1 second stack). -// -// Consumed by placement + BMC reachability grounding; secrets remain in ctrl. - module gunbc.operator_fleet_network import product.network_topology { diff --git a/dsl/gunbc/parse_allowlist.dag b/dsl/gunbc/parse_allowlist.dag index 2c6ff67de55..5bbcf953524 100644 --- a/dsl/gunbc/parse_allowlist.dag +++ b/dsl/gunbc/parse_allowlist.dag @@ -1,9 +1,3 @@ -// gunbc/parse_allowlist.dag β€” enumerated v2 parse-debt allowlist for gate-1. -// -// Shrink-only ratchet on v2 parser debt (1 entry remaining; the ci_emission.dag entry -// was retired with the CI-track rework). Paying debt removes entries; growth requires -// explicit justification. - module gunbc.parse_allowlist import std.types { FilePath } diff --git a/dsl/gunbc/roadmap_authority.dag b/dsl/gunbc/roadmap_authority.dag index fc3787c4c3a..3d5eb699027 100644 --- a/dsl/gunbc/roadmap_authority.dag +++ b/dsl/gunbc/roadmap_authority.dag @@ -1,30 +1,3 @@ -// gunbc/roadmap_authority.dag β€” the REAL ROADMAP, authored as `.dag` data (the transcription). -// -// SCAFFOLD (DESIGN Β§7 / plan invert-hand-maintained Β§6 step 2-3): this is the markdown analogue of -// ci.yml's authored `data ci_workflow` β€” the single AUTHORITY the ROADMAP.md projection is derived from. -// `project_roadmap_to_markdown(roadmap_authority(), merged)` emits the document; the eventual effectful -// `RoadmapGate` byte-compares the committed ROADMAP.md against that emission (the `ci_yaml_gate` shape). -// dissolution-trigger: the authored `data` is INTERMEDIATE (mirrors ci.yml's authored workflow); the -// TERMINAL is bridging the structure from `ctrl.process_algebra.ProcessGraph` once v2 self-host gives -// in-substrate graph traversal, at which point this authored authority dissolves into a walk over the -// work graph (plan Β§6 / DESIGN Β§7 recursion). -// -// FRAME IS THE WIN (warm-lark-306 ruling): model the FRAME faithfully β€” checkbox lines + their PR -// bindings, sub-group labels, plan-doc pointers, the section/forest structure β€” and carry PURE PROSE -// (section intros, the `β—† Milestones` spine) as OPAQUE authored Strings emitted VERBATIM (the Β§5 -// DecodeFidelity fence). Prose is NOT modelled into medium constructs; whole-file byte-exact prose is -// not the goal, the frame-gate is the honest stop. -// -// COMPLETES-IFF, not mention (DESIGN Β§5, plan Β§5): a line is a `DerivableLine` (box DERIVED from `prs`, -// `(#ref)` emitted from the binding) ONLY where the bound PR(s) are the line's completion. A line that -// merely MENTIONS a PR as partial evidence, or whose box is hand-set, is an `AuthoredLine` (verbatim) β€” -// a mention carries no `prs`, so it cannot false-derive a box (the soundness boundary is structural). -// -// STATUS = MERGED REALITY (warm-lark-306, the 6 corrections): rows are authored to what has actually -// merged on main, NOT transcribed from the stale committed ROADMAP. The corrections are flagged inline -// where they apply (C1 measure rows, C2 round-trip law, C3 inversion sub-rows, C4 self-host no-overclaim, -// C5 edge-(b) scoped-not-greenlit). - module gunbc.roadmap_authority import gunbc.roadmap_document { RoadmapDocument, RoadmapSection } @@ -36,24 +9,16 @@ import gunbc.roadmap_status { RoadmapItem, DerivableLine, AuthoredLine } import ctrl.process_algebra { ProcessNodeId } import std.markdown { MarkdownBlock, HeadingBlock, ParagraphBlock, TextInline, H1 } -// === Node constructors (terse line authoring) =============================== - -// ProcessNodeId is a branded NonEmptyStr; mint one from a kebab id literal. (Identity + deps are the -// ProcessGraph's authority β€” these ids stand in until the graph traversal bridge lands, plan Β§6.) fn nid(s: String) -> ProcessNodeId { s } -// An AUTHORED checkbox line: hand-set box, `content` emitted verbatim (the Β§5 fence; bold/refs/links -// live IN the String). The honest default for mentions + hand-checked lines. fn authored(id: String, done: Bool, content: String) -> RoadmapNode { RoadmapNode { node: nid(s: id), line: AuthoredLine { done: done, content: content }, carrier: NoCarrier } } -// An authored line carrying a plan-doc pointer (rendered as ` [plan](path)`; a dangling path is the -// emit error β€” the construction wall, plan Β§2). + fn authored_doc(id: String, done: Bool, content: String, path: String) -> RoadmapNode { RoadmapNode { node: nid(s: id), line: AuthoredLine { done: done, content: content }, carrier: PlanDoc { path: path } } } -// A DERIVABLE checkbox line: box derived from `prs` (done iff all merged), `(#ref)` emitted from the -// binding, `title` bolded by emit, `description` the fenced refs-free prose tail. The inversion. + fn derivable(id: String, prs: List, title: String, description: String) -> RoadmapNode { RoadmapNode { node: nid(s: id), line: DerivableLine { prs: prs, title: title, description: description }, carrier: NoCarrier } } @@ -61,8 +26,6 @@ fn derivable_doc(id: String, prs: List, title: String, description: String, RoadmapNode { node: nid(s: id), line: DerivableLine { prs: prs, title: title, description: description }, carrier: PlanDoc { path: path } } } -// === The document preamble =================================================== - fn preamble() -> List { [ HeadingBlock { level: H1, inlines: [TextInline { text: "gunbc β€” Roadmap" }] }, @@ -72,8 +35,6 @@ fn preamble() -> List { ] } -// === Β§0. Fail-closed lock-down =============================================== - fn section_0() -> RoadmapSection { RoadmapSection { title: "0. Fail-closed lock-down LANE β€” BLOCKS expansion into products", @@ -94,12 +55,12 @@ fn section_0() -> RoadmapSection { section_group( label: "In-scope this window", nodes: [ - // C: numeric-tower grounding completes iff #5428 merged β€” DERIVABLE (the inversion). + derivable_doc(id: "0-numeric-tower", prs: [5428], title: "numeric-tower grounding", description: "β€” `Int=GroupCompletion`; `==` straddle guard now dead-in-corpus", path: "docs/plans/model-realization-fork.md"), authored(id: "0-cache-trustworthy", done: false, content: "**cache trustworthy** β€” authoritative home is Β§2 F2/F3/P1; ship the warm==cold oracle as a detective now"), authored_doc(id: "0-rust-gate", done: false, content: "**rust-gate coverage** (shared Β§1) β€” opt-level=3 restores Pop-A to per-PR (#5456); run-all-unless-`#[ignore]`d (#5427)", path: "docs/plans/ci-selection-vs-scheduling.md"), authored(id: "0-promote-lenses", done: false, content: "**promote-or-delete inert lenses Β· de-vacuum gates** β€” EmitHostGate de-vacuumed βœ“ (#5477); 4 advisory lenses widened+bounded, whole-corpus deferred to `.dag` structural-reflection *(silent-wren-739)*"), - // realization-vocabulary containment guard completes iff #5445/#5453 β€” DERIVABLE. + derivable_doc(id: "0-realization-vocab", prs: [5445, 5453], title: "realization-vocabulary containment guard", description: "β€” target-AST importable only at the realization edge (fail-closed, shrinking-roster)", path: "docs/plans/emission-ingestion-inverse.md"), authored(id: "0-stage0-census", done: false, content: "**stage0 clone-census inert + seed regressed** to 21540 (~1138 over) β€” resolve by clone-reduction / substrate-migration, NEVER a cap-bump; #5427 `#[ignore]` is the interim *(fierce-hawk-540 via quick-ant-298)*"), ], @@ -110,7 +71,7 @@ fn section_0() -> RoadmapSection { nodes: [ authored(id: "0-value-null", done: false, content: "**split `Value::Null`** (None/Absent/miss/Violates β†’ own carriers) β€” ~131-site substrate change, the deeper root; own runway"), authored(id: "0-selfhost-purity", done: false, content: "**self-host purity gate** β€” a Β§5 deliverable, not Β§0 (avoids the Β§0↔§5 cycle)"), - // cross-tree import activation LANDED iff #5473 β€” DERIVABLE (the Β§0↔§5 escalate item now closed). + derivable(id: "0-cross-tree", prs: [5473], title: "cross-tree import activation (Β§5)", description: "β€” LANDED; the Β§0↔§5 escalate item is now closed"), authored_doc(id: "0-disposition", done: false, content: "**`Disposition` carrier** β€” a new concept; parked", path: "docs/plans/disposition-carrier.md"), authored(id: "0-complexity-residue", done: false, content: "complexity-budget whole-codebase (Β§3) Β· cache-redundancy completeness (Β§2 P3) β€” residue, after construction"), @@ -120,11 +81,11 @@ fn section_0() -> RoadmapSection { section_group( label: "Meta β€” lock down the reasoning (Β§7 recursion)", nodes: [ - // inert-lens hygiene backstop completes iff #5433 β€” DERIVABLE. + derivable(id: "0-inert-hygiene", prs: [5433], title: "inert-lens hygiene backstop", description: "β€” every `lens/*.dag` wired or deleted; runs over the corpus"), authored_doc(id: "0-reachability", done: false, content: "**reachability-completeness lens** β€” every declared node (code carrier Β· doc Β· lens) reachable from a run-root, rostered, or deleted; generalizes #5433 to carriers + docs", path: "docs/plans/inert-layer-lens.md"), authored_doc(id: "0-gate-hygiene", done: false, content: "**gate-hygiene: a floor-enrolled gate must be green-on-main at merge** β€” roster-completeness assertion promoted to should-land *(quick-ant-298)*", path: "docs/plans/emission-ingestion-inverse.md"), - // construction-justification rule completes iff #5476 β€” DERIVABLE. + derivable_doc(id: "0-construction-rule", prs: [5476], title: "construction-justification rule", description: "(authoring-time) β€” justify why a class can't be construction before adding a lens *(silent-wren-739)*", path: "docs/plans/construction-justification-rule.md"), authored_doc(id: "0-expressibility", done: false, content: "**expressibility frontier** β€” partition each modeling discipline into wall / lens-residue / undecidable-review *before* gating", path: "docs/plans/expressibility-frontier.md"), authored_doc(id: "0-skipped-modeling", done: false, content: "**confront the skipped modeling decisions** β€” the `🟑` comment backlog", path: "docs/plans/disposition-carrier.md"), @@ -136,8 +97,6 @@ fn section_0() -> RoadmapSection { } } -// === Β§1. CI under control ==================================================== - fn section_1() -> RoadmapSection { RoadmapSection { title: "1. CI under control (the correctness floor)", @@ -148,12 +107,10 @@ fn section_1() -> RoadmapSection { label: "", nodes: [ authored(id: "1-privacy", done: true, content: "privacy (compute fabric)"), - // C1 β€” MEASURE ROWS (bright-stag-194): MISSING from the committed ROADMAP; #5470/#5478 merged. - // The std.measure FLOOR + demand-CEIL families completing the ceil-not-equal-floor money-pair. + derivable_doc(id: "1-measure-foundation", prs: [5470, 5478], title: "Section 1 spawn-width foundation β€” std.measure expressibility", description: "β€” the FLOOR family (measure_scale_fraction_floor + measure_fit_count_floor) and the demand-CEIL family completing the ceil-not-equal-floor money-pair landed, dissolving the measure unwrapβ†’raw-arithβ†’rewrap Β§3 fork. Authority: the expressibility-frontier spec #5467", path: "docs/plans/expressibility-frontier.md"), authored_doc(id: "1-floor-right-things", done: false, content: "**floor runs the right things** β€” cadence = two axes: SELECTION (by *what changed*) vs SCHEDULING (by cost); cost never drives selection", path: "docs/plans/ci-selection-vs-scheduling.md"), - // Sub-items under "floor runs the right things" (nested via the edges below β€” same group so the - // forest resolves; the dependency edge IS the indentation, plan Β§2). + derivable(id: "1-opt3", prs: [5456], title: "opt-level=3 restores Pop-A to per-PR", description: "β€” merged"), authored(id: "1-per-pr-shrink", done: false, content: "per-PR = #5427 run-all sound baseline, shrunk to the affected set (#5427)"), authored(id: "1-nightly", done: false, content: "nightly = full-corpus selector-backstop + non-hermetic residue (#5447 stood down; ⚠ CI-gen load-bearing) *(quick-ant-298)*"), @@ -173,8 +130,6 @@ fn section_1() -> RoadmapSection { } } -// === Β§2. Minimal work β€” caching by realization =============================== - fn section_2() -> RoadmapSection { RoadmapSection { title: "2. Minimal work β€” caching by realization (fail-closed)", @@ -196,8 +151,6 @@ fn section_2() -> RoadmapSection { } } -// === Β§3. Complexity budget gate ============================================== - fn section_3() -> RoadmapSection { RoadmapSection { title: "3. Complexity budget gate (stability β€” validation)", @@ -208,7 +161,7 @@ fn section_3() -> RoadmapSection { label: "", nodes: [ authored(id: "3-complexity-lens", done: true, content: "complexity lens total over the kernel (cost.dag U2); the gate runs a curated subject roster"), - // cost-lens zero-absorption fix / budgets non-toothless completes iff #5437 β€” DERIVABLE. + derivable(id: "3-cost-lens", prs: [5437], title: "cost-lens zero-absorption fix β€” budgets non-toothless", description: ""), authored(id: "3-synthesis-advisory", done: false, content: "synthesis stays advisory (by Rice, optimality is a ratchet not a wall β€” DESIGN Β§5)"), ], @@ -219,8 +172,6 @@ fn section_3() -> RoadmapSection { } } -// === Β§4. Testgen as the bug-class oracle ===================================== - fn section_4() -> RoadmapSection { RoadmapSection { title: "4. Testgen as the bug-class oracle (coverage by construction)", @@ -242,16 +193,12 @@ fn section_4() -> RoadmapSection { } } -// === Β§5. Self-host v2 β†’ delete src/v1 ======================================== - fn section_5() -> RoadmapSection { RoadmapSection { title: "5. Self-host v2 β†’ delete `src/v1` (expansion)", elements: [ section_prose(content: "Anchor (do not flip-flop): `.dag` = truth; purely self-hosting (v2 emits its own seed, no stage0 hand-edits); emit Rust + TypeScript; then shrink the seed to zero. β†’ [plan](docs/plans/v2-self-hosting.md) Β· [de-fork audit](docs/plans/dsl-v2-defork-audit.md)"), - // C4 β€” SELF-HOST PATH-A no-overclaim (bright-stag): #5481 landed the class-3 corpus-coherence - // consolidation + cargo-green seed; Β§7 regen-fixpoint is DEFERRED (#5514), src/v1 NOT yet deletable. - // The milestone spine reads NOW=cargo-builds-green, KEYSTONE/TERMINAL ahead β€” NOT "self-host done". + section_prose(content: "**β—† Milestones (critical path):** front-end βœ“ Β· emit-rust well-typed βœ“ Β· de-fork Step 1 βœ“ (#5473) Β· class-3 corpus-coherence + cargo-green seed βœ“ (#5481) β†’ **β–Έ NOW: emitted crate cargo-builds green** β†’ std forks collapsed β†’ real fixed point β†’ **KEYSTONE: `regen --verify` in CI** β†’ seed-honesty β†’ **TERMINAL: `src/v1` deleted** *(Β§7 regen-fixpoint deferred, #5514; src/v1 NOT yet deletable)*"), section_group( label: "", @@ -262,7 +209,7 @@ fn section_5() -> RoadmapSection { authored(id: "5-frontend", done: true, content: "front-end (parse / resolve / infer) over the whole tree"), authored(id: "5-emit-rust", done: true, content: "emit whole tree `--target rust` (well-typed under CI gate)"), authored(id: "5-defork", done: false, content: "de-fork dsl ↔ v2 (one std authority, no historical forks)"), - // de-fork Step 1 LANDED iff #5473 β€” DERIVABLE; nested under "de-fork dsl ↔ v2". + derivable(id: "5-defork-step1", prs: [5473], title: "turn on cross-tree import β€” Step 1 LANDED", description: "β€” PR-B (collapse forks) next *(nimble-koi-625)*"), authored(id: "5-cargo-green", done: false, content: "emitted crate `cargo build`s green (Route-A last mile)"), authored(id: "5-cargo-fixpoint", done: false, content: "real fixed point: `content_hash` stage1==stage2 (dissolve placeholder hashes) β†’ wire `regen_stage0 --verify` lockstep gate into CI (keystone) β†’ collapse `src/v1` β†’ pinned v2-emitted seed (terminal, not a big-bang `rm`)"), @@ -276,8 +223,6 @@ fn section_5() -> RoadmapSection { } } -// === Β§6. idea β†’ idea compiler ================================================ - fn section_6() -> RoadmapSection { RoadmapSection { title: "6. idea β†’ idea compiler (expansion β€” stop anchoring on code)", @@ -288,10 +233,7 @@ fn section_6() -> RoadmapSection { label: "", nodes: [ authored(id: "6-medium-axis", done: true, content: "**medium axis** β€” `Medium` + `DecodeFidelity`; `LanguageModel` unified (13 forks dissolved); `compile(Eval) β†’ EvalResult\{value: Medium\}`"), - // C2 β€” ROUND-TRIP LAW (bright-stag + quick-seal-137): established across TWO structurally- - // different media β€” markdown (#5525) AND GHA-expr (#5527) β€” generalize-threshold met. Distinct - // from the EMIT medium checkmark (no overclaim): v2-TargetModel convergence is the deferred - // single-authority destination; per-medium round-trips are v1-seed interim. Completes iff both. + derivable_doc(id: "6-roundtrip-law", prs: [5525, 5527], title: "round-trip law (ingest∘emit = id, DecodeFidelity-bounded)", description: "β€” established across two structurally-different media: markdown (block-document) and GHA-expr (recursive-expression). v2-TargetModel convergence is the deferred single-authority destination; per-medium round-trips are v1-seed interim. Authority for the law: the round-trip oracle #5513 Β§5.2", path: "docs/plans/emission-ingestion-inverse.md"), authored(id: "6-language-axis", done: false, content: "**language axis** β€” 15+ targets wave-1; English emit proven"), authored(id: "6-cross-media", done: false, content: "**cross-media targets beyond syntax** β€” JSON / react / diagram as first-class media (not stringified)"), @@ -299,13 +241,9 @@ fn section_6() -> RoadmapSection { authored(id: "6-fidelity-composeup", done: false, content: "`FidelityDisposition` compose-up β†’ medium-level `DecodeFidelity`"), authored(id: "6-eval-generalize", done: false, content: "eval runtime generalization (wave-1 literal pins β†’ `wave1_model_core` primitives)"), authored_doc(id: "6-invert", done: false, content: "**invert hand-maintained artifacts** β€” emit each (ROADMAP flagship Β· doc indexes) from its `.dag` authority + drift-gate it (the ci.yml pattern)", path: "docs/plans/invert-hand-maintained.md"), - // C3 β€” INVERSION SUB-ROWS (warm-lark-306): slice-1 (#5491 status derivation) + slice-2 (#5508 - // section-emit) + step-3a (#5520 projection layer) landed; step-3b (RoadmapItem fold) incoming. - // #5513 medium-as-Node is now operative as quick-seal's acceptance test. Completes iff the - // landed slices merged (step-3b not yet in this set β€” authored to current merged reality). - // Nested under "invert hand-maintained artifacts". + derivable_doc(id: "6-invert-status", prs: [5491, 5508, 5520], title: "PRβ†’checkbox status + section-emit + projection layer", description: "β€” box derived from an explicit *completes-iff-PR* binding (not mere mention), drift-gated; slice-1 status derivation + slice-2 section-emit + step-3a whole-document projection landed; #5513 medium-as-Node operative as the acceptance test", path: "docs/plans/invert-hand-maintained.md"), - // English sub-items nested under "language axis". + authored(id: "6-english-closure", done: false, content: "English vocabulary closure β†’ fail-closed English ingest (today's catch-all is fail-open; also Β§0)"), authored(id: "6-english-roundtrip", done: false, content: "English ingest round-trip (only emit proven today)"), ], @@ -319,8 +257,6 @@ fn section_6() -> RoadmapSection { } } -// === Β§7. HTML / React rendering ============================================== - fn section_7() -> RoadmapSection { RoadmapSection { title: "7. HTML / React rendering (expansion β€” the \"website\" sellable piece)", @@ -339,8 +275,6 @@ fn section_7() -> RoadmapSection { } } -// === Β§8. Session dashboard on .dag (SHELVED) ================================= - fn section_8() -> RoadmapSection { RoadmapSection { title: "8. Session dashboard on `.dag` (SHELVED)", @@ -357,10 +291,6 @@ fn section_8() -> RoadmapSection { } } -// === The whole authority ===================================================== - -// The REAL ROADMAP as the single `.dag` authority β€” preamble + the eight sections in priority order. -// `project_roadmap_to_markdown(roadmap_authority(), merged)` is the emitted ROADMAP.md. fn roadmap_authority() -> RoadmapDocument { RoadmapDocument { preamble: preamble(), diff --git a/dsl/gunbc/roadmap_document.dag b/dsl/gunbc/roadmap_document.dag index e126a57db5f..2fdda746b63 100644 --- a/dsl/gunbc/roadmap_document.dag +++ b/dsl/gunbc/roadmap_document.dag @@ -1,56 +1,23 @@ -// gunbc/roadmap_document.dag β€” the WHOLE-document roadmap authority + projection (slice-2 step-3). -// -// SCAFFOLD (DESIGN Β§7 / plan Β§6 step 2-3): widens the per-section projection (`roadmap_emit`) to the -// whole ROADMAP β€” `project_roadmap_to_markdown(authority) -> MarkdownDocument`, the markdown analogue of -// ci.yml's `project_workflow_to_yaml(ci_workflow)`. The authored `data` authority is the inversion: the -// `.dag` is the single source, ROADMAP.md is its emitted projection (the structure gate, step-3b, then -// byte-compares them β€” the `ci_yaml_gate` shape). -// dissolution-trigger: authored-now is the INTERMEDIATE (mirrors ci.yml's authored `data ci_workflow`); -// the TERMINAL is bridging the structure from `ctrl.process_algebra.ProcessGraph` once v2 self-host -// gives in-substrate graph traversal (it is STAGED today, no traversal fns), at which point the -// authored `data roadmap_authority` dissolves into a walk over the work graph. -// -// O3 DFS (why RoadmapSection is MINTED, not derived from top-level nodes): a ROADMAP `##` section is a -// SEPARATE presentation axis, not a single work-node + flat subtree β€” it carries authored intro prose, -// a plan-doc pointer, and MULTIPLE sub-grouped checkbox lists (`**Audits (done):**`, -// `**In-scope this window:**`). Its WORK content is the existing `RoadmapNode`/`RoadmapEdge` graph; the -// section adds the editorial grouping a work-node does not carry. So RoadmapSection earns its keep as -// the grouping axis β€” net concepts grow by ONE genuinely-distinct concept, not a re-invention (Β§2). - module gunbc.roadmap_document import std.markdown { MarkdownDocument, MarkdownBlock } import gunbc.roadmap_model { RoadmapNode, RoadmapEdge, SectionElement } import gunbc.roadmap_emit { project_roadmap_section } -// One ROADMAP section: an editorial title (the `##` heading) over an ORDERED element sequence -// (`SectionElement` = authored intro prose | a labelled checkbox sub-group). This subsumes the -// slice-2 single-list section (`nodes`+`edges`) β€” that flat list is now one `Group` element with an -// empty label, no fork (Β§3) β€” and carries the real ROADMAP's frame faithfully: intro prose + the -// `β—† Milestones` spine fenced as `Prose`, the `**…:**` sub-groups as `Group`s, all in document order. type RoadmapSection { title: String elements: List } -// The whole ROADMAP as authority. `preamble` is the document-level authored frame above the first -// section (the title/intro blocks) β€” so RoadmapDocument earns its keep over a bare `List` -// (Β§2: a 1-field wrapper would not). DISTINCT from `std.markdown.MarkdownDocument`: this is the -// AUTHORITY (work structure), that is the MEDIUM (rendered blocks) β€” authority vs medium stays split (Β§3). type RoadmapDocument { preamble: List sections: List } -// The medium blocks for one section: delegate to the per-section projection (step-2), take its blocks. fn section_blocks(s: RoadmapSection, merged: List) -> List { project_roadmap_section(title: s.title, elements: s.elements, merged: merged).blocks } -// THE whole-document projection (the ci.yml `project_workflow_to_yaml` analogue, markdown medium): -// preamble blocks, then each section's blocks in order. A pure fold over the authored authority β€” the -// checkbox boxes are rendered from each line's binding against `merged` (derived for a DerivableLine, -// authored for an AuthoredLine), exactly as the per-section projection does. fn project_roadmap_to_markdown(doc: RoadmapDocument, merged: List) -> MarkdownDocument { MarkdownDocument { blocks: fold(doc.sections, init: doc.preamble, f: fn(acc, s) { diff --git a/dsl/gunbc/roadmap_emit.dag b/dsl/gunbc/roadmap_emit.dag index cb7aeb8af38..249fd7533bd 100644 --- a/dsl/gunbc/roadmap_emit.dag +++ b/dsl/gunbc/roadmap_emit.dag @@ -1,20 +1,3 @@ -// gunbc/roadmap_emit.dag β€” project the roadmap work-model to Markdown (slice-2 step 2). -// -// SCAFFOLD (DESIGN Β§7 self-host / plan Β§6): the ROADMAP-specific projection in the SAME shape as -// ci.yml's `expected_ci_yml = serialize_yaml(project_workflow_to_yaml(...))` β€” here -// `expected_roadmap_md = serialize_markdown_source(project_roadmap_to_markdown(...))`, a dsl -// serializer fold on the v1 seed. The generic Markdown medium is deep-newt's -// `std.markdown` + `extdeps.languages.markdown.serialize_markdown_source` (row-driven). This module -// owns ONLY the roadmapβ†’Markdown projection; the medium is not re-modeled here. -// dissolution-trigger: the eventual v2 Markdown TargetModel (one grammar both ways, Β§4) supersedes -// the dsl serializer fold β€” at which point `project_roadmap_to_markdown` emits v2 Nodes and this -// composition retires, exactly as `serialize_yaml`/`ci_yaml_emit` will. -// -// The checkbox cell is where the DONE-authority decision lands (plan Β§6.1): a DerivableLine's box -// is DERIVED from the merged-PR set (the inversion β€” generated, not hand-toggled); an AuthoredLine's -// box is the AUTHORED one (honest un-derivable residue). So the generated ROADMAP cannot carry -// a stale checkbox on a PR-bound line. - module gunbc.roadmap_emit import std.markdown { @@ -26,31 +9,16 @@ import gunbc.roadmap_model { RoadmapParent, TopLevel, UnderParent, roadmap_parent, is_top_level, SectionElement, Prose, Group, SectionProse, SectionGroup, } -// Completion is a Bool here (Β§2: roadmap_status carries no 2-variant enum restating it). The ONLY -// checkbox-state type in the project is std.markdown's GFM glyph `CheckboxState = Checked | Unchecked`; -// this module maps the Bool onto that glyph in `task_item_with` below. The completion concept (Bool, -// roadmap_status) and the render-glyph concept (std.markdown.CheckboxState) stay distinct (Β§3). -// `RoadmapItem` is the closed line sum (DerivableLine | AuthoredLine) β€” emit dispatches the inline -// rendering on its arm (derived title vs verbatim authored content). + import gunbc.roadmap_status { RoadmapItem, DerivableLine, AuthoredLine, item_is_done } import ctrl.process_algebra { ProcessNodeId } -// Bounded nesting depth β€” the roadmap forest is shallow (sections β†’ items β†’ sub-items). Explicit fuel -// gives the recursion its strict-descent evidence (DESIGN Β§4 bounded-and-forward); a tree deeper than -// this truncates, which is loud (a missing deep item is visible drift), not silent corruption. fn roadmap_max_depth() -> Int { 8 } -// === The checkbox cell β€” DONE-authority (plan Β§6.1) ========================== - -// Whether a line's box SHOULD read done β€” the DONE-authority decision (plan Β§6.1), delegated whole to -// `roadmap_status.item_is_done` (DerivableLine β†’ derived from the merged set; AuthoredLine β†’ authored). -// Kept as a Bool so the markdown glyph lands in `MarkdownTaskItem.state` field position below. fn node_is_done(rn: RoadmapNode, merged: List) -> Bool { item_is_done(item: rn.line, merged: merged) } -// === Inline content β€” line arm + optional plan-doc link ====================== - fn carrier_inlines(carrier: PlanDocCarrier) -> List { match carrier { NoCarrier => [] @@ -61,10 +29,6 @@ fn carrier_inlines(carrier: PlanDocCarrier) -> List { } } -// The `(#ref)` annotation, EMITTED FROM THE BINDING (plan TASK-2 emit-refs-from-binding, Β§3 single -// authority): a DerivableLine's `prs` is the one source of both the derived box AND its rendered refs, -// so the `(#5445/#5453)` annotation is generated here, never hand-kept in prose. An empty binding emits -// no annotation. Mentions keep their refs in AuthoredLine prose (no binding to emit from). fn refs_text(prs: List) -> String { fold(prs, init: "", f: (acc, p) => if acc == "" { concat("#", to_string(p)) } else { concat(acc, concat("/#", to_string(p))) }) @@ -72,16 +36,11 @@ fn refs_text(prs: List) -> String { fn refs_inlines(prs: List) -> List { if count(prs) == 0 { [] } else { [TextInline { text: concat(" (", concat(refs_text(prs: prs), ")")) }] } } -// The fenced prose tail of a DerivableLine (verbatim, refs-free β€” the refs emit from `prs` above). A -// leading space separates it from the title/refs; empty renders nothing. + fn desc_inlines(description: String) -> List { if description == "" { [] } else { [TextInline { text: concat(" ", description) }] } } -// Render the line body by arm (the fold's payoff): a DerivableLine is a BOLD title (emit applies the -// markup) + its `(#ref)` annotation derived from `prs` + an optional fenced description tail; an -// AuthoredLine is its `content` String emitted VERBATIM as a single text inline (the Β§5 DecodeFidelity -// fence β€” any bold/refs/links live in the String, so opaque prose round-trips byte-exact). fn line_inlines(line: RoadmapItem) -> List { match line { DerivableLine { prs, title, description } => @@ -100,9 +59,6 @@ fn node_inlines(rn: RoadmapNode) -> List { ) } -// === The forest projection =================================================== - -// Direct children of `parent`: nodes whose decomposition parent is `parent`. fn children_of(nodes: List, edges: List, parent: ProcessNodeId) -> List { nodes |> filter(n => match roadmap_parent(edges: edges, node: n.node) { UnderParent { parent: p } => p == parent @@ -110,11 +66,6 @@ fn children_of(nodes: List, edges: List, parent: Proce }) } -// Build a task item from its done-flag + blocks. The glyph (`Checked`/`Unchecked`) sits DIRECTLY in -// `state:` field position in each branch β€” a bare nullary markdown constructor only resolves where its -// type (`MarkdownTaskItem.state`) is the expected type pushed onto it; it does NOT resolve through an -// `if`/match-arm into the field, nor inside a match-arm body (read there as a variable). Both branches -// build the same record type, so they unify cleanly. fn task_item_with(done: Bool, blocks: List) -> MarkdownTaskItem { if done { MarkdownTaskItem { state: Checked, blocks: blocks } @@ -123,9 +74,6 @@ fn task_item_with(done: Bool, blocks: List) -> MarkdownTaskItem { } } -// Map a roadmap node to a task item, nesting its children one indent level (fuel-bounded, Β§4). The -// status box is the DONE-authority decision (plan Β§6.1): DerivableLine β†’ derived from the merged set, -// AuthoredLine β†’ authored. fn task_item_for(rn: RoadmapNode, nodes: List, edges: List, merged: List, fuel: Int) -> MarkdownTaskItem { let para = ParagraphBlock { inlines: node_inlines(rn: rn) } let kids = if fuel > 0 { children_of(nodes: nodes, edges: edges, parent: rn.node) } else { [] } @@ -137,12 +85,6 @@ fn task_item_for(rn: RoadmapNode, nodes: List, edges: List) -> List { let tops = g.nodes |> filter(n => is_top_level(edges: g.edges, node: n.node)) let list = TaskListBlock { items: tops |> map(n => task_item_for(rn: n, nodes: g.nodes, edges: g.edges, merged: merged, fuel: roadmap_max_depth())) } @@ -156,8 +98,6 @@ fn group_blocks(g: SectionGroup, merged: List) -> List { } } -// One section element's blocks: authored prose emitted VERBATIM as a single-TextInline paragraph (the -// Β§5 fence β€” markup inside the String passes through untouched), or a checkbox sub-group. fn element_blocks(e: SectionElement, merged: List) -> List { match e { Prose { prose } => [ParagraphBlock { inlines: [TextInline { text: prose.content }] }] @@ -165,9 +105,6 @@ fn element_blocks(e: SectionElement, merged: List) -> List { } } -// One ROADMAP section: an H2 heading + its ordered element sequence (intro prose, the `β—† Milestones` -// spine, then one-or-more labelled checkbox sub-groups β€” interleaved IN DOCUMENT ORDER). A pure fold -// over `elements` preserving order; the whole-document projection maps this over sections. fn project_roadmap_section(title: String, elements: List, merged: List) -> MarkdownDocument { MarkdownDocument { blocks: fold(elements, diff --git a/dsl/gunbc/roadmap_model.dag b/dsl/gunbc/roadmap_model.dag index 269778f6166..668c6fe02ab 100644 --- a/dsl/gunbc/roadmap_model.dag +++ b/dsl/gunbc/roadmap_model.dag @@ -1,119 +1,46 @@ -// gunbc/roadmap_model.dag β€” the work-DAG authority model for a ROADMAP line (slice-2 step 1). -// -// The ROADMAP's own claim: "checkboxes are authoritative for progress … a task's real state is its -// branch/PR + the carrier marks." So the real authority is the WORK GRAPH + the substrate; the -// markdown is a hand-kept copy (a Β§2/Β§3 dual representation). Slice-2 inverts it β€” emit each line -// from its work node. This file is step 1: what a roadmap line *is* in `.dag`, grounded on the -// authorities that already exist (DFS-before-mint, Β§2/Β§3 β€” do NOT re-coin the work graph). -// -// A roadmap line is a PROJECTION of a work node, composed from three existing authorities + the two -// presentation fields the work graph does not carry: -// - IDENTITY + DEPENDENCY structure ← `ctrl.process_algebra` (`ProcessNodeId` + the -// `DecomposeProcessNode { parent, children }` decomposition; the indentation edge IS that -// parent/child relation). Referenced, never re-coined β€” the ProcessGraph stays the single -// authority for work structure. -// - STATUS-source ← `gunbc.roadmap_status.RoadmapItem` (DerivableLine #N | AuthoredLine), the -// slice-1 model folded one layer down β€” row 1 of this authority, widened here from "status of a -// line" to "the line is a projection of a work node". -// - TITLE + plan-doc CARRIER ← the line's presentation surface, host-fed (like the live PR set); -// `ProcessNodeFacts` carries neither (Phase-1 identity is the map key), so they are new fields, -// not a fork of the work graph. -// -// Pure modeling: every function takes its host-fed inputs (the decomposition edges, the existing-doc -// set, the merged-PR set) as PARAMETERS β€” no live bridge is wired here. The emitter (step 2) and the -// `roadmap_gate` (step 3, the `ci_yaml_gate` clone) supply them. -// -// Open (for the step-1 checkpoint): the work graph carries its OWN done-signal, `ProcessCloseState` -// (ProcessOpen | ProcessClosed). It and the PR-grounded `RoadmapItem` binding are two groundings of -// "done" that must agree (a node closes iff its completing PR merges). Slice-1/the parent chose the -// PR-grounded one (it ties the box to the artifact's real authority, and carries the Β§5 derivable / -// hand-checked boundary that close-state lacks). Reconciling the two is a bridge, flagged not built. - module gunbc.roadmap_model import ctrl.process_algebra { ProcessNodeId } import gunbc.roadmap_status { RoadmapItem, DriftVerdict, status_drift } -// The plan-doc pointer a line carries (`[plan](path)`), or none. A line may legitimately have no -// pointer; the path is repo-root-relative. type PlanDocCarrier = NoCarrier | PlanDoc { path: String } -// A roadmap line as a work-node projection. `line` reuses the slice-1 model WHOLE (the `RoadmapItem` -// closed sum: a DerivableLine's title + binding, or an AuthoredLine's verbatim content) β€” no field is -// re-coined; `node` binds it to the work graph (identity + deps live in the ProcessGraph, keyed by -// this id); `carrier` is the plan-doc pointer. The COMMITTED box is not stored here β€” it is host-fed -// from the committed ROADMAP file at drift-check time (a DerivableLine derives its box, an AuthoredLine -// carries its own), so the node holds only the authority, never a copy of the rendered box. type RoadmapNode { node: ProcessNodeId line: RoadmapItem carrier: PlanDocCarrier } -// One indentation/dependency edge, a PROJECTION of the `ctrl.process_algebra` decomposition -// (parent β†’ child); the ProcessGraph is the single authority, this is its rendered view, never a -// hand-kept second copy. type RoadmapEdge { child: ProcessNodeId parent: ProcessNodeId } -// === Section content: the frame-is-the-win element sequence ================== -// -// A real ROADMAP `##` section is NOT a single flat checkbox list (what the slice-2 RoadmapSection -// assumed): it interleaves authored INTRO prose (the section rationale, the `β—† Milestones` spine, a -// `β†’ [plan](…)` pointer) with one-or-MORE labelled checkbox SUB-GROUPS (`**Audits (done):**`, -// `**In-scope this window:**`). `SectionElement` is that ordered sequence β€” the frame-is-the-win -// faithful model of the section: model the FRAME (sub-group boxes + their bindings), FENCE the prose. -// -// - `SectionProse` carries authored prose VERBATIM (the Β§5 DecodeFidelity fence): an opaque String -// emitted as a paragraph, ALL markup (bold/links/refs/code-spans) living inside it. It is NOT modelled -// into medium constructs β€” fake-modelling prose is the forbidden over-reach (plan Β§5). -// - `SectionGroup` is one checkbox list: an authored `label` + its node/edge forest (the EXISTING line -// model, reused whole). The label is SEMANTIC TEXT, not literal markup: every real sub-group renders as -// the UNIFORM `**{label}:**` frame, so the bold+colon is a rendering convention the projection owns -// (single authority, Β§3) β€” not the `**…:**` repeated in every String. An empty `label` is the bare -// unlabelled `[ ]`-list that opens a section (no label paragraph emitted). type SectionProse { content: String } type SectionGroup { label: String, nodes: List, edges: List } -// The ordered content of a section: authored prose, or a checkbox sub-group. A closed sum so the -// emitter dispatches the two renderings (a verbatim paragraph vs a task list) β€” no Optional straddle. type SectionElement = Prose { prose: SectionProse } | Group { group: SectionGroup } -// Typed constructors so an element literal in list position carries its declared SectionElement type -// (a bare inline payload arm is read as a Product, cf. roadmap_parent above). fn section_prose(content: String) -> SectionElement { Prose { prose: SectionProse { content: content } } } fn section_group(label: String, nodes: List, edges: List) -> SectionElement { Group { group: SectionGroup { label: label, nodes: nodes, edges: edges } } } -// === Dependency projection: the indentation edge ============================ - -// Where a roadmap line sits in the forest. A closed domain sum, NOT `ProcessNodeId?` β€” the Optional -// of a branded primitive is a raw-nullable that `match` can't branch (the Value::Null model↔realization -// fork, DESIGN open thread), so a two-named-variant sum is the Β§5 "return a closed sum" move. type RoadmapParent = TopLevel | UnderParent { parent: ProcessNodeId } -// Typed constructors so the `if`-branches below unify as RoadmapParent (a bare inline arm with a -// payload is read as a Product in if-branch position; a function call carries its declared type). fn under_parent(p: ProcessNodeId) -> RoadmapParent { UnderParent { parent: p } } fn top_level() -> RoadmapParent { TopLevel } -// This edge's parent if it points at `node`, else TopLevel. fn edge_parent_for(e: RoadmapEdge, node: ProcessNodeId) -> RoadmapParent { if e.child == node { under_parent(p: e.parent) } else { top_level() } } -// The node a line is indented under, looked up from the decomposition edges. TopLevel = a section -// root. First matching edge wins (keep-first fold); the work graph forbids two parents, so a -// duplicate is malformed anyway. fn roadmap_parent(edges: List, node: ProcessNodeId) -> RoadmapParent { fold(edges, init: TopLevel, f: (acc, e) => match acc { UnderParent { parent: p } => UnderParent { parent: p } @@ -121,7 +48,6 @@ fn roadmap_parent(edges: List, node: ProcessNodeId) -> RoadmapParen }) } -// True iff the node sits at the top level (no parent edge) β€” the roots of the roadmap forest. fn is_top_level(edges: List, node: ProcessNodeId) -> Bool { match roadmap_parent(edges: edges, node: node) { TopLevel => true @@ -129,11 +55,6 @@ fn is_top_level(edges: List, node: ProcessNodeId) -> Bool { } } -// === Carrier projection: a dangling link is unwritable ====================== - -// A carrier resolves iff its target is among the existing docs. The emitter refuses to emit an -// unresolved carrier, so a dangling link cannot be written (plan Β§2 β€” the construction wall for -// dangling links). NoCarrier trivially resolves (a pointer-less line is honest, not dangling). fn carrier_resolves(carrier: PlanDocCarrier, existing_docs: List) -> Bool { match carrier { NoCarrier => true @@ -141,17 +62,10 @@ fn carrier_resolves(carrier: PlanDocCarrier, existing_docs: List) -> Boo } } -// A node is carrier-clean iff its plan-doc pointer resolves. A false here is the emit error a -// generated doc-index turns the orphan/dangling class into (plan Β§2/Β§6 step 5). fn node_carrier_clean(rn: RoadmapNode, existing_docs: List) -> Bool { carrier_resolves(carrier: rn.carrier, existing_docs: existing_docs) } -// === Status projection: reuse slice-1 over the embedded entry ================ - -// The node's status drift, routed through the slice-1 authority over its embedded line β€” NOT a -// second drift rule (Β§3). An AuthoredLine is Underivable (honest residue), only a DerivableLine can -// drift. `committed_box` is host-fed (the box observed in the committed ROADMAP file). fn node_status_drift(rn: RoadmapNode, committed_box: Bool, merged: List) -> DriftVerdict { status_drift(item: rn.line, committed_box: committed_box, merged: merged) } diff --git a/dsl/gunbc/roadmap_status.dag b/dsl/gunbc/roadmap_status.dag index 155e22c8a49..b8dbbedbd68 100644 --- a/dsl/gunbc/roadmap_status.dag +++ b/dsl/gunbc/roadmap_status.dag @@ -1,52 +1,13 @@ -// gunbc/roadmap_status.dag β€” PRβ†’checkbox status derivation for the ROADMAP. -// -// First slice of "invert hand-maintained artifacts" (docs/plans/invert-hand-maintained.md Β§6 -// step 4): the ROADMAP checkbox is a hand-toggled SECOND representation of a fact already -// upstream β€” whether the work a line stands for has landed. That copy DRIFTS (the realization-vocab -// guard sat `[ ]` while done on main, #5445/#5453). Invert it: merge-state is the AUTHORITY, the -// checkbox is DERIVED, disagreement is a drift the gate catches (the construction upgrade of the -// reachability lens β€” DESIGN Β§5/Β§6/Β§7). -// -// SOUNDNESS β€” the boundary is COMPLETES-IFF, not mere mention (DESIGN Β§5 fail-closed-but-RIGHT), and -// the fold makes it STRUCTURAL: a roadmap line is a closed sum (`RoadmapItem`), so a prose mention -// CANNOT accidentally derive a box β€” a mention is AuthoredLine content (no `prs` to derive from), the -// bad state unwritable, not runtime-rejected (Β§5 construction over validation). -// - DerivableLine: an explicit "this line is done iff these PR(s) merge" binding β€” the work-DAG -// authority edge; the ONLY class whose checkbox is derivable and drift-gated. `prs` is the single -// authority for both the derived box AND the emitted `(#ref)` annotation (Β§3, no fork). -// - AuthoredLine: a hand-set box; `content` is the whole line after the box, an opaque authored -// String emitted VERBATIM (the Β§5 DecodeFidelity fence β€” bold/refs/links live IN the String). A -// partial-evidence MENTION lives here as prose (e.g. ROADMAP Β§0 "rust-gate coverage" cites merged -// #5456 yet `[ ]`) β€” no binding, so honest un-derivable residue, never gated. -// This sum SUBSUMES the slice-1 CompletionBinding (CompletesIff|HandChecked): the same -// derivable-vs-authored split, one layer down, now carrying the per-arm line content too β€” one -// authority for "what a line is", no parallel binding type (Β§3). -// -// Single authority (DESIGN Β§3): merged-ness is grounded in the GitHub `PullRequest` source fact -// (`extdeps.github.pulls` β€” GitHub sets `merged_at` iff merged), NOT re-coined. The LIVE PR set is -// host-fed (the status edge stays a host bridge until self-host, per the plan Β§7); this module owns -// only the pure derivation + drift verdict the host edge, the gate, and the emitter all consume. - module gunbc.roadmap_status import extdeps.github.pulls { PullRequest } -// A roadmap line. The closed sum IS the Β§5 soundness boundary made structural (see header): a -// DerivableLine derives its box from `prs`; an AuthoredLine cannot derive at all. Folds in the slice-1 -// CompletionBinding (CompletesIffβ†’DerivableLine, HandCheckedβ†’AuthoredLine), now carrying line content. type RoadmapItem - // Box DERIVED: done iff every bound PR merges. `title` is the structural label (emit bolds it); - // `description` is the fenced prose tail (verbatim, refs-free β€” the `(#ref)` annotation emits from - // `prs`, Β§3 single authority). Empty `description` renders a bare bold title. + = DerivableLine { prs: List, title: String, description: String } - // Box AUTHORED (`done`); `content` is the whole line after the box, opaque prose emitted verbatim - // (the Β§5 fence). Mentions are AuthoredLine content, so they cannot derive a box. - | AuthoredLine { done: Bool, content: String } -// === Authority: merged-ness, grounded in the PullRequest source fact ======== + | AuthoredLine { done: Bool, content: String } -// Merged iff GitHub populated `merged_at` (its own merge semantics). The Β§3 single authority for -// "merged" β€” every consumer routes through here, none reads `merged_at` itself. fn pr_merged(pr: PullRequest) -> Bool { match pr.merged_at { Present { value: _ } => true @@ -54,27 +15,14 @@ fn pr_merged(pr: PullRequest) -> Bool { } } -// The host-fed bridge's projection: the numbers of the merged PRs in the live set. The host supplies -// the `PullRequest` list (live PR/branch state); this folds it to the merge facts the derivation -// needs β€” derived from `pr_merged`, never a parallel hand-kept list. fn merged_pr_numbers(prs: List) -> List { prs |> filter(pr => pr_merged(pr: pr)) |> map(pr => pr.number) } -// === Derivation: whether a line SHOULD read done ============================ - -// Done iff the binding is non-empty and EVERY bound PR merged β€” THE completion authority, a plain Bool -// (no 2-variant enum restating it, Β§2). Single authority for the predicate, so the drift gate and the -// emit projection both reuse it. An empty binding is not derivably-done (no merge evidence) β†’ false, -// fail-closed. fn prs_all_merged(prs: List, merged: List) -> Bool { count(prs) > 0 && all(prs, r => merged |> any(m => m == r)) } -// The done-ness a line's box SHOULD show: DERIVED (every bound PR merged) for a DerivableLine β€” the -// inversion; the AUTHORED box for an AuthoredLine β€” honest residue (Β§5 DecodeFidelity). The Bool the -// emitted checkbox glyph maps from (the emit projection turns it into `std.markdown.CheckboxState`, -// which it alone names). fn item_is_done(item: RoadmapItem, merged: List) -> Bool { match item { DerivableLine { prs, title: _, description: _ } => prs_all_merged(prs: prs, merged: merged) @@ -82,18 +30,8 @@ fn item_is_done(item: RoadmapItem, merged: List) -> Bool { } } -// === Drift: only a DerivableLine can drift ================================== - -// The Β§5 boundary made explicit in the verdict. An AuthoredLine is UNDERIVABLE β€” never Drifted, -// honest residue; only a DerivableLine whose derived box β‰  committed box is Drifted. The three states -// are disjoint repair paths: Drifted β†’ fix the box (or the PR); Clean β†’ nothing; Underivable β†’ out of -// the gate's reach, hand-checked. type DriftVerdict = Drifted | Clean | Underivable -// `committed_box` is the OBSERVED box in the committed ROADMAP (host-fed: read from the file, or β€” in -// the lens form β€” the box a fixture asserts). Slice-1 carried it as a `claimed_done` FIELD; the fold -// reparameterizes it to this argument (the field was always a stand-in for the observed box), so a -// DerivableLine need not store a box and the drift logic is otherwise unchanged. fn status_drift(item: RoadmapItem, committed_box: Bool, merged: List) -> DriftVerdict { match item { AuthoredLine { done: _, content: _ } => Underivable @@ -106,9 +44,6 @@ fn status_drift(item: RoadmapItem, committed_box: Bool, merged: List) -> Dr } } -// The gate predicate: a line trips the gate ONLY when its binding disagrees with the committed box. An -// AuthoredLine NEVER trips it β€” a false drift on a partial-evidence line is worse than no gate (Β§5), -// so the residue is honestly excluded, not forced to a verdict. fn item_drifted(item: RoadmapItem, committed_box: Bool, merged: List) -> Bool { match status_drift(item: item, committed_box: committed_box, merged: merged) { Drifted => true @@ -117,7 +52,6 @@ fn item_drifted(item: RoadmapItem, committed_box: Bool, merged: List) -> Bo } } -// Convenience for the host/gate edge: drift one line against the live PR set. fn item_drifts_against_prs(item: RoadmapItem, committed_box: Bool, prs: List) -> Bool { item_drifted(item: item, committed_box: committed_box, merged: merged_pr_numbers(prs: prs)) } diff --git a/dsl/gunbc/runner_spec_from_offer.dag b/dsl/gunbc/runner_spec_from_offer.dag index a0bd304931b..7a7c121088e 100644 --- a/dsl/gunbc/runner_spec_from_offer.dag +++ b/dsl/gunbc/runner_spec_from_offer.dag @@ -1,8 +1,3 @@ -// gunbc/runner_spec_from_offer.dag β€” Phase 3a-generic: ComputeOffer β†’ RunnerSpec projection. -// -// Fleet-agnostic GHA `runs-on:` realization for any self-hosted ComputeOffer β€” no concrete -// SKU catalog import, no operator host names. OUR fleet rows live in gunbc.ci_fleet. - module gunbc.runner_spec_from_offer import extdeps.github.actions { RunnerSpec, SelfHosted } @@ -36,8 +31,6 @@ fn cpu_architecture_runner_label(arch: Architecture) -> String { } } -// GHA `runs-on:` realization of a self-hosted fleet offer (hosted/cloud variants -// dissolve when RunnerSpec gains their typed carriers). fn runner_spec_from_offer(offer: ComputeOffer) -> RunnerSpec { let os = offer.supply.execution.os match compute_host_primary_cpu(host: offer.supply.physical) { diff --git a/dsl/gunbc/test_node_wall_clock_ratchet.dag b/dsl/gunbc/test_node_wall_clock_ratchet.dag index fb8e36a0213..8a5c3d830a4 100644 --- a/dsl/gunbc/test_node_wall_clock_ratchet.dag +++ b/dsl/gunbc/test_node_wall_clock_ratchet.dag @@ -1,16 +1,3 @@ -// gunbc/test_node_wall_clock_ratchet.dag β€” **Interim** Phase-0 per-test wall-clock -// warn policy (libtest name tokens) for shell/JQ consumption. Canonical R3 gate **#102** -// (`slow_test_exemptions_dissolved`) pass target: derive policy from modeled -// `TestNodeCostDimension` / timing facts β€” this table is a bridge until that wiring lands. -// -// CI `scripts/check-test-timeout.sh` projects this modeled `List` into the -// JSONL lines consumed by `jq` (same `{"test":...,"policy":"warn"}` shape as -// the retired hand-only manifest). Single edit surface: add/remove rows here. -// -// Phase-0 convergence: `TestNodeCostDimension.budget_time` / `measured_time` use -// `NanosecondDuration` (std.verification, its timing-authority home); this table names libtest tokens until every -// slow test is either sped up or modeled with explicit budget/measured facts. - module gunbc.test_node_wall_clock_ratchet import std.list { List } diff --git a/dsl/gunbc/tools/bmc_first_contact.dag b/dsl/gunbc/tools/bmc_first_contact.dag index 5b82cdefa19..acb15102f78 100644 --- a/dsl/gunbc/tools/bmc_first_contact.dag +++ b/dsl/gunbc/tools/bmc_first_contact.dag @@ -1,20 +1,3 @@ -// gunbc/tools/bmc_first_contact.dag β€” runnable: prove out-of-band contact with a BMC. -// -// Read-only "first contact": reach the BMC at $BMC_HOST and authenticate with the -// OpenBMC factory login (the cited single authority, extdeps/bmc/openbmc.dag), then read -// the Redfish system resource (power state, manufacturer). Safe β€” no state is changed. -// -// Run it (set BMC_HOST to your board's management IP / hostname): -// BMC_HOST=10.0.0.10 gunbc run --source-root dsl \ -// --entry dsl/gunbc/tools/bmc_first_contact.dag --function bmc_first_contact -// -// Add --dry-run to exercise the modeled mock instead of touching real hardware. -// -// This deliberately uses the FACTORY default login (root / 0penBmc). If the board's BMC -// password has already been rotated, this read will fail auth β€” which is itself the -// signal that rotation has happened (the rotation phase will source the live secret from -// the credential store instead). - module gunbc.tools.bmc_first_contact import extdeps.shell @@ -33,8 +16,6 @@ func bmc_first_contact() -> ProcessExit username: openbmc_factory_login.username, password: openbmc_factory_login.published_password ) - // exit 0 ⟺ the BMC was reachable AND the factory login authenticated. On failure the - // captured body (if any) rides the reason for debugging. The system JSON (PowerState, - // Manufacturer, …) is curl's stdout, captured into resp.body. + return if resp.success { ExitSuccess } else { exit_failure(reason: resp.body) } } diff --git a/dsl/gunbc/tools/bmc_read_telemetry.dag b/dsl/gunbc/tools/bmc_read_telemetry.dag index 9c86e032ea7..316797ff498 100644 --- a/dsl/gunbc/tools/bmc_read_telemetry.dag +++ b/dsl/gunbc/tools/bmc_read_telemetry.dag @@ -1,15 +1,3 @@ -// gunbc/tools/bmc_read_telemetry.dag β€” runnable: poll BMC Redfish telemetry (read-only). -// -// Reaches the BMC at $BMC_HOST using rotated credentials from $BMC_NETRC_FILE (0600 -// netrc β€” password MUST NOT ride curl argv). GETs Systems/system + Chassis sensors. -// -// Run (management network; BMC IP from ctrl operator_fleet): -// BMC_HOST= BMC_NETRC_FILE=~/.bmc-netrc gunbc run --source-root dsl \ -// --entry dsl/gunbc/tools/bmc_read_telemetry.dag --function bmc_read_telemetry -// -// OpenBMC ALTRAD8UD: Chassis Power/Thermal are empty; sensor collection carries power/temp. -// Factory first-contact (unrotated) remains gunbc.tools.bmc_first_contact. - module gunbc.tools.bmc_read_telemetry import extdeps.shell diff --git a/dsl/gunbc/tools/cron_tag.dag b/dsl/gunbc/tools/cron_tag.dag index fcb6cd2fc71..b6cc314a187 100644 --- a/dsl/gunbc/tools/cron_tag.dag +++ b/dsl/gunbc/tools/cron_tag.dag @@ -1,9 +1,3 @@ -// gunbc/tools/cron_tag.dag β€” tag-scoped crontab idempotency (workflow policy). -// -// POSIX `crontab` has no tag primitive; gunbc review workflows stamp entries with -// `# tag:{name}` and upsert by tag. That protocol is product policy β€” it composes -// faithful `cron.Tab.List` + `cron.Tab.Replace` from extdeps, not a fused extdeps op. - module gunbc.tools.cron_tag import extdeps.cron diff --git a/dsl/gunbc/tools/review.dag b/dsl/gunbc/tools/review.dag index 459b98d6fd4..0ed92f9b876 100644 --- a/dsl/gunbc/tools/review.dag +++ b/dsl/gunbc/tools/review.dag @@ -1,12 +1,3 @@ -// gunbc/tools/review.dag -- PR review workflow. -// -// Per-op idempotency is classified by the compiler. CreateReview's -// externally-guarded idempotency is a known workflow-modeling gap. -// -// Entrypoints: -// review_cycle(owner, repo) -- scan and review all open PRs -// review_pr(owner, repo, pr_number) -- review a single PR - module gunbc.tools.review import extdeps.cron.schedule_model { CronSchedule, Wildcard, Step, render_cron_schedule } @@ -17,8 +8,6 @@ import extdeps.llm.anthropic import extdeps.llm.anthropic_rest import extdeps.shell -// -- Configuration as data -------------------------------------------- - data default_model: String = "claude-sonnet-4-6-20250929" data cron_schedule: CronSchedule = CronSchedule { minute: Step { start: 0, step: 10 }, @@ -33,8 +22,6 @@ data review_messages: List = [ } ] -// -- Pure functions --------------------------------------------------- - fn has_review_at_sha(reviews: List, sha: CommitSha) -> Bool { any(reviews, r => r.commit_id == sha && contains(r.body, "Review")) } @@ -57,10 +44,6 @@ fn build_user_message( "PR #{pr_number}: {pr_title}\nBranch: {branch} -> {base_ref}\n\n--- Diff ---\n{diff}" } -// -- Review a single PR ----------------------------------------------- -// Idempotent: checks ListReviews before posting. If a review exists -// at this commit SHA, returns early. - func review_pr( owner: String, repo: String, @@ -68,7 +51,6 @@ func review_pr( model: String = default_model ) -> { reviewed: Bool, comment_url: String } { - // Step 1: Get PR metadata pr = github.Pulls.Get( auth_token: "", owner: owner, @@ -76,7 +58,6 @@ func review_pr( pull_number: pr_number ) - // Step 2: Dedup -- check if already reviewed at this SHA (idempotent guard) existing = github.Pulls.ListReviews( auth_token: "", owner: owner, @@ -85,7 +66,6 @@ func review_pr( ) already_done = has_review_at_sha(reviews: existing.reviews, sha: pr.pr.head.sha) - // Step 3: Fetch context (parallel) diff = github.Pulls.Diff( auth_token: "", owner: owner, @@ -99,7 +79,6 @@ func review_pr( script: "cd ~/gunbc && git show origin/{pr.pr.head.ref}:dsl/std/algebra.dag 2>/dev/null || echo '(not found)'" ) - // Step 4: Build context and invoke LLM via Anthropic REST API system_prompt = build_system_prompt( design: design.stdout, algebra_ref: algebra_ref.stdout @@ -120,7 +99,6 @@ func review_pr( system: "{system_prompt}\n\n{user_msg}" ) - // Step 5: Post review via GitHub API (idempotent: guarded by step 2) posted = github.Pulls.CreateReview( auth_token: "", owner: owner, @@ -134,18 +112,11 @@ func review_pr( return { reviewed: true, comment_url: posted.html_url } } -// -- Top-level: review all open PRs ----------------------------------- -// Idempotent end-to-end: -// 1. Cron upsert: ensures schedule exists (tag-based, converges) -// 2. PR listing: reads current state from GitHub -// 3. Per-PR review: guarded by ListReviews dedup - func review_cycle( owner: String = "gunb-ai", repo: String = "gunbc" ) -> { reviewed_count: Int } { - // Upsert cron -- idempotent, converges on every run (tag protocol in cron_tag) upsert_tagged_cron_tab( tag: "review-agent", schedule: render_cron_schedule(cron_schedule), @@ -153,7 +124,6 @@ func review_cycle( log_path: "/Users/briansrls/.local/share/gunbc-review/logs/cron.log" ) - // List open PRs open_prs = github.Pulls.List( auth_token: "", owner: owner, @@ -161,7 +131,6 @@ func review_cycle( state: Open ) - // Review each PR (review_pr handles dedup internally) results = for pr in open_prs.pulls { review_pr( owner: owner, diff --git a/dsl/gunbc/tools/review_codex.dag b/dsl/gunbc/tools/review_codex.dag index 378ebc3d1a3..8f45de71855 100644 --- a/dsl/gunbc/tools/review_codex.dag +++ b/dsl/gunbc/tools/review_codex.dag @@ -1,21 +1,3 @@ -// gunbc/tools/review_codex.dag -- Codex CLI PR review workflow. -// -// Replaces ctrl/scripts/review-agent (900-line bash script) with a -// .dag specification. Uses Codex CLI as the LLM backend (gpt-5.4, -// included in OpenAI subscription β€” no per-token cost). -// -// Auth model: -// GITHUB_TOKEN β€” env var, used for GitHub API (list PRs, post reviews) -// OPENAI_API_KEY β€” env var, used by codex CLI internally -// -// Both are read from environment via std.credentials.EnvVar. -// The .dag model declares the dependency; the emitter generates -// the acquisition code. -// -// Entrypoints: -// review_cycle(owner, repo) β€” scan + review all open PRs -// review_pr(owner, repo, number) β€” review a single PR (idempotent) - module gunbc.tools.review_codex import extdeps.cron.schedule_model { CronSchedule, Wildcard, Step, render_cron_schedule } @@ -26,8 +8,6 @@ import extdeps.llm.cli import extdeps.shell import std.credentials { CredentialSource, EnvVar } -// ── Configuration ───────────────────────────────────────────── - data default_model: String = "gpt-5.4" data default_reasoning_effort: String = "xhigh" data cron_schedule: CronSchedule = CronSchedule { @@ -41,15 +21,9 @@ data cron_tag: String = "review-agent" data owner: String = "gunb-ai" data repo: String = "gunbc" -// Auth sources β€” declared, not hardcoded. The emitter reads these -// from environment at runtime. data github_auth: CredentialSource = EnvVar { name: "GITHUB_TOKEN" } data openai_auth: CredentialSource = EnvVar { name: "OPENAI_API_KEY" } -// ── Review prompt ───────────────────────────────────────────── -// The prompt template. References DESIGN.md and std/ files by path β€” the -// codex CLI reads them from the working directory (the repo checkout). - data review_instructions: String = "You are a reviewer for the gunbc project (a DAG compiler). FIRST: Read DESIGN.md β€” it defines the project's objective and principles. All @@ -112,8 +86,6 @@ dsl/std/algebra.dag β€” Semiring, Lattice, Monoid, FreeMonoid, etc. dsl/std/termination.dag β€” DescentEvidence, RankingDimension dsl/std/types.dag β€” kernel types, container types" -// ── Pure functions ──────────────────────────────────────────── - fn has_review_at_sha(reviews: List, sha: CommitSha) -> Bool { any(reviews, r => r.commit_id == sha && contains(r.body, "INVARIANTS")) } @@ -141,9 +113,6 @@ fn format_review_header( "\n`{backend}` Β· `{model}` Β· `{sha}`\n\n{body}" } -// ── Review a single PR ──────────────────────────────────────── -// Idempotent: checks ListReviews before posting. - func review_pr( pr_owner: String = owner, pr_repo: String = repo, @@ -152,7 +121,6 @@ func review_pr( reasoning_effort: String = default_reasoning_effort ) -> { reviewed: Bool } { - // Step 1: Get PR metadata pr = github.Pulls.Get( auth_token: github_auth, owner: pr_owner, @@ -160,7 +128,6 @@ func review_pr( pull_number: pr_number ) - // Step 2: Dedup β€” check if already reviewed at this SHA existing = github.Pulls.ListReviews( auth_token: github_auth, owner: pr_owner, @@ -169,7 +136,6 @@ func review_pr( ) already_done = has_review_at_sha(reviews: existing.reviews, sha: pr.pr.head.sha) - // Step 3: Fetch prior line comments for dedup + resolution prior_comments_raw = github.Pulls.ListComments( auth_token: github_auth, owner: pr_owner, @@ -177,7 +143,6 @@ func review_pr( issue_number: pr_number ) - // Step 4: Build prompt (codex will fetch the diff itself via gh CLI) prompt = build_prompt( pr_title: pr.pr.title, pr_number: pr_number, @@ -186,7 +151,6 @@ func review_pr( prior_comments: "none" ) - // Step 5: Invoke Codex CLI llm_result = llm.Codex.Review( prompt: prompt, cwd: "/Users/briansrls/gunbc", @@ -194,7 +158,6 @@ func review_pr( reasoning_effort: reasoning_effort ) - // Step 6: Format and post review review_body = format_review_header( backend: "codex", model: model, @@ -215,15 +178,11 @@ func review_pr( return { reviewed: true } } -// ── Review cycle ────────────────────────────────────────────── -// Scans all open PRs and reviews each. Self-registers cron. - func review_cycle( cycle_owner: String = owner, cycle_repo: String = repo ) -> { reviewed_count: Int } { - // Upsert cron β€” idempotent, converges on every run (tag protocol in cron_tag) upsert_tagged_cron_tab( tag: cron_tag, schedule: render_cron_schedule(cron_schedule), @@ -231,7 +190,6 @@ func review_cycle( log_path: "/Users/briansrls/.local/share/gunbc-review/logs/cron.log" ) - // List open PRs open_prs = github.Pulls.List( auth_token: github_auth, owner: cycle_owner, @@ -239,7 +197,6 @@ func review_cycle( state: Open ) - // Review each (review_pr handles dedup internally) results = for pr in open_prs.pulls { review_pr( pr_owner: cycle_owner, diff --git a/dsl/gunbc/workflow/types.dag b/dsl/gunbc/workflow/types.dag index f0e466e08ce..e3ed56b27a2 100644 --- a/dsl/gunbc/workflow/types.dag +++ b/dsl/gunbc/workflow/types.dag @@ -1,9 +1,3 @@ -// gunbc/workflow/types.dag -- Gunbc workflow domain model. -// -// These types are intentionally not part of std/: they model this repo's -// workflow, review, approval, runtime, and audit domain rather than a -// provider-neutral standard library surface. - module gunbc.workflow.types import std.types { @@ -17,8 +11,6 @@ import std.types { } import extdeps.cloud.gcp.gcp { GcpProjectId, ServiceAccountEmail } -// --- Review model ------------------------------------------------------ - type ArtifactKind = Design | Review | Plan | CiReport type AuthorSource = Llm | Human type SeverityLevel = Blocking | Suggestion | Info @@ -41,8 +33,6 @@ type MergedReviewOutput { summary: String } -// --- Issue lifecycle --------------------------------------------------- - type IssueLifecycleStage = Idea | Design @@ -126,8 +116,6 @@ type PipelineArtifact { url: Url? } -// --- Workflow state ---------------------------------------------------- - type IssueState = Open | Closed type BindingStatus @@ -192,8 +180,6 @@ type StageOutcome { updated_at: Timestamp } -// --- Artifacts --------------------------------------------------------- - type ArtifactType = DesignArtifact | DesignReviewArtifact @@ -229,8 +215,6 @@ type ArtifactMarker { created_at: Timestamp } -// --- Signals ----------------------------------------------------------- - type SignalType = IntentSubmitted { intent_id: NonEmptyStr, intent_version: Int } | WorkReady { issue_id: NonEmptyStr, stage: IssueLifecycleStage, stage_epoch: Int } @@ -249,8 +233,6 @@ type Signal { consumed_at: Timestamp? } -// --- Runtime / credentials / audit ------------------------------------ - type RuntimeProfile = LocalCoLocated | StatelessFleet diff --git a/dsl/gunbc/workflow_yaml_project.dag b/dsl/gunbc/workflow_yaml_project.dag index f7268b908df..8f09ebd98cc 100644 --- a/dsl/gunbc/workflow_yaml_project.dag +++ b/dsl/gunbc/workflow_yaml_project.dag @@ -1,8 +1,3 @@ -// gunbc/workflow_yaml_project.dag β€” structural inverse: Workflow β†’ YamlValue. -// -// `emit_yaml = serialize_yaml ∘ project_workflow_to_yaml` (DESIGN Β§4 one grammar, -// both directions). Key renames mirror GitHub Actions YAML surface syntax. - module gunbc.workflow_yaml_project import extdeps.formats.yaml { diff --git a/dsl/tools/bootstrap.dag b/dsl/tools/bootstrap.dag index 47ce40e74bf..8c82b5272d9 100644 --- a/dsl/tools/bootstrap.dag +++ b/dsl/tools/bootstrap.dag @@ -1,10 +1,3 @@ -// tools/bootstrap.dag -- Workspace bootstrap (.gitignore generation). -// -// Generates .gitignore from DSL discovery + config data. Dynamic tool output -// categories are pre-computed by the binary and injected as a parameter. -// -// Replaces: gunbc-app/src/bootstrap/graph.rs (~16 nodes) - module tools.bootstrap import std.patterns { content_upsert } @@ -17,8 +10,6 @@ import extdeps.gitignore { } import extdeps.gitignore_render { render_gitignore_file } -// -- Entry point ----------------------------------------------------- - func bootstrap(check_mode: Bool?, gitignore_categories: List) -> { success: Bool, crate_count: Int, gitignore_written: Bool } uses fs: Filesystem(mode: ReadWrite) { diff --git a/dsl/tools/build.dag b/dsl/tools/build.dag index 51bc8203004..c0b51c95297 100644 --- a/dsl/tools/build.dag +++ b/dsl/tools/build.dag @@ -1,13 +1,3 @@ -// tools/build.dag -- Cargo build, test, and clippy in parallel. -// -// Runs cargo build first, then test and clippy in parallel (both -// depend on build success). Aggregates results into a summary. -// -// The aggregate fn uses shared/dag_util helpers instead of inline -// aggregation logic. -// -// Replaces: gunbc-app/src/build/graph.rs (~13 nodes) - module tools.build import std.types { Summary, StageResult } @@ -15,17 +5,15 @@ import extdeps.cargo_build import shared.dag_util { aggregate_results, format_report, stage_from_output } func build_all() -> { overall_success: Bool, summary: Summary, report: String, build_stderr: String, test_stderr: String, clippy_stderr: String } { - // Phase 1: Build (must succeed before test/clippy) + build = cargo.Build.Build(extra_args: ["--all-targets"]) - // Phase 2: Test and clippy in parallel (both depend on build) test = cargo.Build.Test(extra_args: ["--workspace"]) [after build, when build.success] clippy = cargo.Build.Clippy( extra_args: ["--all-targets"], lint_args: ["-D", "warnings"] ) [after build, when build.success] - // Phase 3: Aggregate using shared helper stages = [ stage_from_output(name: "build", success: build.success, stdout: build.stdout, stderr: build.stderr, skipped: false), stage_from_output(name: "test", success: test.success, stdout: test.stdout, stderr: test.stderr, skipped: !build.success), diff --git a/dsl/tools/build_step.dag b/dsl/tools/build_step.dag index a4a7759ceed..8ea0463c0b1 100644 --- a/dsl/tools/build_step.dag +++ b/dsl/tools/build_step.dag @@ -1,39 +1,3 @@ -// tools/build_step.dag β€” a build operation modeled as PRODUCING DECLARED ARTIFACTS. -// -// DESIGN Β§1/Β§5: a build step's success is not its exit code. sccache corruption can make -// `cargo build` exit 0 while producing NO artifact (false cache-hit, no relink) β€” a Β§5 -// fail-open IN the CI floor itself: downstream gates then run a stale/missing binary and -// pass green, masking every check. -// -// The construction fix (Β§5 β€” correctness BY CONSTRUCTION, not validation; Β§6 β€” single -// authority, not a forked `[ -x ]` paste): a build site DECLARES the artifacts it produces -// plus the source set those artifacts must be fresh against. ONE generator (`emit_verifications`) -// emits, after the build command, the verification statements DERIVED from `produces`: -// -// built ⟺ exit_success ∧ (βˆ€ a ∈ produces: a exists ∧ no source is newer than a) -// -// Existence is the PRIMARY conjunct (it catches the exit-0-with-no-artifact vector); -// source-relative freshness is the secondary anti-stale conjunct (the make/ninja definition -// of up-to-date β€” false-positive-free, unlike a `β‰₯ build_start` proxy which cries wolf on a -// legitimate no-op rebuild). Both are emitted into the SAME shell program as the build, after -// it, so a verification failure's non-zero exit propagates to the gate's success. -// -// `patterns` covers both Rust sources (`*.rs`) and manifest files (`Cargo.toml`, `Cargo.lock`) -// so a dependency-only change (no `.rs` edits) that alters the build output is also detected. -// The find command groups them: `find \( -name '*.rs' -o -name 'Cargo.toml' … \) -newer …`. -// -// Realizer choice (model-before-implement): every floor build site is EMITTED SHELL run as a -// bootstrap (ci.yml bash before the interpreter binary exists; host gates serialize one -// `shell.Exec.Run` that builds and uses the binary atomically under `set -e`). There is no -// live-interpreter seam between build and use, so the verification is bash codegen derived -// from this model β€” NOT a live host effect. A live `Filesystem.Stat{path}->{exists,mtime}` -// readonly op is the right realizer for any FUTURE interpreter-run build; named-deferred here, -// not built (no call site for this hole). -// -// Consumers: gunbc.ci_spec (the release bootstrap build), tools.host_prelude (the per-gate -// ensure-built preludes). The rows (which command β†’ which artifact) are CI-workflow facts in -// those modules; this module owns only the artifact type and the verification generator. - module tools.build_step import extdeps.languages.bash.program { @@ -43,19 +7,14 @@ import extdeps.languages.bash.program { lit, var_ref, command, assign, serialize_bash } -// A build step's declared output: the path of an artifact the command must produce. type BuildArtifact { path: ShellWord - // Human label for the diagnostic (e.g. "claim_executor"); not load-bearing for the test. + name: String } -// Per-run scratch var holding the find(1) result for the freshness probe. One name, reused -// sequentially per artifact (each artifact reassigns then tests before the next). data build_freshness_probe_var: String = "GUNBC_BUILD_FRESHNESS_NEWER_SRC" -// `echo "" >&2` β€” diagnostic to stderr (GitHub Actions surfaces it; `::error::` prefix -// turns it into an annotation in the ci.yml path). fn build_verify_echo(msg: ShellWord) -> ShellStmt { WithRedir { stmt: command(words: [lit(text: "echo"), msg]), @@ -63,10 +22,6 @@ fn build_verify_echo(msg: ShellWord) -> ShellStmt { } } -// PRIMARY conjunct β€” existence: `if [ ! -x ]; then echo …>&2; exit 1; fi`. -// `-x` (executable) subsumes existence for a binary artifact: absent OR present-but-broken -// both fail closed. This is the conjunct that catches the sccache exit-0-with-no-artifact -// vector the whole change exists for. fn verify_artifact_exists(art: BuildArtifact) -> ShellStmt { If { cond: command(words: [lit(text: "["), lit(text: "!"), lit(text: "-x"), art.path, lit(text: "]")]), @@ -80,8 +35,6 @@ fn verify_artifact_exists(art: BuildArtifact) -> ShellStmt { } } -// `find \( -name p1 -o -name p2 … \) -newer -print -quit` predicate words -// for the pattern list. The `\( … \)` grouping binds the `-name` disjunction before `-newer`. fn name_predicate_words(patterns: List) -> List { concat( [lit(text: "(")], @@ -98,8 +51,6 @@ fn name_predicate_words(patterns: List) -> List { ) } -// `find \( -name p1 -o … \) -newer -print -quit` β€” emits the first source -// path that postdates the artifact, or nothing. `-quit` stops at the first hit (cheap). fn freshness_find_stmt(art: BuildArtifact, roots: List, patterns: List) -> ShellStmt { command(words: concat( concat([lit(text: "find")], roots), @@ -110,13 +61,6 @@ fn freshness_find_stmt(art: BuildArtifact, roots: List, patterns: Lis )) } -// SECONDARY conjunct β€” source-relative freshness: -// NEWER=$(find \( -name p1 … \) -newer -print -quit) -// if [ -n "$NEWER" ]; then echo …>&2; exit 1; fi -// A non-empty result means a source is newer than the artifact β‡’ the build did not actually -// incorporate current sources (stale artifact) β‡’ fail closed. Runs AFTER the existence check, -// so `find -newer` is never handed a missing artifact. No pipe (uses command substitution), -// so it is robust under `set -o pipefail`. fn verify_artifact_fresh(art: BuildArtifact, roots: List, patterns: List) -> List { [ Assign { @@ -136,22 +80,14 @@ fn verify_artifact_fresh(art: BuildArtifact, roots: List, patterns: L ] } -// One artifact's full verification: existence (primary) THEN freshness (secondary). fn verify_artifact(art: BuildArtifact, roots: List, patterns: List) -> List { concat([verify_artifact_exists(art: art)], verify_artifact_fresh(art: art, roots: roots, patterns: patterns)) } -// The verification statements for every declared artifact of a step β€” the single authority a -// build site appends after its build command. Authoring a build site WITHOUT these is the -// thing this module makes structurally avoidable: there is one generator, and it always emits -// exists-then-fresh for each `produces` entry. fn emit_verifications(produces: List, roots: List, patterns: List) -> List { fold(produces, init: [], f: (acc, art) => concat(acc, verify_artifact(art: art, roots: roots, patterns: patterns))) } -// Verification rendered to a shell-script fragment (no `set -e` wrapper, no command) β€” for the -// String-concatenated ci.yml bootstrap path, which appends it after its hand-authored EAGAIN -// retry build string. The explicit `exit 1`s make a failure propagate regardless of `set -e`. fn verifications_script(produces: List, roots: List, patterns: List) -> String { serialize_bash(p: ShellProgram { set_e: false, diff --git a/dsl/tools/ci_gates.dag b/dsl/tools/ci_gates.dag index b3cd0964d55..659407a5b31 100644 --- a/dsl/tools/ci_gates.dag +++ b/dsl/tools/ci_gates.dag @@ -1,13 +1,3 @@ -// tools/ci_gates.dag β€” composed effectful CI gates (one resolve, one process). -// -// Gate list authority: `gunbc_ci_spec.gates` (not a parallel hardcoded sequence). -// Production CI runs gates individually via floor_effect_gate_witness adapters; -// this module remains for direct invocation. -// -// dissolve-on: v1 interpreter terminates effectful `fold` over ProcessExit (same -// class as #5138 floor batch-2 loop). Until then, `main` sequences gates manually -// (short-circuit on first failure) instead of `fold(spec.gates, …)`. - module tools.ci_gates import std.process { ProcessExit, ExitSuccess, exit_failure } @@ -44,7 +34,6 @@ fn run_spec_gate(g: Gate) -> ProcessExit { } } -// Sequential short-circuit β€” order mirrors `gunbc_ci_spec.gates` until dissolve-on. func run_ci_gates_sequential(spec: CiSpec) -> ProcessExit { let g0 = run_spec_gate(g: RustMonolithGate) let g1 = if exit_ok(g0) { run_spec_gate(g: EmitHostGate) } else { g0 } diff --git a/dsl/tools/ci_yaml_gate.dag b/dsl/tools/ci_yaml_gate.dag index 033aa1df407..8722c1f65fb 100644 --- a/dsl/tools/ci_yaml_gate.dag +++ b/dsl/tools/ci_yaml_gate.dag @@ -1,13 +1,3 @@ -// tools/ci_yaml_gate.dag β€” fixed-point drift gate for `.github/workflows/ci.yml`. -// -// The committed ci.yml must equal `expected_ci_yml()` byte-for-byte (DESIGN Β§7 self-emit -// fixed point β€” NO hash pin). Regenerate with `main_wet`. -// -// Run (check): -// gunbc run --source-root dsl --entry dsl/tools/ci_yaml_gate.dag --function main -// Regenerate (write): -// gunbc run --source-root dsl --entry dsl/tools/ci_yaml_gate.dag --function main_wet - module tools.ci_yaml_gate import std.process { ProcessExit, ExitSuccess, exit_failure } @@ -46,7 +36,6 @@ func main_wet() -> ProcessExit { } } -// Composed CI entry point (tools.ci_gates imports this name). fn exit_ok(e: ProcessExit) -> Bool { match e { ExitSuccess => true _ => false } } @@ -63,7 +52,6 @@ func run_ci_yaml_gate() -> ProcessExit { } } -// Β§5 receipt: perturbed bytes must drift (gate would exit non-zero on this content). func drift_red_receipt() -> ProcessExit { let committed = Filesystem.Read(path: ci_yml_path) let clean_ok = committed.success && !ci_yml_drifted(committed: committed.content) diff --git a/dsl/tools/codegen.dag b/dsl/tools/codegen.dag index 48be1eefb4c..6e40db10955 100644 --- a/dsl/tools/codegen.dag +++ b/dsl/tools/codegen.dag @@ -1,28 +1,4 @@ -// tools/codegen.dag -- Conditional codegen execution. -// -// Checks if codegen outputs exist (stamp file). If stale/missing, -// runs the codegen binary and writes a new stamp file. -// Uses conditional execution (when) rather than content_upsert. -// -// Replaces: gunbc-app/src/codegen/graph.rs (~9 nodes) - module tools.codegen import std.resources { Filesystem } import extdeps.gunbc { shell.Codegen } - -// Commented: compiler doesn't bind `uses` resource variables into scope yet. -// func codegen() -> { success: Bool, ran: Bool } -// uses fs: Filesystem -// { -// check = shell.Codegen.Check() -// run = shell.Codegen.Run() [when !check.needed] -// stamp [when run.success] = fs.write( -// path: "target/codegen/.stamp", -// content: "ok" -// ) -// return { -// success: check.needed || run.success, -// ran: !check.needed -// } -// } diff --git a/dsl/tools/dsl_compile_clean_gate.dag b/dsl/tools/dsl_compile_clean_gate.dag index 8115de0a802..47f275d9696 100644 --- a/dsl/tools/dsl_compile_clean_gate.dag +++ b/dsl/tools/dsl_compile_clean_gate.dag @@ -1,16 +1,3 @@ -// tools/dsl_compile_clean_gate.dag β€” whole-tree dsl/ compile-clean gate (dual-root pools), run by `gunbc`. -// -// Run in CI: -// cargo run -p v1-compiler --release --bin gunbc -- run \ -// --source-root dsl --entry dsl/tools/dsl_compile_clean_gate.dag --function main -// -// Transport compiles every .dag under dsl/ with witness_layer_roots (dsl + src/v2) as import -// pools β€” see tools.dsl_compile_clean_transport header for indexing semantics. -// -// SCAFFOLD β€” uses `--target rust` pending v1.compiler.dag_collect identity-key fix (180 -// collisions on `--target dag` emit); flip to `--target dag` when that backend bug lands. -// Parseβ†’resolveβ†’typecheck front-end is identical; rust emit proves the tree is well-typed. - module tools.dsl_compile_clean_gate import std.process { ProcessExit, ExitSuccess, exit_failure } diff --git a/dsl/tools/dsl_compile_clean_transport.dag b/dsl/tools/dsl_compile_clean_transport.dag index 8e4cd11aa06..9bc4498de84 100644 --- a/dsl/tools/dsl_compile_clean_transport.dag +++ b/dsl/tools/dsl_compile_clean_transport.dag @@ -1,30 +1,3 @@ -// tools/dsl_compile_clean_transport.dag β€” shell transport for whole-tree dsl/ compile-clean. -// -// Host runs `gunbc compile` over the live dsl/ tree (GREEN) with witness_layer_roots as the -// dependency pool (Β§3 single authority: dsl first, src/v2 second) and -// `--dependency-pool-index primary-precedence` (primary root authoritative; pool fills absent -// paths only β€” NOT global last-wins). gunbc indexes every .dag under all --source-root flags -// into the module pool, but only compiles entry modules from -// the FIRST root (load_sources / Compile in cli_run.rs); later roots are import pools only β€” -// adding src/v2 does NOT cold-compile the whole v2 tree, only modules pulled by dsl imports. -// -// Also runs: -// * perturb RED receipt β€” planted bad module fails typecheck against the live pools; -// * cross-tree GREEN receipt β€” planted dsl module importing v2.* resolves and compiles; -// * dsl-shell primary-precedence receipt β€” regression guard: last-wins would silently pick -// v2 extdeps.shell overlay (no shell.Env) and fail typecheck (Β§5); not a celebration of -// dual authority. dissolve-on: extdeps.shell de-fork (S2) unifies the module_path row. -// -// 🟑 gated β€” feature:CP-GATE-PRIMARY-PRECEDENCE-KNOB β€” owner: extdeps.shell de-fork (S2 slice). -// dissolve-on: single extdeps.shell authority (delete dsl row or v2 overlay); drop -// primary-precedence opt-in and this receipt; strict-only cross-root panic restored. -// Receipt: run_dsl_shell_primary_precedence_receipt deleted + CI floor green without knob. -// -// Both transports are modeled off hand-written `let script = "..."` blobs onto structured -// `ShellProgram`s rendered by `serialize_bash` (extdeps.languages.bash.program). The shared -// ROOT/GUNBC/ensure-built prelude is a single `ensure_gunbc_built()` (DRY, Β§2). Proven green by -// execution (each gate runs the real compile). - module tools.dsl_compile_clean_transport import extdeps.shell @@ -38,7 +11,6 @@ import extdeps.languages.bash.program { } import tools.host_prelude { ensure_gunbc_built } -// --source-root for every witness_layer_root (Β§3 β€” same roots as the rest of CI). fn dcc_source_root_flags() -> List { fold(witness_layer_roots, init: [], f: (acc, r) => concat(acc, [lit(text: "--source-root"), lit(text: r)])) } @@ -47,7 +19,6 @@ fn dcc_pool_index_flags() -> List { [lit(text: "--dependency-pool-index"), lit(text: "primary-precedence")] } -// set -e; ; cd "$ROOT"; OUT=$(mktemp -d); "$GUNBC" compile ... ; rm -rf "$OUT" fn clean_tree_compile_program() -> ShellProgram { let root = var_ref(name: "ROOT") let gunbc = var_ref(name: "GUNBC") @@ -74,19 +45,12 @@ fn run_clean_tree_compile() -> Bool { result.success } -// The planted module whose legacy Some/None on a builtin T? must fail typecheck. data perturb_module_source: String = "module test.perturb_compile_clean_red\nfn probe() -> String? {\n match Present { value: \"x\" } {\n Some { value: s } => Some { value: s }\n None => none\n }\n}" -// Planted dsl module that imports v2.* β€” must compile when pools include src/v2. data cross_tree_green_module_source: String = "module test.perturb_compile_clean_cross_tree_green\nimport v2.std.logic { Bool }\nfn probe() -> Bool { True }" -// Discriminating primary-precedence receipt: proves dsl extdeps.shell row is selected when -// shell.Env is required β€” last-wins on extdeps.shell would misresolve (Β§5 silent-wrong-answer). data dsl_shell_primary_module_source: String = "module test.perturb_compile_clean_dsl_shell_primary\nimport extdeps.shell\nfn probe() -> String? {\n shell.Env.Get(name: \"PATH\")\n}" -// RED receipt: plant the fresh-name unimported bad module; resolve against witness_layer_roots -// as dependency pools β€” no cp -r + cold whole-tree rebuild. Compile MUST fail (if it succeeds -// β†’ exit 1). fn compile_clean_perturb_program() -> ShellProgram { let root = var_ref(name: "ROOT") let gunbc = var_ref(name: "GUNBC") @@ -128,8 +92,6 @@ fn run_perturb_optional_skew_red_receipt() -> Bool { result.success } -// GREEN receipt: planted dsl module imports v2.std.logic; first --source-root is TMP (entry -// tree), witness_layer_roots are dependency pools β€” compile must succeed (set -e). fn compile_cross_tree_green_program() -> ShellProgram { let root = var_ref(name: "ROOT") let gunbc = var_ref(name: "GUNBC") @@ -164,8 +126,6 @@ fn run_cross_tree_import_green_receipt() -> Bool { result.success } -// GREEN receipt: primary root entry calls shell.Env (dsl-only service); pools supply v2 paths -// absent from dsl β€” extdeps.shell must stay on the dsl row, not the v2 overlay. fn compile_dsl_shell_primary_precedence_program() -> ShellProgram { let root = var_ref(name: "ROOT") let gunbc = var_ref(name: "GUNBC") diff --git a/dsl/tools/emit_host_fixtures.dag b/dsl/tools/emit_host_fixtures.dag index 954421b06c0..fa5a05ce427 100644 --- a/dsl/tools/emit_host_fixtures.dag +++ b/dsl/tools/emit_host_fixtures.dag @@ -1,25 +1,13 @@ -// tools/emit_host_fixtures.dag β€” MVP host-transport fixture sources for `tools.emit_host_gate`. -// -// Authority: v3 `v4_emit_host_harness_test.rs` minimal fixtures (five-byte stdout contract) -// and `typescript.dag` `ts_host_transport_mvp1_harness_suffix`. These are the executable -// programs the gate compiles/runs β€” not the authority_source_text pins in extdeps (those -// are emit-model references; the gate proves the host boundary independently of emit()). -// -// SCAFFOLD β€” dissolves when emit_host.dag host rows wire through gunbc Realization and -// generated TestClaimRun fixtures replace hand-authored sources (T-PB-B / T-22). - module tools.emit_host_fixtures import std.measure { ByteSize, byte_size } -// Five stdout bytes β€” MVP-2 runtime value alignment (rust/python/go row). data rust_mvp2_stdout_fixture_source: String = "fn main() { let _ = std::io::Write::write_all(&mut std::io::stdout(), &[0u8; 5]); }" data python_mvp2_stdout_fixture_source: String = "import sys\nsys.stdout.buffer.write(b'\\x00' * 5)\n" data go_mvp2_stdout_fixture_source: String = "package main\nimport \"os\"\nfunc main() { _, _ = os.Stdout.Write(make([]byte, 5)) }\n" -// TypeScript row β€” add(2,3)=5 as signed i32 LE on stdout (four bytes). data ts_mvp1_host_fixture_prefix: String = "// @ts-nocheck\nfunction add(x: number, y: number): number { return x + y; }\n" data ts_mvp1_host_fixture_harness_suffix: String = " @@ -31,9 +19,5 @@ process.stdout.write(__gunbc_b); data ts_mvp1_host_fixture_source: String = "{ts_mvp1_host_fixture_prefix}{ts_mvp1_host_fixture_harness_suffix}" -// Expected stdout byte counts per row (gate discriminant), modeled as the -// std.measure ByteSize value-Measure β€” not a bare Int domain-unit scalar. The raw -// Nat magnitude is projected only at the shell boundary (emit_host_transport.dag) -// via byte_size_count. data mvp2_stdout_byte_count: ByteSize = byte_size(5) data ts_signed_i32_le_byte_count: ByteSize = byte_size(4) diff --git a/dsl/tools/emit_host_gate.dag b/dsl/tools/emit_host_gate.dag index 5df8fc69e42..4f7c2ff4341 100644 --- a/dsl/tools/emit_host_gate.dag +++ b/dsl/tools/emit_host_gate.dag @@ -1,18 +1,3 @@ -// tools/emit_host_gate.dag β€” emit-host transport gate, run by `gunbc` (NOT a Rust binary). -// -// Replaces `tools/emit_host_runner`: the four MVP host rows (rust/python/go/typescript) are -// shell transports orchestrated here; the decision is pure Bool conjunction. This is the Β§7 -// shape: gate logic is `.dag` authority, the only Rust left is the `gunbc` interpreter seed. -// -// Run in CI: -// cargo run -p v1-compiler --release --bin gunbc -- run \ -// --source-root dsl --entry dsl/tools/emit_host_gate.dag --function main -// (host maps ProcessExit: ExitSuccess β†’ 0, ExitFailure { code } β†’ code.) -// -// SCAFFOLD β€” dissolves when `v2.compiler.emit_host` host rows wire through gunbc Realization -// and generated TestClaimRun fixtures replace these hand-authored sources (T-PB-B / T-22). -// `emit_host.dag` `run_emit_host_*` bodies stay fail-closed in src/v2 (no host effects there). - module tools.emit_host_gate import std.process { ProcessExit, ExitSuccess, exit_failure } @@ -23,7 +8,6 @@ import tools.emit_host_transport { run_ts_mvp1_smoke } -// Run all four MVP rows (no short-circuit β€” surface every target failure in one CI pass). func run_emit_host_gate_body() -> ProcessExit { rust = run_rust_mvp2_smoke() python = run_python_mvp2_smoke() @@ -42,7 +26,6 @@ func main() -> ProcessExit { run_emit_host_gate_body() } -// Composed CI entry point (tools.ci_gates imports this name). func run_emit_host_ci_gate() -> ProcessExit { run_emit_host_gate_body() } diff --git a/dsl/tools/emit_host_transport.dag b/dsl/tools/emit_host_transport.dag index 06460924aa4..bb56209dde9 100644 --- a/dsl/tools/emit_host_transport.dag +++ b/dsl/tools/emit_host_transport.dag @@ -1,15 +1,3 @@ -// tools/emit_host_transport.dag β€” shell transports for emit-host MVP smoke rows. -// -// Each operation writes a fixture to a temp dir, runs the target toolchain, and checks -// stdout byte count. Scripts are POSIX `sh` (gunbc shell transport uses `sh -c`, not bash). -// -// rust + python are modeled as structured `ShellProgram`s (extdeps.languages.bash.program), -// proven green by execution here (cargo + python3 are local). go + ts stay hand-written `let -// script` blobs FOR NOW: each embeds a toolchain *workaround* (go: curl|tar arch-bootstrap of a -// Go release; ts: npx network fetch of tsc) that per DESIGN.md Β§6 is debt to DISSOLVE by modeling -// the underlying provisioning concept, not to mechanically cement into a ShellProgram β€” and -// neither is verifiable without network. They ride the `RawLine` escape hatch at the type flip. - module tools.emit_host_transport import extdeps.shell @@ -32,7 +20,6 @@ import tools.host_prelude { toolchain_provision_shell_exec } data fixture_cargo_toml: String = "[package]\nname = \"emit_host_fixture\"\nversion = \"0.0.0\"\nedition = \"2021\"\n\n[[bin]]\nname = \"fixture\"\npath = \"src/main.rs\"" -// BYTES=$( | wc -c | tr -d ' ') fn byte_count_assign(producer: ShellStmt) -> ShellStmt { assign(name: "BYTES", value: CmdSubst { body: Pipe { left: Pipe { @@ -43,16 +30,10 @@ fn byte_count_assign(producer: ShellStmt) -> ShellStmt { } }) } -// test "$BYTES" -eq fn assert_bytes_eq(expected: Int) -> ShellStmt { command(words: [lit(text: "test"), var_ref(name: "BYTES"), lit(text: "-eq"), lit(text: to_string(expected))]) } -// Run emitted rust fixture: cargo build + run; pass iff stdout is exactly five bytes. -// set -e; WORKDIR=$(mktemp -d); mkdir -p "$WORKDIR"/src -// cat > "$WORKDIR"/Cargo.toml <<'EOF' ... EOF; cat > "$WORKDIR"/src/main.rs <<'EOF' ... EOF -// CARGO_TARGET_DIR="$WORKDIR"/target cargo build --quiet --manifest-path "$WORKDIR"/Cargo.toml -// BYTES=$("$WORKDIR"/target/debug/fixture | wc -c | tr -d ' '); rm -rf "$WORKDIR"; test "$BYTES" -eq N fn rust_mvp2_program() -> ShellProgram { let workdir = var_ref(name: "WORKDIR") ShellProgram { @@ -82,8 +63,6 @@ fn run_rust_mvp2_smoke() -> Bool { result.success } -// set -e; WORKDIR=$(mktemp -d); cat > "$WORKDIR"/fixture.py <<'EOF' ... EOF -// BYTES=$(python3 "$WORKDIR"/fixture.py | wc -c | tr -d ' '); rm -rf "$WORKDIR"; test "$BYTES" -eq N fn python_mvp2_program() -> ShellProgram { let workdir = var_ref(name: "WORKDIR") ShellProgram { @@ -103,15 +82,12 @@ fn run_python_mvp2_smoke() -> Bool { result.success } -// 🟑 go: embeds a curl|tar Go-toolchain arch-bootstrap (a provisioning workaround) β€” dissolve by -// modeling toolchain provisioning, not by cementing into a ShellProgram. Networked, unverifiable here. fn run_go_mvp2_smoke() -> Bool { let expected = byte_size_count(mvp2_stdout_byte_count) let script = "set -e\nWORKDIR=$(mktemp -d)\nif ! command -v go >/dev/null 2>&1; then\n GOBOOT=\"$WORKDIR/gotool\"\n mkdir -p \"$GOBOOT\"\n ARCH=$(uname -m)\n case \"$ARCH\" in aarch64|arm64) GOARCH=arm64 ;; x86_64|amd64) GOARCH=amd64 ;; *) exit 1 ;; esac\n curl -fsSL \"https://go.dev/dl/go1.22.5.linux-$GOARCH.tar.gz\" | tar -xz -C \"$GOBOOT\"\n PATH=\"$GOBOOT/go/bin:$PATH\"\n export PATH\nfi\ncat > \"$WORKDIR/main.go\" <<'EOF'\n{go_mvp2_stdout_fixture_source}\nEOF\nBYTES=$(go run \"$WORKDIR/main.go\" | wc -c | tr -d ' ')\nrm -rf \"$WORKDIR\"\ntest \"$BYTES\" -eq {expected}" toolchain_provision_shell_exec(script: script) } -// 🟑 ts: npx network fetch of typescript@5.9.2 (a provisioning workaround). Unverifiable here. fn run_ts_mvp1_smoke() -> Bool { let expected = byte_size_count(ts_signed_i32_le_byte_count) let script = "set -e\ncommand -v node >/dev/null 2>&1\ncommand -v npx >/dev/null 2>&1\nWORKDIR=$(mktemp -d)\ncat > \"$WORKDIR/fixture.ts\" <<'EOF'\n{ts_mvp1_host_fixture_source}\nEOF\ncd \"$WORKDIR\" && npx -y -p typescript@5.9.2 tsc --target ES2022 --module commonjs --outDir . fixture.ts\nBYTES=$(node \"$WORKDIR/fixture.js\" | wc -c | tr -d ' ')\nrm -rf \"$WORKDIR\"\ntest \"$BYTES\" -eq {expected}" diff --git a/dsl/tools/extdeps_external_authority_gate.dag b/dsl/tools/extdeps_external_authority_gate.dag index 9a542288d4a..34201323271 100644 --- a/dsl/tools/extdeps_external_authority_gate.dag +++ b/dsl/tools/extdeps_external_authority_gate.dag @@ -1,8 +1,3 @@ -// tools/extdeps_external_authority_gate.dag β€” extdeps external-authority anchor gate. -// -// Runs uri + live projection + RED perturb witnesses; fail-closed on CI floor -// (ExtdepsExternalAuthorityGate enrolled in gunbc_ci_spec). - module tools.extdeps_external_authority_gate import std.process { ProcessExit, ExitSuccess, exit_failure } diff --git a/dsl/tools/extdeps_external_authority_transport.dag b/dsl/tools/extdeps_external_authority_transport.dag index ed5d55721fb..c030ca33adc 100644 --- a/dsl/tools/extdeps_external_authority_transport.dag +++ b/dsl/tools/extdeps_external_authority_transport.dag @@ -1,5 +1,3 @@ -// tools/extdeps_external_authority_transport.dag β€” host transport for external-authority gate. - module tools.extdeps_external_authority_transport import extdeps.shell diff --git a/dsl/tools/floor_effect_gate_witness.dag b/dsl/tools/floor_effect_gate_witness.dag index 76338b64300..11b8c602004 100644 --- a/dsl/tools/floor_effect_gate_witness.dag +++ b/dsl/tools/floor_effect_gate_witness.dag @@ -1,13 +1,3 @@ -// tools/floor_effect_gate_witness.dag β€” nullary Bool adapters for the effectful -// CI gates, so the dependency-ordered scheduler (claim_executor) can run each gate -// as a plan node (`RunnableSingleClaim` is nullary β€” one `(entry, function)`). -// -// REUSE, not re-coin (DESIGN Β§2/Β§3): the Gateβ†’effect mapping stays the single -// authority `tools.ci_gates.run_spec_gate` (itself driven by `gunbc_ci_spec.gates`). -// Each adapter just pins one closed `Gate` variant and maps its ProcessExit to the -// Bool the scheduler's per-node verdict needs. These are `func` (effectful) β€” the -// host runs them in Wet mode so the transports fire. - module tools.floor_effect_gate_witness import gunbc.ci_spec { diff --git a/dsl/tools/gunbc_ci.dag b/dsl/tools/gunbc_ci.dag index 6f828b34d53..4edbadac45e 100644 --- a/dsl/tools/gunbc_ci.dag +++ b/dsl/tools/gunbc_ci.dag @@ -1,8 +1,3 @@ -// tools/gunbc_ci.dag β€” collapsed CI consumer (`gunbc ci` subcommand). -// -// Run: cargo run -p v1-compiler --release --bin gunbc -- ci -// (seed CLI subcommand delegates here β€” logic stays .dag authority). - module tools.gunbc_ci import std.process { ProcessExit, ExitSuccess, exit_failure } diff --git a/dsl/tools/host_prelude.dag b/dsl/tools/host_prelude.dag index 75451d3c3bd..7e0e3448e14 100644 --- a/dsl/tools/host_prelude.dag +++ b/dsl/tools/host_prelude.dag @@ -1,12 +1,3 @@ -// tools/host_prelude.dag β€” shared shell-program prelude for host gates that need a built gunbc. -// -// One authority for the ROOT/GUNBC/ensure-built sequence that every compile-or-run host gate -// repeats (Β§2 DRY): de-duplicated out of dsl_compile_clean_transport + layering_imports_transport. -// -// ROOT=$(git rev-parse --show-toplevel 2>/dev/null || pwd) -// GUNBC="$ROOT"/target/release/gunbc -// if [ ! -x "$GUNBC" ]; then (cd "$ROOT" && cargo build -p v1-compiler --release --bin gunbc) || exit 1; fi - module tools.host_prelude import extdeps.shell @@ -20,15 +11,10 @@ import extdeps.languages.bash.program { } import tools.build_step { BuildArtifact, emit_verifications } -// Source set the ensure-built bins must be fresh against β€” `$ROOT/src/**/*.rs` plus -// Cargo.toml/Cargo.lock (same oracle as the release bootstrap build, gunbc.ci_spec; the -// v1-compiler workspace's Rust sources all live under `src/`). Single authority for the -// host-gate freshness inputs (Β§3). fn host_build_source_roots() -> List { [Concat { parts: [var_ref(name: "ROOT"), lit(text: "/src")] }] } -// `ROOT=$(git rev-parse … || pwd)` β€” shared by every ensure-built prelude. fn assign_root_stmt() -> ShellStmt { assign(name: "ROOT", value: CmdSubst { body: AndOr { left: WithRedir { @@ -40,7 +26,6 @@ fn assign_root_stmt() -> ShellStmt { } }) } -// `if [ ! -x ]; then (cd "$ROOT" && cargo build -p v1-compiler --release --bin ) || exit 1; fi` fn build_bin_if_absent_stmt(bin_path: ShellWord, root: ShellWord, bin_name: String) -> ShellStmt { If { cond: test_not_executable(path: bin_path), @@ -63,12 +48,6 @@ fn build_bin_if_absent_stmt(bin_path: ShellWord, root: ShellWord, bin_name: Stri } } -// Ensure a release bin is present, then VERIFY it β€” existence (primary) + source-relative -// freshness (secondary), derived from the declared artifact via the single build_step -// generator. Closes the Β§5 fail-open the old `if ! -x then build` carried: it checked -// existence only BEFORE building (never after) and never freshness, so a present-but-stale bin -// (or a build that exited 0 without producing one) ran a phantom binary in the gate. Stale β‡’ -// fail closed, loud β€” not a silent wrong gate result. fn ensure_bin_built_and_verified(var_name: String, bin_name: String) -> List { let root = var_ref(name: "ROOT") let bin = var_ref(name: var_name) @@ -90,16 +69,10 @@ fn ensure_gunbc_built() -> List { ensure_bin_built_and_verified(var_name: "GUNBC", bin_name: "gunbc") } -// Pre-built release bin for Lane 3a ingest (CI builds with --bins; avoid cargo run under -// batch-2 parallel load β€” races rust_monolith fmt/clippy/test for the lock). fn ensure_discover_source_root_ingest_built() -> List { ensure_bin_built_and_verified(var_name: "DISCOVER_SOURCE_ROOT_INGEST", bin_name: "discover_source_root_ingest") } -// 🟑 toolchain-provision carve-out β€” dissolve-on: model ToolchainProvision in std; -// interim structural allow for emit_host go/ts provisioning workarounds. Callers pass -// literal blobs here; the wrapper's shell.Exec.Run uses the parameter (computed), not -// a literal at the transport site. fn toolchain_provision_shell_exec(script: String) -> Bool { let result = shell.Exec.Run(script: script) result.success diff --git a/dsl/tools/layering_imports_gate.dag b/dsl/tools/layering_imports_gate.dag index a8a923b9a47..5acff97afae 100644 --- a/dsl/tools/layering_imports_gate.dag +++ b/dsl/tools/layering_imports_gate.dag @@ -1,15 +1,3 @@ -// tools/layering_imports_gate.dag β€” cross-layer import gate, run by `gunbc` (NOT a Rust binary). -// -// Replaces scripts/v4-layering-imports-gate.sh and the deleted layering_imports_scan host. -// Host enumerates import facts via tools.layering_imports_transport; v2.lens.layering_imports -// owns violation semantics. This is the Β§7 shape: gate logic is `.dag` authority. -// -// Run in CI: -// cargo run -p v1-compiler --release --bin gunbc -- run \ -// --source-root dsl --entry dsl/tools/layering_imports_gate.dag --function main -// -// SCAFFOLD β€” dissolves when layering-imports scan wires through gunbc Realization. - module tools.layering_imports_gate import std.process { ProcessExit, ExitSuccess, exit_failure } @@ -18,7 +6,6 @@ import tools.layering_imports_transport { run_scanner_perturb_receipts } -// Green pass + scanner-execution perturb receipts (no short-circuit). func run_layering_imports_gate_body() -> ProcessExit { let clean = run_clean_tree_gate() let perturb = run_scanner_perturb_receipts() @@ -35,7 +22,6 @@ func main() -> ProcessExit { run_layering_imports_gate_body() } -// Composed CI entry point (tools.ci_gates imports this name). func run_layering_imports_ci_gate() -> ProcessExit { run_layering_imports_gate_body() } diff --git a/dsl/tools/layering_imports_transport.dag b/dsl/tools/layering_imports_transport.dag index 7e3b69d14c4..ca550235ddf 100644 --- a/dsl/tools/layering_imports_transport.dag +++ b/dsl/tools/layering_imports_transport.dag @@ -1,20 +1,3 @@ -// tools/layering_imports_transport.dag β€” host transport for the layering-imports gate. -// -// The deleted scripts/layering-imports-scan.sh enumerator is retired. Import enumeration -// now lives in the single-authority projection v2.lens.layering_imports.layer_import_facts_live -// (v1 handler: src/v1/stage0/src/layering_imports_project.rs, REUSING the resolver's own -// extract_import_paths + collect_dag_files_tolerant). So this transport no longer scans β€” -// it only runs the gunbc Bool witnesses that call that projection: -// * clean_tree (over the live std/extdeps roots) must hold; -// * the four scanner-execution receipts (over committed fixtures under -// src/v2/test/fixture/layering_scan) must detect their planted violation β€” the -// by-execution oracle that the projection == the deleted shell enumerator. -// Source roots come from witness_layer_roots (Β§3 single authority); there is no manifest -// overlay, no mktemp, no bash