# Changelog

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

## [0.9.43] - 2026-10-24

### Added

- `ctx.workflow(child)` now throws a `WorkflowInfrastructureError` with `retryable: true` and a fault `code` when the local worker pool cannot run a child because of a fault in the pool or its runtime (for example `Local worker retry limit`, `Local worker cleanup was not confirmed`, `Stale work lease`, `Intercom runtime no longer active` or `Storage unavailable`), and `isRetryableWorkflowError(error)` recognizes it anywhere in an error's `cause` chain. Failures of a child's own logic keep throwing a plain `Error` ([#3889](https://github.com/bastani-inc/atomic/issues/3889))

### Changed

- Local worker leases now follow worker liveness. A worker that is still running and responding keeps its child even when the root is too busy to process its heartbeats in time, so a slow root no longer fences healthy workers with `Stale work lease`. A worker that has stopped responding is fenced after `localWorkers.leaseMs` milliseconds, which defaults to 30000 instead of the previous fixed 5000 ([#3888](https://github.com/bastani-inc/atomic/issues/3888))

### Fixed

- A local workflow worker that dies while the root still owes it replies no longer crashes the root with `Error: write EPIPE`. The root fences that worker's attempt and replays the child from its last committed checkpoint on a replacement worker ([#3887](https://github.com/bastani-inc/atomic/issues/3887))
- Each local worker's standard error is now kept in `worker-logs/<root run ID>/<worker ID>.log` in the workflow journal's directory, and the `Local worker exited before readiness`, `Local worker startup timed out` and `Local worker retry limit` errors name that file and include the end of the worker's output. Logs of workers that are still running when the pool shuts down normally are removed ([#3887](https://github.com/bastani-inc/atomic/issues/3887))
- Local worker pools no longer fail with `Local worker startup timed out` on a workflow journal with a long history. Workers no longer read every run in the journal before reporting ready, the pool starts running children once one worker is ready and fails only when none starts, and the readiness timeout can be raised with `localWorkers.startupTimeoutMs` (30000 ms by default). Once running, workers bring their view of the root up to date by reading only the journal events added since their last read, instead of re-reading the root's whole history after every checkpoint and claim. The timeout is not saved with the root, so it can change between resumes ([#3887](https://github.com/bastani-inc/atomic/issues/3887))
- Resuming a pooled root after its host process crashed no longer leaves children leased to workers that died with it. The resumed root releases those attempts as soon as it starts its new pool, and their children are replayed from their last committed checkpoints on the new workers ([#3890](https://github.com/bastani-inc/atomic/issues/3890))
- Opening or resuming a session with a large workflow journal no longer shows a blank screen and then crashes with `JavaScript heap out of memory`. Sessions, `/workflow status` and the `/workflow resume` picker now read each run's latest state instead of every event in the journal, and load a run's full history only when that run is resumed, recovered, inspected or opened ([#3892](https://github.com/bastani-inc/atomic/issues/3892))
- A local worker whose process exit cannot be confirmed during lease recovery no longer fails every child waiting on the pool with `Local worker cleanup was not confirmed`. The pool keeps the attempt fenced and retries recovery until the worker exits ([#3889](https://github.com/bastani-inc/atomic/issues/3889))

## [0.9.43-alpha.1] - 2026-10-24

### Added

- `ctx.workflow(child)` now throws a `WorkflowInfrastructureError` with `retryable: true` and a fault `code` when the local worker pool cannot run a child because of a fault in the pool or its runtime (for example `Local worker retry limit`, `Local worker cleanup was not confirmed`, `Stale work lease`, `Intercom runtime no longer active` or `Storage unavailable`), and `isRetryableWorkflowError(error)` recognizes it anywhere in an error's `cause` chain. Failures of a child's own logic keep throwing a plain `Error` ([#3889](https://github.com/bastani-inc/atomic/issues/3889))

### Changed

- Local worker leases now follow worker liveness. A worker that is still running and responding keeps its child even when the root is too busy to process its heartbeats in time, so a slow root no longer fences healthy workers with `Stale work lease`. A worker that has stopped responding is fenced after `localWorkers.leaseMs` milliseconds, which defaults to 30000 instead of the previous fixed 5000 ([#3888](https://github.com/bastani-inc/atomic/issues/3888))

### Fixed

- A local workflow worker that dies while the root still owes it replies no longer crashes the root with `Error: write EPIPE`. The root fences that worker's attempt and replays the child from its last committed checkpoint on a replacement worker ([#3887](https://github.com/bastani-inc/atomic/issues/3887))
- Each local worker's standard error is now kept in `worker-logs/<root run ID>/<worker ID>.log` in the workflow journal's directory, and the `Local worker exited before readiness`, `Local worker startup timed out` and `Local worker retry limit` errors name that file and include the end of the worker's output. Logs of workers that are still running when the pool shuts down normally are removed ([#3887](https://github.com/bastani-inc/atomic/issues/3887))
- Local worker pools no longer fail with `Local worker startup timed out` on a workflow journal with a long history. Workers no longer read every run in the journal before reporting ready, the pool starts running children once one worker is ready and fails only when none starts, and the readiness timeout can be raised with `localWorkers.startupTimeoutMs` (30000 ms by default). Once running, workers bring their view of the root up to date by reading only the journal events added since their last read, instead of re-reading the root's whole history after every checkpoint and claim. The timeout is not saved with the root, so it can change between resumes ([#3887](https://github.com/bastani-inc/atomic/issues/3887))
- Resuming a pooled root after its host process crashed no longer leaves children leased to workers that died with it. The resumed root releases those attempts as soon as it starts its new pool, and their children are replayed from their last committed checkpoints on the new workers ([#3890](https://github.com/bastani-inc/atomic/issues/3890))
- Opening or resuming a session with a large workflow journal no longer shows a blank screen and then crashes with `JavaScript heap out of memory`. Sessions, `/workflow status` and the `/workflow resume` picker now read each run's latest state instead of every event in the journal, and load a run's full history only when that run is resumed, recovered, inspected or opened ([#3892](https://github.com/bastani-inc/atomic/issues/3892))
- A local worker whose process exit cannot be confirmed during lease recovery no longer fails every child waiting on the pool with `Local worker cleanup was not confirmed`. The pool keeps the attempt fenced and retries recovery until the worker exits ([#3889](https://github.com/bastani-inc/atomic/issues/3889))

## [0.9.42] - 2026-10-23

### Added

- Local workflow pools can be enabled per run through SDK options or workflow settings, with root and optional user-wide admission limits. A root stays local while registered child workflow subtrees run in local worker processes; unsupported process containment and incompatible worker definitions fail closed ([#3869](https://github.com/bastani-inc/atomic/issues/3869)).

### Fixed

- Workflow model chains now share provider-account cooldowns after rate limits, honor `Retry-After`, and wait for the earliest eligible account instead of exhausting a cooling chain. Retries remain bounded, including retries within each session; waits can be paused or cancelled, and workflow status and task results report provider counts and cooldown deadlines. Retrying a follow-up on the same model preserves its conversation history. Follow-ups keep each model's retry allowance across account switches and can return to an earlier account when its cooldown expires ([#3864](https://github.com/bastani-inc/atomic/issues/3864)).
- Workflow stages now reload resources up to four at a time per Atomic process instead of one at a time, so a slow reload no longer blocks every other stage at startup. Cancelling a stage waiting for a reload slot removes it from the queue immediately; an active reload retains its slot until it finishes ([#3861](https://github.com/bastani-inc/atomic/issues/3861)).
- Standalone `run()` now owns Intercom routes for eligible workflow stages until the run settles, so stages can use Intercom without an interactive workflow host. An installed SDK reuses an Intercom owner the extension bundle already registered for the store instead of starting a second one. When a route-update acknowledgement times out, the update retries without disconnecting a healthy owner ([#3863](https://github.com/bastani-inc/atomic/issues/3863))

## [0.9.42-alpha.1] - 2026-10-23

### Added

- Local workflow pools can be enabled per run through SDK options or workflow settings, with root and optional user-wide admission limits. A root stays local while registered child workflow subtrees run in local worker processes; unsupported process containment and incompatible worker definitions fail closed ([#3869](https://github.com/bastani-inc/atomic/issues/3869)).

### Fixed

- Workflow model chains now share provider-account cooldowns after rate limits, honor `Retry-After`, and wait for the earliest eligible account instead of exhausting a cooling chain. Retries remain bounded, including retries within each session; waits can be paused or cancelled, and workflow status and task results report provider counts and cooldown deadlines. Retrying a follow-up on the same model preserves its conversation history. Follow-ups keep each model's retry allowance across account switches and can return to an earlier account when its cooldown expires ([#3864](https://github.com/bastani-inc/atomic/issues/3864)).
- Workflow stages now reload resources up to four at a time per Atomic process instead of one at a time, so a slow reload no longer blocks every other stage at startup. Cancelling a stage waiting for a reload slot removes it from the queue immediately; an active reload retains its slot until it finishes ([#3861](https://github.com/bastani-inc/atomic/issues/3861)).
- Standalone `run()` now owns Intercom routes for eligible workflow stages until the run settles, so stages can use Intercom without an interactive workflow host. An installed SDK reuses an Intercom owner the extension bundle already registered for the store instead of starting a second one. When a route-update acknowledgement times out, the update retries without disconnecting a healthy owner ([#3863](https://github.com/bastani-inc/atomic/issues/3863))

## [0.9.41] - 2026-10-22

### Added

- Added `schemaTimeoutMs` to workflow stage, task, chain, and parallel options: the wall-clock limit in milliseconds for each `structured_output` decision of a schema-backed item, covering its repair attempts, retries, and model fallbacks together. It defaults to the `httpIdleTimeoutMs` setting ([#3806](https://github.com/bastani-inc/atomic/issues/3806))

### Changed

- Reopening `/workflow resume` is faster: the run list is kept between opens and rereads only the runs whose journal changed since the last open, including changes made by other Atomic processes. Whether another session still owns a run is checked when you select it.
- `/workflow connect` and `/workflow status` now list runs the way `/tasks` does. Active runs come before ended ones, with runs waiting for your input or blocked first, then running, then paused; ended runs follow with failed, cancelled, then completed. Within each group the newest run comes first, where before the `/workflow connect` list showed the oldest running run first ([#3824](https://github.com/bastani-inc/atomic/issues/3824)).

### Fixed

- A rejection that workflow code leaves unhandled no longer ends the whole Atomic process. This covers a rejected `ctx.tool`, `ctx.task`, `ctx.chain`, `ctx.parallel`, `ctx.workflow`, `ctx.ui` prompt (`input`, `confirm`, `select`, `editor` or `custom`) or stage method call (`prompt`, `complete`, `steer`, `sendUserMessage`, `setModel`, `compact` and the other promise-returning stage methods), including one that is started and never awaited (`void ctx.task(...)` used to leave the run `completed` with no sign of the failure), a `ctx.tool` call made after its run has stopped (`ctx.tool admission is closed for this run`), a string, number or `undefined` thrown from a `ctx.tool` callback, and an error the workflow file throws or receives from `fs` itself, for example in a rolling pool that keeps `branch.finally(...)` as a separate promise. It also covers `ctx.exit()` called inside such a branch, which ends the run as exited with the status and outputs it asked for (on Bun the process used to end right after the run reported `completed`), and a child workflow's own branch that uses `ctx` after its parent exited. Stopping a run no longer ends the process either: a branch that keeps running after `/workflow quit`, a kill, or an abort signal from the code that started the run, and then calls `ctx.stage`, `ctx.task`, `ctx.workflow` or `ctx.exit()`, or that was waiting on a `ctx.ui` prompt when the run was killed, could end it with `workflow killed` (a kill), the quit error (`/workflow quit`), an `AbortError` or `atomic-workflows: HIL aborted` right after the run reported `killed` or `paused`, and the run keeps that status. `ctx.exit()` called in such a branch while the run is paused ends the run as exited once the run resumes, and a kill of the paused run still ends it as `killed` (on Node it used to end as `failed` with `Workflow exit is waiting for explicit resume`, and on Bun the process ended). The rejection fails its own run when it surfaces before that run decides its final status, so other runs, stages, and the interactive engine keep going; a `ctx.task`, `ctx.chain`, `ctx.parallel`, `ctx.workflow`, `ctx.ui` or stage method rejection that the workflow awaits or catches reaches that code unchanged and does not fail the run. Once the run has ended, an error that a `ctx` call rejected with, what `ctx.exit()` threw and the reason the run was stopped with are ignored (the reason of a kill is the string `workflow killed`, which is ignored by value for the rest of the process, so a branch that wakes up long after the run ended is covered too), and so is an error thrown by the workflow file for the next 30 seconds, so the remaining branches of a failing pool cannot end the process; a later one ends it as before. On Node the owning run is identified exactly; on Bun a `ctx` call's rejection, what `ctx.exit()` threw and the reason the run was stopped with are matched by identity (a `ctx` call's string, number or `undefined` only within the event-loop turn in which the call rejected, and the string a kill uses by value), and an error thrown by the workflow file itself is matched through its stack to the run of the file that calls `workflow()`, but only when no other run of that file is running or has run at the same time (a child workflow defined in the same file does not count), so a primitive thrown outside a `ctx` call on Bun is still fatal, and an error that either of two overlapping runs of one file could have thrown ends the process as before instead of failing a run that may be healthy. This works the same in the bundled install as in a source checkout. A rejection that belongs to no workflow run, including one raised by Atomic's own code, ends the process as before, with its original error and stack, and `--unhandled-rejections=warn|none|warn-with-error-code` are honored ([#3846](https://github.com/bastani-inc/atomic/issues/3846))
- A workflow that omits `name` is now named after the file that defines it when Atomic runs from the bundled install, as it already was in a source checkout, instead of after the bundled extension file (`index.bundle`) ([#3846](https://github.com/bastani-inc/atomic/issues/3846))
- `/workflow status <runId>` no longer reports `durable checkpoint topology is malformed or incomplete` for a running or crashed run whose child `ctx.workflow` calls have started but not yet recorded a stage or tool of their own, such as a pool of concurrent children when the process was killed. The children now show as running, and a crashed run can be inspected and resumed. A run that fails while such children are still starting now cancels them first, so its status can be inspected as well ([#3846](https://github.com/bastani-inc/atomic/issues/3846))
- A workflow stage no longer stays stuck selecting its model when many workflows run at once. A stage with `model: "auto"` now waits at most five minutes for model selection, counting any wait for one of eight routing slots shared by every stage, so a burst of stages queues instead of overloading the router provider. When the wait ends, the stage runs on the current chat model if that model satisfies every routing constraint; otherwise it fails with an error that names the stage and the `model-resolution` startup phase, and its startup status reads `failed` instead of staying active. A failed selection is no longer remembered, so the next prompt on the same stage selects a model again, without launching a replacement workflow.
- After a blocked workflow run is resumed, Intercom sends to `workflow:<rootRunId>/**`, to stage patterns, and to stages that have not started yet are accepted and delivered again instead of failing with `Workflow execution for <runId> is retired`.
- In a long-running session, starting a workflow from a turn that an Intercom message started no longer fails with `Workflow execution for <runId> is retired; startup cleanup failed: …` after an earlier workflow run in the session has ended or been quit. The session's Intercom connection is now opened outside the workflow run that first needed it. The `is retired` error now names the run whose execution actually ended, not the run being started.
- A workflow stage whose fallback session fails to start because an extension's `session_start` failed under load, for example Intercom's `Broker failed to start within timeout` or `connect ECONNREFUSED`, now retries that session with the same-model retry budget and then moves on to its next fallback model, instead of failing the stage and letting fail-fast skip its sibling stages. Any other extension startup error still fails the stage at once. The stage error, model attempts, and fallback warnings now name each failing extension and its error rather than only `Extension startup failed`.
- When a workflow stage falls back to another model and that fallback session cannot start, the stage now closes the session it was replacing. Before, that session kept its session database open after the stage failed, and on Windows the file could not be deleted until the process exited.
- Workflow stage sessions now provide `ctx.ui.theme` and the other default UI members, so extensions that read `ctx.ui.theme.fg(...)` in `session_start`, such as `examples/extensions/status-line.ts`, no longer fail stage startup with `Extension startup failed` ([#3801](https://github.com/bastani-inc/atomic/issues/3801))
- Workflow inputs now reject integer and number values outside the `minimum`/`maximum` declared in the input schema, such as `count: 0` for `Type.Integer({ minimum: 1, maximum: 8 })`, when the run is started, instead of passing them to the workflow body. The error names the input and the violated bound ([#3812](https://github.com/bastani-inc/atomic/issues/3812)).
- A `ctx.parallel(..., { failFast: false })` call that has a failing step no longer loses the results of the steps that succeeded. The `AggregateError` it rejects with now carries `partialResults`, one entry per step in step order, holding each completed step's result and `undefined` for a step that failed. The `WorkflowParallelFailure` type describes it ([#3809](https://github.com/bastani-inc/atomic/issues/3809))
- A workflow stage's corrective prompt after a rejected `structured_output` result now names the failing paths and expected types, or reports that the tool arguments were not valid JSON, instead of only saying the response does not match the decision schema ([#3802](https://github.com/bastani-inc/atomic/issues/3802))
- Disposing a session right after a workflow run reports that it ended no longer leaves the run `running` in the workflow journal, with its lease released, for readers to report as crashed. `session.dispose()` now waits up to 10 seconds for runs that have ended but are still recording their ending, before it closes the journal, and it rejects naming the run when that ending still cannot be recorded. A run whose journal rejects the write of its `completed` status now retries it once, and reports it with an error notice and a rejected `waitForSettled` when it still fails, instead of failing in silence ([#3811](https://github.com/bastani-inc/atomic/issues/3811))
- A schema-backed workflow stage no longer stays `running` for hours inside one `structured_output` call when a slow model keeps generating without calling the tool. The decision now stops after the `httpIdleTimeoutMs` deadline (10 minutes by default) or the stage's `schemaTimeoutMs`, and the error that names the deadline and each attempt's duration reaches the model and the failed stage unchanged instead of being treated as a structured-output contract failure ([#3806](https://github.com/bastani-inc/atomic/issues/3806))

## [0.9.41-alpha.2] - 2026-10-22

### Fixed

- A rejection that workflow code leaves unhandled no longer ends the whole Atomic process. This covers a rejected `ctx.tool`, `ctx.task`, `ctx.chain`, `ctx.parallel`, `ctx.workflow`, `ctx.ui` prompt (`input`, `confirm`, `select`, `editor` or `custom`) or stage method call (`prompt`, `complete`, `steer`, `sendUserMessage`, `setModel`, `compact` and the other promise-returning stage methods), including one that is started and never awaited (`void ctx.task(...)` used to leave the run `completed` with no sign of the failure), a `ctx.tool` call made after its run has stopped (`ctx.tool admission is closed for this run`), a string, number or `undefined` thrown from a `ctx.tool` callback, and an error the workflow file throws or receives from `fs` itself, for example in a rolling pool that keeps `branch.finally(...)` as a separate promise. It also covers `ctx.exit()` called inside such a branch, which ends the run as exited with the status and outputs it asked for (on Bun the process used to end right after the run reported `completed`), and a child workflow's own branch that uses `ctx` after its parent exited. Stopping a run no longer ends the process either: a branch that keeps running after `/workflow quit`, a kill, or an abort signal from the code that started the run, and then calls `ctx.stage`, `ctx.task`, `ctx.workflow` or `ctx.exit()`, or that was waiting on a `ctx.ui` prompt when the run was killed, could end it with `workflow killed` (a kill), the quit error (`/workflow quit`), an `AbortError` or `atomic-workflows: HIL aborted` right after the run reported `killed` or `paused`, and the run keeps that status. `ctx.exit()` called in such a branch while the run is paused ends the run as exited once the run resumes, and a kill of the paused run still ends it as `killed` (on Node it used to end as `failed` with `Workflow exit is waiting for explicit resume`, and on Bun the process ended). The rejection fails its own run when it surfaces before that run decides its final status, so other runs, stages, and the interactive engine keep going; a `ctx.task`, `ctx.chain`, `ctx.parallel`, `ctx.workflow`, `ctx.ui` or stage method rejection that the workflow awaits or catches reaches that code unchanged and does not fail the run. Once the run has ended, an error that a `ctx` call rejected with, what `ctx.exit()` threw and the reason the run was stopped with are ignored (the reason of a kill is the string `workflow killed`, which is ignored by value for the rest of the process, so a branch that wakes up long after the run ended is covered too), and so is an error thrown by the workflow file for the next 30 seconds, so the remaining branches of a failing pool cannot end the process; a later one ends it as before. On Node the owning run is identified exactly; on Bun a `ctx` call's rejection, what `ctx.exit()` threw and the reason the run was stopped with are matched by identity (a `ctx` call's string, number or `undefined` only within the event-loop turn in which the call rejected, and the string a kill uses by value), and an error thrown by the workflow file itself is matched through its stack to the run of the file that calls `workflow()`, but only when no other run of that file is running or has run at the same time (a child workflow defined in the same file does not count), so a primitive thrown outside a `ctx` call on Bun is still fatal, and an error that either of two overlapping runs of one file could have thrown ends the process as before instead of failing a run that may be healthy. This works the same in the bundled install as in a source checkout. A rejection that belongs to no workflow run, including one raised by Atomic's own code, ends the process as before, with its original error and stack, and `--unhandled-rejections=warn|none|warn-with-error-code` are honored ([#3846](https://github.com/bastani-inc/atomic/issues/3846))
- A workflow that omits `name` is now named after the file that defines it when Atomic runs from the bundled install, as it already was in a source checkout, instead of after the bundled extension file (`index.bundle`) ([#3846](https://github.com/bastani-inc/atomic/issues/3846))
- `/workflow status <runId>` no longer reports `durable checkpoint topology is malformed or incomplete` for a running or crashed run whose child `ctx.workflow` calls have started but not yet recorded a stage or tool of their own, such as a pool of concurrent children when the process was killed. The children now show as running, and a crashed run can be inspected and resumed. A run that fails while such children are still starting now cancels them first, so its status can be inspected as well ([#3846](https://github.com/bastani-inc/atomic/issues/3846))

## [0.9.41-alpha.1] - 2026-10-21

### Added

- Added `schemaTimeoutMs` to workflow stage, task, chain, and parallel options: the wall-clock limit in milliseconds for each `structured_output` decision of a schema-backed item, covering its repair attempts, retries, and model fallbacks together. It defaults to the `httpIdleTimeoutMs` setting ([#3806](https://github.com/bastani-inc/atomic/issues/3806))

### Changed

- Reopening `/workflow resume` is faster: the run list is kept between opens and rereads only the runs whose journal changed since the last open, including changes made by other Atomic processes. Whether another session still owns a run is checked when you select it.
- `/workflow connect` and `/workflow status` now list runs the way `/tasks` does. Active runs come before ended ones, with runs waiting for your input or blocked first, then running, then paused; ended runs follow with failed, cancelled, then completed. Within each group the newest run comes first, where before the `/workflow connect` list showed the oldest running run first ([#3824](https://github.com/bastani-inc/atomic/issues/3824)).

### Fixed

- A workflow stage no longer stays stuck selecting its model when many workflows run at once. A stage with `model: "auto"` now waits at most five minutes for model selection, counting any wait for one of eight routing slots shared by every stage, so a burst of stages queues instead of overloading the router provider. When the wait ends, the stage runs on the current chat model if that model satisfies every routing constraint; otherwise it fails with an error that names the stage and the `model-resolution` startup phase, and its startup status reads `failed` instead of staying active. A failed selection is no longer remembered, so the next prompt on the same stage selects a model again, without launching a replacement workflow.
- After a blocked workflow run is resumed, Intercom sends to `workflow:<rootRunId>/**`, to stage patterns, and to stages that have not started yet are accepted and delivered again instead of failing with `Workflow execution for <runId> is retired`.
- In a long-running session, starting a workflow from a turn that an Intercom message started no longer fails with `Workflow execution for <runId> is retired; startup cleanup failed: …` after an earlier workflow run in the session has ended or been quit. The session's Intercom connection is now opened outside the workflow run that first needed it. The `is retired` error now names the run whose execution actually ended, not the run being started.
- A workflow stage whose fallback session fails to start because an extension's `session_start` failed under load, for example Intercom's `Broker failed to start within timeout` or `connect ECONNREFUSED`, now retries that session with the same-model retry budget and then moves on to its next fallback model, instead of failing the stage and letting fail-fast skip its sibling stages. Any other extension startup error still fails the stage at once. The stage error, model attempts, and fallback warnings now name each failing extension and its error rather than only `Extension startup failed`.
- When a workflow stage falls back to another model and that fallback session cannot start, the stage now closes the session it was replacing. Before, that session kept its session database open after the stage failed, and on Windows the file could not be deleted until the process exited.
- Workflow stage sessions now provide `ctx.ui.theme` and the other default UI members, so extensions that read `ctx.ui.theme.fg(...)` in `session_start`, such as `examples/extensions/status-line.ts`, no longer fail stage startup with `Extension startup failed` ([#3801](https://github.com/bastani-inc/atomic/issues/3801))
- Workflow inputs now reject integer and number values outside the `minimum`/`maximum` declared in the input schema, such as `count: 0` for `Type.Integer({ minimum: 1, maximum: 8 })`, when the run is started, instead of passing them to the workflow body. The error names the input and the violated bound ([#3812](https://github.com/bastani-inc/atomic/issues/3812)).
- A `ctx.parallel(..., { failFast: false })` call that has a failing step no longer loses the results of the steps that succeeded. The `AggregateError` it rejects with now carries `partialResults`, one entry per step in step order, holding each completed step's result and `undefined` for a step that failed. The `WorkflowParallelFailure` type describes it ([#3809](https://github.com/bastani-inc/atomic/issues/3809))
- A workflow stage's corrective prompt after a rejected `structured_output` result now names the failing paths and expected types, or reports that the tool arguments were not valid JSON, instead of only saying the response does not match the decision schema ([#3802](https://github.com/bastani-inc/atomic/issues/3802))
- Disposing a session right after a workflow run reports that it ended no longer leaves the run `running` in the workflow journal, with its lease released, for readers to report as crashed. `session.dispose()` now waits up to 10 seconds for runs that have ended but are still recording their ending, before it closes the journal, and it rejects naming the run when that ending still cannot be recorded. A run whose journal rejects the write of its `completed` status now retries it once, and reports it with an error notice and a rejected `waitForSettled` when it still fails, instead of failing in silence ([#3811](https://github.com/bastani-inc/atomic/issues/3811))
- A schema-backed workflow stage no longer stays `running` for hours inside one `structured_output` call when a slow model keeps generating without calling the tool. The decision now stops after the `httpIdleTimeoutMs` deadline (10 minutes by default) or the stage's `schemaTimeoutMs`, and the error that names the deadline and each attempt's duration reaches the model and the failed stage unchanged instead of being treated as a structured-output contract failure ([#3806](https://github.com/bastani-inc/atomic/issues/3806))

## [0.9.40] - 2026-10-20

### Added

- The workflow journal can be selected for one process with `ATOMIC_WORKFLOWS_JOURNAL`, `ATOMIC_STORAGE`, or Atomic's `--storage` and `--storage-file` flags, using the same JSON as the `workflows.journal` and `storage` settings. Setting `ATOMIC_WORKFLOWS_JOURNAL` together with `ATOMIC_WORKFLOW_JOURNAL_PATH` is rejected as a conflict ([#3783](https://github.com/bastani-inc/atomic/issues/3783)).

### Changed

- Updated the bundled Impeccable skill to 4.7.0 with engine 0.1.16. Critique and audit can scan a running Electron, NW.js, CEF, or WebView2 app window through its debugging port (`impeccable detect --cdp 9222`), and critique runs its design review on iOS, Android, and adaptive projects instead of reporting an empty web scan as clean. New `straggler` and `unbalanced-heading` typography checks flag a paragraph ending on one word and a heading whose last line is a stub, and the detector raises fewer false alarms on hidden, screen-reader-only, and layered content. Decision and review pages follow the OS dark mode, `context` offers only workspaces that render a UI as targets, and the Claude Code design hook can be installed in your user settings instead of the project's. Live Mode now starts on LAN and Tailscale addresses over plain HTTP, copying works there when the clipboard API is unavailable, and an interrupted engine download cleans up after itself. Atomic's launcher still turns off the engine's choice reports and update check by default.

### Fixed

- Resuming a workflow restores the background subagents its stages launched and delivers the stages' interrupted messages before the stage continues. Both happen visibly in the stage, and stages stay addressable at the same `workflow:<rootRunId>/...` targets ([#3760](https://github.com/bastani-inc/atomic/issues/3760)).
- An interrupted workflow run stays addressable after the session that launched it restarts, before you run `/workflow resume`. Sends to `workflow:<rootRunId>/<stage>` and `workflow:<rootRunId>/**` are queued in the run's own journal instead of failing with `Session not found`, and `intercom list` shows the run's stages as pending. Each queued message is delivered exactly once when its stage is live again, including messages sent while resume is starting. A queued message no longer makes a resume that started at the same time fail as stale. The background subagents that the run's stages launched stay addressable in the same interval: sends to them wait and are delivered once after the resumed stage restores them. If another Atomic session resumes the run instead, that session takes over the run's Intercom targets and the sends still waiting for the subagents get an error saying so ([#3760](https://github.com/bastani-inc/atomic/issues/3760)).
- A session created with its own `agentDir` now keeps its workflow runs in the same storage as its sessions. Relative paths, `{ file }` secrets, and storage adapters in a shared `storage` selection, from settings or from `ATOMIC_STORAGE`/`--storage`, previously resolved against the default Atomic home for workflow runs, and the default journal ignored the custom `agentDir` ([#3783](https://github.com/bastani-inc/atomic/issues/3783)).
- On Windows, removing a workflow's temporary worktree now deletes the worktree directory and leaves the main checkout's `node_modules` alone. Atomic unlinks the worktree's `node_modules` junction, and any other directory it linked, before asking Git to remove the worktree. Current Git for Windows left these worktrees behind, and older releases could delete the main checkout's `node_modules` through the junction. If Atomic cannot inspect or unlink one of these links, it leaves the worktree and its branch in place rather than risk Git following the link.
- Killing a workflow run while it waits, after Atomic restarts, for `/workflow resume` now ends the background subagents its stages launched. Their launch cards no longer show them as resumable, and reopening a stage's session no longer restores them ([#3784](https://github.com/bastani-inc/atomic/pull/3784)).
- Quitting Atomic after opening the workflow graph or `/workflow` run picker no longer prints an `AbortError: The operation was aborted.` trace. The graph overlay also remounts cleanly when it is opened again after a reload.

## [0.9.40-alpha.2] - 2026-10-20

### Fixed

- Quitting Atomic after opening the workflow graph or `/workflow` run picker no longer prints an `AbortError: The operation was aborted.` trace. The graph overlay also remounts cleanly when it is opened again after a reload.

## [0.9.40-alpha.1] - 2026-10-20

### Added

- The workflow journal can be selected for one process with `ATOMIC_WORKFLOWS_JOURNAL`, `ATOMIC_STORAGE`, or Atomic's `--storage` and `--storage-file` flags, using the same JSON as the `workflows.journal` and `storage` settings. Setting `ATOMIC_WORKFLOWS_JOURNAL` together with `ATOMIC_WORKFLOW_JOURNAL_PATH` is rejected as a conflict ([#3783](https://github.com/bastani-inc/atomic/issues/3783)).

### Changed

- Updated the bundled Impeccable skill to 4.7.0 with engine 0.1.16. Critique and audit can scan a running Electron, NW.js, CEF, or WebView2 app window through its debugging port (`impeccable detect --cdp 9222`), and critique runs its design review on iOS, Android, and adaptive projects instead of reporting an empty web scan as clean. New `straggler` and `unbalanced-heading` typography checks flag a paragraph ending on one word and a heading whose last line is a stub, and the detector raises fewer false alarms on hidden, screen-reader-only, and layered content. Decision and review pages follow the OS dark mode, `context` offers only workspaces that render a UI as targets, and the Claude Code design hook can be installed in your user settings instead of the project's. Live Mode now starts on LAN and Tailscale addresses over plain HTTP, copying works there when the clipboard API is unavailable, and an interrupted engine download cleans up after itself. Atomic's launcher still turns off the engine's choice reports and update check by default.

### Fixed

- Resuming a workflow restores the background subagents its stages launched and delivers the stages' interrupted messages before the stage continues. Both happen visibly in the stage, and stages stay addressable at the same `workflow:<rootRunId>/...` targets ([#3760](https://github.com/bastani-inc/atomic/issues/3760)).
- An interrupted workflow run stays addressable after the session that launched it restarts, before you run `/workflow resume`. Sends to `workflow:<rootRunId>/<stage>` and `workflow:<rootRunId>/**` are queued in the run's own journal instead of failing with `Session not found`, and `intercom list` shows the run's stages as pending. Each queued message is delivered exactly once when its stage is live again, including messages sent while resume is starting. A queued message no longer makes a resume that started at the same time fail as stale. The background subagents that the run's stages launched stay addressable in the same interval: sends to them wait and are delivered once after the resumed stage restores them. If another Atomic session resumes the run instead, that session takes over the run's Intercom targets and the sends still waiting for the subagents get an error saying so ([#3760](https://github.com/bastani-inc/atomic/issues/3760)).
- A session created with its own `agentDir` now keeps its workflow runs in the same storage as its sessions. Relative paths, `{ file }` secrets, and storage adapters in a shared `storage` selection, from settings or from `ATOMIC_STORAGE`/`--storage`, previously resolved against the default Atomic home for workflow runs, and the default journal ignored the custom `agentDir` ([#3783](https://github.com/bastani-inc/atomic/issues/3783)).
- On Windows, removing a workflow's temporary worktree now deletes the worktree directory and leaves the main checkout's `node_modules` alone. Atomic unlinks the worktree's `node_modules` junction, and any other directory it linked, before asking Git to remove the worktree. Current Git for Windows left these worktrees behind, and older releases could delete the main checkout's `node_modules` through the junction. If Atomic cannot inspect or unlink one of these links, it leaves the worktree and its branch in place rather than risk Git following the link.
- Killing a workflow run while it waits, after Atomic restarts, for `/workflow resume` now ends the background subagents its stages launched. Their launch cards no longer show them as resumable, and reopening a stage's session no longer restores them ([#3784](https://github.com/bastani-inc/atomic/pull/3784)).

## [0.9.39] - 2026-10-19

### Added

- `workflow({ action: "status", runId, summary: true })` returns a compact status of one run: status, timing, final outputs (`result`), error and blockers (failed or blocked stages and tools, and stages awaiting input), without the stage and tool history ([#3744](https://github.com/bastani-inc/atomic/issues/3744)).

### Fixed

- `workflow({ action: "status", runId })` for a run another session started now includes the run's final outputs in `detail.result`, because the journal now records them when the run finishes; runs finished by an earlier version have no recorded outputs ([#3744](https://github.com/bastani-inc/atomic/issues/3744)).
- A workflow run that finishes after receiving a sticky Intercom message (for example a send to `workflow:<rootRunId>/**`) no longer prints `pending stage delivery sweep failed: Workflow execution for <runId> is retired`, and its leftover sticky messages are settled instead of staying queued ([#3745](https://github.com/bastani-inc/atomic/issues/3745)).
- The `workflow` tool now honours the session's settings, including in-memory `workflows.journal` settings, and a per-session `journal` passed to `createAgentSession`, instead of reading only `ATOMIC_WORKFLOW_JOURNAL_PATH` and `settings.json`. A memory journal selected through session settings belongs to that session alone, and disposing a session closes the journals it opened (once no other session shares them) instead of keeping them and their process-exit hooks until exit ([#3743](https://github.com/bastani-inc/atomic/issues/3743)).
- Disposing a session now leaves its paused workflow runs `paused` and resumable instead of turning them `failed` with `SessionClosed`, and a run whose stage was mid-step when the session closed is paused rather than failed. `session.workflows.resume(runId)` still adopts the released runs ([#3742](https://github.com/bastani-inc/atomic/issues/3742)).
- Completed workflow stages no longer keep their agent sessions in memory for the life of the process, which could exhaust the V8 heap in long-running sessions. When a run ends, including a run that failed and can be resumed, each completed stage whose conversation is saved is disposed and dropped from the stage registry and completed-workflow inspection; attaching to it or messaging it reopens the saved conversation without rerunning the workflow, and the stage stays in the Intercom list as `closed · reply: post-mortem only` for as long as the session that ran the workflow is open: an ask to it reopens the saved conversation, runs one turn with the question, and returns that turn's answer. A stage with a mounted chat (visible or hidden), queued or in-flight messages, an active turn, compaction or retry, or no saved transcript stays live until the session that ran the workflow is replaced or shut down, and a stage reopened by attach, a message, or an Intercom ask stays in memory until then ([#3622](https://github.com/bastani-inc/atomic/issues/3622) by [@vishnu363728](https://github.com/vishnu363728)).

## [0.9.39-alpha.1] - 2026-10-19

### Added

- `workflow({ action: "status", runId, summary: true })` returns a compact status of one run: status, timing, final outputs (`result`), error and blockers (failed or blocked stages and tools, and stages awaiting input), without the stage and tool history ([#3744](https://github.com/bastani-inc/atomic/issues/3744)).

### Fixed

- `workflow({ action: "status", runId })` for a run another session started now includes the run's final outputs in `detail.result`, because the journal now records them when the run finishes; runs finished by an earlier version have no recorded outputs ([#3744](https://github.com/bastani-inc/atomic/issues/3744)).
- A workflow run that finishes after receiving a sticky Intercom message (for example a send to `workflow:<rootRunId>/**`) no longer prints `pending stage delivery sweep failed: Workflow execution for <runId> is retired`, and its leftover sticky messages are settled instead of staying queued ([#3745](https://github.com/bastani-inc/atomic/issues/3745)).
- The `workflow` tool now honours the session's settings, including in-memory `workflows.journal` settings, and a per-session `journal` passed to `createAgentSession`, instead of reading only `ATOMIC_WORKFLOW_JOURNAL_PATH` and `settings.json`. A memory journal selected through session settings belongs to that session alone, and disposing a session closes the journals it opened (once no other session shares them) instead of keeping them and their process-exit hooks until exit ([#3743](https://github.com/bastani-inc/atomic/issues/3743)).
- Disposing a session now leaves its paused workflow runs `paused` and resumable instead of turning them `failed` with `SessionClosed`, and a run whose stage was mid-step when the session closed is paused rather than failed. `session.workflows.resume(runId)` still adopts the released runs ([#3742](https://github.com/bastani-inc/atomic/issues/3742)).
- Completed workflow stages no longer keep their agent sessions in memory for the life of the process, which could exhaust the V8 heap in long-running sessions. When a run ends, including a run that failed and can be resumed, each completed stage whose conversation is saved is disposed and dropped from the stage registry and completed-workflow inspection; attaching to it or messaging it reopens the saved conversation without rerunning the workflow, and the stage stays in the Intercom list as `closed · reply: post-mortem only` for as long as the session that ran the workflow is open: an ask to it reopens the saved conversation, runs one turn with the question, and returns that turn's answer. A stage with a mounted chat (visible or hidden), queued or in-flight messages, an active turn, compaction or retry, or no saved transcript stays live until the session that ran the workflow is replaced or shut down, and a stage reopened by attach, a message, or an Intercom ask stays in memory until then ([#3622](https://github.com/bastani-inc/atomic/issues/3622) by [@vishnu363728](https://github.com/vishnu363728)).

## [0.9.38] - 2026-10-18

### Breaking Changes

- Workflow discovery now reads only `.atomic` default roots. Discovered workflow modules use `@bastani/atomic/workflows` and `typebox` imports. Removed deprecated imperative API stubs, separate `thinkingLevel` and `fallbackThinkingLevels` authoring fields, old stage-target syntax, and replay without current topology, replay keys, or child exit tags. Put reasoning effort in each model string, such as `provider/model:high`.
- Execution results always include `toolNodes`, inspection details and status summaries always include `tools`, and custom UI adapters must implement every UI method. Queued stage delivery requires persisted admission order.
- Heartbeat records require their original launch cadence; incomplete records no longer inherit the current workflow definition. Configuration load results always include `globalConfig` and `projectConfig`, using `null` when a source is absent or invalid.
- Public run snapshots require `toolNodes`. Inline forms require injected keybindings and no longer include unused submit-choice state. Removed the ignored `preserveAnsi` truncation argument; text truncation remains ANSI-aware.
- Workflow runs now persist only in the local SQLite journal. Journal initialization failures throw `StorageUnavailableError` instead of continuing without durable storage. Postgres connection settings (`workflows.durability.systemDatabaseUrl` and `workflows.durability.poolSize`) and `DBOS_SYSTEM_DATABASE_URL`, `ATOMIC_POSTGRES_*`, and `PG*` environment variables no longer configure workflow storage.
- Removed the SDK `durability` option, `WorkflowDurability`, and `WorkflowDurabilityRequiredError`. Use `RunOpts.journal` to select storage or isolate runs, and handle typed journal errors when storage is unavailable.
- Removed `InMemoryDurableBackend` and `createInMemoryTestBackend`. Use `JournalDurableBackend` over `MemoryRunJournal` for an explicitly in-memory backend. Removed the `legacyRecovery` workflow-tool argument and remaining `workflows.durability` settings.
- Removed the `@bastani/workflows` import alias; use `@bastani/atomic/workflows`.
- Custom `RunJournal` implementations must provide `getRun`, `takeoverExpired`, `leaseState`, lazy paged `read`, and `deleteOwnedRun(lease)` for atomic lease-fenced deletion. Synchronous fast paths are internal.
- Invocation records require `invocationFingerprint`.
- SDK workflow stages now use persistent session storage by default, including stages without `sessionDir`. Ephemeral stages must explicitly supply an in-memory session manager through an adapter. Storage failures do not fall back to memory.
- Replaced `SqliteRunJournal` with async `SqlRunJournal.open(database, { prefix })` and `openSqlRunJournal(pathOrDatabase?)`; await `resolveRunJournal`. Journal tables now use the `wf_` namespace with no migration of earlier unreleased tables. Journal storage errors use the shared `StorageUnavailableError` fields `adapter`, `location`, and `cause` instead of `path`.
- Custom journals must return `LeaseState.ageMs`, a non-negative safe-integer renewal age measured by the journal clock in the same read as the lease state. Ownership probes use this age rather than the process clock.
- Construct `JournalDurableBackend` with asynchronous `open()`; direct construction and internal synchronous journal methods have been removed.
- `RunOpts.journal.database` requires the async SQLite facade; wrap an existing native connection with `wrapNodeSqliteDatabase`. Journal selection errors now use `StorageConfigError` and its `source`, `field`, and `reason` fields instead of `JournalConfigurationError`.
- Replaced `forkFromSessionFile` with `forkFromSessionId`. Use the prior task's `sessionId` in the selected session store. `recordStageSession` now accepts `{ sessionId }` only. Retained chat validation and completed inspection are asynchronous, and transcript paths are display metadata, not resume or fork identities.
- Durable backend registration, status, reset, and checkpoint writes now use awaited `commit*` methods. Replace `registerWorkflow` with `commitWorkflowRegistration`, `setWorkflowStatus` with `commitWorkflowStatus`, `transitionWorkflowStatus` with `commitWorkflowStatusTransition`, `adjustPendingPrompts` with `commitPendingPromptAdjustment`, and `reset` with `commitReset`. Use `commitCheckpoint` instead of either checkpoint writer and `commitAdditiveCheckpointBestEffort` for additive writes. Cached `ctx.stage()` declarations remain synchronous; their replay metadata is committed before the next async execution boundary.

### Added

- Added `MemoryRunJournal`, public SQLite journal and error exports, and `registerRunJournalConformance` for shared journal contract checks.
- Added `RunOpts.journal` and `resolveRunJournal` for explicit journals, caller-owned SQLite connections, memory journals, and configurable files. TUI, CLI, background, and SDK runs use the selected journal. Resolution prioritizes the explicit option, a non-empty `ATOMIC_WORKFLOW_JOURNAL_PATH`, then journal settings and the default path. Relative settings paths resolve against the Atomic home directory.
- Extended shared journal conformance checks to cover detached values, closed-journal rejection, failure atomicity, and deletion tombstones.
- Added stale-only async journal takeover and read-only ownership inspection. Keyed append retries return the original entry before checking sequence expectations. Shared journal conformance covers stale-only takeover and early read termination.
- Added facade-backed SQL journals for user-supplied SQLite-compatible drivers, optional table prefixes, shared session/journal databases, database-clock lease expiry, and sequence-checked `deleteOwnedRun(lease, expectSeq?)`.
- Added journal adapter module selection with environment/file secret references and shared `storage` settings. SDK options override environment, journal settings, shared storage, and persistent defaults; nearer settings replace complete selections. Caller-owned database selections accept the async SQLite facade and remain open after journal close.

### Fixed

- Fixed second and later durable SDK `run()` calls in the same process failing with `atomicWorkflowHandle is not a registered DBOS workflow function`. Each standalone run now recreates its durable backend after the previous run shuts it down ([#3614](https://github.com/bastani-inc/atomic/issues/3614)).
- Fixed workflow fallback leaking the original stage session when an intervening candidate fails to initialize. The original session is now disposed exactly once after it becomes idle when a successor is adopted, or during final cleanup if no successor is created ([#3655](https://github.com/bastani-inc/atomic/issues/3655)).
- Fixed retained stage history load failures appearing as empty archives. Missing, unreadable, malformed, empty, or deleted session files now show an actionable session-unavailable warning without creating a blank session or discarding displayed messages ([#3658](https://github.com/bastani-inc/atomic/issues/3658)).
- Fixed standalone SDK `run()` resolving string stage models, including thinking suffixes and fallback models, instead of crashing during session creation ([#3629](https://github.com/bastani-inc/atomic/issues/3629)).
- Fixed queued Intercom instructions preventing stage model fallback. Delivery failures now block resumably and preserve sticky instructions for resumed runs and later stages ([#3628](https://github.com/bastani-inc/atomic/issues/3628)).
- Fixed workflow recovery reporting a foreign run as available at the exact lease-expiry boundary before takeover is permitted ([#3681](https://github.com/bastani-inc/atomic/pull/3681)).
- SQL journals snapshot append payloads at invocation, including keyed retries, preserving status/event consistency during queued writes. User-supplied facades may return readonly rows. Header and append serialization failures now retain typed storage errors and their original causes without changing fencing, replay, or sequence-check precedence.
- Journal run summaries and status validation now use the serialized `StatusChanged` payload, including transformations by `toJSON`, so recorded events and summaries agree. Ownership inspection now honors the journal clock even when the process clock is skewed.
- Fixed workflow error cards hiding text-only failures as `no result`. Errors without structured details now show their text and an error indication in collapsed and expanded cards ([#3669](https://github.com/bastani-inc/atomic/issues/3669)).
- Fixed failed workflow resumes reporting partial progress solely because a sibling was already running. Requests with no acknowledged effect now report no change and retain their failure code ([#3670](https://github.com/bastani-inc/atomic/issues/3670)).
- Fixed workflow pause reporting `noop` after a stage pause took effect but durable capture failed, including whole-run and bulk requests. The result now reports `partial`, explains that the pause remains in effect, and preserves the failure code and message ([#3671](https://github.com/bastani-inc/atomic/issues/3671)).
- Workflow journal shutdown waits for queued writes before releasing ownership. Status claims and checkpoints on the same run remain ordered with asynchronous journals.
- Completed standalone SDK runs now release their stage sessions when no caller registry owns them. Workflow forks and completed-history inspection release temporary session-store connections while preserving caller-owned stores.
- Starting a workflow after a workflow's completed, failed, or blocked notice no longer fails with `Workflow execution for <runId> is retired`. Notices and late stage messages now reach the chat outside the finished run's execution context.
- Fixed `/workflow resume` no longer listing or resuming runs recorded before 0.9.38-alpha.6. The default journal now lists runs from its earlier tables and converts a run only when you resume or inspect it, so opening the journal does no extra work. The earlier tables are left in place, and deleted runs stay deleted. Stage checkpoints that identified their session only by transcript path now resume by that transcript's session ID, so their conversations reopen after sessions are imported into the default store.
- Fixed the `Workflow discovery diagnostics` warning appearing twice at startup when deferred startup, such as project trust, refreshes workflow discovery. An unchanged report is shown once; a refresh that changes it still shows the new one ([#3703](https://github.com/bastani-inc/atomic/issues/3703)).

### Removed

- Removed DBOS, embedded Postgres, their bundled runtimes and native process ownership, and the non-durable storage fallback. Server-specific admission, recovery, outage handling, and deferred persistence queues are gone; workflow pause, resume, quit, answer, and checkpoint replay remain supported.

## [0.9.38-alpha.11] - 2026-10-17

### Fixed

- Fixed the `Workflow discovery diagnostics` warning appearing twice at startup when deferred startup, such as project trust, refreshes workflow discovery. An unchanged report is shown once; a refresh that changes it still shows the new one ([#3703](https://github.com/bastani-inc/atomic/issues/3703)).

## [0.9.38-alpha.8] - 2026-10-17

### Fixed

- Fixed `/workflow resume` no longer listing or resuming runs recorded before 0.9.38-alpha.6. The default journal now lists runs from its earlier tables and converts a run only when you resume or inspect it, so opening the journal does no extra work. The earlier tables are left in place, and deleted runs stay deleted. Stage checkpoints that identified their session only by transcript path now resume by that transcript's session ID, so their conversations reopen after sessions are imported into the default store.

## [0.9.38-alpha.7] - 2026-10-17

### Breaking Changes

- Construct `JournalDurableBackend` with asynchronous `open()`; direct construction and internal synchronous journal methods have been removed.
- `RunOpts.journal.database` requires the async SQLite facade; wrap an existing native connection with `wrapNodeSqliteDatabase`. Journal selection errors now use `StorageConfigError` and its `source`, `field`, and `reason` fields instead of `JournalConfigurationError`.
- Replaced `forkFromSessionFile` with `forkFromSessionId`. Use the prior task's `sessionId` in the selected session store. `recordStageSession` now accepts `{ sessionId }` only. Retained chat validation and completed inspection are asynchronous, and transcript paths are display metadata, not resume or fork identities.
- Durable backend registration, status, reset, and checkpoint writes now use awaited `commit*` methods. Replace `registerWorkflow` with `commitWorkflowRegistration`, `setWorkflowStatus` with `commitWorkflowStatus`, `transitionWorkflowStatus` with `commitWorkflowStatusTransition`, `adjustPendingPrompts` with `commitPendingPromptAdjustment`, and `reset` with `commitReset`. Use `commitCheckpoint` instead of either checkpoint writer and `commitAdditiveCheckpointBestEffort` for additive writes. Cached `ctx.stage()` declarations remain synchronous; their replay metadata is committed before the next async execution boundary.

### Added

- Added journal adapter module selection with environment/file secret references and shared `storage` settings. SDK options override environment, journal settings, shared storage, and persistent defaults; nearer settings replace complete selections. Caller-owned database selections accept the async SQLite facade and remain open after journal close.

### Fixed

- Workflow journal shutdown waits for queued writes before releasing ownership. Status claims and checkpoints on the same run remain ordered with asynchronous journals.
- Completed standalone SDK runs now release their stage sessions when no caller registry owns them. Workflow forks and completed-history inspection release temporary session-store connections while preserving caller-owned stores.
- Starting a workflow after a workflow's completed, failed, or blocked notice no longer fails with `Workflow execution for <runId> is retired`. Notices and late stage messages now reach the chat outside the finished run's execution context.

## [0.9.38-alpha.6] - 2026-10-16

### Breaking Changes

- Removed the SDK `durability` option, `WorkflowDurability`, and `WorkflowDurabilityRequiredError`. Use `RunOpts.journal` to select storage or isolate runs, and handle typed journal errors when storage is unavailable.
- Removed `InMemoryDurableBackend` and `createInMemoryTestBackend`. Use `JournalDurableBackend` over `MemoryRunJournal` for an explicitly in-memory backend. Removed the `legacyRecovery` workflow-tool argument and remaining `workflows.durability` settings.
- Removed the `@bastani/workflows` import alias; use `@bastani/atomic/workflows`.
- Custom `RunJournal` implementations must provide `getRun`, `takeoverExpired`, `leaseState`, lazy paged `read`, and `deleteOwnedRun(lease)` for atomic lease-fenced deletion. Synchronous fast paths are internal.
- Invocation records require `invocationFingerprint`.
- SDK workflow stages now use persistent session storage by default, including stages without `sessionDir`. Ephemeral stages must explicitly supply an in-memory session manager through an adapter. Storage failures do not fall back to memory.
- Replaced `SqliteRunJournal` with async `SqlRunJournal.open(database, { prefix })` and `openSqlRunJournal(pathOrDatabase?)`; await `resolveRunJournal`. Journal tables now use the `wf_` namespace with no migration of earlier unreleased tables. Journal storage errors use the shared `StorageUnavailableError` fields `adapter`, `location`, and `cause` instead of `path`.
- Custom journals must return `LeaseState.ageMs`, a non-negative safe-integer renewal age measured by the journal clock in the same read as the lease state. Ownership probes use this age rather than the process clock.

### Added

- Added `RunOpts.journal` and `resolveRunJournal` for explicit journals, caller-owned SQLite connections, memory journals, and configurable files. TUI, CLI, background, and SDK runs use the selected journal. Resolution prioritizes the explicit option, a non-empty `ATOMIC_WORKFLOW_JOURNAL_PATH`, then journal settings and the default path. Relative settings paths resolve against the Atomic home directory.
- Extended shared journal conformance checks to cover detached values, closed-journal rejection, failure atomicity, and deletion tombstones.
- Added stale-only async journal takeover and read-only ownership inspection. Keyed append retries return the original entry before checking sequence expectations. Shared journal conformance covers stale-only takeover and early read termination.
- Added facade-backed SQL journals for user-supplied SQLite-compatible drivers, optional table prefixes, shared session/journal databases, database-clock lease expiry, and sequence-checked `deleteOwnedRun(lease, expectSeq?)`.

### Fixed

- Fixed workflow recovery reporting a foreign run as available at the exact lease-expiry boundary before takeover is permitted ([#3681](https://github.com/bastani-inc/atomic/pull/3681)).
- SQL journals snapshot append payloads at invocation, including keyed retries, preserving status/event consistency during queued writes. User-supplied facades may return readonly rows. Header and append serialization failures now retain typed storage errors and their original causes without changing fencing, replay, or sequence-check precedence.
- Journal run summaries and status validation now use the serialized `StatusChanged` payload, including transformations by `toJSON`, so recorded events and summaries agree. Ownership inspection now honors the journal clock even when the process clock is skewed.
- Fixed workflow error cards hiding text-only failures as `no result`. Errors without structured details now show their text and an error indication in collapsed and expanded cards ([#3669](https://github.com/bastani-inc/atomic/issues/3669)).
- Fixed failed workflow resumes reporting partial progress solely because a sibling was already running. Requests with no acknowledged effect now report no change and retain their failure code ([#3670](https://github.com/bastani-inc/atomic/issues/3670)).
- Fixed workflow pause reporting `noop` after a stage pause took effect but durable capture failed, including whole-run and bulk requests. The result now reports `partial`, explains that the pause remains in effect, and preserves the failure code and message ([#3671](https://github.com/bastani-inc/atomic/issues/3671)).

## [0.9.38-alpha.5] - 2026-10-16

### Fixed

- Fixed standalone SDK `run()` resolving string stage models, including thinking suffixes and fallback models, instead of crashing during session creation ([#3629](https://github.com/bastani-inc/atomic/issues/3629)).
- Fixed queued Intercom instructions preventing stage model fallback. Delivery failures now block resumably and preserve sticky instructions for resumed runs and later stages ([#3628](https://github.com/bastani-inc/atomic/issues/3628)).

## [0.9.38-alpha.4] - 2026-10-16

### Breaking Changes

- Workflow discovery now reads only `.atomic` default roots. Discovered workflow modules use `@bastani/atomic/workflows` and `typebox` imports. Removed deprecated imperative API stubs, separate `thinkingLevel` and `fallbackThinkingLevels` authoring fields, old stage-target syntax, and replay without current topology, replay keys, or child exit tags. Put reasoning effort in each model string, such as `provider/model:high`.
- Execution results always include `toolNodes`, inspection details and status summaries always include `tools`, and custom UI adapters must implement every UI method. Queued stage delivery requires persisted admission order.
- Heartbeat records require their original launch cadence; incomplete records no longer inherit the current workflow definition. Configuration load results always include `globalConfig` and `projectConfig`, using `null` when a source is absent or invalid.
- Public run snapshots require `toolNodes`. Inline forms require injected keybindings and no longer include unused submit-choice state. Removed the ignored `preserveAnsi` truncation argument; text truncation remains ANSI-aware.
- Workflow runs now persist only in the local SQLite journal. Journal initialization failures throw `StorageUnavailableError` instead of continuing without durable storage. Postgres connection settings (`workflows.durability.systemDatabaseUrl` and `workflows.durability.poolSize`) and `DBOS_SYSTEM_DATABASE_URL`, `ATOMIC_POSTGRES_*`, and `PG*` environment variables no longer configure workflow storage.

### Removed

- Removed DBOS, embedded Postgres, their bundled runtimes and native process ownership, and the non-durable storage fallback. Server-specific admission, recovery, outage handling, and deferred persistence queues are gone; workflow pause, resume, quit, answer, and checkpoint replay remain supported.

### Added

- Added `MemoryRunJournal`, public SQLite journal and error exports, and `registerRunJournalConformance` for shared journal contract checks.
- Added `RunOpts.journal` types and `resolveRunJournal` for explicit journals, caller-owned SQLite connections, memory journals, and configurable files. Resolution prioritizes the explicit option, a non-empty `ATOMIC_WORKFLOW_JOURNAL_PATH`, then journal settings and the default path. Relative settings paths resolve against the Atomic home directory. Runtime wiring is deferred.

### Fixed

- Fixed workflow fallback leaking the original stage session when an intervening candidate fails to initialize. The original session is now disposed exactly once after it becomes idle when a successor is adopted, or during final cleanup if no successor is created ([#3655](https://github.com/bastani-inc/atomic/issues/3655)).
- Fixed retained stage history load failures appearing as empty archives. Missing, unreadable, malformed, empty, or deleted session files now show an actionable session-unavailable warning without creating a blank session or discarding displayed messages ([#3658](https://github.com/bastani-inc/atomic/issues/3658)).

## [0.9.38-alpha.1] - 2026-10-15

### Fixed

- Fixed second and later durable SDK `run()` calls in the same process failing with `atomicWorkflowHandle is not a registered DBOS workflow function`. Each standalone run now recreates its durable backend after the previous run shuts it down ([#3614](https://github.com/bastani-inc/atomic/issues/3614)).

## [0.9.37] - 2026-10-13

### Changed

- Updated the bundled Impeccable skill to 4.5.2 with engine 0.1.14. App screens and docs use code-first builds with clickable HTML sketches; comp-led builds reuse the chosen image as a fixed reference. Includes detector, Windows hook and capture, and Live Mode fixes, including support for Astro 7.3.6 and newer.

## [0.9.37-alpha.1] - 2026-10-13

### Changed

- Updated the bundled Impeccable skill to 4.5.2 with engine 0.1.14. App screens and docs use code-first builds with clickable HTML sketches; comp-led builds reuse the chosen image as a fixed reference. Includes detector, Windows hook and capture, and Live Mode fixes, including support for Astro 7.3.6 and newer.

## [0.9.35] - 2026-10-13

### Added

- `session.workflows.resume(runId)` now adopts a paused run that was launched through the model-facing `workflow` tool once its owning session has been disposed, in the same process or after the owning process exits. Disposing a session quits its in-flight runs at their last checkpoint and durably records that it released its checkpointed paused runs; the adopting session becomes the owner and the run continues under the same UUID. Runs whose owner is still open, runs whose owner crashed without disposing, and finished runs are still refused ([#3566](https://github.com/bastani-inc/atomic/issues/3566)).
- Switching sessions with `/new`, `/fork`, or `/resume` now releases the previous session's paused workflow runs, the same way disposing a session does. The model in the new session can inspect them with the `workflow` tool's `status` and `stages` actions and resume them, and `session.workflows.resume(runId)` can adopt them; adoption, including the `/workflow resume <id>` slash command, transfers ownership to the resuming session. The new session lists the released runs with their `/workflow resume <id>` commands, and, in the process that released it, a run another session already adopted now reports that it is owned by another session. `/reload` still keeps runs executing and releases nothing ([#3569](https://github.com/bastani-inc/atomic/issues/3569)).
- Resuming a workflow from another project with `/workflow resume <id>` now offers to fork its saved progress into the current directory under a new run ID, leaving the source run unchanged. SDK, tool, and headless resume requests return an actionable error instead of running in a different project.
- Workflow resume history now shows descriptive run identities and saved generated progress summaries, and supplies saved summaries to the main chat when resuming.
- SDK workflow lists and details expose run labels, identities, saved summaries and summarized-through timestamps. `listRuns({ includeDurable: true })` includes stored resumable and completed history; RPC clients can access the same history.
- Added `durability.poolSize` to SDK workflow runs (default 10, minimum 2), applying the connection maximum to DBOS SQL pools, ownership-fence pools, and their replacement connections for managed or remote PostgreSQL. Later requests for a different size reject once the process is configured.

### Fixed

- Fixed an SDK session started after another session in the same process was disposed falling back to non-durable workflows with `Managed Postgres health observer is stopped.`. Releasing the last session now discards the stopped workflow database configuration, so the next session starts a fresh managed Postgres and launches durably ([#3565](https://github.com/bastani-inc/atomic/issues/3565)).
- Fixed durable workflows failing with `atomicWorkflowHandle is not a registered DBOS workflow function` when a new SDK session uses a different working directory after the last session is disposed. Final session disposal now releases workflow registrations so the next session recreates them in its own SDK ([#3577](https://github.com/bastani-inc/atomic/issues/3577)).
- Workflow SDK and RPC history now excludes stored runs from other projects. Resuming through either API respects disabled session summaries, and killing a blocked run requests a new final summary.
- Concurrent workflow metadata writes and legacy recovery now queue instead of exhausting a small ownership-fence connection pool.
- Fixed completed durable workflows leaving their root DBOS record `PENDING` when run metadata was written before DBOS recorded the root's result. Admission, including same-ID retries and admission recovery, now waits for the root's own result to be saved, without holding its lock or database connection, before writing metadata, so the root completes as `SUCCESS` and DBOS cleanup can remove it.
- Retrying or recovering an unfinished durable registration now fails within the admission deadline without starting workflow code or saving resume metadata if its original root cannot finish. Restoring the database does not guarantee that an abandoned registration can be resumed.

## [0.9.35-alpha.5] - 2026-10-12

### Added

- Added `durability.poolSize` to SDK workflow runs (default 10, minimum 2), applying the connection maximum to DBOS SQL pools, ownership-fence pools, and their replacement connections for managed or remote PostgreSQL. Later requests for a different size reject once the process is configured.

### Fixed

- Concurrent workflow metadata writes and legacy recovery now queue instead of exhausting a small ownership-fence connection pool.
- Fixed completed durable workflows leaving their root DBOS record `PENDING` when run metadata was written before DBOS recorded the root's result. Admission, including same-ID retries and admission recovery, now waits for the root's own result to be saved, without holding its lock or database connection, before writing metadata, so the root completes as `SUCCESS` and DBOS cleanup can remove it.
- Retrying or recovering an unfinished durable registration now fails within the admission deadline without starting workflow code or saving resume metadata if its original root cannot finish. Restoring the database does not guarantee that an abandoned registration can be resumed.

## [0.9.35-alpha.3] - 2026-10-12

### Added

- Resuming a workflow from another project with `/workflow resume <id>` now offers to fork its saved progress into the current directory under a new run ID, leaving the source run unchanged. SDK, tool, and headless resume requests return an actionable error instead of running in a different project.
- Workflow resume history now shows descriptive run identities and saved generated progress summaries, and supplies saved summaries to the main chat when resuming.
- SDK workflow lists and details expose run labels, identities, saved summaries and summarized-through timestamps. `listRuns({ includeDurable: true })` includes stored resumable and completed history; RPC clients can access the same history.

### Fixed

- Fixed durable workflows failing with `atomicWorkflowHandle is not a registered DBOS workflow function` when a new SDK session uses a different working directory after the last session is disposed. Final session disposal now releases workflow registrations so the next session recreates them in its own SDK ([#3577](https://github.com/bastani-inc/atomic/issues/3577)).
- Workflow SDK and RPC history now excludes stored runs from other projects. Resuming through either API respects disabled session summaries, and killing a blocked run requests a new final summary.

## [0.9.35-alpha.1] - 2026-10-12

### Added

- `session.workflows.resume(runId)` now adopts a paused run that was launched through the model-facing `workflow` tool once its owning session has been disposed, in the same process or after the owning process exits. Disposing a session quits its in-flight runs at their last checkpoint and durably records that it released its checkpointed paused runs; the adopting session becomes the owner and the run continues under the same UUID. Runs whose owner is still open, runs whose owner crashed without disposing, and finished runs are still refused ([#3566](https://github.com/bastani-inc/atomic/issues/3566)).
- Switching sessions with `/new`, `/fork`, or `/resume` now releases the previous session's paused workflow runs, the same way disposing a session does. The model in the new session can inspect them with the `workflow` tool's `status` and `stages` actions and resume them, and `session.workflows.resume(runId)` can adopt them; adoption, including the `/workflow resume <id>` slash command, transfers ownership to the resuming session. The new session lists the released runs with their `/workflow resume <id>` commands, and, in the process that released it, a run another session already adopted now reports that it is owned by another session. `/reload` still keeps runs executing and releases nothing ([#3569](https://github.com/bastani-inc/atomic/issues/3569)).

### Fixed

- Fixed an SDK session started after another session in the same process was disposed falling back to non-durable workflows with `Managed Postgres health observer is stopped.`. Releasing the last session now discards the stopped workflow database configuration, so the next session starts a fresh managed Postgres and launches durably ([#3565](https://github.com/bastani-inc/atomic/issues/3565)).

## [0.9.33] - 2026-10-10

### Fixed

- Fixed the managed PostgreSQL cluster being refused with `Managed Postgres cluster identity mismatch` after a macOS reboot changed the data volume's device number. Atomic now attaches the cluster and updates its ownership record when the data directory inode, path, cluster ID, major version, and PostgreSQL system identifier still match, and genuine identity mismatches name the fields that differ ([#3555](https://github.com/bastani-inc/atomic/issues/3555)).

## [0.9.33-alpha.1] - 2026-10-10

### Fixed

- Fixed the managed PostgreSQL cluster being refused with `Managed Postgres cluster identity mismatch` after a macOS reboot changed the data volume's device number. Atomic now attaches the cluster and updates its ownership record when the data directory inode, path, cluster ID, major version, and PostgreSQL system identifier still match, and genuine identity mismatches name the fields that differ ([#3555](https://github.com/bastani-inc/atomic/issues/3555)).

## [0.9.32] - 2026-10-10

### Fixed

- Fixed stages without an explicit `cwd` running in the host process directory instead of the workflow invocation directory in SDK-hosted sessions. Stage reports now use the same resolved directory as their sessions, including adapter and session-manager overrides ([#3551](https://github.com/bastani-inc/atomic/issues/3551)).

## [0.9.32-alpha.1] - 2026-10-10

### Fixed

- Fixed stages without an explicit `cwd` running in the host process directory instead of the workflow invocation directory in SDK-hosted sessions. Stage reports now use the same resolved directory as their sessions, including adapter and session-manager overrides ([#3551](https://github.com/bastani-inc/atomic/issues/3551)).

## [0.9.29] - 2026-10-09

### Added

- Stages with `model: "auto"`, including builtin workflow stages that do not name a model, honor the new `modelRouting.allowedModels` and `modelRouting.excludedModels` settings for the routed model and every fallback, and fail before launch with an error naming the setting when no allowed model remains. A stage's `routerSelection` in `workflow` status now lists the `candidates` the router could choose from ([#3528](https://github.com/bastani-inc/atomic/issues/3528)).

## [0.9.29-alpha.1] - 2026-10-08

### Added

- Stages with `model: "auto"`, including builtin workflow stages that do not name a model, honor the new `modelRouting.allowedModels` and `modelRouting.excludedModels` settings for the routed model and every fallback, and fail before launch with an error naming the setting when no allowed model remains. A stage's `routerSelection` in `workflow` status now lists the `candidates` the router could choose from ([#3528](https://github.com/bastani-inc/atomic/issues/3528)).

## [0.9.28] - 2026-10-08

### Added

- Added a Claude Haiku 5.5 prompt-engineering guide based on Anthropic's model-specific guidance, covering effort, search grounding, JSON/tool interactions, completion, verification, and refusal handling.
- Added `createAgentSessionAdapter(baseOptions?)`, which builds the default workflow stage-session adapter with `createAgentSession` options shared by every stage ([#3472](https://github.com/bastani-inc/atomic/issues/3472)).

### Changed

- Updated the bundled Impeccable skill to 4.5.0 with engine 0.1.11, adding the `generate` playbook, component-review guidance, and reading, operating, and persuasion design modes. Atomic's telemetry and update-check defaults remain off.
- Changed the `resumeInFlight` default from `"ask"` to `"never"`. Atomic no longer prompts at startup to resume interrupted durable workflows; resume them with `/workflow resume`, or set `resumeInFlight` to `"ask"` or `"auto"` in the workflow config to restore startup recovery.

### Fixed

- Fixed managed PostgreSQL health checks failing a workflow stage on a healthy but busy host: an unanswered check now retries with a short backoff for up to 15 seconds, the connection limit is 3 seconds instead of 1, and the "did not answer a health check in time" diagnostic clears once PostgreSQL answers again ([#3491](https://github.com/bastani-inc/atomic/issues/3491))
- Fixed Atomic hanging at startup, never accepting input, when the current directory had interrupted durable workflows and `resumeInFlight` was `ask`. Startup no longer waits for workflow recovery; the "Resume interrupted workflows?" prompt now appears after the session is ready.
- Fixed startup recovery and SDK crash recovery skipping interrupted workflows when the project directory was reached through a symlink, such as `/tmp` or `/var` on macOS.
- Fixed long workflow runs retaining a full metadata snapshot for every checkpoint and message update. Atomic now compacts superseded snapshots, removes their duplicate input payloads, and bounds settled delivery state across root and child runs, including failed-stage sticky receipts, while preserving resume and message deduplication ([#3467](https://github.com/bastani-inc/atomic/issues/3467)).
- Fixed archived sticky message receipts being ignored when a failed stage retries delivery without an explicit recipient or through live Intercom transport. Retry forwarding and confirmation deduplication survive cold resume, while a new recipient session can still receive the message ([#3467](https://github.com/bastani-inc/atomic/issues/3467)).
- Fixed sticky messages delivered as pre-start context being forwarded again to the same live session, including after receipt archival and cold resume. Concurrent confirmations remain deduplicated when a stage finishes before they are saved, while a new recipient session can still receive the message ([#3467](https://github.com/bastani-inc/atomic/issues/3467)).
- Fixed interrupted sticky receipt saves losing delivery counts after retry or cold resume and incorrectly reporting delivered messages as undeliverable ([#3467](https://github.com/bastani-inc/atomic/issues/3467)).
- Fixed Goal infrastructure failures incorrectly ending the goal as `needs_human`. The ledger now stays `active`, and direct resume in the same session retries the interrupted stage and completes its turn without quitting Atomic. Malformed reviewer output, including exhausted schema corrections, still requires human attention. Older synthetic failure verdicts with identifiable database/checkpoint diagnostics are also recoverable; ambiguous old failures remain unchanged ([#3466](https://github.com/bastani-inc/atomic/issues/3466)).
- Fixed Goal treating exhausted reviewer corrections for invalid `structured_output` inputs, including whitespace-only instructions and empty named state, as resumable infrastructure failures instead of `needs_human` ([#3466](https://github.com/bastani-inc/atomic/issues/3466)).
- Fixed Goal reviewer corrections hiding an earlier provider failure when a later `structured_output` call has invalid inputs. If no correction succeeds, the goal remains resumable instead of becoming `needs_human` ([#3466](https://github.com/bastani-inc/atomic/issues/3466)).
- Fixed `run()` failing at the first `ctx.task` or `ctx.stage` with "prompt adapter not configured" when `opts.adapters` was omitted. Stages now default to in-process `createAgentSession` sessions with in-memory session managers ([#3472](https://github.com/bastani-inc/atomic/issues/3472)).
- Fixed `resumeInFlight` having no effect at startup. `auto` now resumes eligible interrupted durable workflows, `ask` requests confirmation when a UI is available, and `never` leaves them for `/workflow resume`. Paused, quit, blocked, failed, awaiting-input, and live-owned runs are not automatically restarted ([#3468](https://github.com/bastani-inc/atomic/issues/3468)).
- Fixed startup recovery of agent-owned workflows retaining the previous session's ownership. Safely recovered runs now allow the current session's agent to inspect and control them ([#3468](https://github.com/bastani-inc/atomic/issues/3468)).
- Fixed recovered workflows disconnecting Intercom with pending-stage authorization errors when workflow extension modules load more than once ([#3468](https://github.com/bastani-inc/atomic/issues/3468)).
- Fixed recovered agent stages failing with a stale extension context after accepted startup recovery. Committed host generations hand off synchronously and retired Store observers detach before authority revocation, independently of shutdown handler order ([#3468](https://github.com/bastani-inc/atomic/issues/3468)).
- Fixed startup recovery offering or restarting another project's workflows when projects share a database. Automatic recovery now requires the original invocation directory to match the current working directory; cross-project recovery remains available through `/workflow resume` ([#3468](https://github.com/bastani-inc/atomic/issues/3468)).
- Fixed durable-workflow shutdown returning before ownership and protected SQL connections terminated, including pending SQL acquisitions, so immediate recovery no longer races a stale executor lock ([#3489](https://github.com/bastani-inc/atomic/issues/3489)).
- Attached stage chats honor configured transcript jump shortcuts, defaulting to Ctrl+Home and Ctrl+End, without intercepting the editor's Home and End keys.
- Fixed slow workflow discovery for imports of `@bastani/atomic`, `@bastani/pi-ai`, and `@bastani/pi-ai/providers/all` by sharing the running CLI's modules instead of loading them again for each workflow file. The host's versions take precedence over project copies for these three exact specifiers. These imports no longer need project-local packages in standalone-binary installs; workflow files and relative imports still refresh on reload ([#3454](https://github.com/bastani-inc/atomic/issues/3454)).
- Fixed workflow stage questions in one process hosting several SDK sessions reaching the wrong session. A stage's `ask_user_question`, readiness question, or `ctx.ui.custom` prompt could go to whichever sibling session started last, so its own `HostInput.questionnaire` was never called and the stage stayed `awaiting_input`. Each session now keeps its own workflow store, stage UI broker, and run registries ([#3456](https://github.com/bastani-inc/atomic/issues/3456)).

## [0.9.28-alpha.5] - 2026-10-08

### Fixed

- Fixed managed PostgreSQL health checks failing a workflow stage on a healthy but busy host: an unanswered check now retries with a short backoff for up to 15 seconds, the connection limit is 3 seconds instead of 1, and the "did not answer a health check in time" diagnostic clears once PostgreSQL answers again ([#3491](https://github.com/bastani-inc/atomic/issues/3491))

## [0.9.28-alpha.4] - 2026-10-07

### Added

- Added a Claude Haiku 5.5 prompt-engineering guide based on Anthropic's model-specific guidance, covering effort, search grounding, JSON/tool interactions, completion, verification, and refusal handling.

### Changed

- Updated the bundled Impeccable skill to 4.5.0 with engine 0.1.11, adding the `generate` playbook, component-review guidance, and reading, operating, and persuasion design modes. Atomic's telemetry and update-check defaults remain off.

## [0.9.28-alpha.3] - 2026-10-07

### Changed

- Changed the `resumeInFlight` default from `"ask"` to `"never"`. Atomic no longer prompts at startup to resume interrupted durable workflows; resume them with `/workflow resume`, or set `resumeInFlight` to `"ask"` or `"auto"` in the workflow config to restore startup recovery.

### Fixed

- Fixed Atomic hanging at startup, never accepting input, when the current directory had interrupted durable workflows and `resumeInFlight` was `ask`. Startup no longer waits for workflow recovery; the "Resume interrupted workflows?" prompt now appears after the session is ready.
- Fixed startup recovery and SDK crash recovery skipping interrupted workflows when the project directory was reached through a symlink, such as `/tmp` or `/var` on macOS.

## [0.9.28-alpha.2] - 2026-10-07

### Added

- Added `createAgentSessionAdapter(baseOptions?)`, which builds the default workflow stage-session adapter with `createAgentSession` options shared by every stage ([#3472](https://github.com/bastani-inc/atomic/issues/3472)).

### Fixed

- Fixed long workflow runs retaining a full metadata snapshot for every checkpoint and message update. Atomic now compacts superseded snapshots, removes their duplicate input payloads, and bounds settled delivery state across root and child runs, including failed-stage sticky receipts, while preserving resume and message deduplication ([#3467](https://github.com/bastani-inc/atomic/issues/3467)).
- Fixed archived sticky message receipts being ignored when a failed stage retries delivery without an explicit recipient or through live Intercom transport. Retry forwarding and confirmation deduplication survive cold resume, while a new recipient session can still receive the message ([#3467](https://github.com/bastani-inc/atomic/issues/3467)).
- Fixed sticky messages delivered as pre-start context being forwarded again to the same live session, including after receipt archival and cold resume. Concurrent confirmations remain deduplicated when a stage finishes before they are saved, while a new recipient session can still receive the message ([#3467](https://github.com/bastani-inc/atomic/issues/3467)).
- Fixed interrupted sticky receipt saves losing delivery counts after retry or cold resume and incorrectly reporting delivered messages as undeliverable ([#3467](https://github.com/bastani-inc/atomic/issues/3467)).
- Fixed Goal infrastructure failures incorrectly ending the goal as `needs_human`. The ledger now stays `active`, and direct resume in the same session retries the interrupted stage and completes its turn without quitting Atomic. Malformed reviewer output, including exhausted schema corrections, still requires human attention. Older synthetic failure verdicts with identifiable database/checkpoint diagnostics are also recoverable; ambiguous old failures remain unchanged ([#3466](https://github.com/bastani-inc/atomic/issues/3466)).
- Fixed Goal treating exhausted reviewer corrections for invalid `structured_output` inputs, including whitespace-only instructions and empty named state, as resumable infrastructure failures instead of `needs_human` ([#3466](https://github.com/bastani-inc/atomic/issues/3466)).
- Fixed Goal reviewer corrections hiding an earlier provider failure when a later `structured_output` call has invalid inputs. If no correction succeeds, the goal remains resumable instead of becoming `needs_human` ([#3466](https://github.com/bastani-inc/atomic/issues/3466)).
- Fixed `run()` failing at the first `ctx.task` or `ctx.stage` with "prompt adapter not configured" when `opts.adapters` was omitted. Stages now default to in-process `createAgentSession` sessions with in-memory session managers ([#3472](https://github.com/bastani-inc/atomic/issues/3472)).
- Fixed `resumeInFlight` having no effect at startup. `auto` now resumes eligible interrupted durable workflows, `ask` requests confirmation when a UI is available, and `never` leaves them for `/workflow resume`. Paused, quit, blocked, failed, awaiting-input, and live-owned runs are not automatically restarted ([#3468](https://github.com/bastani-inc/atomic/issues/3468)).
- Fixed startup recovery of agent-owned workflows retaining the previous session's ownership. Safely recovered runs now allow the current session's agent to inspect and control them ([#3468](https://github.com/bastani-inc/atomic/issues/3468)).
- Fixed recovered workflows disconnecting Intercom with pending-stage authorization errors when workflow extension modules load more than once ([#3468](https://github.com/bastani-inc/atomic/issues/3468)).
- Fixed recovered agent stages failing with a stale extension context after accepted startup recovery. Committed host generations hand off synchronously and retired Store observers detach before authority revocation, independently of shutdown handler order ([#3468](https://github.com/bastani-inc/atomic/issues/3468)).
- Fixed startup recovery offering or restarting another project's workflows when projects share a database. Automatic recovery now requires the original invocation directory to match the current working directory; cross-project recovery remains available through `/workflow resume` ([#3468](https://github.com/bastani-inc/atomic/issues/3468)).
- Fixed durable-workflow shutdown returning before ownership and protected SQL connections terminated, including pending SQL acquisitions, so immediate recovery no longer races a stale executor lock ([#3489](https://github.com/bastani-inc/atomic/issues/3489)).

## [0.9.28-alpha.1] - 2026-10-05

### Fixed

- Attached stage chats honor configured transcript jump shortcuts, defaulting to Ctrl+Home and Ctrl+End, without intercepting the editor's Home and End keys.
- Fixed slow workflow discovery for imports of `@bastani/atomic`, `@bastani/pi-ai`, and `@bastani/pi-ai/providers/all` by sharing the running CLI's modules instead of loading them again for each workflow file. The host's versions take precedence over project copies for these three exact specifiers. These imports no longer need project-local packages in standalone-binary installs; workflow files and relative imports still refresh on reload ([#3454](https://github.com/bastani-inc/atomic/issues/3454)).
- Fixed workflow stage questions in one process hosting several SDK sessions reaching the wrong session. A stage's `ask_user_question`, readiness question, or `ctx.ui.custom` prompt could go to whichever sibling session started last, so its own `HostInput.questionnaire` was never called and the stage stayed `awaiting_input`. Each session now keeps its own workflow store, stage UI broker, and run registries ([#3456](https://github.com/bastani-inc/atomic/issues/3456)).

## [0.9.27] - 2026-10-05

### Fixed

- Fixed workflow stages that set `model` or `fallbackModels` using settings or inherited parent models instead of only their declared chain and reasoning levels, including after reattachment. Exhausted explicit chains now stop rather than append the parent model. Numbered account providers such as `openai-1` resolve from their own `auth.json` credentials without alias registrations or `models.json` entries ([#3426](https://github.com/bastani-inc/atomic/issues/3426)).
- Raised the durable database admission and checkpoint deadline from 10 seconds to two minutes to tolerate transient PostgreSQL latency, retaining prompt cancellation. Workflow tool requests now allow 150 seconds so their outer deadline does not cut admission short ([#3428](https://github.com/bastani-inc/atomic/issues/3428)).
- Fixed reattached stages rejecting saved custom or dynamic model IDs that the SDK can reconstruct, and replaying an exhausted explicit reasoning tier when an earlier candidate leaves its thinking level unspecified ([#3432](https://github.com/bastani-inc/atomic/pull/3432)).

## [0.9.27-alpha.1] - 2026-10-04

### Fixed

- Fixed workflow stages that set `model` or `fallbackModels` using settings or inherited parent models instead of only their declared chain and reasoning levels, including after reattachment. Exhausted explicit chains now stop rather than append the parent model. Numbered account providers such as `openai-1` resolve from their own `auth.json` credentials without alias registrations or `models.json` entries ([#3426](https://github.com/bastani-inc/atomic/issues/3426)).
- Raised the durable database admission and checkpoint deadline from 10 seconds to two minutes to tolerate transient PostgreSQL latency, retaining prompt cancellation. Workflow tool requests now allow 150 seconds so their outer deadline does not cut admission short ([#3428](https://github.com/bastani-inc/atomic/issues/3428)).
- Fixed reattached stages rejecting saved custom or dynamic model IDs that the SDK can reconstruct, and replaying an exhausted explicit reasoning tier when an earlier candidate leaves its thinking level unspecified ([#3432](https://github.com/bastani-inc/atomic/pull/3432)).

## [0.9.26] - 2026-10-04

### Added

- Added `workflows.durability.systemDatabaseUrl` and `systemDatabaseUrlFile` in global and trusted project settings to choose a persistent workflow database without launcher-specific environment configuration. `DBOS_SYSTEM_DATABASE_URL` retains precedence; explicit selections never provision embedded PostgreSQL or Docker. Interactive and RPC sessions report the selected provider and host without credentials on the first workflow action; headless sessions print only a Docker fallback selection to stderr. Existing workflow-path arrays remain supported alongside the new object form with `paths` ([#3416](https://github.com/bastani-inc/atomic/issues/3416)).

### Fixed

- Fixed SDK inspection rejecting earlier-process durable runs and crash recovery retaining the old session owner. Explicit SDK resume atomically adopts an eligible crashed root in the same working directory and workflow database, preserves its UUID and completed checkpoints, and excludes healthy connected owners and competing adopters. Database ownership fencing handles cloned VM identities and rejects disconnected owners' late durable writes. Older unfenced runs support controlled enrollment after their workers stop; unfinished external callbacks may overlap recovery and must use idempotent effects ([#3419](https://github.com/bastani-inc/atomic/issues/3419)).
- Fixed managed PostgreSQL monitoring connection timeouts unnecessarily closing healthy workflow ownership connections. Monitoring retries once; a persistent timeout reports database unavailability without discarding connected owners or restarting the database ([#3419](https://github.com/bastani-inc/atomic/issues/3419)).
- Fixed managed PostgreSQL staying down after shutdown when its old launch options were missing. Recovery preserves cluster ownership and identity checks, and database-unavailable admission errors and workflow status now show the provider, credential-redacted endpoint, and retained probe or recovery failure ([#3413](https://github.com/bastani-inc/atomic/issues/3413)).
- Fixed sticky Intercom broadcasts to `workflow:<rootRunId>/**` missing later stages before their first model turn. Workflow status now reports per-stage delivery and skip results for retained messages ([#3406](https://github.com/bastani-inc/atomic/issues/3406)).
- Fixed workflow-stage `ask_user_question` questions never reaching an SDK host's `HostInput` when the stage was already awaiting input, which left the run waiting indefinitely ([#3396](https://github.com/bastani-inc/atomic/issues/3396)).

## [0.9.26-alpha.6] - 2026-10-04

### Fixed

- Fixed SDK inspection rejecting earlier-process durable runs and crash recovery retaining the old session owner. Explicit SDK resume atomically adopts an eligible crashed root in the same working directory and workflow database, preserves its UUID and completed checkpoints, and excludes healthy connected owners and competing adopters. Database ownership fencing handles cloned VM identities and rejects disconnected owners' late durable writes. Older unfenced runs support controlled enrollment after their workers stop; unfinished external callbacks may overlap recovery and must use idempotent effects ([#3419](https://github.com/bastani-inc/atomic/issues/3419)).
- Fixed managed PostgreSQL monitoring connection timeouts unnecessarily closing healthy workflow ownership connections. Monitoring retries once; a persistent timeout reports database unavailability without discarding connected owners or restarting the database ([#3419](https://github.com/bastani-inc/atomic/issues/3419)).

## [0.9.26-alpha.5] - 2026-10-03

### Added

- Added `workflows.durability.systemDatabaseUrl` and `systemDatabaseUrlFile` in global and trusted project settings to choose a persistent workflow database without launcher-specific environment configuration. `DBOS_SYSTEM_DATABASE_URL` retains precedence; explicit selections never provision embedded PostgreSQL or Docker. Interactive and RPC sessions report the selected provider and host without credentials on the first workflow action; headless sessions print only a Docker fallback selection to stderr. Existing workflow-path arrays remain supported alongside the new object form with `paths` ([#3416](https://github.com/bastani-inc/atomic/issues/3416)).

### Fixed

- Fixed managed PostgreSQL staying down after shutdown when its old launch options were missing. Recovery preserves cluster ownership and identity checks, and database-unavailable admission errors and workflow status now show the provider, credential-redacted endpoint, and retained probe or recovery failure ([#3413](https://github.com/bastani-inc/atomic/issues/3413)).

## [0.9.26-alpha.4] - 2026-10-02

### Fixed

- Fixed sticky Intercom broadcasts to `workflow:<rootRunId>/**` missing later stages before their first model turn. Workflow status now reports per-stage delivery and skip results for retained messages ([#3406](https://github.com/bastani-inc/atomic/issues/3406)).

## [0.9.26-alpha.1] - 2026-10-01

### Fixed

- Fixed workflow-stage `ask_user_question` questions never reaching an SDK host's `HostInput` when the stage was already awaiting input, which left the run waiting indefinitely ([#3396](https://github.com/bastani-inc/atomic/issues/3396)).

## [0.9.25] - 2026-10-01

### Added

- `pause`, `quit` and `resume` results from the `workflow` tool now carry a machine-readable `code` (`run_not_found`, `not_resumable`, `owned_elsewhere`, `database_unavailable`, `stage_not_found`, `stage_ambiguous`, `stage_resume_unsupported` or `control_failed`) when the request could not be carried out, so SDK hosts using `session.workflows` receive typed errors. Resuming a run that is executing in another live Atomic process now reports `owned_elsewhere` instead of `not_resumable`. Pausing or quitting, by full run id, a run owned by another session or executing in another live Atomic process now reports `owned_elsewhere` instead of `Run not found`. Pausing or resuming a stage that does not exist or matches several stages, and resuming a single stage of a durable run, now report `stage_not_found`, `stage_ambiguous` or `stage_resume_unsupported` instead of an uncoded no-op ([#3377](https://github.com/bastani-inc/atomic/issues/3377)).
- Added an official-source GPT-6.1 Sol reference to the prompt-engineering skill, with supported-effort migration guidance and selective use of shared templates whose behavior was observed on Astra.

### Fixed

- Pausing a run whose only active stage is waiting for human input now marks the run paused instead of rejecting with `no_active_stages`. An already-open question stays open, questions not yet shown wait until resume, and hosts can hold answers until they resume the run ([#3391](https://github.com/bastani-inc/atomic/issues/3391)).
- `pause` and `quit` with `all: true` no longer report success when some runs could not be stopped. The result is `partial` only when that call stopped at least one run and others are still active, and a `noop` with `control_failed` when active runs could not be stopped and the call stopped none, even if other runs were already paused. Either result lists each failed run id and reason in the message and in a `failedRuns` list. Runs that are already paused or already ended are not failures, and a batch with nothing left to stop is a benign `noop`. `/workflow pause --all` now names runs that failed to pause instead of reporting them as paused or as "No in-flight runs to pause", and reports an error when it stopped no run. Any failure while inspecting the database to pause or quit an unknown full run id now returns a structured `database_unavailable` result instead of throwing or a generic `control_failed` ([#3377](https://github.com/bastani-inc/atomic/issues/3377)).
- On a heavily loaded machine, a workflow run could fail with a bare `Query read timeout` while Atomic verified its managed PostgreSQL connection, even though the database was healthy. Health queries now get more time (3 s) on every path, and both the check of a borrowed connection and Atomic's periodic background health check repeat once after a timeout. If the timeout persists, the run fails with a resumable database-unavailable error instead of `Query read timeout`, and other running workflows' database connections are not closed and PostgreSQL is not restarted. A refused or terminated connection, a server shutdown, or a changed database identity is still treated as an outage.
- Fixed a workflow run resumed right after it was paused failing with `Workflow database admission timed out`. A pause or resume now waits for the control write already in flight instead of cancelling it mid-write, which could leave the run's database claim stuck and stall every later pause, resume, or quit on that run until the admission timeout ([#3377](https://github.com/bastani-inc/atomic/issues/3377)).

## [0.9.25-alpha.5] - 2026-09-30

### Fixed

- Pausing a run whose only active stage is waiting for human input now marks the run paused instead of rejecting with `no_active_stages`. An already-open question stays open, questions not yet shown wait until resume, and hosts can hold answers until they resume the run ([#3391](https://github.com/bastani-inc/atomic/issues/3391)).

## [0.9.25-alpha.3] - 2026-09-30

### Added

- `pause`, `quit` and `resume` results from the `workflow` tool now carry a machine-readable `code` (`run_not_found`, `not_resumable`, `owned_elsewhere`, `database_unavailable`, `stage_not_found`, `stage_ambiguous`, `stage_resume_unsupported` or `control_failed`) when the request could not be carried out, so SDK hosts using `session.workflows` receive typed errors. Resuming a run that is executing in another live Atomic process now reports `owned_elsewhere` instead of `not_resumable`. Pausing or quitting, by full run id, a run owned by another session or executing in another live Atomic process now reports `owned_elsewhere` instead of `Run not found`. Pausing or resuming a stage that does not exist or matches several stages, and resuming a single stage of a durable run, now report `stage_not_found`, `stage_ambiguous` or `stage_resume_unsupported` instead of an uncoded no-op ([#3377](https://github.com/bastani-inc/atomic/issues/3377)).

### Fixed

- `pause` and `quit` with `all: true` no longer report success when some runs could not be stopped. The result is `partial` only when that call stopped at least one run and others are still active, and a `noop` with `control_failed` when active runs could not be stopped and the call stopped none, even if other runs were already paused. Either result lists each failed run id and reason in the message and in a `failedRuns` list. Runs that are already paused or already ended are not failures, and a batch with nothing left to stop is a benign `noop`. `/workflow pause --all` now names runs that failed to pause instead of reporting them as paused or as "No in-flight runs to pause", and reports an error when it stopped no run. Any failure while inspecting the database to pause or quit an unknown full run id now returns a structured `database_unavailable` result instead of throwing or a generic `control_failed` ([#3377](https://github.com/bastani-inc/atomic/issues/3377)).
- On a heavily loaded machine, a workflow run could fail with a bare `Query read timeout` while Atomic verified its managed PostgreSQL connection, even though the database was healthy. Health queries now get more time (3 s) on every path, and both the check of a borrowed connection and Atomic's periodic background health check repeat once after a timeout. If the timeout persists, the run fails with a resumable database-unavailable error instead of `Query read timeout`, and other running workflows' database connections are not closed and PostgreSQL is not restarted. A refused or terminated connection, a server shutdown, or a changed database identity is still treated as an outage.
- Fixed a workflow run resumed right after it was paused failing with `Workflow database admission timed out`. A pause or resume now waits for the control write already in flight instead of cancelling it mid-write, which could leave the run's database claim stuck and stall every later pause, resume, or quit on that run until the admission timeout ([#3377](https://github.com/bastani-inc/atomic/issues/3377)).

## [0.9.25-alpha.1] - 2026-09-29

### Added

- Added an official-source GPT-6.1 Sol reference to the prompt-engineering skill, with supported-effort migration guidance and selective use of shared templates whose behavior was observed on Astra.

## [0.9.24] - 2026-09-29

### Added

- Added source-attributed Claude Sonnet 5.5 guidance to the prompt-engineering skill, covering recalibrated effort, carrying coding work through without unrequested additions, visible progress during tool loops, search and verification prompts, and placement of mid-turn user messages.

### Fixed

- A schema-backed stage whose structured-output correction hits a provider failure (for example a 429) that moves the stage to a new session now sends that session the original stage prompt followed by the correction request. Previously the new session received only the correction, so a model that never saw the task could complete the stage with a schema-valid but empty result ([#3323](https://github.com/bastani-inc/atomic/issues/3323)).
- Workflows from a package listed in a project's `.atomic/settings.json` are now registered as soon as you trust the project at startup. Previously `/workflow <name>` reported `Workflow not found` and `/workflow list` showed only the builtin workflows until you ran `/workflow reload`, even though the package's extensions and skills had loaded ([#3354](https://github.com/bastani-inc/atomic/issues/3354)).

## [0.9.24-alpha.1] - 2026-09-28

### Added

- Added source-attributed Claude Sonnet 5.5 guidance to the prompt-engineering skill, covering recalibrated effort, carrying coding work through without unrequested additions, visible progress during tool loops, search and verification prompts, and placement of mid-turn user messages.

### Fixed

- A schema-backed stage whose structured-output correction hits a provider failure (for example a 429) that moves the stage to a new session now sends that session the original stage prompt followed by the correction request. Previously the new session received only the correction, so a model that never saw the task could complete the stage with a schema-valid but empty result ([#3323](https://github.com/bastani-inc/atomic/issues/3323)).
- Workflows from a package listed in a project's `.atomic/settings.json` are now registered as soon as you trust the project at startup. Previously `/workflow <name>` reported `Workflow not found` and `/workflow list` showed only the builtin workflows until you ran `/workflow reload`, even though the package's extensions and skills had loaded ([#3354](https://github.com/bastani-inc/atomic/issues/3354)).

## [0.9.23] - 2026-09-27

### Fixed

- Resuming a run that failed in a `ctx.tool` call now works when the call ran in parallel with other tools. Siblings that were cancelled or also threw when the run failed are run again on resume, in any order, instead of failing with `replay topology mismatch` or `unfinished or missing completed tool checkpoint`. A resume rejected by changed code no longer runs the failed tool or makes the run unresumable, including after Atomic restarts ([#3314](https://github.com/bastani-inc/atomic/issues/3314)).
- `model: "auto"` routing no longer ignores benchmark results when fewer than four models are available. Each model's results are now ranked against every model in the evals catalog rather than only the models you can route to, so with just two or three models (for example Opus and Haiku) the stronger model is no longer outranked on price alone, and a model scores the same however many models are enabled.

## [0.9.23-alpha.1] - 2026-09-27

### Fixed

- Resuming a run that failed in a `ctx.tool` call now works when the call ran in parallel with other tools. Siblings that were cancelled or also threw when the run failed are run again on resume, in any order, instead of failing with `replay topology mismatch` or `unfinished or missing completed tool checkpoint`. A resume rejected by changed code no longer runs the failed tool or makes the run unresumable, including after Atomic restarts ([#3314](https://github.com/bastani-inc/atomic/issues/3314)).
- `model: "auto"` routing no longer ignores benchmark results when fewer than four models are available. Each model's results are now ranked against every model in the evals catalog rather than only the models you can route to, so with just two or three models (for example Opus and Haiku) the stronger model is no longer outranked on price alone, and a model scores the same however many models are enabled.

## [0.9.21] - 2026-09-26

### Changed

- `model: "auto"` routing has a chat model answer fixed questions about the complete task, then the router chooses between a short, evidence-backed list of models without seeing the task, in at most two small requests. The new `modelRouting` setting's `allowedProviders` and `excludedProviders` lists limit which providers are candidates.
- `model: "auto"` accepts `taskNeeds` so the caller can state the task's kind of work, difficulty, mistake cost, need for images, need for a very large context and whether speed matters, and `modelConstraints.allowedModels` sets the shortlist the router chooses between. `modelConstraints.allowedProviders` and `excludedProviders` skip whole providers and replace the `modelRouting` provider settings for that call. Falling back to the current chat model is silent unless `ATOMIC_MODEL_ROUTING_DEBUG=1`.
- Workflow authoring guidance now tells agents to put a `model: "auto"` stage's role and objective at the start or end of its prompt or in a short `<keepContext>` span, since model routing sees only those parts of long prompts.

### Fixed

- The builtin `goal` and `ralph` workflows no longer count a reviewer's `stop_review_loop=true` as approval when the same review calls the patch incorrect, reports `goal_oracle_satisfied: false`, or lists a blocking finding. A run whose reviewers all flag an empty implementation no longer ends `complete` or starts the pull-request stage ([#3295](https://github.com/bastani-inc/atomic/issues/3295)).

## [0.9.21-alpha.2] - 2026-09-26

### Changed

- `model: "auto"` routing has a chat model answer fixed questions about the complete task, then the router chooses between a short, evidence-backed list of models without seeing the task, in at most two small requests. The new `modelRouting` setting's `allowedProviders` and `excludedProviders` lists limit which providers are candidates.
- `model: "auto"` accepts `taskNeeds` so the caller can state the task's kind of work, difficulty, mistake cost, need for images, need for a very large context and whether speed matters, and `modelConstraints.allowedModels` sets the shortlist the router chooses between. `modelConstraints.allowedProviders` and `excludedProviders` skip whole providers and replace the `modelRouting` provider settings for that call. Falling back to the current chat model is silent unless `ATOMIC_MODEL_ROUTING_DEBUG=1`.

### Fixed

- The builtin `goal` and `ralph` workflows no longer count a reviewer's `stop_review_loop=true` as approval when the same review calls the patch incorrect, reports `goal_oracle_satisfied: false`, or lists a blocking finding. A run whose reviewers all flag an empty implementation no longer ends `complete` or starts the pull-request stage ([#3295](https://github.com/bastani-inc/atomic/issues/3295)).

## [0.9.21-alpha.1] - 2026-09-25

### Changed

- Workflow authoring guidance now tells agents to put a `model: "auto"` stage's role and objective at the start or end of its prompt or in a short `<keepContext>` span, since model routing sees only those parts of long prompts.

## [0.9.20] - 2026-09-24

### Breaking Changes

- Removed the public `workflowDependency()` SDK function and its report/operation types, `/workflow dependency`, and the workflow tool's `dependency` action. Inspect affected runs with workflow status; managed PostgreSQL recovery is automatic.
- Removed the `workflow` tool's `route` action and its router classifier. The agent now decides itself whether a workflow fits and launches with `workflow({ action: "run", workflow: "<name>", inputs, budget? })`. The `workflowId` reservation, `state` parameter, `routerDecision`, `estimatedDuration` labels, and `needs_input`/`not_launched`/`reserved` statuses are gone; `run` validates inputs and fails without launching when they are invalid. Runs launched through the model tool still belong to the launching session.
- Workflow route `state` no longer accepts `executionPreference`, and unknown state fields are rejected before inference. The router now asks an independent question about the user's stated execution preference, judged from the user's own words in `state.task`, `state.conversation` and `state.constraints`: an explicit inline request yields `none` even when a workflow matches, and an explicit workflow request bypasses the lifecycle-benefit gate without inventing an unregistered workflow. The calling assistant passes evidence only, so it can no longer pre-decide the route.
- The `open-claude-design` workflow output `playwright_cli_status` is now `agent_browser_status`: the initial deterministic setup step probes for and installs the `agent-browser` CLI (`npm install -g agent-browser` + `agent-browser install`) instead of `playwright-cli`. Consumers reading `playwright_cli_status` must switch to the new field name.
- Headless launches return an accepted run identity for status inspection, without input pickers. Required durable gates remain pending until an authorized host or answer arrives, including when no host was initially bound. Explicit runtime execution policies remain enforced ([#3105](https://github.com/bastani-inc/atomic/issues/3105)).
- Model-tool execution now requires `route` with content-bearing `state.task`, then `run` with the returned registered `workflowId` and validated inputs. Route returns the input schema without launching; input correction reuses the ID without rerouting. Old run-as-router calls and duration values are rejected. Estimates use 97 canonical labels: quarter-hour increments through `1d`, plus `>1d`, without changing budgets ([#3106](https://github.com/bastani-inc/atomic/issues/3106)).
- Workflow route and registered run results no longer repeat `estimatedDuration` at the top level. Route results also no longer repeat `workflowType`, including `none`. Read the canonical estimate and selection from `routerDecision.estimatedDuration` and `routerDecision.workflowType`.
- Workflow duration estimates no longer accept `unknown`. Routers must give their best estimate using a quarter-hour bucket or `>1d`; estimates remain nonbinding.

### Added

- SDK `run()` accepts a `durability` option: `{ mode: "memory" }` for a throwaway in-memory run, or `{ mode: "durable", systemDatabaseUrl? }` to require durable state and optionally choose the Postgres database, such as a hosted one. Explicit `durable` mode fails fast with the new `WorkflowDurabilityRequiredError` instead of falling back to memory ([#3239](https://github.com/bastani-inc/atomic/issues/3239)). `DBOS_SYSTEM_DATABASE_URL` still overrides `systemDatabaseUrl` when set. Omitting the option keeps today's behavior.
- Added `workflowDependency()`, `/workflow dependency` and the workflow tool's `dependency` action for bounded database inspection and registered managed-cluster recovery, with actual port, verified identity, runtime versions, consumers, retained latest failure and safe guidance. External database endpoints receive query-only checks ([#3074](https://github.com/bastani-inc/atomic/issues/3074)).
- Workflow UUID selectors accept unique 8-character hexadecimal prefixes across live and durable runs, with explicit collision errors ([#2603](https://github.com/bastani-inc/atomic/issues/2603)).
- Attached stage chats show `[stage: name]` on the composer top rule, a mounted question's top rule, and awaiting-input prompt borders ([#2886](https://github.com/bastani-inc/atomic/issues/2886), [#3013](https://github.com/bastani-inc/atomic/pull/3013) by [@sumitvairagar](https://github.com/sumitvairagar)).
- Added live, bounded pending-input previews to the BACKGROUND widget, with per-workflow navigation and automatic clearing ([#2700](https://github.com/bastani-inc/atomic/pull/2700) by [@Shreyasd10](https://github.com/Shreyasd10)).
- Added mandatory bounded routing before model-tool workflow launches, using explicit task state and the full current workflow catalog. Results show validated workflow/budget decisions as formatted JSON; `none` directs the caller to continue inline without launching, and changed registry approvals fail before admission. Routing context containing known configured credentials is rejected before either provider receives it. User `/workflow` commands and authored composition bypass the gate ([#3089](https://github.com/bastani-inc/atomic/issues/3089)).
- Added prompt-based workflow-stage `model: "auto"` selection for stages, chains, and parallel tasks, with hard model constraints, shared router settings, and retained selection metadata across fallback and resume.
- Workflow input and durable approvals can use SDK human-input callbacks without terminal rendering, including nested stage questionnaires with original previews, selections and notes. Pending approvals survive host withdrawal and can be re-presented or resumed under another host without accepting stale answers ([#3105](https://github.com/bastani-inc/atomic/issues/3105)).

### Changed

- The agent again treats workflows as the default for non-trivial work with structure and a verifiable objective. Its guidance names the tasks that fit a workflow (implementation, bug fixes, debugging, migrations, multi-file changes with validation), treats "until" wording such as "fix until green" as a strong workflow signal, and maps task shapes to the pattern workflows. Only tiny, low-risk answers or edits, conversation, unclear goals, or an explicit request to work inline or quickly stay inline.
- Workflow selection guidance now tells the agent that missing, sparse, or mostly inline workflow history is not by itself a reason to work inline; it judges the task's shape first and refines with execution history and your preferences.
- Managed PostgreSQL startup now verifies retained runtime files from a sealed completion manifest instead of re-reading every binary on each attach. Existing marker-less generations remain usable after one verification.
- Managed PostgreSQL can reuse one retained runtime across cluster homes with `ATOMIC_POSTGRES_RUNTIME_CACHE_DIR`; a persisted source stat index avoids repeated full-package hashing on unchanged installations.
- Managed PostgreSQL now avoids repeated runtime-tree scans for npm-installed binaries and running-server attaches; starting or repairing a server still checks the complete retained runtime.
- Managed PostgreSQL runtime repair now rejects incomplete retained generations without scanning their full file trees, and avoids rescanning unchanged damaged generations during the same process.
- Managed PostgreSQL cold runtime staging now avoids repeated setup-lock disk operations during copying and hashing, reducing startup time while preserving publication fencing.
- Managed PostgreSQL now rotates server logs daily through seven weekday files under the cluster's `log` directory, retaining startup diagnostics in `v18.log`. Startup failures include recent output from both logs.
- Durable workflow status changes now verify their transition claim without loading unrelated checkpoint outputs; pause and quit still retain the same ownership and prompt-state checks.
- `/workflow resume` picker rows now use the full workflow ID as their searchable primary label, with status, progress and workflow name beside it so status and progress remain visible at typical terminal widths.
- Generalized the prompt-engineering GPT-6 guide (`references/gpt_6.md`, formerly `gpt_6_astra.md`) to cover GPT-6 Sol and Luna, and replaced its paraphrased snippets with OpenAI's official GPT-6 prompt templates for follow-through, approval timing, skill-instruction priority, writing style, delegation, and verification.
- Focused every prompt-engineering model guide on prompts: removed API request settings such as beta headers, output-token limits, sampling parameters, tool-choice values, API paths, and pricing, while keeping prompt-ordering and caching guidance.
- Added source-attributed Claude Opus 5.5 guidance to the prompt-engineering skill, covering effort calibration, always-on thinking, progress visibility, bounded unattended completion, and API migration checks.
- Reworked all nine prompt-engineering model guides around observed behaviors, practical prompt adjustments, adaptable examples, and caveats, with API details kept secondary.
- `/new`, `/fork`, and `/resume` now quit running workflows instead of leaving them detached from the session that launched them, where their next stage would later fail. When workflows are running, Atomic first asks "Quit N running workflows and …?" and explains that each stops at its last checkpoint and can be resumed with `/workflow resume`; declining cancels the command and the runs keep going. Without an interactive UI the switch proceeds and the runs are quit the same way. `/reload` still keeps runs executing ([#3203](https://github.com/bastani-inc/atomic/issues/3203)).
- Goal and Ralph end-to-end verification guidance and the workflow-authoring guidance now direct desktop, simulator, and emulator verification to Cua Driver: builtin stages load the bundled `cua-driver` skill and drive the exact window with `cua-driver call <tool>` under `CUA_DRIVER_RS_TELEMETRY_ENABLED=false`, save `get_window_state` JSON and `screenshot_out_file` images as evidence, and report a missing permission, session, or refused install as `blocked`/`needs_human` with exact remediation; custom workflows run code-owned scenarios with the `@trycua/cua-driver` SDK inside `ctx.tool` with `timeoutMs` and `signal`, after a preflight `ctx.tool` that exits `blocked` on missing permissions. The OpenAI CUA sample-app reference was removed ([#3181](https://github.com/bastani-inc/atomic/issues/3181)).
- `/workflow connect <run>` no longer prints a `Connected to <run-id>. h hide · ctrl+x leave graph …` notice into the chat; the graph overlay already shows its own key hints, and the picker path never printed one.
- Builtin workflow prompts (`open-claude-design`, `ralph`, goal orchestration, verification guidance, and workflow authoring guidance) now direct browser verification and evidence capture to the `agent-browser` skill and CLI instead of `playwright-cli`, including `agent-browser record start`/`record stop` for QA proof videos.
- Synchronized the bundled `impeccable` skill from upstream `skill-v4.1.1` (`5a149f3fdb1b5793f10567233b1dcab98fc305fd`, `.agents` distribution) to `skill-v4.3.1` (`cd12f8660e2dde57b9615c8a6b8ea674101f9cfc`, `.pi` distribution, engine 0.1.5). Every command now runs through the launcher at `scripts/impeccable` (`impeccable.cmd` on Windows), which executes a self-contained engine binary beside it or downloads the pinned release for the current platform into `~/.impeccable/bin/<version>/` and verifies it against the published SHA-256 before the first run; Node is no longer required, and `IMPECCABLE_BIN` selects a preinstalled engine where network access is unavailable. The launchers default `IMPECCABLE_NO_TELEMETRY` and `IMPECCABLE_NO_UPDATE_CHECK` on, keeping the concept-roll ping and the `npx impeccable update` prompt off for a skill that ships with each Atomic release, and the retained live-browser helpers keep their CSPRNG session-id hardening and removed-editor stripping.
- The `open-claude-design` live review loop drives the bundled Impeccable launcher's `live-poll` verb instead of the removed `live-poll.mjs` script, running `impeccable.cmd` through the platform shell on Windows.
- Workflow authoring guidance now describes stages in one invocation as peers: a live stage can `intercom list` its siblings and `send`/`ask` them directly, queue `send` to a known pending sibling, and `ask` a completed sibling that retains a valid conversation, with prompts expected to name the peers, bound the exchange, and keep each stage's structured result its own.
- All builtin workflow model stages now default to `model: "auto"`, including composed child runs, scoring, reviews and final handoffs. Removed pinned fallback chains while preserving explicit tournament model assignments and custom-workflow defaults.
- Automatic stage model selection ranks up to three distinct eligible models, trying them before remaining configured fallbacks. Durable checkpoints retain the ordered candidates and their efforts without rerouting on resume.
- Workflow model-pinning guidance now treats `evals.md` as factual per-evaluation records and leaves unmatching catalogs unpinned instead of describing benchmark rows as recommendations.
- Automatic stage model selection now receives `evals.md` as markdown tables of dated benchmark records.
- Workflow run displays show only stage execution duration, without redundant startup timing rows. Startup diagnostics remain available through the workflow tool's `stage` and `stages` actions.

### Fixed

- Durable workflows work again on Ubuntu and Debian with the default umask 002. Atomic had refused its own group-writable `~/.atomic` as an ancestor of the PostgreSQL runtime cache and ran workflows in memory, so runs couldn't be resumed after closing Atomic. A group-writable folder is now accepted when its group is your private group: no other account in `/etc/passwd` uses it as its primary group, and `/etc/group` lists no member other than you. World-writable folders and shared groups are still rejected.
- DBOS no longer launches without its migration lock. Previously, when another process held the lock for more than 60 seconds, or the lock connection or query failed, Atomic launched anyway. Two processes could then migrate the same fresh workflow database at once and fail with duplicate-key errors. Atomic now retries lock contention for up to 60 seconds and reopens a failed or dropped lock connection with increasing delays, as Flyway does. If it still has no lock, launch fails with a clear error instead of running unlocked.
- Fixed workflow durability being disabled after upgrading from 0.9.10–0.9.19: Atomic now registers the embedded Postgres cluster that older Atomic provisioned instead of refusing it. If that first start fails, the cluster is left unregistered and checked again on the next startup ([#3235](https://github.com/bastani-inc/atomic/issues/3235)).
- Managed PostgreSQL now runs from a retained runtime outside development worktrees. If that runtime is damaged, reinstalling a complete healthy package lets automatic recovery select a verified replacement, including the same version, even when new database connections are impossible or the server has already exited. Replacement selection now recognizes an in-place repair of a previously incomplete package without requiring a version or path change. A running server's process identity must verify before shutdown; identity mismatches or corruption still require investigation, and Atomic preserves the database.
- Transient PostgreSQL monitoring connection failures no longer interrupt workflow shutdown when a fresh health probe confirms the same server is healthy.
- Fixed managed PostgreSQL recovery refusing to stop its own verified server when PostgreSQL takes more than three seconds after process creation to write its pidfile. A process created after the recorded PostgreSQL start remains ineligible for shutdown.
- Windows managed PostgreSQL recovery now holds a verified process handle through shutdown, preventing PID reuse from directing a signal to an unrelated process.
- Fixed `run()` from `@bastani/atomic/workflows` throwing `DbosNotReadyError` when called from a standalone SDK application. It now starts workflow durability itself and shuts it down after the run, unless another Atomic session in the same process is still using it.
- Fixed workflow durability failing to start when several Atomic sessions or SDK applications first used the same new database at once. The losing processes failed with a duplicate-key or deadlock error during database setup and fell back to memory, or with explicit `durable` mode, failed. Processes now take turns setting up the database.
- Reduced CPU use of the workflow graph view while stages are running: rows that did not change between animation frames are no longer re-measured, truncated, or re-padded on every frame.
- A workflow run that stays in flight across a preserving host `/reload` can now create stages after the reload. Stage session creation and the stage model catalog resolve the newest live extension generation instead of the retired launch `pi` and command ctx, so the next stage no longer fails with `This extension ctx is stale after session replacement or reload` and no longer falls back to `workflows: model catalog unavailable` ([#3201](https://github.com/bastani-inc/atomic/issues/3201)).
- A Goal run with `create_pr=true` could never be resumed after its `pull-request` stage failed with a recoverable error. Every resume failed with `insufficient_state: replay topology mismatch for stage "pull-request"` yet still reported `resumable: true`. On resume, Goal reloads its persisted ledger, which already recorded the approving review round as `complete`, so the turn loop was skipped and `pull-request` ran without its reviewer parents. Goal now replays the turns recorded in a reloaded ledger from their durable checkpoints, so the resume re-executes only the failed stage ([#3207](https://github.com/bastani-inc/atomic/issues/3207)).
- Resuming a Goal run no longer duplicates its ledger history. A replayed turn (one the reloaded ledger already recorded) appended another reducer decision, lifecycle events, a convergence record and reverification entries for the same turn, so the ledger and the final PR report showed repeated history after a resume. Replayed turns are now read-only for the ledger; only live turns append and persist new outcomes ([#3207](https://github.com/bastani-inc/atomic/issues/3207)).
- A workflow stage with `model: "auto"` no longer fails when routing inference fails completely (Jev and the chat structured-output fallback both). The stage now runs on the current chat model with a recorded warning, on fresh runs and resumes alike, when that model is available and satisfies every routing constraint; validation, eligibility, credential-screening failures and cancellation still fail the stage ([#3206](https://github.com/bastani-inc/atomic/issues/3206)).
- Docker fallback Postgres is no longer treated as ready when the published port accepts TCP during `initdb`. Atomic waits for a PostgreSQL query using the endpoint, credentials and TLS settings DBOS will use, retries transient startup resets and refusals (including a connection that terminates while the container is still starting), and shuts down a failed DBOS executor before continuing with the in-memory backend. Invalid readiness ports now fail before connecting rather than leaving a delayed process-crashing error.
- Failed DBOS executor cleanup no longer permits a second launch or an in-memory fallback with unconfirmed executor ownership; startup reports the initialization and cleanup errors instead.
- New Docker fallback containers now publish on the configured `PGPORT`, matching the readiness probe and DBOS connection instead of always binding host port 5432.
- A schema-backed workflow stage whose prompt resolves without any assistant message is no longer recorded as a successful model attempt and pushed into `structured_output` correction prompts. The empty completion is now classified as a transient provider failure at the execution layer: it is retried on the same model using the configured `settings.retry` budget, then advances to the next configured fallback, and its attempt record carries `Model turn ended without an assistant message after the prompt (empty completion)` instead of the structured-output contract error. Genuine cancellation during such a turn stops both the retries and the fallback chain, and corrective prompts remain reserved for turns that actually answered without calling the tool ([#3164](https://github.com/bastani-inc/atomic/issues/3164)).
- An abandoned, owner-less embedded Postgres setup-lock directory (`~/.atomic/postgres/v<major>.setup-lock`, for example a legacy empty-directory lock or a crash remnant) now expires once it is older than the stale threshold, so Atomic recovers embedded provisioning instead of waiting ~30 s for a nonexistent owner and falling back to the non-durable in-memory backend. A freshly created empty directory, a future-dated one, and a live heartbeat owner remain protected ([#3135](https://github.com/bastani-inc/atomic/issues/3135)).
- An embedded Postgres setup-lock creator that is suspended between creating the lock directory and writing its owner marker can no longer end up holding a lease alongside a contender that expired and replaced the empty directory in the meantime. The creator now confirms its marker is the directory's only entry after writing it, and backs off as a lost race otherwise, so two Atomic processes cannot initialize or start the same data directory concurrently.
- After DBOS initialization, bound database-dependent root admission to 10 seconds and stop cancelled admission writes from retrying or starting workflow code later. Unavailable admission skips database cleanup, preserving the failure diagnostic and run identity even when PostgreSQL stops answering. Database readiness lost during admission is rechecked before the next admission without switching existing durable runs to memory. First-time provisioning and initialization are outside this bound ([#3072](https://github.com/bastani-inc/atomic/issues/3072)).
- Malformed saved workflow topology is non-resumable. Rejection during root admission returns a failed run result without executing workflow code or hiding database write failures ([#3072](https://github.com/bastani-inc/atomic/issues/3072)).
- Timed-out or cancelled workflow resume admission no longer publishes stale ownership metadata when its database operation finishes late ([#3072](https://github.com/bastani-inc/atomic/issues/3072)).
- Database-rejected workflow admission preserves PostgreSQL authentication and permission diagnostics and removes a never-persisted local run without reporting it as still running ([#3072](https://github.com/bastani-inc/atomic/issues/3072)).
- Resume continuations skip cleanup when database admission is unavailable, leaving the source resumable instead of waiting on the failed database ([#3072](https://github.com/bastani-inc/atomic/issues/3072)).
- Cancellation during admission now retires a possibly committed database record without waiting on the abandoned admission write, including a checkpointed continuation whose resume has not finished. Failed cancellation persistence retains the local cancelled outcome and warns that database state is unknown ([#3072](https://github.com/bastani-inc/atomic/issues/3072)).
- Graceful quit during startup admission acknowledges the local stop immediately without waiting for registration. Registration settlement retains its admission deadline, including when a local kill arrives while registration finishes. Settlement failures appear in run status while preserving the local pause and resumability for continuations with saved durable progress. Runs without usable durable progress remain nonresumable ([#3072](https://github.com/bastani-inc/atomic/issues/3072)).
- Pausing during startup acknowledges immediately and retains the live executor without waiting for database admission. Later admission failures retain their original diagnostic in run status, and resume releases the failed attempt instead of leaving it stuck behind a rejected pause ([#3072](https://github.com/bastani-inc/atomic/issues/3072)).
- Report root admission phases, dependency errors, phase age, and last progress without healthy-running heartbeats during blocked admission. Bound live executor control persistence, distinguish observed from durable acknowledgements, and retain paused admission for explicit same-owner recovery ([#3072](https://github.com/bastani-inc/atomic/issues/3072)).
- Live executor resume allows up to 10 seconds for database confirmation instead of using the 500ms pause acknowledgement budget, avoiding false timeouts on healthy remote PostgreSQL connections ([#3072](https://github.com/bastani-inc/atomic/issues/3072)).
- Live executor pause acknowledges within 500ms while database confirmation continues for up to 10 seconds. Healthy slower connections no longer leave a false dependency failure; status updates to durable when confirmation succeeds ([#3072](https://github.com/bastani-inc/atomic/issues/3072)).
- Keep ready embedded PostgreSQL running when its starter exits or reloads, retain shared cluster identity and consumer leases outside installation directories, and preserve the original provider's cleanup across bundle reloads ([#3074](https://github.com/bastani-inc/atomic/issues/3074)).
- Verify managed PostgreSQL SQL/data/process identity before attachment, support `ATOMIC_POSTGRES_PORT`, and atomically share the actual port after bounded start/bind retries without adopting foreign listeners or unregistered data ([#3074](https://github.com/bastani-inc/atomic/issues/3074)).
- Monitor managed PostgreSQL SQL/process identity after attachment, invalidate lost connections, elect a shared recovery starter with bounded retries, and reconnect existing database consumers without relaunching workflow execution or changing external database endpoints ([#3074](https://github.com/bastani-inc/atomic/issues/3074)).
- Pool acquisition timeouts and PostgreSQL connection-capacity refusals, including refused managed health checks, no longer disconnect unrelated healthy database consumers or trigger managed PostgreSQL recovery ([#3074](https://github.com/bastani-inc/atomic/issues/3074)).
- Explicit resume reconciles retained database-failed admission under the original run ID, refuses conflicting incomplete records, and prevents stale concurrent resume from claiming a newer running generation. Awaited checkpoint writes now have a 10-second deadline; recovery rereads committed receipts rather than repeating checkpointed effects. External effects without a saved checkpoint remain uncertain and may repeat ([#3072](https://github.com/bastani-inc/atomic/issues/3072), [#3074](https://github.com/bastani-inc/atomic/issues/3074)).
- Same-ID database recovery remains retryable when resume preparation fails after reconciliation, including a temporarily missing workflow definition. Retried resume preserves saved tool receipts instead of switching to a new continuation ([#3072](https://github.com/bastani-inc/atomic/issues/3072)).
- Managed PostgreSQL recovery no longer waits on a vanished server when shutdown overlaps a health check. Recovery retains the existing cluster and checkpoints instead of exhausting readiness polling against the old process ([#3074](https://github.com/bastani-inc/atomic/issues/3074)).
- Managed PostgreSQL startup no longer rejects an owned server when initialization crosses a second boundary. Identity failures now identify the mismatched fields while preserving the cluster and ownership records ([#3074](https://github.com/bastani-inc/atomic/issues/3074)).
- Stage-scoped durable resume now refuses before dispatch instead of resuming the whole root, including restored local shadows of paused durable runs, and prefix resume no longer treats nested children as root candidates ([#2603](https://github.com/bastani-inc/atomic/issues/2603)).
- Request-auth preparation timeouts now block as recoverable `auth_timeout` with source-neutral guidance, instead of asking for `/login`. Established login failures still use `login_required` ([#3087](https://github.com/bastani-inc/atomic/pull/3087)).
- The BACKGROUND panel stays mounted across top-level `/reload` while a run is still awaiting input; status and connect keep targeting the same pending prompt ([#2529](https://github.com/bastani-inc/atomic/issues/2529)).
- Combining-only pending prompts no longer receive a quoted BACKGROUND preview; they keep general needs-attention guidance ([#2529](https://github.com/bastani-inc/atomic/issues/2529)).
- Jev launch routing now supports catalogs above 255 choices through bounded tournaments, retaining `none` in the final comparison and preserving exact user budgets. Partial batch results never authorize a launch ([#3089](https://github.com/bastani-inc/atomic/issues/3089)).
- Fixed workflow routing with strict-schema providers such as Codex when budget limits are omitted or partially supplied, preserving exact limits and zero values without introducing null fields.
- Workflow selection and automatic stage-model selection allow an initial attempt plus up to three repairs for malformed or schema-invalid answers, within the original decision deadline. Authentication/provider errors, cancellation and stale catalogs remain terminal; repairs never duplicate admission.
- Workflow startup no longer removes the default `ask_user_question` tool in headless sessions. Without a UI, execution still returns the existing `no_ui` refusal ([#3105](https://github.com/bastani-inc/atomic/issues/3105)).
- SDK workflow discovery and project configuration now follow the session's working directory rather than the process working directory ([#3105](https://github.com/bastani-inc/atomic/issues/3105)).
- Stage sessions inherit SDK configuration, callbacks and capability restrictions before startup. Questionnaires retain the originating child identity and stay pending through host withdrawal; tool suppression also removes Intercom group access without restoring recursive workflow tooling ([#3105](https://github.com/bastani-inc/atomic/issues/3105)).
- Awaited SDK disposal now drains the owning host's workflow stages and persistence before releasing its runtime resources. Closing or reloading one host no longer clears a sibling host's runs, including separate loaders sharing a caller-supplied event bus; bus sharing does not transfer lifecycle ownership. Borrowed durability backends remain caller-owned ([#3105](https://github.com/bastani-inc/atomic/issues/3105)).
- Borrowed resource discovery no longer acquires a durability lease before session startup. Final cleanup releases the last started owner's lease even when outgoing session retirement fails ([#3105](https://github.com/bastani-inc/atomic/issues/3105)).
- Builtin classifier and category-action stages now retain Intercom coordination without overriding caller-disabled tools or packages.
- Overlapping SDK workflow owners now answer and withdraw questionnaires through their own session's broker rather than a sibling's.
- Retain registered model-tool instance ownership across reload and durable recovery, authorize normalized/default/bulk lifecycle targets before inspection or mutation, and enforce explicit inline preferences even against contrary routing judgments ([#3106](https://github.com/bastani-inc/atomic/issues/3106)).
- Workflow `route` results now display their structured output in a rounded `WORKFLOW ROUTE` box, including inline decisions and routing failures.
- Removed the redundant `ROUTER DECISION` box from workflow `run` output while preserving run status and identity.
- Workflow node model labels now update immediately when a session applies a fallback, including successive fallbacks, without refreshing the graph ([#3110](https://github.com/bastani-inc/atomic/issues/3110)).
- Reduced workflow routing context by sending each workflow contract only with its candidate and preserving exact budgets in code. Verbose catalogs now split into bounded comparisons; oversized task context uses automatic chat fallback or fails when Jev is explicitly pinned, without changing route/run reservations.
- Cold-start workflow stages wait for acknowledged Intercom route authority before connecting, preventing spurious ownership and heavy-initialization failures without weakening route ownership checks.
- Completed stages retain their original start, end, and duration through workflow resume and repeated replay, without rerunning completed work or displaying missing legacy timing as a new zero-duration execution ([#3038](https://github.com/bastani-inc/atomic/issues/3038)).
- Explicit workflow resume now initializes durability in a fresh CLI session instead of silently failing before dispatch, and reports initialization failures ([#3038](https://github.com/bastani-inc/atomic/issues/3038)).

### Removed

- The bundled Impeccable skill no longer ships its Node `scripts/*.mjs` helpers, `scripts/detector/`, `scripts/live/`, `scripts/lib/`, or the Codex-only `agents/` definitions; upstream 4.3.1 moved that logic into the engine binary and the `.pi` distribution carries no Codex agent files.

## [0.9.20-alpha.12] - 2026-09-24

### Changed

- The agent again treats workflows as the default for non-trivial work with structure and a verifiable objective. Its guidance names the tasks that fit a workflow (implementation, bug fixes, debugging, migrations, multi-file changes with validation), treats "until" wording such as "fix until green" as a strong workflow signal, and maps task shapes to the pattern workflows. Only tiny, low-risk answers or edits, conversation, unclear goals, or an explicit request to work inline or quickly stay inline.

## [0.9.20-alpha.11] - 2026-09-24

### Changed

- Workflow selection guidance now tells the agent that missing, sparse, or mostly inline workflow history is not by itself a reason to work inline; it judges the task's shape first and refines with execution history and your preferences.

### Fixed

- Durable workflows work again on Ubuntu and Debian with the default umask 002. Atomic had refused its own group-writable `~/.atomic` as an ancestor of the PostgreSQL runtime cache and ran workflows in memory, so runs couldn't be resumed after closing Atomic. A group-writable folder is now accepted when its group is your private group: no other account in `/etc/passwd` uses it as its primary group, and `/etc/group` lists no member other than you. World-writable folders and shared groups are still rejected.
- DBOS no longer launches without its migration lock. Previously, when another process held the lock for more than 60 seconds, or the lock connection or query failed, Atomic launched anyway. Two processes could then migrate the same fresh workflow database at once and fail with duplicate-key errors. Atomic now retries lock contention for up to 60 seconds and reopens a failed or dropped lock connection with increasing delays, as Flyway does. If it still has no lock, launch fails with a clear error instead of running unlocked.

## [0.9.20-alpha.9] - 2026-09-24

### Breaking Changes

- Removed the public `workflowDependency()` SDK function and its report/operation types, `/workflow dependency`, and the workflow tool's `dependency` action. Inspect affected runs with workflow status; managed PostgreSQL recovery is automatic.

### Added

- SDK `run()` accepts a `durability` option: `{ mode: "memory" }` for a throwaway in-memory run, or `{ mode: "durable", systemDatabaseUrl? }` to require durable state and optionally choose the Postgres database, such as a hosted one. Explicit `durable` mode fails fast with the new `WorkflowDurabilityRequiredError` instead of falling back to memory ([#3239](https://github.com/bastani-inc/atomic/issues/3239)). `DBOS_SYSTEM_DATABASE_URL` still overrides `systemDatabaseUrl` when set. Omitting the option keeps today's behavior.

### Changed

- Managed PostgreSQL startup now verifies retained runtime files from a sealed completion manifest instead of re-reading every binary on each attach. Existing marker-less generations remain usable after one verification.
- Managed PostgreSQL can reuse one retained runtime across cluster homes with `ATOMIC_POSTGRES_RUNTIME_CACHE_DIR`; a persisted source stat index avoids repeated full-package hashing on unchanged installations.
- Managed PostgreSQL now avoids repeated runtime-tree scans for npm-installed binaries and running-server attaches; starting or repairing a server still checks the complete retained runtime.
- Managed PostgreSQL runtime repair now rejects incomplete retained generations without scanning their full file trees, and avoids rescanning unchanged damaged generations during the same process.
- Managed PostgreSQL cold runtime staging now avoids repeated setup-lock disk operations during copying and hashing, reducing startup time while preserving publication fencing.
- Managed PostgreSQL now rotates server logs daily through seven weekday files under the cluster's `log` directory, retaining startup diagnostics in `v18.log`. Startup failures include recent output from both logs.
- Durable workflow status changes now verify their transition claim without loading unrelated checkpoint outputs; pause and quit still retain the same ownership and prompt-state checks.
- `/workflow resume` picker rows now use the full workflow ID as their searchable primary label, with status, progress and workflow name beside it so status and progress remain visible at typical terminal widths.

### Fixed

- Fixed workflow durability being disabled after upgrading from 0.9.10–0.9.19: Atomic now registers the embedded Postgres cluster that older Atomic provisioned instead of refusing it. If that first start fails, the cluster is left unregistered and checked again on the next startup ([#3235](https://github.com/bastani-inc/atomic/issues/3235)).
- Managed PostgreSQL now runs from a retained runtime outside development worktrees. If that runtime is damaged, reinstalling a complete healthy package lets automatic recovery select a verified replacement, including the same version, even when new database connections are impossible or the server has already exited. Replacement selection now recognizes an in-place repair of a previously incomplete package without requiring a version or path change. A running server's process identity must verify before shutdown; identity mismatches or corruption still require investigation, and Atomic preserves the database.
- Transient PostgreSQL monitoring connection failures no longer interrupt workflow shutdown when a fresh health probe confirms the same server is healthy.
- Fixed managed PostgreSQL recovery refusing to stop its own verified server when PostgreSQL takes more than three seconds after process creation to write its pidfile. A process created after the recorded PostgreSQL start remains ineligible for shutdown.
- Windows managed PostgreSQL recovery now holds a verified process handle through shutdown, preventing PID reuse from directing a signal to an unrelated process.
- Fixed `run()` from `@bastani/atomic/workflows` throwing `DbosNotReadyError` when called from a standalone SDK application. It now starts workflow durability itself and shuts it down after the run, unless another Atomic session in the same process is still using it.
- Fixed workflow durability failing to start when several Atomic sessions or SDK applications first used the same new database at once. The losing processes failed with a duplicate-key or deadlock error during database setup and fell back to memory, or with explicit `durable` mode, failed. Processes now take turns setting up the database.

## [0.9.20-alpha.8] - 2026-09-22

### Fixed

- Reduced CPU use of the workflow graph view while stages are running: rows that did not change between animation frames are no longer re-measured, truncated, or re-padded on every frame.

## [0.9.20-alpha.7] - 2026-09-22

### Breaking Changes

- Removed the `workflow` tool's `route` action and its router classifier. The agent now decides itself whether a workflow fits and launches with `workflow({ action: "run", workflow: "<name>", inputs, budget? })`. The `workflowId` reservation, `state` parameter, `routerDecision`, `estimatedDuration` labels, and `needs_input`/`not_launched`/`reserved` statuses are gone; `run` validates inputs and fails without launching when they are invalid. Runs launched through the model tool still belong to the launching session.

### Changed

- Generalized the prompt-engineering GPT-6 guide (`references/gpt_6.md`, formerly `gpt_6_astra.md`) to cover GPT-6 Sol and Luna, and replaced its paraphrased snippets with OpenAI's official GPT-6 prompt templates for follow-through, approval timing, skill-instruction priority, writing style, delegation, and verification.
- Focused every prompt-engineering model guide on prompts: removed API request settings such as beta headers, output-token limits, sampling parameters, tool-choice values, API paths, and pricing, while keeping prompt-ordering and caching guidance.
- Added source-attributed Claude Opus 5.5 guidance to the prompt-engineering skill, covering effort calibration, always-on thinking, progress visibility, bounded unattended completion, and API migration checks.
- Reworked all nine prompt-engineering model guides around observed behaviors, practical prompt adjustments, adaptable examples, and caveats, with API details kept secondary.
- `/new`, `/fork`, and `/resume` now quit running workflows instead of leaving them detached from the session that launched them, where their next stage would later fail. When workflows are running, Atomic first asks "Quit N running workflows and …?" and explains that each stops at its last checkpoint and can be resumed with `/workflow resume`; declining cancels the command and the runs keep going. Without an interactive UI the switch proceeds and the runs are quit the same way. `/reload` still keeps runs executing ([#3203](https://github.com/bastani-inc/atomic/issues/3203)).

### Fixed

- A workflow run that stays in flight across a preserving host `/reload` can now create stages after the reload. Stage session creation and the stage model catalog resolve the newest live extension generation instead of the retired launch `pi` and command ctx, so the next stage no longer fails with `This extension ctx is stale after session replacement or reload` and no longer falls back to `workflows: model catalog unavailable` ([#3201](https://github.com/bastani-inc/atomic/issues/3201)).
- A Goal run with `create_pr=true` could never be resumed after its `pull-request` stage failed with a recoverable error. Every resume failed with `insufficient_state: replay topology mismatch for stage "pull-request"` yet still reported `resumable: true`. On resume, Goal reloads its persisted ledger, which already recorded the approving review round as `complete`, so the turn loop was skipped and `pull-request` ran without its reviewer parents. Goal now replays the turns recorded in a reloaded ledger from their durable checkpoints, so the resume re-executes only the failed stage ([#3207](https://github.com/bastani-inc/atomic/issues/3207)).
- Resuming a Goal run no longer duplicates its ledger history. A replayed turn (one the reloaded ledger already recorded) appended another reducer decision, lifecycle events, a convergence record and reverification entries for the same turn, so the ledger and the final PR report showed repeated history after a resume. Replayed turns are now read-only for the ledger; only live turns append and persist new outcomes ([#3207](https://github.com/bastani-inc/atomic/issues/3207)).
- A workflow stage with `model: "auto"` no longer fails when routing inference fails completely (Jev and the chat structured-output fallback both). The stage now runs on the current chat model with a recorded warning, on fresh runs and resumes alike, when that model is available and satisfies every routing constraint; validation, eligibility, credential-screening failures and cancellation still fail the stage ([#3206](https://github.com/bastani-inc/atomic/issues/3206)).

## [0.9.20-alpha.6] - 2026-09-22

### Changed

- Goal and Ralph end-to-end verification guidance and the workflow-authoring guidance now direct desktop, simulator, and emulator verification to Cua Driver: builtin stages load the bundled `cua-driver` skill and drive the exact window with `cua-driver call <tool>` under `CUA_DRIVER_RS_TELEMETRY_ENABLED=false`, save `get_window_state` JSON and `screenshot_out_file` images as evidence, and report a missing permission, session, or refused install as `blocked`/`needs_human` with exact remediation; custom workflows run code-owned scenarios with the `@trycua/cua-driver` SDK inside `ctx.tool` with `timeoutMs` and `signal`, after a preflight `ctx.tool` that exits `blocked` on missing permissions. The OpenAI CUA sample-app reference was removed ([#3181](https://github.com/bastani-inc/atomic/issues/3181)).

### Fixed

- Docker fallback Postgres is no longer treated as ready when the published port accepts TCP during `initdb`. Atomic waits for a PostgreSQL query using the endpoint, credentials and TLS settings DBOS will use, retries transient startup resets and refusals (including a connection that terminates while the container is still starting), and shuts down a failed DBOS executor before continuing with the in-memory backend. Invalid readiness ports now fail before connecting rather than leaving a delayed process-crashing error.
- Failed DBOS executor cleanup no longer permits a second launch or an in-memory fallback with unconfirmed executor ownership; startup reports the initialization and cleanup errors instead.
- New Docker fallback containers now publish on the configured `PGPORT`, matching the readiness probe and DBOS connection instead of always binding host port 5432.
- A schema-backed workflow stage whose prompt resolves without any assistant message is no longer recorded as a successful model attempt and pushed into `structured_output` correction prompts. The empty completion is now classified as a transient provider failure at the execution layer: it is retried on the same model using the configured `settings.retry` budget, then advances to the next configured fallback, and its attempt record carries `Model turn ended without an assistant message after the prompt (empty completion)` instead of the structured-output contract error. Genuine cancellation during such a turn stops both the retries and the fallback chain, and corrective prompts remain reserved for turns that actually answered without calling the tool ([#3164](https://github.com/bastani-inc/atomic/issues/3164)).

## [0.9.20-alpha.5] - 2026-09-20

### Breaking Changes

- Workflow route `state` no longer accepts `executionPreference`, and unknown state fields are rejected before inference. The router now asks an independent question about the user's stated execution preference, judged from the user's own words in `state.task`, `state.conversation` and `state.constraints`: an explicit inline request yields `none` even when a workflow matches, and an explicit workflow request bypasses the lifecycle-benefit gate without inventing an unregistered workflow. The calling assistant passes evidence only, so it can no longer pre-decide the route.

- The `open-claude-design` workflow output `playwright_cli_status` is now `agent_browser_status`: the initial deterministic setup step probes for and installs the `agent-browser` CLI (`npm install -g agent-browser` + `agent-browser install`) instead of `playwright-cli`. Consumers reading `playwright_cli_status` must switch to the new field name.

### Changed

- `/workflow connect <run>` no longer prints a `Connected to <run-id>. h hide · ctrl+x leave graph …` notice into the chat; the graph overlay already shows its own key hints, and the picker path never printed one.

- Builtin workflow prompts (`open-claude-design`, `ralph`, goal orchestration, verification guidance, and workflow authoring guidance) now direct browser verification and evidence capture to the `agent-browser` skill and CLI instead of `playwright-cli`, including `agent-browser record start`/`record stop` for QA proof videos.

- Synchronized the bundled `impeccable` skill from upstream `skill-v4.1.1` (`5a149f3fdb1b5793f10567233b1dcab98fc305fd`, `.agents` distribution) to `skill-v4.3.1` (`cd12f8660e2dde57b9615c8a6b8ea674101f9cfc`, `.pi` distribution, engine 0.1.5). Every command now runs through the launcher at `scripts/impeccable` (`impeccable.cmd` on Windows), which executes a self-contained engine binary beside it or downloads the pinned release for the current platform into `~/.impeccable/bin/<version>/` and verifies it against the published SHA-256 before the first run; Node is no longer required, and `IMPECCABLE_BIN` selects a preinstalled engine where network access is unavailable. The launchers default `IMPECCABLE_NO_TELEMETRY` and `IMPECCABLE_NO_UPDATE_CHECK` on, keeping the concept-roll ping and the `npx impeccable update` prompt off for a skill that ships with each Atomic release, and the retained live-browser helpers keep their CSPRNG session-id hardening and removed-editor stripping.

- The `open-claude-design` live review loop drives the bundled Impeccable launcher's `live-poll` verb instead of the removed `live-poll.mjs` script, running `impeccable.cmd` through the platform shell on Windows.

- Workflow authoring guidance now describes stages in one invocation as peers: a live stage can `intercom list` its siblings and `send`/`ask` them directly, queue `send` to a known pending sibling, and `ask` a completed sibling that retains a valid conversation, with prompts expected to name the peers, bound the exchange, and keep each stage's structured result its own.

### Fixed

- An abandoned, owner-less embedded Postgres setup-lock directory (`~/.atomic/postgres/v<major>.setup-lock`, for example a legacy empty-directory lock or a crash remnant) now expires once it is older than the stale threshold, so Atomic recovers embedded provisioning instead of waiting ~30 s for a nonexistent owner and falling back to the non-durable in-memory backend. A freshly created empty directory, a future-dated one, and a live heartbeat owner remain protected ([#3135](https://github.com/bastani-inc/atomic/issues/3135)).

- An embedded Postgres setup-lock creator that is suspended between creating the lock directory and writing its owner marker can no longer end up holding a lease alongside a contender that expired and replaced the empty directory in the meantime. The creator now confirms its marker is the directory's only entry after writing it, and backs off as a lost race otherwise, so two Atomic processes cannot initialize or start the same data directory concurrently.

### Removed

- The bundled Impeccable skill no longer ships its Node `scripts/*.mjs` helpers, `scripts/detector/`, `scripts/live/`, `scripts/lib/`, or the Codex-only `agents/` definitions; upstream 4.3.1 moved that logic into the engine binary and the `.pi` distribution carries no Codex agent files.

## [0.9.20-alpha.4] - 2026-09-20

### Breaking Changes

- Headless launches return an accepted run identity for status inspection, without input pickers. Required durable gates remain pending until an authorized host or answer arrives, including when no host was initially bound. Explicit runtime execution policies remain enforced ([#3105](https://github.com/bastani-inc/atomic/issues/3105)).
- Model-tool execution now requires `route` with content-bearing `state.task`, then `run` with the returned registered `workflowId` and validated inputs. Route returns the input schema without launching; input correction reuses the ID without rerouting. Old run-as-router calls and duration values are rejected. Estimates use 97 canonical labels: quarter-hour increments through `1d`, plus `>1d`, without changing budgets ([#3106](https://github.com/bastani-inc/atomic/issues/3106)).
- Workflow route and registered run results no longer repeat `estimatedDuration` at the top level. Route results also no longer repeat `workflowType`, including `none`. Read the canonical estimate and selection from `routerDecision.estimatedDuration` and `routerDecision.workflowType`.
- Workflow duration estimates no longer accept `unknown`. Routers must give their best estimate using a quarter-hour bucket or `>1d`; estimates remain nonbinding.

### Added

- Added `workflowDependency()`, `/workflow dependency` and the workflow tool's `dependency` action for bounded database inspection and registered managed-cluster recovery, with actual port, verified identity, runtime versions, consumers, retained latest failure and safe guidance. External database endpoints receive query-only checks ([#3074](https://github.com/bastani-inc/atomic/issues/3074)).
- Workflow UUID selectors accept unique 8-character hexadecimal prefixes across live and durable runs, with explicit collision errors ([#2603](https://github.com/bastani-inc/atomic/issues/2603)).
- Attached stage chats show `[stage: name]` on the composer top rule, a mounted question's top rule, and awaiting-input prompt borders ([#2886](https://github.com/bastani-inc/atomic/issues/2886), [#3013](https://github.com/bastani-inc/atomic/pull/3013) by [@sumitvairagar](https://github.com/sumitvairagar)).
- Added live, bounded pending-input previews to the BACKGROUND widget, with per-workflow navigation and automatic clearing ([#2700](https://github.com/bastani-inc/atomic/pull/2700) by [@Shreyasd10](https://github.com/Shreyasd10)).
- Added mandatory bounded routing before model-tool workflow launches, using explicit task state and the full current workflow catalog. Results show validated workflow/budget decisions as formatted JSON; `none` directs the caller to continue inline without launching, and changed registry approvals fail before admission. Routing context containing known configured credentials is rejected before either provider receives it. User `/workflow` commands and authored composition bypass the gate ([#3089](https://github.com/bastani-inc/atomic/issues/3089)).
- Added prompt-based workflow-stage `model: "auto"` selection for stages, chains, and parallel tasks, with hard model constraints, shared router settings, and retained selection metadata across fallback and resume.
- Workflow input and durable approvals can use SDK human-input callbacks without terminal rendering, including nested stage questionnaires with original previews, selections and notes. Pending approvals survive host withdrawal and can be re-presented or resumed under another host without accepting stale answers ([#3105](https://github.com/bastani-inc/atomic/issues/3105)).

### Changed

- All builtin workflow model stages now default to `model: "auto"`, including composed child runs, scoring, reviews and final handoffs. Removed pinned fallback chains while preserving explicit tournament model assignments and custom-workflow defaults.
- Automatic stage model selection ranks up to three distinct eligible models, trying them before remaining configured fallbacks. Durable checkpoints retain the ordered candidates and their efforts without rerouting on resume.
- Workflow model-pinning guidance now treats `evals.md` as factual per-evaluation records and leaves unmatching catalogs unpinned instead of describing benchmark rows as recommendations.
- Automatic stage model selection now receives `evals.md` as markdown tables of dated benchmark records.
- Workflow run displays show only stage execution duration, without redundant startup timing rows. Startup diagnostics remain available through the workflow tool's `stage` and `stages` actions.

### Fixed

- After DBOS initialization, bound database-dependent root admission to 10 seconds and stop cancelled admission writes from retrying or starting workflow code later. Unavailable admission skips database cleanup, preserving the failure diagnostic and run identity even when PostgreSQL stops answering. Database readiness lost during admission is rechecked before the next admission without switching existing durable runs to memory. First-time provisioning and initialization are outside this bound ([#3072](https://github.com/bastani-inc/atomic/issues/3072)).
- Malformed saved workflow topology is non-resumable. Rejection during root admission returns a failed run result without executing workflow code or hiding database write failures ([#3072](https://github.com/bastani-inc/atomic/issues/3072)).
- Timed-out or cancelled workflow resume admission no longer publishes stale ownership metadata when its database operation finishes late ([#3072](https://github.com/bastani-inc/atomic/issues/3072)).
- Database-rejected workflow admission preserves PostgreSQL authentication and permission diagnostics and removes a never-persisted local run without reporting it as still running ([#3072](https://github.com/bastani-inc/atomic/issues/3072)).
- Resume continuations skip cleanup when database admission is unavailable, leaving the source resumable instead of waiting on the failed database ([#3072](https://github.com/bastani-inc/atomic/issues/3072)).
- Cancellation during admission now retires a possibly committed database record without waiting on the abandoned admission write, including a checkpointed continuation whose resume has not finished. Failed cancellation persistence retains the local cancelled outcome and warns that database state is unknown ([#3072](https://github.com/bastani-inc/atomic/issues/3072)).
- Graceful quit during startup admission acknowledges the local stop immediately without waiting for registration. Registration settlement retains its admission deadline, including when a local kill arrives while registration finishes. Settlement failures appear in run status while preserving the local pause and resumability for continuations with saved durable progress. Runs without usable durable progress remain nonresumable ([#3072](https://github.com/bastani-inc/atomic/issues/3072)).
- Pausing during startup acknowledges immediately and retains the live executor without waiting for database admission. Later admission failures retain their original diagnostic in run status, and resume releases the failed attempt instead of leaving it stuck behind a rejected pause ([#3072](https://github.com/bastani-inc/atomic/issues/3072)).
- Report root admission phases, dependency errors, phase age, and last progress without healthy-running heartbeats during blocked admission. Bound live executor control persistence, distinguish observed from durable acknowledgements, and retain paused admission for explicit same-owner recovery ([#3072](https://github.com/bastani-inc/atomic/issues/3072)).
- Live executor resume allows up to 10 seconds for database confirmation instead of using the 500ms pause acknowledgement budget, avoiding false timeouts on healthy remote PostgreSQL connections ([#3072](https://github.com/bastani-inc/atomic/issues/3072)).
- Live executor pause acknowledges within 500ms while database confirmation continues for up to 10 seconds. Healthy slower connections no longer leave a false dependency failure; status updates to durable when confirmation succeeds ([#3072](https://github.com/bastani-inc/atomic/issues/3072)).
- Keep ready embedded PostgreSQL running when its starter exits or reloads, retain shared cluster identity and consumer leases outside installation directories, and preserve the original provider's cleanup across bundle reloads ([#3074](https://github.com/bastani-inc/atomic/issues/3074)).
- Verify managed PostgreSQL SQL/data/process identity before attachment, support `ATOMIC_POSTGRES_PORT`, and atomically share the actual port after bounded start/bind retries without adopting foreign listeners or unregistered data ([#3074](https://github.com/bastani-inc/atomic/issues/3074)).
- Monitor managed PostgreSQL SQL/process identity after attachment, invalidate lost connections, elect a shared recovery starter with bounded retries, and reconnect existing database consumers without relaunching workflow execution or changing external database endpoints ([#3074](https://github.com/bastani-inc/atomic/issues/3074)).
- Pool acquisition timeouts and PostgreSQL connection-capacity refusals, including refused managed health checks, no longer disconnect unrelated healthy database consumers or trigger managed PostgreSQL recovery ([#3074](https://github.com/bastani-inc/atomic/issues/3074)).
- Explicit resume reconciles retained database-failed admission under the original run ID, refuses conflicting incomplete records, and prevents stale concurrent resume from claiming a newer running generation. Awaited checkpoint writes now have a 10-second deadline; recovery rereads committed receipts rather than repeating checkpointed effects. External effects without a saved checkpoint remain uncertain and may repeat ([#3072](https://github.com/bastani-inc/atomic/issues/3072), [#3074](https://github.com/bastani-inc/atomic/issues/3074)).
- Same-ID database recovery remains retryable when resume preparation fails after reconciliation, including a temporarily missing workflow definition. Retried resume preserves saved tool receipts instead of switching to a new continuation ([#3072](https://github.com/bastani-inc/atomic/issues/3072)).
- Managed PostgreSQL recovery no longer waits on a vanished server when shutdown overlaps a health check. Recovery retains the existing cluster and checkpoints instead of exhausting readiness polling against the old process ([#3074](https://github.com/bastani-inc/atomic/issues/3074)).
- Managed PostgreSQL startup no longer rejects an owned server when initialization crosses a second boundary. Identity failures now identify the mismatched fields while preserving the cluster and ownership records ([#3074](https://github.com/bastani-inc/atomic/issues/3074)).
- Stage-scoped durable resume now refuses before dispatch instead of resuming the whole root, including restored local shadows of paused durable runs, and prefix resume no longer treats nested children as root candidates ([#2603](https://github.com/bastani-inc/atomic/issues/2603)).
- Request-auth preparation timeouts now block as recoverable `auth_timeout` with source-neutral guidance, instead of asking for `/login`. Established login failures still use `login_required` ([#3087](https://github.com/bastani-inc/atomic/pull/3087)).
- The BACKGROUND panel stays mounted across top-level `/reload` while a run is still awaiting input; status and connect keep targeting the same pending prompt ([#2529](https://github.com/bastani-inc/atomic/issues/2529)).
- Combining-only pending prompts no longer receive a quoted BACKGROUND preview; they keep general needs-attention guidance ([#2529](https://github.com/bastani-inc/atomic/issues/2529)).
- Jev launch routing now supports catalogs above 255 choices through bounded tournaments, retaining `none` in the final comparison and preserving exact user budgets. Partial batch results never authorize a launch ([#3089](https://github.com/bastani-inc/atomic/issues/3089)).
- Fixed workflow routing with strict-schema providers such as Codex when budget limits are omitted or partially supplied, preserving exact limits and zero values without introducing null fields.
- Workflow selection and automatic stage-model selection allow an initial attempt plus up to three repairs for malformed or schema-invalid answers, within the original decision deadline. Authentication/provider errors, cancellation and stale catalogs remain terminal; repairs never duplicate admission.
- Workflow startup no longer removes the default `ask_user_question` tool in headless sessions. Without a UI, execution still returns the existing `no_ui` refusal ([#3105](https://github.com/bastani-inc/atomic/issues/3105)).
- SDK workflow discovery and project configuration now follow the session's working directory rather than the process working directory ([#3105](https://github.com/bastani-inc/atomic/issues/3105)).
- Stage sessions inherit SDK configuration, callbacks and capability restrictions before startup. Questionnaires retain the originating child identity and stay pending through host withdrawal; tool suppression also removes Intercom group access without restoring recursive workflow tooling ([#3105](https://github.com/bastani-inc/atomic/issues/3105)).
- Awaited SDK disposal now drains the owning host's workflow stages and persistence before releasing its runtime resources. Closing or reloading one host no longer clears a sibling host's runs, including separate loaders sharing a caller-supplied event bus; bus sharing does not transfer lifecycle ownership. Borrowed durability backends remain caller-owned ([#3105](https://github.com/bastani-inc/atomic/issues/3105)).
- Borrowed resource discovery no longer acquires a durability lease before session startup. Final cleanup releases the last started owner's lease even when outgoing session retirement fails ([#3105](https://github.com/bastani-inc/atomic/issues/3105)).
- Builtin classifier and category-action stages now retain Intercom coordination without overriding caller-disabled tools or packages.
- Overlapping SDK workflow owners now answer and withdraw questionnaires through their own session's broker rather than a sibling's.
- Retain registered model-tool instance ownership across reload and durable recovery, authorize normalized/default/bulk lifecycle targets before inspection or mutation, and enforce explicit inline preferences even against contrary routing judgments ([#3106](https://github.com/bastani-inc/atomic/issues/3106)).
- Workflow `route` results now display their structured output in a rounded `WORKFLOW ROUTE` box, including inline decisions and routing failures.
- Removed the redundant `ROUTER DECISION` box from workflow `run` output while preserving run status and identity.
- Workflow node model labels now update immediately when a session applies a fallback, including successive fallbacks, without refreshing the graph ([#3110](https://github.com/bastani-inc/atomic/issues/3110)).
- Reduced workflow routing context by sending each workflow contract only with its candidate and preserving exact budgets in code. Verbose catalogs now split into bounded comparisons; oversized task context uses automatic chat fallback or fails when Jev is explicitly pinned, without changing route/run reservations.

## [0.9.20-alpha.1] - 2026-09-14

### Fixed

- Cold-start workflow stages wait for acknowledged Intercom route authority before connecting, preventing spurious ownership and heavy-initialization failures without weakening route ownership checks.
- Completed stages retain their original start, end, and duration through workflow resume and repeated replay, without rerunning completed work or displaying missing legacy timing as a new zero-duration execution ([#3038](https://github.com/bastani-inc/atomic/issues/3038)).
- Explicit workflow resume now initializes durability in a fresh CLI session instead of silently failing before dispatch, and reports initialization failures ([#3038](https://github.com/bastani-inc/atomic/issues/3038)).

## [0.9.19] - 2026-09-13

Cumulative release of the `0.9.19-alpha.1` through `0.9.19-alpha.11` prereleases. Per-change details remain in the unchanged prerelease sections below.

### Breaking Changes

- Workflow control uses `pause` across slash commands, tool actions, runtime APIs and lifecycle events. Run-level pause preserves resumable work, nested checkpoint tails and executor-only waits; targeted stage pause retains queued messages, and targeted `ctx.tool` pause cancels only that call. Use `resume` to continue eligible work.

### Added

- Connected workflow activity to host observers and the built-in Herdr reporter, with root snapshots that distinguish execution, human waits, pauses, recovery and acknowledged failures. Typed lifecycle, activity, completion and heartbeat hooks preserve canonical nested identities without synthesizing completions during restore ([#2891](https://github.com/bastani-inc/atomic/issues/2891)).
- Added source-qualified stage-local `/skill:` discovery and one-time expansion for idle, steering and follow-up submissions, retaining Enter/Ctrl+F intent and human-input ownership. Editable post-mortem chats can use skills without restarting execution; `StageSendUserMessageOptions.expandPromptTemplates` opts programmatic delivery into expansion.
- Added bound owner-task inspection to stage chats with compact background counts below the composer, shared `/tasks` navigation and readable shaded completion cards ([#2884](https://github.com/bastani-inc/atomic/pull/2884)).
- Graph node cards show effective model and thinking identity, preserving canonical fast suffixes, updating on fallback and restoring through durable resume ([#1859](https://github.com/bastani-inc/atomic/pull/1859) by [@sina85](https://github.com/sina85)).
- Main-chat workflow cards support viewport-local wheel scrolling and an overflow-only scrollbar. Configurable Alt+K/J shortcuts, labeled Option on macOS, retain Alt+PageUp/PageDown aliases and yield to editor bindings. Ten-row and short-terminal caps preserve multiline-draft access and run anchors through live changes and resize.

### Changed

- Incoming Intercom sends and asks cancel a live stage's current model call or cancellable tool and process messages in the same generation. Ordered delivery survives preflight and persistence races without replaying completed tools or cancelling a child that is asking its parent.
- Reduced default stage and authored parallel concurrency from 4 to 3, preserving explicit overrides.
- Open Claude Design starts with Fable 5.1 at medium, then Copilot Fable 5.1 and Astra at medium, with Fable-first OpenRouter fallbacks. Goal and Ralph orchestration, Ralph research and design use Fable fallbacks at medium and Sol at high; Goal/Ralph reviewers use Astra/Sol at high. Ralph prompt refinement remains at high, and OpenRouter Grok fallbacks explicitly use xhigh.
- Guidance uses project CI timing to plan critical-path work, avoids redundant full-suite runs without skipping gates, and routes user questions through structured question tools when available. Requests to work "quickly" select inline execution; launches inherit configured limits without routine budget questions while preserving approval before raising exhausted budgets.
- Graph cards omit generated dependency labels and extra padding, leave absent models blank, and show queued-message counts on a separate row. Status detail uses local time rather than UTC ([#3008](https://github.com/bastani-inc/atomic/issues/3008)).

### Fixed

- Model fallback releases failed-attempt Intercom ownership before replacement, shares concurrent attachment/steering setup, and stops on cleanup failure. Repeated nested `ctx.workflow()` calls use unambiguous boundary identities instead of colliding during fallback ([#3020](https://github.com/bastani-inc/atomic/issues/3020)).
- Unchanged stage routes are no longer republished on every store update, avoiding redundant broker traffic and `List sessions timeout`. Genuine changes publish immediately, and rejected or unacknowledged announcements remain retryable.
- Restored embedded Postgres discovery in Bun-compiled and nested npm installations. Early exit reports the retained server's log instead of a readiness timeout; competing listeners and process-query failures cannot masquerade as readiness.
- Reduced checkpoint-heavy durable resume latency, especially on Windows, without changing decoded values or original errors. Ended recoverable blocks resume through continuation rather than reporting snapshot-only success.
- Initialization cancellation no longer leaves uncontrollable empty runs. Whole-run pause retains live executors and nested owners until resume, while quit retires them; durable resume replaces abandoned executors without replacing surviving paused owners. Original tool failures, closed-admission errors and child cleanup survive cancellation races.
- Stage pause cancels owned active and admitted queued agents and commands and waits for admission and cleanup; resume permits fresh work without reviving cancelled executions or affecting siblings. Durable tool callbacks wait for admitted agent tasks to settle before checkpointing, preserving commit/cancellation fences ([#2884](https://github.com/bastani-inc/atomic/pull/2884)).
- Quit and pause dismiss owned active-tool and readiness questions, reject late answers, and ask readiness again on resume. Failed cancellation releases only its temporary hold instead of stranding a running stage ([#2897](https://github.com/bastani-inc/atomic/issues/2897)).
- Completed stages retain their late-message routing for post-mortem asks. Non-agent prompt/tool names do not invalidate genuine duplicate-agent routing ([#2895](https://github.com/bastani-inc/atomic/pull/2895)).
- Preserved complete stage artifacts across follow-up clarification, compaction and fallback. Failed retries discard provisional answers without losing earlier accepted reports; typed child workflows can receive structured output without graph projection freezing it ([#2936](https://github.com/bastani-inc/atomic/issues/2936)).
- Local stage listing and background counts include recursively nested stages without duplicate boundaries. Warm-first verifier and tournament groups declare possible-stage names without spurious builtin discovery warnings ([#3001](https://github.com/bastani-inc/atomic/issues/3001)).
- Skill autocomplete shares lazy attachment without checkpointing on every keystroke. Unsupported custom hosts report unavailable invocation rather than bypassing admission.
- Stage `/tasks` stays local, retains model/reasoning/cwd/branch/MCP context, and keeps counts visible beside questions on narrow terminals. Detail pages remain fullscreen, and navigation does not create false input notices or approval waits.
- Workflow graph interiors and autocomplete use the terminal background; themed chrome and focused tabs retain fill and styling through truncation. Graph/picker navigation no longer falsely marks Herdr blocked.
- Live continuation prevents brief false idle reports. Settled failures retain attention without reporting an active decision wait; genuine questions and exhausted budgets remain blocked. Already-aborted lifecycle kill events and checkpoint interrupt outcomes remain accurate ([#2891](https://github.com/bastani-inc/atomic/issues/2891), [#2912](https://github.com/bastani-inc/atomic/pull/2912)).
- Workflow summaries fit narrow terminals, keep the viewed run anchored across insertion/removal and collapse/resize, and use a concise `↑↓ scroll` hint without a redundant visible-row counter ([#3015](https://github.com/bastani-inc/atomic/issues/3015), [#3017](https://github.com/bastani-inc/atomic/pull/3017)).

## [0.9.19-alpha.11] - 2026-09-13

### Fixed

- Repeated nested `ctx.workflow()` invocations use unambiguous Intercom boundary identities, preventing duplicate-owner and heavy-initialization warnings during model fallback while preserving route ownership checks.

## [0.9.19-alpha.10] - 2026-09-13

### Added

- Main-chat workflow cards now scroll with the wheel over their actual allocated viewport, with a slim scrollbar only when content overflows. Configurable Alt+K/J shortcuts, labeled Option on macOS, retain Alt+PageUp/PageDown aliases and yield to configured editor bindings. The ten-row/short-terminal cap, multiline-draft reachability and run-ID anchors remain intact across insertion, deletion, collapse and resize, including isolated-engine sessions.

### Fixed

- Model fallback releases the failed attempt's Intercom ownership before initializing its replacement, avoiding duplicate live-stage ownership warnings while retaining queued delivery handoff. Concurrent attachment and steering wait for cleanup and share successor creation. Cancellation during cleanup no longer starts a replacement session, and failed extension initialization cleans up its session. If that cleanup fails, the stage stops rather than retrying or creating another session, preserving both the initialization and cleanup errors for diagnosis ([#3020](https://github.com/bastani-inc/atomic/issues/3020)).
- Removed the confusing visible-row counter from the main-chat workflow widget hint; the final hint now reads `↑↓ scroll` followed by available scrolling shortcuts, matching the `/tasks` hint style.

## [0.9.19-alpha.9] - 2026-09-12

### Fixed

- Kept the background workflow summary within narrow terminal widths, including 27 columns. The shared workflow widget now stays within ten rows, shrinks on short terminals, and scrolls one row at a time with Alt+PageUp / Alt+PageDown without taking focus from the editor. All workflow rows remain reachable when a multiline draft reduces the visible widget area ([#3015](https://github.com/bastani-inc/atomic/issues/3015)).
- Kept the workflow being read in view when live runs are inserted or removed above it, including workflows with identical names. Resizing to a collapsed summary and back preserves the reading position; removing the viewed run selects its next surviving neighbour, or the previous one when no later run remains ([#3017](https://github.com/bastani-inc/atomic/pull/3017)).

## [0.9.19-alpha.8] - 2026-09-12

### Fixed

- Workflow status detail now shows started and ended times in the system local timezone instead of UTC, preserving the compact `HH:mm:ss` display and elapsed durations ([#3008](https://github.com/bastani-inc/atomic/issues/3008)).

### Changed

- Removed generated `root`, `dep`, and `deps` labels from workflow graph nodes and left model text blank when no model is set. Cards omit the extra padding row. Queued-message counts appear on a separate `✉ N queued` row, reusing empty space or expanding occupied cards without hiding status or model details. Dependency edges are unchanged.

## [0.9.19-alpha.7] - 2026-09-12

### Fixed

- Warm-first verifier and tournament judge groups now advertise conservative possible-stage names in source and bundled workflows without the builtin `warmSteps`/`restSteps` discovery warnings. Call-scoped `possibleStageNames` metadata leaves execution unchanged and retains diagnostics for unsupported dynamic calls ([#3001](https://github.com/bastani-inc/atomic/issues/3001)).
- Fixed workflow quit hanging while a stage waits on `ask_user_question`. Cancelling the stage's active tool now dismisses its owned question without requiring an answer, including in nested workflows, while preserving paused/resumable state and unrelated questions. Related: [#2897](https://github.com/bastani-inc/atomic/issues/2897).
- Fixed quit leaving a stage's readiness question answerable after stopping. Readiness questions now dismiss on pause or quit, ignore late answers, and ask again after explicit resume instead of advancing a paused workflow. Related: [#2897](https://github.com/bastani-inc/atomic/issues/2897).
- Fixed a failed pause or quit leaving a running stage stuck after its readiness answer was accepted. Failed cancellation now releases that stage's temporary hold without releasing a successful pause. Related: [#2897](https://github.com/bastani-inc/atomic/issues/2897).

## [0.9.19-alpha.6] - 2026-09-11

### Fixed

- Workflow stage routes are no longer republished to the broker when nothing about the route changed. Every store invalidation — including tool events, attachment changes, and notices that leave the route projection identical — previously re-announced every run, so a burst of unrelated activity could produce a thousand redundant broker round trips and surface as `Intercom event relay failed (atomic:workflow-pending-stage-route): List sessions timeout`. Genuine changes still publish immediately and are never debounced, and an announcement that is rejected or that no consumer acknowledges is retried on the next invalidation.

## [0.9.19-alpha.5] - 2026-09-11

### Changed

- Open Claude Design now starts with Anthropic Claude Fable 5.1 at `medium`, then Copilot Fable 5.1 and Codex/Copilot/OpenAI Astra at `medium`; its OpenRouter fallbacks also put Fable 5.1 before Astra.
- Goal and Ralph orchestration, Ralph research, and design now use Fable 5.1/Fable 5 fallbacks at `medium` and Sol at `high`. Goal reviewers and Ralph reviewers use Astra/Sol at `high`, preserving their role-specific fallback order. Ralph prompt refinement remains unchanged.

## [0.9.19-alpha.4] - 2026-09-10

### Breaking Changes

- Workflow run control uses `pause` across slash commands, tool actions, runtime APIs, and lifecycle control events. Run-level pause preserves resumable work, including nested task-result checkpoint tails and executor-only waits; targeted stage pause retains queued messages, and targeted `ctx.tool` pause cancels only that call. Use `resume` to continue eligible work.

### Added

- Added effective model and thinking identity to graph node cards, preserving thinking and canonical fast model suffixes in narrow rows and restoring identity through durable resume. Live fallback replacements update the model row; the `BACKGROUND` widget is unchanged ([#1859](https://github.com/bastani-inc/atomic/pull/1859) by [@sina85](https://github.com/sina85)).

### Fixed

- Reduced durable `/workflow resume` latency for checkpoint-heavy workflows, especially on Windows, by reusing loaded checkpoint envelopes while preserving original checkpoint decoding errors and completed-output values.
- Embedded Postgres startup now reports an early process exit with its actual log output instead of waiting out the full readiness timeout. When the retained postmaster exits before accepting connections (a corrupt cluster, a refused setting, or PostgreSQL's administrator refusal on an unrestricted Windows launch), the startup error includes the log tail from the exact retained process; attached servers, shutdown retry semantics, and non-Postgres platforms are unchanged.
- Embedded Postgres startup no longer treats a competing listener as ready after the owned server exits, and reports process-status query failures without replacing them with a generic timeout.

### Changed

- Incoming Intercom `send` and `ask` messages to a live workflow stage now cancel the stage's current model call or cancellable tool and are processed immediately within the same stage generation, instead of waiting for the next natural model turn. Admitted input survives consumed preflight and overlapping SDK interrupt turns, and persistence retries retain their FIFO position. The stage task is not restarted, completed tool results are kept, and the exact-child foreground detach handshake still runs before cancellation so a child asking its parent stage is not cancelled by its own message.

## [0.9.19-alpha.3] - 2026-09-09

### Fixed

- Local `workflow stages` now uses the same expanded nested graph as exact stage/transcript lookup, matching retained durable inspection instead of listing hidden import boundaries.
- Runner-created workflow sessions retain their pending-delivery context while receiving the host late-message route, so completed-stage Intercom asks can reopen the exact retained conversation without re-running the workflow.
- Stage pause now cancels owned active and admitted queued agents and commands before acknowledging completion, including shells admitted during already-in-flight setup. It waits for cleanup without permanently closing message admission; resume releases queued user and Intercom messages and permits fresh work, without reviving cancelled executions or affecting sibling stages.
- Fixed the `BACKGROUND` workflow list's stage count and `single`/`chain` label to include recursively nested stages as they appear, without double-counting expanded workflow boundaries. Completed, failed, and skipped stages retain their existing progress semantics. Recursive counts share run lookup preparation across cards within each refresh.

### Changed

- Reduced default workflow stage and authored parallel concurrency from 4 to 3, preserving explicit configuration and per-call overrides.

## [0.9.19-alpha.2] - 2026-09-08

### Added

- Connected workflow activity to the host extension observer stream, independently of lifecycle-notification settings and attribution filters. Root activity is projected from workflow snapshots plus run-qualified runtime execution ownership: nested runs fold into full root replacements; independent execution is distinguished from human waits; runnable handoffs, retries, stop draining, pauses, and acknowledged failures are accounted for without treating historical running stages as execution. Tool-only execution, parallel human-input waits, pause, cancellation drain, and unresolved failures publish root activity replacements; late attachment receives current state, and durable hydration announces recovering before ready. Typed lifecycle hooks cover run, stage, tool, prompt, and control transitions with canonical nested identities; successful-stage completion hooks exclude failed/skipped outcomes, explicit execution replay is tagged, and restored history creates no synthetic completions. Heartbeat hooks follow the existing configured cadence without adding timers or graph nodes. Because the workflows extension publishes root activity to the host, Atomic's built-in Herdr reporter reflects workflow execution and human-input waits in the owning pane; the end-to-end path is covered by an integration test against a fake Herdr CLI ([#2891](https://github.com/bastani-inc/atomic/issues/2891)).
- Attached stage chats now suggest stage-local `/skill:` commands with source metadata, qualified selectors, and refreshed catalogs after resource reload. Idle, steering, and follow-up submissions reuse session expansion once, retain stage admission and HIL ownership, and show skill diagnostics locally. Explicit editable post-mortem chats can invoke skills without reopening workflow execution.
- `StageSendUserMessageOptions.expandPromptTemplates` opts native stage-session delivery into existing command and skill/template expansion; ordinary programmatic messages remain literal by default.
- Attached stage chats render a bound owner task store through the shared chat host, keeping task activity separate from pending launch-tool replay and retaining the compact task footer after the launch row scrolls away. This requires the stage producer to bind its owner store ([#2884](https://github.com/bastani-inc/atomic/pull/2884)).

### Changed

- Goal and Ralph orchestration, Ralph research, and Open Claude Design now use GPT-6 Astra at medium. Prompt refinement stays at high, and OpenRouter Grok fallbacks explicitly use xhigh.
- `/tasks` in an attached stage chat opens the shared owner-bound inspector without entering model context, including during interrupt settlement. Task focus exits before the ordinary stage Escape action, and mounted human-input prompts retain input priority ([#2884](https://github.com/bastani-inc/atomic/pull/2884)).
- Stage chat now shows compact background-agent and shell counts below the composer instead of persistent task rows. Shared `/tasks` views retain background results, and completion notifications use shaded cards with readable outcomes and previews in the owning stage chat.
- Workflow guidance now uses project CI/test timing history for critical-path scheduling and launch estimates, avoids redundant full-suite runs while preserving required gates, and compares estimated with actual elapsed time. Agent-authored user questions use `ask_user_question` or an equivalent tool when available; sessions without one continue autonomously using best judgment.
- Workflow guidance treats requests to work "quickly" as task-scoped inline execution. Duration estimates appear before launch without confidence labels. Launches inherit configured limits without a routine budget-choice question; explicit user limits and approval before raising an exhausted budget remain enforced.

### Fixed

- Paused stage skill submissions retain Enter versus Ctrl+F delivery intent. Custom stage hosts without admission-aware user-message delivery now report invocation as unavailable rather than using an unguarded fallback.
- Skill autocomplete reuses the attached stage session without writing durable checkpoints per keystroke. Concurrent lazy discovery requests share one attachment.
- Same-name prompt/tool nodes no longer cause valid duplicate agent matches to be refused as non-agents. Live `ask` retains ambiguity diagnostics and name-based `send` retains sticky agent delivery ([#2895](https://github.com/bastani-inc/atomic/pull/2895)).
- Keep a bound task footer visible beside mounted stage questions within the existing viewport budget, and apply the host's expansion setting consistently to task rows.
- Restored `/tasks` to stage slash suggestions and removed filled backgrounds from skill suggestions, including selected rows. Task status now follows MCP, retaining active counts and `/tasks` without collision with the graph-return shortcut on narrow terminals.
- Stage pause keeps owned background agents and shells running. Closing the stage generation cancels that owner's remaining work without stopping sibling stages.
- Preserve an ordinary stage's complete output artifact when a follow-up clarification arrives before completion. Completed answers from the same prompt generation remain ordered supplements, including executor continuations and close-time delivery, without copying earlier history or tool progress. Accepted answers survive context compaction and model fallback during a continuation; failed attempts cannot discard an earlier successful report. Tree navigation cannot import historical answers, and generation close stops capture of later retained-session chat. Completed artifact receipts stay stable under repeated finalization; structured output keeps its existing capture contract.
- Discard provisional artifact answers from each failed same-model retry, preserving earlier accepted reports and only publishing the successful retry's answers.
- Prevent workflow activity from briefly reporting idle between settled nodes and live author continuation. Historical, paused, blocked, and stopping runs do not gain continuation ownership ([#2891](https://github.com/bastani-inc/atomic/issues/2891)).
- Preserved workflow lifecycle `kill` events for already-aborted caller signals and report task-result checkpoint interrupts as `interrupt`, without changing their graceful paused outcome ([#2912](https://github.com/bastani-inc/atomic/pull/2912)).
- Durable tool callbacks now wait for agent tasks they admit to reach terminal results before checkpointing. Yielded observations are replaced with terminal observations without changing the cancellation-before-persistence or commit-wins fences ([#2884](https://github.com/bastani-inc/atomic/pull/2884)).
- Workflow graph canvas and node interiors now use the terminal's background like main and stage chat, instead of painting a fixed dark palette. Themed chrome and focused title tabs remain unchanged.
- Graph chrome and `/workflow connect` picker rows retain solid background fill across truncated names, filters, and hints. Truncated stage and child-workflow labels keep their focused tab's background, text color, and weight through the ellipsis. Skill, command, and file autocomplete retain terminal-default backgrounds, including selected rows.
- Classified the workflow graph and run picker as navigation so `/workflow connect` no longer creates a false Herdr approval wait. Actual workflow input waits remain reported.
- Workflow-stage `/tasks` now retains the shared compact picker and the stage's model, reasoning, cwd/branch, and MCP footer. Detail pages stay fullscreen. Task navigation no longer triggers the main-chat input notice, and pending-prompt notices clear when the graph hides, closes, or changes host.
- Resume ended recoverable blocks through the existing continuation path rather than returning an unchanged snapshot as success. Non-resumable targets and unchanged blocked snapshots report no progress.
- Settled failed or blocked runs retain attention without reporting an active user-decision wait to Herdr. Pending prompts and exhausted budgets remain blocked.
- Stopped the workflow graph projection from retaining and deep-freezing a completed stage's structured result, and gave input defaulting a resolver-owned copy, so a stage's structured output can still be handed to a typed child workflow ([#2936](https://github.com/bastani-inc/atomic/issues/2936)).

## [0.9.19-alpha.1] - 2026-09-06

### Fixed

- Interrupting a workflow tool call during initialization now cancels its startup owner instead of leaving an empty, uncontrollable running root. Resume preparation respects cancellation, and already-aborted requests cannot begin actions. Accepted request timeouts and acknowledged background execution retain their existing behavior.
- Whole-run pause/interrupt during initialization or between-node awaits now retain the same live executor for explicit resume instead of becoming quit. Later tracked work, cached replay, and completion wait for resume; untracked JavaScript or I/O may still finish. Executor-only quit retires the owner, and zero-progress quits remain nonresumable. Cross-process resume still requires durable progress.
- Executor-only whole-run pause now holds already-live nested child owners as well, preventing their next tracked step or completion until resume. Descendants remain held while the root's durable resume is acknowledged; child-scoped controls preserve sibling isolation.
- Preserved the original selected tool failure when cancellation arrives later, restored closed-admission errors for retained tool calls, and drained cancelled child boundaries before the parent returns. Durable resume replaces abandoned detached executors without replacing surviving live paused owners.
- Fixed embedded PostgreSQL discovery in Bun-compiled installations and ordinary native npm leaves, including nested installs, while retaining explicit database/runtime overrides and legacy package fallback.

## [0.9.18] - 2026-09-05

Cumulative release of the `0.9.18-alpha.3` through `0.9.18-alpha.7` prereleases. Per-change details remain in the unchanged prerelease sections below.

### Breaking Changes

- Workflow-stage Intercom targets require root-anchored `workflow:<rootRunId>/<segment>[/<segment>...]` paths. Legacy `<runId>:<stageKey>` targets fail with a migration hint.
- Removed `fastMode` from task results, stage snapshots, fallback metadata, and durable records. Pin canonical `-fast` model IDs explicitly; normal and fast IDs remain separate ordered fallback candidates.

### Added

- Added checksum-pinned embedded PostgreSQL on Linux musl x64/ARM64 and Windows ARM64, retaining explicit database URL precedence, Docker fallback, privilege dropping, and process-owned shutdown. Windows ARM64 uses PostgreSQL x64 through Windows 11 emulation.
- Launch persists possible literal, patterned, and nested-child stage paths. Sticky sends reach future matches, root broadcasts reach live and future descendants until termination, and `intercom list` shows possible targets and queued counts. Valid unknown paths queue with warnings and settle as undeliverable only if never matched.
- Status, list/detail views, and the `BACKGROUND` panel identify materialized pending stages, expose exact targets only when delivery is available, and distinguish unavailable delivery explicitly.

### Changed

- Heartbeat and stage guidance use one authoritative path broadcast for shared scope changes, teach discovery/globs/live-only asks, and distinguish orchestration from cross-cutting extension policy with explicit companion dependencies.
- Goal/Ralph orchestration, Ralph prompt engineering/research, and Open Claude Design use Astra at high. Goal reviewers and Ralph reviewer B use Astra at xhigh; reviewer A uses Fable 5.1 at high. Added both model families to role-specific fallback chains and updated Ralph research/reviewer ordering.
- Guidance honors task-scoped inline requests, reconciles active runs without duplicate execution, chooses verification by browser/terminal/desktop environment, supports offline qlty setup, and requires verified hosted links for authorized GitHub media uploads. Model-pinning advice consults measured task-specific evals alongside role guidance.
- Expanded the prompt-engineering skill with sourced Astra prompting/API migration guidance and separate GPT-5.6, GPT-5.5, Fable 5.1, Fable 5, Opus 5, Opus 4.8, and Sonnet 5 guides. Shared instructions cover selective references, proportionate verification, permission boundaries, and completion criteria.
- Stage chat uses the same jump-to-latest copy and shortcut as fullscreen chat.

### Fixed

- Fixed invocation-owned stage groups, collision-free identities, durable-resume identity preservation, and isolated Goal/Ralph reviewers. Pending target/ID displays wrap without truncating usable addresses; ended runs no longer advertise delivery, and narrow widgets preserve tool/elapsed metadata with accurate overflow counts ([#2784](https://github.com/bastani-inc/atomic/issues/2784)).
- Tool-only workflows no longer produce `ZERO_STAGES` warnings or advertise tool nodes as chat-stage targets.
- Structured-output exhaustion now advances the model fallback chain. Each candidate gets the prompt plus three corrective follow-ups; failed attempts remain recorded and successful model metadata persists immediately ([#2812](https://github.com/bastani-inc/atomic/issues/2812)).
- Exhausted queued Intercom delivery fails its stage deterministically without model retries or fallback. The first failure settles readiness once, preserves queued steering, disposes the refused session, and handles pre-latched failures and late drains safely.
- Durability degradation uses display-only warnings in interactive/RPC sessions and actionable console diagnostics in headless mode. Pending-message sweeps skip unrelated runs, deduplicate interactive warnings, and preserve messages for recovery.
- In-flight resume, catalog preparation, and completed-run opening retain the backend selected during initialization rather than failing after concurrent mutable-state changes.
- Targeted durable-tool aborts retain exact unfinished-tool identity and an inspection-only cancellation frontier. Resume, DBOS hydration, and session restoration replay completed work and retry that tool without fabricating model stages. Invalid or ambiguous checkpoint state fails before callbacks; older state requires typed checkpoint proof, not transcript inference.
- Graph parent replacement rejects self-edges and cycles before mutation. Tool-frontier continuations reject completion that skips the unfinished tool and reject replacement model/task or child-workflow work before side effects, including worktree setup. Recovery evidence and completed callbacks remain intact.

## [0.9.18-alpha.7] - 2026-09-05

### Fixed

- Pending-stage Intercom settlement now skips unrelated runs with no messages to settle. Genuine sweep failures produce one display-only warning per distinct message in interactive sessions instead of repeated console stack traces; headless sessions retain console diagnostics, and pending messages remain available for recovery.

### Changed

- Updated the bundled prompt-engineering skill with GPT-6 Astra prompting and API migration guidance, plus an attributed instruction audit covering concise skill descriptions, selective reference loading, proportionate testing, permission boundaries, and completion criteria.
- Split prompt-engineering model advice into individually sourced guides for GPT-5.6, GPT-5.5, Claude Fable 5.1, Fable 5, Opus 5, Opus 4.8, and Sonnet 5, alongside Astra. Shared guidance now routes to each model's distinct effort, verification, delegation, and API migration rules.

## [0.9.18-alpha.6] - 2026-09-04

### Breaking Changes

- Workflow-stage Intercom targets now accept only root-anchored `workflow:<rootRunId>/<segment>[/<segment>...]` paths. The legacy `<runId>:<stageKey>` form is refused with a canonical-path migration hint.
- Removed the `fastMode` field from `WorkflowTaskResult`, stage snapshots, fallback metadata, and durable checkpoint/envelope records. Workflow stages now select fast inference explicitly by pinning a canonical `-fast` model ID in `model` or `fallbackModels`; normal and fast IDs remain separate ordered candidates.

### Added

- Durable workflows now resolve checksum-pinned embedded PostgreSQL runtimes on Linux musl x64/ARM64 and Windows ARM64 while preserving explicit database URL precedence, Docker fallback, root privilege dropping, and retained-process shutdown ownership. Windows ARM64 uses the PostgreSQL x64 runtime through Windows 11 x64 emulation.
- Workflow launch now scans and persists possible literal, patterned, and nested-child stage paths. Sticky name and glob sends deliver to every future matching stage, while `workflow:<rootRunId>/**` broadcasts to live stages and remains queued for future descendants until root termination.
- Possible future targets and their queued counts now appear in `intercom list`. Valid paths outside the scanned set are accepted with a `notInKnownSet` warning and settle as undeliverable at terminal only when they never matched.

### Changed

- Heartbeat, workflow-tool, and builtin stage guidance now directs shared scope and acceptance-criteria amendments through one authoritative path broadcast rather than enumerating known stages, and teaches path discovery, globs, sticky delivery, and live-only asks.
- The stage-chat jump indicator now uses the same `↓ Jump to latest message · <shortcut>` copy as the fullscreen transcript overlay.
- Updated Goal/Ralph orchestration, Ralph prompt engineering and research, and Open Claude Design to GPT-6 Astra at `high`; Goal reviewers and Ralph reviewer B use Astra at `xhigh`, while Ralph reviewer A uses Claude Fable 5.1 at `high`. Added Astra and Fable 5.1 fallbacks while retaining role-specific provider order and reasoning levels. Ralph research now places Fable 5 before Sol, and reviewer B places Sol after Fable 5 and Fugu before GPT-5.5 in its OpenRouter group.

- Workflow guidance honors explicit task-scoped inline/no-workflow requests, including safe handoff from active runs without duplicate execution. Default authoring and Goal/Ralph prompts select browser, terminal or desktop/simulator verification by environment, support offline/manual qlty setup, and describe authorized native GitHub media attachments with verified hosted links.
- Model-pinning guidance now points authored workflows at the measured per-evaluation scores in `packages/coding-agent/docs/models/evals.md` (formerly `artificial-analysis-index.md`), whose task-type picker maps each stage type to the eval that measures it, alongside the role guidance in `model-selection.md`.

### Fixed

- Tool-only workflows no longer emit a `ZERO_STAGES` discovery warning. The static scan now recognizes `ctx.tool()` as tracked graph work without advertising tool nodes as future chat-stage targets.
- A schema-backed stage that exhausts its structured-output correction budget now advances the model fallback chain instead of failing the whole stage on its first candidate. Each candidate gets the stage prompt plus three corrective follow-ups; a candidate that never produces a valid `structured_output` call fails over exactly like a rate-limited one, recording its attempts as failures with an error naming what the turn looked like (no assistant message, empty assistant text, or the validation error), emitting a `[fallback]` warning, and re-sending the original stage prompt to the next candidate with a fresh budget. With no candidate left the stage still fails with the existing contract error. A model attempt that succeeds is now recorded in the running stage's durable metadata at the moment it succeeds rather than only when the stage ends, so mid-run status and a run resumed after an interruption both report the model that actually produced the result instead of showing only the attempts that failed. ([#2812](https://github.com/bastani-inc/atomic/issues/2812))
- A stage whose queued Intercom messages can no longer be delivered now fails instead of running forever. `stage-runner-controller` awaits `pendingStageDelivery.ready()` with no timeout, and only a successful drain ever settled it — so when Intercom exhausted its bounded warm-up retries the stage stayed `running` with nothing owning recovery. `createWorkflowPendingStageDelivery` now implements the delivery contract's `fail(reason)`: the first reason wins, `ready()` settles exactly once with a `WorkflowPendingStageDeliveryFailedError` (`code: "pending_stage_delivery_failed"`) carrying the run id, stage id, and stage name, and the stage reaches a deterministic non-retryable `failed` outcome whose error names it. That outcome is now non-retryable by construction rather than by wording: the stage lifecycle refuses a terminal delivery failure as a model failure at both decision sites, so no same-model retry is spent, no fallback candidate is walked, and no `[fallback]` warning blames a model for a stage that would have been refused the same instructions by every candidate. The delivery owner's reason is kept on the error's `reason` property instead of as `cause`, because the shared classifier walks `cause` and Intercom's reason nests the transport error that lost the broker — which made a dead delivery read as a retryable `network_timeout`. A terminal failure latched before the controller's first `ready()` is honored, an unobserved rejection does not surface as an unhandled rejection, a stage with nothing queued still short-circuits and runs, and a drain requested after the latch is a no-op so queued steering stays queued rather than being marked delivered. The session attached just before the gate is disposed and detached on that failure, so a later `ensureSession()` cannot hand back a stage session that skipped its queued instructions.
- Workflow durability degradation now appears as a display-only warning notification for interactive and RPC actions instead of being written to the console; print and headless actions still receive an actionable console diagnostic when no usable UI exists.
- In-flight durable resume, catalog preparation, and completed-workflow opening now keep using the backend selected by initialization instead of re-reading mutable factory state after an asynchronous boundary, preventing a concurrent backend reset from stranding the operation with a not-ready error while preserving distinct malformed, stale, and missing-target diagnostics.

- Uncaught targeted `ctx.tool` aborts now retain the failed tool identity and an inspection-only cancellation frontier. Public resume, including fresh DBOS hydration and session lifecycle restoration, replays completed work and retries the unfinished tool without fabricating a model stage.
- Tool-frontier resume rejects missing, ambiguous, cyclic, or identity-inconsistent state before replaying unfinished callbacks. Older records recover only when typed persisted checkpoints prove a unique safe frontier, including for multiline tool names; transcript text is not converted into checkpoints.
- Incremental graph parent replacement now rejects self-edges and back-edges before mutating the workflow DAG.
- Tool-frontier continuations reject normal returns and explicit completed exits that skip the exact unfinished tool, and reject replacement model/task and child-workflow execution before side effects. Stage/task worktree setup follows replay selection and live admission. The failure names the pending frontier, preserves source recovery evidence, and does not repeat completed callbacks.

## [0.9.18-alpha.3] - 2026-09-01

### Added

- Workflow status text, interactive list/detail views, and the persistent `BACKGROUND` panel now identify materialized pending stages by display name and canonical stage ID, show exact Intercom targets only when pre-start delivery is available, and distinguish unavailable pending delivery truthfully.

### Changed

- Workflow-authoring guidance now distinguishes inspectable workflow orchestration from cross-cutting extension-hook policy, requires companion-extension dependencies to remain explicit, and directs generated workflows toward readable top-level graphs with cohesive source boundaries.

### Fixed

- Fixed pending-stage targets in `/workflow status` cards and the persistent `BACKGROUND` panel being truncated into unusable addresses. Status cards now wrap exact targets, while widget metadata uses only bounded pending-stage forms that fit without displacing existing metadata and width-based omissions show an explicit remaining-stage count. ([#2784](https://github.com/bastani-inc/atomic/issues/2784))
- Fixed `/workflow status` losing pending-stage delivery capability in its bounded graph projection, run detail ellipsizing exact pending targets at narrow widths, terminal runs advertising undeliverable targets, and narrow status cards truncating canonical stage IDs. Exact targets and IDs now wrap where appropriate, while ended runs report pending delivery as unavailable. ([#2784](https://github.com/bastani-inc/atomic/issues/2784))
- Fixed projected pending stages from terminal nested child runs advertising unusable Intercom targets through their still-live root, pending widget labels exceeding their width budget and evicting tool/elapsed metadata, duplicated Intercom coaching in model-facing status hints, and singular overflow counts using a plural noun. ([#2784](https://github.com/bastani-inc/atomic/issues/2784))

- Fixed explicit and automatic stage groups so they become invocation-owned, collision-free subgroups that remain controllable from the workflow invocation while preserving sibling isolation and their exact persisted identity across active durable resume; restored symmetric isolated reviewer groups for Goal and Ralph ([#2784](https://github.com/bastani-inc/atomic/issues/2784)).

## [0.9.16] - 2026-08-29

Cumulative release of the `0.9.16-alpha.1` – `0.9.16-alpha.11` prereleases. The summary below covers the user-visible outcome of that work; the per-change detail remains in the prerelease sections below.

### Added

- Added a dedicated `workflow answer` action for responding to pending primitive and structured human-in-the-loop prompts without exposing stage-message delivery semantics.
- Added durable pending-stage message state for ordinary Intercom delivery, including FIFO delivery before the first model turn, resume/replay persistence, exactly-once stage-attempt handling, lifecycle failure notifications, and guidance for propagating material updates to known workflow stages that have not started. ([#2717](https://github.com/bastani-inc/atomic/issues/2717))
- Added Lauren Tan's bundled `bro`, `how`, `teach`, `unslop`, and `why` pstack skills for plain-language restatement, codebase explanation, teaching, writing cleanup, and evidence-backed design rationale. Sourced from https://github.com/cursor/plugins and distributed under the MIT License.

### Changed

- Every workflow model stage now retains ordinary `intercom` and its invocation group through `tools`, `excludedTools`, `noTools`, extension restrictions, and reload. Restrictions on every other tool and workflow group isolation are unchanged.
- Added the full and Flash GLM-5.3 direct Z.AI, Z.AI Coding Plan, Baseten, and OpenRouter routes to every built-in Goal, Ralph, and Open Claude Design fallback chain.
- Periodic workflow heartbeat prompts now guide supervising agents to use ordinary Intercom when steering or communication is useful, match an update's reach to the expanded workflow topology, send shared scope or acceptance changes consistently across every relevant live and known unstarted worker/reviewer stage, account for immediate and queued pre-first-turn delivery, and use workflow pause, resume, interrupt, or quit for run control.
- Builtin `goal` and `ralph` stage prompts now carry a shared `code_quality_verification` section pointing stages at the `qlty` skill (or `skill: "qlty"` delegation) for linting, auto-formatting, complexity and duplication metrics, and code smells — weighted higher when the objective asks for verifiers or high code quality. It reaches the goal controller, goal orchestrator, goal reviewer, ralph orchestrator, and both ralph reviewers, alongside the existing end-to-end verification guidance. Repository-defined checks in AGENTS.md/CLAUDE.md, package scripts, and CI remain authoritative.
- Builtin `goal` and `ralph` stage prompts now carry a shared `repository_intent` section instructing implementers and reviewers to infer maintainer and requesting-user conventions by mining repository behavior — git history (including `git log --show-signature`), merged PRs, issues and their comments, review comments, commit subjects and trailers, and CI/branch-protection config — for unwritten norms. Behavioral evidence fills contract gaps and never overrides the literal objective, acceptance criteria, or explicit AGENTS.md/CLAUDE.md guidance.
- The `workflow` tool's routing guidance adds a repository-intent clause to the pre-launch architecture pass: for coding tasks, mine git history, merged PRs, issues, commits, and review comments before freezing authored workflow objectives and acceptance criteria so they capture unwritten conventions, weighing the requesting user's own activity highest; non-coding tasks mine their analogous available context sources the same way.
- The `workflow` tool description, agent routing guidance, and workflow docs now treat a blocked run as continuable by default: resume resumable blocks, answer pending prompts, steer past the obstacle, or start a follow-up workflow past a terminal block (inline only when the remaining work is minimal), stopping for user input only when the task is so ambiguous that judgment cannot infer intent from the objective and repository evidence. When `ask_user_question` or human input is unavailable, the agent is instructed to continue fully autonomously on the interpretation best supported by that evidence and to record the assumption.
- `WORKFLOW BLOCKED` lifecycle notices now carry that continuation instruction in their text: resume or steer the run, or continue with a follow-up workflow (inline only if what remains is minimal), and ask the user only when intent cannot be inferred from repository evidence.
- A budget-exceeded stop is now reported as its own blocked-notice variant (`stopped at its <dimension> budget limit`, with `budgetExceeded`/`budgetDimension` details and a `/workflow resume` hint) whose text instructs the agent to summarize progress and estimated next steps, ask the user whether to proceed — preferring the `ask_user_question` tool when available — and resume with a raised `budget` only after approval.
- The public `workflow` tool now has a two-minute request deadline. Timed-out requests return `WORKFLOW_TIMEOUT` with `timeoutMs: 120000`, abort cancellable work, discard late settlement, and never retry. Mutating actions keep the unknown-outcome warning that tells callers to inspect workflow status before retrying ([#2654](https://github.com/bastani-inc/atomic/issues/2654), [#2605](https://github.com/bastani-inc/atomic/issues/2605)).
- Agent guidance now treats "no budget" as the default for workflow runs. A `budget` is passed on `run`/`resume` only when the operator asked for a limit, and only the fields they named; otherwise the field is omitted so the workflow declaration and config resolve normally.
- Agent guidance now assumes the existing 15-minute heartbeat cadence and does not shorten, lengthen, or disable it unless the operator asks. Heartbeats are documented as periodic alignment checks rather than failure signals, so a progressing run is not interrupted, re-capped, or polled in response to one.

### Fixed

- Fixed Git-installed workflow discovery when production-only package installs omit local TypeBox by resolving `typebox/compile`, `typebox/value`, and supported legacy `@sinclair/typebox` aliases through the host loader for workflow files and their helpers.
- Fixed a hung DBOS write in one workflow blocking independent top-level workflows before startup admission. Durable writes now remain ordered per root workflow while workflow-local flushes wait only their own root; process shutdown still drains every root.
- Workflow heartbeat and routing guidance now tells agents to discover a stage's `workflow:<rootRunId>` invocation group with the Intercom `groups` action and join it before steering the stage.
- An in-flight workflow run no longer fails after a preserving `/reload` when the predecessor persistence port becomes stale. Advisory `workflow.stage.end` and `workflow.run.end` transcript appends swallow exactly `isStaleExtensionContextError` and rethrow every other error. ([#2749](https://github.com/bastani-inc/atomic/issues/2749))
- Fixed running durable `ctx.tool` message blocks showing a trailing `●` after the tool call header; running and completed calls now use the same marker-free `$ <tool-name>` presentation while other tool-state markers remain unchanged.
- Fixed a completed `ctx.task` leaving the root raw `running` with no active stage or tool and no path to the next budget boundary. The durable task-result checkpoint now fails closed, duration is rechecked after that checkpoint, quit/interrupt can abort a never-settling persist, and a terminal-only stage checkpoint replays the complete `WorkflowTaskResult` without rerunning the task ([#2650](https://github.com/bastani-inc/atomic/issues/2650)).
- Fixed raised-budget resume of a blocked workflow when parallel stages shared a completed `ctx.tool` parent. Fresh-ID continuations translate tool parent identities during fail-closed topology validation, preserve cached root-level tool siblings without a false mismatch, and keep a blocked source retryable after a rejection without dropping recorded prompt answers ([#2639](https://github.com/bastani-inc/atomic/issues/2639)).
- Fresh-ID continuations reuse the source `ctx.tool` checkpoint, including `failureMode: "return"` success and `return_failure` outcomes. To re-run a completed return-mode callback, start a new run or change the tool name or args ([#2639](https://github.com/bastani-inc/atomic/issues/2639)).
- Fixed ordinary in-process subagents stealing the parent session's workflow store binding. Subagent children retain bundled workflow definitions as resources without loading the workflows extension or exposing its tool, and the extension factory rejects admitted child sessions as a second boundary.
- Fixed simultaneous post-task budget exhaustion in `ctx.parallel(..., { failFast: false })` being replaced by a generic aggregate failure after every task had already persisted a complete result. Budget-only parallel failures now retain the engine-owned resumable `budget_exceeded` classification and replay all completed task results under a raised budget without rerunning their models.
- Fixed workflow name resolution racing past an in-flight `/workflow reload`: a run dispatched immediately after a reload could resolve against the pre-reload registry and execute the old module. Resolution now awaits any in-flight discovery before resolving names. ([#2667](https://github.com/bastani-inc/atomic/pull/2667) by [@uppifyagency](https://github.com/uppifyagency))
- Fixed Goal losing its ledger, orchestrator receipt, and review artifacts when a durable resume continued under a fresh run ID. Goal now checkpoints the complete artifact directory, reloads exact turn-bearing ledger state from a durable sidecar without truncating records or fabricating reducer turns, and scopes artifact ownership to the run's own identity plus its continuation chain.
- Fixed a missing Goal reviewer `reads` artifact being reported as malformed structured reviewer output. Missing referenced files now remain explicit reviewer execution failures attributed to the `reads` contract.
- Fixed Windows embedded Postgres startup waiting forever when the daemon inherited `pg_ctl` pipes by directly spawning Postgres behind an opaque native process lease. Orderly shutdown now sends fast shutdown and bounded-waits on that exact retained child/HANDLE, preventing mutable-pidfile and PID-reuse races while leaving attached clusters untouched ([#2547](https://github.com/bastani-inc/atomic/issues/2547), [#2544](https://github.com/bastani-inc/atomic/pull/2544) by [@darionco](https://github.com/darionco)).
- Fixed active zero-stage workflows whose only work is durable `ctx.tool` calls being under-represented in the below-editor `BACKGROUND` panel. Normal-width cards now show a single pending or running tool node by name and status; when multiple nodes are live, their total appears before the width-clamped node details.
- Fixed a never-settling public workflow tool request blocking the interactive agent indefinitely ([#2605](https://github.com/bastani-inc/atomic/issues/2605)).

### Removed

- Removed the public `workflow send` action and its stage-chat delivery modes. Use `workflow answer` for pending human-input prompts, `workflow resume` for paused control, and ordinary Intercom for live or deferred workflow-stage communication.

## [0.9.16-alpha.11] - 2026-08-28

### Changed

- Every workflow model stage now retains ordinary `intercom` and its invocation group through `tools`, `excludedTools`, `noTools`, extension restrictions, and reload. Restrictions on every other tool and workflow group isolation are unchanged.

### Fixed

- Fixed Git-installed workflow discovery when production-only package installs omit local TypeBox by resolving `typebox/compile`, `typebox/value`, and supported legacy `@sinclair/typebox` aliases through the host loader for workflow files and their helpers.
- Fixed a hung DBOS write in one workflow blocking independent top-level workflows before startup admission. Durable writes now remain ordered per root workflow while workflow-local flushes wait only their own root; process shutdown still drains every root.

## [0.9.16-alpha.10] - 2026-08-28

### Changed

- Added the full and Flash GLM-5.3 direct Z.AI, Z.AI Coding Plan, Baseten, and OpenRouter routes to every built-in Goal, Ralph, and Open Claude Design fallback chain.

### Fixed

- Workflow heartbeat and routing guidance now tells agents to discover a stage's `workflow:<rootRunId>` invocation group with the Intercom `groups` action and join it before steering the stage.
- An in-flight workflow run no longer fails after a preserving `/reload` when the predecessor persistence port becomes stale. Advisory `workflow.stage.end` and `workflow.run.end` transcript appends swallow exactly `isStaleExtensionContextError` and rethrow every other error. ([#2749](https://github.com/bastani-inc/atomic/issues/2749))

## [0.9.16-alpha.8] - 2026-08-27

### Added

- Added a dedicated `workflow answer` action for responding to pending primitive and structured human-in-the-loop prompts without exposing stage-message delivery semantics.
- Added durable pending-stage message state for ordinary Intercom delivery, including FIFO delivery before the first model turn, resume/replay persistence, exactly-once stage-attempt handling, lifecycle failure notifications, and guidance for propagating material updates to known workflow stages that have not started. ([#2717](https://github.com/bastani-inc/atomic/issues/2717))

### Changed

- Periodic workflow heartbeat prompts now guide supervising agents to use ordinary Intercom when steering or communication is useful, match an update's reach to the expanded workflow topology, send shared scope or acceptance changes consistently across every relevant live and known unstarted worker/reviewer stage, account for immediate and queued pre-first-turn delivery, and use workflow pause, resume, interrupt, or quit for run control.

### Removed

- Removed the public `workflow send` action and its stage-chat delivery modes. Use `workflow answer` for pending human-input prompts, `workflow resume` for paused control, and ordinary Intercom for live or deferred workflow-stage communication.

## [0.9.16-alpha.7] - 2026-08-26

### Changed

- Builtin `goal` and `ralph` stage prompts now carry a shared `code_quality_verification` section pointing stages at the `qlty` skill (or `skill: "qlty"` delegation) for linting, auto-formatting, complexity and duplication metrics, and code smells — weighted higher when the objective asks for verifiers or high code quality. It reaches the goal controller, goal orchestrator, goal reviewer, ralph orchestrator, and both ralph reviewers, alongside the existing end-to-end verification guidance. Repository-defined checks in AGENTS.md/CLAUDE.md, package scripts, and CI remain authoritative.
- Builtin `goal` and `ralph` stage prompts now carry a shared `repository_intent` section instructing implementers and reviewers to infer maintainer and requesting-user conventions by mining repository behavior — git history (including `git log --show-signature`), merged PRs, issues and their comments, review comments, commit subjects and trailers, and CI/branch-protection config — for unwritten norms such as commit signing, message style and issue linking, changelog discipline, PR size and review etiquette. The dominant, recent, intentional pattern wins over accidental drift, the requesting user's own activity weighs highest, implementers match inferred conventions in delivered work, and reviewers report deviations as evidence-backed convention findings. Behavioral evidence fills contract gaps and never overrides the literal objective, acceptance criteria, or explicit AGENTS.md/CLAUDE.md guidance. It reaches the same call sites as the code-quality guidance: goal controller, goal orchestrator, goal reviewer, ralph orchestrator, and both ralph reviewers.
- The `workflow` tool's routing guidance adds a repository-intent clause to the pre-launch architecture pass: for coding tasks, mine git history, merged PRs, issues, commits, and review comments before freezing authored workflow objectives and acceptance criteria so they capture unwritten conventions, weighing the requesting user's own activity highest; non-coding tasks mine their analogous available context sources (issue trackers, long-form docs, chat/comment threads, prior artifacts) the same way.

## [0.9.16-alpha.6] - 2026-08-26

### Changed

- The `workflow` tool description, agent routing guidance, and workflow docs now treat a blocked run as continuable by default: resume resumable blocks, answer pending prompts, steer past the obstacle, or start a follow-up workflow past a terminal block (inline only when the remaining work is minimal), stopping for user input only when the task is so ambiguous that judgment cannot infer intent from the objective and repository evidence — git history, commits, PRs, issues, and the user's own comments. When `ask_user_question` or human input is unavailable, the agent is instructed to continue fully autonomously on the interpretation best supported by that evidence and to record the assumption.
- `WORKFLOW BLOCKED` lifecycle notices now carry that continuation instruction in their text: resume or steer the run, or continue with a follow-up workflow (inline only if what remains is minimal), and ask the user only when intent cannot be inferred from repository evidence.
- A budget-exceeded stop is now reported as its own blocked-notice variant (`stopped at its <dimension> budget limit`, with `budgetExceeded`/`budgetDimension` details and a `/workflow resume` hint) whose text instructs the agent to summarize progress and estimated next steps, ask the user whether to proceed — preferring the `ask_user_question` tool when available — and resume with a raised `budget` only after approval. Matching guidance was added to the routing prompts and docs.

## [0.9.16-alpha.5] - 2026-08-26

### Changed

- Raised the public `workflow` tool request deadline from 30 seconds to two minutes. Timed-out requests still return `WORKFLOW_TIMEOUT` with `timeoutMs: 120000`, abort cancellable work, discard late settlement, and never retry. Mutating actions keep the unknown-outcome warning that tells callers to inspect workflow status before retrying ([#2654](https://github.com/bastani-inc/atomic/issues/2654)).
- Agent guidance now treats "no budget" as the default for workflow runs. A `budget` is passed on `run`/`resume` only when the operator asked for a limit, and only the fields they named; otherwise the field is omitted so the workflow declaration and config resolve normally.
- Agent guidance now assumes the existing 15-minute heartbeat cadence and does not shorten, lengthen, or disable it unless the operator asks. Heartbeats are documented as periodic alignment checks rather than failure signals, so a progressing run is not interrupted, re-capped, or polled in response to one.

### Fixed

- Fixed running durable `ctx.tool` message blocks showing a trailing `●` after the tool call header; running and completed calls now use the same marker-free `$ <tool-name>` presentation while other tool-state markers remain unchanged.
- Fixed a completed `ctx.task` leaving the root raw `running` with no active stage or tool and no path to the next budget boundary. The durable task-result checkpoint now fails closed, duration is rechecked after that checkpoint, quit/interrupt can abort a never-settling persist, a checkpoint created after its signal is already aborted settles without an unobserved rejection, an active task-checkpoint control — including one owned by an expanded child run — is not diagnosed as a stranded root, bulk interrupt forwards an injected tool-control registry, cancellation settles the DBOS write queue, and a terminal-only stage checkpoint replays the complete `WorkflowTaskResult` — the exact persisted text including schema-backed `maxOutput` truncation, structured output including `null`, generated worktree artifacts, warnings, session, and model metadata — without rerunning the task. A workflow that catches a task-tail quit rejection and returns outputs still stays paused. Exact-id quit or interrupt of a nested task tail now quits the aggregate root so the parent snapshot and durable handle do not stay raw `running`. Exact `/workflow status <id>` uses the live tool-control registry so a task tail is not reported as stranded. Same-process DBOS hydration rejects unknown checkpoint history instead of replaying around it ([#2650](https://github.com/bastani-inc/atomic/issues/2650)).
- Fixed raised-budget resume of a blocked workflow when parallel stages shared a completed `ctx.tool` parent. Fresh-ID continuations translate tool parent identities during fail-closed topology validation, preserve cached root-level tool siblings without a false mismatch, reject a replayed tool whose restored parents disagree with the continuation graph or cannot be translated, and keep a blocked source retryable after that rejection without dropping recorded prompt answers, pending-prompt descriptors, or its BLOCKED notice. The local source kill remains process-only until settlement: a mismatch leaves no terminal session entry so the durable blocked row stays reload-recoverable, while a successful continuation durably retires the superseded source so reload cannot resurrect it ([#2639](https://github.com/bastani-inc/atomic/issues/2639)).
- Fresh-ID continuations reuse the source `ctx.tool` checkpoint, including `failureMode: "return"` success and `return_failure` outcomes. A later hop reuses that result when the intermediate run republishes it; that write is best-effort. To re-run a completed return-mode callback, start a new run or change the tool name or args ([#2639](https://github.com/bastani-inc/atomic/issues/2639)).
- Fixed ordinary in-process subagents stealing the parent session's workflow store binding. Subagent children retain bundled workflow definitions as resources without loading the workflows extension or exposing its tool, and the extension factory rejects admitted child sessions as a second boundary. Full `/reload` also recovers a live store displaced by an older generation, including stage, job, cancellation, tool-control, and prompt owners, merges retained parent history, and remounts the `BACKGROUND` panel. New session scopes remain isolated.
- Fixed simultaneous post-task budget exhaustion in `ctx.parallel(..., { failFast: false })` being replaced by a generic aggregate failure after every task had already persisted a complete result. Budget-only parallel failures now retain the engine-owned resumable `budget_exceeded` classification, select the earliest authored exhausted task as the deterministic completed resume frontier, and replay all completed task results under a raised budget without rerunning their models; mixed ordinary failures retain the existing aggregate-failure behavior.
- Fixed workflow name resolution racing past an in-flight `/workflow reload`: a run dispatched immediately after a reload could resolve against the pre-reload registry and execute the old module (observed live as reload generation N applying only after the run had started). Resolution now awaits any in-flight discovery before resolving names; a reload that fails while a registry already exists still surfaces through the reload's own caller, and resolution proceeds on the retained registry instead of throwing. ([#2667](https://github.com/bastani-inc/atomic/pull/2667) by [@uppifyagency](https://github.com/uppifyagency))
- Fixed Goal losing its ledger, orchestrator receipt, and review artifacts when a durable resume continued under a fresh run ID. Goal now checkpoints the complete artifact directory, reloads exact turn-bearing ledger state from a durable sidecar without truncating records or fabricating reducer turns, keeps the model-visible ledger free of internal turn numbers, avoids duplicating replayed receipts and reviews, and scopes artifact ownership to the run's own identity plus its continuation chain. Fresh-ID continuation chains retain and report the original referenced owner correctly, and retention pruning protects that owner while any continuation remains live without allowing incidental quoted paths to pin failed runs forever.
- Fixed a missing Goal reviewer `reads` artifact being reported as malformed structured reviewer output. Missing referenced files now remain explicit reviewer execution failures attributed to the `reads` contract, while completed unstructured reviewer responses continue to use the existing parse-failure path.

## [0.9.16-alpha.2] - 2026-08-23

### Added

- Added Lauren Tan's bundled `bro`, `how`, `teach`, `unslop`, and `why` pstack skills for plain-language restatement, codebase explanation, teaching, writing cleanup, and evidence-backed design rationale. Sourced from https://github.com/cursor/plugins and distributed under the MIT License.

## [0.9.16-alpha.1] - 2026-08-23

### Fixed

- Fixed Windows embedded Postgres startup waiting forever when the daemon inherited `pg_ctl` pipes by directly spawning Postgres behind an opaque native process lease. Orderly shutdown now sends fast shutdown and bounded-waits on that exact retained child/HANDLE, preventing mutable-pidfile and PID-reuse races while leaving attached clusters untouched; failed or timed-out shutdown retains the lease for retry. Linux root runtime copies are now exact, root-owned, read/execute-only generations for the dropped Postgres account, with source and post-rename validation, atomically replaced monotonic setup heartbeats, final publication-lease checks, and bounded fail-closed corruption handling ([#2547](https://github.com/bastani-inc/atomic/issues/2547), [#2544](https://github.com/bastani-inc/atomic/pull/2544) by [@darionco](https://github.com/darionco)).

- Fixed active zero-stage workflows whose only work is durable `ctx.tool` calls being under-represented in the below-editor `BACKGROUND` panel. Normal-width cards now show a single pending or running tool node by name and status; when multiple nodes are live, their total appears before the width-clamped node details. The narrow collapsed form shows only the live-tool count, and no synthetic stage is created. The panel mounts for tool-only runs loaded after installation, keeps updating through workflow-resource reload, and remounts from the adopted run store after full `/reload`. Installed builds can evaluate the extension and host SDK as separate jiti module copies; their canonical session-bus map is now process-shared, preventing a replacement generation from adopting an empty store and dropping the live job, cancellation, and tool-control owners. Same-process extension reload preserves the live durable tool callback so its active node settles normally alongside cached completed siblings; a real process exit continues to require explicit durable resume for unfinished callbacks.

- Fixed a never-settling public workflow tool request blocking the interactive agent indefinitely. All 15 workflow actions now share one hard 30-second request deadline that aborts cancellable work, emits one structured timeout error, discards late settlement, and never retries. Timed-out mutations report an unknown outcome and direct callers to inspect workflow status before retrying; a timed-out run that already allocated detached execution returns its exact run id for that inspection, while background run/resume execution remains independent after its acknowledgement ([#2605](https://github.com/bastani-inc/atomic/issues/2605)).

## [0.9.15] - 2026-08-21

Cumulative release of the `0.9.15-alpha.1` prerelease. The summary below covers the user-visible outcome of that work; the per-change detail remains in the prerelease section below.

### Changed

- Workflow-stage orchestration context no longer carries a subagent delegation-depth constraint. A stage remains a top-level session and may still delegate once, while its subagent children cannot delegate further.

### Fixed

- Fixed `/workflow` dispatch, list, and status cards being held as steering messages while an agent streamed. Rendered cards now enter the transcript at once without starting a turn; lifecycle notices still nudge the model.
- Persistent workflow progress widgets now reattach after host UI resets or remote-engine release while keeping mount-once, in-place updates ([#2556](https://github.com/bastani-inc/atomic/issues/2556)).
- Fixed one stalled heartbeat send blocking all later workflow heartbeats in the session. In-flight sends now have a two-minute watchdog, release the run's pending slot on expiry, advance the shared FIFO queue, and guard against late double settlement while preserving retry behavior ([#2557](https://github.com/bastani-inc/atomic/issues/2557)).
- Fixed disposal of a confirmed-paused stage turning an acknowledged pause into a terminal failure. Disposal now waits while the run remains paused and resumable; abort and kill still fail visibly ([#2558](https://github.com/bastani-inc/atomic/issues/2558)).
- Fixed a workflow stage session leak when a confirmed-paused stage was cleared from the live registry, resumed through its stale handle, and completed. Deferred cleanup now drains once on terminal completion.

## [0.9.15-alpha.1] - 2026-08-21

### Changed

- Workflow-stage orchestration context no longer carries a subagent delegation-depth constraint. Stage delegation itself is unchanged: a stage is a top-level session and still launches subagents once. What changed is that the children it launches can no longer delegate further, and nothing configures that.

### Fixed

- Fixed `/workflow` cards being swallowed while the agent is streaming. The dispatch, list, and status cards were sent as ordinary turn-triggering messages, so a card emitted during a live model turn — for example right after a workflow lifecycle notice started one — was queued as steering and did not reach the transcript until that turn ended. Cards are already-rendered transcript surfaces and are now sent as non-turn messages, so they appear immediately whether or not a turn is in flight. Workflow lifecycle notices are unchanged and still nudge the model.
- Persistent workflow progress widgets now reattach after a host UI reset or remote-engine release while keeping the existing mount-once, update-in-place behavior ([#2556](https://github.com/bastani-inc/atomic/issues/2556)).
- Fixed one stuck heartbeat send silencing every workflow heartbeat for the rest of the session. All runs in a session share a single FIFO heartbeat-delivery queue, and its in-flight head had no deadline: a `sendMessage` promise that never settled held that head forever, so later runs queued behind it and never delivered a card, with no error and no degraded mode. Terminal cleanup could not rescue it either, because it deliberately spares a send already handed to the host. Each in-flight send now carries a bounded two-minute watchdog; on expiry the attempt is abandoned as an undelivered heartbeat, its run's pending slot is released so the run re-arms at its next future boundary, and the queue advances to the next run. Settlement is guarded by a per-attempt token, so a late resolution or rejection from an abandoned attempt cannot settle twice, restart retries, or disturb the current head. An emitter that rejects directly now settles as a failed delivery through the existing retry path instead of wedging the queue. The intended one-heartbeat-per-run rule before the deadline, the existing retry backoff and attempt budget, and the deadline-free hold on a card already admitted into the parent's queue are all unchanged ([#2557](https://github.com/bastani-inc/atomic/issues/2557)).
- Fixed a confirmed workflow pause silently reversing to a terminal failed run. Disposing a stage session while its stage was parked on an acknowledged pause rejected the parked pause waiter with `stage "<name>" session has been disposed`, which surfaced as a stage failure and emitted a terminal `workflow.run.end` with status `failed` — after `workflow pause` had already reported success and status had reported the run paused and resumable. Disposal that arrives during a confirmed pause is now deferred instead of rejecting the waiter, so the run stays paused and resumable and explicit resume continues through the normal path with intact metadata. Abort and kill still reject a parked waiter and fail visibly, a deferred disposal is still completed once that abort arrives, and disposal outside a confirmed pause is unchanged and still reported ([#2558](https://github.com/bastani-inc/atomic/issues/2558)).
- Fixed a workflow stage session leak when a confirmed-paused stage was cleared from the live control registry, resumed through its stale handle, and then completed. Deferred controller cleanup now drains once at terminal completion, releasing the session and its listeners without double-disposal.

## [0.9.14] - 2026-08-19

Cumulative release of the `0.9.14-alpha.1` – `0.9.14-alpha.6` prereleases. The summary below covers the user-visible outcome of that work; the per-change detail remains in the prerelease sections below.

### Breaking Changes

- `open-claude-design` removes the `max_refinements` input, the `approved_for_export` and `refinements_completed` outputs, and the `<artifact_dir>/feedback/` feedback artifact. A run now performs one `generate-1`, an optional live review, and export; callers must stop supplying, reading, or expecting those fields and artifacts ([#2401](https://github.com/bastani-inc/atomic/issues/2401)).
- `adversarial-verification` now accepts optional per-criterion `criteria`, `accept_mean`, and bounded `reask_limit` inputs, and returns deterministic graded mean/veto results through `mean_score` and `score_table_path`; callers must migrate from the removed `result`, `verifier_artifact_paths`, and `artifact_dir` outputs. Invalid verifier reports are recorded as invalid markers and re-asked instead of becoming fail votes ([#2487](https://github.com/bastani-inc/atomic/issues/2487)).
- Replaced `bracket_path`/`bracket.json` and the knockout tournament schedule with `comparisons_path`/`comparisons.json` on the soft-scored pivot-pairing schedule. Judge stages now use deterministic `judge-<a>-<b>-<criterion>-r<rep>` identities, and the reducer stage is named `comparisons-reducer` ([#2488](https://github.com/bastani-inc/atomic/issues/2488)).

### Added

- Added `heartbeatIntervalMinutes` to the workflow authoring surface: an optional cadence in minutes that resolves to the `15`-minute default when omitted, treats `0` as an explicit disable, and rejects negative and non-finite values at authoring time. Every compiled definition carries the resolved value, and the default interval, heartbeat custom type, and heartbeat event types are exported from `@bastani/workflows` ([#1975](https://github.com/bastani-inc/atomic/issues/1975)).
- Added workflow heartbeat scheduling and queued parent delivery for `heartbeatIntervalMinutes`. While a top-level run is active, one heartbeat is raised per `startedAt + n × interval` boundary computed from the run's persisted start time. Delivery reuses the lifecycle-notice parent path under the distinct `workflows:workflow-heartbeat` custom type, at most one unread heartbeat is outstanding per run, paused runs emit nothing, nested child runs never heartbeat the parent chat, and a durable cadence-anchor keeps a resumed run on its launch cadence ([#1975](https://github.com/bastani-inc/atomic/issues/1975)).
- Added terminal heartbeat cleanup and restart recovery. Reaching any terminal status drops that run's cadence, queued heartbeats, and durable-anchor memos. A heartbeat whose run has since finished is excluded from the model's context and never steers the parent about a run that is over, while the transcript card remains as a record that the heartbeat was raised ([#1975](https://github.com/bastani-inc/atomic/issues/1975)).
- Every bundled builtin workflow now states its heartbeat cadence rather than inheriting it. The long autonomous workflows declare the `15`-minute default explicitly; `open-claude-design` sets `0` and runs quiet ([#1975](https://github.com/bastani-inc/atomic/issues/1975)).
- Added optional run-budget declarations on workflow config, authored definitions, and `workflow` tool runs or resumes. `maxDurationMs`, `maxTokens`, `maxCost`, and `warnAtPercent` resolve per field with run overrides taking precedence over definition and config values; `0` disables a dimension. Invalid declarations now fail validation, and `budget_exceeded` is reserved as a resumable returned blocked status ([#2212](https://github.com/bastani-inc/atomic/issues/2212)).
- Added duration enforcement for workflow budgets at stage and durable-tool boundaries. Runs emit one user-visible `budget_warning` lifecycle notice at the default 80% threshold or configured threshold, receive one wrap-up turn only when a frontier stage turn is already live, and stop on a resumable `budget_exceeded` blocked rail with a duration report. Paused time is excluded, elapsed time carries across resume, a raised resume budget continues prior spend, root duration scope is enforced inside child workflows, and child-scoped exhaustion returns to the parent without stopping it ([#2212](https://github.com/bastani-inc/atomic/issues/2212)).
- Added tree-wide token and cost budget metering across nested workflow runs and stage retries. Uncached input and output tokens feed `maxTokens`, cache reads and writes remain reported counters, `usage.cost` feeds `maxCost`, and persisted accounting baselines prevent duplicate charges across boundaries and resume ([#2212](https://github.com/bastani-inc/atomic/issues/2212)).
- Added optional per-attempt `timeoutMs` deadlines to `ctx.tool`. Expiry aborts the attempt signal, records a timeout-specific diagnostic, participates in retries, and follows the existing throwing or typed `failureMode: "return"` behavior ([#2424](https://github.com/bastani-inc/atomic/issues/2424)).
- Stage control registries expose `has(runId)` so a pruned registration map is distinguishable from an empty one after `clearDetached()` ([#2462](https://github.com/bastani-inc/atomic/issues/2462)).
- Refined `ctx.tool` graph inspection into one read-only agent-chat-style tool message block. Enter, click, or switcher selection opens it collapsed by default; the configured `app.tools.expand` action (`ctrl+o` by default) toggles the full bounded args, result/error, callback source, timing, and cached/replayed markers ([#2427](https://github.com/bastani-inc/atomic/issues/2427)).
- Added a shared `verification-criteria` module (`parse_rubric`, `normalize_criteria`, `select_criteria`, `VERIFICATION_SCALE`, `decide_verification`) so verification builtins can score one criterion at a time on an anchored 1–20 scale and accept only when a quorum mean clears the threshold with no veto finding ([#2487](https://github.com/bastani-inc/atomic/issues/2487)).
- Added prefix-cache-aware verification prompts with a byte-identical shared head, UTF-8 bounded candidate inlining with whole-family read fallback, and warm-first verifier fan-out scheduling ([#2493](https://github.com/bastani-inc/atomic/issues/2493)).
- `adversarial-verification` now fans out one schema-validated 1–20 score for every criterion/verifier pair, applies mean-plus-veto acceptance, bounds invalid-report re-asks, and consolidates confirmed findings into repair guidance ([#2487](https://github.com/bastani-inc/atomic/issues/2487)).
- Added pure, seeded selection math for probabilistic pivot tournaments: deterministic Hamiltonian ring and deduplicated pivot planning, criterion/repeat slot-swap jobs, normalized Bradley–Terry soft wins, count-normalized pivot selection, and complete candidate rankings ([#2488](https://github.com/bastani-inc/atomic/issues/2488)).
- Added tournament `n_evaluations`, `pivots`, `seed`, `criteria`, and heterogeneous `models` inputs, plus `ranking` and `seed` outputs and the auditable `comparisons.json` score ledger with invalid-report and budget records ([#2488](https://github.com/bastani-inc/atomic/issues/2488)).
- Added Goal and Ralph review-round re-verification for low-confidence, single-reviewer blocking findings, using fresh 1–20 scoring stages, two-tier demotion bars, and durable per-repeat audit evidence while leaving `stop_review_loop` authoritative.
- Added pure `fold_usage` accounting over every model attempt (including retries), returning `UsageTotals` with a derived cache-hit rate; tournament comparisons and adversarial verification round summaries now record per-phase and total usage blocks ([#2494](https://github.com/bastani-inc/atomic/issues/2494)).
- Added observation-grounded progress scoring with batched checkpoint repeats, null-safe invalid-repeat handling, and a pure hysteretic trend classifier that reports evidence without an action ([#2489](https://github.com/bastani-inc/atomic/issues/2489)).
- Added Goal and Ralph per-round convergence evidence series with V7 trend classification, folded usage totals, and escalation-only `needs_human` evidence that never approves or terminates a review loop ([#2490](https://github.com/bastani-inc/atomic/issues/2490)).
- Added reviewer calibration rules that prioritize observed output over agent narration, plus audit-only 1–20 `criterion_scores` in Goal and Ralph review decisions without changing the authoritative closure gate ([#2494](https://github.com/bastani-inc/atomic/issues/2494)).
- Added loop-until-done progress consumers that record per-iteration advisory score curves, final trends, and calibration disclaimers in completion and exhaustion reports without changing stop decisions ([#2489](https://github.com/bastani-inc/atomic/issues/2489)).
- Added HumanLayer's bundled `show-me` skill for visual explanations, diagrams, code-shape sketches, and focused HTML artifacts. Sourced from https://github.com/humanlayer/skills and distributed under the MIT License.
- Updated the bundled `create-spec` skill to choose context-driven Path A or clarify-first Path B, inspect local precedent before design decisions, compare materially different alternatives, and use show-me shape-first visuals. Working-method guidance is drawn from Dillon Mulroy's [tech-spec skill](https://github.com/dmmulroy/skills/blob/main/tech-spec/SKILL.md).

### Changed

- Redesigned the `ctx.tool` inspection surface as a shaded host-style operator card: a `$` call header, a tail preview with an exact earlier-lines expand hint, `Took`/`Elapsed` timing, and a graph statusline that advertises the configured expand key. The forensic ARGS/RESULT/SOURCE/TIMING/MARKERS field table is gone from the operator surface.
- Synchronized the complete bundled `impeccable` skill tree from upstream `skill-v4.0.3` to `skill-v4.1.1`, adding persisted Live roots, framework-aware injection, prompt embedding, CSS acceptance checks, Svelte AST support, mount verification, UI-surface contracts, and the latest detector and design guidance ([#2382](https://github.com/bastani-inc/atomic/issues/2382)).
- Impeccable concept rolls now include platform, grain, register, and card-kind fields and use a bounded `impeccable.style` fallback when no local catalog exists. The OpenAI image fallback supports reference-image edits and generated images only when `OPENAI_API_KEY` is present ([#2382](https://github.com/bastani-inc/atomic/issues/2382)).
- Removed upstream Impeccable's outbound telemetry and update check from the bundled skill. The only request the concept roll can still make is the catalog `GET /api/roll` ([#2382](https://github.com/bastani-inc/atomic/issues/2382)).
- The `open-claude-design` live review session is now the final review boundary: ending it exports the design as it stands with no further round. The run-level gate retains `Start live review` and `Skip remaining review rounds and export as-is` ([#2401](https://github.com/bastani-inc/atomic/issues/2401), [#2382](https://github.com/bastani-inc/atomic/issues/2382)).
- Added model-visible workflow source-layout guidance: keep compact workflows in one entry file, and extract only cohesive prompt, schema/type, model-policy, deterministic-helper, or child-workflow concerns at meaningful boundaries ([#2451](https://github.com/bastani-inc/atomic/issues/2451)).
- Migrated the built-in Goal, Ralph, and open-claude-design model chains from active GLM-5.2 entries to direct Z.AI `zai/glm-5.3:high` and `zai-coding-cn/glm-5.3:high` fallbacks, and raised Grok 4.6 fallbacks from `:high` to `:xhigh` with a matching `github-copilot/grok-4.6:xhigh` twin ([#2459](https://github.com/bastani-inc/atomic/issues/2459)).

### Fixed

- Fixed consumer TypeScript errors in `selection-math` when `noUncheckedIndexedAccess` is enabled ([#2543](https://github.com/bastani-inc/atomic/issues/2543)).
- Opened `ctx.tool` detail now matches the main-chat tool block: inner padding, a blank row under the `$` header, full-width alignment, host tool colors, a dim expand hint, and second-resolution timing.
- Tournament criteria now accepts every documented V1 shape, including markdown rubrics, records, string lists, and CriterionInput objects with optional ids and names.
- Criterion ids are preserved in the ledger while judge artifact filenames are sanitized, collision-free, and contained under the artifact directory.
- Corrected the planned comparison budget for oversized pivot counts and recorded each comparison row's own soft preference separately from pair aggregates.
- Readiness-gate **Type something.** now stays in the stage and sends the typed text as the next stage-chat turn. Empty or whitespace-only custom text cannot be submitted. **Chat about this** is a plain option on the gate.
- Fixed `ask_user_question` failing every workflow stage that called it while the graph viewer was attached. An overlay request now mounts on the stage chat's existing custom-UI slot instead of rejecting overlay mode in the graph viewer.
- Hardened the synced Impeccable executables against shell-based browser launch, remote browser URLs, project-root and symlink escapes, unsafe persisted roots and injection journals, non-atomic generated writes, untrusted live instructions, read failures reported as clean, and unbounded or malformed live protocol values ([#2382](https://github.com/bastani-inc/atomic/issues/2382)).
- Operator-card wrapping no longer drops a `/` or punctuation that could not fit on a truncated row.
- An unbound `app.tools.expand` no longer leaves a keyless `expand`/`collapse` label on the `ctx.tool` operator-card statusline.
- Workflow run-scoped singletons now survive `/reload`'s module re-evaluation. The replacement extension instance re-binds its store, stage-control registry, cancellation registry, tool-control registry, job tracker, and stage UI broker to the host session-scoped state ([#2462](https://github.com/bastani-inc/atomic/issues/2462) by [@makgunay](https://github.com/makgunay)).
- Process-preserving session boundaries (`/reload`, `/fork`, `/new`, `/resume`) no longer kill in-flight workflow runs or drop live executor stage handles. `/reload` reuses the host event bus so the replacement session can still list and control the run; `/new`, `/resume`, and `/fork` get fresh registries and do not list it ([#2462](https://github.com/bastani-inc/atomic/issues/2462), [#2247](https://github.com/bastani-inc/atomic/issues/2247) by [@makgunay](https://github.com/makgunay)).
- DBOS lifecycle state and the registered `atomicWorkflowHandle` / `atomicWorkflowCheckpoint` wrappers now live in a process-global `globalThis` slot, so a re-evaluated workflows bundle reuses the original registrations instead of colliding with the still-live SDK registry ([#2462](https://github.com/bastani-inc/atomic/issues/2462), [#2022](https://github.com/bastani-inc/atomic/issues/2022) by [@makgunay](https://github.com/makgunay)).
- A duplicate DBOS operation registration is no longer reported as a Postgres provisioning failure. The durability error and the non-durable fallback warning now name the registration conflict and no longer suggest changing `DBOS_SYSTEM_DATABASE_URL` ([#2462](https://github.com/bastani-inc/atomic/issues/2462), [#2022](https://github.com/bastani-inc/atomic/issues/2022) by [@makgunay](https://github.com/makgunay)).
- Fixed `workflow send` answers for primitive human-in-the-loop prompts. Confirm answers now preserve booleans and accept the documented yes/no labels, select answers resolve case-insensitive labels or 1-based indexes, and unusable answers remain pending ([#2417](https://github.com/bastani-inc/atomic/pull/2417) by [@makgunay](https://github.com/makgunay)).
- Separated schema-backed workflow result data from runner-owned output artifacts. When a stage configures both `schema` and `output`, the successful `structured_output` arguments remain the typed machine-readable result while ordinary text from that tool-call message becomes the human-readable artifact. Builtin `adversarial-verification`, `generate-and-filter`, `tournament`, and `loop-until-done` now persist their structured decisions themselves so their `*.json` inter-stage artifacts remain machine-readable ([#2198](https://github.com/bastani-inc/atomic/issues/2198)).

### Removed

- Removed find-in-stage-chat. `Ctrl+Shift+F` in an attached workflow stage chat no longer opens a search box over that chat.
- Removed the live-review feedback module and all `<artifact_dir>/feedback/` artifacts, including the JSON record, `iteration-N.md` copy, and annotated-snapshot copies ([#2401](https://github.com/bastani-inc/atomic/issues/2401)).

## [0.9.14-alpha.6] - 2026-08-19

### Fixed

- Fixed consumer TypeScript errors in `selection-math` when `noUncheckedIndexedAccess` is enabled ([#2543](https://github.com/bastani-inc/atomic/issues/2543)).

## [0.9.14-alpha.5] - 2026-08-19

### Added

- Added optional run-budget declarations on workflow config, authored definitions, and `workflow` tool runs or resumes. `maxDurationMs`, `maxTokens`, `maxCost`, and `warnAtPercent` resolve per field with run overrides taking precedence over definition and config values; `0` disables a dimension. Invalid declarations now fail validation, and `budget_exceeded` is reserved as a resumable returned blocked status; these declarations provide the resolution core for the duration enforcement below ([#2212](https://github.com/bastani-inc/atomic/issues/2212)).
- Added duration enforcement for workflow budgets at stage and durable-tool boundaries. Runs emit one user-visible `budget_warning` lifecycle notice at the default 80% threshold or configured threshold, receive one wrap-up turn only when a frontier stage turn is already live, and stop on a resumable `budget_exceeded` blocked rail with a duration report; no new stage is created for wrap-up, no-live-turn boundaries leave the allowance unused, paused time is excluded, elapsed time carries across resume, a raised resume budget continues prior spend, the wrap-up turn's own usage is recorded as `wrapUpUsage` when available without tree-wide token/cost aggregation, root duration scope is enforced inside child workflows and wins simultaneous child exhaustion, and child-scoped exhaustion returns to the parent without stopping it ([#2212](https://github.com/bastani-inc/atomic/issues/2212)).
- Added tree-wide token and cost budget metering across nested workflow runs and stage retries. Uncached input and output tokens feed `maxTokens`, cache reads and writes remain reported counters, `usage.cost` feeds `maxCost`, and persisted accounting baselines prevent duplicate charges across boundaries and resume ([#2212](https://github.com/bastani-inc/atomic/issues/2212)).
- Added HumanLayer's bundled `show-me` skill for visual explanations, diagrams, code-shape sketches, and focused HTML artifacts. Sourced from https://github.com/humanlayer/skills and distributed under the MIT License.
- Updated the bundled `create-spec` skill to choose context-driven Path A or clarify-first Path B, inspect local precedent before design decisions, compare materially different alternatives, and use show-me shape-first visuals (pseudocode, call trees, component/file trees, Mermaid, diffs, and optional focused HTML). Working-method guidance is drawn from Dillon Mulroy's [tech-spec skill](https://github.com/dmmulroy/skills/blob/main/tech-spec/SKILL.md).
### Breaking Changes

- `adversarial-verification` now accepts optional per-criterion `criteria`, `accept_mean`, and bounded `reask_limit` inputs, and returns deterministic graded mean/veto results through `mean_score` and `score_table_path`; callers must migrate from the removed `result`, `verifier_artifact_paths`, and `artifact_dir` outputs. Invalid verifier reports are recorded as invalid markers and re-asked instead of becoming fail votes ([#2487](https://github.com/bastani-inc/atomic/issues/2487)).
- Replaced `bracket_path`/`bracket.json` and the knockout tournament schedule with `comparisons_path`/`comparisons.json` on the soft-scored pivot-pairing schedule. Judge stages now use deterministic `judge-<a>-<b>-<criterion>-r<rep>` identities, and the reducer stage is named `comparisons-reducer`.
- Replaced `bracket_path`/`bracket.json` and the knockout tournament schedule with `comparisons_path`/`comparisons.json` on the soft-scored pivot-pairing schedule. Judge stages now use deterministic `judge-<a>-<b>-<criterion>-r<rep>` identities, and the reducer stage is named `comparisons-reducer`.
- `adversarial-verification` now accepts optional per-criterion `criteria`, `accept_mean`, and bounded `reask_limit` inputs, and returns deterministic graded mean/veto results through `mean_score` and `score_table_path`; callers must migrate from the removed `result`, `verifier_artifact_paths`, and `artifact_dir` outputs. Invalid verifier reports are recorded as invalid markers and re-asked instead of becoming fail votes ([#2487](https://github.com/bastani-inc/atomic/issues/2487)).

### Added

- Added a shared `verification-criteria` module (`parse_rubric`, `normalize_criteria`, `select_criteria`, `VERIFICATION_SCALE`, `decide_verification`) so verification builtins can score one criterion at a time on an anchored 1–20 scale and accept only when a quorum mean clears the threshold with no veto finding. Unparseable reports cannot become scores and cannot shift the mean ([#2487](https://github.com/bastani-inc/atomic/issues/2487)).
- Added prefix-cache-aware verification prompts with a byte-identical shared head, UTF-8 bounded candidate inlining with whole-family read fallback, and warm-first verifier fan-out scheduling that preserves input order while releasing later phases after warm failures ([#2493](https://github.com/bastani-inc/atomic/issues/2493)).
- Added optional run-budget declarations on workflow config, authored definitions, and `workflow` tool runs or resumes. `maxDurationMs`, `maxTokens`, `maxCost`, and `warnAtPercent` resolve per field with run overrides taking precedence over definition and config values; `0` disables a dimension. Invalid declarations now fail validation, and `budget_exceeded` is reserved as a resumable returned blocked status; these declarations provide the resolution core for the duration enforcement below ([#2212](https://github.com/bastani-inc/atomic/issues/2212)).
- Added duration enforcement for workflow budgets at stage and durable-tool boundaries. Runs emit one user-visible `budget_warning` lifecycle notice at the default 80% threshold or configured threshold, receive one wrap-up turn only when a frontier stage turn is already live, and stop on a resumable `budget_exceeded` blocked rail with a duration report; no new stage is created for wrap-up, no-live-turn boundaries leave the allowance unused, paused time is excluded, elapsed time carries across resume, a raised resume budget continues prior spend, the wrap-up turn's own usage is recorded as `wrapUpUsage` when available without tree-wide token/cost aggregation, root duration scope is enforced inside child workflows and wins simultaneous child exhaustion, and child-scoped exhaustion returns to the parent without stopping it ([#2212](https://github.com/bastani-inc/atomic/issues/2212)).
- Added optional run-budget declarations on workflow config, authored definitions, and `workflow` tool runs. `maxDurationMs`, `maxTokens`, `maxCost`, and `warnAtPercent` resolve per field with run overrides taking precedence over definition and config values; `0` disables a dimension. Invalid declarations now fail validation, and `budget_exceeded` is reserved as a resumable returned blocked status. This core slice only resolves and validates budgets; it does not meter or stop runs yet ([#2212](https://github.com/bastani-inc/atomic/issues/2212)).
- Added a shared `verification-criteria` module (`parse_rubric`, `normalize_criteria`, `select_criteria`, `VERIFICATION_SCALE`, `decide_verification`) so verification builtins can score one criterion at a time on an anchored 1–20 scale and accept only when a quorum mean clears the threshold with no veto finding. Unparseable reports cannot become scores and cannot shift the mean ([#2487](https://github.com/bastani-inc/atomic/issues/2487)).
- Added prefix-cache-aware verification prompts with a byte-identical shared head, UTF-8 bounded candidate inlining with whole-family read fallback, and warm-first verifier fan-out scheduling that preserves input order while releasing later phases after warm failures ([#2493](https://github.com/bastani-inc/atomic/issues/2493)).
- Added Goal and Ralph review-round re-verification for low-confidence, single-reviewer blocking findings, using fresh 1–20 scoring stages, two-tier demotion bars, and durable per-repeat audit evidence while leaving `stop_review_loop` authoritative.
- Added pure, seeded selection math for probabilistic pivot tournaments: deterministic Hamiltonian ring and deduplicated pivot planning, criterion/repeat slot-swap jobs, normalized Bradley–Terry soft wins, count-normalized pivot selection, and complete candidate rankings ([#2488](https://github.com/bastani-inc/atomic/issues/2488)).
- Added tournament `n_evaluations`, `pivots`, `seed`, `criteria`, and heterogeneous `models` inputs, plus `ranking` and `seed` outputs and the auditable `comparisons.json` score ledger with invalid-report and budget records ([#2488](https://github.com/bastani-inc/atomic/issues/2488)).
- `adversarial-verification` now fans out one schema-validated 1–20 score for every criterion/verifier pair, applies mean-plus-veto acceptance, bounds invalid-report re-asks, and consolidates confirmed findings into repair guidance ([#2487](https://github.com/bastani-inc/atomic/issues/2487)).
- Added pure `fold_usage` accounting over every model attempt (including retries), returning `UsageTotals { calls, input, output, cacheRead, cacheWrite, cost, turns, cacheHitRate }` with a derived cache-hit rate; tournament comparisons and adversarial verification round summaries now record per-phase and total usage blocks ([#2494](https://github.com/bastani-inc/atomic/issues/2494)).
- Added observation-grounded progress scoring with batched checkpoint repeats, null-safe invalid-repeat handling, and a pure hysteretic trend classifier that reports evidence without an action ([#2489](https://github.com/bastani-inc/atomic/issues/2489)).
- Added Goal and Ralph per-round convergence evidence series with V7 trend classification, folded usage totals, and escalation-only `needs_human` evidence that never approves or terminates a review loop ([#2490](https://github.com/bastani-inc/atomic/issues/2490)).
- Added reviewer calibration rules that prioritize observed output over agent narration, plus audit-only 1–20 `criterion_scores` in Goal and Ralph review decisions without changing the authoritative closure gate ([#2494](https://github.com/bastani-inc/atomic/issues/2494)).
- Added loop-until-done progress consumers that record per-iteration advisory score curves, final trends, and calibration disclaimers in completion and exhaustion reports without changing stop decisions ([#2489](https://github.com/bastani-inc/atomic/issues/2489)).
- Added observation-grounded progress scoring with batched checkpoint repeats, null-safe invalid-repeat handling, and a pure hysteretic trend classifier that reports evidence without an action ([#2489](https://github.com/bastani-inc/atomic/issues/2489)).
- Added loop-until-done progress consumers that record per-iteration advisory score curves, final trends, and calibration disclaimers in completion and exhaustion reports without changing stop decisions ([#2489](https://github.com/bastani-inc/atomic/issues/2489)).
- Added pure, seeded selection math for probabilistic pivot tournaments: deterministic Hamiltonian ring and deduplicated pivot planning, criterion/repeat slot-swap jobs, normalized Bradley–Terry soft wins, count-normalized pivot selection, and complete candidate rankings ([#2488](https://github.com/bastani-inc/atomic/issues/2488)).
- Added tournament `n_evaluations`, `pivots`, `seed`, `criteria`, and heterogeneous `models` inputs, plus `ranking` and `seed` outputs and the auditable `comparisons.json` score ledger with invalid-report and budget records ([#2488](https://github.com/bastani-inc/atomic/issues/2488)).

### Fixed

- Opened `ctx.tool` detail now matches the main-chat tool block: `Box(1,1)` inner padding, a blank row under the `$` header, full-width alignment with the orchestrator bars, unpainted canvas above and below the card, host `toolTitle`/`toolOutput` colors, a dim `ctrl+o Expand` hint, and second-resolution `Took`/`Elapsed` timing.
- Tournament criteria now accepts every documented V1 shape, including markdown rubrics, records, string lists, and CriterionInput objects with optional ids and names.
- Criterion ids are preserved in the ledger while judge artifact filenames are sanitized, collision-free, and contained under the artifact directory.
- Corrected the planned comparison budget for oversized pivot counts and recorded each comparison row's own soft preference separately from pair aggregates.

## [0.9.14-alpha.3] - 2026-08-17

### Changed

- Raised built-in Goal, Ralph, and open-claude-design Grok 4.6 fallbacks from `xai/grok-4.6:high` to `xai/grok-4.6:xhigh` and added the matching `github-copilot/grok-4.6:xhigh` twin immediately after each xAI id.

### Fixed

- Readiness-gate **Type something.** now stays in the stage and sends the typed text as the next stage-chat turn. Empty or whitespace-only custom text cannot be submitted. **Chat about this** is a plain option on the gate (no inline editor) and stays by sending `The user would like to chat more about this`.

- Fixed `ask_user_question` failing every workflow stage that called it while the graph viewer was attached. The tool always mounts with `overlay: true`, and both graph hosts — the attached stage chat and the `ctx.ui.custom` prompt node — rejected that with "ctx.ui.custom overlay mode is unavailable in the workflow graph viewer", so the questionnaire never painted and the stage failed. Overlay is a placement hint rather than a capability request: an overlay request now mounts on the stage chat's existing custom-UI slot, which already keeps the stage transcript visible and scrollable behind the question, takes focus, and resolves through `done(value)`. Workflow-level `ctx.ui.custom(factory, { overlay: true })` completes on the same path. No nested overlay is opened above the graph chrome, so `overlayOptions` and `onHandle` stay unconsumed there, and non-overlay custom UI, readiness gates, detach-does-not-cancel, and mid-mount settle guards are unchanged.

## [0.9.14-alpha.2] - 2026-08-17

### Breaking Changes

- `open-claude-design` removes the `max_refinements` input, the `approved_for_export` and `refinements_completed` outputs, and the `<artifact_dir>/feedback/` feedback artifact. A run now performs one `generate-1`, an optional live review, and export; callers must stop supplying, reading, or expecting those fields and artifacts ([#2401](https://github.com/bastani-inc/atomic/issues/2401)).

### Added

- Added optional per-attempt `timeoutMs` deadlines to `ctx.tool`. Expiry aborts the attempt signal, records a timeout-specific diagnostic, participates in retries, and follows the existing throwing or typed `failureMode: "return"` behavior; each retry gets a fresh signal and deadline, while omitted timeouts preserve existing behavior ([#2424](https://github.com/bastani-inc/atomic/issues/2424)).
- Stage control registries expose `has(runId)` so a pruned registration map is distinguishable from an empty one after `clearDetached()` ([#2462](https://github.com/bastani-inc/atomic/issues/2462)).
- Refined `ctx.tool` graph inspection into one read-only agent-chat-style tool message block. Enter, click, or switcher selection opens it collapsed by default with the tool call and a compact bounded result/error preview; the configured `app.tools.expand` action (`ctrl+o` by default) toggles full bounded args, result/error, callback source, timing, and cached/replayed markers. The block preserves keyboard and mouse scrolling, narrow-terminal layout, status styling, Escape/return navigation, `attachable: false`, and no attach, steer, interrupt, resume, or editable transcript affordances. Hostile payloads now cross precise typed boundaries with one own-key discovery call and bounded descriptor/value work for both retention and display, explicit cycle/accessor/conversion placeholders, and collision-safe truncation markers; the runtime's own key-list materialization remains outside the module's control, while durable checkpoints still keep exact output and raw-args `argsHash` identity ([#2427](https://github.com/bastani-inc/atomic/issues/2427)).

### Removed

- Removed find-in-stage-chat. `Ctrl+Shift+F` in an attached workflow stage chat no longer opens a search box over that chat.

### Changed

- Redesigned the `ctx.tool` inspection surface as a shaded host-style operator card: a `$` call header, a tail preview taken from the fully bounded result/error body with an exact earlier-lines expand hint, `Took`/`Elapsed` timing, status-tinted tool backgrounds that cover every cell of the card, callback source only in the expanded view, and a graph statusline that advertises the configured expand key as `expand`/`collapse` alongside return-to-graph and scroll controls. Plain rendering remains ANSI-free at narrow widths, and capped payload wrapping now scans once without changing its visual output. The forensic ARGS/RESULT/SOURCE/TIMING/MARKERS field table is gone from the operator surface.
- Synchronized the complete bundled `impeccable` skill tree from upstream `skill-v4.0.3` (`68b1129634a1cdd9a0ba50b27376c71b4b083ae8`) to `skill-v4.1.1` (`5a149f3fdb1b5793f10567233b1dcab98fc305fd`), adding persisted Live roots, framework-aware injection, prompt embedding, CSS acceptance checks, Svelte AST support, mount verification, UI-surface contracts, and the latest detector and design guidance. The sync removes obsolete `scripts/live/ui-core.mjs`, keeps the Cursor-only `scripts/hook-before-edit.mjs` omitted, and retains Atomic's package-path and security adaptations ([#2382](https://github.com/bastani-inc/atomic/issues/2382)).
- Impeccable concept rolls now include platform, grain, register, and card-kind fields and use a bounded `impeccable.style` fallback when no local catalog exists. The OpenAI image fallback supports reference-image edits and generated images only when `OPENAI_API_KEY` is present, warns about account spend, and embeds each prompt in the image or a sidecar ([#2382](https://github.com/bastani-inc/atomic/issues/2382)).
- Removed upstream Impeccable's outbound telemetry and update check from the bundled skill. Upstream 4.1.1 posts an anonymous attended-choice ping to `impeccable.style` unless `IMPECCABLE_NO_TELEMETRY` or `DO_NOT_TRACK` is set, and polls `/api/version` once a day to suggest `npx impeccable update`. Atomic ships neither: the ping is removed outright rather than defaulted off, and the update check is dropped because a vendored skill cannot self-update and its version ships with Atomic releases. The only request the concept roll can still make is the catalog `GET /api/roll`, which carries scope, mode, an eight-hex seed key, and a re-roll counter, and no project files, prompts, code, or conversation context ([#2382](https://github.com/bastani-inc/atomic/issues/2382)).
- The `open-claude-design` run-level review gate and the session-start stage now state how a review ends — exit in the Impeccable overlay, closing the browser tab, or `exit live` — that the session waits indefinitely until then, and that ending it exports the design as it stands with no further round ([#2401](https://github.com/bastani-inc/atomic/issues/2401)).
- The live review session is the final review boundary: the workflow-owned poll loop dispatches `generate`, `steer`, `manual_edit_apply`, and failed variant mounts to model stages, keeps successful mounts journal-only, ends on the helper's `exit` event, and exports the preview as it stands without a summary, second opinion, decision, or later review session ([#2401](https://github.com/bastani-inc/atomic/issues/2401), [#2382](https://github.com/bastani-inc/atomic/issues/2382)).
- The run-level gate retains `Start live review` and `Skip remaining review rounds and export as-is`; the skip choice exports immediately without opening the session ([#2401](https://github.com/bastani-inc/atomic/issues/2401)).
- Added model-visible workflow source-layout guidance: keep compact workflows in one entry file, and extract only cohesive prompt, schema/type, model-policy, deterministic-helper, or child-workflow concerns at meaningful boundaries while keeping graph control flow visible in the entry file ([#2451](https://github.com/bastani-inc/atomic/issues/2451)).
- Migrated the built-in Goal, Ralph, and open-claude-design model chains from active GLM-5.2 entries to direct Z.AI `zai/glm-5.3:high` and `zai-coding-cn/glm-5.3:high` fallbacks. OpenRouter's unavailable GLM-5.3 model is intentionally omitted rather than shipped as a placeholder ([#2459](https://github.com/bastani-inc/atomic/issues/2459)).

### Fixed

- Hardened the synced Impeccable executables against shell-based browser launch, remote browser URLs, project-root and symlink escapes, unsafe persisted roots and injection journals, non-atomic generated writes, untrusted live instructions, read failures reported as clean, and unbounded or malformed live protocol values. The `open-claude-design` loop now handles 4.1.1 mount failures, preserves the full event payload, replies with the required event id and status, and fails on helper process errors ([#2382](https://github.com/bastani-inc/atomic/issues/2382)).
- Operator-card wrapping no longer drops a `/` or punctuation that could not fit on a truncated row.
- An unbound `app.tools.expand` no longer leaves a keyless `expand`/`collapse` label on the `ctx.tool` operator-card statusline. The card body already dropped the key from `... (N earlier lines)`; the statusline now matches.
- Workflow run-scoped singletons now survive `/reload`'s module re-evaluation. The replacement extension instance re-binds its store, stage-control registry, cancellation registry, tool-control registry, job tracker, and stage UI broker to the host session-scoped state, so an in-flight run stays visible and controllable instead of vanishing behind empty replacements. Adopting a previously unseen host session creates a fresh instance instead of handing that session the previous session's live object, so controls invoked from the new session cannot cancel or mutate the prior run ([#2462](https://github.com/bastani-inc/atomic/issues/2462) by [@makgunay](https://github.com/makgunay)).
- Process-preserving session boundaries (`/reload`, `/fork`, `/new`, `/resume`) no longer kill in-flight workflow runs or drop live executor stage handles; the run keeps executing. `/reload` reuses the host event bus, so the replacement session can still list a run, report its real state, and answer a stage awaiting input. `/new`, `/resume`, and `/fork` build a new event bus, so the successor session gets fresh registries and does not list the run. `startup` and unrecognised start reasons still clear, and a real `quit` still pauses, clears the registry, and shuts DBOS down exactly once ([#2462](https://github.com/bastani-inc/atomic/issues/2462), [#2247](https://github.com/bastani-inc/atomic/issues/2247) by [@makgunay](https://github.com/makgunay)).
- DBOS lifecycle state and the registered `atomicWorkflowHandle` / `atomicWorkflowCheckpoint` wrappers now live in a process-global `globalThis` slot keyed with `Symbol.for`, so a re-evaluated workflows bundle reuses the original registrations instead of colliding with the still-live SDK registry and silently falling back to an in-memory backend. A later `configureDbosDurableBackend` call after `DBOS.launch` recovers those wrappers and does not call `setConfig` again. A real quit still flushes and shuts DBOS down exactly once ([#2462](https://github.com/bastani-inc/atomic/issues/2462), [#2022](https://github.com/bastani-inc/atomic/issues/2022) by [@makgunay](https://github.com/makgunay)).
- A duplicate DBOS operation registration is no longer reported as a Postgres provisioning failure. The durability error and the non-durable fallback warning now name the registration conflict and no longer suggest changing `DBOS_SYSTEM_DATABASE_URL`. Classification uses the SDK `Error.DBOSConflictingRegistrationError` class and `dbosErrorCode`, not message wording. A wrapper whose `cause`, `name`, or `message` getter throws stays `other` and keeps the original failure in the diagnostic instead of replacing it with the inspection trap. Reading the failure detail for the wrapper itself also uses the guarded accessor, so a throwing `message` getter cannot escape as a raw exception ([#2462](https://github.com/bastani-inc/atomic/issues/2462), [#2022](https://github.com/bastani-inc/atomic/issues/2022) by [@makgunay](https://github.com/makgunay)).
- Fixed `workflow send` answers for primitive human-in-the-loop prompts. Confirm answers now preserve booleans and accept the documented yes/no labels, select answers resolve case-insensitive labels or 1-based indexes instead of silently choosing the first option, and unusable answers remain pending with a helpful no-op response ([#2417](https://github.com/bastani-inc/atomic/pull/2417) by [@makgunay](https://github.com/makgunay)).
- Separated schema-backed workflow result data from runner-owned output artifacts. When a stage configures both `schema` and `output`, the successful `structured_output` arguments now remain the typed machine-readable result while ordered ordinary text blocks from that exact tool-call message become the human-readable artifact. The runner snapshots both against the successful tool-call id so correction attempts and late admitted turns cannot replace either result; missing prose is written empty with an explicit warning instead of silently persisting JSON ([#2198](https://github.com/bastani-inc/atomic/issues/2198)).
- Separated schema-backed workflow result data from runner-owned output artifacts. When a stage configures both `schema` and `output`, the successful `structured_output` arguments now remain the typed machine-readable result while ordered ordinary text blocks from that exact tool-call message become the human-readable artifact. The runner snapshots both against the successful tool-call id so correction attempts and later admitted turns cannot replace either result, and never serializes the tool arguments into the artifact. When the successful message carries no ordinary text — including after a model-fallback session recreation that leaves the live session without that message — the artifact falls back to the most recent earlier assistant text that made no `structured_output` call, and only when no such text exists is it written empty with an explicit warning. Corrective prompts for schema-and-output stages keep the validation-failure guidance, schema-only stages keep their existing result-text behavior, and the builtin `adversarial-verification`, `generate-and-filter`, `tournament`, and `loop-until-done` workflows now persist their structured decisions themselves so their `*.json` inter-stage artifacts remain machine-readable ([#2198](https://github.com/bastani-inc/atomic/issues/2198)).

### Removed

- Removed the live-review feedback module and all `<artifact_dir>/feedback/` artifacts, including the JSON record, `iteration-N.md` copy, and annotated-snapshot copies. No feedback directory is written during a run ([#2401](https://github.com/bastani-inc/atomic/issues/2401)).

## [0.9.14-alpha.1] - 2026-08-14

### Added

- Added `heartbeatIntervalMinutes` to the workflow authoring surface: an optional cadence in minutes that resolves to the `15`-minute default when omitted, treats `0` as an explicit disable, and rejects negative and non-finite values with a `TypeError` while the definition is authored, so a bad cadence fails at authoring rather than at schedule time. Every compiled definition carries the resolved value, and a distinct `workflows:workflow-heartbeat` event contract is declared alongside it — run id, workflow name, start time, scheduled time, and interval, with heartbeat identity keyed by run id plus scheduled time. The default interval constant, heartbeat custom type, and heartbeat event types are exported from the `@bastani/workflows` package root ([#1975](https://github.com/bastani-inc/atomic/issues/1975)).
- Added workflow heartbeat scheduling and queued parent delivery for `heartbeatIntervalMinutes`, so a positive cadence now produces real heartbeats. While a top-level run is active, one heartbeat is raised per `startedAt + n × interval` boundary computed from the run's persisted start time — never from the previous delivery — so a slow send, a retry, or a process restart cannot shift the cadence. A resolved interval of `0` creates no timer and no durable record at all. One globally-next-due wake-up serves every enabled run rather than one recurring timer per run. At most one heartbeat per run is outstanding at a time: an outstanding heartbeat holds its slot until its card is actually consumed into the conversation — not merely until the parent's turn ends, which can happen while the card is still queued or its queue is paused — so a boundary that falls before that is skipped rather than stacked behind it, and the cadence then resumes at the first future boundary. However long a turn runs, and however often the queue is paused, only one unread heartbeat per run is ever waiting on a host that reports message consumption, which Atomic's chat host does. Delivery reuses the lifecycle-notice parent path (`triggerTurn`, `deliverAs: "steer"`, `persistWhenStreaming`) under the distinct `workflows:workflow-heartbeat` custom type with the five-field payload, so a busy parent chat is queued and never interrupted. Paused runs emit nothing and receive no backfill; a resumed or restarted run takes the first future boundary. Simultaneously due heartbeats reach the parent in scheduled-time order with the run id as the stable tie-break — a heartbeat being retried holds its place rather than letting a later one overtake it — terminal state is re-checked immediately before enqueue, again immediately before processing, and again before every delivery attempt including retries, and nested child workflow runs never heartbeat the parent chat. A run keeps the cadence its own definition was authored with, so editing, renaming, deleting, or reloading a workflow mid-run changes what the next launch uses and leaves runs already in flight on their launch cadence; the anchor record carries that cadence too, so it survives a durable resume. A run that launched with heartbeats disabled writes no durable record at all, so if it is resumed in a new process it adopts whatever the workflow then declares. A cadence below a millisecond schedules at the finest representable instant, and the cadence range carries a documented representable upper limit: above roughly 3 × 10^303 minutes `startedAt + interval` exceeds the largest finite timestamp, so no first boundary exists, nothing is scheduled, no durable record is written, and `ATOMIC_WORKFLOW_DEBUG=1` says so — such a cadence stays a valid positive interval but delivers no heartbeat, and `0` remains the only value that declares heartbeats off. A durable resume re-dispatches under the original run id but records a fresh start time, so each run also writes one reserved durable cadence-anchor record as soon as it has durable progress of its own, before its first boundary comes due; the anchor is read only as the earlier of itself and the run's current start time, so it keeps a resumed run on its original cadence without being able to move a boundary or raise a missed one. The delivered card names the workflow, run id, cadence, and elapsed run time and hints `/workflow status <run-id>`, rendered through the existing workflow notice-card renderer ([#1975](https://github.com/bastani-inc/atomic/issues/1975)).
- Added terminal heartbeat cleanup and restart recovery, so a workflow's heartbeats stop when the run does. Reaching any terminal status — completed, failed, blocked, skipped, cancelled, or killed — drops everything that run's cadence held in one pass: its armed wake-up, its next scheduled boundary, its outstanding slot and the card text held for it, any heartbeat of its own still waiting in the delivery queue along with the retry timer that belonged to it, and its cadence and durable-anchor memos. No pending timer and no queued heartbeat outlives the run that owns it. The pass is idempotent: repeating it creates no state, resurrects no schedule, and does not throw, including for a run the scheduler never saw. Both completion races converge on suppression — a run that finishes before its due boundary is enqueued has that boundary dropped and is refused at enqueue, and one that finishes after enqueue but before processing has its queued identity discarded rather than sent. Cleanup keys on the run's observed state rather than on a transition event, so it also covers the paths that reach a terminal snapshot without a normal end transition — durable replay, completed-catalog reconstruction, and a restore that inserts an already-failed run — and the same pass runs at startup, making it the recovery pass: a stale durable anchor or leftover queued record belonging to an already-terminal run is discarded rather than replayed, its anchor is neither read nor rewritten, and a run the store no longer holds is dropped the same way. An active run is never affected by another run's cleanup, a paused run keeps the floor that stops it re-raising a boundary it already delivered, and recovery for an active run still selects the first future boundary rather than replaying a missed one. A late durable acknowledgement or a send that settles after cleanup re-creates nothing. A heartbeat the chat host had already accepted into the parent's queue is past that pass, because no queued message can be withdrawn, so it is invalidated at the moment the parent reads it instead: a heartbeat whose run has since reached a terminal state, or whose run this process no longer knows at all, is excluded from the model's context and never steers the parent about a run that is over. That closes both remaining stale paths — a card parked through a long turn while its run finished, and a card recovered from a previous process at startup, which would otherwise replay a boundary raised before the restart. The card already rendered in the transcript is deliberately left in place as a true record that the heartbeat was raised; only the model-facing steer is invalidated ([#1975](https://github.com/bastani-inc/atomic/issues/1975)).
  A run that is only blocked on a recoverable provider or rate-limit failure remains stored as `running` and resumable: it raises no new heartbeat while blocked, but keeps its cadence state and any card already waiting with the parent. Cleanup runs only when the run's own status is terminal.
  Parent pickup is keyed by the typed `workflows:workflow-heartbeat` entry and exact run id plus scheduled time rather than rendered card text, so a foreign custom message cannot release an unread heartbeat's slot and a durable resume that reuses the run id cannot revive an old admitted card after terminal cleanup ([#1975](https://github.com/bastani-inc/atomic/issues/1975)).
  The cadence-anchor record is now written at the durability boundary itself, so it is durable before the checkpoint that made the run resumable is acknowledged. The scheduler's own write is guarded against runs with no durable progress and can therefore only be issued after resumability already exists; a process that exited inside that window left a resumable run carrying no record of what it launched with, and the next process then took both a freshly minted start time and whatever cadence the definition declared by then, shifting the phase and the cadence of a run already in flight ([#1975](https://github.com/bastani-inc/atomic/issues/1975)).
- Every bundled builtin workflow now states its heartbeat cadence rather than inheriting it. `adversarial-verification`, `classify-and-act`, `fan-out-and-synthesize`, `generate-and-filter`, `goal`, `loop-until-done`, `ralph`, and `tournament` declare the `15`-minute default explicitly, so these long autonomous runs report to the parent chat on a known cadence and a future change to the global default cannot silently re-cadence them. `open-claude-design` sets `0` and runs quiet: it is driven by the user reviewing generated HTML turn by turn, so the parent chat is already holding it to its goal and a periodic alignment steer would interrupt that review rather than inform it. Behaviour is unchanged for the eight that were already resolving to the default; only `open-claude-design` changes ([#1975](https://github.com/bastani-inc/atomic/issues/1975)).

## [0.9.13] - 2026-08-13

Cumulative release of the `0.9.13-alpha.1` – `0.9.13-alpha.4` prereleases. The summary below covers the user-visible outcome of that work; the per-change detail remains in the prerelease sections below.

### Breaking Changes

- Custom workflow UI components must return `true` when they consume input and `false` when they do not. In fullscreen mode an unhandled result lets the transcript process matching viewport navigation keys instead of swallowing them.
- Added `failed` to the `ctx.exit()` status union. An author-initiated failed exit persists its reason and partial declared outputs, returns the discriminated `{ exited: true, status: "failed" }` child result instead of throwing, and defaults to non-resumable unless `resumable: true` is set. Downstream exhaustive switches over `WorkflowExitStatus` must handle it ([#2242](https://github.com/bastani-inc/atomic/issues/2242)).
- Workflow `runId` and `stageId` targets never accepted prefixes. Run ids require the full 36-character UUID and stage ids and names match whole; the README claims to the contrary are corrected.

### Added

- Added four user-initiated lifecycle notices — `started`, `paused`, `quit`, and `resumed` — so the main chat learns when a top-level background run begins, stops, or picks back up. Each travels the same steer delivery, capped-backoff retry, and notice-card path as the existing failure notice, so an agent waiting on a background run no longer mistakes a deliberate stop for work still in progress. The paused and quit cards state that the stop was user-requested and tell the model not to resume or take over unless asked ([#2177](https://github.com/bastani-inc/atomic/issues/2177)).
- Only user actions raise those notices, and one request produces exactly one notice. `/workflow <name>`, `/workflow pause`, `/workflow quit`, and `/workflow resume` notify; the matching tool calls stay silent because the tool result already reports them, and engine-internal transitions stay silent. Each notice carries an origin ("which you started" or "which the user started", recorded once at dispatch and inherited by a continuation) and an actor. The default `workflowNotifications.notifyOn` becomes `["started", "completed", "failed", "blocked", "awaiting_input", "paused", "quit", "resumed"]`; a config that pins `notifyOn` keeps exactly the kinds it lists ([#2177](https://github.com/bastani-inc/atomic/issues/2177)).
- Added the shared "Jump to bottom" follow indicator to workflow stage chat when its transcript is scrolled away from the live end, while preserving composer and footer rows in tight overlays.

### Changed

- Rebuilt the workflow graph overlay on pi-tui 0.84.1's `VStack` and `ScrollView` layout primitives. The graph body adapts to terminal height and resize, supports vertical wheel scrolling and a draggable scrollbar, and keeps wide-graph horizontal panning and existing prompt and navigation key handling ([#2223](https://github.com/bastani-inc/atomic/issues/2223)).
- Model fallback attempt metadata now includes per-attempt input and output tokens, cache reads and writes, provider-reported total cost, and meaningful assistant-turn counts when usage is available ([#2197](https://github.com/bastani-inc/atomic/issues/2197)).
- Stage resource loading carries typed subagent policy in session options instead of mutating process-global child environment flags during reload, so concurrent stage creation preserves tool allowlists and orchestration limits ([#2188](https://github.com/bastani-inc/atomic/issues/2188)).
- Updated the Ralph research stage model configuration: the primary model moves from `openai-codex/gpt-5.6-luna:max` to `anthropic/claude-opus-5:high`, and the fallback chain is rebuilt around high and xhigh thinking levels, adding Kimi K3 and `openrouter/sakana/fugu-ultra:high`.
- Extended workflow-authoring guidance with a stacked implementation-slices starter pattern targeting roughly 100–500 changed lines between verification points, each slice routed through a child lifecycle on an explicitly created branch, stopping at the first failed gate ([#2262](https://github.com/bastani-inc/atomic/issues/2262)).
- Updated authored-workflow model guidance to treat benchmark thinking levels as measurement settings, assign effort by stage role and failure cost, require a compact `Stage | Model | Thinking | Role` declaration before launch, and reserve `max` for high-cost-of-error roles or explicit user requests ([#2203](https://github.com/bastani-inc/atomic/issues/2203)).
- Added bounded constructive-quorum deliberation to Goal and Ralph reviewer prompts: reviewers form independent preliminary verdicts, exchange evidence once over Intercom, and record evidence-backed verdict changes before the existing reducer counts final votes ([#2237](https://github.com/bastani-inc/atomic/issues/2237)).
- Workflow command, worktree Git and setup-hook, and Playwright CLI subprocesses now receive `AI_AGENT=atomic` for generic child-process attribution, without mutating caller-supplied environment objects.

### Fixed

- Fixed long model turns losing their active stage session identity and root liveness when the process died between turn boundaries. Stage start is recorded before the first session checkpoint, that identity must persist before the first model use, and serialized unref'd 30-second checkpoints cover root and nested scoped stages. A checkpoint still in flight at shutdown is drained rather than abandoned, and a stage whose final durability checkpoint fails is recorded as failed instead of completed while its caller still receives the error and its concurrency slot is still released.
- Fixed exact workflow inspection returning `Run not found` after process loss even when DBOS retained a stale running, resumable root. Status, stages, stage, and transcript actions with a full run id, and `/workflow status <id>`, now hydrate only that DBOS root on a local miss, reconstruct its checkpoint DAG as read-only state, report stale owners as `crashed` with resume guidance, protect fresh foreign owners, and reject cyclic or nonreciprocal topology without claiming, transitioning, dispatching, or auto-resuming the run.
- Fixed stage model fallback end to end: transient failures retry the current model with bounded exponential backoff from `settings.retry` before advancing through `fallbackModels`, unrepairable failures advance immediately, a same-candidate retry no longer loses the stage prompt or stops after a completed assistant message, an eagerly created session walks the whole chain, concurrent callers join the creation already in flight instead of starting a second walk, and a controlled pause no longer aborts the stage or strands its replacement objective ([#2170](https://github.com/bastani-inc/atomic/issues/2170)).
- Fixed workflow stages being unable to use the `subagent` tool at all, and nested subagents in stage sessions losing the bundled `subagent` extension. Stages are top-level sessions rather than subagent children, so stage policy sets `fanoutAuthorized: true`, and in-process child resource loading carries the bundled package roots while disabling only the workflow extension's repeated stage lifecycle. Nesting remains bounded by the typed depth policy and Rust admission's five-level ceiling ([#2220](https://github.com/bastani-inc/atomic/pull/2220), regression from [#2205](https://github.com/bastani-inc/atomic/pull/2205)).
- Fixed the `DISPATCHED` confirmation panel being destroyed by any workflow input containing a newline. Values were truncated by visible width, which a control character does not have, so an embedded newline survived and emitted physical lines no border wrapped — and multi-line `prompt` or `acceptance_criteria` input is ordinary, so this fired for most real launches. String values and the object/array JSON projection now collapse control characters, `U+2028`, and `U+2029` to single spaces before truncation, which also stops escape sequences in an input value injecting ANSI styling into the chat surface.
- Fixed fullscreen workflow graph and stage-chat mouse routing. Focused overlays receive SGR/X10 wheel and click press/release sequences through the host's bounded custom-input reply channel before pi-tui's alternate-screen viewport, restoring graph scrolling and click-to-attach without a workflow-owned TTY-tracking seam ([#2303](https://github.com/bastani-inc/atomic/issues/2303)).
- Fixed a stage chat opened on a stage that was already mid-turn showing an empty transcript. The chat now seeds itself from the stage session's in-flight assistant message when it mounts, and later deltas continue that same message.
- Fixed the stage-chat jump-to-bottom indicator: it stayed hidden in paused and read-only archive chats, and clicking it scrolled the host transcript instead of returning that stage chat to the live end ([#2370](https://github.com/bastani-inc/atomic/issues/2370)).
- Fixed graph overlay rendering details: switcher wheel input scrolling an obscured graph, the scrollbar covering the final graph column, lost live vertical position in `ScrollView`, broken OSC-8 hyperlink terminators, corrupted geometry for unhosted overlays, node cards appending the Codex `fast` marker to dependency metadata ([#2337](https://github.com/bastani-inc/atomic/issues/2337)), and the statusline echoing the `i-have-adhd` badge ([#2341](https://github.com/bastani-inc/atomic/issues/2341), [#2223](https://github.com/bastani-inc/atomic/issues/2223)).
- Fixed completed `ctx.exit()` runs losing the reserved returned-status convention, legacy child replay records losing their exit discriminator, and failed author-exit resume surfaces falling back to snapshot inspection instead of durable retry.
- Fixed late workflow messages and MCP scope cleanup that finish after an extension reload. Stale event-bus calls stop without retrying through stale APIs, stale-context guards consume the host's exported predicate, late-message routing rejects stale drops consistently for Intercom and generic batches, and active routes keep their normal fallback behavior.
- Fixed the inline workflow form editor not inheriting the host's `autocompleteMaxVisible` setting when Atomic installs it as a custom editor.

### Removed

- Removed workflow-owned mouse-scroll reporting and attached-stage copy mode. Fullscreen pi-tui keeps application-owned drag and multi-click selection available over workflow overlays, and `ctrl+t` is left to the host keybindings. Copy still uses OSC 52; terminals that refuse OSC 52 writes require the modifier-drag bypass (Shift/Option, as provided by the terminal).

## [0.9.13-alpha.4] - 2026-08-13

### Added

- Added the shared "Jump to bottom" follow indicator to workflow stage chat when its transcript is scrolled away from the live end, while preserving composer and footer rows in tight overlays.

### Fixed

- Fixed the stage-chat jump-to-bottom follow indicator remaining hidden in paused and read-only archive chats, while keeping their callout and instruction rows intact in tight overlays.
- Fixed clicking the stage-chat jump-to-bottom indicator so its OSC-8 activation returns that stage chat to the live end instead of scrolling the host transcript ([#2370](https://github.com/bastani-inc/atomic/issues/2370)).

## [0.9.13-alpha.3] - 2026-08-13

### Changed

- Workflow model fallback attempt metadata now includes per-attempt input/output tokens, cache reads/writes, provider-reported total cost, and meaningful assistant-turn counts when usage is available ([#2197](https://github.com/bastani-inc/atomic/issues/2197)).

### Fixed

- Corrected stale README claims that `workflow` tool `runId`/`stageId` targets and expanded-graph stage identifiers accept prefixes; run ids require the full 36-character UUID and stage ids/names match whole, matching `resolveRunId` and `stageMatchesExpandedIdentifier` behavior.
- Fixed exact workflow inspection returning `Run not found` after process loss even when DBOS retained a stale running, resumable root. `workflow` status/stages/stage/transcript actions with an explicit full run id and `/workflow status <id>` now hydrate only that DBOS root on a local miss, reconstruct its authoritative checkpoint DAG as read-only state, report stale owners as `crashed` with explicit resume guidance, protect fresh foreign owners, distinguish absent/deleted/malformed records, and reject cyclic or nonreciprocal topology without claiming, transitioning, dispatching, or auto-resuming the run. Status without an id remains current-session-only.
- Fixed long model turns losing their active stage session identity and root liveness when the process died between turn boundaries. Atomic now records stage start before the first session checkpoint, waits for that identity to persist before the first model use, and runs serialized, unref'd 30-second checkpoints for root and nested scoped stages. Heartbeats stop on every exit, refresh root metadata without status transitions, and surface persistent storage or MCP cleanup faults instead of dropping them in detached promise handlers. A checkpoint still in flight when the stage shuts down is drained rather than abandoned, so a late durability failure is never silently discarded, and a stage whose final durability checkpoint fails is recorded as failed instead of completed while its caller still receives the error and its concurrency slot is still released; explicit resume still replays completed effects exactly once.

## [0.9.13-alpha.2] - 2026-08-12

### Breaking Changes

- Custom workflow UI components must return `true` when they consume input and `false` when they do not. In fullscreen mode, an unhandled result lets the transcript process matching viewport navigation keys instead of swallowing them.
- Added `failed` to the `ctx.exit()` status union. Author-initiated failed exits persist their reason and partial declared outputs, return the discriminated `{ exited: true, status: "failed" }` child result instead of throwing, and default to non-resumable unless `resumable: true` is set. Downstream exhaustive switches over `WorkflowExitStatus` must handle the new failed-exit case ([#2242](https://github.com/bastani-inc/atomic/issues/2242)).

### Changed

- Updated the Ralph research stage model configuration. The primary model moves from `openai-codex/gpt-5.6-luna:max` to `anthropic/claude-opus-5:high`, and the fallback chain is rebuilt around high/xhigh thinking levels: GPT-5.6 Sol at `xhigh` replaces the Luna variants, Claude Fable 5 and Claude Opus 4.8 step up from `low`/`medium` to `high`, GPT-5.5 and GLM-5.2 step up to `xhigh`, and Kimi K3 (`kimi-coding`, `moonshotai`, `moonshotai-cn`, and OpenRouter) plus `openrouter/sakana/fugu-ultra:high` join the chain.
- Extended workflow-authoring guidance with a stacked implementation-slices starter pattern: authors target roughly 100–500 changed lines between verification points by default, route each slice through a child lifecycle, explicitly create or check out each named branch before its child because `base_branch` and `git_worktree_dir` alone do not create feature branches, stack each verified branch and worktree, and stop at the first failed gate while preserving earlier verification ([#2262](https://github.com/bastani-inc/atomic/issues/2262)).
- Updated authored-workflow model guidance to treat benchmark thinking levels as measurement settings, assign effort by stage role and failure cost, require a compact `Stage | Model | Thinking | Role` declaration before launch, reserve `max` for high-cost-of-error roles or explicit user requests, and apply catalog-aware role policy to primary and fallback attempts ([#2203](https://github.com/bastani-inc/atomic/issues/2203)).
- Added bounded constructive-quorum deliberation to Goal and Ralph reviewer prompts: reviewers form independent preliminary verdicts, exchange evidence once over Intercom, and record evidence-backed verdict changes before the existing reducer counts final votes ([#2237](https://github.com/bastani-inc/atomic/issues/2237)).

- Rebuilt the workflow graph overlay on pi-tui 0.84.1's `VStack` and `ScrollView` layout primitives. The graph body now adapts to terminal height and resize, supports vertical wheel scrolling and a draggable scrollbar, and keeps wide-graph horizontal panning and existing prompt/navigation key handling ([#2223](https://github.com/bastani-inc/atomic/issues/2223)).
- Retired the legacy terminal-row callback thread from graph and stage-chat views. The two fullscreen-frame consumers still read `terminal.rows` directly: GraphView uses it for the overlay frame, and StageChatView uses it for the chat line count, falling back to the unhosted `VIEW_LINE_COUNT = 32` frame when no host is present. `PiCustomComponent.render` supplies only a width, so the #2223 viewport-row criterion remains partial at those call paths ([#2223](https://github.com/bastani-inc/atomic/issues/2223)).

- Workflow command, worktree Git/setup-hook, and Playwright CLI subprocesses now receive `AI_AGENT=atomic` for generic child-process attribution without mutating caller-supplied environment objects.

### Fixed
- Fixed completed `ctx.exit()` runs losing the reserved returned-status convention, legacy child replay records losing their exit discriminator, and failed author-exit resume surfaces falling back to snapshot inspection instead of durable retry.
- Fixed workflow graph node cards appending the Codex `fast` marker to dependency metadata; cards now show only topology details such as `root`, `1 dep`, or `<n> deps` while fast-mode state remains available to the stage and its model label ([#2337](https://github.com/bastani-inc/atomic/issues/2337)).

- Fixed the workflow graph overlay statusline echoing the `i-have-adhd` extension's `ADHD Mode` badge. The badge remains in the main-chat footer while other extension statuses continue to render in the overlay ([#2341](https://github.com/bastani-inc/atomic/issues/2341)).

- Fixed fullscreen workflow graph and stage-chat mouse routing. Focused workflow overlays now receive SGR/X10 wheel and click press/release sequences through the host's bounded custom-input reply channel before pi-tui's alternate-screen viewport, restoring graph scrolling and click-to-attach without a workflow-owned TTY-tracking seam; the fullscreen route also mirrors consumed left-button events into pi-tui's application-owned selection path ([#2303](https://github.com/bastani-inc/atomic/issues/2303)).
- Fixed graph overlay rendering to keep its live vertical position in pi-tui's `ScrollView` and preserve OSC-8 hyperlink terminators when normalizing layout rows.

- Fixed switcher wheel input scrolling an obscured graph and the scrollbar covering the final graph column; overflow now reserves its scrollbar column and the switcher owns wheel selection ([#2223](https://github.com/bastani-inc/atomic/issues/2223)).
- Restored natural graph geometry for unhosted overlays by removing the fixed-height fallback and kept pi-tui's layout metadata aligned with sparse, deeply scrolled content, so large graphs track their natural geometry without corrupting OSC-8 rows ([#2223](https://github.com/bastani-inc/atomic/issues/2223)).

- Fixed the inline workflow form editor not inheriting the host's `autocompleteMaxVisible` setting when Atomic installs it as a custom editor.
- Fixed late workflow messages and MCP scope cleanup that finish after an extension reload. Stale event-bus calls now stop without retrying through stale APIs, while active routes keep their normal fallback behavior.
- Fixed workflow stale-context guards by consuming the host's exported predicate instead of copying its error-message marker.
- Fixed late-message routing to reject stale drops consistently for Intercom and generic batches, so a resolved route means delivery was accepted instead of silently treating a dropped message as routed; non-stale failures still propagate.

- Fixed the `DISPATCHED` confirmation panel being torn apart by any workflow input containing a newline. Input values were truncated by visible width, which a control character does not have, so an embedded newline survived truncation and emitted extra physical lines that no border ever wrapped — the box was destroyed from that row down. Multi-line inputs are ordinary, so this fired for most real launches: a `prompt` or an `acceptance_criteria` block reliably reproduced it. String values and the object/array JSON projection now collapse control characters, `U+2028`, and `U+2029` to single spaces before truncation, so a run card stays one row per value. `U+2028`/`U+2029` are included because `JSON.stringify` does not escape them and some terminals still break lines on them. As a side effect, escape sequences in an input value can no longer inject ANSI styling into the chat surface.
- Fixed workflow stages being unable to use the `subagent` tool at all. The stage policy set `managementActions: "full"` and `fanoutAuthorized: false` together, which contradict: stages could neither delegate nor, because of the companion subagents defect, run read-only management such as `subagent list`. Workflow stages are top-level sessions rather than subagent children, so the policy now sets `fanoutAuthorized: true`, restoring the delegation the workflow docs already describe. Nesting remains bounded by the typed in-process depth policy and Rust admission’s five-level ceiling ([#2220](https://github.com/bastani-inc/atomic/pull/2220), regression from [#2205](https://github.com/bastani-inc/atomic/pull/2205)).
- Fixed nested subagents in workflow-stage sessions losing the bundled `subagent` extension. In-process child resource loading now carries the bundled package roots and disables only the workflow extension's repeated stage lifecycle, so a stage can delegate and its nested child receives the bundled tools instead of only the base built-in ones ([#2220](https://github.com/bastani-inc/atomic/pull/2220), regression from [#2205](https://github.com/bastani-inc/atomic/pull/2205)).
- Fixed a stage chat opened on a stage that was already mid-turn showing an empty transcript. The stage's assistant message joins the handle's message list only when its turn ends, and streaming updates now carry a delta rather than the message so far, so a chat mounted after the stream started had nothing to draw and nothing that would restate it — a stage held mid-turn stayed blank for the whole turn. The chat now seeds itself from the stage session's in-flight assistant message when it mounts, and the deltas that arrive after that continue the same message.

### Removed

- Removed workflow-owned mouse-scroll reporting and attached-stage copy mode. Fullscreen pi-tui now keeps application-owned drag and multi-click selection available over workflow overlays, and `ctrl+t` is left to the host keybindings. Copy still uses OSC 52; terminals that refuse OSC 52 writes require the modifier-drag bypass (Shift/Option, as provided by the terminal).

## [0.9.13-alpha.1] - 2026-08-05

### Added

- Added four user-initiated workflow lifecycle notices — `started`, `paused`, `quit`, and `resumed` — so the main chat learns when a top-level background run begins, stops, or picks back up. Each travels the same steer delivery, capped-backoff retry, and notice-card path the failure notice already uses, so an agent waiting on a background run no longer mistakes a deliberate stop for work still in progress. `WORKFLOW STARTED` (`▶`), `WORKFLOW PAUSED` (`⏸`, warning tone), `WORKFLOW QUIT` (`⏹`, warning tone, also reporting whether the run stayed resumable), and `WORKFLOW RESUMED` (`▶`) render as cards; the paused and quit text states that the stop was deliberate and user-requested and tells the model not to resume the run or take over the work unless asked, hinting `/workflow resume <run-id>`, while the resumed text does not, because the run is progressing again ([#2177](https://github.com/bastani-inc/atomic/issues/2177)).
- Only user actions raise those notices. `/workflow <name>`, `/workflow pause`, `/workflow quit`, and `/workflow resume` notify; the matching `workflow({ action: "run" | "pause" | "quit" | "resume" })` tool calls stay silent because the tool result already reports them, and `/workflow interrupt` raises nothing. Engine-internal transitions stay silent as well: a notice exists only where a control path recorded an actor, which is what keeps answering a human-in-the-loop prompt, per-stage control, and the resume-acknowledgement pass out of the chat ([#2177](https://github.com/bastani-inc/atomic/issues/2177)).
- Lifecycle notices now carry two attributions. *Origin* — who launched the run — renders on every kind as "which you started" or "which the user started", is recorded once at dispatch, survives session restore and durable resume, and is inherited by a continuation from the run it continues rather than recomputed. *Actor* — who performed this one event — renders as "The user paused". A run with no recorded origin, including a legacy or restored snapshot, omits the clause entirely instead of guessing ([#2177](https://github.com/bastani-inc/atomic/issues/2177)).
- One request now produces exactly one notice. A whole-run pause or resume reports at run scope; a stage-scoped pause or resume that leaves siblings paused reports at stage scope, and one that stops or restarts the whole run reports the run instead, never both. A quit reports the quit alone rather than the pause it publishes on the way. Because control actions are reversible, they are deduplicated by run id together with the occurrence timestamp, so pause → resume → pause → resume notifies four times while repeated snapshot invalidations at one unchanged state notify once. Resuming reports a resume and never a start, whoever requested it: resuming a failed or blocked run launches a continuation under a fresh id whose notice names both run ids, while resuming a quit run reuses the original workflow id so durable checkpoints replay and its notice names the one id. A run already started, paused, or quit when notifications install (restore, replay, `/reload`, session-preserving reinstall) stays silent, and nested child runs never notify at top level. The default `workflowNotifications.notifyOn` becomes `["started", "completed", "failed", "blocked", "awaiting_input", "paused", "quit", "resumed"]`; a config that pins `notifyOn` explicitly keeps exactly the kinds it lists ([#2177](https://github.com/bastani-inc/atomic/issues/2177)).

### Changed

- Workflow stage resource loading now carries typed subagent policy in session options and no longer mutates process-global child environment flags during reload. Concurrent stage creation preserves tool allowlists and orchestration limits without the process-era isolation race ([#2188](https://github.com/bastani-inc/atomic/issues/2188)).

### Fixed

- Fixed thrown transient stage failures — rate limits, provider outages, network timeouts, transport errors — to retry the current model with bounded exponential backoff from `settings.retry` before advancing through `fallbackModels`; disabling retry keeps immediate candidate advancement. Failures another request to the same model cannot repair — a rejected credential, an unavailable model, an incompatible request — skip the same-model retry and advance to the next candidate immediately, for prompt delivery and session creation alike ([#2170](https://github.com/bastani-inc/atomic/issues/2170)).
- Fixed a same-candidate stage retry losing the stage prompt. The retry resumed the existing session turn with a transcript that no longer ended in the prompt it was resuming, which the agent rejects; the prompt is now retained for that path and still re-sent on the re-prompt path ([#2170](https://github.com/bastani-inc/atomic/issues/2170)).
- Fixed a same-candidate stage retry stopping outright when the failed attempt had already streamed a completed assistant message. Resuming the existing turn is now attempted only when the transcript, as converted for the provider, still ends in a message the agent can continue from; otherwise the retry re-sends the prompt, which recovers instead of failing. Messages that convert away — a note excluded from context, an empty branch summary — no longer look like a valid tail ([#2170](https://github.com/bastani-inc/atomic/issues/2170)).
- Fixed an eagerly created stage session never reaching its `fallbackModels`. A session created before any prompt — by an eager stage call, a control attach, or `ctx.__ensureSession()` — retried only its first candidate and then failed the stage. It now walks the configured chain, and a failure that exhausts the chain is no longer cached and replayed to every later caller ([#2170](https://github.com/bastani-inc/atomic/issues/2170)).
- Fixed a paused eager session creation dropping its replacement objective when the stage had explicit model candidates. The resumed text is now authoritative for the next prompt and is sent exactly once ([#2170](https://github.com/bastani-inc/atomic/issues/2170)).
- Fixed a context overflow that compaction had already failed to resolve being retried on the same candidate for the whole `settings.retry` budget. Re-sending an identical request cannot fit a context compaction could not shrink, so the chain now advances immediately while still treating the failure as fallbackable ([#2170](https://github.com/bastani-inc/atomic/issues/2170)).
- Fixed a stage running two candidate walks at once. Advancing a candidate released the shared creation gate while the walk was still creating the next session, so a concurrent `ctx.__ensureSession()` or a first `ctx.prompt()` could start a second walk, duplicate provider work, and leave the losing session live and undisposed. Concurrent callers now join the creation already in flight ([#2170](https://github.com/bastani-inc/atomic/issues/2170)).
- Fixed a controlled pause that both started and finished while a stage session was still being created losing its replacement objective, so the stale objective was prompted instead ([#2170](https://github.com/bastani-inc/atomic/issues/2170)).
- Fixed a controlled pause during a same-candidate continuation aborting the stage unrecoverably. The abort a pause causes is no longer classified as a terminal model failure: the pause settles, and resuming with a replacement objective re-prompts on the same candidate instead of spending a fallback ([#2170](https://github.com/bastani-inc/atomic/issues/2170)).

## [0.9.12] - 2026-08-04

Cumulative release of the `0.9.12-alpha.1` prerelease. The summary below covers the user-visible outcome of that work; the per-change detail remains in the prerelease section below.

### Added

- Added `keepContext` to the public authoring surface: `import { keepContext } from "@bastani/workflows"`. It wraps prompt text so compaction protects it verbatim regardless of the compression ratio, and is a pure, idempotent string helper rather than a `ctx.*` primitive — no graph node, no side effect, callable anywhere a prompt is assembled. `KEEP_CONTEXT_OPEN_TAG` and `KEEP_CONTEXT_CLOSE_TAG` are exported alongside it. Reserve it for text whose loss silently changes behavior — role constraints, acceptance criteria, explicit prohibitions, and identifiers a stage must not lose — and not for bulk context, since protected lines count against the keep target rather than raising it ([#2172](https://github.com/bastani-inc/atomic/issues/2172)).
- `<keepContext>` tags also work in the run inputs and steering messages sent through the `workflow` tool, not only in authored stage prompts. Workflows inject inputs into their stage prompts, so a tagged clause in `prompt` or `acceptance_criteria` is inherited and protected by every stage that receives it, and a tagged `send` amendment survives until the stage acts on it instead of competing with the whole transcript for retention. Because `keepContext` is idempotent, an already-tagged input is not double-wrapped by a workflow that protects the same field. The workflow tool description and agent guidance now say so, so an agent can decide per launch or per steering message which clauses to protect ([#2172](https://github.com/bastani-inc/atomic/issues/2172)).

### Fixed

- Builtin workflows protect their own invariants with `keepContext`, so a long-running stage can no longer lose the rules that bound it: the steering propagation contract carried by every builtin stage prompt, the literal objective contract, scope discipline, worktree discipline, ralph's per-run acceptance criteria, ralph's research-only role constraint, and goal's reviewer "inspect and report; do not implement" constraint. Previously a research stage could be compacted past its own prohibition and start implementing, and a stage could lose the checkout it was bound to ([#2172](https://github.com/bastani-inc/atomic/issues/2172)).

## [0.9.12-alpha.1] - 2026-08-04

### Added

- Added `keepContext` to the public authoring surface: `import { keepContext } from "@bastani/workflows"`. It wraps prompt text so compaction protects it verbatim regardless of the compression ratio, and is a pure, idempotent string helper rather than a `ctx.*` primitive — no graph node, no side effect, callable anywhere a prompt is assembled. `KEEP_CONTEXT_OPEN_TAG` and `KEEP_CONTEXT_CLOSE_TAG` are exported alongside it. Reserve it for text whose loss silently changes behavior — role constraints, acceptance criteria, explicit prohibitions, and identifiers a stage must not lose — and not for bulk context, since protected lines count against the keep target rather than raising it ([#2172](https://github.com/bastani-inc/atomic/issues/2172)).
- `<keepContext>` tags also work in the run inputs and steering messages sent through the `workflow` tool, not only in authored stage prompts. Workflows inject inputs into their stage prompts, so a tagged clause in `prompt` or `acceptance_criteria` is inherited and protected by every stage that receives it, and a tagged `send` amendment survives until the stage acts on it instead of competing with the whole transcript for retention. Because `keepContext` is idempotent, an already-tagged input is not double-wrapped by a workflow that protects the same field. The workflow tool description and agent guidance now say so, so an agent can decide per launch or per steering message which clauses to protect ([#2172](https://github.com/bastani-inc/atomic/issues/2172)).

### Fixed

- Builtin workflows protect their own invariants with `keepContext`, so a long-running stage can no longer lose the rules that bound it: the steering propagation contract carried by every builtin stage prompt, the literal objective contract, scope discipline, worktree discipline, ralph's per-run acceptance criteria, ralph's research-only role constraint, and goal's reviewer "inspect and report; do not implement" constraint. Previously a research stage could be compacted past its own prohibition and start implementing, and a stage could lose the checkout it was bound to ([#2172](https://github.com/bastani-inc/atomic/issues/2172)).

## [0.9.11] - 2026-08-03

### Added

- Added per-node cancellation and abort targeting to `ctx.tool`. Every callback receives a `WorkflowToolContext` (`{ signal }`) combining a per-invocation controller with the run signal, and `workflow({ action: "quit"|"interrupt", runId, stageId })` resolves a tool node by expanded id, local `tool:<argsHash>` id, or tool name. Aborting one node leaves siblings running; existing zero-argument callbacks are unchanged ([#2078](https://github.com/bastani-inc/atomic/issues/2078)).
- Added opt-in `ctx.tool(..., { failureMode: "return" })` for checks that may fail during repair flows, preserving bounded redacted `exitCode`, `stdout`, and `stderr` as typed durable data that replays without rerunning the callback ([#1993](https://github.com/bastani-inc/atomic/issues/1993)).
- Re-added the built-in Goal and Ralph workflows with their typed composition exports, command metadata, tests, and docs.
- Added a run-contract discipline to every builtin workflow: only the user may change a run's contract, mid-run steering and resume text are authoritative amendments, and each stage restates the amendments it received. Every bundled workflow wraps its context once through `withSteeringPropagationContext` (exported from `@bastani/workflows/builtin/steering-context`), so `ctx.task`, `ctx.chain`, and `ctx.parallel` prompts carry it automatically. Implementation stages also freeze acceptance criteria before writing code and keep a deferred list instead of a growing diff.
- Added a draft handoff for `ralph` runs that exhaust their review budget: with `create_pr` enabled, the run opens a draft pull request reproducing every unresolved blocking finding with priority and cited `file:line` instead of leaving the branch unpushed.
- Added the opt-in `autoAttach` workflow-definition field, which opens the graph overlay for interactive top-level named launches, and `ctx.models`, which optionally exposes the host session's model catalog to custom definitions.
- Embedded DBOS Postgres now works when Atomic runs as root on Linux (containers, CI sandboxes, eval harnesses) by resolving an unprivileged system account and keeping the cluster under `/var/lib/atomic-postgres`.

### Changed

- Workflow invocations now assign a stable, non-`default` Intercom group from the top-level run identity and apply it to every Intercom-capable stage. Nested workflows, model fallback, pause/resume, durable replay, and subagent inheritance retain the group; separate runs stay isolated and explicit overrides still win, so authors no longer thread group names manually ([#1999](https://github.com/bastani-inc/atomic/issues/1999)).
- Adopted Claude Opus 5 as the primary model for the Ralph prompt-engineer, orchestrator, and reviewer-A stages, the Goal orchestrator and reviewer stages, and the Open Claude Design chain, with Copilot and OpenRouter mirrors added throughout. Ralph's research and reviewer-B chains keep GPT-5.6 primaries and gain Opus 5 fallbacks.
- Reworked the Goal, Ralph, Open Claude Design, and six pattern-workflow stage prompts, plus the bundled `prompt-engineer` skill (864 → 396 lines), for GPT-5.6, Claude Opus 5, and Claude Fable 5: artifacts before the final query, explicit output and stop contracts, evidence-grounded status claims, damped delegation, and no response prefilling or internal-reasoning requests. Schemas, convergence semantics, and exports are preserved.
- Changed the builtin Goal execution stage from a direct worker into a Ralph-style sub-agent orchestrator that delegates implementation, validation, and documentation through the `subagent` tool and writes `orchestrator-receipt.md`, while retaining Goal's ledger, reviewer, reducer, and optional PR flow.
- Strengthened reviewer prompts with a contract-probe playbook and a code-delta integrity contract: reviewers prove the delta exists in the review checkout before trusting receipts, treat claimed-but-absent work as blocking, and flag modified or deleted pre-existing tests ([#1973](https://github.com/bastani-inc/atomic/issues/1973)).
- Strengthened workflow-authoring and routing guidance to require DAG-only dynamic topologies with pre-launch cycle rejection, bounded loop unrolling, and topology sketches, and to triage multi-item queues into bounded concurrent top-level runs with separate worktrees ([#2010](https://github.com/bastani-inc/atomic/issues/2010), [#2012](https://github.com/bastani-inc/atomic/issues/2012)).
- Added a worktree-discipline contract to Goal and Ralph prompts (work stays in the invoking checkout), and made PR creation an explicitly authorized `create_pr=true` action rather than embedded task text.
- Documented deterministic delivery timing for stage messages: `steer` is consumed after the current response finishes its whole tool batch and before the next model request, `followUp` only when the agent would otherwise stop ([#2074](https://github.com/bastani-inc/atomic/issues/2074)).
- Workflow stage chat now renders Atomic's one-cell `∀` on the shared 88 ms luminance ramp, honours caller-supplied palettes through the detected terminal color mode, and drops redundant overlay status chrome.

### Removed

- Removed the parenthesized context-window authoring token (`(1m)`, `(1.1m)`, `(936k)`, `(long)`) from workflow model strings along with the `contextWindow` / `contextWindowStrict` stage options. Every stage session uses its model's catalog context window.
- Removed Cursor model fallbacks and Cursor-branded Impeccable harness compatibility ([#1994](https://github.com/bastani-inc/atomic/issues/1994)), and removed the built-in `deep-research-codebase` workflow.

### Fixed

- Fixed workflow graph rendering and memory on large fan-outs. Cards, edges, and composed rows clip to the viewport; store observation offers a synchronous invalidation channel plus one memoized immutable graph projection per store version, so a status update no longer `JSON.stringify`/`JSON.parse`-clones the full run payload; and truncated fields plus durable tool-result summaries copy into fresh flat strings, since a V8 SlicedString kept multi-megabyte results alive behind a 240-character summary ([#2100](https://github.com/bastani-inc/atomic/issues/2100)).
- Fixed graceful quit ignoring in-flight `ctx.tool` calls, which previously reported `No controllable stages on run <id>` and left callbacks running. Quit now counts running tool nodes as controllable work, closes the tool-admission boundary, aborts the whole root/nested set, and only then records the durable paused transition. Resume re-executes the cancelled call at the same node instead of replaying a cancellation as data, a caught cancellation cannot publish a completed run over quit's paused record, and a failed durable write still leaves the run controllable so a retried quit can upgrade the pause ([#2078](https://github.com/bastani-inc/atomic/issues/2078)).
- Fixed durable nested `ctx.workflow(...)` resume and completed hydration across fresh processes: boundary identity persists before child dispatch, ids stay stable under reversed parallel ordering, and stale, aliased, cyclic, or nonreciprocal records fail closed instead of flattening an unrelated run. Completed child work and `ctx.tool(...)` effects stay exactly-once, and ambiguous child-local stage ids no longer route to the first match.
- Fixed `ctx.tool()` calls durably completing side effects before a late empty-stage rejection. Tools now create ordered, inspectable, non-attachable graph nodes with live, failed, completed, cancelled, and cached states; tool-only workflows complete normally; and terminal publication closes admission so post-terminal calls reject before any callback runs ([#1991](https://github.com/bastani-inc/atomic/issues/1991)).
- Fixed host-session replacement (`/new`, `/resume`, `/fork`, `/reload`) leaving the process-global DBOS executor stopped, so every later run in the same process failed at its first durable checkpoint with `` `DBOS.launch()` must be called before running workflows ``. The executor lifetime is now process-scoped, and the backend factory never hands out a stopped backend ([#1957](https://github.com/bastani-inc/atomic/issues/1957)).
- Fixed stage message queues across detach and reattach: a typed Enter in an attached stage chat names steering explicitly instead of being demoted to a follow-up, the stage handle keeps its own projection of `queue_update` snapshots so pending rows survive detaching, the graph shows a `✉ N queued` badge, a session that arrives already holding queued messages replays the snapshot its listeners missed, and Escape restores queued steering and follow-ups into the editor ([#2074](https://github.com/bastani-inc/atomic/issues/2074)).
- Fixed controlled workflow pauses allowing queued or late-arriving work to run after a stage was visibly paused. A synchronous raw queue hold is established before one serialized abort boundary, and resume releases preserved steering, follow-up, custom, async, and user entries exactly once ([#1983](https://github.com/bastani-inc/atomic/issues/1983)).
- Fixed programmatic `workflow send` reopening retained stage conversations after the root workflow had terminated; terminal roots now return a structured `WORKFLOW_TERMINAL` failure before any session probing or delivery, while `/workflow attach` and Intercom keep their explicit post-mortem paths ([#2009](https://github.com/bastani-inc/atomic/issues/2009)).
- Fixed three `open-claude-design` faults: a failed `user-feedback-*` stage no longer converts into design approval and exports an unreviewed design ([#2123](https://github.com/bastani-inc/atomic/issues/2123)); research context now persists to `<artifact_dir>/design-context.md` and `references.md` and is read through `reads` instead of embedded inline, removing the `413 request_too_large` class ([#2121](https://github.com/bastani-inc/atomic/issues/2121)); and each refinement round raises a run-level prompt naming the preview path and `file://` URL instead of blocking on live review while reporting `running` ([#2060](https://github.com/bastani-inc/atomic/issues/2060)).
- Fixed the Ralph research stage destroying its own artifact by declaring the authored report path as its runner-owned `output`; research stages now return the full report as their final message. Fixed the Classify-and-act, Fan-out-and-synthesize, Generate-and-filter, Loop-until-done, and Tournament workflows returning whole terminal artifacts into the calling session's context — each `result` is now the compact artifact reference, with the full report on the existing path outputs.
- Fixed admitted durable `ctx.tool(...)` failures being misclassified as killed or cancelled, and fixed failed physical session appends leaving malformed JSONL tails, duplicate ids, or phantom parents after a partial write ([#2021](https://github.com/bastani-inc/atomic/issues/2021)).
- Fixed fresh-process resume and completed-run inspection losing nested child-workflow and parallel hierarchy, and fixed `workflow({ action: "resume", runId })` returning `Run not found` for eligible durably paused runs after session-local state was cleared ([#1924](https://github.com/bastani-inc/atomic/issues/1924)).
- Fixed session teardown crashing the process with exit code 1 after DBOS provisioning had failed, which turned otherwise-successful `--print` runs into nonzero exits. When no durable backend can be provisioned at all, workflows degrade to a loud non-durable in-memory backend instead of failing every action.
- Hardened the bundled `impeccable` live-mode scripts against four CodeQL findings (insecure randomness, resource exhaustion, regex injection, double escaping), preserving behaviour for all valid inputs.
- Fixed retained terminal stage chats dropping the Working indicator after Enter and before the follow-up turn started ([#1982](https://github.com/bastani-inc/atomic/issues/1982)).

## [0.9.11-alpha.11] - 2026-08-03

### Fixed

- Fixed workflow graph rendering for large, wide fan-outs by clipping cards, edges, and composed rows to the visible viewport, retaining cached topology and layout across status-only updates, and making idle animation eligibility constant-time ([#2100](https://github.com/bastani-inc/atomic/issues/2100)).
- Fixed every interactive store mutation cloning the full run payload before the graph could repaint. A status or question update used to build a complete `JSON.stringify`/`JSON.parse` snapshot, traversing workflow inputs, authored stage result bodies, child output values, and tool input/output bodies, so mutation cost scaled with payload size rather than with the graph. Store observation now offers a synchronous invalidation-only channel plus one immutable memoized graph projection per store version, and the graph, overlay, attach pane, stage chat, widget, lifecycle and HIL notifications, resume picker, and send admission all read that projection. In the default configuration (`statusFile: false`), mutations no longer build the legacy full snapshot; enabling `statusFile` retains that snapshot and status-file serialization cost. Topology, status, timing, prompts, attachment state, notices, bounded returned-status fields, durable tool summaries, and child output counts are preserved; the existing `Store.snapshot()` / `Store.subscribe(snapshot)` contract is unchanged for external consumers ([#2100](https://github.com/bastani-inc/atomic/issues/2100)).
- Fixed the memoized graph projection keeping whole run results in memory. Truncating a result field with `slice()` leaves a V8 SlicedString that points at its untruncated parent, so a 1 KiB projected field kept a multi-megabyte run result alive — inside the store's cached projection, and inside every long-lived holder of one — long after the run itself was removed. Truncated fields are now copied into fresh flat strings, so a session with large workflow results no longer grows heap ([#2100](https://github.com/bastani-inc/atomic/issues/2100)).
- Fixed durable tool-result summaries retaining the payloads they summarize. `summarizeToolResult` and `summarizeCompletedToolResult` bounded a serialized value with `` `${serialized.slice(0, 237)}...` ``, which leaves a V8 SlicedString behind a ConsString, both pointing at the untruncated parent — so a 240-character summary written into a durable checkpoint or held in a completed-run catalog row kept the entire `JSON.stringify` output alive (measured at 8.4 MiB for one large tool result). Both summaries now copy into fresh flat strings via a shared `flattenTruncatedString` helper, which the memoized graph projection also uses ([#2100](https://github.com/bastani-inc/atomic/issues/2100)).
- Fixed Escape in an attached workflow-stage chat restoring queued steering and follow-up messages into the editor instead of leaving them stuck in the pending-message queue.

## [0.9.11-alpha.9] - 2026-08-01

### Added

- Added per-node cancellation to `ctx.tool`. Every callback now receives a `WorkflowToolContext` (`{ signal }`) derived from a per-invocation `AbortController` combined with the run signal, so a run abort still cascades to every node while one node can be aborted alone. All retries of a call share that one signal, and existing zero-argument callbacks keep compiling and running unchanged. `WorkflowToolContext` is exported from the authoring surface ([#2078](https://github.com/bastani-inc/atomic/issues/2078)).
- Added tool nodes as addressable abort targets for `workflow({ action: "quit"|"interrupt", runId, stageId })`. A node resolves by expanded id, local `tool:<argsHash>` id, or tool name with the same exact-then-unique precedence and ambiguity diagnostics stages get. Aborting one node marks it `cancelled` and leaves sibling stages and tool nodes running; tool nodes stay non-attachable, so this adds abort, not chat. The result reports the node outcome and the run separately — `status: "cancelled"` with the observed `workflowStatus` — instead of claiming the run was paused. `pause` on a tool node is now rejected explicitly instead of resolving to nothing ([#2078](https://github.com/bastani-inc/atomic/issues/2078)).

### Changed

- Declared `handlesCtrlC` on every workflow surface mounted through `ctx.ui.custom()` — the graph pane (which hosts stage chat, prompt cards, and the inline form) and the inputs picker. In isolated interactive sessions the terminal host now closes an undeclared remote component on the first Ctrl+C, so the declaration is what keeps `ctrl+c Skip`, `ctrl+c Close`, and picker cancel working.
- Documented deterministic delivery timing for workflow stage messages. `steer` (and `auto` against a streaming stage) is consumed after the current assistant response finishes its whole tool batch and before the next model request — never between two tool calls of the same response; `followUp` is consumed only when the agent would otherwise stop. Each queue is FIFO in admission order, and steering keeps priority over an earlier-submitted follow-up, so there is no global FIFO across the two queues ([#2074](https://github.com/bastani-inc/atomic/issues/2074)).

### Fixed

- Fixed `open-claude-design` converting a failed `user-feedback-*` stage into design approval (the [#1499](https://github.com/bastani-inc/atomic/issues/1499) catch-then-approve path). A rejected feedback stage — provider errors, model-fallback exhaustion, broken session forks — now propagates and fails the run instead of silently setting `approved_for_export` and exporting an unreviewed design. Resolved results are unchanged: a stage that runs and reports no meaningful notes, including degraded manual/headless display paths, still legitimately reads as approval, and browser/tooling trouble continues to resolve gracefully rather than reject (playwright-cli auto-install, the early browser exit, and the stage's degradation contract are unaffected) ([#2123](https://github.com/bastani-inc/atomic/issues/2123)).
- Fixed `open-claude-design` embedding unbounded research context inline in single stage prompts, the same single-message overflow class as the [#1499](https://github.com/bastani-inc/atomic/issues/1499) `413 request_too_large`. The composed project design context now persists to `<artifact_dir>/design-context.md` and the curated references brief always persists to `<artifact_dir>/references.md` (with the no-references fallback when discovery is skipped); `reference-discovery` reads the design context, and the generate and exporter stages read both files via `reads` with explicit read-the-file instructions instead of inline `design_system`/`reference_inspiration` embeds. The joined research results are no longer injected as `previous` payloads into `generate-1` or `reference-discovery`. Because the files are required stage inputs, a failed write no longer passes silently: the run exits `blocked` through `ctx.exit` with the artifact paths surfaced (or propagates the error when `ctx.exit` is unavailable) instead of dispatching stages against nonexistent context. Deliberately small inline payloads are unchanged: verbatim-threaded user annotations (the #1464 guardrail) and the word-capped prior design summary ([#2121](https://github.com/bastani-inc/atomic/issues/2121)).
- Fixed `open-claude-design` blocking on browser live review while reporting `running`, leaving the user with no input affordance. Each refinement round now raises a deterministic run-level `ctx.ui` prompt before its `user-feedback-*` stage starts, so the needs-attention badge fires and the prompt names the preview path and `file://` URL; choosing the skip option accepts the current design and proceeds to export. Only the executor's unavailable-UI rejection (headless mode or a missing UI adapter) degrades to running the review directly; any other gate failure — interruption, a failed durable checkpoint — propagates and stops the run. The feedback-stage prompt additionally instructs the agent to print the live `http://` review URL before starting any long-poll wait, so the URL is visible at the top of the stage output when attaching mid-run ([#2060](https://github.com/bastani-inc/atomic/issues/2060)).
- Hardened the bundled `impeccable` live-mode scripts against four CodeQL security findings, preserving behavior for all valid inputs: live-edit session ids now fall back to `crypto.getRandomValues` instead of `Math.random` outside secure contexts (`js/insecure-randomness`); the live server clamps the client-supplied poll timeout to the 10-minute default ceiling (`js/resource-exhaustion`); `live-accept` escapes the `--variant` value before splicing it into a `RegExp` (`js/regex-injection`); and manual-edit evidence decodes `&amp;` last so crafted input cannot be double-unescaped (`js/double-escaping`).
- Fixed worktree setup hooks being reported as failed when they never read their stdin. The hook's JSON input is written to its stdin, but nothing requires a hook to consume it; a hook that exited before that write flushed made `spawnSync` report `EPIPE` and the whole worktree creation was torn down, even though the hook had run to completion and its stdout was captured in full. The child's exit status and output are now authoritative, so only a spawn that never produced a status is treated as a hook failure. Timeouts and every other spawn error stay fatal as before. This race was lost far more often on loaded machines, making it look intermittent.
- Fixed graceful quit ignoring in-flight `ctx.tool` calls. A run whose only in-flight work was a durable tool node reported `No controllable stages on run <id>; the run remains active` and left the callback running with no way to stop it. Quit now counts running tool nodes as controllable work; after stage pauses acknowledge it closes the root-shared tool-admission boundary, so a call admitted during that wait is still included and none can start afterwards — not even while the durable write is in flight. It then aborts the complete root/nested set, waits a bounded interval for settlement, and only then records the durable paused/resumable transition, so quit is again an exact durability boundary rather than a pause declared while a callback is still mutating the world. A call attempted after the close is refused with the graceful-quit signal and never runs. A callback that ignores its signal is abandoned instead of pinning quit, and the result reports cancelled and abandoned calls by owning `{runId, nodeId}` identity, so two nested children sharing one local node id stay distinguishable ([#2078](https://github.com/bastani-inc/atomic/issues/2078)).
- Fixed resume after quitting an unfinished `ctx.tool` call. A cancelled call now writes no replayable checkpoint and no `return_failure` outcome, so a cancellation can never replay as data; under `failureMode: "return"` it keeps exactly one inspection-only `tool-failure:` record, which stays out of the replay cache. Resume recomputes the same ordinal and `argsHash` and re-executes exactly that callback at the same `tool:<argsHash>` node, while completed sibling tools still replay from cache. A late value returned by an abandoned callback is discarded before persistence ([#2078](https://github.com/bastani-inc/atomic/issues/2078)).
- Fixed a quit-time hole where workflow code that caught the tool cancellation could still publish a completed run over quit's paused record: the executor now suspends whenever its own tool work was aborted or refused by a whole-run quit, whichever path the author's code takes afterwards. A catch may clean up, but it is not an opt-out; targeted node abort remains the way to abort one call and keep a run going ([#2078](https://github.com/bastani-inc/atomic/issues/2078)).
- Fixed resume adopting the stale executor after a callback was abandoned. Quit now detaches that background job, so resume relaunches a fresh executor under the same workflow id and actually re-runs the unfinished call instead of flipping the run to running with nothing driving it. Job and cancellation cleanup are identity-conditional and tool-node store writes are generation-owned, so a late zombie callback can neither evict the replacement's registrations nor mutate its graph node, and registering a second job for one live run id is now a loud error instead of silent double dispatch ([#2078](https://github.com/bastani-inc/atomic/issues/2078)).
- Fixed a quit whose durable paused transition failed or was refused leaving the run reported as running with nothing running it. Aborting an in-flight `ctx.tool` call commits its executor to suspending, so quit now records the local pause whatever the durable write does; only the resumable promise follows the durable outcome, and the reported error names the durable failure and what it left behind instead of just failing. The run stays controllable, so a retried `/workflow quit` re-attempts the transition and upgrades the pause to resumable — previously the tool handles were already gone, so the retry answered `No controllable stages on run <id>` and the run could never be quit, resumed, or ended ([#2078](https://github.com/bastani-inc/atomic/issues/2078)).
- Fixed a typed message in an attached workflow stage chat being demoted to a follow-up. When the chat read the stage as idle while workflow message admission still owned the retiring turn, Enter fell through to the unspecified-delivery default and landed at the end of the turn instead of at the next steering boundary, so mid-run correction did not work. Typed Enter now names steering explicitly, matching normal session steering. The choice is scoped to one submission — it travels with the submitting key through the chat host — so a slow in-flight Ctrl+F cannot make a later Enter a follow-up. Ctrl+F still queues a follow-up, a genuinely idle stage still starts a fresh turn, and the authored `stage.sendUserMessage()` default is unchanged ([#2074](https://github.com/bastani-inc/atomic/issues/2074)).
- Fixed queued steering and follow-up rows disappearing when you left a stage. The queue lives on the stage session, but its display lived in the chat pane that detach destroys, so reattaching showed nothing even though the messages were still queued. The stage handle now keeps its own projection of the session's `queue_update` snapshots for its whole lifetime, and reattaching rehydrates the pending rows from it. Because the projection is fed by the events rather than by a concrete Atomic `AgentSession`, a stage backed by a custom `AgentSessionAdapter` keeps its rows too ([#2074](https://github.com/bastani-inc/atomic/issues/2074)).
- Fixed a queued stage message being invisible from the workflow graph. A stage node with pending queued messages now shows a `✉ N queued` badge read from that same handle projection, so a message queued before detaching stays visible without reattaching. The badge claims the node's dim metadata row, or the redundant `waiting for response` row on an awaiting-input node so its `↵ enter to respond` hint survives. Nested child stages resolve to their real run and stage identity, tool nodes are never asked, card geometry is unchanged, and no queue state enters a store snapshot ([#2074](https://github.com/bastani-inc/atomic/issues/2074)).
- Fixed a stage session that arrives already holding queued messages showing an empty queue. A session announces its queue by event, so a queue that exists before this stage's listeners are bound to that session was announced to nobody: a retiring stage session hands its pending messages to the session replacing it, and a retained session reopened for post-mortem chat is restored with whatever it was holding. Both published that queue while the handle's projection was attached to nothing, so the badge read zero and a reattached chat redrew no rows even though the messages were still pending. Attaching a session now replays the one snapshot its listeners missed, read from the session itself; every later change still arrives as an ordinary `queue_update`, and a runtime that does not expose its queues is unaffected ([#2074](https://github.com/bastani-inc/atomic/issues/2074)).
- Fixed Ctrl+F losing its follow-up intent on a stage handle that predates the delivery-aware send. The compatibility path submitted the message as an ordinary prompt, so a follow-up typed while the stage streamed a retiring turn was admitted with prompt delivery instead of waiting in the follow-up queue. Ctrl+F now reaches the follow-up queue exactly while the stage streams, and still starts a turn on a genuinely idle stage — matching what the delivery-aware path does, rather than parking text no turn would consume ([#2074](https://github.com/bastani-inc/atomic/issues/2074)).

## [0.9.11-alpha.6] - 2026-07-28

### Added

- Added opt-in `ctx.tool(..., { failureMode: "return" })` outcomes for checks that may fail during repair flows. Exhausted callback failures now preserve bounded, best-effort redacted `exitCode`, `stdout`, and `stderr` as typed durable data; replay returns the same outcome without rerunning the callback; failed tool nodes remain truthful while explicit downstream repair and bounded reruns continue; and default failures, cancellation, admission errors, and storage faults still throw ([#1993](https://github.com/bastani-inc/atomic/issues/1993)).
- Re-added the built-in Goal and Ralph workflows, including their typed composition exports, command metadata, focused tests, and user-facing docs.
- Added a run-contract discipline to every builtin workflow. Only the user may change a run's contract: mid-run steering, follow-ups, and resume text are authoritative amendments, while agents may never widen the contract themselves. A new steering propagation contract requires each stage to restate the amendments it received under a `Contract amendments received` heading in its handoff, keep them separate from its own observations, treat inherited amendments as contract clauses rather than out-of-scope work, and resolve ambiguity through `intercom` before implementing. Every bundled workflow wraps its run context once through `withSteeringPropagationContext` (exported from `@bastani/workflows/builtin/steering-context`), so `ctx.task`, `ctx.chain`, and `ctx.parallel` prompts carry the contract automatically and a stage added later inherits it. Without propagation an implementer builds to an amended contract while reviewers still score the launch contract and mark the added work as unrequested scope.
- Added a scope discipline contract to builtin implementation stages: freeze the acceptance criteria before writing code, stop when they pass, trace every addition to a criterion, keep a deferred list instead of a growing diff, prefer the smallest diff that satisfies the contract, and report the contract, per-criterion evidence, and deferred items at the end.
- Added a draft handoff for `ralph` runs that exhaust their review budget. When `create_pr` is enabled and the loop ends without unanimous approval, the run now opens a provider-native draft pull request that reproduces every unresolved blocking finding with priority, objective alignment, and cited `file:line`, states the iteration count, and requests no reviewers. Previously the branch was left unpushed with no handoff. Runs without `create_pr` still never touch a pull request, approved or not.
- Added workflow-authoring guidance so, after creating and reloading a custom workflow, Atomic reports `Custom workflow created. You can inspect its code at: <workflow-folder-path>` only for newly created custom workflows, explicitly excluding builtin and pre-existing workflows ([#1978](https://github.com/bastani-inc/atomic/issues/1978)).

### Removed

- Removed the parenthesized context-window authoring token from workflow model strings. `(1m)`, `(1.1m)`, `(936k)`, and the generic `(long)` marker are no longer parsed from `model` / `fallbackModels` entries, and the `contextWindow` / `contextWindowStrict` stage options are gone. Builtin workflow model policies now use plain ids such as `github-copilot/claude-opus-4.8:high`, and every stage session uses its model's catalog context window.

### Changed

- Cleaned up workflow overlay status chrome. The orchestrator pane no longer echoes the host `MCP: <n>/<n> servers` count in its statusline, and attaching to a stage no longer adds a `pi-workflows/<workflow>/<stage>` tag next to the footer statuses in stage chat. Other extension statuses, such as async subagent progress, still render in the orchestrator statusline.
- Changed workflow stage chat to render Atomic's exact one-cell `∀` with a pronounced, theme-aware dark → accent → bright/bold → accent → dark luminance ramp at 88ms and the ordinary one-row working geometry, while preserving `NO_COLOR` weight activity, reduced-motion static accent styling, blocked/prompt chrome suppression, composer space, and factual-state precedence.
- Workflow invocations now assign a stable, non-`default` Intercom group from the persistent top-level run identity and apply it to every Intercom-capable stage by default. Nested workflows, model fallback, pause/resume, durable replay, and subagent inheritance retain the group; separate runs remain isolated; explicit stage/task/parallel groups (including `"default"`) still override it; and stages without Intercom access remain ungrouped. Workflow authors no longer need to mint and thread group names manually ([#1999](https://github.com/bastani-inc/atomic/issues/1999)).
- Strengthened workflow-authoring prompts and docs to require every dynamically materialized execution topology to remain a DAG, reject self-edges and ancestor back-edges before launch, unroll bounded loops into distinct tracked work, distinguish discovery diagnostics from runtime/replay/DBOS topology validation, and require topology sketches for branches, loops, and nested workflow boundaries ([#2012](https://github.com/bastani-inc/atomic/issues/2012)).
- Changed model-visible workflow routing to triage multi-item implementation queues before launch, run independent items as bounded concurrent top-level workflows with separate worktrees and root failure boundaries, preserve ordered composition for real dependencies and clusters, and report per-item run/worktree/branch/results ([#2010](https://github.com/bastani-inc/atomic/issues/2010)).
- Adopted Claude Opus 5 as the primary model for the Ralph prompt-engineer, orchestrator, and reviewer-A stages, the Goal orchestrator and reviewer stages, and the Open Claude Design chain, with `github-copilot/claude-opus-5` and `openrouter/anthropic/claude-opus-5` mirrors added to every affected chain. Ralph's research and reviewer-B chains keep their GPT-5.6 primaries and gain Opus 5 fallbacks. Anthropic candidates now list the direct `anthropic/...` entry ahead of its `github-copilot/...` mirror, and `claude-fable-5` gains its missing Copilot mirror. Goal's orchestrator remains an exact local copy of Ralph's.
- Reworked the shipped Goal, Ralph, Open Claude Design, and six pattern-workflow stage prompts for GPT-5.6, Claude Opus 5, and Claude Fable 5. Prompts now put artifacts before the final query, use explicit output and stop contracts, ground status claims in current tool evidence, damp unnecessary delegation, and request commands, observed results, and file:line evidence instead of internal reasoning; shared reviewer, acceptance, E2E/QA-video, and `stop_review_loop` derivation rules now have canonical definitions. This reduces repetition and avoids Claude Fable 5 `reasoning_extraction` refusals that could force model fallback while preserving schemas, convergence semantics, and exports.
- Rewrote the bundled `prompt-engineer` skill and its three progressive-disclosure references for current GPT-5.6, Claude Opus 5, and Claude Fable 5 behavior, reducing them from 864 to 396 lines. Removed response-prefilling guidance that errors on Claude 4.6+, visible chain-of-thought as a primary technique, and generic self-check loops; added a delete-first optimization workflow, model-family guidance, agentic prompt structure, tool routing, adaptive-thinking effort and response-length controls, query-last long-context ordering, delegation damping, grounded reporting, and the Fable 5 `reasoning_extraction` hazard.

### Fixed

- Fixed the Ralph research stage destroying its own research artifact. The stage prompt told the agent to write the run's research file while the stage also declared that same path as its runner-owned `output`, so the runner overwrote the authored report with the stage's final chat message once the stage ended. Because `reads` passes a path rather than file content, the orchestrator and both reviewers then read a short pointer stub instead of the findings, and each loop re-derived context the research stage had already paid for. Research stages now return the full report as their final message and are explicitly told not to write the artifact path themselves; skill-owned notes under `research/docs/` and `research/web/` are unaffected.
- Fixed the Classify-and-act, Fan-out-and-synthesize, Generate-and-filter, Loop-until-done, and Tournament workflows returning a whole terminal artifact into the calling session's context window. The first three set `outputMode: "file-only"` to keep the parent result compact and then read the saved file back with `readFile` before returning it, cancelling the saving; the last two declared `output` without `outputMode: "file-only"`, so the runner returned the full report text alongside the saved-file reference. Each `result` output is now the compact artifact reference, and the existing `action_path`, `synthesis_path`, `final_path`, and `result_path` outputs carry the full report for callers that want it. Passing file references rather than content is now the documented default for stage handoffs and workflow outputs alike.
- Fixed admitted durable `ctx.tool(...)` callback and command failures being misclassified as killed/cancelled when no run cancellation won, including cancellation-shaped errors and wrappers with nested process evidence. First-event arbitration now preserves the first observed failure error and node even for concurrent same-value errors. Once the workflow body settles, an ordinary failure winner closes tool admission and cancels non-cooperative sibling nodes without needing an external kill; cancellation-first races still end killed. Failed resumable roots remain on the execution-resume path and win direct same-ID collisions with completed read-only history. Awaited and unawaited failures, concise nested command errors, root metadata, and selected tool links survive session and fresh DBOS inspection without becoming replay cache hits. Named interactive launches emit one failed lifecycle card and hidden reconciliation turn; prompt-start retries and restores reuse the card's atomic recovery marker, while status inspection and repeated startup binding do not duplicate it. Failed physical session appends now roll back partial single-entry and initial-batch writes to the exact prior file state, preventing malformed JSONL tails, duplicate IDs, phantom parents, and lost retry entries after reopen ([#2021](https://github.com/bastani-inc/atomic/issues/2021)).
- Fixed durable nested `ctx.workflow(...)` resume and completed hydration across fresh processes. Atomic now persists an awaited, input-bound boundary-start identity before child dispatch, reuses stable boundary/child ids across reversed parallel ordering, keeps identical calls distinct by ordinal, scopes child checkpoint reads symmetrically at every nesting depth, and preserves source stage ids/order/parents/status and exact owner targets. Active and completed topology, boundary lifecycle transitions, and child results are validated atomically before cache/control/child dispatch; stale, aliased, cyclic, poisoned, or nonreciprocal records fail closed without repair execution. Completed child work and `ctx.tool(...)` effects remain exactly once, completed graphs remain root-catalog-only/read-only, retained child chat stays detached from execution, and ambiguous local stage ids or names no longer route to the first match.
- Fixed workflow-supplied working-indicator palettes to quantize through Atomic's detected terminal color mode, preserving the intended phase progression in 256-color and conhost-like environments instead of forcing truecolor output.
- Fixed controlled workflow pauses allowing queued or late-arriving work and continuation to run after a stage was visibly paused. Atomic's native session now establishes a synchronous raw queue hold before one serialized abort boundary; repeated pause and early resume share that boundary, abort failure rollback is explicitly observed and retried, and the existing resume action releases preserved steering, follow-up, duplicate, custom, async, and user-message entries exactly once. Clearing the final item never opens the gate. Existing custom adapters remain compatible without the optional native queue-pause methods and retain fallback abort/suspension behavior, including deferring runner-admitted public deliveries until resume. Fallback replacement installs an acyclic retirement forwarding fence before atomically moving raw/display/protected ownership source-first within each queue kind, serializes source and replacement interrupts through the live owner, clears the source, and leaves the target paused. Completed post-mortem stage chat resumes only its retained conversation queue on the next ordinary submission and never changes terminal workflow state ([#1983](https://github.com/bastani-inc/atomic/issues/1983)).
- Fixed `ctx.tool()` calls durably completing side effects before a late empty-stage rejection. Tools now create ordered, inspectable, non-chat graph nodes with live, failed, completed, cancelled, and cached states; root completion waits for every admitted tool and promotes the first observed admitted failure left by a fulfilled body, while ordinary body rejections keep their exact error and link the selected matching failed tool when available; tool-only workflows complete normally; durable replay reconstructs and migrates topology without repeating callbacks; and completed tool-only runs open read-only without appearing stale or treating inspection as a new lifecycle transition. Terminal publication now atomically closes tool admission after admitted settlement continuations drain, so retained post-terminal calls reject before callbacks, retries, nodes, or checkpoints; rejected legacy child-topology annotation writes remain best-effort cache hits, do not poison DBOS flush, and retry on later replay; top-level status/session projections include nested tools with rewritten graph identity and explicit ownership; and completed retained-session stages remain chat-openable while tool nodes stay non-chat ([#1991](https://github.com/bastani-inc/atomic/issues/1991)).
- Fixed live and restored nested `ctx.workflow()` graphs flattening valid child stages without preserving the authored composition topology. Hidden import boundaries now connect every boundary parent to every child root and every child terminal to downstream parent stages regardless of snapshot order; recursive one-level and deeper composition preserves sibling, sequential, parallel, and repeated child workflows; and boundaries with invalid, missing, empty, stale, mismatched, or recursively unusable child graphs, plus failed or skipped boundaries, retain the boundary summary rather than flattening an unrelated run. Duplicate child-local stage IDs and names keep distinct virtual IDs and exact owning `{runId, stageId}` targets across attach, messaging, pause, interrupt, resume, inspection, selection, and post-mortem chat, while nested runs remain excluded from top-level listings and ordinary workflow graph behavior is unchanged.
- Fixed retained terminal stage chats dropping the Working indicator after Enter and before the follow-up agent turn started; the indicator now remains visible and animated throughout prompt attachment and processing without reviving stale terminal activity ([#1982](https://github.com/bastani-inc/atomic/issues/1982)).
- Fixed programmatic `workflow send` reopening retained stage conversations after the authoritative root workflow had terminated. Completed, failed, skipped, cancelled, killed, and terminal-blocked roots now return a structured `WORKFLOW_TERMINAL` failure before stage or nested-owner resolution, prompt inspection, session probing/revival, handle lookup, admission, or delivery. Atomic rechecks the shared terminal authority at final synchronous SDK admission, including after awaited retained-session creation and paused or isolated-session resume setup; unsafe legacy handle delivery has no fallback. Terminal publication promptly unregisters and disposes an unclaimed provisional handle without waiting for hung session creation, late-created sessions are disposed, and handle replacement revokes stale admission while settling every provisional lease against one disposal. Prompt, model, tool, file, transcript, and workflow-snapshot side effects remain blocked. Live idle/streaming sends, pending-input answers, and explicit paused/interrupted resume remain available, while `/workflow attach` and Intercom can claim the retained handle and keep their explicit post-mortem chat paths ([#2009](https://github.com/bastani-inc/atomic/issues/2009)).

### Removed

- Removed Cursor model fallbacks and Cursor-branded Impeccable harness compatibility from shipped workflows and skills ([#1994](https://github.com/bastani-inc/atomic/issues/1994)).
- Removed the built-in `deep-research-codebase` workflow.

## [0.9.11-alpha.5] - 2026-07-23

### Changed

- Strengthened the existing Goal and Ralph reviewer prompts with a conditional contract-probe playbook for exact external-consumer APIs, build/feature matrices, schema optionality, state transitions, configuration precedence, low-level feature-flag independence, and permissive inputs. Reviewers now record independent probe outcomes in existing evidence fields and withhold approval when a material literal clause remains unverified, without changing reviewer counts, schemas, or convergence semantics. ([#1973](https://github.com/bastani-inc/atomic/issues/1973))
- Strengthened model-visible workflow routing guidance with a pre-launch requirement/risk/evidence coverage pass, a one-launch composition commitment, concrete graph-selection signals, and bounded skeptical-reviewer loops whose model-selected probes are executed authoritatively through durable `ctx.tool(...)` verifier gates rather than model self-report ([#1974](https://github.com/bastani-inc/atomic/issues/1974)).
- Changed the builtin Goal execution stage from a direct worker into a Ralph-style sub-agent orchestrator. Goal now runs `orchestrator-N` stages that track and delegate implementation, validation, documentation, and follow-up repairs through the `subagent` tool; writes `orchestrator-receipt.md`; forks later turns from the prior orchestrator session; and uses a locally contained copy of Ralph's exact xhigh orchestrator model and fallback chain while retaining Goal's ledger, reviewer, reducer, and optional final PR flow.
- Reordered Goal's reviewer fallbacks so GPT-5.6 is tried before Kimi K3 within both the leading direct-provider group and the OpenRouter group, while retaining Claude Fable 5 as primary and preserving each group's position in the full chain.

## [0.9.11-alpha.4] - 2026-07-23

### Added

- Added the opt-in `autoAttach` workflow-definition field, which opens the graph overlay when an interactive top-level named workflow is launched through `/workflow <name>` or the registered `workflow` tool without changing headless launches, nested workflow composition, or the existing input-form launch path.
- `WorkflowRunContext` now optionally exposes the host session's model catalog as `ctx.models` (including `currentModel`, the user-selected session model, and `listModels()`). Custom workflow definitions can use it to select stage models from the live catalog; the field is absent when the host provides no catalog, and builtin workflow model chains are unchanged.

### Changed

- Workflow prompt guidance now instructs agents to give each workflow invocation its own intercom group by default — unless the user requests otherwise — by minting one invocation-scoped literal group name inside the workflow's `run` function (e.g. `"myflow-" + randomUUID()`) and passing it via the `group` option on each stage, task, or parallel step that should share it; `group: true`/`"auto"` mints one shared UUID group per `ctx.parallel(...)` set but a fresh UUID per non-parallel stage. This keeps stage and subagent intercom chatter isolated from the parent chat and other concurrent runs, since ungrouped sessions all share the `"default"` group; subagent inheritance, capability gating, and cross-group `contact_supervisor` escalation are unchanged.
- Attached workflow stage chats now match the main interactive footer by showing the home-shortened current folder with its cached, live-updating Git branch and by mirroring current extension status lines such as MCP connectivity, using the workflow chat theme without replacing the existing hierarchy and copy-mode hints.
- The builtin `goal` and `ralph` workflow descriptions and their `objective`/`prompt`/`create_pr` input descriptions now instruct launching agents that when a delegated task includes submitting a pull request (or MR/review), that final action must be stripped from the objective/prompt text and requested via `create_pr=true` instead when preparing the workflow inputs. This keeps PR creation an explicitly authorized final-stage action rather than embedded task text that intermediate stages are told to ignore.
- Goal worker and Ralph orchestrator prompts now carry an explicit worktree-discipline contract: all work happens in the invoking checkout (or the run's explicitly configured worktree), stages never create additional git worktrees, clones, or repository copies unless the user's task explicitly requests them, and work discovered stranded outside the invoking checkout must be brought back in before continuing. The `git_worktree_dir` input descriptions state the same rule for launching agents.
- Goal and Ralph reviewer prompts now include a code-delta presence and integrity contract: before trusting receipts or stage summaries, reviewers must prove the code delta actually exists in the review checkout using the repository's version-control tooling (for git: `git worktree list`, `git status`, and a baseline diff), treat claimed-but-absent work as a blocking finding instead of approving over an empty or unrelated delta, treat uncommitted work at claimed readiness as remaining work unless the objective forbids committing, and flag any modification, rename, or deletion of pre-existing test files or test functions as a finding requiring explicit justification.
- Goal worker prompts now require committing work in the current checkout with a descriptive message before claiming readiness for review — verifying a clean working tree with the repository's version-control status command and reporting the commit identifier in the receipt — unless the objective or acceptance criteria explicitly forbid committing. Delivery verification stays with reviewers and prompts (version-control-agnostic) rather than a hardcoded git gate in the runner.

### Fixed

- Fixed host-session replacement (`/new`, `/resume`, `/fork`, `/reload`) leaving the process-global DBOS executor stopped so every subsequent workflow run in the same Atomic process failed at its first durable checkpoint with `` `DBOS.launch()` must be called before running workflows ``. The DBOS executor lifetime is now process-scoped: process-preserving session boundaries flush pending durable writes but keep the executor launched, and SDK shutdown is reserved for actual process exit (`quit`/`beforeExit`), which still flushes and shuts down exactly once. Defense in depth: the durable-backend factory revalidates its memoized backend against the current DBOS lifecycle generation and never hands out a stopped backend (post-shutdown initialization fails loudly instead of silently degrading to a non-durable backend), the extension runtime no longer caches a permanently resolved readiness promise across lifecycle generations, and root workflow registration is durably flushed before startup admission so a stopped or unhealthy backend fails before workflow code executes any side effects. ([#1957](https://github.com/bastani-inc/atomic/issues/1957))

## [0.9.11-alpha.2] - 2026-07-21

### Fixed

- Fixed fresh-process workflow resume and completed-run inspection losing nested child-workflow and parallel stage hierarchy. DBOS stage checkpoints now retain owning-run and boundary topology, replay restores source parentage and child runs, graceful quit persists exact sub-30-second stage timing, completed runs persist and display accumulated run duration, and project-local workflows reloaded during a chat are rediscovered from their original invocation directory. The `/workflow resume` and `/workflows` picker rows also no longer display the redundant `N prompts` segment.

## [0.9.11-alpha.1] - 2026-07-20

### Added

- Embedded DBOS Postgres now works when Atomic runs as root on Linux (containers, CI sandboxes, eval harnesses): PostgreSQL refuses UID 0, so Atomic resolves an unprivileged system account (`postgres`, `nobody`, or `daemon`), keeps the cluster under `/var/lib/atomic-postgres` (a root home directory is untraversable for that account), and runs `initdb`/`pg_ctl` with dropped privileges. When the embedded binaries sit under an untraversable prefix (for example a root-owned `~/.nvm` global install), the Postgres runtime is copied into the cluster directory once and reused.

### Changed

- Updated workflow-creation guidance to prefer `ctx.tool(...)` for workflow-owned side effects, connecting durable cached results to safe resume while distinguishing pure TypeScript computation and agent-stage internals ([#1923](https://github.com/bastani-inc/atomic/issues/1923)).
- Clarified the built-in `deep-research-codebase` discovery guidance so agents reserve the heavy workflow for tasks requiring comprehensive whole-repository context ([#1925](https://github.com/bastani-inc/atomic/issues/1925)).
- When no durable backend can be provisioned at all (no `DBOS_SYSTEM_DATABASE_URL`, embedded Postgres unavailable, and no Docker), workflows now degrade to a process-local in-memory backend with a loud non-durable warning instead of failing every workflow action. Degraded runs execute normally but do not survive the process, so `/workflow resume` after exit has nothing to restore; DBOS query and write failures on a provisioned backend still fail the workflow action.

### Fixed

- Fixed `workflow({ action: "resume", runId })` returning `Run not found` for eligible durably paused workflows after session-local run state was cleared. Explicit tool resume now resolves exact IDs and unique or ambiguous prefixes through the authoritative DBOS catalog before refusing the target, preserves original workflow IDs and checkpoint replay, and surfaces resource or durable lookup failures without making ordinary status listing hydrate durable history. ([#1924](https://github.com/bastani-inc/atomic/issues/1924))
- Fixed session teardown crashing the process (exit code 1) after DBOS durability provisioning had failed: `shutdownDbos` re-awaited the memoized rejected configuration promise and rethrew the original provisioning error out of session dispose and the `beforeExit` hook, turning otherwise-successful `--print` runs into nonzero exits (surfacing as `NonZeroAgentExitCodeError` in eval harnesses). Shutdown is now a no-op for a backend that never reached readiness, and genuine teardown failures are logged instead of thrown.


## [0.9.10] - 2026-07-20

### Breaking Changes

- Removed the workflow tool's direct one-off `task`, `tasks`, and `chain` execution shapes and the corresponding `runTask`, `runParallel`, and `runChain` SDK entry points. The tool now accepts only named workflow execution (`workflow` + `inputs`), discovery, inspection, messaging, run control, and reload; direct-only top-level stage/session, worktree, output, concurrency, fail-fast, grouping, async, and Intercom arguments are rejected. Author reusable or task-specific definitions and use the unchanged in-workflow `ctx.task`, `ctx.chain`, and `ctx.parallel` primitives instead.
- Workflow persistence now requires DBOS/Postgres. Removed the local JSON/SQLite backend, user opt-out/backend selection, session-JSONL discovery, and support for prior durable formats; existing local or older DBOS workflow data is not converted.
- The `/workflow resume` picker is now host-native ONLY and requires the host session-picker capability (`ctx.ui.hostSessionPicker`, Atomic's interactive hosts — both isolated and non-isolated — expose it with one identical API). The picker mounts the real built-in session selector directly in the terminal process, so arrow-key navigation and search never cross the host⇄extension boundary and stay instant even while the extension's event loop is busy (e.g. during catalog hydration or run-store refreshes); this also removes the per-keypress render round trip the remote-rendered picker paid under engine isolation. The previous remote-rendered `ctx.ui.custom()` selector path was deleted with no fallback: on a host without the capability, `/workflow resume` (picker form) now fails with one actionable error suggesting `/workflow resume <id>` instead of degrading. All picker semantics carry over unchanged — live rows seed the first frame, the durable/completed catalog hydrates once and merges into the open picker, watch/poll refreshes push row updates, deletion remains extension-owned with live rows protected ("Cannot delete an in-flight workflow run"), and the resolved catalog is still returned for the follow-on resume. The headless/non-interactive printed-list flow is unaffected.

### Added

- Unified workflow **post-mortem stage chat** across every inspection surface. Any eligible terminal agent stage with a valid retained session now reopens as an interactive follow-up conversation — not only completed-workflow inspection (#1758), but also generic `/workflow attach` / `/workflow connect`, restored/replayed durable snapshots after a process restart, and `workflow({ action: "send" })`. A shared runtime resolver (`ensurePostMortemStageHandle`) validates the retained session is an existing, readable, context-bearing Atomic transcript, then lazily reopens it through a detached, single-flight stage-control handle keyed by the real `{ runId, stageId }` (including nested/expanded child stages). Follow-up turns are appended in place to the retained session and the agent keeps its ordinary tools, while run/stage status, results, timings, checkpoints, replay metadata, and graph topology remain immutable — post-mortem chat can never resume, retry, rewind, pause, or re-dispatch workflow execution. Explicit `workflow send` delivery modes `resume` and `steer` on a completed post-mortem stage return a structured `noop` with follow-up guidance and do not append the supplied text. Stages without a valid retained agent session (prompt/HIL and boundary/summary nodes, skipped nodes, non-terminal handle-less stages, and missing/malformed/deleted session files) keep the existing read-only transcript, and recoverably failed stages retain their execution-resume semantics. `workflow send` now revives such a stage on a registry miss and delivers the message as a conversational follow-up instead of reporting `No live handle for stage.` ([#1811](https://github.com/bastani-inc/atomic/issues/1811))
- Added resumable `/workflow quit [run-id|--all]` and `workflow({ action: "quit" })` controls, preserving exact run-id, unique-prefix, active-run default, bulk, terminal, and ambiguity handling.
- Added six composable builtin pattern workflows: `classify-and-act` (structured confidence routing with human fallback), `fan-out-and-synthesize` (bounded artifact fan-out and evidence synthesis), `adversarial-verification` (fresh-context rubric verification with bounded repair), `generate-and-filter` (candidate generation, dedupe, filtering, and optional judging), `tournament` (balanced pairwise comparison and auditable bracket reduction), and `loop-until-done` (durable progress ledger with explicit completion and inspectable bound exhaustion). Each ships with bounded typed/defaulted inputs, dedicated stage prompts, parent-consumable declared outputs, and an export from `@bastani/workflows/builtin` for nested `ctx.workflow(...)` composition.
- Added a `group` option to workflow stages, tasks, parallel steps, and run-level defaults (`context`/`stage`/`task`/`parallel`) that sets each stage session's intercom home group so orchestrated stages can be isolated into coordination groups. A named string joins that group; `true` auto-generates one shared UUID group per parallel set (minted once and shared across every item in the set, never per-item) so a whole level lands in the same isolated group. Precedence is most-specific-first (`parallel-item > task/stage > parallel-step > run-level`), resolved into a per-session `orchestrationContext.intercomGroup` that is race-safe across concurrently running in-process stages (no global env mutation) and stable across model-fallback session replacement. Group assignment is gated on intercom capability: a stage with `noTools`, a `tools` allowlist omitting `intercom`, or `excludedTools` containing `intercom` is never placed into a group. Subagents spawned by a grouped stage inherit that stage's group by default (overridable per subagent), so a reviewer level and its helper subagents form one isolated group. The builtin `goal` and `ralph` workflows now isolate each reviewer level into its own group (`goal-reviewers-turn-N` / `ralph-reviewers-iter-N`): same-level reviewers can intercom each other but cannot reach the worker, orchestrator, parent chat, or other levels, which also keeps reviewer intercom chatter out of the main/parent context window.
- Added `/workflows [run-id]` as a retained-run alias for `/workflow resume`, plus confirmed Ctrl+D deletion for non-live durable/completed rows. Deletion rechecks same-process activity and authoritative status, atomically refuses `running` workflows, updates the catalog, and leaves host/stage session transcripts untouched.
- Added zero-configuration workflow durability: when no `DBOS_SYSTEM_DATABASE_URL` is set, Atomic runs DBOS against its own embedded Postgres built from npm-distributed binaries (`embedded-postgres` platform packages) — no Docker daemon or system Postgres install required. The cluster lives under `~/.atomic/postgres/v18` on dedicated port 5439, is initialized once, started as a detached daemon via `pg_ctl` (surviving Atomic exit and shared across concurrent sessions, never stopped by Atomic), and native lib symlinks are hydrated at runtime so `--ignore-scripts`/Bun installs work. DBOS's reusable `dbos-db` Docker container remains only as a fallback when the embedded binaries are unavailable for the platform; if both are unusable, the workflow action fails with one actionable message instead of a raw connection dump, and DBOS internal logging is routed to a silent logger so connection probes cannot spam the TUI.
- Added multi-session coordination for concurrent Atomic processes sharing one DBOS database: each process launches DBOS with a unique executor id; running root workflows carry owner/heartbeat metadata (refreshed by the ≤30s stage-timing checkpoints); another session's fresh-running workflow is hidden from the resume picker and refused by direct `/workflow resume <id>` with an actionable message until its owner pauses, quits, or its heartbeat goes stale; and contended paused→running transitions are decided by a durable first-writer-wins claim record so exactly one session dispatches the resumed run. Hydration preserves the authoritative `updatedAt` heartbeat instead of stamping local time.
- Made the `/workflow resume` picker live-updating: rows re-list on local run-store changes (debounced) and through a bounded cross-session poll (default 5s) while the picker stays open, so a workflow that pauses, fails, or completes appears — and a freshly running one disappears — without reopening. Watchers and timers stop when the picker closes, and a failed refresh keeps the previous rows.
- Running workflows are no longer resume targets anywhere: a running row with a fresh ownership heartbeat is hidden from the picker and the catalog regardless of which session owns it, eliminating double-dispatch of one workflow from two sessions. Only stale-heartbeat running workflows surface, presented as red `crashed` rows rather than `running`. Picker rows now carry semantic colors: completed green, paused yellow, failed/blocked/crashed red.
- Refined the workflow tool's `status` action into a first-class session run listing. `workflow({ action: "status" })` without a `runId` now returns concise per-run summaries alongside the full snapshots: run id and abbreviated prefix, workflow/run name, run status, started/ended timing plus pause-adjusted elapsed time, currently active stages, and awaiting-input details (count plus the stage, prompt id, kind, and message for each pending human prompt) — everything needed to feed `pause`/`resume`/`interrupt`/`quit`/`send` directly. In-flight runs are listed first. The agent-visible text output is now a concise per-run summary list instead of a raw snapshot dump, and `format: "json"` returns the structured listing.
- Added `statusFilter` support to the `status` run listing: run statuses (`pending`/`running`/`paused`/`blocked`/`completed`/`failed`/`skipped`/`cancelled`/`killed`) filter runs directly, `awaiting_input` selects runs with at least one stage awaiting input or pending human prompt, and `all` (the default) includes everything. The `cancelled` and `killed` filter values are newly accepted, and the tool schema descriptions for `action`, `runId`, `statusFilter`, and `format` now document the no-`runId` listing mode so agents can discover it.

### Changed

- Changed workflow hierarchy navigation to an unconditional Ctrl+X chord: attached stage chats now preserve composer and prompt drafts and pending custom questions while returning to the graph, and graph overlays return to main chat even with switchers or legacy prompts open. Ctrl+D retains ordinary editor/prompt behavior, `q` remains printable in text-owning prompts, workflow surfaces take Ctrl+X precedence over configurable actions, and graph/stage guidance now states the destination explicitly.
- Reworded workflow-start guidance around actionable `/workflow connect <run-id>` commands so users know they can see agents working and chat with or steer each stage.
- Reworked runner-managed Git worktrees to use Claude Code's git-native lifecycle: canonical main-root anchoring, `.atomic/worktrees/` locations, `worktree-*` branches with default-remote base resolution, local-settings/hooks/ignored-file setup, configurable `worktree.symlinkDirectories`, and force-remove plus branch-delete cleanup. Reusable `gitWorktreeDir` creation is now anchored at the canonical main root while retaining its existing path, validation, and cache semantics.
- DBOS is configured, registered, and launched lazily on the first workflow action (never during CLI/session startup), reused process-wide, and readiness is awaited across workflow execution, control, resume, inspection, and deletion paths. Initialization and persistence failures fail the workflow action; no alternate backend is selected.
- Debounced durable stage-session timing checkpoints into 30-second buckets. Duration-only progress no longer forces a full durable state read-merge-rewrite on every prompt/steer event; session identity changes (session id/file/start) still persist immediately, so cross-process resume continues from the same retained session with at most a 30-second loss of accumulated timing precision.
- Matched coding-agent `/resume` retention semantics for workflow history: all eligible durable runs remain searchable regardless of age or count, with no automatic history GC; the 10-row selector viewport remains display-only.

### Fixed

- Fixed live workflow stages abandoning their objective after a user-queued message across every delivery path: attached-stage-chat steering (Enter) and follow-up (Ctrl+F), including the chat host's SDK-direct `AgentSession.prompt(..., { streamingBehavior })` bypass; `workflow({ action: "send" })` `steer`/`followUp`; and workflow-author `StageContext.steer()`, `followUp()`, or streaming `sendUserMessage()`. Workflows now detect when the SDK actually consumes queued user messages and inject the exact deterministic continuation prompt ("Continue where you left off. If you believe you are finished with your original task (or a redefined task if the user told you), stop.") once after the consuming turn, even when the readiness gate is disabled. Multiple consumed messages coalesce into one injection, initial/idle and injected continuation prompts cannot re-arm the mechanism, aborted/finalized/fail-fast-skipped stages remain suppressed, and pause→resume continuation still requires the readiness gate.
- Fixed session-boundary races in lazy post-mortem stage-chat attachment so every host session replacement or shutdown (`new`, `resume`, `fork`, `reload`, and `quit`) synchronously invalidates detached handles; a retained-session creation that finishes after the boundary is disposed and its already-submitted prompt is rejected instead of executing in the replacement session or leaking an unowned SDK session.
- Fixed explicit `/workflow attach <root-run> <nested-stage>` commands to resolve expanded child stages through their owning nested run, preserve that owner through overlay retargeting when sibling child runs reuse the same local stage ID, and retain post-mortem resolver failure reasons so invalid or unavailable sessions render a complete actionable `SESSION UNAVAILABLE` explanation—even at the supported 40-column minimum—instead of a misleading archived-transcript label. Reopened nested terminal stages now restore cwd from their durable root workflow metadata (preferring the resolved workflow cwd, then the original invocation cwd) rather than silently falling back to the current review checkout.
- Hardened repository release recovery so externally merged PRs require exact current identity, refs, SHA, checks, merge evidence, and retained branch state. Workflow-qualified Actions reruns use name plus workflow; empty-workflow external statuses and GitHub App checks support linked kind/name grouping and linkless cross-kind inspection. All-passing linkless candidates and duplicate aliases are accepted, while any pending/failure blocks and nonempty-workflow Actions remain excluded. Checks refresh after merge, tag recovery proves `verified merge → tag parent → current base`, protected dispatch coordination retains its lock through ambiguous acceptance visibility, and recovered success is bound to the exact integrity-job tag SHA.
- Fixed workflow stage-chat compaction to show one reason-aware animated spinner for manual, automatic-threshold, and overflow compaction, retain the normal expandable `✻ Context compacted` boundary when the live session snapshot is temporarily unavailable, and contain `/compact` cancellation or planner/provider rejection after its authoritative `compaction_end` event so the CLI and stage remain usable.
- Fixed workflow stage finalization to atomically close the AgentSession notification-admission boundary before publishing terminal snapshots. Already-admitted Intercom and async completion turns are drained and reflected in the terminal result, while late detached traffic cannot mutate/reopen the stage and is routed externally. The boundary does not wait for producers that are still running and preserves deliberate post-completion `sendUserMessage` and post-mortem chat.
- Fixed live in-process workflow resume so quitting a chain stage mid-turn and resuming without a message re-drives the interrupted stage with the continuation prompt before result harvesting, preventing partial assistant text from being durably checkpointed or handed to downstream `{previous}` stages while preserving explicit-message and cross-process durable resume behavior. ([#1829](https://github.com/bastani-inc/atomic/issues/1829))
- Made graceful quit wait for live stage pause acknowledgement before persisting resumable state, report runs with no controllable stage as still active, propagate rejected pauses instead of claiming success, and reconcile session-restored running snapshots with authoritative paused durability so `/workflow resume` legally redispatches them.
- Made bulk quit settle every run and report per-run failures, made pause/resume state follow asynchronous control acknowledgements, synchronized successful resume back to durable state, and shared paused/orphaned-running durable shadow recovery across slash and workflow-tool resume.
- Made graceful `/workflow quit` propagate durable backend failures for workflows that are durably tracked: `markDurableQuit` now swallows errors only while discovering whether a run has durable state, and lets a failed paused-status transition or flush (for example an unwritable/unknown default file-backend state) surface instead of masking it as `not_needed`. Quit no longer records a resumable pause or reports success when the persistent backend never captured the paused state, so a follow-up process cannot be left with nothing to `/workflow resume`.
- Made graceful quit recognize live/synthetic awaiting-input and already-paused states without cancelling prompts, persist race-safe unresolved prompt counts across file/in-memory/DBOS backends, and hold answered quit prompts behind explicit resume before checkpointing.
- Made durable resume shadows use the authoritative progress predicate, leaving zero-progress restored orphans untouched, and made multi-stage resume settle every acknowledgement, reconcile truthful partial-running durability, retain failed paused stages, and report aggregated run/stage failures.
- Fixed prompt replay/reservation identity and cross-instance atomicity for scoped, file, and DBOS durability; refreshed prompt pause barriers on every quit; reconciled late resume outcomes and durable-write failures from visible state without reviving terminal runs; and added connect guidance to direct asynchronous accepted results.
- Made prompt releases consume one identity-owned reservation generation at most once, with persisted file/DBOS release tombstones and saturating legacy-scalar migration; made author callsites stable across process working-directory changes; composed nested parent/child checkpoint scopes; and made later resume requests retry a paused durable handle after local resume already succeeded.
- Made resume-shadow reads and conditional lifecycle writes use one authoritative durable generation, preventing stale file instances from reviving terminal workflows; reconciled fulfilled quit controls and nested child resume progress through aggregate root Store/durability; preserved DBOS prompt-token ownership across workflow re-registration; and made mixed bulk quit outcomes report ordered partial successes.
- Reported fulfilled resume acknowledgements whose controls finish before aggregate root finalization as successful progress instead of falsely claiming that no paused stages existed.
- Made DBOS conditional lifecycle transitions terminal-absorbing under concurrent metadata writes, made legacy custom backends without an atomic transition primitive refuse safely, and distinguished omitted prompt counts from explicit new reservation-ledger baselines during DBOS re-registration.
- Fixed attached stage-chat footers at the supported 40-column minimum to keep truncated provider/model context separated from the compact Ctrl+X/Copy Mode controls instead of merging both segments into corrupted text.
- Fixed stage-less named workflow body failures such as a throwing `ctx.tool()` being misclassified as killed instead of retained as failed with their concrete startup error.
- Fixed busy workflow stages deadlocking when a foreground subagent waited on Intercom or blocking `contact_supervisor`. Exact foreground-owner detach now completes before the request enters the stage generation boundary, owner loss before commit falls back to normal open-stage admission, and parallel foreground groups release aggregate supervision while retaining every child's lifecycle and result recovery. Native workflow messaging and terminal close semantics remain unchanged.
- Fixed Ctrl+O (`app.tools.expand`) being consumed without expanding tool and workflow-node detail in attached workflow stage chats under Atomic's isolated interactive engine. The remote workflow pane now preserves pi-tui's key-release opt-in contract, so Kitty terminals cannot deliver both the press and release as two expansion toggles that cancel each other. Repeated expand/collapse toggles match main chat across active and completed runs, single/parallel/chain views, and narrow terminals while prompts, custom questions, and unrelated keybindings retain input ownership.
- Fixed authored `ctx.parallel(...)` calls treating string auto-group sentinels such as `group: "auto"` as literal group names. The engine now normalizes trimmed, case-insensitive `"auto"`/`"true"` values at both set and per-step levels before deciding whether to mint one shared UUID for the parallel set. Separate sets still receive distinct UUIDs, boolean `true` remains supported, and named groups stay literal.
- Fixed `/workflow <name>` forms hanging under Atomic's isolated interactive engine when required inputs were missing. The command now prefers the host-native input-form capability, so the form is mounted and focused in the terminal host and Tab/Shift+Tab, arrows, text editing, configured keybindings, Enter, Escape, and Ctrl+C remain responsive without per-keypress engine traffic. Escape/Ctrl+C cancel without dispatch, supplied/default values and typed coercion are preserved, and the existing inline-editor and remote-custom paths remain compatibility fallbacks for older hosts.
- Fixed named workflow startup feedback so pre-body setup failures, including a `goal` run whose `git_worktree_dir` points inside the invoking checkout, return immediately from the original workflow tool call as a structured failed result with the concrete setup error and allocated run id instead of first claiming background acceptance and relying on a later lifecycle notice. Successful named runs still return promptly after startup admission without waiting for workflow completion; failed admission now cleans job, cancellation, store, and durable state, and continuation/durable-resume launches preserve resumability while reporting their startup error.
- Fixed named background workflows that stopped on a recoverable provider, authentication, or rate-limit failure without notifying the invoking chat. Top-level active/resumable blocks now emit one deduplicated `WORKFLOW BLOCKED` lifecycle card per blocked occurrence (keyed by run id and blocked timestamp, so a resumed workflow that hits another recoverable block re-notifies), delivered through native idle-prompt admission when the parent chat is idle or persisted directly to the transcript when it is streaming; status/headless surfaces report blocked; and durable state retains blocked/resumable discovery across session boundaries and exposes the run in the resume picker. Lifecycle delivery commits dedupe only after admission succeeds and retains the original payload with capped-backoff retries while the invoking chat remains active, including across run-state changes and notification reinstallations; session replacement cancels and clears those attempts. Resuming an active block dispatches a fresh-ID continuation that replays completed stages and re-runs the failed one; the durable source is left untouched (stays blocked/resumable for crash recoverability, including zero-checkpoint first-stage blocks) and the local source snapshot is killed so the same session will not re-resume it; a process-local claim prevents concurrent same-session double-dispatch. Historical restore seeding, headless duplicate suppression, nested workflows, and human-input prompts remain non-notifying.
- Fixed completed workflow stages being visible to Intercom but unable to process a sibling's blocking `intercom.ask`. The late-message handoff now carries exact run/stage ownership into the shared post-mortem resolver, serializes wakeups per retained conversation, reopens only eligible completed sessions without mutating workflow execution, and reports deleted, invalid, non-resumable, or failed revival targets within a bounded interval. Claimed completions now have single-owner semantics across the production workflow and Intercom listeners, so listener registration order and duplicate listeners cannot replace or double-deliver the authoritative revival result. Exact child-to-child reply correlation remains isolated from parent and unrelated sessions ([#1854](https://github.com/bastani-inc/atomic/issues/1854)).
- Fixed interactive non-schema stages treating typed/freeform `ask_user_question` chat answers as an invisible implicit “stay”. The conversational acknowledgement now precedes a brokered readiness gate; in that chat flow, Not ready allows a genuine chat turn before readiness is asked again and Ready releases dependents. Structured-option behavior remains unchanged, and schema-finalized stages remain terminal. ([#1849](https://github.com/bastani-inc/atomic/issues/1849))
- Fixed idle live workflow-stage messaging so `workflow send` `followUp` and eligible `auto` deliveries start a real prompt instead of stranding an unconsumable queue item, while streaming follow-ups remain queued and steering remains in-turn. Send results now report the action actually taken. Paused idle stage-chat waits resumed with a non-empty message start exactly one recorded prompt, while interrupted streaming resumes preserve their existing nonduplicating loop and lifecycle/abort guards prevent late prompt creation. Custom `AgentSessionAdapter` implementations now have a typed public `agent_start`/`agent_end` subscription contract for asynchronous ownership through both native `sendUserMessage()` and the optional-method `prompt()` fallback. Serialized admission retains generation-correlated logical turn ownership after `agent_start`, preventing a second idle prompt when an adapter's public `isStreaming` state publication lags its lifecycle event. Untagged synchronous replay snapshots no longer consume a current end; adapters whose replayed turn may end after a newer turn starts can provide a stable `turnId` for exact old-end correlation. Late terminal events, older promise settlement, rejection, and abort cannot clear a newer turn. Stage-chat input handled by an extension remains accepted if the stage becomes terminal during handling instead of reporting rejection after the side effect ([#1850](https://github.com/bastani-inc/atomic/issues/1850)).
- Fixed durable `/workflow resume` restarting workflow timers: the resumed run's total duration in the main-chat dashboard and status surfaces now inherits the elapsed time accumulated before the quit/failure (prior sessions + current session) instead of resetting to zero, and a resumed mid-running stage's timer continues from its previously accumulated elapsed time. The run's total accumulated elapsed is persisted durably alongside the existing 30-second stage-timing checkpoints, exactly at graceful quit and recoverable-failure boundaries, and round-trips through DBOS hydration and session-entry restore. In-process continuation resumes of failed runs inherit the source run's total the same way.
- Fixed background workflow activity flickering the main-chat tail and snapping native terminal scrollback back to the live bottom after wheel-scrolling away ([#1856](https://github.com/bastani-inc/atomic/issues/1856)). The below-editor workflow companion remains one long-lived mounted component: semantic changes and elapsed-clock updates repaint it in place without `setWidget` dispose/remount churn, byte-identical store mutations do not broadcast redundant host renders, and hidden workflow graph/stage overlays do not request host renders on store updates. A visible running workflow's elapsed label now advances continuously from `0s` on exact one-second boundaries without requiring an orchestrator-panel switch; paused labels stay frozen, and ended cards retain only their one-shot ~30-second expiry timer.
- Normalized `DBOS_SYSTEM_DATABASE_URL` handling: the URL is trimmed before being handed to DBOS, so values injected from secrets managers or env files with trailing whitespace/newlines connect cleanly, and a whitespace-only value is treated as unset. Explicit-URL precedence is unchanged — when the variable is set, Atomic never provisions its embedded Postgres or Docker fallback, including on connection failures, which surface as actionable errors against the configured database.
- Fixed completed and in-progress workflows disappearing from `/workflow resume` in a fresh Atomic process. Stage-session timing checkpoint writers omit topology; the in-memory mirror defaulted it on write but the DBOS persist path encoded the raw checkpoint, so cross-process hydration classified those records as foreign and suppressed the whole workflow. Topology is now normalized at the shared encode boundary, making the durable record identical to the mirror (regression-tested through a full write→fresh-hydrate round trip). Runs persisted before this fix keep their topology-less records and remain hidden; re-run or delete them.
- Fixed DBOS step/metadata writes returning before the underlying checkpoint workflow completed: `recordStepOutput` now awaits the stored result (resolving duplicates to the first durable record), so a passed `flush()` boundary guarantees the write is durable and readable — required for correct cross-process claim reads and crash-safe checkpoint exposure.
- Fixed the resumed workflow graph overlay ignoring the mouse wheel (wheel gestures scrolled native/main-chat scrollback) under Atomic's isolated interactive engine. The graph overlay adapter runs inside the engine child, whose stdout is the JSONL transport rather than a TTY, so writing mouse-tracking escape sequences to its local `process.stdout` was a no-op and the host TTY never entered mouse-reporting mode. The adapter now prefers the host's typed remote terminal-control capability exposed on the factory TUI's `terminal` (`setMouseScrollTracking`/`setAutowrap`) so the real host TTY enters mouse-reporting (and Windows autowrap) mode, routing wheel input to the remote `GraphView` scroll offsets while a visible overlay captures the mouse; stage-chat wheel capture and Ctrl+T copy mode continue to work, and main-chat scrollback no longer moves while a visible overlay owns the mouse. Non-isolated hosts and existing test seams keep the local `process.stdout` fallback. Modes are reset on overlay hide/close/dispose and on engine crash/restart, and `/workflow resume` selection deterministically disposes the inline picker before the fullscreen overlay mounts and is focused.
- Made `/workflow resume` mount its picker before loading workflow resources or the durable/completed catalog. Eligible live runs seed the first rendered frame and the durable/completed catalog now hydrates asynchronously, merging its rows into the open picker on resolve instead of blocking the slash command until the scan finishes. Catalog errors render inside the still-usable picker when live rows are present, closing the picker cancels late hydration and ignores stale results, and the resolved catalog is reused for the follow-on resume so there is no second scan. Together with the coding-agent long-lived-RPC timeout fix, this removes the `Timeout waiting for response to prompt` failure when opening `/workflow resume`.
- Hardened the durable workflow catalog against cross-process races: rebuild publication now serializes its final signature/marker verification with incremental writers and never consumes a marker created after scanning began; one-row updates no longer bless unrelated external additions, deletions, or edits; and automatic terminal-file pruning rechecks the authoritative status under the per-workflow lock so a concurrently resumed `running` workflow survives.
- Prevented blocking workflow author/stage code from freezing the Atomic terminal by running the interactive agent engine and bundled workflows extension in the supervised engine child. Workflow commands, tools, custom graph/picker components, and stage callbacks retain child-owned closure state while the terminal host continues input and render ticks; watchdog diagnostics identify the active callback and interrupted results remain explicitly unknown until resumed from an authoritative checkpoint.
- Fixed the host TUI flickering (rapid full repaints at ~58 Hz) when the `workflow` tool's `quit`/`pause` action ran while a workflow stage was actively streaming. The root cause was not in the workflows extension: under Atomic's isolated interactive engine, rendering the first tool card of a turn (typically the `workflow` quit/pause call, but any tool call reproduced it) entered a self-sustaining host⇄engine render ping-pong in the remote tool-card renderer, which fought the still-streaming turn. The renderer fix ships in `@bastani/atomic` (see the coding-agent changelog); quitting or pausing a streaming workflow now renders its tool card once and stays quiet.

### Removed

- Removed public workflow `kill` slash/tool actions, completions, picker shortcuts, confirmations, renderers, and help/docs while retaining internal cancellation machinery used by engine and session lifecycle paths.

## [0.9.10-alpha.1] - 2026-07-19

### Breaking Changes

- Removed the workflow tool's direct one-off `task`, `tasks`, and `chain` execution shapes and the corresponding `runTask`, `runParallel`, and `runChain` SDK entry points. The tool now accepts only named workflow execution (`workflow` + `inputs`), discovery, inspection, messaging, run control, and reload; direct-only top-level stage/session, worktree, output, concurrency, fail-fast, grouping, async, and Intercom arguments are rejected. Author reusable or task-specific definitions and use the unchanged in-workflow `ctx.task`, `ctx.chain`, and `ctx.parallel` primitives instead.
- Workflow persistence now requires DBOS/Postgres. Removed the local JSON/SQLite backend, user opt-out/backend selection, session-JSONL discovery, and support for prior durable formats; existing local or older DBOS workflow data is not converted.
- The `/workflow resume` picker is now host-native ONLY and requires the host session-picker capability (`ctx.ui.hostSessionPicker`, Atomic's interactive hosts — both isolated and non-isolated — expose it with one identical API). The picker mounts the real built-in session selector directly in the terminal process, so arrow-key navigation and search never cross the host⇄extension boundary and stay instant even while the extension's event loop is busy (e.g. during catalog hydration or run-store refreshes); this also removes the per-keypress render round trip the remote-rendered picker paid under engine isolation. The previous remote-rendered `ctx.ui.custom()` selector path was deleted with no fallback: on a host without the capability, `/workflow resume` (picker form) now fails with one actionable error suggesting `/workflow resume <id>` instead of degrading. All picker semantics carry over unchanged — live rows seed the first frame, the durable/completed catalog hydrates once and merges into the open picker, watch/poll refreshes push row updates, deletion remains extension-owned with live rows protected ("Cannot delete an in-flight workflow run"), and the resolved catalog is still returned for the follow-on resume. The headless/non-interactive printed-list flow is unaffected.

### Added

- Unified workflow **post-mortem stage chat** across every inspection surface. Any eligible terminal agent stage with a valid retained session now reopens as an interactive follow-up conversation — not only completed-workflow inspection (#1758), but also generic `/workflow attach` / `/workflow connect`, restored/replayed durable snapshots after a process restart, and `workflow({ action: "send" })`. A shared runtime resolver (`ensurePostMortemStageHandle`) validates the retained session is an existing, readable, context-bearing Atomic transcript, then lazily reopens it through a detached, single-flight stage-control handle keyed by the real `{ runId, stageId }` (including nested/expanded child stages). Follow-up turns are appended in place to the retained session and the agent keeps its ordinary tools, while run/stage status, results, timings, checkpoints, replay metadata, and graph topology remain immutable — post-mortem chat can never resume, retry, rewind, pause, or re-dispatch workflow execution. Explicit `workflow send` delivery modes `resume` and `steer` on a completed post-mortem stage return a structured `noop` with follow-up guidance and do not append the supplied text. Stages without a valid retained agent session (prompt/HIL and boundary/summary nodes, skipped nodes, non-terminal handle-less stages, and missing/malformed/deleted session files) keep the existing read-only transcript, and recoverably failed stages retain their execution-resume semantics. `workflow send` now revives such a stage on a registry miss and delivers the message as a conversational follow-up instead of reporting `No live handle for stage.` ([#1811](https://github.com/bastani-inc/atomic/issues/1811))
- Added resumable `/workflow quit [run-id|--all]` and `workflow({ action: "quit" })` controls, preserving exact run-id, unique-prefix, active-run default, bulk, terminal, and ambiguity handling.
- Added six composable builtin pattern workflows: `classify-and-act` (structured confidence routing with human fallback), `fan-out-and-synthesize` (bounded artifact fan-out and evidence synthesis), `adversarial-verification` (fresh-context rubric verification with bounded repair), `generate-and-filter` (candidate generation, dedupe, filtering, and optional judging), `tournament` (balanced pairwise comparison and auditable bracket reduction), and `loop-until-done` (durable progress ledger with explicit completion and inspectable bound exhaustion). Each ships with bounded typed/defaulted inputs, dedicated stage prompts, parent-consumable declared outputs, and an export from `@bastani/workflows/builtin` for nested `ctx.workflow(...)` composition.
- Added a `group` option to workflow stages, tasks, parallel steps, and run-level defaults (`context`/`stage`/`task`/`parallel`) that sets each stage session's intercom home group so orchestrated stages can be isolated into coordination groups. A named string joins that group; `true` auto-generates one shared UUID group per parallel set (minted once and shared across every item in the set, never per-item) so a whole level lands in the same isolated group. Precedence is most-specific-first (`parallel-item > task/stage > parallel-step > run-level`), resolved into a per-session `orchestrationContext.intercomGroup` that is race-safe across concurrently running in-process stages (no global env mutation) and stable across model-fallback session replacement. Group assignment is gated on intercom capability: a stage with `noTools`, a `tools` allowlist omitting `intercom`, or `excludedTools` containing `intercom` is never placed into a group. Subagents spawned by a grouped stage inherit that stage's group by default (overridable per subagent), so a reviewer level and its helper subagents form one isolated group. The builtin `goal` and `ralph` workflows now isolate each reviewer level into its own group (`goal-reviewers-turn-N` / `ralph-reviewers-iter-N`): same-level reviewers can intercom each other but cannot reach the worker, orchestrator, parent chat, or other levels, which also keeps reviewer intercom chatter out of the main/parent context window.
- Added `/workflows [run-id]` as a retained-run alias for `/workflow resume`, plus confirmed Ctrl+D deletion for non-live durable/completed rows. Deletion rechecks same-process activity and authoritative status, atomically refuses `running` workflows, updates the catalog, and leaves host/stage session transcripts untouched.
- Added zero-configuration workflow durability: when no `DBOS_SYSTEM_DATABASE_URL` is set, Atomic runs DBOS against its own embedded Postgres built from npm-distributed binaries (`embedded-postgres` platform packages) — no Docker daemon or system Postgres install required. The cluster lives under `~/.atomic/postgres/v18` on dedicated port 5439, is initialized once, started as a detached daemon via `pg_ctl` (surviving Atomic exit and shared across concurrent sessions, never stopped by Atomic), and native lib symlinks are hydrated at runtime so `--ignore-scripts`/Bun installs work. DBOS's reusable `dbos-db` Docker container remains only as a fallback when the embedded binaries are unavailable for the platform; if both are unusable, the workflow action fails with one actionable message instead of a raw connection dump, and DBOS internal logging is routed to a silent logger so connection probes cannot spam the TUI.
- Added multi-session coordination for concurrent Atomic processes sharing one DBOS database: each process launches DBOS with a unique executor id; running root workflows carry owner/heartbeat metadata (refreshed by the ≤30s stage-timing checkpoints); another session's fresh-running workflow is hidden from the resume picker and refused by direct `/workflow resume <id>` with an actionable message until its owner pauses, quits, or its heartbeat goes stale; and contended paused→running transitions are decided by a durable first-writer-wins claim record so exactly one session dispatches the resumed run. Hydration preserves the authoritative `updatedAt` heartbeat instead of stamping local time.
- Made the `/workflow resume` picker live-updating: rows re-list on local run-store changes (debounced) and through a bounded cross-session poll (default 5s) while the picker stays open, so a workflow that pauses, fails, or completes appears — and a freshly running one disappears — without reopening. Watchers and timers stop when the picker closes, and a failed refresh keeps the previous rows.
- Running workflows are no longer resume targets anywhere: a running row with a fresh ownership heartbeat is hidden from the picker and the catalog regardless of which session owns it, eliminating double-dispatch of one workflow from two sessions. Only stale-heartbeat running workflows surface, presented as red `crashed` rows rather than `running`. Picker rows now carry semantic colors: completed green, paused yellow, failed/blocked/crashed red.
- Refined the workflow tool's `status` action into a first-class session run listing. `workflow({ action: "status" })` without a `runId` now returns concise per-run summaries alongside the full snapshots: run id and abbreviated prefix, workflow/run name, run status, started/ended timing plus pause-adjusted elapsed time, currently active stages, and awaiting-input details (count plus the stage, prompt id, kind, and message for each pending human prompt) — everything needed to feed `pause`/`resume`/`interrupt`/`quit`/`send` directly. In-flight runs are listed first. The agent-visible text output is now a concise per-run summary list instead of a raw snapshot dump, and `format: "json"` returns the structured listing.
- Added `statusFilter` support to the `status` run listing: run statuses (`pending`/`running`/`paused`/`blocked`/`completed`/`failed`/`skipped`/`cancelled`/`killed`) filter runs directly, `awaiting_input` selects runs with at least one stage awaiting input or pending human prompt, and `all` (the default) includes everything. The `cancelled` and `killed` filter values are newly accepted, and the tool schema descriptions for `action`, `runId`, `statusFilter`, and `format` now document the no-`runId` listing mode so agents can discover it.

### Changed

- Changed workflow hierarchy navigation to an unconditional Ctrl+X chord: attached stage chats now preserve composer and prompt drafts and pending custom questions while returning to the graph, and graph overlays return to main chat even with switchers or legacy prompts open. Ctrl+D retains ordinary editor/prompt behavior, `q` remains printable in text-owning prompts, workflow surfaces take Ctrl+X precedence over configurable actions, and graph/stage guidance now states the destination explicitly.
- Reworded workflow-start guidance around actionable `/workflow connect <run-id>` commands so users know they can see agents working and chat with or steer each stage.
- Reworked runner-managed Git worktrees to use Claude Code's git-native lifecycle: canonical main-root anchoring, `.atomic/worktrees/` locations, `worktree-*` branches with default-remote base resolution, local-settings/hooks/ignored-file setup, configurable `worktree.symlinkDirectories`, and force-remove plus branch-delete cleanup. Reusable `gitWorktreeDir` creation is now anchored at the canonical main root while retaining its existing path, validation, and cache semantics.
- DBOS is configured, registered, and launched lazily on the first workflow action (never during CLI/session startup), reused process-wide, and readiness is awaited across workflow execution, control, resume, inspection, and deletion paths. Initialization and persistence failures fail the workflow action; no alternate backend is selected.
- Debounced durable stage-session timing checkpoints into 30-second buckets. Duration-only progress no longer forces a full durable state read-merge-rewrite on every prompt/steer event; session identity changes (session id/file/start) still persist immediately, so cross-process resume continues from the same retained session with at most a 30-second loss of accumulated timing precision.
- Matched coding-agent `/resume` retention semantics for workflow history: all eligible durable runs remain searchable regardless of age or count, with no automatic history GC; the 10-row selector viewport remains display-only.

### Fixed

- Fixed live workflow stages abandoning their objective after a user-queued message across every delivery path: attached-stage-chat steering (Enter) and follow-up (Ctrl+F), including the chat host's SDK-direct `AgentSession.prompt(..., { streamingBehavior })` bypass; `workflow({ action: "send" })` `steer`/`followUp`; and workflow-author `StageContext.steer()`, `followUp()`, or streaming `sendUserMessage()`. Workflows now detect when the SDK actually consumes queued user messages and inject the exact deterministic continuation prompt ("Continue where you left off. If you believe you are finished with your original task (or a redefined task if the user told you), stop.") once after the consuming turn, even when the readiness gate is disabled. Multiple consumed messages coalesce into one injection, initial/idle and injected continuation prompts cannot re-arm the mechanism, aborted/finalized/fail-fast-skipped stages remain suppressed, and pause→resume continuation still requires the readiness gate.
- Fixed session-boundary races in lazy post-mortem stage-chat attachment so every host session replacement or shutdown (`new`, `resume`, `fork`, `reload`, and `quit`) synchronously invalidates detached handles; a retained-session creation that finishes after the boundary is disposed and its already-submitted prompt is rejected instead of executing in the replacement session or leaking an unowned SDK session.
- Fixed explicit `/workflow attach <root-run> <nested-stage>` commands to resolve expanded child stages through their owning nested run, preserve that owner through overlay retargeting when sibling child runs reuse the same local stage ID, and retain post-mortem resolver failure reasons so invalid or unavailable sessions render a complete actionable `SESSION UNAVAILABLE` explanation—even at the supported 40-column minimum—instead of a misleading archived-transcript label. Reopened nested terminal stages now restore cwd from their durable root workflow metadata (preferring the resolved workflow cwd, then the original invocation cwd) rather than silently falling back to the current review checkout.
- Hardened repository release recovery so externally merged PRs require exact current identity, refs, SHA, checks, merge evidence, and retained branch state. Workflow-qualified Actions reruns use name plus workflow; empty-workflow external statuses and GitHub App checks support linked kind/name grouping and linkless cross-kind inspection. All-passing linkless candidates and duplicate aliases are accepted, while any pending/failure blocks and nonempty-workflow Actions remain excluded. Checks refresh after merge, tag recovery proves `verified merge → tag parent → current base`, protected dispatch coordination retains its lock through ambiguous acceptance visibility, and recovered success is bound to the exact integrity-job tag SHA.
- Fixed workflow stage-chat compaction to show one reason-aware animated spinner for manual, automatic-threshold, and overflow compaction, retain the normal expandable `✻ Context compacted` boundary when the live session snapshot is temporarily unavailable, and contain `/compact` cancellation or planner/provider rejection after its authoritative `compaction_end` event so the CLI and stage remain usable.
- Fixed workflow stage finalization to atomically close the AgentSession notification-admission boundary before publishing terminal snapshots. Already-admitted Intercom and async completion turns are drained and reflected in the terminal result, while late detached traffic cannot mutate/reopen the stage and is routed externally. The boundary does not wait for producers that are still running and preserves deliberate post-completion `sendUserMessage` and post-mortem chat.
- Fixed live in-process workflow resume so quitting a chain stage mid-turn and resuming without a message re-drives the interrupted stage with the continuation prompt before result harvesting, preventing partial assistant text from being durably checkpointed or handed to downstream `{previous}` stages while preserving explicit-message and cross-process durable resume behavior. ([#1829](https://github.com/bastani-inc/atomic/issues/1829))
- Made graceful quit wait for live stage pause acknowledgement before persisting resumable state, report runs with no controllable stage as still active, propagate rejected pauses instead of claiming success, and reconcile session-restored running snapshots with authoritative paused durability so `/workflow resume` legally redispatches them.
- Made bulk quit settle every run and report per-run failures, made pause/resume state follow asynchronous control acknowledgements, synchronized successful resume back to durable state, and shared paused/orphaned-running durable shadow recovery across slash and workflow-tool resume.
- Made graceful `/workflow quit` propagate durable backend failures for workflows that are durably tracked: `markDurableQuit` now swallows errors only while discovering whether a run has durable state, and lets a failed paused-status transition or flush (for example an unwritable/unknown default file-backend state) surface instead of masking it as `not_needed`. Quit no longer records a resumable pause or reports success when the persistent backend never captured the paused state, so a follow-up process cannot be left with nothing to `/workflow resume`.
- Made graceful quit recognize live/synthetic awaiting-input and already-paused states without cancelling prompts, persist race-safe unresolved prompt counts across file/in-memory/DBOS backends, and hold answered quit prompts behind explicit resume before checkpointing.
- Made durable resume shadows use the authoritative progress predicate, leaving zero-progress restored orphans untouched, and made multi-stage resume settle every acknowledgement, reconcile truthful partial-running durability, retain failed paused stages, and report aggregated run/stage failures.
- Fixed prompt replay/reservation identity and cross-instance atomicity for scoped, file, and DBOS durability; refreshed prompt pause barriers on every quit; reconciled late resume outcomes and durable-write failures from visible state without reviving terminal runs; and added connect guidance to direct asynchronous accepted results.
- Made prompt releases consume one identity-owned reservation generation at most once, with persisted file/DBOS release tombstones and saturating legacy-scalar migration; made author callsites stable across process working-directory changes; composed nested parent/child checkpoint scopes; and made later resume requests retry a paused durable handle after local resume already succeeded.
- Made resume-shadow reads and conditional lifecycle writes use one authoritative durable generation, preventing stale file instances from reviving terminal workflows; reconciled fulfilled quit controls and nested child resume progress through aggregate root Store/durability; preserved DBOS prompt-token ownership across workflow re-registration; and made mixed bulk quit outcomes report ordered partial successes.
- Reported fulfilled resume acknowledgements whose controls finish before aggregate root finalization as successful progress instead of falsely claiming that no paused stages existed.
- Made DBOS conditional lifecycle transitions terminal-absorbing under concurrent metadata writes, made legacy custom backends without an atomic transition primitive refuse safely, and distinguished omitted prompt counts from explicit new reservation-ledger baselines during DBOS re-registration.
- Fixed attached stage-chat footers at the supported 40-column minimum to keep truncated provider/model context separated from the compact Ctrl+X/Copy Mode controls instead of merging both segments into corrupted text.
- Fixed stage-less named workflow body failures such as a throwing `ctx.tool()` being misclassified as killed instead of retained as failed with their concrete startup error.
- Fixed busy workflow stages deadlocking when a foreground subagent waited on Intercom or blocking `contact_supervisor`. Exact foreground-owner detach now completes before the request enters the stage generation boundary, owner loss before commit falls back to normal open-stage admission, and parallel foreground groups release aggregate supervision while retaining every child's lifecycle and result recovery. Native workflow messaging and terminal close semantics remain unchanged.
- Fixed Ctrl+O (`app.tools.expand`) being consumed without expanding tool and workflow-node detail in attached workflow stage chats under Atomic's isolated interactive engine. The remote workflow pane now preserves pi-tui's key-release opt-in contract, so Kitty terminals cannot deliver both the press and release as two expansion toggles that cancel each other. Repeated expand/collapse toggles match main chat across active and completed runs, single/parallel/chain views, and narrow terminals while prompts, custom questions, and unrelated keybindings retain input ownership.
- Fixed authored `ctx.parallel(...)` calls treating string auto-group sentinels such as `group: "auto"` as literal group names. The engine now normalizes trimmed, case-insensitive `"auto"`/`"true"` values at both set and per-step levels before deciding whether to mint one shared UUID for the parallel set. Separate sets still receive distinct UUIDs, boolean `true` remains supported, and named groups stay literal.
- Fixed `/workflow <name>` forms hanging under Atomic's isolated interactive engine when required inputs were missing. The command now prefers the host-native input-form capability, so the form is mounted and focused in the terminal host and Tab/Shift+Tab, arrows, text editing, configured keybindings, Enter, Escape, and Ctrl+C remain responsive without per-keypress engine traffic. Escape/Ctrl+C cancel without dispatch, supplied/default values and typed coercion are preserved, and the existing inline-editor and remote-custom paths remain compatibility fallbacks for older hosts.
- Fixed named workflow startup feedback so pre-body setup failures, including a `goal` run whose `git_worktree_dir` points inside the invoking checkout, return immediately from the original workflow tool call as a structured failed result with the concrete setup error and allocated run id instead of first claiming background acceptance and relying on a later lifecycle notice. Successful named runs still return promptly after startup admission without waiting for workflow completion; failed admission now cleans job, cancellation, store, and durable state, and continuation/durable-resume launches preserve resumability while reporting their startup error.
- Fixed named background workflows that stopped on a recoverable provider, authentication, or rate-limit failure without notifying the invoking chat. Top-level active/resumable blocks now emit one deduplicated `WORKFLOW BLOCKED` lifecycle card per blocked occurrence (keyed by run id and blocked timestamp, so a resumed workflow that hits another recoverable block re-notifies), delivered through native idle-prompt admission when the parent chat is idle or persisted directly to the transcript when it is streaming; status/headless surfaces report blocked; and durable state retains blocked/resumable discovery across session boundaries and exposes the run in the resume picker. Lifecycle delivery commits dedupe only after admission succeeds and retains the original payload with capped-backoff retries while the invoking chat remains active, including across run-state changes and notification reinstallations; session replacement cancels and clears those attempts. Resuming an active block dispatches a fresh-ID continuation that replays completed stages and re-runs the failed one; the durable source is left untouched (stays blocked/resumable for crash recoverability, including zero-checkpoint first-stage blocks) and the local source snapshot is killed so the same session will not re-resume it; a process-local claim prevents concurrent same-session double-dispatch. Historical restore seeding, headless duplicate suppression, nested workflows, and human-input prompts remain non-notifying.
- Fixed completed workflow stages being visible to Intercom but unable to process a sibling's blocking `intercom.ask`. The late-message handoff now carries exact run/stage ownership into the shared post-mortem resolver, serializes wakeups per retained conversation, reopens only eligible completed sessions without mutating workflow execution, and reports deleted, invalid, non-resumable, or failed revival targets within a bounded interval. Claimed completions now have single-owner semantics across the production workflow and Intercom listeners, so listener registration order and duplicate listeners cannot replace or double-deliver the authoritative revival result. Exact child-to-child reply correlation remains isolated from parent and unrelated sessions ([#1854](https://github.com/bastani-inc/atomic/issues/1854)).
- Fixed interactive non-schema stages treating typed/freeform `ask_user_question` chat answers as an invisible implicit “stay”. The conversational acknowledgement now precedes a brokered readiness gate; in that chat flow, Not ready allows a genuine chat turn before readiness is asked again and Ready releases dependents. Structured-option behavior remains unchanged, and schema-finalized stages remain terminal. ([#1849](https://github.com/bastani-inc/atomic/issues/1849))
- Fixed idle live workflow-stage messaging so `workflow send` `followUp` and eligible `auto` deliveries start a real prompt instead of stranding an unconsumable queue item, while streaming follow-ups remain queued and steering remains in-turn. Send results now report the action actually taken. Paused idle stage-chat waits resumed with a non-empty message start exactly one recorded prompt, while interrupted streaming resumes preserve their existing nonduplicating loop and lifecycle/abort guards prevent late prompt creation. Custom `AgentSessionAdapter` implementations now have a typed public `agent_start`/`agent_end` subscription contract for asynchronous ownership through both native `sendUserMessage()` and the optional-method `prompt()` fallback. Serialized admission retains generation-correlated logical turn ownership after `agent_start`, preventing a second idle prompt when an adapter's public `isStreaming` state publication lags its lifecycle event. Untagged synchronous replay snapshots no longer consume a current end; adapters whose replayed turn may end after a newer turn starts can provide a stable `turnId` for exact old-end correlation. Late terminal events, older promise settlement, rejection, and abort cannot clear a newer turn. Stage-chat input handled by an extension remains accepted if the stage becomes terminal during handling instead of reporting rejection after the side effect ([#1850](https://github.com/bastani-inc/atomic/issues/1850)).
- Fixed durable `/workflow resume` restarting workflow timers: the resumed run's total duration in the main-chat dashboard and status surfaces now inherits the elapsed time accumulated before the quit/failure (prior sessions + current session) instead of resetting to zero, and a resumed mid-running stage's timer continues from its previously accumulated elapsed time. The run's total accumulated elapsed is persisted durably alongside the existing 30-second stage-timing checkpoints, exactly at graceful quit and recoverable-failure boundaries, and round-trips through DBOS hydration and session-entry restore. In-process continuation resumes of failed runs inherit the source run's total the same way.
- Fixed background workflow activity flickering the main-chat tail and snapping native terminal scrollback back to the live bottom after wheel-scrolling away ([#1856](https://github.com/bastani-inc/atomic/issues/1856)). The below-editor workflow companion remains one long-lived mounted component: semantic changes and elapsed-clock updates repaint it in place without `setWidget` dispose/remount churn, byte-identical store mutations do not broadcast redundant host renders, and hidden workflow graph/stage overlays do not request host renders on store updates. A visible running workflow's elapsed label now advances continuously from `0s` on exact one-second boundaries without requiring an orchestrator-panel switch; paused labels stay frozen, and ended cards retain only their one-shot ~30-second expiry timer.
- Normalized `DBOS_SYSTEM_DATABASE_URL` handling: the URL is trimmed before being handed to DBOS, so values injected from secrets managers or env files with trailing whitespace/newlines connect cleanly, and a whitespace-only value is treated as unset. Explicit-URL precedence is unchanged — when the variable is set, Atomic never provisions its embedded Postgres or Docker fallback, including on connection failures, which surface as actionable errors against the configured database.
- Fixed completed and in-progress workflows disappearing from `/workflow resume` in a fresh Atomic process. Stage-session timing checkpoint writers omit topology; the in-memory mirror defaulted it on write but the DBOS persist path encoded the raw checkpoint, so cross-process hydration classified those records as foreign and suppressed the whole workflow. Topology is now normalized at the shared encode boundary, making the durable record identical to the mirror (regression-tested through a full write→fresh-hydrate round trip). Runs persisted before this fix keep their topology-less records and remain hidden; re-run or delete them.
- Fixed DBOS step/metadata writes returning before the underlying checkpoint workflow completed: `recordStepOutput` now awaits the stored result (resolving duplicates to the first durable record), so a passed `flush()` boundary guarantees the write is durable and readable — required for correct cross-process claim reads and crash-safe checkpoint exposure.
- Fixed the resumed workflow graph overlay ignoring the mouse wheel (wheel gestures scrolled native/main-chat scrollback) under Atomic's isolated interactive engine. The graph overlay adapter runs inside the engine child, whose stdout is the JSONL transport rather than a TTY, so writing mouse-tracking escape sequences to its local `process.stdout` was a no-op and the host TTY never entered mouse-reporting mode. The adapter now prefers the host's typed remote terminal-control capability exposed on the factory TUI's `terminal` (`setMouseScrollTracking`/`setAutowrap`) so the real host TTY enters mouse-reporting (and Windows autowrap) mode, routing wheel input to the remote `GraphView` scroll offsets while a visible overlay captures the mouse; stage-chat wheel capture and Ctrl+T copy mode continue to work, and main-chat scrollback no longer moves while a visible overlay owns the mouse. Non-isolated hosts and existing test seams keep the local `process.stdout` fallback. Modes are reset on overlay hide/close/dispose and on engine crash/restart, and `/workflow resume` selection deterministically disposes the inline picker before the fullscreen overlay mounts and is focused.
- Made `/workflow resume` mount its picker before loading workflow resources or the durable/completed catalog. Eligible live runs seed the first rendered frame and the durable/completed catalog now hydrates asynchronously, merging its rows into the open picker on resolve instead of blocking the slash command until the scan finishes. Catalog errors render inside the still-usable picker when live rows are present, closing the picker cancels late hydration and ignores stale results, and the resolved catalog is reused for the follow-on resume so there is no second scan. Together with the coding-agent long-lived-RPC timeout fix, this removes the `Timeout waiting for response to prompt` failure when opening `/workflow resume`.
- Hardened the durable workflow catalog against cross-process races: rebuild publication now serializes its final signature/marker verification with incremental writers and never consumes a marker created after scanning began; one-row updates no longer bless unrelated external additions, deletions, or edits; and automatic terminal-file pruning rechecks the authoritative status under the per-workflow lock so a concurrently resumed `running` workflow survives.
- Prevented blocking workflow author/stage code from freezing the Atomic terminal by running the interactive agent engine and bundled workflows extension in the supervised engine child. Workflow commands, tools, custom graph/picker components, and stage callbacks retain child-owned closure state while the terminal host continues input and render ticks; watchdog diagnostics identify the active callback and interrupted results remain explicitly unknown until resumed from an authoritative checkpoint.
- Fixed the host TUI flickering (rapid full repaints at ~58 Hz) when the `workflow` tool's `quit`/`pause` action ran while a workflow stage was actively streaming. The root cause was not in the workflows extension: under Atomic's isolated interactive engine, rendering the first tool card of a turn (typically the `workflow` quit/pause call, but any tool call reproduced it) entered a self-sustaining host⇄engine render ping-pong in the remote tool-card renderer, which fought the still-streaming turn. The renderer fix ships in `@bastani/atomic` (see the coding-agent changelog); quitting or pausing a streaming workflow now renders its tool card once and stays quiet.

### Removed

- Removed public workflow `kill` slash/tool actions, completions, picker shortcuts, confirmations, renderers, and help/docs while retaining internal cancellation machinery used by engine and session lifecycle paths.

## [0.9.9] - 2026-07-15

### Changed

- Hardened the shared builtin `goal`/`ralph` prompt contracts against over-implementation drift (observed in eval traces where near-perfect patches lost binary reward to a single invented strictness: returning a read-only mapping proxy where the contract said "dict", marking an optional schema field required, and rejecting duplicate aliases the task's hidden tests expected to be tolerated). The literal objective contract now states that the loud-error preference applies only to error conditions the contract enumerates and that the default for unenumerated behavior is permissive acceptance (never invent a validation error, required field, uniqueness constraint, or rejection the contract does not name); that contract-named types/shapes/formats must be produced exactly, with no defensive substitutes such as read-only proxies, frozen collections, or tuples-for-lists, because consumers may check type identity literally; and that unspecified behavior defaults to preserving input verbatim over normalizing, deduplicating, reordering, or rewriting it.
- Extended the worker/orchestrator acceptance-matrix contract with rows for literal contract examples (checked character-for-character rather than paraphrased) and for each contract-constrained interface decision (types by identity, required-vs-optional per field, duplicate handling, ordering, raw-vs-normalized text), recording the permissive/preserving default whenever the contract leaves a decision open.
- Added a shared `CONTRACT_FIDELITY_AUDIT` adversarial divergence pass to the Goal worker and Ralph orchestrator prompts (`<divergence_audit>`): after checks are green and before claiming readiness, re-read each contract clause asking what plausible independent check would fail the implementation, probing the recurring divergence categories — type-identity assertions, optional fields omitted, duplicated/aliased inputs, ordering assumptions, verbatim-vs-normalized text, and any raised error the contract does not enumerate. Forked continuation prompts reference the audit in their established-guidance pointer.
- Made Goal and Ralph reviewers hunt over-implementation as seriously as gaps via a shared `REVIEWER_OVERIMPLEMENTATION_GUARD`: validation errors, required fields, uniqueness/format constraints, immutability wrappers, or normalization the contract does not require are `required_by_objective` defects, and reviewers must probe at least one contract-permitted input the worker's own tests do not exercise before approving. The independent-verification contract and reviewer action items now include contract-permitted-input and type/shape/text-identity probes alongside the existing boundary/edge/negative probes.
- Added a shared Intercom coordination protocol to every concurrent builtin Goal and Ralph reviewer prompt: reviewers now check Intercom and discover same-run siblings at review start, communicate validation plans and ownership, serialize conflicting shared-checkout or shared-environment checks, announce starts/completions/releases, share reusable execution evidence, and retain independent patch analysis and verdicts ([#1803](https://github.com/bastani-inc/atomic/issues/1803)).
- Aligned the workflows extension peer dependency with `@earendil-works/pi-tui` `^0.80.7` as part of the consolidated Pi v0.80.7 dependency update; no workflow source changes were needed.
- Updated the runtime `typebox` range to `^1.3.6`.

### Fixed

- Fixed the builtin `open-claude-design` artifact directory fallback to use a per-user OS tmpdir namespace (`open-claude-design-<username>`), preventing `EACCES` failures on shared hosts where another user already owns the plain `<tmpdir>/open-claude-design` directory. The legacy shared path remains a secondary fallback, and the last-resort synthesized path now also uses the per-user namespace so best-effort feedback persistence can actually create it.
- Prevented the synced Impeccable fixture's nested `git init` from inheriting hook-local Git repository variables and corrupting a linked repository's shared `core.worktree`. Runner-managed reusable worktrees now remap propagated invoking-repository `cwd` values and relative direct outputs into the selected worktree; reject blank, self, nested, foreign, lexical-escape, symlink-escape, and changed cached targets before opening a later session; key cached identity by canonical repository/target across equivalent path and ref spellings; revalidate newly created targets; and expose clearer workflow tool guidance/schema descriptions so natural-language worktree requests cannot be mistaken for runtime configuration. Temporary direct task and parallel worktrees also derive omitted/relative task cwd values from the runner invocation cwd and clean up when startup fails before their workflow callback, while relative outputs are persisted to stable runner-owned artifacts before cleanup and reject parent traversal, child symlink escapes, or a linked trusted artifact root across direct, parallel, and chain modes; blank `chainDir` values no longer bypass reusable-worktree output routing.
- Fixed the active Workflow Orchestrator graph pane to pan left and right for horizontal trackpad and terminal mouse-wheel events while preserving vertical wheel panning and pane-local input capture ([#1756](https://github.com/bastani-inc/atomic/issues/1756)).
- Fixed `/workflow resume` so its single globally newest-first, deduplicated picker includes current paused or recoverably failed and durable resumable entries alongside authoritative successful completed workflows. Completed rows use green `✓ completed` styling and open an immutable detail/chat snapshot with transcript follow-up conversation, without durable re-dispatch or workflow side-effect replay. Full IDs take precedence and prefixes resolve across the mixed namespace; completed rows require checkpoints and at least one strictly valid retained conversation, invalid per-stage paths cannot attach chat, repeated inspection refreshes changed authoritative chat handles, and selector mount failures close safely. Existing resumable workflow and ordinary internal-session history behavior remains on the original paths. ([#1532](https://github.com/bastani-inc/atomic/issues/1532))
- Fixed `/workflow resume` to deduplicate live and durable choices with live-row precedence, then globally sort the combined selector by latest run/stage or durable-update activity, newest first, with deterministic workflow-id tie-breaking independent of source enumeration order ([#1714](https://github.com/bastani-inc/atomic/issues/1714)).
- Fixed startup and restored-session workflow notices to use the authoritative durable resume catalog's status/progress rules: failed and blocked root workflows are advertised unless explicitly marked `resumable: false`, running and paused workflows require durable progress, nested child workflows and stale cache-only entries are excluded, and legacy direct or payload-wrapped checkpoint entries are parsed correctly.
- Fixed durable mid-stage workflow resume to refresh pause-adjusted active stage/task duration at repeated session checkpoints, preserve it through file and DBOS hydration, and continue accumulating it across repeated process-boundary resumes without resetting the baseline when concurrent tracked stage calls begin, double-counting earlier pauses, changing replay identity, or re-running completed side effects ([#1713](https://github.com/bastani-inc/atomic/issues/1713)).
- Fixed incompatible durable workflow records appearing as loadable resume targets by moving file state, DBOS metadata/checkpoint envelopes, and JSONL discovery caches to one shared v2 format contract; exact legacy v1 file and DBOS rows are now suppressed and permanently deleted (including DBOS checkpoint-prefix records), with per-workflow deletion and loadability queries implemented across durable backends and safely isolated from child scopes. Resume selectors, explicit target resolution, completed catalogs, restored-session notices, status/listing state, cache merges, and live resume paths accept only loadable current-format rows; compatibility preparation purges matching restored/live snapshots even when DBOS deletion fails, so failure fallbacks cannot resurrect or dispatch them. Repeated discovery is idempotent, deletion failures stay hidden and retry later, compatible and newly registered runs plus unmarked raw DBOS checkpoint outputs remain supported, and malformed, unavailable, future-version, or unsupported marked-envelope data is conservatively preserved and hidden rather than overwritten, reinterpreted, or broadly deleted.
- Fixed workflow stage session classification so fresh and fork-context stages persist complete ownership metadata before their transcripts can enter normal resume history, including custom session directories.
- Made `workflow({ action: "status", runId })` apply the same exact-or-unique-prefix contract as the other run actions. A prefix shared by multiple retained runs now returns the standard ambiguity diagnostic instead of silently inspecting the first match, so abbreviated run IDs printed by status surfaces remain safe and actionable.
- Fixed workflow resource reload to build and atomically publish a fresh registry for additions, edits, renames, deletions, config paths, conventional/legacy directories, and package resources without restarting Atomic. Reloads now serialize and coalesce, reject stale session generations, retain the active registry on fatal failures, remain safe during in-flight runs, and return visible config/discovery diagnostics through both slash-command and tool surfaces while preserving valid siblings.
- Fixed exact paused top-level live `/workflow resume <id>` targets to resume before enumerating retained completed durable history, preserving live-over-durable precedence and keeping headless command output responsive when the durable catalog is large, while exact nested child IDs remain excluded from the top-level resume namespace. Slash-dispatch tests now isolate durable state in memory and restore the backend after each test so they never read or populate a user's workflow history.
- Isolated lazy-startup continuation tests with fresh in-memory durable backends and a completed-catalog regression guard, preventing test runs from enumerating or populating the user's real durable workflow history while preserving failed-run resource-loading coverage.

## [0.9.9-alpha.4] - 2026-07-15

### Fixed

- Fixed workflow resource reload to build and atomically publish a fresh registry for additions, edits, renames, deletions, config paths, conventional/legacy directories, and package resources without restarting Atomic. Reloads now serialize and coalesce, reject stale session generations, retain the active registry on fatal failures, remain safe during in-flight runs, and return visible config/discovery diagnostics through both slash-command and tool surfaces while preserving valid siblings.
- Fixed completed named and direct workflow inspection after a process restart to preserve linear and parallel fan-out/fan-in stage topology through additive versioned durable metadata and reconstructed parent-id remapping. Legacy topology-less checkpoints remain readable with an explicit `topology unavailable` graph label instead of false root claims, and unsupported or malformed optional topology is now decoded as unavailable without dropping otherwise valid file-backed checkpoints or DBOS stage envelopes. Inspection remains read-only without redispatching completed work ([#1816](https://github.com/bastani-inc/atomic/issues/1816)).
- Fixed exact paused top-level live `/workflow resume <id>` targets to resume before enumerating retained completed durable history, preserving live-over-durable precedence and keeping headless command output responsive when the durable catalog is large, while exact nested child IDs remain excluded from the top-level resume namespace. Slash-dispatch tests now isolate durable state in memory and restore the backend after each test so they never read or populate a user's workflow history.
- Isolated lazy-startup continuation tests with fresh in-memory durable backends and a completed-catalog regression guard, preventing test runs from enumerating or populating the user's real durable workflow history while preserving failed-run resource-loading coverage.

## [0.9.9-alpha.3] - 2026-07-14

### Fixed

- Made `workflow({ action: "status", runId })` apply the same exact-or-unique-prefix contract as the other run actions. A prefix shared by multiple retained runs now returns the standard ambiguity diagnostic instead of silently inspecting the first match, so abbreviated run IDs printed by status surfaces remain safe and actionable.

## [0.9.9-alpha.2] - 2026-07-14

### Changed

- Aligned the workflows extension peer dependency with `@earendil-works/pi-tui` `^0.80.7` as part of the consolidated Pi v0.80.7 dependency update; no workflow source changes were needed.
- Updated the runtime `typebox` range to `^1.3.6`.

## [0.9.9-alpha.1] - 2026-07-14

### Changed

- Hardened the shared builtin `goal`/`ralph` prompt contracts against over-implementation drift (observed in eval traces where near-perfect patches lost binary reward to a single invented strictness: returning a read-only mapping proxy where the contract said "dict", marking an optional schema field required, and rejecting duplicate aliases the task's hidden tests expected to be tolerated). The literal objective contract now states that the loud-error preference applies only to error conditions the contract enumerates and that the default for unenumerated behavior is permissive acceptance (never invent a validation error, required field, uniqueness constraint, or rejection the contract does not name); that contract-named types/shapes/formats must be produced exactly, with no defensive substitutes such as read-only proxies, frozen collections, or tuples-for-lists, because consumers may check type identity literally; and that unspecified behavior defaults to preserving input verbatim over normalizing, deduplicating, reordering, or rewriting it.
- Extended the worker/orchestrator acceptance-matrix contract with rows for literal contract examples (checked character-for-character rather than paraphrased) and for each contract-constrained interface decision (types by identity, required-vs-optional per field, duplicate handling, ordering, raw-vs-normalized text), recording the permissive/preserving default whenever the contract leaves a decision open.
- Added a shared `CONTRACT_FIDELITY_AUDIT` adversarial divergence pass to the Goal worker and Ralph orchestrator prompts (`<divergence_audit>`): after checks are green and before claiming readiness, re-read each contract clause asking what plausible independent check would fail the implementation, probing the recurring divergence categories — type-identity assertions, optional fields omitted, duplicated/aliased inputs, ordering assumptions, verbatim-vs-normalized text, and any raised error the contract does not enumerate. Forked continuation prompts reference the audit in their established-guidance pointer.
- Made Goal and Ralph reviewers hunt over-implementation as seriously as gaps via a shared `REVIEWER_OVERIMPLEMENTATION_GUARD`: validation errors, required fields, uniqueness/format constraints, immutability wrappers, or normalization the contract does not require are `required_by_objective` defects, and reviewers must probe at least one contract-permitted input the worker's own tests do not exercise before approving. The independent-verification contract and reviewer action items now include contract-permitted-input and type/shape/text-identity probes alongside the existing boundary/edge/negative probes.
- Added a shared Intercom coordination protocol to every concurrent builtin Goal and Ralph reviewer prompt: reviewers now check Intercom and discover same-run siblings at review start, communicate validation plans and ownership, serialize conflicting shared-checkout or shared-environment checks, announce starts/completions/releases, share reusable execution evidence, and retain independent patch analysis and verdicts ([#1803](https://github.com/bastani-inc/atomic/issues/1803)).

### Fixed

- Fixed the builtin `open-claude-design` artifact directory fallback to use a per-user OS tmpdir namespace (`open-claude-design-<username>`), preventing `EACCES` failures on shared hosts where another user already owns the plain `<tmpdir>/open-claude-design` directory. The legacy shared path remains a secondary fallback, and the last-resort synthesized path now also uses the per-user namespace so best-effort feedback persistence can actually create it.
- Prevented the synced Impeccable fixture's nested `git init` from inheriting hook-local Git repository variables and corrupting a linked repository's shared `core.worktree`. Runner-managed reusable worktrees now remap propagated invoking-repository `cwd` values and relative direct outputs into the selected worktree; reject blank, self, nested, foreign, lexical-escape, symlink-escape, and changed cached targets before opening a later session; key cached identity by canonical repository/target across equivalent path and ref spellings; revalidate newly created targets; and expose clearer workflow tool guidance/schema descriptions so natural-language worktree requests cannot be mistaken for runtime configuration. Temporary direct task and parallel worktrees also derive omitted/relative task cwd values from the runner invocation cwd and clean up when startup fails before their workflow callback, while relative outputs are persisted to stable runner-owned artifacts before cleanup and reject parent traversal, child symlink escapes, or a linked trusted artifact root across direct, parallel, and chain modes; blank `chainDir` values no longer bypass reusable-worktree output routing.
- Fixed the active Workflow Orchestrator graph pane to pan left and right for horizontal trackpad and terminal mouse-wheel events while preserving vertical wheel panning and pane-local input capture ([#1756](https://github.com/bastani-inc/atomic/issues/1756)).
- Fixed `/workflow resume` so its single globally newest-first, deduplicated picker includes current paused or recoverably failed and durable resumable entries alongside authoritative successful completed workflows. Completed rows use green `✓ completed` styling and open an immutable detail/chat snapshot with transcript follow-up conversation, without durable re-dispatch or workflow side-effect replay. Full IDs take precedence and prefixes resolve across the mixed namespace; completed rows require checkpoints and at least one strictly valid retained conversation, invalid per-stage paths cannot attach chat, repeated inspection refreshes changed authoritative chat handles, and selector mount failures close safely. Existing resumable workflow and ordinary internal-session history behavior remains on the original paths. ([#1532](https://github.com/bastani-inc/atomic/issues/1532))
- Fixed `/workflow resume` to deduplicate live and durable choices with live-row precedence, then globally sort the combined selector by latest run/stage or durable-update activity, newest first, with deterministic workflow-id tie-breaking independent of source enumeration order ([#1714](https://github.com/bastani-inc/atomic/issues/1714)).
- Fixed startup and restored-session workflow notices to use the authoritative durable resume catalog's status/progress rules: failed and blocked root workflows are advertised unless explicitly marked `resumable: false`, running and paused workflows require durable progress, nested child workflows and stale cache-only entries are excluded, and legacy direct or payload-wrapped checkpoint entries are parsed correctly.
- Fixed durable mid-stage workflow resume to refresh pause-adjusted active stage/task duration at repeated session checkpoints, preserve it through file and DBOS hydration, and continue accumulating it across repeated process-boundary resumes without resetting the baseline when concurrent tracked stage calls begin, double-counting earlier pauses, changing replay identity, or re-running completed side effects ([#1713](https://github.com/bastani-inc/atomic/issues/1713)).
- Fixed incompatible durable workflow records appearing as loadable resume targets by moving file state, DBOS metadata/checkpoint envelopes, and JSONL discovery caches to one shared v2 format contract; exact legacy v1 file and DBOS rows are now suppressed and permanently deleted (including DBOS checkpoint-prefix records), with per-workflow deletion and loadability queries implemented across durable backends and safely isolated from child scopes. Resume selectors, explicit target resolution, completed catalogs, restored-session notices, status/listing state, cache merges, and live resume paths accept only loadable current-format rows; compatibility preparation purges matching restored/live snapshots even when DBOS deletion fails, so failure fallbacks cannot resurrect or dispatch them. Repeated discovery is idempotent, deletion failures stay hidden and retry later, compatible and newly registered runs plus unmarked raw DBOS checkpoint outputs remain supported, and malformed, unavailable, future-version, or unsupported marked-envelope data is conservatively preserved and hidden rather than overwritten, reinterpreted, or broadly deleted.
- Fixed workflow stage session classification so fresh and fork-context stages persist complete ownership metadata before their transcripts can enter normal resume history, including custom session directories.

## [0.9.8] - 2026-07-12

### Changed

- Changed builtin `goal` and `ralph` reviewer approval to be deterministic on the reviewer's self-reported `stop_review_loop` boolean: a reviewer approves exactly when it returns `stop_review_loop=true` with no `reviewer_error`, parse failures still count as non-approval, and Goal's reducer completes on quorum of those booleans without recomputing approval from findings arrays, priorities, or `requirements_traceability` statuses. Recomputing approval from those arrays could deadlock runs whose acceptance criteria referenced the review process itself (for example "three reviewers approve" or "an unmerged PR is created"): no individual reviewer can prove such clauses, so traceability never became fully `proven` even when every reviewer explicitly approved, and the loop burned worker/review turns until `needs_human`. Reviewer prompts now state that the boolean is the single authoritative convergence signal, spell out how to derive it (blocking P0/P1/P2 findings and `required_by_objective` findings at any priority mean `false`; in-scope P3 nice-to-haves, `beyond_objective`/`contradicts_objective` observations, the reviewer-quorum process itself, and the authorized post-approval PR/MR/review final action must never hold it at `false`), and keep findings/traceability as required audit evidence. `findingBlocksClosure`/`isBlockingFinding` still classify findings for prompts and consolidated repair batches.
- Synchronized the complete builtin `impeccable` skill tree with pbakaus/impeccable at `630fc2682a5bd39b25a8e61f74b6b3f14f2b1e21`, including its latest references, detector libraries, live-review scripts, and provider integrations.

### Fixed

- Disabled terminal autowrap while the fullscreen workflow graph overlay is visible on Windows and restored the previous terminal mode when the overlay closes, preventing wrapped graph rows and stale terminal state ([#1760](https://github.com/bastani-inc/atomic/issues/1760)).
- Hardened synced Impeccable HTML filtering and preview selector escaping against nested sanitizer inputs, permissive script/style closing tags, HTML comment end-bang syntax, and backslash-containing session identifiers; also removed an ineffective CSS property replacement flagged by CodeQL.

## [0.9.8-alpha.1] - 2026-07-12

### Changed

- Changed builtin `goal` and `ralph` reviewer approval to be deterministic on the reviewer's self-reported `stop_review_loop` boolean: a reviewer approves exactly when it returns `stop_review_loop=true` with no `reviewer_error`, parse failures still count as non-approval, and Goal's reducer completes on quorum of those booleans without recomputing approval from findings arrays, priorities, or `requirements_traceability` statuses. Recomputing approval from those arrays could deadlock runs whose acceptance criteria referenced the review process itself (for example "three reviewers approve" or "an unmerged PR is created"): no individual reviewer can prove such clauses, so traceability never became fully `proven` even when every reviewer explicitly approved, and the loop burned worker/review turns until `needs_human`. Reviewer prompts now state that the boolean is the single authoritative convergence signal, spell out how to derive it (blocking P0/P1/P2 findings and `required_by_objective` findings at any priority mean `false`; in-scope P3 nice-to-haves, `beyond_objective`/`contradicts_objective` observations, the reviewer-quorum process itself, and the authorized post-approval PR/MR/review final action must never hold it at `false`), and keep findings/traceability as required audit evidence. `findingBlocksClosure`/`isBlockingFinding` still classify findings for prompts and consolidated repair batches.
- Synchronized the complete builtin `impeccable` skill tree with pbakaus/impeccable at `630fc2682a5bd39b25a8e61f74b6b3f14f2b1e21`, including its latest references, detector libraries, live-review scripts, and provider integrations.

### Fixed

- Disabled terminal autowrap while the fullscreen workflow graph overlay is visible on Windows and restored the previous terminal mode when the overlay closes, preventing wrapped graph rows and stale terminal state ([#1760](https://github.com/bastani-inc/atomic/issues/1760)).
- Hardened synced Impeccable HTML filtering and preview selector escaping against nested sanitizer inputs, permissive script/style closing tags, HTML comment end-bang syntax, and backslash-containing session identifiers; also removed an ineffective CSS property replacement flagged by CodeQL.

## [0.9.7] - 2026-07-12

### Added

- Added a shared convergence contract for the builtin `goal` and `ralph` workflows (`builtin/shared-prompts.ts` + deterministic gates in `builtin/review-convergence.ts`): workers/orchestrators must derive an observable acceptance/contract matrix from the literal objective/acceptance criteria before implementing (one row per clause mapped to the concrete check that proves it) and must model states, transitions, and invariants explicitly for stateful work; reviewers must independently derive adversarial checks (boundary/edge/negative and state/transition/invariant probes) from the literal contract before relying on the worker receipt, implementation notes, or worker-authored tests; reproduced findings require durable regression evidence (a persisted test or exact re-runnable check) before they count as resolved; and the evidence-closure policy is stated to both roles so approval semantics are visible in-prompt. All contracts inherit the literal-contract scope controls, so no behavior beyond the objective/acceptance criteria is required.
- Added deduplicated cross-reviewer `consolidated_findings` batches to the Goal and Ralph `review-round-latest.json` artifacts (`consolidateFindingsBatch` in `builtin/review-convergence.ts`), with blocking entries sorted first and reviewer attribution merged per finding. Goal's next worker turn reads the round artifact first and is instructed to plan and repair the whole batch — grouped by root cause, with regression evidence — instead of fixing one finding per turn; Ralph's research/orchestrator stages receive the same batch through the round artifact.

### Changed

- Changed the built-in `goal` and `ralph` reviewer model defaults for GPT-5.6 Sol from the `:max` reasoning suffix to `:xhigh` across every provider form (`openai-codex`, `github-copilot`, `openai`, `cursor`, and `openrouter/openai`), including Ralph's `reviewer-b` primary model (`openai-codex/gpt-5.6-sol:xhigh`).
- Aligned all built-in Goal reviewer stages with Ralph's clean, non-forked reviewer context behavior and exact `reviewer-a` model configuration, making Claude Fable 5 the shared primary reviewer while keeping one canonical fallback chain.
- Changed builtin `goal` completion to evidence closure rather than reviewer agreement alone: the deterministic reducer now completes only when reviewer quorum is met AND no objective-relevant blocking finding from any reviewer in the current round remains unresolved. A quorum-met round with unresolved findings continues with an inspectable decision reason listing the findings, and the bounded loop still stops at `max_turns` as `needs_human` (with the closure gap recorded) so vetoes cannot drift indefinitely.
- Changed the shared Goal/Ralph review gate so severity labels alone can no longer dismiss objective-relevant findings: `required_by_objective` findings now block at any priority (P3 included) via the shared `findingBlocksClosure` predicate, while `consistent_with_objective` P3 nice-to-haves remain non-blocking (preserving the dummy-finding anti-spin behavior) and `beyond_objective`/`contradicts_objective` findings remain non-blocking scope controls. Goal's `reviewApproved` and Ralph's `isBlockingFinding`/`reviewDecisionApproved` now share this single deterministic predicate.
- Slimmed the builtin `goal`, `ralph`, and `open-claude-design` stage prompts to remove context-mode bloat: prompts no longer describe the stage's own context window ("previous conversation context", "previous workflow reasoning", or sibling parallel passes that a fresh stage cannot see), and forked continuation prompts now send only the per-iteration delta. Goal's forked worker turns send just the ledger pointer, latest receipts, and latest review artifacts; Ralph's forked orchestrator sends the rewritten research path and notes reminder; and Ralph's forked research-prompt-refinement and research continuations reference the skill, request, and contracts already present in their forked histories instead of re-injecting them (new `renderForkedResearchPromptRefinementPrompt`/`renderForkedResearchPrompt`). Each forked prompt carries a one-line pointer that previously established guidance still applies unchanged.

### Fixed

- Fixed workflow stage model fallback to classify provider usage-limit exhaustion (for example `Codex error: The usage limit has been reached`, plus `usage_limit`/`usage_limit_reached`/`usage_limit_exceeded`/`insufficient_quota` codes) as a retryable quota/rate-limit failure, so configured `fallbackModels` advance to the next candidate provider/model instead of failing the stage. The message matcher tolerates the same space/underscore/hyphen/joined separators as the code path, so provider errors that flatten the token into free text (for example `usage_limit_reached` or `usage-limit`) also advance the chain. Nested cause/diagnostic and session-shaped errors classify the same way, while cancellations, safety refusals, task/tool failures, and unrelated errors remain non-retryable.
- Fixed model orchestration guidance so every workflow launch from interactive chat stays in the background: named runs remain automatically detached, direct `task`/`tasks`/`chain` launches require top-level `async: true`, inspection and control calls are excluded, and foreground launches require an explicit user request or technical necessity plus advance notice ([#1765](https://github.com/bastani-inc/atomic/issues/1765)).

## [0.9.7-alpha.1] - 2026-07-12

### Added

- Added a shared convergence contract for the builtin `goal` and `ralph` workflows (`builtin/shared-prompts.ts` + deterministic gates in `builtin/review-convergence.ts`): workers/orchestrators must derive an observable acceptance/contract matrix from the literal objective/acceptance criteria before implementing (one row per clause mapped to the concrete check that proves it) and must model states, transitions, and invariants explicitly for stateful work; reviewers must independently derive adversarial checks (boundary/edge/negative and state/transition/invariant probes) from the literal contract before relying on the worker receipt, implementation notes, or worker-authored tests; reproduced findings require durable regression evidence (a persisted test or exact re-runnable check) before they count as resolved; and the evidence-closure policy is stated to both roles so approval semantics are visible in-prompt. All contracts inherit the literal-contract scope controls, so no behavior beyond the objective/acceptance criteria is required.
- Added deduplicated cross-reviewer `consolidated_findings` batches to the Goal and Ralph `review-round-latest.json` artifacts (`consolidateFindingsBatch` in `builtin/review-convergence.ts`), with blocking entries sorted first and reviewer attribution merged per finding. Goal's next worker turn reads the round artifact first and is instructed to plan and repair the whole batch — grouped by root cause, with regression evidence — instead of fixing one finding per turn; Ralph's research/orchestrator stages receive the same batch through the round artifact.

### Changed

- Changed the built-in `goal` and `ralph` reviewer model defaults for GPT-5.6 Sol from the `:max` reasoning suffix to `:xhigh` across every provider form (`openai-codex`, `github-copilot`, `openai`, `cursor`, and `openrouter/openai`), including Ralph's `reviewer-b` primary model (`openai-codex/gpt-5.6-sol:xhigh`).
- Aligned all built-in Goal reviewer stages with Ralph's clean, non-forked reviewer context behavior and exact `reviewer-a` model configuration, making Claude Fable 5 the shared primary reviewer while keeping one canonical fallback chain.
- Changed builtin `goal` completion to evidence closure rather than reviewer agreement alone: the deterministic reducer now completes only when reviewer quorum is met AND no objective-relevant blocking finding from any reviewer in the current round remains unresolved. A quorum-met round with unresolved findings continues with an inspectable decision reason listing the findings, and the bounded loop still stops at `max_turns` as `needs_human` (with the closure gap recorded) so vetoes cannot drift indefinitely.
- Changed the shared Goal/Ralph review gate so severity labels alone can no longer dismiss objective-relevant findings: `required_by_objective` findings now block at any priority (P3 included) via the shared `findingBlocksClosure` predicate, while `consistent_with_objective` P3 nice-to-haves remain non-blocking (preserving the dummy-finding anti-spin behavior) and `beyond_objective`/`contradicts_objective` findings remain non-blocking scope controls. Goal's `reviewApproved` and Ralph's `isBlockingFinding`/`reviewDecisionApproved` now share this single deterministic predicate.
- Slimmed the builtin `goal`, `ralph`, and `open-claude-design` stage prompts to remove context-mode bloat: prompts no longer describe the stage's own context window ("previous conversation context", "previous workflow reasoning", or sibling parallel passes that a fresh stage cannot see), and forked continuation prompts now send only the per-iteration delta. Goal's forked worker turns send just the ledger pointer, latest receipts, and latest review artifacts; Ralph's forked orchestrator sends the rewritten research path and notes reminder; and Ralph's forked research-prompt-refinement and research continuations reference the skill, request, and contracts already present in their forked histories instead of re-injecting them (new `renderForkedResearchPromptRefinementPrompt`/`renderForkedResearchPrompt`). Each forked prompt carries a one-line pointer that previously established guidance still applies unchanged.

### Fixed

- Fixed workflow stage model fallback to classify provider usage-limit exhaustion (for example `Codex error: The usage limit has been reached`, plus `usage_limit`/`usage_limit_reached`/`usage_limit_exceeded`/`insufficient_quota` codes) as a retryable quota/rate-limit failure, so configured `fallbackModels` advance to the next candidate provider/model instead of failing the stage. The message matcher tolerates the same space/underscore/hyphen/joined separators as the code path, so provider errors that flatten the token into free text (for example `usage_limit_reached` or `usage-limit`) also advance the chain. Nested cause/diagnostic and session-shaped errors classify the same way, while cancellations, safety refusals, task/tool failures, and unrelated errors remain non-retryable.
- Fixed model orchestration guidance so every workflow launch from interactive chat stays in the background: named runs remain automatically detached, direct `task`/`tasks`/`chain` launches require top-level `async: true`, inspection and control calls are excluded, and foreground launches require an explicit user request or technical necessity plus advance notice ([#1765](https://github.com/bastani-inc/atomic/issues/1765)).

## [0.9.6] - 2026-07-12

### Changed

- Restored workflow-first model routing for non-trivial, structured, and verifiable work while retaining the newer ability to author task-specific TypeScript workflows inline. Prompt guidance now explicitly combines the documented classify/branch, fan-out/synthesis, adversarial verification, generate/filter, tournament, and bounded loop patterns instead of forcing every workflow-fit task into an installed workflow, direct shape, or builtin.
- Restored Ralph's builtin implementation-stage prompts to require subagent-led investigation, editing, and validation, reversing the selective direct-implementation wording introduced with intent-first routing.
- Expanded model-facing workflow guidance to treat composition as a first-class design option: custom parents can import reusable project/package workflows or bundled builtin definitions, invoke them through `ctx.workflow(...)`, and nest further child workflows within `maxDepth` while preserving expanded graph visibility, HIL, durability, controls, and declared output contracts.

## [0.9.6-alpha.1] - 2026-07-12

### Changed

- Restored workflow-first model routing for non-trivial, structured, and verifiable work while retaining the newer ability to author task-specific TypeScript workflows inline. Prompt guidance now explicitly combines the documented classify/branch, fan-out/synthesis, adversarial verification, generate/filter, tournament, and bounded loop patterns instead of forcing every workflow-fit task into an installed workflow, direct shape, or builtin.
- Restored Ralph's builtin implementation-stage prompts to require subagent-led investigation, editing, and validation, reversing the selective direct-implementation wording introduced with intent-first routing.
- Expanded model-facing workflow guidance to treat composition as a first-class design option: custom parents can import reusable project/package workflows or bundled builtin definitions, invoke them through `ctx.workflow(...)`, and nest further child workflows within `maxDepth` while preserving expanded graph visibility, HIL, durability, controls, and declared output contracts.

## [0.9.5] - 2026-07-11

### Breaking Changes

- Hardened the builtin `goal` and `ralph` review contracts against objective-drift failures: review findings now require `objective_alignment`, Goal and Ralph review decisions require `requirements_traceability`, and reviewer approval rejects empty or non-proven traceability. Consumers that parse or synthesize these structured reviewer outputs must emit the new required fields.

### Added

- Added model-capability-aware `max` reasoning suffix support throughout workflow stage schemas, fallback candidates, authoring contracts, and TUI status labels ([#1703](https://github.com/bastani-inc/atomic/issues/1703)).
- Added `git_worktree_dir` to the builtin `goal` workflow with Ralph-parity input binding so Goal runs can create or reuse a repository worktree from `base_branch` while preserving the invoking repo-relative cwd for worker, reviewer, and optional final PR stages.
- Added immutable `acceptance_criteria` to the builtin `goal` and `ralph` workflows. Goal persists it in the ledger/model-visible projection and final reports; Ralph threads it through research, orchestrator, and reviewer prompts next to the literal objective contract. Orchestrators should pass the original task text when launching follow-up Goal or Ralph runs from reviewer findings.
- Added literal-contract prompt language shared by `goal` and `ralph`, objective-alignment arbitration for reviewer findings, non-blocking treatment for `beyond_objective`/`contradicts_objective` findings, and clause-by-clause requirements traceability so reviewer evidence must map directly back to the objective/acceptance criteria.
- Added attempt-first E2E guidance for `goal` and `ralph`: workers/reviewers must not skip playwright-cli/tmux validation because credentials or auth are merely assumed missing, and skipped E2E must cite the exact attempted commands and observed failure output.

### Changed

- Aligned the workflows extension peer dependency with upstream `pi-tui` `^0.80.6` as part of the consolidated Pi sync ([#1703](https://github.com/bastani-inc/atomic/issues/1703)).
- Replaced workflow-default routing with intent-first least orchestration: interactive exploration stays inline, bounded specialist delegation uses subagents, and workflows are reserved for clearly delegated autonomous jobs that benefit from long-running/background execution or durable stages, artifacts, resumability, HIL, gates, retries, or loops. Explicit loop and stop-condition requests remain key workflow signals when the user delegates execution, so convergence and evidence are tracked. Guidance now documents builtin/project/user/package workflows, direct one-off shapes, and the option to author a custom TypeScript workflow inline whenever that shape best achieves a workflow-fit task.
- Changed the builtin `ralph` workflow review fan-out from three reviewers to two (`reviewer-a` and `reviewer-b`), removing `reviewer-c` and its GLM-led model chain while keeping unanimous approval across the remaining reviewers.
- Aligned durable mid-chat workflow resumes with the standard pause/resume continuation prompt so resumed stages continue only when their scoped work remains unfinished.
- Improved workflow extension startup by seeding only the bundled startup registry during extension registration/session start, then loading user, project, and package workflow modules in the background or when `/workflow` commands and workflow tool actions need the full registry.
- Tightened the workflow-stage resume continuation prompt so resumed agents continue interrupted work only when needed and stop when the original or user-redefined task is already complete.
- Updated the bundled `impeccable` skill from upstream 3.8.0 to 3.9.1, adding native platform guidance, hooks support, expanded detector rules, and the latest reference/script fixes ([#1696](https://github.com/bastani-inc/atomic/issues/1696)).
- Changed the Claude Fable 5 reasoning level from `xhigh` to `high` across all builtin workflow model chains (`ralph` prompt-engineer/orchestrator/reviewer-a/reviewer-b/reviewer-c, `goal` reviewer, `deep-research-codebase` planner, and `open-claude-design`), covering both the native `anthropic/claude-fable-5` entries and their OpenRouter mirrors.
- Changed the Claude Opus 4.8 reasoning level from `xhigh` to `high` across the same builtin workflow model chains, covering the `github-copilot/claude-opus-4.8 (1m)`, `anthropic/claude-opus-4-8`, and `openrouter/anthropic/claude-opus-4-8` entries; Opus 4.8 entries already at `medium`/`low` value points are unchanged.
- Hardened the builtin `goal` and `ralph` loops against spec-vs-objective drift on enumerated error behavior (observed in an eval trace where an adversarial reviewer flagged a task-mandated diagnostic as a spec-conformance defect and the fix cycle silently reinterpreted the ambiguous input as valid behavior, losing the required error): the shared literal objective contract now instructs workers and reviewers to prefer loud errors over silent reinterpretation — when the objective/acceptance criteria enumerate required error conditions, messages, or rejections, each enumerated error gets the widest plausible trigger surface, ambiguous or unspecified inputs near an enumerated error case default to raising that error even when external spec knowledge says the input is valid, and narrowing an enumerated error's trigger surface requires explicit contract or pre-existing required-test demand. Both loops' reviewer bug-selection guidelines now forbid using external spec/standard conformance alone to flag a wide trigger surface for a contract-enumerated error as a defect; such spec-vs-objective tension must be classified `beyond_objective` instead of becoming a blocking finding that steers the implementation away from the contract's errors.
- Extracted the Ralph reviewer prompt into `builtin/ralph-reviewer-prompt.ts` (`renderRalphReviewerPrompt`) and deduplicated the new reviewer guard into a shared `REVIEWER_SPEC_VS_OBJECTIVE_GUARD` constant consumed by both the Goal and Ralph reviewer prompts, keeping `ralph-runner.ts` under the repository's 500-line file gate. No behavioral change beyond the guard itself.
- Hardened the workflow-tool prompt guidance against inline analysis-paralysis drift (observed in eval transcripts where an agent spent ~2 hours of pure reconnaissance on a workflow-fit task without ever considering a workflow): the agent must now decide and state the inline-vs-workflow execution mode before its first tool call (reconnaissance explicitly counts as inline execution), budget pre-workflow scoping to a few quick reads that only sharpen the objective and validation criteria, course-correct after roughly ten deliverable-free exploration tool calls (or repeated "let me verify one more thing" loops) by writing findings to a context file and handing off to the best-fit workflow via `reads` (named or user-defined workflows discovered with `action: "list"` first, builtin `goal`/`ralph` as fallbacks when nothing more specific fits), and treat sunk inline research as transferable via files rather than a reason to stay inline. Mirrored the same "Decide before you explore" and "Course-correct instead of drifting" guidance in `docs/workflows.md` under "When to Use Workflows".
- Refreshed the July 2026 frontier model rosters for the builtin Ralph, Goal, deep-research-codebase, and open-claude-design workflows: critical prompt-engineering, orchestration, planning, and review chains now use high-capacity Fable 5 `:xhigh` primaries or fallbacks with GPT-5.5, Opus 4.8 long-context `:xhigh`, GLM-5.2, and OpenRouter Fugu Ultra coverage, while Ralph research stays on the measured GPT-5.5 `:medium` / Fable 5 `:low` performance-per-dollar path and reviewer-C remains GLM-led for diversity.
- Updated workflow model-option schema documentation to show `:xhigh` long-context examples and kept the fallback fixtures aligned so unsupported direct `sakana/` IDs stay out of workflow chains while the valid `openrouter/sakana/fugu-ultra:high` mirror remains available.

### Fixed

- Fixed archived/read-only workflow transcript views to use the standard responsive footer and Ctrl+T copy-mode toggle/status, enabling normal terminal or tmux text selection while preserving Escape and Ctrl+D navigation ([#1706](https://github.com/bastani-inc/atomic/issues/1706)).
- Fixed workflow tool validation coercing `output: false` into the literal file path `false`, so disabled output remains disabled across direct task, parallel task, and chain execution.
- Hardened the bundled `impeccable` skill's local detector/live scripts against CodeQL-reported sanitization and command-injection patterns by tightening HTML block stripping, avoiding shell interpolation for `git check-ignore`, escaping Svelte preview CSS selectors correctly, and fixing the `ms*` JSX style prefix conversion.
- Fixed lazy workflow startup follow-through so `session_start` loads only workflow config before restore/cleanup, discovery diagnostics are reported after deferred discovery settles, failed lazy discovery attempts are retryable, direct workflow-tool `task`/`tasks`/`chain` runs bypass full workflow discovery, named workflow-tool runs and failed-run resume re-resolve their runtime after discovery, paused/current live-run resume and live resume pickers avoid registry discovery, failed/durable resume still loads resources before registry-dependent lookups, and command autocomplete falls back to current/admin completions when lazy discovery fails without evaluating workflow modules on the startup path.
- Fixed workflow lazy-startup session generation so session restarts and shutdowns invalidate in-flight background discovery before it can publish stale workflow registries into later sessions.
- Fixed workflow failure finalization so structured recoverable auth, rate-limit, and provider-exhaustion metadata captured on the run or its blocking stage (`failedStageId`) no longer allows the top-level run, `/workflow status`, durable status, or lifecycle notice to appear as a successful `completed` state. Goal-like `needs_human`, incomplete, or auth-blocked reducer outputs are still treated as blocked, structured provider/auth fallback exhaustion now preserves an actionable blocked/failure message and resumable metadata, legacy completed snapshots with incomplete returned statuses or structured blocking-stage failures render as blocked, tolerated non-fail-fast branch failures no longer reclassify completed runs, and Goal reviewer-batch fallback exhaustion stops promptly as `needs_human` instead of launching another worker turn.
- Fixed the fullscreen workflow graph statusline to mirror non-workflow extension statuses, so async/background subagent progress and completion remain visible while the graph overlay is active.
- Fixed `/workflow resume` and fresh runs for workflows that use reusable `gitWorktreeDir`/`git_worktree_dir` worktrees by persisting the original invocation cwd and resolved reusable-worktree metadata, replaying durable resumes from that original repository context instead of the resumed interactive session cwd, caching repeated per-run reusable-worktree setup, retrying transient read-only Git `rev-parse` timeouts, hardening Git subprocesses against interactive prompts, and reporting exact Git command/cwd/timeout/elapsed/status/signal diagnostics when worktree preflight fails.
- Fixed builtin `goal` and `ralph` reviewer convergence reporting so review artifacts and reducer/controller decisions now persist explicit parse/convergence summaries (`parsed`, `approved`, `stopReviewLoop`, `nextAction`, `finalActionRemaining`, and diagnostics). Malformed or missing structured reviewer output is surfaced as a parse failure distinct from parsed reviewer rejection/findings; PR/MR/review creation is represented as a post-approval final action when it is the only remaining task; successful reviewer convergence records the final action (`pull-request` or `finish`) without consuming another implementation loop; and the workflow authoring docs, default workflow guidance, and create-spec prompt now tell custom reviewer-gated workflows to model authorized PR, release, deployment, or publication work as final actions rather than implementation blockers while writing local, action-oriented prompts that do not rely on workflow/stage names as hidden context.
- Fixed workflow stage model fallback for unrecoverable context-window overflow: when Atomic's same-model auto-compaction exhausts its recovery attempt, the stage now advances to the next configured `fallbackModels` tier and, once all tiers are exhausted, stops with the terminal context-overflow error instead of compacting and retrying the same model indefinitely.
- Fixed workflow controlled-pause ordering around unresolved context overflow: paused stages now honor the pause/resume handshake before surfacing the terminal overflow, and a resume message is not sent over an already-recorded unresolved-overflow signal.
- Fixed reattached workflow stage fallback after unresolved context overflow: if the restored/resumed model tier exhausts context recovery, fallback now continues with the next tier after that resumed model (or stops terminally when it was the final tier) instead of replaying the primary model.
- Fixed durable workflow resume hydration so replayed `ctx.parallel`/`ctx.task` fanout keeps its original branch parentage, completed stages restore persisted summaries, timing, session/model metadata, and DBOS/file checkpoints round-trip the richer stage metadata used by status and graph views.
- Fixed workflow stage chats so attach, exit, and re-attach cycles during an in-flight `subagent` call replay the latest live tool partial result immediately instead of collapsing single, parallel, or chain calls back to the bare `renderCall` title until the next update; stage chats also prefer renderers from the stage's own agent session before falling back to the host chat so nested workflow stages can render tools that the parent chat does not expose. ([#1643](https://github.com/bastani-inc/atomic/issues/1643))

## [0.9.5-alpha.10] - 2026-07-11

### Added

- Added model-capability-aware `max` reasoning suffix support throughout workflow stage schemas, fallback candidates, authoring contracts, and TUI status labels ([#1703](https://github.com/bastani-inc/atomic/issues/1703)).

### Changed

- Aligned the workflows extension peer dependency with upstream `pi-tui` `^0.80.6` as part of the consolidated Pi sync ([#1703](https://github.com/bastani-inc/atomic/issues/1703)).
- Replaced workflow-default routing with intent-first least orchestration: interactive exploration stays inline, bounded specialist delegation uses subagents, and workflows are reserved for clearly delegated autonomous jobs that benefit from long-running/background execution or durable stages, artifacts, resumability, HIL, gates, retries, or loops. Explicit loop and stop-condition requests remain key workflow signals when the user delegates execution, so convergence and evidence are tracked. Guidance now documents builtin/project/user/package workflows, direct one-off shapes, and the option to author a custom TypeScript workflow inline whenever that shape best achieves a workflow-fit task.

- Changed the builtin `ralph` workflow review fan-out from three reviewers to two (`reviewer-a` and `reviewer-b`), removing `reviewer-c` and its GLM-led model chain while keeping unanimous approval across the remaining reviewers.

- Aligned durable mid-chat workflow resumes with the standard pause/resume continuation prompt so resumed stages continue only when their scoped work remains unfinished.

### Fixed

- Fixed archived/read-only workflow transcript views to use the standard responsive footer and Ctrl+T copy-mode toggle/status, enabling normal terminal or tmux text selection while preserving Escape and Ctrl+D navigation ([#1706](https://github.com/bastani-inc/atomic/issues/1706)).
- Fixed workflow tool validation coercing `output: false` into the literal file path `false`, so disabled output remains disabled across direct task, parallel task, and chain execution.

## [0.9.5-alpha.9] - 2026-07-09

### Changed

- Improved workflow extension startup by seeding only the bundled startup registry during extension registration/session start, then loading user, project, and package workflow modules in the background or when `/workflow` commands and workflow tool actions need the full registry.
- Tightened the workflow-stage resume continuation prompt so resumed agents continue interrupted work only when needed and stop when the original or user-redefined task is already complete.
- Updated the bundled `impeccable` skill from upstream 3.8.0 to 3.9.1, adding native platform guidance, hooks support, expanded detector rules, and the latest reference/script fixes ([#1696](https://github.com/bastani-inc/atomic/issues/1696)).

### Fixed

- Hardened the bundled `impeccable` skill's local detector/live scripts against CodeQL-reported sanitization and command-injection patterns by tightening HTML block stripping, avoiding shell interpolation for `git check-ignore`, escaping Svelte preview CSS selectors correctly, and fixing the `ms*` JSX style prefix conversion.
- Fixed lazy workflow startup follow-through so `session_start` loads only workflow config before restore/cleanup, discovery diagnostics are reported after deferred discovery settles, failed lazy discovery attempts are retryable, direct workflow-tool `task`/`tasks`/`chain` runs bypass full workflow discovery, named workflow-tool runs and failed-run resume re-resolve their runtime after discovery, paused/current live-run resume and live resume pickers avoid registry discovery, failed/durable resume still loads resources before registry-dependent lookups, and command autocomplete falls back to current/admin completions when lazy discovery fails without evaluating workflow modules on the startup path.
- Fixed workflow lazy-startup session generation so session restarts and shutdowns invalidate in-flight background discovery before it can publish stale workflow registries into later sessions.

- Fixed workflow failure finalization so structured recoverable auth, rate-limit, and provider-exhaustion metadata captured on the run or its blocking stage (`failedStageId`) no longer allows the top-level run, `/workflow status`, durable status, or lifecycle notice to appear as a successful `completed` state. Goal-like `needs_human`, incomplete, or auth-blocked reducer outputs are still treated as blocked, structured provider/auth fallback exhaustion now preserves an actionable blocked/failure message and resumable metadata, legacy completed snapshots with incomplete returned statuses or structured blocking-stage failures render as blocked, tolerated non-fail-fast branch failures no longer reclassify completed runs, and Goal reviewer-batch fallback exhaustion stops promptly as `needs_human` instead of launching another worker turn.
- Fixed the fullscreen workflow graph statusline to mirror non-workflow extension statuses, so async/background subagent progress and completion remain visible while the graph overlay is active.
- Fixed `/workflow resume` and fresh runs for workflows that use reusable `gitWorktreeDir`/`git_worktree_dir` worktrees by persisting the original invocation cwd and resolved reusable-worktree metadata, replaying durable resumes from that original repository context instead of the resumed interactive session cwd, caching repeated per-run reusable-worktree setup, retrying transient read-only Git `rev-parse` timeouts, hardening Git subprocesses against interactive prompts, and reporting exact Git command/cwd/timeout/elapsed/status/signal diagnostics when worktree preflight fails.

## [0.9.5-alpha.8] - 2026-07-08

### Fixed

- Fixed builtin `goal` and `ralph` reviewer convergence reporting so review artifacts and reducer/controller decisions now persist explicit parse/convergence summaries (`parsed`, `approved`, `stopReviewLoop`, `nextAction`, `finalActionRemaining`, and diagnostics). Malformed or missing structured reviewer output is surfaced as a parse failure distinct from parsed reviewer rejection/findings; PR/MR/review creation is represented as a post-approval final action when it is the only remaining task; successful reviewer convergence records the final action (`pull-request` or `finish`) without consuming another implementation loop; and the workflow authoring docs, default workflow guidance, and create-spec prompt now tell custom reviewer-gated workflows to model authorized PR, release, deployment, or publication work as final actions rather than implementation blockers while writing local, action-oriented prompts that do not rely on workflow/stage names as hidden context.

- Fixed workflow stage model fallback for unrecoverable context-window overflow: when Atomic's same-model auto-compaction exhausts its recovery attempt, the stage now advances to the next configured `fallbackModels` tier and, once all tiers are exhausted, stops with the terminal context-overflow error instead of compacting and retrying the same model indefinitely.
- Fixed workflow controlled-pause ordering around unresolved context overflow: paused stages now honor the pause/resume handshake before surfacing the terminal overflow, and a resume message is not sent over an already-recorded unresolved-overflow signal.
- Fixed reattached workflow stage fallback after unresolved context overflow: if the restored/resumed model tier exhausts context recovery, fallback now continues with the next tier after that resumed model (or stops terminally when it was the final tier) instead of replaying the primary model.
- Fixed durable workflow resume hydration so replayed `ctx.parallel`/`ctx.task` fanout keeps its original branch parentage, completed stages restore persisted summaries, timing, session/model metadata, and DBOS/file checkpoints round-trip the richer stage metadata used by status and graph views.

## [0.9.5-alpha.6] - 2026-07-06

### Fixed

- Fixed workflow stage chats so attach, exit, and re-attach cycles during an in-flight `subagent` call replay the latest live tool partial result immediately instead of collapsing single, parallel, or chain calls back to the bare `renderCall` title until the next update; stage chats also prefer renderers from the stage's own agent session before falling back to the host chat so nested workflow stages can render tools that the parent chat does not expose. ([#1643](https://github.com/bastani-inc/atomic/issues/1643))

## [0.9.5-alpha.5] - 2026-07-06

### Added

- Added `git_worktree_dir` to the builtin `goal` workflow with Ralph-parity input binding so Goal runs can create or reuse a repository worktree from `base_branch` while preserving the invoking repo-relative cwd for worker, reviewer, and optional final PR stages.

### Changed

- Changed the Claude Fable 5 reasoning level from `xhigh` to `high` across all builtin workflow model chains (`ralph` prompt-engineer/orchestrator/reviewer-a/reviewer-b/reviewer-c, `goal` reviewer, `deep-research-codebase` planner, and `open-claude-design`), covering both the native `anthropic/claude-fable-5` entries and their OpenRouter mirrors.
- Changed the Claude Opus 4.8 reasoning level from `xhigh` to `high` across the same builtin workflow model chains, covering the `github-copilot/claude-opus-4.8 (1m)`, `anthropic/claude-opus-4-8`, and `openrouter/anthropic/claude-opus-4-8` entries; Opus 4.8 entries already at `medium`/`low` value points are unchanged.

## [0.9.5-alpha.4] - 2026-07-05

### Changed

- Hardened the builtin `goal` and `ralph` loops against spec-vs-objective drift on enumerated error behavior (observed in an eval trace where an adversarial reviewer flagged a task-mandated diagnostic as a spec-conformance defect and the fix cycle silently reinterpreted the ambiguous input as valid behavior, losing the required error): the shared literal objective contract now instructs workers and reviewers to prefer loud errors over silent reinterpretation — when the objective/acceptance criteria enumerate required error conditions, messages, or rejections, each enumerated error gets the widest plausible trigger surface, ambiguous or unspecified inputs near an enumerated error case default to raising that error even when external spec knowledge says the input is valid, and narrowing an enumerated error's trigger surface requires explicit contract or pre-existing required-test demand. Both loops' reviewer bug-selection guidelines now forbid using external spec/standard conformance alone to flag a wide trigger surface for a contract-enumerated error as a defect; such spec-vs-objective tension must be classified `beyond_objective` instead of becoming a blocking finding that steers the implementation away from the contract's errors.
- Extracted the Ralph reviewer prompt into `builtin/ralph-reviewer-prompt.ts` (`renderRalphReviewerPrompt`) and deduplicated the new reviewer guard into a shared `REVIEWER_SPEC_VS_OBJECTIVE_GUARD` constant consumed by both the Goal and Ralph reviewer prompts, keeping `ralph-runner.ts` under the repository's 500-line file gate. No behavioral change beyond the guard itself.

## [0.9.5-alpha.3] - 2026-07-04

### Changed

- Hardened the workflow-tool prompt guidance against inline analysis-paralysis drift (observed in eval transcripts where an agent spent ~2 hours of pure reconnaissance on a workflow-fit task without ever considering a workflow): the agent must now decide and state the inline-vs-workflow execution mode before its first tool call (reconnaissance explicitly counts as inline execution), budget pre-workflow scoping to a few quick reads that only sharpen the objective and validation criteria, course-correct after roughly ten deliverable-free exploration tool calls (or repeated "let me verify one more thing" loops) by writing findings to a context file and handing off to the best-fit workflow via `reads` (named or user-defined workflows discovered with `action: "list"` first, builtin `goal`/`ralph` as fallbacks when nothing more specific fits), and treat sunk inline research as transferable via files rather than a reason to stay inline. Mirrored the same "Decide before you explore" and "Course-correct instead of drifting" guidance in `docs/workflows.md` under "When to Use Workflows".

## [0.9.5-alpha.2] - 2026-07-04

### Changed

- Refreshed the July 2026 frontier model rosters for the builtin Ralph, Goal, deep-research-codebase, and open-claude-design workflows: critical prompt-engineering, orchestration, planning, and review chains now use high-capacity Fable 5 `:xhigh` primaries or fallbacks with GPT-5.5, Opus 4.8 long-context `:xhigh`, GLM-5.2, and OpenRouter Fugu Ultra coverage, while Ralph research stays on the measured GPT-5.5 `:medium` / Fable 5 `:low` performance-per-dollar path and reviewer-C remains GLM-led for diversity.
- Updated workflow model-option schema documentation to show `:xhigh` long-context examples and kept the fallback fixtures aligned so unsupported direct `sakana/` IDs stay out of workflow chains while the valid `openrouter/sakana/fugu-ultra:high` mirror remains available.

## [0.9.5-alpha.1] - 2026-07-04

### Breaking Changes

- Hardened the builtin `goal` and `ralph` review contracts against objective-drift failures: review findings now require `objective_alignment`, Goal and Ralph review decisions require `requirements_traceability`, and reviewer approval rejects empty or non-proven traceability. Consumers that parse or synthesize these structured reviewer outputs must emit the new required fields.

### Added

- Added immutable `acceptance_criteria` to the builtin `goal` and `ralph` workflows. Goal persists it in the ledger/model-visible projection and final reports; Ralph threads it through research, orchestrator, and reviewer prompts next to the literal objective contract. Orchestrators should pass the original task text when launching follow-up Goal or Ralph runs from reviewer findings.
- Added literal-contract prompt language shared by `goal` and `ralph`, objective-alignment arbitration for reviewer findings, non-blocking treatment for `beyond_objective`/`contradicts_objective` findings, and clause-by-clause requirements traceability so reviewer evidence must map directly back to the objective/acceptance criteria.
- Added attempt-first E2E guidance for `goal` and `ralph`: workers/reviewers must not skip playwright-cli/tmux validation because credentials or auth are merely assumed missing, and skipped E2E must cite the exact attempted commands and observed failure output.

## [0.9.4] - 2026-07-03

### Changed

- Curated all builtin workflow model chains against Atomic's agentic-coding benchmark (pass@1 / avg cost per task, 2026-07-02) under a role-based placement principle: reviewer stages keep best-in-class verification models (`anthropic/claude-fable-5:xhigh`, `openai-codex/gpt-5.5:xhigh`, and `zai/glm-5.2:xhigh` for third-family diversity), every other stage leads with the best measured performance-per-dollar candidate (`ralph` prompt-engineer and the `deep-research-codebase` planner move to `openai-codex/gpt-5.5:xhigh`, the explorer to `openai-codex/gpt-5.5:low`), strictly dominated models (`claude-sonnet-5`, `claude-sonnet-4.6`, `gemini-3.1-pro`, `gemini-3.5-flash`) and unbenchmarked entries (`gpt-5.4-mini`, `claude-haiku-4.5`) were dropped, and every remaining chain entry corresponds to a benchmark datapoint. `open-claude-design` keeps its Anthropic-led chain with `claude-fable-5:xhigh` primary.
- Normalized all GLM-5.2 chain entries to the model's two real reasoning tiers: native `zai`/`zai-coding-cn` entries in medium-tier chains now say `:high` explicitly (replacing misleading `:medium` labels that silently billed at the "high" tier), judgment-tier chains keep `:xhigh`, and the `openrouter/z-ai/glm-5.2` mirror is now always `:xhigh`.
- Aligned the workflows extension peer dependency with upstream pi TUI `^0.80.3`.

### Fixed

- Fixed attached workflow stage viewers so the host `app.tools.expand` keybinding (Ctrl+O by default) toggles live-detail/tool-output expansion just like the main chat, including custom keybinding remaps ([#1607](https://github.com/bastani-inc/atomic/issues/1607)).
- Fixed workflow stage model fallback so request/context incompatibility failures (HTTP 400/413/422, unsupported tool/parameter, context-window overflow, `invalid_request`/`bad_request`/`too_large` errors) advance the chain to the next candidate, falling back to the current user-selected model when no configured candidate can serve the request; refusals, content-filter/safety blocks, cancellations, and task failures still stop the chain ([#1580](https://github.com/bastani-inc/atomic/issues/1580)).
- Fixed the builtin `goal` reviewer and `deep-research-codebase` planner model fallback chains missing the `openrouter/anthropic/claude-fable-5` mirror of their primary model, matching the ordering used by the other builtin chains.
- Classified generic provider `Connection error.` / `fetch failed` transport outages as explicit workflow transport errors so stage fallback metadata can distinguish them from ordinary provider/model outages while preserving the normal next-model fallback order.
- Fixed workflow lifecycle notices for structured workflow outputs whose returned `status` is `failed` or `blocked`: the runtime now records those runs as failed/blocked instead of successful completions, preserves their returned output, carries blocked summaries into lifecycle notice reasons, marks returned failures non-resumable with explicit terminal failure metadata, and emits failure/blocked lifecycle cards rather than success notices.

## [0.9.4-alpha.11] - 2026-07-03

### Fixed

- Fixed attached workflow stage viewers so the host `app.tools.expand` keybinding (Ctrl+O by default) toggles live-detail/tool-output expansion just like the main chat, including custom keybinding remaps ([#1607](https://github.com/bastani-inc/atomic/issues/1607)).

## [0.9.4-alpha.9] - 2026-07-02

### Changed

- Changed the Claude Fable 5 reasoning level back from `high` to `xhigh` across all builtin workflow model chains (`ralph` prompt-engineer/reviewer-a/reviewer-b/reviewer-c, `goal` reviewer, `deep-research-codebase` planner, and `open-claude-design`), covering both the native `anthropic/claude-fable-5` entries and their OpenRouter mirrors; this reverts the `xhigh` → `high` change shipped in 0.9.4-alpha.8.
- Curated all builtin workflow model chains against Atomic's agentic-coding benchmark (pass@1 / avg cost per task, 2026-07-02) under a role-based placement principle: **reviewers get best-in-class verification quality, every other stage gets the best measured performance-per-dollar**. Reviewer stages keep `anthropic/claude-fable-5:xhigh` (70% / $13.41, `ralph` reviewer-a and the `goal` reviewer), `openai-codex/gpt-5.5:xhigh` (67% / $7.23, reviewer-b), and `zai/glm-5.2:xhigh` (44% / $3.92, reviewer-c for third-family diversity). Non-reviewer stages moved to perf-per-dollar primaries: `ralph` prompt-engineer and the `deep-research-codebase` planner from `claude-fable-5:xhigh` to `openai-codex/gpt-5.5:xhigh` (−3pts for half the cost, with `fable-5:xhigh` as the first cross-family fallback), and the `deep-research-codebase` explorer from unbenchmarked `gpt-5.4-mini:low` to the measured cheap-tier value point `openai-codex/gpt-5.5:low` ($1.20 / task, 28 steps, 9.4k output tokens), backed only by measured fallbacks (`claude-opus-4.8:low` at 41% / $2.29, then `glm-5.2:high`). Unbenchmarked models (`gpt-5.4-mini`, `claude-haiku-4.5`) and unmeasured levels (`gemini-3.5-flash:low`) are removed entirely — every chain entry now corresponds to a benchmark datapoint. Dropped strictly dominated candidates from every chain: `claude-sonnet-5` (40–54% at $4.08–$26.40 per task with up to 268 steps), `claude-sonnet-4.6` (30% / $5.52), `gemini-3.1-pro` (12% / $9.48), and `gemini-3.5-flash` (37% / $7.34 with 276k output tokens). Moved `claude-opus-4.8` fallback entries from `:xhigh` to `:high` — its cost/value point (52% / $4.28 vs 54% / $8.01) — everywhere except `open-claude-design`, which keeps an Anthropic-led chain (`fable-5:xhigh` primary, Opus at `:xhigh`) since design quality, not $/task, is its objective. Added `anthropic/claude-fable-5:low` (60% / $3.76) as the Anthropic candidate in the medium-tier `ralph` research/orchestrator and `goal` worker chains.
- Normalized all GLM-5.2 chain entries to the model's two real reasoning tiers: GLM-5.2's thinking-level map collapses `minimal`/`low`/`medium`/`high` to its "high" effort and `xhigh` to "max", so the previous `zai/glm-5.2:medium` entries in the `ralph` research/orchestrator and `goal` worker chains silently ran (and billed) at the "high" tier under a misleading label. Native `zai`/`zai-coding-cn` entries in medium-tier chains now say `:high` explicitly, judgment-tier chains keep `:xhigh` (→ "max"), and the `openrouter/z-ai/glm-5.2` mirror — which only maps `:xhigh` — is now always `:xhigh` instead of unsupported `:medium`.

## [0.9.4-alpha.8] - 2026-07-02

### Changed

- Changed the Claude Fable 5 reasoning level from `xhigh` to `high` across all builtin workflow model chains (`ralph` prompt-engineer/reviewer-a/reviewer-b/reviewer-c, `goal` reviewer, `deep-research-codebase` planner, and `open-claude-design`), covering both the native `anthropic/claude-fable-5` entries and their OpenRouter mirrors.

### Fixed

- Fixed the builtin `goal` reviewer and `deep-research-codebase` planner model fallback chains missing the OpenRouter mirror of their primary model: `openrouter/anthropic/claude-fable-5` is now the first OpenRouter fallback candidate in both chains, matching the ordering already used by the `ralph` prompt-engineer/reviewer and `open-claude-design` chains.

## [0.9.4-alpha.7] - 2026-07-02

### Fixed

- Fixed workflow stage model fallback so request/context incompatibility failures (HTTP 400/413/422 bad/unprocessable/payload-too-large request, unsupported tool/parameter, context-length/context-window overflow, `invalid_request`/`bad_request`/`too_large` errors) advance the chain to the next candidate instead of stopping. When none of the configured candidates can serve the request, the stage now falls back to the current user-selected model. Refusals, content-filter/safety blocks, cancellations, and task failures still stop the chain ([#1580](https://github.com/bastani-inc/atomic/issues/1580)).

## [0.9.4-alpha.6] - 2026-07-01

### Changed

- Aligned the workflows extension peer dependency with upstream pi TUI `^0.80.3`; no workflows extension source changes were needed for this metadata sync.

## [0.9.4-alpha.5] - 2026-07-01

### Changed

- Published a synchronized Atomic 0.9.4-alpha.5 prerelease for the workflows extension; no workflow changes were made after 0.9.4-alpha.3.

## [0.9.4-alpha.4] - 2026-06-30

### Changed

- Published a synchronized Atomic 0.9.4-alpha.4 prerelease for the workflows extension; no workflow changes were made after 0.9.4-alpha.3.

## [0.9.4-alpha.3] - 2026-06-30

### Fixed

- Classified generic provider `Connection error.` / `fetch failed` transport outages as explicit workflow transport errors so stage fallback metadata can distinguish them from ordinary provider/model outages while preserving the normal next-model fallback order.

## [0.9.4-alpha.1] - 2026-06-29

### Fixed

- Fixed workflow lifecycle notices for structured workflow outputs whose returned `status` is `failed` or `blocked`: the runtime now records those runs as failed/blocked instead of successful completions, preserves their returned output, carries blocked summaries into lifecycle notice reasons, marks returned failures non-resumable with explicit terminal failure metadata, and emits failure/blocked lifecycle cards rather than success/checkmark notices.

## [0.9.3] - 2026-06-29

### Breaking Changes

- Enabled workflow durability by default with a zero-infrastructure per-workflow file backend under `~/.atomic/workflow-durable`, replacing the previous process-local in-memory default and removing the old `ATOMIC_WORKFLOW_DURABLE_DIR` opt-in path. Explicit in-memory durability remains available through custom/test backends or `ATOMIC_WORKFLOW_DURABLE=0`/`false`/`off`/`memory`.

### Added

- Added `StageContext.sendUserMessage(content, { deliverAs? })` so workflow authors can inject follow-on user turns into live stage sessions after `prompt()` resolves while preserving MCP scope, abort handling, and structured-output guards.
- Added cross-session durable workflow resumability with cached `ctx.tool`, `ctx.ui`, `ctx.stage`/`ctx.task`/`ctx.chain`/`ctx.parallel`, and child-workflow checkpoints, plus `/workflow resume` discovery of durable workflow history from session metadata and the durable backend.
- Added optional DBOS-backed durability through the lazily loaded `@dbos-inc/dbos-sdk`, including DBOS read-side hydration for resumable workflows when `DBOS_SYSTEM_DATABASE_URL` is set.
- Added OpenRouter fallback coverage to builtin `goal`, `ralph`, `deep-research-codebase`, and `open-claude-design` workflow model configs.

### Changed

- Marked workflow stage sessions as internal so they are excluded from normal Atomic resume history while remaining inspectable and resumable through workflow-specific commands and tools.
- Revised builtin `goal`, `ralph`, and `open-claude-design` prompts to emphasize full objective completion, stable non-ordinal artifacts, a shared five-level subagent nesting budget, and model-facing workflow guidance that routes non-trivial structured work to workflows by default.
- Aligned the workflows extension peer dependency with upstream pi TUI `^0.80.2`.

### Fixed

- Fixed workflow graph and attached-stage chat interactions, including direct mouse-click activation, mouse/trackpad wheel capture, copy-mode toggling, stale `Working...` spinners, terminal-row animation cleanup, and post-terminal subagent progress handling.
- Hardened durable resume, replay, checkpoint, and listing behavior across file and DBOS backends, including pending prompts, terminal/non-resumable states, stale cache entries, repeated quit/resume cycles, child workflow scope isolation, checkpoint identity hashing, retries, cancellation, and durable write failures.
- Fixed `/workflow resume` picker behavior for live, paused, failed, and cross-session durable workflows so it matches the standard Atomic resume selector and handles empty, headless, mixed live/durable, and cache-only states consistently.
- Fixed builtin workflow continuity and configuration edge cases, including `open-claude-design` generator/feedback forking, isolated workflow config discovery, durable schema-backed stage replay, parallel fail-fast finalization, and custom-backend propagation into child workflows.

## [0.9.3-alpha.6] - 2026-06-29

### Added

- Added OpenRouter fallback coverage to the builtin `goal`, `ralph`, `deep-research-codebase`, and `open-claude-design` workflow model configs so workflow stages have additional frontier, GLM, and Gemini provider redundancy.

## [0.9.3-alpha.5] - 2026-06-28

### Changed

- Aligned the workflows extension peer dependency with upstream pi TUI `^0.80.2`; no workflows extension source changes were needed for this metadata sync.

## [0.9.3-alpha.4] - 2026-06-28

### Changed

- Strengthened the model-facing workflow prompt guidance to treat workflows as the default path for non-trivial tasks and requests with inherent structure plus verifiable objectives, explicitly including implementation, build, debugging, bug-fix, migration, new-feature, scoped multi-file, and validation-heavy docs/code prompts alongside loop-shaped phrasing such as `do X until Y`, `repeat until`, `iterate until`, and review/fix/test-until-passing prompts.

## [0.9.3-alpha.3] - 2026-06-27

### Changed

- Published the Atomic 0.9.3-alpha.3 prerelease for the workflows extension from the same code as 0.9.3-alpha.2; no workflow changes were made after the previous prerelease.

## [0.9.3-alpha.2] - 2026-06-27

### Breaking Changes

- Workflow durability is now enabled by default with the zero-infrastructure per-workflow file backend rooted under `~/.atomic/workflow-durable`; the previous process-local in-memory default and `ATOMIC_WORKFLOW_DURABLE_DIR` opt-in path were removed. In-memory durability remains available for explicit test/custom backend overrides and for the privacy opt-out `ATOMIC_WORKFLOW_DURABLE=0`/`false`/`off`/`memory`. ([#1498](https://github.com/bastani-inc/atomic/issues/1498))

### Added

- Added `StageContext.sendUserMessage(content, { deliverAs? })` so workflow authors can inject a normal follow-on user turn into a stage session after `prompt()` resolves. Idle sessions start immediately, streaming sessions queue as follow-up by default (or steering with `deliverAs: "steer"`), schema-backed stages can continue after their one allowed structured `prompt()` without tripping the one-shot prompt guard, follow-on turns preserve the stage MCP allow/deny scope, and native stage sessions accept the same string or text/image block content as `AgentSession.sendUserMessage()`. Durable replayed cached stages now reject this live-session operation instead of silently ignoring it. ([#1520](https://github.com/bastani-inc/atomic/issues/1520))
- Added cross-session workflow resumability via a durable workflow backend seam (`packages/workflows/src/durable/`). Workflows now persist `ctx.*` operation checkpoints (tool, ui, stage) to a durable backend so a new Atomic session can resume a workflow started in a prior session from the last completed checkpoint, without re-running completed work. Cross-session persistence is enabled by default through a lock-protected per-workflow file backend at `~/.atomic/workflow-durable`; no environment variable is required. When `DBOS_SYSTEM_DATABASE_URL` is set, Atomic lazily initializes DBOS with Postgres-backed workflow/control records and falls back to the file backend if DBOS is unavailable. Top-level workflow metadata is mirrored as `workflow.durable.checkpoint` session entries for `/workflow resume` discovery. ([#1498](https://github.com/bastani-inc/atomic/issues/1498))
- Introduced `ctx.tool(name, args, fn, options?)` — a durable cached tool execution primitive that runs arbitrary TypeScript code and caches the result so completed side effects are not repeated on resume. Supports optional retry with exponential backoff via `retriesAllowed`, `maxAttempts`, `intervalMs`, and `backoffRate` options. Only `ctx.*` blocks produce durable checkpoints. ([#1498](https://github.com/bastani-inc/atomic/issues/1498))
- Added durable `ctx.ui` checkpointing: completed `ctx.ui.input` / `confirm` / `select` / `editor` / `custom` responses are cached by prompt identity that includes method, label/message, options, and call order, so repeated prompts do not collide and a resumed workflow does not re-ask already-answered prompts. ([#1498](https://github.com/bastani-inc/atomic/issues/1498))
- Added durable `ctx.stage` / `ctx.task` / `ctx.chain` / `ctx.parallel` / child `ctx.workflow` checkpointing: completed stage-like outputs are recorded with stable ordinal replay keys and replayed on resume, skipping re-execution while avoiding checkpoint id collisions after redispatch. Chain and parallel items reuse durable task checkpoints, and child workflow calls checkpoint the completed child result at the parent boundary. ([#1498](https://github.com/bastani-inc/atomic/issues/1498))
- Wired `/workflow resume` into the TUI command surface to fall back to the cross-session durable resume catalog when a target id is not a live run, and to surface durable root workflow history in fresh sessions. It lists resumable workflows by top-level id and resumes via DBOS-style replay (re-dispatch with the original workflow id so completed checkpoints are skipped), mirroring `/resume` ergonomics. ([#1498](https://github.com/bastani-inc/atomic/issues/1498))
- Added `@dbos-inc/dbos-sdk` as an optional dependency of `@bastani/atomic` so DBOS-backed durable execution is available without a separate install when the SDK resolves. The workflows package remains dependency-free at runtime; the DBOS adapter is loaded lazily only when `DBOS_SYSTEM_DATABASE_URL` is set. ([#1498](https://github.com/bastani-inc/atomic/issues/1498))
- Added a cross-session resume catalog (`scanResumableWorkflows`) that scans session JSONL files for durable checkpoint entries to build the `/workflow resume` selector list, displaying root workflow name, status, completed checkpoint count, and pending prompts. The scanner understands Atomic's actual extension custom-entry JSONL shape (`type: "custom"`, `customType: "workflow.durable.checkpoint"`) as well as legacy direct checkpoint rows.
- Added cancellation, failure, and retry semantics for durable workflows: killed/cancelled workflows are marked `cancelled` and excluded from automatic resume; recoverable failures remain in the resumable list; non-recoverable failures are filtered out; `ctx.tool` retries with exponential backoff; pending `ctx.ui` prompts leave off on resume for the user to answer.
- Added DBOS read-side hydration: when `DBOS_SYSTEM_DATABASE_URL` is set, a fresh Atomic process now hydrates its in-memory checkpoint mirror from DBOS on `/workflow resume` so workflows persisted by a prior session can be discovered and replayed without prior in-process state. Checkpoint records are stored as structured envelopes (including kind, checkpoint id, args hash, prompt hash, and replay key) in DBOS so hydration fully reconstructs the original checkpoint metadata. Root workflow metadata is mirrored separately, so DBOS helper-workflow completion does not make Atomic roots appear completed; `ctx.tool`/`ctx.ui`/`ctx.task` await async DBOS checkpoint persistence before returning side-effect results. Legacy/simple DBOS step outputs without the envelope are handled gracefully as generic stage checkpoints. ([#1498](https://github.com/bastani-inc/atomic/issues/1498))

### Fixed

- Added direct mouse-click activation for visible workflow graph nodes: clicking a node now focuses it and opens/attaches it through the same path as pressing Enter, with hit-testing based on the rendered node rectangles so overlay chrome/scroll geometry stays in sync while wheel scrolling and empty-space/chrome clicks remain safe no-ops. ([#1521](https://github.com/bastani-inc/atomic/issues/1521))
- Fixed attached workflow stage chats to capture mouse/trackpad wheel events by default and enable button-event SGR terminal reporting, keeping scroll gestures inside the active stage transcript or prompt instead of falling through to terminal/main-chat scrollback; `ctrl+t` now toggles true copy mode by disabling workflow-chat mouse reporting so terminal/tmux text selection works normally. ([#1519](https://github.com/bastani-inc/atomic/issues/1519))
- Routed idle `StageContext.sendUserMessage()` turns through the workflow stage guard so first-call injected turns record normal stage lifecycle and all idle injected turns observe abort/kill wiring, MCP scope, readiness handling, and the concurrency limiter. ([#1520](https://github.com/bastani-inc/atomic/issues/1520))
- Fixed attached workflow stage chats so stale terminal, paused, blocked, skipped, or otherwise no-longer-running live stage handles, terminal run/stage transitions before `agent_end`, reopened terminal chats, late post-terminal subagent tool updates, and partial subagent workflow-graph progress no longer keep the `Working...` spinner, animation tick, subagent renderer interval, renderer animation registry entry, or subagent progress spinner active, while genuine follow-up/prompt/resume `agent_start` work still shows progress on retained terminal stage chats. ([#1518](https://github.com/bastani-inc/atomic/issues/1518))
- Fixed `/workflow resume`'s interactive picker to reuse the same Atomic `/resume` session-selector tree chrome for live, paused, failed-resumable, and cross-session durable workflows, replacing the hand-rolled durable/combined picker so the selector is cosmetically consistent across resume flows. ([#1498](https://github.com/bastani-inc/atomic/issues/1498))
- Matched `/resume` empty-state behavior for interactive `/workflow resume` by opening the shared empty selector when no resumable workflow rows remain after filtering instead of printing an error. ([#1498](https://github.com/bastani-inc/atomic/issues/1498))
- Hid `/workflow resume` selector entries that only exist as stale session-cache metadata with no matching durable backend handle and hid durable `running`/`failed`/`blocked` rows whose workflow definition is no longer registered, filtering old pre-checkpoint-engine/test workflow runs instead of surfacing rows that can only fail as stale or missing-definition. ([#1498](https://github.com/bastani-inc/atomic/issues/1498))
- Persisted terminal non-resumable durable metadata during finalization so non-recoverable failed/blocked workflows do not remain visible in `/workflow resume` as resumable entries after they are completely finished. ([#1498](https://github.com/bastani-inc/atomic/issues/1498))
- Delayed durable `/workflow resume` discovery for `running`/`paused` workflows until the first durable checkpoint or pending checkpointable prompt exists, records resumable LM-stage session metadata as soon as a stage opens, and reopens that exact Atomic/Pi session file on durable resume so eligible stages continue mid-session while completed tool/UI/stage checkpoints still replay all-or-nothing. CLI/orchestrator quit now leaves durable-progress workflows resumable instead of treating panel close as an authoritative kill; `/workflow kill` remains the explicit non-resumable disposal path, and successful completion still marks the root workflow terminal and removes the row once the whole workflow terminates to the end. ([#1498](https://github.com/bastani-inc/atomic/issues/1498))
- Fixed repeated quit/resume durable LM-stage cycles by keeping in-progress stage-session metadata separate from completed stage-output checkpoints, persisting DBOS checkpoint records by checkpoint id rather than replay key, removing stale quit snapshots before reusing the original durable workflow id, and sending a single `Continue` continuation message to the recorded LM session instead of replaying the original workflow prompt. ([#1498](https://github.com/bastani-inc/atomic/issues/1498))
- Made `/workflow resume` list only inactive workflows: actively-running durable runs are hidden from the selector and refused on resume (in-session or cross-session) with an intuitive error pointing at `/workflow connect`/`/workflow kill`, while quitting the CLI/panel flips the durable handle from `running` to `paused` so it re-enters the resumable set. ([#1498](https://github.com/bastani-inc/atomic/issues/1498))
- Fixed DBOS durable metadata updates to use versioned metadata records with latest-timestamp hydration, removed invalid DBOS `duplicationPolicy` parameters, awaited completed stage checkpoint writes before returning to workflow code where practical, awaited DBOS initialization before first dispatch/list/resume in DBOS-configured runtimes, opened an interactive durable picker for no-arg `/workflow resume` when only durable entries exist (including sessions with only completed local runs), distinguished repeated same-name/same-args `ctx.tool` calls by stable ordinal identity, and made retry backoff observe cancellation before later attempts run. ([#1498](https://github.com/bastani-inc/atomic/issues/1498))
- Fixed durable stage lifecycle persistence so workflow completion waits for pending backend checkpoint writes (including DBOS async writes) and reports a failed run when those writes fail instead of acknowledging success before checkpoints are durable. Terminal durable status metadata is flushed before completed/failed/cancelled root runs return. Cached `ctx.task`, `ctx.chain`/`ctx.parallel` items, and child `ctx.workflow` replay now record completed replay nodes in the workflow graph/store, matching cached `ctx.stage` visibility. DBOS `recordCheckpointAsync()` updates the replay mirror only after DBOS accepts the checkpoint, so failed durable writes do not make the current process believe a side effect is safely replayable. ([#1498](https://github.com/bastani-inc/atomic/issues/1498))
- Fixed repeated `ctx.workflow(child)` calls to use a dedicated durable replay-key counter so cache-hit calls do not desync ordinal sequencing across resume; direct completed stages now checkpoint under the durable replay key used for lookup instead of the executor snapshot key; `ctx.exit` terminal states (`cancelled`, `blocked`, `skipped`) are now persisted to durable metadata and flushed; no-arg `/workflow resume` surfaces durable workflow history even when live local runs exist; and `durableBackend` is propagated into child workflow run options so custom backends are shared across parent and child instead of split-braining. ([#1498](https://github.com/bastani-inc/atomic/issues/1498))
- Fixed durable resume edge cases where workflows discovered only from session JSONL could be dropped before actual resume, schema-backed stage replay returned raw JSON text instead of structured values, parallel fail-fast skipped stages before async finalizers completed, retry backoff left abort listeners behind after normal sleeps, and durable stage checkpointing could ignore an explicit stage replay key. ([#1498](https://github.com/bastani-inc/atomic/issues/1498))
- Fixed durable replay robustness: child workflow internal `ctx.tool`/`ctx.ui`/`ctx.stage` side effects are now checkpointed under the parent/root durable workflow via a scoped backend keyed by the child boundary, so an interrupted child does not re-execute completed side effects on parent resume (previously child checkpoints were written under a fresh per-run UUID that was never recovered). `/workflow resume` now refuses cache-only entries as `stale` when a workflow has session-JSONL metadata but no durable checkpoint state in the backend, instead of silently re-running from scratch. Durable replay identities (`durableHash`) now use a SHA-256 digest instead of a 32-bit DJB2 hash that could collide across distinct tool/stage identities. `ctx.tool` re-checks cancellation after the tool function resolves and before recording/returning the side-effect result, so a side effect that completes concurrently with cancellation is not persisted as a replayable checkpoint. File-backed durability recovers from a stale lock directory left by a crashed process (backdated beyond a threshold) instead of wedging until the acquire timeout. ([#1498](https://github.com/bastani-inc/atomic/issues/1498))
- Fixed terminal durable cache suppression so stale session-JSONL entries cannot resurrect workflows the backend knows are completed/cancelled/non-resumable: the backend terminal state now takes precedence over older JSONL cache entries during listing and resume. Successful durable `/workflow resume <id>` now connects/opens the overlay to the resumed run, matching live resume ergonomics. No-arg `/workflow resume` now shows a combined selector (live runs + cross-session durable workflows) so durable workflows are directly selectable even when live runs exist, instead of only being printed as hints. Fixed `ScopedDurableBackend.listCheckpoints` to exclude sibling child scopes that shared a common id prefix (previously re-prefixing caused sibling checkpoints to leak into the wrong scope). Cleaned up a cosmetic merged import line in `run.ts`. ([#1498](https://github.com/bastani-inc/atomic/issues/1498))
- Fixed empty string stage outputs to be preserved durably as empty strings instead of being collapsed into status objects, so a stage completing with empty assistant text replays as empty rather than appearing to have no checkpoint. Schema-backed stage prompts with empty string results are now also checkpointed. Stage finalization failures (including durable checkpoint write errors) no longer leak the concurrency limiter/semaphore because each cleanup step is independently guarded. Mixed live+durable `/workflow resume` now uses async DBOS-hydrated durable listing (`prepareDurableResumable`) instead of a synchronous in-memory listing so cross-session entries discovered from Postgres are included in the combined selector. Replayed durable stages now register in the graph frontier tracker so parent/lineage topology is preserved for subsequent stages. Dismissing the combined resume picker returns to chat without opening a second live-only picker. ([#1498](https://github.com/bastani-inc/atomic/issues/1498))
- Fixed Ralph review regressions in durable resume: durable and combined pickers now settle selections before synchronous custom-UI disposal can dismiss them; headless no-arg durable resume prints the catalog instead of awaiting unavailable/no-op picker UI; failed live runs selected from the combined picker resume through the continuation path; durable resume dispatch forwards the interactive/non-interactive command policy; `ctx.ui.custom` replays cached void/`undefined` responses instead of treating them as cache misses; stage finalization errors are rethrown after releasing handles/limiters; and resume integration tests isolate the durable singleton so full integration runs remain deterministic. ([#1498](https://github.com/bastani-inc/atomic/issues/1498))
- Fixed default file-backed durability to write one JSON state file per root workflow instead of rewriting a shared `state.json` on every checkpoint, avoid all-files scans on point checkpoint lookups, prune completed/cancelled/non-resumable terminal workflow files while retaining running/paused/recoverable-failed files for crash recovery until resumed or killed, use restrictive `0700` durable directories and `0600` state/lock-owner files, fail closed to in-memory durability when no home directory is available, and reclaim stale locks only when their owner marker belongs to a dead process. Added `ATOMIC_WORKFLOW_DURABLE=0`/`false`/`off`/`memory` as a documented privacy opt-out for plaintext cross-session checkpoint persistence. ([#1498](https://github.com/bastani-inc/atomic/issues/1498))

## [0.9.3-alpha.1] - 2026-06-25

### Changed

- Workflow stage sessions are now marked as internal and excluded from the standard Atomic `/resume`, `atomic -r`, and `--continue` history, while remaining fully resumable/inspectable through `/workflow resume`, `/workflow attach`, and the `workflow` tool's `status`/`stages`/`stage`/`resume` actions via the run/stage store and its `sessionFile` links ([#1504](https://github.com/bastani-inc/atomic/issues/1504)).
- Revised the builtin `goal` worker/continuation prompts and the builtin `ralph` orchestrator prompts to emphasize implementing the requested task through full completion ("do not stop until the objective is complete") instead of preparing a partial implementation for incremental review.
- Removed model-visible current-iteration/turn/loop information from the builtin `goal`, `ralph`, and `open-claude-design` workflows so models are not biased by which iteration they are on. This drops the worker `Turn: N/M` banner, `Implement iteration N/M` / `Research iteration N/M` framing, "first iteration/worker turn" phrasing, and the live-preview `iteration N/M` label; switches model-relayed artifacts to stable non-ordinal names (`worker-receipt.md`, `review-<reviewer>.json`, `review-round-latest.json`, `orchestrator-report.md`); and strips turn fields from the model-facing goal ledger artifact. Internal UI stage names (e.g. `work-turn-2`, `orchestrator-2`) are unchanged, and the `max_turns`/`max_loops` inputs and `turns_completed`/`iterations_completed` outputs are retained.
- Raised workflow-stage subagent recursion to the shared five-level nesting budget so workflow stages match main-chat delegation depth.

### Fixed

- Fixed the builtin `open-claude-design` continuation loop so generator stages fork only from prior generator sessions and user-feedback stages fork only from prior feedback sessions; the first feedback stage now starts its own chain instead of inheriting generator context.
- Fixed workflow config loading and user-global discovery to honor `ATOMIC_CODING_AGENT_DIR` isolation instead of reading `~/.atomic/agent` when an isolated agent dir is configured.

## [0.9.2] - 2026-06-23

### Changed

- Removed the initial `prompt-refinement` stage and shared prompt-refinement helper from the builtin `goal` and `ralph` workflows so both now use the raw objective/prompt as the operative task text for their first downstream stages; the now-obsolete refined/original trace outputs were also removed.
- Updated builtin `goal` and `ralph` reviewer prompts to inspect referenced QA end-to-end video evidence before treating it as proof of user-visible behavior.
- Aligned the workflows package peer dependency with upstream pi TUI `^0.79.10`; no workflow source changes were needed for this metadata sync.

## [0.9.2-alpha.1] - 2026-06-23

### Changed

- Removed the initial `prompt-refinement` stage and shared prompt-refinement helper from the builtin `goal` and `ralph` workflows so both now use the raw objective/prompt as the operative task text for their first downstream stages; the now-obsolete refined/original trace outputs were also removed.
- Updated builtin `goal` and `ralph` reviewer prompts to inspect referenced QA end-to-end video evidence before treating it as proof of user-visible behavior.
- Aligned the workflows package peer dependency with upstream pi TUI `^0.79.10`; no workflow source changes were needed for this metadata sync.

## [0.9.1] - 2026-06-23

### Changed

- Changed the shared `goal`/`ralph` prompt-refinement stage to use a workflow-neutral, model-only rubric prompt that returns only the refined objective instead of invoking the `prompt-engineer` skill directly.

### Fixed

- Fixed the builtin `ralph` reviewer-c model configuration to use Gemini 3.1 Pro as the third reviewer with Gemini 3.1 provider fallbacks, removing Gemini 3.5 Flash from that slot's fallback chain ([#1484](https://github.com/bastani-inc/atomic/issues/1484)).

## [0.9.1-alpha.1] - 2026-06-22

### Changed

- Changed the shared `goal`/`ralph` prompt-refinement stage to use a workflow-neutral, model-only rubric prompt that returns only the refined objective instead of invoking the `prompt-engineer` skill directly.

### Fixed

- Fixed the builtin `ralph` reviewer-c model configuration to use Gemini 3.1 Pro as the third reviewer with Gemini 3.1 provider fallbacks, removing Gemini 3.5 Flash from that slot's fallback chain ([#1484](https://github.com/bastani-inc/atomic/issues/1484)).

## [0.9.0] - 2026-06-22

### Breaking Changes

- Replaced the removed `defineWorkflow(...).run(...).compile()` builder with the single `workflow({ name?, description, inputs, outputs, run })` authoring door; authored workflows now import and export the `workflow` definition directly.
- Removed the workflow stage/task/direct-mode `bashPolicy` option and schema so workflow-launched `bash` tools match upstream pi behavior; use `tools`/`noTools`, custom tools, or external sandboxing for command scoping.
- Changed the builtin `open-claude-design` workflow contract by renaming `browse_cli_status` to `playwright_cli_status` and removing the `reference`, `output_type`, and `design_system` inputs in favor of discovery-stage questioning.

### Added

- Added per-model context-window workflow authoring tokens such as `github-copilot/claude-opus-4.8 (1m):xhigh`, plus `contextWindow`/`contextWindowStrict` stage and direct-task options.
- Added deterministic workflow-stage resume handling that suppresses duplicate readiness prompts after interactive resumes and continues promptable stages exactly once.
- Added a `playwright-cli` QA proof-video path to the builtin `ralph` workflow and a safe final-stage attachment/link handoff when `create_pr=true`.
- Added shared initial prompt-refinement stages to the builtin `ralph` and `goal` workflows so raw requests are clarified with the `prompt-engineer` skill before research and orchestration.
- Added the builtin `goal` workflow's safe-by-default `create_pr` toggle and final `pull-request` stage for GitHub, Azure Repos, GitLab, Bitbucket, Sapling, or Phabricator handoff after reviewer/reducer approval.
- Restructured the builtin `open-claude-design` workflow around `impeccable` discovery/init, design-system/reference gathering, optional reference discovery, forked generate/user-feedback iterations, and a minimal exporter/final-display phase.

### Changed

- Decomposed the foreground workflow executor behind an internal `EngineRuntime.spawnStage(...)` chokepoint while preserving run, resume, kill, HIL, worktree, model-fallback, graph-frontier, and continuation behavior.
- Changed builtin `ralph`, `goal`, and `open-claude-design` browser automation guidance from the removed `browser` skill / `browse` CLI to the `playwright-cli` skill and command.
- Changed builtin `ralph` review fan-out to three independent model-family reviewers with severity-aware unanimous approval, stronger implementation-notes evidence requirements, and non-blocking P3 nit handling.
- Changed builtin workflows to use long-context GitHub Copilot fallback model tokens where available and to inherit upstream pi TUI `^0.79.9` compatibility fixes.
- Changed contributor validation to include the monorepo-wide file-length gate for tracked TS/JS/Rust files in local `prek` hooks and PR CI, with only documented generated/vendored exclusions and no grandfathered baseline allowlist.

### Fixed

- Fixed workflow stage sessions to inherit the host's non-default session directory in headless/forked runs while preserving explicit per-stage overrides.
- Fixed manual workflow pause/resume state so attached-stage controls update the main run status the same way `/workflow pause` and `/workflow resume` do.
- Fixed the builtin `ralph` review loop to stop on deterministic severity-aware unanimous approval instead of treating non-blocking P3 findings or placeholder findings as blockers.
- Fixed workflow model fallback to reuse the initially loaded credential/model registry, report real credential-store load failures, and resume follow-ups on the settled fallback model instead of replaying from the unavailable primary.
- Fixed `open-claude-design` user-feedback threading, test artifact placement, browser-unavailable early exits, snapshot copy safety, placeholder filtering, and read-only final display behavior.

## [0.9.0-alpha.4] - 2026-06-22

### Breaking Changes

- Restructured the builtin `open-claude-design` workflow's input contract. Removed the `reference`, `output_type`, and `design_system` inputs; the workflow now gathers those through a new `discovery` interview stage instead. The remaining inputs are `prompt`, `discover_references`, and `max_refinements`. Existing invocations that passed `reference=…`, `output_type=…`, or `design_system=…` should drop those arguments and let the discovery stage ask for the output type and references (or describe them in `prompt`).

### Added

- Restructured the builtin `open-claude-design` workflow around the accessible `impeccable` skill (`/skill:impeccable …`). The current phase order is: (1) **combined discovery/init** — one `discovery` stage runs `/skill:impeccable shape` to confirm the brief, output type, and references, then runs `/skill:impeccable init` so impeccable detects/creates/reconciles `PRODUCT.md` / `DESIGN.md` without a separate init stage; (2) **context/reference phase** — `ds-locator` / `ds-analyzer` / `ds-patterns` first gather project design-system evidence and handle user-provided URL/file reference capture/parsing, then optional `reference-discovery` browses curated galleries using the ds-* evidence and asks the user which curated direction they prefer (or asks for a reference image/screenshot/URL/path if none fit); (3) **forked generate/user-feedback loop** — `generate-1` produces the first `preview.html`, each `user-feedback-*` stage drives `/skill:impeccable live`, and meaningful feedback threads into the next forked `generate-*` stage; (4) **export** — export is now deliberately only `exporter` followed by `final-display`, with no `pre-export-scan`, `forced-fix`, `web-capture-*`, `file-parser-*`, or `design-system-builder` stages. User-provided references take **precedence over `DESIGN.md`/`PRODUCT.md`** through the `REFERENCE_PRECEDENCE` prompt block. Added unit coverage for the trimmed input contract, combined discovery/init stage, direct `ds-*` reference handling, forked generate/user-feedback continuity, removed export/parse/builder/init stages, and feedback persistence/threading.
- Added a safe-by-default `create_pr` toggle to the builtin `goal` workflow, matching Ralph's final-stage PR handoff behavior. Goal now skips PR/MR/review creation unless `create_pr=true` **and** reviewer quorum plus the reducer mark the run `complete` within the turn budget, omits `pr_report` when disabled or not approved, and runs a provider-aware `pull-request` stage only at the end when explicitly authorized. The final stage reads the goal ledger, worker receipts, latest review artifact, final report, and sanitized `base_branch` before attempting GitHub, Azure Repos, GitLab, Bitbucket, Sapling, or Phabricator handoff tooling. Goal worker/reviewer prompts now include an intermediate-stage guardrail telling them to ignore PR-creation requests because only the final `pull-request` stage may attempt that handoff.

### Fixed

- Fixed the builtin `open-claude-design` workflow feedback threading so `user-feedback-*` live annotations (`user_notes`, `live_changes`, and `annotated_snapshot`) are parsed, persisted under `<artifact_dir>/feedback/iteration-<n>.*`, and required to appear in the next `generate-*` prompt before a revision runs. The old internal critique/screenshot/apply stages were removed, so user feedback is now the sole refinement signal.
- Fixed the builtin `open-claude-design` workflow polluting the project's `specs/design/` tree with per-run artifact folders during automated test runs; `prepareArtifactDir` now writes to the OS tmpdir when `NODE_ENV=test`.
- Hardened the builtin `open-claude-design` browser and artifact safety paths: when the `playwright-cli` browser is unavailable the run exits cleanly up front (skipped under the test harness), annotation snapshot copies are constrained to the project/artifact dir, one-character real notes survive placeholder filtering, and the final `final-display` stage is read-only so it only surfaces the exported spec and re-run instructions.

## [0.9.0-alpha.3] - 2026-06-21

### Added

- Added a shared `prompt-refinement` stage to the builtin `ralph` and `goal` workflows. Both now run one `prompt-refinement` stage at the start that invokes the `prompt-engineer` skill (`/skill:prompt-engineer`) to sharpen the raw user request into a clearer, more actionable objective using the Workflow Best Practices prompt anatomy documented in `packages/coding-agent/docs/workflows.md` (`## Workflow Best Practices`). The refined request replaces the original as the operative objective for all downstream stages (research, orchestration, worker/review loops); the original request is preserved for traceability. `ralph` exposes `original_prompt` and `refined_prompt` outputs, and `goal` exposes `original_objective` (omitted when refinement left it unchanged) and records the original objective in the ledger and final report. The stage uses the same model chain as ralph's prompt-engineering stage (`promptEngineerModelConfig`).
- Renamed the builtin `ralph` workflow's per-iteration `prompt-engineer-${iteration}` stage to `research-prompt-refinement-${iteration}` (`renderPromptEngineerPrompt` → `renderResearchPromptRefinementPrompt`). It now consumes the clarity-refined request as input and continues to transform it into a codebase/online research question for the research stage.

## [0.9.0-alpha.2] - 2026-06-21

### Breaking Changes

- Replaced the removed `defineWorkflow(...).run(...).compile()` builder with the single `workflow({ name?, description, inputs, outputs, run })` authoring door. Authored workflows must import `workflow` from `@bastani/workflows`, import `Type` from `typebox`, provide an `outputs` map, and export the returned definition directly; `.compile()` and the builder types are no longer exported.
- Removed the workflow stage/task/direct-mode `bashPolicy` option and schema so workflow-launched `bash` tools match upstream pi behavior. Use `tools`/`noTools` to expose or hide `bash`, custom tools for narrow operations, and an OS/container sandbox for command allowlisting.

### Changed

- Decomposed the foreground workflow executor behind an internal, host-injected `EngineRuntime.spawnStage(...)` chokepoint. Agent stages, task/chain/parallel primitives, nested workflow boundary stages, MCP stage scope setup/cleanup, continuation replay wiring, and graph-frontier tracking now live under the engine seams while preserving the existing run, resume, kill, HIL, worktree, and model-fallback behavior.
- Aligned the workflows extension peer dependency with upstream pi TUI `^0.79.9` so workflow graph, custom UI, prompt-broker, and streamed Markdown surfaces inherit the latest shared TUI compatibility fixes, including stabilized partial code-fence rendering during streaming; no workflows extension source changes were needed for this dependency-covered sync.

## [0.9.0-alpha.1] - 2026-06-20

### Breaking Changes

- Renamed the builtin `open-claude-design` workflow output `browse_cli_status` to `playwright_cli_status` as part of migrating the workflow's preview/review tooling from the removed `browse` CLI to the `playwright-cli` command. Update any workflow-composition consumers that read `browse_cli_status`.

### Added

- Added a deterministic workflow-stage resume stop hook: after an interactive interrupt/pause is resumed with a message, the executor suppresses the #1099/#1264 readiness prompt for that resume-answer turn (including `ask_user_question` turns) and, when the stage remains promptable, sends `Continue where you left off.` in the same stage session once per resume; schema-backed stages that already finalized with `structured_output` consume the token without a second prompt ([#1407](https://github.com/bastani-inc/atomic/issues/1407)).
- Added a QA end-to-end proof video to the builtin `ralph` workflow. For UI-applicable or full-stack changes, the orchestrator now runs a `playwright-cli` end-to-end QA pass that drives the running app like a user, records a reviewable video (`playwright-cli video-start`/`video-stop`) to a stable run path, references it in the implementation notes (`## QA E2E Video`), and exposes it as the new optional `qa_video_path` output so the proof is available when the orchestrator finishes. When `create_pr=true`, the final `pull-request` stage attaches or links that video to the created PR/MR/review (embedding/linking where the provider supports media uploads, otherwise surfacing the absolute path). When no user-visible UI scenario applies, no video is produced and the notes record why.
- Added a per-model context-window authoring token to workflow model strings: a parenthesized token in the model-name portion, e.g. `github-copilot/claude-opus-4.8 (1m):xhigh`. The token may precede *or* follow the optional `:reasoning` suffix (`(1m):xhigh` or `:xhigh (1m)`); adopting GitHub Copilot's `Claude Opus 4.8 (1M context)` naming convention keeps the window separate from the reasoning level so the two never collide. Accepted token forms, all selecting the model's long tier when one exists: a generic size-agnostic `(long)` marker, or a rounded size matching the model's long tier (e.g. `(1m)` for claude-opus-4.8's 1M tier or `(1.1m)` for gpt-5.5's 1.05M tier). A request at or below the model's default keeps the default; a request above it selects the long tier (exact match wins, otherwise the smallest advertised window at or above the request, rounding **up** so a rounded marker always reaches the long tier); it falls back to the model's default (short) window when no long tier exists. It applies only to the candidate that carries the token, leaving primary and other fallback models untouched. Without the token, a tiered model now **pins its natural default (short) context window** in workflow stages so a persisted interactive long-context preference does not leak in (a stage-level `contextWindow`/`(long)` token still opts into long context). Also surfaced `contextWindow`/`contextWindowStrict` on `StageOptions` and the workflow tool's direct-task schema for stage-level selection.

### Changed

- Changed the shared `goal`/`ralph` prompt-refinement stage to use a workflow-neutral, model-only rubric prompt that returns only the refined objective instead of invoking the `prompt-engineer` skill directly.
- Changed the builtin `ralph`, `goal`, and `open-claude-design` workflows and the shared end-to-end verification guidance to drive browsers through the `playwright-cli` skill and `playwright-cli` command instead of the removed `browser` skill / `browse` CLI. Ralph/goal subagents now verify web and full-stack flows with `skill: "playwright-cli"`, and `open-claude-design`'s deterministic setup step now ensures `playwright-cli` (`npm install -g @playwright/cli@latest`) instead of `browse`, with every preview/review stage prompt updated to `playwright-cli open`/`snapshot`/`screenshot --filename`/`resize`/`show --annotate`.
- Changed the builtin `ralph` workflow review fan-out from two reviewers to three independent reviewers, each running on a different primary model family (Claude Fable 5, GPT-5.5 Codex, and Gemini 3.1 Pro) with shared fallbacks, so the adversarial review gets cross-model coverage instead of repeated passes from one model. The review loop stops only when all three reviewers independently approve (find no issues), so a P0–P3 finding from any single reviewer keeps Ralph iterating instead of being out-voted by a majority quorum. Also strengthened the orchestrator's implementation-notes contract to require verifiable evidence for any claims recorded in the notes and reviewer artifacts.
- Changed the builtin `deep-research-codebase`, `goal`, `ralph`, and `open-claude-design` workflows to run their GitHub Copilot `claude-opus-4.8` fallbacks at the model's largest advertised long-context (~1M/936K) window via the new `(1m)` token, automatically degrading to the 200K short window when Copilot's long-context tier is unavailable. Other models in each fallback chain are unaffected.
- Aligned the workflows extension peer dependency with upstream pi TUI `^0.79.7` so workflow graph, custom UI, and prompt-broker integrations consume the latest shared TUI color-scheme, Warp image capability, and compatibility fixes; no workflows extension code changes were made for this metadata sync ([#1413](https://github.com/bastani-inc/atomic/issues/1413)).
- Changed contributor validation to include the monorepo-wide file-length gate for tracked TS/JS/Rust files in local `prek` hooks and PR CI, with only documented generated/vendored exclusions and no grandfathered baseline allowlist ([#1445](https://github.com/bastani-inc/atomic/issues/1445)).

### Fixed

- Fixed the builtin `ralph` reviewer-c model configuration to use Gemini 3.1 Pro as the third reviewer and remove Gemini 3.5 Flash from that slot's fallback chain ([#1484](https://github.com/bastani-inc/atomic/issues/1484)).
- Fixed workflow stage transcripts ignoring the host's resolved non-default session directory in headless runs. Stages without an explicit `sessionDir` now inherit the active main-session directory when it comes from `--session-dir`, `ATOMIC_CODING_AGENT_SESSION_DIR`, or settings; explicit per-stage `sessionDir` still wins, default host sessions keep writing stages to the global store, and forked stages inherit the non-default directory too ([#1444](https://github.com/bastani-inc/atomic/issues/1444)).
- Fixed a manual workflow pause/resume not updating the main-chat run status the way the `workflow` tool and `/workflow pause`/`/workflow resume` do. Pausing a stage from the attached stage chat (Escape) or any direct live-handle path recorded only the **stage** as paused (`recordStagePaused`) and never the **run** (`recordRunPaused`), so the below-editor status widget and `/workflow status` kept showing the run as `running` (`●`) even though work was paused; resume had the symmetric gap. The executor stage-control handle now records run-level pause/resume itself — marking the run paused once no stage is still actively running (mirroring `pauseRun`'s all-active-stages-paused rule) and restoring it on resume — so manual and tool-driven pause/resume update the main chat identically. Both run-level transitions are idempotent, so the tool/slash path and cascade re-entry stay safe.
- Fixed the builtin `ralph` workflow review loop iterating until `max_loops` even when reviewers judged the patch correct. The unanimous-approval gate required a literally empty `findings` array, so a single low-priority **P3** nit — or a placeholder/dummy finding a reviewer appended because it wrongly believed an empty array would fail schema validation — kept the loop spinning despite every reviewer reporting `overall_correctness: "patch is correct"`. Approval is now **severity-aware and deterministic**: a reviewer approves when it judged the patch correct, reported no `reviewer_error`, and filed no *blocking* finding, where blocking = **P0/P1/P2** (priority 0/1/2) and **P3** (priority 3) is a non-blocking nice-to-have; a finding without a determinable priority (`null`/`undefined`) is treated as blocking so ambiguity never silently approves. The decision is computed from finding priorities rather than the reviewer's self-reported `stop_review_loop` flag. Extracted the gate into `builtin/ralph-review-gate.ts` (`reviewDecisionApproved`, `isBlockingFinding`) with unit coverage, and updated the reviewer prompt so an empty `findings` array is explicitly valid and placeholder findings are never fabricated ([#1407](https://github.com/bastani-inc/atomic/issues/1407)).
- Fixed workflow stage **model fallback misreporting configured providers as `No API key found`**. Each fallback candidate session was created with a fresh `AuthStorage`/`ModelRegistry`, so after a primary model failed (for example the Ralph `reviewer-a` chain hitting an unavailable `anthropic/claude-fable-5` and getting a real provider 404), every fallback candidate re-read `auth.json` from scratch. Under concurrent reviewer stages and OAuth token refreshes holding the `auth.json` lock, that fresh synchronous reload could fail and silently fall back to an empty credential set, reporting `No API key found` for `anthropic`/`openai-codex`/`github-copilot` even while sibling reviewer stages used those exact providers successfully. A stage now captures the `ModelRegistry` (and its already-loaded `AuthStorage`) from its first session and threads it into every subsequent fallback candidate, so a successfully-loaded credential store is reused across the whole fallback chain instead of being discarded and re-loaded per candidate. Combined with the coding-agent change that surfaces a real credential-store load failure instead of `No API key found`, a transient store-read failure remains a recoverable/retryable auth failure ([#1431](https://github.com/bastani-inc/atomic/issues/1431)).
- Fixed post-completion workflow follow-ups replaying the entire model-fallback chain from an unavailable primary instead of resuming on the model the stage settled on. After model fallback succeeded, the stage kept its working `session` but left `sessionPromise` undefined, and `ensureSession()` only checked `sessionPromise` — so a follow-up (`ctx.followUp`/`ctx.steer`/`ensureAttached`, and post-completion `workflow send`/TUI prompts) created a brand-new session from `candidates[0]` (the primary), discarding the working fallback session. For a chain whose primary 404s (e.g. `anthropic/claude-fable-5`), every follow-up re-ran `primary -> 404 -> ... -> working model` and could leave the stage stuck on the unavailable primary. `ensureSession()` now reuses an already-attached session, and `promptWithFallback()` retries the last-settled model first (for both live retained sessions and disk-reattached sessions), restarting the full chain from the primary only if that model fails again retryably ([#1431](https://github.com/bastani-inc/atomic/issues/1431)).

## [0.8.30] - 2026-06-17

### Changed

- Aligned the workflows extension peer dependency with upstream pi TUI `^0.79.4` so workflow graph, custom UI, and prompt-broker integrations consume the latest shared TUI fixes; no workflows extension code changes were made for this metadata sync.

### Fixed

- Fixed workflow stage sessions for workflows loaded through `atomic -e` to build fresh child resource loaders from the parent Atomic resource snapshot, preserving custom extensions/tools, subagents and agent definitions, skills, prompt templates, themes, packages, workflows, trusted borrowed project-local resources, explicit `resourceLoader` overrides, and recursive workflow-extension filtering.
- Fixed schema-backed workflow stages to send up to three corrective follow-up prompts when a turn finishes without the required `structured_output` call or with an invalid `structured_output` call, echoing the concrete contract/validation error before failing the stage.
- Fixed failed workflow stages to retain and persist SDK `sessionId`/`sessionFile` metadata, so post-error transcript inspection and follow-up messaging resume from the failed conversation instead of silently creating a fresh empty session.
- Fixed schema-backed workflow stages with `noTools: "all"` to keep the restrictive allowlist while still exposing the required `structured_output` final-answer tool.
- Fixed `ctx.parallel` graph inference so queued branches launched under a limited `concurrency` setting keep the same parent frontier as their sibling branches, even when an earlier sibling fails with `failFast: false`, instead of appearing as downstream children of failed siblings.

## [0.8.29] - 2026-06-15

### Added

- Added opt-in schema-backed workflow item results: `ctx.stage(..., { schema })`, `ctx.task(..., { schema })`, `ctx.chain` items, and `ctx.parallel` items now receive a schema-specific `structured_output` tool only for that item, return the captured value from `ctx.stage().prompt(...)`, and expose parsed task values as `result.structured` while preserving formatted JSON handoff text ([#1350](https://github.com/bastani-inc/atomic/issues/1350)).

### Changed

- Changed the builtin `ralph` workflow to start each iteration with `/skill:prompt-engineer` prompt-engineering and `/skill:research-codebase` research instead of an RFC/planner stage, pass the resulting research artifact to the orchestrator as primary implementation context, fork follow-up research from prior research session data, and feed unresolved reviewer findings into subsequent research passes ([#1371](https://github.com/bastani-inc/atomic/issues/1371)).
- Changed builtin `goal`, `ralph`, and `open-claude-design` decision gates to use schema-backed workflow `structured_output` stages with TypeBox-native schema builders instead of registering bespoke terminating custom tools or wrapping plain JSON schemas with `Type.Unsafe`.
- Changed the builtin `ralph` prompt-engineering stage to disable all tools while relying on the `/skill:prompt-engineer` skill prompt, keeping that first-pass rewrite focused and tool-free.
- Changed builtin `goal` worker/reviewer prompts and `ralph` orchestrator/reviewer prompts to request end-to-end verification when practical, using browser-skilled subagents for web/frontend flows that may depend on backend/API behavior and tmux-skilled subagents for TUI or terminal-app scenarios.
- Aligned the workflows extension with upstream pi TUI `^0.79.3` so workflow graph, custom UI, and prompt-broker integrations inherit the latest shared TUI compatibility fixes.
- Documented the opt-in `structured_output` workflow path and clarified that ordinary workflow stages do not receive `structured_output` from the default tool registry; schema-enabled items auto-add the runtime tool to explicit `tools` allowlists without adding extra workflow prompt text about the tool ([#1350](https://github.com/bastani-inc/atomic/issues/1350)).
- Removed top-level-object restrictions from workflow `structured_output` gate schemas; Atomic now passes any plain JSON Schema object directly to the tool and documents the one-`prompt()` limit for schema-backed `StageContext` result contracts ([#1350](https://github.com/bastani-inc/atomic/issues/1350)).

### Fixed

- Fixed direct workflow tool validation so schema-enabled `task`, `tasks`, `chain`, and `parallel` items accept plain JSON Schema objects without additional object-root constraints ([#1350](https://github.com/bastani-inc/atomic/issues/1350)).
- Fixed schema-backed workflow stages to fail with a clear stage-level error when `prompt()` is called more than once on the same `StageContext`, rather than surfacing the lower-level structured-output single-use guard ([#1350](https://github.com/bastani-inc/atomic/issues/1350)).
- Fixed schema-backed workflow model fallback so an attempt that already captured a valid terminating `structured_output` result is treated as successful instead of retrying against fallback models and tripping the single-use result guard ([#1350](https://github.com/bastani-inc/atomic/issues/1350)).
- Fixed the workflow graph overlay remaining interactive when the parent/main-chat agent opens `ask_user_question`: the graph keeps focus, the parent question stays pending behind it with a clear “Main chat needs input — exit graph to answer.” status hint, hiding/exiting the graph focuses the pending question, and host custom-UI state changes no longer hide, restore, remount, or repaint the overlay ([#1353](https://github.com/bastani-inc/atomic/issues/1353)).
- Fixed builtin `ralph` skill-prompt stages to invoke bundled skills through `/skill:<name>` expansion so prompt engineering and research stages receive the intended skill instructions.
- Fixed concurrent workflow stage resource reloads to serialize temporary subagent child environment isolation so parallel stage startup cannot leave parent process child flags accidentally cleared.
- Fixed workflow stage sessions to keep bundled workflow package skills (`create-spec`, `impeccable`, `prompt-engineer`, `research-codebase`, and `skill-creator`) available while still disabling only the recursive workflows extension inside child sessions.
- Fixed workflow stage resource discovery so bundled subagent definitions stay available, `subagent` is active by default with the same two-hop nesting budget as main chat, and explicitly allowlisted bundled extension tools such as `subagent`, `web_search`, `fetch_content`, and `intercom` remain visible even when a workflow is launched from a subagent child process.

## [0.8.28] - 2026-06-11

### Added

- Added workflow `ctx.ui.custom<T>(factory, options?)` for graph-visible custom TUI human-in-the-loop prompts. Custom prompts create `awaiting_input` prompt nodes, reuse the stage UI broker/attached stage chat component path, expose the same real TUI/theme/keybinding/component types as Atomic extension custom UI, participate in live-memory prompt replay through hashed custom identities, honor prompt/run abort signals, and reject clearly in headless/unavailable UI modes ([#1309](https://github.com/bastani-inc/atomic/issues/1309)).
- Added workflow authoring `ctx.exit(options?)` for intentional early terminal runs from any call depth, supporting `completed`, `skipped`, `cancelled`, and `blocked` terminal statuses, optional persisted/displayed reasons, and partial declared outputs with strict validation for provided output keys. Public run/detail/child status unions widen with `skipped`, `cancelled`, and `blocked`, and child workflow results are discriminated by `exited`.
- Added workflow stage/task `bashPolicy` wiring so individual workflow stages can constrain the built-in `bash` tool with command-level allow/deny rules, command-string glob matching, fail-closed invalid-policy validation, and default-allow no-rule compatibility.

### Changed

- Changed the builtin `deep-research-codebase`, `goal`, `ralph`, and `open-claude-design` workflows to use `anthropic/claude-fable-5:xhigh` as the primary planner/reviewer/design model, demoting each previous primary to the head of the fallback chain ([#1345](https://github.com/bastani-inc/atomic/pull/1345)).
- Changed workflow transcript introspection to return `sessionFile`/`transcriptPath` metadata with a lazy-read prompt by default when a transcript path exists, keeping bounded inline previews behind explicit `tail`/`limit` requests ([#1314](https://github.com/bastani-inc/atomic/issues/1314)).

### Fixed

- Fixed a workflow kill/abort race that could crash the entire CLI with a process-level uncaught exception when a workflow was killed mid-prompt; `raceAbort` now always observes the in-flight promise in the already-aborted branch so a killed run can no longer orphan a rejecting prompt.
- Fixed `ctx.exit(...)` cleanup races across the executor: the selected exit is a level-triggered gate so delayed `ctx.stage`/`ctx.task`/`ctx.chain`/`ctx.parallel`/`ctx.workflow`/graph-backed `ctx.ui.*` calls and retained `StageContext` session-control methods no longer create artifacts after exit, queued `ctx.parallel` work stops after exit, parent exits cancel linked hidden child workflows with typed parent-exit abort reasons and exactly-once stage-end ordering, and prompt-node abort handling preserves `workflow-exit` skipped reasons.
- Fixed terminal run-end reconciliation after `ctx.exit(...)` so when an external kill or another terminal writer wins `Store.recordRunEnd(...)`, the returned `RunResult` and `onRunEnd` callback report the canonical store status and only the winning run-end write is persisted.
- Fixed workflow-boundary child-edge metadata cleanup for `ctx.exit(...)` and continuation replay: skipped/failed boundaries clear `workflowChild`/`workflowChildRun`, stage-end persistence only emits child replay metadata for completed boundary stages, and expanded graph views no longer flatten stale child stages.
- Fixed `ctx.exit({ outputs })` payload capture to snapshot outputs by value at the first selected exit call, and deep-froze the thrown exit signal so author code cannot rewrite the terminal status, reason, or outputs after the fact.
- Fixed continuation replay races where replayed stage `prompt`/`complete` or prompt-node finalizers could complete after a concurrent `ctx.exit(...)`; pending replay finalizers now re-check the exit gate so resumed runs skip those stages instead of writing misleading completed stage-end entries.
- Fixed control-signal probing for arbitrary workflow-thrown values and abort reasons to use non-throwing reads, so throwing or inaccessible author accessors no longer leak from the executor catch path.
- Fixed interactive `ctx.ui.*` handling so workflow runs degrade gracefully: every primitive is guarded against method-less UI adapters with a clear per-method error, and headless (non-interactive) runs without a UI adapter reject with an explicit actionable message ([#1339](https://github.com/bastani-inc/atomic/issues/1339)).
- Fixed the builtin `open-claude-design` workflow not installing the browser skill's `browse` CLI before it is needed: a deterministic best-effort setup step probes `PATH` and installs the CLI when missing, per-run bootstrap guidance is injected into every browser-using stage, the install outcome is exposed via a new `browse_cli_status` output, and read-only `read`/`grep`/`ls` tools are granted to the refinement and pre-export decision gates ([#1327](https://github.com/bastani-inc/atomic/issues/1327)).
- Fixed paused workflow runs being counted as running in `/workflow status` (now shown separately as `❚❚ paused`) and run detail cards to surface the natural `workflow resume` action hint ([#1283](https://github.com/bastani-inc/atomic/issues/1283)).

## [0.8.28-alpha.4] - 2026-06-11

### Changed

- Changed the builtin `deep-research-codebase`, `goal`, `ralph`, and `open-claude-design` workflows to use `anthropic/claude-fable-5:xhigh` as the primary planner/reviewer/design model, demoting each previous primary (`openai-codex/gpt-5.5:xhigh` or `github-copilot/claude-opus-4.8:xhigh`) to the head of the fallback chain ([#1345](https://github.com/bastani-inc/atomic/pull/1345)).

## [0.8.28-alpha.3] - 2026-06-11

### Added

- Added workflow stage/task `bashPolicy` wiring so individual workflow stages can constrain the built-in `bash` tool with command-level allow/deny rules, command-string glob matching, escaped glob bracket-class literal preservation, reserved/compound-head rejection, leading-redirection and attached command-head redirection rejection, non-leading `>|` noclobber redirection handling, assignment-head rejection, invalid glob range handling through `invalid-policy`, unknown top-level policy key rejection, runtime invalid-policy validation, and default-allow no-rule compatibility.
- Added workflow authoring `ctx.exit(options?)` for intentional early terminal runs from any call depth. `ctx.exit` supports `completed`, `skipped`, `cancelled`, and `blocked` terminal statuses, optional persisted/displayed reasons (including in the default status list), and partial declared outputs while preserving strict validation for provided output keys. This widens public run/detail/child status unions with `skipped`, `cancelled`, and `blocked`; downstream exhaustive switches should add cases for those statuses, while `failed` remains for thrown errors and `killed` remains external run-control. Child workflow results are now discriminated by `exited`: `exited: false` has full declared outputs, while `exited: true` has partial outputs plus the child exit status/reason.

### Fixed

- Fixed `ctx.exit(...)` cleanup races so the selected exit is a level-triggered gate: delayed `ctx.stage`/`ctx.task`/`ctx.chain`/`ctx.parallel`/`ctx.workflow`/graph-backed `ctx.ui.*` calls and retained `StageContext` session-control methods no longer create graph, control, or `AgentSession` artifacts after exit; queued `ctx.parallel` work stops after exit even with `failFast: false`; parent exits cancel already-linked hidden child workflows with a typed parent-exit abort reason while the child executor owns skipped child stage/prompt cleanup, live handle/session disposal, and non-resumable `cancelled` child run finalization; parent finalization waits for that child cleanup so child `workflow.stage.end` entries are written exactly once before child and parent `workflow.run.end`; and prompt-node abort handling preserves `workflow-exit` skipped reasons instead of overwriting them with `run-aborted`.
- Fixed terminal run-end reconciliation after `ctx.exit(...)` cleanup races. If an external kill or another terminal writer wins `Store.recordRunEnd(...)` while exit cleanup or exit-output validation is pending, the returned `RunResult` and `onRunEnd` callback now report the canonical store status/result/error/reason (for example `killed`) and only the winning run-end write is persisted.
- Fixed workflow-boundary child-edge metadata cleanup for `ctx.exit(...)` and continuation replay. Boundaries that finalize as `skipped` or `failed` now clear `workflowChild`/`workflowChildRun`, stage-end persistence only emits child replay metadata for completed boundary stages, restore ignores stale child metadata on skipped/failed stage-end entries, and expanded graph views no longer flatten stale child stages from non-completed boundaries.
- Fixed `ctx.exit({ outputs })` payload capture to snapshot outputs by value at the first selected exit call. Later `finally` mutations can no longer remove undeclared keys or change valid/invalid values before post-cleanup validation, and option/output getter or enumeration failures now run workflow-exit cleanup before finalizing as non-resumable authoring failures when that terminal write wins.
- Fixed `ctx.exit(...)` exposing mutable finalization state to author code. The thrown exit signal and its captured output snapshot are now deep-frozen, so a workflow that catches the exit signal in a broad `try`/`catch` and mutates it before rethrowing can no longer rewrite the terminal status, reason, or outputs (finalization recovers the same frozen object via the run abort reason or the rethrow).
- Fixed continuation replay races where replayed stage `prompt`/`complete` or prompt-node finalizers could complete after a concurrent `ctx.exit(...)`. Pending replay finalizers now register with workflow-exit cleanup and re-check the exit gate after their replay microtask, so resumed runs skip/suppress those stages instead of writing misleading completed stage-end entries.
- Fixed control-signal probing for arbitrary workflow-thrown values and abort reasons. `ctx.exit(...)`/parent-exit detection now uses non-throwing reads for private markers, `scope`, aggregate `errors`, `cause`, and `reason`; throwing or inaccessible author accessors are ignored for that probe branch so runs finalize as ordinary failures or kills instead of leaking accessor errors from the executor catch path.
- Fixed interactive `ctx.ui.*` handling so workflow runs degrade gracefully instead of crashing or emitting a confusing error. Partial/method-less UI adapters could previously surface a raw `TypeError: <method> is not a function` for `input`/`confirm`/`select`/`editor` (only `custom` was already guarded); every primitive is now guarded and rejects with a clear, actionable per-method error. Separately, headless/background (non-interactive) runs without a UI adapter now reject with an explicit "interactive ctx.ui.<primitive> is unavailable in headless (non-interactive) mode…" error that points to running interactively or removing the prompt, replacing the generic "Atomic runtime did not provide a UI adapter" wording for that path. Earlier completed stages remain completed, and interactive background runs keep brokering `ctx.ui.custom` through awaiting-input prompt nodes ([#1339](https://github.com/bastani-inc/atomic/issues/1339)).

## [0.8.28-alpha.2] - 2026-06-10

### Fixed

- Fixed the builtin `open-claude-design` workflow not installing the browser skill's `browse` CLI before it is needed. The workflow now runs an initial deterministic, best-effort setup step that probes `PATH` (`which`/`where browse`) and installs the CLI with `npm install -g browse` when missing (skipped under automated tests); per-run bootstrap guidance is derived from the outcome and injected into every browser-using stage (assume-available when ensured, with concrete recovery steps surfaced when the install failed), the install outcome is exposed via a new `browse_cli_status` output, and the read-only `read`/`grep`/`ls` tools are granted to the refinement and pre-export decision gates so they can inspect `preview.html` without mutating it. The step never throws or blocks the run, so stages keep their graceful-degradation fallback ([#1327](https://github.com/bastani-inc/atomic/issues/1327)).
- Fixed paused workflow run detail cards to surface the natural `workflow resume` action hint while preserving the interrupt hint for non-paused active runs ([#1283](https://github.com/bastani-inc/atomic/issues/1283)).
- Fixed paused workflow runs being counted as running and displayed as pending/running in `/workflow status` and `/workflow status <id>`, with paused runs now shown separately as `❚❚ paused` ([#1283](https://github.com/bastani-inc/atomic/issues/1283)).

## [0.8.28-alpha.1] - 2026-06-09

### Added

- Added workflow `ctx.ui.custom<T>(factory, options?)` for graph-visible custom TUI human-in-the-loop prompts. Custom prompts create `awaiting_input` prompt nodes, reuse the stage UI broker/attached stage chat component path, expose the same real TUI/theme/keybinding/component types as Atomic extension custom UI, participate in live-memory prompt replay through hashed custom identities, keep labels display-only/outside replay identity, honor prompt/run abort signals, and reject clearly in headless/unavailable UI modes. Iteration 1 supports inline graph rendering; `overlay: true` and non-TUI `workflow send` answers for arbitrary custom widget results return clear unsupported errors rather than silently degrading ([#1309](https://github.com/bastani-inc/atomic/issues/1309)).

### Changed

- Changed workflow transcript introspection to return `sessionFile`/`transcriptPath` metadata with a lazy-read prompt by default when a transcript path exists, while keeping bounded inline previews behind explicit `tail`/`limit` requests and falling back to a small preview when no path is available ([#1314](https://github.com/bastani-inc/atomic/issues/1314)).

### Fixed

- Fixed a workflow kill/abort race that could crash the entire CLI with a process-level uncaught exception (for example `No API key found for ...`). When a workflow was killed mid-prompt, the executor's `raceAbort` left the already-in-flight stage prompt promise unobserved; its later rejection escaped every workflow error boundary and became an unhandled rejection. `raceAbort` now always observes the in-flight promise in the already-aborted branch so a killed run can no longer orphan a rejecting prompt.

## [0.8.27] - 2026-06-08

### Changed

- Promoted the 0.8.27 prerelease package version to a stable release.

## [0.8.26] - 2026-06-08

### Changed

- Updated workflow-stage chat so `/compact` is the no-argument compaction command and `/context-compact` is no longer handled locally.
- Refined bundled workflow prompts to keep natural instructions inside meaningful XML sections while removing redundant wrapper noise.
- Upgraded builtin workflow fallback model tiers so degraded runs land on stronger models across `deep-research-codebase`, `goal`, `ralph`, and `open-claude-design` ([#1259](https://github.com/bastani-inc/atomic/issues/1259)).
- Changed the builtin `ralph` workflow to include the workflow current working directory in every stage prompt and to skip pull-request creation by default unless `create_pr=true`, omitting `pr_report` when disabled while keeping provider-aware PR/MR/review creation instructions in the final stage ([#1255](https://github.com/bastani-inc/atomic/issues/1255)).
- Updated the `research-codebase` skill to capture and carry a `breaking_changes_allowed` compatibility posture through research fanout and downstream research documents ([#1225](https://github.com/bastani-inc/atomic/issues/1225)).

### Fixed

- Fixed workflow custom-message renderers for inline forms and workflow run banners so persisted workflow messages no longer crash the host TUI with `child.render is not a function` on `/resume` ([#1236](https://github.com/bastani-inc/atomic/issues/1236)).
- Fixed the workflow input form so transient `/workflow <name>` argument selectors do not leak into model context and rehydrated stale input-form cards render nothing after `/resume`.
- Made stage sessions emit `session_shutdown` before `dispose()`, giving bound extensions graceful shutdown and preventing leaked child MCP servers or stale-context MCP initialization noise.
- Fixed stage-local workflow HIL `input` and `editor` prompts losing draft text across Ctrl+D detach/reattach; drafts are kept live-only in memory and cleared when the prompt or run/stage exits ([#1179](https://github.com/bastani-inc/atomic/issues/1179)).
- Fixed workflow worktree Git commands to strip ambient repository-local Git environment variables before inspecting or creating targeted worktrees.
- Suppressed intermediate model fallback failure warnings from successful workflow stages while preserving final failures and raw per-attempt diagnostics ([#1226](https://github.com/bastani-inc/atomic/issues/1226)).
- Fixed the workflow global tool-event hook ignoring unscoped parent-session prompts instead of attributing them to running stages, preventing false `awaiting_input` / "needs attention" states from unrelated `ask_user_question` calls ([#1261](https://github.com/bastani-inc/atomic/issues/1261)).
- Fixed the builtin `goal` and `ralph` workflows to fork looped worker/orchestrator-stage sessions from their matching prior iteration, preserving accumulated context while keeping reviewer stages independent ([#1275](https://github.com/bastani-inc/atomic/issues/1275)).
- Fixed workflow completion gates to rely on structured decision fields instead of manual text/regex heuristics in `goal` and `open-claude-design`.

## [0.8.26-alpha.11] - 2026-06-08

### Changed

- Published a synchronized Atomic 0.8.26-alpha.11 prerelease alongside the subagent codebase-agent tool restriction changes; no functional changes were made in the workflows extension.

## [0.8.26-alpha.10] - 2026-06-08

### Changed

- Bumped package version for the Atomic 0.8.26-alpha.10 prerelease.

## [0.8.26-alpha.9] - 2026-06-07

### Changed

- Bumped package version for the Atomic 0.8.26-alpha.9 prerelease.

## [0.8.26-alpha.8] - 2026-06-07

### Changed

- Updated workflow-stage chat so `/compact` is the no-argument compaction command and `/context-compact` is no longer handled locally.

## [0.8.26-alpha.7] - 2026-06-07

### Changed

- Refined bundled workflow prompts to keep natural instructions inside meaningful XML sections while removing redundant wrapper noise.

### Fixed

- Fixed the builtin `goal` and `ralph` workflows to fork looped worker/orchestrator-stage sessions from their matching prior iteration, preserving accumulated context while keeping reviewer stages independent ([#1275](https://github.com/bastani-inc/atomic/issues/1275)).
- Fixed workflow completion gates to rely on structured decision fields instead of manual text/regex heuristics in `goal` and `open-claude-design`.

## [0.8.26-alpha.6] - 2026-06-06

### Changed

- Bumped package version for the Atomic 0.8.26-alpha.6 prerelease.

## [0.8.26-alpha.5] - 2026-06-06

### Fixed

- Fixed the workflow global tool-event hook ignoring unscoped parent-session prompts instead of attributing them to running stages, preventing false `awaiting_input` / "needs attention" states from unrelated `ask_user_question` calls ([#1261](https://github.com/bastani-inc/atomic/issues/1261)).

## [0.8.26-alpha.4] - 2026-06-05

### Changed

- Upgraded builtin workflow fallback model tiers so degraded runs land on stronger models: bumped `github-copilot/claude-opus-4.8` fallbacks from `:medium` to `:xhigh` in `deep-research-codebase` and `ralph`, replaced `claude-sonnet-4-8`/`4.8` fallbacks with `claude-opus-4-8`/`4.8` in the `goal` and `ralph` runner configs, and raised `claude-sonnet-4-6`/`4.6` fallbacks from `:medium` to `:high` in `open-claude-design` ([#1259](https://github.com/bastani-inc/atomic/issues/1259)).

## [0.8.26-alpha.3] - 2026-06-05

### Changed

- Changed the builtin `ralph` workflow to include the workflow current working directory in every stage prompt so planner, implementation, simplification, review, and PR handoff stages keep repository work anchored to the workflow checkout.
- Changed the builtin `ralph` workflow to skip pull-request creation by default unless `create_pr=true`, omit `pr_report` when disabled, and keep provider-aware PR/MR/review creation instructions in the final stage ([#1255](https://github.com/bastani-inc/atomic/issues/1255)).

## [0.8.26-alpha.2] - 2026-06-05

### Changed

- Updated the `research-codebase` skill to capture a `breaking_changes_allowed` compatibility posture before research fanout, carry it through sub-agent prompts, and record it in research documents so downstream specs and workflows do not preserve legacy APIs by default when breaking changes are allowed ([#1225](https://github.com/bastani-inc/atomic/issues/1225)).

### Fixed

- Fixed stage-local workflow HIL `input` and `editor` prompts losing draft text across Ctrl+D detach/reattach; drafts are kept live-only in memory and cleared when the prompt or run/stage exits ([#1179](https://github.com/bastani-inc/atomic/issues/1179)).
- Fixed workflow worktree Git commands to strip ambient repository-local Git environment variables before inspecting or creating targeted worktrees.
- Suppressed intermediate model fallback failure warnings from successful workflow stages while preserving final failures and raw per-attempt diagnostics ([#1226](https://github.com/bastani-inc/atomic/issues/1226)).

## [0.8.26-alpha.1] - 2026-06-05

### Fixed

- Fixed the inline-form "snapshot lost" renderer and the `workflow.run.start`/`workflow.run.end` banner renderers returning bare strings, which crashed the host TUI with `child.render is not a function` when resuming a session containing persisted workflow custom messages. These renderers now return proper render components ([#1236](https://github.com/bastani-inc/atomic/issues/1236)).
- Fixed the workflow input form (the `/workflow <name>` argument selector) leaking into model context: spawning the picker and exiting without running the workflow no longer sends the form to the LLM. The input-form card is now emitted with `excludeFromContext` since it is transient UI, not conversation.
- Fixed the workflow input widget re-rendering in chat after `/resume`. Inline-form state is now cleared on `session_start`, and a rehydrated `workflows:input-form` card whose backing state is gone now renders nothing (returns `null`) instead of a stale form or "snapshot lost" placeholder.
- Stage sessions now emit `session_shutdown` before `dispose()` (mirroring the host `AgentSessionRuntime` teardown) so bound extensions receive a graceful shutdown signal instead of being silently invalidated. This stops disposed stage sessions from leaking child MCP servers and from triggering spurious stale-context "MCP initialization failed" errors when an extension's deferred `session_start` work races with stage disposal.

## [0.8.25] - 2026-06-04

### Changed

- Promoted the 0.8.25 prerelease package version to a stable release.

## [0.8.25-alpha.1] - 2026-06-04

### Fixed

- Fixed the interactive workflow inputs selector so it hides the working loader while replacing the editor, keeping the picker pinned to the bottom like `ask_user_question` without wedged host chrome ([#1224](https://github.com/bastani-inc/atomic/issues/1224)).

## [0.8.24] - 2026-06-04

### Changed

- Promoted the 0.8.24 prerelease package version to a stable release.

## [0.8.24-alpha.4] - 2026-06-04

### Changed

- Bumped package version for the Atomic 0.8.24-alpha.4 prerelease.

## [0.8.24-alpha.3] - 2026-06-03

### Changed

- Bumped package version for the Atomic 0.8.24-alpha.3 prerelease.

## [0.8.24-alpha.2] - 2026-06-03

### Added

- The `@bastani/workflows` authoring SDK types are now externally resolvable in installed packages through `@bastani/atomic`'s new `./workflows` exports and ambient bridge, so workflow files type-check `import { defineWorkflow, Type } from "@bastani/workflows"` (and `@bastani/workflows/builtin/*`) under `tsc` (NodeNext) without a hand-authored `.d.ts`, `declare module` shim, or `paths` alias. Workflow packages declare `@bastani/atomic` and `typebox` as peer dependencies; the package continues to distribute raw TypeScript with no build step, and the runtime virtual-module loader is unchanged ([#1208](https://github.com/bastani-inc/atomic/issues/1208)).

### Fixed

- Fixed builtin (and any) workflows falling back to the user's currently selected model instead of the stage's defined model. A fully-qualified `provider/model` id that the live model catalog did not list was treated as a hard "not available" failure; because candidate validation throws on any failure and the catalog resolver catches that throw and collapses the whole ordered candidate list down to the user's `currentModel`, a single absent cross-provider fallback discarded the defined primary plus every fallback. Provider-qualified ids are now trusted (passed through with the reasoning suffix split off the last colon), mirroring the subagent resolver, so the defined primary is used and only genuinely failing candidates fall through at runtime. Regressed when bundled workflow model lists were refreshed onto newer multi-provider ids alongside suffix-first reasoning levels ([#1199](https://github.com/bastani-inc/atomic/issues/1199)).

## [0.8.24-alpha.1] - 2026-06-02

### Breaking Changes

- Removed the imperative `runWorkflow` object-form API from `@bastani/workflows`; workflow authors must export definitions produced by `defineWorkflow(...).compile()`, and forged `__piWorkflow: true` objects are rejected by discovery and composition.

### Added

- Added suffix-first workflow reasoning levels for `model` and `fallbackModels` entries such as `openai/gpt-5:high`, plus `WorkflowModelAttempt.reasoningLevel` metadata and optional `fallbackThinkingLevels` compatibility mapping ([#1199](https://github.com/bastani-inc/atomic/issues/1199)).

### Changed

- Changed bundled workflows to encode their existing reasoning levels directly on model and fallback model strings ([#1199](https://github.com/bastani-inc/atomic/issues/1199)).
- Documented the `model_name:thinking_effort` suffix syntax and `thinkingLevel` migration guidance in the workflows docs and package README ([#1199](https://github.com/bastani-inc/atomic/issues/1199)).
- Adopted the new `-alpha.N` prerelease version convention (revision starting at 1), replacing the legacy numeric `-N` prerelease suffix in the release tooling (bump script, CI publish validation, and changelog parsing).
- Dropped the leading `v` from release git tags and `release/`/`prerelease/` branch names; the Publish CI now triggers on and validates bare version tags such as `0.8.24` or `0.8.24-alpha.1`.

### Deprecated

- Deprecated workflow `thinkingLevel` stage options in favor of per-candidate `:off|minimal|low|medium|high|xhigh` model suffixes; removal is deferred ([#1199](https://github.com/bastani-inc/atomic/issues/1199)).

### Fixed

- Made workflow reasoning-suffix parsing lenient so it no longer rejects legitimate colon-tagged model ids (for example OpenRouter `:free`/`:exacto` variants and Ollama `llama3:latest`); only canonical `:off|minimal|low|medium|high|xhigh` suffixes are stripped as reasoning levels, and unknown ids still surface the generic catalog "not available" error ([#1199](https://github.com/bastani-inc/atomic/issues/1199)).

## [0.8.23] - 2026-06-02

### Changed

- Promoted the 0.8.23 prerelease package version to a stable release.

## [0.8.23-0] - 2026-06-02

### Added

- Added a workflow node chat Ctrl+D hint that shares the bottom footer line with model/cwd metadata and appears in the bottom-right corner of stage-local ctx.ui widgets.

### Changed

- Changed bundled Goal and Ralph workflows to save reviewer feedback as JSON artifacts and hand only latest review artifact paths to downstream agents instead of injecting full review histories or session tails.
- Removed Ralph's separate `infra-locate-*`, `infra-analyze-*`, and `infra-patterns-*` discovery stages; Ralph reviewers now inspect repository infrastructure directly as needed during review.
- Documented artifact-path handoffs, `outputMode: "file-only"`, `reads`, and explicit `Read the file at <path>...` downstream prompts as the preferred pattern for large workflow context.
- Updated the workflow tool description to tell agents to hand off large stage context through files/artifacts instead of injected previous text.

### Fixed

- Fixed paused workflow stage chats so Ctrl+D returns to the orchestrator graph instead of closing back to the main chat.

## [0.8.22] - 2026-06-01

### Breaking Changes

- Migrated workflow contracts to TypeBox schemas and fully explicit outputs, removing legacy descriptor schemas, `.import(...)`, string-alias child workflow calls, parent-side output remapping, implicit `result`/`rawOutput`, and declaration-time `.humanInTheLoop(...)` metadata.

### Added

- Added TypeBox re-exports, TypeScript module-style child workflow composition, schema-validated child outputs, reusable builtin workflow modules, and flattened nested child workflow stages.

### Changed

- Raised the bundled deep-research workflow's default parallelism, renamed workflow runtime errors to `atomic-workflows:`, rendered workflow notices as compact TUI cards, flattened imported workflow graph boundaries, and expanded registered workflow-tool metadata.

### Fixed

- Fixed defaulted input validation, slow workflow discovery through the jiti loader, headless workflow shutdown and print-mode automation, builtin workflow initialization cycles, package-manifest workflow reloads, nested workflow widgets/graph cards, portable deep-research line counting, Codex fast-mode workflow markers, human-in-the-loop focus/answer behavior, background widget rendering, and deterministic headless command output.

## [0.8.22-0] - 2026-06-01

### Breaking Changes

- Migrated workflow input/output declarations to a TypeBox-native schema system, replacing the legacy `{ type, required, default, choices }` descriptor. Authors now declare inputs/outputs with TypeBox schemas (`.input("prompt", Type.String({ description }))`, `.input("count", Type.Number({ default: 2 }))`, `.input("flavor", Type.Union([Type.Literal("a"), Type.Literal("b")]))`, `.output("packet", Type.Object({ topic: Type.String(), score: Type.Number() }))`). `ctx.inputs`, the `.run()` return, and `ctx.workflow(child).outputs` are precisely typed via `Static<>`, and the runtime validates inputs and outputs with TypeBox `Value`. `Type` is re-exported from `@bastani/workflows` (with types `Static` and `TSchema`) so workflow authors single-import. An optional field is declared with `Type.Optional(...)`; a `default` keeps the key required at the type level. This is a clean break with no legacy descriptor support.
- Removed the unshipped `.import(...)` workflow builder API and string-alias child workflow calls. Workflows now compose children by importing compiled workflow definitions with TypeScript imports and passing those definitions directly to `ctx.workflow(workflowDefinition, options)`.
- Removed parent-side child output selection/renaming from `ctx.workflow(...)`. Parent workflows now receive the child's declared `.output(...)` contract as `child.outputs`.
- Made workflow outputs fully explicit so a workflow's input/output contract is the stable, self-documenting surface other workflows compose against. A workflow now exposes exactly the outputs it declares with `.output(...)`, and a `.run()` return that contains a key the workflow did not declare fails the run with `atomic-workflows: ... returned undeclared output "<key>"`. The implicit string `result` output and the `child.rawOutput` escape hatch were removed: declare `.output("result", schema)` and return `{ result }` if you want a `result` output, and declare every other field a parent should read.
- Changed default transcript inspection from inlining about 50 recent entries to a reference-first 5-entry preview with `sessionFile`/`transcriptPath`; pass explicit `tail` or `limit` to override the preview size.
- Removed the obsolete `.humanInTheLoop(...)` workflow builder API and its declaration-time interaction metadata; workflows should use runtime `ctx.ui.*` calls directly when they need human input.

### Added

- Added TypeBox as the workflow schema engine and re-exported `Type` (plus the `Static` and `TSchema` types) from the `@bastani/workflows` public entry point so authors single-import the authoring surface.
- Added TypeScript module-style workflow composition: parent workflows can pass compiled child workflow definitions directly to `ctx.workflow(compiledWorkflow, options)`. The bundled `deep-research-codebase`, `goal`, `ralph`, and `open-claude-design` workflows are reusable from `@bastani/workflows/builtin` or individual builtin module paths.
- Added first-class workflow composition: child workflows can declare `.output()` contracts, and `ctx.workflow()` runs compiled child workflow definitions as nested runs with input validation, schema-validated declared outputs, and the nested workflow's stages flattened inline into the parent graph ([#1071](https://github.com/bastani-inc/atomic/issues/1071)).

### Removed

- Removed the `zod` dependency from `@bastani/workflows`; JSON-serializable validation and input/output validation now run on TypeBox `Value`.

### Changed

- Raised the bundled `deep-research-codebase` default `max_concurrency` from 4 to 100 so partitioned research stages fan out in parallel by default; lower it via the `max_concurrency` input on rate-limited or cost-sensitive setups (with `max_partitions` up to 100 and one locator/pattern-finder/analyzer/online-researcher specialist per partition, a single run can otherwise spawn many concurrent stage sessions).
- Declared explicit output contracts for the bundled `deep-research-codebase`, `goal`, `ralph`, and `open-claude-design` workflows so parent workflows receive schema-validated child outputs.
- Renamed workflow runtime error prefixes from `pi-workflows:` to `atomic-workflows:`.
- Render workflow stage notices, lifecycle notices, and HiL answer notices as compact emoji-free TUI cards instead of plain wrapped rows, matching the debugger warning card treatment.
- Flatten imported workflows in the expanded run graph so a `ctx.workflow()` import reads as a single flat layout: the child run's stages stand in for the import instead of rendering an extra boundary "information" node above them. The boundary's incoming dependencies become the child roots' dependencies and downstream stages rewire to the child's terminal stages, so a depth-1 composition of single-stage leaves now shows one node per import instead of two. A boundary whose child run produced no stages of its own is still kept as a single node so the import stays visible. Affects the graph overlay, session list, `status` stage counts/details, and attach resolution alike.
- Updated the registered `workflow` tool description so agent-facing metadata covers named and direct runs, discovery, inspection, prompt answering/steering, run control, and reload ([#1151](https://github.com/bastani-inc/atomic/issues/1151)).

### Fixed

- Fixed the programmatic named-workflow runner (`runWorkflow`) to resolve declared input defaults before validating, so an input declared with both `required: true` and a `default` is no longer rejected as missing when omitted, matching the resolve-then-validate order used by the other dispatch paths.
- Fixed slow workflow discovery outside the compiled binary by always resolving the `@bastani/workflows` SDK (and its builtin submodules) to in-memory virtual modules in the jiti loader instead of aliasing to the on-disk package. The alias path re-evaluated the entire SDK module graph once per workflow file (the loader keeps `moduleCache: false` so edits stay observable), so projects with many workflow files saw multi-second discovery and timing-sensitive workflow tests flaked at the default test timeout; workflow files are still evaluated fresh from disk, so `/workflow reload` keeps observing edits.
- Fixed headless workflow shutdown so completed stage chat handles are disposed on CLI quit, allowing successful non-interactive `/workflow` runs to return to the shell prompt ([#1167](https://github.com/bastani-inc/atomic/issues/1167)).
- Fixed bundled workflow modules so they import the leaf `defineWorkflow` authoring API instead of the public package entrypoint, avoiding an ESM initialization cycle during builtin workflow discovery.
- Fixed workflow HIL prompts so awaiting-input and answered-prompt notices no longer wake the main chat agent, answer notices stay out of LLM context and explicitly forbid auto-answering later HIL prompts, and stale Enter input from graph/connect focus transitions is quarantined when prompts appear after the attach pane is already open, covering input, confirm, select, and editor prompts ([#1163](https://github.com/bastani-inc/atomic/issues/1163)).
- Fixed workflow run widgets so store changes and elapsed-time ticks repaint through a long-lived reactive widget instead of waiting for unrelated chat input or remounting the widget ([#1150](https://github.com/bastani-inc/atomic/issues/1150)).
- Fixed `/workflow reload` and `workflow({ action: "reload" })` so newly added package-manifest workflow entries are rediscovered in-process without requiring top-level `/reload` or restart ([#1155](https://github.com/bastani-inc/atomic/issues/1155)).
- Fixed completed child workflow boundary stages rendering as empty graph nodes by showing the child workflow name, child run id prefix, and output count in the node card.
- Fixed the background workflow widget (`BACKGROUND` panel) listing nested `ctx.workflow()` child runs as separate top-level entries, so a two-level composition no longer shows the root, parent, and child runs as three separate items with an inflated `N runs` count. The widget now applies the same top-level visibility rule (`run.parentRunId === undefined`) already used by `statusRuns`, the `status` action, and the `/workflow connect` session picker. The "needs attention" (awaiting HiL input) badge still fires for a hidden nested descendant by attributing its awaiting state to the visible top-level ancestor via `rootRunId`, so a HiL prompt waiting inside an imported child workflow stays discoverable.
- Fixed the bundled deep-research workflow line-count heuristic hanging Windows CI by replacing its POSIX `wc` subprocess with portable in-process line counting.
- Kept workflow stage model metadata as the raw model id while surfacing Codex fast mode as a separate visible `fast` marker on workflow node cards, including stages that use the default Atomic SDK adapter settings manager.
- Show workflow Codex fast-mode metadata on running workflow nodes as soon as the stage session starts, including explicit-model stages, catalog-resolved bare model aliases, and custom resource-loader stages whose settings manager is created by the Atomic SDK.
- Kept workflow Codex fast-mode markers synchronized across fallback attempts: running nodes now update when fallback switches to a fast-eligible model, completed nodes clear stale `fast` markers when fallback finishes on a non-eligible model, and prompt-adapter stages no longer create SDK sessions only to compute fast metadata.
- Made successful headless `/workflow` informational commands emit displayable command output instead of dropping success messages through the no-op non-interactive UI reporter, made degraded terminal-detail fallback rendering avoid fabricating successful status for unknown run states, and preserved non-interactive execution policy when resuming failed workflow runs ([#1123](https://github.com/bastani-inc/atomic/issues/1123)).
- Suppressed workflow lifecycle steer notices while awaited non-interactive workflow dispatch is already waiting for terminal completion, and made workflow chat-surface custom-message content printable by default for headless list/status/detail/dispatch/killed output ([#1123](https://github.com/bastani-inc/atomic/issues/1123)).
- Re-enabled deterministic non-interactive workflow execution: headless sessions keep the `workflow` tool, `/workflow <name> key=value` skips interactive pickers, named workflow dispatch waits for the terminal run snapshot, declared human-in-the-loop workflows are rejected, top-level `ctx.ui.*` is unavailable, and non-interactive stage sessions exclude `ask_user_question` without binding broker-backed extension UI ([#1123](https://github.com/bastani-inc/atomic/issues/1123)).
- Added a concise display-only `User responded with: ...` workflow HiL answer notice so the main chat transcript records the answer for user-visible audit without triggering an autonomous model turn or adding the notice to LLM context ([#1137](https://github.com/bastani-inc/atomic/issues/1137)).
- Suppressed workflow HiL answer interrupt notices for prompts answered by the main-chat `workflow` tool, so tool-driven answers do not dismiss the current main-chat turn with workflow-chat wording ([#1137](https://github.com/bastani-inc/atomic/issues/1137)).
- Hardened workflow awaiting-input lifecycle notices and readiness-gate answers: awaiting-input lifecycle states now emit main-chat steer notices for dedupe-aware model visibility while preserving the existing `/workflow connect` and `workflow send` response hints, readiness gates use unique prompt ids per gate instance, and duplicate/raced `workflow send` answers for a just-resolved brokered input request now report the request as already answered instead of falling through to `No matching pending prompt` ([#1137](https://github.com/bastani-inc/atomic/issues/1137)).
- Prevented Enter used for `/workflow connect`, graph attach, direct stage attach, unrelated graph-node inspection, or transition key-repeat from immediately submitting workflow HIL prompts; prompt submission now requires the user to be past the attach transition and press Enter while the specific prompted node is attached, leaving sibling HIL prompts pending ([#1148](https://github.com/bastani-inc/atomic/issues/1148)).
- Fixed completed human-in-the-loop prompt archives so reattached read-only prompt nodes keep their prompt card scrollable with keyboard and mouse-wheel input ([#1140](https://github.com/bastani-inc/atomic/issues/1140)).
- Kept the workflow graph overlay navigable while a stage-local human-input prompt is awaiting a response: graph navigation, the stage switcher, Ctrl+D detach, and mouse-wheel scrolling now stay owned by graph mode until the user explicitly attaches to the prompted stage ([#1141](https://github.com/bastani-inc/atomic/issues/1141)).
- Preserved literal slash text entry in legacy run-level workflow prompt cards, so paths and URLs such as `/tmp/file` remain typable while the prompt owns input ([#1141](https://github.com/bastani-inc/atomic/issues/1141)).
- Cleared brokered stage HIL UI during terminal stage cleanup so a completed workflow does not leave an active `ask_user_question`/custom prompt card visible after detach ([#1141](https://github.com/bastani-inc/atomic/issues/1141)).
- Fixed workflow HIL select/editor prompts so navigation, scroll input, and ambiguous Escape-prefix input cannot advance prompts before an explicit configured confirm/Enter submit or Ctrl+C skip. Graph-mode prompt cards now honor custom select keybindings, and Enter submitted during connect/attach/detach transitions is time-boxed so key repeat cannot attach or answer the next prompt accidentally ([#1148](https://github.com/bastani-inc/atomic/issues/1148)).
- Preserved synthetic workflow HiL prompt nodes as `awaiting_input` when an unrelated main-chat `ask_user_question` result arrives, so choosing to leave a workflow prompt open no longer makes the orchestrator node look like it resumed while the prompt is still unanswered ([#1137](https://github.com/bastani-inc/atomic/issues/1137)).
- Fixed headless `/workflow <name>` print-mode automation so successful non-interactive runs wait for terminal snapshots and emit printable run-detail summaries, while terminal failures surface as command-visible errors instead of silent zero-output successes ([#1156](https://github.com/bastani-inc/atomic/issues/1156)).

## [0.8.21] - 2026-05-30

### Changed

- Promoted the 0.8.21 prerelease changes to a stable release.

## [0.8.21-0] - 2026-05-30

### Added

- Enabled the `/workflow send` action (with `delivery: "answer"`) to answer a stage's brokered structured prompts — an in-stage `ask_user_question` call or the deterministic readiness gate — without the interactive TUI/graph overlay. These prompts resolve through the `StageUiBroker` (`ctx.ui.custom`) rather than the simple `store.pendingPrompt` model, so `send` previously no-op'd ("No pending prompt to answer") and they could only be answered by attaching the graph viewer. The stage UI broker now carries an optional headless-answer adapter (`provideStagePrompt` / `peekStagePrompt` / `answerStagePrompt` / `clearStagePrompt`), keyed by `(runId, stageId)`, that maps a simple answer — a free-text reply, an option label, a 1-based option index, comma-separated labels for multi-select, or a pre-built `response` — into the `QuestionnaireResult` the tool expects. The executor's existing `ask_user_question` watcher captures the tool-call `args` to build the adapter, and the readiness gate registers one statically; both surface a serializable `inputRequest` descriptor on the stage snapshot (shown in `/workflow stage` / `stages` output) so an orchestrating agent can see the questions/options and answer them programmatically.
- Added a deterministic readiness gate after `ask_user_question` tool calls inside workflow stages. When a stage's model turn issues an `ask_user_question` call, the workflow re-uses the structured `ask_user_question` UI — rendered inline in the attached stage chat via the stage UI broker — to ask "Are you ready to move on to the next stage?" (Yes/No) before completing/advancing the stage. Answering **No** (or "Chat about this"/cancel) steers the stage with a continuation message so the conversation keeps going, then re-shows the gate after the next turn, repeating until **Yes**; **Yes** resumes normal sequential and dependent-parallel progression. Detection is independent of how the underlying UI is implemented, and the executor exposes a `confirmStageReadiness` seam so the gate is fully testable. `@bastani/atomic` now also exports `createAskUserQuestionToolDefinition` so first-party extensions can invoke the structured prompt deterministically ([#1099](https://github.com/bastani-inc/atomic/issues/1099)).

### Fixed

- Fixed background workflow HIL prompt nodes becoming input-dead when they appeared while the orchestrator graph overlay was already open: the visible overlay now reclaims focus on awaiting-input store updates, and the graph auto-focuses newly awaiting prompt nodes so Enter attaches directly to the HIL response UI.
- Fixed the `/workflow status <id>` run-detail card still ticking (and flickering the whole screen) even after the chat-surface clock was frozen: a running stage's in-flight tool-activity label (e.g. `bash · 6s`) was computed inside `stageActivityString()` from a fresh `Date.now()`, bypassing the capture-once `now` that `renderRunDetail` threads everywhere else. While a background workflow ran, the below-editor companion widget drove a full re-render roughly once per second (and on every store mutation); each re-render advanced that label, and once the detail card had scrolled above the viewport fold pi-tui took the full-screen-clear path (CSI 2J + CSI H + CSI 3J), read as whole-page + chat-box flicker. `stageActivityString()` now uses the threaded `now`, so scrollback run-detail cards are byte-stable across re-renders (the companion widget still owns the live, ticking view).
- Fixed the `/workflow status` and `/workflow status <id>` chat-surface cards triggering a full-screen redraw (clear + scrollback wipe) every render tick once they scroll above the viewport fold. Their custom-message renderer's `render()` lambda re-runs on every TUI frame (pi-tui fans out to every child each `doRender`, and the live workflow/subagent widgets request a frame ~12×/sec while runs are active), and it called `renderStatusList` / `renderRunDetail` without a captured clock, so they fell through to `Date.now()` each frame and ticked the `elapsed` / `running` labels — and pi-tui full-clears the screen (CSI 2J + CSI H + CSI 3J) whenever a changed line sits above the fold, read as whole-screen flicker on terminals without synchronized output (e.g. mosh). The renderer now captures wall-clock once when the chat entry's component is created and threads it through to the status/detail renderers, so these point-in-time scrollback snapshots stay byte-stable across re-renders (the live widget still owns live state). Mirrors the earlier tool-result status-card fix.
- Fixed answering a stage's brokered structured prompt (an in-stage `ask_user_question` or the readiness gate) via `/workflow send` replying **"User declined to answer questions"** and leaving the stage stuck `running` with no pending input — even though a real answer was sent. A structured `response` was forwarded verbatim to the `ask_user_question` tool: a JSON-encoded string was captured as raw free text, and — most damagingly — any object with an `answers` array (e.g. the orchestrator-friendly `{ answers: [{ question, answer }] }`) was treated as a pre-built `QuestionnaireResult` despite lacking the numeric `questionIndex` the tool envelope requires, so it matched no question segment and declined. `coerceStageInputAnswer` now forwards `raw` ONLY for a fully-formed result (every answer carries a numeric `questionIndex`); every other shape — JSON strings, `answers[]`/`questions[]` entries, flat `{ answer | label | selected }`, string arrays — is normalized to a label/index/multi-select value that the stage prompt adapter resolves against the question's options (assigning the correct `questionIndex`). The readiness decision (`readinessResultMeansAdvance`) matches the advance option case/whitespace-insensitively and via `selected[]`. A new regression test drives the real `StageUiBroker` + `ask_user_question` tool resolution path (the seam the earlier unit tests missed) and reproduces the decline for the `answers[]`-without-`questionIndex` payload. The "keep exploring"/stay path is unchanged ([#1099](https://github.com/bastani-inc/atomic/issues/1099)).
- Hardened the `/workflow` tool-result renderer against missing or unshaped payloads. `renderResult` is passed `result.details`, which can be absent during streaming/partial renders or on error paths, and previously dereferenced a missing `action` and crashed the TUI render loop. It now degrades gracefully (renders nothing for partials, a generic notice otherwise) ([#1099](https://github.com/bastani-inc/atomic/issues/1099)).
- Made `terminate: true` tool results deterministic when deriving a stage/task's result text: when an agent turn ends on a terminating tool, the stage runner now returns that tool result's output instead of any prose the model emitted before the tool call. This fixes the `goal` and `ralph` review gates, whose terminating `review_decision` structured-output tool emits clean JSON — previously the preceding assistant narration was captured instead, so the strict `JSON.parse` failed and a valid verdict was misclassified as a reviewer failure ("returned invalid structured JSON"), blocking quorum and forcing extra turns ([#1099](https://github.com/bastani-inc/atomic/issues/1099)).
- Tightened terminating-tool result detection when deriving a stage/task's result text. The stage runner now treats a trailing tool result as the deterministic turn output ONLY when that tool call actually returned `terminate: true` — tracked at runtime from the session's `tool_execution_end` events, since the tool-result message itself does not carry the flag — instead of whenever the last conversational message merely happened to be a tool result. A turn that ends on a non-terminating tool result (e.g. aborted or interrupted right after a tool call) now correctly falls back to the last assistant message, and that fallback no longer surfaces non-terminating tool output. Verified end-to-end against real `terminate: true`, `terminate: false`, and no-tool stages ([#1099](https://github.com/bastani-inc/atomic/issues/1099)).
- Fixed a mid-turn `ask_user_question` (or readiness gate) rendering but being input-dead in the attached stage chat. After a readiness-gate "stay" returns to the composer and the user submits another message, the agent's next question mounts while host keyboard focus has drifted off the overlay; the focus re-assertion was suppressed during streaming (a blunt guard added to avoid a prior continuation stall), so arrows/Enter were ignored and nothing could be answered or sent to the model. The overlay's `requestFocus` is now idempotent — it grabs focus only when the overlay does not already own it (`isFocused()`), so the redundant `focus()` that stalled the stream never runs. The stage chat now requests focus whenever a custom UI is shown (including mid-turn) and the focus-hold timer keeps a mounted question focused, trusting `requestFocus` to no-op when unnecessary ([#1120](https://github.com/bastani-inc/atomic/issues/1120)).
- Detaching or closing the attached stage chat (Ctrl+D / Ctrl+C) while a stage has a pending human-input request — an agent `ask_user_question` call or the readiness gate — no longer cancels that request. Previously, tearing down the chat view (or its stage UI broker host) rejected the pending prompt, so the stage silently dropped out of `awaiting_input` and the question disappeared. Detaching, closing, and disposing now only stop *displaying* the request: it stays pending (the stage remains `awaiting_input`) and is re-displayed when a host re-attaches. A pending request is settled only by the user answering (broker resolve) or the run aborting via its `AbortSignal` — the single chokepoints for ending a human-input request ([#1099](https://github.com/bastani-inc/atomic/issues/1099)).

## [0.8.20] - 2026-05-29

### Changed

- Promoted the 0.8.20 prerelease changes to a stable release.

## [0.8.20-0] - 2026-05-29

### Added

- Added main-chat lifecycle steer notices for workflow completion, failure, and awaiting-input pauses with global notification config controls ([#1085](https://github.com/bastani-inc/atomic/issues/1085)).

### Fixed

- Fixed the background-workflow companion counter widget flickering every second while a run is active by updating a single long-lived above-editor widget in place instead of disposing and re-mounting a fresh widget factory on each elapsed-clock tick ([#1109](https://github.com/bastani-inc/atomic/issues/1109)).
- Fixed workflow lifecycle completion/failure/awaiting-input notices crashing the TUI on narrow or freshly-resized terminals: the notice component now wraps to the render width (hard-breaking long run ids) instead of emitting a single fixed line, which pi-tui rejects with a hard "Rendered line exceeds terminal width" throw ([#1109](https://github.com/bastani-inc/atomic/issues/1109)).
- Fixed the workflow companion counter widget triggering a full-screen redraw (clear + scrollback wipe) on every elapsed-clock tick after the terminal is resized while a run is active. The widget now mounts `belowEditor` instead of `aboveEditor`, keeping its live clock line within the bottom viewport; pi-tui full-clears the screen whenever a changed line sits above the viewport fold, and an above-editor widget was pushed above the fold once the editor/status region grew tall ([#1109](https://github.com/bastani-inc/atomic/issues/1109)).
- Disabled workflows in non-interactive (`-p` / `--print` / `--mode json`) sessions, which bind a no-op UI surface and cannot drive workflow prompts, pickers, or the graph overlay: the `workflow` tool is removed from the model's active tool set at session start, and the `/workflow` command (reachable via `atomic -p "/workflow …"`) is refused — preventing headless runs from stalling on work that can never complete ([#1096](https://github.com/bastani-inc/atomic/issues/1096)).
- Escaped workflow lifecycle notice text and structured response hints, isolated lifecycle send failures from store subscribers, and rejected empty lifecycle notification event lists ([#1085](https://github.com/bastani-inc/atomic/issues/1085)).
- Fixed stage awaiting-input lifecycle notice dedupe so promptless pauses after resolved prompts are not suppressed by historical prompt metadata ([#1085](https://github.com/bastani-inc/atomic/issues/1085)).
- Reset workflow lifecycle-notification dedupe state at chat session boundaries so reused workflow run IDs in later sessions still emit completion/failure/input notices ([#1085](https://github.com/bastani-inc/atomic/issues/1085)).
- Warn before starting or resuming another session when workflows are still in flight, allowing users to cancel before those runs are killed and current-session workflow history is cleared ([#1082](https://github.com/bastani-inc/atomic/issues/1082)).
- Prevented workflow stage sessions from exposing or executing the `workflow` tool while preserving stage-level subagent delegation.
- Retained completed, failed, and killed workflow runs in user-facing status/connect surfaces and changed workflow kill controls to mark runs killed without removing them from live inspection history ([#1083](https://github.com/bastani-inc/atomic/issues/1083)).

## [0.8.18] - 2026-05-27

### Changed

- Promoted the 0.8.18 prerelease changes to a stable release.

## [0.8.18-0] - 2026-05-27

### Added

- Added Ralph `git_worktree_dir` support for running stages from an optional Git worktree, reusing/sharing existing worktrees from the invoking repository as-is and leaving worktrees in place for retries.

### Changed

- Replaced regex-based workflow discovery stage validation with runtime empty-graph validation based on actual stage creation while keeping discovery side-effect-free.
- Threaded named workflow invocation cwd into workflow run contexts so workflow-owned artifacts can use the explicit runner cwd.
- Split worker project-initialization preflight guidance from Goal receipt/reporting instructions.

### Fixed

- Defaulted workflow `ctx.cwd` to the reusable worktree cwd when `worktreeFromInputs` resolves a `gitWorktreeDir`, so workflow-owned artifacts such as Ralph specs are written inside the worktree unless explicitly overridden.
- Avoided blank deep-research display paths when a displayed artifact path equals the workflow invocation directory.
- Distinguished Ralph same-repository worktree classification and canonicalization failures from definitely non-Git existing `git_worktree_dir` paths.
- Updated Ralph to revise a stable original spec file across planner iterations and clarified `git_worktree_dir` null-byte diagnostics.

## [0.8.17] - 2026-05-26

### Changed

- Promoted the 0.8.17 prerelease changes to a stable release.

## [0.8.17-0] - 2026-05-26

### Breaking Changes

- Removed Ralph's configurable `review_quorum` and `blocker_threshold` inputs; `max_turns` remains configurable while reviewer quorum and blocker threshold use fixed controller defaults ([#1061](https://github.com/bastani-inc/atomic/issues/1061)).

### Changed

- Aligned Ralph's goal-continuation prompt more closely with Codex `/goal` hidden continuation guidance, including current-state evidence, non-shrinking scope, fidelity, completion audit, and strict blocked audit language ([#1061](https://github.com/bastani-inc/atomic/issues/1061)).
- Restored Ralph's stronger historical review gate prompt and `review_decision` schema with findings, oracle satisfaction, receipt assessment, verification remaining, and reviewer-error guard fields.

## [0.8.16] - 2026-05-26

### Changed

- Promoted the 0.8.16 prerelease changes to a stable release.

## [0.8.16-0] - 2026-05-26

### Breaking Changes

- Removed Ralph's `prompt` and `max_loops` compatibility inputs; use the canonical `objective` and `max_turns` inputs instead ([#1061](https://github.com/bastani-inc/atomic/issues/1061)).

### Changed

- Reworked Ralph into a Goal Runner workflow with a persisted goal ledger, bounded worker turns, parallel structured reviewers, reviewer-quorum completion, repeated-blocker gating, and final status reporting while excluding token-budget behavior ([#1061](https://github.com/bastani-inc/atomic/issues/1061)).

### Fixed

- Hardened Ralph's goal-runner edge cases around base-branch sanitization coverage, worker/reviewer failure handling, cross-turn review context, bounded blocker-threshold handling, and unused ledger state ([#1061](https://github.com/bastani-inc/atomic/issues/1061)).

## [0.8.15] - 2026-05-26

### Breaking Changes

- Changed workflow human-in-the-loop prompts (`ctx.ui.input`, `ctx.ui.confirm`, `ctx.ui.select`, and `ctx.ui.editor`) to render as synthetic graph stages with `awaiting_input` status; consumers should handle the new `StageSnapshot.promptAnswerState` metadata and avoid caching `StageSnapshot.parentIds` references across store updates ([#1046](https://github.com/bastani-inc/atomic/issues/1046)).
- Changed `ctx.ui.select(..., [])` to throw `pi-workflows: ctx.ui.select requires at least one option` before creating a prompt node instead of returning an empty string ([#1046](https://github.com/bastani-inc/atomic/issues/1046)).

### Added

- Added workflow tool stage introspection and control actions (`stages`, `stage`, `transcript`, `send`, `pause`, and `reload`) for inspecting stage state, reading transcripts, answering prompts, controlling live stages, pausing runs, and reloading workflow resources ([#1023](https://github.com/bastani-inc/atomic/issues/1023)).
- Added live-memory prompt answer replay for workflow continuations using snapshot-safe `promptAnswerState` markers and a private `PromptAnswerRecord` ledger that is excluded from snapshots and persistence ([#1046](https://github.com/bastani-inc/atomic/issues/1046)).

### Changed

- Updated Ralph around an autonomous goal contract so planner, implementation, and reviewer/auditor stages infer verifiable criteria, require receipts, and judge completion against the verification oracle instead of document completeness alone ([#1053](https://github.com/bastani-inc/atomic/issues/1053)).
- Updated Ralph's orchestrator prompt to discover project initialization needs from repository evidence before implementation work proceeds ([#1048](https://github.com/bastani-inc/atomic/issues/1048)).
- Added a final Ralph PR-preparation phase that reviews changes against the configured base branch, tries available GitHub credentials using local git identity as a hint, posts implementation notes as a PR comment, and creates a pull request when possible.
- Updated Ralph to persist planner goal contracts and implementation notes as OS-temp workflow artifacts, and pass file paths rather than full plan text to later stages ([#1037](https://github.com/bastani-inc/atomic/issues/1037)).
- Updated `deep-research-codebase` output layout to write public reports under `research/` and hidden per-run handoff artifacts under `research/.deep-research-<run-id>/`.

### Fixed

- Returned the workflow overlay to the graph orchestrator after answering or skipping a `ctx.ui` prompt node, and preserved the prompt's question footprint for read-only prompt-node views.
- Removed biasing stage-output and iteration-count context from Ralph reviewer prompts while making the comparison base branch explicit ([#1037](https://github.com/bastani-inc/atomic/issues/1037)).
- Ordered snapshot transcript fallback entries chronologically before applying `tail`/`limit`, preserving terminal result/error entries after tools for missing or tied timestamps ([#1023](https://github.com/bastani-inc/atomic/issues/1023)).
- Reloaded workflow resources directly for `workflow({ action: "reload" })` instead of queuing a literal `/workflow reload` follow-up ([#1023](https://github.com/bastani-inc/atomic/issues/1023)).
- Kept pending prompts unresolved when `workflow({ action: "send" })` omits `text`, `response`, and `message`, while preserving explicit empty-string answers ([#1023](https://github.com/bastani-inc/atomic/issues/1023)).
- Included `deep-research-codebase` discovery-stage handoff files in the persisted run manifest.
- Persisted `deep-research-codebase` final reports as dated Markdown research docs while retaining file-only handoffs for bounded aggregation.
- Prevented `deep-research-codebase` aggregation from inlining large specialist transcripts by using file-only handoff artifacts ([#1016](https://github.com/bastani-inc/atomic/issues/1016)).
- Removed model metadata from workflow node cards while retaining fallback dependency metadata ([#1011](https://github.com/bastani-inc/atomic/issues/1011)).
- Preserve the selected workflow switcher row highlight through truncation ellipses on long stage names.

## [0.0.1] — 2026-05-15

### Added

- Initial release of `@bastani/workflows`, a raw TypeScript pi package for multi-stage workflow authoring and execution.
- pi extension entry point at `src/extension/index.ts` registered through the package `pi` manifest.
- Public authoring API with `defineWorkflow`, `createRegistry`, workflow identity helpers, and programmatic workflow runners.
- `workflow` LLM tool and `/workflow` slash command surface for listing, inspecting, running, interrupting, and resuming workflows.
- Background workflow execution with persisted run/stage state, status rendering, cancellation, pause/resume support, and HIL prompt routing.
- TUI surfaces for live workflow progress, graph overlays, run details, stage chat, input collection, and status widgets.
- Workflow discovery from bundled workflows, project-local `.atomic/workflows/`, user-global `~/.atomic/agent/workflows/`, and configured workflow directories.
- Built-in workflows: `deep-research-codebase`, `open-claude-design`, and `ralph`.
- Optional runtime integrations with companion pi packages including `pi-subagents`, `pi-mcp-adapter`, `pi-intercom`, and `pi-web-access`.
- Bundled skills, agents, themes, examples, and documentation for authoring and operating workflows.
