Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
1fc1bb1
shell→dag arc: record operator flag signs on the census carrier (2a(i…
briansrls Jul 14, 2026
3ef753f
Address #6571 review: reconcile P2/B1 consequence (for/heredoc band s…
briansrls Jul 14, 2026
9617d4a
WIP: shell -> dag
briansrls Jul 14, 2026
d29365e
Fix #6571 CI red: ROADMAP.md is a GENERATED projection — move the sli…
briansrls Jul 14, 2026
73a4a91
Merge remote-tracking branch 'origin/main' into session/calm-ferret-849
briansrls Jul 14, 2026
11fe938
Merge remote-tracking branch 'origin/main' into session/calm-ferret-849
briansrls Jul 14, 2026
79bbd2c
Merge remote-tracking branch 'origin/main' into session/calm-ferret-849
briansrls Jul 14, 2026
d05189a
Fix quadratic receipt-emit fold (bare-minimum-cost ruling): left-asso…
briansrls Jul 14, 2026
62cc0cc
WIP: shell -> dag
briansrls Jul 14, 2026
98d60e7
Merge remote-tracking branch 'origin/main' into session/calm-ferret-849
briansrls Jul 14, 2026
d5001e5
Merge remote-tracking branch 'origin/main' into session/calm-ferret-849
briansrls Jul 14, 2026
f344483
Merge remote-tracking branch 'origin/main' into session/calm-ferret-849
briansrls Jul 14, 2026
a10819a
WIP: shell -> dag
briansrls Jul 14, 2026
802a89e
Merge remote-tracking branch 'origin/main' into session/calm-ferret-849
briansrls Jul 14, 2026
878d444
Complete the HostEffect arm set: dedupe SetHostnameCas (merge doubled…
briansrls Jul 14, 2026
66fb040
Merge remote-tracking branch 'origin/main' into session/calm-ferret-849
briansrls Jul 14, 2026
bb81126
WIP: shell -> dag
briansrls Jul 14, 2026
b1529e1
Merge remote-tracking branch 'origin/main' into session/calm-ferret-849
briansrls Jul 15, 2026
c8ea2f0
Merge remote-tracking branch 'origin/main' into session/calm-ferret-849
briansrls Jul 15, 2026
23920cf
Merge remote-tracking branch 'origin/main' into session/calm-ferret-849
briansrls Jul 15, 2026
c37249f
Merge remote-tracking branch 'origin/main' into session/calm-ferret-849
briansrls Jul 16, 2026
4c9b4a1
Merge remote-tracking branch 'origin/main' into session/calm-ferret-849
briansrls Jul 16, 2026
1d9f4ce
WIP: shell -> dag
briansrls Jul 16, 2026
68ac441
plans: refresh shell_emission_model status — Slices 0/1(If band)/2 ha…
briansrls Jul 16, 2026
4581175
WIP: shell -> dag
briansrls Jul 16, 2026
ce4157b
plans: address review 38787 — Slice 1 marker + stop contradicting the…
briansrls Jul 16, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions dag/gunbc/plans/shell_emission_model.dag
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@ fn shell_emission_model_body() -> List<MarkdownBlock> {
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` rostered for dissolution), §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** everywhere — even `host_effect.dag` carries `ShellCommand\{script: String\}`. But the arc is **~20% built**, not 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-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:"),
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)."),
li(text: "**Intent→bash lowering exists but is bespoke** — `src/v2/compiler/05_emit_orchestration.dag` is a per-construct dispatcher, **not** the same `target_model_edge_translation_rules` table that emits Rust/TS (`06_translate.dag` has zero orchestration refs)."),
li(text: "**Control-flow emission is the greenfield work, scoped by the pre-runtime census** — `If`/`For`/`While` all return `outcome_rejected` today; only `Do\{Run\}` + a hardcoded 2-level `Retry` lower. The 2026-07-03 census found every live `For`/`While`/trap/background site is RUNTIME-PRESENT (dissolves to typed folds + argv/Pipeline interpreted by the binary), so only the `If` band is pre-runtime-justified. `Run.command:String` is the **same anemic leaf** as `host_effect.ShellCommand.script` — dissolution target `Do\{effect\}` with typed effect leaves ([host-effect-orchestration](host-effect-orchestration.md) effect-plan band)."),
li(text: "**Control-flow emission — the `If` band has since LANDED (verified 2026-07-16).** The 'all return `outcome_rejected`' text was written 2026-07-03 and is superseded: `05_emit_orchestration.dag:497` lowers `If` via `orch_emit_if_step` **with `else_`**, and every `Predicate` arm lowers (`ExitZero`, `StrEq`, `StrEmpty`, `StrNonempty`, `LogMatches`, `Not`, `And`, `Or`). `Retry` lowers with `on_exhausted` threaded. `For`/`While` still return `outcome_rejected` **by design** — the 2026-07-03 census found every live `For`/`While`/trap/background site is RUNTIME-PRESENT (dissolves to typed folds + argv/Pipeline interpreted by the binary), so only the `If` band is pre-runtime-justified; this is a decision, not a gap. `Run.command:String` remains the **same anemic leaf** as `host_effect.ShellCommand.script` — dissolution target `Do\{effect\}` with typed effect leaves ([host-effect-orchestration](host-effect-orchestration.md) effect-plan band)."),
]),
h2(text: "2. The model (locked)"),
p(text: "**ADOPT:** `intent(std)` → `bash(extdeps)` via `emit(intent, Bash)`, extending the existing dispatcher."),
Expand All @@ -38,9 +38,9 @@ fn shell_emission_model_body() -> List<MarkdownBlock> {
p(text: "**Done bar:** green by **execution** vs frozen bytes, RED on perturb — never typechecks/emits/self-referential-gate."),
h2(text: "5. Slice sequence (each gated by a frozen committed byte oracle)"),
ol(items: [
li(text: "**Slice 0 — CI EAGAIN-retry cutover:** route `dag/gunbc/ci_spec.dag` `ci_cargo_eagain_retry_core` (nested-concat blob, :68) through `render(emit(Retry,Bash))`; proven by committed `ci.yml` drift-gate staying byte-identical + existing teeth witness `orch_retry_env_value_has_teeth_holds`. Env lowering is structured since #5868+#6137 (`EnvUnset` + multi-binding `EnvPrefixed`; the former `orch_emit_run_env_welded` weld is dissolved). **Precondition:** `Retry.on_exhausted` is emitter-ignored today (matched as `_`; exhaustion baked as a fixed token) — wire it into the registry row or narrow the field to the supported behavior before cutover; a declared-but-unread field is a lying carrier."),
li(text: "**Slice 1 — control-flow emission (census-scoped):** the `If` band only — `orch_emit_step::If` arm with else, the three condition forms (command status incl. `if !`, negated pipeline, `[ ]` tests), plus pipes / cmdsubst assignment / `$?` propagation / AndOr / redirects incl. `>>` / env framing word support, each with byte goldens. `For`/`While` emission is **NOT in scope**: the pre-runtime census found zero pre-runtime sites needing them (the mirror-retry `for` loop maps to the typed Retry/escalation model interpreted by the binary). While `While` stays emitter-unsupported the model must say so — no inert `While.bound` carried as if meaningful."),
li(text: "**Slice 2 — converge thin-run:** fleet_converge steady-state (the srv1/srv2 arms: 4 for-loops, while-read drain, verdict arithmetic, 12 functions) moves INTO the binary as a typed plan interpreted via `apply()` (`EmitArtifactThenThinRun` — currently prose-only, must be MODELED as a transport arm); the emitted bash golden shrinks to the fresh-standup/self-repair bootstrap fragment plus a thin invocation line. Replaces the former 'emit the whole `.github/fleet-converge.sh`' framing per the bash-minimization rule."),
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`/`While` emission is **NOT in scope**: the pre-runtime census found zero pre-runtime sites needing them (the mirror-retry `for` loop maps to the typed Retry/escalation model interpreted by the binary) — they refuse **by design**, which is a decision, not a gap. While `While` stays emitter-unsupported the model must say so — no inert `While.bound` carried as if meaningful (the inert field is dissolved by #6718)."),
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 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)."),
]),
Expand Down
Loading
Loading