Task orchestrator
Autonomous multi-agent task orchestration with dependency analysis, parallel tmux/Codex execution, and self-healing heartbeat monitoring.
How to use it
Claude Code
- Run the line below. It pulls the whole folder into
~/.claude/skills/task-orchestrator, including the files SKILL.md points to. - Describe your job in plain words. Claude Code follows the skill from there.
npx degit jdrhyne/agent-skills/skills/task-orchestrator#main ~/.claude/skills/task-orchestratorFor one project only, change the path to .claude/skills/task-orchestrator. This skill also uses issues.json, check_progress.sh, manifest.json, ceo_root_manager.js, workspace_validator.js, kill_switch.js — copying SKILL.md alone won't be enough. See the folder on GitHub.
Claude (web or desktop app)
- On this page open ⋯ → Download .md.
- Save it as SKILL.md in a folder, zip the folder, then Customize → Skills → + → Create skill → Upload a skill.
- Pick the file and Save. Claude shows the name and description and runs a security scan.
- Check the skill is switched on.
- Start a new chat and describe your job in plain words. The AI follows the skill from there.
ChatGPT or another app
- ChatGPT: make a Project and paste it into Instructions.
- Neither? Paste it at the top of a new chat — it works for that chat.
Not working?
- Check which app you pasted it into — the steps above name the right one.
- Some skills need the paid tier of Claude or ChatGPT.
Paste into Claude, ChatGPT or Cursor.
Source of Task orchestrator
Show the full text416 lines
| name | description | metadata | permissions |
|---|---|---|---|
| task-orchestrator | Autonomous multi-agent task orchestration with dependency analysis, parallel tmux/Codex execution, and self-healing heartbeat monitoring. Use for large projects with multiple issues/tasks that need coordinated parallel execution. | {"clawdbot":{"emoji":"🎭","requires":{"anyBins":["tmux","codex","gh"]}}} | - exec: "Runs local git, tmux, gh, and codex commands to coordinate isolated task workers. - file_write: "Creates manifests, logs, and per-task working directories for the orchestration run. - network: "Uses GitHub CLI and git remotes for issue metadata and repository operations. |
Task Orchestrator
Autonomous orchestration of multi-agent builds using tmux + Codex with self-healing monitoring.
Load the senior-engineering skill alongside this one for engineering principles.
Safety Boundaries
- Do not launch parallel workers for tasks with overlapping write scope until the dependency is resolved.
- Do not push branches, merge work, or self-heal by guessing when human review is required.
- Do not store secrets in manifests, logs, prompts, or tmux pane captures.
- Do not continue retrying a failing task indefinitely; stop and surface the blocker after bounded retries.
Core Concepts
1. Task Manifest
A JSON file defining all tasks, their dependencies, files touched, and status.
{
"project": "project-name",
"repo": "owner/repo",
"workdir": "/path/to/worktrees",
"created": "2026-01-17T00:00:00Z",
"model": "gpt-5.2-codex",
"modelTier": "high",
"phases": [
{
"name": "Phase 1: Critical",
"tasks": [
{
"id": "t1",
"issue": 1,
"title": "Fix X",
"files": ["src/foo.js"],
"dependsOn": [],
"status": "pending",
"worktree": null,
"tmuxSession": null,
"startedAt": null,
"lastProgress": null,
"completedAt": null,
"prNumber": null
}
]
}
]
}
2. Dependency Rules
- Same file = sequential — Tasks touching the same file must run in order or merge
- Different files = parallel — Independent tasks can run simultaneously
- Explicit depends = wait —
dependsOnarray enforces ordering - Phase gates — Next phase waits for current phase completion
3. Execution Model
- Each task gets its own git worktree (isolated branch)
- Each task runs in its own tmux session
- Use Codex with --yolo for autonomous execution
- Model: GPT-5.2-codex high (configurable)
Setup Commands
Initialize Orchestration
# 1. Create working directory
WORKDIR="${TMPDIR:-/tmp}/orchestrator-$(date +%s)"
mkdir -p "$WORKDIR"
# 2. Clone repo for worktrees
git clone https://github.com/OWNER/REPO.git "$WORKDIR/repo"
cd "$WORKDIR/repo"
# 3. Create tmux socket
SOCKET="$WORKDIR/orchestrator.sock"
# 4. Initialize manifest
cat > "$WORKDIR/manifest.json" << 'EOF'
{
"project": "PROJECT_NAME",
"repo": "OWNER/REPO",
"workdir": "WORKDIR_PATH",
"socket": "SOCKET_PATH",
"created": "TIMESTAMP",
"model": "gpt-5.2-codex",
"modelTier": "high",
"phases": []
}
EOF
Analyze GitHub Issues for Dependencies
# Fetch all open issues
gh issue list --repo OWNER/REPO --state open --json number,title,body,labels > issues.json
# Group by files mentioned in issue body
# Tasks touching same files should serialize
Create Worktrees
# For each task, create isolated worktree
cd "$WORKDIR/repo"
git worktree add -b fix/issue-N "$WORKDIR/task-tN" main
Launch Tmux Sessions
SOCKET="$WORKDIR/orchestrator.sock"
# Create session for task
tmux -S "$SOCKET" new-session -d -s "task-tN"
# Launch Codex (uses gpt-5.2-codex with reasoning_effort=high from ~/.codex/config.toml)
# Note: Model config is in ~/.codex/config.toml, not CLI flag
tmux -S "$SOCKET" send-keys -t "task-tN" \
"cd $WORKDIR/task-tN && codex --yolo 'Fix issue #N: DESCRIPTION. Run tests, commit with good message, push to origin.'" Enter
Monitoring & Self-Healing
Progress Check Script
#!/bin/bash
# check_progress.sh - Run via heartbeat
WORKDIR="$1"
SOCKET="$WORKDIR/orchestrator.sock"
MANIFEST="$WORKDIR/manifest.json"
STALL_THRESHOLD_MINS=20
check_session() {
local session="$1"
local task_id="$2"
# Capture recent output
local output=$(tmux -S "$SOCKET" capture-pane -p -t "$session" -S -50 2>/dev/null)
# Check for completion indicators
if echo "$output" | grep -qE "(All tests passed|Successfully pushed|❯ $)"; then
echo "DONE:$task_id"
return 0
fi
# Check for errors
if echo "$output" | grep -qiE "(error:|failed:|FATAL|panic)"; then
echo "ERROR:$task_id"
return 1
fi
# Check for stall (prompt waiting for input)
if echo "$output" | grep -qE "(\? |Continue\?|y/n|Press any key)"; then
echo "STUCK:$task_id:waiting_for_input"
return 2
fi
echo "RUNNING:$task_id"
return 0
}
# Check all active sessions
for session in $(tmux -S "$SOCKET" list-sessions -F "#{session_name}" 2>/dev/null); do
check_session "$session" "$session"
done
Self-Healing Actions
When a task is stuck, the orchestrator should:
Waiting for input → Send appropriate response
tmux -S "$SOCKET" send-keys -t "$session" "y" EnterError/failure → Capture logs, analyze, retry with fixes
# Capture error context tmux -S "$SOCKET" capture-pane -p -t "$session" -S -100 > "$WORKDIR/logs/$task_id-error.log" # Kill and restart with error context tmux -S "$SOCKET" kill-session -t "$session" tmux -S "$SOCKET" new-session -d -s "$session" tmux -S "$SOCKET" send-keys -t "$session" \ "cd $WORKDIR/$task_id && codex --model gpt-5.2-codex-high --yolo 'Previous attempt failed with: $(cat error.log | tail -20). Fix the issue and retry.'" EnterNo progress for 20+ mins → Nudge or restart
# Check git log for recent commits cd "$WORKDIR/$task_id" LAST_COMMIT=$(git log -1 --format="%ar" 2>/dev/null) # If no commits in threshold, restart
Heartbeat Cron Setup
# Add to cron (every 15 minutes)
cron action:add job:{
"label": "orchestrator-heartbeat",
"schedule": "*/15 * * * *",
"prompt": "Check orchestration progress at WORKDIR. Read manifest, check all tmux sessions, self-heal any stuck tasks, advance to next phase if current is complete. Do NOT ping human - fix issues yourself."
}
Workflow: Full Orchestration Run
Step 1: Analyze & Plan
# 1. Fetch issues
gh issue list --repo OWNER/REPO --state open --json number,title,body > /tmp/issues.json
# 2. Analyze for dependencies (files mentioned, explicit deps)
# Group into phases:
# - Phase 1: Critical/blocking issues (no deps)
# - Phase 2: High priority (may depend on Phase 1)
# - Phase 3: Medium/low (depends on earlier phases)
# 3. Within each phase, identify:
# - Parallel batch: Different files, no deps → run simultaneously
# - Serial batch: Same files or explicit deps → run in order
Step 2: Create Manifest
Write manifest.json with all tasks, dependencies, file mappings.
Step 3: Launch Phase 1
# Create worktrees for Phase 1 tasks
for task in phase1_tasks; do
git worktree add -b "fix/issue-$issue" "$WORKDIR/task-$id" main
done
# Launch tmux sessions
for task in phase1_parallel_batch; do
tmux -S "$SOCKET" new-session -d -s "task-$id"
tmux -S "$SOCKET" send-keys -t "task-$id" \
"cd $WORKDIR/task-$id && codex --model gpt-5.2-codex-high --yolo '$PROMPT'" Enter
done
Step 4: Monitor & Self-Heal
Heartbeat checks every 15 mins:
- Poll all sessions
- Update manifest with progress
- Self-heal stuck tasks
- When all Phase N tasks complete → launch Phase N+1
Step 5: Create PRs
# When task completes successfully
cd "$WORKDIR/task-$id"
git push -u origin "fix/issue-$issue"
gh pr create --repo OWNER/REPO \
--head "fix/issue-$issue" \
--title "fix: Issue #$issue - $TITLE" \
--body "Closes #$issue
## Changes
[Auto-generated by Codex orchestrator]
## Testing
- [ ] Unit tests pass
- [ ] Manual verification"
Step 6: Cleanup
# After all PRs merged or work complete
tmux -S "$SOCKET" kill-server
cd "$WORKDIR/repo"
for task in all_tasks; do
git worktree remove "$WORKDIR/task-$id" --force
done
rm -rf "$WORKDIR"
Manifest Status Values
| Status | Meaning |
|---|---|
pending |
Not started yet |
blocked |
Waiting on dependency |
running |
Codex session active |
stuck |
Needs intervention (auto-heal) |
error |
Failed, needs retry |
complete |
Done, ready for PR |
pr_open |
PR created |
merged |
PR merged |
Example: Security Framework Orchestration
{
"project": "nuri-security-framework",
"repo": "jdrhyne/nuri-security-framework",
"phases": [
{
"name": "Phase 1: Critical",
"tasks": [
{"id": "t1", "issue": 1, "files": ["ceo_root_manager.js"], "dependsOn": []},
{"id": "t2", "issue": 2, "files": ["ceo_root_manager.js"], "dependsOn": ["t1"]},
{"id": "t3", "issue": 3, "files": ["workspace_validator.js"], "dependsOn": []}
]
},
{
"name": "Phase 2: High",
"tasks": [
{"id": "t4", "issue": 4, "files": ["kill_switch.js", "container_executor.js"], "dependsOn": []},
{"id": "t5", "issue": 5, "files": ["kill_switch.js"], "dependsOn": ["t4"]},
{"id": "t6", "issue": 6, "files": ["ceo_root_manager.js"], "dependsOn": ["t2"]},
{"id": "t7", "issue": 7, "files": ["container_executor.js"], "dependsOn": []},
{"id": "t8", "issue": 8, "files": ["container_executor.js", "egress_proxy.js"], "dependsOn": ["t7"]}
]
}
]
}
Parallel execution in Phase 1:
- t1 and t3 run in parallel (different files)
- t2 waits for t1 (same file)
Parallel execution in Phase 2:
- t4, t6, t7 can start together
- t5 waits for t4, t8 waits for t7
Tips
- Always use GPT-5.2-codex high for complex work:
--model gpt-5.2-codex-high - Clear prompts — Include issue number, description, expected outcome, test instructions
- Atomic commits — Tell Codex to commit after each logical change
- Push early — Push to remote branch so progress isn't lost if session dies
- Checkpoint logs — Capture tmux output periodically to files
- Phase gates — Don't start Phase N+1 until Phase N is 100% complete
- Self-heal aggressively — If stuck >10 mins, intervene automatically
- Browser relay limits — If CDP automation is blocked, use iframe batch scraping or manual browser steps
Integration with Other Skills
- senior-engineering: Load for build principles and quality gates
- coding-agent: Reference for Codex CLI patterns
- github: Use for PR creation, issue management
Lessons Learned (2026-01-17)
Codex Sandbox Limitations
When using codex exec --full-auto, the sandbox:
- No network access —
git pushfails with "Could not resolve host" - Limited filesystem — Can't write to paths like
~/nuri_workspace
Heartbeat Detection Improvements
The heartbeat should check for:
- Shell prompt idle — If tmux pane shows
username@hostname path %, worker is done - Unpushed commits —
git log @{u}.. --onelineshows commits not on remote - Push failures — Look for "Could not resolve host" in output
When detected, the orchestrator (not the worker) should:
- Push the commit from outside the sandbox
- Create the PR via
gh pr create - Update manifest and notify
Recommended Pattern
# In heartbeat, for each task:
cd /tmp/orchestrator-*/task-tN
if tmux capture-pane shows shell prompt; then
# Worker finished, check for unpushed work
if git log @{u}.. --oneline | grep -q .; then
git push -u origin HEAD
gh pr create --title "$(git log --format=%s -1)" --body "Closes #N" --base main
fi
fi
| 1 | |
| 2 | name task-orchestrator |
| 3 | description Autonomous multi-agent task orchestration with dependency analysis, parallel tmux/Codex execution, and self-healing heartbeat monitoring. Use for large projects with multiple issues/tasks that need coordinated parallel execution. |
| 4 | metadata {"clawdbot":{"emoji":"🎭","requires":{"anyBins":["tmux","codex","gh"]}}} |
| 5 | permissions |
| 6 | - exec: "Runs local git, tmux, gh, and codex commands to coordinate isolated task workers." |
| 7 | - file_write: "Creates manifests, logs, and per-task working directories for the orchestration run." |
| 8 | - network: "Uses GitHub CLI and git remotes for issue metadata and repository operations." |
| 9 | |
| 10 | |
| 11 | # Task Orchestrator |
| 12 | |
| 13 | Autonomous orchestration of multi-agent builds using tmux + Codex with self-healing monitoring. |
| 14 | |
| 15 | **Load the senior-engineering skill alongside this one for engineering principles.** |
| 16 | |
| 17 | ## Safety Boundaries |
| 18 | |
| 19 | Do not launch parallel workers for tasks with overlapping write scope until the dependency is resolved. |
| 20 | Do not push branches, merge work, or self-heal by guessing when human review is required. |
| 21 | Do not store secrets in manifests, logs, prompts, or tmux pane captures. |
| 22 | Do not continue retrying a failing task indefinitely; stop and surface the blocker after bounded retries. |
| 23 | |
| 24 | ## Core Concepts |
| 25 | |
| 26 | ### 1. Task Manifest |
| 27 | A JSON file defining all tasks, their dependencies, files touched, and status. |
| 28 | |
| 29 | |
| 30 | { |
| 31 | "project": "project-name", |
| 32 | "repo": "owner/repo", |
| 33 | "workdir": "/path/to/worktrees", |
| 34 | "created": "2026-01-17T00:00:00Z", |
| 35 | "model": "gpt-5.2-codex", |
| 36 | "modelTier": "high", |
| 37 | "phases": [ |
| 38 | { |
| 39 | "name": "Phase 1: Critical", |
| 40 | "tasks": [ |
| 41 | { |
| 42 | "id": "t1", |
| 43 | "issue": 1, |
| 44 | "title": "Fix X", |
| 45 | "files": ["src/foo.js"], |
| 46 | "dependsOn": [], |
| 47 | "status": "pending", |
| 48 | "worktree": null, |
| 49 | "tmuxSession": null, |
| 50 | "startedAt": null, |
| 51 | "lastProgress": null, |
| 52 | "completedAt": null, |
| 53 | "prNumber": null |
| 54 | } |
| 55 | ] |
| 56 | } |
| 57 | ] |
| 58 | } |
| 59 | |
| 60 | |
| 61 | ### 2. Dependency Rules |
| 62 | **Same file = sequential** — Tasks touching the same file must run in order or merge |
| 63 | **Different files = parallel** — Independent tasks can run simultaneously |
| 64 | **Explicit depends = wait** — `dependsOn` array enforces ordering |
| 65 | **Phase gates** — Next phase waits for current phase completion |
| 66 | |
| 67 | ### 3. Execution Model |
| 68 | Each task gets its own **git worktree** (isolated branch) |
| 69 | Each task runs in its own **tmux session** |
| 70 | Use **Codex with --yolo** for autonomous execution |
| 71 | Model: **GPT-5.2-codex high** (configurable) |
| 72 | |
| 73 | |
| 74 | |
| 75 | ## Setup Commands |
| 76 | |
| 77 | ### Initialize Orchestration |
| 78 | |
| 79 | |
| 80 | # 1. Create working directory |
| 81 | WORKDIR="${TMPDIR:-/tmp}/orchestrator-$(date +%s)" |
| 82 | mkdir -p "$WORKDIR" |
| 83 | |
| 84 | # 2. Clone repo for worktrees |
| 85 | git clone https://github.com/OWNER/REPO.git "$WORKDIR/repo" |
| 86 | cd "$WORKDIR/repo" |
| 87 | |
| 88 | # 3. Create tmux socket |
| 89 | SOCKET="$WORKDIR/orchestrator.sock" |
| 90 | |
| 91 | # 4. Initialize manifest |
| 92 | cat > "$WORKDIR/manifest.json" << 'EOF' |
| 93 | { |
| 94 | "project": "PROJECT_NAME", |
| 95 | "repo": "OWNER/REPO", |
| 96 | "workdir": "WORKDIR_PATH", |
| 97 | "socket": "SOCKET_PATH", |
| 98 | "created": "TIMESTAMP", |
| 99 | "model": "gpt-5.2-codex", |
| 100 | "modelTier": "high", |
| 101 | "phases": [] |
| 102 | } |
| 103 | EOF |
| 104 | |
| 105 | |
| 106 | ### Analyze GitHub Issues for Dependencies |
| 107 | |
| 108 | |
| 109 | # Fetch all open issues |
| 110 | gh issue list --repo OWNER/REPO --state open --json number,title,body,labels > issues.json |
| 111 | |
| 112 | # Group by files mentioned in issue body |
| 113 | # Tasks touching same files should serialize |
| 114 | |
| 115 | |
| 116 | ### Create Worktrees |
| 117 | |
| 118 | |
| 119 | # For each task, create isolated worktree |
| 120 | cd "$WORKDIR/repo" |
| 121 | git worktree add -b fix/issue-N "$WORKDIR/task-tN" main |
| 122 | |
| 123 | |
| 124 | ### Launch Tmux Sessions |
| 125 | |
| 126 | |
| 127 | SOCKET="$WORKDIR/orchestrator.sock" |
| 128 | |
| 129 | # Create session for task |
| 130 | tmux -S "$SOCKET" new-session -d -s "task-tN" |
| 131 | |
| 132 | # Launch Codex (uses gpt-5.2-codex with reasoning_effort=high from ~/.codex/config.toml) |
| 133 | # Note: Model config is in ~/.codex/config.toml, not CLI flag |
| 134 | tmux -S "$SOCKET" send-keys -t "task-tN" \ |
| 135 | "cd $WORKDIR/task-tN && codex --yolo 'Fix issue #N: DESCRIPTION. Run tests, commit with good message, push to origin.'" Enter |
| 136 | |
| 137 | |
| 138 | |
| 139 | |
| 140 | ## Monitoring & Self-Healing |
| 141 | |
| 142 | ### Progress Check Script |
| 143 | |
| 144 | |
| 145 | #!/bin/bash |
| 146 | # check_progress.sh - Run via heartbeat |
| 147 | |
| 148 | WORKDIR="$1" |
| 149 | SOCKET="$WORKDIR/orchestrator.sock" |
| 150 | MANIFEST="$WORKDIR/manifest.json" |
| 151 | STALL_THRESHOLD_MINS=20 |
| 152 | |
| 153 | check_session() { |
| 154 | local session="$1" |
| 155 | local task_id="$2" |
| 156 | |
| 157 | # Capture recent output |
| 158 | local output=$(tmux -S "$SOCKET" capture-pane -p -t "$session" -S -50 2>/dev/null) |
| 159 | |
| 160 | # Check for completion indicators |
| 161 | if echo "$output" | grep -qE "(All tests passed|Successfully pushed|❯ $)"; then |
| 162 | echo "DONE:$task_id" |
| 163 | return 0 |
| 164 | fi |
| 165 | |
| 166 | # Check for errors |
| 167 | if echo "$output" | grep -qiE "(error:|failed:|FATAL|panic)"; then |
| 168 | echo "ERROR:$task_id" |
| 169 | return 1 |
| 170 | fi |
| 171 | |
| 172 | # Check for stall (prompt waiting for input) |
| 173 | if echo "$output" | grep -qE "(\? |Continue\?|y/n|Press any key)"; then |
| 174 | echo "STUCK:$task_id:waiting_for_input" |
| 175 | return 2 |
| 176 | fi |
| 177 | |
| 178 | echo "RUNNING:$task_id" |
| 179 | return 0 |
| 180 | } |
| 181 | |
| 182 | # Check all active sessions |
| 183 | for session in $(tmux -S "$SOCKET" list-sessions -F "#{session_name}" 2>/dev/null); do |
| 184 | check_session "$session" "$session" |
| 185 | done |
| 186 | |
| 187 | |
| 188 | ### Self-Healing Actions |
| 189 | |
| 190 | When a task is stuck, the orchestrator should: |
| 191 | |
| 192 | **Waiting for input** → Send appropriate response |
| 193 | |
| 194 | tmux -S "$SOCKET" send-keys -t "$session" "y" Enter |
| 195 | |
| 196 | |
| 197 | **Error/failure** → Capture logs, analyze, retry with fixes |
| 198 | |
| 199 | # Capture error context |
| 200 | tmux -S "$SOCKET" capture-pane -p -t "$session" -S -100 > "$WORKDIR/logs/$task_id-error.log" |
| 201 | |
| 202 | # Kill and restart with error context |
| 203 | tmux -S "$SOCKET" kill-session -t "$session" |
| 204 | tmux -S "$SOCKET" new-session -d -s "$session" |
| 205 | tmux -S "$SOCKET" send-keys -t "$session" \ |
| 206 | "cd $WORKDIR/$task_id && codex --model gpt-5.2-codex-high --yolo 'Previous attempt failed with: $(cat error.log | tail -20). Fix the issue and retry.'" Enter |
| 207 | |
| 208 | |
| 209 | **No progress for 20+ mins** → Nudge or restart |
| 210 | |
| 211 | # Check git log for recent commits |
| 212 | cd "$WORKDIR/$task_id" |
| 213 | LAST_COMMIT=$(git log -1 --format="%ar" 2>/dev/null) |
| 214 | |
| 215 | # If no commits in threshold, restart |
| 216 | |
| 217 | |
| 218 | ### Heartbeat Cron Setup |
| 219 | |
| 220 | |
| 221 | # Add to cron (every 15 minutes) |
| 222 | cron action:add job:{ |
| 223 | "label": "orchestrator-heartbeat", |
| 224 | "schedule": "*/15 * * * *", |
| 225 | "prompt": "Check orchestration progress at WORKDIR. Read manifest, check all tmux sessions, self-heal any stuck tasks, advance to next phase if current is complete. Do NOT ping human - fix issues yourself." |
| 226 | } |
| 227 | |
| 228 | |
| 229 | |
| 230 | |
| 231 | ## Workflow: Full Orchestration Run |
| 232 | |
| 233 | ### Step 1: Analyze & Plan |
| 234 | |
| 235 | |
| 236 | # 1. Fetch issues |
| 237 | gh issue list --repo OWNER/REPO --state open --json number,title,body > /tmp/issues.json |
| 238 | |
| 239 | # 2. Analyze for dependencies (files mentioned, explicit deps) |
| 240 | # Group into phases: |
| 241 | # - Phase 1: Critical/blocking issues (no deps) |
| 242 | # - Phase 2: High priority (may depend on Phase 1) |
| 243 | # - Phase 3: Medium/low (depends on earlier phases) |
| 244 | |
| 245 | # 3. Within each phase, identify: |
| 246 | # - Parallel batch: Different files, no deps → run simultaneously |
| 247 | # - Serial batch: Same files or explicit deps → run in order |
| 248 | |
| 249 | |
| 250 | ### Step 2: Create Manifest |
| 251 | |
| 252 | Write manifest.json with all tasks, dependencies, file mappings. |
| 253 | |
| 254 | ### Step 3: Launch Phase 1 |
| 255 | |
| 256 | |
| 257 | # Create worktrees for Phase 1 tasks |
| 258 | for task in phase1_tasks; do |
| 259 | git worktree add -b "fix/issue-$issue" "$WORKDIR/task-$id" main |
| 260 | done |
| 261 | |
| 262 | # Launch tmux sessions |
| 263 | for task in phase1_parallel_batch; do |
| 264 | tmux -S "$SOCKET" new-session -d -s "task-$id" |
| 265 | tmux -S "$SOCKET" send-keys -t "task-$id" \ |
| 266 | "cd $WORKDIR/task-$id && codex --model gpt-5.2-codex-high --yolo '$PROMPT'" Enter |
| 267 | done |
| 268 | |
| 269 | |
| 270 | ### Step 4: Monitor & Self-Heal |
| 271 | |
| 272 | Heartbeat checks every 15 mins: |
| 273 | Poll all sessions |
| 274 | Update manifest with progress |
| 275 | Self-heal stuck tasks |
| 276 | When all Phase N tasks complete → launch Phase N+1 |
| 277 | |
| 278 | ### Step 5: Create PRs |
| 279 | |
| 280 | |
| 281 | # When task completes successfully |
| 282 | cd "$WORKDIR/task-$id" |
| 283 | git push -u origin "fix/issue-$issue" |
| 284 | gh pr create --repo OWNER/REPO \ |
| 285 | --head "fix/issue-$issue" \ |
| 286 | --title "fix: Issue #$issue - $TITLE" \ |
| 287 | --body "Closes #$issue |
| 288 | |
| 289 | ## Changes |
| 290 | [Auto-generated by Codex orchestrator] |
| 291 | |
| 292 | ## Testing |
| 293 | - [ ] Unit tests pass |
| 294 | - [ ] Manual verification" |
| 295 | |
| 296 | |
| 297 | ### Step 6: Cleanup |
| 298 | |
| 299 | |
| 300 | # After all PRs merged or work complete |
| 301 | tmux -S "$SOCKET" kill-server |
| 302 | cd "$WORKDIR/repo" |
| 303 | for task in all_tasks; do |
| 304 | git worktree remove "$WORKDIR/task-$id" --force |
| 305 | done |
| 306 | rm -rf "$WORKDIR" |
| 307 | |
| 308 | |
| 309 | |
| 310 | |
| 311 | ## Manifest Status Values |
| 312 | |
| 313 | | Status | Meaning | |
| 314 | |--------|---------| |
| 315 | | `pending` | Not started yet | |
| 316 | | `blocked` | Waiting on dependency | |
| 317 | | `running` | Codex session active | |
| 318 | | `stuck` | Needs intervention (auto-heal) | |
| 319 | | `error` | Failed, needs retry | |
| 320 | | `complete` | Done, ready for PR | |
| 321 | | `pr_open` | PR created | |
| 322 | | `merged` | PR merged | |
| 323 | |
| 324 | |
| 325 | |
| 326 | ## Example: Security Framework Orchestration |
| 327 | |
| 328 | |
| 329 | { |
| 330 | "project": "nuri-security-framework", |
| 331 | "repo": "jdrhyne/nuri-security-framework", |
| 332 | "phases": [ |
| 333 | { |
| 334 | "name": "Phase 1: Critical", |
| 335 | "tasks": [ |
| 336 | {"id": "t1", "issue": 1, "files": ["ceo_root_manager.js"], "dependsOn": []}, |
| 337 | {"id": "t2", "issue": 2, "files": ["ceo_root_manager.js"], "dependsOn": ["t1"]}, |
| 338 | {"id": "t3", "issue": 3, "files": ["workspace_validator.js"], "dependsOn": []} |
| 339 | ] |
| 340 | }, |
| 341 | { |
| 342 | "name": "Phase 2: High", |
| 343 | "tasks": [ |
| 344 | {"id": "t4", "issue": 4, "files": ["kill_switch.js", "container_executor.js"], "dependsOn": []}, |
| 345 | {"id": "t5", "issue": 5, "files": ["kill_switch.js"], "dependsOn": ["t4"]}, |
| 346 | {"id": "t6", "issue": 6, "files": ["ceo_root_manager.js"], "dependsOn": ["t2"]}, |
| 347 | {"id": "t7", "issue": 7, "files": ["container_executor.js"], "dependsOn": []}, |
| 348 | {"id": "t8", "issue": 8, "files": ["container_executor.js", "egress_proxy.js"], "dependsOn": ["t7"]} |
| 349 | ] |
| 350 | } |
| 351 | ] |
| 352 | } |
| 353 | |
| 354 | |
| 355 | **Parallel execution in Phase 1:** |
| 356 | t1 and t3 run in parallel (different files) |
| 357 | t2 waits for t1 (same file) |
| 358 | |
| 359 | **Parallel execution in Phase 2:** |
| 360 | t4, t6, t7 can start together |
| 361 | t5 waits for t4, t8 waits for t7 |
| 362 | |
| 363 | |
| 364 | |
| 365 | ## Tips |
| 366 | |
| 367 | **Always use GPT-5.2-codex high** for complex work: `--model gpt-5.2-codex-high` |
| 368 | **Clear prompts** — Include issue number, description, expected outcome, test instructions |
| 369 | **Atomic commits** — Tell Codex to commit after each logical change |
| 370 | **Push early** — Push to remote branch so progress isn't lost if session dies |
| 371 | **Checkpoint logs** — Capture tmux output periodically to files |
| 372 | **Phase gates** — Don't start Phase N+1 until Phase N is 100% complete |
| 373 | **Self-heal aggressively** — If stuck >10 mins, intervene automatically |
| 374 | **Browser relay limits** — If CDP automation is blocked, use iframe batch scraping or manual browser steps |
| 375 | |
| 376 | |
| 377 | |
| 378 | ## Integration with Other Skills |
| 379 | |
| 380 | **senior-engineering**: Load for build principles and quality gates |
| 381 | **coding-agent**: Reference for Codex CLI patterns |
| 382 | **github**: Use for PR creation, issue management |
| 383 | |
| 384 | |
| 385 | |
| 386 | ## Lessons Learned (2026-01-17) |
| 387 | |
| 388 | ### Codex Sandbox Limitations |
| 389 | When using `codex exec --full-auto`, the sandbox: |
| 390 | **No network access** — `git push` fails with "Could not resolve host" |
| 391 | **Limited filesystem** — Can't write to paths like `~/nuri_workspace` |
| 392 | |
| 393 | ### Heartbeat Detection Improvements |
| 394 | The heartbeat should check for: |
| 395 | **Shell prompt idle** — If tmux pane shows `username@hostname path %`, worker is done |
| 396 | **Unpushed commits** — `git log @{u}.. --oneline` shows commits not on remote |
| 397 | **Push failures** — Look for "Could not resolve host" in output |
| 398 | |
| 399 | When detected, the orchestrator (not the worker) should: |
| 400 | Push the commit from outside the sandbox |
| 401 | Create the PR via `gh pr create` |
| 402 | Update manifest and notify |
| 403 | |
| 404 | ### Recommended Pattern |
| 405 | |
| 406 | # In heartbeat, for each task: |
| 407 | cd /tmp/orchestrator-*/task-tN |
| 408 | if tmux capture-pane shows shell prompt; then |
| 409 | # Worker finished, check for unpushed work |
| 410 | if git log @{u}.. --oneline | grep -q .; then |
| 411 | git push -u origin HEAD |
| 412 | gh pr create --title "$(git log --format=%s -1)" --body "Closes #N" --base main |
| 413 | fi |
| 414 | fi |
| 415 | |
| 416 |
Discussion
Browse more free Claude skills.