@aitne-sh/aitne 0.1.3 → 0.1.4

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 (87) hide show
  1. package/README.md +151 -147
  2. package/agent-assets/agent-profiles/conversational.md +23 -1
  3. package/agent-assets/agent-profiles/observer.md +15 -0
  4. package/agent-assets/agent-profiles/routine-fetch-window.md +128 -0
  5. package/agent-assets/agent-profiles/routine.md +16 -0
  6. package/agent-assets/agent-profiles/task.md +15 -0
  7. package/agent-assets/docs/concepts/auth-health.md +25 -9
  8. package/agent-assets/docs/concepts/backends-and-tiers.md +40 -4
  9. package/agent-assets/docs/concepts/costs-and-quotas.md +87 -25
  10. package/agent-assets/docs/concepts/delegated-mode.md +7 -13
  11. package/agent-assets/docs/concepts/memory-model.md +14 -1
  12. package/agent-assets/docs/concepts/observations.md +19 -1
  13. package/agent-assets/docs/concepts/process-keys.md +5 -0
  14. package/agent-assets/docs/concepts/routines.md +22 -10
  15. package/agent-assets/docs/concepts/safety-model.md +3 -8
  16. package/agent-assets/docs/concepts/skills.md +36 -1
  17. package/agent-assets/docs/features/integrations/calendar.md +74 -3
  18. package/agent-assets/docs/features/integrations/git.md +4 -4
  19. package/agent-assets/docs/features/integrations/github.md +75 -107
  20. package/agent-assets/docs/features/lifestyle/git.md +169 -22
  21. package/agent-assets/docs/features/messaging/overview.md +10 -1
  22. package/agent-assets/docs/features/routines/morning-routine.md +1 -1
  23. package/agent-assets/docs/getting-started/01-what-is-this.md +30 -12
  24. package/agent-assets/docs/getting-started/02-first-steps.md +15 -4
  25. package/agent-assets/docs/getting-started/03-what-can-this-do.md +17 -2
  26. package/agent-assets/docs/guides/install-and-run.md +10 -1
  27. package/agent-assets/docs/guides/setup-wizard.md +43 -6
  28. package/agent-assets/docs/guides/switch-default-backend.md +7 -3
  29. package/agent-assets/docs/reference/skills.md +10 -1
  30. package/agent-assets/docs/troubleshooting/auth-failed.md +27 -8
  31. package/agent-assets/docs/troubleshooting/quota-exhausted.md +35 -12
  32. package/agent-assets/skills/context/SKILL.md +6 -0
  33. package/agent-assets/skills/external-services/SKILL.md +4 -0
  34. package/agent-assets/skills/external-services/SKILL.native.claude.md +320 -0
  35. package/agent-assets/skills/external-services/SKILL.native.codex.md +243 -0
  36. package/agent-assets/skills/external-services/SKILL.native.gemini.md +237 -0
  37. package/agent-assets/skills/mail/SKILL.md +42 -14
  38. package/agent-assets/skills/mail/SKILL.native.claude.md +175 -0
  39. package/agent-assets/skills/mail/SKILL.native.codex.md +165 -0
  40. package/agent-assets/skills/mail/SKILL.native.gemini.md +169 -0
  41. package/agent-assets/skills/management-task-modify/SKILL.md +2 -1
  42. package/agent-assets/skills/management-task-stop/SKILL.md +2 -2
  43. package/agent-assets/skills/notify/SKILL.md +4 -4
  44. package/agent-assets/skills/notion/SKILL.md +6 -0
  45. package/agent-assets/skills/notion/SKILL.native.claude.md +202 -0
  46. package/agent-assets/skills/notion/SKILL.native.codex.md +166 -0
  47. package/agent-assets/skills/notion/SKILL.native.gemini.md +167 -0
  48. package/agent-assets/skills/observations/SKILL.md +7 -0
  49. package/agent-assets/skills/project-doc/SKILL.md +6 -0
  50. package/agent-assets/skills/reading/SKILL.md +2 -0
  51. package/agent-assets/skills/roadmap/SKILL.md +7 -0
  52. package/agent-assets/skills/today/SKILL.md +7 -0
  53. package/agent-assets/skills/user-interview/SKILL.md +1 -1
  54. package/agent-assets/skills/user-profile/SKILL.md +7 -0
  55. package/agent-assets/task-flows/_partials/calendar-acquire.google_calendar.md +119 -0
  56. package/agent-assets/task-flows/_partials/calendar-acquire.outlook_calendar.md +101 -0
  57. package/agent-assets/task-flows/_partials/mail-acquire.gmail.md +113 -0
  58. package/agent-assets/task-flows/_partials/mail-acquire.outlook_mail.md +97 -0
  59. package/agent-assets/task-flows/_partials/notion-acquire.notion.md +104 -0
  60. package/agent-assets/task-flows/git.project.refresh_architecture.md +24 -1
  61. package/agent-assets/task-flows/message.received.dm.md +3 -0
  62. package/agent-assets/task-flows/message.received.dm.native.claude.md +76 -0
  63. package/agent-assets/task-flows/message.received.dm.native.codex.md +57 -0
  64. package/agent-assets/task-flows/message.received.dm.native.gemini.md +70 -0
  65. package/agent-assets/task-flows/message.received.dm_first.md +3 -0
  66. package/agent-assets/task-flows/message.received.dm_first.native.claude.md +56 -0
  67. package/agent-assets/task-flows/message.received.dm_first.native.codex.md +48 -0
  68. package/agent-assets/task-flows/message.received.dm_first.native.gemini.md +54 -0
  69. package/agent-assets/task-flows/routine.evening_review.md +28 -1
  70. package/agent-assets/task-flows/routine.fetch_window.md +93 -0
  71. package/agent-assets/task-flows/routine.hourly_check.md +44 -5
  72. package/agent-assets/task-flows/routine.monthly_review.md +13 -2
  73. package/agent-assets/task-flows/routine.morning_routine.md +55 -42
  74. package/agent-assets/task-flows/routine.morning_routine_initial.md +37 -38
  75. package/agent-assets/task-flows/routine.roadmap_refresh.md +38 -46
  76. package/agent-assets/task-flows/routine.today_refresh.md +53 -96
  77. package/agent-assets/task-flows/routine.weekly_review.md +40 -17
  78. package/agent-assets/task-flows/scheduled.dm.md +13 -11
  79. package/agent-assets/task-flows/scheduled.task.md +2 -2
  80. package/agent-assets/task-flows/setup.initial.md +5 -4
  81. package/agent-assets/task-flows/setup.update.md +1 -1
  82. package/agent-assets/templates/README.md +13 -6
  83. package/package.json +4 -4
  84. package/scripts/regen-skill-fixtures.mjs +39 -0
  85. package/agent-assets/task-flows/routine.hourly_check.delegated.claude.md +0 -405
  86. package/agent-assets/task-flows/routine.hourly_check.delegated.codex.md +0 -400
  87. package/agent-assets/task-flows/routine.hourly_check.delegated.gemini.md +0 -404
@@ -0,0 +1,243 @@
1
+ ---
2
+ name: external-services
3
+ description: Load when an external-services surface is in scope (Google Calendar / Obsidian / GitHub / Skills CRUD / scheduling) and Google Calendar is in native mode bound to Codex (`nativeBackend === "codex"`). Calendar runs through Codex's hosted Calendar MCP directly; the daemon does not proxy Calendar. Other surfaces (Apple/Outlook Calendar, Obsidian, GitHub, scheduling, Skills CRUD) keep their direct routes.
4
+ allowed-tools:
5
+ - Bash(curl *)
6
+ - Bash(jq *)
7
+ - Read
8
+ ---
9
+
10
+ # External Services — Native Mode (Codex Calendar MCP)
11
+
12
+ Base URL: `http://localhost:8321`. All daemon calls via `curl -s`
13
+ with `Content-Type: application/json` on POST/PATCH/PUT.
14
+
15
+ > **Refusal directive — read first.** Google Calendar is in `native`
16
+ > mode bound to Codex. Do **NOT** call any of:
17
+ >
18
+ > - `POST /api/integrations/google_calendar/exec` (410 with
19
+ > `X-Integration-Mode: native`)
20
+ > - `POST /api/integrations/google_calendar/reconcile` (410)
21
+ > - `/api/calendar/*` (route-prefix 410)
22
+ >
23
+ > Reach Google Calendar through the
24
+ > `mcp__codex_apps__google_calendar._*` MCP tools your Codex session
25
+ > already holds.
26
+ >
27
+ > Only **Google Calendar** is integration-gated here. Apple Calendar,
28
+ > Outlook Calendar, Obsidian, GitHub, recurring-schedule CRUD,
29
+ > one-shot scheduling, and Skills CRUD remain direct-mode routes.
30
+
31
+ Confirm the binding via `<integration_modes>` (`google_calendar="native"`)
32
+ and the `<integration-routing-table>` block in the session preamble.
33
+
34
+ ## Source of Truth (READ FIRST)
35
+
36
+ Same as the direct-mode body — `rules/management.md` →
37
+ `## Source of Truth` and `~/.personal-agent/integrations.md` →
38
+ `## Note Sources`. If `rules/management.md` Schedule != Google
39
+ Calendar, the native binding is irrelevant; route through the
40
+ provider-specific direct route (`/api/apple-calendar/*` or
41
+ `/api/calendar/outlook/*`).
42
+
43
+ ## Shell rules
44
+
45
+ `jq`, never `python3`. `curl` restricted to `http://localhost:8321`.
46
+ See the direct-mode body's "Shell rules" subsection for the full
47
+ allowlist constraints.
48
+
49
+ ---
50
+
51
+ <!-- service:calendar -->
52
+ ## Google Calendar — Codex hosted Calendar MCP (native)
53
+
54
+ Tool namespace: `mcp__codex_apps__google_calendar._`
55
+
56
+ The Codex namespace terminates with `._`; the bare suffix below is what
57
+ you write after the namespace (`_search` = `mcp__codex_apps__google_calendar._search`).
58
+
59
+ ### Read-class tools
60
+
61
+ | Capability | Tool(s) | Use |
62
+ |---|---|---|
63
+ | `search` | `_search`, `_search_events` | Free-text / filter search. |
64
+ | `read` | `_read_event`, `_fetch` | Single-event read; `_fetch` returns the full payload incl. attendees. |
65
+ | `get_availability` | `_get_availability` | Free-busy across one or more calendars (pure compute, no side effect). |
66
+ | `batch_read` | `_batch_read_event` | Pull many events by id in one round-trip. |
67
+
68
+ Canonical search call (window-list):
69
+
70
+ ```
71
+ mcp__codex_apps__google_calendar._search_events(
72
+ calendar_id="primary",
73
+ time_min="<ISO-8601 with offset>",
74
+ time_max="<ISO-8601 with offset>",
75
+ max_results=50
76
+ )
77
+ ```
78
+
79
+ Canonical detail read:
80
+
81
+ ```
82
+ mcp__codex_apps__google_calendar._read_event(
83
+ calendar_id="primary",
84
+ event_id="<id>"
85
+ )
86
+ ```
87
+
88
+ ### Destructive tools (require explicit user confirmation)
89
+
90
+ Per the registry's
91
+ `google_calendar.backendConnectors.codex.destructiveTools`:
92
+
93
+ - `_create_event`
94
+ - `_update_event` — attendees field is whole-list replacement; see
95
+ warning below.
96
+ - `_delete_event`
97
+ - `_respond_event` — dispatches an RSVP to the organizer.
98
+
99
+ Apply the destructive-confirm contract: summarise the plan, wait for
100
+ explicit OK, then issue. The starter `deniedTools` list is enforced
101
+ before the call lands.
102
+
103
+ **ATTENDEES WARNING.** `_update_event(attendees=[...])` replaces the
104
+ list verbatim. To add one attendee:
105
+
106
+ 1. `_read_event(...)` → copy `attendees`.
107
+ 2. Append the new attendee.
108
+ 3. `_update_event(..., attendees=[<full list>])`.
109
+
110
+ **Recurring events.** Single-instance edits require the instance id;
111
+ master-id PATCH shifts the whole series. Confirm scope before issuing.
112
+
113
+ ### Time discipline
114
+
115
+ Same as Claude's native body — ISO 8601 with TZ offset for timed
116
+ events; `YYYY-MM-DD` for all-day. Reject naked-ISO inputs.
117
+
118
+ ### Imminent-event reminders (hourly_check)
119
+
120
+ The hourly_check native variant's Step 0b drives the imminent-window
121
+ fetch each hour; this skill describes the per-call surface. POST each
122
+ materialised event to `/api/observations` per the section at the end of
123
+ this file.
124
+
125
+ <!-- /service:calendar -->
126
+
127
+ ---
128
+
129
+ <!-- service:apple-calendar -->
130
+ ## Apple Calendar (iCloud CalDAV) — direct, unchanged
131
+
132
+ If `rules/management.md` Schedule = Apple Calendar, use the
133
+ `/api/apple-calendar/*` routes documented in the base body. Apple
134
+ Calendar has no MCP connector; native-mode gating does not apply.
135
+ <!-- /service:apple-calendar -->
136
+
137
+ ---
138
+
139
+ <!-- service:outlook-calendar -->
140
+ ## Outlook Calendar (Microsoft Graph) — direct, unchanged
141
+
142
+ If `rules/management.md` Schedule = Outlook Calendar, use
143
+ `/api/calendar/outlook/*` per the direct-mode body. No Outlook
144
+ connector ships for Codex today; native-mode gating does not apply.
145
+ <!-- /service:outlook-calendar -->
146
+
147
+ ---
148
+
149
+ <!-- service:obsidian -->
150
+ ## Obsidian (external vault) — direct, unchanged
151
+
152
+ Same surface as the direct-mode body. Full CRUD via
153
+ `/api/obsidian/*`; requires the Obsidian app running. Omit `.md`
154
+ extensions from paths. Never use this skill to read or write the
155
+ agent's primary management vault (`today.md`, `roadmap.md`,
156
+ `projects/`, `rules/`, …) — that lives behind `/api/context/*`.
157
+
158
+ ```bash
159
+ curl -s http://localhost:8321/api/obsidian/status
160
+ curl -s "http://localhost:8321/api/obsidian/search?q=meeting+notes&limit=10"
161
+ curl -s http://localhost:8321/api/obsidian/notes/Daily%20Notes/2026-04-06
162
+ curl -s -X POST http://localhost:8321/api/obsidian/notes \
163
+ -H 'Content-Type: application/json' \
164
+ -d '{"name": "Meeting Notes 2026-04-02", "content": "# Meeting\n..."}'
165
+ curl -s -X PUT http://localhost:8321/api/obsidian/notes/Projects/ProjectA \
166
+ -H 'Content-Type: application/json' -d '{"content": "# Full body"}'
167
+ curl -s -X PATCH http://localhost:8321/api/obsidian/notes \
168
+ -H 'Content-Type: application/json' \
169
+ -d '{"file": "Meeting Notes 2026-04-02", "content": "\n- Action item"}'
170
+ curl -s -X PATCH http://localhost:8321/api/obsidian/daily \
171
+ -H 'Content-Type: application/json' -d '{"content": "- [ ] Follow up"}'
172
+ curl -s -X DELETE http://localhost:8321/api/obsidian/notes/Projects/Old
173
+ ```
174
+ <!-- /service:obsidian -->
175
+
176
+ ---
177
+
178
+ <!-- service:github -->
179
+ ## GitHub — direct, unchanged
180
+
181
+ ```bash
182
+ curl -s http://localhost:8321/api/github/repos
183
+ curl -s "http://localhost:8321/api/github/pulls?state=open"
184
+ curl -s -X POST http://localhost:8321/api/github/pulls/comment \
185
+ -H 'Content-Type: application/json' \
186
+ -d '{"owner": "user", "repo": "repo", "pullNumber": 42, "body": "LGTM"}'
187
+ ```
188
+ <!-- /service:github -->
189
+
190
+ ---
191
+
192
+ <!-- service:notion -->
193
+ ## Notion
194
+
195
+ Load the dedicated `notion` skill — its body picks the right variant
196
+ from the session's integration state independently of Calendar.
197
+ <!-- /service:notion -->
198
+
199
+ ---
200
+
201
+ ## Persisting Calendar observations from native fetches
202
+
203
+ ```bash
204
+ curl -s -X POST http://localhost:8321/api/observations \
205
+ -H 'Content-Type: application/json' \
206
+ -d '{
207
+ "source": "google_calendar",
208
+ "type": "calendar:lifecycle",
209
+ "ref": "<eventId>",
210
+ "actor": "user",
211
+ "receivedAt": "<ISO-8601 UTC>",
212
+ "summary_text": "<title — start..end>",
213
+ "refs": {
214
+ "eventId": "<id>",
215
+ "calendarId": "primary",
216
+ "windowKey": "primary:imminent"
217
+ },
218
+ "payload": <verbatim MCP event object>
219
+ }'
220
+ ```
221
+
222
+ The daemon computes `contentHash` server-side — pass the raw `payload`
223
+ verbatim. HTTP 409 indicates a mode-flip race window (§11.3.1); stop
224
+ and re-read `<integration_modes>`.
225
+
226
+ ---
227
+
228
+ ## Scheduling — direct, unchanged
229
+
230
+ `/api/schedule`, `/api/schedule/dm`, `/api/recurring-schedules` live in
231
+ the `schedule` skill. Native-mode gating does not apply.
232
+
233
+ ## Skills Management — direct, unchanged
234
+
235
+ `/api/skills` CRUD per the direct-mode body. User-authored only;
236
+ built-ins are read-only (403). Native-mode gating does not apply.
237
+
238
+ ## Cost / audit
239
+
240
+ Native MCP calls land `agent_actions` rows of type `mcp_call` with
241
+ `provider="codex"`, the tool name, and the parent `event_id` /
242
+ `processKey`. The cost dashboard joins these to the registry by
243
+ `toolNamespace` prefix (§14.4 `nativeAttribution`).
@@ -0,0 +1,237 @@
1
+ ---
2
+ name: external-services
3
+ description: Load when an external-services surface is in scope (Google Calendar / Obsidian / GitHub / Skills CRUD / scheduling) and Google Calendar is in native mode bound to Gemini (`nativeBackend === "gemini"`). Calendar runs through the google-workspace extension directly; the daemon does not proxy Calendar. Other surfaces (Apple/Outlook Calendar, Obsidian, GitHub, scheduling, Skills CRUD) keep their direct routes.
4
+ allowed-tools:
5
+ - Bash(curl *)
6
+ - Bash(jq *)
7
+ - Read
8
+ ---
9
+
10
+ # External Services — Native Mode (Gemini google-workspace extension)
11
+
12
+ Base URL: `http://localhost:8321`. All daemon calls via `curl -s` with
13
+ `Content-Type: application/json` on POST/PATCH/PUT.
14
+
15
+ > **Refusal directive — read first.** Google Calendar is in `native`
16
+ > mode bound to Gemini. Do **NOT** call any of:
17
+ >
18
+ > - `POST /api/integrations/google_calendar/exec` (410 with
19
+ > `X-Integration-Mode: native`)
20
+ > - `POST /api/integrations/google_calendar/reconcile` (410)
21
+ > - `/api/calendar/*` (route-prefix 410)
22
+ >
23
+ > Reach Google Calendar through the
24
+ > `mcp_google-workspace_calendar.*` MCP tools your Gemini session
25
+ > already holds via the `google-workspace` extension.
26
+ >
27
+ > Only **Google Calendar** is integration-gated here. Apple Calendar,
28
+ > Outlook Calendar, Obsidian, GitHub, scheduling, and Skills CRUD
29
+ > remain direct-mode routes.
30
+
31
+ Confirm the binding via `<integration_modes>` (`google_calendar="native"`)
32
+ and the `<integration-routing-table>` block in the session preamble.
33
+
34
+ ## Source of Truth (READ FIRST)
35
+
36
+ Same files as the direct-mode body — `rules/management.md` →
37
+ `## Source of Truth` and `~/.personal-agent/integrations.md` →
38
+ `## Note Sources`. If Schedule != Google Calendar, route through the
39
+ provider-specific direct route (`/api/apple-calendar/*` or
40
+ `/api/calendar/outlook/*`); the native binding is irrelevant.
41
+
42
+ ## Shell rules
43
+
44
+ `jq`, never `python3`. `curl` restricted to `http://localhost:8321`.
45
+
46
+ ---
47
+
48
+ <!-- service:calendar -->
49
+ ## Google Calendar — google-workspace extension (native MCP)
50
+
51
+ Tool namespace: `mcp_google-workspace_calendar.`
52
+
53
+ ### Read-class tools
54
+
55
+ | Capability | Tool | Use |
56
+ |---|---|---|
57
+ | `list_events` | `listEvents` | Window-list events on a calendar. |
58
+ | `get_event` | `getEvent` | Single-event read. |
59
+ | `list_calendars` | `list` | Enumerate the user's calendars (the `primary: true` flag identifies the default). |
60
+ | `find_free_time` | `findFreeTime` | Free-slot proposal — pure compute. |
61
+
62
+ Canonical list call:
63
+
64
+ ```
65
+ mcp_google-workspace_calendar.listEvents(
66
+ calendarId="primary",
67
+ timeMin="<ISO-8601 with offset>",
68
+ timeMax="<ISO-8601 with offset>",
69
+ maxResults=50
70
+ )
71
+ ```
72
+
73
+ **Gemini-specific Calendar quirk** (carries over from delegated mode):
74
+
75
+ | Quirk | Effect | Workaround |
76
+ |---|---|---|
77
+ | `maxResults` is silently ignored on `listEvents` | Result set bounded only by the time window + Google's default | Narrow the time window when the connector returns more than expected; do not assume the cap applies. |
78
+ | Default `attendeeResponseStatus = ["accepted","tentative","needsAction"]` drops declined events | Declined meetings invisible | Pass `attendeeResponseStatus=["declined"]` or the full set explicitly when needed. |
79
+
80
+ Canonical detail read (always GET-before-PATCH):
81
+
82
+ ```
83
+ mcp_google-workspace_calendar.getEvent(
84
+ calendarId="primary",
85
+ eventId="<id>"
86
+ )
87
+ ```
88
+
89
+ ### Destructive tools (require explicit user confirmation)
90
+
91
+ Per the registry's
92
+ `google_calendar.backendConnectors.gemini.destructiveTools`:
93
+
94
+ - `createEvent`
95
+ - `updateEvent` — attendees whole-list replacement; see warning below.
96
+ - `deleteEvent`
97
+ - `respondToEvent` — dispatches RSVP.
98
+
99
+ Apply the destructive-confirm contract every time. The starter
100
+ `deniedTools` list is enforced before the call lands.
101
+
102
+ **ATTENDEES WARNING.** `updateEvent(attendees=[...])` replaces the
103
+ list verbatim. To add one attendee:
104
+
105
+ 1. `getEvent(...)` → copy `attendees`.
106
+ 2. Append the new attendee.
107
+ 3. `updateEvent(..., attendees=[<full list>])`.
108
+
109
+ **Recurring events.** Single-instance edits require the instance id;
110
+ master-id update shifts the whole series. Confirm scope.
111
+
112
+ ### Time discipline
113
+
114
+ ISO 8601 with TZ offset for timed events; `YYYY-MM-DD` for all-day.
115
+ The extension rejects naked-ISO inputs.
116
+
117
+ ### Imminent-event reminders (hourly_check)
118
+
119
+ The hourly_check native variant's Step 0b drives the imminent-window
120
+ fetch each hour; this skill describes the per-call surface. POST each
121
+ materialised event to `/api/observations` per the section below.
122
+
123
+ <!-- /service:calendar -->
124
+
125
+ ---
126
+
127
+ <!-- service:apple-calendar -->
128
+ ## Apple Calendar (iCloud CalDAV) — direct, unchanged
129
+
130
+ Use `/api/apple-calendar/*` per the direct-mode body if
131
+ `rules/management.md` Schedule = Apple Calendar.
132
+ <!-- /service:apple-calendar -->
133
+
134
+ ---
135
+
136
+ <!-- service:outlook-calendar -->
137
+ ## Outlook Calendar (Microsoft Graph) — direct, unchanged
138
+
139
+ Use `/api/calendar/outlook/*` per the direct-mode body if Schedule =
140
+ Outlook Calendar. No Outlook MCP connector ships for Gemini today.
141
+ <!-- /service:outlook-calendar -->
142
+
143
+ ---
144
+
145
+ <!-- service:obsidian -->
146
+ ## Obsidian (external vault) — direct, unchanged
147
+
148
+ `/api/obsidian/*` per the direct-mode body. Requires the Obsidian app
149
+ running. Never use this skill to read or write the agent's primary
150
+ management vault.
151
+
152
+ ```bash
153
+ curl -s http://localhost:8321/api/obsidian/status
154
+ curl -s "http://localhost:8321/api/obsidian/search?q=meeting+notes&limit=10"
155
+ curl -s http://localhost:8321/api/obsidian/notes/Daily%20Notes/2026-04-06
156
+ curl -s -X POST http://localhost:8321/api/obsidian/notes \
157
+ -H 'Content-Type: application/json' \
158
+ -d '{"name": "Meeting Notes 2026-04-02", "content": "# Meeting\n..."}'
159
+ curl -s -X PUT http://localhost:8321/api/obsidian/notes/Projects/ProjectA \
160
+ -H 'Content-Type: application/json' -d '{"content": "# Full body"}'
161
+ curl -s -X PATCH http://localhost:8321/api/obsidian/notes \
162
+ -H 'Content-Type: application/json' \
163
+ -d '{"file": "Meeting Notes 2026-04-02", "content": "\n- Action item"}'
164
+ curl -s -X PATCH http://localhost:8321/api/obsidian/daily \
165
+ -H 'Content-Type: application/json' -d '{"content": "- [ ] Follow up"}'
166
+ curl -s -X DELETE http://localhost:8321/api/obsidian/notes/Projects/Old
167
+ ```
168
+ <!-- /service:obsidian -->
169
+
170
+ ---
171
+
172
+ <!-- service:github -->
173
+ ## GitHub — direct, unchanged
174
+
175
+ ```bash
176
+ curl -s http://localhost:8321/api/github/repos
177
+ curl -s "http://localhost:8321/api/github/pulls?state=open"
178
+ curl -s -X POST http://localhost:8321/api/github/pulls/comment \
179
+ -H 'Content-Type: application/json' \
180
+ -d '{"owner": "user", "repo": "repo", "pullNumber": 42, "body": "LGTM"}'
181
+ ```
182
+ <!-- /service:github -->
183
+
184
+ ---
185
+
186
+ <!-- service:notion -->
187
+ ## Notion
188
+
189
+ Load the dedicated `notion` skill — its body picks the right variant
190
+ from the session's integration state independently of Calendar.
191
+ <!-- /service:notion -->
192
+
193
+ ---
194
+
195
+ ## Persisting Calendar observations from native fetches
196
+
197
+ ```bash
198
+ curl -s -X POST http://localhost:8321/api/observations \
199
+ -H 'Content-Type: application/json' \
200
+ -d '{
201
+ "source": "google_calendar",
202
+ "type": "calendar:lifecycle",
203
+ "ref": "<eventId>",
204
+ "actor": "user",
205
+ "receivedAt": "<ISO-8601 UTC>",
206
+ "summary_text": "<title — start..end>",
207
+ "refs": {
208
+ "eventId": "<id>",
209
+ "calendarId": "primary",
210
+ "windowKey": "primary:imminent"
211
+ },
212
+ "payload": <verbatim MCP event object>
213
+ }'
214
+ ```
215
+
216
+ The daemon computes `contentHash` server-side. Pass the raw `payload`.
217
+ HTTP 409 indicates a mode-flip race window (§11.3.1); stop and re-read
218
+ `<integration_modes>`.
219
+
220
+ ---
221
+
222
+ ## Scheduling — direct, unchanged
223
+
224
+ `/api/schedule`, `/api/schedule/dm`, `/api/recurring-schedules` live
225
+ in the `schedule` skill. Native-mode gating does not apply.
226
+
227
+ ## Skills Management — direct, unchanged
228
+
229
+ `/api/skills` CRUD per the direct-mode body. Native-mode gating does
230
+ not apply.
231
+
232
+ ## Cost / audit
233
+
234
+ Native MCP calls land `agent_actions` rows of type `mcp_call` with
235
+ `provider="gemini"`, the tool name, and the parent `event_id` /
236
+ `processKey`. The cost dashboard joins these to the registry by
237
+ `toolNamespace` prefix (§14.4 `nativeAttribution`).
@@ -12,28 +12,56 @@ All mail work goes through `/api/mail/*`. Gmail, Outlook, Yahoo, iCloud —
12
12
  same route surface, per-account routing, provider-native translation at the
13
13
  daemon.
14
14
 
15
- ## 0. Delegation-aware routing (read before §1)
15
+ ## 0. Per-account mode-aware routing (read before §1)
16
16
 
17
- This body is materialized only in direct mode and same-backend Gmail
17
+ This body is materialized in direct mode and same-backend Gmail
18
18
  delegation. (Cross-backend Gmail delegation pulls
19
19
  `SKILL.delegated.<backend>.md` instead — that variant has its own
20
- routing prose.) Read the `<integration_modes>` block injected above:
21
-
22
- - **Non-Gmail accounts (iCloud, Outlook, Yahoo, IMAP):** unaffected —
23
- use the `/api/mail/:acct/*` endpoints documented below regardless of
24
- Gmail's mode.
25
- - **Gmail accounts AND `gmail="delegated"` (same-backend):** the
26
- per-account gate inside the mail handler returns
27
- `410 {"error": "integration_delegated"}`. Do NOT retry through
28
- `/api/mail/*`. Use the connector tools your session already holds
29
- natively `mcp__claude_ai_Gmail__*` (Claude session),
20
+ routing prose.) Read the `<integration_modes>` block injected above
21
+ for every gated kind that is not in direct mode and dispatch
22
+ accordingly:
23
+
24
+ - **IMAP, Yahoo, iCloud:** always reachable via `/api/mail/:acct/*` —
25
+ these kinds have no integration-registry entry and stay direct-only
26
+ by design. They are unaffected by Gmail / Outlook mode flips.
27
+
28
+ <!-- mode:delegated-same:gmail -->
29
+ - **Gmail when `gmail="delegated"` (same-backend):** the per-account
30
+ gate returns `410 {"error": "integration_delegated"}`. Do NOT retry
31
+ via `/api/mail/*`. Use the connector tools your session already
32
+ holds natively — `mcp__claude_ai_Gmail__*` (Claude session),
30
33
  `mcp__codex_apps__gmail._*` (Codex session), or
31
34
  `mcp_google-workspace_gmail.*` (Gemini session, via the
32
35
  `google-workspace` extension).
36
+ <!-- /mode:delegated-same:gmail -->
37
+
38
+ <!-- mode:delegated:outlook_mail -->
39
+ - **Outlook when `outlook_mail="delegated"`:** the per-account gate
40
+ returns `410 {"error": "integration_delegated"}`. `outlook_mail` is
41
+ a user-managed connector — the daemon ships no proxy. Use whatever
42
+ Outlook / Microsoft Graph MCP server or connector you (the user)
43
+ registered on the backend named in the 410 body's `backend` field.
44
+ If your session runs on a different backend, ask the user which
45
+ Outlook tools are available there; the daemon cannot route this for
46
+ you.
47
+ <!-- /mode:delegated:outlook_mail -->
48
+
49
+ <!-- mode:native:outlook_mail -->
50
+ - **Outlook when `outlook_mail="native"`:** the per-account gate
51
+ returns `410 {"error": "integration_native"}`. Native is bound to
52
+ the main backend (see the 410 body's `backend` field) and the
53
+ daemon ships no proxy. Use the Outlook MCP / connector you (the
54
+ user) registered on that backend. The daemon does not poll Outlook
55
+ in this mode — mail observations only land when the agent fetches
56
+ in-turn through the user's MCP during a DM that needs them. There
57
+ is no proactive hourly_check fetch for `outlook_mail` (user-managed
58
+ reactive-only contract; see
59
+ `docs/design/appendices/native-integration-mode.md`).
60
+ <!-- /mode:native:outlook_mail -->
33
61
 
34
62
  Account-resolution (§1) is unchanged: `accounts.md` lists every active
35
- account regardless of mode. The branch above only affects the wire call
36
- once an account is selected.
63
+ account regardless of mode. The branches above only affect the wire
64
+ call once an account is selected.
37
65
 
38
66
  ## 1. Account resolution (do this first)
39
67