diff --git a/ROADMAP.md b/ROADMAP.md index 714bf1fa46c..806aaf2d23a 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -102,7 +102,7 @@ Receipts + adjacent levers: [fractal Gantt](docs/plans/ci-floor-fractal-gantt.md - [ ] **emit partition cleanup — shell/json/yaml as grammar rows, zero language knowledge in the wrong layer** *(operator directive, 2026-07-01)* — one grammar per language, read in both directions (DESIGN §4); emission is rows in `extdeps/languages/`, never stage code. Four leftovers: (a) `src/v2/compiler/05_emit_orchestration.dag` still carries orchestration→bash lowering IN the compiler stage (the retry 2-level expansion, seq-join) — the #6106 registry dispatch is the exit mechanism; the former env-weld half is DISCHARGED (#5868 grew the bash AST `EnvUnset` + multi-binding `EnvPrefixed`; #6137 dissolved `orch_emit_run_env_welded`); the stage keeps ONE agnostic fold. (b) the bash grammar itself is FORKED across trees — `dag/extdeps/languages/bash/` vs `src/v2/extdeps/languages/bash.dag`+`bash_command_fold.dag` — the same §3 class as the `extdeps.shell` fork (hotfixed #6112), one authority must win. (c) JSON has no grammar authority: N hand-rolled emitters (`roadmap_spawner`'s `json_escape`/`json_str` is a marked scaffold dissolving to `std.primitives.to_json`; `bmc_onboard` and `tailscale_acl_emit` carry their own). (d) YAML: `ci_yaml_emit`/`ci_yaml_validate`/`gha_yaml_fold_pilot` sit in `dag/gunbc/` (workflow layer) while the fold pilot is `src/v2/extdeps/languages/gha_workflow_yaml_fold.dag` — YAML-the-language rows belong in `extdeps/languages/` with GHA-workflow as rows on top, retiring the `yaml_check` Rust scaffold once parse is grammar-owned. The construction wall that makes the splice class unwritable (a string literal is an ATOM, never a COMPOSITION — joins live in `extdeps/languages` rows, never workflow code): [no-smuggled-programs wall dissolved with program.dag FULL DELETE — shell → intent design](docs/plans/shell-intent-emit-realization-design.md). - [x] **slice 0 — CI EAGAIN-retry** ✓ (#6467) — `ci_cargo_eagain_retry_core` → `emit(Retry, Bash)`; byte-oracle = committed `ci.yml` [plan](docs/plans/shell-emission-model.md) — ✓ signed off: operator - [x] **slice 1 — control-flow emit (census-scoped)** ✓ (#6475; tier-2 Procedure/Let band #6566) — the `If` band only (`orch_emit_step::If` + else + condition forms + pipes/cmdsubst/`$?`/AndOr/redirect/env words, byte goldens); `For`/`While` NOT in scope — the pre-runtime census (2026-07-03) found zero pre-runtime sites needing them [plan](docs/plans/shell-emission-model.md) — ✓ signed off: operator - - [ ] **slice 2 — converge thin-run** *(IN FLIGHT 2026-07-14 — FLAGs 2a(i)/2b/2c operator-signed, keystone worker dispatched; [census](docs/plans/shell-to-dag-residual-census-and-arc-completion.md) §2)* — fleet_converge steady-state moves into the binary as a typed plan via `apply()` (models `EmitArtifactThenThinRun`); emitted bash shrinks to the fresh-standup/self-repair bootstrap fragment + a thin invocation line (supersedes 'emit the whole `.github/fleet-converge.sh`') [plan](docs/plans/shell-emission-model.md) + - [ ] **slice 2 — converge thin-run** — implementation MERGED (#6572 keystone `ConvergePlan`+`EmitArtifactThenThinRun`+`converge_apply` · #6585 golden shrink 323→21 lines · #6598 `gunbc converge --host` CLI receiver), operator sign-off PENDING — fleet_converge steady-state interpreted in the binary as a typed plan via `apply()`; emitted bash is the fresh-standup bootstrap fragment + thin invocation lines (supersedes 'emit the whole `.github/fleet-converge.sh`'). FLAGs 2a(i)/2b/2c signed/discharged 2026-07-14 ([census](docs/plans/shell-to-dag-residual-census-and-arc-completion.md) §2); receipts re-verified by execution 2026-07-20 (`fleet_converge_emit`/`fleet_converge_apply` witnesses). Flip to `done: true` + `sign(operator)` on sign-off (mirrors `6-shell-intent-phase1`). [plan](docs/plans/shell-emission-model.md) - [ ] **shell→intent Phase 1 — agnostic orchestration emit** — MERGED (#6832), operator sign-off PENDING — `While`/`BoundedPoll`/general `Retry` (N-level escalation) emit via `05_emit_orchestration` + bash grammar rows; byte goldens `orchestration_*_emit_test`; production consumer `ci_floor_peak_emit.dag`. Flip to `done: true` + `sign(operator)` on sign-off (mirrors `6-shell-slice2`). [plan](docs/plans/shell-intent-emit-realization-design.md) - [ ] **`apply()` Phases B–F** — B `host_exec`→`apply()` (gated on srv3 OsInstalled) · C Redfish live (partially via #6097) · D converge lane = EmitArtifactThenThinRun handler (first ctrl LOC deleted) · E pull-mode self-converge (autoinstall plants the on-host agent; the push star retires) · F decom. Phase A landed (#5756). [plan](docs/plans/host-effect-orchestration.md) - [ ] **temporal-effect-spine-a — temporal realization spine (T1 vocabulary)** *(operator 2026-07-02; not a workflow engine)* — `std.temporal_effect`: durable facts + `plan_next_step_from_prior_receipt_and_lease` (single prior+lease; list fold is consumer-side); 🟡 markers on stringly receipt labels + derived step id. RED: approval/lease/read-back gates. **Non-goals:** live mutation, DB, scheduler. **Accept (T1):** witness suite green. diff --git a/dag/gunbc/plans/shell_emission_model.dag b/dag/gunbc/plans/shell_emission_model.dag index fc950fc1087..d593287e9dd 100644 --- a/dag/gunbc/plans/shell_emission_model.dag +++ b/dag/gunbc/plans/shell_emission_model.dag @@ -11,7 +11,7 @@ fn shell_emission_model_body() -> List { BlockquoteBlock { blocks: [p(text: "Operator-signed design (multi-agent audit, verified against live tree). Shell emission lane: medium-agnostic orchestration intent → `emit(intent, Bash)` via the existing `05_emit_orchestration` dispatcher — **not** a new `ShellProgram` AST. DESIGN refs: §2 (intent vs transport vs spelling), §3 (single authority; `program.dag` deleted #6831 Phase 0), §4 (`emit = serialize_target ∘ translate` — endgame Q3), §5 (emit-only faithfulness; green by execution vs frozen bytes), §6 (purity-trap fence: no construct without a named live site). Complements [regime-2 shared emission fold](regime2-shared-emission-fold.md) (`std.layout.Doc` = **layout only**, never shell content) and [format-model-reconciliation](format-model-reconciliation.md) (record spelling). Parent arc: [emission-ingestion-inverse.md](emission-ingestion-inverse.md) gap (B). Residual census + arc-completion scoping: [shell-to-dag-residual-census-and-arc-completion.md](shell-to-dag-residual-census-and-arc-completion.md) (witty-ibex-317, #6514).")] }, p(text: "**Status:** planning tracker · **`.dag` carrier is authority** (§6). Linked from `ROADMAP.md` §6. **This PR is docs/authority only** — no emitter/serializer code."), h2(text: "1. The finding (reframes the frontier)"), - p(text: "Shell is emitted as **raw strings** in the residue — `host_effect.dag` still carries `ShellCommand\{script: String\}`. The '~20% built' figure below dates to authoring. As of **2026-07-16**: Slices **0 and 1 (`If` band) are LANDED and operator-signed** (`roadmap_authority.dag` `6-shell-slice0`/`6-shell-slice1`); Slice **2's work is observably complete but its sign-off is pending** (see §5); the remaining arc is Slice 3 (live_deploy), Slice 4 (tail consumers), and the parallel sidecar dissolution. **`roadmap_authority.dag` is the status authority — this doc must never contradict it (§3: one fact, one home).** Status lines here are load-bearing: a stale TODO in this doc caused a worker to be dispatched onto finished work (Slice 0) on 2026-07-16. Read the tree, and check the roadmap carrier, before trusting a slice's status. The arc was never greenfield:"), + p(text: "Shell is emitted as **raw strings** in the residue — `host_effect.dag` still carries `ShellCommand\{script: String\}`. The '~20% built' figure below dates to authoring. As of **2026-07-20**: Slices **0 and 1 (`If` band) are LANDED and operator-signed** (`roadmap_authority.dag` `6-shell-slice0`/`6-shell-slice1`); Slice **2's implementation is MERGED (#6572/#6585/#6598) with receipts re-verified by execution, sign-off pending** (see §5); the remaining arc is Slice 3 (live_deploy), Slice 4 (tail consumers), and the parallel sidecar dissolution. **`roadmap_authority.dag` is the status authority — this doc must never contradict it (§3: one fact, one home).** Status lines here are load-bearing: stale slice status in this doc/census caused workers to be dispatched onto finished work twice (Slice 0 on 2026-07-16, Slice 2 on 2026-07-20). Read the tree, and check the roadmap carrier, before trusting a slice's status. The arc was never greenfield:"), ul(items: [ li(text: "**Intent coproduct exists** — `src/v2/std/orchestration.dag`: `Run` / `Step\{Do,If,For,While,Retry\}` / `Pipeline` / `Predicate`."), li(text: "**Bidirectional bash language exists** — `src/v2/extdeps/languages/bash.dag` (~2201 lines, POSIX-cited)."), @@ -42,7 +42,7 @@ fn shell_emission_model_body() -> List { ol(items: [ li(text: "**Slice 0 — CI EAGAIN-retry cutover — LANDED (#6467, verified 2026-07-16).** `dag/gunbc/ci_spec.dag` `ci_cargo_eagain_retry_intent` (:222) is a real `Retry \{ body: Pipeline\{steps:[Do\{run\}], on_failure: FailFast\}, escalations, on_exhausted \}` and `ci_cargo_eagain_retry_core` (:235) routes it through `orch_emit_step(medium: bash_orchestration_emit_medium())`, matching Accepted/Rejected. Refusal carries `ci_retry_emit_refused_poison` — a deliberately-invalid marker so a rejected emission reds BOTH the committed `ci.yml` drift gate and the yaml parse gate rather than letting a hand-spelled fallback mask it (§5 refuse-never-widen). Env lowering is structured since #5868+#6137 (`EnvUnset` + multi-binding `EnvPrefixed`; the `orch_emit_run_env_welded` weld is dissolved). **Precondition RESOLVED:** `Retry.on_exhausted` is no longer emitter-ignored — `05_emit_orchestration.dag:503` threads it to `orch_emit_retry`, bound at :627 via `orch_emit_pipeline(p: on_exhausted)`. The residual `concat` at :250 is a two-part `\"set -o pipefail\\n\"` prefix, not a nested-concat blob."), li(text: "**Slice 1 — control-flow emission (census-scoped) — LANDED (#6475; tier-2 Procedure/Let band #6566; operator-signed in `roadmap_authority.dag` `6-shell-slice1`).** The `If` band only — `orch_emit_step::If` arm with else (`05_emit_orchestration.dag:497` → `orch_emit_if_step`), the condition forms, plus pipes / cmdsubst assignment / `$?` propagation / AndOr / redirects incl. `>>` / env framing word support, each with byte goldens. Every `Predicate` arm lowers (`ExitZero`, `StrEq`, `StrEmpty`, `StrNonempty`, `LogMatches`, `Not`, `And`, `Or`). `For` emission is **NOT in scope** (census-scoped): the mirror-retry `for` loop maps to the typed Retry/escalation model interpreted by the binary — it refuses **by design**, a decision, not a gap. **`While` emission has since LANDED (#6832):** the 2026-07-03 'zero pre-runtime `While` sites' finding was superseded by the `ci_floor_peak_emit` readiness-poll, so `While`/`BoundedPoll` now lower via `05_emit_orchestration` with byte goldens (`orchestration_while_emit_test`) and `While` is no longer emitter-unsupported (the earlier inert `While.bound` field was dissolved by #6718; #6832 gave `While` a real bound-carrying emit)."), - li(text: "**Slice 2 — converge thin-run — WORK OBSERVABLY COMPLETE; operator sign-off PENDING (receipts read 2026-07-16).** Tree receipts: `.github/fleet-converge.sh` is now **21 lines** — `gunbc converge --host srv1|srv2|srv3` (ConvergePlan interpreted in-process) plus the fresh-standup bootstrap fragment, the one arm the bash-minimization rule sanctions as pre-runtime; `fleet_converge_emit.dag` has **zero** bash fn defs and emits one artifact (`expected_fleet_converge_sh`); `EmitArtifactThenThinRun` is a live `transport:` arm on `gunbc.host_effect` (`dag/test/claim/fleet_converge_apply_witness_test.dag`), no longer prose-only. The 4 for-loops / while-read drain / verdict arithmetic / 12 functions are gone. **This doc does NOT declare the slice done.** `roadmap_authority.dag` `6-shell-slice2` is the status authority and still reads `done: false` (*IN FLIGHT 2026-07-14 — FLAGs 2a(i)/2b/2c*); flipping it requires an `operator` `signed(...)` attestation, which only the operator can give — every `done: true` row in that carrier is operator-signed. The FLAGs are not resolvable from tree receipts alone. **Operator: if the FLAGs are discharged, sign `6-shell-slice2` and this row becomes LANDED.** The `~275 lines / 12+ fn defs` row in [the residual census](shell-to-dag-residual-census-and-arc-completion.md) is likewise stale against the current emitter."), + li(text: "**Slice 2 — converge thin-run — implementation MERGED (#6572 keystone `ConvergePlan`+`EmitArtifactThenThinRun`+`converge_apply` · #6585 golden shrink 323→21 lines · #6598 `gunbc converge --host` CLI receiver); operator sign-off PENDING (receipts re-verified by execution 2026-07-20).** Tree receipts: `.github/fleet-converge.sh` is **21 lines** — `gunbc converge --host srv1|srv2|srv3` (ConvergePlan interpreted in-process) plus the fresh-standup bootstrap fragment, the one arm the bash-minimization rule sanctions as pre-runtime; `fleet_converge_emit.dag` has **zero** bash fn defs and emits one artifact (`expected_fleet_converge_sh`); `EmitArtifactThenThinRun` is a live `transport:` arm on `gunbc.host_effect` (`dag/test/claim/fleet_converge_apply_witness_test.dag`), no longer prose-only. The 4 for-loops / while-read drain / verdict arithmetic / 12 functions are gone; FLAGs 2a(i)/2b/2c were signed/discharged 2026-07-14 (recorded in the census §2). **This doc does NOT declare the slice done.** `roadmap_authority.dag` `6-shell-slice2` is the status authority and still reads `done: false` (MERGED, sign-off pending); flipping it requires an `operator` `signed(...)` attestation, which only the operator can give — every `done: true` row in that carrier is operator-signed. **Operator: sign `6-shell-slice2` and this row becomes LANDED.** Dispatch note: do NOT re-dispatch workers onto this slice — the stale `~275 lines / 12+ fn defs` census framing caused two misdispatches onto finished work (2026-07-16 slice 0, 2026-07-20 slice 2); the census §2/§3 rows now carry the landed receipts."), li(text: "**Slice 3 — live_deploy:** RUNTIME-PRESENT (runs on srv1 over LocalShell with gunbc as the invoker) → thin-run/typed-effect candidate, **not** a golden to freeze-and-emit: heredoc file bodies become typed `Filesystem.Write` effects with foreign-media payloads as data; apt/systemctl/tailscale become typed argv invocations. Its self-referential drift gate (compares the emit fn to itself) stays named as the #6023-class trap until the reshape."), li(text: "**Slice 4 — tail consumers (pre-runtime residue):** `bmc_token_federation` (two `Do\{Run\}` rows — slice-0 machinery suffices) → `ci_workflow` inline `RunStep`s (case/`uname` → model as `TargetArchitecture`; cross-link ROADMAP §1 `1-inline-shell-defork`) → githooks as a **thin shim** (ensure-built + exec `claim_batch --pre-push` with stdin passed through; the case-rosters/arrays/while-read stdin parse move into the binary)."), ]), diff --git a/dag/gunbc/roadmap_authority.dag b/dag/gunbc/roadmap_authority.dag index f0c00a75216..386a07bafc4 100644 --- a/dag/gunbc/roadmap_authority.dag +++ b/dag/gunbc/roadmap_authority.dag @@ -221,7 +221,7 @@ fn section_2() -> RoadmapSection { sign(rn: authored_doc(id: "6-shell-slice0", done: true, content: "**slice 0 — CI EAGAIN-retry** ✓ (#6467) — `ci_cargo_eagain_retry_core` → `emit(Retry, Bash)`; byte-oracle = committed `ci.yml`", path: "docs/plans/shell-emission-model.md"), s: signed(by: "operator", works: true, scope_equivalent: true, as_expected: true)), sign(rn: authored_doc(id: "6-shell-slice1", done: true, content: "**slice 1 — control-flow emit (census-scoped)** ✓ (#6475; tier-2 Procedure/Let band #6566) — the `If` band only (`orch_emit_step::If` + else + condition forms + pipes/cmdsubst/`$?`/AndOr/redirect/env words, byte goldens); `For`/`While` NOT in scope — the pre-runtime census (2026-07-03) found zero pre-runtime sites needing them", path: "docs/plans/shell-emission-model.md"), s: signed(by: "operator", works: true, scope_equivalent: true, as_expected: true)), authored_doc(id: "6-shell-intent-phase1", done: false, content: "**shell→intent Phase 1 — agnostic orchestration emit** — MERGED (#6832), operator sign-off PENDING — `While`/`BoundedPoll`/general `Retry` (N-level escalation) emit via `05_emit_orchestration` + bash grammar rows; byte goldens `orchestration_*_emit_test`; production consumer `ci_floor_peak_emit.dag`. Flip to `done: true` + `sign(operator)` on sign-off (mirrors `6-shell-slice2`).", path: "docs/plans/shell-intent-emit-realization-design.md"), - authored_doc(id: "6-shell-slice2", done: false, content: "**slice 2 — converge thin-run** *(IN FLIGHT 2026-07-14 — FLAGs 2a(i)/2b/2c operator-signed, keystone worker dispatched; [census](docs/plans/shell-to-dag-residual-census-and-arc-completion.md) §2)* — fleet_converge steady-state moves into the binary as a typed plan via `apply()` (models `EmitArtifactThenThinRun`); emitted bash shrinks to the fresh-standup/self-repair bootstrap fragment + a thin invocation line (supersedes 'emit the whole `.github/fleet-converge.sh`')", path: "docs/plans/shell-emission-model.md"), + authored_doc(id: "6-shell-slice2", done: false, content: "**slice 2 — converge thin-run** — implementation MERGED (#6572 keystone `ConvergePlan`+`EmitArtifactThenThinRun`+`converge_apply` · #6585 golden shrink 323→21 lines · #6598 `gunbc converge --host` CLI receiver), operator sign-off PENDING — fleet_converge steady-state interpreted in the binary as a typed plan via `apply()`; emitted bash is the fresh-standup bootstrap fragment + thin invocation lines (supersedes 'emit the whole `.github/fleet-converge.sh`'). FLAGs 2a(i)/2b/2c signed/discharged 2026-07-14 ([census](docs/plans/shell-to-dag-residual-census-and-arc-completion.md) §2); receipts re-verified by execution 2026-07-20 (`fleet_converge_emit`/`fleet_converge_apply` witnesses). Flip to `done: true` + `sign(operator)` on sign-off (mirrors `6-shell-intent-phase1`).", path: "docs/plans/shell-emission-model.md"), authored_doc(id: "2-host-effect-phases", done: false, content: "**`apply()` Phases B–F** — B `host_exec`→`apply()` (gated on srv3 OsInstalled) · C Redfish live (partially via #6097) · D converge lane = EmitArtifactThenThinRun handler (first ctrl LOC deleted) · E pull-mode self-converge (autoinstall plants the on-host agent; the push star retires) · F decom. Phase A landed (#5756).", path: "docs/plans/host-effect-orchestration.md"), owned(rn: authored_wi(id: "2-temporal-effect-spine-a", done: false, content: "**temporal-effect-spine-a — temporal realization spine (T1 vocabulary)** *(operator 2026-07-02; not a workflow engine)* — `std.temporal_effect`: durable facts + `plan_next_step_from_prior_receipt_and_lease` (single prior+lease; list fold is consumer-side); 🟡 markers on stringly receipt labels + derived step id. RED: approval/lease/read-back gates. **Non-goals:** live mutation, DB, scheduler. **Accept (T1):** witness suite green.", intricacy: IntricacyHigh, volume: VolumeSmall, repo: "gunbc"), owner: "dispatched 2026-07-02 · zesty-bat-588"), owned(rn: authored_wi(id: "2-os-install-deduction-a", done: false, content: "**os-install-deduction-a — preflight + KVM diagnostic vocabulary (T1)** *(operator 2026-07-02; deduction half; NOT wired to srv3_os_install_diagnostic until reconcile-a)* — `gunbc.os_install_deduction`: `fold_nbd_proxy_os_install_preflight_verdict` (NBD-proxy/on-ISO actuator scope — NoCloudNet incomplete for this path only), storage policy on payload, `TargetDiskState`, weak KVM verdicts (`KvmFirmwareIdleObserved`, `KvmSuggestsOsBooted`; `OsInstalled` reserved for router read-back). RED: remove storage flips ReadyToBoot; KVM login ≠ OsInstalled. **Non-goals:** live mutation, monitoring product, DB. **Accept (T1):** witness suite green.", intricacy: IntricacyHigh, volume: VolumeSmall, repo: "gunbc"), owner: "dispatched 2026-07-02 · zesty-bat-588"), diff --git a/docs/plans/shell-emission-model.md b/docs/plans/shell-emission-model.md index 9a69399052e..0ccaae4faf2 100644 --- a/docs/plans/shell-emission-model.md +++ b/docs/plans/shell-emission-model.md @@ -6,7 +6,7 @@ ## 1. The finding (reframes the frontier) -Shell is emitted as **raw strings** in the residue — `host_effect.dag` still carries `ShellCommand{script: String}`. The '~20% built' figure below dates to authoring. As of **2026-07-16**: Slices **0 and 1 (`If` band) are LANDED and operator-signed** (`roadmap_authority.dag` `6-shell-slice0`/`6-shell-slice1`); Slice **2's work is observably complete but its sign-off is pending** (see §5); the remaining arc is Slice 3 (live_deploy), Slice 4 (tail consumers), and the parallel sidecar dissolution. **`roadmap_authority.dag` is the status authority — this doc must never contradict it (§3: one fact, one home).** Status lines here are load-bearing: a stale TODO in this doc caused a worker to be dispatched onto finished work (Slice 0) on 2026-07-16. Read the tree, and check the roadmap carrier, before trusting a slice's status. The arc was never greenfield: +Shell is emitted as **raw strings** in the residue — `host_effect.dag` still carries `ShellCommand{script: String}`. The '~20% built' figure below dates to authoring. As of **2026-07-20**: Slices **0 and 1 (`If` band) are LANDED and operator-signed** (`roadmap_authority.dag` `6-shell-slice0`/`6-shell-slice1`); Slice **2's implementation is MERGED (#6572/#6585/#6598) with receipts re-verified by execution, sign-off pending** (see §5); the remaining arc is Slice 3 (live_deploy), Slice 4 (tail consumers), and the parallel sidecar dissolution. **`roadmap_authority.dag` is the status authority — this doc must never contradict it (§3: one fact, one home).** Status lines here are load-bearing: stale slice status in this doc/census caused workers to be dispatched onto finished work twice (Slice 0 on 2026-07-16, Slice 2 on 2026-07-20). Read the tree, and check the roadmap carrier, before trusting a slice's status. The arc was never greenfield: - **Intent coproduct exists** — `src/v2/std/orchestration.dag`: `Run` / `Step{Do,If,For,While,Retry}` / `Pipeline` / `Predicate`. - **Bidirectional bash language exists** — `src/v2/extdeps/languages/bash.dag` (~2201 lines, POSIX-cited). @@ -61,7 +61,7 @@ Shell-orchestration sites are **emit-only** (regime-2 class): no round-trip orac 1. **Slice 0 — CI EAGAIN-retry cutover — LANDED (#6467, verified 2026-07-16).** `dag/gunbc/ci_spec.dag` `ci_cargo_eagain_retry_intent` (:222) is a real `Retry { body: Pipeline{steps:[Do{run}], on_failure: FailFast}, escalations, on_exhausted }` and `ci_cargo_eagain_retry_core` (:235) routes it through `orch_emit_step(medium: bash_orchestration_emit_medium())`, matching Accepted/Rejected. Refusal carries `ci_retry_emit_refused_poison` — a deliberately-invalid marker so a rejected emission reds BOTH the committed `ci.yml` drift gate and the yaml parse gate rather than letting a hand-spelled fallback mask it (§5 refuse-never-widen). Env lowering is structured since #5868+#6137 (`EnvUnset` + multi-binding `EnvPrefixed`; the `orch_emit_run_env_welded` weld is dissolved). **Precondition RESOLVED:** `Retry.on_exhausted` is no longer emitter-ignored — `05_emit_orchestration.dag:503` threads it to `orch_emit_retry`, bound at :627 via `orch_emit_pipeline(p: on_exhausted)`. The residual `concat` at :250 is a two-part `"set -o pipefail\n"` prefix, not a nested-concat blob. 2. **Slice 1 — control-flow emission (census-scoped) — LANDED (#6475; tier-2 Procedure/Let band #6566; operator-signed in `roadmap_authority.dag` `6-shell-slice1`).** The `If` band only — `orch_emit_step::If` arm with else (`05_emit_orchestration.dag:497` → `orch_emit_if_step`), the condition forms, plus pipes / cmdsubst assignment / `$?` propagation / AndOr / redirects incl. `>>` / env framing word support, each with byte goldens. Every `Predicate` arm lowers (`ExitZero`, `StrEq`, `StrEmpty`, `StrNonempty`, `LogMatches`, `Not`, `And`, `Or`). `For` emission is **NOT in scope** (census-scoped): the mirror-retry `for` loop maps to the typed Retry/escalation model interpreted by the binary — it refuses **by design**, a decision, not a gap. **`While` emission has since LANDED (#6832):** the 2026-07-03 'zero pre-runtime `While` sites' finding was superseded by the `ci_floor_peak_emit` readiness-poll, so `While`/`BoundedPoll` now lower via `05_emit_orchestration` with byte goldens (`orchestration_while_emit_test`) and `While` is no longer emitter-unsupported (the earlier inert `While.bound` field was dissolved by #6718; #6832 gave `While` a real bound-carrying emit). -3. **Slice 2 — converge thin-run — WORK OBSERVABLY COMPLETE; operator sign-off PENDING (receipts read 2026-07-16).** Tree receipts: `.github/fleet-converge.sh` is now **21 lines** — `gunbc converge --host srv1|srv2|srv3` (ConvergePlan interpreted in-process) plus the fresh-standup bootstrap fragment, the one arm the bash-minimization rule sanctions as pre-runtime; `fleet_converge_emit.dag` has **zero** bash fn defs and emits one artifact (`expected_fleet_converge_sh`); `EmitArtifactThenThinRun` is a live `transport:` arm on `gunbc.host_effect` (`dag/test/claim/fleet_converge_apply_witness_test.dag`), no longer prose-only. The 4 for-loops / while-read drain / verdict arithmetic / 12 functions are gone. **This doc does NOT declare the slice done.** `roadmap_authority.dag` `6-shell-slice2` is the status authority and still reads `done: false` (*IN FLIGHT 2026-07-14 — FLAGs 2a(i)/2b/2c*); flipping it requires an `operator` `signed(...)` attestation, which only the operator can give — every `done: true` row in that carrier is operator-signed. The FLAGs are not resolvable from tree receipts alone. **Operator: if the FLAGs are discharged, sign `6-shell-slice2` and this row becomes LANDED.** The `~275 lines / 12+ fn defs` row in [the residual census](shell-to-dag-residual-census-and-arc-completion.md) is likewise stale against the current emitter. +3. **Slice 2 — converge thin-run — implementation MERGED (#6572 keystone `ConvergePlan`+`EmitArtifactThenThinRun`+`converge_apply` · #6585 golden shrink 323→21 lines · #6598 `gunbc converge --host` CLI receiver); operator sign-off PENDING (receipts re-verified by execution 2026-07-20).** Tree receipts: `.github/fleet-converge.sh` is **21 lines** — `gunbc converge --host srv1|srv2|srv3` (ConvergePlan interpreted in-process) plus the fresh-standup bootstrap fragment, the one arm the bash-minimization rule sanctions as pre-runtime; `fleet_converge_emit.dag` has **zero** bash fn defs and emits one artifact (`expected_fleet_converge_sh`); `EmitArtifactThenThinRun` is a live `transport:` arm on `gunbc.host_effect` (`dag/test/claim/fleet_converge_apply_witness_test.dag`), no longer prose-only. The 4 for-loops / while-read drain / verdict arithmetic / 12 functions are gone; FLAGs 2a(i)/2b/2c were signed/discharged 2026-07-14 (recorded in the census §2). **This doc does NOT declare the slice done.** `roadmap_authority.dag` `6-shell-slice2` is the status authority and still reads `done: false` (MERGED, sign-off pending); flipping it requires an `operator` `signed(...)` attestation, which only the operator can give — every `done: true` row in that carrier is operator-signed. **Operator: sign `6-shell-slice2` and this row becomes LANDED.** Dispatch note: do NOT re-dispatch workers onto this slice — the stale `~275 lines / 12+ fn defs` census framing caused two misdispatches onto finished work (2026-07-16 slice 0, 2026-07-20 slice 2); the census §2/§3 rows now carry the landed receipts. 4. **Slice 3 — live_deploy:** RUNTIME-PRESENT (runs on srv1 over LocalShell with gunbc as the invoker) → thin-run/typed-effect candidate, **not** a golden to freeze-and-emit: heredoc file bodies become typed `Filesystem.Write` effects with foreign-media payloads as data; apt/systemctl/tailscale become typed argv invocations. Its self-referential drift gate (compares the emit fn to itself) stays named as the #6023-class trap until the reshape. 5. **Slice 4 — tail consumers (pre-runtime residue):** `bmc_token_federation` (two `Do{Run}` rows — slice-0 machinery suffices) → `ci_workflow` inline `RunStep`s (case/`uname` → model as `TargetArchitecture`; cross-link ROADMAP §1 `1-inline-shell-defork`) → githooks as a **thin shim** (ensure-built + exec `claim_batch --pre-push` with stdin passed through; the case-rosters/arrays/while-read stdin parse move into the binary). diff --git a/docs/plans/shell-to-dag-residual-census-and-arc-completion.md b/docs/plans/shell-to-dag-residual-census-and-arc-completion.md index 73ff2088c6a..ae407294b1e 100644 --- a/docs/plans/shell-to-dag-residual-census-and-arc-completion.md +++ b/docs/plans/shell-to-dag-residual-census-and-arc-completion.md @@ -41,7 +41,7 @@ These run before a gunbc runtime exists on the target, so shell is the honest lo | site | what | current path | dissolves to | | --- | --- | --- | --- | -| `fleet_converge_emit.dag` | **~275 lines** Doc-literal bash: 12+ fn defs (`emit_receipt`,`converge_runner_width`,…), 4 for-loops, while-read drain, `$((…))` arithmetic, verdict if/elif | committed `.github/fleet-converge.sh`, run by thin ctrl reconciler | `EmitArtifactThenThinRun` (slice 2) — §2 | +| `fleet_converge_emit.dag` | **dissolved** (slice 2 keystone LANDED: #6572 `ConvergePlan`+`EmitArtifactThenThinRun`+`converge_apply` · #6585 golden shrink 323→21 lines · #6598 `gunbc converge --host` CLI receiver) — the census-time ~275 lines / 12+ fn defs / 4 for-loops / while-read drain / arithmetic / verdict if-elif are gone; the emitter now projects only the fresh-standup bootstrap intent + thin invocation lines | committed `.github/fleet-converge.sh` (21-line thin-run golden), steady-state interpreted in-process | done — `EmitArtifactThenThinRun` (slice 2) — §2 | | srv3 tails (9 files) | observe scripts, receipt echoes, token-extract, sleep glue; **2 heavy**: `srv3_install_diagnostic_checklist` (curl/redfish/sol probing, FROZEN/terminal), `srv3_os_install_actuator_toolchain_ensure` (apt/curl/websocat) | `shell_exec_via_bash` heredoc → `shell.Exec.Run` | typed observe/effect on `host_effect_apply` (their scaffolds already say so) | | `host_identity_converge.dag` | 1–2 line `sudo hostnamectl set-hostname` as `ShellCommand{script}` | **already** `host_effect_apply_gated` | typed hostname effect (drop the shell string) | | `floor_diff_observe.dag` | `git diff` observe as `ShellCommand{script}` | **already** `host_effect_apply` LocalShell | **this is the target pattern already realized** | @@ -69,7 +69,7 @@ The srv3 dissolution triggers are unanimous: `srv3_install_diagnostic_checklist_ ## 2. `EmitArtifactThenThinRun` scoping — srv1/srv2 subsumption keystone -**Goal:** move the fleet-converge srv1/srv2 steady-state (category C, ~275 lines) *out of emitted bash and into the gunbc binary*, which interprets the typed converge policy in-process and emits typed receipts. The emitted artifact shrinks to the fresh-standup bootstrap fragment + a thin `gunbc converge` invocation line. +**Goal — ACHIEVED (2026-07-20 receipts; roadmap `6-shell-slice2` sign-off pending):** move the fleet-converge srv1/srv2 steady-state (category C, ~275 lines at census time) *out of emitted bash and into the gunbc binary*, which interprets the typed converge policy in-process and emits typed receipts. The emitted artifact shrinks to the fresh-standup bootstrap fragment + a thin `gunbc converge` invocation line. **Landed:** G1+G2 minted in #6572, G3 consumed in #6585, CLI receiver in #6598; witnesses (`fleet_converge_emit_*`, `fleet_converge_apply_holds`) green by execution 2026-07-20. ### What already exists (the pieces) @@ -88,9 +88,9 @@ The srv3 dissolution triggers are unanimous: `srv3_install_diagnostic_checklist_ ### Sequence (each gated by the byte oracle) -1. **Mint G1+G2 together** (one PR, co-owned with the host-effect lane — they must not land alone per host-effect-orchestration §co-owned): `ConvergePlan` effect + `ConvergeOnHost` cell + `EmitArtifactThenThinRun` transport + the in-process knob interpreter, with a fail-closed `Unimplemented`-per-knob frontier so unmodeled knobs refuse (not fabricate). -2. **Consume from fleet_converge** (G3): `converge_apply` for the steady-state arms; keep the Doc projection emitting *only* the fresh-standup bootstrap + the thin invocation; the committed `.github/fleet-converge.sh` golden shrinks and the drift gate proves the shrink is exactly the steady-state functions. -3. **Retire** `fleet_converge_steady_state_doc_projection_dissolution_trigger` and the ctrl reconciler's script fan-out (host-effect Phase D's first net ctrl deletion — `runner_host_reconcile.mjs` hash/fan-out). +1. **Mint G1+G2 together** — **LANDED (#6572)**: `ConvergePlan` effect + `ConvergeOnHost` cell + `EmitArtifactThenThinRun` transport + the in-process knob interpreter, with a fail-closed `Unimplemented`-per-knob frontier so unmodeled knobs refuse (not fabricate). +2. **Consume from fleet_converge** (G3) — **LANDED (#6585, CLI receiver #6598)**: `converge_apply` for the steady-state arms; the Doc projection emits *only* the fresh-standup bootstrap + the thin invocations; the committed `.github/fleet-converge.sh` golden shrank 323→21 lines with the drift gate green. +3. **Retire** `fleet_converge_steady_state_doc_projection_dissolution_trigger` and the ctrl reconciler's script fan-out (host-effect Phase D's first net ctrl deletion — `runner_host_reconcile.mjs` hash/fan-out). *(Still open: the trigger remains a Scaffold binding `fleet_converge_thin_invocation` — it dissolves when the thin invocation becomes typed argv dispatch rather than a shell line.)* **⚠ FLAG 2c — ownership.** `host_effect.dag` is a DESIGN-named seam co-owned by smart-newt-512 (dag-managed-infra) / neat-boar-71 (BMC), and its note requires **operator + bright-stag-194 sign-off before any transport arm is minted**. This scoping is the sign-ready shape; the mint is that lane's, not a solo edit from here. **✓ DISCHARGED** (operator, 2026-07-14): operator dispatch order via calm-ferret-849 supplies the sign; sessions bright-stag-194 / smart-newt-512 / neat-boar-71 verified archived at sign time (no live co-owner lane to co-sign or conflict with), so the mint proceeds under a dedicated worker owned by calm-ferret-849. @@ -103,7 +103,7 @@ Two tracks run in parallel; deletion is the join. ### Track 1 — legitimate shell onto the v2 bash rows (bounded) - **P1 (ready now, no sign-off):** the `ci_workflow` concat-built floor-peak/cgroup runners → `emit(intent, Bash)` via the landed If-band + word support (they carry `…_shell_emit_dissolution_trigger` rows). Foreign-executor, so they *emit*; no `apply()`. -- **P2:** the Procedure/Let emit band for the 3 fresh-standup frontier rows — the one genuinely new *emitter* vocabulary the arc still needs, scoped by the bootstrap census, fail-closed where a construct isn't modeled. *(Tier-2 band LANDED #6566; the consumer slice — route the fresh-standup fragment, byte-oracle vs `.github/fleet-converge.sh`, retire the frontier rows, delete the site-less arith arm — is in flight. The former "ubuntu-media files need `for`/heredoc" clause is superseded by the FLAG B1 working default above: ubuntu-media dissolves to typed argv/`Filesystem.Write`, so the for/heredoc band is never built.)* +- **P2:** the Procedure/Let emit band for the 3 fresh-standup frontier rows — the one genuinely new *emitter* vocabulary the arc still needs, scoped by the bootstrap census, fail-closed where a construct isn't modeled. *(Tier-2 band LANDED #6566; the consumer slice — route the fresh-standup fragment through `emit(intent,Bash)`, byte-oracle vs `.github/fleet-converge.sh` — LANDED #6573. The former "ubuntu-media files need `for`/heredoc" clause is superseded by the FLAG B1 working default above: ubuntu-media dissolves to typed argv/`Filesystem.Write`, so the for/heredoc band is never built.)* - **P3:** `local_tidy_spec` pre-push hook + cron lines stay `serialize_bash`/foreign-executor **permanently** (roster entries, category (a)). These never dissolve — they're the honest residue. ### Track 2 — runtime-present shell onto `host_effect_apply` (the §2 keystone cascade) @@ -117,7 +117,7 @@ Two tracks run in parallel; deletion is the join. When Track 1's emitters route through the v2 bash rows and Track 2's runtime-present shell is on `apply()` with typed effects, the `bash_program_importer_count` reaches the permanent-residue floor (the v2 replacement emitter + the foreign-executor roster). At that point `bash.program`/`serialize_bash` has no runtime importer, the ratchet's baseline hits the floor, and `program.dag` + `serialize_bash` delete — the arc's terminal step. The v2 bidirectional bash language is the single bash authority. -**Critical-path summary:** everything non-foreign converges on **P4 (the `host_effect_apply` typed-effect + `EmitArtifactThenThinRun` mint)**. P5/P6 are mechanical once P4 lands; P1/P2 (emitter side) run independently. The former gate — the P4 sign-off (⚠ FLAG 2a/2b/2c) — is **cleared**: signed/discharged 2026-07-14 (see §2) and the keystone worker is dispatched; the critical path is now P4's execution, not its authorization. +**Critical-path summary:** everything non-foreign converges on **P4 (the `host_effect_apply` typed-effect + `EmitArtifactThenThinRun` mint)** — **P4 is LANDED** (#6572/#6585/#6598; FLAGs 2a(i)/2b/2c signed/discharged 2026-07-14, see §2). The critical path is now P5/P6 (mechanical on the landed interface) and the operator sign of roadmap `6-shell-slice2`; P1/P2 (emitter side) run independently. **Dispatch note (2026-07-20):** do not re-dispatch workers onto P4/slice 2 from the old ~275-line framing — that staleness produced two misdispatches onto finished work. ## Dissolution trigger