@aitne-sh/aitne 0.1.9 → 0.1.11

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 (218) hide show
  1. package/README.md +41 -11
  2. package/agent-assets/agent-profiles/background-task.md +53 -0
  3. package/agent-assets/agent-profiles/conversational.md +1 -0
  4. package/agent-assets/agent-profiles/routine-fetch-window.md +14 -75
  5. package/agent-assets/agent-profiles/routine.md +1 -1
  6. package/agent-assets/agents/{hourly-check → activity-scan}/agent.md +22 -17
  7. package/agent-assets/agents/monthly-review/agent.md +6 -5
  8. package/agent-assets/docs/concepts/agent-day.md +6 -7
  9. package/agent-assets/docs/concepts/auth-health.md +23 -20
  10. package/agent-assets/docs/concepts/backends-and-tiers.md +13 -9
  11. package/agent-assets/docs/concepts/costs-and-quotas.md +14 -12
  12. package/agent-assets/docs/concepts/delegated-mode.md +18 -17
  13. package/agent-assets/docs/concepts/memory-model.md +16 -9
  14. package/agent-assets/docs/concepts/observations.md +24 -20
  15. package/agent-assets/docs/concepts/process-keys.md +10 -9
  16. package/agent-assets/docs/concepts/routines.md +34 -31
  17. package/agent-assets/docs/concepts/safety-and-execution.md +11 -7
  18. package/agent-assets/docs/concepts/safety-model.md +39 -25
  19. package/agent-assets/docs/concepts/skills.md +12 -10
  20. package/agent-assets/docs/features/integrations/browser-history.md +23 -18
  21. package/agent-assets/docs/features/integrations/calendar.md +28 -17
  22. package/agent-assets/docs/features/integrations/git.md +13 -11
  23. package/agent-assets/docs/features/integrations/github.md +22 -14
  24. package/agent-assets/docs/features/integrations/mail.md +25 -22
  25. package/agent-assets/docs/features/integrations/notion.md +35 -11
  26. package/agent-assets/docs/features/integrations/obsidian.md +8 -8
  27. package/agent-assets/docs/features/lifestyle/git.md +27 -23
  28. package/agent-assets/docs/features/lifestyle/reading.md +20 -11
  29. package/agent-assets/docs/features/lifestyle/receipts.md +11 -10
  30. package/agent-assets/docs/features/lifestyle/travel-bookings.md +4 -3
  31. package/agent-assets/docs/features/memory-files/agent-journal.md +53 -26
  32. package/agent-assets/docs/features/memory-files/agent-lessons.md +178 -0
  33. package/agent-assets/docs/features/memory-files/projects.md +11 -8
  34. package/agent-assets/docs/features/memory-files/roadmap.md +17 -14
  35. package/agent-assets/docs/features/memory-files/schedule.md +6 -3
  36. package/agent-assets/docs/features/memory-files/today.md +10 -7
  37. package/agent-assets/docs/features/memory-files/user-profile.md +14 -9
  38. package/agent-assets/docs/features/messaging/bang-commands.md +21 -6
  39. package/agent-assets/docs/features/messaging/overview.md +17 -14
  40. package/agent-assets/docs/features/messaging/telegram.md +10 -9
  41. package/agent-assets/docs/features/operations/activity-and-conversations.md +6 -5
  42. package/agent-assets/docs/features/operations/approvals.md +6 -5
  43. package/agent-assets/docs/features/operations/browser-tasks.md +184 -0
  44. package/agent-assets/docs/features/operations/cost-tracking.md +11 -1
  45. package/agent-assets/docs/features/operations/managed-chromium.md +4 -2
  46. package/agent-assets/docs/features/operations/notifications.md +11 -1
  47. package/agent-assets/docs/features/operations/quiet-hours.md +41 -11
  48. package/agent-assets/docs/features/operations/schedule-approaching.md +2 -2
  49. package/agent-assets/docs/features/routines/activity-scan.md +220 -0
  50. package/agent-assets/docs/features/routines/custom-routines.md +82 -134
  51. package/agent-assets/docs/features/routines/evening-review.md +23 -13
  52. package/agent-assets/docs/features/routines/morning-routine.md +7 -5
  53. package/agent-assets/docs/features/routines/weekly-review.md +24 -3
  54. package/agent-assets/docs/features/wiki/commands.md +4 -4
  55. package/agent-assets/docs/features/wiki/cost-and-approval.md +4 -3
  56. package/agent-assets/docs/features/wiki/dashboard.md +7 -6
  57. package/agent-assets/docs/features/wiki/overview.md +3 -3
  58. package/agent-assets/docs/features/wiki/search.md +5 -5
  59. package/agent-assets/docs/features/wiki/workspaces.md +2 -2
  60. package/agent-assets/docs/getting-started/01-what-is-this.md +3 -3
  61. package/agent-assets/docs/getting-started/02-first-steps.md +5 -3
  62. package/agent-assets/docs/getting-started/04-first-day.md +27 -30
  63. package/agent-assets/docs/glossary.md +8 -8
  64. package/agent-assets/docs/guides/add-a-custom-routine.md +122 -68
  65. package/agent-assets/docs/guides/budget-and-cost-for-wiki.md +2 -2
  66. package/agent-assets/docs/guides/connect-a-new-mail-account.md +4 -2
  67. package/agent-assets/docs/guides/explore-with-trace-and-connect.md +5 -4
  68. package/agent-assets/docs/guides/install-and-run.md +2 -2
  69. package/agent-assets/docs/guides/maintain-wiki-health.md +2 -2
  70. package/agent-assets/docs/guides/pause-the-agent.md +27 -21
  71. package/agent-assets/docs/guides/reinstall-cleanly.md +2 -0
  72. package/agent-assets/docs/guides/setup-wizard.md +12 -6
  73. package/agent-assets/docs/guides/use-an-existing-obsidian-vault.md +6 -6
  74. package/agent-assets/docs/reference/api.md +26 -5
  75. package/agent-assets/docs/reference/cli-commands.md +3 -3
  76. package/agent-assets/docs/reference/config.md +51 -24
  77. package/agent-assets/docs/reference/disallowed-tools.md +6 -4
  78. package/agent-assets/docs/reference/keyboard-shortcuts.md +2 -2
  79. package/agent-assets/docs/reference/knowledge-layout.md +25 -12
  80. package/agent-assets/docs/reference/process-keys.md +9 -9
  81. package/agent-assets/docs/reference/skills.md +10 -6
  82. package/agent-assets/docs/troubleshooting/auth-failed.md +9 -8
  83. package/agent-assets/docs/troubleshooting/dashboard-shows-degraded.md +16 -9
  84. package/agent-assets/docs/troubleshooting/messaging-not-pairing.md +2 -2
  85. package/agent-assets/docs/troubleshooting/morning-routine-didnt-run.md +32 -16
  86. package/agent-assets/docs/troubleshooting/observation-not-detected.md +26 -24
  87. package/agent-assets/docs/troubleshooting/quota-exhausted.md +7 -6
  88. package/agent-assets/docs/troubleshooting/wiki-write-failed.md +3 -3
  89. package/agent-assets/skills/agent-actions/SKILL.md +23 -39
  90. package/agent-assets/skills/agent-create/SKILL.md +26 -6
  91. package/agent-assets/skills/attach/SKILL.md +8 -27
  92. package/agent-assets/skills/background-task/SKILL.md +184 -0
  93. package/agent-assets/skills/background-task-reply/SKILL.md +100 -0
  94. package/agent-assets/skills/browser-history/SKILL.md +60 -29
  95. package/agent-assets/skills/browser-history-respond/SKILL.md +6 -1
  96. package/agent-assets/skills/browser-task/SKILL.md +33 -31
  97. package/agent-assets/skills/context/SKILL.md +26 -34
  98. package/agent-assets/skills/context/curation.json +12 -12
  99. package/agent-assets/skills/context/references/api.md +22 -20
  100. package/agent-assets/skills/context/references/required-frontmatter.md +10 -9
  101. package/agent-assets/skills/context/references/snapshot-files.md +16 -15
  102. package/agent-assets/skills/context/seeds/file-responsibilities.seed.json +5 -5
  103. package/agent-assets/skills/context/seeds/frontmatter-requirements.seed.json +3 -3
  104. package/agent-assets/skills/docs-search/SKILL.md +19 -31
  105. package/agent-assets/skills/external-services/SKILL.delegated.claude.md +8 -95
  106. package/agent-assets/skills/external-services/SKILL.delegated.codex.md +8 -94
  107. package/agent-assets/skills/external-services/SKILL.delegated.gemini.md +8 -94
  108. package/agent-assets/skills/external-services/SKILL.native.claude.md +15 -9
  109. package/agent-assets/skills/external-services/SKILL.native.codex.md +11 -5
  110. package/agent-assets/skills/external-services/SKILL.native.gemini.md +11 -5
  111. package/agent-assets/skills/external-services/references/exec-errors.md +32 -0
  112. package/agent-assets/skills/external-services/references/skills-crud.md +5 -5
  113. package/agent-assets/skills/gmail-lifestyle/SKILL.md +3 -2
  114. package/agent-assets/skills/gmail-lifestyle/references/receipts-api.md +4 -0
  115. package/agent-assets/skills/gmail-lifestyle/references/travel-bookings-api.md +9 -0
  116. package/agent-assets/skills/mail/SKILL.delegated.claude.md +13 -25
  117. package/agent-assets/skills/mail/SKILL.delegated.codex.md +3 -2
  118. package/agent-assets/skills/mail/SKILL.delegated.gemini.md +3 -2
  119. package/agent-assets/skills/mail/SKILL.md +12 -20
  120. package/agent-assets/skills/mail/SKILL.native.claude.md +24 -16
  121. package/agent-assets/skills/mail/SKILL.native.codex.md +16 -9
  122. package/agent-assets/skills/mail/SKILL.native.gemini.md +12 -6
  123. package/agent-assets/skills/mail/references/api.md +6 -1
  124. package/agent-assets/skills/mail/references/examples.md +2 -1
  125. package/agent-assets/skills/managed-tasks/SKILL.md +44 -77
  126. package/agent-assets/skills/managed-tasks/references/errors.md +25 -14
  127. package/agent-assets/skills/managed-tasks/references/output-path.md +33 -17
  128. package/agent-assets/skills/managed-tasks/references/recurrence-rule.md +26 -16
  129. package/agent-assets/skills/management-policy/SKILL.md +36 -28
  130. package/agent-assets/skills/management-policy/curation.json +1 -1
  131. package/agent-assets/skills/management-policy/references/policy-workflow.md +30 -18
  132. package/agent-assets/skills/notify/SKILL.md +16 -13
  133. package/agent-assets/skills/notify/references/priority.md +42 -26
  134. package/agent-assets/skills/notion/SKILL.delegated.claude.md +1 -1
  135. package/agent-assets/skills/notion/SKILL.delegated.codex.md +1 -1
  136. package/agent-assets/skills/notion/SKILL.delegated.gemini.md +1 -1
  137. package/agent-assets/skills/notion/SKILL.md +18 -18
  138. package/agent-assets/skills/notion/SKILL.native.claude.md +4 -4
  139. package/agent-assets/skills/notion/SKILL.native.codex.md +3 -3
  140. package/agent-assets/skills/notion/SKILL.native.gemini.md +3 -3
  141. package/agent-assets/skills/observations/SKILL.md +9 -24
  142. package/agent-assets/skills/observations/references/fetch-fallback.md +22 -0
  143. package/agent-assets/skills/project-doc/SKILL.md +9 -6
  144. package/agent-assets/skills/project-doc/curation.json +3 -3
  145. package/agent-assets/skills/project-doc/seeds/project-shape.seed.json +2 -2
  146. package/agent-assets/skills/project-doc/seeds/slug-grammar.seed.json +3 -3
  147. package/agent-assets/skills/reading/SKILL.md +8 -42
  148. package/agent-assets/skills/reading/references/reading-taste.md +5 -5
  149. package/agent-assets/skills/roadmap/SKILL.md +3 -19
  150. package/agent-assets/skills/roadmap/references/api.md +23 -8
  151. package/agent-assets/skills/roadmap/references/horizon-tags.md +11 -0
  152. package/agent-assets/skills/roadmap/references/migration.md +8 -6
  153. package/agent-assets/skills/roadmap/references/retention.md +18 -0
  154. package/agent-assets/skills/schedule/SKILL.md +20 -28
  155. package/agent-assets/skills/schedule/references/importance.md +23 -0
  156. package/agent-assets/skills/schedule/references/recurrence-rule.md +26 -16
  157. package/agent-assets/skills/scheduled-managed-task/SKILL.md +46 -46
  158. package/agent-assets/skills/today/SKILL.md +38 -81
  159. package/agent-assets/skills/today/references/agent-plan-lifecycle.md +9 -4
  160. package/agent-assets/skills/today/references/agent-plan-revision.md +28 -0
  161. package/agent-assets/skills/today/references/today-skeleton.md +66 -0
  162. package/agent-assets/skills/today/seeds/agent-notes-flavors.seed.json +1 -1
  163. package/agent-assets/skills/today/seeds/section-shape.seed.json +6 -6
  164. package/agent-assets/skills/user-interview/SKILL.md +15 -90
  165. package/agent-assets/skills/user-interview/references/op-briefing.md +1 -1
  166. package/agent-assets/skills/user-interview/references/op-dm-handler.md +88 -0
  167. package/agent-assets/skills/user-interview/references/op-morning.md +2 -2
  168. package/agent-assets/skills/user-interview/references/sweep-and-fallback.md +1 -1
  169. package/agent-assets/skills/user-profile/SKILL.md +16 -26
  170. package/agent-assets/skills/user-profile/curation.json +3 -3
  171. package/agent-assets/skills/user-profile/references/character-preferences.md +3 -3
  172. package/agent-assets/skills/wiki/wiki-ask/SKILL.md +1 -1
  173. package/agent-assets/skills/wiki/wiki-compile/SKILL.md +5 -4
  174. package/agent-assets/skills/wiki/wiki-connect/SKILL.md +32 -5
  175. package/agent-assets/skills/wiki/wiki-ingest/SKILL.md +6 -50
  176. package/agent-assets/skills/wiki/wiki-ingest/references/curl-errors.md +58 -0
  177. package/agent-assets/skills/wiki/wiki-lint/SKILL.md +20 -14
  178. package/agent-assets/skills/wiki/wiki-trace/SKILL.md +10 -5
  179. package/agent-assets/skills/wiki/wiki-vault-rules/SKILL.md +2 -0
  180. package/agent-assets/system-prompts/routine-research-cluster-update.md +71 -0
  181. package/agent-assets/task-flows/_partials/feedback-capture.md +30 -0
  182. package/agent-assets/task-flows/_partials/notion-acquire.notion.md +47 -21
  183. package/agent-assets/task-flows/background_task.md +81 -0
  184. package/agent-assets/task-flows/git.local_ahead.stale.md +1 -1
  185. package/agent-assets/task-flows/git.push.detected.md +1 -1
  186. package/agent-assets/task-flows/git.tag.created.md +1 -1
  187. package/agent-assets/task-flows/github.assigned.md +1 -1
  188. package/agent-assets/task-flows/github.pull_request.review_requested.md +2 -2
  189. package/agent-assets/task-flows/github.security_alert.md +1 -1
  190. package/agent-assets/task-flows/message.received.dm.md +11 -3
  191. package/agent-assets/task-flows/message.received.dm_first.md +8 -2
  192. package/agent-assets/task-flows/{routine.hourly_check.md → routine.activity_scan.md} +31 -23
  193. package/agent-assets/task-flows/{routine.hourly_check.triage.md → routine.activity_scan.triage.md} +3 -3
  194. package/agent-assets/task-flows/routine.evening_review.md +80 -0
  195. package/agent-assets/task-flows/routine.monthly_review.md +81 -8
  196. package/agent-assets/task-flows/routine.research_cluster_update.md +33 -19
  197. package/agent-assets/task-flows/routine.roadmap_refresh.md +2 -2
  198. package/agent-assets/task-flows/routine.today_refresh.md +1 -1
  199. package/agent-assets/task-flows/routine.weekly_review.md +124 -4
  200. package/agent-assets/task-flows/schedule.approaching.md +2 -2
  201. package/agent-assets/task-flows/scheduled.dm.md +77 -1
  202. package/agent-assets/task-flows/scheduled.task.md +7 -1
  203. package/agent-assets/task-flows/wiki.trace.md +1 -1
  204. package/agent-assets/templates/_manifest.json +2 -2
  205. package/agent-assets/templates/knowledge/dossiers/_index.md +1 -1
  206. package/agent-assets/templates/knowledge/dossiers/{hourly.md → activity-scan.md} +1 -1
  207. package/agent-assets/templates/policies/journal-format.md +1 -1
  208. package/agent-assets/templates/policies/mcp.md +1 -1
  209. package/agent-assets/templates/policies/routines/_index.md +1 -1
  210. package/agent-assets/templates/policies/routines/{hourly.md → activity-scan.md} +5 -5
  211. package/bin/aitne.mjs +45 -11
  212. package/package.json +6 -5
  213. package/scripts/commands/doctor.mjs +11 -2
  214. package/scripts/lib/process-identity.d.mts +46 -0
  215. package/scripts/lib/process-identity.mjs +193 -0
  216. package/scripts/lib/read-api-token.mjs +1 -1
  217. package/scripts/start.mjs +14 -4
  218. package/agent-assets/docs/features/routines/hourly-check.md +0 -205
@@ -13,7 +13,7 @@ summary: |
13
13
  Causes are ordered by frequency: daemon was stopped at the trigger
14
14
  time, both backends failed, quota exhausted, the routine threw and is
15
15
  mid-retry, or it is a day-boundary subtlety. Most cases self-heal via
16
- boot-time catch-up or the retry/stall watchdog.
16
+ boot/wake catch-up, the missed-fire self-heal, or the retry chain.
17
17
  section: morning-routine-didnt-run
18
18
  tags:
19
19
  - troubleshooting
@@ -28,7 +28,7 @@ ask_examples:
28
28
  - How do I regenerate today.md by hand?
29
29
  locale: en-US
30
30
  created: 2026-04-25
31
- updated: 2026-05-28
31
+ updated: 2026-06-10
32
32
  keywords:
33
33
  - morning routine didn't run
34
34
  - morning routine skipped
@@ -37,7 +37,7 @@ keywords:
37
37
  - regenerate today
38
38
  related:
39
39
  - features/routines/morning-routine
40
- - features/routines/hourly-check
40
+ - features/routines/activity-scan
41
41
  - concepts/agent-day
42
42
  - troubleshooting/auth-failed
43
43
  - troubleshooting/quota-exhausted
@@ -52,7 +52,7 @@ config_keys:
52
52
  context_files:
53
53
  - state/today.md
54
54
  ui_anchors:
55
- - /settings/routines
55
+ - /agents/morning-routine
56
56
  - /activity
57
57
  ---
58
58
 
@@ -66,26 +66,42 @@ ui_anchors:
66
66
 
67
67
  ## Before You Worry: It Often Self-Heals
68
68
 
69
- The morning routine has two recovery paths that usually fix this
69
+ The morning routine has several recovery paths that usually fix this
70
70
  without any action from you:
71
71
 
72
72
  - **Boot-time catch-up.** If the daemon was stopped during the trigger
73
73
  window, it fires the unrun morning routine the next time it starts.
74
74
  So a missed routine often resolves itself on the next `aitne start`
75
75
  or `aitne restart`.
76
+ - **Sleep wake catch-up.** If the machine was asleep at the trigger
77
+ minute (laptop lid closed at 04:00), the cron fire is silently lost —
78
+ cron never replays missed ticks. The daemon detects the wall-clock
79
+ gap when the machine wakes and queues the morning routine itself,
80
+ along with any missed evening/weekly reviews.
81
+ - **Missed-fire self-heal.** A periodic check (every 10 minutes)
82
+ notices when the day is more than ~15 minutes old with no morning
83
+ attempt and nothing queued, and queues the routine. This covers
84
+ sleeps too short for the wake detector and any other lost trigger.
76
85
  - **Retry on failure.** If the routine runs but fails to produce a
77
86
  fresh `state/today.md`, the daemon retries up to 3 times with an
78
87
  exponential back-off (5, then 10, then 15 minutes). After 3 failed
79
- attempts it sends you a DM asking you to regenerate manually. If the
80
- wake row sits unfinished for ~2 hours (the stall watchdog threshold),
81
- you also get an owner DM so the silence never goes unnoticed.
88
+ attempts it sends you a DM asking you to regenerate manually.
89
+ - **Hung-run recovery.** If a run starts and then wedges (typically a
90
+ sleep mid-run that kills the backend connection), the self-heal
91
+ check re-queues it once the run has been silent past the stall
92
+ threshold (~2 hours by default) — at most twice per day, after which
93
+ it alerts instead of re-running. Either way you get an owner DM so
94
+ the silence never goes unnoticed.
82
95
 
83
96
  Give it a few minutes, or restart the daemon, before digging deeper.
84
97
 
85
98
  ## Most Likely Causes (in probability order)
86
99
 
87
- 1. **Daemon was stopped at the trigger time.** Check `aitne status`.
88
- Boot-time catch-up should cover this once the daemon is back up.
100
+ 1. **Daemon was stopped or the machine was asleep at the trigger
101
+ time.** Check `aitne status`. Boot-time catch-up covers the stopped
102
+ case once the daemon is back up; sleep wake catch-up and the
103
+ missed-fire self-heal cover the asleep case within minutes of the
104
+ machine waking.
89
105
  2. **Both backends failed.** The routine tried the main backend, fell
90
106
  back, and the fallback failed too. Check `/activity` for an error
91
107
  outcome and `aitne logs` for the failure.
@@ -99,9 +115,9 @@ Give it a few minutes, or restart the daemon, before digging deeper.
99
115
  the routine still "belongs to" yesterday — see
100
116
  [Agent Day](../concepts/agent-day.md).
101
117
 
102
- Note: the morning routine takes priority over the hourly check, not the
103
- other way around. The hourly check skips itself while the morning
104
- routine is active, so a running hourly check never blocks the morning
118
+ Note: the morning routine takes priority over the activity scan, not the
119
+ other way around. The activity scan skips itself while the morning
120
+ routine is active, so a running activity scan never blocks the morning
105
121
  routine.
106
122
 
107
123
  ## Diagnostic Steps
@@ -109,8 +125,8 @@ routine.
109
125
  1. `aitne status` — is the daemon up?
110
126
  2. `/activity` — is there a row for `routine.morning_routine`? An error
111
127
  outcome points to a backend failure (cause 2 or 3).
112
- 3. `/settings/routines` — the routine list shows the next scheduled
113
- fire and recent runs.
128
+ 3. `/agents` — the morning-routine card shows its schedule, status,
129
+ and last run; open `/agents/morning-routine` for recent executions.
114
130
  4. `aitne logs` — search for `morning_routine` to see the trigger,
115
131
  any fallback, and retry scheduling.
116
132
 
@@ -136,5 +152,5 @@ synthesis immediately.
136
152
  ## Related
137
153
 
138
154
  - [Morning Routine](../features/routines/morning-routine.md)
139
- - [Hourly Check](../features/routines/hourly-check.md)
155
+ - [Activity Scan](../features/routines/activity-scan.md)
140
156
  - [Agent Day](../concepts/agent-day.md)
@@ -7,47 +7,47 @@ aliases:
7
7
  - observation missing
8
8
  - no observations
9
9
  - polling broken
10
- - hourly check empty
10
+ - activity scan empty
11
11
  category: troubleshooting
12
12
  summary: |
13
13
  An expected change (commit, note, calendar move) didn't surface in
14
- the hourly check. Most often a polling delay, a vault/repo not
14
+ the activity scan. Most often a polling delay, a vault/repo not
15
15
  watched, or a change the agent authored itself (filtered out).
16
16
  section: troubleshooting
17
17
  tags:
18
18
  - troubleshooting
19
19
  - observations
20
20
  - polling
21
- - hourly-check
21
+ - activity-scan
22
22
  status: stable
23
23
  ask_examples:
24
24
  - Why didn't the agent notice my new commit?
25
25
  - Why didn't a calendar change show up?
26
- - Why is the hourly check empty?
26
+ - Why is the activity scan empty?
27
27
  locale: en-US
28
28
  created: 2026-04-25
29
- updated: 2026-05-28
29
+ updated: 2026-06-10
30
30
  keywords:
31
31
  - observation
32
32
  - polling
33
33
  - observer
34
34
  - AgentWriteTracker
35
- - hourly check
35
+ - activity scan
36
36
  related:
37
37
  - concepts/observations
38
- - features/routines/hourly-check
38
+ - features/routines/activity-scan
39
39
  - features/integrations/git
40
40
  - features/integrations/obsidian
41
41
  config_keys:
42
- - hourlyCheckMinObservations
43
- - hourlyCheckEnabled
44
- - hourlyCheckIntervalMinutes
42
+ - activityScanMinObservations
43
+ - activityScanEnabled
44
+ - activityScanIntervalMinutes
45
45
  process_keys:
46
- - routine.hourly_check
46
+ - routine.activity_scan
47
47
  ui_anchors:
48
48
  - /connections/repositories
49
49
  - /connections/calendar
50
- - /settings/schedule
50
+ - /agents/activity-scan
51
51
  context_files:
52
52
  - state/today.md
53
53
  ---
@@ -55,24 +55,24 @@ context_files:
55
55
  # Observation Not Detected
56
56
 
57
57
  You made a change by hand — a commit, an Obsidian note, a calendar move — and
58
- expected the agent to notice it on the next hourly check. It didn't.
58
+ expected the agent to notice it on the next activity scan. It didn't.
59
59
 
60
60
  This is almost always one of four things: the poller hasn't run yet, the
61
61
  source isn't being watched, the agent itself made the change (so it was
62
- filtered out), or there weren't enough observations to clear the hourly-check
62
+ filtered out), or there weren't enough observations to clear the activity-scan
63
63
  gate. Work through them in that order.
64
64
 
65
65
  ## How detection actually works
66
66
 
67
67
  Observers (Obsidian, Git, Notion, Calendar) do **not** fire an event per
68
68
  change. They poll on a cadence and call `recordObservation(...)`, which
69
- appends a row to the `observations` table. The hourly check later reads those
69
+ appends a row to the `observations` table. The activity scan later reads those
70
70
  rows in a single batch. So a "missing" observation is usually a row that was
71
71
  never written, or one that was written but filtered.
72
72
 
73
73
  `AgentWriteTracker` tags every change as `actor='agent'` or `actor='user'`.
74
74
  Changes the agent itself wrote are tagged `actor='agent'` and skipped by the
75
- hourly check — this is the deliberate anti-loop filter that stops the agent
75
+ activity scan — this is the deliberate anti-loop filter that stops the agent
76
76
  from observing its own output.
77
77
 
78
78
  ## Most likely causes
@@ -84,9 +84,10 @@ from observing its own output.
84
84
  was never connected, nothing polls it.
85
85
  3. **The change was tagged `actor='agent'`.** If the agent (not you) authored
86
86
  the commit or note, the anti-loop filter drops it.
87
- 4. **It was below the gate threshold.** The hourly check only runs its full
88
- pass when at least `hourlyCheckMinObservations` (default `1`) pending
89
- observations exist. A single low-signal change can be held back.
87
+ 4. **It was below the gate threshold.** The activity scan only runs its full
88
+ pass when at least the activity-scan agent's **min observations**
89
+ threshold (default `1`; legacy key `activityScanMinObservations`) of
90
+ pending observations exists. A single low-signal change can be held back.
90
91
 
91
92
  ## Diagnostic steps
92
93
 
@@ -101,21 +102,22 @@ from observing its own output.
101
102
  3. **Rule out the agent-authored filter.** If the commit or note was written
102
103
  by the agent, that's expected — it's filtered by design. Look for a change
103
104
  *you* made by hand to test detection.
104
- 4. **Lower the gate threshold to test.** Temporarily set
105
- `hourlyCheckMinObservations` to `1` (its default) on `/settings/schedule`
105
+ 4. **Lower the gate threshold to test.** Temporarily set **Min
106
+ observations** to `1` (its default) on the activity-scan agent's page
107
+ (`/agents/activity-scan`, Definition tab → Cadence card)
106
108
  so even a single observation triggers the check, then make a manual change
107
- and wait for the next hourly run.
109
+ and wait for the next activity-scan run.
108
110
 
109
111
  ## Confirming the fix
110
112
 
111
113
  After the next poll runs, a manual change you made should record an
112
- observation and surface in the next hourly check. You can cross-check recent
114
+ observation and surface in the next activity scan. You can cross-check recent
113
115
  agent activity from the CLI with `aitne audit`, which reads the `agent_actions`
114
116
  log read-only.
115
117
 
116
118
  ## Related
117
119
 
118
120
  - [Observations](../concepts/observations.md) — what gets recorded and why
119
- - [Hourly Check](../features/routines/hourly-check.md) — the gate and its thresholds
121
+ - [Activity Scan](../features/routines/activity-scan.md) — the gate and its thresholds
120
122
  - [Git integration](../features/integrations/git.md)
121
123
  - [Obsidian integration](../features/integrations/obsidian.md)
@@ -26,7 +26,7 @@ ask_examples:
26
26
  - Why did an autonomous run get skipped for the cost cap?
27
27
  locale: en-US
28
28
  created: 2026-04-25
29
- updated: 2026-05-28
29
+ updated: 2026-06-07
30
30
  keywords:
31
31
  - quota
32
32
  - BackendQuotaError
@@ -54,8 +54,9 @@ related:
54
54
  - Fallback ran the next routine instead of main.
55
55
  - Or: an autonomous run was skipped with reason
56
56
  `autonomous_cost_cap_exceeded` — this is a *separate* safety net
57
- (`autonomousDailyCostCapUsd` / `autonomousMonthlyCostCapUsd`,
58
- default off) that skips only autonomous work, never reactive DMs.
57
+ (`autonomousDailyCostCapUsd`, default off) that skips only autonomous
58
+ work, never reactive DMs. (`autonomousMonthlyCostCapUsd`, also default
59
+ off, is notifications-only — it never skips a run, just alerts.)
59
60
  It is not a provider quota error; raise the cap on `/settings/models`
60
61
  or wait for the next agent day.
61
62
 
@@ -92,9 +93,9 @@ related:
92
93
  account's spending / rate-limit settings. For cloud providers,
93
94
  open the matching console (AWS / GCP / Azure) and check the
94
95
  per-region / per-model quota.
95
- 4. If on the subscription fallback, the backend card shows the
96
- "next reset" timestamp for the rolling window. Consider
97
- registering an API key — see
96
+ 4. If on the subscription fallback, the `BackendQuotaError` message in
97
+ Activity carries the "next reset" timestamp for the rolling window
98
+ (when the provider reports one). Consider registering an API key — see
98
99
  [Costs and Quotas](../concepts/costs-and-quotas.md).
99
100
 
100
101
  ## Confirming the Fix
@@ -25,7 +25,7 @@ ask_examples:
25
25
  - How do I retry the write-strategy probe?
26
26
  locale: en-US
27
27
  created: 2026-05-12
28
- updated: 2026-05-28
28
+ updated: 2026-06-11
29
29
  keywords:
30
30
  - wiki write failed
31
31
  - wiki API failure
@@ -36,7 +36,7 @@ api_endpoints:
36
36
  - /api/wiki/:workspace/health
37
37
  ui_anchors:
38
38
  - /settings/wiki
39
- - /connections/knowledge
39
+ - /connections/notes
40
40
  related:
41
41
  - features/wiki/overview
42
42
  - guides/use-an-existing-obsidian-vault
@@ -84,7 +84,7 @@ If any of these is missing, the daemon surfaces a structured error:
84
84
 
85
85
  | Error code | Meaning | Fix |
86
86
  |---|---|---|
87
- | `EWIKI_CLI_UNAVAILABLE` | Aitne's `ObsidianService` is not configured (the `obsidian` binary is not resolvable on `PATH`). | Open **Connections → Knowledge** and connect Obsidian via the Obsidian card, then confirm Obsidian 1.12+ is installed with the CLI enabled. |
87
+ | `EWIKI_CLI_UNAVAILABLE` | Aitne's `ObsidianService` is not configured (the `obsidian` binary is not resolvable on `PATH`). | Open **Connections → Notes** and connect Obsidian via the Obsidian card, then confirm Obsidian 1.12+ is installed with the CLI enabled. |
88
88
  | `EWIKI_CLI_NOT_RUNNING` | The CLI is configured but the Obsidian app is not running, so it cannot reach the sandboxed vault. | Launch the Obsidian app and retry. |
89
89
 
90
90
  ## Force a Re-Probe
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: agent-actions
3
- description: Load when the running session needs to write structured metadata into its own `agent_actions` row so daemon-side consumers (morning-routine AgentJournalAppender, anomaly surfacing, audit log) read structured data instead of parsing prose.
3
+ description: Load near the end of a morning-routine / dispatcher session to record dayType, anomalies, inbox stats, and files-touched into your own `agent_actions` row, so daemon-side consumers (morning-routine journal appender, audit log) read structured data instead of parsing prose.
4
4
  allowed-tools:
5
5
  - Bash(curl *)
6
6
  - Read
@@ -41,7 +41,8 @@ header attachment for you — you do not type them. The endpoint returns
41
41
  if no in-flight row matches your session — typically because the row
42
42
  has already settled to a terminal `result`, or because the dispatcher
43
43
  spawned the session without the pre-insert step that the morning
44
- routine's pipeline orchestrator owns. Surface as anomaly and continue.
44
+ routine's pipeline orchestrator owns. Record it in this endpoint's
45
+ `anomalies` field (when accessible) or DM the operator, then continue.
45
46
 
46
47
  ## Metadata shape
47
48
 
@@ -51,12 +52,12 @@ The morning-routine Stage A is the primary caller. Its expected shape:
51
52
 
52
53
  | Field | Type | Purpose |
53
54
  |---|---|---|
54
- | `dayType` | `"weekday" \| "weekend" \| "focus" \| "off"` | The day-type Stage A derived. ⑥ AgentJournalAppender writes this into agent/journal.md's header line. |
55
- | `anomalies` | `string[]` | Free-form anomalies you encountered (e.g. "AgentPlan cardinality mismatch: today.md has 6 rows, batch had 5"). ⑥ surfaces these in agent/journal.md and `pnpm audit` filters on them. |
56
- | `filesTouched` | `string[]` | Paths your turn wrote to (e.g. `context/today.md`, `context/roadmap.md`). |
55
+ | `dayType` | `"weekday" \| "weekend" \| "focus" \| "off"` | The day-type Stage A derived. ⑥ AgentJournalAppender writes this into journal/agent.md's header line. |
56
+ | `anomalies` | `string[]` | Free-form anomalies you encountered (e.g. "AgentPlan cardinality mismatch: today.md has 6 rows, batch had 5"). ⑥ surfaces these in journal/agent.md. |
57
+ | `filesTouched` | `string[]` | Paths your turn wrote to (e.g. `state/today.md`, `plans/roadmap.md`). |
57
58
  | `inboxStats` | `{triaged, movedToScratch, dmConfirmsSent, secretsSkipped}` | Inbox triage counts from Step 4. All keys integers >= 0. `secretsSkipped` is collected but NOT rendered by ⑥; surface secret-skip events through `anomalies` as well so they reach the audit trail. |
58
59
  | `morningChecks` | `string[]` | Short labels for every Step 8 `policies/routines/morning.md` extension check executed (e.g. `"water bottle filled"`). ⑥ joins these with `, ` into the `Checks from routines/morning.md:` bullet. Empty array → renders as `(none)`. |
59
- | `scheduleBatchSize` | `number` | Cardinality you observed when posting to `/api/schedule/batch`. Mirrors what was POSTed so ⑥ can detect cardinality mismatches against today.md. |
60
+ | `scheduleBatchSize` | `number` | Cardinality you observed when posting to `/api/schedule/batch`. Informational metadata mirroring what was POSTed. |
60
61
 
61
62
  The endpoint accepts any well-formed JSON object — these are the keys
62
63
  the morning-routine pipeline consumes. Skills can extend the shape
@@ -71,7 +72,7 @@ curl -s -X PATCH http://localhost:8321/api/agent-actions/self \
71
72
  "metadata": {
72
73
  "dayType": "weekday",
73
74
  "anomalies": [],
74
- "filesTouched": ["context/today.md", "context/roadmap.md"],
75
+ "filesTouched": ["state/today.md", "plans/roadmap.md"],
75
76
  "inboxStats": { "triaged": 4, "movedToScratch": 4, "dmConfirmsSent": 1, "secretsSkipped": 0 },
76
77
  "morningChecks": ["water bottle filled", "calendar synced"],
77
78
  "scheduleBatchSize": 5
@@ -86,37 +87,20 @@ Success (200):
86
87
 
87
88
  ## Errors
88
89
 
89
- Every error response uses the **agent-consumable envelope**:
90
-
91
- ```jsonc
92
- {
93
- "ok": false,
94
- "summary": "Request rejected: agent_actions.session_identity_missing on headers.x-pa-event-correlation-id.",
95
- "errors": [
96
- {
97
- "rowIndex": null,
98
- "code": "agent_actions.session_identity_missing",
99
- "field": "headers.x-pa-event-correlation-id",
100
- "received": "<missing>",
101
- "expected": "x-pa-event-correlation-id and x-process-key headers identifying the running session",
102
- "hint": "The pa-api shim auto-injects these from PA_EVENT_CORRELATION_ID and PA_PROCESS_KEY when running inside a dispatcher-spawned session.",
103
- "skillAnchor": "agent-actions#self-write-auth",
104
- "severity": "error"
105
- }
106
- ],
107
- "retryable": false
108
- }
109
- ```
90
+ Failures return an agent-consumable envelope (`ok:false`) carrying a
91
+ `code`, a `hint`, and a `skillAnchor` back into this skill. The two
92
+ session-state codes below are `retryable:false` — do NOT re-fire; record
93
+ the failure in this endpoint's `anomalies` field (when accessible) or DM
94
+ the operator, then continue. A malformed-body code is retryable — fix the
95
+ body and resend.
110
96
 
111
- ### Codes the endpoint can emit
97
+ Two codes reflect session state you must reason about:
112
98
 
113
- | Code | When | Fix |
114
- |---|---|---|
115
- | `agent_actions.session_identity_missing` | `x-pa-event-correlation-id` or `x-process-key` header is absent / empty. | Running inside a dispatcher-spawned session the pa-api shim attaches both headers from env. If you see this, the session is misconfigured — surface it as an anomaly via `<safety_violation>` and stop. Not retryable in the same turn. |
116
- | `agent_actions.session_row_not_found` | No in-flight `agent_actions` row matches `(event_id, action_type)`. | Either the row has already settled to a terminal result (success/failed/partial) and your PATCH arrived late, or the dispatcher spawned this session without the orchestrator-side pre-insert that the morning-routine pipeline relies on. Either way, the PATCH cannot land — surface as anomaly and continue. Not retryable. |
117
- | `agent_actions.body_not_object` | Request body is not a JSON object. | POST `{"metadata":{…}}`. |
118
- | `agent_actions.metadata_field_invalid` | `metadata` slot is missing, not an object, an array, or carries non-JSON-serialisable values (functions, Symbols, BigInts). | Pass a plain JSON object literal. Arrays go inside named keys (e.g. `anomalies:[…]`). |
119
-
120
- `retryable:false` means the agent should NOT retry the same call; it
121
- should surface the failure as a structured anomaly (via this endpoint's
122
- `anomalies` field when accessible) or DM the operator.
99
+ | Code | When |
100
+ |---|---|
101
+ | `agent_actions.session_identity_missing` | `x-pa-event-correlation-id` or `x-process-key` header is absent / empty the session is misconfigured. The shim normally attaches both from env. |
102
+ | `agent_actions.session_row_not_found` | No in-flight row matches `(event_id, action_type)` either the row already settled to a terminal result and your PATCH arrived late, or the dispatcher spawned the session without the orchestrator-side pre-insert. |
103
+
104
+ A malformed body fails with `agent_actions.body_not_object` (send
105
+ PATCH `{"metadata":{…}}`) or `agent_actions.metadata_field_invalid`
106
+ (pass a plain JSON object; arrays go inside named keys).
@@ -28,7 +28,10 @@ recurring DM with no autonomous work, use `dm_session` (above), not an Agent.
28
28
  ## Before creating — dedup (mandatory)
29
29
 
30
30
  1. `GET /api/agents` — does an enabled Agent already do this on this cadence? If
31
- so, do not create a duplicate (edit it via the dashboard / `PATCH /api/agents/:slug`).
31
+ so, do not create a duplicate. To edit one: `PATCH /api/agents/:slug` only
32
+ toggles `enabled` (field edits return `400 user_agent_edit_via_file`); to
33
+ change a user Agent's prompt/schedule/backend, edit its `agent.md`
34
+ (`PATCH /api/context/policies/agents/<slug>/agent.md`) or the dashboard editor.
32
35
  2. `GET /api/recurring-schedules?enabled=true` — confirm no existing recurring
33
36
  row already covers the cadence.
34
37
 
@@ -54,8 +57,12 @@ curl -s -X POST http://localhost:8321/api/agents \
54
57
  ```
55
58
 
56
59
  Fields:
57
- - **`slug`** — kebab-case, unique, immutable after creation (the `/agents/<slug>` URL).
58
- - **`name`**, **`description`** human labels shown in the dashboard.
60
+ - **`slug`** — kebab-case, must start with a lowercase letter (`^[a-z][a-z0-9-]*`),
61
+ unique, immutable after creation (the `/agents/<slug>` URL). A leading digit or
62
+ hyphen is rejected as `invalid_definition` on field `slug`.
63
+ - **`name`**, **`description`** — required human labels shown in the dashboard; an
64
+ empty/omitted `description` is rejected as `invalid_definition` on field
65
+ `description`.
59
66
  - **`schedule.kind`** — `"recurring"` (structured, preferred) or `"cron"` (raw
60
67
  expression). A `one_shot`/`event` schedule is rejected with
61
68
  `one_shot_not_supported` (use `/schedule` for one-time work). Note:
@@ -77,10 +84,18 @@ Fields:
77
84
  in the resolved timezone (`min hour day-of-month month day-of-week`). Examples:
78
85
  `0 9 * * *` (daily 09:00), `0 8 * * 1` (Mondays 08:00), `0 * * * *` (hourly at
79
86
  :00), `0 */2 * * *` (every 2 hours), `0 18 1 * *` (1st of each month 18:00).
80
- Only cron shapes that map to a recurrence are accepted: minute a single value;
81
- hour a single value or `*` / `*/N`. Sub-hourly steps (`*/30`) and hour
82
- ranges/lists are NOT representable pick one explicit cadence.
87
+ A syntactically-valid cron is accepted at create (`201`, valid row) even if it
88
+ cannot be mapped to a recurrence but a non-mappable shape (sub-hourly steps
89
+ like `*/30`, hour ranges/lists like `9-17`) is never paired and silently never
90
+ fires. Only shapes that map are actually run: minute a single value; hour a
91
+ single value or `*` / `*/N`. Pick one explicit, mappable cadence.
83
92
  - **`schedule.timezone`** — IANA zone; omit to inherit the daemon default.
93
+ - **`schedule.defer_in_quiet_hours`** — boolean, default `false`. When `true`, a
94
+ firing that lands inside the user's quiet hours is pushed to the window's end
95
+ instead of running — the whole run moves, so the data is fresh at delivery
96
+ time. Mechanical rule: **set `true` whenever the Expected output includes
97
+ DMing the user**; leave it `false` for silent file-writing work deliberately
98
+ scheduled overnight.
84
99
  - **`backend`** — optional. `tier` is `lite`/`medium`/`high` (cost/capability knob;
85
100
  the standalone control that works). `process_key` defaults to `agent.task`;
86
101
  omit unless you know you need another. (Pinning a backend *engine* without a
@@ -128,6 +143,11 @@ Each morning, surface inbox items that need the user's decision today.
128
143
  **Bad prompt:** `"Triage my inbox."` — no requirements, no steps, no output
129
144
  contract; the Agent will improvise differently every day.
130
145
 
146
+ The Expected-output decision feeds one schedule field: if the output contract
147
+ includes DMing the user, also set `schedule.defer_in_quiet_hours: true` so a
148
+ firing inside quiet hours waits for the window's end instead of producing a
149
+ message that would be held anyway.
150
+
131
151
  ## Responses & errors
132
152
 
133
153
  - `201 { "status": "created", "slug": "…" }` — the Agent is live; its recurring
@@ -27,21 +27,7 @@ Only the following tools are available inside this skill. Everything else is den
27
27
  | `Write` | Create the file to upload (text, markdown, CSV, JSON, YAML). |
28
28
  | `Bash(curl *)` | Issue exactly one POST to the daemon per file. |
29
29
 
30
- ### Commands that WILL be denieddo not attempt
31
-
32
- The Claude Code permission classifier blocks these patterns under `dontAsk`. Attempting them wastes a turn and confuses the user.
33
-
34
- - **Any shell expansion of an environment variable**: `$PA_TURN_TOKEN`, `$HOME`, `$(date +%Y)`, `` `whoami` `` — all auto-denied. This is why the turn token is injected by the daemon's curl wrapper instead of being passed inline (see below).
35
- - `ls /tmp/...` / `ls <absolute-path>` — absolute-path listings are auto-denied.
36
- - `cat <file>`, `head`, `tail`, `stat`, `file`, `test -f`, `echo <anything>` — none are on the allowlist.
37
- - Chained commands via `&&`, `||`, `;`, `|` — each segment is evaluated separately; any segment outside the allowlist fails the whole line.
38
- - `python3 ...`, `pandoc`, `node <script>`, `sh -c`, etc. — not on the allowlist. Binary/PDF/chart generation is out of scope for Phase 1; stick to text formats you can `Write`.
39
-
40
- If you *think* you need one of the above, the answer is to pre-compute the value in your reasoning, write it as a literal, and invoke curl once with no substitutions.
41
-
42
- ## Per-turn capability token
43
-
44
- The daemon issues a per-turn token and makes the session's curl wrapper (`.pa/bin/curl`) attach it automatically to requests to `/api/chat/outbound-attachments`. **Do not pass `X-Turn-Token` yourself** — inline `$PA_TURN_TOKEN` expansion is blocked by the permission classifier, and the wrapper already handles this for you.
30
+ - **curl with literal strings only.** No `$VAR` / `$(...)` / backticks / pipes / chained commands (`&&`, `||`, `;`, `|`) the `dontAsk` classifier silently denies them. Pre-compute any value in your reasoning and write it as a literal. The session's curl wrapper (`.pa/bin/curl`) injects `X-Turn-Token` from `PA_TURN_TOKEN` for you — never pass it yourself, and binary/PDF/chart generation (`python3`, `pandoc`, `node`) is out of scope for Phase 1; stick to text formats you can `Write`.
45
31
 
46
32
  If the turn has already ended (or no token was issued), the daemon returns HTTP 403 `missing_turn_token`. Treat that as a terminal signal, not something to retry.
47
33
 
@@ -56,21 +42,19 @@ curl -s -X POST http://localhost:8321/api/chat/outbound-attachments \
56
42
  -H "X-Filename: weekly-summary.md" \
57
43
  -H "X-Caption: Weekly summary" \
58
44
  -F "file=@/tmp/weekly-summary.md"
59
- # → {"id":"<uuid>"} on success
60
- # → {"error":"missing_turn_token"} HTTP 403
61
- # → {"error":"invalid_turn_token"} HTTP 403
62
- # → {"error":"too_large"} HTTP 400
63
- # → {"error":"disallowed_mime"} HTTP 400
64
- # → {"error":"too_many_uploads"} HTTP 429
45
+ # → {"id":"<uuid>"} HTTP 200 — success
46
+ # → 403 — turn token missing/invalid; do not retry (see Errors table)
65
47
  ```
66
48
 
49
+ Errors return the standard agent-error envelope `{ok:false,summary,errors:[{code,field,hint}],retryable,error:<code>}`. Branch on the flat `error` field (a legacy alias for the single issue code); the codes in the Errors table are accurate.
50
+
67
51
  | Header / field | Purpose |
68
52
  |---|---|
69
53
  | `file` (form field, binary) | The bytes to deliver. Stream from a file you just created with `Write`. |
70
54
  | `X-Filename` | Optional. Overrides the filename shown to the user. Literal string — no substitutions. Default: the multipart `filename` parameter. |
71
55
  | `X-Caption` | Optional. ≤ 1024 chars. Literal string — no `$(...)` / backticks. |
72
56
 
73
- > The wrapper silently adds `X-Turn-Token` from `PA_TURN_TOKEN`. Do not add it yourself. If you *do* pass `X-Turn-Token` explicitly (e.g. during local debugging), the wrapper will respect your value and not overwrite it.
57
+ > If you *do* pass `X-Turn-Token` explicitly (e.g. during local debugging), the wrapper respects your value and does not overwrite it.
74
58
 
75
59
  ### Size and type limits (Phase 1)
76
60
 
@@ -84,12 +68,9 @@ Per-turn total across all attachments is capped at **100 MB**; the endpoint retu
84
68
  ## Workflow
85
69
 
86
70
  1. Decide the filename and caption up front (literal strings — no shell interpolation).
87
- 2. Generate the content and write it with the `Write` tool. Use `/tmp/<name>` as the path only every other path (`~/`, session workdir, context dir, `/var/`, `/Users/...`) is denied by the absolute-block layer (`packages/daemon/src/safety/always-disallowed.ts`). Never write into the session workdir or the context dir.
71
+ 2. Generate the content and write it with the `Write` tool. Write scratch files under `/tmp/<name>` the session workdir is re-materialized between turns and the context dir is daemon-owned, so `/tmp` avoids collisions.
88
72
  3. Issue the single curl POST shown above. One file per call.
89
- 4. Branch on the response:
90
- - Success (`{"id": "..."}`) — mention the attachment in your reply, e.g. `"Attached: weekly-summary.md"`. You may discard the id; the daemon links it to your message automatically.
91
- - HTTP 403 (`missing_turn_token` / `invalid_turn_token`) — the turn has already been released or the skill was invoked outside a turn. Do not retry. Fall back to inline paste and tell the user the attachment could not be sent.
92
- - Other errors — follow the table below.
73
+ 4. On success (`{"id": "..."}`) mention the attachment in your reply, e.g. `"Attached: weekly-summary.md"` — you may discard the id; the daemon links it automatically. On any error, follow the Errors table below.
93
74
 
94
75
  Never base-64 embed files into your reply body. Always go through this endpoint.
95
76