@aitne-sh/aitne 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (249) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +464 -0
  3. package/agent-assets/agent-profiles/_safety.md +26 -0
  4. package/agent-assets/agent-profiles/conversational.md +33 -0
  5. package/agent-assets/agent-profiles/docs-qa.md +24 -0
  6. package/agent-assets/agent-profiles/observer.md +28 -0
  7. package/agent-assets/agent-profiles/profile-importer.md +63 -0
  8. package/agent-assets/agent-profiles/proxy.md +28 -0
  9. package/agent-assets/agent-profiles/routine.md +16 -0
  10. package/agent-assets/agent-profiles/task.md +18 -0
  11. package/agent-assets/docs/concepts/agent-day.md +88 -0
  12. package/agent-assets/docs/concepts/auth-health.md +75 -0
  13. package/agent-assets/docs/concepts/backends-and-tiers.md +126 -0
  14. package/agent-assets/docs/concepts/costs-and-quotas.md +103 -0
  15. package/agent-assets/docs/concepts/delegated-mode.md +223 -0
  16. package/agent-assets/docs/concepts/memory-model.md +118 -0
  17. package/agent-assets/docs/concepts/observations.md +80 -0
  18. package/agent-assets/docs/concepts/process-keys.md +89 -0
  19. package/agent-assets/docs/concepts/routines.md +108 -0
  20. package/agent-assets/docs/concepts/safety-and-execution.md +109 -0
  21. package/agent-assets/docs/concepts/safety-model.md +279 -0
  22. package/agent-assets/docs/concepts/skills.md +100 -0
  23. package/agent-assets/docs/features/integrations/calendar.md +92 -0
  24. package/agent-assets/docs/features/integrations/git.md +95 -0
  25. package/agent-assets/docs/features/integrations/github.md +170 -0
  26. package/agent-assets/docs/features/integrations/mail.md +106 -0
  27. package/agent-assets/docs/features/integrations/notion.md +69 -0
  28. package/agent-assets/docs/features/integrations/obsidian.md +71 -0
  29. package/agent-assets/docs/features/lifestyle/git.md +178 -0
  30. package/agent-assets/docs/features/lifestyle/reading.md +93 -0
  31. package/agent-assets/docs/features/lifestyle/receipts.md +71 -0
  32. package/agent-assets/docs/features/lifestyle/travel-bookings.md +44 -0
  33. package/agent-assets/docs/features/lifestyle/travel-time.md +52 -0
  34. package/agent-assets/docs/features/memory-files/agent-journal.md +105 -0
  35. package/agent-assets/docs/features/memory-files/projects.md +56 -0
  36. package/agent-assets/docs/features/memory-files/roadmap.md +61 -0
  37. package/agent-assets/docs/features/memory-files/schedule.md +112 -0
  38. package/agent-assets/docs/features/memory-files/today.md +73 -0
  39. package/agent-assets/docs/features/memory-files/user-profile.md +81 -0
  40. package/agent-assets/docs/features/messaging/dashboard-chat.md +93 -0
  41. package/agent-assets/docs/features/messaging/discord.md +50 -0
  42. package/agent-assets/docs/features/messaging/overview.md +111 -0
  43. package/agent-assets/docs/features/messaging/pairing-and-magic-phrase.md +69 -0
  44. package/agent-assets/docs/features/messaging/slack.md +51 -0
  45. package/agent-assets/docs/features/messaging/telegram.md +63 -0
  46. package/agent-assets/docs/features/messaging/whatsapp.md +48 -0
  47. package/agent-assets/docs/features/operations/activity-and-conversations.md +105 -0
  48. package/agent-assets/docs/features/operations/approvals.md +58 -0
  49. package/agent-assets/docs/features/operations/backend-routing.md +62 -0
  50. package/agent-assets/docs/features/operations/cost-tracking.md +59 -0
  51. package/agent-assets/docs/features/operations/notifications.md +69 -0
  52. package/agent-assets/docs/features/operations/quiet-hours.md +106 -0
  53. package/agent-assets/docs/features/operations/schedule-approaching.md +60 -0
  54. package/agent-assets/docs/features/routines/custom-routines.md +101 -0
  55. package/agent-assets/docs/features/routines/evening-review.md +81 -0
  56. package/agent-assets/docs/features/routines/hourly-check.md +85 -0
  57. package/agent-assets/docs/features/routines/monthly-review.md +65 -0
  58. package/agent-assets/docs/features/routines/morning-routine.md +123 -0
  59. package/agent-assets/docs/features/routines/weekly-review.md +70 -0
  60. package/agent-assets/docs/getting-started/01-what-is-this.md +192 -0
  61. package/agent-assets/docs/getting-started/02-first-steps.md +80 -0
  62. package/agent-assets/docs/getting-started/03-what-can-this-do.md +110 -0
  63. package/agent-assets/docs/getting-started/04-first-day.md +287 -0
  64. package/agent-assets/docs/glossary.md +116 -0
  65. package/agent-assets/docs/guides/add-a-custom-routine.md +71 -0
  66. package/agent-assets/docs/guides/backup-and-restore.md +54 -0
  67. package/agent-assets/docs/guides/change-which-model-handles-x.md +47 -0
  68. package/agent-assets/docs/guides/connect-a-new-mail-account.md +59 -0
  69. package/agent-assets/docs/guides/import-knowledge-file.md +275 -0
  70. package/agent-assets/docs/guides/install-and-run.md +72 -0
  71. package/agent-assets/docs/guides/migrate-machines.md +52 -0
  72. package/agent-assets/docs/guides/pause-the-agent.md +65 -0
  73. package/agent-assets/docs/guides/reinstall-cleanly.md +52 -0
  74. package/agent-assets/docs/guides/setup-wizard.md +107 -0
  75. package/agent-assets/docs/guides/switch-default-backend.md +60 -0
  76. package/agent-assets/docs/reference/api.md +51 -0
  77. package/agent-assets/docs/reference/cli-commands.md +121 -0
  78. package/agent-assets/docs/reference/config.md +74 -0
  79. package/agent-assets/docs/reference/disallowed-tools.md +76 -0
  80. package/agent-assets/docs/reference/keyboard-shortcuts.md +39 -0
  81. package/agent-assets/docs/reference/process-keys.md +59 -0
  82. package/agent-assets/docs/reference/skills.md +50 -0
  83. package/agent-assets/docs/troubleshooting/auth-failed.md +57 -0
  84. package/agent-assets/docs/troubleshooting/dashboard-shows-degraded.md +55 -0
  85. package/agent-assets/docs/troubleshooting/fallback-keeps-firing.md +54 -0
  86. package/agent-assets/docs/troubleshooting/messaging-not-pairing.md +53 -0
  87. package/agent-assets/docs/troubleshooting/morning-routine-didnt-run.md +75 -0
  88. package/agent-assets/docs/troubleshooting/observation-not-detected.md +57 -0
  89. package/agent-assets/docs/troubleshooting/quota-exhausted.md +57 -0
  90. package/agent-assets/optimizer-skills/drift-analysis/SKILL.md +75 -0
  91. package/agent-assets/optimizer-skills/knowledge-map/SKILL.md +71 -0
  92. package/agent-assets/optimizer-skills/skill-curation/SKILL.md +108 -0
  93. package/agent-assets/project-doc-templates/git-repo.md +21 -0
  94. package/agent-assets/project-doc-templates/project.md +38 -0
  95. package/agent-assets/skills/attach/SKILL.md +104 -0
  96. package/agent-assets/skills/context/SKILL.md +257 -0
  97. package/agent-assets/skills/context/curation.json +37 -0
  98. package/agent-assets/skills/context/seeds/file-responsibilities.seed.json +13 -0
  99. package/agent-assets/skills/context/seeds/frontmatter-requirements.seed.json +40 -0
  100. package/agent-assets/skills/docs-search/SKILL.md +176 -0
  101. package/agent-assets/skills/external-services/SKILL.delegated.claude.md +369 -0
  102. package/agent-assets/skills/external-services/SKILL.delegated.codex.md +349 -0
  103. package/agent-assets/skills/external-services/SKILL.delegated.gemini.md +347 -0
  104. package/agent-assets/skills/external-services/SKILL.md +371 -0
  105. package/agent-assets/skills/mail/SKILL.delegated.claude.md +284 -0
  106. package/agent-assets/skills/mail/SKILL.delegated.codex.md +261 -0
  107. package/agent-assets/skills/mail/SKILL.delegated.gemini.md +255 -0
  108. package/agent-assets/skills/mail/SKILL.md +313 -0
  109. package/agent-assets/skills/mail/references/errors.md +17 -0
  110. package/agent-assets/skills/mail/references/providers.md +40 -0
  111. package/agent-assets/skills/mail/references/query-grammar.md +24 -0
  112. package/agent-assets/skills/management-policy/SKILL.md +307 -0
  113. package/agent-assets/skills/management-policy/curation.json +13 -0
  114. package/agent-assets/skills/management-policy/seeds/policy-file-shape.seed.json +16 -0
  115. package/agent-assets/skills/management-task-modify/SKILL.md +202 -0
  116. package/agent-assets/skills/management-task-register/SKILL.md +330 -0
  117. package/agent-assets/skills/management-task-stop/SKILL.md +166 -0
  118. package/agent-assets/skills/notify/SKILL.md +196 -0
  119. package/agent-assets/skills/notion/SKILL.delegated.claude.md +254 -0
  120. package/agent-assets/skills/notion/SKILL.delegated.codex.md +195 -0
  121. package/agent-assets/skills/notion/SKILL.delegated.gemini.md +194 -0
  122. package/agent-assets/skills/notion/SKILL.md +86 -0
  123. package/agent-assets/skills/observations/SKILL.md +234 -0
  124. package/agent-assets/skills/observations/curation.json +13 -0
  125. package/agent-assets/skills/observations/seeds/source-namespacing.seed.json +20 -0
  126. package/agent-assets/skills/project-doc/SKILL.md +86 -0
  127. package/agent-assets/skills/project-doc/curation.json +21 -0
  128. package/agent-assets/skills/project-doc/seeds/project-shape.seed.json +25 -0
  129. package/agent-assets/skills/project-doc/seeds/slug-grammar.seed.json +20 -0
  130. package/agent-assets/skills/reading/SKILL.md +198 -0
  131. package/agent-assets/skills/reading/references/reading-taste.md +197 -0
  132. package/agent-assets/skills/receipts/SKILL.md +134 -0
  133. package/agent-assets/skills/roadmap/SKILL.md +276 -0
  134. package/agent-assets/skills/roadmap/curation.json +13 -0
  135. package/agent-assets/skills/roadmap/references/horizon-tags.md +40 -0
  136. package/agent-assets/skills/roadmap/references/preparation-timeline.md +47 -0
  137. package/agent-assets/skills/roadmap/seeds/entry-types.seed.json +16 -0
  138. package/agent-assets/skills/schedule/SKILL.md +228 -0
  139. package/agent-assets/skills/scheduled-managed-task/SKILL.md +392 -0
  140. package/agent-assets/skills/today/SKILL.md +198 -0
  141. package/agent-assets/skills/today/curation.json +21 -0
  142. package/agent-assets/skills/today/seeds/agent-notes-flavors.seed.json +17 -0
  143. package/agent-assets/skills/today/seeds/section-shape.seed.json +17 -0
  144. package/agent-assets/skills/travel/SKILL.md +132 -0
  145. package/agent-assets/skills/travel-time/SKILL.md +149 -0
  146. package/agent-assets/skills/user-interview/SKILL.md +323 -0
  147. package/agent-assets/skills/user-interview/references/sweep-and-fallback.md +94 -0
  148. package/agent-assets/skills/user-profile/SKILL.md +210 -0
  149. package/agent-assets/skills/user-profile/curation.json +29 -0
  150. package/agent-assets/skills/user-profile/seeds/learned-context-format.seed.json +14 -0
  151. package/agent-assets/skills/user-profile/seeds/routing-table.seed.json +53 -0
  152. package/agent-assets/skills/user-profile/seeds/topic-files.seed.json +27 -0
  153. package/agent-assets/task-flows/dashboard.docs_qa.md +43 -0
  154. package/agent-assets/task-flows/default.md +11 -0
  155. package/agent-assets/task-flows/git.branch.created.md +25 -0
  156. package/agent-assets/task-flows/git.lifecycle.poll.md +52 -0
  157. package/agent-assets/task-flows/git.local_ahead.stale.md +34 -0
  158. package/agent-assets/task-flows/git.merge_to_default.md +30 -0
  159. package/agent-assets/task-flows/git.project.refresh_architecture.md +100 -0
  160. package/agent-assets/task-flows/git.project.retemplate.md +73 -0
  161. package/agent-assets/task-flows/git.push.detected.md +32 -0
  162. package/agent-assets/task-flows/git.push.force_pushed.md +36 -0
  163. package/agent-assets/task-flows/git.tag.created.md +24 -0
  164. package/agent-assets/task-flows/github.assigned.md +43 -0
  165. package/agent-assets/task-flows/github.pull_request.review_requested.md +57 -0
  166. package/agent-assets/task-flows/github.security_alert.md +45 -0
  167. package/agent-assets/task-flows/github.workflow_run.failed.md +57 -0
  168. package/agent-assets/task-flows/knowledge.import.md +161 -0
  169. package/agent-assets/task-flows/message.received.dm.md +142 -0
  170. package/agent-assets/task-flows/message.received.dm_first.md +117 -0
  171. package/agent-assets/task-flows/message.received.md +14 -0
  172. package/agent-assets/task-flows/routine.custom.md +38 -0
  173. package/agent-assets/task-flows/routine.evening_review.md +323 -0
  174. package/agent-assets/task-flows/routine.hourly_check.delegated.claude.md +405 -0
  175. package/agent-assets/task-flows/routine.hourly_check.delegated.codex.md +400 -0
  176. package/agent-assets/task-flows/routine.hourly_check.delegated.gemini.md +404 -0
  177. package/agent-assets/task-flows/routine.hourly_check.md +184 -0
  178. package/agent-assets/task-flows/routine.hourly_check.triage.md +93 -0
  179. package/agent-assets/task-flows/routine.monthly_review.md +250 -0
  180. package/agent-assets/task-flows/routine.morning_routine.md +300 -0
  181. package/agent-assets/task-flows/routine.morning_routine_initial.md +184 -0
  182. package/agent-assets/task-flows/routine.roadmap_refresh.md +275 -0
  183. package/agent-assets/task-flows/routine.today_refresh.md +172 -0
  184. package/agent-assets/task-flows/routine.user_profile_sweep.md +242 -0
  185. package/agent-assets/task-flows/routine.weekly_review.md +247 -0
  186. package/agent-assets/task-flows/schedule.approaching.md +124 -0
  187. package/agent-assets/task-flows/scheduled.dm.md +391 -0
  188. package/agent-assets/task-flows/scheduled.task.md +141 -0
  189. package/agent-assets/task-flows/setup.initial.md +277 -0
  190. package/agent-assets/task-flows/setup.update.md +53 -0
  191. package/agent-assets/templates/README.md +85 -0
  192. package/agent-assets/templates/_index.md +39 -0
  193. package/agent-assets/templates/_manifest.json +103 -0
  194. package/agent-assets/templates/agent/journal.md +10 -0
  195. package/agent-assets/templates/agent/profile-questions.md +74 -0
  196. package/agent-assets/templates/context-index.md +42 -0
  197. package/agent-assets/templates/dossiers/_index.md +22 -0
  198. package/agent-assets/templates/dossiers/evening.md +23 -0
  199. package/agent-assets/templates/dossiers/hourly.md +23 -0
  200. package/agent-assets/templates/dossiers/monthly.md +23 -0
  201. package/agent-assets/templates/dossiers/morning.md +23 -0
  202. package/agent-assets/templates/dossiers/roadmap.md +23 -0
  203. package/agent-assets/templates/dossiers/weekly.md +23 -0
  204. package/agent-assets/templates/projects/_active.base +14 -0
  205. package/agent-assets/templates/projects/_index.md +29 -0
  206. package/agent-assets/templates/roadmap.md +15 -0
  207. package/agent-assets/templates/routines/_index.md +20 -0
  208. package/agent-assets/templates/routines/evening.md +22 -0
  209. package/agent-assets/templates/routines/hourly.md +30 -0
  210. package/agent-assets/templates/routines/monthly.md +25 -0
  211. package/agent-assets/templates/routines/morning.md +26 -0
  212. package/agent-assets/templates/routines/weekly.md +23 -0
  213. package/agent-assets/templates/rules/_index.md +19 -0
  214. package/agent-assets/templates/rules/journal-export.md +41 -0
  215. package/agent-assets/templates/rules/journal-format.md +61 -0
  216. package/agent-assets/templates/rules/management.md +48 -0
  217. package/agent-assets/templates/rules/mcp.md +40 -0
  218. package/agent-assets/templates/rules/policies/_index.md +22 -0
  219. package/agent-assets/templates/rules/redaction.md +30 -0
  220. package/agent-assets/templates/today.md +13 -0
  221. package/agent-assets/templates/user/_index.md +16 -0
  222. package/agent-assets/templates/user/expertise.md +7 -0
  223. package/agent-assets/templates/user/goals.md +7 -0
  224. package/agent-assets/templates/user/people.md +7 -0
  225. package/agent-assets/templates/user/personal.md +7 -0
  226. package/agent-assets/templates/user/profile.md +28 -0
  227. package/agent-assets/templates/user/work.md +7 -0
  228. package/bin/aitne.mjs +1096 -0
  229. package/package.json +78 -0
  230. package/personal-agent.mjs +39 -0
  231. package/scripts/browser.mjs +99 -0
  232. package/scripts/check-redaction-coverage.mjs +109 -0
  233. package/scripts/commands/audit.mjs +309 -0
  234. package/scripts/commands/doctor.mjs +437 -0
  235. package/scripts/commands/open.mjs +40 -0
  236. package/scripts/commands/setup.mjs +21 -0
  237. package/scripts/commands/uninstall.mjs +114 -0
  238. package/scripts/commands/update.mjs +96 -0
  239. package/scripts/commands/version.mjs +62 -0
  240. package/scripts/commands.md +0 -0
  241. package/scripts/lib/sqlite-loader.mjs +49 -0
  242. package/scripts/message-discipline-digest.mjs +535 -0
  243. package/scripts/poc/google-connector-inheritance/REPORT.md +197 -0
  244. package/scripts/poc/google-connector-inheritance/claude-sdk-probe.mjs +79 -0
  245. package/scripts/remint-roadmap-ids.mjs +257 -0
  246. package/scripts/rm-paths.mjs +22 -0
  247. package/scripts/run-node.mjs +223 -0
  248. package/scripts/smoke-obsidian-api.mjs +166 -0
  249. package/scripts/start.mjs +160 -0
@@ -0,0 +1,400 @@
1
+ {context}
2
+
3
+ ## Hourly Observation Review — Delegated Mode (Codex connectors)
4
+
5
+ Variant of `routine.hourly_check` selected when any of Gmail /
6
+ Google Calendar / Notion is `delegated` on the Codex backend. The
7
+ corresponding direct-mode signal paths (`MailPoller` mail:lifecycle,
8
+ `CalendarPoller` calendar:* + `schedule.approaching` emits, `NotionPoller`
9
+ notion:* observations) shut off under delegation; Step 0 below restores
10
+ coverage by fetching the same windows via MCP tools. The rest of the
11
+ decision workflow is identical to the direct variant.
12
+
13
+ > **Connector mode (Codex DM)**: `<integration_modes>` carries
14
+ > `<key>_delegated_to="<backend>"` for delegated keys. Same-backend
15
+ > (`=codex`) → use `mcp__codex_apps__*` natively. Cross-backend
16
+ > (`=claude` / `=gemini`) → route through `POST
17
+ > /api/integrations/<key>/exec` with a natural-language `task` and
18
+ > a JSON `outputSchema`; do NOT call `mcp__codex_apps__*` for that
19
+ > integration. The daemon enforces allowed-tools / destructive /
20
+ > deniedTools / cost / audit and validates the JSON. The
21
+ > `/api/notion/databases` label → UUID config dump is ungated in
22
+ > either mode — use it before any Notion read so your `task` prose
23
+ > carries a concrete data-source UUID.
24
+
25
+ The "Vault policy files" block appended to this prompt includes
26
+ `routines/hourly.md` — your canonical check list for this cadence.
27
+ The "Vault review context" block includes `context-index.md` and
28
+ `dossiers/hourly.md`; consult it before Step 1 and update the dossier's
29
+ Open items / Last run before finishing. Writes to `dossiers/<flow>.md`
30
+ MUST preserve the existing YAML frontmatter block (`---\ntype: dossier\nowner: agent\nupdated: <date>\n---`); prefer `PATCH` with a
31
+ section target to mutate a single block, and when doing a `PUT` full
32
+ rewrite keep the frontmatter and only refresh `updated:` — writes that
33
+ drop the frontmatter are rejected with 422.
34
+ Execute each `### <label>` entry in order, skipping any whose
35
+ precondition does not hold. The steps below are the built-in decision
36
+ framework for the observation-review step; additional checks the user
37
+ has added to the routine file run alongside them using the same
38
+ routing rules.
39
+
40
+ Fetch pending user-originated observations:
41
+ `GET /api/observations?pending=true&actor=user&limit=20`. Obsidian /
42
+ Git always feed that table; Notion only in direct mode.
43
+ Delegated signals arrive via Step 0 below.
44
+
45
+ ### Execution budget
46
+ Target: 5–10 turns. If you reach 15 turns, wrap up current work and log.
47
+ Do NOT read roadmap.md, projects/*.md, or user/*.md unless an
48
+ observation warrants project-state context (e.g. references a project,
49
+ milestone, or deliverable — not merely a file edit in a watched repo).
50
+
51
+ ### Default stance — silence + idempotence
52
+ Most hourly runs are silent bookkeeping: consume observations, update
53
+ today.md, log, done. The baseline assumption for every step below is
54
+ that the user does NOT want another notification and does NOT want a
55
+ new Agent Plan row unless this run has something genuinely new to add.
56
+ The morning routine is authoritative for the day's plan; your job is
57
+ to fold in new signals, not to re-plan. Two hard rules:
58
+
59
+ - **No duplicate Agent Plan rows / schedules.** Before appending to
60
+ `## Agent Plan` or calling `POST /api/schedule`, run the dedup
61
+ pre-check in Step 4. If a matching row/schedule already exists,
62
+ skip and log — never add a second one.
63
+ - **No duplicate notifications.** Before `POST /api/notify`, run the
64
+ dedup pre-check in Step 8. If the same item was already notified
65
+ earlier today, stay silent and log.
66
+
67
+ When in doubt, stay silent and log to `## Agent Log`.
68
+
69
+ ### External services are read-only this hour
70
+
71
+ This routine reads external state for context — it does not push back. While running this hourly check, do **not**:
72
+
73
+ - Create / update / archive Notion pages or change Notion schema.
74
+ - Send / draft / move / tag mail.
75
+ - Create / update / delete calendar events.
76
+ - Open / merge / comment on GitHub PRs or issues.
77
+
78
+ External-source signals (`mail:*`, `notion:*`, `calendar:*`, `git:*`) reach you through `<observations>` and the delegated-sync-worker rows pulled in Step 0 below. Consume them, route to `today.md` / `projects/*.md` / the `roadmap_candidate` queue per the Decision Framework, but do **not** act back on the source system through the connector or the daemon `/exec` proxy. Outbound writes against external services belong in the morning routine, evening review, or DM-reply paths — `routine.hourly_check` is a silent bookkeeping pass.
79
+
80
+ This rule applies regardless of integration mode (same-backend delegated, cross-backend delegated). It is owned by the routine, so a session whose `notion` / `mail` / `external-services` skill body was dropped under same-backend delegation (because the connector covers the surface) still inherits the constraint.
81
+
82
+ ### Decision Framework
83
+
84
+ #### Step 0 — Collect delegated-mode signals (replaces lost observations)
85
+
86
+ Run this step FIRST, before fetching `/api/observations`. The
87
+ delegated-sync-worker (0a / 0c) and the calendar reconcile route (0b)
88
+ write **real** `mail:lifecycle` / `notion:<db>` / `calendar:<id>`
89
+ observation rows server-side, so Step 1's `/api/observations` fetch
90
+ already includes them; Step 7's `/api/observations/consume` call still
91
+ applies — there are no "synthetic, row-less" Step 0 signals after
92
+ Phase 5. The only Step 0 output that does NOT flow through the
93
+ observations table is the imminent-meeting reminder (0b → EventBus
94
+ `schedule.approaching`), which the daemon DMs the user directly
95
+ without a DB row.
96
+
97
+ **Per-substep precondition.** Each `0[abc]` substep runs only when its
98
+ integration is `delegated`: 0a iff `gmail="delegated"`, 0b iff
99
+ `google_calendar="delegated"`, 0c iff `notion="delegated"`. In `direct`
100
+ / `disabled` mode the corresponding poller (MailPoller / CalendarPoller
101
+ / NotionPoller) is recording observations normally — Step 1's
102
+ `/api/observations` call sees them. Calendar additionally restores the
103
+ `schedule.approaching` emit path under direct mode.
104
+
105
+ **0a. Recent Gmail (delegated worker owns the drift snapshot).**
106
+ When `gmail="delegated"`, the daemon's `delegated-sync-worker` polls
107
+ Gmail on its own cadence (~30 min default, operator-tunable) and writes
108
+ coalesced `mail:lifecycle` observations server-side via the
109
+ `integration_snapshots` (`inbox:7d`) partition. Drafts the agent
110
+ created or labels the agent applied within the `integration_writes` TTL
111
+ window are pre-tagged `actor='agent'` so Step 1's
112
+ `GET /api/observations?actor=user` already excludes them. **Do NOT call
113
+ `/api/integrations/gmail/reconcile` from this step** — the route's
114
+ LLM-callable allowlist excludes the gmail partition for this reason: a
115
+ narrow `newer_than:1d` LLM fetch posted into the worker's 7d partition
116
+ would classify every prior 1-7d-old thread as `deleted` and trigger
117
+ ghost observations on the next worker tick.
118
+
119
+ If a downstream observation references a thread you want to read for
120
+ deeper context (e.g. an `mail:lifecycle` row in Step 1 looks
121
+ actionable), branch on `gmail_delegated_to`. Cross-backend reads are
122
+ dispatched through `/exec` with a natural-language intent — the
123
+ daemon's delegate composes the right MCP primitives whichever backend
124
+ currently owns Gmail.
125
+
126
+ ```bash
127
+ curl -sS -X POST http://localhost:8321/api/integrations/gmail/exec \
128
+ -H 'Content-Type: application/json' \
129
+ -d '{
130
+ "task": "Fetch every message in Gmail thread <THREAD_ID>. For each return from / subject / body / timestamp. Sort ascending by timestamp.",
131
+ "outputSchema": { "type": "object", "required": ["messages"], "properties": { "messages": { "type": "array", "items": { "type": "object", "required": ["from","subject","body","ts"] } } } },
132
+ "maxToolCalls": 7,
133
+ "cacheable": true
134
+ }'
135
+ ```
136
+
137
+ | `gmail_delegated_to` | Routing | How |
138
+ |---|---|---|
139
+ | `codex` | same-backend | `mcp__codex_apps__gmail._read_email_thread(threadId="<id>")` |
140
+ | `claude` / `gemini` / custom | cross-backend | `POST /api/integrations/gmail/exec` with the task prose above |
141
+
142
+ The worker's snapshot covers the actor-attribution case the legacy
143
+ prompt used to call out: you do NOT need to cross-check the agent
144
+ journal for prior agent writes; the daemon's `integration_writes` row
145
+ does it for you.
146
+
147
+ **0b. Calendar drift detection (replaces `calendar:*` observations AND
148
+ the lost `schedule.approaching` emit path).** When
149
+ `google_calendar="delegated"`, branch on `google_calendar_delegated_to`,
150
+ run TWO fetches against the connector, and POST each result to the
151
+ daemon's reconcile chokepoint. The chokepoint computes the structural
152
+ diff against the prior snapshot, fires per-change side effects
153
+ (observations, `routine.today_refresh` auto-schedule, roadmap-refresh
154
+ trigger), and returns `{diff, sideEffects}` for you to reason over.
155
+ Cross-backend fetches go through `/exec` with a natural-language
156
+ `task`:
157
+
158
+ ```bash
159
+ curl -sS -X POST http://localhost:8321/api/integrations/google_calendar/exec \
160
+ -H 'Content-Type: application/json' \
161
+ -d '{
162
+ "task": "List every event on the primary calendar between <timeMin> and <timeMax>. Return up to <maxResults> with id, title, start, end, attendees.",
163
+ "outputSchema": { "type": "object", "required": ["events"], "properties": { "events": { "type": "array", "items": { "type": "object", "required": ["id","title","start","end"] } } } },
164
+ "cacheable": true
165
+ }'
166
+ ```
167
+
168
+ | `google_calendar_delegated_to` | Routing | How |
169
+ |---|---|---|
170
+ | `codex` | same-backend | `mcp__codex_apps__google_calendar._search` |
171
+ | `claude` / `gemini` / custom | cross-backend | `POST /api/integrations/google_calendar/exec` with the task prose above |
172
+
173
+ **Gemini-specific Calendar flow** (when `google_calendar_delegated_to=gemini`):
174
+
175
+ | Quirk | Effect | Workaround |
176
+ |---|---|---|
177
+ | `maxResults` is silently ignored | Result set bounded only by the time window + Google's per-list default | Cross-backend curl still passes `maxResults` (codex / claude honor it); accept the wider gemini result set |
178
+ | Default `attendeeResponseStatus = ["accepted","tentative","needsAction"]` drops declined events | Declined meetings invisible | Pass `attendeeResponseStatus=["declined"]` or the full set explicitly when you need them |
179
+
180
+ (The previous Gemini `updated`-field gap no longer applies under
181
+ reconcile: the daemon hashes the normalized payload on each call and
182
+ detects mid-horizon edits regardless of whether the connector surfaces
183
+ `updated`.)
184
+
185
+ Run TWO fetches with the same call shape, swapping only the time
186
+ window and `maxResults`. Same-backend form (Codex shown):
187
+
188
+ ```
189
+ mcp__codex_apps__google_calendar._search(
190
+ timeMin="<...>", timeMax="<...>",
191
+ )
192
+ ```
193
+
194
+ - **Fetch 1 — imminent meeting window**: `timeMin=now-15min`, `timeMax=now+60min`, `maxResults=50`.
195
+ - **Fetch 2 — 24-hour change-detection window**: `timeMin=now`, `timeMax=now+24h`, `maxResults=250`.
196
+
197
+ POST each result to the reconcile chokepoint. The daemon normalises
198
+ event payloads server-side and re-hashes them to detect drift, so pass
199
+ the raw connector items verbatim — no `contentHash`, no per-item
200
+ hashing on your side:
201
+
202
+ ```bash
203
+ # Fetch 1 — imminent (windowKey="primary:imminent")
204
+ curl -s -X POST http://localhost:8321/api/integrations/google_calendar/reconcile \
205
+ -H 'Content-Type: application/json' \
206
+ -d '{
207
+ "windowKey": "primary:imminent",
208
+ "windowMin": "<now-15min UTC ISO>",
209
+ "windowMax": "<now+60min UTC ISO>",
210
+ "fetchedAt": "<now UTC ISO>",
211
+ "items": [<raw event objects from Fetch 1>]
212
+ }'
213
+
214
+ # Fetch 2 — 24h (windowKey="primary:24h")
215
+ curl -s -X POST http://localhost:8321/api/integrations/google_calendar/reconcile \
216
+ -H 'Content-Type: application/json' \
217
+ -d '{
218
+ "windowKey": "primary:24h",
219
+ "windowMin": "<now UTC ISO>",
220
+ "windowMax": "<now+24h UTC ISO>",
221
+ "fetchedAt": "<now UTC ISO>",
222
+ "items": [<raw event objects from Fetch 2>]
223
+ }'
224
+ ```
225
+
226
+ Each response carries:
227
+
228
+ - `diff.created` — events new to this window-key partition since the previous reconcile.
229
+ - `diff.modified` — events whose normalised hash changed (start/end/summary/location/attendees moved).
230
+ - `diff.deleted` — events present in the prior snapshot but absent now AND still inside the queried window. Items that simply slid out of the window are pruned silently and counted under `diff.prunedOutOfWindow`; do not treat those as deletions.
231
+ - `diff.unchanged` — count only, no item bodies returned. Most hourly runs are mostly-unchanged.
232
+ - `diff.isInitialSnapshot` — `true` on the first reconcile of this window-key partition (e.g. fresh install, after a clean reinstall, or after a long downtime). Treat as "no signal": skip all per-change actions for that fetch this run; the next tick returns real diffs.
233
+ - `sideEffects.scheduleApproachingEmitted` — array of `eventId`s the daemon's imminent-event-scheduler already published to the EventBus (DM dispatch is in flight). Skip notifying these — re-notifying duplicates the user-facing reminder.
234
+ - `sideEffects.observationsWritten` — count of `observations` rows the daemon coalesced from this diff. The downstream `/api/observations` fetch in Step 1 picks them up.
235
+ - `sideEffects.todayRefreshScheduled` / `todayRefreshPending` — whether the daemon queued a `routine.today_refresh` (or deferred until the morning lock releases). When `true`, you should NOT also rewrite `## User Schedule` from Step 4 — the auto-refresh will own that section.
236
+ - `sideEffects.roadmapRefreshTriggered` — whether the daemon enqueued a roadmap-refresh because a created/modified event landed beyond the 14-day horizon.
237
+
238
+ Use the diff response for downstream decisions:
239
+
240
+ - **Imminent (Fetch 1, ≤15 min away).** The daemon's imminent-event-scheduler emits `schedule.approaching` every 60s for any snapshot row whose `start` falls in `[now, now+15min]`. **Do NOT send a duplicate `POST /api/notify` for any `eventId` listed in `sideEffects.scheduleApproachingEmitted`** — the dispatcher is already running the DM. For events NOT in that array AND NOT already covered by a `## Agent Log` `[cal] ... — reminder sent` entry within the last hour AND NOT covered by a matching Agent Plan row firing in the next 20 minutes, fold into Step 8 trigger (b) "calendar change needing same-hour attention" for at most one `POST /api/notify`. Then append a line to `## Agent Log`: `- HH:MM [cal] "<summary>" starts HH:MM — reminder sent`.
241
+ - **15–60 min out (Fetch 1).** Information-only; do not notify.
242
+ - **24-hour horizon (Fetch 2).** Treat each `diff.created` / `diff.modified` / `diff.deleted` entry as a calendar observation for Steps 1–5. The daemon already wrote the matching `observations` row (counted in `sideEffects.observationsWritten`) AND, when the change lands inside today's local-day window, scheduled `routine.today_refresh` to rewrite `## User Schedule` autonomously. **Do NOT cross-reference the Fetch 2 result with `## User Schedule` text-by-text** — `diff.deleted` carries the deletion signal that the legacy text-scan used to derive, and double-rewriting User Schedule races the auto-refresh.
243
+
244
+ If either fetch returns `diff.isInitialSnapshot === true`, log
245
+ `- HH:MM [delegated-sync] calendar partition <windowKey> bootstrapped (no diff this run)` to ## Agent Log and skip the per-change actions for that fetch.
246
+
247
+ **Dedup against a truncated `## Agent Log`:** if `<today>` contains
248
+ `[...N earlier entries omitted ...]`, a prior reminder this day may be
249
+ hidden. Before sending any notify from this step, issue
250
+ `curl -s http://localhost:8321/api/context/today` once and scan the
251
+ full log for the item. Do NOT skip this check — duplicate 15-min
252
+ reminders within the same meeting are a reported UX regression.
253
+
254
+ **0c. Recent Notion edits (delegated worker owns the drift snapshot).**
255
+ When `notion="delegated"`, the daemon's `delegated-sync-worker` polls
256
+ Notion on its own cadence (~60 min default) and writes coalesced
257
+ `notion:<parentDatabase>` (or `notion:lifecycle` for workspace-rooted
258
+ pages) observations server-side via the `integration_snapshots`
259
+ (`recently_updated`) partition. The daemon hashes each page on
260
+ `{title, lastEditedTime, parentDatabase, propertiesSummaryHash,
261
+ relationsHash}`, so a property-only edit surfaces as `modified` even
262
+ without a body fetch. Pages the agent wrote within the
263
+ `integration_writes` TTL window are pre-tagged `actor='agent'` so Step
264
+ 1's `GET /api/observations?actor=user` already excludes them. **Do NOT
265
+ call `/api/integrations/notion/reconcile` from this step** — the
266
+ route's LLM-callable allowlist excludes the notion partition for this
267
+ reason: a narrow `created_date_range:yesterday` LLM fetch posted into
268
+ the worker's 7d partition would classify every prior 1-7d-old page as
269
+ `deleted` and trigger ghost observations on the next worker tick.
270
+
271
+ If a downstream observation references a page you want to fetch the
272
+ full body for (e.g. a `notion:<db>` row in Step 1 needs context for
273
+ routing), branch on `notion_delegated_to`. The label→UUID map is
274
+ ungated under delegation (`/api/notion/databases` is a config dump, no
275
+ Notion API call) and remains useful when an observation identifies a
276
+ page by database label rather than UUID:
277
+
278
+ ```
279
+ curl -s http://localhost:8321/api/notion/databases
280
+ # → { "databases": { "tasks": "<uuid>", "projects": "<uuid>", ... } }
281
+ ```
282
+
283
+ | `notion_delegated_to` | Routing | Fetch tool |
284
+ |-----------------------|---------|------------|
285
+ | `codex` | same-backend | `mcp__codex_apps__notion._fetch(id="<page-url-or-uuid>")` |
286
+ | `claude` / `gemini` / custom | cross-backend | `POST /api/integrations/notion/exec` with `{"task": "Fetch Notion page <UUID> with its block tree…", "outputSchema": …, "cacheable": true}` |
287
+
288
+ **Notion delegation coverage gap** (accepted): the worker's search uses
289
+ `created_date_range` (no `last_edited_time` filter exists upstream), so
290
+ pages created more than 7 days ago but edited within the last hour can
291
+ fall outside the worker's window; pages whose body / title don't match
292
+ the worker's `"updated"` query token may rank off the first 25 results
293
+ even when recently edited. Direct-mode `NotionPoller` covers both. If
294
+ the user notices missed Notion updates, flip the integration back to
295
+ `direct` mode.
296
+
297
+ **0d. Log the calendar collection summary** to ## Agent Log when Step
298
+ 0b ran: `- HH:MM [delegated-sync] calendar <M> events (<K> imminent)`.
299
+ The daemon's `delegated-sync-worker` records its own gmail / notion
300
+ audit rows in `agent_actions` (queryable via `audit --type=delegated_sync`),
301
+ so no prompt-side log line is needed for those. Skip this whole step
302
+ if `google_calendar` is `direct` / `disabled` this run.
303
+
304
+ #### Steps 1–9 — identical to the direct variant
305
+
306
+ 1. Group related observations before acting. One concise update beats many small patches.
307
+ 2. Classify each observation with a category tag: work/ folders, employer
308
+ repos, Notion "Work" → `[work]`; coursework, study notes → `[study]`;
309
+ journals, hobby repos, fitness, medical → `[personal]`; home logistics
310
+ → `[home]`. Default `[personal]` when ambiguous.
311
+ 3. Read the day-type filter on line 2 of <today>. Map categories to focus
312
+ dimensions per the today skill's "Category → focus-dimension mapping".
313
+ Drop observations whose focus is `off` and log:
314
+ `- HH:MM [observations] skipped <n> item(s): <category> focus off`.
315
+ 4. Route each surviving actionable observation to the right today.md section.
316
+ **Before writing a new row or scheduling anything, run the dedup
317
+ pre-check**:
318
+ - Scan `<today>` `## Agent Plan` for an existing row with HH:MM
319
+ within ±15 min AND overlapping subject/keywords. If found → skip
320
+ (log `- HH:MM [observations] skipped <item>: already planned`).
321
+ - Scan `<today>` `## User Tasks` for the same subject. If found →
322
+ skip (log `skipped: already in User Tasks`).
323
+ - For schedule registrations, also query:
324
+ `GET /api/schedule?status=pending,running` AND
325
+ `GET /api/recurring-schedules?enabled=true`.
326
+ If a pending/recurring item covers the same trigger → skip.
327
+
328
+ Only after dedup clears, route the observation:
329
+ - New TODO for the user → append to ## User Tasks with the row shape in the
330
+ context skill. Derive HH:MM from (a) deadline if known, (b) proximity
331
+ to a related calendar event, or (c) working-hours midpoint.
332
+ - New proactive reminder Claude should fire → append to ## Agent Plan AND
333
+ register the matching POST /api/schedule in the same turn. Agent Plan rows
334
+ and schedule entries are always in lock-step (see skill "User Tasks vs
335
+ Agent Plan → The Agent Plan contract").
336
+ - Day-time observation (git push, Step 0a/0b/0c sync, or `notion:*`
337
+ observation in direct mode) → append to ## Agent Notes.
338
+ 5. Update projects/*.md when the observation materially changes project
339
+ state. Do NOT write to roadmap.md from hourly — for long-horizon
340
+ signals that don't belong in today.md but aren't yet strong enough
341
+ for direct roadmap edits (e.g. a user edited a vault note mentioning
342
+ a trip "sometime this summer", a far-future calendar event with an
343
+ unclear prep window), **queue them as `roadmap_candidate`
344
+ observations** via POST /api/observations (observations skill). The
345
+ next roadmap_refresh run consumes them and decides routing; this
346
+ hourly flow intentionally does not load the long-term-plan taxonomy
347
+ at all.
348
+ ```
349
+ curl -s -X POST http://localhost:8321/api/observations \
350
+ -H 'Content-Type: application/json' \
351
+ -d '{"source":"roadmap_candidate:<subkind>","ref":"<stable-ref>","changeType":"created","actor":"agent","payload":{...}}'
352
+ ```
353
+ `<subkind>` examples: `travel`, `calendar`, `vault`, `dm`.
354
+ 6. Skip noise: journal-only edits, trivial formatting, auto-generated churn,
355
+ already-processed agent writes, deletion of auto-generated artifacts.
356
+ 7. Mark processed observations consumed via POST /api/observations/consume.
357
+ Note: Step 0b imminent-meeting reminders are emitted on the EventBus
358
+ (`schedule.approaching`), not the observations table — those are
359
+ delivered as direct DMs and have no row to consume here.
360
+ 8. Urgency gate for POST /api/notify — the default is SILENCE. At most
361
+ ONE call per run, and only after the dedup pre-check passes AND one
362
+ of (a)(b)(c) holds with its concrete threshold:
363
+
364
+ **Dedup pre-check (mandatory — skip `/api/notify` if any hit):**
365
+ - `<today>` `## Agent Log` contains a `notify sent` / `DM sent` /
366
+ `[cal] ... — reminder sent` entry for the same item within the
367
+ last 4 hours.
368
+ - The truncation marker `[...N earlier entries omitted ...]` appears
369
+ in `<today>` and you cannot rule out a same-day prior notification
370
+ from the truncated view. In that case `GET /api/context/today`
371
+ once for the full log before deciding.
372
+ - A matching pending `POST /api/schedule/dm` or Agent Plan row is
373
+ already going to fire for this item within the next 2 hours
374
+ (prefer the planned channel — don't pre-empt it).
375
+
376
+ **Positive triggers — at least one must hold with its threshold:**
377
+ (a) Hard deadline ≤ 2 hours away that the agent surfaced **this
378
+ hour** from new input (mail, DM, observation) AND the user has
379
+ not yet acted on it. **Self-set deadlines, course assignments,
380
+ class times, and items already in `today.md` ## User Tasks do
381
+ NOT qualify** — they fail the awareness gate (see notify skill
382
+ § Universal user-facing message discipline § Awareness gate).
383
+ A 6-hour deadline is NOT urgent regardless.
384
+ (b) Inbound DM, Gmail (from Step 0a), or calendar change (from Step
385
+ 0b) received in the last hour that needs a same-hour reply or
386
+ decision from the user. This is also where a Step 0b imminent
387
+ meeting (≤ 15 min) cleared for notification is delivered.
388
+ (c) Concrete failure / blocker / conflict the user would not
389
+ discover in time on their own (e.g. meeting moved onto an
390
+ existing slot; CI flagged a deploy the user triggered).
391
+
392
+ **Never urgency triggers** (log-only, no notify): "processed N
393
+ observations", Agent Plan / schedule reshuffles, context-file
394
+ updates, routine summaries of agent activity, roadmap candidates
395
+ queued, observations consumed.
396
+
397
+ When in doubt, stay silent and log.
398
+ 9. Append one line to ## Agent Log even on no-op runs (Agent Log only — do
399
+ not echo as final text, do not send via notify):
400
+ `- HH:MM [observations] reviewed N items, added X tasks / Y plan rows, skipped Z`.