@jaybeeuu/agent-cortex 2.0.0 → 2.2.0
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 +437 -0
- package/README.md +46 -15
- package/agents/README.md +22 -10
- package/agents/plan/agent.md +2 -2
- package/agents/ralph/agent.md +128 -91
- package/agents/ralph/claude/frontmatter.json +3 -3
- package/agents/ralph/claude/wake.md +46 -0
- package/agents/ralph/pi/{polling.md → wake.md} +35 -20
- package/agents/ralph-plan/agent.md +23 -11
- package/bin/agent-cortex.mjs +66 -4
- package/bin/installers/claude.mjs +262 -77
- package/bin/installers/pi.mjs +200 -24
- package/extensions/agent-guardrails/README.md +1 -1
- package/extensions/agent-guardrails/guardrails.ts +1 -1
- package/extensions/agent-guardrails/index.ts +1 -1
- package/extensions/agent-modes/discover.test.ts +2 -2
- package/extensions/output-style/README.md +58 -0
- package/extensions/output-style/index.ts +23 -0
- package/extensions/output-style/output-style.md +43 -0
- package/extensions/output-style/output-style.test.ts +50 -0
- package/extensions/output-style/output-style.ts +32 -0
- package/extensions/output-style/package.json +19 -0
- package/hooks/claude/scripts/notify.mjs +8 -1
- package/lib/cli.mjs +91 -2
- package/package.json +29 -4
- package/scripts/check-changeset.mjs +4 -0
- package/scripts/check-no-sync.mjs +5 -1
- package/scripts/check-skill-frontmatter.mjs +21 -0
- package/scripts/lib/compose-agent.mjs +69 -9
- package/scripts/lib/fs.mjs +10 -2
- package/scripts/lib/migrate.mjs +736 -0
- package/scripts/lib/release-gates.mjs +21 -1
- package/scripts/lib/skill-frontmatter.mjs +152 -0
- package/scripts/lib/skill-links.mjs +52 -0
- package/scripts/lib/verify-worker-tree.mjs +25 -0
- package/scripts/resolve-publish-command.mjs +4 -0
- package/skills/engineering/design-an-interface/SKILL.md +3 -3
- package/skills/engineering/grill-with-docs/SKILL.md +3 -5
- package/skills/engineering/improve-codebase-architecture/SKILL.md +5 -4
- package/skills/engineering/tdd/SKILL.md +5 -7
- package/skills/engineering/technical-direction/SKILL.md +5 -5
- package/skills/planning/classify-bead/REFERENCE.md +3 -3
- package/skills/planning/classify-bead/SKILL.md +14 -9
- package/skills/planning/classify-bead/scripts/classify-bead.mjs +5 -4
- package/skills/planning/create-task/REFERENCE.md +52 -3
- package/skills/planning/create-task/SKILL.md +70 -26
- package/skills/planning/create-task/scripts/{create-chores.ts → create-chores.mjs} +48 -23
- package/skills/planning/flesh-out-idea/REFERENCE.md +116 -0
- package/skills/planning/flesh-out-idea/SKILL.md +146 -0
- package/skills/planning/prd-to-tasks/REFERENCE.md +54 -5
- package/skills/planning/prd-to-tasks/SKILL.md +22 -16
- package/skills/planning/record-idea/FORMAT.md +66 -17
- package/skills/planning/record-idea/SKILL.md +48 -24
- package/skills/planning/request-refactor-plan/SKILL.md +4 -4
- package/skills/planning/spec-to-tickets/SKILL.md +5 -5
- package/skills/planning/write-a-prd/SKILL.md +8 -9
- package/skills/planning/write-a-ticket/SKILL.md +4 -6
- package/skills/productivity/bd-tool/SKILL.md +15 -10
- package/skills/productivity/grill-me/SKILL.md +5 -0
- package/skills/productivity/init-beads/SKILL.md +3 -3
- package/skills/productivity/migration/REFERENCE.md +227 -0
- package/skills/productivity/migration/SKILL.md +188 -0
- package/skills/productivity/validate-agent-dir/scripts/{validate-agent-dir.ts → validate-agent-dir.mjs} +49 -28
- package/skills/productivity/write-a-skill/SKILL.md +5 -5
- package/skills/review/maintain-agent-docs/SKILL.md +5 -7
- package/skills/review/refactor-skill/SKILL.md +4 -3
- package/skills/review/review-security/SKILL.md +3 -5
- package/skills/style/style-code/SKILL.md +5 -10
- package/skills/style/style-comms/SKILL.md +5 -7
- package/skills/style/style-documentation/SKILL.md +5 -6
- package/skills/style/style-tests/SKILL.md +5 -7
- package/skills/workflow/git-workflow/SKILL.md +28 -4
- package/skills/workflow/hitl-collab/SKILL.md +4 -6
- package/skills/workflow/plan/SKILL.md +41 -30
- package/skills/workflow/ralph/REFERENCE.md +209 -55
- package/skills/workflow/ralph/SKILL.md +89 -50
- package/skills/workflow/ralph/scripts/pending-gates.mjs +134 -0
- package/skills/workflow/run-pipeline-stage/SKILL.md +72 -71
- package/skills/workflow/run-pipeline-stage/playbooks/code.md +11 -0
- package/skills/workflow/run-pipeline-stage/playbooks/document.md +12 -0
- package/skills/workflow/run-pipeline-stage/playbooks/fix.md +12 -0
- package/skills/workflow/run-pipeline-stage/playbooks/review.md +11 -0
- package/skills/workflow/run-pipeline-stage/playbooks/verify.md +13 -0
- package/skills/workflow/run-pipeline-stage/prompts/stage-runner.md +73 -1
- package/token-map.README.md +9 -4
- package/token-map.json +13 -6
- package/.agents/skills/style-versioning/SKILL.md +0 -172
- package/.changeset/README.md +0 -8
- package/.changeset/config.json +0 -11
- package/.github/workflows/ci.yml +0 -302
- package/.junie/guidelines.md +0 -87
- package/.junie/mcp/mcp.json +0 -10
- package/AGENTS.md +0 -151
- package/agents/ralph/claude/polling.md +0 -31
- package/agents-native/ralph.md +0 -193
- package/docs/claude-hooks.md +0 -128
- package/docs/commit-signing.md +0 -231
- package/docs/ideas/auto-model-selection.md +0 -75
- package/docs/ideas/ban-content-assertion-tests.md +0 -75
- package/docs/ideas/bead-progress-notes-for-session-resumption.md +0 -75
- package/docs/ideas/classify-beads-via-deterministic-script-with-agent-fallback.md +0 -70
- package/docs/ideas/ctx-alias-version-and-update-commands.md +0 -65
- package/docs/ideas/ctx-feedback-command-for-capturing-ideas-from-any-machine.md +0 -67
- package/docs/ideas/dedicated-review-tests-skill.md +0 -71
- package/docs/ideas/deployment-beads-for-post-merge-pipelines.md +0 -36
- package/docs/ideas/design-and-delivery-as-separate-bead-trees/design-and-delivery-as-separate-bead-trees.md +0 -99
- package/docs/ideas/enable-signed-commit-enforcement-changesets-bot-commits-must-be-signed.md +0 -42
- package/docs/ideas/extension-manifests.md +0 -121
- package/docs/ideas/improve-pi-system-prompt.md +0 -37
- package/docs/ideas/map-every-cortex-tool-to-a-real-pi-equivalent.md +0 -95
- package/docs/ideas/model-selector.md +0 -40
- package/docs/ideas/pi-task-memory.md +0 -34
- package/docs/ideas/qa-extension.md +0 -43
- package/docs/ideas/record-idea-implementation-questions.md +0 -68
- package/docs/ideas/record-ideas-as-beads.md +0 -115
- package/docs/ideas/self-flushing-session.md +0 -72
- package/docs/ideas/state-in-beads-not-md.md +0 -69
- package/docs/ideas/subagent-visibility.md +0 -72
- package/docs/ideas/task-session-context.local.md +0 -95
- package/docs/ideas/task-session-context.md +0 -89
- package/docs/ideas/test-data-creation-helpers.md +0 -92
- package/docs/ideas/test-planning-stage-bead-in-feature-planning.md +0 -68
- package/docs/ideas/unified-ci-pipeline.md +0 -28
- package/docs/ideas/unify-the-ticket-and-task-decomposition-workflows.md +0 -71
- package/docs/ideas/worktree-housekeeping-for-closed-beads.md +0 -39
- package/docs/inspirations.md +0 -33
- package/docs/research/disable-model-invocation.md +0 -82
- package/docs/research/gas-city-research.md +0 -256
- package/docs/research/skill-design-research.md +0 -286
- package/docs/research/skill-improvements-analysis.md +0 -117
- package/docs/research/skill-patterns-research.md +0 -24
- package/docs/skills/skill-anatomy.md +0 -197
- package/docs/technical-direction/harness-config.md +0 -177
- package/docs/technical-direction/migration-execution-labels.md +0 -177
- package/docs/user-preferences.md +0 -17
- package/extensions/agent-guardrails/tsconfig.json +0 -12
- package/extensions/agent-modes/tsconfig.json +0 -12
- package/extensions/session-start/tsconfig.json +0 -12
- package/extensions/skill-stats/pnpm-lock.yaml +0 -329
- package/extensions/skill-stats/tsconfig.json +0 -12
- package/extensions/subagent/agents/planner.md +0 -37
- package/extensions/subagent/agents/reviewer.md +0 -35
- package/extensions/subagent/agents/scout.md +0 -50
- package/extensions/subagent/agents/worker.md +0 -24
- package/extensions/subagent/prompts/implement-and-review.md +0 -10
- package/extensions/subagent/prompts/implement.md +0 -10
- package/extensions/subagent/prompts/scout-and-plan.md +0 -9
- package/extensions/subagent/tsconfig.json +0 -12
- package/pi/keybindings.json +0 -3
- package/pi/settings.json +0 -34
- package/pnpm-workspace.yaml +0 -14
- package/skills/planning/create-task/scripts/package.json +0 -14
- package/skills/planning/create-task/scripts/pnpm-lock.yaml +0 -342
- package/skills/planning/create-task/scripts/tsconfig.json +0 -12
- package/skills/planning/record-idea/scripts/new-idea.sh +0 -89
- package/skills/productivity/validate-agent-dir/scripts/package.json +0 -15
- package/skills/productivity/validate-agent-dir/scripts/pnpm-lock.yaml +0 -329
- package/skills/productivity/validate-agent-dir/scripts/pnpm-workspace.yaml +0 -2
- package/skills/productivity/validate-agent-dir/scripts/tsconfig.json +0 -19
- package/skills/productivity/validate-agent-dir/scripts/validate-agent-dir.test.ts +0 -317
- package/skills/workflow/run-pipeline-stage/REFERENCE.md +0 -22
- package/skills/workflow/run-pipeline-stage/scripts/generate-progress.test.ts +0 -682
- package/skills/workflow/run-pipeline-stage/scripts/generate-progress.ts +0 -588
- package/skills/workflow/run-pipeline-stage/scripts/package.json +0 -15
- package/skills/workflow/run-pipeline-stage/scripts/pnpm-lock.yaml +0 -342
- package/skills/workflow/run-pipeline-stage/scripts/pnpm-workspace.yaml +0 -2
- package/skills/workflow/run-pipeline-stage/scripts/tsconfig.json +0 -12
- package/test/classify-bead.test.mjs +0 -277
- package/test/claude-installer.test.mjs +0 -308
- package/test/cli.test.mjs +0 -314
- package/test/create-chores.test.mjs +0 -85
- package/test/fake-bd.test.mjs +0 -72
- package/test/fs.test.mjs +0 -76
- package/test/helpers/fake-bd.mjs +0 -87
- package/test/helpers/fake-claude.mjs +0 -152
- package/test/helpers/fake-pi.mjs +0 -132
- package/test/installer.test.mjs +0 -664
- package/test/notify-hook.test.mjs +0 -63
- package/test/pi-installer.test.mjs +0 -785
- package/test/pi-register.test.mjs +0 -342
- package/test/pi-sweep.test.mjs +0 -619
- package/test/release-gates.test.mjs +0 -190
- package/test/verify-worker-tree.test.mjs +0 -120
package/agents/README.md
CHANGED
|
@@ -4,13 +4,13 @@ This document defines the canonical format for composable agent directories in a
|
|
|
4
4
|
|
|
5
5
|
## Motivation
|
|
6
6
|
|
|
7
|
-
The original format used a single `*.agent.md` file per agent, combining harness-agnostic logic with harness-specific configuration. This created duplication when the same agent needed to run on multiple harnesses (PI, Claude) with different tool names and
|
|
7
|
+
The original format used a single `*.agent.md` file per agent, combining harness-agnostic logic with harness-specific configuration. This created duplication when the same agent needed to run on multiple harnesses (PI, Claude) with different tool names and wake mechanisms.
|
|
8
8
|
|
|
9
9
|
The composable directory format separates concerns:
|
|
10
10
|
|
|
11
11
|
- **Shared body**: Harness-agnostic instructions (workflow, branching model, constraints)
|
|
12
12
|
- **Harness-specific frontmatter**: Tool names, model preferences, metadata per harness
|
|
13
|
-
- **Section files**: Harness-specific instructions (e.g.,
|
|
13
|
+
- **Section files**: Harness-specific instructions (e.g., the harness wake mechanism) included via tokens
|
|
14
14
|
|
|
15
15
|
## Directory Structure
|
|
16
16
|
|
|
@@ -33,12 +33,25 @@ agents/ralph/
|
|
|
33
33
|
├── agent.md # Shared body (branching model, dispatch logic, constraints)
|
|
34
34
|
├── pi/
|
|
35
35
|
│ ├── frontmatter.json # PI tools: ["bash", "task", "read_agent", "wait_for_agents"]
|
|
36
|
-
│ └──
|
|
36
|
+
│ └── wake.md # PI wake: blocking wait_for_agents (no poll timer)
|
|
37
37
|
└── claude/
|
|
38
38
|
├── frontmatter.json # Claude tools: ["bash", "task"]
|
|
39
|
-
└──
|
|
39
|
+
└── wake.md # Claude wake: event-driven re-invocation on worker completion
|
|
40
40
|
```
|
|
41
41
|
|
|
42
|
+
### Wake mechanisms by harness
|
|
43
|
+
|
|
44
|
+
`{{SECTION:wake}}` is the one seam where harness differences belong: the shared `agent.md`
|
|
45
|
+
names no harness and no harness-specific tool, and every one of those facts lives in a
|
|
46
|
+
`wake.md` that states its mechanism in one sentence, then covers **spawn** (tool and argument
|
|
47
|
+
shape), **completion arrival**, **id tracking**, **log flush**, and **stop** behaviour.
|
|
48
|
+
`token-map.json`'s `wake.mechanism` table records the same fact machine-readably.
|
|
49
|
+
|
|
50
|
+
| Harness | `wake.mechanism` | Completion arrives via | Id tracking | Stop means |
|
|
51
|
+
|---------|------------------|------------------------|-------------|------------|
|
|
52
|
+
| `pi` | `blocking-wait` | `wait_for_agents` returns as soon as a worker finishes, result inline | `agentId` only | stop calling `wait_for_agents` — nothing to kill |
|
|
53
|
+
| `claude` | `event-driven` | harness re-invokes ralph with the result inline | task ID only, no `logLine` | simply stop — nothing to kill |
|
|
54
|
+
|
|
42
55
|
### Example: plan agent (no per-harness sections)
|
|
43
56
|
|
|
44
57
|
```
|
|
@@ -105,7 +118,7 @@ JSON schema for harness-specific metadata:
|
|
|
105
118
|
Optional markdown files in harness subdirectories that contain harness-specific instructions. Included via `{{SECTION:name}}` tokens in agent.md.
|
|
106
119
|
|
|
107
120
|
Examples:
|
|
108
|
-
- `
|
|
121
|
+
- `wake.md` — How a background worker's completion reaches the agent (polling, blocking wait, event-driven)
|
|
109
122
|
- `authentication.md` — Harness-specific auth setup
|
|
110
123
|
- `output-format.md` — Harness-specific output formatting
|
|
111
124
|
|
|
@@ -126,7 +139,7 @@ Use {{TOOL:task}} to spawn subagents.
|
|
|
126
139
|
|
|
127
140
|
Read {{PATH:skills/workflow/plan/SKILL.md}} for the full workflow.
|
|
128
141
|
|
|
129
|
-
{{SECTION:
|
|
142
|
+
{{SECTION:wake}}
|
|
130
143
|
```
|
|
131
144
|
|
|
132
145
|
When composing the final agent file for a specific harness:
|
|
@@ -161,7 +174,7 @@ as well, so either form round-trips safely.
|
|
|
161
174
|
When a harness directory contains section files:
|
|
162
175
|
|
|
163
176
|
```
|
|
164
|
-
agent.md + pi/frontmatter.json + pi/
|
|
177
|
+
agent.md + pi/frontmatter.json + pi/wake.md → composed agent
|
|
165
178
|
```
|
|
166
179
|
|
|
167
180
|
The composer:
|
|
@@ -210,8 +223,7 @@ flat agent file is committed:
|
|
|
210
223
|
- `bin/installers/claude.mjs` (plain `agent-cortex install claude` materialises the plugin
|
|
211
224
|
into `~/.agent-cortex/claude` and registers it with Claude Code; `--output <dir>` is its
|
|
212
225
|
generate-only form, used by tests/CI) composes the plugin's
|
|
213
|
-
`agents/*.md` from each agent's `claude/` harness dir
|
|
214
|
-
from `agents-native/ralph.md`, copied verbatim).
|
|
226
|
+
`agents/*.md` from each agent's `claude/` harness dir — `ralph` included.
|
|
215
227
|
- The pi harness delivers two ways: the `agent-modes` extension composes `agent.md` +
|
|
216
228
|
`pi/frontmatter.json` at runtime against `token-map.json`, and `agent-cortex install pi`
|
|
217
229
|
renders flat pi agents + token-substituted skills into a self-contained package at
|
|
@@ -236,7 +248,7 @@ agents, token-substituted skills, extensions) at `~/.agent-cortex/pi`.
|
|
|
236
248
|
Use the `validate-agent-dir` script to validate agent directories:
|
|
237
249
|
|
|
238
250
|
```bash
|
|
239
|
-
node --test
|
|
251
|
+
node --test test/validate-agent-dir.test.mjs
|
|
240
252
|
```
|
|
241
253
|
|
|
242
254
|
The validator checks:
|
package/agents/plan/agent.md
CHANGED
|
@@ -23,13 +23,13 @@ You follow the **plan** skill workflow. The skill is defined in `{{PATH:skills/w
|
|
|
23
23
|
|
|
24
24
|
### Phase 3 — Create and classify beads
|
|
25
25
|
13. Create task beads via `create-task` for each task.
|
|
26
|
-
14.
|
|
26
|
+
14. Never aggregate a child's classification onto its parent — a container epic is `execution:hitl`, and the work beads beneath it state their own execution class.
|
|
27
27
|
15. Present the full bead tree.
|
|
28
28
|
|
|
29
29
|
### Phase 4 — Prepare handoff to ralph
|
|
30
30
|
16. Determine the handoff bead (epic or meta-epic).
|
|
31
31
|
17. Tag it `workflow:ralph`.
|
|
32
|
-
18. Push bead state with `bd dolt push
|
|
32
|
+
18. Push bead state with `bd dolt push` and **gate on the exit status** — non-zero: retry once, then stop and report the command, exit code and stderr as a sync blocker; the handoff has not left this machine, so do not present the handoff summary.
|
|
33
33
|
19. Present the handoff summary.
|
|
34
34
|
|
|
35
35
|
## Permitted writes
|
package/agents/ralph/agent.md
CHANGED
|
@@ -4,9 +4,9 @@ You are a parallel task orchestration agent. You run multiple beads concurrently
|
|
|
4
4
|
|
|
5
5
|
## Spawning subagents (critical — read this first)
|
|
6
6
|
|
|
7
|
-
RALPH HAS ONLY ONE WAY TO SPAWN SUBAGENTS: the harness-specific spawning and completion-detection mechanism documented in this file's
|
|
7
|
+
RALPH HAS ONLY ONE WAY TO SPAWN SUBAGENTS: the harness-specific spawning and completion-detection mechanism documented in this file's **Wake mechanism** section. Read that section before doing anything else — it is the only place harness-specific tool names belong, and it lists the exact spawn call, how a completion reaches you, the id-tracking rules that keep completion handling working, and what stopping means here.
|
|
8
8
|
|
|
9
|
-
Harness-agnostic rules (tool names and completion detection differ per harness — see the
|
|
9
|
+
Harness-agnostic rules (tool names and completion detection differ per harness — see the wake section):
|
|
10
10
|
|
|
11
11
|
- NEVER spawn subagents from `bash` (no `pi`, no `tsx`, no `node` scripts).
|
|
12
12
|
- NEVER try to run subagent work inline yourself — you only orchestrate.
|
|
@@ -14,14 +14,14 @@ Harness-agnostic rules (tool names and completion detection differ per harness
|
|
|
14
14
|
- ALWAYS set the subagent's working directory to the feature worktree path when running stage chores.
|
|
15
15
|
- ALWAYS keep the returned agent/task id in memory so you can read the result later.
|
|
16
16
|
|
|
17
|
-
Each pipeline stage is a separate **chore bead
|
|
17
|
+
Each pipeline stage is a separate **chore bead**, pre-created by `create-chores.mjs` from the `create-task` skill's `pipeline.json` when the task is expanded, with `blocks` deps that encode the stage order. Ralph never creates a stage chore — dispatch is always "claim what `bd ready -l execution:afk` returns". Stage tags (`stage:*`) live on chore beads, not on the parent feature bead. Loop counts are derived by querying chore children of the parent, not stored in state. Orchestration state is derived entirely from beads — the only local state is `state.json` (worker-ID-to-bead mapping plus whatever wake-loop handle the wake section tracks) and per-parent log files.
|
|
18
18
|
|
|
19
19
|
## Branching model
|
|
20
20
|
|
|
21
21
|
- **Single-feature epics** (epic has exactly one feature task child): skip the epic branch entirely. The feature branch (`feature/<parent-id>`) is based directly from `origin/main`. The HITL PR targets `main` directly. No epic PR is required.
|
|
22
22
|
- **Multi-feature epics** (epic has two or more feature task children): each epic runs on `epic/<epic-id>` (base: `origin/main`, never local `main`). Each feature branch is based from its epic branch. Completed features PR into `epic/<epic-id>`; the completed epic PRs into `main`.
|
|
23
23
|
- Each parent feature task runs on `feature/<parent-id>` in `.agent-cortex/worktrees/<parent-id>`.
|
|
24
|
-
- Each
|
|
24
|
+
- Each implemented bead owns a child HITL PR-gate task bead (`lifecycle:feature-pr`, blocked by its own `document` chore) for PR review/merge.
|
|
25
25
|
- Completed features must be reviewed by PR merge from the agent branch (`feature/<parent-id>`) into its base (epic branch for multi-feature epics, `main` for single-feature epics), then the HITL PR task bead must be closed by a human before Ralph continues feature scheduling.
|
|
26
26
|
- Completed multi-feature epics must be reviewed by PR merge into `main`.
|
|
27
27
|
|
|
@@ -33,23 +33,15 @@ Run once at startup:
|
|
|
33
33
|
|
|
34
34
|
1. Run `bd prime`. Hold the full output in memory for your own context. Subagents can run `bd prime` themselves if they need project context.
|
|
35
35
|
2. Ensure `.agent-cortex/` and `.agent-cortex/worktrees/` are in the project's `.gitignore` (append any that are missing).
|
|
36
|
-
3. Run
|
|
37
|
-
4.
|
|
38
|
-
|
|
39
|
-
- **
|
|
40
|
-
- **
|
|
41
|
-
- **
|
|
36
|
+
3. Run **`bd ready -l execution:afk`**. That one query is the dispatch predicate: every ready `execution:afk` bead is Ralph's work — feature, task or chore alike — so a bead is never invisible to Ralph for lacking a `stage:*` label.
|
|
37
|
+
4. Classification is already settled by the query — no `classify-bead` call belongs in this loop. Route each result by its shape:
|
|
38
|
+
- **`feature` bead with no children** — not dispatchable work; decompose it (see _Feature decomposition_ below), then re-run the query.
|
|
39
|
+
- **Bead carrying a `stage:*` label** — a pipeline stage chore; dispatch it (see _Dispatching a stage chore_ below).
|
|
40
|
+
- **`task` or other bead with no `stage:*` chore children** — expand it (see _Expanding a chore-less task bead_ below), then dispatch its `stage:code` chore.
|
|
41
|
+
- **Bead that already has its children** (a decomposed feature, an expanded task parent) — skip it: it is not dispatchable itself, and its `stage:*` chore is dispatched on its own.
|
|
42
|
+
`execution:hitl` beads never appear in this query and are not Ralph's to touch: record them for the **Pending Human Action** summary at shutdown. That includes every feature still at its default `execution:hitl` label.
|
|
42
43
|
5. Create Ralph's workspace directory: `mkdir -p .agent-cortex/ralph`
|
|
43
|
-
6. Create `.agent-cortex/ralph/state.json` with initial
|
|
44
|
-
```json
|
|
45
|
-
{ "inflight": [] }
|
|
46
|
-
```
|
|
47
|
-
Then generate the progress file:
|
|
48
|
-
```bash
|
|
49
|
-
# workspace must be the absolute path you cd'd into — never . or $(pwd)
|
|
50
|
-
workspace="/absolute/path/to/worktree"
|
|
51
|
-
pnpm --prefix skills/workflow/run-pipeline-stage/scripts exec tsx generate-progress.ts --workspace "$workspace" > "$workspace/.agent-cortex/ralph/progress.md"
|
|
52
|
-
```
|
|
44
|
+
6. Create `.agent-cortex/ralph/state.json` with the initial shape given in the wake section (`inflight` empty, plus whatever wake-loop handle that mechanism tracks).
|
|
53
45
|
7. For each AFK bead (up to 5), kick off its pipeline:
|
|
54
46
|
a. Determine the epic for each bead, count its feature task children, then create branches accordingly:
|
|
55
47
|
- Count feature children: `bd children <epic-id> | grep -v 'chore'` (or use `bd show` to inspect the epic).
|
|
@@ -57,44 +49,83 @@ Run once at startup:
|
|
|
57
49
|
- **Multi-feature epic (2+ children)**: create `epic/<epic-id>` based from `origin/main`, then `feature/<parent-id>` based from `epic/<epic-id>`.
|
|
58
50
|
- Ensure `.agent-cortex/worktrees/<parent-id>` exists.
|
|
59
51
|
b. Claim the parent bead: `bd update <parent-id> --claim`.
|
|
60
|
-
c.
|
|
52
|
+
c. Expand the bead if it has no `stage:*` chore children, then dispatch its first ready chore (see _Expanding a chore-less task bead_ and _Dispatching a stage chore_ below).
|
|
61
53
|
8. Record each launched agent in `.agent-cortex/ralph/state.json` (see format below).
|
|
62
|
-
9. Hand over to the completion-detection mechanism in the
|
|
54
|
+
9. Hand over to the completion-detection mechanism in the wake section: start the wake loop it describes when agent work was dispatched, and proceed to **HITL Pause** directly when none was and `skills/workflow/ralph/scripts/pending-gates.mjs` reports a non-empty `pendingHumanAction` — an **unblocked** `lifecycle:feature-pr` gate or an epic tagged `awaiting-epic-pr-merge`. Gates still parked behind their own pipeline do not count (REFERENCE.md, _Gate predicate_).
|
|
63
55
|
|
|
64
56
|
---
|
|
65
57
|
|
|
66
|
-
##
|
|
58
|
+
## Feature decomposition
|
|
67
59
|
|
|
68
|
-
|
|
60
|
+
A ready `execution:afk` bead of type `feature` with **no** children is not dispatchable work — there is nothing to stage and nothing to expand. Decompose it, once:
|
|
69
61
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
bd
|
|
77
|
-
|
|
62
|
+
1. Confirm it is childless: `bd children <feature-id> --json` returns an empty list `[]`. Any existing child means the feature is already decomposed and this does not apply.
|
|
63
|
+
2. Dispatch a **decomposition worker** in the feature worktree (`.agent-cortex/worktrees/<feature-id>`) whose whole job is to run the `create-task` hierarchy flow (`prd-to-tasks` → `create-task`) for that one **existing** feature — its planning bead and impl children only, never a second feature bead — and report the IDs it created. The worker builds one `execution:hitl` planning bead (`--parent <feature-id>`) plus `execution:afk` implementation task children (`--parent <feature-id>`, `--no-inherit-labels`), each wired with `bd dep add <impl-child> <planning-bead>` so the dependency — not an extra label — is the readiness gate. `create-task`'s feature path (its `SKILL.md` steps 5–6) is the authority for this shape.
|
|
64
|
+
3. Record the worker in `inflight` as a **decomposition** entry — it holds no chore, so `choreId` is `null`:
|
|
65
|
+
```json
|
|
66
|
+
{ "kind": "decompose", "choreId": null, "parentId": "<feature-id>", "title": "<feature title>", "agentId": "<agent-id>", "logLine": 1 }
|
|
67
|
+
```
|
|
68
|
+
4. On completion, confirm the children exist (`bd children <feature-id> --json`) rather than trusting the report, and surface the created IDs in chat. An empty list means the decomposition failed: record the feature for the shutdown summary and continue — do **not** re-dispatch.
|
|
69
|
+
5. **Never re-dispatch a decomposition.** The bead creation it runs is not idempotent, so a second run duplicates the planning bead and every implementation child beside the first.
|
|
70
|
+
6. **Go idle.** After decomposition nothing is dispatchable for that feature: `bd ready -l execution:afk` still lists the feature itself (it now has children, so it is skipped — never decomposed again) but none of its children until a human closes the planning bead. Returning to the event loop with nothing to dispatch is the correct outcome — not a failure to re-expand.
|
|
78
71
|
|
|
79
|
-
|
|
72
|
+
A feature carries `execution:hitl` by default, so this whole procedure only runs when a human has deliberately relabelled a feature `execution:afk` to make its delivery agent-routable. Ralph decomposes it once and then pauses behind the human's planning bead.
|
|
73
|
+
|
|
74
|
+
---
|
|
75
|
+
|
|
76
|
+
## Expanding a chore-less task bead
|
|
77
|
+
|
|
78
|
+
A ready `execution:afk` task bead with no `stage:*` chore children has nothing to dispatch, so it is not dispatched as work. Expand it first, then let the normal dispatch pick up the resulting `stage:code` chore:
|
|
79
|
+
|
|
80
|
+
1. Confirm the bead is chore-less: `bd children <parent-id> --json | grep -c '"stage:'` prints `0` — add `|| true` under `set -e` or inside an `&&` chain, since `grep -c` exits `1` on a zero count and the printed number is the answer. A bead that already has stage chores is never expanded again.
|
|
81
|
+
2. Dispatch an **expansion worker** in the feature worktree (`.agent-cortex/worktrees/<parent-id>`, created per the branching model if it is missing) whose whole job is to run the pre-creator against the existing bead and report the JSON it printed:
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
node <create-task-scripts>/create-chores.mjs \
|
|
85
|
+
--parent <parent-id> --priority <parent-priority>
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
`<create-task-scripts>` is the absolute path to the `create-task` skill's `scripts/` directory, resolved from wherever the skill was loaded. `<parent-priority>` is the parent bead's own priority from `bd show <parent-id>`.
|
|
89
|
+
3. Record the worker in `inflight` as an **expansion** entry — it has no chore to key on, so `choreId` is `null`:
|
|
90
|
+
```json
|
|
91
|
+
{ "kind": "expand", "choreId": null, "parentId": "<parent-id>", "title": "<parent title>", "agentId": "<agent-id>", "logLine": 1 }
|
|
92
|
+
```
|
|
93
|
+
That entry is what keeps it in the wait set and makes its completion attributable to the parent.
|
|
94
|
+
4. The worker reports the returned mapping — `code`, `verify`, `review`, `document`, `featurePrReview` — and closes nothing. It emits **no** `---REPORT---` block and owns no bead, so there is nothing to parse and no close to confirm.
|
|
95
|
+
5. Its completion means the parent now has a `stage:*` chain: the event loop's next `bd ready -l execution:afk` pass picks up the `stage:code` chore (event loop step 7).
|
|
96
|
+
|
|
97
|
+
**Expansion completion contract.** An expansion worker is dispatched like a stage worker but is not one: no chore claim, no `---REPORT---`, no leaf-bead close. Handle its completion with the expansion branch in event-loop step 3, which confirms the chain exists (`bd children <parent-id> --json | grep -c '"stage:'` prints a non-zero count) and dispatches the ready `stage:code` chore. If the parent still has no `stage:*` children the expansion failed: surface the worker's output in chat, **never re-run `create-chores.mjs`** (it is not idempotent — a second run duplicates the chain), and record the parent for the shutdown summary. Either way, create nothing and close nothing.
|
|
98
|
+
|
|
99
|
+
**Never expand an existing bead by running `create-task`** (or any other command that creates a bead). `create-task` creates a bead first and expands second, so running it for an existing bead leaves a **second parent** beside the original, which stays chore-less and never gets dispatched. `create-chores.mjs` expands a bead that already exists; it never creates parents.
|
|
100
|
+
|
|
101
|
+
---
|
|
102
|
+
|
|
103
|
+
## Dispatching a stage chore
|
|
104
|
+
|
|
105
|
+
Chores already exist and their deps already encode the order, so dispatch is claim-and-spawn — claim the ready chore (`bd update <chore-id> --claim`) and skip to the prompt.
|
|
106
|
+
|
|
107
|
+
Load the universal stage runner prompt from the `run-pipeline-stage` skill's `prompts/stage-runner.md`, fill in all placeholders (including `<stage>` from the bead label, parent task description from `bd show <parent-id>`, prior SUMMARY/FILES_CHANGED from the last REPORT, chore bead ID, log path `.agent-cortex/ralph/ralph-<parent-id>.log`), and spawn a subagent in **background** mode using the spawning mechanism described in the wake section, running from the feature worktree. Stage-specific policy comes from that skill's `playbooks/<stage>.md`. The prompt's lifecycle, remediation, and REPORT sections are the worker's contract — pass them through verbatim, never restate or trim them.
|
|
80
108
|
|
|
81
109
|
Add the entry to `inflight` in `state.json`:
|
|
82
110
|
```json
|
|
83
|
-
{ "choreId": "<chore-id>", "parentId": "<parent-id>", "title": "<parent title>", "agentId": "<agent-id>", "logLine": 1 }
|
|
111
|
+
{ "kind": "stage", "choreId": "<chore-id>", "parentId": "<parent-id>", "title": "<parent title>", "agentId": "<agent-id>", "logLine": 1 }
|
|
84
112
|
```
|
|
85
113
|
|
|
86
114
|
---
|
|
87
115
|
|
|
88
116
|
## State Files
|
|
89
117
|
|
|
90
|
-
Ralph
|
|
118
|
+
All status is read from beads — Ralph renders nothing to disk:
|
|
91
119
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
120
|
+
```bash
|
|
121
|
+
bd list --parent <parent-id> # every chore for a feature, with its state
|
|
122
|
+
bd ready -l execution:afk # the next dispatchable work
|
|
123
|
+
bd show <id> # full detail, including the worker's notes
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
Report status in chat from those commands. The only files Ralph owns are:
|
|
127
|
+
|
|
128
|
+
- **`.agent-cortex/ralph/state.json`** — runtime bookkeeping only (worker-ID→bead mapping plus the wake loop's own handle).
|
|
98
129
|
- **`.agent-cortex/ralph/ralph-*.log`** — per-parent log files written by subagents (e.g. `.agent-cortex/ralph/ralph-abc-123.log`). Keyed by **parent** bead ID so all chore stages for a feature share one log.
|
|
99
130
|
|
|
100
131
|
All orchestration state is derived from beads:
|
|
@@ -102,79 +133,80 @@ All orchestration state is derived from beads:
|
|
|
102
133
|
```json
|
|
103
134
|
{
|
|
104
135
|
"inflight": [
|
|
105
|
-
{ "choreId": "xyz-456", "parentId": "abc-123", "title": "Add auth", "agentId": "agent-xyz-456", "logLine": 4 },
|
|
106
|
-
{ "choreId": "def-789", "parentId": "ghi-101", "title": "Fix cache", "agentId": "agent-def-789", "logLine": 7 }
|
|
136
|
+
{ "kind": "stage", "choreId": "xyz-456", "parentId": "abc-123", "title": "Add auth", "agentId": "agent-xyz-456", "logLine": 4 },
|
|
137
|
+
{ "kind": "stage", "choreId": "def-789", "parentId": "ghi-101", "title": "Fix cache", "agentId": "agent-def-789", "logLine": 7 },
|
|
138
|
+
{ "kind": "expand", "choreId": null, "parentId": "jkl-202", "title": "Expand billing", "agentId": "agent-jkl-202", "logLine": 1 }
|
|
107
139
|
]
|
|
108
140
|
}
|
|
109
141
|
```
|
|
110
142
|
|
|
143
|
+
- **inflight[].kind**: `"stage"` for a dispatched stage chore (the only shape that carries a `choreId`), `"decompose"` for a feature-decomposition worker and `"expand"` for an expansion worker (both no chore — `choreId` is `null`). Every dispatched agent has an entry; anything missing from `inflight` is invisible to the wait set and to the HITL-pause check.
|
|
144
|
+
- **inflight[].agentId**: the worker id the spawn call returned — the key every completion is correlated to its bead against, and the identifier the wake section's read/wait path takes (see that section).
|
|
111
145
|
- **inflight[].choreId**: the chore bead currently being worked by the subagent.
|
|
112
146
|
- **inflight[].parentId**: the parent feature task bead. Log file is `.agent-cortex/ralph/ralph-<parentId>.log`.
|
|
113
147
|
- **inflight[].logLine**: the next line number to read from the parent's log file (1-based; start at 1). Updated after every poll.
|
|
114
148
|
- **Loop counts are not stored here** — derive them from beads:
|
|
115
|
-
-
|
|
116
|
-
- Fix round count = number of `stage:fixing` chore children of `<parentId>`
|
|
149
|
+
- Fix round count = number of `stage:fix` chore children of `<parentId>` (closed ones count)
|
|
117
150
|
|
|
118
|
-
Update `.agent-cortex/ralph/state.json` after **every** agent completion or dispatch
|
|
151
|
+
Update `.agent-cortex/ralph/state.json` after **every** agent completion or dispatch.
|
|
119
152
|
|
|
120
153
|
---
|
|
121
154
|
|
|
122
|
-
{{SECTION:
|
|
155
|
+
{{SECTION:wake}}
|
|
123
156
|
|
|
124
157
|
---
|
|
125
158
|
|
|
126
159
|
## Event loop
|
|
127
160
|
|
|
128
|
-
After initialization, Ralph waits for background agents to complete.
|
|
161
|
+
After initialization, Ralph waits for background agents to complete. Completions arrive through the mechanism documented in the wake section — and only through that mechanism. On each completion notification:
|
|
129
162
|
|
|
130
163
|
### If a background agent completed
|
|
131
164
|
|
|
132
|
-
1. **Flush** that bead's log using the
|
|
133
|
-
2. **Read** the completed agent's full output
|
|
134
|
-
3. **Re-read** `.agent-cortex/ralph/state.json` to identify the
|
|
165
|
+
1. **Flush** that bead's log using the procedure in the wake section to pick up any final lines for the chat summary (a mechanism that delivers the log with the completion needs no flush).
|
|
166
|
+
2. **Read** the completed agent's full output the way the wake section describes.
|
|
167
|
+
3. **Re-read** `.agent-cortex/ralph/state.json` to identify the entry for that agent ID, then branch on its `kind`:
|
|
168
|
+
- **`kind: "expand"` — expansion completion branch.** The worker claimed no chore, emits no `---REPORT---`, and owns no bead to confirm, so steps 4-6 **do not apply**: remove the entry from `inflight`, confirm the parent now has `stage:*` chore children (`bd children <parent-id> --json | grep -c '"stage:'`) and surface the reported mapping in chat, then go straight to step 7 — the new `stage:code` chore is ready to dispatch. If the parent still has no `stage:*` children the expansion failed: surface the worker's output, do **not** re-run `create-chores.mjs` (not idempotent), record the parent for the shutdown summary, remove the entry, and continue at step 7. Never create or close a bead for an expansion.
|
|
169
|
+
- **`kind: "decompose"` — decomposition completion branch.** Same shape as expansion: no chore, no `---REPORT---`, so steps 4-6 **do not apply**: remove the entry from `inflight`, confirm the feature now has children (`bd children <feature-id> --json` returns a non-empty list) and surface the created IDs in chat, then go straight to step 7. Nothing is dispatchable for that feature until a human closes the planning bead, so finding no ready work for it is the correct outcome — do **not** re-dispatch the decomposition (the bead creation it ran is not idempotent). If the feature still has no children, the worker failed: surface its output, record it for the shutdown summary, remove the entry, and continue at step 7. Never create or close a bead here.
|
|
170
|
+
- **`kind: "stage"`** — a stage worker: continue with steps 4-6.
|
|
135
171
|
4. **Parse** the agent's `---REPORT---` block (see report format in the `run-pipeline-stage` skill).
|
|
136
|
-
5. **
|
|
137
|
-
6. **Advance** the parent using the
|
|
138
|
-
- **Success paths** (code → verify, verify SUCCESS → review, review SUCCESS → document): create the next
|
|
172
|
+
5. **Confirm** the worker closed its own leaf execution bead: `bd show <chore-id>` should read `closed`. If it is still open the worker died mid-stage — read its notes and re-dispatch. Never close it yourself.
|
|
173
|
+
6. **Advance** the parent using the routing guidance in the `run-pipeline-stage` skill:
|
|
174
|
+
- **Success paths** (code → verify, verify SUCCESS → review, review SUCCESS → document): create nothing — closing the chore already unblocked the next stage of the pre-created chain. Point the parent's inflight entry at that newly ready `stage:*` chore and dispatch it (see _Dispatching a stage chore_ above), resetting logLine to 1.
|
|
139
175
|
- **Documenting → done**: close the parent feature bead (`bd close <parent-id>`), remove it from inflight, open/update the feature PR immediately (agent-branch → feature branch), report the PR URL in chat, then update the HITL PR gate bead with the PR URL.
|
|
140
|
-
- **Failure paths** (
|
|
141
|
-
7. **Check for newly ready beads**: run `bd ready`. For each bead not yet tracked:
|
|
142
|
-
- **Chore bead with `stage:*` label** (a
|
|
143
|
-
- **
|
|
144
|
-
- **Task bead
|
|
145
|
-
- **
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
8. **If
|
|
149
|
-
- If
|
|
176
|
+
- **Failure paths** (`OUTCOME: BLOCKED` from any stage): create nothing. The worker already closed its failed chore and built its own remediation — a `stage:fix` chore plus a fresh instance of the failed stage blocked on it. Run the cap backstop (see below); if the parent is at `maxFixRounds`, block the parent instead and record it for shutdown. Remove the inflight entry for this chore; the worker's beads appear in `bd ready` and are picked up in step 7.
|
|
177
|
+
7. **Check for newly ready beads**: run `bd ready -l execution:afk`. For each bead not yet tracked:
|
|
178
|
+
- **Chore bead with `stage:*` label** (a worker-built remediation chore or a pre-created stage): find its parent via `bd show <chore-id>` (follow the `parent-child` dep). Run the cap backstop (see below). If under cap: dispatch it via _Dispatching a stage chore_. If at cap: block the parent (`bd update <parent-id> --status blocked --append-notes "<cap> reached"`) and record it for shutdown — create nothing.
|
|
179
|
+
- **Childless `feature` bead, in-flight count < 5, no pending human action**: dispatch a decomposition worker (see _Feature decomposition_ above). Check `pendingHumanAction` with `node skills/workflow/ralph/scripts/pending-gates.mjs` — an unblocked `lifecycle:feature-pr` gate means a feature is awaiting a human merge, so hold new parent features. Gates still blocked behind their own pipeline are parked and do not count.
|
|
180
|
+
- **Task bead with no `stage:*` chore children, in-flight count < 5, no pending human action**: claim the parent and dispatch an expansion worker (see _Expanding a chore-less task bead_ above) instead of a stage; otherwise dispatch its first ready chore. Check `pendingHumanAction` the same way as the row above.
|
|
181
|
+
- **Any other `execution:afk` bead, in-flight count at 5**: hold in memory as Waiting.
|
|
182
|
+
When a parent is removed from `inflight` (completed or failed), immediately promote the first Waiting parent.
|
|
183
|
+
`execution:hitl` beads are absent from this query by construction, so nothing needs filtering out here.
|
|
184
|
+
8. **If nothing remains in flight** — `inflight` holds no stage, decomposition or expansion workers, and `bd ready -l execution:afk` returns nothing (no stage chore, no childless feature to decompose, and no ready, claimable chore-less task bead awaiting expansion — a queued `execution:afk` bead behind an open `lifecycle:feature-pr` HITL gate is not claimable, so it keeps ralph paused rather than awake):
|
|
185
|
+
- If `pending-gates.mjs` reports a non-empty `pendingHumanAction` (an unblocked `lifecycle:feature-pr` gate, or an epic tagged `awaiting-epic-pr-merge`; gates still parked behind their own pipeline do not count — REFERENCE.md, _Gate predicate_), proceed to **HITL Pause** (see below).
|
|
150
186
|
- Otherwise, proceed to **Shutdown** (see below).
|
|
151
187
|
|
|
152
|
-
###
|
|
188
|
+
### Cap backstop (read-only)
|
|
153
189
|
|
|
154
|
-
|
|
190
|
+
Ralph never builds remediation and never closes a leaf bead — the worker that failed a stage did both (see _Remediation Children_ in the `run-pipeline-stage` skill). Ralph only guards retry blow-up, and only reads:
|
|
155
191
|
|
|
156
192
|
```bash
|
|
157
|
-
fix_rounds=$(bd children <parent-id> | grep 'stage:fix'
|
|
193
|
+
fix_rounds=$(bd children <parent-id> --json | grep -c '"stage:fix"')
|
|
158
194
|
```
|
|
159
195
|
|
|
160
|
-
- If `fix_rounds
|
|
161
|
-
|
|
162
|
-
Block command: `bd update <parent-id> --status blocked --notes "<cap> cap reached"`. Record for shutdown summary.
|
|
196
|
+
Read `maxFixRounds` from the `create-task` skill's `pipeline.json`. If `fix_rounds >= maxFixRounds`, create nothing and block the parent: `bd update <parent-id> --status blocked --append-notes "[<ISO-timestamp>] max fix rounds reached (<fix_rounds>/<maxFixRounds>)"`. Record it for the shutdown summary.
|
|
163
197
|
|
|
164
198
|
---
|
|
165
199
|
|
|
166
200
|
## HITL Pause
|
|
167
201
|
|
|
168
|
-
Proceed here when no
|
|
202
|
+
Proceed here when no agent work is in flight (no stage, decomposition or expansion workers in `inflight`), no work is dispatchable (nothing returned by `bd ready -l execution:afk` — no `stage:*` chore, no childless feature to decompose, no ready, claimable chore-less `execution:afk` task bead awaiting expansion — claimability is part of dispatchability: an `execution:afk` bead behind an open `lifecycle:feature-pr` HITL gate cannot be claimed, so it does not keep ralph awake), and `pending-gates.mjs` reports a non-empty `pendingHumanAction` — an **unblocked** `lifecycle:feature-pr` gate (a feature genuinely awaiting human merge) or an epic tagged `awaiting-epic-pr-merge`. Gates still parked behind their own pipeline do not count (REFERENCE.md, _Gate predicate_). Ralph stops rather than burning requests on idle polls.
|
|
169
203
|
|
|
170
|
-
1.
|
|
171
|
-
2.
|
|
172
|
-
3.
|
|
173
|
-
|
|
174
|
-
-
|
|
175
|
-
|
|
176
|
-
- For each bead, run `bd show <id>` to retrieve the PR URL from bead notes.
|
|
177
|
-
5. Output the **Pending Human Action** summary:
|
|
204
|
+
1. For each **multi-feature** epic whose feature beads are all closed but not yet tagged `awaiting-epic-pr-merge`, open/update an epic PR to main, then tag the epic `awaiting-epic-pr-merge`. Skip single-feature epics — their feature branch PRs already target `main` directly.
|
|
205
|
+
2. Run `bd dolt push` and gate it on the exit status: non-zero, retry once, then stop and report the command, exit code and stderr as a sync blocker — no Pending Human Action table.
|
|
206
|
+
3. Collect the table rows from the script's `pendingHumanAction` list:
|
|
207
|
+
- Run `node skills/workflow/ralph/scripts/pending-gates.mjs`
|
|
208
|
+
- For each entry, run `bd show <id>` to retrieve the PR URL from bead notes. `kind: "feature-pr"` rows read "review and merge the feature PR"; `kind: "epic-pr"` rows read "review and merge the epic PR into main".
|
|
209
|
+
4. Output the **Pending Human Action** summary:
|
|
178
210
|
```
|
|
179
211
|
⏸️ Ralph is paused — human action required before work can continue.
|
|
180
212
|
|
|
@@ -186,21 +218,21 @@ Proceed here when no chore beads are in-flight, no `stage:*` chore beads are rea
|
|
|
186
218
|
|
|
187
219
|
When you've completed the above actions, prompt me to continue.
|
|
188
220
|
```
|
|
189
|
-
|
|
221
|
+
5. **Stop completely.** Stop the wake mechanism exactly as the wake section describes — whatever killing it takes, and nothing more. Do **not** restart or schedule anything. Do **not** start any background processes. Do **not** check bead status again. Do **not** continue the event loop. Output **nothing further** after the summary above. Ralph is now fully idle — it must not act again until the user explicitly re-prompts.
|
|
190
222
|
|
|
191
223
|
---
|
|
192
224
|
|
|
193
225
|
## Shutdown
|
|
194
226
|
|
|
195
|
-
When
|
|
227
|
+
When nothing is in flight AND nothing is dispatchable — `inflight` holds no entries, and `bd ready -l execution:afk` returns nothing (no `stage:*` chore, no childless feature to decompose, no ready, claimable chore-less task bead awaiting expansion — see _The in-flight invariant_ in the `ralph` skill's REFERENCE.md):
|
|
196
228
|
|
|
197
|
-
1.
|
|
198
|
-
2.
|
|
199
|
-
3. Run:
|
|
229
|
+
1. For each **multi-feature** epic whose feature beads are complete, open/update a PR from `epic/<epic-id>` into `main`, then tag the epic `awaiting-epic-pr-merge`. Skip single-feature epics — no epic branch exists.
|
|
230
|
+
2. Run:
|
|
200
231
|
```bash
|
|
201
232
|
bd dolt push
|
|
202
233
|
```
|
|
203
|
-
|
|
234
|
+
**Gate on the exit status.** Non-zero: retry once, then stop and report the command, exit code and stderr as a sync blocker — no completion summary, no "All beads complete.", and the remaining shutdown steps are not run.
|
|
235
|
+
3. If any HITL beads were noted during the session, output:
|
|
204
236
|
```
|
|
205
237
|
All agent work is complete. The following steps require human action before work can continue:
|
|
206
238
|
|
|
@@ -211,7 +243,7 @@ When `bd list --status=in_progress --type=chore` returns no results AND `bd read
|
|
|
211
243
|
|
|
212
244
|
Run `bd show <id>` for full details on each step.
|
|
213
245
|
```
|
|
214
|
-
|
|
246
|
+
4. If any needs-refinement beads were noted during the session, output:
|
|
215
247
|
```
|
|
216
248
|
The following beads need refinement before they can be implemented:
|
|
217
249
|
|
|
@@ -222,7 +254,7 @@ The following beads need refinement before they can be implemented:
|
|
|
222
254
|
|
|
223
255
|
Remove the `needs-refinement` label once a bead is ready to implement.
|
|
224
256
|
```
|
|
225
|
-
|
|
257
|
+
5. If any parents were blocked due to cap exhaustion, output:
|
|
226
258
|
```
|
|
227
259
|
The following features were blocked after reaching their retry cap and need human intervention:
|
|
228
260
|
|
|
@@ -234,8 +266,8 @@ The following features were blocked after reaching their retry cap and need huma
|
|
|
234
266
|
|
|
235
267
|
Run `bd show <id>` for full details on each.
|
|
236
268
|
```
|
|
237
|
-
|
|
238
|
-
|
|
269
|
+
6. If any epics are tagged `awaiting-epic-pr-merge`, output a **Pending Epic Review** table (epic bead ID, branch, PR URL) and stop.
|
|
270
|
+
7. If no HITL, needs-refinement, cap-blocked, or pending epic-review beads remain, output:
|
|
239
271
|
```
|
|
240
272
|
All beads complete.
|
|
241
273
|
```
|
|
@@ -250,8 +282,13 @@ All beads complete.
|
|
|
250
282
|
- **ALWAYS use the documented spawning mechanism to spawn subagents** — never use bash, never run stages inline, never use any other tool. This is your only spawning mechanism.
|
|
251
283
|
- **Always** derive orchestration state from beads — do not store loop counts in state.json.
|
|
252
284
|
- **Subagents can fetch their own context** — they will run `bd prime` if they need project-level state. Do not inject `bd prime` output into subagent prompts.
|
|
253
|
-
- **Max 5** tasks in-flight at once (counted by parent features, not individual chore beads)
|
|
254
|
-
- **
|
|
285
|
+
- **Max 5** tasks in-flight at once (counted by parent features, not individual chore beads) — a parent counts while any of its workers, stage, decomposition or expansion, sits in `inflight`.
|
|
286
|
+
- **Never** close a leaf execution bead and **never** create a `stage:fix`/feedback bead — the worker owns its bead's lifecycle and builds its own remediation chain.
|
|
287
|
+
- **Never** create a stage chore — `create-chores.mjs` pre-creates the chain; dispatch what `bd ready -l execution:afk` returns.
|
|
288
|
+
- **Never** re-dispatch a decomposition or an expansion, and never narrow the dispatch query to "chores with `stage:*`": an `execution:afk` bead with no stage chores is work waiting, not work that does not exist.
|
|
289
|
+
- **Always** record every dispatch in `inflight`, stage workers as `kind: "stage"`, decomposition workers as `kind: "decompose"` and expansion workers as `kind: "expand"` with `choreId: null` — an untracked worker is never waited on, and its absence can make HITL Pause or Shutdown fire mid-decomposition.
|
|
290
|
+
- **Never** run `create-task` for a bead that already exists to give it a pipeline — it creates a **second parent**. Expand with `create-chores.mjs --parent <id>`.
|
|
291
|
+
- **Max fix rounds** per parent is a read-only backstop (read `maxFixRounds` from the `create-task` skill's `pipeline.json`; count `stage:fix` chore children); block the parent at cap and create nothing.
|
|
255
292
|
- **Always** run feature chores in the feature worktree (`.agent-cortex/worktrees/<parent-id>`), never from repo root.
|
|
256
293
|
- **Never** auto-merge feature or epic PRs — merge decisions are human-controlled.
|
|
257
294
|
- **Never** continue past feature completion until PR `feature/<parent-id> -> epic/<epic-id>` is merged and the child HITL PR gate bead is closed by a human.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agent-cortex:ralph",
|
|
3
|
-
"description": "Use when running all pending beads end-to-end: finds the next available beads (dependencies met),
|
|
4
|
-
"tools": ["Bash", "Read", "Grep", "Glob", "Skill", "Task", "TaskList", "TaskGet", "TaskStop"
|
|
3
|
+
"description": "Use when running all pending beads end-to-end: finds the next available beads (dependencies met), advances each one through its pre-created pipeline-stage chores (code → verify → review → document) in its own worktree, opens and reports PRs immediately, then waits for human merges before continuing.",
|
|
4
|
+
"tools": ["Bash", "Read", "Grep", "Glob", "Skill", "Task", "TaskList", "TaskGet", "TaskStop"],
|
|
5
5
|
"argumentHint": "Run all pending beads"
|
|
6
|
-
}
|
|
6
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
## Wake mechanism (Claude Code — event-driven)
|
|
2
|
+
|
|
3
|
+
**Mechanism: event-driven — the harness re-invokes you automatically when a background worker completes and delivers that worker's result inline, so there is no poll timer, no sleep, and no log flush.**
|
|
4
|
+
|
|
5
|
+
### Spawn
|
|
6
|
+
|
|
7
|
+
RALPH HAS ONLY ONE WAY TO SPAWN SUBAGENTS: call the **`Task`** tool (not bash, not any other tool).
|
|
8
|
+
|
|
9
|
+
**`Task`** — Spawn a background sub-agent and return a task ID immediately.
|
|
10
|
+
- `prompt` (string, required): Full task prompt for the sub-agent.
|
|
11
|
+
- `cwd` (string, optional): Working directory for the sub-agent (default: current project root). Always set this to the feature worktree path when running stage chores.
|
|
12
|
+
- `model`, `subagent_type` (optional): Overrides for the worker; the Implementer and Reviewer workers keep the default (full reasoning), the Fix worker uses `model: haiku`.
|
|
13
|
+
|
|
14
|
+
The response is a plain task ID string. Store it in memory — you need it to track the worker against its parent bead. Use `TaskList`/`TaskGet` to see which workers are still running and `TaskStop` to cancel one.
|
|
15
|
+
|
|
16
|
+
Rules:
|
|
17
|
+
- NEVER use `bash` to spawn subagents (no `claude`, no `tsx`, no `node` scripts).
|
|
18
|
+
- NEVER try to run subagent work inline yourself — you only orchestrate.
|
|
19
|
+
- ALWAYS use `Task` for every subagent interaction; track running workers with `TaskList`/`TaskGet`.
|
|
20
|
+
- ALWAYS set `cwd` to the feature worktree path when running stage chores.
|
|
21
|
+
- ALWAYS keep the task ID in memory to correlate a completion with its parent bead.
|
|
22
|
+
|
|
23
|
+
### Completion arrival
|
|
24
|
+
|
|
25
|
+
A completion is **delivered, not observed**: Claude Code re-invokes you automatically when a background worker finishes, with the worker's result inline on the wake-up. **Do not poll and do not `sleep`.** React to completions as they arrive. On each completion, apply the shared handling in the **Event loop** section of agent.md (steps 3–8: correlate the task ID to its entry via `state.json`'s `inflight`, branch on the entry's `kind` — a `stage` entry parses the REPORT and confirms the worker closed its chore, an `expand` entry has no REPORT and no bead to confirm, so confirm the parent now has `stage:*` chores and dispatch its ready `stage:code` — advance the parent, check for newly ready beads, run the shutdown check).
|
|
26
|
+
|
|
27
|
+
### Id tracking
|
|
28
|
+
|
|
29
|
+
Initialize `.agent-cortex/ralph/state.json` as `{ "inflight": [] }` — there is no timer handle to track.
|
|
30
|
+
|
|
31
|
+
- **inflight[].agentId** — the task ID `Task` returned for that worker; it is the key the delivered completion is correlated to its bead, and the equivalent of `TaskGet`'s identifier when you need to inspect one worker.
|
|
32
|
+
- **inflight[].logLine** — not used on Claude; leave it at `1`. Progress lines (`.agent-cortex/ralph/ralph-<parentId>.log`) are written by the workers themselves and surfaced by the harness with the completion.
|
|
33
|
+
|
|
34
|
+
### Log flush
|
|
35
|
+
|
|
36
|
+
None. There is **no log tailing on Claude**: the completion is delivered with the result already in hand, so there is nothing to flush and nothing to poll. Produce the shared chat summaries from the delivered result instead.
|
|
37
|
+
|
|
38
|
+
### Stop
|
|
39
|
+
|
|
40
|
+
Stopping means simply **stop**: there is no poll timer to kill and no wait to cancel, so you do nothing further and the harness wakes you again when the user re-invokes you. Never schedule a replacement wake-up or start a background process.
|
|
41
|
+
|
|
42
|
+
### Completion constraints
|
|
43
|
+
|
|
44
|
+
- **Always** keep completion tracking active while worker results are outstanding — the harness delivers each completion precisely once; never re-request a result.
|
|
45
|
+
- **Never** poll, **never** `sleep`, **never** start a background timer.
|
|
46
|
+
- **Never** post empty status updates — only surface actual completions.
|