fengming 0.3.9 → 0.3.11

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 (763) hide show
  1. package/dist/build-info.json +2 -2
  2. package/dist/{bundled-channel-config-schema-DpdKMATU.d.ts → bundled-channel-config-schema-Bte--ZlY.d.ts} +26 -26
  3. package/dist/canvas-host/a2ui/.bundle.hash +1 -1
  4. package/dist/cli-startup-metadata.json +8 -8
  5. package/dist/control-ui/assets/{activity-B2W-IeAT.js → activity-wgT0-JR0.js} +2 -2
  6. package/dist/control-ui/assets/{agents-mRUyNVCz.js → agents-DG5PobrT.js} +2 -2
  7. package/dist/control-ui/assets/{channels-8QHOqBnt.js → channels-CX28oM42.js} +2 -2
  8. package/dist/control-ui/assets/{cron-H3unP_mO.js → cron-B8ixwBqU.js} +2 -2
  9. package/dist/control-ui/assets/{debug-CxLsQ9vH.js → debug-CnkYZUXy.js} +2 -2
  10. package/dist/control-ui/assets/{index-jtIYT0Eh.js → index-DQRZJKbO.js} +4 -4
  11. package/dist/control-ui/assets/{instances-B1JQeCRb.js → instances-BE3mV1JC.js} +2 -2
  12. package/dist/control-ui/assets/{nodes-RGOmq_1l.js → nodes-Cou4PWRX.js} +2 -2
  13. package/dist/control-ui/assets/{sessions-C2O-Jgpg.js → sessions-DpAaBT21.js} +2 -2
  14. package/dist/control-ui/assets/{skills-jyJOYA4I.js → skills-DjA_j_20.js} +2 -2
  15. package/dist/control-ui/assets/{workboard-uM_kK8cQ.js → workboard-BFnvbS0k.js} +2 -2
  16. package/dist/control-ui/index.html +1 -1
  17. package/dist/control-ui/sw.js +1 -1
  18. package/dist/gateway/protocol/index.d.ts +1 -1
  19. package/dist/{index-DhOQs6M_.d.ts → index-DuDY3bCZ.d.ts} +45 -45
  20. package/dist/plugin-sdk/.boundary-entry-shims.stamp +1 -1
  21. package/dist/plugin-sdk/agent-config-primitives.d.ts +1 -1
  22. package/dist/plugin-sdk/{bundled-channel-config-schema-Dfn3b8sF.d.ts → bundled-channel-config-schema-BPFNnbwu.d.ts} +23 -23
  23. package/dist/plugin-sdk/bundled-channel-config-schema.d.ts +3 -3
  24. package/dist/plugin-sdk/channel-config-primitives.d.ts +2 -2
  25. package/dist/plugin-sdk/channel-config-schema-legacy.d.ts +3 -3
  26. package/dist/plugin-sdk/channel-config-schema.d.ts +2 -2
  27. package/dist/plugin-sdk/channel-core.d.ts +1 -1
  28. package/dist/plugin-sdk/channel-plugin-common.d.ts +1 -1
  29. package/dist/plugin-sdk/compat.d.ts +2 -2
  30. package/dist/plugin-sdk/{config-schema-DUddICQM.d.ts → config-schema-D7cABQ6o.d.ts} +1 -1
  31. package/dist/plugin-sdk/config-schema.d.ts +4 -4
  32. package/dist/plugin-sdk/core.d.ts +1 -1
  33. package/dist/plugin-sdk/discord.d.ts +2 -2
  34. package/dist/plugin-sdk/tts-runtime.d.ts +1 -1
  35. package/dist/plugin-sdk/{zod-schema.core-B4_b2R5K.d.ts → zod-schema.core-CwBNqcXp.d.ts} +1 -1
  36. package/dist/{zod-schema.core-Cuz0lz6m.d.ts → zod-schema.core-BGLctDlK.d.ts} +1 -1
  37. package/package.json +7 -412
  38. package/CHANGELOG.md +0 -38
  39. package/THIRD_PARTY_NOTICES.md +0 -37
  40. package/docs/.i18n/README.md +0 -81
  41. package/docs/.i18n/ar-navigation.json +0 -18
  42. package/docs/.i18n/de-navigation.json +0 -18
  43. package/docs/.i18n/es-navigation.json +0 -18
  44. package/docs/.i18n/fr-navigation.json +0 -18
  45. package/docs/.i18n/glossary.ar.json +0 -78
  46. package/docs/.i18n/glossary.de.json +0 -78
  47. package/docs/.i18n/glossary.es.json +0 -78
  48. package/docs/.i18n/glossary.fa.json +0 -78
  49. package/docs/.i18n/glossary.fr.json +0 -78
  50. package/docs/.i18n/glossary.id.json +0 -78
  51. package/docs/.i18n/glossary.it.json +0 -78
  52. package/docs/.i18n/glossary.ja-JP.json +0 -98
  53. package/docs/.i18n/glossary.ko.json +0 -78
  54. package/docs/.i18n/glossary.nl.json +0 -78
  55. package/docs/.i18n/glossary.pl.json +0 -78
  56. package/docs/.i18n/glossary.pt-BR.json +0 -78
  57. package/docs/.i18n/glossary.th.json +0 -78
  58. package/docs/.i18n/glossary.tr.json +0 -78
  59. package/docs/.i18n/glossary.uk.json +0 -78
  60. package/docs/.i18n/glossary.vi.json +0 -78
  61. package/docs/.i18n/glossary.zh-CN.json +0 -1122
  62. package/docs/.i18n/glossary.zh-TW.json +0 -78
  63. package/docs/.i18n/id-navigation.json +0 -18
  64. package/docs/.i18n/it-navigation.json +0 -18
  65. package/docs/.i18n/ja-navigation.json +0 -18
  66. package/docs/.i18n/ko-navigation.json +0 -18
  67. package/docs/.i18n/pl-navigation.json +0 -18
  68. package/docs/.i18n/pt-BR-navigation.json +0 -18
  69. package/docs/.i18n/tr-navigation.json +0 -18
  70. package/docs/.i18n/translation-workflow.md +0 -111
  71. package/docs/.i18n/zh-Hans-navigation.json +0 -552
  72. package/docs/AGENTS.md +0 -36
  73. package/docs/CLAUDE.md +0 -1
  74. package/docs/agent-runtime-architecture.md +0 -48
  75. package/docs/announcements/bluebubbles-imessage.md +0 -79
  76. package/docs/auth-credential-semantics.md +0 -124
  77. package/docs/automation/auth-monitoring.md +0 -11
  78. package/docs/automation/clawflow.md +0 -12
  79. package/docs/automation/cron-jobs.md +0 -534
  80. package/docs/automation/cron-vs-heartbeat.md +0 -11
  81. package/docs/automation/gmail-pubsub.md +0 -11
  82. package/docs/automation/hooks.md +0 -387
  83. package/docs/automation/index.md +0 -135
  84. package/docs/automation/poll.md +0 -12
  85. package/docs/automation/standing-orders.md +0 -250
  86. package/docs/automation/taskflow.md +0 -155
  87. package/docs/automation/tasks.md +0 -374
  88. package/docs/automation/troubleshooting.md +0 -12
  89. package/docs/automation/webhook.md +0 -12
  90. package/docs/brave-search.md +0 -11
  91. package/docs/channels/access-groups.md +0 -201
  92. package/docs/channels/ambient-room-events.md +0 -214
  93. package/docs/channels/bot-loop-protection.md +0 -131
  94. package/docs/channels/broadcast-groups.md +0 -472
  95. package/docs/channels/channel-routing.md +0 -162
  96. package/docs/channels/clickclack.md +0 -138
  97. package/docs/channels/discord.md +0 -1758
  98. package/docs/channels/feishu.md +0 -650
  99. package/docs/channels/googlechat.md +0 -284
  100. package/docs/channels/group-messages.md +0 -95
  101. package/docs/channels/groups.md +0 -524
  102. package/docs/channels/imessage-from-bluebubbles.md +0 -259
  103. package/docs/channels/imessage.md +0 -839
  104. package/docs/channels/index.md +0 -64
  105. package/docs/channels/irc.md +0 -253
  106. package/docs/channels/line.md +0 -243
  107. package/docs/channels/location.md +0 -71
  108. package/docs/channels/matrix-migration.md +0 -370
  109. package/docs/channels/matrix-presentation.md +0 -77
  110. package/docs/channels/matrix-push-rules.md +0 -150
  111. package/docs/channels/matrix.md +0 -921
  112. package/docs/channels/mattermost.md +0 -542
  113. package/docs/channels/msteams.md +0 -1096
  114. package/docs/channels/nextcloud-talk.md +0 -176
  115. package/docs/channels/nostr.md +0 -253
  116. package/docs/channels/pairing.md +0 -214
  117. package/docs/channels/qqbot.md +0 -314
  118. package/docs/channels/signal.md +0 -417
  119. package/docs/channels/slack.md +0 -1623
  120. package/docs/channels/synology-chat.md +0 -187
  121. package/docs/channels/telegram.md +0 -1124
  122. package/docs/channels/tlon.md +0 -296
  123. package/docs/channels/troubleshooting.md +0 -162
  124. package/docs/channels/twitch.md +0 -431
  125. package/docs/channels/wechat.md +0 -171
  126. package/docs/channels/whatsapp.md +0 -796
  127. package/docs/channels/yuanbao.md +0 -416
  128. package/docs/channels/zalo.md +0 -253
  129. package/docs/channels/zalouser.md +0 -217
  130. package/docs/ci.md +0 -657
  131. package/docs/clawhub/publishing.md +0 -96
  132. package/docs/cli/acp.md +0 -370
  133. package/docs/cli/agent.md +0 -109
  134. package/docs/cli/agents.md +0 -253
  135. package/docs/cli/approvals.md +0 -190
  136. package/docs/cli/backup.md +0 -98
  137. package/docs/cli/browser.md +0 -307
  138. package/docs/cli/channels.md +0 -154
  139. package/docs/cli/clawbot.md +0 -25
  140. package/docs/cli/commitments.md +0 -90
  141. package/docs/cli/completion.md +0 -39
  142. package/docs/cli/config.md +0 -504
  143. package/docs/cli/configure.md +0 -77
  144. package/docs/cli/crestodian.md +0 -337
  145. package/docs/cli/cron.md +0 -304
  146. package/docs/cli/daemon.md +0 -67
  147. package/docs/cli/dashboard.md +0 -33
  148. package/docs/cli/devices.md +0 -240
  149. package/docs/cli/directory.md +0 -68
  150. package/docs/cli/dns.md +0 -53
  151. package/docs/cli/docs.md +0 -63
  152. package/docs/cli/doctor.md +0 -241
  153. package/docs/cli/flows.md +0 -52
  154. package/docs/cli/gateway.md +0 -572
  155. package/docs/cli/health.md +0 -43
  156. package/docs/cli/hooks.md +0 -345
  157. package/docs/cli/index.md +0 -400
  158. package/docs/cli/infer.md +0 -364
  159. package/docs/cli/logs.md +0 -68
  160. package/docs/cli/mcp.md +0 -529
  161. package/docs/cli/memory.md +0 -183
  162. package/docs/cli/message.md +0 -317
  163. package/docs/cli/migrate.md +0 -334
  164. package/docs/cli/models.md +0 -239
  165. package/docs/cli/node.md +0 -177
  166. package/docs/cli/nodes.md +0 -76
  167. package/docs/cli/onboard.md +0 -250
  168. package/docs/cli/pairing.md +0 -77
  169. package/docs/cli/path.md +0 -511
  170. package/docs/cli/plugins.md +0 -459
  171. package/docs/cli/policy.md +0 -886
  172. package/docs/cli/proxy.md +0 -89
  173. package/docs/cli/qr.md +0 -56
  174. package/docs/cli/reset.md +0 -39
  175. package/docs/cli/sandbox.md +0 -208
  176. package/docs/cli/secrets.md +0 -202
  177. package/docs/cli/security.md +0 -136
  178. package/docs/cli/sessions.md +0 -164
  179. package/docs/cli/setup.md +0 -59
  180. package/docs/cli/skills.md +0 -122
  181. package/docs/cli/status.md +0 -45
  182. package/docs/cli/system.md +0 -89
  183. package/docs/cli/tasks.md +0 -111
  184. package/docs/cli/transcripts.md +0 -151
  185. package/docs/cli/tui.md +0 -91
  186. package/docs/cli/uninstall.md +0 -44
  187. package/docs/cli/update.md +0 -243
  188. package/docs/cli/voicecall.md +0 -204
  189. package/docs/cli/webhooks.md +0 -117
  190. package/docs/cli/wiki.md +0 -256
  191. package/docs/concepts/active-memory.md +0 -856
  192. package/docs/concepts/agent-loop.md +0 -185
  193. package/docs/concepts/agent-runtimes.md +0 -276
  194. package/docs/concepts/agent-workspace.md +0 -230
  195. package/docs/concepts/agent.md +0 -140
  196. package/docs/concepts/architecture.md +0 -154
  197. package/docs/concepts/channel-docking.md +0 -145
  198. package/docs/concepts/commitments.md +0 -150
  199. package/docs/concepts/compaction.md +0 -203
  200. package/docs/concepts/context-engine.md +0 -347
  201. package/docs/concepts/context.md +0 -199
  202. package/docs/concepts/delegate-architecture.md +0 -319
  203. package/docs/concepts/dreaming.md +0 -264
  204. package/docs/concepts/experimental-features.md +0 -109
  205. package/docs/concepts/features.md +0 -91
  206. package/docs/concepts/fengming-sdk.md +0 -323
  207. package/docs/concepts/mantis-slack-desktop-runbook.md +0 -231
  208. package/docs/concepts/mantis.md +0 -744
  209. package/docs/concepts/markdown-formatting.md +0 -139
  210. package/docs/concepts/memory-builtin.md +0 -148
  211. package/docs/concepts/memory-honcho.md +0 -144
  212. package/docs/concepts/memory-qmd.md +0 -271
  213. package/docs/concepts/memory-search.md +0 -167
  214. package/docs/concepts/memory.md +0 -299
  215. package/docs/concepts/message-lifecycle-refactor.md +0 -1126
  216. package/docs/concepts/messages.md +0 -214
  217. package/docs/concepts/model-failover.md +0 -384
  218. package/docs/concepts/model-providers.md +0 -719
  219. package/docs/concepts/models.md +0 -371
  220. package/docs/concepts/multi-agent.md +0 -625
  221. package/docs/concepts/oauth.md +0 -198
  222. package/docs/concepts/parallel-specialist-lanes.md +0 -127
  223. package/docs/concepts/personal-agent-benchmark-pack.md +0 -74
  224. package/docs/concepts/presence.md +0 -117
  225. package/docs/concepts/progress-drafts.md +0 -406
  226. package/docs/concepts/qa-e2e-automation.md +0 -947
  227. package/docs/concepts/qa-matrix.md +0 -139
  228. package/docs/concepts/queue-steering.md +0 -90
  229. package/docs/concepts/queue.md +0 -136
  230. package/docs/concepts/retry.md +0 -86
  231. package/docs/concepts/session-pruning.md +0 -104
  232. package/docs/concepts/session-tool.md +0 -188
  233. package/docs/concepts/session.md +0 -164
  234. package/docs/concepts/soul.md +0 -116
  235. package/docs/concepts/streaming.md +0 -257
  236. package/docs/concepts/system-prompt.md +0 -328
  237. package/docs/concepts/timezone.md +0 -47
  238. package/docs/concepts/typebox.md +0 -309
  239. package/docs/concepts/typing-indicators.md +0 -88
  240. package/docs/concepts/usage-tracking.md +0 -66
  241. package/docs/date-time.md +0 -126
  242. package/docs/debug/node-issue.md +0 -90
  243. package/docs/diagnostics/flags.md +0 -182
  244. package/docs/docs.json +0 -1862
  245. package/docs/fengming-agent-runtime.md +0 -82
  246. package/docs/gateway/authentication.md +0 -256
  247. package/docs/gateway/background-process.md +0 -147
  248. package/docs/gateway/bonjour.md +0 -303
  249. package/docs/gateway/bridge-protocol.md +0 -97
  250. package/docs/gateway/cli-backends.md +0 -439
  251. package/docs/gateway/config-agents.md +0 -1525
  252. package/docs/gateway/config-channels.md +0 -945
  253. package/docs/gateway/config-tools.md +0 -774
  254. package/docs/gateway/configuration-examples.md +0 -704
  255. package/docs/gateway/configuration-reference.md +0 -1391
  256. package/docs/gateway/configuration.md +0 -739
  257. package/docs/gateway/diagnostics.md +0 -213
  258. package/docs/gateway/discovery.md +0 -154
  259. package/docs/gateway/doctor.md +0 -575
  260. package/docs/gateway/gateway-lock.md +0 -37
  261. package/docs/gateway/health.md +0 -73
  262. package/docs/gateway/heartbeat.md +0 -498
  263. package/docs/gateway/index.md +0 -383
  264. package/docs/gateway/local-model-services.md +0 -205
  265. package/docs/gateway/local-models.md +0 -355
  266. package/docs/gateway/logging.md +0 -149
  267. package/docs/gateway/multiple-gateways.md +0 -178
  268. package/docs/gateway/network-model.md +0 -15
  269. package/docs/gateway/openai-http-api.md +0 -378
  270. package/docs/gateway/openresponses-http-api.md +0 -347
  271. package/docs/gateway/openshell.md +0 -316
  272. package/docs/gateway/opentelemetry.md +0 -433
  273. package/docs/gateway/operator-scopes.md +0 -119
  274. package/docs/gateway/pairing.md +0 -207
  275. package/docs/gateway/prometheus.md +0 -249
  276. package/docs/gateway/protocol.md +0 -826
  277. package/docs/gateway/remote-gateway-readme.md +0 -169
  278. package/docs/gateway/remote.md +0 -280
  279. package/docs/gateway/sandbox-vs-tool-policy-vs-elevated.md +0 -148
  280. package/docs/gateway/sandboxing.md +0 -546
  281. package/docs/gateway/secrets-plan-contract.md +0 -159
  282. package/docs/gateway/secrets.md +0 -805
  283. package/docs/gateway/security/audit-checks.md +0 -127
  284. package/docs/gateway/security/exposure-runbook.md +0 -212
  285. package/docs/gateway/security/index.md +0 -1343
  286. package/docs/gateway/security/secure-file-operations.md +0 -76
  287. package/docs/gateway/security/shrinkwrap.md +0 -111
  288. package/docs/gateway/tailscale.md +0 -156
  289. package/docs/gateway/tools-invoke-http-api.md +0 -169
  290. package/docs/gateway/troubleshooting.md +0 -877
  291. package/docs/gateway/trusted-proxy-auth.md +0 -483
  292. package/docs/help/debugging.md +0 -341
  293. package/docs/help/environment.md +0 -233
  294. package/docs/help/faq-first-run.md +0 -870
  295. package/docs/help/faq-models.md +0 -556
  296. package/docs/help/faq.md +0 -2041
  297. package/docs/help/index.md +0 -39
  298. package/docs/help/scripts.md +0 -56
  299. package/docs/help/testing-live.md +0 -587
  300. package/docs/help/testing-updates-plugins.md +0 -299
  301. package/docs/help/testing.md +0 -977
  302. package/docs/help/troubleshooting.md +0 -449
  303. package/docs/index.md +0 -196
  304. package/docs/install/ansible.md +0 -233
  305. package/docs/install/azure.md +0 -315
  306. package/docs/install/bun.md +0 -59
  307. package/docs/install/clawdock.md +0 -112
  308. package/docs/install/development-channels.md +0 -148
  309. package/docs/install/digitalocean.md +0 -174
  310. package/docs/install/docker-vm-runtime.md +0 -154
  311. package/docs/install/docker.md +0 -564
  312. package/docs/install/exe-dev.md +0 -201
  313. package/docs/install/fly.md +0 -524
  314. package/docs/install/gcp.md +0 -418
  315. package/docs/install/hetzner.md +0 -285
  316. package/docs/install/hostinger.md +0 -98
  317. package/docs/install/index.md +0 -232
  318. package/docs/install/installer.md +0 -447
  319. package/docs/install/kubernetes.md +0 -196
  320. package/docs/install/macos-vm.md +0 -281
  321. package/docs/install/migrating-claude.md +0 -165
  322. package/docs/install/migrating-hermes.md +0 -178
  323. package/docs/install/migrating.md +0 -137
  324. package/docs/install/nix.md +0 -112
  325. package/docs/install/node.md +0 -142
  326. package/docs/install/northflank.mdx +0 -44
  327. package/docs/install/oracle.md +0 -218
  328. package/docs/install/podman.md +0 -216
  329. package/docs/install/railway.mdx +0 -92
  330. package/docs/install/raspberry-pi.md +0 -234
  331. package/docs/install/render.mdx +0 -167
  332. package/docs/install/uninstall.md +0 -131
  333. package/docs/install/updating.md +0 -284
  334. package/docs/install/upstash.md +0 -96
  335. package/docs/logging.md +0 -320
  336. package/docs/nav-tabs-underline.js +0 -100
  337. package/docs/network.md +0 -72
  338. package/docs/nodes/audio.md +0 -216
  339. package/docs/nodes/camera.md +0 -166
  340. package/docs/nodes/images.md +0 -77
  341. package/docs/nodes/index.md +0 -439
  342. package/docs/nodes/location-command.md +0 -102
  343. package/docs/nodes/media-understanding.md +0 -495
  344. package/docs/nodes/talk.md +0 -160
  345. package/docs/nodes/troubleshooting.md +0 -123
  346. package/docs/nodes/voicewake.md +0 -93
  347. package/docs/perplexity.md +0 -11
  348. package/docs/plan/codex-context-engine-harness.md +0 -624
  349. package/docs/plan/ui-channels.md +0 -284
  350. package/docs/platforms/digitalocean.md +0 -12
  351. package/docs/platforms/easyrunner.md +0 -109
  352. package/docs/platforms/index.md +0 -51
  353. package/docs/platforms/linux.md +0 -141
  354. package/docs/platforms/mac/bundled-gateway.md +0 -79
  355. package/docs/platforms/mac/canvas.md +0 -128
  356. package/docs/platforms/mac/child-process.md +0 -72
  357. package/docs/platforms/mac/dev-setup.md +0 -112
  358. package/docs/platforms/mac/health.md +0 -39
  359. package/docs/platforms/mac/icon.md +0 -36
  360. package/docs/platforms/mac/logging.md +0 -62
  361. package/docs/platforms/mac/menu-bar.md +0 -93
  362. package/docs/platforms/mac/peekaboo.md +0 -96
  363. package/docs/platforms/mac/permissions.md +0 -73
  364. package/docs/platforms/mac/remote.md +0 -123
  365. package/docs/platforms/mac/signing.md +0 -52
  366. package/docs/platforms/mac/skills.md +0 -43
  367. package/docs/platforms/mac/voice-overlay.md +0 -66
  368. package/docs/platforms/mac/voicewake.md +0 -73
  369. package/docs/platforms/mac/webchat.md +0 -54
  370. package/docs/platforms/mac/xpc.md +0 -66
  371. package/docs/platforms/oracle.md +0 -12
  372. package/docs/platforms/raspberry-pi.md +0 -13
  373. package/docs/platforms/windows.md +0 -286
  374. package/docs/plugins/adding-capabilities.md +0 -146
  375. package/docs/plugins/admin-http-rpc.md +0 -216
  376. package/docs/plugins/agent-tools.md +0 -13
  377. package/docs/plugins/architecture-internals.md +0 -1196
  378. package/docs/plugins/architecture.md +0 -483
  379. package/docs/plugins/building-extensions.md +0 -13
  380. package/docs/plugins/building-plugins.md +0 -335
  381. package/docs/plugins/bundles.md +0 -310
  382. package/docs/plugins/cli-backend-plugins.md +0 -310
  383. package/docs/plugins/codex-computer-use.md +0 -297
  384. package/docs/plugins/codex-harness-reference.md +0 -470
  385. package/docs/plugins/codex-harness-runtime.md +0 -268
  386. package/docs/plugins/codex-harness.md +0 -780
  387. package/docs/plugins/codex-native-plugins.md +0 -276
  388. package/docs/plugins/community.md +0 -77
  389. package/docs/plugins/compatibility.md +0 -167
  390. package/docs/plugins/copilot.md +0 -356
  391. package/docs/plugins/dependency-resolution.md +0 -176
  392. package/docs/plugins/google-meet.md +0 -1737
  393. package/docs/plugins/hooks.md +0 -484
  394. package/docs/plugins/install-overrides.md +0 -80
  395. package/docs/plugins/manage-plugins.md +0 -210
  396. package/docs/plugins/manifest.md +0 -1457
  397. package/docs/plugins/memory-lancedb.md +0 -385
  398. package/docs/plugins/memory-wiki.md +0 -529
  399. package/docs/plugins/message-presentation.md +0 -473
  400. package/docs/plugins/oc-path.md +0 -166
  401. package/docs/plugins/plugin-inventory.md +0 -189
  402. package/docs/plugins/plugin-permission-requests.md +0 -193
  403. package/docs/plugins/reference/acpx.md +0 -23
  404. package/docs/plugins/reference/admin-http-rpc.md +0 -23
  405. package/docs/plugins/reference/alibaba.md +0 -23
  406. package/docs/plugins/reference/amazon-bedrock-mantle.md +0 -23
  407. package/docs/plugins/reference/amazon-bedrock.md +0 -23
  408. package/docs/plugins/reference/anthropic-vertex.md +0 -19
  409. package/docs/plugins/reference/anthropic.md +0 -23
  410. package/docs/plugins/reference/arcee.md +0 -23
  411. package/docs/plugins/reference/azure-speech.md +0 -23
  412. package/docs/plugins/reference/bonjour.md +0 -19
  413. package/docs/plugins/reference/brave.md +0 -23
  414. package/docs/plugins/reference/browser.md +0 -23
  415. package/docs/plugins/reference/byteplus.md +0 -19
  416. package/docs/plugins/reference/canvas.md +0 -19
  417. package/docs/plugins/reference/cerebras.md +0 -23
  418. package/docs/plugins/reference/chutes.md +0 -23
  419. package/docs/plugins/reference/clickclack.md +0 -23
  420. package/docs/plugins/reference/cloudflare-ai-gateway.md +0 -23
  421. package/docs/plugins/reference/codex-supervisor.md +0 -27
  422. package/docs/plugins/reference/codex.md +0 -23
  423. package/docs/plugins/reference/comfy.md +0 -23
  424. package/docs/plugins/reference/copilot-proxy.md +0 -19
  425. package/docs/plugins/reference/copilot.md +0 -23
  426. package/docs/plugins/reference/deepgram.md +0 -23
  427. package/docs/plugins/reference/deepinfra.md +0 -23
  428. package/docs/plugins/reference/deepseek.md +0 -23
  429. package/docs/plugins/reference/diagnostics-otel.md +0 -19
  430. package/docs/plugins/reference/diagnostics-prometheus.md +0 -19
  431. package/docs/plugins/reference/diffs-language-pack.md +0 -19
  432. package/docs/plugins/reference/diffs.md +0 -19
  433. package/docs/plugins/reference/discord.md +0 -23
  434. package/docs/plugins/reference/document-extract.md +0 -23
  435. package/docs/plugins/reference/duckduckgo.md +0 -23
  436. package/docs/plugins/reference/elevenlabs.md +0 -23
  437. package/docs/plugins/reference/exa.md +0 -23
  438. package/docs/plugins/reference/fal.md +0 -23
  439. package/docs/plugins/reference/feishu.md +0 -23
  440. package/docs/plugins/reference/file-transfer.md +0 -19
  441. package/docs/plugins/reference/firecrawl.md +0 -23
  442. package/docs/plugins/reference/fireworks.md +0 -23
  443. package/docs/plugins/reference/github-copilot.md +0 -23
  444. package/docs/plugins/reference/gmi.md +0 -23
  445. package/docs/plugins/reference/google-meet.md +0 -23
  446. package/docs/plugins/reference/google.md +0 -23
  447. package/docs/plugins/reference/googlechat.md +0 -23
  448. package/docs/plugins/reference/gradium.md +0 -23
  449. package/docs/plugins/reference/groq.md +0 -23
  450. package/docs/plugins/reference/huggingface.md +0 -23
  451. package/docs/plugins/reference/imessage.md +0 -23
  452. package/docs/plugins/reference/inworld.md +0 -23
  453. package/docs/plugins/reference/irc.md +0 -23
  454. package/docs/plugins/reference/kilocode.md +0 -23
  455. package/docs/plugins/reference/kimi.md +0 -23
  456. package/docs/plugins/reference/line.md +0 -23
  457. package/docs/plugins/reference/litellm.md +0 -23
  458. package/docs/plugins/reference/llm-task.md +0 -19
  459. package/docs/plugins/reference/lmstudio.md +0 -23
  460. package/docs/plugins/reference/lobster.md +0 -19
  461. package/docs/plugins/reference/matrix.md +0 -23
  462. package/docs/plugins/reference/mattermost.md +0 -23
  463. package/docs/plugins/reference/memory-core.md +0 -19
  464. package/docs/plugins/reference/memory-lancedb.md +0 -23
  465. package/docs/plugins/reference/memory-wiki.md +0 -23
  466. package/docs/plugins/reference/microsoft-foundry.md +0 -19
  467. package/docs/plugins/reference/microsoft.md +0 -19
  468. package/docs/plugins/reference/migrate-claude.md +0 -19
  469. package/docs/plugins/reference/migrate-hermes.md +0 -19
  470. package/docs/plugins/reference/minimax.md +0 -23
  471. package/docs/plugins/reference/mistral.md +0 -23
  472. package/docs/plugins/reference/moonshot.md +0 -23
  473. package/docs/plugins/reference/msteams.md +0 -23
  474. package/docs/plugins/reference/nextcloud-talk.md +0 -23
  475. package/docs/plugins/reference/nostr.md +0 -23
  476. package/docs/plugins/reference/novita.md +0 -23
  477. package/docs/plugins/reference/nvidia.md +0 -23
  478. package/docs/plugins/reference/oc-path.md +0 -23
  479. package/docs/plugins/reference/ollama.md +0 -23
  480. package/docs/plugins/reference/open-prose.md +0 -19
  481. package/docs/plugins/reference/openai.md +0 -23
  482. package/docs/plugins/reference/opencode-go.md +0 -23
  483. package/docs/plugins/reference/opencode.md +0 -23
  484. package/docs/plugins/reference/openrouter.md +0 -23
  485. package/docs/plugins/reference/openshell.md +0 -19
  486. package/docs/plugins/reference/perplexity.md +0 -23
  487. package/docs/plugins/reference/pixverse.md +0 -23
  488. package/docs/plugins/reference/policy.md +0 -72
  489. package/docs/plugins/reference/qa-channel.md +0 -23
  490. package/docs/plugins/reference/qa-lab.md +0 -19
  491. package/docs/plugins/reference/qa-matrix.md +0 -19
  492. package/docs/plugins/reference/qianfan.md +0 -23
  493. package/docs/plugins/reference/qqbot.md +0 -23
  494. package/docs/plugins/reference/qwen.md +0 -23
  495. package/docs/plugins/reference/runway.md +0 -23
  496. package/docs/plugins/reference/searxng.md +0 -19
  497. package/docs/plugins/reference/senseaudio.md +0 -23
  498. package/docs/plugins/reference/sglang.md +0 -23
  499. package/docs/plugins/reference/signal.md +0 -23
  500. package/docs/plugins/reference/skill-workshop.md +0 -23
  501. package/docs/plugins/reference/slack.md +0 -23
  502. package/docs/plugins/reference/stepfun.md +0 -23
  503. package/docs/plugins/reference/synology-chat.md +0 -23
  504. package/docs/plugins/reference/synthetic.md +0 -23
  505. package/docs/plugins/reference/tavily.md +0 -23
  506. package/docs/plugins/reference/telegram.md +0 -23
  507. package/docs/plugins/reference/tencent.md +0 -23
  508. package/docs/plugins/reference/tlon.md +0 -23
  509. package/docs/plugins/reference/together.md +0 -23
  510. package/docs/plugins/reference/tokenjuice.md +0 -23
  511. package/docs/plugins/reference/tts-local-cli.md +0 -19
  512. package/docs/plugins/reference/twitch.md +0 -23
  513. package/docs/plugins/reference/venice.md +0 -23
  514. package/docs/plugins/reference/vercel-ai-gateway.md +0 -23
  515. package/docs/plugins/reference/vllm.md +0 -23
  516. package/docs/plugins/reference/voice-call.md +0 -23
  517. package/docs/plugins/reference/volcengine.md +0 -23
  518. package/docs/plugins/reference/voyage.md +0 -19
  519. package/docs/plugins/reference/vydra.md +0 -23
  520. package/docs/plugins/reference/web-readability.md +0 -19
  521. package/docs/plugins/reference/webhooks.md +0 -23
  522. package/docs/plugins/reference/whatsapp.md +0 -23
  523. package/docs/plugins/reference/workboard.md +0 -23
  524. package/docs/plugins/reference/xai.md +0 -23
  525. package/docs/plugins/reference/xiaomi.md +0 -23
  526. package/docs/plugins/reference/zai.md +0 -23
  527. package/docs/plugins/reference/zalo.md +0 -23
  528. package/docs/plugins/reference/zalouser.md +0 -24
  529. package/docs/plugins/reference.md +0 -145
  530. package/docs/plugins/sdk-agent-harness.md +0 -338
  531. package/docs/plugins/sdk-channel-inbound.md +0 -70
  532. package/docs/plugins/sdk-channel-ingress.md +0 -137
  533. package/docs/plugins/sdk-channel-message.md +0 -18
  534. package/docs/plugins/sdk-channel-outbound.md +0 -113
  535. package/docs/plugins/sdk-channel-plugins.md +0 -765
  536. package/docs/plugins/sdk-channel-turn.md +0 -9
  537. package/docs/plugins/sdk-entrypoints.md +0 -344
  538. package/docs/plugins/sdk-migration.md +0 -979
  539. package/docs/plugins/sdk-overview.md +0 -511
  540. package/docs/plugins/sdk-provider-plugins.md +0 -846
  541. package/docs/plugins/sdk-runtime.md +0 -676
  542. package/docs/plugins/sdk-setup.md +0 -550
  543. package/docs/plugins/sdk-subpaths.md +0 -391
  544. package/docs/plugins/sdk-testing.md +0 -403
  545. package/docs/plugins/skill-workshop.md +0 -713
  546. package/docs/plugins/tool-plugins.md +0 -411
  547. package/docs/plugins/voice-call.md +0 -942
  548. package/docs/plugins/webhooks.md +0 -192
  549. package/docs/plugins/workboard.md +0 -252
  550. package/docs/plugins/zalouser.md +0 -86
  551. package/docs/prose.md +0 -137
  552. package/docs/providers/alibaba.md +0 -158
  553. package/docs/providers/anthropic.md +0 -381
  554. package/docs/providers/arcee.md +0 -144
  555. package/docs/providers/azure-speech.md +0 -119
  556. package/docs/providers/bedrock-mantle.md +0 -211
  557. package/docs/providers/bedrock.md +0 -414
  558. package/docs/providers/cerebras.md +0 -130
  559. package/docs/providers/chutes.md +0 -153
  560. package/docs/providers/claude-max-api-proxy.md +0 -191
  561. package/docs/providers/cloudflare-ai-gateway.md +0 -119
  562. package/docs/providers/comfy.md +0 -362
  563. package/docs/providers/deepgram.md +0 -184
  564. package/docs/providers/deepinfra.md +0 -92
  565. package/docs/providers/deepseek.md +0 -146
  566. package/docs/providers/ds4.md +0 -309
  567. package/docs/providers/elevenlabs.md +0 -130
  568. package/docs/providers/fal.md +0 -240
  569. package/docs/providers/fireworks.md +0 -144
  570. package/docs/providers/github-copilot.md +0 -257
  571. package/docs/providers/gmi.md +0 -92
  572. package/docs/providers/google.md +0 -472
  573. package/docs/providers/gradium.md +0 -123
  574. package/docs/providers/groq.md +0 -171
  575. package/docs/providers/huggingface.md +0 -235
  576. package/docs/providers/index.md +0 -105
  577. package/docs/providers/inferrs.md +0 -272
  578. package/docs/providers/inworld.md +0 -120
  579. package/docs/providers/kilocode.md +0 -135
  580. package/docs/providers/litellm.md +0 -234
  581. package/docs/providers/lmstudio.md +0 -224
  582. package/docs/providers/minimax.md +0 -505
  583. package/docs/providers/mistral.md +0 -235
  584. package/docs/providers/models.md +0 -64
  585. package/docs/providers/moonshot.md +0 -413
  586. package/docs/providers/novita.md +0 -92
  587. package/docs/providers/nvidia.md +0 -158
  588. package/docs/providers/ollama-cloud.md +0 -115
  589. package/docs/providers/ollama.md +0 -1225
  590. package/docs/providers/openai.md +0 -1093
  591. package/docs/providers/opencode-go.md +0 -123
  592. package/docs/providers/opencode.md +0 -149
  593. package/docs/providers/openrouter.md +0 -349
  594. package/docs/providers/perplexity-provider.md +0 -123
  595. package/docs/providers/pixverse.md +0 -165
  596. package/docs/providers/qianfan.md +0 -132
  597. package/docs/providers/qwen-oauth.md +0 -115
  598. package/docs/providers/qwen.md +0 -364
  599. package/docs/providers/runway.md +0 -103
  600. package/docs/providers/senseaudio.md +0 -68
  601. package/docs/providers/sglang.md +0 -161
  602. package/docs/providers/stepfun.md +0 -229
  603. package/docs/providers/synthetic.md +0 -154
  604. package/docs/providers/tencent.md +0 -130
  605. package/docs/providers/together.md +0 -140
  606. package/docs/providers/venice.md +0 -312
  607. package/docs/providers/vercel-ai-gateway.md +0 -128
  608. package/docs/providers/vllm.md +0 -407
  609. package/docs/providers/volcengine.md +0 -199
  610. package/docs/providers/vydra.md +0 -180
  611. package/docs/providers/xai.md +0 -571
  612. package/docs/providers/xiaomi.md +0 -262
  613. package/docs/providers/zai.md +0 -224
  614. package/docs/refactor/access.md +0 -9
  615. package/docs/refactor/acp.md +0 -298
  616. package/docs/refactor/canvas.md +0 -131
  617. package/docs/refactor/database-first.md +0 -2256
  618. package/docs/refactor/ingress-core.md +0 -341
  619. package/docs/reference/AGENTS.default.md +0 -131
  620. package/docs/reference/RELEASING.md +0 -799
  621. package/docs/reference/api-usage-costs.md +0 -208
  622. package/docs/reference/application-modernization-plan.md +0 -208
  623. package/docs/reference/code-mode.md +0 -773
  624. package/docs/reference/credits.md +0 -33
  625. package/docs/reference/device-models.md +0 -50
  626. package/docs/reference/fengming-sdk-api-design.md +0 -390
  627. package/docs/reference/full-release-validation.md +0 -202
  628. package/docs/reference/memory-config.md +0 -604
  629. package/docs/reference/prompt-caching.md +0 -358
  630. package/docs/reference/release-performance-sweep.md +0 -360
  631. package/docs/reference/rich-output-protocol.md +0 -101
  632. package/docs/reference/rpc.md +0 -43
  633. package/docs/reference/secret-placeholder-conventions.md +0 -33
  634. package/docs/reference/secretref-credential-surface.md +0 -159
  635. package/docs/reference/secretref-user-supplied-credentials-matrix.json +0 -663
  636. package/docs/reference/session-management-compaction.md +0 -474
  637. package/docs/reference/templates/AGENTS.dev.md +0 -90
  638. package/docs/reference/templates/AGENTS.md +0 -227
  639. package/docs/reference/templates/BOOT.md +0 -16
  640. package/docs/reference/templates/BOOTSTRAP.md +0 -66
  641. package/docs/reference/templates/CLAUDE.md +0 -1
  642. package/docs/reference/templates/HEARTBEAT.md +0 -24
  643. package/docs/reference/templates/IDENTITY.dev.md +0 -52
  644. package/docs/reference/templates/IDENTITY.md +0 -34
  645. package/docs/reference/templates/SOUL.dev.md +0 -82
  646. package/docs/reference/templates/SOUL.md +0 -49
  647. package/docs/reference/templates/TOOLS.dev.md +0 -29
  648. package/docs/reference/templates/TOOLS.md +0 -51
  649. package/docs/reference/templates/USER.dev.md +0 -23
  650. package/docs/reference/templates/USER.md +0 -28
  651. package/docs/reference/test.md +0 -247
  652. package/docs/reference/token-use.md +0 -246
  653. package/docs/reference/transcript-hygiene.md +0 -214
  654. package/docs/reference/wizard.md +0 -252
  655. package/docs/security/CONTRIBUTING-THREAT-MODEL.md +0 -101
  656. package/docs/security/THREAT-MODEL-ATLAS.md +0 -611
  657. package/docs/security/formal-verification.md +0 -170
  658. package/docs/security/incident-response.md +0 -59
  659. package/docs/security/network-proxy.md +0 -268
  660. package/docs/snippets/plugin-publish/minimal-fengming.plugin.json +0 -12
  661. package/docs/snippets/plugin-publish/minimal-package.json +0 -16
  662. package/docs/specs/claw-supervisor.md +0 -247
  663. package/docs/start/bootstrapping.md +0 -49
  664. package/docs/start/docs-directory.md +0 -69
  665. package/docs/start/fengming.md +0 -252
  666. package/docs/start/getting-started.md +0 -152
  667. package/docs/start/hubs.md +0 -201
  668. package/docs/start/lore.md +0 -223
  669. package/docs/start/onboarding-overview.md +0 -72
  670. package/docs/start/onboarding.md +0 -98
  671. package/docs/start/quickstart.md +0 -25
  672. package/docs/start/setup.md +0 -178
  673. package/docs/start/showcase.md +0 -363
  674. package/docs/start/wizard-cli-automation.md +0 -232
  675. package/docs/start/wizard-cli-reference.md +0 -331
  676. package/docs/start/wizard.md +0 -141
  677. package/docs/style.css +0 -137
  678. package/docs/superpowers/specs/2026-04-22-tweakcn-custom-theme-import-design.md +0 -316
  679. package/docs/tools/acp-agents-setup.md +0 -351
  680. package/docs/tools/acp-agents.md +0 -854
  681. package/docs/tools/agent-send.md +0 -130
  682. package/docs/tools/apply-patch.md +0 -64
  683. package/docs/tools/brave-search.md +0 -139
  684. package/docs/tools/browser-control.md +0 -391
  685. package/docs/tools/browser-linux-troubleshooting.md +0 -173
  686. package/docs/tools/browser-login.md +0 -77
  687. package/docs/tools/browser-wsl2-windows-remote-cdp-troubleshooting.md +0 -219
  688. package/docs/tools/browser.md +0 -810
  689. package/docs/tools/btw.md +0 -159
  690. package/docs/tools/capability-cookbook.md +0 -12
  691. package/docs/tools/clawhub.md +0 -5
  692. package/docs/tools/code-execution.md +0 -173
  693. package/docs/tools/creating-skills.md +0 -158
  694. package/docs/tools/diffs.md +0 -525
  695. package/docs/tools/duckduckgo-search.md +0 -109
  696. package/docs/tools/elevated.md +0 -128
  697. package/docs/tools/exa-search.md +0 -152
  698. package/docs/tools/exec-approvals-advanced.md +0 -444
  699. package/docs/tools/exec-approvals.md +0 -494
  700. package/docs/tools/exec.md +0 -285
  701. package/docs/tools/firecrawl.md +0 -155
  702. package/docs/tools/gemini-search.md +0 -114
  703. package/docs/tools/goal.md +0 -217
  704. package/docs/tools/grok-search.md +0 -129
  705. package/docs/tools/image-generation.md +0 -493
  706. package/docs/tools/index.md +0 -178
  707. package/docs/tools/kimi-search.md +0 -105
  708. package/docs/tools/llm-task.md +0 -137
  709. package/docs/tools/lobster.md +0 -365
  710. package/docs/tools/loop-detection.md +0 -154
  711. package/docs/tools/media-overview.md +0 -160
  712. package/docs/tools/minimax-search.md +0 -102
  713. package/docs/tools/multi-agent-sandbox-tools.md +0 -409
  714. package/docs/tools/music-generation.md +0 -372
  715. package/docs/tools/ollama-search.md +0 -153
  716. package/docs/tools/pdf.md +0 -213
  717. package/docs/tools/perplexity-search.md +0 -220
  718. package/docs/tools/plugin.md +0 -363
  719. package/docs/tools/reactions.md +0 -100
  720. package/docs/tools/searxng-search.md +0 -141
  721. package/docs/tools/skills-config.md +0 -195
  722. package/docs/tools/skills.md +0 -569
  723. package/docs/tools/slash-commands.md +0 -487
  724. package/docs/tools/steer.md +0 -77
  725. package/docs/tools/subagents.md +0 -651
  726. package/docs/tools/tavily.md +0 -162
  727. package/docs/tools/thinking.md +0 -142
  728. package/docs/tools/tokenjuice.md +0 -84
  729. package/docs/tools/tool-search.md +0 -269
  730. package/docs/tools/trajectory.md +0 -229
  731. package/docs/tools/tts.md +0 -1009
  732. package/docs/tools/video-generation.md +0 -555
  733. package/docs/tools/web-fetch.md +0 -210
  734. package/docs/tools/web.md +0 -461
  735. package/docs/tts.md +0 -11
  736. package/docs/vps.md +0 -139
  737. package/docs/web/control-ui.md +0 -512
  738. package/docs/web/dashboard.md +0 -107
  739. package/docs/web/index.md +0 -133
  740. package/docs/web/tui.md +0 -250
  741. package/docs/web/webchat.md +0 -102
  742. package/npm-shrinkwrap.json +0 -12861
  743. package/patches/.gitkeep +0 -0
  744. package/patches/@agentclientprotocol__claude-agent-acp@0.37.0.patch +0 -41
  745. package/pnpm-workspace.yaml +0 -120
  746. package/scripts/crabbox-wrapper.mjs +0 -2004
  747. package/scripts/lib/official-external-channel-catalog.json +0 -560
  748. package/scripts/lib/official-external-plugin-catalog.json +0 -264
  749. package/scripts/lib/official-external-provider-catalog.json +0 -158
  750. package/scripts/lib/package-dist-imports.mjs +0 -171
  751. package/scripts/npm-runner.mjs +0 -91
  752. package/scripts/postinstall-bundled-plugins.mjs +0 -978
  753. package/scripts/preinstall-package-manager-warning.mjs +0 -64
  754. package/scripts/prepare-git-hooks.mjs +0 -72
  755. package/scripts/windows-cmd-helpers.mjs +0 -22
  756. package/skills/batch/SKILL.md +0 -118
  757. package/skills/code-review/SKILL.md +0 -107
  758. package/skills/debug/SKILL.md +0 -83
  759. package/skills/loop/SKILL.md +0 -118
  760. package/skills/run/SKILL.md +0 -79
  761. package/skills/run-skill-generator/SKILL.md +0 -179
  762. package/skills/verify/SKILL.md +0 -103
  763. package/src/agents/templates/HEARTBEAT.md +0 -3
@@ -1,2256 +0,0 @@
1
- ---
2
- summary: "Migration plan for making SQLite the primary durable state and cache layer while keeping config file-backed"
3
- title: "Database-first state refactor"
4
- read_when:
5
- - Moving FengMing runtime data, cache, transcripts, task state, or scratch files into SQLite
6
- - Designing doctor migrations from legacy JSON or JSONL files
7
- - Changing backup, restore, VFS, or worker storage behavior
8
- - Removing session locks, pruning, truncation, or JSON compatibility paths
9
- ---
10
-
11
- # Database-First State Refactor
12
-
13
- ## Decision
14
-
15
- Use a two-level SQLite layout:
16
-
17
- - Global database: `~/.fengming/state/fengming.sqlite`
18
- - Agent database: one SQLite database per agent for agent-owned workspace,
19
- transcript, VFS, artifact, and large per-agent runtime state
20
- - Configuration stays file-backed: `fengming.json` remains outside the
21
- database. Runtime auth profiles move to SQLite; external provider or CLI
22
- credential files remain owner-managed outside FengMing's database.
23
-
24
- The global database is the control-plane database. It owns agent discovery,
25
- shared gateway state, pairing, device/node state, task and flow ledgers, plugin
26
- state, scheduler runtime state, backup metadata, and migration state.
27
-
28
- The agent database is the data-plane database. It owns the agent's session
29
- metadata, transcript event stream, VFS workspace or scratch namespace, tool
30
- artifacts, run artifacts, and searchable/indexable agent-local cache data.
31
-
32
- This gives one durable global view without forcing large agent workspaces,
33
- transcripts, and binary scratch data into the shared gateway write lane.
34
-
35
- ## Hard Contract
36
-
37
- This migration has one canonical runtime shape:
38
-
39
- - Session rows persist session metadata only. They must not persist
40
- `transcriptLocator`, transcript file paths, sibling JSONL paths, lock paths,
41
- pruning metadata, or file-era compatibility pointers.
42
- - Transcript identity is always SQLite identity: `{agentId, sessionId}` plus
43
- optional topic metadata where the protocol needs it.
44
- - `sqlite-transcript://...` is not a runtime or protocol identity. New code must
45
- not derive, persist, pass, parse, or migrate transcript locators. Runtime and
46
- tests should not contain pseudo-locators at all; docs may mention the string
47
- only to ban it.
48
- - Legacy `sessions.json`, transcript JSONL, `.jsonl.lock`, pruning, truncation,
49
- and old session-path logic belong only to the doctor migration/import path.
50
- - Legacy session config aliases belong only to doctor migration. Runtime does
51
- not interpret `session.idleMinutes`, `session.resetByType.dm`, or
52
- cross-agent `agent:main:*` main-session aliases for another configured agent.
53
- - Session routing identity is typed relational state. Hot runtime and UI paths
54
- should read `sessions.session_scope`, `sessions.account_id`,
55
- `sessions.primary_conversation_id`, `conversations`, and
56
- `session_conversations`; they must not parse `session_key` or mine
57
- `session_entries.entry_json` for provider identity except as a compatibility
58
- shadow while old call sites are being deleted.
59
- - Channel-level direct-message markers such as `dm` versus `direct` are routing
60
- vocabulary, not transcript locators or file-store compatibility handles.
61
- - Legacy hook handler config belongs only to doctor warning/migration surfaces.
62
- Runtime must not load `hooks.internal.handlers`; hooks run through discovered
63
- hook directories and `HOOK.md` metadata only.
64
- - Runtime startup, hot reply paths, compaction, reset, recovery, diagnostics,
65
- TTS, memory hooks, subagents, plugin command routing, protocol boundaries, and
66
- hooks must pass `{agentId, sessionId}` through the runtime.
67
- - Tests should seed and assert SQLite transcript rows through
68
- `{agentId, sessionId}`. Tests that only prove JSONL path forwarding,
69
- caller-supplied locator preservation, or transcript-file compatibility should
70
- be deleted unless they cover doctor import, non-session support/debug
71
- materialization, or protocol shape.
72
- - `runEmbeddedPiAgent(...)`, prepared worker runs, and the inner embedded
73
- attempt must not accept transcript locators. They open the SQLite transcript
74
- manager by `{agentId, sessionId}` and pass that manager to the internalized
75
- PI-compatible agent session, so stale callers cannot make the runner write
76
- JSON/JSONL transcripts.
77
- - Runner diagnostics must store runtime/cache/payload trace records in SQLite.
78
- Runtime diagnostics must not expose JSONL file override knobs or generic
79
- transcript JSONL export helpers; user-facing exports can materialize explicit
80
- artifacts from database rows without feeding file names back into runtime.
81
- - Raw stream logging uses `FENGMING_RAW_STREAM=1` plus SQLite diagnostics rows.
82
- The old pi-mono `PI_RAW_STREAM`, `PI_RAW_STREAM_PATH`, and
83
- `raw-openai-completions.jsonl` file logger contract is not part of FengMing
84
- runtime or tests.
85
- - QMD memory indexing must not export SQLite transcripts to markdown files.
86
- QMD indexes configured memory files only; session transcript search stays
87
- SQLite-backed.
88
- - The QMD SDK subpath is QMD-only for new code. SQLite session transcript
89
- indexing helpers live on `memory-core-host-engine-session-transcripts`; any
90
- QMD re-export is compatibility only and must not be used by runtime code.
91
- - Built-in memory indexes live in the owning agent database. Runtime config and
92
- resolved runtime contracts must not expose `memorySearch.store.path`; doctor
93
- deletes that legacy config key and current code passes the agent
94
- `databasePath` internally.
95
-
96
- Implementation work should keep deleting code until these statements are true
97
- without exceptions outside doctor/import/export/debug boundaries.
98
-
99
- ## Goal state and progress
100
-
101
- ### Hard goal
102
-
103
- - One global SQLite database owns control-plane state:
104
- `state/fengming.sqlite`.
105
- - One per-agent SQLite database owns data-plane state:
106
- `agents/<agentId>/agent/fengming-agent.sqlite`.
107
- - Config remains file-backed. `fengming.json` is not part of this database
108
- refactor.
109
- - Legacy files are doctor migration inputs only.
110
- - Runtime never writes or reads session or transcript JSONL as active state.
111
-
112
- ### Goal states
113
-
114
- - `not-started`: file-era runtime code still writes active state.
115
- - `migrating`: doctor/import code can move file data into SQLite.
116
- - `dual-read`: temporary bridge reads both SQLite and legacy files. This state
117
- is forbidden for this refactor unless it is explicitly documented as
118
- doctor-only.
119
- - `sqlite-runtime`: runtime reads and writes SQLite only.
120
- - `clean`: legacy runtime APIs and tests are removed, and the guard prevents
121
- regressions.
122
- - `done`: docs, tests, backup, doctor migration, and changed checks prove the
123
- clean state.
124
-
125
- ### Current state
126
-
127
- - Sessions: `clean` for runtime. Session rows live in the per-agent database,
128
- runtime APIs use `{agentId, sessionId}` or `{agentId, sessionKey}`, and
129
- `sessions.json` is doctor-only legacy input.
130
- - Transcripts: `clean` for runtime. Transcript events, identities, snapshots,
131
- and trajectory runtime events live in the per-agent database. Runtime no
132
- longer accepts transcript locators or JSONL transcript paths.
133
- - PI embedded runner: `clean`. Embedded PI runs, prepared workers, compaction,
134
- and retry loops use SQLite session scope and reject stale transcript handles.
135
- - Cron: `clean` for runtime. Runtime uses `cron_jobs` and `cron_run_logs`;
136
- runtime tests use SQLite `storeKey` naming, and file-era cron paths remain in
137
- doctor legacy migration tests only.
138
- - Task registry: `clean`. Task and Task Flow runtime rows live in
139
- `state/fengming.sqlite`; unshipped sidecar SQLite importers are deleted.
140
- - Plugin state: `clean`. Plugin state/blob rows live in the shared global
141
- database; old plugin-state sidecar SQLite helpers are guarded against.
142
- - Memory: `sqlite-runtime` for built-in memory and session transcript indexing.
143
- Memory index tables live in the per-agent database, plugin memory state uses
144
- shared plugin-state rows, and legacy memory files are doctor migration inputs
145
- or user workspace content.
146
- - Backup: `sqlite-runtime`. Backup stages compact SQLite snapshots, omits live
147
- WAL/SHM sidecars, verifies SQLite integrity, and records backup runs in the
148
- global database.
149
- - Doctor migration: `migrating`, intentionally. Doctor imports legacy JSON,
150
- JSONL, and retired sidecar stores into SQLite, records migration runs/sources,
151
- and removes successful sources.
152
- - E2E scripts: `clean` for runtime coverage. Docker MCP seeding writes SQLite
153
- rows. The runtime-context Docker script creates legacy JSONL only inside the
154
- doctor migration seed and names the legacy session index path explicitly.
155
-
156
- ### Remaining work
157
-
158
- - [x] Rename cron runtime-test store variables away from `storePath` unless
159
- they are doctor legacy inputs.
160
- Files: `src/cron/service.test-harness.ts`,
161
- `src/cron/service.runs-one-shot-main-job-disables-it.test.ts`,
162
- `src/cron/service/timer.regression.test.ts`,
163
- `src/cron/service/ops.test.ts`, `src/cron/service/store.test.ts`,
164
- `src/cron/service.heartbeat-ok-summary-suppressed.test.ts`,
165
- `src/cron/service.main-job-passes-heartbeat-target-last.test.ts`,
166
- `src/cron/store.test.ts`.
167
- Proof: `pnpm check:database-first-legacy-stores`; `rg -n 'storePath' src/cron --glob '!**/commands/doctor/**'`.
168
- - [x] Remove or rename obsolete file-era export test mocks.
169
- File: `src/auto-reply/reply/commands-export-test-mocks.ts`.
170
- Proof: `rg -n 'resolveSessionFilePath|sessionFile|storePath|transcriptLocator' src/auto-reply/reply`.
171
- - [x] Make the Docker runtime-context legacy JSONL seed obviously doctor-only.
172
- File: `scripts/e2e/session-runtime-context-docker-client.ts`.
173
- Proof: `rg -n 'sessions\\.json|sessionFile|\\.jsonl' scripts/e2e/session-runtime-context-docker-client.ts` shows only
174
- `seedBrokenLegacySessionForDoctorMigration`.
175
- - [x] Keep Kysely generated types aligned after any schema change.
176
- Files: `src/state/fengming-state-schema.sql`,
177
- `src/state/fengming-agent-schema.sql`,
178
- `src/state/*generated*`.
179
- Proof: no schema change in this pass; `pnpm db:kysely:check`;
180
- `pnpm lint:kysely`.
181
- - [x] Re-run focused tests for touched stores, commands, and scripts.
182
- Proof: `pnpm test src/cron/service/store.test.ts src/cron/store.test.ts src/cron/service.heartbeat-ok-summary-suppressed.test.ts src/cron/service.main-job-passes-heartbeat-target-last.test.ts src/cron/service.every-jobs-fire.test.ts src/cron/service.persists-delivered-status.test.ts src/cron/service.runs-one-shot-main-job-disables-it.test.ts src/cron/service/ops.test.ts src/cron/service/timer.regression.test.ts src/auto-reply/reply/commands-export-trajectory.test.ts extensions/telegram/src/thread-bindings.test.ts extensions/slack/src/monitor/message-handler/prepare.test.ts src/acp/translator.session-lineage-meta.test.ts`; `git diff --check`.
183
- - [x] Before declaring `done`, run the changed gate or remote broad proof.
184
- Proof: `pnpm check:changed --timed -- <changed extension paths>` passed on
185
- Hetzner Crabbox run `run_3f1cabf6b25c` after temporary Node 24/pnpm setup and
186
- explicit path routing for the synced no-`.git` workspace.
187
-
188
- ### Do not regress
189
-
190
- - No transcript locators.
191
- - No active session files.
192
- - No fake JSONL test fixtures except doctor legacy migration tests.
193
- - No raw SQLite access where Kysely is expected.
194
- - No new legacy DB migrations. This layout has not shipped; keep schema version
195
- at `1` unless there is a strong reason.
196
-
197
- ## Code-Read Assumptions
198
-
199
- No follow-up product decisions are blocking this plan. The implementation should
200
- proceed with these assumptions:
201
-
202
- - Use `node:sqlite` directly and require the Node 22+ runtime for this storage
203
- path.
204
- - Keep exactly one normal configuration file. Do not move config, plugin
205
- manifests, or Git workspaces into SQLite in this refactor.
206
- - Runtime compatibility files are not required. Legacy JSON and JSONL files are
207
- migration inputs only. The branch-local SQLite sidecars never shipped and are
208
- deleted instead of imported.
209
- - `fengming doctor --fix` owns the legacy file-to-database migration step.
210
- Runtime startup and `fengming migrate` should not carry legacy FengMing
211
- database-upgrade paths.
212
- - Credential compatibility follows the same rule: runtime credentials live in
213
- SQLite. Old `auth-profiles.json`, per-agent `auth.json`, and shared
214
- `credentials/oauth.json` files are doctor migration inputs, then removed
215
- after import.
216
- - Generated model catalog state is database-backed. Runtime code must not write
217
- `agents/<agentId>/agent/models.json`; existing `models.json` files are legacy
218
- doctor inputs and are removed after import into `agent_model_catalogs`.
219
- - Runtime must not migrate, normalize, or bridge transcript locators. Active
220
- transcript identity is `{agentId, sessionId}` in SQLite. File paths are
221
- legacy doctor inputs only, and `sqlite-transcript://...` must disappear from
222
- runtime, protocol, hook, and plugin surfaces instead of being treated as a
223
- boundary handle.
224
- - Runtime SQLite transcript reads do not run old JSONL entry-shape migrations or
225
- rewrite whole transcripts for compatibility. Legacy entry normalization stays in
226
- explicit doctor/import utilities. Doctor normalizes legacy JSONL transcript
227
- files before inserting SQLite rows; current runtime rows are
228
- already written in the current transcript schema. Trajectory/session export
229
- reads those rows as-is and must not perform export-time legacy migrations.
230
- - Legacy transcript JSONL parse/migration helpers are doctor-only. Runtime
231
- transcript format code builds current SQLite transcript context only; doctor
232
- owns old JSONL entry upgrades before inserting rows.
233
- - The old runtime-owned JSONL transcript streaming helper was deleted. Doctor
234
- import code owns explicit legacy file reads; runtime session history reads
235
- SQLite rows.
236
- - Codex app-server bindings use the FengMing `sessionId` as the canonical
237
- key in the Codex plugin-state namespace. `sessionKey` is metadata for
238
- routing/display and must not replace the durable session id or resurrect
239
- transcript-file identity.
240
- - Context engines receive the current runtime contract directly. The registry
241
- must not wrap engines with retry shims that delete `sessionKey`,
242
- `transcriptScope`, or `prompt`; engines that cannot accept the current
243
- database-first params should fail loudly instead of being bridged.
244
- - Backup output should remain one archive file. Database contents should enter
245
- that archive as compact SQLite snapshots, not raw live WAL sidecars.
246
- - Transcript search is useful but not required for the first database-first
247
- cut. Design the schema so FTS can be added later.
248
- - Worker execution should stay experimental behind settings while the database
249
- boundary settles.
250
-
251
- ## Code-Read Findings
252
-
253
- The current branch is already past the proof-of-concept stage. The shared
254
- database exists, Node `node:sqlite` is wired through a small runtime helper, and
255
- former stores now write to `state/fengming.sqlite` or the owning
256
- `fengming-agent.sqlite` database.
257
-
258
- The remaining work is not choosing SQLite; it is keeping the new boundary clean
259
- and deleting any compatibility-shaped interfaces that still look like the old
260
- file world:
261
-
262
- - Session `storePath` is no longer a runtime identity, test fixture shape, or
263
- status payload field. Runtime and bridge tests no longer contain the
264
- `storePath` contract name; doctor/migration code owns that legacy vocabulary.
265
- - Session writes no longer pass through the old in-process `store-writer.ts`
266
- queue. SQLite patch writes use conflict detection and bounded retry instead.
267
- - Legacy path discovery still has valid migration uses, but runtime code should
268
- stop treating `sessions.json` and transcript JSONL files as possible write
269
- targets.
270
- - Agent-owned tables live in per-agent SQLite databases. The global DB keeps
271
- registry/control-plane rows; transcript identity is `{agentId, sessionId}` in
272
- the per-agent transcript rows. Runtime code must not persist transcript file
273
- paths or migrate transcript locators.
274
- - Doctor already imports several legacy files. The cleanup is to make that a
275
- single explicit migration implementation that doctor calls, with a durable
276
- migration report.
277
-
278
- No additional product questions are blocking implementation.
279
-
280
- ## Current Code Shape
281
-
282
- The branch already has a real shared SQLite base:
283
-
284
- - The runtime floor is now Node 22+: `package.json`, the CLI runtime guard,
285
- installer defaults, macOS runtime locator, CI, and public install docs all
286
- agree. The old Node 22 compatibility lane is removed.
287
- - `src/state/fengming-state-db.ts` opens `fengming.sqlite`, sets WAL,
288
- `synchronous=NORMAL`, `busy_timeout=30000`, `foreign_keys=ON`, and applies
289
- the generated schema module derived from
290
- `src/state/fengming-state-schema.sql`.
291
- - Kysely table types and runtime schema modules are generated from disposable
292
- SQLite databases created from the committed `.sql` files; runtime code no
293
- longer keeps copy-pasted schema strings for global, per-agent, or proxy
294
- capture databases.
295
- - Runtime stores derive selected and inserted row types from those generated
296
- Kysely `DB` interfaces instead of shadowing SQLite row shapes by hand. Raw SQL
297
- remains limited to schema application, pragmas, and migration-only DDL.
298
- - The SQLite schemas are collapsed to `user_version = 1` because this database
299
- layout has not shipped yet. Runtime openers create the current schema only;
300
- file-to-database import remains in doctor code, and branch-local
301
- database upgrade helpers have been deleted.
302
- - Relational ownership is enforced where the ownership boundary is canonical:
303
- source migration rows cascade from `migration_runs`, task delivery state
304
- cascades from `task_runs`, and transcript identity rows cascade from
305
- transcript events.
306
- - Current shared tables include `agent_databases`,
307
- `auth_profile_stores`, `auth_profile_state`,
308
- `plugin_state_entries`, `plugin_blob_entries`, `media_blobs`,
309
- `skill_uploads`, `capture_sessions`, `capture_events`, `capture_blobs`,
310
- `sandbox_registry_entries`, `cron_run_logs`, `cron_jobs`, `commitments`,
311
- `delivery_queue_entries`, `model_capability_cache`,
312
- `workspace_setup_state`, `native_hook_relay_bridges`,
313
- `current_conversation_bindings`, `plugin_binding_approvals`,
314
- `tui_last_sessions`, `task_runs`, `task_delivery_state`, `flow_runs`,
315
- `subagent_runs`, `migration_runs`, and `backup_runs`.
316
- - Arbitrary plugin-owned state does not get host-owned typed tables. Installed
317
- plugins use `plugin_state_entries` for versioned JSON payloads and
318
- `plugin_blob_entries` for bytes, with namespace/key ownership, TTL cleanup,
319
- backup, and plugin migration records. Host-owned plugin orchestration state can
320
- still have typed tables when the host owns the query contract, such as
321
- `plugin_binding_approvals`.
322
- - Plugin migrations are data migrations over plugin-owned namespaces, not host
323
- schema migrations. A plugin can migrate its own versioned state/blob entries
324
- through a migration provider, and the host records source/run status in the
325
- normal migration ledger. New plugin installs do not require changing
326
- `fengming-state-schema.sql` unless the host itself is taking ownership of a
327
- new cross-plugin contract.
328
- - `src/state/fengming-agent-db.ts` opens
329
- `agents/<agentId>/agent/fengming-agent.sqlite`, registers the database in the
330
- global DB, and owns agent-local session, transcript, VFS, artifact, cache,
331
- and memory-index tables. Shared runtime discovery now reads the generated-typed
332
- `agent_databases` registry instead of reimplementing that query at each call
333
- site.
334
- - Global and per-agent databases record a `schema_meta` row with database role,
335
- schema version, timestamps, and agent id for agent databases. The layout still
336
- stays at `user_version = 1` because this SQLite schema has not shipped yet.
337
- - Per-agent session identity now has a canonical `sessions` root table keyed by
338
- `session_id`, with `session_key`, `session_scope`, `account_id`,
339
- `primary_conversation_id`, timestamps, display fields, model metadata,
340
- harness id, and parent/spawn linkage as queryable columns. `session_routes`
341
- is the unique active route index from `session_key` to the current
342
- `session_id`, so a route key can move to a fresh durable session without
343
- making hot reads pick between duplicate `sessions.session_key` rows. The old
344
- `session_entries.entry_json` compatibility-shaped payload hangs off the
345
- durable `session_id` root by foreign key; it is no longer the only
346
- schema-level representation of a session.
347
- - Per-agent external conversation identity is relational too:
348
- `conversations` stores normalized provider/account/conversation identity, and
349
- `session_conversations` links one FengMing session to one or more external
350
- conversations. This covers shared-main DM sessions where multiple peers can
351
- intentionally map to one session without lying in `session_key`. SQLite also
352
- enforces uniqueness for the natural provider identity so the same
353
- channel/account/kind/peer/thread tuple cannot fork across conversation ids.
354
- Shared-main direct peers are linked with a `participant` role, so one
355
- FengMing session can represent multiple external DM peers without demoting
356
- older peers into vague related rows. `sessions.primary_conversation_id` still
357
- points at the current typed delivery target. Closed routing/status columns
358
- are enforced with SQLite `CHECK` constraints instead of relying only on
359
- TypeScript unions.
360
- Runtime session projection clears compatibility routing shadows from
361
- `session_entries.entry_json` before applying typed session/conversation
362
- columns, so stale JSON payloads cannot resurrect delivery targets.
363
- Subagent announce routing likewise requires the typed SQLite delivery context;
364
- it no longer falls back to compatibility `SessionEntry` route fields.
365
- Gateway `chat.send` explicit delivery inheritance reads the typed SQLite
366
- delivery context instead of `origin`/`last*` compatibility fields.
367
- `tools.effective` likewise derives provider/account/thread context from typed
368
- SQLite delivery/routing rows, not stale `last*` session-entry shadows.
369
- System-event prompt context rebuilds channel/to/account/thread fields from
370
- typed delivery fields instead of `origin` shadows.
371
- The shared `deliveryContextFromSession` helper and session-to-conversation
372
- mapper now ignore `SessionEntry.origin` entirely; only typed delivery fields
373
- and relational conversation rows can create hot route identity.
374
- Runtime session entry normalization strips `origin` before persisting or
375
- projecting `entry_json`, and inbound metadata writes typed channel/chat
376
- fields plus relational conversation rows instead of creating new origin
377
- shadows.
378
- - Transcript events, transcript snapshots, and trajectory runtime events now
379
- reference the canonical per-agent `sessions` root and cascade on session
380
- deletion. Transcript identity/idempotency rows continue to cascade from the
381
- exact transcript event row.
382
- - Memory-core indexes now use explicit agent-database tables
383
- `memory_index_meta`, `memory_index_sources`, `memory_index_chunks`, and
384
- `memory_embedding_cache`; optional FTS/vector side indexes use the same
385
- `memory_index_*` prefix instead of generic `meta`, `files`, `chunks`, or
386
- `chunks_vec` tables. `memory_index_sources` is keyed by
387
- `(source_kind, source_key)` and carries optional `session_id` ownership, so
388
- session-derived sources and chunks cascade when a session is deleted. Cached
389
- chunk embeddings are stored as Float32 SQLite BLOBs, not JSON text arrays.
390
- These tables are derived/search cache, not canonical transcript storage; they
391
- can be deleted and rebuilt from `sessions`, `transcript_events`, and memory
392
- workspace files.
393
- - Subagent run recovery state now lives in typed shared `subagent_runs` rows
394
- with indexed child, requester, and controller session keys. The old
395
- `subagents/runs.json` file is doctor migration input only.
396
- - Current conversation bindings now live in typed shared
397
- `current_conversation_bindings` rows keyed by normalized conversation id, with
398
- target agent/session columns, conversation kind, status, expiry, and metadata
399
- stored as relational columns instead of a duplicated opaque binding record.
400
- The durable binding key includes the normalized conversation kind so
401
- direct/group/channel refs cannot collide, and SQLite rejects invalid binding
402
- kind/status values. The old
403
- `bindings/current-conversations.json` file is doctor migration input only.
404
- - Delivery queue recovery now overlays typed queue columns for channel, target,
405
- account, session, retry, error, platform-send, and recovery state onto the
406
- replay JSON. `entry_json` keeps the replay payloads, hooks, and formatting
407
- payload, but typed columns are authoritative for hot queue routing/state.
408
- - TUI last-session restore pointers now live in typed shared
409
- `tui_last_sessions` rows keyed by the hashed TUI connection/session scope.
410
- The old TUI JSON file is doctor migration input only.
411
- - Default TTS prefs now live in shared plugin-state SQLite rows keyed under the
412
- `speech-core` plugin. The old `settings/tts.json` file is doctor migration
413
- input only; runtime no longer reads or writes TTS prefs JSON files, and the
414
- legacy path resolver lives in the doctor migration module.
415
- - Secret target metadata now talks about stores instead of pretending every
416
- credential target is a config file. `fengming.json` remains the config store;
417
- auth-profile targets use typed SQLite `auth_profile_stores` rows with
418
- provider-shaped credentials kept as JSON payloads.
419
- - Secret audit no longer scans retired per-agent `auth.json` files. Doctor owns
420
- warning about, importing, and removing that legacy file.
421
- - Legacy auth profile path helpers now live in doctor legacy code. Core auth
422
- profile path helpers expose SQLite auth-store identity and display locations,
423
- not `auth-profiles.json` or `auth-state.json` runtime paths.
424
- - Subagent run recovery and OpenRouter model capability cache runtime modules
425
- now keep SQLite snapshot readers/writers separate from doctor-only legacy JSON
426
- import helpers. OpenRouter capabilities use the typed generic
427
- `model_capability_cache` rows under `provider_id = "openrouter"` instead of
428
- one opaque cache blob or a provider-specific host table. Subagent run
429
- `taskName` is stored in the typed `subagent_runs.task_name` column; the
430
- `payload_json` copy is replay/debug data, not the source for hot display or
431
- lookup fields.
432
- - `src/agents/filesystem/virtual-agent-fs.sqlite.ts` implements a SQLite VFS
433
- over the agent database `vfs_entries` table. Directory reads, recursive
434
- exports, deletes, and renames use indexed `(namespace, path)` prefix ranges
435
- instead of scanning a whole namespace or relying on `LIKE` path matching.
436
- - `src/agents/runtime-worker.entry.ts` creates per-run SQLite VFS, tool artifact,
437
- run artifact, and scoped cache stores for workers.
438
- - Workspace bootstrap completion markers now live in typed shared
439
- `workspace_setup_state` rows keyed by resolved workspace path instead of
440
- `.fengming/workspace-state.json`; runtime no longer reads or rewrites the
441
- legacy workspace marker, and helper APIs no longer pass around a fake
442
- `.fengming/setup-state` path just to derive storage identity.
443
- - Exec approvals now live in the typed shared SQLite `exec_approvals_config`
444
- singleton row. Doctor imports legacy `~/.fengming/exec-approvals.json`;
445
- runtime writes no longer create, rewrite, or report that file as its active
446
- store location. The macOS companion reads and writes the same
447
- `state/fengming.sqlite` table row; it keeps only the Unix prompt socket on disk
448
- because that is IPC, not durable runtime state.
449
- - Device identity, device auth, and bootstrap runtime modules now keep their
450
- SQLite snapshot readers/writers separate from doctor-only legacy JSON import
451
- helpers. Device identity uses typed `device_identities` rows and device auth
452
- tokens use typed `device_auth_tokens` rows. Device auth writes reconcile rows
453
- by device/role instead of truncating the token table, and runtime no longer
454
- routes single-token updates through the old whole-store adapter. The legacy
455
- version-1 JSON payloads exist only as doctor import/export shapes.
456
- - GitHub Copilot token exchange cache uses the shared SQLite plugin-state table
457
- under `github-copilot/token-cache/default`. It is provider-owned cache state,
458
- so it intentionally does not add a host schema table.
459
- - The shared Swift runtime (`FengMingKit`) uses the same
460
- `state/fengming.sqlite` rows for device identity and device auth. macOS app
461
- helpers import the shared SQLite helpers instead of owning a second JSON or
462
- SQLite path. A leftover legacy `identity/device.json` blocks identity creation
463
- until doctor imports it into SQLite, matching the TypeScript and Android
464
- startup gate.
465
- - Android device identity uses the same TypeScript-compatible key material
466
- stored in typed `state/fengming.sqlite#table/device_identities` rows. It never
467
- reads or writes `fengming/identity/device.json`; a leftover legacy file blocks
468
- startup until doctor imports it into SQLite.
469
- - Android cached device auth tokens also use typed
470
- `state/fengming.sqlite#table/device_auth_tokens` rows and share the same
471
- version-1 token semantics as TypeScript and Swift. Runtime no longer reads `SecurePrefs`
472
- `gateway.deviceToken*` compatibility keys; those belong to migration/doctor
473
- logic only.
474
- - Android notification recent-package history uses typed
475
- `android_notification_recent_packages` rows. Runtime no longer migrates or
476
- reads the old SharedPreferences CSV keys.
477
- - Device identity creation fails closed when legacy `identity/device.json`
478
- exists, when the SQLite identity row is invalid, or when the SQLite identity
479
- store cannot be opened. Doctor imports and removes that file first, so runtime
480
- startup cannot silently rotate pairing identity before migration.
481
- - Device identity selection is a SQLite row key, not a JSON file locator. Tests
482
- and gateway helpers pass explicit identity keys; only doctor migration and the
483
- fail-closed startup gate know the retired `identity/device.json` filename.
484
- - Session reset compatibility now lives in doctor config migration:
485
- `session.idleMinutes` is moved into `session.reset.idleMinutes`,
486
- `session.resetByType.dm` is moved into `session.resetByType.direct`, and the
487
- runtime reset policy only reads canonical reset keys.
488
- - Legacy config compatibility now lives under `src/commands/doctor/`. Normal
489
- `readConfigFileSnapshot()` validation does not import doctor legacy detectors
490
- or annotate legacy issues; `runDoctorConfigPreflight()` adds those issues for
491
- doctor repair/reporting. The doctor config flow imports
492
- `src/commands/doctor/legacy-config.ts`, and old OAuth profile-id repair lives
493
- under
494
- `src/commands/doctor/legacy/oauth-profile-ids.ts`.
495
- - Non-doctor commands do not auto-run legacy config repair. For example,
496
- `fengming update --channel` now fails on invalid legacy config and asks the
497
- user to run doctor, rather than silently importing doctor migration code.
498
- - Web push, APNs, Voice Wake, update checks, and config health now use typed shared SQLite
499
- tables for subscriptions, VAPID keys, node registrations, trigger rows,
500
- routing rows, update-notification state, and config health entries instead of
501
- whole opaque JSON blobs. Web push and APNs snapshot writes now reconcile
502
- subscriptions/registrations by primary key instead of clearing their tables;
503
- config health does the same by config path.
504
- Their runtime modules keep SQLite snapshot readers/writers separate from
505
- doctor-only legacy JSON import helpers.
506
- - Node-host config now uses a typed singleton row in the shared SQLite database;
507
- doctor imports the old `node.json` file before normal runtime use.
508
- - Device/node pairing, channel pairing, channel allowlists, and bootstrap state
509
- now use typed SQLite rows instead of whole opaque JSON blobs. Plugin binding
510
- approvals and cron job state follow the same split: runtime modules expose
511
- SQLite-backed operations and neutral snapshot helpers, and pairing/bootstrap
512
- plus plugin binding approval snapshot writes reconcile rows by primary key
513
- instead of truncating tables, while doctor imports/removes the old JSON files through
514
- `src/commands/doctor/legacy/*` modules.
515
- - Installed plugin records now live in the SQLite installed-plugin index.
516
- Runtime config read/write no longer migrates or preserves old
517
- `plugins.installs` authored-config data; doctor imports that legacy config
518
- shape into SQLite before normal runtime use.
519
- - QQBot credential recovery snapshots now live in SQLite plugin state under
520
- `qqbot/credential-backups`. Runtime no longer writes
521
- `qqbot/data/credential-backup*.json`; doctor imports and removes those
522
- legacy backup files with the other QQBot state inputs.
523
- - Gateway reload planning compares SQLite installed-plugin index snapshots under
524
- an internal `installedPluginIndex.installRecords.*` diff namespace. Runtime
525
- reload decisions no longer wrap those rows in fake `plugins.installs` config
526
- objects.
527
- - Matrix named-account credential upgrade no longer happens during runtime
528
- reads. Doctor owns the old top-level `credentials/matrix/credentials.json`
529
- rename when a single/default Matrix account can be resolved.
530
- - Core pairing and cron runtime modules no longer export legacy JSON path
531
- builders. Doctor-owned legacy modules construct `pending.json`, `paired.json`,
532
- `bootstrap.json`, and `cron/jobs.json` source paths for import tests and
533
- migration only. Legacy cron job-shape normalization and cron run-log import
534
- live under `src/commands/doctor/legacy/cron*.ts`.
535
- - `src/commands/doctor/legacy/runtime-state.ts` imports legacy JSON state
536
- files, including node host config, into SQLite from doctor. New legacy file
537
- importers stay under `src/commands/doctor/legacy/`.
538
- - `src/commands/doctor/state-migrations.ts` imports legacy `sessions.json` and
539
- `*.jsonl` transcripts directly into SQLite and removes successful sources. It
540
- no longer stages root legacy transcripts through
541
- `agents/<agentId>/sessions/*.jsonl` or creates a canonical JSONL target before
542
- import.
543
- - State integrity doctor checks no longer scan legacy session directories or
544
- offer orphan JSONL deletion. Legacy transcript files are migration inputs
545
- only, and the migration step owns import plus source removal.
546
- - Legacy sandbox registry import lives under
547
- `src/commands/doctor/legacy/sandbox-registry.ts`; active sandbox registry
548
- reads and writes remain SQLite-only.
549
- - The legacy session transcript health/import repair lives under
550
- `src/commands/doctor/legacy/session-transcript-health.ts`; runtime command
551
- modules no longer carry JSONL transcript parsing or active-branch repair code.
552
-
553
- Completed consolidation/deletion highlights:
554
-
555
- - Plugin state now uses the shared `state/fengming.sqlite` database. The old
556
- branch-local `plugin-state/state.sqlite` sidecar importer is removed because
557
- that SQLite layout never shipped. Probe/test helpers report the shared
558
- `databasePath` instead of exposing a plugin-state-specific SQLite path.
559
- - Task and Task Flow runtime tables now live in the shared
560
- `state/fengming.sqlite` database instead of `tasks/runs.sqlite` and
561
- `tasks/flows/registry.sqlite`; the old sidecar importers are removed for the
562
- same unshipped-layout reason.
563
- - `src/config/sessions/store.ts` no longer needs `storePath` for inbound
564
- metadata, route updates, or updated-at reads. Command persistence, CLI
565
- session cleanup, subagent depth, auth overrides, and transcript session
566
- identity use agent/session row APIs. Writes are applied as SQLite row patches
567
- with optimistic conflict retry.
568
- - Session target resolution now exposes per-agent database targets, not legacy
569
- `sessions.json` paths. Shared gateway, ACP metadata, doctor route repair, and
570
- `fengming sessions` enumerate `agent_databases` plus configured agents.
571
- - Gateway session routing now uses `resolveGatewaySessionDatabaseTarget`; the
572
- returned target carries `databasePath` and candidate SQLite row keys instead
573
- of a legacy session-store file path.
574
- - Channel session runtime types now expose `{agentId, sessionKey}` for
575
- updated-at reads, inbound metadata, and last-route updates. The old
576
- `saveSessionStore(storePath, store)` compatibility type is gone.
577
- - Plugin runtime, extension API, and `config/sessions` barrel surfaces now steer
578
- plugin code to SQLite-backed session row helpers. Root library compatibility
579
- exports (`loadSessionStore`, `saveSessionStore`, `resolveStorePath`) remain as
580
- deprecated shims for existing consumers. The old
581
- `resolveLegacySessionStorePath` helper is gone; legacy `sessions.json` path
582
- construction is now local to migration and test fixtures.
583
- - `src/config/sessions/session-entries.sqlite.ts` now stores canonical session
584
- entries in the per-agent database and has row-level read/upsert/delete patch
585
- support. Runtime upsert/patch/delete no longer scans for case variants or
586
- prunes legacy alias keys; doctor owns canonicalization. The
587
- standalone JSON import helper is gone, and migration merges upsert newer rows
588
- instead of replacing the whole session table. Public read/list/load helpers
589
- project hot session metadata from typed `sessions` and `conversations` rows;
590
- `entry_json` is a compatibility/debug shadow and can be stale or invalid
591
- without losing typed session identity or delivery context.
592
- - `src/config/sessions/delivery-info.ts` now resolves delivery context from the
593
- typed per-agent `sessions` + `conversations` + `session_conversations` rows.
594
- It no longer reconstructs runtime delivery identity from
595
- `session_entries.entry_json`; a missing typed conversation row is a doctor
596
- migration/repair problem, not a runtime fallback.
597
- - Stored-session reset decisions now prefer typed `sessions.session_scope`,
598
- `sessions.chat_type`, and `sessions.channel` metadata. `sessionKey` parsing
599
- remains only for explicit thread/topic suffixes on command targets; group vs
600
- direct reset classification no longer comes from key shape.
601
- - Session list/status display classification now uses typed chat metadata and
602
- gateway session kind. It no longer treats `:group:` or `:channel:` substrings
603
- inside `session_key` as durable group/direct truth.
604
- - Silent-reply policy selection now uses explicit conversation type or surface
605
- metadata only. It no longer guesses direct/group policy from
606
- `session_key` substrings.
607
- - Session display model resolution now receives the agent id from the SQLite
608
- session database target instead of splitting it out of `session_key`.
609
- - Agent-to-agent announce target hydration now uses typed `sessions.list`
610
- `deliveryContext` only. It no longer recovers channel/account/thread routing
611
- from legacy `origin`, mirrored `last*` fields, or `session_key` shape.
612
- - `sessions_send` thread-target rejection now reads typed SQLite routing
613
- metadata. It no longer rejects or accepts targets by parsing thread suffixes
614
- out of the target key.
615
- - Group-scoped tool policy validation now reads typed SQLite conversation
616
- routing for the current or spawned session. It no longer trusts group/channel
617
- identity by decoding `sessionKey`; caller-provided group ids are dropped when
618
- no typed session row vouches for them.
619
- - Channel model override matching now uses explicit group and parent
620
- conversation metadata. It no longer decodes parent conversation ids from
621
- `parentSessionKey`.
622
- - Stored model override inheritance now requires an explicit parent session key
623
- from typed session context. It no longer derives parent overrides from
624
- `:thread:` or `:topic:` suffixes in `sessionKey`.
625
- - The old session thread-info wrapper and loaded-plugin thread parser are gone;
626
- no runtime code imports `config/sessions/thread-info`.
627
- - The channel conversation helper no longer exposes full-session-key parsing
628
- bridges. Core still normalizes provider-owned raw conversation ids through
629
- `resolveSessionConversation(...)`, but it does not reconstruct route facts
630
- from `sessionKey`.
631
- - Completion delivery, send policy, and task maintenance no longer derive chat
632
- type from `session_key` shape. The old chat-type key parser has been deleted;
633
- these paths require typed session metadata, typed delivery context, or
634
- explicit delivery target vocabulary.
635
- - Session list/status, diagnostics, approval account binding, TUI heartbeat
636
- filtering, and usage summaries no longer mine `SessionEntry.origin` for
637
- provider/account/thread/display routing. The only remaining runtime
638
- `origin` reads are non-session concepts or current-turn delivery objects.
639
- - Approval-request native conversation lookup now reads typed per-agent session
640
- routing rows. It no longer parses channel/group/thread conversation identity
641
- from `sessionKey`; missing typed metadata is a migration/repair issue.
642
- - Gateway session changed/chat/session event payloads no longer echo
643
- `SessionEntry.origin` or `last*` route shadows; clients receive typed
644
- `channel`, `chatType`, and `deliveryContext`.
645
- - Heartbeat delivery resolution can now receive the typed SQLite
646
- `deliveryContext` directly, and heartbeat runtime passes the per-agent
647
- session delivery row instead of relying on compatibility `session_entries`
648
- shadows for current routing.
649
- - Cron isolated-agent delivery target resolution also hydrates its current
650
- route from the typed per-agent session delivery row before falling back to the
651
- compatibility entry payload.
652
- - Subagent announce origin resolution now threads the typed requester-session
653
- delivery context through `loadRequesterSessionEntry` and prefers that row over
654
- compatibility `last*`/`deliveryContext` shadows.
655
- - Inbound session metadata updates now merge against the typed per-agent
656
- delivery row first; old `SessionEntry` delivery fields are only the fallback
657
- when no typed conversation row exists.
658
- - Restart/update delivery extraction now lets the typed SQLite delivery
659
- `threadId` win over topic/thread fragments parsed from `sessionKey`; parsing
660
- is only a fallback for legacy thread-shaped keys.
661
- - Hook agent context channel ids now prefer typed SQLite conversation identity,
662
- then explicit message metadata. They no longer parse provider/group/channel
663
- fragments from `sessionKey`.
664
- - Gateway `chat.send` external-route inheritance now reads typed SQLite session
665
- routing metadata instead of inferring channel/direct/group scope from
666
- `sessionKey` pieces. Channel-scoped sessions inherit only when the typed
667
- session channel and chat type match the stored delivery context; shared-main
668
- sessions keep their stricter CLI/no-client-metadata rule.
669
- - Restart-sentinel wake and continuation routing now reads typed SQLite
670
- delivery/routing rows before queueing heartbeat wakes or routed agent-turn
671
- continuations. It no longer reconstructs delivery context from the
672
- session-entry JSON shadow.
673
- - Gateway `tools.effective` context resolution now reads typed SQLite
674
- delivery/routing rows for provider, account, target, thread, and reply-mode
675
- inputs. It no longer recovers those hot routing fields from stale
676
- `session_entries.entry_json` origin shadows.
677
- - Realtime voice consult routing now resolves parent/call delivery from typed
678
- per-agent SQLite session rows. It no longer falls back to compatibility
679
- `SessionEntry.deliveryContext` shadows when choosing the embedded agent
680
- message route.
681
- - ACP spawn heartbeat relay and parent-stream routing now read parent delivery
682
- from typed SQLite session rows. They no longer reconstruct parent delivery
683
- context from compatibility session-entry shadows.
684
- - Session delivery route preservation now follows typed chat metadata and
685
- persisted delivery columns. It no longer extracts channel hints, direct/main
686
- markers, or thread shape from `sessionKey`; internal webchat routes only
687
- inherit an external target when SQLite already has typed/persisted delivery
688
- identity for the session.
689
- - Generic session delivery extraction now reads only the exact typed SQLite
690
- session delivery row. It no longer parses thread/topic suffixes or falls back
691
- from a thread-shaped key to a base session key.
692
- - Reply dispatch, restart sentinel recovery, and realtime voice consult routing
693
- now use exact typed SQLite session/conversation rows for thread routing. They
694
- no longer recover thread ids or base-session delivery context by parsing
695
- thread-shaped session keys.
696
- - Embedded PI history limiting now uses the typed SQLite session routing
697
- projection (`sessions` + primary `conversations`) for provider, chat type,
698
- and peer identity. It no longer parses provider, DM, group, or thread shape
699
- out of `sessionKey`.
700
- - Cron tool delivery inference now uses explicit delivery or the current typed
701
- delivery context only. It no longer decodes channel, peer, account, or thread
702
- targets from `agentSessionKey`.
703
- - Runtime session rows no longer carry the old `lastProvider` route alias.
704
- Helpers and tests use typed `lastChannel` and `deliveryContext` fields;
705
- doctor migration is the only place that should translate older route aliases
706
- or persisted `origin` shadows.
707
- - Transcript events, VFS rows, and tool artifact rows now write to the per-agent
708
- database. The unshipped global transcript-file mapping table is gone; doctor
709
- records legacy source paths in durable migration rows instead.
710
- - Runtime transcript lookup no longer scans JSONL byte offsets or probes legacy
711
- transcript files. Gateway chat/media/history paths read transcript rows from
712
- SQLite; session JSONL is now only a legacy doctor input, not a runtime state
713
- or export format.
714
- - Transcript parent and branch relationships use structured
715
- `parentTranscriptScope: {agentId, sessionId}` metadata in SQLite transcript
716
- headers, not path-like `agent-db:...transcript_events...` locator strings.
717
- - The transcript manager contract no longer exposes implicit persisted
718
- `create(cwd)` or `continueRecent(cwd)` constructors. Persisted transcript
719
- managers are opened with an explicit `{agentId, sessionId}` scope; only
720
- in-memory managers remain scope-free for tests and pure transcript transforms.
721
- - Runtime transcript store APIs resolve SQLite scope, not filesystem paths. The
722
- old `resolve...ForPath` helper and unused `transcriptPath` write options are
723
- gone from runtime callers.
724
- - Runtime session resolution now uses `{agentId, sessionId}` and must not derive
725
- `sqlite-transcript://<agent>/<session>` strings for external boundaries.
726
- Legacy absolute JSONL paths are doctor migration inputs only.
727
- - Native hook relay direct-bridge records now live in typed shared
728
- `native_hook_relay_bridges` rows keyed by relay id. Runtime no longer writes a
729
- `/tmp` JSON registry or opaque generic records for those short-lived bridge
730
- records.
731
- - `runEmbeddedPiAgent(...)` no longer has a transcript-locator parameter.
732
- Prepared worker descriptors also omit transcript locators. Runtime session
733
- state and queued follow-up runs carry `{agentId, sessionId}` instead of
734
- derived transcript handles.
735
- - Embedded compaction now takes SQLite scope from `agentId` and `sessionId`.
736
- Compaction hooks, context-engine calls, CLI delegation, and protocol replies
737
- must not receive derived `sqlite-transcript://...` handles. Export/debug code
738
- can materialize explicit user artifacts from rows, but it does not provide a
739
- generic session JSONL export path or feed file names back into runtime
740
- identity.
741
- - `/export-session` reads transcript rows from SQLite and writes the requested
742
- standalone HTML view only. The embedded viewer no longer reconstructs or
743
- downloads session JSONL from those rows.
744
- - Context-engine delegation no longer parses a transcript locator to recover
745
- agent identity. The prepared runtime context carries the resolved `agentId`
746
- into the built-in compaction adapter.
747
- - Transcript rewrite and live tool-result truncation now read and persist
748
- transcript state by `{agentId, sessionId}` and do not derive temporary
749
- locators for transcript-update event payloads.
750
- - The transcript-state helper surface no longer has locator-based
751
- `readTranscriptState`, `replaceTranscriptStateEvents`, or
752
- `persistTranscriptStateMutation` variants. Runtime callers must use the
753
- `{agentId, sessionId}` APIs. Doctor import reads legacy files by explicit file
754
- path and writes SQLite rows; it does not migrate locator strings.
755
- - The runtime session-manager contract no longer exposes `open(locator)`,
756
- `forkFrom(locator)`, or `setTranscriptLocator(...)`. Persisted session
757
- managers open by `{agentId, sessionId}` only; list/fork helpers live on
758
- row-oriented session and checkpoint APIs instead of the transcript manager
759
- facade.
760
- - Gateway transcript reader APIs are scope-first. They take
761
- `{agentId, sessionId}` and do not accept a positional transcript locator that
762
- could accidentally become runtime identity. Active transcript locator parsing
763
- is gone; legacy source paths are read only by doctor import code.
764
- - Transcript update events are also scope-first. `emitSessionTranscriptUpdate`
765
- no longer accepts a bare locator string, and listeners route by
766
- `{agentId, sessionId}` without parsing a handle.
767
- - Gateway session-message broadcast resolves session keys from agent/session
768
- scope, not from a transcript locator. The old transcript-locator-to-session
769
- key resolver/cache is gone.
770
- - Gateway session-history SSE filters live updates by agent/session scope. It no
771
- longer canonicalizes transcript locator candidates, realpaths, or file-shaped
772
- transcript identities to decide whether a stream should receive an update.
773
- - Session lifecycle hooks no longer derive or expose transcript locators on
774
- `session_end`. Hook consumers get `sessionId`, `sessionKey`, next-session
775
- ids, and agent context; transcript files are not part of the lifecycle
776
- contract.
777
- - Reset hooks no longer derive or expose transcript locators either. The
778
- `before_reset` payload carries recovered SQLite messages plus the reset
779
- reason, while session identity stays in hook context.
780
- - Agent harness reset no longer accepts a transcript locator. Reset dispatch is
781
- scoped by `sessionId`/`sessionKey` plus reason.
782
- - Agent extension session types no longer expose `transcriptLocator`; extensions
783
- should use session context and runtime APIs rather than reaching for a
784
- file-shaped transcript identity.
785
- - Plugin compaction hooks no longer expose transcript locators. Hook context
786
- already carries session identity, and transcript reads must go through SQLite
787
- scope-aware APIs instead of file-shaped handles.
788
- - `before_agent_finalize` hooks no longer expose `transcriptPath`, including
789
- native hook relay payloads. Finalization hooks use session context only.
790
- - Gateway reset responses no longer synthesize a transcript locator on the
791
- returned entry. The reset creates SQLite transcript rows, returns the clean
792
- session entry, and leaves transcript access to scope-aware readers.
793
- - Embedded run and compaction results no longer surface transcript locators for
794
- session accounting. Automatic compaction updates only the active `sessionId`,
795
- compaction counters, and token metadata.
796
- - Embedded attempt results no longer return `transcriptLocatorUsed`, and
797
- context-engine `compact()` results no longer return transcript locators.
798
- Runtime retry loops only accept a successor `sessionId`.
799
- - Delivery-mirror transcript append results no longer return transcript
800
- locators. Callers get the appended `messageId`; transcript update signals use
801
- SQLite scope.
802
- - Parent-session fork helpers return only the forked `sessionId`. Subagent
803
- preparation passes the child agent/session scope to engines.
804
- - CLI runner params and history reseeding no longer accept transcript locators.
805
- CLI history reads resolve the SQLite transcript scope from `{agentId,
806
- sessionId}` and session key context.
807
- - CLI and embedded-runner test fixtures now seed and read SQLite transcript rows
808
- by session id instead of pretending active sessions are `*.jsonl` files or
809
- passing a `sqlite-transcript://...` string through runtime params.
810
- - Session tool-result guard events emit from known session scope even when an
811
- in-memory manager has no derived locator. Its tests no longer fake active
812
- `/tmp/*.jsonl` transcript files.
813
- - BTW and compaction-checkpoint helpers now read and fork transcript rows by
814
- SQLite scope. Checkpoint metadata now stores session ids and leaf/entry ids
815
- only; derived locators are no longer written into checkpoint payloads.
816
- - Gateway transcript-key lookup uses SQLite transcript scope at protocol
817
- boundaries and no longer realpaths or stats transcript filenames.
818
- - Automatic compaction transcript rotation writes successor transcript rows
819
- directly through the SQLite transcript store. Session rows keep only the
820
- successor session identity, not a durable JSONL path or persisted locator.
821
- - Embedded context-engine compaction uses SQLite-named transcript rotation
822
- helpers. The rotation tests no longer construct JSONL successor paths or
823
- model active sessions as files.
824
- - Managed outgoing image retention keys its transcript-message cache from
825
- SQLite transcript stats instead of filesystem stat calls.
826
- - Runtime session locks and the standalone legacy `.jsonl.lock` doctor
827
- lane have been removed.
828
- - The Microsoft Teams runtime barrel and public plugin SDK no longer re-export
829
- the old file-lock helper; durable plugin state paths are SQLite-backed.
830
- - Session age/count pruning and explicit session cleanup have been removed.
831
- Doctor owns legacy import; stale sessions are reset or deleted explicitly.
832
- - Doctor integrity checks no longer count a legacy JSONL file as a valid active
833
- transcript for a SQLite session row. Active transcript health is SQLite-only;
834
- legacy JSONL files are reported as migration/orphan-cleanup inputs.
835
- - Doctor no longer treats `agents/<agent>/sessions/` as required runtime
836
- state. It only scans that directory when it already exists, as legacy import
837
- or orphan-cleanup input.
838
- - Gateway `sessions.resolve`, session patch/reset/compact paths, subagent
839
- spawning, fast abort, ACP metadata, heartbeat-isolated sessions, and TUI
840
- patching no longer migrate or prune legacy session keys as a side effect of
841
- normal runtime work.
842
- - CLI command session resolution now returns the owning `agentId` instead of a
843
- `storePath`, and it no longer copies legacy main-session rows during normal
844
- `--to` or `--session-id` resolution. Legacy main-row canonicalization belongs
845
- to doctor only.
846
- - Runtime subagent depth resolution no longer reads `sessions.json` or JSON5
847
- session stores. It reads SQLite `session_entries` by agent id, and legacy
848
- depth/session metadata can only enter through the doctor import path.
849
- - Auth profile session overrides persist through direct `{agentId, sessionKey}`
850
- row upserts instead of lazy-loading a file-shaped session-store runtime.
851
- - Auto-reply verbose gating and session update helpers now read/upsert SQLite
852
- session rows by session identity and no longer require a legacy store path
853
- before touching persisted row state.
854
- - Command-run session metadata helpers now use entry-oriented names and module
855
- paths; the old `session-store` command helper surface has been removed.
856
- - Bootstrap header seeding and manual compaction boundary hardening now mutate
857
- SQLite transcript rows directly. Runtime callers pass session identity, not
858
- writable `.jsonl` paths.
859
- - Silent session-rotation replay copies recent user/assistant turns by
860
- `{agentId, sessionId}` from SQLite transcript rows. It no longer accepts
861
- source or target transcript locators.
862
- - Fresh runtime session rows no longer store transcript locators. Callers use
863
- `{agentId, sessionId}` directly; export/debug commands can choose output file
864
- names when they materialize rows.
865
- - Starting a new persisted transcript session now always opens SQLite rows by
866
- scope. The session manager no longer reuses a previous file-era transcript
867
- path or locator as the identity for the new session.
868
- - Persisted transcript sessions use the explicit
869
- `openTranscriptSessionManagerForSession({agentId, sessionId})` API. The old
870
- static `SessionManager.create/openForSession/list/forkFromSession` facades are
871
- gone so tests and runtime code cannot accidentally recreate file-era session
872
- discovery.
873
- - Plugin runtime no longer exposes `api.runtime.agent.session.resolveTranscriptLocatorPath`;
874
- plugin code uses SQLite row helpers and scope values.
875
- - The public `session-store-runtime` SDK surface now only exports session row
876
- and transcript row helpers. Raw SQLite database open/path and close/reset
877
- helpers live in the focused `sqlite-runtime` SDK surface, so plugin tests no
878
- longer pull the deprecated broad testing barrel for database cleanup.
879
- - Legacy `.jsonl` trajectory/checkpoint filename classifiers now live in the
880
- doctor legacy session-file module. Core session validation no longer imports
881
- file-artifact helpers to decide normal SQLite session ids.
882
- - Active-memory blocking subagent runs use SQLite transcript rows instead of
883
- creating temporary or persisted `session.jsonl` files under plugin state. The
884
- old `transcriptDir` option is removed.
885
- - One-off slug generation and Crestodian planner runs use SQLite transcript rows
886
- instead of creating temporary `session.jsonl` files.
887
- - `llm-task` helper runs and hidden commitment extraction also use SQLite
888
- transcript rows, so these model-only helper sessions no longer create
889
- temporary JSON/JSONL transcript files.
890
- - `TranscriptSessionManager` is only an opened SQLite transcript scope now.
891
- Runtime code opens it with `openTranscriptSessionManagerForSession({agentId,
892
- sessionId})`; create, branch, continue, list, and fork flows live in their
893
- owning SQLite row helpers rather than static manager facades.
894
- Doctor/import/debug code handles explicit legacy source files outside the
895
- runtime session manager.
896
- - The stale `SessionManager.newSession()` and
897
- `SessionManager.createBranchedSession()` facade methods were removed. New
898
- sessions and transcript descendants are created by their owning SQLite
899
- workflow instead of mutating an already-open manager into a different
900
- persisted session.
901
- - Parent transcript fork decisions and fork creation no longer accept
902
- `storePath` or `sessionsDir`; they use `{agentId, sessionId}` SQLite
903
- transcript scope instead of retained filesystem path metadata.
904
- - Memory-host no longer exports no-op session-directory transcript
905
- classification helpers; transcript filtering now derives from SQLite row
906
- metadata during entry construction.
907
- - Memory-host and QMD session-export tests use SQLite transcript scopes. Old
908
- `agents/<agentId>/sessions/*.jsonl` paths stay covered only where a test is
909
- intentionally proving doctor/import/export compatibility.
910
- - QA-lab raw session inspection now uses `sessions.list` through the gateway
911
- instead of reading `agents/qa/sessions/sessions.json`; MSteams feedback
912
- appends directly to SQLite transcripts without fabricating a JSONL path.
913
- - Shared inbound channel turns now carry `{agentId, sessionKey}` rather than a
914
- legacy `storePath`. LINE, WhatsApp, Slack, Discord, Telegram, Matrix, Signal,
915
- iMessage, BlueBubbles, Feishu, Google Chat, IRC, Nextcloud Talk, Zalo,
916
- Zalo Personal, QA Channel, Microsoft Teams, Mattermost, Synology Chat, Tlon,
917
- Twitch, and QQBot recording paths now read updated-at metadata and record
918
- inbound session rows through SQLite identity.
919
- - Transcript locator persistence is removed from active session rows.
920
- `resolveSessionTranscriptTarget` returns `agentId`, `sessionId`, and optional
921
- topic metadata; doctor is the only code that imports legacy transcript file
922
- names.
923
- - Runtime transcript headers start at SQLite version `1`. Old JSONL V1/V2/V3
924
- shape upgrades live only in doctor import and normalize imported headers to
925
- the current SQLite transcript version before rows are stored.
926
- - The database-first guard now bans `SessionManager.listAll` and
927
- `SessionManager.forkFromSession`; session listing and fork/restore workflows
928
- must stay on row/scoped SQLite APIs.
929
- - The guard also bans legacy transcript JSONL parse/active-branch repair helper
930
- names outside doctor/import code, so runtime cannot grow a second legacy
931
- transcript migration path.
932
- - Embedded PI runs reject incoming transcript handles. They use the SQLite
933
- `{agentId, sessionId}` identity before worker launch and again before the
934
- attempt touches transcript state. A stale `/tmp/*.jsonl` input cannot select a
935
- runtime write target.
936
- - Cache trace, Anthropic payload, raw stream, and diagnostics timeline records
937
- now write to typed SQLite `diagnostic_events` rows. Gateway stability bundles
938
- now write to typed SQLite `diagnostic_stability_bundles` rows. The old
939
- `diagnostics.cacheTrace.filePath`, `FENGMING_CACHE_TRACE_FILE`,
940
- `FENGMING_ANTHROPIC_PAYLOAD_LOG_FILE`, and
941
- `FENGMING_DIAGNOSTICS_TIMELINE_PATH` JSONL override paths are removed, and
942
- normal stability capture no longer writes `logs/stability/*.json` files.
943
- - Cron persistence now reconciles SQLite `cron_jobs` rows instead of
944
- deleting/reinserting the whole job table on each save. Plugin target
945
- writebacks update matching cron rows directly and keep runtime cron state in
946
- the same state-database transaction.
947
- - Cron runtime callers now use a stable SQLite cron store key. Legacy
948
- `cron.store` paths are doctor import inputs only; production gateway, task
949
- maintenance, status, run-log, and Telegram target writeback paths use
950
- `resolveCronStoreKey` and no longer path-normalize the key. Cron status now
951
- reports `storeKey` rather than the old file-shaped `storePath` field.
952
- - Cron runtime load and scheduling no longer normalize legacy persisted job
953
- shapes such as `jobId`, `schedule.cron`, numeric `atMs`, string booleans, or
954
- missing `sessionTarget`. Doctor legacy import owns those repairs before rows
955
- are inserted into SQLite.
956
- - ACP spawn no longer resolves or persists transcript JSONL file paths. Spawn
957
- and thread-bind setup persist the SQLite session row directly and keep the
958
- session id as the retained transcript identity.
959
- - ACP session metadata APIs now read/list/upsert SQLite rows by `agentId` and
960
- no longer expose `storePath` as part of the ACP session entry contract.
961
- - Session usage accounting and gateway usage aggregation now resolve transcripts
962
- by `{agentId, sessionId}` only. The cost/usage cache and discovered-session
963
- summaries no longer synthesize or return transcript locator strings.
964
- - Gateway chat append, abort-partial persistence, `/sessions.send`, and
965
- webchat media transcript writes append directly through SQLite transcript
966
- scope. The gateway transcript-injection helper no longer accepts a
967
- `transcriptLocator` parameter.
968
- - SQLite transcript discovery now lists transcript scopes and stats only:
969
- `{agentId, sessionId, updatedAt, eventCount}`. The dead
970
- `listSqliteSessionTranscriptLocators` compatibility helper and per-row
971
- `locator` field are gone.
972
- - Transcript repair runtime now exposes only
973
- `repairTranscriptSessionStateIfNeeded({agentId, sessionId})`. The old
974
- locator-based repair helper is deleted; doctor/debug code reads explicit
975
- source file paths and never migrates locator strings.
976
- - ACP replay ledger runtime now stores per-session replay rows in the shared
977
- SQLite state database instead of `acp/event-ledger.json`; doctor imports and
978
- removes the legacy file.
979
- - Gateway transcript reader helpers now live in
980
- `src/gateway/session-transcript-readers.ts` instead of the old
981
- `session-utils.fs` module name. The fallback retry history check is named for
982
- SQLite transcript content instead of the old file-helper surface.
983
- - Gateway injected-chat and compaction helpers now pass SQLite transcript scope
984
- through internal helper APIs instead of naming values transcript paths or
985
- source files.
986
- - Bootstrap continuation detection now checks SQLite transcript rows through
987
- `hasCompletedBootstrapTranscriptTurn`; it no longer exposes a file-shaped
988
- helper name.
989
- - Embedded-runner tests now use SQLite transcript identity, and opening a new
990
- transcript manager always requires an explicit `sessionId`.
991
- - Memory indexing helpers now use SQLite transcript terminology end to end:
992
- host exports `listSessionTranscriptScopesForAgent` and
993
- `sessionTranscriptKeyForScope`, targeted sync queues `sessionTranscripts`,
994
- public session-search hits expose opaque `transcript:<agent>:<session>` paths,
995
- and the internal DB source key is `session:<session>` under
996
- `source_kind='sessions'` instead of a fake file path.
997
- - The generic plugin SDK persistent-dedupe helper no longer exposes file-shaped
998
- options. Callers provide SQLite scope keys and durable dedupe rows live in
999
- shared plugin state.
1000
- - Microsoft Teams SSO and delegated OAuth tokens moved from locked JSON files
1001
- to SQLite plugin state. Doctor imports `msteams-sso-tokens.json` and
1002
- `msteams-delegated.json`, rebuilds canonical SSO token keys from payloads,
1003
- and removes the source files.
1004
- - Matrix sync cache state moved from `bot-storage.json` to SQLite plugin
1005
- state. Doctor imports legacy raw or wrapped sync payloads and removes the
1006
- source file. Active Matrix and QA Matrix clients pass a SQLite sync-store root
1007
- directory, not a fake `sync-store.json` or `bot-storage.json` path.
1008
- - Matrix legacy crypto migration status moved from
1009
- `legacy-crypto-migration.json` to SQLite plugin state. Doctor imports the
1010
- old status file; Matrix SDK IndexedDB snapshots moved from
1011
- `crypto-idb-snapshot.json` to SQLite plugin blobs. Matrix recovery keys and
1012
- credentials are SQLite plugin-state rows; their old JSON files are doctor
1013
- migration inputs only.
1014
- - Memory Wiki activity logs now use SQLite plugin state instead of
1015
- `.fengming-wiki/log.jsonl`. The Memory Wiki migration provider imports old
1016
- JSONL logs; wiki markdown and user vault content stay file-backed as
1017
- workspace content.
1018
- - Memory Wiki no longer creates `.fengming-wiki/state.json` or the unused
1019
- `.fengming-wiki/locks` directory. The migration provider removes those retired
1020
- plugin metadata files if an older vault still has them.
1021
- - Crestodian audit entries now use core SQLite plugin state instead of
1022
- `audit/crestodian.jsonl`. Doctor imports the legacy JSONL audit log and
1023
- removes it after successful import.
1024
- - Config write/observe audit entries now use core SQLite plugin state instead
1025
- of `logs/config-audit.jsonl`. Doctor imports the legacy JSONL audit log and
1026
- removes it after successful import.
1027
- - The macOS companion no longer writes app-local `logs/config-audit.jsonl` or
1028
- `logs/config-health.json` sidecars while editing `fengming.json`. The config
1029
- file remains file-backed, recovery snapshots stay next to the config file,
1030
- and durable config audit/health state belongs to the Gateway SQLite store.
1031
- - Crestodian rescue pending approvals now use core SQLite plugin state instead
1032
- of `crestodian/rescue-pending/*.json`. Doctor imports legacy pending approval
1033
- files and removes them after successful import.
1034
- - Phone Control temporary arm state now uses SQLite plugin state instead of
1035
- `plugins/phone-control/armed.json`. Doctor imports the legacy armed-state
1036
- file into the `phone-control/arm-state` namespace and removes the file.
1037
- - Doctor no longer repairs JSONL transcripts in place or creates backup JSONL
1038
- files. It imports the active branch into SQLite and removes the legacy source.
1039
- - Session-memory hook transcript lookup uses `{agentId, sessionId}` scope-only
1040
- SQLite reads. Its helper no longer accepts or derives transcript locators,
1041
- legacy file reads, or file-rewrite options.
1042
- - Codex app-server conversation bindings now key SQLite plugin state by
1043
- FengMing session key or explicit `{agentId, sessionId}` scope. They must not
1044
- preserve transcript-path fallback bindings.
1045
- - Codex app-server mirrored-history reads use the SQLite transcript scope only;
1046
- they must not recover identity from transcript file paths.
1047
- - Role-ordering and compaction reset paths no longer unlink old transcript
1048
- files; reset only rotates the SQLite session row and transcript identity.
1049
- - Gateway reset and checkpoint responses return clean session rows plus session
1050
- ids. They no longer synthesize SQLite transcript locators for clients.
1051
- - Memory-core dreaming no longer prunes session rows by probing for missing
1052
- JSONL files. Subagent cleanup goes through the session runtime API instead of
1053
- filesystem existence checks. Its transcript-ingestion tests seed SQLite rows
1054
- directly instead of creating `agents/<id>/sessions` fixtures or locator
1055
- placeholders.
1056
- - Memory transcript indexing may expose `transcript:<agentId>:<sessionId>` as a
1057
- virtual search-hit path for citation/read helpers. The durable index source is
1058
- relational (`source_kind='sessions'`, `source_key='session:<sessionId>'`,
1059
- `session_id=<sessionId>`), so the value is not a runtime transcript locator,
1060
- not a filesystem path, and must never be passed back into session runtime APIs.
1061
- - Gateway doctor memory status reads short-term recall and phase-signal counts
1062
- from SQLite plugin-state rows instead of `memory/.dreams/*.json`; CLI and
1063
- doctor output now label that storage as a SQLite store, not a path.
1064
- - Memory-core runtime, CLI status, Gateway doctor methods, and plugin SDK
1065
- facades no longer audit or archive legacy `.dreams/session-corpus` files.
1066
- Those files are migration inputs only; doctor imports them into SQLite and
1067
- deletes the source after verification. Active session-ingestion evidence rows
1068
- now use the virtual SQLite path `memory/session-ingestion/<day>.txt`; runtime
1069
- never writes or derives state from `.dreams/session-corpus`.
1070
- - Memory-core public artifacts expose SQLite host events as the virtual JSON
1071
- artifact `memory/events/memory-host-events.json`; they no longer reuse the
1072
- legacy `.dreams/events.jsonl` source path.
1073
- - Sandbox container/browser registries now use the shared
1074
- `sandbox_registry_entries` SQLite table with typed session, image, timestamp,
1075
- backend/config, and browser port columns. Doctor imports legacy monolithic and
1076
- sharded JSON registry files and removes successful sources. Runtime reads use
1077
- the typed row columns as source of truth; `entry_json` is only a replay/debug
1078
- copy.
1079
- - Commitments now use a typed shared `commitments` table instead of a
1080
- whole-store JSON blob. Snapshot saves upsert by commitment id and delete only
1081
- missing rows instead of clearing and reinserting the table. Runtime loads
1082
- commitments from typed scope, delivery-window, status, attempt, and text
1083
- columns; `record_json` is only a replay/debug copy. Doctor imports legacy
1084
- `commitments.json` and removes it after a successful import.
1085
- - Cron job definitions, schedule state, and run history no longer have runtime
1086
- JSON writers or readers. Runtime uses `cron_jobs` rows with typed schedule,
1087
- payload, delivery, failure-alert, session, status, and runtime-state columns plus typed
1088
- `cron_run_logs` metadata for status, diagnostics summary, delivery status/error,
1089
- session/run, model, and token totals. `job_json` is only a replay/debug copy; `state_json` keeps nested
1090
- runtime diagnostics that do not yet have hot query fields, while runtime
1091
- rehydrates hot state fields from typed columns. Doctor imports
1092
- legacy `jobs.json`, `jobs-state.json`, and `runs/*.jsonl` files and removes
1093
- the imported sources. Plugin target writebacks update matching `cron_jobs`
1094
- rows instead of loading and replacing the whole cron store.
1095
- - If doctor cannot safely translate legacy `notify: true` webhook fallback
1096
- without replacing an explicit delivery target, it records a warning and leaves
1097
- the legacy source in place instead of publishing a lossy SQLite row.
1098
- - Outbound and session delivery queues now store queue status, entry kind,
1099
- session key, channel, target, account id, retry count, last attempt/error,
1100
- recovery state, and platform-send markers as typed columns in the shared
1101
- `delivery_queue_entries` table. Runtime recovery reads those hot fields from
1102
- the typed columns, and retry/recovery mutations update those columns directly
1103
- without rewriting replay JSON. The full JSON payload remains only as the
1104
- replay/debug blob for message bodies and other cold replay data.
1105
- - Managed outgoing image records now use typed shared
1106
- `managed_outgoing_image_records` rows with media bytes still stored in
1107
- `media_blobs`. The JSON record remains only as a replay/debug copy.
1108
- - Discord model-picker preferences, command-deploy hashes, and thread bindings
1109
- now use shared SQLite plugin state. Their legacy JSON import plans live in the
1110
- Discord plugin setup/doctor migration surface, not in core migration code.
1111
- - Plugin legacy import detectors use doctor-named modules such as
1112
- `doctor-legacy-state.ts` or `doctor-state-imports.ts`; normal channel runtime
1113
- modules must not import legacy JSON detectors.
1114
- - BlueBubbles catchup cursors and inbound dedupe markers now use shared SQLite
1115
- plugin state. Their legacy JSON import plans live in the BlueBubbles plugin
1116
- setup/doctor migration surface, not in core migration code.
1117
- - Telegram update offsets, sticker cache rows, sent-message cache rows,
1118
- topic-name cache rows, and thread bindings now use shared SQLite plugin
1119
- state. Their legacy JSON import plans live in the Telegram plugin
1120
- setup/doctor migration surface, not in core migration code.
1121
- - iMessage catchup cursors, reply short-id mappings, and sent-echo dedupe rows
1122
- now use shared SQLite plugin state. The old `imessage/catchup/*.json`,
1123
- `imessage/reply-cache.jsonl`, and `imessage/sent-echoes.jsonl` files are
1124
- doctor inputs only.
1125
- - Feishu message dedupe rows now use shared SQLite plugin state instead of
1126
- `feishu/dedup/*.json` files. Its legacy JSON import plan lives in the Feishu
1127
- plugin setup/doctor migration surface, not in core migration code.
1128
- - Microsoft Teams conversations, polls, pending upload buffers, and feedback
1129
- learnings now use shared SQLite plugin state/blob tables. The pending upload
1130
- path uses `plugin_blob_entries` so media buffers are stored as SQLite BLOBs
1131
- instead of base64 JSON. The runtime helper names now use SQLite/state naming
1132
- rather than `*-fs` file-store naming, and the old `storePath` shim is gone
1133
- from these stores. Its legacy JSON import plan lives in the Microsoft Teams
1134
- plugin setup/doctor migration surface.
1135
- - Zalo hosted outbound media now uses shared SQLite `plugin_blob_entries`
1136
- instead of `fengming-zalo-outbound-media` JSON/bin temp sidecars.
1137
- - Diffs viewer HTML and metadata now use shared SQLite `plugin_blob_entries`
1138
- instead of `meta.json`/`viewer.html` temp files. Rendered PNG/PDF outputs stay
1139
- temp materializations because channel delivery still needs a file path.
1140
- - Canvas managed documents now use shared SQLite `plugin_blob_entries` instead
1141
- of a default `state/canvas/documents` directory. The Canvas host serves those
1142
- blobs directly; local files are created only for explicit `host.root`
1143
- operator content or temporary materialization when a downstream media reader
1144
- requires a path.
1145
- - File Transfer audit decisions now use shared SQLite `plugin_state_entries`
1146
- instead of the unbounded `audit/file-transfer.jsonl` runtime log. Doctor
1147
- imports the legacy JSONL audit file into plugin state and removes the source
1148
- after a clean import.
1149
- - ACPX process leases and gateway instance identity now use shared SQLite plugin
1150
- state. Doctor imports the legacy `gateway-instance-id` file into plugin state
1151
- and removes the source.
1152
- - ACPX generated wrapper scripts and the isolated Codex home are temporary
1153
- materialization under the FengMing temp root, not durable FengMing state. The
1154
- durable ACPX runtime records are the SQLite lease and gateway-instance rows;
1155
- the old ACPX `stateDir` config surface is removed because no runtime state is
1156
- written there anymore.
1157
- - Gateway media attachments now use the shared `media_blobs` SQLite table as
1158
- the canonical byte store. Local paths returned to channel and sandbox
1159
- compatibility surfaces are temp materializations of the database row, not the
1160
- durable media store. Runtime media allowlists no longer include legacy
1161
- `$FENGMING_STATE_DIR/media` or config-dir `media` roots; those directories are
1162
- doctor import sources only.
1163
- - Shell completion no longer writes `$FENGMING_STATE_DIR/completions/*` cache
1164
- files. Install, doctor, update, and release smoke paths use generated
1165
- completion output or profile sourcing instead of durable completion cache
1166
- files.
1167
- - Gateway skill-upload staging now uses shared `skill_uploads` rows. Upload
1168
- metadata, idempotency keys, and archive bytes live in SQLite; the installer
1169
- only receives a temporary materialized archive path while an install is
1170
- running.
1171
- - Subagent inline attachments no longer materialize under workspace
1172
- `.fengming/attachments/*`. The spawn path prepares SQLite VFS seed entries,
1173
- inline runs seed those entries into the per-agent runtime scratch namespace,
1174
- and disk-backed tools overlay that SQLite scratch for attachment paths. The
1175
- old subagent-run attachment-dir registry columns and cleanup hooks are gone.
1176
- - CLI image hydration no longer maintains stable `fengming-cli-images` cache
1177
- files. External CLI backends still receive file paths, but those paths are
1178
- per-run temp materializations with cleanup.
1179
- - Cache-trace diagnostics, Anthropic payload diagnostics, raw model stream
1180
- diagnostics, diagnostics timeline events, and Gateway stability bundles now
1181
- write SQLite rows instead of `logs/*.jsonl` or
1182
- `logs/stability/*.json` files.
1183
- Runtime path override flags and env vars have been removed; export/debug
1184
- commands can materialize files explicitly from database rows.
1185
- - The macOS companion no longer has a rolling `diagnostics.jsonl` writer. App
1186
- logs go to unified logging, and durable Gateway diagnostics stay SQLite-backed.
1187
- - The macOS port-guardian record list now uses typed shared SQLite
1188
- `macos_port_guardian_records` rows instead of an Application Support JSON file
1189
- or opaque singleton blob.
1190
- - Gateway singleton locks now use typed shared SQLite `state_leases` rows under
1191
- the `gateway_locks` scope instead of temp-dir lock files. Fly and OAuth
1192
- troubleshooting docs now point at the SQLite lease/auth refresh lock instead
1193
- of stale file-lock cleanup.
1194
- - Gateway restart sentinel state now uses typed shared SQLite
1195
- `gateway_restart_sentinel` rows instead of `restart-sentinel.json`; runtime
1196
- reads sentinel kind, status, routing, message, continuation, and stats from
1197
- typed columns. `payload_json` is only a replay/debug copy. Runtime code clears
1198
- the SQLite row directly and no longer carries file cleanup plumbing.
1199
- - Gateway restart intent and supervisor handoff state now use typed shared
1200
- SQLite `gateway_restart_intent` and `gateway_restart_handoff` rows instead of
1201
- `gateway-restart-intent.json` and
1202
- `gateway-supervisor-restart-handoff.json` sidecars.
1203
- - Gateway singleton coordination now uses typed `state_leases` rows under
1204
- `gateway_locks` instead of writing `gateway.<hash>.lock` files. The lease row
1205
- owns the lock owner, expiry, heartbeat, and debug payload; SQLite owns the
1206
- atomic acquire/release boundary. The retired file-lock directory option is
1207
- gone; tests use the SQLite row identity directly.
1208
- - The old unreferenced cron usage-report helper that scanned `cron/runs/*.jsonl`
1209
- files was deleted. Cron run history reports should read the typed
1210
- `cron_run_logs` SQLite rows.
1211
- - Main-session restart recovery now discovers candidate agents through the
1212
- SQLite `agent_databases` registry instead of scanning `agents/*/sessions`
1213
- directories.
1214
- - Gemini session-corruption recovery now deletes only the SQLite session row;
1215
- it no longer needs a legacy `storePath` gate or tries to unlink a derived
1216
- transcript JSONL path.
1217
- - Path override handling now treats literal `undefined`/`null` environment
1218
- values as unset, preventing accidental repo-root `undefined/state/*.sqlite`
1219
- databases during tests or shell handoffs.
1220
- - Config health fingerprints now use typed shared SQLite `config_health_entries`
1221
- rows instead of `logs/config-health.json`, keeping the normal config file as
1222
- the only non-credential configuration document. The macOS companion keeps only
1223
- process-local health state and does not recreate the old JSON sidecar.
1224
- - Auth profile runtime no longer imports or writes credential JSON files. The
1225
- canonical credential store is SQLite; `auth-profiles.json`, per-agent
1226
- `auth.json`, and shared `credentials/oauth.json` are doctor migration inputs
1227
- that are removed after import.
1228
- - Auth profile save/state tests now assert typed SQLite auth tables directly
1229
- and only use legacy auth-profile filenames for doctor migration inputs.
1230
- - `fengming secrets apply` scrubs the config file, env file, and SQLite
1231
- auth-profile store only. It no longer carries compatibility logic that edits
1232
- retired per-agent `auth.json`; doctor owns importing and deleting that file.
1233
- - Hermes secret migration plans and applies imported API-key profiles directly
1234
- into the SQLite auth-profile store. It no longer writes or verifies
1235
- `auth-profiles.json` as an intermediate target.
1236
- - User-facing auth docs now describe
1237
- `state/fengming.sqlite#table/auth_profile_stores/<agentDir>` instead of
1238
- telling users to inspect or copy `auth-profiles.json`; legacy OAuth/auth JSON
1239
- names remain documented only as doctor-import inputs.
1240
- - Core state-path helpers no longer expose the retired `credentials/oauth.json`
1241
- file. The legacy filename is local to the doctor auth import path.
1242
- - Install, security, onboarding, model-auth, and SecretRef docs now describe
1243
- SQLite auth-profile rows and whole-state backup/migration instead of
1244
- per-agent auth-profile JSON files.
1245
- - PI model discovery now passes canonical credentials into in-memory
1246
- `pi-coding-agent` auth storage. It no longer creates, scrubs, or writes
1247
- per-agent `auth.json` during discovery.
1248
- - Voice Wake trigger and routing settings now use typed shared SQLite tables
1249
- instead of `settings/voicewake.json`, `settings/voicewake-routing.json`, or
1250
- opaque generic rows; doctor imports the legacy JSON files and removes them after a
1251
- successful migration.
1252
- - Update-check state now uses a typed shared `update_check_state` row instead of
1253
- `update-check.json` or an opaque generic blob; doctor imports
1254
- the legacy JSON file and removes it after a successful migration.
1255
- - Config health state now uses typed shared `config_health_entries` rows instead
1256
- of `logs/config-health.json` or an opaque generic blob; doctor
1257
- imports the legacy JSON file and removes it after a successful migration.
1258
- - Plugin conversation binding approvals now use typed
1259
- `plugin_binding_approvals` rows instead of opaque shared SQLite state or
1260
- `plugin-binding-approvals.json`; the legacy file is a doctor migration input.
1261
- - Generic current-conversation bindings now store typed
1262
- `current_conversation_bindings` rows instead of rewriting
1263
- `bindings/current-conversations.json`; doctor imports the legacy JSON file and
1264
- removes it after a successful migration.
1265
- - Memory Wiki imported-source sync ledgers now store one SQLite plugin-state row
1266
- per vault/source key instead of rewriting `.fengming-wiki/source-sync.json`;
1267
- the migration provider imports and removes the legacy JSON ledger.
1268
- - Memory Wiki ChatGPT import-run records now store one SQLite plugin-state row
1269
- per vault/run id instead of writing `.fengming-wiki/import-runs/*.json`.
1270
- Rollback snapshots remain explicit vault files until import-run snapshot
1271
- archival is moved into blob storage.
1272
- - Memory Wiki compiled digests now store SQLite plugin blob rows instead of
1273
- writing `.fengming-wiki/cache/agent-digest.json` and
1274
- `.fengming-wiki/cache/claims.jsonl`. The migration provider imports old cache
1275
- files and removes the cache directory when it becomes empty.
1276
- - ClawHub skill install tracking now stores one SQLite plugin-state row per
1277
- workspace/skill instead of writing or reading `.clawhub/lock.json` and
1278
- `.clawhub/origin.json` sidecars at runtime. Runtime code uses tracked-install
1279
- state objects rather than file-shaped lockfile/origin abstractions. Doctor
1280
- imports the legacy sidecars from configured agent workspaces and removes them
1281
- after a clean import.
1282
- - The installed plugin index now reads and writes the typed shared SQLite
1283
- `installed_plugin_index` singleton row instead of `plugins/installs.json`; the
1284
- legacy JSON file is only a doctor migration input and is removed after import.
1285
- - The legacy `plugins/installs.json` path helper now lives in doctor legacy
1286
- code. Runtime plugin-index modules expose only SQLite-backed persistence
1287
- options, not a JSON file path.
1288
- - Gateway restart sentinel, restart intent, and supervisor handoff state now use
1289
- typed shared SQLite rows (`gateway_restart_sentinel`,
1290
- `gateway_restart_intent`, and `gateway_restart_handoff`) instead of generic
1291
- opaque blobs. Runtime restart code has no file-shaped sentinel/intent/handoff
1292
- contract.
1293
- - Matrix sync cache, storage metadata, thread bindings, inbound dedupe markers,
1294
- startup verification cooldown state, SDK IndexedDB crypto snapshots,
1295
- credentials, and recovery keys now use shared SQLite plugin state/blob
1296
- tables. Runtime path structs no longer expose a `storage-meta.json` metadata
1297
- path; that filename is a legacy migration input only. Their legacy JSON import
1298
- plan lives in the Matrix plugin setup/doctor migration surface.
1299
- - Matrix startup no longer scans, reports, or completes legacy Matrix file
1300
- state. Matrix file detection, legacy crypto snapshot creation, room-key
1301
- restore migration state, import, and source removal are all doctor-owned.
1302
- - Matrix runtime migration barrels were removed. Legacy state/crypto detection
1303
- and mutation helpers are imported by Matrix doctor directly instead of being
1304
- part of runtime API surface.
1305
- - Matrix migration snapshot reuse markers now live in SQLite plugin state
1306
- instead of `matrix/migration-snapshot.json`; doctor can still reuse the same
1307
- verified pre-migration archive without writing a sidecar state file.
1308
- - Nostr bus cursors and profile publish state now use shared SQLite plugin
1309
- state. Their legacy JSON import plan lives in the Nostr plugin setup/doctor
1310
- migration surface.
1311
- - Active Memory session toggles now use shared SQLite plugin state instead of
1312
- `session-toggles.json`; toggling memory back on deletes the row instead of
1313
- rewriting a JSON object.
1314
- - Skill Workshop proposals and review counters now use shared SQLite plugin
1315
- state instead of per-workspace `skill-workshop/<workspace>.json` stores. Each
1316
- proposal is a separate row under `skill-workshop/proposals`, and the review
1317
- counter is a separate row under `skill-workshop/reviews`.
1318
- - Skill Workshop reviewer subagent runs now use the runtime session transcript
1319
- resolver instead of creating `skill-workshop/<sessionId>.json` sidecar session
1320
- paths.
1321
- - ACPX process leases now use shared SQLite plugin state under
1322
- `acpx/process-leases` instead of a whole-file `process-leases.json` registry.
1323
- Each lease is stored as its own row, preserving startup stale-process reaping
1324
- without a runtime JSON rewrite path.
1325
- - ACPX wrapper scripts and the isolated Codex home are generated in the
1326
- FengMing temp root. They are recreated as needed and are not backup or
1327
- migration inputs.
1328
- - Subagent run registry persistence uses typed shared `subagent_runs` rows. The
1329
- old `subagents/runs.json` path is now only a doctor migration input, and
1330
- runtime helper names no longer describe the state layer as disk-backed.
1331
- Runtime tests no longer create invalid or empty `runs.json` fixtures to prove
1332
- registry behavior; they seed/read SQLite rows directly.
1333
- - Backup stages the state directory before archiving, copies non-database files,
1334
- snapshots `*.sqlite` databases with `VACUUM INTO`, omits live WAL/SHM
1335
- sidecars, records snapshot metadata in the archive manifest, and records
1336
- completed backup runs in SQLite with the archive manifest. `fengming backup
1337
- create` validates the written archive by default; `--no-verify` is the
1338
- explicit fast path.
1339
- - `fengming backup restore` validates the archive before extraction, reuses the
1340
- verifier's normalized manifest, and restores verified manifest assets to their
1341
- recorded source paths. It requires `--yes` for writes and supports `--dry-run`
1342
- for a restore plan.
1343
- - The old backup volatile-path filter is deleted. Backup no longer needs a
1344
- live-tar skip list for legacy session or cron JSON/JSONL files because SQLite
1345
- snapshots are staged before archive creation.
1346
- - Plain setup and onboarding workspace preparation no longer create
1347
- `agents/<agentId>/sessions/` directories. They create config/workspace only;
1348
- SQLite session rows and transcript rows are created on demand in the
1349
- per-agent database.
1350
- - Security permission repair now targets the global and per-agent SQLite
1351
- databases plus WAL/SHM sidecars instead of `sessions.json` and transcript
1352
- JSONL files.
1353
- - Sandbox registry runtime names now describe SQLite registry kinds directly
1354
- instead of carrying legacy JSON registry terminology through the active store.
1355
- - `fengming reset --scope config+creds+sessions` removes per-agent
1356
- `fengming-agent.sqlite` databases plus WAL/SHM sidecars, not only legacy
1357
- `sessions/` directories.
1358
- - Gateway aggregate session helpers now use entry-oriented names:
1359
- `loadCombinedSessionEntriesForGateway` returns `{ databasePath, entries }`.
1360
- The old combined-store naming has been removed from runtime callers.
1361
- - Docker MCP channel seeding now writes the main session row and transcript
1362
- events into the per-agent SQLite database instead of creating
1363
- `sessions.json` and a JSONL transcript.
1364
- - The bundled session-memory hook now resolves previous-session context from
1365
- SQLite by `{agentId, sessionId}`. It no longer scans, stores, or synthesizes
1366
- transcript paths or `workspace/sessions` directories.
1367
- - The bundled command-logger hook now writes command audit rows to the shared
1368
- SQLite `command_log_entries` table instead of appending
1369
- `logs/commands.log`.
1370
- - Channel pairing allowlists now expose only SQLite-backed read/write helpers at
1371
- runtime and in the plugin SDK. The old `*-allowFrom.json` path resolver and
1372
- file reader live only under doctor legacy import code.
1373
- - `migration_runs` records legacy-state migration executions with status,
1374
- timestamps, and JSON reports.
1375
- - `migration_sources` records each imported legacy file source with hash, size,
1376
- record count, target table, run id, status, and source-removal state.
1377
- - `backup_runs` records backup archive paths, status, and JSON manifests.
1378
- - The global schema does not keep an unused `agents` registry table. Agent
1379
- database discovery is the canonical `agent_databases` registry until runtime
1380
- has a real agent-record owner.
1381
- - Generated model catalog config is stored in typed global SQLite
1382
- `agent_model_catalogs` rows keyed by agent directory. Runtime callers use
1383
- `ensureFengMingModelCatalog`; there is no `models.json` compatibility API in
1384
- runtime code. The implementation writes SQLite and the embedded PI registry is
1385
- hydrated from that stored payload without creating a `models.json` file.
1386
- - QMD session transcript markdown export and `memory.qmd.sessions` config were
1387
- removed. There is no QMD transcript collection, no `qmd/sessions*` runtime
1388
- path, and no file-backed session memory bridge.
1389
- - Memory-core runtime imports SQLite transcript indexing helpers from
1390
- `fengming/plugin-sdk/memory-core-host-engine-session-transcripts`, not the
1391
- QMD SDK subpath. The QMD subpath keeps a compatibility re-export only for
1392
- external callers until a major SDK cleanup can remove it.
1393
- - QMD's own `index.sqlite` is now a temp runtime materialization backed by the
1394
- main SQLite `plugin_blob_entries` table. Runtime no longer creates a durable
1395
- `~/.fengming/agents/<agentId>/qmd` sidecar.
1396
- - The optional `memory-lancedb` plugin no longer creates
1397
- `~/.fengming/memory/lancedb` as an implicit FengMing-managed store. It is an
1398
- external LanceDB backend and stays disabled until the operator configures an
1399
- explicit `dbPath`.
1400
- - `check:database-first-legacy-stores` fails new runtime source that pairs
1401
- legacy store names with write-style filesystem APIs. It also fails runtime
1402
- source that reintroduces transcript bridge contracts such as
1403
- `transcriptLocator`, `sqlite-transcript://...`, `sessionFile`, or
1404
- `storePath`, and scans tests for those bridge-contract names too. It also
1405
- bans `SessionManager.open(...)` and the old static SessionManager facades so
1406
- runtime and tests cannot silently re-create a file-backed session opener or
1407
- file-era session discovery. It also bans the old session JSONL downloader
1408
- hook/class from export UI. It also bans sidecar-shaped plugin-state/task
1409
- SQLite helper names; tests should assert `databasePath` and the shared
1410
- `state/fengming.sqlite` location instead of pretending those features own
1411
- separate SQLite files. It also bans the old generic memory index SQL table
1412
- names (`meta`, `files`, `chunks`, `chunks_vec`,
1413
- `chunks_fts`, `embedding_cache`) in runtime source so the agent database keeps
1414
- its explicit `memory_index_*` schema. It also bans embedding TEXT schemas and
1415
- embedding JSON-array writes so vectors stay compact SQLite BLOBs. Migration,
1416
- doctor, import, and explicit non-session export code remain allowed. The
1417
- guard now also covers runtime `cache/*.json` stores, generic
1418
- `thread-bindings.json` sidecars, cron state/run-log JSON, config health JSON,
1419
- restart and lock sidecars, Voice Wake settings, plugin binding approvals,
1420
- installed plugin index JSON, File Transfer audit JSONL, Memory Wiki activity
1421
- logs, the old bundled `command-logger` text log, and pi-mono raw-stream JSONL
1422
- diagnostics knobs. It also bans old root-level doctor legacy module names so
1423
- compatibility code stays under `src/commands/doctor/`. Android debug handlers
1424
- also use logcat/in-memory output instead of staging `camera_debug.log` or
1425
- `debug_logs.txt` cache files.
1426
-
1427
- ## Target Schema Shape
1428
-
1429
- Keep schemas explicit. Host-owned runtime state uses typed tables. Plugin-owned
1430
- opaque state uses `plugin_state_entries` / `plugin_blob_entries`; there is no
1431
- generic host `kv` table.
1432
-
1433
- Global database:
1434
-
1435
- ```text
1436
- state_leases(scope, lease_key, owner, expires_at, heartbeat_at, payload_json, created_at, updated_at)
1437
- exec_approvals_config(config_key, raw_json, socket_path, has_socket_token, default_security, default_ask, default_ask_fallback, auto_allow_skills, agent_count, allowlist_count, updated_at_ms)
1438
- schema_meta(meta_key, role, schema_version, agent_id, app_version, created_at, updated_at)
1439
- agent_databases(agent_id, path, schema_version, last_seen_at, size_bytes)
1440
- task_runs(...)
1441
- task_delivery_state(...)
1442
- flow_runs(...)
1443
- subagent_runs(run_id, child_session_key, requester_session_key, controller_session_key, created_at, ended_at, cleanup_handled, payload_json)
1444
- current_conversation_bindings(binding_key, binding_id, target_agent_id, target_session_id, target_session_key, channel, account_id, conversation_kind, parent_conversation_id, conversation_id, target_kind, status, bound_at, expires_at, metadata_json, updated_at)
1445
- plugin_binding_approvals(plugin_root, channel, account_id, plugin_id, plugin_name, approved_at)
1446
- tui_last_sessions(scope_key, session_key, updated_at)
1447
- plugin_state_entries(plugin_id, namespace, entry_key, value_json, created_at, expires_at)
1448
- plugin_blob_entries(plugin_id, namespace, entry_key, metadata_json, blob, created_at, expires_at)
1449
- media_blobs(subdir, id, content_type, size_bytes, blob, created_at, updated_at)
1450
- skill_uploads(upload_id, kind, slug, force, size_bytes, sha256, actual_sha256, received_bytes, archive_blob, created_at, expires_at, committed, committed_at, idempotency_key_hash)
1451
- web_push_subscriptions(endpoint_hash, subscription_id, endpoint, p256dh, auth, created_at_ms, updated_at_ms)
1452
- web_push_vapid_keys(key_id, public_key, private_key, subject, updated_at_ms)
1453
- apns_registrations(node_id, transport, token, relay_handle, send_grant, installation_id, topic, environment, distribution, token_debug_suffix, updated_at_ms)
1454
- node_host_config(config_key, version, node_id, token, display_name, gateway_host, gateway_port, gateway_tls, gateway_tls_fingerprint, updated_at_ms)
1455
- device_identities(identity_key, device_id, public_key_pem, private_key_pem, created_at_ms, updated_at_ms)
1456
- device_auth_tokens(device_id, role, token, scopes_json, updated_at_ms)
1457
- macos_port_guardian_records(pid, port, command, mode, timestamp)
1458
- workspace_setup_state(workspace_key, workspace_path, version, bootstrap_seeded_at, setup_completed_at, updated_at)
1459
- native_hook_relay_bridges(relay_id, pid, hostname, port, token, expires_at_ms, updated_at_ms)
1460
- model_capability_cache(provider_id, model_id, name, input_text, input_image, reasoning, supports_tools, context_window, max_tokens, cost_input, cost_output, cost_cache_read, cost_cache_write, updated_at_ms)
1461
- agent_model_catalogs(catalog_key, agent_dir, raw_json, updated_at)
1462
- managed_outgoing_image_records(attachment_id, session_key, message_id, created_at, updated_at, retention_class, alt, original_media_id, original_media_subdir, original_content_type, original_width, original_height, original_size_bytes, original_filename, record_json)
1463
- gateway_restart_sentinel(sentinel_key, version, kind, status, ts, session_key, thread_id, delivery_channel, delivery_to, delivery_account_id, message, continuation_json, doctor_hint, stats_json, payload_json, updated_at_ms)
1464
- channel_pairing_requests(channel_key, account_id, request_id, code, created_at, last_seen_at, meta_json)
1465
- channel_pairing_allow_entries(channel_key, account_id, entry, sort_order, updated_at)
1466
- voicewake_triggers(config_key, position, trigger, updated_at_ms)
1467
- voicewake_routing_config(config_key, version, default_target_mode, default_target_agent_id, default_target_session_key, updated_at_ms)
1468
- voicewake_routing_routes(config_key, position, trigger, target_mode, target_agent_id, target_session_key, updated_at_ms)
1469
- update_check_state(state_key, last_checked_at, last_notified_version, last_notified_tag, last_available_version, last_available_tag, auto_install_id, auto_first_seen_version, auto_first_seen_tag, auto_first_seen_at, auto_last_attempt_version, auto_last_attempt_at, auto_last_success_version, auto_last_success_at, updated_at_ms)
1470
- config_health_entries(config_path, last_known_good_json, last_promoted_good_json, last_observed_suspicious_signature, updated_at_ms)
1471
- sandbox_registry_entries(registry_kind, container_name, session_key, backend_id, runtime_label, image, created_at_ms, last_used_at_ms, config_label_kind, config_hash, cdp_port, no_vnc_port, entry_json, updated_at)
1472
- cron_run_logs(store_key, job_id, seq, ts, status, error, summary, diagnostics_summary, delivery_status, delivery_error, delivered, session_id, session_key, run_id, run_at_ms, duration_ms, next_run_at_ms, model, provider, total_tokens, entry_json, created_at)
1473
- cron_jobs(store_key, job_id, name, description, enabled, delete_after_run, created_at_ms, agent_id, session_key, schedule_kind, schedule_expr, schedule_tz, every_ms, anchor_ms, at, stagger_ms, session_target, wake_mode, payload_kind, payload_message, payload_model, payload_fallbacks_json, payload_thinking, payload_timeout_seconds, payload_allow_unsafe_external_content, payload_external_content_source_json, payload_light_context, payload_tools_allow_json, delivery_mode, delivery_channel, delivery_to, delivery_thread_id, delivery_account_id, delivery_best_effort, failure_delivery_mode, failure_delivery_channel, failure_delivery_to, failure_delivery_account_id, failure_alert_disabled, failure_alert_after, failure_alert_channel, failure_alert_to, failure_alert_cooldown_ms, failure_alert_include_skipped, failure_alert_mode, failure_alert_account_id, next_run_at_ms, running_at_ms, last_run_at_ms, last_run_status, last_error, last_duration_ms, consecutive_errors, consecutive_skipped, schedule_error_count, last_delivery_status, last_delivery_error, last_delivered, last_failure_alert_at_ms, job_json, state_json, runtime_updated_at_ms, schedule_identity, sort_order, updated_at)
1474
- delivery_queue_entries(queue_name, id, status, entry_kind, session_key, channel, target, account_id, retry_count, last_attempt_at, last_error, recovery_state, platform_send_started_at, entry_json, enqueued_at, updated_at, failed_at)
1475
- commitments(id, agent_id, session_key, channel, account_id, recipient_id, thread_id, sender_id, kind, sensitivity, source, status, reason, suggested_text, dedupe_key, confidence, due_earliest_ms, due_latest_ms, due_timezone, source_message_id, source_run_id, created_at_ms, updated_at_ms, attempts, last_attempt_at_ms, sent_at_ms, dismissed_at_ms, snoozed_until_ms, expired_at_ms, record_json)
1476
- migration_runs(id, started_at, finished_at, status, report_json)
1477
- migration_sources(source_key, migration_kind, source_path, target_table, source_sha256, source_size_bytes, source_record_count, last_run_id, status, imported_at, removed_source, report_json)
1478
- backup_runs(id, created_at, archive_path, status, manifest_json)
1479
- ```
1480
-
1481
- Agent database:
1482
-
1483
- ```text
1484
- schema_meta(meta_key, role, schema_version, agent_id, app_version, created_at, updated_at)
1485
- sessions(session_id, session_key, session_scope, created_at, updated_at, started_at, ended_at, status, chat_type, channel, account_id, primary_conversation_id, model_provider, model, agent_harness_id, parent_session_key, spawned_by, display_name)
1486
- conversations(conversation_id, channel, account_id, kind, peer_id, parent_conversation_id, thread_id, native_channel_id, native_direct_user_id, label, metadata_json, created_at, updated_at)
1487
- session_conversations(session_id, conversation_id, role, first_seen_at, last_seen_at)
1488
- session_routes(session_key, session_id, updated_at)
1489
- session_entries(session_id, session_key, entry_json, updated_at)
1490
- transcript_events(session_id, seq, event_json, created_at)
1491
- transcript_event_identities(session_id, event_id, seq, event_type, has_parent, parent_id, message_idempotency_key, created_at)
1492
- transcript_snapshots(session_id, snapshot_id, reason, event_count, created_at, metadata_json)
1493
- vfs_entries(namespace, path, kind, content_blob, metadata_json, updated_at)
1494
- tool_artifacts(run_id, artifact_id, kind, metadata_json, blob, created_at)
1495
- run_artifacts(run_id, path, kind, metadata_json, blob, created_at)
1496
- trajectory_runtime_events(session_id, run_id, seq, event_json, created_at)
1497
- memory_index_meta(meta_key, schema_version, provider, model, provider_key, sources_json, scope_hash, chunk_tokens, chunk_overlap, vector_dims, fts_tokenizer, config_hash, updated_at)
1498
- memory_index_sources(source_kind, source_key, path, session_id, hash, mtime, size)
1499
- memory_index_chunks(id, source_kind, source_key, path, session_id, start_line, end_line, hash, model, text, embedding, embedding_dims, updated_at)
1500
- memory_embedding_cache(provider, model, provider_key, hash, embedding, dims, updated_at)
1501
- cache_entries(scope, key, value_json, blob, expires_at, updated_at)
1502
- ```
1503
-
1504
- Future search can add FTS tables without changing the canonical event tables:
1505
-
1506
- ```text
1507
- transcript_events_fts(session_id, seq, text)
1508
- vfs_entries_fts(namespace, path, text)
1509
- ```
1510
-
1511
- Large values should use `blob` columns, not JSON string encoding. Keep
1512
- `value_json` for small structured data that must remain inspectable with plain
1513
- SQLite tooling.
1514
-
1515
- `agent_databases` is the canonical registry for this branch. Do not add an
1516
- `agents` table until a real agent-record owner exists; agent config remains in
1517
- `fengming.json`.
1518
-
1519
- ## Doctor Migration Shape
1520
-
1521
- Doctor should call one explicit migration step that is reportable and safe to
1522
- rerun:
1523
-
1524
- ```bash
1525
- fengming doctor --fix
1526
- ```
1527
-
1528
- `fengming doctor --fix` invokes the state migration implementation after
1529
- ordinary config preflight and creates a verified backup before import. Runtime
1530
- startup and `fengming migrate` must not import legacy FengMing state files.
1531
-
1532
- Migration properties:
1533
-
1534
- - One migration pass discovers all legacy file sources and produces a plan
1535
- before mutating anything.
1536
- - Doctor creates a verified pre-migration backup archive before importing
1537
- legacy files.
1538
- - Imports are idempotent and keyed by source path, mtime, size, hash, and target
1539
- table.
1540
- - Successful source files are removed or archived after the target database has
1541
- committed.
1542
- - Failed imports leave the source untouched and record a warning in
1543
- `migration_runs`.
1544
- - Runtime code reads SQLite only after the migration exists.
1545
- - No downgrade/export-to-runtime-files path is required.
1546
-
1547
- ## Migration Inventory
1548
-
1549
- Move these into the global database:
1550
-
1551
- - Task registry runtime writes now use the shared database; the unshipped
1552
- `tasks/runs.sqlite` sidecar importer is deleted. Snapshot saves upsert by task
1553
- id and delete only missing task/delivery rows.
1554
- - Task Flow runtime writes now use the shared database; the unshipped
1555
- `tasks/flows/registry.sqlite` sidecar importer is deleted. Snapshot saves
1556
- upsert by flow id and delete only missing flow rows.
1557
- - Plugin state runtime writes now use the shared database; the unshipped
1558
- `plugin-state/state.sqlite` sidecar importer is deleted.
1559
- - Builtin memory search no longer defaults to `memory/<agentId>.sqlite`; its
1560
- index tables live in the owning agent database, and the explicit
1561
- `memorySearch.store.path` sidecar opt-in has been retired to doctor config
1562
- migration.
1563
- - Builtin memory reindex resets only memory-owned tables in the agent database.
1564
- It must not replace the whole SQLite file, because the same database owns
1565
- sessions, transcripts, VFS rows, artifacts, and runtime caches.
1566
- - Sandbox container/browser registries from monolithic and sharded JSON. Runtime
1567
- writes now use the shared database; legacy JSON import remains.
1568
- - Cron job definitions, schedule state, and run history now use shared SQLite;
1569
- doctor imports/removes legacy `jobs.json`, `jobs-state.json`, and
1570
- `cron/runs/*.jsonl` files
1571
- - Device identity/auth, push, update check, commitments, OpenRouter model
1572
- cache, installed plugin index, and app-server bindings
1573
- - Device/node pairing and bootstrap records now use typed SQLite tables
1574
- - Device-pair notification subscribers and delivered-request markers now use the
1575
- shared SQLite plugin-state table instead of `device-pair-notify.json`.
1576
- - Voice-call call records now use the shared SQLite plugin-state table under the
1577
- `voice-call` / `calls` namespace instead of `calls.jsonl`; the plugin CLI
1578
- tails and summarizes SQLite-backed call history.
1579
- - QQBot gateway sessions, known-user records, and ref-index quote cache now use
1580
- SQLite plugin state under `qqbot` namespaces (`sessions`, `known-users`,
1581
- `ref-index`) instead of `session-*.json`, `known-users.json`, and
1582
- `ref-index.jsonl`; the QQBot doctor/setup migration imports and removes the
1583
- legacy files.
1584
- - Discord model-picker preferences, command-deploy hashes, and thread bindings
1585
- now use SQLite plugin state under `discord` namespaces
1586
- (`model-picker-preferences`, `command-deploy-hashes`, `thread-bindings`)
1587
- instead of `model-picker-preferences.json`, `command-deploy-cache.json`, and
1588
- `thread-bindings.json`; the Discord doctor/setup migration imports and
1589
- removes the legacy files.
1590
- - BlueBubbles catchup cursors and inbound dedupe markers now use SQLite plugin
1591
- state under `bluebubbles` namespaces (`catchup-cursors`, `inbound-dedupe`)
1592
- instead of `bluebubbles/catchup/*.json` and
1593
- `bluebubbles/inbound-dedupe/*.json`; the BlueBubbles doctor/setup migration
1594
- imports and removes the legacy files.
1595
- - Telegram update offsets, sticker cache entries, reply-chain message cache
1596
- entries, sent-message cache entries, topic-name cache entries, and thread
1597
- bindings now use SQLite plugin state under `telegram` namespaces
1598
- (`update-offsets`, `sticker-cache`, `message-cache`, `sent-messages`,
1599
- `topic-names`, `thread-bindings`) instead of `update-offset-*.json`,
1600
- `sticker-cache.json`, `*.telegram-messages.json`,
1601
- `*.telegram-sent-messages.json`, `*.telegram-topic-names.json`, and
1602
- `thread-bindings-*.json`; the Telegram doctor/setup migration imports and
1603
- removes the legacy files.
1604
- - iMessage catchup cursors, reply short-id mappings, and sent-echo dedupe rows
1605
- now use SQLite plugin state under `imessage` namespaces (`catchup-cursors`,
1606
- `reply-cache`, `sent-echoes`) instead of `imessage/catchup/*.json`,
1607
- `imessage/reply-cache.jsonl`, and `imessage/sent-echoes.jsonl`; the iMessage
1608
- doctor/setup migration imports and removes the legacy files.
1609
- - Microsoft Teams conversations, polls, delegated tokens, pending uploads, and
1610
- feedback learnings now use SQLite plugin state/blob namespaces
1611
- (`conversations`, `polls`, `delegated-tokens`, `pending-uploads`,
1612
- `feedback-learnings`) instead of `msteams-conversations.json`,
1613
- `msteams-polls.json`, `msteams-delegated.json`,
1614
- `msteams-pending-uploads.json`, and `*.learnings.json`; the Microsoft Teams
1615
- doctor/setup migration imports and removes the legacy files.
1616
- - Matrix sync cache, storage metadata, thread bindings, inbound dedupe markers,
1617
- startup verification cooldown state, credentials, recovery keys, and SDK
1618
- IndexedDB crypto snapshots now use SQLite plugin state/blob namespaces under
1619
- `matrix` (`sync-store`, `storage-meta`, `thread-bindings`, `inbound-dedupe`,
1620
- `startup-verification`, `credentials`, `recovery-key`, `idb-snapshots`)
1621
- instead of `bot-storage.json`, `storage-meta.json`, `thread-bindings.json`,
1622
- `inbound-dedupe.json`, `startup-verification.json`, `credentials.json`,
1623
- `recovery-key.json`, and `crypto-idb-snapshot.json`; the Matrix doctor/setup
1624
- migration imports and removes those legacy files from account-scoped Matrix
1625
- storage roots.
1626
- - Nostr bus cursors and profile publish state now use SQLite plugin state under
1627
- `nostr` namespaces (`bus-state`, `profile-state`) instead of
1628
- `bus-state-*.json` and `profile-state-*.json`; the Nostr doctor/setup
1629
- migration imports and removes the legacy files.
1630
- - Active Memory session toggles now use SQLite plugin state under
1631
- `active-memory/session-toggles` instead of `session-toggles.json`.
1632
- - Skill Workshop proposal queues and review counters now use SQLite plugin state
1633
- under `skill-workshop/proposals` and `skill-workshop/reviews` instead of
1634
- per-workspace `skill-workshop/<workspace>.json` files.
1635
- - Outbound delivery and session delivery queues now share the global SQLite
1636
- `delivery_queue_entries` table under separate queue names
1637
- (`outbound-delivery`, `session-delivery`) instead of durable
1638
- `delivery-queue/*.json`, `delivery-queue/failed/*.json`, and
1639
- `session-delivery-queue/*.json` files. The doctor legacy-state step imports
1640
- pending and failed rows, removes stale delivered markers, and deletes the old
1641
- JSON files after import. Hot routing and retry fields are typed columns; the
1642
- JSON payload is retained only for replay/debug.
1643
- - ACPX process leases now use SQLite plugin state under `acpx/process-leases`
1644
- instead of `process-leases.json`.
1645
- - Backup and migration run metadata
1646
-
1647
- Move these into agent databases:
1648
-
1649
- - Agent session roots and compatibility-shaped session-entry payloads. Done for
1650
- runtime writes: hot session metadata is queryable in `sessions`, while the
1651
- legacy-shaped full `SessionEntry` payload remains in `session_entries`.
1652
- - Agent transcript events. Done for runtime writes.
1653
- - Compaction checkpoints and transcript snapshots. Done for runtime writes:
1654
- checkpoint transcript copies are SQLite transcript rows and checkpoint
1655
- metadata is recorded in `transcript_snapshots`. Gateway checkpoint helpers
1656
- now name these values as transcript snapshots rather than source files.
1657
- - Agent VFS scratch/workspace namespaces. Done for runtime VFS writes.
1658
- - Subagent attachment payloads. Done for runtime writes: they are SQLite VFS
1659
- seed entries and never durable workspace files.
1660
- - Tool artifacts. Done for runtime writes.
1661
- - Run artifacts. Done for worker runtime writes through the per-agent
1662
- `run_artifacts` table.
1663
- - Agent-local runtime caches. Done for worker runtime scoped cache writes through
1664
- the per-agent `cache_entries` table. Gateway-wide model caches stay in the
1665
- global database unless they become agent-specific.
1666
- - ACP parent stream logs. Done for runtime writes.
1667
- - ACP replay ledger sessions. Done for runtime writes via
1668
- `acp_replay_sessions` and `acp_replay_events`; legacy `acp/event-ledger.json`
1669
- remains only as doctor input.
1670
- - Trajectory sidecars when they are not explicit export files. Done for runtime
1671
- writes: trajectory capture writes agent-database `trajectory_runtime_events`
1672
- rows and mirrors run-scoped artifacts into SQLite. Legacy sidecars are doctor
1673
- import inputs only; export can materialize fresh JSONL support-bundle outputs
1674
- but does not read or migrate old trajectory/transcript sidecars at runtime.
1675
- Runtime trajectory capture exposes SQLite scope; JSONL path helpers are
1676
- isolated to export/debug support and are not re-exported from the runtime module.
1677
- Embedded-runner trajectory metadata records `{agentId, sessionId, sessionKey}`
1678
- identity instead of persisting a transcript locator.
1679
-
1680
- Keep these file-backed for now:
1681
-
1682
- - `fengming.json`
1683
- - provider or CLI credential files
1684
- - plugin/package manifests
1685
- - user workspaces and Git repositories when disk mode is selected
1686
- - logs intended for operator tailing, unless a specific log surface is moved
1687
-
1688
- ## Migration Plan
1689
-
1690
- ### Phase 0: Freeze The Boundary
1691
-
1692
- Make the durable-state boundary explicit before moving more rows:
1693
-
1694
- - Add a `migration_runs` table to the global database.
1695
- Done for legacy-state migration execution reports.
1696
- - Add a single doctor-owned state migration service for file-to-database import.
1697
- Done: `fengming doctor --fix` uses the legacy-state migration implementation.
1698
- - Make `plan` read-only and make `apply` create a backup, import, verify, and
1699
- then delete or quarantine old files.
1700
- Done: doctor creates a verified pre-migration backup, passes the backup path
1701
- into `migration_runs`, and reuses the importer/removal paths.
1702
- - Add static bans so new runtime code cannot write legacy state files while
1703
- migration code and tests can still seed/read them.
1704
- Done for the currently migrated legacy stores; the guard also scans nested
1705
- tests for forbidden runtime transcript locator contracts.
1706
-
1707
- ### Phase 1: Finish The Global Control Plane
1708
-
1709
- Keep shared coordination state in `state/fengming.sqlite`:
1710
-
1711
- - Agents and agent database registry
1712
- - Task and Task Flow ledgers
1713
- - Plugin state
1714
- - Sandbox container/browser registry
1715
- - Cron/scheduler run history
1716
- - Pairing, device, push, update-check, TUI, OpenRouter/model caches, and other
1717
- small gateway-scoped runtime state
1718
- - Backup and migration metadata
1719
- - Gateway media attachment bytes. Done for runtime writes; direct file paths
1720
- are temp materializations for compatibility with channel senders and sandbox
1721
- staging. Runtime allowlists accept SQLite materialization paths, not legacy
1722
- state/config media roots. Doctor imports legacy media files into
1723
- `media_blobs` and removes the source files after successful row writes.
1724
- - Debug proxy capture sessions, events, and payload blobs. Done: captures live
1725
- in the shared state DB and open through the shared state DB bootstrap, schema,
1726
- WAL, and busy-timeout settings. There is no debug proxy runtime sidecar DB
1727
- override, blob directory, or proxy-capture-only generated schema/codegen
1728
- target.
1729
-
1730
- This phase also deletes duplicate sidecar openers, permission helpers, WAL
1731
- setup, filesystem pruning, and compatibility writers from those subsystems.
1732
-
1733
- ### Phase 2: Introduce Per-Agent Databases
1734
-
1735
- Create one database per agent and register it from the global DB:
1736
-
1737
- ```text
1738
- ~/.fengming/state/fengming.sqlite
1739
- ~/.fengming/agents/<agentId>/agent/fengming-agent.sqlite
1740
- ```
1741
-
1742
- The global `agent_databases` row stores the path, schema version, last-seen
1743
- timestamp, and basic size/integrity metadata. Runtime code asks the registry for
1744
- the agent DB instead of deriving file paths directly.
1745
-
1746
- The agent DB owns:
1747
-
1748
- - `sessions` as the canonical session root, with `session_entries` as the
1749
- compatibility-shaped payload table attached to that root, and
1750
- `session_routes` as the unique active `session_key` lookup
1751
- - `conversations` and `session_conversations` as the normalized provider
1752
- routing identity attached to sessions
1753
- - `transcript_events`
1754
- - transcript snapshots and compaction checkpoints. Done for runtime writes.
1755
- - `vfs_entries`
1756
- - `tool_artifacts` and run artifacts
1757
- - agent-local runtime/cache rows. Done for worker scoped caches.
1758
- - ACP parent stream events
1759
- - trajectory runtime events when they are not explicit export artifacts
1760
-
1761
- ### Phase 3: Replace Session Store APIs
1762
-
1763
- Done for runtime. The file-shaped session store surface is not an active
1764
- runtime contract:
1765
-
1766
- - Runtime no longer calls `loadSessionStore(storePath)` or treats `storePath` as
1767
- session identity.
1768
- - Runtime row operations are `getSessionEntry`, `upsertSessionEntry`,
1769
- `patchSessionEntry`, `deleteSessionEntry`, and `listSessionEntries`.
1770
- - Whole-store rewrite helpers, file writers, queue tests, alias pruning, and
1771
- legacy-key deletion parameters are gone from runtime.
1772
- - Deprecated root-package compatibility exports still adapt canonical
1773
- `sessions.json` paths onto the SQLite row APIs.
1774
- - `sessions.json` parsing remains only in doctor migration/import code and
1775
- doctor tests.
1776
- - Runtime lifecycle fallback reads SQLite transcript headers, not JSONL first
1777
- lines.
1778
-
1779
- Keep deleting anything that reintroduces file-lock parameters,
1780
- pruning/truncation-as-file-maintenance vocabulary, store-path identity, or tests
1781
- whose only assertion is JSON persistence.
1782
-
1783
- ### Phase 4: Move Transcripts, ACP Streams, Trajectories, And VFS
1784
-
1785
- Make every agent data stream database-native:
1786
-
1787
- - Transcript append writes go through one SQLite transaction that ensures the
1788
- session header, checks message idempotency, selects the parent tail, inserts
1789
- into `transcript_events`, and records queryable identity metadata in
1790
- `transcript_event_identities`. Done for direct transcript message appends and
1791
- normal persisted `TranscriptSessionManager` appends; explicit branch
1792
- operations keep their explicit parent choice and still write SQLite rows
1793
- without deriving any file locator.
1794
- - ACP parent stream logs become rows, not `.acp-stream.jsonl` files. Done.
1795
- - ACP spawn setup no longer persists transcript JSONL paths. Done.
1796
- - Runtime trajectory capture writes event rows/artifacts directly. The explicit
1797
- support/export command can still produce support-bundle JSONL artifacts as an
1798
- export format, but session export does not recreate session JSONL. Done.
1799
- - Disk workspaces stay on disk when configured as disk mode.
1800
- - VFS scratch and experimental VFS-only workspace mode use the agent DB.
1801
-
1802
- The migration imports old JSONL files once, records counts/hashes in
1803
- `migration_runs`, and removes imported files after integrity checks.
1804
-
1805
- ### Phase 5: Backup, Restore, Vacuum, And Verify
1806
-
1807
- Backups remain one archive file:
1808
-
1809
- - Checkpoint every global and agent database.
1810
- - Snapshot each DB with SQLite backup semantics or `VACUUM INTO`.
1811
- - Archive compact DB snapshots, config, external credentials, and requested
1812
- workspace exports.
1813
- - Omit raw live `*.sqlite-wal` and `*.sqlite-shm` files.
1814
- - Verify by opening every DB snapshot and running `PRAGMA integrity_check`.
1815
- `fengming backup create` does this archive verification by default;
1816
- `--no-verify` skips only the post-write archive pass, not the snapshot
1817
- creation integrity check.
1818
- - Restore copies snapshots back to their target paths. This branch resets the
1819
- unshipped SQLite layout to `user_version = 1`; future shipped schema changes
1820
- can add explicit migrations when they are needed.
1821
-
1822
- ### Phase 6: Worker Runtime
1823
-
1824
- Keep worker mode experimental while the database split lands:
1825
-
1826
- - Workers receive agent id, run id, filesystem mode, and DB registry identity.
1827
- - Each worker opens its own SQLite connection.
1828
- - Parent keeps channel delivery, approvals, config, and cancellation authority.
1829
- - Start with one worker per active run; add pooling only after lifecycle and DB
1830
- connection ownership are stable.
1831
-
1832
- ### Phase 7: Delete The Old World
1833
-
1834
- Done for runtime session management. The old world is allowed only as explicit
1835
- doctor input or support/export output:
1836
-
1837
- - No runtime `sessions.json`, transcript JSONL, sandbox registry JSON, task
1838
- sidecar SQLite, or plugin-state sidecar SQLite writes.
1839
- - No JSON/session file pruning, file transcript truncation, session file locks,
1840
- or lock-shaped session tests.
1841
- - No runtime compatibility exports whose purpose is keeping old session files
1842
- current.
1843
- - Explicit support exports remain user-requested archive/materialization
1844
- formats and must not feed file names back into runtime identity.
1845
-
1846
- ## Backup And Restore
1847
-
1848
- Backups should be one archive file, but database capture should be
1849
- SQLite-native:
1850
-
1851
- 1. Stop long-running write activity or enter a short backup barrier.
1852
- 2. For every global and agent database, run a checkpoint.
1853
- 3. Snapshot each database using SQLite backup semantics or `VACUUM INTO` into a
1854
- temporary backup directory.
1855
- 4. Archive the compacted database snapshots, config file, credentials directory,
1856
- selected workspaces, and a manifest.
1857
- 5. Verify the archive by opening every included SQLite snapshot and running
1858
- `PRAGMA integrity_check`.
1859
- `fengming backup create` does this by default; `--no-verify` is only for
1860
- intentionally skipping the post-write archive pass.
1861
-
1862
- Do not rely on raw live `*.sqlite`, `*.sqlite-wal`, and `*.sqlite-shm` copies as
1863
- the primary backup format. The archive manifest should record database role,
1864
- agent id, schema version, source path, snapshot path, byte size, and integrity
1865
- status.
1866
-
1867
- Restore should rebuild the global database and agent database files from the
1868
- archive snapshots. Because the SQLite layout has not shipped yet, this refactor
1869
- keeps only the version-1 schema plus doctor file-to-database import. The restore
1870
- command validates the archive first, then replaces each manifest asset from the
1871
- verified extracted payload.
1872
-
1873
- ## Runtime Refactor Plan
1874
-
1875
- 1. Add database registry APIs.
1876
- - Resolve global DB and per-agent DB paths.
1877
- - Keep the unshipped schemas at `user_version = 1`; do not add schema
1878
- migration runner code until a shipped schema needs it.
1879
- - Add close/checkpoint/integrity helpers used by tests, backup, and doctor.
1880
-
1881
- 2. Collapse sidecar SQLite stores.
1882
- - Move plugin state tables into the global database. Done for runtime
1883
- writes; the unshipped legacy sidecar importer is deleted.
1884
- - Move task registry tables into the global database. Done for runtime
1885
- writes; the unshipped legacy sidecar importer is deleted.
1886
- - Move Task Flow tables into the global database. Done for runtime writes;
1887
- the unshipped legacy sidecar importer is deleted.
1888
- - Move builtin memory-search tables into each agent database. Done; explicit
1889
- custom `memorySearch.store.path` is now removed by doctor config migration.
1890
- Full reindex runs in place against memory tables only; the old whole-file
1891
- swap path and sidecar index swap helper are deleted.
1892
- - Delete duplicate database openers, WAL setup, permission helpers, and
1893
- close paths from those subsystems.
1894
-
1895
- 3. Move agent-owned tables into per-agent databases.
1896
- - Create agent DB on demand through the global database registry. Done.
1897
- - Move runtime session entries, transcript events, VFS rows, and tool
1898
- artifacts to agent DBs. Done.
1899
- - Do not migrate branch-local shared-DB session entries, transcript events,
1900
- VFS rows, or tool artifacts; that layout never shipped. Keep only legacy
1901
- file-to-database import in doctor.
1902
-
1903
- 4. Replace session store APIs.
1904
- - Remove `storePath` as the runtime identity. Done for runtime and guarded
1905
- by `check:database-first-legacy-stores`: session metadata, route updates,
1906
- command persistence, CLI session cleanup, Feishu reasoning previews,
1907
- transcript-state persistence, subagent depth, auth profile session
1908
- overrides, parent-fork logic, and QA-lab inspection now resolve the
1909
- database from canonical agent/session keys.
1910
- Gateway/TUI/UI/macOS session-list responses now expose `databasePath`
1911
- instead of legacy `path`; macOS debug surfaces show the per-agent database
1912
- as read-only state instead of writing `session.store` config.
1913
- `/status`, chat-driven trajectory export, and CLI dependency proxies no
1914
- longer propagate legacy store paths; transcript usage fallback reads
1915
- SQLite by agent/session identity. Runtime and bridge tests no longer expose
1916
- `storePath`; doctor/migration inputs own that legacy field name.
1917
- Gateway combined-session loading no longer has a special runtime branch for
1918
- non-templated `session.store` values; it aggregates per-agent SQLite rows.
1919
- The legacy session-lock doctor lane and its `.jsonl.lock` cleanup helper
1920
- were removed; SQLite is the session concurrency boundary now.
1921
- Hot runtime call sites use row-oriented helper names such as
1922
- `resolveSessionRowEntry`; the old `resolveSessionStoreEntry` compatibility
1923
- alias has been removed from runtime and plugin SDK exports.
1924
-
1925
- - Use `{ agentId, sessionKey }` row operations.
1926
- Done: `getSessionEntry`, `upsertSessionEntry`, `deleteSessionEntry`,
1927
- `patchSessionEntry`, and `listSessionEntries` are SQLite-first APIs that do
1928
- not require a session store path. Status summary, local agent status, health,
1929
- and the `fengming sessions` listing command now read per-agent rows directly
1930
- and display per-agent SQLite database paths instead of `sessions.json` paths.
1931
- - Replace whole-store delete/insert with `upsertSessionEntry`,
1932
- `deleteSessionEntry`, `listSessionEntries`, and SQL cleanup queries.
1933
- Done for runtime: hot paths now use row APIs and conflict-retried row patches;
1934
- remaining whole-store import/replace helpers are limited to migration import
1935
- code and SQLite backend tests.
1936
- - Delete `store-writer.ts` and writer-queue tests. Done.
1937
- - Delete runtime legacy-key pruning and alias-delete parameters from session
1938
- row upserts/patches. Done.
1939
-
1940
- 5. Delete runtime JSON registry behavior.
1941
- - Make sandbox registry reads and writes SQLite-only. Done.
1942
- - Import monolithic and sharded JSON only from the migration step. Done.
1943
- - Remove sharded registry locks and JSON writes. Done.
1944
-
1945
- - Keep one typed registry table instead of storing registry rows as generic
1946
- opaque JSON if the shape remains hot-path operational state. Done.
1947
-
1948
- 6. Delete file-lock-shaped session mutation.
1949
- - Done for runtime lock creation and runtime lock APIs.
1950
- - The standalone legacy `.jsonl.lock` doctor cleanup lane is removed.
1951
- - `session.writeLock` is doctor-migrated legacy config, not a typed runtime
1952
- setting.
1953
- - State integrity no longer has a separate orphan transcript-file pruning
1954
- path; doctor migration imports/removes legacy JSONL sources in one place.
1955
- - Gateway singleton coordination uses typed SQLite `state_leases` rows under
1956
- `gateway_locks` and no longer exposes a file-lock directory seam.
1957
- - Generic plugin SDK dedupe persistence no longer uses file locks or JSON
1958
- files; it writes shared SQLite plugin-state rows. Done.
1959
- - QMD embed coordination uses a SQLite state lease instead of
1960
- `qmd/embed.lock`. Done.
1961
-
1962
- 7. Make workers database-aware.
1963
- - Workers open their own SQLite connections.
1964
- - Parent owns delivery, channel callbacks, and config.
1965
- - Worker receives agent id, run id, filesystem mode, and DB registry
1966
- identity, not live handles.
1967
- - `vfs-only` stays experimental and uses the agent database as its storage
1968
- root.
1969
- - Keep one worker per active run first. Pooling can wait until DB connection
1970
- lifetime and cancellation behavior are boring.
1971
-
1972
- 8. Backup integration.
1973
- - Teach backup to snapshot global and agent databases via SQLite backup or
1974
- `VACUUM INTO`. Done for discovered `*.sqlite` files under the state asset.
1975
- - Add backup verification for SQLite integrity and schema version. Done for
1976
- backup creation and default archive verification integrity checks.
1977
- - Record backup run metadata in SQLite. Done via the shared `backup_runs`
1978
- table with archive path, status, and manifest JSON.
1979
- - Add restore from verified archive snapshots. Done: `fengming backup
1980
- restore` validates before extraction, uses the verifier's normalized
1981
- manifest, supports `--dry-run`, and requires `--yes` before replacing
1982
- recorded source paths.
1983
- - Include VFS/workspace export only when requested; do not export session
1984
- internals as JSON or JSONL.
1985
-
1986
- 9. Delete obsolete tests and code. Done for the known runtime session surfaces.
1987
-
1988
- - Remove tests that assert runtime creation of `sessions.json` or transcript
1989
- JSONL files. Done for core session store, chat, gateway transcript events,
1990
- preview, lifecycle, command session-entry updates, auto-reply reset/trace, and
1991
- memory-core dreaming fixtures, approval target routing, session transcript
1992
- repair, security permission repair, trajectory export, and session export.
1993
- Active-memory transcript tests now assert SQLite scopes and no temporary or
1994
- persisted JSONL file creation.
1995
- The old heartbeat transcript-pruning regression was removed because
1996
- runtime no longer truncates JSONL transcripts.
1997
- Agent session-list tool tests no longer model legacy `sessions.json` paths
1998
- as the gateway response shape; app/UI/macOS tests use `databasePath`.
1999
- `/status` transcript-usage tests now seed SQLite transcript rows directly
2000
- instead of writing JSONL files.
2001
- Gateway session lifecycle tests now use SQLite transcript seeding helpers
2002
- directly; the old single-line session-file fixture shape is gone from reset
2003
- and delete coverage.
2004
- `sessions.delete` no longer returns a file-era `archived: []` field; deletion
2005
- reports only the row mutation result. The old `deleteTranscript` option is
2006
- gone too: deleting a session removes the canonical `sessions` root and lets
2007
- SQLite cascade session-owned transcript, snapshot, and trajectory rows, so no
2008
- caller can leave transcript orphans behind or forget a cleanup branch.
2009
- Context-engine trajectory capture tests now read `trajectory_runtime_events`
2010
- rows from an isolated agent database instead of reading
2011
- `session.trajectory.jsonl`.
2012
- Docker MCP channel seed scripts now seed SQLite rows directly. Direct
2013
- `sessions.json` writes are limited to doctor fixtures.
2014
- Tool Search Gateway E2E reads tool-call evidence from SQLite transcript rows
2015
- instead of scanning `agents/<agentId>/sessions/*.jsonl` files.
2016
- Memory-core host events and session-corpus scratch rows now live in shared
2017
- SQLite plugin-state; `events.jsonl` and `session-corpus/*.txt` are legacy
2018
- doctor migration inputs only. Active rows use `memory/session-ingestion/`
2019
- virtual paths, not `.dreams/session-corpus`. The old memory-core dreaming
2020
- repair module and its CLI/Gateway tests were removed because runtime no
2021
- longer owns file archive repair for that corpus. Memory-core
2022
- bridge/public-artifact tests no longer surface `.dreams/events.jsonl`; they
2023
- use the SQLite-backed virtual JSON artifact name.
2024
- Public SDK/Codex testing docs now say SQLite session state instead of session
2025
- files, and the channel-turn example no longer exposes a `storePath` argument.
2026
- Matrix sync state now uses the SQLite plugin-state store directly. Active
2027
- client/runtime contracts pass an account storage root, not a `bot-storage.json`
2028
- path, and doctor imports legacy `bot-storage.json` into SQLite before deleting
2029
- the source. QA Matrix restart/destructive scenarios now mutate the SQLite sync
2030
- row directly instead of creating or deleting fake `bot-storage.json` files, and
2031
- the E2EE substrate passes a sync-store root instead of a fake
2032
- `sync-store.json` path.
2033
- Matrix storage-root selection no longer scores roots by legacy sync/thread JSON
2034
- files; it uses durable root metadata plus real crypto state.
2035
- The runtime SQLite session backend test suite no longer fabricates a
2036
- `sessions.json`; legacy source fixtures now live in the doctor
2037
- tests that import them.
2038
- Gateway session tests no longer expose a `createSessionStoreDir` helper or
2039
- unused temp session-store path setup; fixture dirs are explicit, and direct
2040
- row setup uses SQLite session-row naming.
2041
- Doctor-only JSON5 session-store parser coverage moved out of infra tests and
2042
- into doctor migration tests, so runtime test suites no longer own legacy
2043
- session-file parsing.
2044
- Microsoft Teams runtime SSO/pending-upload tests no longer carry JSON sidecar
2045
- fixtures or parsers; legacy SSO token parsing lives only in the plugin
2046
- migration module. Telegram tests no longer seed fake `/tmp/*.json` store
2047
- paths; they reset the SQLite-backed message cache directly. The generic
2048
- FengMing test-state helper no longer exposes a legacy `auth-profiles.json`
2049
- writer; doctor auth migration tests own that fixture locally.
2050
- Runtime tests for TUI last-session pointers, exec approvals, active-memory
2051
- toggles, Matrix dedupe/startup verification, Memory Wiki source sync,
2052
- current-conversation bindings, onboarding auth, and Hermes secret imports no
2053
- longer manufacture old sidecar files or assert old filenames are absent. They
2054
- prove behavior through SQLite rows and public store APIs; doctor/migration
2055
- tests are the only place legacy source filenames belong.
2056
- Runtime tests for device/node pairing, channel allowFrom, restart intents,
2057
- restart handoff, session delivery queue entries, config health, iMessage
2058
- caches, cron jobs, PI transcript headers, subagent registries, and managed
2059
- image attachments also no longer create retired JSON/JSONL files just to prove
2060
- they are ignored or absent.
2061
- PI overflow recovery no longer has a SessionManager rewrite/truncation
2062
- fallback: tool-result truncation and context-engine transcript rewrites mutate
2063
- SQLite transcript rows, then refresh active prompt state from the database.
2064
- Persisted SessionManager message appends delegate to the atomic SQLite
2065
- transcript append helper for parent selection and idempotency. Normal
2066
- metadata/custom entry appends also select the current parent inside SQLite, so
2067
- stale manager instances do not resurrect pre-SQLite parent-chain races.
2068
- Synthetic PI tail cleanup for mid-turn prechecks and `sessions_yield` now
2069
- trims SQLite transcript state directly; the old SessionManager tail-removal
2070
- bridge and its tests are deleted.
2071
- Compaction checkpoint capture also snapshots from SQLite only; callers no
2072
- longer pass a live SessionManager as an alternate transcript source.
2073
- - Keep tests that seed legacy files only for migration.
2074
- - JSON-file proof has been replaced with SQL row proof for active runtime
2075
- surfaces.
2076
-
2077
- - Add static bans for runtime writes to legacy session/cache JSON paths.
2078
- Done for the repo guard.
2079
-
2080
- 10. Make the migration report auditable.
2081
- - Record migration runs in SQLite with started/finished timestamps, source
2082
- paths, source hashes, counts, warnings, and backup path.
2083
- Done: legacy-state migration executions now persist a `migration_runs`
2084
- report with source path/table inventory, source file SHA-256, sizes,
2085
- record counts, warnings, and backup path.
2086
- Done: legacy-state migration executions also persist `migration_sources`
2087
- rows for source-level audit and future skip/backfill decisions.
2088
- - Make apply idempotent. Re-running after a partial import should either
2089
- skip an already imported source or merge by stable key.
2090
- Done: session indexes, transcripts, delivery queues, plugin state, task
2091
- ledgers, and agent-owned global SQLite rows import through stable keys or
2092
- upsert/replace semantics, so reruns merge without duplicating durable
2093
- rows.
2094
- - Failed imports must keep the original source file in place.
2095
- Done: failed transcript imports now leave the original JSONL source at
2096
- its detected path, and `migration_sources` records the source as
2097
- `warning` with `removed_source=0` for the next doctor run.
2098
-
2099
- ## Performance Rules
2100
-
2101
- - One connection per thread/process is fine; do not share handles across
2102
- workers.
2103
- - Use WAL, `foreign_keys=ON`, a 30s busy timeout, and short `BEGIN IMMEDIATE`
2104
- write transactions.
2105
- - Keep write transaction helpers synchronous unless/until an async transaction
2106
- API adds explicit mutex/backpressure semantics.
2107
- - Keep parent delivery writes small and transactional.
2108
- - Avoid whole-store rewrites; use row-level upsert/delete.
2109
- - Add indexes for list-by-agent, list-by-session, updated-at, run id, and
2110
- expiration paths before moving hot code.
2111
- - Store large artifacts, media, and vectors as BLOBs or chunked BLOB rows, not
2112
- base64 or numeric-array JSON.
2113
- - Keep opaque plugin-state entries small and scoped.
2114
- - Add SQL cleanup for TTL/expiration instead of filesystem pruning.
2115
- Done for database-owned runtime stores: media, plugin state, plugin blobs,
2116
- persistent dedupe, and agent cache all expire through SQLite rows. Remaining
2117
- filesystem cleanup is limited to temporary materializations or explicit
2118
- removal commands.
2119
-
2120
- ## Static Bans
2121
-
2122
- Add a repo check that fails new runtime writes to legacy state paths:
2123
-
2124
- - `sessions.json`
2125
- - `*.trajectory.jsonl` except materialized support-bundle outputs
2126
- - `.acp-stream.jsonl`
2127
- - `acp/event-ledger.json`
2128
- - `cache/*.json` runtime cache files
2129
- - `agents/<agentId>/agent/auth.json`
2130
- - `agents/<agentId>/agent/models.json`
2131
- - `credentials/oauth.json`
2132
- - `github-copilot.token.json`
2133
- - `openrouter-models.json`
2134
- - `auth-profiles.json`
2135
- - `auth-state.json`
2136
- - `exec-approvals.json`
2137
- - `workspace-state.json`
2138
- - Matrix `credentials*.json` and `recovery-key.json`
2139
- - `cron/runs/*.jsonl`
2140
- - `cron/jobs.json`
2141
- - `jobs-state.json`
2142
- - `device-pair-notify.json`
2143
- - `devices/pending.json`
2144
- - `devices/paired.json`
2145
- - `devices/bootstrap.json`
2146
- - `nodes/pending.json`
2147
- - `nodes/paired.json`
2148
- - `identity/device.json`
2149
- - `identity/device-auth.json`
2150
- - `push/web-push-subscriptions.json`
2151
- - `push/vapid-keys.json`
2152
- - `push/apns-registrations.json`
2153
- - `process-leases.json`
2154
- - `gateway-instance-id`
2155
- - `session-toggles.json`
2156
- - Memory-core `.dreams/events.jsonl`
2157
- - Memory-core `.dreams/session-corpus/`
2158
- - Memory-core `.dreams/daily-ingestion.json`
2159
- - Memory-core `.dreams/session-ingestion.json`
2160
- - Memory-core `.dreams/short-term-recall.json`
2161
- - Memory-core `.dreams/phase-signals.json`
2162
- - Memory-core `.dreams/short-term-promotion.lock`
2163
- - Skill Workshop `skill-workshop/<workspace>.json`
2164
- - Skill Workshop `skill-workshop/skill-workshop-review-*.json`
2165
- - Nostr `bus-state-*.json`
2166
- - Nostr `profile-state-*.json`
2167
- - `calls.jsonl`
2168
- - `known-users.json`
2169
- - `ref-index.jsonl`
2170
- - QQBot `session-*.json`
2171
- - BlueBubbles `bluebubbles/catchup/*.json`
2172
- - BlueBubbles `bluebubbles/inbound-dedupe/*.json`
2173
- - Telegram `update-offset-*.json`
2174
- - Telegram `sticker-cache.json`
2175
- - Telegram `*.telegram-messages.json`
2176
- - Telegram `*.telegram-sent-messages.json`
2177
- - Telegram `*.telegram-topic-names.json`
2178
- - Telegram `thread-bindings-*.json`
2179
- - iMessage `catchup/*.json`
2180
- - iMessage `reply-cache.jsonl`
2181
- - iMessage `sent-echoes.jsonl`
2182
- - Microsoft Teams `msteams-conversations.json`
2183
- - Microsoft Teams `msteams-polls.json`
2184
- - Microsoft Teams `msteams-sso-tokens.json`
2185
- - Microsoft Teams `msteams-delegated.json`
2186
- - Microsoft Teams `msteams-pending-uploads.json`
2187
- - Microsoft Teams `*.learnings.json`
2188
- - Matrix `bot-storage.json`
2189
- - Matrix `sync-store.json`
2190
- - Matrix `thread-bindings.json`
2191
- - Matrix `inbound-dedupe.json`
2192
- - Matrix `startup-verification.json`
2193
- - Matrix `storage-meta.json`
2194
- - Matrix `crypto-idb-snapshot.json`
2195
- - Discord `model-picker-preferences.json`
2196
- - Discord `command-deploy-cache.json`
2197
- - sandbox registry shard JSON files
2198
- - native hook relay `/tmp` bridge JSON files
2199
- - `plugin-state/state.sqlite`
2200
- - ad-hoc `fengming-state.sqlite` runtime sidecars
2201
- - `tasks/runs.sqlite`
2202
- - `tasks/flows/registry.sqlite`
2203
- - `bindings/current-conversations.json`
2204
- - `restart-sentinel.json`
2205
- - `gateway-restart-intent.json`
2206
- - `gateway-supervisor-restart-handoff.json`
2207
- - `gateway.<hash>.lock`
2208
- - `qmd/embed.lock`
2209
- - `commands.log`
2210
- - `config-health.json`
2211
- - `port-guard.json`
2212
- - `settings/voicewake.json`
2213
- - `settings/voicewake-routing.json`
2214
- - `plugin-binding-approvals.json`
2215
- - `plugins/installs.json`
2216
- - `audit/file-transfer.jsonl`
2217
- - `audit/crestodian.jsonl`
2218
- - `crestodian/rescue-pending/*.json`
2219
- - `plugins/phone-control/armed.json`
2220
- - Memory Wiki `.fengming-wiki/log.jsonl`
2221
- - Memory Wiki `.fengming-wiki/state.json`
2222
- - Memory Wiki `.fengming-wiki/locks/`
2223
- - Memory Wiki `.fengming-wiki/source-sync.json`
2224
- - Memory Wiki `.fengming-wiki/import-runs/*.json`
2225
- - Memory Wiki `.fengming-wiki/cache/agent-digest.json`
2226
- - Memory Wiki `.fengming-wiki/cache/claims.jsonl`
2227
- - ClawHub `.clawhub/lock.json`
2228
- - ClawHub `.clawhub/origin.json`
2229
- - Browser profile decoration `.fengming-profile-decorated`
2230
- - `SessionManager.open(...)` file-backed session openers
2231
- - `SessionManager.listAll(...)` and `TranscriptSessionManager.listAll(...)`
2232
- transcript listing facades
2233
- - `SessionManager.forkFromSession(...)` and
2234
- `TranscriptSessionManager.forkFromSession(...)` transcript fork facades
2235
- - `SessionManager.newSession(...)` and `TranscriptSessionManager.newSession(...)`
2236
- mutable session replacement facades
2237
- - `SessionManager.createBranchedSession(...)` and
2238
- `TranscriptSessionManager.createBranchedSession(...)` branch-session facades
2239
-
2240
- The ban should allow tests to create legacy fixtures and allow migration code to
2241
- read/import/remove legacy file sources. Unshipped SQLite sidecars stay banned
2242
- and do not get doctor import allowances.
2243
-
2244
- ## Done Criteria
2245
-
2246
- - Runtime data and cache writes go to the global or agent SQLite database.
2247
- - Runtime no longer writes session indexes, transcript JSONL, sandbox registry
2248
- JSON, task sidecar SQLite, or plugin-state sidecar SQLite. The unshipped task
2249
- and plugin-state sidecar SQLite importers are deleted.
2250
- - Legacy file import is doctor-only.
2251
- - Backup produces one archive with compact SQLite snapshots and integrity proof.
2252
- - Agent workers can run with disk, VFS scratch, or experimental VFS-only
2253
- storage.
2254
- - Config and explicit credential files remain the only expected persistent
2255
- non-database control files.
2256
- - Repo checks prevent reintroducing legacy runtime file stores.