feed-the-machine 1.0.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 (120) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +268 -0
  3. package/bin/generate-manifest.mjs +210 -0
  4. package/bin/install.mjs +114 -0
  5. package/ftm/SKILL.md +88 -0
  6. package/ftm-audit/SKILL.md +146 -0
  7. package/ftm-audit/references/protocols/PROJECT-PATTERNS.md +91 -0
  8. package/ftm-audit/references/protocols/RUNTIME-WIRING.md +66 -0
  9. package/ftm-audit/references/protocols/WIRING-CONTRACTS.md +135 -0
  10. package/ftm-audit/references/strategies/AUTO-FIX-STRATEGIES.md +69 -0
  11. package/ftm-audit/references/templates/REPORT-FORMAT.md +96 -0
  12. package/ftm-audit/scripts/run-knip.sh +23 -0
  13. package/ftm-audit.yml +2 -0
  14. package/ftm-brainstorm/SKILL.md +379 -0
  15. package/ftm-brainstorm/evals/evals.json +100 -0
  16. package/ftm-brainstorm/evals/promptfoo.yaml +109 -0
  17. package/ftm-brainstorm/references/agent-prompts.md +224 -0
  18. package/ftm-brainstorm/references/plan-template.md +121 -0
  19. package/ftm-brainstorm.yml +2 -0
  20. package/ftm-browse/SKILL.md +415 -0
  21. package/ftm-browse/daemon/browser-manager.ts +206 -0
  22. package/ftm-browse/daemon/bun.lock +30 -0
  23. package/ftm-browse/daemon/cli.ts +347 -0
  24. package/ftm-browse/daemon/commands.ts +410 -0
  25. package/ftm-browse/daemon/main.ts +357 -0
  26. package/ftm-browse/daemon/package.json +17 -0
  27. package/ftm-browse/daemon/server.ts +189 -0
  28. package/ftm-browse/daemon/snapshot.ts +519 -0
  29. package/ftm-browse/daemon/tsconfig.json +22 -0
  30. package/ftm-browse.yml +4 -0
  31. package/ftm-codex-gate/SKILL.md +302 -0
  32. package/ftm-codex-gate.yml +2 -0
  33. package/ftm-config/SKILL.md +310 -0
  34. package/ftm-config.default.yml +80 -0
  35. package/ftm-config.yml +2 -0
  36. package/ftm-council/SKILL.md +132 -0
  37. package/ftm-council/references/prompts/CLAUDE-INVESTIGATION.md +60 -0
  38. package/ftm-council/references/prompts/CODEX-INVESTIGATION.md +58 -0
  39. package/ftm-council/references/prompts/GEMINI-INVESTIGATION.md +58 -0
  40. package/ftm-council/references/prompts/REBUTTAL-TEMPLATE.md +57 -0
  41. package/ftm-council/references/protocols/PREREQUISITES.md +47 -0
  42. package/ftm-council/references/protocols/STEP-0-FRAMING.md +46 -0
  43. package/ftm-council.yml +2 -0
  44. package/ftm-dashboard.yml +4 -0
  45. package/ftm-debug/SKILL.md +146 -0
  46. package/ftm-debug/references/phases/PHASE-0-INTAKE.md +58 -0
  47. package/ftm-debug/references/phases/PHASE-1-TRIAGE.md +46 -0
  48. package/ftm-debug/references/phases/PHASE-2-WAR-ROOM-AGENTS.md +279 -0
  49. package/ftm-debug/references/phases/PHASE-3-TO-6-EXECUTION.md +436 -0
  50. package/ftm-debug/references/protocols/BLACKBOARD.md +86 -0
  51. package/ftm-debug/references/protocols/EDGE-CASES.md +103 -0
  52. package/ftm-debug.yml +2 -0
  53. package/ftm-diagram/SKILL.md +233 -0
  54. package/ftm-diagram.yml +2 -0
  55. package/ftm-executor/SKILL.md +657 -0
  56. package/ftm-executor/references/STYLE-TEMPLATE.md +73 -0
  57. package/ftm-executor/references/phases/PHASE-0-VERIFICATION.md +62 -0
  58. package/ftm-executor/references/phases/PHASE-2-AGENT-ASSEMBLY.md +34 -0
  59. package/ftm-executor/references/phases/PHASE-3-WORKTREES.md +38 -0
  60. package/ftm-executor/references/phases/PHASE-4-5-AUDIT.md +72 -0
  61. package/ftm-executor/references/phases/PHASE-4-DISPATCH.md +66 -0
  62. package/ftm-executor/references/phases/PHASE-5-5-CODEX-GATE.md +73 -0
  63. package/ftm-executor/references/protocols/DOCUMENTATION-BOOTSTRAP.md +36 -0
  64. package/ftm-executor/references/protocols/MODEL-PROFILE.md +44 -0
  65. package/ftm-executor/references/protocols/PROGRESS-TRACKING.md +66 -0
  66. package/ftm-executor/runtime/ftm-runtime.mjs +252 -0
  67. package/ftm-executor/runtime/package.json +8 -0
  68. package/ftm-executor.yml +2 -0
  69. package/ftm-git/SKILL.md +195 -0
  70. package/ftm-git/evals/evals.json +26 -0
  71. package/ftm-git/evals/promptfoo.yaml +75 -0
  72. package/ftm-git/hooks/post-commit-experience.sh +92 -0
  73. package/ftm-git/references/patterns/SECRET-PATTERNS.md +104 -0
  74. package/ftm-git/references/protocols/REMEDIATION.md +139 -0
  75. package/ftm-git/scripts/pre-commit-secrets.sh +110 -0
  76. package/ftm-git.yml +2 -0
  77. package/ftm-intent/SKILL.md +198 -0
  78. package/ftm-intent.yml +2 -0
  79. package/ftm-map.yml +2 -0
  80. package/ftm-mind/SKILL.md +986 -0
  81. package/ftm-mind/evals/promptfoo.yaml +142 -0
  82. package/ftm-mind/references/blackboard-schema.md +328 -0
  83. package/ftm-mind/references/complexity-guide.md +110 -0
  84. package/ftm-mind/references/event-registry.md +299 -0
  85. package/ftm-mind/references/mcp-inventory.md +296 -0
  86. package/ftm-mind/references/protocols/COMPLEXITY-SIZING.md +72 -0
  87. package/ftm-mind/references/protocols/MCP-HEURISTICS.md +32 -0
  88. package/ftm-mind/references/protocols/PLAN-APPROVAL.md +80 -0
  89. package/ftm-mind/references/reflexion-protocol.md +249 -0
  90. package/ftm-mind/references/routing/SCENARIOS.md +22 -0
  91. package/ftm-mind/references/routing-scenarios.md +35 -0
  92. package/ftm-mind.yml +2 -0
  93. package/ftm-pause/SKILL.md +133 -0
  94. package/ftm-pause/references/protocols/SKILL-RESTORE-PROTOCOLS.md +186 -0
  95. package/ftm-pause/references/protocols/VALIDATION.md +80 -0
  96. package/ftm-pause.yml +2 -0
  97. package/ftm-researcher.yml +2 -0
  98. package/ftm-resume/SKILL.md +166 -0
  99. package/ftm-resume/references/protocols/VALIDATION.md +172 -0
  100. package/ftm-resume.yml +2 -0
  101. package/ftm-retro/SKILL.md +189 -0
  102. package/ftm-retro/references/protocols/SCORING-RUBRICS.md +89 -0
  103. package/ftm-retro/references/templates/REPORT-FORMAT.md +109 -0
  104. package/ftm-retro.yml +2 -0
  105. package/ftm-routine.yml +4 -0
  106. package/ftm-state/blackboard/context.json +23 -0
  107. package/ftm-state/blackboard/experiences/index.json +9 -0
  108. package/ftm-state/blackboard/patterns.json +6 -0
  109. package/ftm-state/schemas/context.schema.json +130 -0
  110. package/ftm-state/schemas/experience-index.schema.json +77 -0
  111. package/ftm-state/schemas/experience.schema.json +78 -0
  112. package/ftm-state/schemas/patterns.schema.json +44 -0
  113. package/ftm-upgrade/SKILL.md +153 -0
  114. package/ftm-upgrade/scripts/check-version.sh +76 -0
  115. package/ftm-upgrade/scripts/upgrade.sh +143 -0
  116. package/ftm-upgrade.yml +2 -0
  117. package/ftm.yml +2 -0
  118. package/install.sh +102 -0
  119. package/package.json +74 -0
  120. package/uninstall.sh +25 -0
package/ftm/SKILL.md ADDED
@@ -0,0 +1,88 @@
1
+ ---
2
+ name: ftm
3
+ description: Universal entry point for all ftm skills. Routes freeform text to the right ftm skill. ftm-mind is the default cognitive entry point for all unclassified input.
4
+ ---
5
+
6
+ # Feed The Machine — Universal Skill Router
7
+
8
+ You are the entry point for the ftm skill system. Your job is routing — fast, thin, decisive.
9
+
10
+ ## Routing Rules
11
+
12
+ Evaluate the user's input in this order:
13
+
14
+ ### 1. Help Menu
15
+ If input is empty, "help", "?", or "menu" → display the help menu below. Do NOT invoke any skill.
16
+
17
+ ### 2. Explicit Skill Name
18
+ If input starts with a recognized skill name, route directly to that skill:
19
+
20
+ | Input prefix | Route to |
21
+ |---|---|
22
+ | `brainstorm` | ftm-brainstorm |
23
+ | `execute`, `run` (+ file path) | ftm-executor |
24
+ | `debug` | ftm-debug |
25
+ | `audit` | ftm-audit |
26
+ | `council` | ftm-council |
27
+ | `intent` | ftm-intent |
28
+ | `diagram` | ftm-diagram |
29
+ | `codex-gate`, `codex gate` | ftm-codex-gate |
30
+ | `pause` | ftm-pause |
31
+ | `resume` | ftm-resume |
32
+ | `browse` | ftm-browse |
33
+ | `upgrade` | ftm-upgrade |
34
+ | `retro` | ftm-retro |
35
+ | `config` | ftm-config |
36
+ | `mind` | ftm-mind |
37
+
38
+ When routing to a specific skill:
39
+ 1. Update the blackboard context: read `~/.claude/ftm-state/blackboard/context.json`, set `current_task` to reflect the incoming request, append to `session_metadata.skills_invoked`, write back.
40
+ 2. Show: `Routing to ftm-[skill]: [one-line reason]`
41
+ 3. Invoke the skill via the Skill tool with the user's full input as args.
42
+
43
+ ### 3. Everything Else → ftm-mind
44
+ All freeform input that does not match an explicit skill prefix goes to ftm-mind for OODA processing:
45
+ 1. Update the blackboard context (same as above).
46
+ 2. Show: `Routing to ftm-mind: analyzing your request.`
47
+ 3. Invoke: Skill tool with skill="ftm-mind", args="<full user input>"
48
+
49
+ ### Legacy Fallback
50
+ If ftm-mind fails (errors, timeouts, no actionable output) AND `legacy_router_fallback` is `true` in `~/.claude/ftm-config.yml`, fall back to keyword matching:
51
+
52
+ - "bug", "broken", "error", "fix", "crash", "failing" → ftm-debug
53
+ - "plan", "think", "build", "design", "how should" → ftm-brainstorm
54
+ - file path + "execute"/"go"/"run" → ftm-executor
55
+ - All other → ftm-brainstorm (default)
56
+
57
+ This fallback can be disabled after stable operation.
58
+
59
+ ## Help Menu
60
+
61
+ When the user provides no input or asks for help, display this exactly:
62
+
63
+ ```
64
+ FTM Skills:
65
+ /ftm mind [anything] — Default cognitive entry point (OODA reasoning)
66
+ /ftm brainstorm [idea] — Research-backed idea development
67
+ /ftm execute [plan-path] — Autonomous plan execution with agent teams
68
+ /ftm debug [description] — Multi-vector deep debugging war room
69
+ /ftm audit — Wiring verification (knip + adversarial)
70
+ /ftm council [question] — Multi-model deliberation (Claude + Codex + Gemini)
71
+ /ftm intent — Manage INTENT.md documentation layer
72
+ /ftm diagram — Manage ARCHITECTURE.mmd diagram layer
73
+ /ftm codex-gate — Run adversarial Codex validation
74
+ /ftm pause — Save session state for later
75
+ /ftm resume — Resume a paused session
76
+ /ftm browse [url] — Visual verification with headless browser
77
+ /ftm upgrade — Check for and install skill updates
78
+ /ftm retro — Post-execution retrospective
79
+ /ftm config — View and edit ftm configuration
80
+
81
+ Or just describe what you need and ftm-mind will handle it.
82
+ ```
83
+
84
+ ## Important Notes
85
+ - Pass through the full user input as args to the target skill. Let the target skill parse details.
86
+ - Do not attempt to do the work yourself — route only.
87
+ - Be fast — decisive routing, not conversation.
88
+ - Case insensitive matching for all prefix detection.
@@ -0,0 +1,146 @@
1
+ ---
2
+ name: ftm-audit
3
+ description: Dual-purpose wiring audit that verifies all code is actually connected to the running application. Combines static analysis (knip) with adversarial LLM audit and auto-fixes anything it finds. Use when user says "audit", "wiring check", "verify wiring", "dead code", "check imports", "unused code", "find dead code", or "audit wiring". Also auto-invoked by ftm-executor after each task.
4
+ ---
5
+
6
+ ## Events
7
+
8
+ ### Emits
9
+ - `audit_complete` — when all three audit layers finish and the final changelog is produced
10
+ - `issue_found` — when Layer 1 (knip) or Layer 2 (adversarial audit) identifies an unwired or dead-code problem
11
+ - `task_completed` — when an audit-initiated fix cycle finishes and the audited scope is verified clean
12
+
13
+ ### Listens To
14
+ - `code_committed` — run post-commit verification: trigger Layer 1 and Layer 2 against the committed diff
15
+ - `review_complete` — validate that review findings align with static analysis results; flag discrepancies
16
+
17
+ ## Blackboard Read
18
+
19
+ Before starting, load context from the blackboard:
20
+
21
+ 1. Read `~/.claude/ftm-state/blackboard/context.json` — check current_task, recent_decisions, active_constraints
22
+ 2. Read `~/.claude/ftm-state/blackboard/experiences/index.json` — filter entries by task_type="test" or tags matching "audit" or "wiring"
23
+ 3. Load top 3-5 matching experience files for commonly found issues and effective fix strategies
24
+ 4. Read `~/.claude/ftm-state/blackboard/patterns.json` — check recurring_issues for common wiring failures and execution_patterns for what types of code changes need more scrutiny
25
+
26
+ If index.json is empty or no matches found, proceed normally without experience-informed shortcuts.
27
+
28
+ ## Execution Protocol
29
+
30
+ 1. Phase 0 — detect project patterns (framework, router, state, API layer)
31
+ 2. Layer 1 — knip static analysis
32
+ 3. Layer 2 — adversarial audit, calibrated to detected patterns
33
+ 4. Combine findings, deduplicate
34
+ 5. Layer 3 — auto-fix each finding
35
+ 6. Re-verify (re-run Layers 1+2)
36
+ 7. Phase 3 — runtime wiring via ftm-browse (if prerequisites met)
37
+ 8. Produce final changelog report
38
+
39
+
40
+ ## Phase 0: Detect Project Patterns
41
+
42
+ Scan the project to calibrate which wiring dimensions apply. Read `references/protocols/PROJECT-PATTERNS.md` for the full detection table and dimension activation matrix.
43
+
44
+ **Quick scan:** `package.json` deps + `next.config.*`, `vite.config.*`, `app/` directory, `pages/` directory.
45
+
46
+ **Output:** Store detected context for all subsequent layers.
47
+ ```
48
+ Project detected: React 18 + Vite + react-router v6 + Zustand + TanStack Query
49
+ Dimensions active: D1 ✓ D2 ✓ D3 (router config) D4 (Zustand) D5 (TanStack Query)
50
+ ```
51
+
52
+ ---
53
+
54
+ ## Layer 1: Static Analysis (knip)
55
+
56
+ Detects unused files, exports, dependencies, and unreachable modules from the import graph.
57
+
58
+ **Prerequisites:** Requires `package.json` — skip and note if absent. Use `npx knip` if not locally installed.
59
+
60
+ ```bash
61
+ npx knip --reporter json 2>/dev/null
62
+ ```
63
+
64
+ **Output:** `files` (unused files) + `issues` array (`type`/`filePath`/`symbol`). Issue types: `exports`, `types`, `duplicates`, `dependencies`, `devDependencies`, `unlisted`, `binaries`, `unresolved`.
65
+
66
+ Fix actions by finding type: see `references/strategies/AUTO-FIX-STRATEGIES.md`. Helper script: `scripts/run-knip.sh`.
67
+
68
+ ---
69
+
70
+ ## Layer 2: LLM Adversarial Audit
71
+
72
+ **Mindset:** Prove code is dead, not confirm it works. Every new/modified export is guilty until you find a complete chain from entry point to it.
73
+
74
+ **Scope:** `git diff HEAD~1` (or current task diff). For each new or modified export, check all five wiring dimensions.
75
+
76
+ ### The 5 Wiring Dimensions
77
+
78
+ Calibrate each dimension to the detected project pattern from Phase 0. Framework-specific method variations are in `references/protocols/PROJECT-PATTERNS.md`.
79
+
80
+ | Dim | Name | Trace | GUILTY if | Evidence required |
81
+ |---|---|---|---|---|
82
+ | D1 | Import Chain | `export` → `import` → ... → entry point | No importer found, OR importing file itself unimported | Full chain with file:line each link |
83
+ | D2 | JSX Rendering | Component → parent JSX → root (React/Vue/Svelte only) | Imported but absent from every JSX return | Parent file:line where rendered, or "NOT FOUND" |
84
+ | D3 | Route Registration | View → route config → router (method varies by router type) | View exists but no route points to it | Route config file:line, or "NOT FOUND" |
85
+ | D4 | Store Consumption | Store field defined → selector/hook → component | Field written but never read | Consumer file:line, or "NOT FOUND" |
86
+ | D5 | API Invocation | API function → call site → used in app | Exported but never called | Call site file:line, or "NOT FOUND" |
87
+
88
+ **D2 valid rendering:** lazy imports, conditional rendering (`{cond && <C/>}`), render props, HOCs — all count.
89
+ **D3 nav link check:** A route with no nav link might be orphaned — flag as a warning.
90
+ **Non-React projects:** Skip D2-D3. Focus on D1, D4 (adapted to state management pattern), D5.
91
+
92
+ **Key principle:** File:line evidence for EVERY finding. Show the grep results and the missing chain link — "I think this might be unused" is not acceptable.
93
+
94
+ ---
95
+
96
+ ## Layer 3: Auto-Fix and Changelog
97
+
98
+ **Purpose:** When Layers 1 or 2 find unwired code, generate fixes, apply them, re-verify, and produce a structured changelog.
99
+
100
+ For fix strategies by finding type and the conditions that block auto-fix, see `references/strategies/AUTO-FIX-STRATEGIES.md`.
101
+
102
+ **Fix protocol for each finding:** Report → determine fix (check wiring contract for WHERE) → show proposed change → apply → re-verify → log to changelog.
103
+
104
+ ```
105
+ FIX: [UNWIRED_COMPONENT] NewWidget in Dashboard.tsx
106
+ Proposed: Add <NewWidget /> to Dashboard.tsx return JSX after line 45
107
+ ```
108
+
109
+ **When auto-fix is not possible:** Flag with `MANUAL_INTERVENTION_NEEDED`, a suggested action, and the reason skipped.
110
+
111
+ **Re-verification:** After all fixes, re-run Layers 1+2. Maximum 3 iterations to prevent loops.
112
+
113
+ ---
114
+
115
+ ## Wiring Contracts
116
+
117
+ A wiring contract is a YAML block in a plan task declaring expected wiring for code produced by that task. See `references/protocols/WIRING-CONTRACTS.md` for full schema, examples (React component, API functions, route/view), and per-field verification checks.
118
+
119
+ **Fields:** `exports`, `imported_by`, `rendered_in`, `route_path`, `nav_link`, `store_reads`, `store_writes`, `api_calls` — all optional.
120
+
121
+ **Graceful degradation:** Full contract → check every wire. Partial → check what's declared. No contract → pure Layer 1 + Layer 2 analysis.
122
+
123
+ ---
124
+
125
+ ## Phase 3: Runtime Wiring (Optional)
126
+
127
+ Verify that components and routes that passed static analysis actually render in the running application. See `references/protocols/RUNTIME-WIRING.md` for full prerequisites, process, and what runtime wiring catches that static analysis misses.
128
+
129
+ **Prerequisites (all required):** ftm-browse binary at `$HOME/.claude/skills/ftm-browse/bin/ftm-browse` + dev server running + wiring contracts include `route_path` entries.
130
+
131
+ **If any prerequisite fails:** Log the reason and skip. Do NOT fail the overall audit.
132
+
133
+ ---
134
+
135
+ ## Blackboard Write
136
+
137
+ After completing:
138
+
139
+ 1. Update `~/.claude/ftm-state/blackboard/context.json` — set current_task complete, append to recent_decisions (cap 10), update session_metadata
140
+ 2. Write experience file to `~/.claude/ftm-state/blackboard/experiences/YYYY-MM-DD_task-slug.json` — findings count, fix count, dimensions fired, manual interventions
141
+ 3. Update `experiences/index.json`
142
+ 4. Emit `audit_complete` event
143
+
144
+ ## Report Format
145
+
146
+ See `references/templates/REPORT-FORMAT.md` for the full report template (summary, changelog table, layer-by-layer finding format with examples).
@@ -0,0 +1,91 @@
1
+ # Project Pattern Detection
2
+
3
+ Pre-audit calibration: detect framework, router, state management, and API layer so wiring checks apply the right rules. This prevents false positives from applying React patterns to a Vue project, or App Router patterns to a Pages Router project.
4
+
5
+ **Cross-reference:** ftm-debug uses this same detection to calibrate its error tracing. Run once and share results with both skills.
6
+
7
+ ---
8
+
9
+ ## Detection Protocol
10
+
11
+ Read `package.json` dependencies and scan key config/directory signals.
12
+
13
+ ### Framework Detection
14
+
15
+ | Signal | Detection | Impact on Audit |
16
+ |---|---|---|
17
+ | **React** | `react` in deps | Dimensions 1-5 all apply |
18
+ | **Next.js** | `next` in deps | File-based routing, check App vs Pages Router |
19
+ | **Vue** | `vue` in deps | `<template>` instead of JSX, check vue-router |
20
+ | **Svelte** | `svelte` in deps | Svelte components, SvelteKit file-based routes |
21
+ | **Angular** | `@angular/core` in deps | Module-based wiring, check NgModule declarations |
22
+ | **No framework** | None of the above | Skip D2 (JSX) and D3 (Routes) |
23
+
24
+ ### Router Detection
25
+
26
+ | Signal | Detection | Dimension 3 Behavior |
27
+ |---|---|---|
28
+ | `react-router-dom` | dep exists | Check explicit router config file |
29
+ | `@tanstack/react-router` | dep exists | Check router config file |
30
+ | `next` + `app/` directory | `app/layout.tsx` or `app/page.tsx` exists | File-based: `app/path/page.tsx` = `/path` |
31
+ | `next` + `pages/` directory | `pages/` exists, no `app/` | File-based: `pages/foo.tsx` = `/foo` |
32
+ | `vue-router` | dep exists | Check router config file |
33
+ | SvelteKit | `@sveltejs/kit` in deps | File-based routes in `src/routes/` |
34
+
35
+ ### State Management Detection
36
+
37
+ | Signal | Detection | Dimension 4 Behavior |
38
+ |---|---|---|
39
+ | `zustand` | dep exists | Check `useStore` hooks and `create()` calls |
40
+ | `@reduxjs/toolkit` | dep exists | Check `useSelector`/`useDispatch` and slice reducers |
41
+ | `jotai` | dep exists | Check `useAtom` calls |
42
+ | `recoil` | dep exists | Check `useRecoilState`/`useRecoilValue` calls |
43
+ | `pinia` | dep exists | Check `defineStore` and `useXStore()` calls |
44
+ | None detected | — | Skip D4 or adapt to any custom store pattern found |
45
+
46
+ ### API Layer Detection
47
+
48
+ | Signal | Detection | Dimension 5 Behavior |
49
+ |---|---|---|
50
+ | `@tanstack/react-query` | dep exists | Check `useQuery`/`useMutation` calls |
51
+ | `swr` | dep exists | Check `useSWR` calls |
52
+ | `@trpc/client` | dep exists | Check tRPC router procedure calls |
53
+ | `@apollo/client` | dep exists | Check `useQuery`/`useMutation` with gql tags |
54
+ | `axios` / `fetch` | explicit patterns | Check direct call sites |
55
+
56
+ ### Build Tool Detection
57
+
58
+ | Signal | Detection | Impact |
59
+ |---|---|---|
60
+ | `vite.config.*` exists | File scan | Entry point: `index.html` → `src/main.tsx` |
61
+ | `next.config.*` exists | File scan | Entry managed by Next.js framework |
62
+ | `webpack.config.*` exists | File scan | Check entry field in config |
63
+
64
+ ---
65
+
66
+ ## Dimension Activation Matrix
67
+
68
+ Based on detected patterns, set active dimensions before running Layer 2.
69
+
70
+ | Framework | D1 (Import) | D2 (JSX) | D3 (Routes) | D4 (Store) | D5 (API) |
71
+ |---|---|---|---|---|---|
72
+ | React + react-router | Standard | Standard | Router config file | Per state lib | Per API lib |
73
+ | Next.js App Router | Check `app/` tree | Standard | File-based: `page.tsx` in dir = route | Per state lib | Check Server Actions too |
74
+ | Next.js Pages Router | Check `pages/` tree | Standard | File-based: `pages/foo.tsx` = `/foo` | Per state lib | Check `getServerSideProps`/`getStaticProps` |
75
+ | Remix | Check `app/routes/` | Standard | File-based + `remix.config` | Per state lib | Check `loader`/`action` exports |
76
+ | Vue + vue-router | Standard | `<template>` | Router config file | Pinia: `defineStore` | Per API lib |
77
+ | Svelte | Standard | Svelte components | SvelteKit: `src/routes/` | Svelte stores | Per API lib |
78
+ | No framework (Node.js) | Standard | Skip D2 | Skip D3 | Skip D4 | Standard |
79
+
80
+ ---
81
+
82
+ ## Output
83
+
84
+ Store detected context for use by all subsequent layers. Do not include it in the report unless something unusual was detected (e.g., conflicting signals, ambiguous router type).
85
+
86
+ ```
87
+ Project detected: React 18 + Vite + react-router v6 + Zustand + TanStack Query
88
+ Dimensions active: D1 ✓ D2 ✓ D3 (router config) D4 (Zustand) D5 (TanStack Query)
89
+ ```
90
+
91
+ If signals are ambiguous (e.g., both `app/` and `pages/` directories exist), note the ambiguity and default to the more restrictive check — verify both routing patterns.
@@ -0,0 +1,66 @@
1
+ # Runtime Wiring Verification
2
+
3
+ Phase 3 of the audit: verify that components and routes that passed static analysis actually render in the running application. Catches bugs static analysis cannot detect.
4
+
5
+ ---
6
+
7
+ ## Prerequisites
8
+
9
+ This phase runs only when ALL of the following conditions are met:
10
+
11
+ 1. The ftm-browse binary exists at `$HOME/.claude/skills/ftm-browse/bin/ftm-browse`
12
+ 2. A dev server is running — detected via:
13
+ - `lsof -i :3000` (Create React App, Next.js default)
14
+ - `lsof -i :5173` (Vite default)
15
+ - `lsof -i :8080` (various)
16
+ 3. The wiring contracts for the audited tasks include at least one `route_path` entry
17
+
18
+ If any prerequisite is not met, skip this phase and log: `Phase 3 (Runtime Wiring) skipped — [reason: no browse binary | no dev server | no route_path in contracts]`. Do NOT fail the overall audit.
19
+
20
+ ---
21
+
22
+ ## Process
23
+
24
+ For each wiring contract that includes a `route_path`:
25
+
26
+ 1. **Navigate** — `$PB goto <dev_server_url><route_path>`
27
+ 2. **Snapshot** — `$PB snapshot -i` to get the ARIA tree of interactive elements
28
+ 3. **Verify components render** — Check that expected components from the wiring contract appear in the ARIA tree:
29
+ - Expected buttons, links, inputs by their labels/roles
30
+ - Expected headings and landmarks
31
+ - Expected form fields
32
+ 4. **Screenshot** — `$PB screenshot` as evidence of the render state
33
+ 5. **Report findings:**
34
+ - `PASS` — All expected components found in ARIA tree
35
+ - `WARN` — Page renders but some expected components are missing
36
+ - `FAIL` — Page doesn't render (blank, error page, 404)
37
+
38
+ Where `$PB` is `$HOME/.claude/skills/ftm-browse/bin/ftm-browse`.
39
+
40
+ ---
41
+
42
+ ## What Runtime Wiring Catches
43
+
44
+ Static analysis (Layers 1-2) cannot detect these failure modes:
45
+
46
+ | Failure Mode | Example | Detection |
47
+ |---|---|---|
48
+ | Conditional render always false | `{isAdmin && <AdminPanel />}` where `isAdmin` is hardcoded `false` | Component missing from ARIA tree |
49
+ | Component crashes on mount | Runtime error in `useEffect` causes blank render | Error page or blank instead of expected content |
50
+ | CSS visibility hidden | `display: none` or `visibility: hidden` | Component in ARIA tree but not visually accessible |
51
+ | Server-side data dependency fails | `getServerSideProps` throws → component in error state | Error boundary rendered instead of component |
52
+ | Route registered but redirects | Route exists in config but always redirects away | Final URL differs from expected `route_path` |
53
+
54
+ These are flagged as **runtime-only findings** in the audit report if found after Layers 1-2 both passed.
55
+
56
+ ---
57
+
58
+ ## Integration with Layers 1-2
59
+
60
+ Runtime wiring is additive — it extends static analysis, not replaces it. The layer execution order is:
61
+
62
+ ```
63
+ Layer 1 (knip) → Layer 2 (adversarial) → Layer 3 (auto-fix) → Phase 3 (runtime, if prerequisites met)
64
+ ```
65
+
66
+ Runtime findings that survive after Layers 1-2 are clean represent genuine runtime-only bugs. Flag them separately so the developer knows they cannot be caught by future static checks alone.
@@ -0,0 +1,135 @@
1
+ # Wiring Contracts
2
+
3
+ A wiring contract is a YAML block in a plan task that declares the expected wiring for code produced by that task. It tells ftm-audit exactly what to verify — instead of guessing, the audit checks specific expectations.
4
+
5
+ **Graceful degradation:**
6
+ - Full contract → audit checks every declared wire
7
+ - Partial contract → audit checks what's declared, uses heuristics for the rest
8
+ - No contract → audit falls back to pure Layer 1 + Layer 2 analysis
9
+
10
+ ---
11
+
12
+ ## Schema
13
+
14
+ ```yaml
15
+ Wiring:
16
+ exports:
17
+ - symbol: ComponentName # What's being exported
18
+ from: src/components/Thing.tsx # From which file
19
+
20
+ imported_by:
21
+ - file: src/views/Dashboard.tsx # Which file should import it
22
+ line_hint: "import section" # Approximate location (optional)
23
+
24
+ rendered_in: # For React components
25
+ - parent: Dashboard # Parent component name
26
+ placement: "main content area" # Where in the JSX (descriptive)
27
+
28
+ route_path: /dashboard/thing # For routed views (optional)
29
+
30
+ nav_link: # For views that need navigation (optional)
31
+ - location: sidebar # Where the nav link goes
32
+ label: "Thing" # Display text
33
+
34
+ store_reads: # Store fields this code reads (optional)
35
+ - store: useAppStore
36
+ field: user.preferences
37
+
38
+ store_writes: # Store fields this code writes (optional)
39
+ - store: useAppStore
40
+ field: user.preferences
41
+ action: setPreferences
42
+
43
+ api_calls: # API functions this code invokes (optional)
44
+ - function: fetchUserPrefs
45
+ from: src/api/user.ts
46
+ ```
47
+
48
+ All fields are optional. Include only the dimensions relevant to the task.
49
+
50
+ ---
51
+
52
+ ## Contract Examples
53
+
54
+ ### React Component
55
+
56
+ ```yaml
57
+ ### Task 3: Build UserPreferences component
58
+ **Files:** Create src/components/UserPreferences.tsx
59
+ **Wiring:**
60
+ exports:
61
+ - symbol: UserPreferences
62
+ from: src/components/UserPreferences.tsx
63
+ imported_by:
64
+ - file: src/views/SettingsView.tsx
65
+ rendered_in:
66
+ - parent: SettingsView
67
+ placement: "below profile section"
68
+ store_reads:
69
+ - store: useAppStore
70
+ field: user.preferences
71
+ api_calls:
72
+ - function: updatePreferences
73
+ from: src/api/user.ts
74
+ ```
75
+
76
+ ### API Client Functions
77
+
78
+ ```yaml
79
+ ### Task 5: Add billing API functions
80
+ **Files:** Create src/api/billing.ts
81
+ **Wiring:**
82
+ exports:
83
+ - symbol: fetchInvoices
84
+ from: src/api/billing.ts
85
+ - symbol: createSubscription
86
+ from: src/api/billing.ts
87
+ imported_by:
88
+ - file: src/hooks/useBilling.ts
89
+ api_calls: [] # These ARE the API functions — nothing to call downstream
90
+ ```
91
+
92
+ ### New Route/View
93
+
94
+ ```yaml
95
+ ### Task 7: Build AnalyticsDashboard view
96
+ **Files:** Create src/views/AnalyticsDashboard.tsx
97
+ **Wiring:**
98
+ exports:
99
+ - symbol: AnalyticsDashboard
100
+ from: src/views/AnalyticsDashboard.tsx
101
+ imported_by:
102
+ - file: src/router.tsx
103
+ rendered_in:
104
+ - parent: RouterConfig
105
+ placement: "route element"
106
+ route_path: /analytics
107
+ nav_link:
108
+ - location: sidebar
109
+ label: "Analytics"
110
+ icon: BarChart
111
+ store_reads:
112
+ - store: useAppStore
113
+ field: analytics.dateRange
114
+ ```
115
+
116
+ ---
117
+
118
+ ## Verification Checks
119
+
120
+ For each field in the wiring contract, audit runs the corresponding check:
121
+
122
+ | Field | Check | Method |
123
+ |---|---|---|
124
+ | `exports` | Symbol exists as named export in specified file | `grep "export.*SymbolName"` or AST check |
125
+ | `imported_by` | Importing file contains the import statement | Check for `import { Symbol } from './path'` |
126
+ | `rendered_in` | Parent component's JSX contains `<Symbol` | Search JSX/TSX return statements |
127
+ | `route_path` | Router config contains route pointing to this component | Search router config file |
128
+ | `nav_link` | Navigation component has link with matching label and path | Search sidebar/navbar file |
129
+ | `store_reads` | Selector/hook call reads this field in the component | Search for selector usage |
130
+ | `store_writes` | Dispatch/action call writes this field | Search for action dispatch |
131
+ | `api_calls` | Function is imported and called in component or its hooks | Search for call sites |
132
+
133
+ Each check produces: `✅ VERIFIED file:line` or `❌ NOT FOUND — [what was expected] [where it was expected]`
134
+
135
+ **Rendering special cases:** Lazy imports (`React.lazy(() => import(...))`), conditional rendering (`{condition && <Component/>}`), render props, and HOCs all count as valid rendering for Dimension 2.
@@ -0,0 +1,69 @@
1
+ # Auto-Fix Strategies
2
+
3
+ Layer 3 applies fixes for each finding type, re-verifies, and produces a changelog. This document defines the fix strategy for each finding type and when to skip auto-fix.
4
+
5
+ ---
6
+
7
+ ## Fix Strategies by Finding Type
8
+
9
+ | Finding Type | Fix Strategy | Fallback |
10
+ |---|---|---|
11
+ | `UNUSED_FILE` | If created by the current task, add import from the appropriate parent module. If pre-existing dead code, flag for removal. | Flag for manual review — might be intentionally standalone (config, script) |
12
+ | `UNUSED_EXPORT` | If another module should consume it (check wiring contract), add the import. If truly unnecessary, remove the export keyword. | Flag for manual review |
13
+ | `UNWIRED_COMPONENT` | Add `<ComponentName />` to the parent component's JSX return. Determine placement from component name and parent structure. | Flag — can't determine correct placement |
14
+ | `ORPHAN_ROUTE` | Add route entry to the router config. Infer path from component name (e.g., `SettingsView` → `/settings`). Add nav link to sidebar/navbar if one exists. | Flag — route path ambiguous |
15
+ | `DEAD_STORE_FIELD` | If a component should read this field (check wiring contract), add the selector/hook usage. If truly unused, remove the field. | Flag — store design decision needed |
16
+ | `UNCALLED_API` | If a hook or component should call this (check wiring contract), add the invocation. If truly unused, remove the function. | Flag — API integration decision needed |
17
+ | `UNUSED_DEP` | Remove from `package.json` `dependencies` or `devDependencies`. | Flag if it might be used in scripts, config files, or CLI |
18
+ | `UNLISTED_DEP` | Run `npm install <package>` (or appropriate package manager command). | Flag if the import might be wrong |
19
+
20
+ ---
21
+
22
+ ## Fix Protocol
23
+
24
+ For each finding, follow this sequence:
25
+
26
+ 1. **Report** — Log the finding with type, file:line, and evidence
27
+ 2. **Determine fix** — Match finding type to fix strategy above. Check wiring contract for WHERE to wire, if available.
28
+ 3. **Show proposed fix** — Display the exact code change before applying:
29
+ ```
30
+ FIX: [UNWIRED_COMPONENT] NewWidget in Dashboard.tsx
31
+ Proposed: Add <NewWidget /> to Dashboard.tsx return JSX after line 45
32
+ ```
33
+ 4. **Apply fix** — Use Edit tool to make the change
34
+ 5. **Re-verify** — Run the specific check that found the issue:
35
+ - For knip findings: re-run `npx knip --reporter json`
36
+ - For adversarial findings: re-trace the specific wiring dimension
37
+ 6. **Log to changelog** — Record: timestamp, finding, fix applied, verification result
38
+
39
+ ---
40
+
41
+ ## When Auto-Fix Is Not Safe
42
+
43
+ Some findings cannot be auto-fixed without risking incorrect behavior:
44
+
45
+ - **Ambiguous placement** — cannot determine where exactly in a component the new element should render
46
+ - **Design decision needed** — whether a store field should exist at all requires product judgment
47
+ - **Cross-cutting changes** — fix requires modifying 5+ files simultaneously
48
+ - **Test-only code** — might be intentionally not wired into the app
49
+
50
+ For these, flag clearly:
51
+
52
+ ```
53
+ MANUAL_INTERVENTION_NEEDED:
54
+ - [ORPHAN_ROUTE] src/views/AdminPanel.tsx — cannot determine route path or nav placement
55
+ Suggested action: Add route to router config and nav link to sidebar
56
+ Reason auto-fix skipped: Multiple possible route paths (/admin, /settings/admin, /dashboard/admin)
57
+ ```
58
+
59
+ ---
60
+
61
+ ## Re-Verification Loop
62
+
63
+ After all auto-fixes are applied:
64
+
65
+ 1. Re-run Layer 1 (knip) — confirm no new unused code introduced by fixes
66
+ 2. Re-run Layer 2 (adversarial audit on the fix diff) — confirm fixes actually wire correctly
67
+ 3. If re-verification finds new issues, fix those too
68
+
69
+ **Loop limit:** Maximum 3 iterations to prevent infinite fix cycles. If issues persist after 3 iterations, stop and flag all remaining issues for manual intervention with a note explaining the loop was capped.