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
@@ -0,0 +1,163 @@
1
+ ---
2
+ name: ftm-dashboard
3
+ description: Session and weekly analytics dashboard for the FTM skill ecosystem. Reads events.log and blackboard state to show skills invoked, plans presented, approval rates, experiences recorded, and patterns promoted. Use when user says "dashboard", "analytics", "stats", "ftm-dashboard", "show session stats", or "how's the system doing".
4
+ ---
5
+
6
+ # FTM Dashboard
7
+
8
+ Provides analytics about FTM system usage by reading the event log and blackboard state.
9
+
10
+ ## Commands
11
+
12
+ ### `/ftm-dashboard` (default: current session)
13
+
14
+ Shows stats for the current session:
15
+
16
+ ```
17
+ ━━━━━━━━━━━ FTM Session Dashboard ━━━━━━━━━━━
18
+
19
+ Session started: [timestamp]
20
+ Duration: [hours:minutes]
21
+
22
+ Skills Invoked:
23
+ ftm-mind ████████████ 12
24
+ ftm-debug ████ 4
25
+ ftm-executor ██ 2
26
+ ftm-brainstorm █ 1
27
+
28
+ Plans:
29
+ Presented: 5
30
+ Approved: 4 (80%)
31
+ Modified before approval: 2
32
+ Saved as playbook: 1
33
+
34
+ Experiences Recorded:
35
+ Total: 8
36
+ From LLM: 5 (rich)
37
+ From git hook: 3 (minimal)
38
+
39
+ Patterns:
40
+ Active: 12
41
+ Reinforced this session: 3
42
+ Aging (>30 days): 2
43
+ Decayed: 0
44
+
45
+ Context Budget:
46
+ Orient mode: Full (conversation ~25% used)
47
+
48
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
49
+ ```
50
+
51
+ ### `/ftm-dashboard week`
52
+
53
+ Shows aggregate stats for the past 7 days:
54
+
55
+ ```
56
+ ━━━━━━━━━━ FTM Weekly Dashboard ━━━━━━━━━━━━━
57
+
58
+ Period: [date] — [date]
59
+
60
+ Tasks by Complexity:
61
+ Micro: ██████████████████ 18
62
+ Small: ████████████ 12
63
+ Medium: ██████ 6
64
+ Large: ██ 2
65
+
66
+ Top Skills:
67
+ 1. ftm-mind (45 invocations)
68
+ 2. ftm-executor (12 invocations)
69
+ 3. ftm-debug (8 invocations)
70
+ 4. ftm-brainstorm (6 invocations)
71
+ 5. ftm-audit (4 invocations)
72
+
73
+ Playbooks:
74
+ Created: 2
75
+ Reused: 3
76
+ Parameterized: 0
77
+
78
+ Learning:
79
+ Experiences recorded: 38
80
+ Patterns promoted: 1
81
+ Patterns decayed: 0
82
+ Sizing corrections: 0
83
+
84
+ Approval Rate: 85% (34/40 plans approved on first presentation)
85
+ Average plan modifications: 1.2 per plan
86
+
87
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
88
+ ```
89
+
90
+ ## Data Sources
91
+
92
+ ### events.log (`~/.claude/ftm-state/events.log`)
93
+ - JSONL format, one entry per line
94
+ - Each entry has: timestamp, event_type, tool_name, session_id, skill_context
95
+ - Filter by session_id for current session, by date range for weekly
96
+
97
+ ### Blackboard State
98
+ - `~/.claude/ftm-state/blackboard/context.json` — current session metadata
99
+ - `~/.claude/ftm-state/blackboard/experiences/index.json` — experience counts and types
100
+ - `~/.claude/ftm-state/blackboard/patterns.json` — pattern health
101
+
102
+ ### Playbooks (`~/.ftm/playbooks/`)
103
+ - Count `.yml` files for total playbooks
104
+ - Check `use_count` field for reuse stats
105
+ - Check `parameterized` field for parameterization stats
106
+
107
+ ## Implementation
108
+
109
+ 1. Read the relevant data sources
110
+ 2. Compute aggregates
111
+ 3. Render as markdown tables with ASCII bar charts
112
+ 4. Output directly — no approval gates needed (read-only operation)
113
+
114
+ ## Rendering
115
+
116
+ - Use Unicode block characters for bar charts: █ ▓ ░
117
+ - Tables in markdown format for terminal rendering
118
+ - Keep output concise — one screen max
119
+ - If data sources are empty (fresh install), show: "No data yet. Use FTM for a few sessions and check back."
120
+
121
+ ## Requirements
122
+
123
+ - reference: `~/.claude/ftm-state/events.log` | optional | JSONL event log for skill invocation tracking
124
+ - reference: `~/.claude/ftm-state/blackboard/context.json` | required | current session metadata
125
+ - reference: `~/.claude/ftm-state/blackboard/experiences/index.json` | optional | experience inventory and counts
126
+ - reference: `~/.claude/ftm-state/blackboard/patterns.json` | optional | pattern health for weekly stats
127
+ - reference: `~/.ftm/playbooks/` | optional | playbook use counts and stats
128
+
129
+ ## Risk
130
+
131
+ - level: read_only
132
+ - scope: reads event log and blackboard state only; does not modify any files
133
+ - rollback: no mutations to reverse
134
+
135
+ ## Approval Gates
136
+
137
+ - complexity_routing: micro → auto | small → auto | medium → auto | large → auto | xl → auto
138
+
139
+ ## Fallbacks
140
+
141
+ - condition: events.log missing or empty | action: show "No session events recorded yet" for relevant sections
142
+ - condition: blackboard context.json missing | action: show "No session data available" and suggest using FTM skills first
143
+ - condition: experiences/index.json missing | action: skip experience stats sections
144
+ - condition: playbooks directory missing | action: show 0 for all playbook stats
145
+
146
+ ## Capabilities
147
+
148
+ - env: none required
149
+
150
+ ## Event Payloads
151
+
152
+ ### (none)
153
+ ftm-dashboard is read-only and does not emit events directly. It listens to task_completed for session tracking only.
154
+
155
+ ## Events
156
+
157
+ ### Listens To
158
+ - `task_completed` — for session stats tracking
159
+
160
+ ### Blackboard Read
161
+ - `context.json` — session metadata
162
+ - `experiences/index.json` — experience inventory
163
+ - `patterns.json` — pattern health
@@ -144,3 +144,87 @@ After completing, update the blackboard. Read `references/protocols/BLACKBOARD.m
144
144
  Before dispatching agents, read `~/.claude/ftm-config.yml`:
145
145
  - Use the `planning` model from the active profile for all investigation agents
146
146
  - If config missing, use session default
147
+
148
+ ## Requirements
149
+
150
+ - config: `~/.claude/ftm-config.yml` | optional | model profiles for investigation agents
151
+ - reference: `references/protocols/BLACKBOARD.md` | required | blackboard read/write protocol
152
+ - reference: `references/protocols/EDGE-CASES.md` | required | anti-patterns and fallback handling
153
+ - reference: `references/phases/PHASE-0-INTAKE.md` | required | intake steps and Explore agent prompt
154
+ - reference: `references/phases/PHASE-1-TRIAGE.md` | required | agent selection guide and worktree strategy
155
+ - reference: `references/phases/PHASE-2-WAR-ROOM-AGENTS.md` | required | all four agent prompts
156
+ - reference: `references/phases/PHASE-3-TO-6-EXECUTION.md` | required | synthesis, solver, reviewer prompts
157
+ - tool: `git` | required | worktree creation, diff inspection, commit history
158
+ - reference: `~/.claude/ftm-state/blackboard/context.json` | optional | session state
159
+ - reference: `~/.claude/ftm-state/blackboard/experiences/index.json` | optional | past bug fixes and known issues
160
+ - reference: `~/.claude/ftm-state/blackboard/patterns.json` | optional | recurring failure patterns
161
+
162
+ ## Risk
163
+
164
+ - level: medium_write
165
+ - scope: creates git worktrees for investigation and fix branches; modifies source files in Solver agent worktree; merges fix after Reviewer approval
166
+ - rollback: git worktree remove + git branch -D for debug/* worktrees; all fix changes isolated until user confirms merge
167
+
168
+ ## Approval Gates
169
+
170
+ - trigger: investigation plan formulated in Phase 0 | action: present plan to user and proceed unless user objects
171
+ - trigger: Solver produces fix | action: Reviewer agent must independently verify before presenting to user (hard gate — cannot skip)
172
+ - trigger: Reviewer APPROVED | action: present root cause + changes + evidence to user, wait for user confirmation before merging
173
+ - trigger: Solver NEEDS REWORK after 3 attempts | action: escalate to user with full context, wait for direction
174
+ - complexity_routing: micro → auto | small → auto | medium → plan_first | large → plan_first | xl → always_ask
175
+
176
+ ## Fallbacks
177
+
178
+ - condition: Instrumenter agent fails or produces no useful output | action: skip instrumentation worktree, proceed with remaining agents
179
+ - condition: Reproducer cannot create a minimal failing test | action: note as "reproduction failed", proceed with hypothesis-only approach
180
+ - condition: Researcher finds no relevant issues or docs | action: proceed with instrumentation and hypothesis findings only
181
+ - condition: fix still failing after 3 Solver iterations | action: escalate to user with all hypotheses tested and evidence gathered
182
+ - condition: project has no test suite | action: Reviewer uses build check + diff review + live runtime verification instead of test runner
183
+
184
+ ## Capabilities
185
+
186
+ - cli: `git` | required | worktree isolation for investigation agents
187
+ - mcp: `sequential-thinking` | optional | complex multi-hypothesis analysis
188
+ - mcp: `playwright` | optional | visual bug verification in Reviewer phase
189
+ - mcp: `WebSearch` | optional | Researcher agent for GitHub issues and Stack Overflow
190
+ - mcp: `WebFetch` | optional | Researcher agent for docs and changelogs
191
+
192
+ ## Event Payloads
193
+
194
+ ### bug_fixed
195
+ - skill: string — "ftm-debug"
196
+ - root_cause: string — one-sentence root cause description
197
+ - fix_approach: string — description of the fix applied
198
+ - worktree: string — path to fix worktree
199
+ - iterations: number — number of solver-reviewer cycles needed
200
+ - duration_ms: number — total war room duration
201
+
202
+ ### issue_found
203
+ - skill: string — "ftm-debug"
204
+ - phase: string — "phase1" | "phase2"
205
+ - agent: string — "instrumenter" | "researcher" | "reproducer" | "hypothesizer"
206
+ - finding: string — description of the specific issue found
207
+ - confidence: string — high | medium | low
208
+
209
+ ### test_passed
210
+ - skill: string — "ftm-debug"
211
+ - scope: string — "reproduction" | "full_suite"
212
+ - worktree: string — worktree path where tests ran
213
+
214
+ ### test_failed
215
+ - skill: string — "ftm-debug"
216
+ - scope: string — "reproduction" | "full_suite"
217
+ - worktree: string — worktree path
218
+ - error_summary: string — brief failure description
219
+
220
+ ### error_encountered
221
+ - skill: string — "ftm-debug"
222
+ - phase: string — war room phase where error occurred
223
+ - agent: string | null — agent that encountered the error
224
+ - error: string — error description
225
+
226
+ ### task_completed
227
+ - skill: string — "ftm-debug"
228
+ - outcome: string — "fixed" | "escalated" | "unresolved"
229
+ - root_cause: string — root cause if found
230
+ - duration_ms: number — total session duration
@@ -231,3 +231,47 @@ Read and display `ARCHITECTURE.mmd` + list available module diagrams.
231
231
  ### Auto-Invocation by ftm-executor
232
232
 
233
233
  This skill's format is used by ftm-executor's documentation pipeline. After every commit during plan execution, agents update INTENT.md (or DIAGRAM.mmd) entries following this skill's templates. The updates are automatic and don't require explicit skill invocation — agents reference the format directly.
234
+
235
+ ## Requirements
236
+
237
+ - reference: `.ftm-map/map.db` | optional | SQLite knowledge graph for accurate diagram generation (graph-powered mode)
238
+ - tool: `ftm-map/scripts/.venv/bin/python3` | optional | Python runtime for graph-powered views.py
239
+ - reference: `package.json` | optional | project structure detection for bootstrap
240
+ - reference: `tsconfig.json` | optional | TypeScript project structure detection
241
+
242
+ ## Risk
243
+
244
+ - level: low_write
245
+ - scope: writes .mmd diagram files to project directories; only creates or modifies ARCHITECTURE.mmd and per-module DIAGRAM.mmd files; does not touch source code
246
+ - rollback: git checkout on modified .mmd files; delete newly created .mmd files
247
+
248
+ ## Approval Gates
249
+
250
+ - trigger: bootstrap mode on large codebase (50+ modules) | action: report what was found and what will be created before writing, proceed unless user objects
251
+ - complexity_routing: micro → auto | small → auto | medium → auto | large → auto | xl → auto
252
+
253
+ ## Fallbacks
254
+
255
+ - condition: .ftm-map/map.db not found | action: fall back to standard import-grep analysis for diagram generation
256
+ - condition: Python venv not set up | action: fall back to standard analysis, log "Graph-powered mode unavailable — run ftm-map to enable"
257
+ - condition: no src/ or identifiable source root | action: ask user for source root before bootstrapping
258
+
259
+ ## Capabilities
260
+
261
+ - cli: `ftm-map/scripts/.venv/bin/python3` | optional | graph-powered diagram generation
262
+ - mcp: `git` | optional | detect changed files for incremental updates
263
+
264
+ ## Event Payloads
265
+
266
+ ### documentation_updated
267
+ - skill: string — "ftm-diagram"
268
+ - files_written: string[] — absolute paths to .mmd files created or modified
269
+ - modules_added: number — new module nodes added to ARCHITECTURE.mmd
270
+ - functions_added: number — new function nodes added across module DIAGRAMs
271
+ - edges_added: number — new dependency edges added
272
+
273
+ ### task_completed
274
+ - skill: string — "ftm-diagram"
275
+ - mode: string — "bootstrap" | "incremental"
276
+ - files_count: number — total .mmd files written
277
+ - duration_ms: number — total diagram sync duration
@@ -655,3 +655,100 @@ After completing, update the blackboard:
655
655
  2. Write an experience file to `/Users/kioja.kudumu/.claude/ftm-state/blackboard/experiences/YYYY-MM-DD_task-slug.json` capturing task_type, agent team used, wave count, audit outcomes, and lessons learned
656
656
  3. Update `/Users/kioja.kudumu/.claude/ftm-state/blackboard/experiences/index.json` with the new entry
657
657
  4. Emit `task_completed` event
658
+
659
+ ## Requirements
660
+
661
+ - tool: `git` | required | worktree creation, branch management, commit operations
662
+ - config: `~/.claude/ftm-config.yml` | optional | model profiles, max_parallel_agents, auto_audit, progress_tracking
663
+ - reference: `~/.claude/plans/` | optional | plan documents for execution
664
+ - tool: `node` | optional | project setup commands in worktrees
665
+ - reference: `~/.claude/skills/ftm-executor/references/STYLE-TEMPLATE.md` | optional | STYLE.md bootstrap template
666
+
667
+ ## Risk
668
+
669
+ - level: high_write
670
+ - scope: creates git worktrees and branches, modifies source files across multiple tasks, runs tests and builds, optionally pushes branches or creates PRs
671
+ - rollback: git worktree remove + git branch -D for each worktree; all changes isolated to plan-exec/* branches until explicitly merged
672
+
673
+ ## Approval Gates
674
+
675
+ - trigger: no plan document provided | action: generate plan and wait for explicit user approval before any code is written
676
+ - trigger: plan_checker returns FAIL | action: present blockers and ask user to fix or override before proceeding
677
+ - trigger: plan_checker returns WARN | action: show warnings to user, proceed unless they object
678
+ - trigger: wave complete and all agents done | action: auto-invoke ftm-codex-gate (no user gate needed for this step)
679
+ - trigger: final phase 6 verification passes | action: present 4 branch finishing options and wait for explicit user choice
680
+ - trigger: codex gate FAIL after 2 fix attempts | action: report to user and wait for input before continuing
681
+ - complexity_routing: micro → auto | small → auto | medium → plan_first | large → plan_first | xl → always_ask
682
+
683
+ ## Fallbacks
684
+
685
+ - condition: ftm-browse not installed at $HOME/.claude/skills/ftm-browse/bin/ftm-browse | action: skip visual smoke test checks, log "Visual smoke test skipped — ftm-browse not installed"
686
+ - condition: ftm-retro skill not available | action: skip retrospective phase, note in output and proceed to branch finishing
687
+ - condition: codex CLI not found | action: skip codex gate, log "Codex gate skipped — codex not installed", proceed to next wave
688
+ - condition: no package.json in project | action: skip npm install in worktree setup; skip knip-based audit layers
689
+ - condition: project has no test suite | action: skip test verification gates, rely on diff review and build checks
690
+ - condition: agent fails or gets stuck | action: read agent output, fix directly or respawn with more context
691
+
692
+ ## Capabilities
693
+
694
+ - cli: `git` | required | worktree management and version control
695
+ - cli: `node` | optional | project dependency installation
696
+ - mcp: `sequential-thinking` | optional | complex dependency analysis and plan validation
697
+ - env: none required directly (agents inherit from session)
698
+
699
+ ## Event Payloads
700
+
701
+ ### task_received
702
+ - skill: string — "ftm-executor"
703
+ - task_description: string — description of the task being queued
704
+ - plan_path: string — absolute path to plan document
705
+
706
+ ### plan_generated
707
+ - skill: string — "ftm-executor"
708
+ - plan_path: string — absolute path to saved plan file
709
+ - task_count: number — total tasks in the plan
710
+ - wave_count: number — number of parallel execution waves
711
+
712
+ ### plan_approved
713
+ - skill: string — "ftm-executor"
714
+ - plan_path: string — absolute path to approved plan
715
+ - approved_steps: number[] — step numbers approved for execution
716
+
717
+ ### code_changed
718
+ - skill: string — "ftm-executor"
719
+ - worktree: string — path to the worktree where files changed
720
+ - files: string[] — list of modified file paths
721
+ - agent: string — agent type that made the changes
722
+
723
+ ### code_committed
724
+ - skill: string — "ftm-executor"
725
+ - worktree: string — path to worktree
726
+ - commit_hash: string — short commit hash
727
+ - message: string — commit message
728
+ - task_number: number — plan task number this commit belongs to
729
+
730
+ ### test_passed
731
+ - skill: string — "ftm-executor"
732
+ - scope: string — "task" | "full_suite"
733
+ - task_number: number | null — task number if scoped to task
734
+ - worktree: string — worktree path
735
+
736
+ ### test_failed
737
+ - skill: string — "ftm-executor"
738
+ - scope: string — "task" | "full_suite"
739
+ - task_number: number | null — task number if scoped
740
+ - worktree: string — worktree path
741
+ - error_summary: string — brief description of failure
742
+
743
+ ### task_completed
744
+ - skill: string — "ftm-executor"
745
+ - task_number: number — completed task number
746
+ - audit_result: string — "pass" | "pass_with_fixes" | "fail" | "skipped"
747
+ - auto_fixed_count: number — issues auto-remediated by ftm-audit
748
+ - duration_ms: number — task execution time
749
+
750
+ ### error_encountered
751
+ - skill: string — "ftm-executor"
752
+ - phase: string — execution phase where error occurred
753
+ - task_number: number | null — associated task if applicable
754
+ - error: string — error description
package/ftm-git/SKILL.md CHANGED
@@ -193,3 +193,63 @@ After completing, update the blackboard:
193
193
  - Which patterns matched (to improve future scans)
194
194
  3. Update `experiences/index.json` with the new entry
195
195
  4. Emit `secrets_clear` or `secrets_remediated` or `secrets_blocked`
196
+
197
+ ## Requirements
198
+
199
+ - tool: `git` | required | staged file inspection, commit history scanning
200
+ - reference: `references/patterns/SECRET-PATTERNS.md` | required | Tier 1/2 patterns, severity table, ignore list
201
+ - reference: `references/protocols/REMEDIATION.md` | required | remediation protocol, env var patterns, report formats
202
+ - reference: `~/.claude/skills/ftm-git/scripts/pre-commit-secrets.sh` | required | pre-commit hook script for installation
203
+ - reference: `~/.claude/skills/ftm-git/hooks/post-commit-experience.sh` | optional | post-commit experience recorder hook
204
+
205
+ ## Risk
206
+
207
+ - level: medium_write
208
+ - scope: modifies source files to replace hardcoded secrets with env var references; creates/updates .env and .env.example files; installs git hooks in .git/hooks/; re-stages files after remediation
209
+ - rollback: git checkout on refactored source files; manually remove added .env and .gitignore entries; remove hook from .git/hooks/pre-commit
210
+
211
+ ## Approval Gates
212
+
213
+ - trigger: CRITICAL or HIGH severity secret found | action: BLOCK commit/push immediately, announce "BLOCKED — N secret(s) found", then attempt auto-remediation
214
+ - trigger: auto-remediation proposed for a finding | action: show proposed change (file, variable name, env var name) before applying
215
+ - trigger: re-scan after remediation still finds secrets | action: report remaining findings to user, do not proceed with commit
216
+ - complexity_routing: micro → auto | small → auto | medium → auto | large → auto | xl → auto
217
+
218
+ ## Fallbacks
219
+
220
+ - condition: .env file does not exist | action: create .env and .env.example and add .env to .gitignore before extracting secrets
221
+ - condition: .gitignore does not exist | action: create .gitignore with .env entry before remediation
222
+ - condition: language detection fails for env var pattern | action: extract secret to .env but flag source file refactoring as MANUAL_INTERVENTION_NEEDED
223
+ - condition: pre-commit hook already exists | action: append ftm-git scan to existing hook rather than overwriting
224
+
225
+ ## Capabilities
226
+
227
+ - cli: `git` | required | staged file listing, diff inspection, commit history traversal
228
+
229
+ ## Event Payloads
230
+
231
+ ### secrets_found
232
+ - skill: string — "ftm-git"
233
+ - findings_count: number — total secrets detected
234
+ - critical_count: number — CRITICAL severity findings
235
+ - high_count: number — HIGH severity findings
236
+ - files_affected: string[] — files containing secrets
237
+ - blocked: boolean — whether commit/push was halted
238
+
239
+ ### secrets_clear
240
+ - skill: string — "ftm-git"
241
+ - files_scanned: number — total files checked
242
+ - scope: string — "staged" | "working_tree" | "history" | "pre-push"
243
+
244
+ ### secrets_remediated
245
+ - skill: string — "ftm-git"
246
+ - findings_remediated: number — secrets successfully extracted
247
+ - env_vars_added: string[] — environment variable names created
248
+ - files_refactored: string[] — source files updated to use env vars
249
+ - manual_needed: number — findings requiring manual intervention
250
+
251
+ ### task_completed
252
+ - skill: string — "ftm-git"
253
+ - outcome: string — "clear" | "remediated" | "blocked"
254
+ - files_scanned: number — total files scanned
255
+ - duration_ms: number — total scan and remediation time
File without changes
File without changes
@@ -0,0 +1,64 @@
1
+ """
2
+ Exponential-backoff retry decorator for HTTP adapter calls.
3
+
4
+ Usage:
5
+ @retry(max_attempts=3, base_delay=1.0)
6
+ def poll(self) -> list[dict]:
7
+ ...
8
+ """
9
+
10
+ from __future__ import annotations
11
+
12
+ import functools
13
+ import logging
14
+ import time
15
+ from typing import Callable, TypeVar
16
+
17
+ logger = logging.getLogger(__name__)
18
+
19
+ F = TypeVar("F", bound=Callable)
20
+
21
+
22
+ def retry(
23
+ max_attempts: int = 3,
24
+ base_delay: float = 1.0,
25
+ backoff_factor: float = 2.0,
26
+ exceptions: tuple[type[Exception], ...] = (Exception,),
27
+ ) -> Callable[[F], F]:
28
+ """
29
+ Decorator: retry on exception with exponential backoff.
30
+
31
+ Args:
32
+ max_attempts: Total number of attempts (including the first).
33
+ base_delay: Initial sleep duration in seconds.
34
+ backoff_factor: Multiplier applied to delay after each failure.
35
+ exceptions: Exception types that trigger a retry.
36
+ """
37
+
38
+ def decorator(func: F) -> F:
39
+ @functools.wraps(func)
40
+ def wrapper(*args, **kwargs):
41
+ delay = base_delay
42
+ last_exc: Exception | None = None
43
+ for attempt in range(1, max_attempts + 1):
44
+ try:
45
+ return func(*args, **kwargs)
46
+ except exceptions as exc:
47
+ last_exc = exc
48
+ if attempt == max_attempts:
49
+ break
50
+ logger.warning(
51
+ "%s failed (attempt %d/%d): %s — retrying in %.1fs",
52
+ func.__qualname__,
53
+ attempt,
54
+ max_attempts,
55
+ exc,
56
+ delay,
57
+ )
58
+ time.sleep(delay)
59
+ delay *= backoff_factor
60
+ raise last_exc # type: ignore[misc]
61
+
62
+ return wrapper # type: ignore[return-value]
63
+
64
+ return decorator