@aitne-sh/aitne 0.1.7 → 0.1.8

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 (222) hide show
  1. package/README.md +195 -829
  2. package/agent-assets/agent-profiles/_safety.md +49 -17
  3. package/agent-assets/agent-profiles/profile-importer.md +1 -1
  4. package/agent-assets/agent-profiles/routine.md +4 -3
  5. package/agent-assets/docs/concepts/agent-day.md +6 -1
  6. package/agent-assets/docs/concepts/auth-health.md +10 -1
  7. package/agent-assets/docs/concepts/backends-and-tiers.md +74 -40
  8. package/agent-assets/docs/concepts/costs-and-quotas.md +25 -5
  9. package/agent-assets/docs/concepts/delegated-mode.md +147 -68
  10. package/agent-assets/docs/concepts/memory-model.md +9 -4
  11. package/agent-assets/docs/concepts/observations.md +13 -1
  12. package/agent-assets/docs/concepts/process-keys.md +20 -5
  13. package/agent-assets/docs/concepts/routines.md +38 -20
  14. package/agent-assets/docs/concepts/safety-model.md +30 -13
  15. package/agent-assets/docs/concepts/skills.md +12 -7
  16. package/agent-assets/docs/features/integrations/calendar.md +1 -1
  17. package/agent-assets/docs/features/integrations/git.md +2 -2
  18. package/agent-assets/docs/features/integrations/github.md +9 -2
  19. package/agent-assets/docs/features/integrations/mail.md +1 -1
  20. package/agent-assets/docs/features/integrations/notion.md +34 -6
  21. package/agent-assets/docs/features/integrations/obsidian.md +7 -2
  22. package/agent-assets/docs/features/lifestyle/git.md +4 -7
  23. package/agent-assets/docs/features/lifestyle/receipts.md +17 -2
  24. package/agent-assets/docs/features/lifestyle/travel-bookings.md +15 -0
  25. package/agent-assets/docs/features/lifestyle/travel-time.md +7 -1
  26. package/agent-assets/docs/features/memory-files/agent-journal.md +2 -2
  27. package/agent-assets/docs/features/memory-files/projects.md +6 -0
  28. package/agent-assets/docs/features/memory-files/roadmap.md +5 -0
  29. package/agent-assets/docs/features/memory-files/today.md +1 -0
  30. package/agent-assets/docs/features/memory-files/user-profile.md +6 -0
  31. package/agent-assets/docs/features/messaging/bang-commands.md +20 -10
  32. package/agent-assets/docs/features/messaging/discord.md +12 -1
  33. package/agent-assets/docs/features/messaging/overview.md +10 -7
  34. package/agent-assets/docs/features/messaging/slack.md +13 -1
  35. package/agent-assets/docs/features/messaging/telegram.md +7 -1
  36. package/agent-assets/docs/features/messaging/whatsapp.md +12 -1
  37. package/agent-assets/docs/features/operations/activity-and-conversations.md +2 -2
  38. package/agent-assets/docs/features/operations/approvals.md +6 -0
  39. package/agent-assets/docs/features/operations/backend-routing.md +7 -0
  40. package/agent-assets/docs/features/operations/cost-tracking.md +6 -0
  41. package/agent-assets/docs/features/operations/notifications.md +6 -0
  42. package/agent-assets/docs/features/operations/schedule-approaching.md +22 -9
  43. package/agent-assets/docs/features/routines/custom-routines.md +10 -4
  44. package/agent-assets/docs/features/routines/evening-review.md +1 -1
  45. package/agent-assets/docs/features/routines/hourly-check.md +1 -1
  46. package/agent-assets/docs/features/routines/morning-routine.md +24 -15
  47. package/agent-assets/docs/features/routines/weekly-review.md +38 -12
  48. package/agent-assets/docs/features/wiki/commands.md +11 -0
  49. package/agent-assets/docs/features/wiki/overview.md +13 -3
  50. package/agent-assets/docs/getting-started/01-what-is-this.md +32 -11
  51. package/agent-assets/docs/getting-started/02-first-steps.md +17 -4
  52. package/agent-assets/docs/getting-started/03-what-can-this-do.md +21 -11
  53. package/agent-assets/docs/getting-started/04-first-day.md +14 -0
  54. package/agent-assets/docs/glossary.md +65 -12
  55. package/agent-assets/docs/guides/add-a-custom-routine.md +12 -0
  56. package/agent-assets/docs/guides/backup-and-restore.md +16 -2
  57. package/agent-assets/docs/guides/budget-and-cost-for-wiki.md +6 -0
  58. package/agent-assets/docs/guides/build-your-wiki.md +14 -0
  59. package/agent-assets/docs/guides/change-which-model-handles-x.md +7 -0
  60. package/agent-assets/docs/guides/connect-a-new-mail-account.md +16 -0
  61. package/agent-assets/docs/guides/explore-with-trace-and-connect.md +6 -0
  62. package/agent-assets/docs/guides/import-knowledge-file.md +11 -0
  63. package/agent-assets/docs/guides/install-and-run.md +20 -4
  64. package/agent-assets/docs/guides/maintain-wiki-health.md +6 -0
  65. package/agent-assets/docs/guides/migrate-machines.md +13 -1
  66. package/agent-assets/docs/guides/multiple-wikis-for-multiple-domains.md +9 -0
  67. package/agent-assets/docs/guides/pause-the-agent.md +12 -4
  68. package/agent-assets/docs/guides/reinstall-cleanly.md +19 -4
  69. package/agent-assets/docs/guides/setup-wizard.md +20 -9
  70. package/agent-assets/docs/guides/switch-default-backend.md +10 -1
  71. package/agent-assets/docs/guides/use-an-existing-obsidian-vault.md +5 -0
  72. package/agent-assets/docs/reference/api.md +29 -1
  73. package/agent-assets/docs/reference/cli-commands.md +22 -3
  74. package/agent-assets/docs/reference/config.md +37 -5
  75. package/agent-assets/docs/reference/disallowed-tools.md +13 -0
  76. package/agent-assets/docs/reference/keyboard-shortcuts.md +13 -0
  77. package/agent-assets/docs/reference/process-keys.md +70 -20
  78. package/agent-assets/docs/reference/skills.md +27 -9
  79. package/agent-assets/docs/troubleshooting/auth-failed.md +7 -2
  80. package/agent-assets/docs/troubleshooting/dashboard-shows-degraded.md +13 -1
  81. package/agent-assets/docs/troubleshooting/fallback-keeps-firing.md +10 -0
  82. package/agent-assets/docs/troubleshooting/messaging-not-pairing.md +11 -0
  83. package/agent-assets/docs/troubleshooting/morning-routine-didnt-run.md +9 -4
  84. package/agent-assets/docs/troubleshooting/observation-not-detected.md +12 -0
  85. package/agent-assets/docs/troubleshooting/quota-exhausted.md +7 -1
  86. package/agent-assets/docs/troubleshooting/wiki-ingest-full-blocked.md +5 -0
  87. package/agent-assets/docs/troubleshooting/wiki-write-failed.md +5 -0
  88. package/agent-assets/optimizer-skills/drift-analysis/SKILL.md +1 -1
  89. package/agent-assets/optimizer-skills/skill-curation/SKILL.md +2 -2
  90. package/agent-assets/skills/agent-actions/SKILL.md +122 -0
  91. package/agent-assets/skills/attach/SKILL.md +1 -2
  92. package/agent-assets/skills/context/SKILL.md +36 -454
  93. package/agent-assets/skills/context/references/api.md +220 -0
  94. package/agent-assets/skills/context/references/required-frontmatter.md +73 -0
  95. package/agent-assets/skills/context/references/snapshot-files.md +103 -0
  96. package/agent-assets/skills/context/seeds/file-responsibilities.seed.json +1 -1
  97. package/agent-assets/skills/docs-search/SKILL.md +13 -13
  98. package/agent-assets/skills/external-services/SKILL.delegated.claude.md +5 -7
  99. package/agent-assets/skills/external-services/SKILL.delegated.codex.md +5 -7
  100. package/agent-assets/skills/external-services/SKILL.delegated.gemini.md +5 -7
  101. package/agent-assets/skills/external-services/SKILL.md +6 -259
  102. package/agent-assets/skills/external-services/SKILL.native.claude.md +1 -2
  103. package/agent-assets/skills/external-services/SKILL.native.codex.md +1 -2
  104. package/agent-assets/skills/external-services/SKILL.native.gemini.md +1 -2
  105. package/agent-assets/skills/external-services/references/calendar-apple.md +97 -0
  106. package/agent-assets/skills/external-services/references/calendar-google.md +72 -0
  107. package/agent-assets/skills/external-services/references/calendar-outlook.md +36 -0
  108. package/agent-assets/skills/external-services/references/github.md +17 -0
  109. package/agent-assets/skills/external-services/references/obsidian.md +49 -0
  110. package/agent-assets/skills/external-services/references/skills-crud.md +27 -0
  111. package/agent-assets/skills/gmail-lifestyle/SKILL.md +224 -0
  112. package/agent-assets/skills/gmail-lifestyle/references/receipts-api.md +93 -0
  113. package/agent-assets/skills/gmail-lifestyle/references/travel-bookings-api.md +75 -0
  114. package/agent-assets/skills/gmail-lifestyle/references/travel-time-api.md +59 -0
  115. package/agent-assets/skills/mail/SKILL.delegated.claude.md +1 -1
  116. package/agent-assets/skills/mail/SKILL.delegated.codex.md +1 -1
  117. package/agent-assets/skills/mail/SKILL.delegated.gemini.md +1 -1
  118. package/agent-assets/skills/mail/SKILL.md +9 -114
  119. package/agent-assets/skills/mail/SKILL.native.claude.md +1 -1
  120. package/agent-assets/skills/mail/SKILL.native.codex.md +1 -1
  121. package/agent-assets/skills/mail/SKILL.native.gemini.md +1 -1
  122. package/agent-assets/skills/mail/references/api.md +108 -0
  123. package/agent-assets/skills/mail/references/examples.md +70 -0
  124. package/agent-assets/skills/mail/references/providers.md +8 -8
  125. package/agent-assets/skills/managed-tasks/SKILL.md +472 -0
  126. package/agent-assets/skills/managed-tasks/references/errors.md +70 -0
  127. package/agent-assets/skills/managed-tasks/references/output-path.md +75 -0
  128. package/agent-assets/skills/managed-tasks/references/recurrence-rule.md +86 -0
  129. package/agent-assets/skills/management-policy/SKILL.md +33 -105
  130. package/agent-assets/skills/management-policy/references/policy-workflow.md +101 -0
  131. package/agent-assets/skills/notify/SKILL.md +6 -78
  132. package/agent-assets/skills/notify/references/priority.md +60 -0
  133. package/agent-assets/skills/notion/SKILL.delegated.claude.md +1 -1
  134. package/agent-assets/skills/notion/SKILL.delegated.codex.md +1 -1
  135. package/agent-assets/skills/notion/SKILL.delegated.gemini.md +1 -1
  136. package/agent-assets/skills/notion/SKILL.md +6 -10
  137. package/agent-assets/skills/notion/SKILL.native.claude.md +1 -2
  138. package/agent-assets/skills/notion/SKILL.native.codex.md +1 -2
  139. package/agent-assets/skills/notion/SKILL.native.gemini.md +1 -2
  140. package/agent-assets/skills/observations/SKILL.md +1 -6
  141. package/agent-assets/skills/project-doc/SKILL.md +1 -5
  142. package/agent-assets/skills/reading/SKILL.md +2 -2
  143. package/agent-assets/skills/roadmap/SKILL.md +37 -135
  144. package/agent-assets/skills/roadmap/references/api.md +100 -0
  145. package/agent-assets/skills/roadmap/references/cross-check.md +73 -0
  146. package/agent-assets/skills/roadmap/references/migration.md +56 -0
  147. package/agent-assets/skills/roadmap/references/preparation-timeline.md +2 -2
  148. package/agent-assets/skills/schedule/SKILL.md +52 -88
  149. package/agent-assets/skills/schedule/references/batch.md +93 -0
  150. package/agent-assets/skills/schedule/references/errors.md +214 -0
  151. package/agent-assets/skills/schedule/references/model-selection.md +96 -0
  152. package/agent-assets/skills/schedule/references/recurrence-rule.md +86 -0
  153. package/agent-assets/skills/schedule/references/recurring.md +185 -0
  154. package/agent-assets/skills/scheduled-managed-task/SKILL.md +13 -15
  155. package/agent-assets/skills/today/SKILL.md +27 -57
  156. package/agent-assets/skills/today/references/agent-plan-lifecycle.md +113 -0
  157. package/agent-assets/skills/user-interview/SKILL.md +12 -59
  158. package/agent-assets/skills/user-interview/references/op-briefing.md +51 -0
  159. package/agent-assets/skills/user-interview/references/op-morning.md +59 -0
  160. package/agent-assets/skills/user-interview/references/sweep-and-fallback.md +1 -1
  161. package/agent-assets/skills/user-profile/SKILL.md +43 -63
  162. package/agent-assets/skills/user-profile/references/character-preferences.md +83 -0
  163. package/agent-assets/skills/user-profile/seeds/topic-files.seed.json +28 -0
  164. package/agent-assets/skills/wiki/wiki-ask/SKILL.md +0 -1
  165. package/agent-assets/skills/wiki/wiki-compile/SKILL.md +0 -1
  166. package/agent-assets/skills/wiki/wiki-connect/SKILL.md +0 -1
  167. package/agent-assets/skills/wiki/wiki-graduate/SKILL.md +0 -1
  168. package/agent-assets/skills/wiki/wiki-ingest/SKILL.md +0 -1
  169. package/agent-assets/skills/wiki/wiki-lint/SKILL.md +0 -1
  170. package/agent-assets/skills/wiki/wiki-trace/SKILL.md +0 -1
  171. package/agent-assets/skills/wiki/wiki-vault-rules/SKILL.md +0 -1
  172. package/agent-assets/system-prompts/routine-fetch-window.md +68 -0
  173. package/agent-assets/system-prompts/skill-index-instruction.md +26 -0
  174. package/agent-assets/task-flows/_partials/calendar-acquire.google_calendar.md +18 -11
  175. package/agent-assets/task-flows/_partials/calendar-acquire.outlook_calendar.md +16 -9
  176. package/agent-assets/task-flows/_partials/capture-user-info.md +24 -0
  177. package/agent-assets/task-flows/_partials/confirm-subflow.md +68 -0
  178. package/agent-assets/task-flows/_partials/dm-intent.long-horizon.md +35 -0
  179. package/agent-assets/task-flows/_partials/dm-intent.project.md +391 -0
  180. package/agent-assets/task-flows/_partials/mail-acquire.gmail.md +20 -11
  181. package/agent-assets/task-flows/_partials/mail-acquire.outlook_mail.md +17 -9
  182. package/agent-assets/task-flows/_partials/notion-acquire.notion.md +18 -12
  183. package/agent-assets/task-flows/knowledge.import.md +1 -1
  184. package/agent-assets/task-flows/message.received.dm.md +13 -15
  185. package/agent-assets/task-flows/message.received.dm_first.md +10 -14
  186. package/agent-assets/task-flows/routine.custom.md +3 -1
  187. package/agent-assets/task-flows/routine.evening_review.md +39 -163
  188. package/agent-assets/task-flows/routine.fetch_window.md +17 -12
  189. package/agent-assets/task-flows/routine.hourly_check.md +16 -8
  190. package/agent-assets/task-flows/routine.hourly_check.triage.md +1 -1
  191. package/agent-assets/task-flows/routine.monthly_review.md +46 -4
  192. package/agent-assets/task-flows/routine.morning_routine_journal.md +113 -0
  193. package/agent-assets/task-flows/routine.morning_routine_today.md +673 -0
  194. package/agent-assets/task-flows/routine.roadmap_refresh.md +60 -15
  195. package/agent-assets/task-flows/routine.user_profile_sweep.md +9 -10
  196. package/agent-assets/task-flows/routine.weekly_review.md +285 -70
  197. package/agent-assets/task-flows/scheduled.dm.md +8 -8
  198. package/agent-assets/task-flows/scheduled.task.md +5 -5
  199. package/agent-assets/task-flows/setup.initial.md +165 -245
  200. package/agent-assets/task-flows/wiki.ingest_url.md +1 -1
  201. package/agent-assets/templates/_manifest.json +7 -7
  202. package/agent-assets/templates/dossiers/_index.md +1 -1
  203. package/agent-assets/templates/rules/journal-format.md +145 -38
  204. package/agent-assets/templates/user/expertise.md +4 -2
  205. package/agent-assets/templates/user/goals.md +4 -2
  206. package/agent-assets/templates/user/people.md +8 -2
  207. package/agent-assets/templates/user/personal.md +4 -2
  208. package/agent-assets/templates/user/work.md +4 -2
  209. package/bin/aitne.mjs +8 -1
  210. package/package.json +4 -4
  211. package/scripts/commands/doctor.mjs +52 -0
  212. package/scripts/commands/run-now.mjs +202 -0
  213. package/scripts/commands/verify.mjs +264 -0
  214. package/agent-assets/docs/features/routines/monthly-review.md +0 -65
  215. package/agent-assets/skills/management-task-modify/SKILL.md +0 -203
  216. package/agent-assets/skills/management-task-register/SKILL.md +0 -330
  217. package/agent-assets/skills/management-task-stop/SKILL.md +0 -166
  218. package/agent-assets/skills/receipts/SKILL.md +0 -134
  219. package/agent-assets/skills/travel/SKILL.md +0 -132
  220. package/agent-assets/skills/travel-time/SKILL.md +0 -158
  221. package/agent-assets/task-flows/routine.morning_routine.md +0 -322
  222. package/agent-assets/task-flows/routine.morning_routine_initial.md +0 -204
@@ -0,0 +1,673 @@
1
+ {context}
2
+
3
+ ## Task: Morning Routine — Stage A (today.md synthesis)
4
+
5
+ You are Stage A of the 04:00 morning-routine pipeline. Stage B
6
+ (`routine.morning_routine_journal`) is running in parallel and owns
7
+ `daily/<yesterday>.md` end-to-end — do **not** write that file. Your
8
+ scope:
9
+
10
+ - §5.9 Steps 1-4, 6, 6b, 7, 7.5, 8 — today.md, roadmap maintenance,
11
+ schedule fan-out, profile-question mirror, user-editable checks.
12
+ - A single structured self-report at the end (Step 9 is daemon-owned;
13
+ you patch metadata, the daemon writes `agent/journal.md`).
14
+
15
+ Follow the `context` skill for section formats and entry shapes — this
16
+ prompt owns the workflow; the skill owns the schema.
17
+
18
+ > **First-run detection.** When `<yesterday>` is **absent** from your
19
+ > prompt context, this is the first morning routine after setup — no
20
+ > prior agent-day exists yet. Branches marked **first-run** below apply;
21
+ > branches marked **recurring** are skipped.
22
+
23
+ The "Vault review context" block appended to this prompt includes
24
+ `context-index.md` and `dossiers/morning.md`; consult it during context
25
+ gathering and update the dossier's Open items / Last run before
26
+ finishing. Writes to `dossiers/<flow>.md` MUST preserve the existing
27
+ YAML frontmatter block; prefer `PATCH` with a section target, and on
28
+ `PUT` keep the frontmatter and only refresh `updated:` — writes that
29
+ drop the frontmatter are rejected with 422.
30
+
31
+ Global rules (apply at every step):
32
+ - Do **not** add meta-maintenance tasks about context files, setup
33
+ completion, or placeholder cleanup (for example, "initialize context
34
+ files") to User Tasks or Handoff, whether carried from yesterday or
35
+ newly discovered, unless the user explicitly asked to track them.
36
+ - If `<today_write_lock_id>` is present, every PUT/PATCH to
37
+ `/api/context/today` must send header `X-Lock-Id: <today_write_lock_id>`.
38
+ - Silent-by-default: your final text is agent-internal. User
39
+ notifications require an explicit `POST /api/notify`.
40
+ - Stage B owns `daily/<yesterday>.md`. You MUST NOT write any
41
+ `daily/*.md` file from this session — Step 5 is delegated. The
42
+ daemon's parent audit row gates on YOUR success + today.md health,
43
+ so a Stage B failure does not stop the day from "opening".
44
+
45
+ ### Step 1 — Read handoff and derive day-type
46
+
47
+ 1. **Read the handoff.** When `<handoff_parsed>` is in your prompt
48
+ context, use it verbatim — `<tomorrow>` items feed today's User
49
+ Tasks / Agent Notes, `<later>` items carry into the new `today.md`
50
+ ## Handoff, and `<item>(none)</item>` means the section is empty.
51
+ When `<handoff_parsed>` is absent: parse `<yesterday>` ## Handoff
52
+ inline if `<yesterday>` is present; otherwise (first-run) treat
53
+ both lists as empty and Step 6 initialises ## Handoff to `- (none)`.
54
+
55
+ 2. **Recurring (`<yesterday>` present):** Mark `<yesterday>` ## Agent
56
+ Plan rows that did not fire. The daemon rotated `today.md →
57
+ yesterday.md` at the 04:00 day boundary, so every `- [ ] HH:MM …`
58
+ row in `<yesterday>` ## Agent Plan is past — the row's intended
59
+ user-facing moment has elapsed. Flip each such row to
60
+ `- [x] HH:MM … (did-not-fire)` via PATCH `/api/context/yesterday`,
61
+ `section=agent_plan`, `mode=replace`, and append one
62
+ `- HH:MM [agent_plan] <action> — did-not-fire` line per flipped row
63
+ to `<yesterday>` ## Agent Log (PATCH `section=agent_log`,
64
+ `mode=append`), where `HH:MM` is the **original row's planned time**
65
+ (not the current wall-clock; the entry is anchored to the gap, not
66
+ to when you logged it) and `<action>` is the row's action text —
67
+ the segment between the timestamp and the `[category]` tag, e.g.
68
+ for `- [ ] 10:00 Send meeting pre-brief [work] →DM` the log line is
69
+ `- 10:00 [agent_plan] Send meeting pre-brief — did-not-fire`. The
70
+ today-write-lock only gates `/api/context/today`, so NO `X-Lock-Id`
71
+ header is needed on either yesterday.md PATCH. Skip this substep
72
+ entirely when `<yesterday>` ## Agent Plan has no `[ ]` rows.
73
+
74
+ **Section-body-rebuild discipline** (applies to the
75
+ `section=agent_plan` PATCH). LLM rebuilds silently drop lines far
76
+ too easily. Before the PATCH:
77
+ - GET the current `## Agent Plan` body fresh.
78
+ - Enumerate kept lines (every `- [x]` row, verbatim) vs. mutated
79
+ lines (each `- [ ]` flipped to `- [x] … (did-not-fire)`). Write
80
+ the keep-list in your reasoning before constructing the new body.
81
+ - The new body equals `keep-list + mutated lines`, byte-for-byte
82
+ for kept lines. Do NOT paraphrase, reformat, drop, or reorder
83
+ sibling rows.
84
+
85
+ Do NOT retroactively execute the flipped actions — the user-facing
86
+ moment has passed; logging `did-not-fire` is the close-the-loop
87
+ contract. Note any genuine anomalies (e.g. the row's matching
88
+ scheduled task was mid-execution when the daemon crashed) in
89
+ Step 9's `anomalies` array rather than re-firing here.
90
+
91
+ **First-run (`<yesterday>` absent):** Skip this substep — there is
92
+ no prior Agent Plan to reconcile.
93
+
94
+ 3. Derive today's day-type header per the today skill "Header line —
95
+ day-type filter". Read `<user>` ## Notification Preferences for the
96
+ matching policy. The resulting line 2 of `today.md` is load-bearing
97
+ — every downstream event parses it. Remember the chosen day-type
98
+ string — Step 9 reports it via `metadata.dayType`.
99
+
100
+ > **Date reference for today.md.** Take the H1 date from
101
+ > `<current_agent_day date="…" weekday="…" />` in your prompt context,
102
+ > not from `<current_time>`. The two diverge between local midnight
103
+ > and `boundary_hour:00` local; the daemon validates line 1 against
104
+ > `<current_agent_day>` and rejects mismatches with 422. The morning
105
+ > routine prepares the agent-day in progress — never tomorrow.
106
+
107
+ ### Step 2 — Sync external sources (apply the day-type filter at read time)
108
+
109
+ 4. Mail, Calendar, and Notion acquisition. The pre-pass fetcher
110
+ session (`routine.fetch_window`) ran ahead of you and posted a
111
+ `<fetch>` row's worth of observations for every active mail /
112
+ calendar / notion integration. Calendar windows are pre-fetched
113
+ ONLY for non-direct modes (delegated / native); direct-mode
114
+ calendar data is still inlined into `<calendar_events_7d>` by
115
+ ContextBuilder. The `<fetch_report>` block injected ahead of this
116
+ body tells you the pre-pass status:
117
+
118
+ - `status="success"` or `"partial"` → freshly-fetched rows are
119
+ visible in `/api/observations?pending=true`. Trust the table.
120
+ - `status="failed"` → the pre-pass either crashed or its output
121
+ was unparseable. Pending observations from prior ticks may still
122
+ be present; treat the table as best-effort and skip integration
123
+ sections whose source_prefix returns nothing.
124
+ - `status="skipped"` → no integration was active for this routine
125
+ this tick; mail / notion sections are no-ops for this run.
126
+
127
+ Then drain pending observations and apply category / focus filtering:
128
+
129
+ a. **Mail observations**:
130
+ `GET /api/observations?pending=true&source_prefix=gmail:,outlook_mail:&limit=30`.
131
+ Classify each per the `mail` skill's category taxonomy. Drop any
132
+ whose day-type focus is `off`. When `summary_text` is NULL (the
133
+ async summarizer has not drained yet) fall back to a one-line
134
+ snippet from `payload.raw` (subject + from). Mail data arrives
135
+ here regardless of integration mode — the pre-pass partial
136
+ handled the direct / delegated-same / delegated-cross / native
137
+ wire surface for you.
138
+
139
+ b. **Notion observations**:
140
+ `GET /api/observations?pending=true&source_prefix=notion:&limit=20`.
141
+ Use for project / decision context only. Do NOT graduate Notion
142
+ edits into User Tasks unless the user explicitly tagged the entry.
143
+
144
+ c. **Calendar context** is already injected as `<calendar_events_7d>`
145
+ (multi-provider) ahead of this prompt — reference the block
146
+ directly in Step 6 (today.md generation). Mode-aware shape:
147
+ direct providers carry inline events; non-direct providers
148
+ (delegated / native) carry a hint pointing at
149
+ `/api/observations?source_prefix=google_calendar:,outlook_calendar:`
150
+ because the pre-pass already POSTed events there. Read the
151
+ observations table verbatim for non-direct providers — do NOT
152
+ re-drive the connector yourself.
153
+
154
+ Skip the entire step when no integrations are active and no mail /
155
+ notion observations are pending.
156
+
157
+ 5. Source-of-Truth tasks: read `<management_rules>` ## Source of Truth
158
+ → Tasks, call the matching endpoint, drop filtered-off items before
159
+ merge. Skip if no external source is configured.
160
+
161
+ 6. Roadmap ## Agent Action Plan — process items dated today or overdue
162
+ (without a `completed` Preparation Timeline row). Drop items whose
163
+ category focus is off, then:
164
+ - `[notify]` → one row in `today.md` ## Agent Plan (registered in
165
+ Step 7 below).
166
+ - `[today]` → collect for `today.md` ## User Tasks.
167
+ - `[check]` → one row in ## Agent Plan with trigger `check-in`
168
+ (registered in Step 7 below).
169
+ - If a roadmap row includes `[provisional ...]`, copy that tag and
170
+ its meaning into the eventual scheduled `taskDescription` so
171
+ `scheduled.task.md` frames the first contact as a confirmation
172
+ question, not a directive.
173
+ - Mark processed roadmap rows complete via `PATCH /api/context/roadmap`,
174
+ `section=agent_action_plan`, `mode=replace`, rewriting the exact
175
+ row from `- YYYY-MM-DD [tag]: ...` to
176
+ `- completed <today>: YYYY-MM-DD [tag]: ...`. Keep the entry ID
177
+ marker and all existing completed rows byte-for-byte.
178
+
179
+ Then generate **look-ahead entries** for tomorrow → +3 days by
180
+ cross-referencing unprocessed roadmap items against
181
+ `<calendar_events_7d>`. These go into `today.md` ## Agent Notes
182
+ using the skill's "Agent Notes flavor 1: Look-ahead checklist"
183
+ format (`- [ ] (HIGH/MID/LOW) ...`). Skip this step entirely if no
184
+ today-items and no look-ahead items exist.
185
+
186
+ **First-run note:** the roadmap may still be the setup-wizard
187
+ skeleton carrying `_(Not yet configured)_` placeholders. In that
188
+ case there are no Agent Action Plan rows to process; this step is
189
+ a no-op until Step 6b populates the roadmap inline.
190
+
191
+ ### Step 3 — Review overnight user-originated observations
192
+
193
+ 7. Call `GET /api/observations?pending=true&actor=user` (observations
194
+ skill). This is the **user-actor** complement to Step 2 — mail /
195
+ notion rows posted by the pre-pass / partials carry `actor=agent`
196
+ and have already been folded in. Step 3 picks up anything the user
197
+ themselves changed overnight (Obsidian edits, manual file drops,
198
+ git commits) that the daemon recorded under `actor=user`. Fold
199
+ only meaningful changes into the `today.md` draft you're building,
200
+ respecting the day-type filter.
201
+
202
+ ### Step 4 — Inbox triage (B-007 §5.9 Q5 case A)
203
+
204
+ 8. `GET /api/context/list/inbox` to enumerate pasted memos. For each
205
+ file:
206
+ - `GET /api/context/inbox/<file>` to read the body, then classify:
207
+ **project**, **user**, **memo**, **task**.
208
+ - Integrate into the right target:
209
+ - existing project → append to `projects/<slug>.md` (notify tier).
210
+ - new-project shape → DM to confirm *"create project `<slug>`?"*
211
+ and wait for reply before creating the file.
212
+ - New `projects/<slug>.md` files must include YAML frontmatter:
213
+ `type: project`, `owner: shared`, `updated: YYYY-MM-DD`, then
214
+ an H1.
215
+ - user dictionary (people / health / goals / …) → append to the
216
+ matching `user/<area>.md`.
217
+ - date-bound memo → summarize into `today.md` ## Agent Notes.
218
+ - unclassifiable → DM the user an excerpt asking what to do;
219
+ leave the file in `inbox/` for next pass.
220
+ - After integration, move the original: (a)
221
+ `PUT /api/context/agent/scratch/inbox-YYYY-MM-DD-<orig-slug>.md`
222
+ with the original body, then (b)
223
+ `DELETE /api/context/inbox/<file>` to remove the source. The
224
+ 30-day retention on `agent/scratch/` is a convention for now —
225
+ no sweeper exists yet.
226
+ - **High-risk triggers — DM for confirmation before writing:**
227
+ new project creation, wholesale overwrite of `user/profile.md`,
228
+ financial or health data with a numeric impact. The agent's own
229
+ judgment is the gate — call `POST /api/notify` with the proposed
230
+ change and wait for confirmation; don't auto-write. Increment
231
+ your running `inboxStats.dmConfirmsSent` counter (reported in
232
+ Step 9).
233
+ - **Hard stop (never write)** — if the memo contains anything that
234
+ looks like a credential, password, API key, or private token, do
235
+ NOT write it to any context file. Log one line to ## Agent Log
236
+ (`- HH:MM [inbox] skipped <file>: secret suspected`), leave the
237
+ source file in `inbox/` for the user to handle, and move on.
238
+ Increment your running `inboxStats.secretsSkipped` counter AND
239
+ append a string to your `anomalies` array
240
+ (`"secret suspected in <file>"`) so the audit trail surfaces the
241
+ skip — `agent_actions.metadata.inboxStats.secretsSkipped` is not
242
+ yet rendered in the daemon-emitted journal bullet. This
243
+ overrides the "DM then proceed" path above — see _safety.md.
244
+
245
+ Track counts as you triage so you can report them in Step 9:
246
+ `triaged` (every file you processed), `movedToScratch` (every
247
+ `PUT /api/context/agent/scratch/...` you sent), `dmConfirmsSent`
248
+ (every high-risk DM-confirm), `secretsSkipped` (every hard-stop).
249
+
250
+ ### Step 5 — Daily journal synthesis [handled by Stage B]
251
+
252
+ 9. The daily journal author (`routine.morning_routine_journal`) runs
253
+ in parallel with you and owns `daily/<yesterday>.md` end-to-end.
254
+ **Do NOT write `daily/*.md` in this session** — Stage B reads its
255
+ own `<journal_skeleton>` (deterministic frontmatter +
256
+ pre-aggregated facts from SQLite) and authors the body per
257
+ `rules/journal-format.md`. Skip this step entirely. Surface any
258
+ anomalies you spot about yesterday's data (corrupted yesterday.md,
259
+ missing SQLite rows) via the `anomalies` array you write in Step 9.
260
+
261
+ ### Step 6 — Generate new today.md (PUT full replace)
262
+
263
+ 10. Follow the context skill "Structure overview", "Entry formats",
264
+ and "Required sections for full replace" sections for the exact
265
+ schema. The H1 (line 1) MUST be
266
+ `# <current_agent_day.date> (<current_agent_day.weekday>)` exactly
267
+ — the daemon rejects mismatches with 422. No YAML frontmatter on
268
+ today.md. Agent Plan rows MUST match
269
+ `- [ ] HH:MM <action> [work|study|personal|home] →<DM|notify|check-in|wake>`;
270
+ any other category or trigger keyword is rejected and forces a
271
+ retry at medium tier.
272
+
273
+ Source → section mapping:
274
+ - ## User Schedule ← `<calendar_events_7d>` (filtered). Write
275
+ `- (calendar unavailable)` when the block has been replaced by
276
+ `<calendar_status>Calendar service not available...</calendar_status>`
277
+ (no active provider) or when every `<provider>` sub-block's
278
+ directive fetch failed for this run.
279
+ - ## User Tasks ← Step 1 handoff `<tomorrow>` (recurring only) +
280
+ Step 2 email actionables + SoT tasks + roadmap `[today]`. Use
281
+ `<active_projects>` for context.
282
+ - ## Agent Plan ← Step 2 `[notify]`/`[check]` rows plus any
283
+ proactive reminders you add (meeting pre-briefs, deadline
284
+ nudges). Every row will be registered in Step 7 in a single
285
+ batch — the Agent Plan contract is defined in the skill's
286
+ "User Tasks vs Agent Plan" section.
287
+ - ## Agent Notes ← Step 2 look-ahead items + date-bound memos
288
+ folded from Step 4 inbox triage.
289
+ - ## Agent Log ← initialize with
290
+ `- HH:MM Morning Routine completed (day-type: …)`. On a
291
+ first-run day, use
292
+ `- HH:MM Morning Routine (initial) completed (day-type: …)`
293
+ so the audit log distinguishes the first agent-day.
294
+ - ## Handoff ← Step 1 `<later>` items (recurring), or `- (none)`
295
+ (first-run, or recurring with no Later items). Drop past dates.
296
+
297
+ Track every context-file path you wrote (today.md, roadmap.md,
298
+ yesterday.md, dossiers/morning.md, projects/*.md, …) so you can
299
+ report it via `metadata.filesTouched` in Step 9.
300
+
301
+ ### Step 6b — Roadmap maintenance
302
+
303
+ 11. **Recurring:** Update `roadmap.md` only if a milestone completed
304
+ or shifted today.
305
+
306
+ **First-run — populate roadmap.md inline.** On the very first
307
+ morning routine the setup wizard's skeleton roadmap is still in
308
+ place (the `## Annual Goals`, `## Quarterly Focus`, and
309
+ `## Agent Action Plan` sections all contain the placeholder line
310
+ `_(Not yet configured)_`). When *any* of those placeholders is
311
+ still present, the daemon has injected a `<roadmap_skeleton>`
312
+ block carrying pre-aggregated scratch data — Annual Goals
313
+ extracted from `rules/management.md`, active projects + 7-day
314
+ calendar for Quarterly Focus, upcoming `travel_bookings` for
315
+ Preparation Timeline. **Read `<roadmap_skeleton>` first**: use
316
+ its data as the source for your populate, reshape / prune /
317
+ reword as the roadmap.md operator template (and your judgement
318
+ about which projects / events are actually relevant) dictates.
319
+ The skeleton has no byte-for-byte preservation contract — it is
320
+ scratch input, not output. Compose the `## Agent Action Plan`
321
+ section yourself from today's User Tasks + roadmap-relevant
322
+ `agent_schedule` rows (the skeleton deliberately omits this
323
+ section because it ages on the same agent-day cadence as
324
+ today.md). Acquire the cross-request write lock via the skill
325
+ before any `PUT /api/context/roadmap` — the daemon enforces it
326
+ and a missing lock returns 423. If every placeholder has already
327
+ been replaced (rare: a previous first-run completed this step
328
+ then today.md failed, or a manual edit landed), the
329
+ `<roadmap_skeleton>` block may still be injected; fall back to
330
+ the recurring semantics regardless and spot-update only if a
331
+ milestone completed or shifted. Skipping this branch leaves
332
+ roadmap.md as the wizard skeleton — the daemon's
333
+ `isRoadmapStale()` post-hook would then schedule a separate
334
+ `routine.roadmap_refresh` to make it good, but the user would
335
+ see a blank-looking roadmap until that second session lands.
336
+ Doing it inline here is one medium-tier turn instead of two and
337
+ removes ~1–2 minutes of post-setup latency.
338
+
339
+ ### Step 7 — Register schedule (single batch POST)
340
+
341
+ 12. Register every `## Agent Plan` row in **one** call to
342
+ `POST /api/schedule/batch`. Per the `schedule` skill's
343
+ "POST /api/schedule/batch" section, atomic-by-default and each
344
+ row carries a rich `taskContext` so the future
345
+ `scheduled.task` / `scheduled.dm` session has the context it
346
+ needs hours later — the daemon cannot reconstruct it from the
347
+ user-facing Agent Plan line.
348
+
349
+ **Per-row composition.** For every `- [ ] HH:MM <action>
350
+ [cat] →<trigger>` line you wrote to ## Agent Plan, compose one
351
+ batch row:
352
+
353
+ - `scheduledFor`: ISO 8601 with timezone offset from `HH:MM` +
354
+ today's date.
355
+ - `taskType`: `wake` for `→DM` / `→notify` / `→check-in`
356
+ triggers; `dm_session` for `→wake` triggers that should run as
357
+ an interactive DM.
358
+ - `taskDescription`: self-contained (min 20 chars). Same shape
359
+ as the schedule skill's "Writing a Good Description" — verb +
360
+ object + concrete names. Copy any `[provisional ...]` framing
361
+ from the roadmap row.
362
+ - `taskContext.background` (min 30 chars): why this is being
363
+ scheduled — the trigger (roadmap row, calendar event,
364
+ handoff), and what the future session needs to know upfront
365
+ that it could not derive from today.md alone.
366
+ - `taskContext.expected_output` (min 20 chars): what the future
367
+ session should produce (DM shape, file written, check verdict).
368
+ - `taskContext.references` (optional): stable handles the future
369
+ session can look up (`projects/<slug>.md#section`,
370
+ `calendar:event:<id>`, `daily/YYYY-MM-DD.md#agent-revision`,
371
+ roadmap entry id markers).
372
+ - `taskContext.tone` (optional): tone hint for DM-shaped output.
373
+ - `taskContext.scheduledBy`: `"morning_routine"`.
374
+
375
+ Pre-flight dedup per the `schedule` skill's "Before creating —
376
+ dedup pre-check" section: scan `<today>` ## Agent Plan,
377
+ pending+running schedules, recurring rules. Drop any row already
378
+ covered before composing the batch — do not POST it.
379
+
380
+ **POST the batch.** Each row carries **either** `tier`
381
+ (`lite`/`medium`/`high`, the default cost knob) **or** `model` (a
382
+ registered id like `claude-opus-4-7`, a legacy alias `sonnet`/`opus`,
383
+ or composite `<backendId>/<modelId>`) — never both. Prefer `tier`;
384
+ only pin `model` for rows that must outlive a `/settings/models`
385
+ re-route (e.g. a row whose `expected_output` depends on Opus-class
386
+ reasoning). Omit both fields to let the dispatcher's process-key
387
+ default decide.
388
+
389
+ ```bash
390
+ curl -s -X POST http://localhost:8321/api/schedule/batch \
391
+ -H 'Content-Type: application/json' \
392
+ --json @- <<'JSON'
393
+ {
394
+ "rows": [
395
+ {
396
+ "scheduledFor": "2026-05-15T14:30:00-04:00",
397
+ "taskType": "wake",
398
+ "taskDescription": "Pre-brief the 15:00 standup with the two open Q2 risks.",
399
+ "tier": "medium",
400
+ "taskContext": {
401
+ "background": "User flagged Q2 roadmap risks in yesterday's DM; standup needs the two open items front-loaded so the team aligns before 15:30.",
402
+ "expected_output": "DM with two bullet items + one suggested mitigation each, sent 30 min before standup.",
403
+ "references": ["projects/q2-roadmap.md#open-risks", "calendar:event:standup-2026-05-15"],
404
+ "tone": "concise",
405
+ "scheduledBy": "morning_routine"
406
+ }
407
+ },
408
+ {
409
+ "scheduledFor": "2026-05-15T20:00:00-04:00",
410
+ "taskType": "wake",
411
+ "taskDescription": "Synthesise the Q2 roadmap revision draft based on today's risk discussion.",
412
+ "model": "claude-opus-4-7",
413
+ "taskContext": {
414
+ "background": "User asked at standup for a written revision proposal by EOD; row pins Opus because the draft quality depends on the higher-tier reasoning.",
415
+ "expected_output": "projects/q2-roadmap.md revision section appended with three concrete proposals + rationale.",
416
+ "references": ["projects/q2-roadmap.md"],
417
+ "scheduledBy": "morning_routine"
418
+ }
419
+ }
420
+ ],
421
+ "atomic": true
422
+ }
423
+ JSON
424
+ ```
425
+
426
+ Per-row issues (`schedule.model_unknown`,
427
+ `schedule.tier_and_model_conflict`) carry `rowIndex` in the
428
+ `errors[]` envelope; map the index back to your `rows` array,
429
+ fix in place, and resubmit the entire batch (`atomic:true`).
430
+ `warnings[]` may carry `schedule.model_deprecated` —
431
+ persistence still happens; surface the warning in anomalies.
432
+
433
+ **Cardinality invariant.** `len(rows POSTed) === len(## Agent
434
+ Plan rows you wrote in Step 6, minus duplicates dropped by
435
+ pre-flight dedup)`. The daemon does NOT enforce this — verify it
436
+ yourself before POSTing. On mismatch, append a string to your
437
+ `anomalies` array
438
+ (`"AgentPlan cardinality mismatch: today.md has N rows, batch
439
+ had M"`) so the audit trail surfaces the gap, and remember the
440
+ POSTed count for Step 9's `metadata.scheduleBatchSize`.
441
+
442
+ **Error handling.** A 422 response carries the
443
+ agent-consumable envelope (`{ errors: [...], retryable: true }`).
444
+ Per the `schedule` skill's `## Errors` section, read each
445
+ `errors[].hint`, fix the value at `errors[].field`, and POST the
446
+ full body again — `atomic:true` means no rows committed, so
447
+ resubmit the entire batch. Do not retry against a different
448
+ field path; do not loop more than twice (after two failed
449
+ attempts append a string to your `anomalies` array and continue
450
+ — Stage B and Step 9 still need to run).
451
+
452
+ > **Morning briefing scheduling moved.** The morning briefing is no
453
+ > longer registered here. It is a `recurring_schedules` row
454
+ > (`task_type='dm_session'`, `task_context.sub_flow='morning_briefing'`)
455
+ > created at setup completion and reconciled daily by the daemon. The
456
+ > firing session runs under the `conversational` profile via the
457
+ > `scheduled.dm.md` task-flow. See SCHEDULED-DM-IMPLEMENTATION-PLAN.md.
458
+
459
+ 13. **First-run only — ensure the daily morning briefing recurring
460
+ schedule exists.** The setup wizard's
461
+ `ensureMorningBriefingRecurring`
462
+ (`packages/daemon/src/api/routes/setup.ts`) normally seeds this
463
+ row at first save-rules, so the daily fire path is daemon-owned
464
+ and the description is hardcoded. The check below covers the
465
+ rare case where setup completed without the seeder (legacy
466
+ setup, partial DB restore).
467
+
468
+ Skip this step on recurring days — the row already exists.
469
+
470
+ a. **Pre-flight.** `GET /api/recurring-schedules?enabled=true`
471
+ and scan for an item with `taskType === "dm_session"` AND
472
+ `taskContext.sub_flow === "morning_briefing"`. If found, skip
473
+ the rest of this step — duplicate insertion would cause
474
+ double daily fires. Log one line to `## Agent Log`:
475
+ `- HH:MM [morning_routine] morning briefing recurring already seeded`.
476
+
477
+ b. **If absent, register via `POST /api/recurring-schedules`**
478
+ (NOT batch / not `POST /api/schedule`) with this body:
479
+
480
+ ```json
481
+ {
482
+ "taskType": "dm_session",
483
+ "description": "morning briefing — daily summary",
484
+ "recurrenceRule": {
485
+ "frequency": "daily",
486
+ "time": "<quiet_hours_end or 08:00>",
487
+ "timezone": "<user timezone from <settings primary_timezone> or system default>"
488
+ },
489
+ "taskContext": {
490
+ "sub_flow": "morning_briefing",
491
+ "pin_to_quiet_hours_end": true
492
+ }
493
+ }
494
+ ```
495
+
496
+ The `dm_session` task_type + `sub_flow=morning_briefing` is
497
+ the activation key the daemon's scheduler keys off to emit a
498
+ `scheduled.dm` event. Description ≥ 20 chars per the schema;
499
+ `"morning briefing — daily summary"` matches the wording the
500
+ daemon's seeder uses verbatim.
501
+
502
+ Do **not** add a one-off `## Agent Plan` row for today's
503
+ briefing here. The recurring-schedule reconciler materialises
504
+ today's `agent_schedule` row automatically from `next_run_at`;
505
+ hand-seeding would duplicate. Do **not** send the briefing
506
+ yourself from this run — this runs during quiet hours.
507
+
508
+ ### Step 7.5 — Profile-interview queue (latent, two-phase)
509
+
510
+ Use the **user-interview** skill. Phase (a) ALWAYS runs (it is what
511
+ keeps today.md's ## Agent Notes mirror in sync across day boundaries,
512
+ since today.md is PUT-replaced fresh each morning); phase (b) only
513
+ runs when there is no open question.
514
+
515
+ #### Step 7.5a — Mirror existing latent entries to today.md (always)
516
+
517
+ GET `agent/profile-questions.md ## In Progress`. For every entry
518
+ whose state is `latent` (NOT `asked` — those have already been
519
+ answered or will be cleaned up by the sweep), append one line to
520
+ `today.md` `## Agent Notes` using the **today** skill's "Latent
521
+ profile question" Agent Notes flavor:
522
+
523
+ ```
524
+ - Profile question (latent): <id> — wait for natural opportunity
525
+ ```
526
+
527
+ This is the only writer of the `Profile question (latent):` line.
528
+ Without it, a row that stays latent across multiple days disappears
529
+ from today.md after day 1's PUT-replace and the DM-handler /
530
+ morning-briefing opportunity checks lose their visible cue.
531
+
532
+ #### Step 7.5b — Pick a new question (conditional)
533
+
534
+ Skip phase (b) entirely if any of:
535
+ (a) `## In Progress` is non-empty (a prior latent / asked entry is
536
+ already open — we hold to the 1-question-at-a-time invariant).
537
+ (b) The user has not sent a DM in the last 24h (no point if
538
+ they're absent).
539
+ (c) Day-type focus for `[personal]` on line 2 of `<today>` is `off`.
540
+ (d) `## Pending` is empty.
541
+
542
+ Otherwise, walk Pending rows in priority order (HIGH → MID → LOW,
543
+ then file order). For each candidate:
544
+ - If the row carries `<!-- last_attempted=YYYY-MM-DD -->` within
545
+ the last 7 days, skip — cooldown.
546
+ - GET `/api/profile-questions/slot-filled?path=<target>&section=<section?>&anchor=<anchor?>`
547
+ for the row. If `filled: true`, the slot was filled since the
548
+ last sweep — tick the row `[ ]` → `[x]` (read-rebuild + replace),
549
+ append `- [x] <today> → <id> (reconciled:morning)` to
550
+ `## Answered`, continue to the next candidate.
551
+ - Otherwise this is the chosen row. Stop walking.
552
+
553
+ If a row was chosen:
554
+
555
+ 1. PATCH `agent/profile-questions.md ## In Progress` (read-rebuild +
556
+ replace) — add a single entry. The `since=<today>` field is
557
+ load-bearing for the evening sweep's 3-day fallback computation:
558
+ ```
559
+ - <id> :: state=latent :: since=<today>
560
+ ```
561
+ 2. PATCH `today.md ## Agent Notes` (mode=append) — same flavor as
562
+ phase (a):
563
+ ```
564
+ - Profile question (latent): <id> — wait for natural opportunity
565
+ ```
566
+
567
+ **Do NOT register a `POST /api/schedule` (single OR batch) for this
568
+ row.** Latent rows are NOT scheduled DMs — they wait for a natural
569
+ opportunity (DM topic match or morning briefing piggyback). The
570
+ fallback DM path is owned by the evening sweep (Operation 5B), not
571
+ the morning routine.
572
+
573
+ ### Step 8 — Extension checks from routines/morning.md
574
+
575
+ 14. The `Morning routine checks` policy block above is the
576
+ user-editable extension surface. Execute any check listed there
577
+ that is **not already covered by Steps 1-7**. User-added entries
578
+ typically carry an `**Added: YYYY-MM-DD by user via DM**` line —
579
+ those are your target. Remember the short label of every check
580
+ you executed (e.g. `"water bottle filled"`, `"calendar synced"`)
581
+ — Step 9 reports them via `metadata.morningChecks`.
582
+
583
+ ### Step 9 — Self-report structured metadata (single PATCH)
584
+
585
+ 15. The daemon's `AgentJournalAppender` writes the morning-routine
586
+ paragraph to `agent/journal.md` from **structured metadata you
587
+ patch onto your own `agent_actions` row** — no LLM final-text
588
+ parsing. Use the `agent-actions` skill's "PATCH /api/agent-actions/self"
589
+ endpoint to publish the metadata exactly once near the end of
590
+ your turn, after every other side-effect has settled:
591
+
592
+ ```bash
593
+ curl -s -X PATCH http://localhost:8321/api/agent-actions/self \
594
+ -H 'Content-Type: application/json' \
595
+ --json @- <<'JSON'
596
+ {
597
+ "metadata": {
598
+ "dayType": "weekday",
599
+ "anomalies": ["pre-pass partial (gmail)"],
600
+ "filesTouched": ["context/today.md", "context/roadmap.md"],
601
+ "inboxStats": {
602
+ "triaged": 4,
603
+ "movedToScratch": 4,
604
+ "dmConfirmsSent": 1,
605
+ "secretsSkipped": 0
606
+ },
607
+ "morningChecks": ["water bottle filled", "calendar synced"],
608
+ "scheduleBatchSize": 3
609
+ }
610
+ }
611
+ JSON
612
+ ```
613
+
614
+ Field shapes (see the `agent-actions` skill `## Metadata shape`
615
+ table for the full contract):
616
+
617
+ - `dayType` — the string you derived in Step 1.3 (the second
618
+ line of today.md is the authoritative form).
619
+ - `anomalies` — `string[]` of short English notes. Empty array
620
+ when none. Cover at minimum: secret-suspected hard stops
621
+ (Step 4), did-not-fire mid-execution anomalies (Step 1.2),
622
+ schedule batch retries (Step 7), AgentPlan / batch cardinality
623
+ mismatches, Stage B-visible data corruption you spotted.
624
+ - `filesTouched` — `string[]` of every `/api/context/*` path you
625
+ wrote or patched during this run. Include `context/today.md`,
626
+ `context/roadmap.md` (if updated), `context/dossiers/morning.md`,
627
+ `context/yesterday.md` (if you patched did-not-fire rows),
628
+ `context/projects/<slug>.md` (if Step 4 created or appended to
629
+ one), `context/user/<area>.md`, `context/agent/profile-questions.md`
630
+ (if Step 7.5b chose a question), `context/agent/scratch/...`
631
+ (one entry per inbox file moved).
632
+ - `inboxStats` — running counts from Step 4. All keys integers
633
+ ≥ 0. Emit `{0,0,0,0}` when Step 4 was a no-op (empty inbox).
634
+ - `morningChecks` — `string[]` of short labels for every Step 8
635
+ extension check you executed. Empty array when there were
636
+ none. The daemon renders the list joined with `, ` into the
637
+ `Checks from routines/morning.md:` bullet.
638
+ - `scheduleBatchSize` — the number of rows you POSTed to
639
+ `/api/schedule/batch` in Step 7. `0` when no rows were
640
+ registered (cardinality contract: this should equal the
641
+ number of `## Agent Plan` rows minus dedup-drops).
642
+
643
+ A single PATCH per turn. Repeat PATCHes shallow-merge (later
644
+ keys win), but the daemon expects one consolidated call so the
645
+ journal entry reads cleanly. The daemon's appender will surface
646
+ these fields in `agent/journal.md` on a recurring day as:
647
+
648
+ ```
649
+ ## YYYY-MM-DD morning routine
650
+ - Day-type: <dayType>
651
+ - Journal: daily/YYYY-MM-DD.md (<N lines, M projects referenced>)
652
+ - Inbox: <triaged> files triaged, <movedToScratch> moved to scratch, <dmConfirmsSent> DM-confirmations sent
653
+ - Checks from routines/morning.md: <morningChecks joined>
654
+ - Anomalies / skipped steps: <anomalies joined or "(none)">
655
+ ```
656
+
657
+ On a first-run day (Stage B skipped, no `daily/<date>.md`
658
+ landed) the `Journal:` line becomes
659
+ `- Journal synthesis: skipped (no prior-day data)` automatically
660
+ — the daemon derives the variant from disk state, you do NOT
661
+ need a flag in metadata.
662
+
663
+ If the PATCH returns `agent_actions.session_row_not_found`
664
+ (404), the dispatcher has not pre-inserted your in-flight row —
665
+ surface a one-line warning to `## Agent Log`
666
+ (`- HH:MM [morning_routine] agent-self self-report 404 — no in-flight row`)
667
+ and continue. Do NOT block the turn on telemetry, and do NOT
668
+ fall back to writing `agent/journal.md` directly (the daemon
669
+ owns that file in V2; a direct write would race).
670
+
671
+ <output_language>english_only — Policy A surface (agent journal,
672
+ parsed log); `<output_language_policy>` carves this out
673
+ explicitly.</output_language>