feed-the-machine 1.6.0 → 1.7.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 (269) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +170 -170
  3. package/bin/brain.py +1340 -0
  4. package/bin/convert_claude_skills_to_codex.py +490 -0
  5. package/bin/generate-manifest.mjs +463 -463
  6. package/bin/harden_codex_skills.py +141 -0
  7. package/bin/install.mjs +491 -491
  8. package/bin/migrate-eng-buddy-data.py +875 -0
  9. package/bin/playbook_engine/__init__.py +1 -0
  10. package/bin/playbook_engine/conftest.py +8 -0
  11. package/bin/playbook_engine/extractor.py +33 -0
  12. package/bin/playbook_engine/manager.py +102 -0
  13. package/bin/playbook_engine/models.py +84 -0
  14. package/bin/playbook_engine/registry.py +35 -0
  15. package/bin/playbook_engine/test_extractor.py +72 -0
  16. package/bin/playbook_engine/test_integration.py +129 -0
  17. package/bin/playbook_engine/test_manager.py +85 -0
  18. package/bin/playbook_engine/test_models.py +166 -0
  19. package/bin/playbook_engine/test_registry.py +67 -0
  20. package/bin/playbook_engine/test_tracer.py +86 -0
  21. package/bin/playbook_engine/tracer.py +93 -0
  22. package/bin/tasks_db.py +456 -0
  23. package/docs/HOOKS.md +243 -243
  24. package/docs/INBOX.md +233 -233
  25. package/ftm/SKILL.md +125 -122
  26. package/ftm-audit/SKILL.md +623 -623
  27. package/ftm-audit/references/protocols/PROJECT-PATTERNS.md +91 -91
  28. package/ftm-audit/references/protocols/RUNTIME-WIRING.md +66 -66
  29. package/ftm-audit/references/protocols/WIRING-CONTRACTS.md +135 -135
  30. package/ftm-audit/references/strategies/AUTO-FIX-STRATEGIES.md +69 -69
  31. package/ftm-audit/references/templates/REPORT-FORMAT.md +96 -96
  32. package/ftm-audit/scripts/run-knip.sh +23 -23
  33. package/ftm-audit.yml +2 -2
  34. package/ftm-brainstorm/SKILL.md +1003 -498
  35. package/ftm-brainstorm/evals/evals.json +180 -100
  36. package/ftm-brainstorm/evals/promptfoo.yaml +109 -109
  37. package/ftm-brainstorm/references/agent-prompts.md +552 -224
  38. package/ftm-brainstorm/references/plan-template.md +209 -121
  39. package/ftm-brainstorm.yml +2 -2
  40. package/ftm-browse/SKILL.md +454 -454
  41. package/ftm-browse/daemon/browser-manager.ts +206 -206
  42. package/ftm-browse/daemon/bun.lock +30 -30
  43. package/ftm-browse/daemon/cli.ts +347 -347
  44. package/ftm-browse/daemon/commands.ts +410 -410
  45. package/ftm-browse/daemon/main.ts +357 -357
  46. package/ftm-browse/daemon/package.json +17 -17
  47. package/ftm-browse/daemon/server.ts +189 -189
  48. package/ftm-browse/daemon/snapshot.ts +519 -519
  49. package/ftm-browse/daemon/tsconfig.json +22 -22
  50. package/ftm-browse.yml +4 -4
  51. package/ftm-capture/SKILL.md +370 -370
  52. package/ftm-capture.yml +4 -4
  53. package/ftm-codex-gate/SKILL.md +361 -361
  54. package/ftm-codex-gate.yml +2 -2
  55. package/ftm-config/SKILL.md +422 -345
  56. package/ftm-config.default.yml +125 -82
  57. package/ftm-config.yml +44 -2
  58. package/ftm-council/SKILL.md +416 -416
  59. package/ftm-council/references/prompts/CLAUDE-INVESTIGATION.md +60 -60
  60. package/ftm-council/references/prompts/CODEX-INVESTIGATION.md +58 -58
  61. package/ftm-council/references/prompts/GEMINI-INVESTIGATION.md +58 -58
  62. package/ftm-council/references/prompts/REBUTTAL-TEMPLATE.md +57 -57
  63. package/ftm-council/references/protocols/PREREQUISITES.md +47 -47
  64. package/ftm-council/references/protocols/STEP-0-FRAMING.md +46 -46
  65. package/ftm-council.yml +2 -2
  66. package/ftm-dashboard/SKILL.md +163 -163
  67. package/ftm-dashboard.yml +4 -4
  68. package/ftm-debug/SKILL.md +1037 -1037
  69. package/ftm-debug/references/phases/PHASE-0-INTAKE.md +58 -58
  70. package/ftm-debug/references/phases/PHASE-1-TRIAGE.md +46 -46
  71. package/ftm-debug/references/phases/PHASE-2-WAR-ROOM-AGENTS.md +279 -279
  72. package/ftm-debug/references/phases/PHASE-3-TO-6-EXECUTION.md +436 -436
  73. package/ftm-debug/references/protocols/BLACKBOARD.md +86 -86
  74. package/ftm-debug/references/protocols/EDGE-CASES.md +103 -103
  75. package/ftm-debug.yml +2 -2
  76. package/ftm-diagram/SKILL.md +277 -277
  77. package/ftm-diagram.yml +2 -2
  78. package/ftm-executor/SKILL.md +777 -777
  79. package/ftm-executor/references/STYLE-TEMPLATE.md +73 -73
  80. package/ftm-executor/references/phases/PHASE-0-VERIFICATION.md +62 -62
  81. package/ftm-executor/references/phases/PHASE-2-AGENT-ASSEMBLY.md +34 -34
  82. package/ftm-executor/references/phases/PHASE-3-WORKTREES.md +38 -38
  83. package/ftm-executor/references/phases/PHASE-4-5-AUDIT.md +72 -72
  84. package/ftm-executor/references/phases/PHASE-4-DISPATCH.md +66 -66
  85. package/ftm-executor/references/phases/PHASE-5-5-CODEX-GATE.md +73 -73
  86. package/ftm-executor/references/protocols/DOCUMENTATION-BOOTSTRAP.md +36 -36
  87. package/ftm-executor/references/protocols/MODEL-PROFILE.md +59 -59
  88. package/ftm-executor/references/protocols/PROGRESS-TRACKING.md +66 -66
  89. package/ftm-executor/runtime/ftm-runtime.mjs +252 -252
  90. package/ftm-executor/runtime/package.json +8 -8
  91. package/ftm-executor.yml +2 -2
  92. package/ftm-git/SKILL.md +441 -441
  93. package/ftm-git/evals/evals.json +26 -26
  94. package/ftm-git/evals/promptfoo.yaml +75 -75
  95. package/ftm-git/hooks/post-commit-experience.sh +92 -92
  96. package/ftm-git/references/patterns/SECRET-PATTERNS.md +104 -104
  97. package/ftm-git/references/protocols/REMEDIATION.md +139 -139
  98. package/ftm-git/scripts/pre-commit-secrets.sh +110 -110
  99. package/ftm-git.yml +2 -2
  100. package/ftm-inbox/backend/__pycache__/main.cpython-314.pyc +0 -0
  101. package/ftm-inbox/backend/adapters/_retry.py +64 -64
  102. package/ftm-inbox/backend/adapters/base.py +230 -230
  103. package/ftm-inbox/backend/adapters/freshservice.py +104 -104
  104. package/ftm-inbox/backend/adapters/gmail.py +125 -125
  105. package/ftm-inbox/backend/adapters/jira.py +136 -136
  106. package/ftm-inbox/backend/adapters/registry.py +192 -192
  107. package/ftm-inbox/backend/adapters/slack.py +110 -110
  108. package/ftm-inbox/backend/db/connection.py +54 -54
  109. package/ftm-inbox/backend/db/schema.py +78 -78
  110. package/ftm-inbox/backend/executor/__init__.py +7 -7
  111. package/ftm-inbox/backend/executor/engine.py +149 -149
  112. package/ftm-inbox/backend/executor/step_runner.py +98 -98
  113. package/ftm-inbox/backend/main.py +103 -103
  114. package/ftm-inbox/backend/models/__init__.py +1 -1
  115. package/ftm-inbox/backend/models/unified_task.py +36 -36
  116. package/ftm-inbox/backend/planner/__init__.py +6 -6
  117. package/ftm-inbox/backend/planner/__pycache__/__init__.cpython-314.pyc +0 -0
  118. package/ftm-inbox/backend/planner/__pycache__/generator.cpython-314.pyc +0 -0
  119. package/ftm-inbox/backend/planner/__pycache__/schema.cpython-314.pyc +0 -0
  120. package/ftm-inbox/backend/planner/generator.py +127 -127
  121. package/ftm-inbox/backend/planner/schema.py +34 -34
  122. package/ftm-inbox/backend/requirements.txt +5 -5
  123. package/ftm-inbox/backend/routes/__pycache__/plan.cpython-314.pyc +0 -0
  124. package/ftm-inbox/backend/routes/execute.py +186 -186
  125. package/ftm-inbox/backend/routes/health.py +52 -52
  126. package/ftm-inbox/backend/routes/inbox.py +68 -68
  127. package/ftm-inbox/backend/routes/plan.py +271 -271
  128. package/ftm-inbox/bin/launchagent.mjs +91 -91
  129. package/ftm-inbox/bin/setup.mjs +188 -188
  130. package/ftm-inbox/bin/start.sh +10 -10
  131. package/ftm-inbox/bin/status.sh +17 -17
  132. package/ftm-inbox/bin/stop.sh +8 -8
  133. package/ftm-inbox/config.example.yml +55 -55
  134. package/ftm-inbox/package-lock.json +2898 -2898
  135. package/ftm-inbox/package.json +26 -26
  136. package/ftm-inbox/postcss.config.js +6 -6
  137. package/ftm-inbox/src/app.css +199 -199
  138. package/ftm-inbox/src/app.html +18 -18
  139. package/ftm-inbox/src/lib/api.ts +166 -166
  140. package/ftm-inbox/src/lib/components/ExecutionLog.svelte +81 -81
  141. package/ftm-inbox/src/lib/components/InboxFeed.svelte +143 -143
  142. package/ftm-inbox/src/lib/components/PlanStep.svelte +271 -271
  143. package/ftm-inbox/src/lib/components/PlanView.svelte +206 -206
  144. package/ftm-inbox/src/lib/components/StreamPanel.svelte +99 -99
  145. package/ftm-inbox/src/lib/components/TaskCard.svelte +190 -190
  146. package/ftm-inbox/src/lib/components/ui/EmptyState.svelte +63 -63
  147. package/ftm-inbox/src/lib/components/ui/KawaiiCard.svelte +86 -86
  148. package/ftm-inbox/src/lib/components/ui/PillButton.svelte +106 -106
  149. package/ftm-inbox/src/lib/components/ui/StatusBadge.svelte +67 -67
  150. package/ftm-inbox/src/lib/components/ui/StreamDrawer.svelte +149 -149
  151. package/ftm-inbox/src/lib/components/ui/ThemeToggle.svelte +80 -80
  152. package/ftm-inbox/src/lib/theme.ts +47 -47
  153. package/ftm-inbox/src/routes/+layout.svelte +76 -76
  154. package/ftm-inbox/src/routes/+page.svelte +401 -401
  155. package/ftm-inbox/svelte.config.js +12 -12
  156. package/ftm-inbox/tailwind.config.ts +63 -63
  157. package/ftm-inbox/tsconfig.json +13 -13
  158. package/ftm-inbox/vite.config.ts +6 -6
  159. package/ftm-intent/SKILL.md +241 -241
  160. package/ftm-intent.yml +2 -2
  161. package/ftm-manifest.json +3794 -3794
  162. package/ftm-map/SKILL.md +291 -291
  163. package/ftm-map/scripts/db.py +712 -712
  164. package/ftm-map/scripts/index.py +415 -415
  165. package/ftm-map/scripts/parser.py +224 -224
  166. package/ftm-map/scripts/queries/go-tags.scm +20 -20
  167. package/ftm-map/scripts/queries/javascript-tags.scm +35 -35
  168. package/ftm-map/scripts/queries/python-tags.scm +31 -31
  169. package/ftm-map/scripts/queries/ruby-tags.scm +19 -19
  170. package/ftm-map/scripts/queries/rust-tags.scm +37 -37
  171. package/ftm-map/scripts/queries/typescript-tags.scm +41 -41
  172. package/ftm-map/scripts/query.py +301 -301
  173. package/ftm-map/scripts/ranker.py +377 -377
  174. package/ftm-map/scripts/requirements.txt +5 -5
  175. package/ftm-map/scripts/setup-hooks.sh +27 -27
  176. package/ftm-map/scripts/setup.sh +56 -56
  177. package/ftm-map/scripts/test_db.py +364 -364
  178. package/ftm-map/scripts/test_parser.py +174 -174
  179. package/ftm-map/scripts/test_query.py +183 -183
  180. package/ftm-map/scripts/test_ranker.py +199 -199
  181. package/ftm-map/scripts/views.py +591 -591
  182. package/ftm-map.yml +2 -2
  183. package/ftm-mind/SKILL.md +201 -1943
  184. package/ftm-mind/evals/promptfoo.yaml +142 -142
  185. package/ftm-mind/references/blackboard-protocol.md +110 -0
  186. package/ftm-mind/references/blackboard-schema.md +328 -328
  187. package/ftm-mind/references/complexity-guide.md +110 -110
  188. package/ftm-mind/references/complexity-sizing.md +138 -0
  189. package/ftm-mind/references/decide-act-protocol.md +172 -0
  190. package/ftm-mind/references/direct-execution.md +51 -0
  191. package/ftm-mind/references/environment-discovery.md +77 -0
  192. package/ftm-mind/references/event-registry.md +319 -319
  193. package/ftm-mind/references/mcp-inventory.md +300 -296
  194. package/ftm-mind/references/ops-routing.md +47 -0
  195. package/ftm-mind/references/orient-protocol.md +234 -0
  196. package/ftm-mind/references/personality.md +40 -0
  197. package/ftm-mind/references/protocols/COMPLEXITY-SIZING.md +72 -72
  198. package/ftm-mind/references/protocols/MCP-HEURISTICS.md +32 -32
  199. package/ftm-mind/references/protocols/PLAN-APPROVAL.md +80 -80
  200. package/ftm-mind/references/reflexion-protocol.md +249 -249
  201. package/ftm-mind/references/routing/SCENARIOS.md +22 -22
  202. package/ftm-mind/references/routing-scenarios.md +35 -35
  203. package/ftm-mind.yml +2 -2
  204. package/ftm-ops.yml +4 -0
  205. package/ftm-pause/SKILL.md +395 -395
  206. package/ftm-pause/references/protocols/SKILL-RESTORE-PROTOCOLS.md +186 -186
  207. package/ftm-pause/references/protocols/VALIDATION.md +80 -80
  208. package/ftm-pause.yml +2 -2
  209. package/ftm-researcher/SKILL.md +275 -275
  210. package/ftm-researcher/evals/agent-diversity.yaml +17 -17
  211. package/ftm-researcher/evals/synthesis-quality.yaml +12 -12
  212. package/ftm-researcher/evals/trigger-accuracy.yaml +39 -39
  213. package/ftm-researcher/references/adaptive-search.md +116 -116
  214. package/ftm-researcher/references/agent-prompts.md +193 -193
  215. package/ftm-researcher/references/council-integration.md +193 -193
  216. package/ftm-researcher/references/output-format.md +203 -203
  217. package/ftm-researcher/references/synthesis-pipeline.md +165 -165
  218. package/ftm-researcher/scripts/score_credibility.py +234 -234
  219. package/ftm-researcher/scripts/validate_research.py +92 -92
  220. package/ftm-researcher.yml +2 -2
  221. package/ftm-resume/SKILL.md +518 -518
  222. package/ftm-resume/references/protocols/VALIDATION.md +172 -172
  223. package/ftm-resume.yml +2 -2
  224. package/ftm-retro/SKILL.md +380 -380
  225. package/ftm-retro/references/protocols/SCORING-RUBRICS.md +89 -89
  226. package/ftm-retro/references/templates/REPORT-FORMAT.md +109 -109
  227. package/ftm-retro.yml +2 -2
  228. package/ftm-routine/SKILL.md +170 -170
  229. package/ftm-routine.yml +4 -4
  230. package/ftm-state/blackboard/capabilities.json +5 -5
  231. package/ftm-state/blackboard/capabilities.schema.json +27 -27
  232. package/ftm-state/blackboard/context.json +37 -23
  233. package/ftm-state/blackboard/experiences/doom-statusline-fix.json +26 -0
  234. package/ftm-state/blackboard/experiences/hackathon-pages-site.json +26 -0
  235. package/ftm-state/blackboard/experiences/hindsight-sso-kickoff.json +42 -0
  236. package/ftm-state/blackboard/experiences/index.json +58 -9
  237. package/ftm-state/blackboard/experiences/learning-ragnarok-api-access.json +23 -0
  238. package/ftm-state/blackboard/experiences/nordlayer-members-auto-assign.json +26 -0
  239. package/ftm-state/blackboard/experiences/saml2aws-stale-session-fix.json +41 -0
  240. package/ftm-state/blackboard/patterns.json +6 -6
  241. package/ftm-state/schemas/context.schema.json +130 -130
  242. package/ftm-state/schemas/experience-index.schema.json +77 -77
  243. package/ftm-state/schemas/experience.schema.json +78 -78
  244. package/ftm-state/schemas/patterns.schema.json +44 -44
  245. package/ftm-upgrade/SKILL.md +194 -194
  246. package/ftm-upgrade/scripts/check-version.sh +76 -76
  247. package/ftm-upgrade/scripts/upgrade.sh +143 -143
  248. package/ftm-upgrade.yml +2 -2
  249. package/ftm-verify.yml +2 -2
  250. package/ftm.yml +2 -2
  251. package/hooks/ftm-auto-log.sh +137 -0
  252. package/hooks/ftm-blackboard-enforcer.sh +93 -93
  253. package/hooks/ftm-discovery-reminder.sh +90 -90
  254. package/hooks/ftm-drafts-gate.sh +61 -61
  255. package/hooks/ftm-event-logger.mjs +107 -107
  256. package/hooks/ftm-install-hooks.sh +240 -0
  257. package/hooks/ftm-learning-capture.sh +117 -0
  258. package/hooks/ftm-map-autodetect.sh +79 -79
  259. package/hooks/ftm-pending-sync-check.sh +22 -22
  260. package/hooks/ftm-plan-gate.sh +92 -92
  261. package/hooks/ftm-post-commit-trigger.sh +57 -57
  262. package/hooks/ftm-post-compaction.sh +138 -0
  263. package/hooks/ftm-pre-compaction.sh +147 -0
  264. package/hooks/ftm-session-end.sh +52 -0
  265. package/hooks/ftm-session-snapshot.sh +213 -0
  266. package/hooks/settings-template.json +81 -81
  267. package/install.sh +363 -363
  268. package/package.json +84 -84
  269. package/uninstall.sh +25 -25
@@ -1,328 +1,328 @@
1
- # FTM-Mind Blackboard Schema Reference
2
-
3
- **Location**: `~/.claude/ftm-state/blackboard/`
4
- **Purpose**: Shared persistent memory for the ftm-mind unified intelligence system. Skills read from and write to these files using the Read and Write tools directly — no code libraries, no APIs.
5
-
6
- ---
7
-
8
- ## Source of Truth Matrix
9
-
10
- Each file has a single, non-overlapping responsibility. Never duplicate information across files.
11
-
12
- | File / Location | Owns | Never Contains |
13
- |---|---|---|
14
- | `blackboard/context.json` | Active session state — current task, decisions made this session, live constraints, user prefs | Cross-session learnings, historical patterns |
15
- | `blackboard/experiences/` | Cross-session learnings recorded after task completion | Current session state, live constraints |
16
- | `blackboard/patterns.json` | Promoted meta-insights distilled from multiple experiences | Raw individual experiences, session state |
17
- | `blackboard/experiences/index.json` | Index of all experience files (titles, tags, types, paths) | Full experience content |
18
- | `STATE.md` | Pause/resume snapshots (ftm-pause / ftm-resume) | Anything not related to pausing a session mid-stream |
19
- | `PROGRESS.md` | Executor wave progress during multi-agent runs | Session state, historical learnings |
20
- | `DEBUG.md` | Debug session traces from ftm-debug | Non-debug information |
21
- | `INTENT.md` | Codebase contract documents (API shapes, invariants) | Session state, learnings |
22
-
23
- ---
24
-
25
- ## 1. context.json
26
-
27
- **Path**: `~/.claude/ftm-state/blackboard/context.json`
28
- **Role**: Single source of truth for what is happening RIGHT NOW in the active session. Overwritten frequently — treat every write as a full replacement of the file.
29
-
30
- ### Full Schema
31
-
32
- ```json
33
- {
34
- "current_task": {
35
- "id": "string | null",
36
- "description": "string | null",
37
- "type": "string | null",
38
- "started_at": "ISO8601 timestamp | null",
39
- "status": "pending | in_progress | blocked | complete | null"
40
- },
41
- "recent_decisions": [
42
- {
43
- "decision": "string — what was decided",
44
- "reasoning": "string — why this choice was made",
45
- "timestamp": "ISO8601 timestamp",
46
- "task_id": "string | null — links back to current_task.id if applicable"
47
- }
48
- ],
49
- "active_constraints": [
50
- {
51
- "constraint": "string — description of the constraint",
52
- "source": "string — where it came from (e.g. user, skill-name, inferred)",
53
- "expires_at": "ISO8601 timestamp | null — null means indefinite"
54
- }
55
- ],
56
- "user_preferences": {
57
- "communication_style": "string | null — e.g. terse, detailed, bullet-first",
58
- "approval_gates": "string | null — e.g. ask_before_write, ask_before_commit, never",
59
- "default_model_profile": "string | null — e.g. fast, balanced, thorough"
60
- },
61
- "session_metadata": {
62
- "started_at": "ISO8601 timestamp | null",
63
- "last_updated": "ISO8601 timestamp | null",
64
- "conversation_id": "string | null",
65
- "messages_count": "integer",
66
- "skills_invoked": ["array of skill name strings invoked this session"]
67
- }
68
- }
69
- ```
70
-
71
- ### Field Notes
72
-
73
- - **`current_task.id`**: Use a short slug, e.g. `"refactor-auth-flow"` or `"debug-poller-crash"`. Does not need to be globally unique — it scopes within the session.
74
- - **`current_task.type`**: Free-form but aim for consistency: `feature`, `bug`, `refactor`, `investigation`, `configuration`, `documentation`, `test`, `deploy`.
75
- - **`recent_decisions`**: Cap at 10 entries. When adding an 11th, drop the oldest. This is a rolling window, not a history log.
76
- - **`active_constraints`**: Anything that limits what the system can do — e.g. "do not modify production DB", "user wants no auto-commits". Remove expired entries on each write.
77
- - **`user_preferences`**: Populated from observation or explicit instruction. Skills should read this before deciding how verbose to be or whether to ask for approval.
78
- - **`session_metadata.skills_invoked`**: Append skill names as they are activated. Used for retrospectives and debugging.
79
-
80
- ### Write Convention
81
-
82
- Always read the file first, apply your changes to the parsed object in memory, then write the entire file back. Never write partial JSON.
83
-
84
- ---
85
-
86
- ## 2. patterns.json
87
-
88
- **Path**: `~/.claude/ftm-state/blackboard/patterns.json`
89
- **Role**: Promoted meta-insights. An entry here means the same thing has been observed across multiple sessions and is considered reliable enough to act on without re-deriving it each time.
90
-
91
- ### Full Schema
92
-
93
- ```json
94
- {
95
- "codebase_insights": [
96
- {
97
- "insight": "string — the observation about the codebase",
98
- "file_pattern": "string — glob or path description, e.g. 'src/**/*.ts' or 'bin/poller*.py'",
99
- "confidence": "low | medium | high",
100
- "last_seen": "ISO8601 timestamp",
101
- "occurrences": "integer — how many times this was independently observed"
102
- }
103
- ],
104
- "execution_patterns": [
105
- {
106
- "pattern": "string — description of the recurring execution approach",
107
- "context": "string — what situation triggers this pattern",
108
- "outcome": "string — what typically results",
109
- "confidence": "low | medium | high",
110
- "occurrences": "integer",
111
- "last_reinforced": "ISO8601 timestamp"
112
- }
113
- ],
114
- "user_behavior": [
115
- {
116
- "behavior": "string — description of the observed user behavior or preference",
117
- "frequency": "rarely | sometimes | usually | always",
118
- "context": "string — when or under what conditions this behavior appears",
119
- "confidence": "low | medium | high"
120
- }
121
- ],
122
- "recurring_issues": [
123
- {
124
- "issue": "string — short title for the issue",
125
- "symptoms": "string — what it looks like when it occurs",
126
- "root_cause": "string | null — the underlying reason, if known",
127
- "resolution": "string | null — how to fix or work around it",
128
- "occurrences": "integer",
129
- "last_seen": "ISO8601 timestamp"
130
- }
131
- ]
132
- }
133
- ```
134
-
135
- ### Promotion Threshold
136
-
137
- A pattern should be promoted into patterns.json only after it has appeared in at least 2 separate experience files (different dates, different task slugs). A single observation belongs in an experience file, not here. Use `confidence: "low"` for newly promoted patterns with only 2 occurrences; raise to `"medium"` at 4+, `"high"` at 8+.
138
-
139
- ### Write Convention
140
-
141
- patterns.json is written infrequently — typically at the end of a session or after multiple experiences are reviewed. Read it, merge new insights, and write the full file back.
142
-
143
- ---
144
-
145
- ## 3. Experience Files
146
-
147
- **Directory**: `~/.claude/ftm-state/blackboard/experiences/`
148
- **Role**: Durable cross-session learnings, one file per completed task or significant interaction.
149
-
150
- ### File Naming Convention
151
-
152
- ```
153
- YYYY-MM-DD_task-slug.json
154
- ```
155
-
156
- Examples:
157
- - `2026-03-17_refactor-auth-flow.json`
158
- - `2026-03-17_debug-slack-poller-crash.json`
159
- - `2026-03-18_add-freshservice-enrichment.json`
160
-
161
- The task slug should be lowercase kebab-case, derived from `current_task.id` or the task description. If two tasks share a date and slug (rare), append a short suffix: `2026-03-17_refactor-auth-flow-2.json`.
162
-
163
- ### Experience Entry Schema
164
-
165
- ```json
166
- {
167
- "task_type": "string — matches current_task.type vocabulary: feature | bug | refactor | investigation | configuration | documentation | test | deploy",
168
- "description": "string — 1-2 sentence summary of what was attempted",
169
- "approach": "string — how the task was approached: tools used, strategies employed, sequence of steps",
170
- "outcome": "success | partial | failure",
171
- "lessons": [
172
- "string — each lesson is a concrete, actionable takeaway",
173
- "string — avoid vague statements like 'be more careful'; prefer 'check X before doing Y'"
174
- ],
175
- "time_taken": "string | null — approximate duration, e.g. '12 minutes', '2 hours'",
176
- "complexity_estimated": "trivial | low | medium | high | very_high",
177
- "complexity_actual": "trivial | low | medium | high | very_high",
178
- "capabilities_used": [
179
- "string — skill names, MCP tools, or agent types that were activated"
180
- ],
181
- "tags": [
182
- "string — searchable labels, e.g. 'python', 'slack', 'database', 'auth', 'poller'"
183
- ],
184
- "confidence": "low | medium | high",
185
- "recorded_at": "ISO8601 timestamp"
186
- }
187
- ```
188
-
189
- ### Field Notes
190
-
191
- - **`outcome`**: Use `partial` when the core task completed but side effects failed or follow-up is needed. Use `failure` only when the primary objective was not achieved.
192
- - **`lessons`**: The most important field. Write at least one lesson per experience. Make it specific enough that a future skill loading this file can act on it without further context.
193
- - **`complexity_estimated` vs `complexity_actual`**: Track both so the system can learn when its estimates are systematically off. If they diverge by more than one level, note why in `approach` or `lessons`.
194
- - **`capabilities_used`**: Include skill names (e.g. `ftm-executor`, `ftm-debug`), MCP server names (e.g. `mcp__mcp-atlassian-personal__jira_get_issue`), and agent types (e.g. `backend-architect`).
195
- - **`confidence`**: Reflects how certain you are that the lessons are generalizable. A one-off issue warrants `low`; a pattern confirmed multiple times within the session warrants `high`.
196
-
197
- ---
198
-
199
- ## 4. experiences/index.json
200
-
201
- **Path**: `~/.claude/ftm-state/blackboard/experiences/index.json`
202
- **Role**: Lightweight index for fast retrieval. Never contains full experience content — only enough metadata to decide which files to load.
203
-
204
- ### Full Schema
205
-
206
- ```json
207
- {
208
- "entries": [
209
- {
210
- "filename": "YYYY-MM-DD_task-slug.json",
211
- "task_type": "string",
212
- "tags": ["array", "of", "tags"],
213
- "outcome": "success | partial | failure",
214
- "confidence": "low | medium | high",
215
- "recorded_at": "ISO8601 timestamp"
216
- }
217
- ],
218
- "metadata": {
219
- "total_count": "integer",
220
- "last_updated": "ISO8601 timestamp | null",
221
- "max_entries": 200,
222
- "pruning_strategy": "remove_oldest_low_confidence"
223
- }
224
- }
225
- ```
226
-
227
- ### Pruning Rules
228
-
229
- When `total_count` exceeds `max_entries` (200):
230
- 1. Collect all entries where `confidence == "low"`.
231
- 2. Sort by `recorded_at` ascending (oldest first).
232
- 3. Delete index entries and their corresponding files until `total_count` is back under 200.
233
- 4. If all low-confidence entries are removed and the count is still over 200, repeat the process with `confidence == "medium"`, oldest first.
234
- 5. Never delete `confidence == "high"` entries through automatic pruning.
235
-
236
- ---
237
-
238
- ## 5. Retrieval Protocol
239
-
240
- When a skill needs to consult past experience before acting:
241
-
242
- 1. **Read** `experiences/index.json`.
243
- 2. **Filter** entries where `task_type` matches the current task type OR there is at least one tag overlap with the current task's tags.
244
- 3. **Sort** filtered results by `recorded_at` descending (most recent first).
245
- 4. **Load** the top 3–5 matching experience files by reading each `filename` from the `experiences/` directory.
246
- 5. **Synthesize** lessons from loaded files to inform the current approach. Prefer lessons from `confidence: "high"` or `outcome: "success"` entries.
247
- 6. If no matches are found, proceed without historical context (see Cold Start section).
248
-
249
- ---
250
-
251
- ## 6. Cold Start Protocol
252
-
253
- The blackboard starts empty. Empty is not broken — it is the normal starting state.
254
-
255
- When `experiences/index.json` has `total_count == 0` or `entries == []`:
256
-
257
- - **Do not enter a degraded mode.** The system has full capability.
258
- - **Do not warn the user** that there is no historical context unless directly asked.
259
- - **Proceed with full confidence**, relying on the current session context and skill instructions.
260
- - **Record experiences aggressively** during the first ~10 interactions. Every completed task, even trivial ones, should produce an experience file. This is how the system bootstraps its memory.
261
- - **Set `confidence: "low"` on early experiences** — they have not been cross-validated yet. Promote to `"medium"` or `"high"` as patterns recur.
262
-
263
- The goal of the cold start window is to populate the blackboard fast enough that by the 10th interaction, retrieval is already returning useful context.
264
-
265
- ---
266
-
267
- ## 7. Concurrency Rules
268
-
269
- Multiple executor agents may run in parallel during a ftm-executor wave. To prevent index corruption:
270
-
271
- - **Single-writer model for index.json**: Only the orchestrator (the coordinating skill, not individual executor agents) writes to `index.json`.
272
- - **Executor agents write individual experience files only.** Each executor writes its own `YYYY-MM-DD_task-slug.json` file using a unique slug derived from its task ID. Because filenames are unique, parallel writes to different files are safe.
273
- - **After wave completion**, the orchestrator reads all newly created experience files, merges their metadata entries into `index.json`, updates `total_count` and `last_updated`, and writes `index.json` once.
274
- - **context.json** is session-scoped and is written only by the primary coordinating agent for that session. Executors do not write context.json.
275
- - **patterns.json** is written only during post-session review or by an explicit pattern-promotion step, never during active execution.
276
-
277
- ---
278
-
279
- ## 8. Read/Write Conventions for Skills
280
-
281
- ### Reading
282
-
283
- Always use the Read tool with the absolute path:
284
-
285
- ```
286
- Read: ~/.claude/ftm-state/blackboard/context.json
287
- ```
288
-
289
- Parse the JSON content mentally before acting on it. If the file is empty or malformed, treat it as if all fields are null/empty and proceed without crashing.
290
-
291
- ### Writing
292
-
293
- Always:
294
- 1. Read the current file first.
295
- 2. Apply your changes to the parsed content.
296
- 3. Write the complete, valid JSON back using the Write tool.
297
-
298
- Never write partial files or append to JSON files. Every write is a full replacement.
299
-
300
- Use absolute paths:
301
-
302
- ```
303
- Write: ~/.claude/ftm-state/blackboard/context.json
304
- Write: ~/.claude/ftm-state/blackboard/patterns.json
305
- Write: ~/.claude/ftm-state/blackboard/experiences/index.json
306
- Write: ~/.claude/ftm-state/blackboard/experiences/YYYY-MM-DD_task-slug.json
307
- ```
308
-
309
- ### Validation Before Writing
310
-
311
- Before writing, verify:
312
- - All required fields are present (nulls are acceptable, missing keys are not).
313
- - Arrays are arrays, objects are objects — no type mismatches.
314
- - Timestamps are ISO8601 strings or null, never integers.
315
- - `recent_decisions` in context.json has at most 10 entries.
316
- - `entries` in index.json matches `metadata.total_count`.
317
-
318
- ---
319
-
320
- ## 9. Quick Reference: Key Paths
321
-
322
- | What | Absolute Path |
323
- |---|---|
324
- | Session state | `~/.claude/ftm-state/blackboard/context.json` |
325
- | Meta-patterns | `~/.claude/ftm-state/blackboard/patterns.json` |
326
- | Experience index | `~/.claude/ftm-state/blackboard/experiences/index.json` |
327
- | Experience files | `~/.claude/ftm-state/blackboard/experiences/YYYY-MM-DD_slug.json` |
328
- | This document | `~/.claude/skills/ftm-mind/references/blackboard-schema.md` |
1
+ # FTM-Mind Blackboard Schema Reference
2
+
3
+ **Location**: `~/.claude/ftm-state/blackboard/`
4
+ **Purpose**: Shared persistent memory for the ftm-mind unified intelligence system. Skills read from and write to these files using the Read and Write tools directly — no code libraries, no APIs.
5
+
6
+ ---
7
+
8
+ ## Source of Truth Matrix
9
+
10
+ Each file has a single, non-overlapping responsibility. Never duplicate information across files.
11
+
12
+ | File / Location | Owns | Never Contains |
13
+ |---|---|---|
14
+ | `blackboard/context.json` | Active session state — current task, decisions made this session, live constraints, user prefs | Cross-session learnings, historical patterns |
15
+ | `blackboard/experiences/` | Cross-session learnings recorded after task completion | Current session state, live constraints |
16
+ | `blackboard/patterns.json` | Promoted meta-insights distilled from multiple experiences | Raw individual experiences, session state |
17
+ | `blackboard/experiences/index.json` | Index of all experience files (titles, tags, types, paths) | Full experience content |
18
+ | `STATE.md` | Pause/resume snapshots (ftm-pause / ftm-resume) | Anything not related to pausing a session mid-stream |
19
+ | `PROGRESS.md` | Executor wave progress during multi-agent runs | Session state, historical learnings |
20
+ | `DEBUG.md` | Debug session traces from ftm-debug | Non-debug information |
21
+ | `INTENT.md` | Codebase contract documents (API shapes, invariants) | Session state, learnings |
22
+
23
+ ---
24
+
25
+ ## 1. context.json
26
+
27
+ **Path**: `~/.claude/ftm-state/blackboard/context.json`
28
+ **Role**: Single source of truth for what is happening RIGHT NOW in the active session. Overwritten frequently — treat every write as a full replacement of the file.
29
+
30
+ ### Full Schema
31
+
32
+ ```json
33
+ {
34
+ "current_task": {
35
+ "id": "string | null",
36
+ "description": "string | null",
37
+ "type": "string | null",
38
+ "started_at": "ISO8601 timestamp | null",
39
+ "status": "pending | in_progress | blocked | complete | null"
40
+ },
41
+ "recent_decisions": [
42
+ {
43
+ "decision": "string — what was decided",
44
+ "reasoning": "string — why this choice was made",
45
+ "timestamp": "ISO8601 timestamp",
46
+ "task_id": "string | null — links back to current_task.id if applicable"
47
+ }
48
+ ],
49
+ "active_constraints": [
50
+ {
51
+ "constraint": "string — description of the constraint",
52
+ "source": "string — where it came from (e.g. user, skill-name, inferred)",
53
+ "expires_at": "ISO8601 timestamp | null — null means indefinite"
54
+ }
55
+ ],
56
+ "user_preferences": {
57
+ "communication_style": "string | null — e.g. terse, detailed, bullet-first",
58
+ "approval_gates": "string | null — e.g. ask_before_write, ask_before_commit, never",
59
+ "default_model_profile": "string | null — e.g. fast, balanced, thorough"
60
+ },
61
+ "session_metadata": {
62
+ "started_at": "ISO8601 timestamp | null",
63
+ "last_updated": "ISO8601 timestamp | null",
64
+ "conversation_id": "string | null",
65
+ "messages_count": "integer",
66
+ "skills_invoked": ["array of skill name strings invoked this session"]
67
+ }
68
+ }
69
+ ```
70
+
71
+ ### Field Notes
72
+
73
+ - **`current_task.id`**: Use a short slug, e.g. `"refactor-auth-flow"` or `"debug-poller-crash"`. Does not need to be globally unique — it scopes within the session.
74
+ - **`current_task.type`**: Free-form but aim for consistency: `feature`, `bug`, `refactor`, `investigation`, `configuration`, `documentation`, `test`, `deploy`.
75
+ - **`recent_decisions`**: Cap at 10 entries. When adding an 11th, drop the oldest. This is a rolling window, not a history log.
76
+ - **`active_constraints`**: Anything that limits what the system can do — e.g. "do not modify production DB", "user wants no auto-commits". Remove expired entries on each write.
77
+ - **`user_preferences`**: Populated from observation or explicit instruction. Skills should read this before deciding how verbose to be or whether to ask for approval.
78
+ - **`session_metadata.skills_invoked`**: Append skill names as they are activated. Used for retrospectives and debugging.
79
+
80
+ ### Write Convention
81
+
82
+ Always read the file first, apply your changes to the parsed object in memory, then write the entire file back. Never write partial JSON.
83
+
84
+ ---
85
+
86
+ ## 2. patterns.json
87
+
88
+ **Path**: `~/.claude/ftm-state/blackboard/patterns.json`
89
+ **Role**: Promoted meta-insights. An entry here means the same thing has been observed across multiple sessions and is considered reliable enough to act on without re-deriving it each time.
90
+
91
+ ### Full Schema
92
+
93
+ ```json
94
+ {
95
+ "codebase_insights": [
96
+ {
97
+ "insight": "string — the observation about the codebase",
98
+ "file_pattern": "string — glob or path description, e.g. 'src/**/*.ts' or 'bin/poller*.py'",
99
+ "confidence": "low | medium | high",
100
+ "last_seen": "ISO8601 timestamp",
101
+ "occurrences": "integer — how many times this was independently observed"
102
+ }
103
+ ],
104
+ "execution_patterns": [
105
+ {
106
+ "pattern": "string — description of the recurring execution approach",
107
+ "context": "string — what situation triggers this pattern",
108
+ "outcome": "string — what typically results",
109
+ "confidence": "low | medium | high",
110
+ "occurrences": "integer",
111
+ "last_reinforced": "ISO8601 timestamp"
112
+ }
113
+ ],
114
+ "user_behavior": [
115
+ {
116
+ "behavior": "string — description of the observed user behavior or preference",
117
+ "frequency": "rarely | sometimes | usually | always",
118
+ "context": "string — when or under what conditions this behavior appears",
119
+ "confidence": "low | medium | high"
120
+ }
121
+ ],
122
+ "recurring_issues": [
123
+ {
124
+ "issue": "string — short title for the issue",
125
+ "symptoms": "string — what it looks like when it occurs",
126
+ "root_cause": "string | null — the underlying reason, if known",
127
+ "resolution": "string | null — how to fix or work around it",
128
+ "occurrences": "integer",
129
+ "last_seen": "ISO8601 timestamp"
130
+ }
131
+ ]
132
+ }
133
+ ```
134
+
135
+ ### Promotion Threshold
136
+
137
+ A pattern should be promoted into patterns.json only after it has appeared in at least 2 separate experience files (different dates, different task slugs). A single observation belongs in an experience file, not here. Use `confidence: "low"` for newly promoted patterns with only 2 occurrences; raise to `"medium"` at 4+, `"high"` at 8+.
138
+
139
+ ### Write Convention
140
+
141
+ patterns.json is written infrequently — typically at the end of a session or after multiple experiences are reviewed. Read it, merge new insights, and write the full file back.
142
+
143
+ ---
144
+
145
+ ## 3. Experience Files
146
+
147
+ **Directory**: `~/.claude/ftm-state/blackboard/experiences/`
148
+ **Role**: Durable cross-session learnings, one file per completed task or significant interaction.
149
+
150
+ ### File Naming Convention
151
+
152
+ ```
153
+ YYYY-MM-DD_task-slug.json
154
+ ```
155
+
156
+ Examples:
157
+ - `2026-03-17_refactor-auth-flow.json`
158
+ - `2026-03-17_debug-slack-poller-crash.json`
159
+ - `2026-03-18_add-freshservice-enrichment.json`
160
+
161
+ The task slug should be lowercase kebab-case, derived from `current_task.id` or the task description. If two tasks share a date and slug (rare), append a short suffix: `2026-03-17_refactor-auth-flow-2.json`.
162
+
163
+ ### Experience Entry Schema
164
+
165
+ ```json
166
+ {
167
+ "task_type": "string — matches current_task.type vocabulary: feature | bug | refactor | investigation | configuration | documentation | test | deploy",
168
+ "description": "string — 1-2 sentence summary of what was attempted",
169
+ "approach": "string — how the task was approached: tools used, strategies employed, sequence of steps",
170
+ "outcome": "success | partial | failure",
171
+ "lessons": [
172
+ "string — each lesson is a concrete, actionable takeaway",
173
+ "string — avoid vague statements like 'be more careful'; prefer 'check X before doing Y'"
174
+ ],
175
+ "time_taken": "string | null — approximate duration, e.g. '12 minutes', '2 hours'",
176
+ "complexity_estimated": "trivial | low | medium | high | very_high",
177
+ "complexity_actual": "trivial | low | medium | high | very_high",
178
+ "capabilities_used": [
179
+ "string — skill names, MCP tools, or agent types that were activated"
180
+ ],
181
+ "tags": [
182
+ "string — searchable labels, e.g. 'python', 'slack', 'database', 'auth', 'poller'"
183
+ ],
184
+ "confidence": "low | medium | high",
185
+ "recorded_at": "ISO8601 timestamp"
186
+ }
187
+ ```
188
+
189
+ ### Field Notes
190
+
191
+ - **`outcome`**: Use `partial` when the core task completed but side effects failed or follow-up is needed. Use `failure` only when the primary objective was not achieved.
192
+ - **`lessons`**: The most important field. Write at least one lesson per experience. Make it specific enough that a future skill loading this file can act on it without further context.
193
+ - **`complexity_estimated` vs `complexity_actual`**: Track both so the system can learn when its estimates are systematically off. If they diverge by more than one level, note why in `approach` or `lessons`.
194
+ - **`capabilities_used`**: Include skill names (e.g. `ftm-executor`, `ftm-debug`), MCP server names (e.g. `mcp__mcp-atlassian-personal__jira_get_issue`), and agent types (e.g. `backend-architect`).
195
+ - **`confidence`**: Reflects how certain you are that the lessons are generalizable. A one-off issue warrants `low`; a pattern confirmed multiple times within the session warrants `high`.
196
+
197
+ ---
198
+
199
+ ## 4. experiences/index.json
200
+
201
+ **Path**: `~/.claude/ftm-state/blackboard/experiences/index.json`
202
+ **Role**: Lightweight index for fast retrieval. Never contains full experience content — only enough metadata to decide which files to load.
203
+
204
+ ### Full Schema
205
+
206
+ ```json
207
+ {
208
+ "entries": [
209
+ {
210
+ "filename": "YYYY-MM-DD_task-slug.json",
211
+ "task_type": "string",
212
+ "tags": ["array", "of", "tags"],
213
+ "outcome": "success | partial | failure",
214
+ "confidence": "low | medium | high",
215
+ "recorded_at": "ISO8601 timestamp"
216
+ }
217
+ ],
218
+ "metadata": {
219
+ "total_count": "integer",
220
+ "last_updated": "ISO8601 timestamp | null",
221
+ "max_entries": 200,
222
+ "pruning_strategy": "remove_oldest_low_confidence"
223
+ }
224
+ }
225
+ ```
226
+
227
+ ### Pruning Rules
228
+
229
+ When `total_count` exceeds `max_entries` (200):
230
+ 1. Collect all entries where `confidence == "low"`.
231
+ 2. Sort by `recorded_at` ascending (oldest first).
232
+ 3. Delete index entries and their corresponding files until `total_count` is back under 200.
233
+ 4. If all low-confidence entries are removed and the count is still over 200, repeat the process with `confidence == "medium"`, oldest first.
234
+ 5. Never delete `confidence == "high"` entries through automatic pruning.
235
+
236
+ ---
237
+
238
+ ## 5. Retrieval Protocol
239
+
240
+ When a skill needs to consult past experience before acting:
241
+
242
+ 1. **Read** `experiences/index.json`.
243
+ 2. **Filter** entries where `task_type` matches the current task type OR there is at least one tag overlap with the current task's tags.
244
+ 3. **Sort** filtered results by `recorded_at` descending (most recent first).
245
+ 4. **Load** the top 3–5 matching experience files by reading each `filename` from the `experiences/` directory.
246
+ 5. **Synthesize** lessons from loaded files to inform the current approach. Prefer lessons from `confidence: "high"` or `outcome: "success"` entries.
247
+ 6. If no matches are found, proceed without historical context (see Cold Start section).
248
+
249
+ ---
250
+
251
+ ## 6. Cold Start Protocol
252
+
253
+ The blackboard starts empty. Empty is not broken — it is the normal starting state.
254
+
255
+ When `experiences/index.json` has `total_count == 0` or `entries == []`:
256
+
257
+ - **Do not enter a degraded mode.** The system has full capability.
258
+ - **Do not warn the user** that there is no historical context unless directly asked.
259
+ - **Proceed with full confidence**, relying on the current session context and skill instructions.
260
+ - **Record experiences aggressively** during the first ~10 interactions. Every completed task, even trivial ones, should produce an experience file. This is how the system bootstraps its memory.
261
+ - **Set `confidence: "low"` on early experiences** — they have not been cross-validated yet. Promote to `"medium"` or `"high"` as patterns recur.
262
+
263
+ The goal of the cold start window is to populate the blackboard fast enough that by the 10th interaction, retrieval is already returning useful context.
264
+
265
+ ---
266
+
267
+ ## 7. Concurrency Rules
268
+
269
+ Multiple executor agents may run in parallel during a ftm-executor wave. To prevent index corruption:
270
+
271
+ - **Single-writer model for index.json**: Only the orchestrator (the coordinating skill, not individual executor agents) writes to `index.json`.
272
+ - **Executor agents write individual experience files only.** Each executor writes its own `YYYY-MM-DD_task-slug.json` file using a unique slug derived from its task ID. Because filenames are unique, parallel writes to different files are safe.
273
+ - **After wave completion**, the orchestrator reads all newly created experience files, merges their metadata entries into `index.json`, updates `total_count` and `last_updated`, and writes `index.json` once.
274
+ - **context.json** is session-scoped and is written only by the primary coordinating agent for that session. Executors do not write context.json.
275
+ - **patterns.json** is written only during post-session review or by an explicit pattern-promotion step, never during active execution.
276
+
277
+ ---
278
+
279
+ ## 8. Read/Write Conventions for Skills
280
+
281
+ ### Reading
282
+
283
+ Always use the Read tool with the absolute path:
284
+
285
+ ```
286
+ Read: ~/.claude/ftm-state/blackboard/context.json
287
+ ```
288
+
289
+ Parse the JSON content mentally before acting on it. If the file is empty or malformed, treat it as if all fields are null/empty and proceed without crashing.
290
+
291
+ ### Writing
292
+
293
+ Always:
294
+ 1. Read the current file first.
295
+ 2. Apply your changes to the parsed content.
296
+ 3. Write the complete, valid JSON back using the Write tool.
297
+
298
+ Never write partial files or append to JSON files. Every write is a full replacement.
299
+
300
+ Use absolute paths:
301
+
302
+ ```
303
+ Write: ~/.claude/ftm-state/blackboard/context.json
304
+ Write: ~/.claude/ftm-state/blackboard/patterns.json
305
+ Write: ~/.claude/ftm-state/blackboard/experiences/index.json
306
+ Write: ~/.claude/ftm-state/blackboard/experiences/YYYY-MM-DD_task-slug.json
307
+ ```
308
+
309
+ ### Validation Before Writing
310
+
311
+ Before writing, verify:
312
+ - All required fields are present (nulls are acceptable, missing keys are not).
313
+ - Arrays are arrays, objects are objects — no type mismatches.
314
+ - Timestamps are ISO8601 strings or null, never integers.
315
+ - `recent_decisions` in context.json has at most 10 entries.
316
+ - `entries` in index.json matches `metadata.total_count`.
317
+
318
+ ---
319
+
320
+ ## 9. Quick Reference: Key Paths
321
+
322
+ | What | Absolute Path |
323
+ |---|---|
324
+ | Session state | `~/.claude/ftm-state/blackboard/context.json` |
325
+ | Meta-patterns | `~/.claude/ftm-state/blackboard/patterns.json` |
326
+ | Experience index | `~/.claude/ftm-state/blackboard/experiences/index.json` |
327
+ | Experience files | `~/.claude/ftm-state/blackboard/experiences/YYYY-MM-DD_slug.json` |
328
+ | This document | `~/.claude/skills/ftm-mind/references/blackboard-schema.md` |