feed-the-machine 1.0.0 → 1.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.
Files changed (136) hide show
  1. package/bin/generate-manifest.mjs +253 -0
  2. package/bin/install.mjs +134 -4
  3. package/docs/HOOKS.md +243 -0
  4. package/docs/INBOX.md +233 -0
  5. package/ftm/SKILL.md +34 -0
  6. package/ftm-audit/SKILL.md +69 -0
  7. package/ftm-brainstorm/SKILL.md +51 -0
  8. package/ftm-browse/SKILL.md +39 -0
  9. package/ftm-capture/SKILL.md +370 -0
  10. package/ftm-capture.yml +4 -0
  11. package/ftm-codex-gate/SKILL.md +59 -0
  12. package/ftm-config/SKILL.md +35 -0
  13. package/ftm-council/SKILL.md +56 -0
  14. package/ftm-dashboard/SKILL.md +163 -0
  15. package/ftm-debug/SKILL.md +84 -0
  16. package/ftm-diagram/SKILL.md +44 -0
  17. package/ftm-executor/SKILL.md +97 -0
  18. package/ftm-git/SKILL.md +60 -0
  19. package/ftm-inbox/backend/__init__.py +0 -0
  20. package/ftm-inbox/backend/__pycache__/main.cpython-314.pyc +0 -0
  21. package/ftm-inbox/backend/adapters/__init__.py +0 -0
  22. package/ftm-inbox/backend/adapters/_retry.py +64 -0
  23. package/ftm-inbox/backend/adapters/base.py +230 -0
  24. package/ftm-inbox/backend/adapters/freshservice.py +104 -0
  25. package/ftm-inbox/backend/adapters/gmail.py +125 -0
  26. package/ftm-inbox/backend/adapters/jira.py +136 -0
  27. package/ftm-inbox/backend/adapters/registry.py +192 -0
  28. package/ftm-inbox/backend/adapters/slack.py +110 -0
  29. package/ftm-inbox/backend/db/__init__.py +0 -0
  30. package/ftm-inbox/backend/db/connection.py +54 -0
  31. package/ftm-inbox/backend/db/schema.py +78 -0
  32. package/ftm-inbox/backend/executor/__init__.py +7 -0
  33. package/ftm-inbox/backend/executor/engine.py +149 -0
  34. package/ftm-inbox/backend/executor/step_runner.py +98 -0
  35. package/ftm-inbox/backend/main.py +103 -0
  36. package/ftm-inbox/backend/models/__init__.py +1 -0
  37. package/ftm-inbox/backend/models/unified_task.py +36 -0
  38. package/ftm-inbox/backend/planner/__init__.py +6 -0
  39. package/ftm-inbox/backend/planner/__pycache__/__init__.cpython-314.pyc +0 -0
  40. package/ftm-inbox/backend/planner/__pycache__/generator.cpython-314.pyc +0 -0
  41. package/ftm-inbox/backend/planner/__pycache__/schema.cpython-314.pyc +0 -0
  42. package/ftm-inbox/backend/planner/generator.py +127 -0
  43. package/ftm-inbox/backend/planner/schema.py +34 -0
  44. package/ftm-inbox/backend/requirements.txt +5 -0
  45. package/ftm-inbox/backend/routes/__init__.py +0 -0
  46. package/ftm-inbox/backend/routes/__pycache__/plan.cpython-314.pyc +0 -0
  47. package/ftm-inbox/backend/routes/execute.py +186 -0
  48. package/ftm-inbox/backend/routes/health.py +52 -0
  49. package/ftm-inbox/backend/routes/inbox.py +68 -0
  50. package/ftm-inbox/backend/routes/plan.py +271 -0
  51. package/ftm-inbox/bin/launchagent.mjs +91 -0
  52. package/ftm-inbox/bin/setup.mjs +188 -0
  53. package/ftm-inbox/bin/start.sh +10 -0
  54. package/ftm-inbox/bin/status.sh +17 -0
  55. package/ftm-inbox/bin/stop.sh +8 -0
  56. package/ftm-inbox/config.example.yml +55 -0
  57. package/ftm-inbox/package-lock.json +2898 -0
  58. package/ftm-inbox/package.json +26 -0
  59. package/ftm-inbox/postcss.config.js +6 -0
  60. package/ftm-inbox/src/app.css +199 -0
  61. package/ftm-inbox/src/app.html +18 -0
  62. package/ftm-inbox/src/lib/api.ts +166 -0
  63. package/ftm-inbox/src/lib/components/ExecutionLog.svelte +81 -0
  64. package/ftm-inbox/src/lib/components/InboxFeed.svelte +143 -0
  65. package/ftm-inbox/src/lib/components/PlanStep.svelte +271 -0
  66. package/ftm-inbox/src/lib/components/PlanView.svelte +206 -0
  67. package/ftm-inbox/src/lib/components/StreamPanel.svelte +99 -0
  68. package/ftm-inbox/src/lib/components/TaskCard.svelte +190 -0
  69. package/ftm-inbox/src/lib/components/ui/EmptyState.svelte +63 -0
  70. package/ftm-inbox/src/lib/components/ui/KawaiiCard.svelte +86 -0
  71. package/ftm-inbox/src/lib/components/ui/PillButton.svelte +106 -0
  72. package/ftm-inbox/src/lib/components/ui/StatusBadge.svelte +67 -0
  73. package/ftm-inbox/src/lib/components/ui/StreamDrawer.svelte +149 -0
  74. package/ftm-inbox/src/lib/components/ui/ThemeToggle.svelte +80 -0
  75. package/ftm-inbox/src/lib/theme.ts +47 -0
  76. package/ftm-inbox/src/routes/+layout.svelte +76 -0
  77. package/ftm-inbox/src/routes/+page.svelte +401 -0
  78. package/ftm-inbox/static/favicon.png +0 -0
  79. package/ftm-inbox/svelte.config.js +12 -0
  80. package/ftm-inbox/tailwind.config.ts +63 -0
  81. package/ftm-inbox/tsconfig.json +13 -0
  82. package/ftm-inbox/vite.config.ts +6 -0
  83. package/ftm-intent/SKILL.md +44 -0
  84. package/ftm-manifest.json +3794 -0
  85. package/ftm-map/SKILL.md +259 -0
  86. package/ftm-map/scripts/db.py +391 -0
  87. package/ftm-map/scripts/index.py +341 -0
  88. package/ftm-map/scripts/parser.py +455 -0
  89. package/ftm-map/scripts/queries/.gitkeep +0 -0
  90. package/ftm-map/scripts/queries/javascript-tags.scm +23 -0
  91. package/ftm-map/scripts/queries/python-tags.scm +17 -0
  92. package/ftm-map/scripts/queries/typescript-tags.scm +29 -0
  93. package/ftm-map/scripts/query.py +149 -0
  94. package/ftm-map/scripts/requirements.txt +2 -0
  95. package/ftm-map/scripts/setup-hooks.sh +27 -0
  96. package/ftm-map/scripts/setup.sh +45 -0
  97. package/ftm-map/scripts/test_db.py +124 -0
  98. package/ftm-map/scripts/test_parser.py +106 -0
  99. package/ftm-map/scripts/test_query.py +66 -0
  100. package/ftm-map/scripts/tests/fixtures/__init__.py +0 -0
  101. package/ftm-map/scripts/tests/fixtures/sample_project/api.ts +16 -0
  102. package/ftm-map/scripts/tests/fixtures/sample_project/auth.py +15 -0
  103. package/ftm-map/scripts/tests/fixtures/sample_project/utils.js +16 -0
  104. package/ftm-map/scripts/views.py +545 -0
  105. package/ftm-mind/SKILL.md +173 -66
  106. package/ftm-pause/SKILL.md +43 -0
  107. package/ftm-researcher/SKILL.md +275 -0
  108. package/ftm-researcher/evals/agent-diversity.yaml +17 -0
  109. package/ftm-researcher/evals/synthesis-quality.yaml +12 -0
  110. package/ftm-researcher/evals/trigger-accuracy.yaml +39 -0
  111. package/ftm-researcher/references/adaptive-search.md +116 -0
  112. package/ftm-researcher/references/agent-prompts.md +193 -0
  113. package/ftm-researcher/references/council-integration.md +193 -0
  114. package/ftm-researcher/references/output-format.md +203 -0
  115. package/ftm-researcher/references/synthesis-pipeline.md +165 -0
  116. package/ftm-researcher/scripts/score_credibility.py +234 -0
  117. package/ftm-researcher/scripts/validate_research.py +92 -0
  118. package/ftm-resume/SKILL.md +47 -0
  119. package/ftm-retro/SKILL.md +54 -0
  120. package/ftm-routine/SKILL.md +170 -0
  121. package/ftm-state/blackboard/capabilities.json +5 -0
  122. package/ftm-state/blackboard/capabilities.schema.json +27 -0
  123. package/ftm-upgrade/SKILL.md +41 -0
  124. package/ftm-upgrade/scripts/check-version.sh +1 -1
  125. package/ftm-upgrade/scripts/upgrade.sh +1 -1
  126. package/hooks/ftm-blackboard-enforcer.sh +94 -0
  127. package/hooks/ftm-discovery-reminder.sh +90 -0
  128. package/hooks/ftm-drafts-gate.sh +61 -0
  129. package/hooks/ftm-event-logger.mjs +107 -0
  130. package/hooks/ftm-map-autodetect.sh +79 -0
  131. package/hooks/ftm-pending-sync-check.sh +22 -0
  132. package/hooks/ftm-plan-gate.sh +96 -0
  133. package/hooks/ftm-post-commit-trigger.sh +57 -0
  134. package/hooks/settings-template.json +81 -0
  135. package/install.sh +140 -11
  136. package/package.json +12 -2
package/docs/INBOX.md ADDED
@@ -0,0 +1,233 @@
1
+ # ftm-inbox
2
+
3
+ ftm-inbox is an optional background service that polls your work tools (Jira, Freshservice, Slack, Gmail) and surfaces actionable items directly inside the FTM Operator Cockpit dashboard. It runs locally on your machine and never sends data to external services.
4
+
5
+ ## What It Does
6
+
7
+ Without ftm-inbox, the Operator Cockpit is a static interface. With it:
8
+
9
+ - Jira issues assigned to you appear as inbox items
10
+ - Freshservice tickets awaiting your response are surfaced
11
+ - Slack DMs and mentions are queued for triage
12
+ - Gmail threads that match configurable filters are included
13
+
14
+ Each item is stored in a local SQLite database. The FTM skills (`/ftm-mind`, `/ftm-executor`) can read from this inbox to generate plans and take action on your behalf.
15
+
16
+ ## Installation
17
+
18
+ ```bash
19
+ npx feed-the-machine --with-inbox
20
+ ```
21
+
22
+ This will:
23
+
24
+ 1. Install core FTM skills (same as `npx feed-the-machine`)
25
+ 2. Copy `ftm-inbox/` to `~/.claude/ftm-inbox/`
26
+ 3. Run `npm install` for Node dependencies
27
+ 4. Run `pip3 install -r requirements.txt` for Python dependencies
28
+ 5. Launch the interactive setup wizard
29
+ 6. Optionally install a macOS LaunchAgent for auto-start on login
30
+
31
+ The core `npx feed-the-machine` install (without `--with-inbox`) is completely unchanged.
32
+
33
+ ### Requirements
34
+
35
+ - Node.js 18+
36
+ - Python 3.9+
37
+ - `pip3` in PATH
38
+
39
+ ## Configuration
40
+
41
+ The setup wizard writes credentials to `~/.claude/ftm-inbox/config.yml`. This directory is outside any git repository and should never be committed.
42
+
43
+ ### config.yml reference
44
+
45
+ ```yaml
46
+ server:
47
+ port: 8042 # Port for the local API (default: 8042)
48
+
49
+ adapters:
50
+ jira:
51
+ enabled: true
52
+ base_url: "https://yourorg.atlassian.net"
53
+ email: "you@example.com"
54
+ api_token: "your-jira-api-token"
55
+ poll_interval_seconds: 60
56
+
57
+ freshservice:
58
+ enabled: true
59
+ domain: "yourorg.freshservice.com"
60
+ api_key: "your-freshservice-api-key"
61
+ poll_interval_seconds: 120
62
+
63
+ slack:
64
+ enabled: true
65
+ bot_token: "xoxb-your-slack-bot-token"
66
+ poll_interval_seconds: 30
67
+
68
+ gmail:
69
+ enabled: false
70
+ credentials_path: "~/credentials.json"
71
+ poll_interval_seconds: 120
72
+
73
+ database:
74
+ path: "~/.claude/ftm-inbox/inbox.db"
75
+
76
+ logging:
77
+ level: "INFO"
78
+ path: "~/.claude/ftm-inbox/logs"
79
+ ```
80
+
81
+ To re-run the wizard after initial setup:
82
+
83
+ ```bash
84
+ node ~/.claude/ftm-inbox/bin/setup.mjs
85
+ ```
86
+
87
+ To edit manually:
88
+
89
+ ```bash
90
+ $EDITOR ~/.claude/ftm-inbox/config.yml
91
+ ```
92
+
93
+ ## Starting and Stopping
94
+
95
+ ```bash
96
+ # Start the service
97
+ ~/.claude/ftm-inbox/bin/start.sh
98
+
99
+ # Stop the service
100
+ ~/.claude/ftm-inbox/bin/stop.sh
101
+
102
+ # Check status and last poll times
103
+ ~/.claude/ftm-inbox/bin/status.sh
104
+ ```
105
+
106
+ The port can be overridden at runtime:
107
+
108
+ ```bash
109
+ FTM_INBOX_PORT=9000 ~/.claude/ftm-inbox/bin/start.sh
110
+ ```
111
+
112
+ ## Auto-start on Login (macOS)
113
+
114
+ To generate and load a LaunchAgent that starts ftm-inbox on login:
115
+
116
+ ```bash
117
+ node ~/.claude/ftm-inbox/bin/launchagent.mjs
118
+ ```
119
+
120
+ This creates `~/Library/LaunchAgents/com.ftm.inbox.plist` and loads it immediately. Logs are written to `~/.claude/ftm-inbox/logs/`.
121
+
122
+ To remove the LaunchAgent:
123
+
124
+ ```bash
125
+ launchctl unload ~/Library/LaunchAgents/com.ftm.inbox.plist
126
+ rm ~/Library/LaunchAgents/com.ftm.inbox.plist
127
+ ```
128
+
129
+ ## Architecture
130
+
131
+ ```
132
+ External Services ftm-inbox FTM Skills
133
+ ────────────────── ───────────────────────── ──────────────────
134
+ Jira REST API ──────► Jira Adapter (poller) ─┐
135
+ Freshservice API ──────► Freshservice Adapter ─┤► SQLite DB ──► FastAPI ──► /ftm-mind
136
+ Slack API ──────► Slack Adapter ─┤ inbox.db 8042 /ftm-executor
137
+ Gmail API ──────► Gmail Adapter ─┘
138
+
139
+
140
+ Svelte Dashboard
141
+ (Operator Cockpit)
142
+ ```
143
+
144
+ - **Adapters** poll their respective APIs on configurable intervals and write normalized `InboxItem` records to SQLite
145
+ - **FastAPI backend** (`backend/main.py`) exposes a REST API at `http://localhost:8042`
146
+ - **Svelte dashboard** reads from the API and renders the Operator Cockpit UI
147
+ - **FTM skills** use the API to read inbox items and generate or execute plans
148
+
149
+ ## Adding a Custom Poller
150
+
151
+ 1. Create a new file in `ftm-inbox/backend/adapters/`:
152
+
153
+ ```python
154
+ # ftm-inbox/backend/adapters/my_service.py
155
+ from .base import BaseAdapter, InboxItem
156
+ from typing import List
157
+
158
+ class MyServiceAdapter(BaseAdapter):
159
+ name = "my_service"
160
+
161
+ async def fetch(self) -> List[InboxItem]:
162
+ # Hit your API, return a list of InboxItem objects
163
+ items = []
164
+ # ... your logic here ...
165
+ return items
166
+ ```
167
+
168
+ 2. Add credentials to `~/.claude/ftm-inbox/config.yml`:
169
+
170
+ ```yaml
171
+ adapters:
172
+ my_service:
173
+ enabled: true
174
+ api_key: "your-key"
175
+ poll_interval_seconds: 60
176
+ ```
177
+
178
+ 3. Register it in `ftm-inbox/backend/adapters/__init__.py`:
179
+
180
+ ```python
181
+ from .my_service import MyServiceAdapter
182
+ ADAPTERS = [..., MyServiceAdapter]
183
+ ```
184
+
185
+ 4. Restart the service: `~/.claude/ftm-inbox/bin/stop.sh && ~/.claude/ftm-inbox/bin/start.sh`
186
+
187
+ ## Troubleshooting
188
+
189
+ ### Service won't start
190
+
191
+ Check that Python 3 and uvicorn are installed:
192
+ ```bash
193
+ python3 --version
194
+ python3 -c "import uvicorn; print(uvicorn.__version__)"
195
+ ```
196
+
197
+ If uvicorn is missing:
198
+ ```bash
199
+ pip3 install -r ~/.claude/ftm-inbox/requirements.txt
200
+ ```
201
+
202
+ ### No items appearing in the dashboard
203
+
204
+ 1. Check the service is running: `~/.claude/ftm-inbox/bin/status.sh`
205
+ 2. Check logs: `tail -f ~/.claude/ftm-inbox/logs/*.log`
206
+ 3. Verify credentials in `~/.claude/ftm-inbox/config.yml`
207
+ 4. Confirm the adapter is set to `enabled: true`
208
+
209
+ ### Port conflict
210
+
211
+ If port 8042 is already in use:
212
+ ```bash
213
+ FTM_INBOX_PORT=9042 ~/.claude/ftm-inbox/bin/start.sh
214
+ ```
215
+
216
+ Update `config.yml` to match so the dashboard connects to the right port.
217
+
218
+ ### Jira authentication errors
219
+
220
+ Jira Cloud requires an API token, not your password. Generate one at:
221
+ `https://id.atlassian.com/manage-profile/security/api-tokens`
222
+
223
+ ### Freshservice 403 errors
224
+
225
+ Ensure the API key belongs to an agent with at least Viewer permissions on the relevant groups.
226
+
227
+ ### Re-running setup
228
+
229
+ ```bash
230
+ node ~/.claude/ftm-inbox/bin/setup.mjs
231
+ ```
232
+
233
+ This overwrites `~/.claude/ftm-inbox/config.yml` but does not touch the database.
package/ftm/SKILL.md CHANGED
@@ -33,6 +33,7 @@ If input starts with a recognized skill name, route directly to that skill:
33
33
  | `upgrade` | ftm-upgrade |
34
34
  | `retro` | ftm-retro |
35
35
  | `config` | ftm-config |
36
+ | `capture`, `codify`, `save as routine` | ftm-capture |
36
37
  | `mind` | ftm-mind |
37
38
 
38
39
  When routing to a specific skill:
@@ -77,6 +78,7 @@ FTM Skills:
77
78
  /ftm upgrade — Check for and install skill updates
78
79
  /ftm retro — Post-execution retrospective
79
80
  /ftm config — View and edit ftm configuration
81
+ /ftm capture [name] — Extract routine + playbook from current session
80
82
 
81
83
  Or just describe what you need and ftm-mind will handle it.
82
84
  ```
@@ -86,3 +88,35 @@ Or just describe what you need and ftm-mind will handle it.
86
88
  - Do not attempt to do the work yourself — route only.
87
89
  - Be fast — decisive routing, not conversation.
88
90
  - Case insensitive matching for all prefix detection.
91
+
92
+ ## Requirements
93
+
94
+ - config: `~/.claude/ftm-config.yml` | optional | legacy_router_fallback setting
95
+ - reference: `~/.claude/ftm-state/blackboard/context.json` | optional | session state for blackboard update on routing
96
+ - tool: none beyond skill invocation mechanism
97
+
98
+ ## Risk
99
+
100
+ - level: read_only
101
+ - scope: reads blackboard context.json and updates session_metadata.skills_invoked before routing; does not modify any project files
102
+ - rollback: no mutations to reverse; blackboard update is a metadata append
103
+
104
+ ## Approval Gates
105
+
106
+ - trigger: ftm-mind failure AND legacy_router_fallback enabled | action: fall back to keyword routing automatically (no user gate needed)
107
+ - complexity_routing: micro → auto | small → auto | medium → auto | large → auto | xl → auto
108
+
109
+ ## Fallbacks
110
+
111
+ - condition: ftm-mind fails or times out | action: check legacy_router_fallback in ftm-config.yml; if true, use keyword matching; if false, report failure
112
+ - condition: blackboard context.json missing | action: skip blackboard update, proceed with routing
113
+ - condition: skill tool unavailable for target skill | action: report routing failure to user with the target skill name
114
+
115
+ ## Capabilities
116
+
117
+ - env: none required
118
+
119
+ ## Event Payloads
120
+
121
+ ### (none)
122
+ ftm is a pure router and does not emit events directly. Events are emitted by the target skill after routing.
@@ -144,3 +144,72 @@ After completing:
144
144
  ## Report Format
145
145
 
146
146
  See `references/templates/REPORT-FORMAT.md` for the full report template (summary, changelog table, layer-by-layer finding format with examples).
147
+
148
+ ## Requirements
149
+
150
+ - tool: `knip` | optional | static dead-code and unused-export analysis (Layer 1)
151
+ - tool: `node` | required | runtime for knip via npx
152
+ - config: `knip.config.ts` | optional | custom knip configuration at project root
153
+ - reference: `references/protocols/PROJECT-PATTERNS.md` | required | framework detection table and dimension activation matrix
154
+ - reference: `references/strategies/AUTO-FIX-STRATEGIES.md` | required | fix actions by finding type
155
+ - reference: `references/protocols/WIRING-CONTRACTS.md` | optional | wiring contract schema for plan-driven audits
156
+ - reference: `references/protocols/RUNTIME-WIRING.md` | optional | runtime verification protocol
157
+ - reference: `references/templates/REPORT-FORMAT.md` | required | structured report template
158
+ - tool: `$HOME/.claude/skills/ftm-browse/bin/ftm-browse` | optional | runtime wiring verification via browser (Phase 3)
159
+
160
+ ## Risk
161
+
162
+ - level: medium_write
163
+ - scope: modifies source files to fix wiring issues (auto-fix layer); also adds/removes imports and route registrations; reads codebase broadly
164
+ - rollback: git checkout on auto-fixed files; all changes are tracked in the changelog report before being applied
165
+
166
+ ## Approval Gates
167
+
168
+ - trigger: auto-fix proposed for a finding | action: report proposed change before applying (show "Proposed: ..." format)
169
+ - trigger: finding flagged MANUAL_INTERVENTION_NEEDED | action: surface to user with suggested action, do not auto-fix
170
+ - trigger: re-verification still fails after 3 iterations | action: stop and report remaining issues to user
171
+ - complexity_routing: micro → auto | small → auto | medium → plan_first | large → plan_first | xl → always_ask
172
+
173
+ ## Fallbacks
174
+
175
+ - condition: knip not installed and npx unavailable | action: skip Layer 1, run Layer 2 adversarial audit only
176
+ - condition: no package.json found | action: skip knip entirely, run adversarial audit only
177
+ - condition: ftm-browse not installed | action: skip Phase 3 runtime wiring check, log reason and continue
178
+ - condition: dev server not running | action: skip Phase 3 runtime wiring check, log reason and continue
179
+ - condition: wiring contracts absent | action: run pure Layer 1 + Layer 2 analysis without contract checking
180
+ - condition: project has no identifiable entry point | action: skip knip, run adversarial audit only
181
+
182
+ ## Capabilities
183
+
184
+ - cli: `knip` | optional | dead code detection via npx knip
185
+ - cli: `node` | required | JavaScript runtime for npx
186
+ - cli: `$HOME/.claude/skills/ftm-browse/bin/ftm-browse` | optional | headless browser for runtime wiring
187
+ - mcp: `git` | optional | diff scope for Layer 2 adversarial audit
188
+
189
+ ## Event Payloads
190
+
191
+ ### audit_complete
192
+ - skill: string — "ftm-audit"
193
+ - findings_count: number — total issues found across all layers
194
+ - auto_fixed_count: number — issues auto-remediated by Layer 3
195
+ - manual_count: number — issues requiring manual intervention
196
+ - scope: string[] — file paths audited
197
+ - duration_ms: number — total audit duration
198
+ - layers_run: string[] — which layers executed (e.g., ["layer1", "layer2", "layer3"])
199
+
200
+ ### issue_found
201
+ - skill: string — "ftm-audit"
202
+ - layer: string — "layer1" | "layer2" | "layer3"
203
+ - dimension: string — D1 | D2 | D3 | D4 | D5 (for Layer 2 findings)
204
+ - finding_type: string — exports | types | duplicates | UNWIRED_COMPONENT | etc.
205
+ - file_path: string — affected file
206
+ - symbol: string — affected symbol name
207
+ - severity: string — CRITICAL | HIGH | MEDIUM | LOW
208
+ - auto_fixable: boolean — whether Layer 3 can fix this automatically
209
+
210
+ ### task_completed
211
+ - skill: string — "ftm-audit"
212
+ - result: string — "pass" | "pass_with_fixes" | "fail"
213
+ - findings_count: number — total findings
214
+ - auto_fixed_count: number — auto-remediated count
215
+ - manual_count: number — manual intervention needed
@@ -377,3 +377,54 @@ After completing, update:
377
377
  3. Update `experiences/index.json` with the new entry
378
378
  4. Emit `plan_generated` with `{ plan_path, plan_title, task_count, wave_count }` (if Phase 3 completed)
379
379
  5. Emit `task_completed` with `{ task_title, plan_path, duration_ms }`
380
+
381
+ ## Requirements
382
+
383
+ - config: `~/.claude/ftm-config.yml` | optional | model profile for planning agents
384
+ - reference: `references/agent-prompts.md` | required | research agent prompt templates
385
+ - reference: `references/plan-template.md` | required | plan document generation template
386
+ - reference: `~/.claude/ftm-state/blackboard/context.json` | optional | session state and active constraints
387
+ - reference: `~/.claude/ftm-state/blackboard/experiences/index.json` | optional | past brainstorm lessons
388
+ - reference: `~/.claude/ftm-state/blackboard/patterns.json` | optional | execution and user behavior patterns
389
+
390
+ ## Risk
391
+
392
+ - level: low_write
393
+ - scope: writes plan documents to ~/.claude/plans/; writes blackboard context and experience files; does not modify project source code
394
+ - rollback: delete generated plan file; blackboard writes can be reverted by editing JSON files
395
+
396
+ ## Approval Gates
397
+
398
+ - trigger: Phase 3 plan generation ready | action: present "Here's what I think we've landed on" summary and wait for explicit user approval before generating plan
399
+ - trigger: plan document generated | action: present plan incrementally (vision → tasks → agents/waves) and get approval at each step
400
+ - trigger: research returns thin results on all agents | action: note research gaps, present fewer suggestions, do not fabricate citations
401
+ - complexity_routing: micro → auto | small → auto | medium → plan_first | large → plan_first | xl → always_ask
402
+
403
+ ## Fallbacks
404
+
405
+ - condition: ftm-researcher not available | action: dispatch 3 direct parallel research agents (web/github/competitive) using built-in prompts from references/agent-prompts.md
406
+ - condition: no git repo detected in Phase 0 | action: skip repo scan, ask about tech stack during intake
407
+ - condition: blackboard missing or empty | action: proceed without experience-informed shortcuts, rely on direct analysis
408
+ - condition: ftm-config.yml missing | action: use session default model for all agents
409
+
410
+ ## Capabilities
411
+
412
+ - mcp: `WebSearch` | optional | web research agents use for blog posts and case studies
413
+ - mcp: `WebFetch` | optional | GitHub exploration and competitive analysis
414
+ - mcp: `sequential-thinking` | optional | complex trade-off analysis during synthesis
415
+ - env: none required
416
+
417
+ ## Event Payloads
418
+
419
+ ### plan_generated
420
+ - skill: string — "ftm-brainstorm"
421
+ - plan_path: string — absolute path to generated plan file
422
+ - plan_title: string — human-readable plan title
423
+ - task_count: number — total tasks in the plan
424
+ - wave_count: number — number of parallel execution waves
425
+
426
+ ### task_completed
427
+ - skill: string — "ftm-brainstorm"
428
+ - task_title: string — title of the brainstorm topic
429
+ - plan_path: string | null — path to generated plan if Phase 3 completed
430
+ - duration_ms: number — total session duration
@@ -413,3 +413,42 @@ When ftm-browse is used directly (not within a plan), supervised mode is OFF by
413
413
  - The daemon uses a 1280x800 headless Chromium viewport with a standard Mac Chrome user-agent, so most sites render predictably.
414
414
  - To stop the daemon explicitly: `$PB stop`. It will auto-restart on next use.
415
415
  - `$PB eval` is the escape hatch for anything the ARIA tree doesn't expose — hidden inputs, JS globals, localStorage, computed values.
416
+
417
+ ## Requirements
418
+
419
+ - tool: `$HOME/.claude/skills/ftm-browse/bin/ftm-browse` | required | headless browser CLI binary
420
+ - tool: `npx playwright install chromium` | required | Chromium browser engine (first-time setup)
421
+ - reference: none required
422
+
423
+ ## Risk
424
+
425
+ - level: low_write
426
+ - scope: navigates browser, takes screenshots saved to ~/.ftm-browse/screenshots/; does not modify project source files; form fills and clicks can have side effects on the target application
427
+ - rollback: no project file mutations; browser interactions on local dev servers are typically reversible by reloading
428
+
429
+ ## Approval Gates
430
+
431
+ - trigger: auth redirect detected during supervised execution | action: STOP immediately, present options (retry/skip/abort/manual), wait for user choice
432
+ - trigger: unexpected browser state during plan step | action: STOP, take screenshot, present situation to user, wait for explicit choice
433
+ - trigger: supervised mode enabled AND state mismatch detected | action: halt and report before proceeding
434
+ - complexity_routing: micro → auto | small → auto | medium → auto | large → auto | xl → auto
435
+
436
+ ## Fallbacks
437
+
438
+ - condition: daemon binary not found at expected path | action: report installation instructions and stop
439
+ - condition: Chromium not installed | action: instruct user to run "npx playwright install chromium" and stop
440
+ - condition: daemon fails to start within 10 seconds | action: check ~/.ftm-browse/ logs, report binary or Bun issue
441
+ - condition: dev server not running when navigating to localhost | action: report timeout error with the URL attempted
442
+ - condition: stale ref after navigation | action: re-run snapshot -i before retrying click/fill
443
+
444
+ ## Capabilities
445
+
446
+ - cli: `$HOME/.claude/skills/ftm-browse/bin/ftm-browse` | required | headless Chromium control CLI
447
+
448
+ ## Event Payloads
449
+
450
+ ### task_completed
451
+ - skill: string — "ftm-browse"
452
+ - workflow: string — description of the visual verification or interaction performed
453
+ - screenshots: string[] — absolute paths to screenshots taken
454
+ - duration_ms: number — total workflow duration