@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,405 @@
1
+ {context}
2
+
3
+ ## Hourly Observation Review — Delegated Mode (Claude connectors)
4
+
5
+ Variant of `routine.hourly_check` selected when any of Gmail /
6
+ Google Calendar / Notion is `delegated` on the Claude 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 (Claude DM)**: `<integration_modes>` carries
14
+ > `<key>_delegated_to="<backend>"` for delegated keys. Same-backend
15
+ > (`=claude`) → use `mcp__claude_ai_*` natively. Cross-backend
16
+ > (`=codex` / `=gemini`) → route through `POST
17
+ > /api/integrations/<key>/exec` with a natural-language `task` and
18
+ > a JSON `outputSchema`; do NOT call `mcp__claude_ai_*` 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 (Codex
124
+ `read_email_thread`, Gemini `search` + `get` × N, custom MCP servers,
125
+ etc.) so you don't have to.
126
+
127
+ ```bash
128
+ curl -s -X POST http://localhost:8321/api/integrations/gmail/exec \
129
+ -H 'Content-Type: application/json' \
130
+ -d '{
131
+ "task": "Fetch every message in Gmail thread <THREAD_ID>. For each return from / subject / body / timestamp. Sort ascending by timestamp.",
132
+ "outputSchema": { "type": "object", "required": ["messages"], "properties": { "messages": { "type": "array", "items": { "type": "object", "required": ["from","subject","body","ts"] } } } },
133
+ "maxToolCalls": 7,
134
+ "cacheable": true
135
+ }'
136
+ ```
137
+
138
+ | `gmail_delegated_to` | Routing | How |
139
+ |---|---|---|
140
+ | `claude` | same-backend | `mcp__claude_ai_Gmail__get_thread(threadId="<id>")` |
141
+ | `codex` / `gemini` / custom | cross-backend | `POST /api/integrations/gmail/exec` with the task prose above |
142
+
143
+ The worker's snapshot covers the actor-attribution case the legacy
144
+ prompt used to call out: you do NOT need to cross-check the agent
145
+ journal for prior agent writes; the daemon's `integration_writes` row
146
+ does it for you.
147
+
148
+ **0b. Calendar drift detection (replaces `calendar:*` observations AND
149
+ the lost `schedule.approaching` emit path).** When
150
+ `google_calendar="delegated"`, branch on `google_calendar_delegated_to`,
151
+ run TWO fetches against the connector, and POST each result to the
152
+ daemon's reconcile chokepoint. The chokepoint computes the structural
153
+ diff against the prior snapshot, fires per-change side effects
154
+ (observations, `routine.today_refresh` auto-schedule, roadmap-refresh
155
+ trigger), and returns `{diff, sideEffects}` for you to reason over.
156
+ Cross-backend fetches go through `/exec` with a natural-language
157
+ `task` — the daemon's delegate picks the right primitive
158
+ (`list_events` / `listEvents` / `search_events` / custom MCP) so the
159
+ same prose works regardless of which backend currently owns Calendar.
160
+
161
+ ```bash
162
+ curl -s -X POST http://localhost:8321/api/integrations/google_calendar/exec \
163
+ -H 'Content-Type: application/json' \
164
+ -d '{
165
+ "task": "List every event on the primary calendar between <timeMin> and <timeMax>. Return up to <maxResults> with id, title, start, end, attendees.",
166
+ "outputSchema": { "type": "object", "required": ["events"], "properties": { "events": { "type": "array", "items": { "type": "object", "required": ["id","title","start","end"] } } } },
167
+ "cacheable": true
168
+ }'
169
+ ```
170
+
171
+ | `google_calendar_delegated_to` | Routing | How |
172
+ |---|---|---|
173
+ | `claude` | same-backend | `mcp__claude_ai_Google_Calendar__list_events` |
174
+ | `codex` / `gemini` / custom | cross-backend | `POST /api/integrations/google_calendar/exec` with the task prose above |
175
+
176
+ **Gemini-specific Calendar flow** (when `google_calendar_delegated_to=gemini`):
177
+
178
+ | Quirk | Effect | Workaround |
179
+ |---|---|---|
180
+ | `maxResults` is silently ignored | Result set bounded only by the time window + Google's per-list default | Cross-backend curl still passes `maxResults` (claude / codex honor it); accept the wider gemini result set |
181
+ | Default `attendeeResponseStatus = ["accepted","tentative","needsAction"]` drops declined events | Declined meetings invisible | Pass `attendeeResponseStatus=["declined"]` or the full set explicitly when you need them |
182
+
183
+ (The previous Gemini `updated`-field gap no longer applies under
184
+ reconcile: the daemon hashes the normalized payload on each call and
185
+ detects mid-horizon edits regardless of whether the connector surfaces
186
+ `updated`.)
187
+
188
+ Run TWO fetches with the same call shape, swapping only the time
189
+ window and `maxResults`. Same-backend form (Claude shown):
190
+
191
+ ```
192
+ mcp__claude_ai_Google_Calendar__list_events(
193
+ calendarId="primary",
194
+ timeMin="<...>", timeMax="<...>",
195
+ maxResults=<...>,
196
+ )
197
+ ```
198
+
199
+ - **Fetch 1 — imminent meeting window**: `timeMin=now-15min`, `timeMax=now+60min`, `maxResults=50`.
200
+ - **Fetch 2 — 24-hour change-detection window**: `timeMin=now`, `timeMax=now+24h`, `maxResults=250`.
201
+
202
+ POST each result to the reconcile chokepoint. The daemon normalises
203
+ event payloads server-side and re-hashes them to detect drift, so pass
204
+ the raw connector items verbatim — no `contentHash`, no per-item
205
+ hashing on your side:
206
+
207
+ ```bash
208
+ # Fetch 1 — imminent (windowKey="primary:imminent")
209
+ curl -s -X POST http://localhost:8321/api/integrations/google_calendar/reconcile \
210
+ -H 'Content-Type: application/json' \
211
+ -d '{
212
+ "windowKey": "primary:imminent",
213
+ "windowMin": "<now-15min UTC ISO>",
214
+ "windowMax": "<now+60min UTC ISO>",
215
+ "fetchedAt": "<now UTC ISO>",
216
+ "items": [<raw event objects from Fetch 1>]
217
+ }'
218
+
219
+ # Fetch 2 — 24h (windowKey="primary:24h")
220
+ curl -s -X POST http://localhost:8321/api/integrations/google_calendar/reconcile \
221
+ -H 'Content-Type: application/json' \
222
+ -d '{
223
+ "windowKey": "primary:24h",
224
+ "windowMin": "<now UTC ISO>",
225
+ "windowMax": "<now+24h UTC ISO>",
226
+ "fetchedAt": "<now UTC ISO>",
227
+ "items": [<raw event objects from Fetch 2>]
228
+ }'
229
+ ```
230
+
231
+ Each response carries:
232
+
233
+ - `diff.created` — events new to this window-key partition since the previous reconcile.
234
+ - `diff.modified` — events whose normalised hash changed (start/end/summary/location/attendees moved).
235
+ - `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.
236
+ - `diff.unchanged` — count only, no item bodies returned. Most hourly runs are mostly-unchanged.
237
+ - `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.
238
+ - `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.
239
+ - `sideEffects.observationsWritten` — count of `observations` rows the daemon coalesced from this diff. The downstream `/api/observations` fetch in Step 1 picks them up.
240
+ - `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.
241
+ - `sideEffects.roadmapRefreshTriggered` — whether the daemon enqueued a roadmap-refresh because a created/modified event landed beyond the 14-day horizon.
242
+
243
+ Use the diff response for downstream decisions:
244
+
245
+ - **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`.
246
+ - **15–60 min out (Fetch 1).** Information-only; do not notify.
247
+ - **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.
248
+
249
+ If either fetch returns `diff.isInitialSnapshot === true`, log
250
+ `- HH:MM [delegated-sync] calendar partition <windowKey> bootstrapped (no diff this run)` to ## Agent Log and skip the per-change actions for that fetch.
251
+
252
+ **Dedup against a truncated `## Agent Log`:** if `<today>` contains
253
+ `[...N earlier entries omitted ...]`, a prior reminder this day may be
254
+ hidden. Before sending any notify from this step, issue
255
+ `curl -s http://localhost:8321/api/context/today` once and scan the
256
+ full log for the item. Do NOT skip this check — duplicate 15-min
257
+ reminders within the same meeting are a reported UX regression.
258
+
259
+ **0c. Recent Notion edits (delegated worker owns the drift snapshot).**
260
+ When `notion="delegated"`, the daemon's `delegated-sync-worker` polls
261
+ Notion on its own cadence (~60 min default) and writes coalesced
262
+ `notion:<parentDatabase>` (or `notion:lifecycle` for workspace-rooted
263
+ pages) observations server-side via the `integration_snapshots`
264
+ (`recently_updated`) partition. The daemon hashes each page on
265
+ `{title, lastEditedTime, parentDatabase, propertiesSummaryHash,
266
+ relationsHash}`, so a property-only edit surfaces as `modified` even
267
+ without a body fetch. Pages the agent wrote within the
268
+ `integration_writes` TTL window are pre-tagged `actor='agent'` so Step
269
+ 1's `GET /api/observations?actor=user` already excludes them. **Do NOT
270
+ call `/api/integrations/notion/reconcile` from this step** — the
271
+ route's LLM-callable allowlist excludes the notion partition for this
272
+ reason: a narrow `created_date_range:yesterday` LLM fetch posted into
273
+ the worker's 7d partition would classify every prior 1-7d-old page as
274
+ `deleted` and trigger ghost observations on the next worker tick.
275
+
276
+ If a downstream observation references a page you want to fetch the
277
+ full body for (e.g. a `notion:<db>` row in Step 1 needs context for
278
+ routing), branch on `notion_delegated_to`. The label→UUID map is
279
+ ungated under delegation (`/api/notion/databases` is a config dump, no
280
+ Notion API call) and remains useful when an observation identifies a
281
+ page by database label rather than UUID:
282
+
283
+ ```
284
+ curl -s http://localhost:8321/api/notion/databases
285
+ # → { "databases": { "tasks": "<uuid>", "projects": "<uuid>", ... } }
286
+ ```
287
+
288
+ | `notion_delegated_to` | Routing | Fetch tool |
289
+ |-----------------------|---------|------------|
290
+ | `claude` | same-backend | `mcp__claude_ai_Notion__notion-fetch(id="<page-url-or-uuid>")` |
291
+ | `codex` / `gemini` / custom | cross-backend | `POST /api/integrations/notion/exec` with `{"task": "Fetch Notion page <UUID> with its block tree…", "outputSchema": …, "cacheable": true}` |
292
+
293
+ **Notion delegation coverage gap** (accepted): the worker's search uses
294
+ `created_date_range` (no `last_edited_time` filter exists upstream), so
295
+ pages created more than 7 days ago but edited within the last hour can
296
+ fall outside the worker's window; pages whose body / title don't match
297
+ the worker's `"updated"` query token may rank off the first 25 results
298
+ even when recently edited. Direct-mode `NotionPoller` covers both. If
299
+ the user notices missed Notion updates, flip the integration back to
300
+ `direct` mode.
301
+
302
+ **0d. Log the calendar collection summary** to ## Agent Log when Step
303
+ 0b ran: `- HH:MM [delegated-sync] calendar <M> events (<K> imminent)`.
304
+ The daemon's `delegated-sync-worker` records its own gmail / notion
305
+ audit rows in `agent_actions` (queryable via `audit --type=delegated_sync`),
306
+ so no prompt-side log line is needed for those. Skip this whole step
307
+ if `google_calendar` is `direct` / `disabled` this run.
308
+
309
+ #### Steps 1–9 — identical to the direct variant
310
+
311
+ 1. Group related observations before acting. One concise update beats many small patches.
312
+ 2. Classify each observation with a category tag: work/ folders, employer
313
+ repos, Notion "Work" → `[work]`; coursework, study notes → `[study]`;
314
+ journals, hobby repos, fitness, medical → `[personal]`; home logistics
315
+ → `[home]`. Default `[personal]` when ambiguous.
316
+ 3. Read the day-type filter on line 2 of <today>. Map categories to focus
317
+ dimensions per the today skill's "Category → focus-dimension mapping".
318
+ Drop observations whose focus is `off` and log:
319
+ `- HH:MM [observations] skipped <n> item(s): <category> focus off`.
320
+ 4. Route each surviving actionable observation to the right today.md section.
321
+ **Before writing a new row or scheduling anything, run the dedup
322
+ pre-check**:
323
+ - Scan `<today>` `## Agent Plan` for an existing row with HH:MM
324
+ within ±15 min AND overlapping subject/keywords. If found → skip
325
+ (log `- HH:MM [observations] skipped <item>: already planned`).
326
+ - Scan `<today>` `## User Tasks` for the same subject. If found →
327
+ skip (log `skipped: already in User Tasks`).
328
+ - For schedule registrations, also query:
329
+ `GET /api/schedule?status=pending,running` AND
330
+ `GET /api/recurring-schedules?enabled=true`.
331
+ If a pending/recurring item covers the same trigger → skip.
332
+
333
+ Only after dedup clears, route the observation:
334
+ - New TODO for the user → append to ## User Tasks with the row shape in the
335
+ context skill. Derive HH:MM from (a) deadline if known, (b) proximity
336
+ to a related calendar event, or (c) working-hours midpoint.
337
+ - New proactive reminder Claude should fire → append to ## Agent Plan AND
338
+ register the matching POST /api/schedule in the same turn. Agent Plan rows
339
+ and schedule entries are always in lock-step (see skill "User Tasks vs
340
+ Agent Plan → The Agent Plan contract").
341
+ - Day-time observation (git push, Step 0a/0b/0c sync, or `notion:*`
342
+ observation in direct mode) → append to ## Agent Notes.
343
+ 5. Update projects/*.md when the observation materially changes project
344
+ state. Do NOT write to roadmap.md from hourly — for long-horizon
345
+ signals that don't belong in today.md but aren't yet strong enough
346
+ for direct roadmap edits (e.g. a user edited a vault note mentioning
347
+ a trip "sometime this summer", a far-future calendar event with an
348
+ unclear prep window), **queue them as `roadmap_candidate`
349
+ observations** via POST /api/observations (observations skill). The
350
+ next roadmap_refresh run consumes them and decides routing; this
351
+ hourly flow intentionally does not load the long-term-plan taxonomy
352
+ at all.
353
+ ```
354
+ curl -s -X POST http://localhost:8321/api/observations \
355
+ -H 'Content-Type: application/json' \
356
+ -d '{"source":"roadmap_candidate:<subkind>","ref":"<stable-ref>","changeType":"created","actor":"agent","payload":{...}}'
357
+ ```
358
+ `<subkind>` examples: `travel`, `calendar`, `vault`, `dm`.
359
+ 6. Skip noise: journal-only edits, trivial formatting, auto-generated churn,
360
+ already-processed agent writes, deletion of auto-generated artifacts.
361
+ 7. Mark processed observations consumed via POST /api/observations/consume.
362
+ Note: Step 0b imminent-meeting reminders are emitted on the EventBus
363
+ (`schedule.approaching`), not the observations table — those are
364
+ delivered as direct DMs and have no row to consume here.
365
+ 8. Urgency gate for POST /api/notify — the default is SILENCE. At most
366
+ ONE call per run, and only after the dedup pre-check passes AND one
367
+ of (a)(b)(c) holds with its concrete threshold:
368
+
369
+ **Dedup pre-check (mandatory — skip `/api/notify` if any hit):**
370
+ - `<today>` `## Agent Log` contains a `notify sent` / `DM sent` /
371
+ `[cal] ... — reminder sent` entry for the same item within the
372
+ last 4 hours.
373
+ - The truncation marker `[...N earlier entries omitted ...]` appears
374
+ in `<today>` and you cannot rule out a same-day prior notification
375
+ from the truncated view. In that case `GET /api/context/today`
376
+ once for the full log before deciding.
377
+ - A matching pending `POST /api/schedule/dm` or Agent Plan row is
378
+ already going to fire for this item within the next 2 hours
379
+ (prefer the planned channel — don't pre-empt it).
380
+
381
+ **Positive triggers — at least one must hold with its threshold:**
382
+ (a) Hard deadline ≤ 2 hours away that the agent surfaced **this
383
+ hour** from new input (mail, DM, observation) AND the user has
384
+ not yet acted on it. **Self-set deadlines, course assignments,
385
+ class times, and items already in `today.md` ## User Tasks do
386
+ NOT qualify** — they fail the awareness gate (see notify skill
387
+ § Universal user-facing message discipline § Awareness gate).
388
+ A 6-hour deadline is NOT urgent regardless.
389
+ (b) Inbound DM, Gmail (from Step 0a), or calendar change (from Step
390
+ 0b) received in the last hour that needs a same-hour reply or
391
+ decision from the user. This is also where a Step 0b imminent
392
+ meeting (≤ 15 min) cleared for notification is delivered.
393
+ (c) Concrete failure / blocker / conflict the user would not
394
+ discover in time on their own (e.g. meeting moved onto an
395
+ existing slot; CI flagged a deploy the user triggered).
396
+
397
+ **Never urgency triggers** (log-only, no notify): "processed N
398
+ observations", Agent Plan / schedule reshuffles, context-file
399
+ updates, routine summaries of agent activity, roadmap candidates
400
+ queued, observations consumed.
401
+
402
+ When in doubt, stay silent and log.
403
+ 9. Append one line to ## Agent Log even on no-op runs (Agent Log only — do
404
+ not echo as final text, do not send via notify):
405
+ `- HH:MM [observations] reviewed N items, added X tasks / Y plan rows, skipped Z`.