@bastani/atomic 0.9.6 → 0.9.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +33 -0
- package/dist/builtin/cursor/CHANGELOG.md +12 -0
- package/dist/builtin/cursor/package.json +2 -2
- package/dist/builtin/intercom/CHANGELOG.md +20 -0
- package/dist/builtin/intercom/README.md +1 -1
- package/dist/builtin/intercom/contact-supervisor-tool.ts +19 -32
- package/dist/builtin/intercom/index-heavy.ts +8 -51
- package/dist/builtin/intercom/index.ts +13 -1
- package/dist/builtin/intercom/intercom-tool.ts +24 -23
- package/dist/builtin/intercom/package.json +1 -1
- package/dist/builtin/intercom/reply-waiter.ts +115 -0
- package/dist/builtin/intercom/skills/intercom/SKILL.md +9 -2
- package/dist/builtin/intercom/subagent-relay.ts +11 -1
- package/dist/builtin/mcp/CHANGELOG.md +12 -0
- package/dist/builtin/mcp/package.json +1 -1
- package/dist/builtin/subagents/CHANGELOG.md +12 -0
- package/dist/builtin/subagents/package.json +1 -1
- package/dist/builtin/subagents/skills/subagent/SKILL.md +3 -1
- package/dist/builtin/subagents/src/runs/shared/model-fallback.ts +3 -2
- package/dist/builtin/web-access/CHANGELOG.md +12 -0
- package/dist/builtin/web-access/package.json +1 -1
- package/dist/builtin/workflows/CHANGELOG.md +40 -0
- package/dist/builtin/workflows/README.md +5 -5
- package/dist/builtin/workflows/builtin/goal-artifacts.ts +17 -4
- package/dist/builtin/workflows/builtin/goal-prompts.ts +32 -22
- package/dist/builtin/workflows/builtin/goal-reducer.ts +29 -5
- package/dist/builtin/workflows/builtin/goal-review.ts +6 -11
- package/dist/builtin/workflows/builtin/goal-runner.ts +10 -11
- package/dist/builtin/workflows/builtin/open-claude-design-runner.ts +2 -2
- package/dist/builtin/workflows/builtin/ralph-core.ts +5 -54
- package/dist/builtin/workflows/builtin/ralph-forked-prompts.ts +103 -0
- package/dist/builtin/workflows/builtin/ralph-models.ts +10 -10
- package/dist/builtin/workflows/builtin/ralph-review-gate.ts +27 -24
- package/dist/builtin/workflows/builtin/ralph-reviewer-prompt.ts +16 -9
- package/dist/builtin/workflows/builtin/ralph-runner.ts +47 -21
- package/dist/builtin/workflows/builtin/review-convergence.ts +118 -0
- package/dist/builtin/workflows/builtin/shared-prompts.ts +40 -0
- package/dist/builtin/workflows/package.json +1 -1
- package/dist/builtin/workflows/src/extension/workflow-prompts.ts +1 -0
- package/dist/builtin/workflows/src/runs/shared/model-fallback-failures.ts +4 -5
- package/dist/core/agent-session-retry.d.ts.map +1 -1
- package/dist/core/agent-session-retry.js +2 -2
- package/dist/core/agent-session-retry.js.map +1 -1
- package/docs/settings.md +1 -1
- package/docs/subagents.md +5 -1
- package/docs/workflows.md +111 -5
- package/npm-shrinkwrap.json +23 -23
- package/package.json +2 -2
package/docs/workflows.md
CHANGED
|
@@ -37,6 +37,7 @@ Loop or stop-condition phrasing is an especially strong workflow signal: `do X u
|
|
|
37
37
|
- [Built-in Workflows](#built-in-workflows)
|
|
38
38
|
- [When to Use Workflows](#when-to-use-workflows)
|
|
39
39
|
- [Workflow Starter Patterns](#workflow-starter-patterns)
|
|
40
|
+
- [Choosing an Execution Shape](#choosing-an-execution-shape)
|
|
40
41
|
- [Atomic vs Claude Code Dynamic Workflows](#atomic-vs-claude-code-dynamic-workflows)
|
|
41
42
|
- [Workflow Locations](#workflow-locations)
|
|
42
43
|
- [Workflow Configuration](#workflow-configuration)
|
|
@@ -226,7 +227,7 @@ Inputs:
|
|
|
226
227
|
| `git_worktree_dir` | string | no | `""` | Optional reusable Git worktree root. Empty runs in the invoking checkout; non-empty values run Goal stages in the created/reused worktree. |
|
|
227
228
|
| `create_pr` | boolean | no | `false` | Safe-by-default PR creation flag. Omitted or `false` skips the final `pull-request` stage and omits `pr_report`; prompt text alone does not opt in, and only strict `true` authorizes the final `pull-request` stage to attempt provider-appropriate PR/MR/review creation after Goal reaches `complete`. |
|
|
228
229
|
|
|
229
|
-
`goal` defaults to 10 worker/review turns. Reviewer quorum is fixed internally at 2 reviewer `complete` votes. The repeated-blocker threshold defaults to 3 consecutive same-blocker turns and is clamped to `max_turns` when you run fewer than 3 turns.
|
|
230
|
+
`goal` defaults to 10 worker/review turns. Reviewer quorum is fixed internally at 2 reviewer `complete` votes, but approval is evidence closure rather than reviewer agreement alone: quorum can only complete the run when no objective-relevant blocking finding from any reviewer in the current round remains unresolved. The repeated-blocker threshold defaults to 3 consecutive same-blocker turns and is clamped to `max_turns` when you run fewer than 3 turns.
|
|
230
231
|
|
|
231
232
|
Run examples:
|
|
232
233
|
|
|
@@ -244,9 +245,9 @@ Set `git_worktree_dir` when you want Goal's worker and reviewer stages isolated
|
|
|
244
245
|
|
|
245
246
|
Write the `objective` like a compact acceptance spec. Say what should exist when the run is done, how you want testing handled, which command(s) or manual checks matter, and what outcome proves completion. The workflow is intentionally lean: it does not first generate an RFC or migration plan, so the developer-supplied objective is where scope, validation, and completion criteria belong.
|
|
246
247
|
|
|
247
|
-
Goal worker/reviewer prompts treat the objective and acceptance criteria as the sole literal source of truth: if follow-up deltas, language specs, upstream issues, in-repo comments, or best practices conflict with explicit wording, reviewers surface the conflict instead of silently implementing external knowledge. Reviewer findings carry `objective_alignment` (`required_by_objective`, `consistent_with_objective`, `beyond_objective`, or `contradicts_objective`); `beyond_objective` and `contradicts_objective` findings are reported but do not block completion and must not be promoted into follow-up objectives without reconciling them against the acceptance criteria. Review decisions also include `requirements_traceability`, a clause-by-clause evidence map over every explicit objective/acceptance-criteria requirement. Goal approval requires that map to be non-empty and fully `proven` except for a missing PR/MR/review row when `create_pr=true` and that final handoff is the only remaining action; passing worker-authored tests or snapshots alone is circular evidence unless tied to independent current-state proof.
|
|
248
|
+
Goal worker/reviewer prompts treat the objective and acceptance criteria as the sole literal source of truth: if follow-up deltas, language specs, upstream issues, in-repo comments, or best practices conflict with explicit wording, reviewers surface the conflict instead of silently implementing external knowledge. Reviewer findings carry `objective_alignment` (`required_by_objective`, `consistent_with_objective`, `beyond_objective`, or `contradicts_objective`); `beyond_objective` and `contradicts_objective` findings are reported but do not block completion and must not be promoted into follow-up objectives without reconciling them against the acceptance criteria. Severity labels alone never dismiss objective-relevant findings: `required_by_objective` findings block at any priority (P3 included), while `consistent_with_objective` P3 nice-to-haves stay non-blocking. Review decisions also include `requirements_traceability`, a clause-by-clause evidence map over every explicit objective/acceptance-criteria requirement. Goal approval requires that map to be non-empty and fully `proven` except for a missing PR/MR/review row when `create_pr=true` and that final handoff is the only remaining action; passing worker-authored tests or snapshots alone is circular evidence unless tied to independent current-state proof.
|
|
248
249
|
|
|
249
|
-
The worker may claim readiness, but it cannot finalize completion. Workers and reviewers are prompted to verify user-visible behavior end-to-end when practical, using `playwright-cli`-skilled subagents for web/frontend flows that may depend on backend/API behavior and tmux-skilled subagents for TUI or terminal-app scenarios. They must assume credentials/auth/environment access exists until concrete checks plus an actual app/flow launch attempt prove otherwise; skipped E2E is valid only when exact attempted commands and observed failure output are recorded. Goal reviewers also look for any QA E2E video referenced by the ledger or receipt and must inspect the actual video before treating it as proof. Three reviewers independently inspect the ledger, worker receipt, repository state, and diff against `base_branch`; each returns structured JSON with findings, evidence, verification still remaining, and an optional blocker. A TypeScript reducer marks the goal complete only when reviewer quorum approves, marks blocked only when the same dependency/tool blocker repeats for the blocker threshold, continues when evidence is missing, and returns `needs_human` when `max_turns` is exhausted or worker execution fails.
|
|
250
|
+
The worker may claim readiness, but it cannot finalize completion. Workers start from an observable acceptance/contract matrix derived from the literal objective/acceptance criteria (one row per clause, each mapped to the concrete check that proves it), and are prompted to model states, transitions, and invariants explicitly when the work is stateful. Reviewer findings from the latest round are consolidated into a deduplicated cross-reviewer batch persisted in the round artifact (`consolidated_findings` in `review-round-latest.json`), and the next worker turn is instructed to plan and repair the whole batch — with durable regression evidence for reproduced findings — rather than fixing one finding per turn. Workers and reviewers are prompted to verify user-visible behavior end-to-end when practical, using `playwright-cli`-skilled subagents for web/frontend flows that may depend on backend/API behavior and tmux-skilled subagents for TUI or terminal-app scenarios. They must assume credentials/auth/environment access exists until concrete checks plus an actual app/flow launch attempt prove otherwise; skipped E2E is valid only when exact attempted commands and observed failure output are recorded. Goal reviewers also look for any QA E2E video referenced by the ledger or receipt and must inspect the actual video before treating it as proof. Three reviewers independently inspect the ledger, worker receipt, repository state, and diff against `base_branch`; each starts in a clean, non-forked context, matching Ralph's reviewer context behavior, and every Goal reviewer uses Ralph's `reviewer-a` model chain with Claude Fable 5 as the primary model. Each reviewer is instructed to first derive its own adversarial check list from the literal contract — boundary/edge/negative probes plus state/transition/invariant probes — before relying on the worker receipt or worker-authored tests, and each returns structured JSON with findings, evidence, verification still remaining, and an optional blocker. A TypeScript reducer marks the goal complete only when reviewer quorum approves and evidence closure holds (no unresolved objective-relevant blocking finding from any reviewer in the round), marks blocked only when the same dependency/tool blocker repeats for the blocker threshold, continues when evidence is missing or closure fails (recording the unresolved findings in the decision reason), and returns `needs_human` when `max_turns` is exhausted or worker execution fails, so the bounded loop always stops with an inspectable reason.
|
|
250
251
|
|
|
251
252
|
When Goal's reducer returns `needs_human`, `blocked`, or another incomplete status, the top-level workflow run is not reported as a successful completion. `/workflow status` and lifecycle notices surface it as blocked/failed according to the run's terminal condition. Atomic also preserves structured recoverable failure metadata from the run's blocking stage (`failedStageId`) or run-level failure metadata, so auth, rate-limit, and provider fallback exhaustion remains blocked/resumable even if the workflow later returns ordinary outputs instead of a reserved `status` value. Tolerated branch failures from non-fail-fast parallel work do not reclassify an otherwise completed run.
|
|
252
253
|
|
|
@@ -292,7 +293,7 @@ Run examples:
|
|
|
292
293
|
/workflow ralph prompt="Safely implement the API refactor" git_worktree_dir=../atomic-ralph-api-wt base_branch=main
|
|
293
294
|
```
|
|
294
295
|
|
|
295
|
-
Each `ralph` run uses the raw `prompt` exactly as supplied as the operative objective for research, orchestration, and review, and stores `acceptance_criteria` as the immutable literal contract (defaulting to the prompt when omitted). Shared literal-contract prompt language forbids adding behaviors, restrictions, or error conditions beyond the prompt/acceptance criteria and requires surfacing conflicts with external knowledge; Ralph does not run an initial prompt-refinement stage. Each iteration transforms that raw prompt with `/skill:prompt-engineer Transform the following user request into a codebase and online research question which can be thoroughly explored: ...` (`research-prompt-refinement`), researches that transformed question with `/skill:research-codebase ...`, and writes the findings under `research/`. The research, orchestrator, and reviewer prompts carry `acceptance_criteria` next to the literal contract, so orchestrators should pass the ORIGINAL task text when launching follow-up Ralph runs from reviewer findings. The orchestrator treats the research artifact as its primary implementation context, initializes/updates an OS-temp implementation notes file while generating verifiable evidence for any claims it records in the notes and reviewer artifacts, delegates implementation through sub-agents, and asks two independent reviewers (`reviewer-a` and `reviewer-b`) to inspect the patch directly against `base_branch`. The reviewer fan-out runs reviewers on different primary model families (Claude Fable 5 and GPT-5.5 Codex, with shared fallbacks) so the adversarial review gets cross-model coverage instead of repeated passes from one model. Ralph's orchestrator and reviewers are prompted to verify user-visible behavior end-to-end when practical, using `playwright-cli`-skilled subagents for web/frontend flows that may depend on backend/API behavior and tmux-skilled subagents for TUI or terminal-app scenarios. They must assume credentials/auth/environment access exists until concrete checks plus an actual app/flow launch attempt prove otherwise; skipped E2E is valid only when exact attempted commands and observed failure output are recorded. For UI-applicable or full-stack changes, the orchestrator runs a `playwright-cli` end-to-end QA pass and records a reviewable proof video (referenced in the implementation notes and surfaced as `qa_video_path`); reviewers receive that path and must inspect the actual video before treating it as proof. When `create_pr=true`, the final `pull-request` stage attaches or links that video to the created PR/MR/review after reviewer approval. If reviewers find issues, the next `research-prompt-refinement` and research stages receive the review artifact path so follow-up research can address unresolved findings, and research stages fork from prior research session data when available. The loop stops only when both reviewers independently approve or `max_loops` is reached. Ralph findings include the same `objective_alignment` classification used by Goal: `required_by_objective`
|
|
296
|
+
Each `ralph` run uses the raw `prompt` exactly as supplied as the operative objective for research, orchestration, and review, and stores `acceptance_criteria` as the immutable literal contract (defaulting to the prompt when omitted). Shared literal-contract prompt language forbids adding behaviors, restrictions, or error conditions beyond the prompt/acceptance criteria and requires surfacing conflicts with external knowledge; Ralph does not run an initial prompt-refinement stage. Each iteration transforms that raw prompt with `/skill:prompt-engineer Transform the following user request into a codebase and online research question which can be thoroughly explored: ...` (`research-prompt-refinement`), researches that transformed question with `/skill:research-codebase ...`, and writes the findings under `research/`. The research, orchestrator, and reviewer prompts carry `acceptance_criteria` next to the literal contract, so orchestrators should pass the ORIGINAL task text when launching follow-up Ralph runs from reviewer findings. The orchestrator starts from an observable acceptance/contract matrix derived from the literal prompt/acceptance criteria (one row per clause mapped to the concrete observable check that proves it) and is prompted to model states, transitions, and invariants explicitly when the work is stateful; it treats the research artifact as its primary implementation context, initializes/updates an OS-temp implementation notes file while generating verifiable evidence for any claims it records in the notes and reviewer artifacts, delegates implementation through sub-agents, repairs unresolved reviewer findings as one consolidated batch (with durable regression evidence for reproduced findings) rather than one finding per iteration, and asks two independent reviewers (`reviewer-a` and `reviewer-b`) to inspect the patch directly against `base_branch`. The reviewer fan-out runs reviewers on different primary model families (Claude Fable 5 and GPT-5.5 Codex, with shared fallbacks) so the adversarial review gets cross-model coverage instead of repeated passes from one model, and each reviewer is instructed to first derive its own adversarial check list from the literal contract — boundary/edge/negative probes plus state/transition/invariant probes — before relying on the implementation notes, orchestrator report, or worker-authored tests. Ralph's orchestrator and reviewers are prompted to verify user-visible behavior end-to-end when practical, using `playwright-cli`-skilled subagents for web/frontend flows that may depend on backend/API behavior and tmux-skilled subagents for TUI or terminal-app scenarios. They must assume credentials/auth/environment access exists until concrete checks plus an actual app/flow launch attempt prove otherwise; skipped E2E is valid only when exact attempted commands and observed failure output are recorded. For UI-applicable or full-stack changes, the orchestrator runs a `playwright-cli` end-to-end QA pass and records a reviewable proof video (referenced in the implementation notes and surfaced as `qa_video_path`); reviewers receive that path and must inspect the actual video before treating it as proof. When `create_pr=true`, the final `pull-request` stage attaches or links that video to the created PR/MR/review after reviewer approval. If reviewers find issues, the next `research-prompt-refinement` and research stages receive the review artifact path (whose `review-round-latest.json` now also carries a deduplicated cross-reviewer `consolidated_findings` batch) so follow-up research can address unresolved findings, and research stages fork from prior research session data when available. The loop stops only when both reviewers independently approve or `max_loops` is reached, so the bounded loop always stops with an inspectable review round. Ralph findings include the same `objective_alignment` classification used by Goal: `required_by_objective` findings block at any priority (P3 included, because severity labels alone never dismiss objective-relevant findings), `consistent_with_objective` P0/P1/P2 findings block while P3 remains a non-blocking nice-to-have, and `beyond_objective`/`contradicts_objective` findings are surfaced but non-blocking so they are not silently converted into new requirements. Ralph review decisions also include `requirements_traceability`, a clause-by-clause evidence map over every explicit prompt/acceptance-criteria requirement; approval requires that map to be non-empty and fully `proven` except for a missing PR/MR/review row when `create_pr=true` and that final handoff is the only remaining action. Worker-authored tests or snapshots passing are circular evidence unless tied to independent current-state proof. By default Ralph does not start the final `pull-request` stage, and `pr_report` is omitted. Prompt text alone does not opt in. Pass `create_pr=true` only when you explicitly want the final `pull-request` stage to inspect provider credentials and attempt provider-appropriate PR/MR/review creation, such as GitHub `gh`, Azure Repos `az repos pr create`, or Sapling/Phabricator tooling; Ralph's own PR-creation instructions live in that final stage and run only after approval.
|
|
296
297
|
|
|
297
298
|
Each Ralph review artifact and `review-round-latest.json` includes a `convergence_decision` summary with `parsed`, `approved`, `stopReviewLoop`, `nextAction`, `finalActionRemaining`, and `diagnostics`. This makes malformed or missing structured reviewer output visible as a parse failure, separate from a parsed reviewer rejection or blocking finding. When `create_pr=true`, reviewers are told that PR/MR/review creation is a post-approval final action: if implementation and validation requirements are proven and only PR creation remains, the implementation can approve with `finalActionRemaining: true` and `nextAction: "pull-request"` instead of consuming another orchestration iteration. When both reviewers converge, the latest round records `approved: true`, `stopReviewLoop: true`, and `nextAction: "pull-request"` when `create_pr=true` (otherwise `"finish"`), and the implementation loop stops before the final handoff stage.
|
|
298
299
|
|
|
@@ -615,6 +616,98 @@ Best practices:
|
|
|
615
616
|
|
|
616
617
|
Record the selected pattern in your spec or workflow README, then adapt the diagram to the actual stage graph. If the final design does not resemble any starter pattern, explain why in the workflow's design notes.
|
|
617
618
|
|
|
619
|
+
## Choosing an Execution Shape
|
|
620
|
+
|
|
621
|
+
"Use a workflow" is not one decision — it is a ladder of execution shapes with different costs and guarantees. This section is written as agent-facing guidance: it is the self-prompt an orchestrating agent should run before the first tool call on a new request, and it doubles as documentation for humans who want to steer that choice explicitly.
|
|
622
|
+
|
|
623
|
+
The shapes, cheapest first:
|
|
624
|
+
|
|
625
|
+
| Shape | What it is | Guarantees you gain | Cost you pay |
|
|
626
|
+
|---|---|---|---|
|
|
627
|
+
| **Inline** | Answer or edit directly in the current session. | Lowest latency, zero ceremony. | No tracking, no gates, no isolation, easy to drift. |
|
|
628
|
+
| **Inline + subagents** | Bounded specialist delegation (locate/analyze/research/debug passes, noisy command investigation, parallel read-only fanouts) while the parent keeps control and synthesizes. | Context isolation for noisy or parallel evidence-gathering. | No completion gate, no durable stages; the parent is the only reviewer. |
|
|
629
|
+
| **Direct one-off shapes** | `workflow({ task })`, `workflow({ tasks })`, or `workflow({ chain })` without saving a definition. | Stage tracking, artifacts, model fallbacks, monitoring, resume. | Linear/parallel control flow only; no custom branching or loops. |
|
|
630
|
+
| **Named workflows** | Installed builtin, project, user, or package workflows (`goal`, `ralph`, `deep-research-codebase`, `open-claude-design`, ...). | A proven graph: bounded loops, reviewer gates, ledgers, evidence contracts, tuned model chains. | The task must actually match the graph's objective and inputs. |
|
|
631
|
+
| **Custom workflow** | A task-specific TypeScript `workflow({...})` authored inline, composing the starter patterns. | Exactly the control flow the task needs: runtime branching, dynamic fan-out, custom gates, tournaments, bounded loops. | Authoring and reload time; you own the design quality. |
|
|
632
|
+
| **Composed/nested workflows** | A custom parent that imports proven definitions and calls `ctx.workflow(child)`. | Reuse of hardened children (research, review loops) inside custom control flow, within `maxDepth`. | Parent/child input-output contracts must be mapped deliberately. |
|
|
633
|
+
|
|
634
|
+
### The self-prompt
|
|
635
|
+
|
|
636
|
+
Ask these questions in order and stop at the first shape that satisfies every remaining requirement. Decide before the first tool call and state the decision; reconnaissance already counts as inline execution.
|
|
637
|
+
|
|
638
|
+
1. **Is the outcome provable?** If success can be stated as evidence (tests green, artifact exists, behavior demonstrated, reviewer approves), the task is workflow-shaped. If no proof is possible or needed, inline is probably fine.
|
|
639
|
+
2. **Is there structure?** Multiple subtasks, dependencies, handoffs, or parallel slices push past inline. A single focused evidence-gathering pass does not.
|
|
640
|
+
3. **Is there a loop or gate?** Any "until Y", "fix until passing", review/approval gate, or unknown-length repair cycle requires an engine that owns the stop condition — a workflow, never an improvised inline retry loop or a stretched subagent chain.
|
|
641
|
+
4. **Is it one task or a queue of tasks?** "Address all open issues" or "fix every ticket assigned to me" is a factory request, not one workflow. Enumerate and dependency-classify the items first, then follow [Task queues and software factories](#task-queues-and-software-factories): independent items become separate per-item runs; dependent items share one composed graph.
|
|
642
|
+
5. **Does an installed graph already fit?** If a named workflow's objective and inputs cover essentially the whole task, run it. Do not force-fit: a builtin that matches 60% of the task and fights the other 40% is worse than a small custom graph.
|
|
643
|
+
6. **Does the control flow need shapes builtins don't offer?** Runtime classification, per-item dynamic fan-out, generate-and-filter, tournaments, or domain-specific gates mean authoring a custom workflow from the starter patterns.
|
|
644
|
+
7. **Is a sub-problem already solved by a proven graph?** Nest it with `ctx.workflow(...)` instead of re-authoring its prompts and gates. Composition beats duplication whenever a child's input/output contract can be mapped cleanly.
|
|
645
|
+
8. **Is it only specialist evidence-gathering?** If the parent keeps control, no completion gate is needed, and the work is bounded (a debug pass, a parallel research fanout, one noisy investigation), inline subagents are enough — and cheaper than a workflow.
|
|
646
|
+
9. **Is it truly tiny?** Deterministic, low-risk, single-file/no-test/no-review — answer or edit inline and stop.
|
|
647
|
+
|
|
648
|
+
### Scoring rubric
|
|
649
|
+
|
|
650
|
+
When the ladder is ambiguous, score the task on six dimensions (0–2 each):
|
|
651
|
+
|
|
652
|
+
| Dimension | 0 | 1 | 2 |
|
|
653
|
+
|---|---|---|---|
|
|
654
|
+
| **Structure** | one action | a few sequential steps | many steps, dependencies, or parallel slices |
|
|
655
|
+
| **Verifiability** | no objective check | spot-checkable | provable by tests, builds, artifacts, or review evidence |
|
|
656
|
+
| **Iteration** | one pass suffices | may need one repair round | unknown-length loop until evidence passes |
|
|
657
|
+
| **Risk** | trivial, reversible | scoped multi-file change | regressions, migrations, releases, or user-visible behavior |
|
|
658
|
+
| **Duration** | seconds to minutes | tens of minutes | long-running, background, or resumable across sessions |
|
|
659
|
+
| **Isolation** | one context is fine | one noisy investigation to quarantine | many slices needing clean contexts or adversarial independence |
|
|
660
|
+
|
|
661
|
+
Interpretation:
|
|
662
|
+
|
|
663
|
+
- **0–3 total:** inline. Adding stages costs more than it buys.
|
|
664
|
+
- **4–6 total, Iteration ≤ 1, no gate:** inline subagents (parent-controlled) or a direct one-off `task`/`tasks`/`chain` when tracking and artifacts help.
|
|
665
|
+
- **7+ total, or Iteration = 2, or Verifiability = 2 with a review/approval gate:** a real workflow. Prefer a named workflow when one fits the whole task; otherwise author a custom graph, nesting proven children where sub-problems overlap.
|
|
666
|
+
- **Any single hard signal overrides the arithmetic:** an explicit loop/stop condition, an approval or evidence gate, or a request for durable/background execution puts the task in workflow territory regardless of total score.
|
|
667
|
+
|
|
668
|
+
Two common misuses the rubric exists to prevent: stretching parent-controlled subagent calls into an ad hoc implement→review→retry pipeline (that is adversarial verification without an engine — use a workflow and let its stages delegate specialists), and unbounded inline reconnaissance (after roughly ten exploratory calls with no artifact, write findings to a context file and hand off through `reads`; sunk research transfers, it is not a reason to stay inline).
|
|
669
|
+
|
|
670
|
+
### Task queues and software factories
|
|
671
|
+
|
|
672
|
+
Some requests are not one task but a queue of them: "address all open issues", "fix every Linear ticket assigned to me", "burn down the TODO backlog", "upgrade every service to the new SDK". These fire-and-forget factory requests get their own decision step, because the biggest mistake is jumping straight to one monolithic workflow that grinds through the queue serially in a single ever-growing context.
|
|
673
|
+
|
|
674
|
+
**Triage the queue before choosing the shape.** The first action is always a cheap enumeration-and-dependency pass, not implementation: list the items (issue tracker query, ticket API, grep for TODOs), then classify how they relate:
|
|
675
|
+
|
|
676
|
+
- **Independent items** — different subsystems, no shared files, no ordering constraints, each individually verifiable.
|
|
677
|
+
- **Dependent items** — one blocks another, they touch the same files/modules, they share a migration or API change, or their acceptance criteria reference each other.
|
|
678
|
+
- **Clustered** — the queue splits into groups: dependencies inside a group, independence between groups.
|
|
679
|
+
|
|
680
|
+
**Independent items → many small runs, not one big one.** Spawn one workflow run per item (typically `goal` with the item's text as the objective and acceptance criteria, `create_pr=true` for per-item PRs), each in its own `git_worktree_dir`, running in the background. One run per item buys what a monolith cannot:
|
|
681
|
+
|
|
682
|
+
- **Isolation:** a hard item that stalls or fails does not poison the remaining ones; each run resumes, retries, or gets killed independently.
|
|
683
|
+
- **Clean contexts:** every item starts with full attention on its own objective instead of inheriting twenty finished tickets of transcript.
|
|
684
|
+
- **Independent evidence:** per-item reviewer gates, receipts, and PRs that a human can merge or reject one at a time.
|
|
685
|
+
- **Real parallelism:** runs proceed concurrently, bounded by however many you choose to have in flight at once (worktrees prevent filesystem collisions).
|
|
686
|
+
|
|
687
|
+
Do not spawn unbounded: dispatch in waves (for example 3–5 concurrent runs), wait for lifecycle notices, then dispatch the next wave — and report the dispatch plan (item → run id → worktree) so the queue is auditable.
|
|
688
|
+
|
|
689
|
+
**Dependent items → one graph that encodes the ordering.** When items block each other or share a change surface, isolation stops being a feature — separate runs would fight over the same files or implement against stale assumptions. Encode the dependency structure explicitly instead:
|
|
690
|
+
|
|
691
|
+
- **A composed parent workflow** that nests a proven child (for example `ctx.workflow(goal, ...)` per item) in dependency order, passing each item's outputs/artifacts to its dependents — the preferred form, because each item still gets its own bounded loop and reviewer gate while the parent owns sequencing.
|
|
692
|
+
- **A single monolithic workflow** only when the items are so entangled they are really one task with subtasks (one migration touching every call site is one task, not a queue).
|
|
693
|
+
|
|
694
|
+
**Clustered queues → both.** Compose within a cluster, fan out across clusters: each cluster becomes one run (a composed parent or a single `goal` objective covering the cluster), and independent clusters are dispatched as parallel background runs in waves.
|
|
695
|
+
|
|
696
|
+
The self-prompt for factory requests, condensed: **enumerate → classify dependencies → fan out runs where independent, compose graphs where dependent → dispatch in bounded waves → report the plan.** When dependency classification is uncertain, prefer smaller independent runs and let per-item reviewer gates catch collisions — a rejected PR is cheaper than a monolith that carried a bad assumption through the whole queue.
|
|
697
|
+
|
|
698
|
+
### Prompting the choice
|
|
699
|
+
|
|
700
|
+
Humans can steer the shape directly. The strongest levers, in rough order of effect:
|
|
701
|
+
|
|
702
|
+
- **Name the shape or workflow.** "Do this inline", "use subagents to investigate", "run the goal workflow", or "write a custom workflow for this" is honored over the agent's own scoring.
|
|
703
|
+
- **State acceptance criteria.** Verbatim acceptance criteria make the objective provable, which both selects workflow execution and pins the immutable contract that `goal`/`ralph` reviewers enforce.
|
|
704
|
+
- **State the loop.** "Iterate until tests pass", "review and fix until approved" — loop wording is a hard workflow signal and defines the stop condition.
|
|
705
|
+
- **State the evidence.** Asking for a PR, a QA video, test output, or reviewer sign-off tells the agent which gates the graph needs.
|
|
706
|
+
- **State the boundary.** "Work in a separate worktree", "don't create the PR yet", or "stop after implementation" separates the implementation loop from explicitly authorized final actions.
|
|
707
|
+
- **State the queue policy.** For factory requests, say how to split and gate the queue: "one workflow and PR per issue", "these three tickets depend on each other — do them in order in one run", "triage first and show me the dependency plan before dispatching", or "no more than three runs at a time". Absent a policy, the agent triages dependencies itself and defaults to independent per-item runs with per-item evidence.
|
|
708
|
+
|
|
709
|
+
Absent these levers, the agent applies the self-prompt and rubric above — so a prompt that mentions none of them is delegating the shape decision, not avoiding it.
|
|
710
|
+
|
|
618
711
|
## Atomic vs Claude Code Dynamic Workflows
|
|
619
712
|
|
|
620
713
|
Claude Code Dynamic Workflows and Atomic are trying to solve a similar class of problem: important software engineering work is too large for one agent pass, so the system should split the job into stages, run agents in parallel, verify the result, and keep enough state to finish long-running work.
|
|
@@ -839,6 +932,8 @@ The workflow tool action surface is:
|
|
|
839
932
|
- messaging and run control: `send`, `pause`, `interrupt`, `kill`, `resume`
|
|
840
933
|
- rediscovery: `reload`
|
|
841
934
|
|
|
935
|
+
From interactive chat, model-launched workflows run in the background so the parent chat stays available. Named workflow launches already detach automatically; direct `task`, `tasks`, and `chain` launches must pass top-level `async: true`. This rule applies only to launches, not inspection or control calls (`status`, `stages`, `stage`, `transcript`, `send`, `pause`, `resume`, `interrupt`, `kill`). A model may launch in the foreground only when the user explicitly requests it or foreground execution is technically required, and it must tell the user before launching.
|
|
936
|
+
|
|
842
937
|
Run a named workflow with inputs:
|
|
843
938
|
|
|
844
939
|
```ts
|
|
@@ -1833,7 +1928,7 @@ export default workflow({
|
|
|
1833
1928
|
|
|
1834
1929
|
For lower-level integrations, `@bastani/workflows` also exports `setupGitWorktree({ gitWorktreeDir, baseBranch, cwd })`, returning `{ worktreeRoot, cwd, repositoryRoot, created }` with the same validation, symlink-preserving path handling, and cwd-preservation behavior used by workflow stages.
|
|
1835
1930
|
|
|
1836
|
-
`fallbackModels` retries transient provider/model failures with the primary `model` first, then each fallback, then the current Atomic-selected model when available. It is for rate limits, quota/auth/provider outages, unavailable models, network timeouts, generic transport errors such as `Connection error.` / `fetch failed`, and 5xx errors — not workflow-code errors, tool failures, validation failures, or cancellations.
|
|
1931
|
+
`fallbackModels` retries transient provider/model failures with the primary `model` first, then each fallback, then the current Atomic-selected model when available. It is for rate limits, quota/usage-limit exhaustion (provider messages such as `The usage limit has been reached` and codes such as `usage_limit_reached`/`insufficient_quota` classify as retryable rate-limit failures so the chain advances to a candidate provider/model with remaining headroom), auth/provider outages, unavailable models, network timeouts, generic transport errors such as `Connection error.` / `fetch failed`, and 5xx errors — not workflow-code errors, tool failures, validation failures, or cancellations.
|
|
1837
1932
|
|
|
1838
1933
|
A candidate that is **request/context incompatible** with the current turn — for example an HTTP 400/413/422 bad/unprocessable/payload-too-large request, an unsupported tool or parameter, a context-length/context-window overflow, or a `too large` / `invalid_request` / `bad_request` error — also advances the chain to the next candidate rather than stopping. This ensures that if none of the configured candidates can serve the request, the workflow stage falls back to the currently selected user model instead of hard-failing. Refusals, content-filter/safety blocks, cancellations, and task failures still stop the chain and are never retried on another model.
|
|
1839
1934
|
|
|
@@ -1983,6 +2078,17 @@ Avoid unrelated workflow internals such as reducer algorithms, future PR stages,
|
|
|
1983
2078
|
|
|
1984
2079
|
Choose context mode deliberately. Use `context: "fork"` or `forkFromSessionFile` for coherent long-running implementation stages that need continuity from their own earlier work. Use `context: "fresh"` for unbiased reviewer, evaluator, and gate stages so they inspect the current files and explicit artifacts rather than inheriting the implementer's assumptions. When continuity is needed across fresh stages, pass it explicitly through files, declared outputs, and `reads`.
|
|
1985
2080
|
|
|
2081
|
+
### Context-Mode-Aware Prompt Text
|
|
2082
|
+
|
|
2083
|
+
Context mode is an execution property configured with `context`/`forkFromSessionFile`; it is not something the model can act on, so keep it out of prompt text:
|
|
2084
|
+
|
|
2085
|
+
- **Never describe the stage's own context mode.** Sentences like "you are running in a fresh context window", "your context is clean/non-forked", or "this is a forked session" add tokens without changing behavior. State the concrete action, inputs, and success criteria instead.
|
|
2086
|
+
- **Fresh stages must not reference invisible context.** A fresh stage has no "previous conversation", cannot see sibling stages, and does not know the surrounding graph, so instructions like "compare against previous workflow reasoning" or "this runs in parallel with the locator pass" are noise at best and confusing at worst. Phrase the same intent stage-locally ("compare the working tree against the baseline branch"; "do your own scan; do not assume any other stage's output is available") and pass any state the stage genuinely needs through files, declared outputs, and `reads`.
|
|
2087
|
+
- **Forked continuation prompts send only the delta.** A forked stage already carries the role, contracts, guidance, and output format from its own earlier prompts, so repeating them re-spends the tokens and invites drift between the two copies. Send what changed since the fork point — new artifacts, updated state, the next action — plus a one-line pointer back ("the contracts and report format established earlier in this thread still apply unchanged") instead of re-injecting the full text.
|
|
2088
|
+
- **Keep one canonical copy of shared contracts.** When fresh and forked variants of a stage share guidance, render the full contract only in the prompt that first establishes it and reference it from continuations. If a continuation genuinely needs a contract restated (for example, after a schema change), that is a new contract version, not a repeat.
|
|
2089
|
+
|
|
2090
|
+
The builtin `goal` and `ralph` workflows follow this pattern: their first worker/orchestrator prompts carry the full contracts, while forked continuation turns send only the per-turn state (new receipts, the latest review artifacts, the rewritten research file) with a pointer back to the established guidance.
|
|
2091
|
+
|
|
1986
2092
|
### Context Fundamentals
|
|
1987
2093
|
|
|
1988
2094
|
Treat context as a finite attention budget. Include only information needed for the current decision, place critical constraints near the beginning or end of prompts, and use progressive disclosure instead of loading every possible reference up front.
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bastani/atomic",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.7",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@bastani/atomic",
|
|
9
|
-
"version": "0.9.
|
|
9
|
+
"version": "0.9.7",
|
|
10
10
|
"license": "MIT",
|
|
11
11
|
"dependencies": {
|
|
12
|
-
"@bastani/atomic-natives": "0.9.
|
|
12
|
+
"@bastani/atomic-natives": "0.9.7",
|
|
13
13
|
"@bufbuild/protobuf": "^2.12.1",
|
|
14
14
|
"@earendil-works/pi-agent-core": "^0.80.6",
|
|
15
15
|
"@earendil-works/pi-ai": "^0.80.6",
|
|
@@ -515,16 +515,16 @@
|
|
|
515
515
|
}
|
|
516
516
|
},
|
|
517
517
|
"node_modules/@bastani/atomic-natives": {
|
|
518
|
-
"version": "0.9.
|
|
519
|
-
"resolved": "https://registry.npmjs.org/@bastani/atomic-natives/-/atomic-natives-0.9.
|
|
518
|
+
"version": "0.9.7",
|
|
519
|
+
"resolved": "https://registry.npmjs.org/@bastani/atomic-natives/-/atomic-natives-0.9.7.tgz",
|
|
520
520
|
"license": "MIT",
|
|
521
521
|
"optionalDependencies": {
|
|
522
|
-
"@bastani/atomic-natives-darwin-arm64": "0.9.
|
|
523
|
-
"@bastani/atomic-natives-darwin-x64": "0.9.
|
|
524
|
-
"@bastani/atomic-natives-linux-arm64-gnu": "0.9.
|
|
525
|
-
"@bastani/atomic-natives-linux-x64-gnu": "0.9.
|
|
526
|
-
"@bastani/atomic-natives-win32-arm64-msvc": "0.9.
|
|
527
|
-
"@bastani/atomic-natives-win32-x64-msvc": "0.9.
|
|
522
|
+
"@bastani/atomic-natives-darwin-arm64": "0.9.7",
|
|
523
|
+
"@bastani/atomic-natives-darwin-x64": "0.9.7",
|
|
524
|
+
"@bastani/atomic-natives-linux-arm64-gnu": "0.9.7",
|
|
525
|
+
"@bastani/atomic-natives-linux-x64-gnu": "0.9.7",
|
|
526
|
+
"@bastani/atomic-natives-win32-arm64-msvc": "0.9.7",
|
|
527
|
+
"@bastani/atomic-natives-win32-x64-msvc": "0.9.7"
|
|
528
528
|
},
|
|
529
529
|
"engines": {
|
|
530
530
|
"bun": ">=1.3.14",
|
|
@@ -532,8 +532,8 @@
|
|
|
532
532
|
}
|
|
533
533
|
},
|
|
534
534
|
"node_modules/@bastani/atomic-natives-darwin-arm64": {
|
|
535
|
-
"version": "0.9.
|
|
536
|
-
"resolved": "https://registry.npmjs.org/@bastani/atomic-natives-darwin-arm64/-/atomic-natives-darwin-arm64-0.9.
|
|
535
|
+
"version": "0.9.7",
|
|
536
|
+
"resolved": "https://registry.npmjs.org/@bastani/atomic-natives-darwin-arm64/-/atomic-natives-darwin-arm64-0.9.7.tgz",
|
|
537
537
|
"license": "MIT",
|
|
538
538
|
"os": [
|
|
539
539
|
"darwin"
|
|
@@ -544,8 +544,8 @@
|
|
|
544
544
|
"optional": true
|
|
545
545
|
},
|
|
546
546
|
"node_modules/@bastani/atomic-natives-darwin-x64": {
|
|
547
|
-
"version": "0.9.
|
|
548
|
-
"resolved": "https://registry.npmjs.org/@bastani/atomic-natives-darwin-x64/-/atomic-natives-darwin-x64-0.9.
|
|
547
|
+
"version": "0.9.7",
|
|
548
|
+
"resolved": "https://registry.npmjs.org/@bastani/atomic-natives-darwin-x64/-/atomic-natives-darwin-x64-0.9.7.tgz",
|
|
549
549
|
"license": "MIT",
|
|
550
550
|
"os": [
|
|
551
551
|
"darwin"
|
|
@@ -556,8 +556,8 @@
|
|
|
556
556
|
"optional": true
|
|
557
557
|
},
|
|
558
558
|
"node_modules/@bastani/atomic-natives-linux-arm64-gnu": {
|
|
559
|
-
"version": "0.9.
|
|
560
|
-
"resolved": "https://registry.npmjs.org/@bastani/atomic-natives-linux-arm64-gnu/-/atomic-natives-linux-arm64-gnu-0.9.
|
|
559
|
+
"version": "0.9.7",
|
|
560
|
+
"resolved": "https://registry.npmjs.org/@bastani/atomic-natives-linux-arm64-gnu/-/atomic-natives-linux-arm64-gnu-0.9.7.tgz",
|
|
561
561
|
"license": "MIT",
|
|
562
562
|
"os": [
|
|
563
563
|
"linux"
|
|
@@ -571,8 +571,8 @@
|
|
|
571
571
|
"optional": true
|
|
572
572
|
},
|
|
573
573
|
"node_modules/@bastani/atomic-natives-linux-x64-gnu": {
|
|
574
|
-
"version": "0.9.
|
|
575
|
-
"resolved": "https://registry.npmjs.org/@bastani/atomic-natives-linux-x64-gnu/-/atomic-natives-linux-x64-gnu-0.9.
|
|
574
|
+
"version": "0.9.7",
|
|
575
|
+
"resolved": "https://registry.npmjs.org/@bastani/atomic-natives-linux-x64-gnu/-/atomic-natives-linux-x64-gnu-0.9.7.tgz",
|
|
576
576
|
"license": "MIT",
|
|
577
577
|
"os": [
|
|
578
578
|
"linux"
|
|
@@ -586,8 +586,8 @@
|
|
|
586
586
|
"optional": true
|
|
587
587
|
},
|
|
588
588
|
"node_modules/@bastani/atomic-natives-win32-arm64-msvc": {
|
|
589
|
-
"version": "0.9.
|
|
590
|
-
"resolved": "https://registry.npmjs.org/@bastani/atomic-natives-win32-arm64-msvc/-/atomic-natives-win32-arm64-msvc-0.9.
|
|
589
|
+
"version": "0.9.7",
|
|
590
|
+
"resolved": "https://registry.npmjs.org/@bastani/atomic-natives-win32-arm64-msvc/-/atomic-natives-win32-arm64-msvc-0.9.7.tgz",
|
|
591
591
|
"license": "MIT",
|
|
592
592
|
"os": [
|
|
593
593
|
"win32"
|
|
@@ -598,8 +598,8 @@
|
|
|
598
598
|
"optional": true
|
|
599
599
|
},
|
|
600
600
|
"node_modules/@bastani/atomic-natives-win32-x64-msvc": {
|
|
601
|
-
"version": "0.9.
|
|
602
|
-
"resolved": "https://registry.npmjs.org/@bastani/atomic-natives-win32-x64-msvc/-/atomic-natives-win32-x64-msvc-0.9.
|
|
601
|
+
"version": "0.9.7",
|
|
602
|
+
"resolved": "https://registry.npmjs.org/@bastani/atomic-natives-win32-x64-msvc/-/atomic-natives-win32-x64-msvc-0.9.7.tgz",
|
|
603
603
|
"license": "MIT",
|
|
604
604
|
"os": [
|
|
605
605
|
"win32"
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bastani/atomic",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.7",
|
|
4
4
|
"description": "Atomic coding agent CLI with read, bash, edit, write tools and session management",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"atomicConfig": {
|
|
@@ -77,7 +77,7 @@
|
|
|
77
77
|
"prepublishOnly": "bun run clean && bun run build && bun run shrinkwrap"
|
|
78
78
|
},
|
|
79
79
|
"dependencies": {
|
|
80
|
-
"@bastani/atomic-natives": "0.9.
|
|
80
|
+
"@bastani/atomic-natives": "0.9.7",
|
|
81
81
|
"@bufbuild/protobuf": "^2.12.1",
|
|
82
82
|
"@earendil-works/pi-agent-core": "^0.80.6",
|
|
83
83
|
"@earendil-works/pi-ai": "^0.80.6",
|