diff --git a/.planning/quick/1-remove-orphan-node-chain-starting-with-b/1-PLAN.md b/.planning/quick/1-remove-orphan-node-chain-starting-with-b/1-PLAN.md new file mode 100644 index 0000000..396b78e --- /dev/null +++ b/.planning/quick/1-remove-orphan-node-chain-starting-with-b/1-PLAN.md @@ -0,0 +1,310 @@ +--- +phase: quick-1 +plan: 1 +type: execute +wave: 1 +depends_on: [] +files_modified: [n8n-workflow.json] +autonomous: true + +must_haves: + truths: + - "Orphan node chain is removed from main workflow" + - "Node count reaches structural minimum of 166 nodes" + - "No connections reference the removed nodes" + artifacts: + - path: "n8n-workflow.json" + provides: "Main workflow without orphan nodes" + min_lines: 5000 + key_links: + - from: "n8n-workflow.json nodes array" + to: "n8n-workflow.json connections object" + via: "node references" + pattern: '"node":\\s*"(Build Callback Action|Execute Callback Action|Parse Callback Result|Answer Action Query|Delete Suggestion Message|Send Callback Result)"' +--- + + +Remove orphan node chain starting with "Build Callback Action" from the main n8n workflow. + +Purpose: Clean up 6 orphan nodes that have no incoming connections (legacy callback infrastructure removed in Phase 10 modularization). This achieves the structural minimum of 166 nodes identified in Phase 10.1-07 analysis. + +Output: n8n-workflow.json with 166 nodes (down from 172) + + + +@/home/luc/.claude/get-shit-done/workflows/execute-plan.md +@/home/luc/.claude/get-shit-done/templates/summary.md + + + +@.planning/STATE.md +@CLAUDE.md + +Current state: 172 nodes in main workflow +Target state: 166 nodes (structural minimum per Phase 10.1-07 analysis) + + + + + + Remove orphan node chain from workflow JSON + n8n-workflow.json + +Remove the following 6 orphan nodes from the workflow (identified via dependency analysis - no incoming connections): + +**Nodes to remove from `nodes` array:** +1. "Build Callback Action" (id: "code-build-callback-cmd") +2. "Execute Callback Action" (id: "exec-callback-action") +3. "Parse Callback Result" (id: "code-parse-callback-result") +4. "Answer Action Query" (id: follows pattern) +5. "Delete Suggestion Message" (id: follows pattern) +6. "Send Callback Result" (id: follows pattern) + +**Connections to remove from `connections` object:** +- "Build Callback Action" +- "Execute Callback Action" +- "Parse Callback Result" +- "Answer Action Query" +- "Delete Suggestion Message" +- "Send Callback Result" + +Implementation approach: +```python +import json + +with open('n8n-workflow.json') as f: + wf = json.load(f) + +orphan_names = [ + 'Build Callback Action', + 'Execute Callback Action', + 'Parse Callback Result', + 'Answer Action Query', + 'Delete Suggestion Message', + 'Send Callback Result' +] + +# Remove nodes +wf['nodes'] = [n for n in wf['nodes'] if n['name'] not in orphan_names] + +# Remove connections +for name in orphan_names: + wf['connections'].pop(name, None) + +with open('n8n-workflow.json', 'w') as f: + json.dump(wf, f, indent=2) +``` + +Why these nodes are safe to remove: Phase 10 modularization replaced the old callback infrastructure with sub-workflow architecture. These nodes were part of the legacy callback execution path that has been fully replaced by Execute Workflow nodes calling n8n-actions.json and other sub-workflows. + + +```bash +# Verify node count reduced to 166 +python3 -c " +import json +with open('n8n-workflow.json') as f: + wf = json.load(f) +print(f'Node count: {len(wf[\"nodes\"])}') +print(f'Expected: 166') +assert len(wf['nodes']) == 166, f'Expected 166 nodes, got {len(wf[\"nodes\"])}' +print('✓ Node count correct') +" + +# Verify no orphan node references remain +python3 -c " +import json +with open('n8n-workflow.json') as f: + wf = json.load(f) + +orphan_names = [ + 'Build Callback Action', + 'Execute Callback Action', + 'Parse Callback Result', + 'Answer Action Query', + 'Delete Suggestion Message', + 'Send Callback Result' +] + +# Check nodes +for node in wf['nodes']: + assert node['name'] not in orphan_names, f'Orphan node still exists: {node[\"name\"]}' + +# Check connections +for name in orphan_names: + assert name not in wf['connections'], f'Orphan connection still exists: {name}' + +print('✓ No orphan node references remain') +" + +# Verify valid JSON structure +python3 -c " +import json +with open('n8n-workflow.json') as f: + json.load(f) +print('✓ Valid JSON structure') +" +``` + + +- n8n-workflow.json contains exactly 166 nodes +- All 6 orphan nodes removed from nodes array +- All 6 orphan connections removed from connections object +- JSON structure remains valid +- No references to orphan nodes remain in the workflow + + + + + Deploy cleaned workflow to n8n + n8n-workflow.json + +Push the cleaned workflow to n8n using the n8n API. + +Use the established push pattern from CLAUDE.md: +1. Source .env.n8n-api credentials +2. Prepare payload (strip `active` field - it's read-only) +3. PUT to main workflow ID: `HmiXBlJefBRPMS0m4iNYc` + +```bash +. .env.n8n-api + +python3 -c " +import json +with open('n8n-workflow.json') as f: + wf = json.load(f) +payload = { + 'name': wf.get('name', 'Docker Manager'), + 'nodes': wf['nodes'], + 'connections': wf['connections'], + 'settings': wf.get('settings', {}), +} +if wf.get('staticData'): + payload['staticData'] = wf['staticData'] +with open('/tmp/n8n-push-payload.json', 'w') as f: + json.dump(payload, f) +" + +CODE=$(curl -s -o /tmp/n8n-push-result.txt -w "%{http_code}" \ + -X PUT "${N8N_HOST}/api/v1/workflows/HmiXBlJefBRPMS0m4iNYc" \ + -H "X-N8N-API-KEY: ${N8N_API_KEY}" \ + -H "Content-Type: application/json" \ + -d @/tmp/n8n-push-payload.json) + +echo "Deployment result: HTTP ${CODE}" +``` + +Critical: Must source credentials in the same command chain as curl (each Bash call is a fresh shell). + + +```bash +# Verify deployment returned HTTP 200 +. .env.n8n-api +CODE=$(curl -s -o /tmp/n8n-verify.txt -w "%{http_code}" \ + "${N8N_HOST}/api/v1/workflows/HmiXBlJefBRPMS0m4iNYc" \ + -H "X-N8N-API-KEY: ${N8N_API_KEY}") + +echo "Verification: HTTP ${CODE}" + +# Extract and verify node count from deployed workflow +python3 -c " +import json +with open('/tmp/n8n-verify.txt') as f: + deployed = json.load(f) +node_count = len(deployed.get('nodes', [])) +print(f'Deployed node count: {node_count}') +assert node_count == 166, f'Expected 166 nodes, deployed has {node_count}' +print('✓ Deployment verified: 166 nodes') +" +``` + + +- Workflow deployed successfully (HTTP 200) +- Deployed workflow contains 166 nodes +- n8n instance reflects the cleaned workflow structure + + + + + Commit cleaned workflow + n8n-workflow.json + +Commit the cleaned workflow to git using gsd-tools commit helper. + +```bash +node /home/luc/.claude/get-shit-done/bin/gsd-tools.js commit \ + "refactor(workflow): remove orphan callback node chain (172→166 nodes)" \ + --files n8n-workflow.json +``` + +Commit message rationale: Removed 6 orphan nodes from legacy callback infrastructure (Build Callback Action, Execute Callback Action, Parse Callback Result, Answer Action Query, Delete Suggestion Message, Send Callback Result). These nodes had no incoming connections after Phase 10 modularization replaced callback execution with sub-workflow architecture. Achieves structural minimum of 166 nodes identified in Phase 10.1-07 analysis. + + +```bash +# Verify commit exists +git log -1 --oneline | grep "remove orphan callback node chain" + +# Verify n8n-workflow.json is in the commit +git show --name-only | grep "n8n-workflow.json" +``` + + +- Commit created with descriptive message +- n8n-workflow.json included in commit +- Git history shows the cleanup + + + + + + +## Overall Verification + +```bash +# Final state verification +python3 -c " +import json + +with open('n8n-workflow.json') as f: + wf = json.load(f) + +orphan_names = [ + 'Build Callback Action', + 'Execute Callback Action', + 'Parse Callback Result', + 'Answer Action Query', + 'Delete Suggestion Message', + 'Send Callback Result' +] + +node_count = len(wf['nodes']) +print(f'Node count: {node_count}') +assert node_count == 166, f'Expected 166 nodes, got {node_count}' + +# Verify no orphans in nodes +node_names = [n['name'] for n in wf['nodes']] +for name in orphan_names: + assert name not in node_names, f'Orphan node found: {name}' + +# Verify no orphans in connections +for name in orphan_names: + assert name not in wf['connections'], f'Orphan connection found: {name}' + +print('✓ All verification checks passed') +print('✓ Structural minimum of 166 nodes achieved') +print('✓ Orphan node chain fully removed') +" +``` + + + +- n8n-workflow.json contains exactly 166 nodes (structural minimum) +- All 6 orphan nodes removed (Build Callback Action chain) +- All orphan connections removed from connections object +- Workflow deployed successfully to n8n instance +- Changes committed to git with descriptive message +- No functional regressions (orphan nodes had no incoming connections) + + + +After completion, create `.planning/quick/1-remove-orphan-node-chain-starting-with-b/1-SUMMARY.md` +