Identity
| Field | Value |
|---|---|
| Workflow ID | MasflGBKdowUZwpJ |
| Webhook path | /webhook/atomiser |
| n8n instance | https://hab.so1.io |
| Local JSON | /TOMMY.json (untracked) |
| Node count | 34 |
| Purpose | Decompose a repo into tasksets, atomise into task-lets, execute each via Claude Code CLI over SSH |
Five Phases
| Phase | Purpose | Token cost |
|---|---|---|
| P0: INIT | Merge webhook input with defaults | 0 |
| P1: INSPECT | Fetch repo tree, pipeline.yaml, README from GitHub API | 0 |
| P2: IDENTIFY | Single Anthropic API call to identify tasksets (~1100 tokens). Skipped when forge_tasks provided or pipeline.yaml exists. | 0-1100 |
| P3: ATOMISE | Convert tasksets into individual task-let prompts | 0 |
| P4: EXECUTE | SplitInBatches → SSH → claude --print --output-format json --max-turns 3 --dangerously-skip-permissions -p '<prompt>' | Variable |
| P5: CONFIRM | Aggregate results, return ALL_PASS or HAS_FAILURES | 0 |
Webhook Input Schema
forge_tasks+forge_context: When provided, TOMMY skips Phases 1-2 and jumps straight to Atomise (FORGE shortcut).dry_run: true: Logs task-let prompts without executing.taskset_filter: Array of taskset numbers to execute. Null = all.
Response Schema
Success (ALL_PASS):SSH Execution Command
Credentials
| Name | ID | Type |
|---|---|---|
| GitHub (Dev4rno) | tSg1ejqnd5r3clEg | githubApi |
| google_ai_key | PdEKB19B1R0PQ4th | httpHeaderAuth |
| SSH | (n8n internal) | ssh |
Architecture Changes (2026-03-28)
Phase 1 fetch nodes were rewired from parallel fan-out to sequential chain to eliminate duplication:{{ $json.repo }} to {{ $('📋 Merge & Set Defaults').first().json.repo }} since they no longer receive the config directly.
Assemble Inspection Context code uses $() node references instead of $input.all():
Credentials
| Name | ID | Type |
|---|---|---|
| GitHub (Dev4rno) | tSg1ejqnd5r3clEg | githubApi |
| Anthropic API Key | PdEKB19B1R0PQ4th | httpHeaderAuth (header: x-api-key) |
| SSH | QF2ld9Q3UGLT5yUK | ssh |
google_ai_key credential was reconfigured to use header name x-api-key for the Anthropic API.
Known Issues
- No
pipeline.yamlfiles exist in any repo — TOMMY always takes LLM-identify (Path B) or FORGE shortcut (Path C). Path A is dormant. - Timeout: FORGE triggers TOMMY with 600s timeout. Rover UI also uses 600s for tommy-mode.
- 📄 Fetch pipeline.yaml must have
On Error: Continue (Using Regular Output)— a 404 is expected when pipeline.yaml doesn’t exist. - 🚀 FORGE Shortcut? If node: condition uses
{{ $json.forge_tasks.length }} > 0(number comparison), NOT array “is not empty” — avoids strict type validation crash when forge_tasks is[]. - 📋 Merge & Set Defaults:
forge_tasksdefaults to[](empty array), notnull— prevents type coercion errors downstream. - 🔍 Filter: Skip Completed: Code returns
{json: ...}(bare object), not[{json: ...}]— required forrunOnceForEachItemmode. - ⚛️ Atomise to Task-lets: Uses
$('📊 Parse Tasksets').first()?.json || $('📄 Parse Existing Pipeline').first()?.jsonto bypass the empty Merge node output. - 🔄 Task-let Execution Loop: SplitInBatches v3 — batch size must be explicitly set to 1 in Options. Default empty options skip the loop body.
- ❓ Pipeline YAML Exists?: has Execute Once enabled to prevent downstream duplication from Phase 1 multi-trigger.