---
url: 'https://adk.nht.io/batteries/orchestration/prose.md'
description: >-
  There is no dry run, so the deterministically rendered prose IS the review
  surface — for the operator at the gate and for a model re-reading a plan it
  did not author.
---

# The Prose

## LLM summary — orchestration prose renderer

* `renderPlan(view: RawPlanView, options: RenderPlanOptions): string`. Options: `{audience: 'operator'|'model', view: 'as_planned'}` or `{audience, view: 'as_executed', run: RunProjection}`.
* Deterministic: the same view renders byte-identically every time.
* Node IDS are printed VERBATIM — a model must cite `NodeRef{node:'archive_files'}` exactly, and a step ORDINAL cannot be cited because nothing in the IR is addressed by position.
* Side-effect marking is derived from the authority VERBS, three visually distinct cases: read-only → "(no changes made — all declared verbs are read-only)"; mutating → "THIS MODIFIES DATA"; unclaimed → "NO AUTHORITY CLAIMED — … Treat as potentially mutating."
* A `NodeRef` argument renders as PROVENANCE ("← every output of step `x`"), never a fabricated value; a literal in the same call renders as its value.
* `retry`/`halt`/`skip` render distinctly, with `skip` stating its consequence. A clone's prose warns, naming the parent and the specific completed nodes.

This design has **no dry run**. We refuse to build a preview mode that pretends to execute: a simulation that mocks away real tools cannot tell you what those tools would actually do in the wild.

There is no fake execution. The rendered prose is the actual review surface: what a human operator reads before granting sign-off at the gate, and what a model reads when inspecting a plan it did not author.

```typescript
const view = await orchestration.raw.plan(orchestration.store, 'my-plan')
const prose = orchestration.render(view, { audience: 'operator', view: 'as_planned' })
```

Two audiences with opposing requirements. The operator view formats a readable narrative for risk evaluation; the model view enforces the strict inverse—exact identifiers, zero conversational filler, and no paraphrasing. Both are **deterministic**: the same view renders byte-identically every time. That determinism is what allows a cryptographic digest and human prose to correspond without silent drift.

## Node ids appear verbatim

A model extending an existing plan cannot work with conversational hand-waving. It must write `NodeRef{node: 'archive_files'}` citing the identifier verbatim.

Step **ordinals** do not appear in the prose. Nothing in the IR is addressed by position; the moment an upstream node is inserted, every subsequent ordinal is invalidated. If you hand a model "Step 3", the model will write dependencies assuming it remains Step 3. It will not.

An early iteration numbered steps sequentially and printed tool names while omitting node identifiers entirely. It produced legible, clean narrative that was completely useless: every step could be read, and not a single one could be addressed. It broke the model audience completely. Node ids are now printed verbatim.

## The side-effect marker means something

Every `call` node declares its authority—capability, scope, and verb. The side-effect marker in the prose is derived strictly from those **verbs**, never inferred from the mere existence of a call.

Three visually distinct cases:

```
(no changes made — all declared verbs are read-only)

THIS MODIFIES DATA
  ↳ plus replay-safety and what happens if it is interrupted

NO AUTHORITY CLAIMED — whether this changes anything is UNKNOWN.
  Treat as potentially mutating.
```

::: warning We are about to state an opinion
An earlier version stamped `THIS MODIFIES DATA` on **every** tool call, including a read-only directory listing.

That is not cautious engineering; it is alarm fatigue engineered into the UI. The entire purpose of the marker is to let an operator instantly distinguish innocuous reads from destructive writes. Crying wolf on twenty steps out of twenty destroys the signal. An operator scanning twenty steps for the three destructive operations will glaze over after the fifth identical banner and rubber-stamp the whole plan without reading.

The third case is worded without compromise. If an integration fails to declare its authority verbs, the engine admits ignorance immediately: whether anything changes is unknown. An unclaimed side effect is the single most critical hazard an operator needs flagged. Its absence of an explicit mutating label must never be mistaken for safety.
:::

## Arguments render as provenance

Because execution is strictly staged, a `NodeRef` argument has no evaluated value at approval time. The referenced node has not run yet. It cannot have a value, and fabricating a synthetic placeholder would be dishonest.

The renderer displays **provenance**:

```
archive_files
  paths ← every output of step `list_files`
  destination: "/backup/2026-09"
```

A literal renders as its actual value; a reference renders as the explicit origin of its incoming data. The operator is not asked to approve an imaginary preview of data that does not exist yet. They are approving the **authority bound** and the dependency wiring.

## A clone says what it is

Cloning a plan that has already run produces a plan that looks structurally identical to the original. It is not. Re-running a clone re-triggers side effects that the parent execution already committed to the outside world.

The clone's rendered prose states this fact upfront, naming the parent plan identifier and explicitly listing the specific completed nodes.

The graph itself will happily show you steps and arrows without mentioning that half of them already changed something in the outside world during an earlier run. The prose renderer exists to expose that reality, because "this copy will repeat actions already completed by a parent" is the exact piece of context a reviewer needs and cannot see from the graph.
