@aitne-sh/aitne 0.1.8 → 0.1.9

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 (276) hide show
  1. package/README.md +218 -161
  2. package/agent-assets/agent-profiles/_safety.md +3 -3
  3. package/agent-assets/agent-profiles/browser-task.md +108 -0
  4. package/agent-assets/agent-profiles/conversational.md +3 -3
  5. package/agent-assets/agent-profiles/profile-importer.md +2 -2
  6. package/agent-assets/agent-profiles/routine-fetch-window.md +30 -19
  7. package/agent-assets/agents/context-index-reconcile/agent.md +52 -0
  8. package/agent-assets/agents/evening-review/agent.md +53 -0
  9. package/agent-assets/agents/hourly-check/agent.md +62 -0
  10. package/agent-assets/agents/monthly-review/agent.md +55 -0
  11. package/agent-assets/agents/morning-routine/agent.md +78 -0
  12. package/agent-assets/agents/roadmap-maintenance/agent.md +52 -0
  13. package/agent-assets/agents/skill-curation/agent.md +52 -0
  14. package/agent-assets/agents/user-profile-sweep-evening/agent.md +48 -0
  15. package/agent-assets/agents/user-profile-sweep-morning/agent.md +53 -0
  16. package/agent-assets/agents/weekly-review/agent.md +51 -0
  17. package/agent-assets/docs/concepts/agent-day.md +13 -11
  18. package/agent-assets/docs/concepts/auth-health.md +47 -10
  19. package/agent-assets/docs/concepts/backends-and-tiers.md +66 -31
  20. package/agent-assets/docs/concepts/costs-and-quotas.md +50 -15
  21. package/agent-assets/docs/concepts/delegated-mode.md +52 -13
  22. package/agent-assets/docs/concepts/memory-model.md +72 -32
  23. package/agent-assets/docs/concepts/observations.md +49 -11
  24. package/agent-assets/docs/concepts/process-keys.md +56 -22
  25. package/agent-assets/docs/concepts/routines.md +60 -33
  26. package/agent-assets/docs/concepts/safety-and-execution.md +50 -21
  27. package/agent-assets/docs/concepts/safety-model.md +42 -34
  28. package/agent-assets/docs/concepts/skills.md +33 -17
  29. package/agent-assets/docs/features/integrations/browser-history.md +195 -0
  30. package/agent-assets/docs/features/integrations/calendar.md +39 -29
  31. package/agent-assets/docs/features/integrations/git.md +18 -7
  32. package/agent-assets/docs/features/integrations/github.md +84 -33
  33. package/agent-assets/docs/features/integrations/mail.md +59 -16
  34. package/agent-assets/docs/features/integrations/notion.md +18 -6
  35. package/agent-assets/docs/features/integrations/obsidian.md +28 -5
  36. package/agent-assets/docs/features/lifestyle/git.md +42 -38
  37. package/agent-assets/docs/features/lifestyle/reading.md +50 -22
  38. package/agent-assets/docs/features/lifestyle/receipts.md +51 -21
  39. package/agent-assets/docs/features/lifestyle/travel-bookings.md +76 -14
  40. package/agent-assets/docs/features/memory-files/agent-journal.md +111 -50
  41. package/agent-assets/docs/features/memory-files/projects.md +71 -17
  42. package/agent-assets/docs/features/memory-files/roadmap.md +50 -10
  43. package/agent-assets/docs/features/memory-files/schedule.md +113 -70
  44. package/agent-assets/docs/features/memory-files/today.md +46 -21
  45. package/agent-assets/docs/features/memory-files/user-profile.md +63 -33
  46. package/agent-assets/docs/features/messaging/bang-commands.md +113 -36
  47. package/agent-assets/docs/features/messaging/dashboard-chat.md +43 -21
  48. package/agent-assets/docs/features/messaging/discord.md +35 -4
  49. package/agent-assets/docs/features/messaging/overview.md +37 -19
  50. package/agent-assets/docs/features/messaging/pairing-and-magic-phrase.md +94 -27
  51. package/agent-assets/docs/features/messaging/slack.md +67 -14
  52. package/agent-assets/docs/features/messaging/telegram.md +18 -5
  53. package/agent-assets/docs/features/messaging/whatsapp.md +71 -17
  54. package/agent-assets/docs/features/operations/activity-and-conversations.md +44 -15
  55. package/agent-assets/docs/features/operations/approvals.md +48 -16
  56. package/agent-assets/docs/features/operations/backend-routing.md +68 -16
  57. package/agent-assets/docs/features/operations/cost-tracking.md +84 -17
  58. package/agent-assets/docs/features/operations/managed-chromium.md +221 -0
  59. package/agent-assets/docs/features/operations/notifications.md +52 -11
  60. package/agent-assets/docs/features/operations/quiet-hours.md +63 -40
  61. package/agent-assets/docs/features/operations/schedule-approaching.md +54 -24
  62. package/agent-assets/docs/features/routines/custom-routines.md +88 -20
  63. package/agent-assets/docs/features/routines/evening-review.md +74 -21
  64. package/agent-assets/docs/features/routines/hourly-check.md +149 -29
  65. package/agent-assets/docs/features/routines/morning-routine.md +53 -35
  66. package/agent-assets/docs/features/routines/weekly-review.md +40 -21
  67. package/agent-assets/docs/features/wiki/commands.md +26 -16
  68. package/agent-assets/docs/features/wiki/cost-and-approval.md +240 -0
  69. package/agent-assets/docs/features/wiki/dashboard.md +255 -0
  70. package/agent-assets/docs/features/wiki/overview.md +68 -10
  71. package/agent-assets/docs/features/wiki/search.md +248 -0
  72. package/agent-assets/docs/features/wiki/workspaces.md +254 -0
  73. package/agent-assets/docs/getting-started/01-what-is-this.md +34 -23
  74. package/agent-assets/docs/getting-started/02-first-steps.md +13 -8
  75. package/agent-assets/docs/getting-started/03-what-can-this-do.md +25 -14
  76. package/agent-assets/docs/getting-started/04-first-day.md +38 -20
  77. package/agent-assets/docs/glossary.md +235 -24
  78. package/agent-assets/docs/guides/add-a-custom-routine.md +63 -23
  79. package/agent-assets/docs/guides/backup-and-restore.md +80 -16
  80. package/agent-assets/docs/guides/budget-and-cost-for-wiki.md +56 -25
  81. package/agent-assets/docs/guides/build-your-wiki.md +22 -9
  82. package/agent-assets/docs/guides/change-which-model-handles-x.md +64 -10
  83. package/agent-assets/docs/guides/connect-a-new-mail-account.md +64 -15
  84. package/agent-assets/docs/guides/explore-with-trace-and-connect.md +28 -11
  85. package/agent-assets/docs/guides/import-knowledge-file.md +50 -40
  86. package/agent-assets/docs/guides/install-and-run.md +48 -19
  87. package/agent-assets/docs/guides/maintain-wiki-health.md +35 -10
  88. package/agent-assets/docs/guides/migrate-machines.md +74 -18
  89. package/agent-assets/docs/guides/multiple-wikis-for-multiple-domains.md +111 -60
  90. package/agent-assets/docs/guides/pause-the-agent.md +65 -24
  91. package/agent-assets/docs/guides/reinstall-cleanly.md +88 -18
  92. package/agent-assets/docs/guides/setup-wizard.md +113 -54
  93. package/agent-assets/docs/guides/switch-default-backend.md +62 -16
  94. package/agent-assets/docs/guides/use-an-existing-obsidian-vault.md +26 -10
  95. package/agent-assets/docs/reference/api.md +143 -32
  96. package/agent-assets/docs/reference/cli-commands.md +38 -17
  97. package/agent-assets/docs/reference/config.md +224 -49
  98. package/agent-assets/docs/reference/disallowed-tools.md +29 -10
  99. package/agent-assets/docs/reference/keyboard-shortcuts.md +34 -10
  100. package/agent-assets/docs/reference/knowledge-layout.md +620 -0
  101. package/agent-assets/docs/reference/process-keys.md +61 -5
  102. package/agent-assets/docs/reference/skills.md +38 -12
  103. package/agent-assets/docs/troubleshooting/auth-failed.md +48 -19
  104. package/agent-assets/docs/troubleshooting/dashboard-shows-degraded.md +90 -28
  105. package/agent-assets/docs/troubleshooting/fallback-keeps-firing.md +86 -22
  106. package/agent-assets/docs/troubleshooting/messaging-not-pairing.md +68 -24
  107. package/agent-assets/docs/troubleshooting/morning-routine-didnt-run.md +80 -20
  108. package/agent-assets/docs/troubleshooting/observation-not-detected.md +73 -21
  109. package/agent-assets/docs/troubleshooting/quota-exhausted.md +29 -5
  110. package/agent-assets/docs/troubleshooting/wiki-ingest-full-blocked.md +126 -54
  111. package/agent-assets/docs/troubleshooting/wiki-write-failed.md +29 -12
  112. package/agent-assets/optimizer-skills/drift-analysis/SKILL.md +1 -1
  113. package/agent-assets/optimizer-skills/knowledge-map/SKILL.md +1 -1
  114. package/agent-assets/optimizer-skills/skill-curation/SKILL.md +1 -1
  115. package/agent-assets/sandbox/linux/aitne-chromium.apparmor +91 -0
  116. package/agent-assets/sandbox/macos/aitne-chromium.sb +156 -0
  117. package/agent-assets/skills/agent-actions/SKILL.md +2 -2
  118. package/agent-assets/skills/agent-create/SKILL.md +149 -0
  119. package/agent-assets/skills/attach/SKILL.md +2 -2
  120. package/agent-assets/skills/browser-history/SKILL.md +198 -0
  121. package/agent-assets/skills/browser-history-respond/SKILL.md +106 -0
  122. package/agent-assets/skills/browser-task/SKILL.md +169 -0
  123. package/agent-assets/skills/context/SKILL.md +12 -12
  124. package/agent-assets/skills/context/curation.json +2 -2
  125. package/agent-assets/skills/context/references/api.md +43 -31
  126. package/agent-assets/skills/context/references/required-frontmatter.md +3 -3
  127. package/agent-assets/skills/context/references/snapshot-files.md +6 -6
  128. package/agent-assets/skills/context/seeds/file-responsibilities.seed.json +3 -3
  129. package/agent-assets/skills/docs-search/SKILL.md +4 -3
  130. package/agent-assets/skills/external-services/SKILL.delegated.claude.md +11 -21
  131. package/agent-assets/skills/external-services/SKILL.delegated.codex.md +11 -21
  132. package/agent-assets/skills/external-services/SKILL.delegated.gemini.md +11 -21
  133. package/agent-assets/skills/external-services/SKILL.md +3 -3
  134. package/agent-assets/skills/external-services/SKILL.native.claude.md +5 -5
  135. package/agent-assets/skills/external-services/SKILL.native.codex.md +7 -7
  136. package/agent-assets/skills/external-services/SKILL.native.gemini.md +4 -4
  137. package/agent-assets/skills/external-services/references/calendar-apple.md +2 -2
  138. package/agent-assets/skills/external-services/references/calendar-outlook.md +1 -1
  139. package/agent-assets/skills/external-services/references/obsidian.md +2 -2
  140. package/agent-assets/skills/gmail-lifestyle/SKILL.md +9 -82
  141. package/agent-assets/skills/mail/SKILL.delegated.claude.md +14 -5
  142. package/agent-assets/skills/mail/SKILL.delegated.codex.md +8 -4
  143. package/agent-assets/skills/mail/SKILL.delegated.gemini.md +8 -4
  144. package/agent-assets/skills/mail/references/api.md +4 -2
  145. package/agent-assets/skills/mail/references/providers.md +1 -1
  146. package/agent-assets/skills/managed-tasks/SKILL.md +9 -9
  147. package/agent-assets/skills/managed-tasks/references/errors.md +9 -6
  148. package/agent-assets/skills/managed-tasks/references/recurrence-rule.md +1 -1
  149. package/agent-assets/skills/management-policy/SKILL.md +32 -31
  150. package/agent-assets/skills/management-policy/curation.json +1 -1
  151. package/agent-assets/skills/management-policy/references/policy-workflow.md +9 -9
  152. package/agent-assets/skills/management-policy/seeds/policy-file-shape.seed.json +1 -1
  153. package/agent-assets/skills/notify/SKILL.md +4 -4
  154. package/agent-assets/skills/notify/references/priority.md +9 -4
  155. package/agent-assets/skills/notion/SKILL.delegated.claude.md +1 -1
  156. package/agent-assets/skills/notion/SKILL.delegated.codex.md +1 -1
  157. package/agent-assets/skills/notion/SKILL.delegated.gemini.md +1 -1
  158. package/agent-assets/skills/notion/SKILL.native.claude.md +10 -6
  159. package/agent-assets/skills/notion/SKILL.native.codex.md +9 -4
  160. package/agent-assets/skills/notion/SKILL.native.gemini.md +9 -4
  161. package/agent-assets/skills/observations/SKILL.md +24 -8
  162. package/agent-assets/skills/project-doc/SKILL.md +1 -1
  163. package/agent-assets/skills/project-doc/curation.json +3 -3
  164. package/agent-assets/skills/project-doc/seeds/project-shape.seed.json +7 -4
  165. package/agent-assets/skills/project-doc/seeds/slug-grammar.seed.json +3 -3
  166. package/agent-assets/skills/reading/SKILL.md +10 -0
  167. package/agent-assets/skills/reading/references/reading-taste.md +2 -2
  168. package/agent-assets/skills/roadmap/SKILL.md +5 -5
  169. package/agent-assets/skills/roadmap/curation.json +1 -1
  170. package/agent-assets/skills/roadmap/references/api.md +7 -7
  171. package/agent-assets/skills/roadmap/references/cross-check.md +15 -8
  172. package/agent-assets/skills/roadmap/references/migration.md +4 -4
  173. package/agent-assets/skills/roadmap/seeds/entry-types.seed.json +1 -1
  174. package/agent-assets/skills/schedule/SKILL.md +42 -34
  175. package/agent-assets/skills/schedule/references/batch.md +2 -2
  176. package/agent-assets/skills/schedule/references/errors.md +7 -4
  177. package/agent-assets/skills/schedule/references/model-selection.md +3 -3
  178. package/agent-assets/skills/schedule/references/recurrence-rule.md +1 -1
  179. package/agent-assets/skills/scheduled-managed-task/SKILL.md +46 -36
  180. package/agent-assets/skills/today/SKILL.md +9 -9
  181. package/agent-assets/skills/today/curation.json +3 -3
  182. package/agent-assets/skills/today/references/agent-plan-lifecycle.md +6 -5
  183. package/agent-assets/skills/today/seeds/section-shape.seed.json +1 -1
  184. package/agent-assets/skills/user-interview/SKILL.md +12 -9
  185. package/agent-assets/skills/user-interview/references/op-briefing.md +2 -2
  186. package/agent-assets/skills/user-interview/references/sweep-and-fallback.md +8 -0
  187. package/agent-assets/skills/user-profile/SKILL.md +17 -17
  188. package/agent-assets/skills/user-profile/curation.json +2 -2
  189. package/agent-assets/skills/user-profile/references/character-preferences.md +2 -2
  190. package/agent-assets/skills/user-profile/seeds/routing-table.seed.json +8 -8
  191. package/agent-assets/skills/user-profile/seeds/topic-files.seed.json +6 -6
  192. package/agent-assets/skills/wiki/wiki-compile/SKILL.md +4 -4
  193. package/agent-assets/system-prompts/routine-fetch-window.md +22 -12
  194. package/agent-assets/task-flows/_partials/calendar-acquire.google_calendar.md +4 -2
  195. package/agent-assets/task-flows/_partials/calendar-acquire.outlook_calendar.md +4 -2
  196. package/agent-assets/task-flows/_partials/capture-user-info.md +2 -2
  197. package/agent-assets/task-flows/_partials/dm-intent.long-horizon.md +1 -1
  198. package/agent-assets/task-flows/_partials/dm-intent.project.md +9 -9
  199. package/agent-assets/task-flows/_partials/mail-acquire.outlook_mail.md +3 -2
  200. package/agent-assets/task-flows/_partials/notion-acquire.notion.md +10 -5
  201. package/agent-assets/task-flows/browser_task.md +84 -0
  202. package/agent-assets/task-flows/github.assigned.md +1 -1
  203. package/agent-assets/task-flows/github.pull_request.review_requested.md +2 -2
  204. package/agent-assets/task-flows/github.workflow_run.failed.md +2 -2
  205. package/agent-assets/task-flows/knowledge.import.md +14 -14
  206. package/agent-assets/task-flows/message.received.dm.md +9 -4
  207. package/agent-assets/task-flows/message.received.dm_first.md +3 -3
  208. package/agent-assets/task-flows/routine.custom.md +3 -3
  209. package/agent-assets/task-flows/routine.evening_review.md +8 -8
  210. package/agent-assets/task-flows/routine.fetch_window.md +2 -2
  211. package/agent-assets/task-flows/routine.hourly_check.md +16 -12
  212. package/agent-assets/task-flows/routine.monthly_review.md +21 -21
  213. package/agent-assets/task-flows/routine.morning_routine_journal.md +119 -97
  214. package/agent-assets/task-flows/routine.morning_routine_today.md +43 -43
  215. package/agent-assets/task-flows/routine.research_cluster_update.md +35 -0
  216. package/agent-assets/task-flows/routine.research_dispatch.md +38 -0
  217. package/agent-assets/task-flows/routine.research_offer_dm.md +125 -0
  218. package/agent-assets/task-flows/routine.research_wiki_summary.md +53 -0
  219. package/agent-assets/task-flows/routine.roadmap_refresh.md +10 -10
  220. package/agent-assets/task-flows/routine.today_refresh.md +4 -4
  221. package/agent-assets/task-flows/routine.user_profile_sweep.md +10 -10
  222. package/agent-assets/task-flows/routine.weekly_review.md +93 -24
  223. package/agent-assets/task-flows/schedule.approaching.md +0 -1
  224. package/agent-assets/task-flows/scheduled.dm.md +5 -5
  225. package/agent-assets/task-flows/scheduled.task.md +4 -4
  226. package/agent-assets/task-flows/setup.initial.md +21 -21
  227. package/agent-assets/task-flows/setup.update.md +2 -2
  228. package/agent-assets/templates/README.md +27 -20
  229. package/agent-assets/templates/_index.md +42 -26
  230. package/agent-assets/templates/_manifest.json +34 -99
  231. package/agent-assets/templates/{user → identity}/_index.md +1 -1
  232. package/agent-assets/templates/{user → identity}/profile.md +2 -2
  233. package/agent-assets/templates/{dossiers → knowledge/dossiers}/_index.md +1 -1
  234. package/agent-assets/templates/{projects → plans/projects}/_active.base +1 -1
  235. package/agent-assets/templates/policies/_index.md +21 -0
  236. package/agent-assets/templates/{rules → policies}/journal-export.md +1 -1
  237. package/agent-assets/templates/{rules → policies}/journal-format.md +5 -5
  238. package/agent-assets/templates/{rules/policies → policies/management-captures}/_index.md +2 -2
  239. package/agent-assets/templates/{rules → policies}/management.md +3 -3
  240. package/agent-assets/templates/{rules → policies}/mcp.md +1 -1
  241. package/agent-assets/templates/{rules → policies}/redaction.md +1 -1
  242. package/agent-assets/templates/{routines → policies/routines}/_index.md +1 -1
  243. package/agent-assets/templates/{routines → policies/routines}/evening.md +2 -2
  244. package/agent-assets/templates/{routines → policies/routines}/hourly.md +1 -1
  245. package/agent-assets/templates/{routines → policies/routines}/monthly.md +2 -2
  246. package/bin/aitne.mjs +13 -4
  247. package/package.json +5 -4
  248. package/scripts/commands/doctor.mjs +14 -8
  249. package/scripts/commands/run-now.mjs +6 -21
  250. package/scripts/lib/ports.d.mts +27 -0
  251. package/scripts/lib/ports.mjs +36 -0
  252. package/scripts/lib/read-api-token.mjs +176 -0
  253. package/scripts/start.mjs +2 -1
  254. package/agent-assets/docs/features/lifestyle/travel-time.md +0 -58
  255. package/agent-assets/skills/gmail-lifestyle/references/travel-time-api.md +0 -59
  256. package/agent-assets/skills/schedule/references/recurring.md +0 -185
  257. package/agent-assets/templates/context-index.md +0 -42
  258. package/agent-assets/templates/rules/_index.md +0 -19
  259. /package/agent-assets/templates/{user → identity}/expertise.md +0 -0
  260. /package/agent-assets/templates/{user → identity}/goals.md +0 -0
  261. /package/agent-assets/templates/{user → identity}/people.md +0 -0
  262. /package/agent-assets/templates/{user → identity}/personal.md +0 -0
  263. /package/agent-assets/templates/{user → identity}/work.md +0 -0
  264. /package/agent-assets/templates/{agent/journal.md → journal/agent.md} +0 -0
  265. /package/agent-assets/templates/{dossiers → knowledge/dossiers}/evening.md +0 -0
  266. /package/agent-assets/templates/{dossiers → knowledge/dossiers}/hourly.md +0 -0
  267. /package/agent-assets/templates/{dossiers → knowledge/dossiers}/monthly.md +0 -0
  268. /package/agent-assets/templates/{dossiers → knowledge/dossiers}/morning.md +0 -0
  269. /package/agent-assets/templates/{dossiers → knowledge/dossiers}/roadmap.md +0 -0
  270. /package/agent-assets/templates/{dossiers → knowledge/dossiers}/weekly.md +0 -0
  271. /package/agent-assets/templates/{projects → plans/projects}/_index.md +0 -0
  272. /package/agent-assets/templates/{roadmap.md → plans/roadmap.md} +0 -0
  273. /package/agent-assets/templates/{routines → policies/routines}/morning.md +0 -0
  274. /package/agent-assets/templates/{routines → policies/routines}/weekly.md +0 -0
  275. /package/agent-assets/templates/{agent → state}/profile-questions.md +0 -0
  276. /package/agent-assets/templates/{today.md → state/today.md} +0 -0
@@ -22,7 +22,7 @@ context. Other flows (DM handler, evening sweeper) may acquire and
22
22
  release manually.
23
23
 
24
24
  Include `X-Lock-Id: <roadmap_write_lock_id>` on every PUT / PATCH to
25
- `/api/context/roadmap` when the tag is in your context. Other
25
+ `/api/context/plans/roadmap` when the tag is in your context. Other
26
26
  sessions get `409 roadmap_write_lock_held` while the lock is held —
27
27
  back off 30 s and retry up to 3 times.
28
28
 
@@ -31,18 +31,18 @@ back off 30 s and retry up to 3 times.
31
31
  These return `404 {"error":"unknown_route", …}` with a hint pointing
32
32
  at the correct path:
33
33
 
34
- - `POST /api/context/roadmap/lock` — order reversed
35
- - `POST /api/context/roadmap/write-lock` — order reversed and wrong noun
34
+ - `POST /api/context/plans/roadmap/lock` — order reversed
35
+ - `POST /api/context/plans/roadmap/write-lock` — order reversed and wrong noun
36
36
  - `POST /api/context/lock/roadmap-write` — wrong noun
37
37
 
38
38
  A `401 {"error":"unauthorized"}` from a path you believe is correct
39
39
  means the path is still wrong (the lock endpoints are Autonomous-tier
40
40
  so no bearer token is required).
41
41
 
42
- ## ID mint — `POST /api/context/roadmap/id`
42
+ ## ID mint — `POST /api/context/plans/roadmap/id`
43
43
 
44
44
  ```bash
45
- curl -s -X POST http://localhost:8321/api/context/roadmap/id \
45
+ curl -s -X POST http://localhost:8321/api/context/plans/roadmap/id \
46
46
  -H 'Content-Type: application/json' \
47
47
  -H 'X-Lock-Id: <roadmap_write_lock_id>' \
48
48
  -d '{"creationDate":"YYYY-MM-DD"}'
@@ -64,7 +64,7 @@ The roadmap API validates two invariants on every PUT / PATCH:
64
64
  file. Duplicate ids return:
65
65
 
66
66
  ```json
67
- {"error":"validation_error","message":"duplicate roadmap id rm-YYYYMMDD-abcdef","path":"roadmap.md"}
67
+ {"error":"validation_error","message":"duplicate roadmap id rm-YYYYMMDD-abcdef","path":"plans/roadmap.md"}
68
68
  ```
69
69
 
70
70
  Recovery: re-GET `roadmap`, mint a fresh id **for the colliding
@@ -78,7 +78,7 @@ The roadmap API validates two invariants on every PUT / PATCH:
78
78
  row returns:
79
79
 
80
80
  ```json
81
- {"error":"validation_error","message":"transition_guard: completed row for rm-… changed","path":"roadmap.md"}
81
+ {"error":"validation_error","message":"transition_guard: completed row for rm-… changed","path":"plans/roadmap.md"}
82
82
  ```
83
83
 
84
84
  This is intentional: completed prep rows are the audit trail for
@@ -25,14 +25,21 @@ Response shape (one row per booking):
25
25
  {
26
26
  "bookings": [
27
27
  {
28
- "kind": "flight" | "hotel" | "rail" | "other",
29
- "depart_at": "ISO8601 with tz",
30
- "return_at": "ISO8601 with tz | null",
28
+ "id": "<int>",
29
+ "type": "flight" | "hotel" | "restaurant" | "train" | "bus" | "other",
30
+ "provider": "<string>",
31
31
  "destination": "city / airport / property name",
32
- "confirmation_number": "<string>",
33
- "source": "gmail" | "manual" | "ical"
32
+ "startDate": "ISO8601 | YYYY-MM-DD | null",
33
+ "endDate": "ISO8601 | YYYY-MM-DD | null",
34
+ "confirmationNumber": "<string | null>",
35
+ "amount": "<number | null>",
36
+ "currency": "<string | null>",
37
+ "status": "upcoming",
38
+ "providerMsgId": "<string | null>",
39
+ "createdAt": "ISO8601"
34
40
  }
35
- ]
41
+ ],
42
+ "total": "<int>"
36
43
  }
37
44
  ```
38
45
 
@@ -43,7 +50,7 @@ A booking matches a roadmap event entry when **either**:
43
50
  - The booking's `destination` substring-matches the event entry's
44
51
  `Destination:` field (case-insensitive, after stripping common
45
52
  prefixes / suffixes — "Paris" matches "Paris, FR" and "Paris CDG").
46
- - The booking's `depart_at` date falls within the event entry's
53
+ - The booking's `startDate` date falls within the event entry's
47
54
  `YYYY-MM-DD ~ MM-DD` header range (inclusive on both ends).
48
55
 
49
56
  When a match is found:
@@ -54,7 +61,7 @@ When a match is found:
54
61
  <YYYY-MM-DD> confirmation #<conf>`), preserving the original
55
62
  `[tag]` and date.
56
63
  3. Append a line to the entry's `**Agent Notes:**` block:
57
- `- Booking confirmed (<kind>) — #<confirmation_number>`.
64
+ `- Booking confirmed (<type>) — #<confirmationNumber>`.
58
65
 
59
66
  ## When no match exists
60
67
 
@@ -4,7 +4,7 @@ name: migration
4
4
  description: Section auto-ensure recipe for legacy roadmaps missing ## Long-term Plans. PATCH-driven; full-file PUT writers (refresh routine) do not need this.
5
5
  ---
6
6
 
7
- # Section auto-ensure — legacy `roadmap.md` files
7
+ # Section auto-ensure — legacy `plans/roadmap.md` files
8
8
 
9
9
  Roadmaps created before the `## Long-term Plans` section was
10
10
  introduced may be missing that header. A direct
@@ -24,19 +24,19 @@ they never trigger `section_not_found` and never need this recipe.
24
24
 
25
25
  ```bash
26
26
  # 1. Read the file
27
- curl -s http://localhost:8321/api/context/roadmap
27
+ curl -s http://localhost:8321/api/context/plans/roadmap
28
28
 
29
29
  # 2. Inspect the body for "## Long-term Plans". If present, skip the
30
30
  # insert and go straight to the normal PATCH below.
31
31
 
32
32
  # 3. Absent → insert it after "## Quarterly Focus":
33
- curl -s -X PATCH http://localhost:8321/api/context/roadmap \
33
+ curl -s -X PATCH http://localhost:8321/api/context/plans/roadmap \
34
34
  -H 'Content-Type: application/json' \
35
35
  -H 'X-Lock-Id: <roadmap_write_lock_id>' \
36
36
  -d '{"section": "quarterly_focus", "mode": "append", "content": "\n## Long-term Plans\n"}'
37
37
 
38
38
  # 4. Then PATCH long_term_plans normally
39
- curl -s -X PATCH http://localhost:8321/api/context/roadmap \
39
+ curl -s -X PATCH http://localhost:8321/api/context/plans/roadmap \
40
40
  -H 'Content-Type: application/json' \
41
41
  -H 'X-Lock-Id: <roadmap_write_lock_id>' \
42
42
  -d '{"section": "long_term_plans", "mode": "append", "content": "- [undated] …"}'
@@ -2,7 +2,7 @@
2
2
  "kind": "knowledge_layout",
3
3
  "files": [
4
4
  {
5
- "path": "roadmap.md",
5
+ "path": "plans/roadmap.md",
6
6
  "purpose": "Long-horizon user intent: goals, focus, plans, scheduled tasks, and recurring entries",
7
7
  "sections": [
8
8
  { "heading": "## Annual Goals", "contains": "user-authored yearly goals preserved verbatim" },
@@ -31,9 +31,10 @@ user but compound into duplicate DMs/notifications at fire time.
31
31
  PATCH the existing item if it needs updating — never register a
32
32
  parallel second one).
33
33
  3. **Recurring check.** `GET /api/recurring-schedules?enabled=true` to
34
- confirm no recurring rule already covers this cadence (e.g. a daily
35
- 09:00 inbox triage). If covered, skip — the recurring instance will
36
- regenerate on its own.
34
+ confirm no recurring rule/Agent already covers this cadence (e.g. a
35
+ daily 09:00 inbox triage, or the morning briefing). If covered, skip.
36
+ (Recurring *work* is created as an Agent via the `agent-create` skill;
37
+ recurring *DMs* via `POST /api/recurring-schedules` `taskType:dm_session`.)
37
38
  4. **`confirm_dedup_key` check (mandatory for `confirm:` sub-flow rows
38
39
  only).** When scheduling a `dm_session` row with
39
40
  `taskContext.sub_flow="confirm"`, run the dedup pre-check + shape
@@ -54,11 +55,14 @@ If the request expresses an **ongoing management practice** with a
54
55
  recorded reason — "every morning, run my finance app and log the
55
56
  balance to a finance dossier", "from now on whenever X happens, do
56
57
  Y" — switch to the `management-policy` skill instead. It creates a
57
- `rules/policies/<slug>.md` that captures the WHY alongside the cadence
58
- (via `routines/custom/<slug>.md`) so the rule survives a context
59
- reset. Plain recurring schedules via `/api/recurring-schedules` are
60
- still right when the cadence is all that matters and there is no need
61
- to record intent.
58
+ `policies/management-captures/<slug>.md` that captures the WHY alongside the cadence
59
+ (via `policies/routines/custom/<slug>.md`) so the rule survives a context
60
+ reset. When the cadence is all that matters and there is no intent to
61
+ record: recurring autonomous **work** create a **recurring Agent** via
62
+ the `agent-create` skill (`POST /api/agents`); recurring scheduled
63
+ **DM / briefing** → `POST /api/recurring-schedules` with
64
+ `taskType: "dm_session"`. (Creating a recurring `agent.task` row directly
65
+ on `/api/recurring-schedules` is **410 Gone** — use an Agent.)
62
66
 
63
67
  ## DM vs Agent Task
64
68
 
@@ -71,11 +75,11 @@ to record intent.
71
75
 
72
76
  **Default to DM** when possible. Every agent wake-up costs money and context.
73
77
 
74
- ## Writing a Good Description (for agent tasks)
78
+ ## Writing a Good Prompt (for agent tasks)
75
79
 
76
- > **The wake-up agent has NO memory of why it was scheduled.** It receives only: `today.md`, a fresh 1-day calendar, `user/profile.md` + `rules/management.md`, and the `description` + `taskContext` fields you provide. Nothing else.
80
+ > **The wake-up agent has NO memory of why it was scheduled.** It receives only: `state/today.md`, a fresh 1-day calendar, `identity/profile.md` + `policies/management.md`, and the `prompt` + `taskContext` fields you provide. Nothing else. (`description` is just an optional list label — never the agent body.)
77
81
 
78
- Include all four elements:
82
+ Include all four elements in the `prompt`:
79
83
 
80
84
  | Element | What it answers |
81
85
  |---|---|
@@ -89,13 +93,13 @@ Include all four elements:
89
93
  **Bad:** `"Meeting prep"` — which meeting? when? what to prepare?
90
94
 
91
95
  ## Using `taskContext`
92
- Structured metadata for IDs, URLs, and correlation. Put long identifiers here so `description` stays under ~2 sentences:
96
+ Structured metadata for IDs, URLs, and correlation. Put long identifiers here so the `prompt` stays focused:
93
97
  ```json
94
98
  { "scheduledBy": "morning_routine", "prUrl": "https://github.com/user/repo/pull/42" }
95
99
  ```
96
100
 
97
101
  **`importance` convention.** This controls whether `agent_schedule`
98
- rows become `roadmap.md` `Scheduled:` entries:
102
+ rows become `plans/roadmap.md` `Scheduled:` entries:
99
103
 
100
104
  | Tier | Roadmap behavior | Use |
101
105
  |---|---|---|
@@ -149,16 +153,16 @@ Response: `{ "status":"scheduled", "scheduleId":"123", "scheduledFor":"..." }`.
149
153
  ```bash
150
154
  curl -s -X POST http://localhost:8321/api/schedule \
151
155
  -H 'Content-Type: application/json' \
152
- -d '{"time":"2026-04-06T16:00:00-04:00","taskType":"wake","description":"Hourly docker health check: run `docker ps --format` and DM if any container is in restart loop.","tier":"lite","taskContext":{"scheduledBy":"docker_monitor"}}'
156
+ -d '{"time":"2026-04-06T16:00:00-04:00","taskType":"wake","prompt":"Hourly docker health check: run `docker ps --format` and DM if any container is in restart loop.","description":"Docker health check","tier":"lite","taskContext":{"scheduledBy":"docker_monitor"}}'
153
157
  ```
154
158
  | Field | Required | Description |
155
159
  |---|---|---|
156
160
  | `time` | Yes | ISO 8601 with timezone offset |
157
- | `taskType` | Yes | `wake` for scheduled tasks |
158
- | `description` | Yes | Self-contained (min 20 chars). See format above. Doubles as the agent body unless `prompt` overrides it. |
159
- | `prompt` | No | Optional override for the agent body (min 20 chars when set). When set, the dispatcher injects this not `description` into the task-flow template. Use when you want a short list-friendly `description` plus a longer, separate instruction for the agent. |
161
+ | `taskType` | Yes | Free-form provenance label for the row (no allowlist on the single endpoint). Use `wake` for an agent wake-up — the convention this skill follows. The closed set `wake`/`dm_session`/`check`/`dm` is enforced only on `/api/schedule/batch`; e.g. the dashboard's manual "+ New task" sends `custom`. The label does not change firing — the scheduler runs every non-`dm`/`dm_session`/`browser_task` row as a generic `scheduled.task`. |
162
+ | `prompt` | Yes | The agent's instruction at fire time — its ONLY context (the session has no memory). Self-contained: what + why + who + expected output. See format above. Max 8000 chars (~2000 tokens); move bulk reference material into a file the agent reads at fire time rather than inlining it. |
163
+ | `description` | No | Optional short label shown in the schedule list (max 200 chars). NOT the agent bodythat is `prompt`. Omit it and the list shows a `prompt` excerpt. |
160
164
  | `tier` | No | `lite` / `medium` / `high`. Omit to use the dispatcher's process-key default (medium for `scheduled.task`). See "Tier / Model selection" above. Mutually exclusive with `model`. |
161
- | `model` | No | Registered model id (`claude-opus-4-7`, `gpt-5.4`, …), legacy alias (`sonnet` / `opus`, auto-rewritten to `tier`), or composite `<backendId>/<modelId>`. See "Tier / Model selection" above. Mutually exclusive with `tier`. |
165
+ | `model` | No | Registered model id (`claude-opus-4-8`, `gpt-5.4`, …), legacy alias (`sonnet` / `opus`, auto-rewritten to `tier`), or composite `<backendId>/<modelId>`. See "Tier / Model selection" above. Mutually exclusive with `tier`. |
162
166
  | `taskContext` | No | Structured metadata object |
163
167
 
164
168
  Response: `{ "status":"scheduled", "scheduleId":"123", "scheduledFor":"YYYY-MM-DD HH:MM:SS" }`. `scheduledFor` is the normalized UTC SQLite timestamp the daemon actually stored — log this verbatim instead of re-formatting the input `time`. Rejects times in the past (> 1 min ago), same as `/api/schedule/dm`.
@@ -169,7 +173,7 @@ curl -s -X PATCH http://localhost:8321/api/schedule/42 \
169
173
  -H 'Content-Type: application/json' \
170
174
  -d '{"time":"2026-04-06T17:00:00-04:00"}'
171
175
  ```
172
- Fields: `time` (ISO 8601), `description` (min 20 chars, non-dm only), `prompt` (min 20 chars OR `null` to clear; non-dm only), `message` (dm only), `tier` (`lite`/`medium`/`high` OR `null` to clear), `model` (registered id / alias / composite OR `null` to clear), `taskContext`. At least one required. Only `pending` items editable. `description`/`message` mutually exclusive; `prompt`/`message` mutually exclusive. Tier ↔ model swap form is in the model-selection reference above. Response: `{ "status":"updated", "id":42, "warnings":[] }` / 404 / 409 — surface `warnings[]` (e.g. `schedule.model_deprecated`) to the next turn.
176
+ Fields: `time` (ISO 8601), `prompt` (the agent instruction, ≤8000 chars, non-dm only, OR `null` to clear on a legacy row), `description` (optional label ≤200 chars, non-dm only), `message` (dm only), `tier` (`lite`/`medium`/`high` OR `null` to clear), `model` (registered id / alias / composite OR `null` to clear), `taskContext`. At least one required. Only `pending` items editable. `description`/`message` mutually exclusive; `prompt`/`message` mutually exclusive. Tier ↔ model swap form is in the model-selection reference above. Response: `{ "status":"updated", "id":42, "warnings":[] }` / 404 / 409 — surface `warnings[]` (e.g. `schedule.model_deprecated`) to the next turn.
173
177
 
174
178
  ### GET /api/schedule — List scheduled items
175
179
  ```bash
@@ -210,24 +214,28 @@ model, batch) are in the errors reference below.
210
214
 
211
215
  ---
212
216
 
213
- ## Recurring Schedules
217
+ ## Recurring: work → Agent; DM → dm_session
214
218
 
215
- For tasks that repeat on a fixed pattern. The daemon auto-regenerates
216
- the next one-shot occurrence after each execution. **Hourly / daily /
217
- weekly / monthly** cadences are supported; the recurring reference
218
- below documents the full shape, the hourly + monthly missing-day
219
- recipes, pause-vs-delete trade-off, and PATCH / GET / DELETE surface.
219
+ `/schedule` registers **one-shot** wake-ups and DMs. For repeating tasks:
220
220
 
221
- {{> ref:recurring }}
221
+ - **Recurring autonomous work** (daily inbox triage, weekly review, hourly
222
+ health check) is a **recurring Agent** — a durable, named identity with
223
+ metrics on `/agents`. Create it with the **`agent-create` skill**
224
+ (`POST /api/agents`). Creating a recurring `agent.task` row directly on
225
+ `POST /api/recurring-schedules` is **410 Gone** — use an Agent.
226
+ - **Recurring scheduled DM / briefing** ("DM me a summary every morning")
227
+ stays on `POST /api/recurring-schedules` with `taskType: "dm_session"`
228
+ (its fire time can track quiet-hours; PATCH/DELETE edit it). The morning
229
+ briefing is one of these.
222
230
 
223
- ### recurrenceRule grammar engine vs consumer
231
+ `GET /api/recurring-schedules` stays read-only for the dedup pre-check.
224
232
 
225
- The full engine grammar (mapping table, frequency-vs-field matrix,
226
- cadence-string-must-match-recurrenceRule discipline) is shared with
227
- the `managed-tasks` skill. The reference is byte-identical across
228
- both skills pinned by `skills-manifest.test.ts` so they cannot
229
- drift. Schedule callers may use any of the four frequencies the
230
- engine accepts; the `managed-tasks` consumer chooses to refuse
231
- sub-daily for app-fetch correctness and that constraint lives there.
233
+ ### recurrenceRule grammar the shared recurrence engine
234
+
235
+ The recurrence engine grammar (mapping table, frequency-vs-field matrix,
236
+ cadence-string discipline) is shared with the `managed-tasks` skill and
237
+ the `dm_session` recurring rule above. The reference is byte-identical
238
+ across both skills
239
+ pinned by `skills-manifest.test.ts` so they cannot drift.
232
240
 
233
241
  {{> ref:recurrence-rule }}
@@ -31,7 +31,7 @@ curl -s -X POST http://localhost:8321/api/schedule/batch \
31
31
  "taskContext": {
32
32
  "background": "User flagged Q2 roadmap risks in yesterdays DM; standup needs the two open items front-loaded so the team aligns before 15:30.",
33
33
  "expected_output": "DM with two bullet items + one suggested mitigation each, sent 30min before standup.",
34
- "references": ["projects/q2-roadmap.md#open-risks", "calendar:event:standup-2026-05-15"],
34
+ "references": ["plans/projects/q2-roadmap.md#open-risks", "calendar:event:standup-2026-05-15"],
35
35
  "tone": "concise"
36
36
  }
37
37
  }
@@ -57,7 +57,7 @@ curl -s -X POST http://localhost:8321/api/schedule/batch \
57
57
  | `rows[].taskContext.sub_flow` | No | Branches the task-flow rendering when the dispatcher needs a specialised sub-flow. |
58
58
  | `rows[].taskPrompt` | No | Override for the agent body (min 20 chars when set). |
59
59
  | `rows[].correlationId` | No | Defaults to the morning routine's correlation id when omitted. |
60
- | `rows[].model` | No | Registered model id (`claude-opus-4-7`, `claude-sonnet-4-6`, `gpt-5.4`, `gemini-3.1-pro-preview`, …), legacy alias (`sonnet` / `opus` — auto-rewritten to `tier`), composite `<backendId>/<modelId>`, or `null`. Mutually exclusive with `rows[].tier`. Omit both to let `process_backend_config` decide. |
60
+ | `rows[].model` | No | Registered model id (`claude-opus-4-8`, `claude-sonnet-4-6`, `gpt-5.4`, `gemini-3.1-pro-preview`, …), legacy alias (`sonnet` / `opus` — auto-rewritten to `tier`), composite `<backendId>/<modelId>`, or `null`. Mutually exclusive with `rows[].tier`. Omit both to let `process_backend_config` decide. |
61
61
  | `atomic` | No | `true` (default) wraps inserts in one transaction — any row error rolls back all. `false` commits successful rows individually. |
62
62
 
63
63
  ## Success
@@ -133,9 +133,12 @@ Apply to `POST /api/schedule` and `POST /api/schedule/batch`.
133
133
 
134
134
  | Code | When | Fix |
135
135
  |---|---|---|
136
- | <a id="task_type_unknown"></a> `schedule.task_type_unknown` | `taskType` is not `wake` / `dm_session` / `check` / `dm`. | Pick the matching type. Use `/api/schedule/dm` for the precomposed-DM variant. |
137
- | <a id="description_too_short"></a> `schedule.description_too_short` | `description` / `taskDescription` < 20 chars. | Expand the description so the wake-up agent has enough context to act. |
138
- | <a id="prompt_too_short"></a> `schedule.prompt_too_short` | `prompt` / `taskPrompt` is set but < 20 chars. | Either remove it (description doubles as the body) or expand it. |
136
+ | <a id="task_type_unknown"></a> `schedule.task_type_unknown` | **Batch only** (`/api/schedule/batch` rows): `taskType` is not one of the closed set `wake` / `dm_session` / `check` / `dm`. On the single `POST /api/schedule`, `taskType` is a free-form provenance label (no allowlist) — this code fires there only when `taskType` is missing or not a string. | Batch: pick one of the four. Single endpoint: send any non-empty string (`wake` is the convention for agent wake-ups). Use `/api/schedule/dm` for the precomposed-DM variant. |
137
+ | <a id="prompt_required"></a> `schedule.prompt_required` | `POST /api/schedule` (or a PATCH that sets it) with `prompt` missing or empty. | `prompt` is the wake-up agent's only instruction write the full instruction there. `description` is just the optional list label, no longer the agent body. |
138
+ | <a id="prompt_too_long"></a> `schedule.prompt_too_long` | `prompt` / `taskPrompt` > 8000 chars. | Tighten the instruction (goal + key context + expected output); move bulk reference material into a file the agent reads at fire time instead of inlining it. |
139
+ | <a id="description_too_long"></a> `schedule.description_too_long` | `description` > 200 chars. | The description is the short list label — keep it under 200 chars and put the full instruction in `prompt`. |
140
+ | <a id="description_too_short"></a> `schedule.description_too_short` | `taskDescription` (batch) / recurring `description` < 20 chars. | Expand the body so the wake-up agent has enough context to act. (Does not apply to the single `/api/schedule` row, where `description` is an optional label.) |
141
+ | <a id="prompt_too_short"></a> `schedule.prompt_too_short` | Batch `taskPrompt` / recurring `prompt` is set but < 20 chars. | Either remove it (the description body is used) or expand it. (The single `/api/schedule` row requires `prompt`; see `schedule.prompt_required`.) |
139
142
 
140
143
  ### taskContext required fields
141
144
 
@@ -161,7 +164,7 @@ here.
161
164
 
162
165
  `model` accepts a free-form token after SCHEDULE_API_REDESIGN_PLAN
163
166
  §4.3: legacy aliases (`sonnet` / `opus` — rewritten to `tier` at
164
- the route), full registered model ids (e.g. `claude-opus-4-7`,
167
+ the route), full registered model ids (e.g. `claude-opus-4-8`,
165
168
  `gpt-5.4`), or the composite `<backendId>/<modelId>` form when an
166
169
  id appears under multiple backends. `tier` (`lite` | `medium` |
167
170
  `high`) is the abstract cost knob and is mutually exclusive with
@@ -25,7 +25,7 @@ even after `/settings/models` re-routes the process key). The two are
25
25
  route to `tier:"medium"` / `tier:"high"`; the alias is not stored
26
26
  verbatim.
27
27
  - **Registered model ids** — any id from `MODEL_REGISTRY` across the
28
- four backends. Examples: `claude-opus-4-7`, `claude-sonnet-4-6`,
28
+ four backends. Examples: `claude-opus-4-8`, `claude-sonnet-4-6`,
29
29
  `claude-haiku-4-5-20251001`, `gpt-5.4`, `gemini-3.1-pro-preview`.
30
30
  The row persists `(model, backend_id)` together so the dispatcher
31
31
  honors the pin at fire time.
@@ -33,7 +33,7 @@ even after `/settings/models` re-routes the process key). The two are
33
33
  registry that has the same model id under multiple backends (today
34
34
  unreachable but accepted). The prefix MUST be one of `claude` /
35
35
  `codex` / `gemini` / `opencode`; opencode model ids like
36
- `anthropic/claude-opus-4-7` are NOT composites and fall through to
36
+ `anthropic/claude-opus-4-8` are NOT composites and fall through to
37
37
  the cross-backend scan.
38
38
 
39
39
  Unknown / ambiguous / deprecated model tokens surface through the
@@ -76,7 +76,7 @@ Response shape:
76
76
  "tiers": ["lite", "medium", "high"],
77
77
  "modelAliases": { "sonnet": "medium", "opus": "high" },
78
78
  "models": {
79
- "claude": [{ "id": "claude-opus-4-7", "tier": "high", "deprecated": false }, ...],
79
+ "claude": [{ "id": "claude-opus-4-8", "tier": "high", "deprecated": false }, ...],
80
80
  "codex": [...],
81
81
  "gemini": [...],
82
82
  "opencode": [...]
@@ -76,7 +76,7 @@ Same template applies to "every 5 minutes", "every 30 minutes",
76
76
  ## Cadence string vs structured rule
77
77
 
78
78
  Always send both `cadence` (human-readable, rendered in
79
- `rules/management.md` §B) and `recurrenceRule` (structured, what the
79
+ `policies/management.md` §B) and `recurrenceRule` (structured, what the
80
80
  scheduler executes). They must agree — if they drift, the rendered
81
81
  file misleads the user about what the scheduler will actually do.
82
82
 
@@ -175,39 +175,49 @@ runs. The (`section`, `mode`, `content`, `cutoff`, `maxEntries`)
175
175
  shape is the contract today — see `contextPatchSchema` in
176
176
  `packages/shared/src/schemas.ts`.
177
177
 
178
- **Source-id capture (write the `external_id` into the body lines):**
179
- the entity-mirror watcher (P5) reparses the file's frontmatter on
180
- change, so the dedup contract in §7.6 hinges on the upstream id
181
- landing in **frontmatter**, not just the body. Until the entity-mirror
182
- reconciler ships AND the context API gains a `frontmatter*` patch
183
- mode for `<domain>/<type-plural>/*` files, do this:
184
-
185
- 1. Always include `- external_id: <id>` on its own line in the
186
- appended `## <App> Notes` body so a future reconciler-rebuild can
187
- recover the binding from prose.
188
- 2. Track the binding in the §B "Recently changed" path — the
189
- `agent_actions.management_task.run_recorded` row's `detail` is
190
- structured and survives even when the file body doesn't reflect
191
- the binding cleanly.
192
-
193
- > **Implementation gap to flag** (Phase 5 / extended Phase 3): the
194
- > context PATCH route does not currently:
195
- > - allow writes under `<domain>/<type-plural>/*` (no entry in
196
- > `CONTEXT_WRITE_PERMISSIONS`), so this PATCH returns `403
197
- > forbidden` until the whitelist is widened, and
198
- > - expose a `frontmatterMerge` mode for deep-merging
199
- > `frontmatter.sources.<app>`.
200
- > Both are required by design 21 §10.4 step 4b and must land before
201
- > this Step 5a goes from "designed" to "operational". Until then,
202
- > Step 5b's audit row is the durable trace of the run — surface that
203
- > in the activity-view rather than relying on the entity body.
204
-
205
- If the entity file does not previously exist, today's API requires a
206
- PUT with full content (the `<domain>/<type-plural>/*` write path is
207
- gated by the same whitelist note above). When the gap closes, the
208
- first PATCH must include a complete frontmatter block — `type`,
209
- `domain`, `slug`, `title`, `created`, `sources` or the daemon
210
- returns 422 against `EntitySchema`.
178
+ **Source-id capture deep-merge into frontmatter (`mode:"frontmatterMerge"`):**
179
+ the §7.6 dedup contract hinges on the upstream id landing in **frontmatter**
180
+ (`sources.<app>.external_id`) the canonical signal the entity-mirror watcher
181
+ reparses and `GET /api/entities?source=…&external_id=…` queries not just the
182
+ body. The context PATCH route exposes `mode:"frontmatterMerge"` for exactly this
183
+ (design 21 §10.4 step 4b): it deep-merges a partial frontmatter object into the
184
+ file's existing YAML (nested objects merge key-by-key; scalars/arrays replace),
185
+ so a new `<app>` source is linked without clobbering other apps' ids, other
186
+ frontmatter keys, or the body:
187
+
188
+ ```bash
189
+ curl -sS -X PATCH "http://localhost:8321/api/context/work/meetings/2026-12-04-foo-1on1" \
190
+ -H 'Content-Type: application/json' \
191
+ -d @- <<'JSON'
192
+ {
193
+ "mode": "frontmatterMerge",
194
+ "frontmatter": {
195
+ "sources": { "zoom": { "external_id": "zm_xyz789" } },
196
+ "last_synced_at": "2026-12-04T09:00:00Z"
197
+ }
198
+ }
199
+ JSON
200
+ ```
201
+
202
+ `frontmatterMerge` requires a non-empty `frontmatter` object and takes no
203
+ `section` (it never touches the body). Append the human-readable
204
+ `## <App> Notes` section in a separate `mode:"append"` / `"append_to_file"`
205
+ PATCH. Also keep Step 5b's audit row as the durable structured trace of the run.
206
+
207
+ > **Write path:** the bare `<domain>/<type-plural>/<slug>` path is alias-rewritten
208
+ > to `knowledge/entities/<domain>/<type-plural>/<slug>` by `context-vault-aliases.ts`,
209
+ > which **is** whitelisted in `CONTEXT_WRITE_PERMISSIONS` for `PUT`/`PATCH`
210
+ > (autonomous tier), so both the frontmatterMerge and the body-append PATCH
211
+ > succeed on an existing entity file. (Recognised domains: `work`, `travel`,
212
+ > `finance`, `personal`, `health`, `learning`.)
213
+
214
+ If the entity file does not previously exist, PATCH returns
215
+ `404 context.path_not_found` — today's API requires a PUT with full
216
+ content to create it first (the `<domain>/<type-plural>/*` write path
217
+ is whitelisted for both PUT and PATCH; only the file-existence rule
218
+ forces the PUT-first ordering). The creating PUT must include a
219
+ complete frontmatter block — `type`, `domain`, `slug`, `title`,
220
+ `created`, `sources` — or the daemon returns 422 against `EntitySchema`.
211
221
 
212
222
  ### Step 5b — Update the row
213
223
 
@@ -296,7 +306,7 @@ agent keeps trying, but doesn't disappear silently.
296
306
  `scheduled.task` flow's "Output contract — your final text becomes a
297
307
  DM" applies (`scheduled.task.md`). For managed-task runs the default
298
308
  is **empty final text**: bookkeeping is invisible by design. The user
299
- sees the change reflected in `_activity/<source>.md` (auto-built) and
309
+ sees the change reflected in `state/activity/<source>.md` (auto-built) and
300
310
  `<domain>/_index.md`, not in a chat ping per fire.
301
311
 
302
312
  Exceptions:
@@ -343,7 +353,7 @@ appended `## <App> Notes` body, not as a separate DM.
343
353
  | HTTP | `error` | What to do |
344
354
  |---|---|---|
345
355
  | 400 (`/api/managed-tasks/:id/run-result`) | `invalid_id` / `validation_error` | Body shape drift — re-check field names exactly match `last_run_at` / `last_result` / `consecutive_failures` |
346
- | 403 (`/api/context/<domain>/<type-plural>/...`) | `forbidden` | Entity-domain write paths are not yet whitelisted (Phase 5 gap, §Step 5a). Skip the entity merge for this run, still record run-result, and surface a one-line warning in `last_result`. |
356
+ | 404 (`/api/context/<domain>/<type-plural>/...`) | `context.path_not_found` | The entity file does not exist yet PATCH cannot create it. Create it first with a PUT carrying full content + complete frontmatter (§Step 5a), then the merge succeeds. (Entity-domain write paths ARE whitelisted for PUT/PATCH; the prior 403 claim is obsolete.) |
347
357
  | 404 (`/api/managed-tasks/:id`) | `not_found` | Row was stopped mid-run. End the session quietly. |
348
358
  | 422 (`/api/context/...`) | `validation_error` | Frontmatter incomplete or malformed; populate all required fields and retry once |
349
359
  | 422 (`/api/managed-tasks/:id`) | `validation_error` | Path / body shape rejected; drop the offending field (typically `output_path`) and retry once with the rest |
@@ -379,7 +389,7 @@ appended `## <App> Notes` body, not as a separate DM.
379
389
  | `GET /api/entities?source=` | Step 4 bias hint (list-by-source-key) |
380
390
  | `GET /api/entities?domain=&type=&date=&q=` | Step 4.2 (tier-2 fuzzy) |
381
391
  | `GET /api/entities/by-path?path=` | Step 4 (verify before merging) |
382
- | `PATCH /api/context/<domain>/<type-plural>/<slug>` | Step 5a (gated by entity-domain write whitelistPhase 5 gap) |
392
+ | `PATCH /api/context/<domain>/<type-plural>/<slug>` | Step 5a (whitelisted PUT/PATCH; PATCH requires the file to exist PUT-create first if 404) |
383
393
  | `PATCH /api/managed-tasks/:id/run-result` | Step 5b (internal — last_run_at / last_result / consecutive_failures) |
384
394
  | `PATCH /api/managed-tasks/:id` | Step 5b output-path back-fill only |
385
395
  | `POST /api/notify` | Step 6 (only on the 3-failures-in-a-row crossing edge) |
@@ -23,7 +23,7 @@ Output language: today.md is Policy B — see `<output_language_policy>`. The sk
23
23
  `## Agent Plan`, `## Agent Notes`, `## Agent Log`, `## Handoff` —
24
24
  in this order.
25
25
 
26
- A `PUT /api/context/today` whose line 1 or line 2 fails the exact regex
26
+ A `PUT /api/context/state/today` whose line 1 or line 2 fails the exact regex
27
27
  is rejected with 400 and the daemon does NOT write the file. Translating
28
28
  any keyword on line 2 (the field labels, the `Weekday`/`Weekend` value,
29
29
  or `on`/`off`) into the user's primary language is the most common
@@ -63,9 +63,9 @@ line 1 is exactly `# 2026-04-28 (Tuesday)`. Do **not** advance the date
63
63
  because the routine is "preparing tomorrow"; the morning routine always
64
64
  prepares the agent-day in progress, not the next one.
65
65
 
66
- `PUT /api/context/today` returns 422 if line 1 disagrees with the
67
- daemon's current agent-day; the error message echoes both values so a
68
- mistake is recoverable in the same session.
66
+ `PUT /api/context/state/today` returns 400 (`error:"validation_error"`) if
67
+ line 1 disagrees with the daemon's current agent-day; the error message
68
+ echoes both values so a mistake is recoverable in the same session.
69
69
 
70
70
  today.md has **no YAML frontmatter** — the H1 must be the first byte of
71
71
  the file.
@@ -80,7 +80,7 @@ Line 2 encodes today's filter policy (field order is fixed — downstream parser
80
80
 
81
81
  Derivation (Morning Routine at 04:00):
82
82
  1. Day-of-week from `<current_time>`. Weekday = Mon–Fri, Weekend = Sat–Sun (unless user/profile.md overrides).
83
- 2. Read `user/profile.md` → ## Notification Preferences. Apply matching policy.
83
+ 2. Read `identity/profile.md` → ## Notification Preferences. Apply matching policy.
84
84
  3. No explicit policy → default: weekday = all on, weekend = work off, study on, personal on.
85
85
 
86
86
  Category → focus-dimension mapping:
@@ -143,7 +143,7 @@ Violations: row without schedule → silently never fires. Schedule without row
143
143
  `scheduled.task` and `scheduled.dm` (and any other event that flips an
144
144
  Agent Plan row) follow the close-the-loop lifecycle in the reference
145
145
  below: execute, append Agent Log entry, read-then-flip the row to
146
- `[x]` with annotation, retry on `today.md` lock, surface missing-row
146
+ `[x]` with annotation, retry on `state/today.md` lock, surface missing-row
147
147
  state.
148
148
 
149
149
  DM handlers and hourly checks do not flip Agent Plan rows — read the
@@ -195,14 +195,14 @@ The generic GET / PUT / PATCH / DELETE surface — modes, fields, error
195
195
  envelopes, body-submission shape — is documented in the **context**
196
196
  skill `references/api.md`. today.md-specific rules layered on top:
197
197
 
198
- - **Lock.** `today.md` is locked by the Morning Routine. Include
198
+ - **Lock.** `state/today.md` is locked by the Morning Routine. Include
199
199
  `X-Lock-Id: <today_write_lock_id>` on every PUT / PATCH when the
200
200
  tag is in your context; other sessions get `409
201
- today_write_lock_held` while the lock is held.
201
+ morning_routine_lock_held` while the lock is held.
202
202
  - **Skeleton validators.** PUT is rejected (400) if line 1 fails the
203
203
  H1 date regex or line 2 fails the day-type quote regex (see §"Line 1
204
204
  — which date?" and §"Header line — day-type filter" above). PUT is
205
- rejected (422) if line 1's date disagrees with the daemon's current
205
+ also rejected (400) if line 1's date disagrees with the daemon's current
206
206
  agent-day — the error echoes both values.
207
207
 
208
208
  ## Knowledge map — section shape (auto-curated)
@@ -5,9 +5,9 @@
5
5
  "id": "section-shape",
6
6
  "kind": "knowledge_layout",
7
7
  "anchor": "<!-- CURATION:knowledge_layout id=\"section-shape\" -->",
8
- "human_label": "today.md section shape",
8
+ "human_label": "state/today.md section shape",
9
9
  "description": "Required sections in today.md and what each holds",
10
- "scope_paths": ["today.md"]
10
+ "scope_paths": ["state/today.md"]
11
11
  },
12
12
  {
13
13
  "id": "agent-notes-flavors",
@@ -15,7 +15,7 @@
15
15
  "anchor": "<!-- CURATION:convention_notes id=\"agent-notes-flavors\" -->",
16
16
  "human_label": "Agent Notes flavors",
17
17
  "description": "Sub-shapes the agent uses inside ## Agent Notes (look-ahead, day-time observation, latent profile question)",
18
- "scope_paths": ["today.md"]
18
+ "scope_paths": ["state/today.md"]
19
19
  }
20
20
  ]
21
21
  }
@@ -49,10 +49,10 @@ the action it represents, before the session exits.
49
49
  + action text), and flip `[ ]` → `[x]`:
50
50
 
51
51
  ```bash
52
- curl -s http://localhost:8321/api/context/today
52
+ curl -s http://localhost:8321/api/context/state/today
53
53
  # Find the agent_plan section. Edit the matching row's checkbox.
54
54
  # Then PATCH the full updated section body:
55
- curl -s -X PATCH http://localhost:8321/api/context/today \
55
+ curl -s -X PATCH http://localhost:8321/api/context/state/today \
56
56
  -H 'Content-Type: application/json' \
57
57
  -H 'X-Lock-Id: <today_write_lock_id>' \
58
58
  -d '{"section": "agent_plan", "mode": "replace", "content": "<full merged section>"}'
@@ -86,10 +86,11 @@ triggers self-recovery and inflates the agent-actions audit.
86
86
 
87
87
  ## Lock retry rules
88
88
 
89
- The Morning Routine holds the `today.md` write lock. Other sessions
90
- get `409 today_write_lock_held` on PUT / PATCH while the lock is held.
89
+ The Morning Routine holds the `state/today.md` write lock. Other sessions
90
+ get `409 morning_routine_lock_held` on PUT / PATCH while the lock is held.
91
91
 
92
- - Detect by the response body `{"error":"lock_held"}` or by the
92
+ - Detect by the response body `{"error":"morning_routine_lock_held"}`
93
+ (with `errors[0].code: "context.morning_routine_lock_held"`) or by the
93
94
  status code 409 alone.
94
95
  - Retry policy: 30 s back-off, max 3 attempts. If the third attempt
95
96
  also returns 409, log `loop-closeout deferred (lock_held)` to Agent
@@ -2,7 +2,7 @@
2
2
  "kind": "knowledge_layout",
3
3
  "files": [
4
4
  {
5
- "path": "today.md",
5
+ "path": "state/today.md",
6
6
  "purpose": "today's plan, schedule, agent log, and handoff to tomorrow",
7
7
  "sections": [
8
8
  { "heading": "## Plan", "contains": "the day's intent in plain prose" },