feed-the-machine 1.7.14 → 1.7.16

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.
@@ -370,12 +370,12 @@ For EACH task, follow this cycle:
370
370
  - Review again
371
371
  - Repeat until clean
372
372
 
373
- 5. **Continue** — Move to the next task. Do not stop to ask questions. If something is ambiguous, make the best technical decision and document it in your commit message.
373
+ 5. **Continue** — HARD GATE: Before moving to the next task, verify a commit was made for this task. Run `git log --oneline -1` and confirm the most recent commit message matches what you just did. If there is no commit, STOP you skipped step 2. Go back and commit now. You CANNOT proceed to the next task without a commit. This is not optional.
374
374
 
375
375
  ## Rules
376
376
 
377
+ - NEVER move to the next task without committing the current one. Run `git log --oneline -1` to verify. No exceptions.
377
378
  - NEVER stop to ask for input. Make decisions and keep going.
378
- - ALWAYS commit after each task (not one big commit at the end).
379
379
  - ALWAYS review after each commit. The review-fix loop is not optional.
380
380
  - Follow the plan's steps exactly — don't improvise unless the plan is clearly wrong.
381
381
  - Stay in your worktree. Don't touch files outside your assigned scope.
@@ -51,42 +51,16 @@ If next move reveals new information → plan to re-enter Observe after.
51
51
 
52
52
  ## Act
53
53
 
54
- ### Pre-Act Checkpoint (HARD GATE)
54
+ ### Pre-Act Checkpoint
55
55
 
56
- Before executing ANYTHING — Bash, MCP, Write, Edit, API calls:
56
+ Before executing, verify:
57
57
 
58
- 1. **Checkbox plan presented?** Medium+ tasks require `N. [ ] action → target` format, approved by user. Prose is NOT a plan.
58
+ 1. **Checkbox plan presented?** Medium+ tasks require `N. [ ] action → target` format, approved by user.
59
59
  2. **User approved?** Wait for explicit go/approve/yes.
60
60
  3. **Plan marker written?** Write to `~/.claude/ftm-state/.plan-presented` after approval.
61
- 4. **External mutations approved?** Per Approval Gates in orient-protocol.
62
- 5. None apply (micro/small, no forced escalation) → proceed.
61
+ 4. None apply (micro/small, no forced escalation) proceed.
63
62
 
64
- | Rationalization | Reality |
65
- |---|---|
66
- | "Do as much as you can" = implicit approval | That's the task description, not plan approval |
67
- | "I know what to do, plan is overhead" | Plan is for the USER |
68
- | "Just one small API call first" | One becomes five becomes a full unplanned execution |
69
- | "User seems impatient" | 30-second plan saves 10 minutes of wrong work |
70
-
71
- Applies to ALL execution methods including Bash/curl/python. The plan-gate hook catches Edit/Write/MCP; this checkpoint catches everything else.
72
-
73
- ### Compare Before You Loop (MANDATORY for external systems)
74
-
75
- **Never trial-and-error. Always compare first.**
76
-
77
- 1. **Find working reference** — GET a resource that already works the way you want
78
- 2. **Diff** — compare field-by-field against the broken one. Fix is almost always a small, specific difference
79
- 3. **Targeted change** — change ONLY what the diff revealed. Verify after each change
80
-
81
- **Loop detection red flags:**
82
- - 3+ API calls to same system without success
83
- - Trying different URL formats (underscore vs hyphen, internal vs display ID)
84
- - Shuffling payload fields hoping one works
85
- - Reading API docs for endpoint paths (playbook should have this)
86
-
87
- **On detection:** STOP. Tell user: "Tried N approaches, none worked. Comparing against working reference." Do step 1.
88
-
89
- See `references/incidents.md` → Braintrust Incident for the cost of skipping this.
63
+ **Note**: The `ftm-guard` hook enforces approval gates, destructive action prevention, playbook checks, and loop detection at the tool-call level. You don't need to self-check these — the hook will stop you. But you should still present plans and get approval before acting.
90
64
 
91
65
  ### 1. Direct action
92
66
 
@@ -98,11 +72,11 @@ Show one routing line, then invoke: `Routing to ftm-debug: flaky failure with di
98
72
 
99
73
  ### 3. MCP execution
100
74
 
101
- Parallel reads, sequential writes, approval gates for external-facing actions.
75
+ Parallel reads, sequential writes. The ftm-guard hook handles approval gates for external-facing actions.
102
76
 
103
77
  ### 3.5 Draft-before-send
104
78
 
105
- Slack/email/outbound comms → save to `.ftm-drafts/` first. Filename: `YYYY-MM-DD_HH-MM_<type>_<recipient>.md`. Present for approval, update status on send/cancel.
79
+ Slack/email/outbound comms → save to `.ftm-drafts/` AND `~/.claude/ftm-ops/drafts/` first. Filename: `YYYY-MM-DD_HH-MM_<type>_<recipient>.md`. Present for approval, update status on send/cancel.
106
80
 
107
81
  ### 4. Blackboard updates (mandatory)
108
82
 
@@ -56,54 +56,6 @@ Look for the arc, not just the last message:
56
56
 
57
57
  Check: dirty worktree, recent commits, active branch, in-progress changes, conflicts with request. Clean tree = lower cost of direct action. Uncommitted changes = continuity and risk.
58
58
 
59
- ## Approval Gates (HARD STOP)
60
-
61
- **Circuit breaker. External mutations require explicit user approval. No exceptions.**
62
-
63
- See `references/incidents.md` → Hindsight Incident for why this exists.
64
-
65
- ### Requires approval (STOP before each)
66
-
67
- Every individual external mutation. "User approved the plan" ≠ "user approved every API call."
68
-
69
- - **Okta**: create apps/groups, assign users, modify policies
70
- - **Freshservice**: create tickets/records/catalog items/custom objects
71
- - **Jira/Confluence**: create/update issues, pages, comments
72
- - **Slack/Email**: send messages (draft-before-send applies)
73
- - **Calendar**: create/modify events
74
- - **S3/cloud**: write/modify objects
75
- - **Browser forms**: submit data
76
- - **Deploys**: any production-affecting operation
77
- - **Git remote**: push, PR creation
78
-
79
- Batch by phase — not per-call, not whole-plan.
80
-
81
- ### Destructive Actions (EXTRA HARD GATE)
82
-
83
- **NEVER delete/recreate external resources without per-resource user confirmation.**
84
-
85
- - DELETE any external resource
86
- - Recreate (delete + create) — new ID breaks all automation referencing the old one
87
- - Overwrite S3 objects other systems read
88
- - Remove users from groups, deactivate accounts
89
- - Close/resolve tickets others watch
90
-
91
- When you can't update via API: tell the user, suggest manual fix (admin UI link + steps). Only delete if user explicitly confirms with dependency awareness. See `references/incidents.md` → Braintrust Incident.
92
-
93
- ### Auto-proceeds (no approval)
94
-
95
- Local edits, tests, lint, builds, audits, local git, GET requests, blackboard reads/writes, saving drafts.
96
-
97
- ### Rationalization traps
98
-
99
- | Thought | Reality |
100
- |---|---|
101
- | "The user clearly wants this" | Present the action, wait for approval |
102
- | "It's part of the approved plan" | Each mutation needs its own gate |
103
- | "I already started" | Sunk cost. Stop and ask |
104
- | "Just one more API call" | That's how incidents start |
105
- | "User will appreciate proactivity" | User will appreciate not breaking things |
106
-
107
59
  ## Blackboard-First Rule (before any access/auth questions)
108
60
 
109
61
  Before asking about credentials, API access, or authorization:
@@ -148,8 +100,19 @@ Load active tasks, surface high-priority via TaskCreate. Skip if brain.py absent
148
100
  2. `ls docs/playbooks/` in current repo
149
101
  3. Blackboard experiences filtered by target system tags — check `code_patterns` and `api_gotchas`
150
102
 
151
- If any source has relevant content, read it before writing code. See `references/incidents.md` Braintrust Incident for what happens when you skip this.
103
+ If any source has relevant content, read it before writing code. After checking, write a marker: `~/.claude/ftm-state/.playbook-checked-{system}` so the ftm-guard hook knows you checked.
152
104
 
153
105
  ## Orient Synthesis
154
106
 
155
107
  Before leaving Orient, have one clear internal picture: what the user wants, task type, session continuity, codebase constraints, relevant lessons/patterns, capability mix, correct task size, whether approval or clarification is needed. Orient is complete when the next move feels obvious.
108
+
109
+ ## Safety Protocols
110
+
111
+ **Approval gates, destructive action prevention, compare-before-you-loop, and loop detection are enforced by the `ftm-guard` hook**, which fires on every mutating tool call automatically. You do not need to self-enforce these — the hook will inject warnings if you're about to do something dangerous. But you should still be aware of them:
112
+
113
+ - External mutations need user approval per-phase (not per-call, not whole-plan)
114
+ - Destructive actions (delete, recreate) need per-resource confirmation
115
+ - 3+ failed API calls = stop and compare against a working reference
116
+ - Never trial-and-error; always diff a working resource first
117
+
118
+ See `references/incidents.md` for the full incident history behind these rules.
@@ -0,0 +1,121 @@
1
+ #!/bin/sh
2
+ # ftm-guard.sh
3
+ # Safety system for all Claude Code sessions with ftm installed.
4
+ # Fires on PreToolUse for mutating tools. Injects safety context
5
+ # before Claude executes external mutations, destructive actions,
6
+ # or enters trial-and-error loops.
7
+ #
8
+ # Hook: PreToolUse (matcher: Edit|Write|Bash|mcp__*)
9
+ #
10
+ # This is NOT gated on ftm session state — it protects ALL sessions.
11
+
12
+ set -eu
13
+
14
+ INPUT=$(cat)
15
+ TOOL_NAME=$(echo "$INPUT" | jq -r '.tool_name // ""' 2>/dev/null)
16
+
17
+ # Only gate mutating operations
18
+ IS_MUTATING=false
19
+
20
+ case "$TOOL_NAME" in
21
+ Edit|Write) IS_MUTATING=true ;;
22
+ Bash)
23
+ # Check if the bash command contains mutating API patterns
24
+ COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // ""' 2>/dev/null)
25
+ case "$COMMAND" in
26
+ *deleteFS*|*delete_custom_object*|*DELETE*|*putFS*|*postFS*) IS_MUTATING=true ;;
27
+ *"curl -X DELETE"*|*"curl -X PUT"*|*"curl -X POST"*|*"curl -X PATCH"*) IS_MUTATING=true ;;
28
+ *"requests.delete"*|*"requests.put"*|*"requests.post"*|*"requests.patch"*) IS_MUTATING=true ;;
29
+ esac
30
+ ;;
31
+ esac
32
+
33
+ # Also catch mutating MCP calls
34
+ case "$TOOL_NAME" in
35
+ mcp__*create*|mcp__*update*|mcp__*delete*|mcp__*send*|mcp__*add*|mcp__*remove*|mcp__*apply*|mcp__*transition*|mcp__*commit*|mcp__*push*|mcp__*post_message*|mcp__*reply*|mcp__*modify*|mcp__*batch*|mcp__*convert*)
36
+ IS_MUTATING=true ;;
37
+ esac
38
+
39
+ if [ "$IS_MUTATING" != "true" ]; then
40
+ exit 0
41
+ fi
42
+
43
+ # --- Build safety context based on what's about to happen ---
44
+
45
+ FTM_STATE="$HOME/.claude/ftm-state"
46
+ CONTEXT_PARTS=""
47
+
48
+ # Check 1: Is this a destructive action?
49
+ IS_DESTRUCTIVE=false
50
+ case "$TOOL_NAME" in
51
+ mcp__*delete*|mcp__*remove*) IS_DESTRUCTIVE=true ;;
52
+ esac
53
+ case "${COMMAND:-}" in
54
+ *deleteFS*|*delete_custom_object*|*"curl -X DELETE"*|*"requests.delete"*|*DELETE*) IS_DESTRUCTIVE=true ;;
55
+ esac
56
+
57
+ if [ "$IS_DESTRUCTIVE" = "true" ]; then
58
+ CONTEXT_PARTS="$CONTEXT_PARTS [DESTRUCTIVE ACTION GATE] You are about to DELETE an external resource. STOP. Confirm with the user FIRST — name the specific resource being deleted and warn about downstream dependencies (workflow configs, automation references, lookup fields). Never delete-and-recreate to fix something. See ftm-mind/references/incidents.md -> Braintrust Incident."
59
+ fi
60
+
61
+ # Check 2: Is there a playbook for this system?
62
+ SYSTEM=""
63
+ case "$TOOL_NAME" in
64
+ mcp__freshservice*) SYSTEM="freshservice" ;;
65
+ mcp__mcp-atlassian*) SYSTEM="jira" ;;
66
+ mcp__slack*) SYSTEM="slack" ;;
67
+ mcp__gmail*) SYSTEM="gmail" ;;
68
+ esac
69
+ # Also detect from bash commands
70
+ case "${COMMAND:-}" in
71
+ *freshservice*|*getFS*|*putFS*|*postFS*|*deleteFS*) SYSTEM="freshservice" ;;
72
+ *okta*|*OktaGroup*|*OktaUser*) SYSTEM="okta" ;;
73
+ esac
74
+
75
+ if [ -n "$SYSTEM" ]; then
76
+ # Check if playbook was consulted this session
77
+ PLAYBOOK_MARKER="$FTM_STATE/.playbook-checked-$SYSTEM"
78
+ if [ ! -f "$PLAYBOOK_MARKER" ]; then
79
+ CONTEXT_PARTS="$CONTEXT_PARTS [PLAYBOOK CHECK] You are calling $SYSTEM APIs. Did you check for playbooks FIRST? Run: brain.py --playbook-match and check docs/playbooks/ and blackboard experiences with code_patterns. If you haven't, STOP and check now. Write to $PLAYBOOK_MARKER after checking."
80
+ fi
81
+ fi
82
+
83
+ # Check 3: Loop detection — count recent failures for this system
84
+ ERROR_TRACKER="$FTM_STATE/.error-tracker.jsonl"
85
+ if [ -f "$ERROR_TRACKER" ] && [ -n "$SYSTEM" ]; then
86
+ NOW=$(date +%s)
87
+ RECENT_ERRORS=$(python3 -c "
88
+ import json
89
+ count = 0
90
+ cutoff = $NOW - 600
91
+ for line in open('$ERROR_TRACKER'):
92
+ line = line.strip()
93
+ if not line: continue
94
+ try:
95
+ ev = json.loads(line)
96
+ if ev.get('module','').lower().find('$SYSTEM') >= 0 and ev.get('type') == 'error' and ev.get('ts',0) >= cutoff:
97
+ count += 1
98
+ except: pass
99
+ print(count)
100
+ " 2>/dev/null || echo "0")
101
+
102
+ if [ "$RECENT_ERRORS" -ge 3 ]; then
103
+ CONTEXT_PARTS="$CONTEXT_PARTS [LOOP DETECTED] $RECENT_ERRORS recent errors on $SYSTEM in the last 10 minutes. STOP trial-and-error. Find a WORKING reference resource, GET it, diff field-by-field against the broken one, and make targeted changes. The answer is in the diff, not in your next guess."
104
+ fi
105
+ fi
106
+
107
+ # Output combined safety context if any checks triggered
108
+ if [ -n "$CONTEXT_PARTS" ]; then
109
+ # Escape for JSON
110
+ ESCAPED=$(echo "$CONTEXT_PARTS" | sed 's/"/\\"/g' | tr '\n' ' ')
111
+ cat <<JSONEOF
112
+ {
113
+ "hookSpecificOutput": {
114
+ "hookEventName": "PreToolUse",
115
+ "additionalContext": "[ftm-guard]$ESCAPED"
116
+ }
117
+ }
118
+ JSONEOF
119
+ fi
120
+
121
+ exit 0
@@ -22,6 +22,16 @@
22
22
  "timeout": 5
23
23
  }
24
24
  ]
25
+ },
26
+ {
27
+ "matcher": "Bash|mcp__freshservice-mcp|mcp__mcp-atlassian|mcp__slack|mcp__gmail|mcp__git",
28
+ "hooks": [
29
+ {
30
+ "type": "command",
31
+ "command": "~/.claude/hooks/ftm-guard.sh",
32
+ "timeout": 5
33
+ }
34
+ ]
25
35
  }
26
36
  ],
27
37
  "UserPromptSubmit": [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "feed-the-machine",
3
- "version": "1.7.14",
3
+ "version": "1.7.16",
4
4
  "description": "A brain upgrade for Claude Code — 26 skills that teach it how to think before acting, remember across conversations, debug like a war room, run plans on autopilot with agent teams, and get second opinions from GPT & Gemini. Plus 15 hooks that automate the boring stuff.",
5
5
  "license": "MIT",
6
6
  "author": "kkudumu",