@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
@@ -0,0 +1,184 @@
1
+ ---
2
+ name: background-task
3
+ description: Hand a long-running or open-ended task (deep research, multi-repo CI audit, monitor X over time, bulk compile) to /api/background-task. Compose a self-contained brief, set the notification policy, POST, ack, end the turn. Read GET /:id for follow-up detail.
4
+ allowed-tools:
5
+ - Bash(curl *)
6
+ ---
7
+
8
+ # Background Task — long-running work from DM
9
+
10
+ A detached worker runs the task in its own session with its own budget.
11
+ **The daemon delivers the result to the user directly — in your own voice —
12
+ when it finishes or needs input. You are NOT in that delivery path.** Your
13
+ job is the front bookend only: scope the task *now*, compose a
14
+ self-contained **brief**, choose a notification policy, POST it,
15
+ acknowledge in one line, and **end your turn**. The worker's run is
16
+ invisible to you.
17
+
18
+ This is the surface for *generic* long tasks. For an open-ended **browser**
19
+ job (post a tweet, fill a form) use the `browser-task` skill. For a
20
+ *recurring* cadence ("every morning…", "each hour check my PRs") use
21
+ `agent-create` / `schedule` — a background task is a single detached run.
22
+
23
+ ## When to background it (triage)
24
+
25
+ Background work that is **long-running or open-ended** so the user can keep
26
+ chatting. No duration guess — decide on the signals:
27
+
28
+ 1. **Category** — deep research, a multi-repo / multi-file audit,
29
+ "monitor / watch X", a multi-step web dig, a bulk compile. Strongest
30
+ signal.
31
+ 2. **Owner signal** — explicit ("take your time", "report back later") or a
32
+ research-style bang command.
33
+ 3. **Scoping reveals size** — if resolving the request shows large or
34
+ genuinely open-ended work, delegate it.
35
+
36
+ **Bias toward backgrounding category-1 work; keep plausibly-quick lookups
37
+ inline** (delivery costs a turn's latency). One task per request: "research
38
+ X AND audit Y" → two POSTs.
39
+
40
+ ## Compose the brief — this is the real work
41
+
42
+ The worker sees ONLY your `brief` (it does not inherit the conversation,
43
+ the user profile, or the management rules). An under-specified brief forces
44
+ a clarification round-trip you can avoid by writing it well *this turn*.
45
+ Resolve ambiguity with the user now, then encode all of:
46
+
47
+ - **Objective** — the end state as an outcome ("find which repos have a red
48
+ main build", not "go look at repos").
49
+ - **Scope & inputs** — the concrete inputs the worker can't infer: the repo
50
+ list, what "failing" means, which sites, the date range.
51
+ - **Output language** — the user's language for `result`, `draft`, and any
52
+ clarification.
53
+ - **Persona hints** — a line on the user's voice so the `draft` summary
54
+ reads right if it's sent directly.
55
+ - **Notification policy + criteria** — see below; for `if_significant` the
56
+ criteria MUST be written into the brief in concrete terms.
57
+ - **Expected output** — what a good `result` contains (a per-repo table, a
58
+ ranked list, a one-paragraph verdict).
59
+
60
+ The worker can read owner memory itself to fill in preferences, so you need
61
+ only supply the *task-specific* inputs above. **Promoting an inline task?**
62
+ Also fold in the work you already did (findings, partial results) so the
63
+ worker continues rather than restarting cold.
64
+
65
+ ## Notification policy — you author it
66
+
67
+ `notificationPolicy` decides whether the worker's result reaches the user.
68
+ The worker doesn't free-judge; it evaluates the policy you set:
69
+
70
+ - **`always`** (default) — the user asked and wants the answer, even
71
+ "nothing found / 0 issues". The common case; always delivered.
72
+ - **`if_significant`** — delivered **only if** the concrete criteria are
73
+ met. Prefer the structured **`significanceCriteria`** array (below) over
74
+ prose; vague criteria defeat the policy.
75
+ - **`silent`** — never delivered; filed only.
76
+
77
+ A filed (`silent` / unmet-`if_significant`) result is not lost — it surfaces
78
+ in the daily digest and the user can pull it (see "Filed results" below).
79
+
80
+ ## Endpoints (localhost only)
81
+
82
+ | Method | Path | Purpose |
83
+ |---|---|---|
84
+ | POST | `/api/background-task` | Create + dispatch, or schedule (`scheduleAt`). |
85
+ | GET | `/api/background-task?state=...` | List (also `notify`, `sinceHours` for the filed pull). |
86
+ | GET | `/api/background-task/:id` | The artifact — verbatim `report`, `draft`, `notify`, clarifications. |
87
+ | POST | `/api/background-task/:id/cancel` | Force-stop. |
88
+
89
+ Clarifications are answered with the **`background-task-reply`** skill.
90
+
91
+ ## Hard rules
92
+
93
+ 1. **Localhost only.** `http://127.0.0.1:8321/api/background-task/*`.
94
+ 2. **POST, ack, end the turn. NEVER poll for completion.** After a
95
+ successful POST, reply once and stop. Do NOT GET `/:id` in a loop or
96
+ "wait and check". Ending your turn has zero effect on the detached
97
+ worker — it keeps running and the daemon delivers the result as a DM in
98
+ your voice. The only allowed GET is a single on-demand read answering an
99
+ explicit user question (see "Follow-up detail").
100
+ 3. **Never invent `taskId` / `clarificationId`** — uuid v4 minted by the
101
+ daemon; read them from responses.
102
+ 4. **The worker has no messaging tool** — it cannot DM the user; it writes
103
+ its artifact and *you* (the daemon, in your voice) deliver.
104
+ 5. **One task per request.**
105
+
106
+ ## POST — composing a request
107
+
108
+ `POST /api/background-task` with the self-contained brief:
109
+
110
+ ```bash
111
+ curl --silent --fail -X POST -H 'Content-Type: application/json' \
112
+ -d '{"brief":"Audit these repos for a red main-branch CI build: aitne/daemon, aitne/web. \"Failing\" = the latest default-branch run concluded failure. Summary in English. Only notify if at least one repo is red. Output: one line per failing repo with the job.","title":"CI audit","notificationPolicy":"if_significant"}' \
113
+ http://127.0.0.1:8321/api/background-task
114
+ ```
115
+
116
+ Body:
117
+
118
+ - `brief` (1..16384) — the self-contained worker prompt above.
119
+ - `title` (1..200, optional) — short human label for status + the DM.
120
+ - `notificationPolicy` — `always` (default) / `if_significant` / `silent`.
121
+ - `significanceCriteria` (optional, `if_significant` only) — up to 12
122
+ atomic conditions (each ≤500 chars), e.g. `["any repo's main build is
123
+ red","spend > $100"]`. Worker notifies iff one is met. Omit otherwise.
124
+ - `tier` (optional) — `lite` / `medium` / `high` budget envelope. Default
125
+ is fine; use `high` only for genuinely heavy research.
126
+ - `maxBudgetUsd` (optional) — override the dollar cap (hard ceiling `15`;
127
+ a larger value is rejected `400`). Prefer `tier` over a raw dollar value.
128
+ - `scheduleAt` (ISO 8601, optional) — defer the *run* to a fire time (the
129
+ worker starts then; it is compute, so it runs even during quiet hours).
130
+ The eventual *result delivery* is what respects quiet hours, not the run.
131
+ `202` with `{ taskId, status:"scheduled", scheduledFor, scheduleRowId }`.
132
+ A time more than 60s in the past is rejected `400`.
133
+
134
+ Immediate response carries `taskId` and `status`. Then ack once and stop
135
+ (Hard rule 2).
136
+
137
+ ## Acknowledgement
138
+
139
+ One line, no ceremony, no internal mechanism names (`taskId`, "worker",
140
+ "artifact"); your output language is already governed by your policy.
141
+ Structural examples (English): *"Started the audit in the background — I'll
142
+ report when it's done."* / *"On it. I'll dig into that and come back with
143
+ what I find."* Do NOT promise a specific time; say "when it's done".
144
+
145
+ ## Follow-up detail — answer from the artifact, don't guess
146
+
147
+ The delivered DM carries a *summary*. When the user later asks for precise
148
+ detail it didn't include ("what exactly did it find on repo X?", "show me
149
+ the numbers"), do a **single** read and answer from the verbatim `report`:
150
+
151
+ ```bash
152
+ curl --silent --fail http://127.0.0.1:8321/api/background-task/<taskId>
153
+ ```
154
+
155
+ `report` is the full, unparaphrased result. Quote from it; don't invent
156
+ detail. If you lack the `taskId`, list `state=completed` and match by
157
+ `title`.
158
+
159
+ ## Filed results — the "did that monitor ever run?" pull
160
+
161
+ A `silent` / unmet-`if_significant` result is filed (`notify=false`), not
162
+ pushed. When the user asks whether a backgrounded task ran:
163
+
164
+ ```bash
165
+ curl --silent --fail "http://127.0.0.1:8321/api/background-task?state=completed&notify=false&sinceHours=168"
166
+ ```
167
+
168
+ Each row carries `title`, `significance`, and `report`. Summarize
169
+ naturally; offer to pull any in full.
170
+
171
+ ## Force-stop — "stop" / "cancel" / "abort"
172
+
173
+ On a clear stop signal, find the task (by `taskId`, or list
174
+ `state=running,awaiting_user,pending` and match the topic), then
175
+ `POST /api/background-task/<taskId>/cancel` with optional
176
+ `{"reason":"user_cancel"}`. `200` = accepted; `404 not_found` = stale id,
177
+ re-read; `409 already_terminal` = too late, report `currentState`
178
+ verbatim. "wait" is NOT a cancel.
179
+
180
+ ## Scheduling — `scheduleAt` ≠ the `schedule` skill
181
+
182
+ For "do this research at <time>" use `scheduleAt` in this POST. The
183
+ `schedule` skill is for listing / modifying / cancelling pending schedules;
184
+ a recurring cadence is `agent-create`.
@@ -0,0 +1,100 @@
1
+ ---
2
+ name: background-task-reply
3
+ description: |
4
+ When a background task is parked on a clarifying question and the
5
+ owner's DM answers it, relay the answer via
6
+ POST /api/background-task/<taskId>/clarify. Use ONLY when a task is in
7
+ awaiting_user AND the conversation shows the question was just asked.
8
+ allowed-tools:
9
+ - Bash(curl *)
10
+ ---
11
+
12
+ # Background Task — clarification relay
13
+
14
+ A detached background task can pause to ask the owner one question
15
+ (`awaiting_user`). The daemon already DMed that question to the owner, in
16
+ your voice — you did NOT author it and you do not poll for it. You act only
17
+ when the owner comes back with an answer, translating their natural-language
18
+ reply into the structured `/clarify` call that un-parks the worker.
19
+
20
+ This skill does NOT spawn tasks (that's `background-task`) and does NOT
21
+ deliver results (the daemon does that directly).
22
+
23
+ ## Hard rule — never cold-call
24
+
25
+ This skill is a no-op unless BOTH hold:
26
+
27
+ 1. `GET /api/background-task?state=awaiting_user` returns a non-empty list
28
+ (call this FIRST). Empty → do nothing; the owner's message is not a
29
+ clarification answer.
30
+ 2. The conversation shows the agent recently asked that task's question —
31
+ a pending `task_clarification` in your catchup context, or a recent
32
+ assistant DM that posed it. No recent question → the reply is about
33
+ something else; leave the parked task alone (its deadline scanner
34
+ handles a genuine no-answer).
35
+
36
+ Relaying when the owner didn't answer the question is a worse failure than
37
+ missing an ambiguous reply. When unsure whether the message answers the
38
+ question, ask ONE short clarifier rather than guessing.
39
+
40
+ ## Endpoints
41
+
42
+ | Method | Path | Purpose |
43
+ |---|---|---|
44
+ | GET | `/api/background-task?state=awaiting_user` | List parked tasks. Call FIRST. |
45
+ | GET | `/api/background-task/:id` | Read the open `clarifications` row (`resolved:false`) for its `id` + `question`. |
46
+ | POST | `/api/background-task/:id/clarify` | Relay the answer. |
47
+
48
+ ## Resolving which task
49
+
50
+ 1. `GET /api/background-task?state=awaiting_user`. Usually exactly one
51
+ parked task; if several, match the owner's reply to the right one by
52
+ topic / `title`, or ask which.
53
+ 2. `GET /api/background-task/<taskId>` — read the open `clarifications`
54
+ entry (`resolved:false`) and re-read the `question` so you can confirm
55
+ the owner's message actually answers it. The GET response exposes each
56
+ clarification row's identifier as `id`; to answer, POST `/clarify` with
57
+ that value in the request-body field `clarificationId`.
58
+
59
+ If your catchup context already carries the `clarificationId` in metadata,
60
+ you may use it — but **never surface a `clarificationId` or `taskId` in
61
+ user-visible text** (token hygiene). The GET is the authoritative source.
62
+
63
+ ## Relay the answer
64
+
65
+ ```bash
66
+ curl --silent --fail -X POST -H 'Content-Type: application/json' \
67
+ -d '{"clarificationId":"<uuid>","answer":"api first"}' \
68
+ http://127.0.0.1:8321/api/background-task/<taskId>/clarify
69
+ ```
70
+
71
+ - `answer` (1..8192) — the owner's reply, verbatim and faithful. Do not
72
+ re-decide the task on their behalf; pass what they said.
73
+ - `clarificationId` is optional — if you omit it the daemon resolves the
74
+ single open clarification — but prefer passing the explicit id when more
75
+ than one task is parked.
76
+
77
+ Then ack briefly ("Got it, picking that back up.") and end the turn — the
78
+ worker resumes on its own and the daemon delivers the eventual result.
79
+
80
+ Status codes — handle each, don't retry blindly:
81
+
82
+ - `200` — recorded; the worker resumes. Brief ack.
83
+ - `400 validation_error` — `clarificationId` not a uuid, or `answer` empty
84
+ / > 8192 chars. Re-read with GET and re-send.
85
+ - `409 not_awaiting_user` (carries `currentState`) — the task already moved
86
+ on (finished, cancelled, or the window closed). Tell the owner the state
87
+ plainly; do not re-send.
88
+ - `409 no_open_clarification` — nothing to answer; your state was stale.
89
+ Re-read with GET first.
90
+ - `409 already_resolved` — the question was already answered (a racing
91
+ reply landed first). The worker has resumed; do not re-send. A brief ack
92
+ is enough.
93
+ - `410 expired` — the clarification deadline passed; the worker will time
94
+ out. Apologise briefly and offer to re-run if relevant.
95
+ - `404 not_found` — stale `taskId`; re-read with GET.
96
+
97
+ ## Localhost only
98
+
99
+ `http://127.0.0.1:8321/api/background-task/*`. JSON body in single quotes
100
+ (project convention) so the daemon hooks classify the payload as data.
@@ -33,23 +33,18 @@ their own destination policy — see the cluster-update flow below.
33
33
  topic / domain labels, not raw URLs. There is no path that exposes a
34
34
  full URL string; do not try to reconstruct one and feed it to
35
35
  WebFetch / Read.
36
- 5. **`context/research/*` writes currently 403.** The cluster-journal /
36
+ 5. **`context/research/*` is writable.** The cluster-journal /
37
37
  assistance / wiki destinations below (`PUT`/`PATCH
38
38
  /api/context/research/<slug>.md`, `…-assistance-<date>.md`,
39
- `…-wiki.md`) are the design-intended canonical paths, but `research/`
40
- is **not** in the six-class vault write whitelist
41
- (`CONTEXT_WRITE_PERMISSIONS`), so those writes return **HTTP 403
42
- `context.write_forbidden`** today. `GET /api/context/research/<slug>.md`
43
- reads are unaffected. Until the whitelist gains a `research/*` entry,
44
- prefer the Obsidian / Notion destination for the wiki flow when
45
- configured, and surface the 403 to the owner rather than reporting a
46
- successful local-context write.
39
+ `…-wiki.md`) accept `PUT` and `PATCH` today (`DELETE` is intentionally
40
+ omitted concluding a cluster preserves its journal).
47
41
 
48
42
  ## Endpoint reference
49
43
 
50
44
  All endpoints respond with JSON validated against
51
- `packages/shared/src/browser-history-schemas.ts`. The 13 routes below
52
- are the entire agent-facing surface.
45
+ `packages/shared/src/browser-history-schemas.ts`. 12 of the 13 routes
46
+ below are agent-facing; `GET /status` is operator/dashboard-only (Approve
47
+ tier — see the note after the table).
53
48
 
54
49
  | Method | Path | Purpose |
55
50
  |---|---|---|
@@ -67,19 +62,35 @@ are the entire agent-facing surface.
67
62
  | POST | `/api/browser-history/offers/<slug>/mute` | Permanently silence the cluster |
68
63
  | POST | `/api/browser-history/research-clusters/<slug>/wiki-written` | Stamp `wikiSummaryWrittenAt`. Call this from `routine.research_wiki_summary` AFTER a successful destination write — never on acceptance. |
69
64
 
65
+ **`GET /status` is operator/dashboard-only (Approve tier, Bearer
66
+ required).** An autonomous agent curl from a session workdir carries no
67
+ `Authorization: Bearer` header and is rejected with **401** before the
68
+ handler runs — so `/status` is NOT part of the agent-facing surface. Do
69
+ not call it; treat detector capabilities/lifecycle as out of scope for
70
+ the agent. (The `/offers/<slug>/accept` POST is ReadSensitive, not
71
+ Approve — call it as plain curl; the shim auto-injects `x-read-token`,
72
+ so do NOT add an auth header to it.)
73
+
70
74
  ### Common curl shape
71
75
 
72
76
  ```bash
73
- curl --silent --fail \
77
+ curl --silent --show-error \
74
78
  http://127.0.0.1:8321/api/browser-history/research-clusters
75
79
  ```
76
80
 
81
+ Use `--silent --show-error` (not `--fail`): the agent's `curl` runs
82
+ through a session shim that rejects `--fail` / `-f` as an unsupported
83
+ flag — the command hard-errors before any request (it does not merely
84
+ suppress the body). `--show-error` still surfaces the routes' structured
85
+ `{error: …}` JSON on a 4xx, so you can branch on 404 (`not_found`) vs
86
+ 400 (`invalid_slug` / `invalid_body`).
87
+
77
88
  For POSTs, pass a single-quoted JSON body so the daemon's hooks do not
78
89
  misclassify the payload as a shell command (the project convention from
79
90
  `_safety.md`):
80
91
 
81
92
  ```bash
82
- curl --silent --fail \
93
+ curl --silent --show-error \
83
94
  -X POST \
84
95
  -H 'Content-Type: application/json' \
85
96
  -d '{"kind":"research_assist"}' \
@@ -88,20 +99,36 @@ curl --silent --fail \
88
99
 
89
100
  ## Flow: routine.research_cluster_update
90
101
 
91
- Runs nightly at the day boundary for every cluster with new activity.
92
-
93
- 1. List active clusters via `GET /research-clusters`. Filter to
94
- `status="active"` and `lastActivityAt` within the last 24h. For each
95
- match continue.
96
- 2. Fetch `GET /research-clusters/<slug>/delta` (capped at 31 days; the
97
- route returns the most recent buckets first).
102
+ Runs nightly at the day boundary. The daemon already selected exactly
103
+ one cluster and passed it as `event.data.slug` — the fan-out enqueues
104
+ one event per cluster, so operate on **that slug only**. Do **not** call
105
+ `GET /research-clusters` or iterate clusters here; that contradicts the
106
+ single-slug contract.
107
+
108
+ 1. (Optional) Fetch `GET /research-clusters/<slug>` for `displayName`,
109
+ `topDomains`, and `agentSummaryRevision` (frontmatter for the
110
+ initial-file case).
111
+ 2. Fetch `GET /research-clusters/<slug>/delta`. `days[]` is capped to the
112
+ most recent 31 days and ordered **oldest-first**. Each entry carries
113
+ `complete` — `false` only on the still-accumulating current agent
114
+ day.
98
115
  3. Read the existing cluster journal at
99
116
  `context/research/<slug>.md` via
100
- `GET /api/context/research/<slug>.md`. The first run will return
101
- 404 create the file from the template below.
102
- 4. Append today's day entry. **Do not** rewrite earlier days; this is
103
- an append-only ledger. Use `PATCH /api/context/research/<slug>.md`
104
- with a multi-line `append:` body.
117
+ `GET /api/context/research/<slug>.md`, and note which
118
+ `### <YYYY-MM-DD>` headings already exist under `## Day log`. The
119
+ first run will return 404 create the file from the template below.
120
+ 4. Append a block for **every** `complete: true` day in `days[]` not
121
+ already present under `## Day log`, **oldest first** (iterate `days[]`
122
+ in order). Never append a `complete: false` day — its counts are
123
+ still growing, and a premature block freezes an undercounted day in
124
+ this append-only ledger (it arrives complete on a later run). This
125
+ backfills nights that were skipped or failed — a failed run waits a
126
+ full agent-day before retrying, so missed days accumulate until the
127
+ next successful run (bounded by the 31-day delta window). **Do not**
128
+ rewrite earlier days; this is an append-only ledger. Use
129
+ `PATCH /api/context/research/<slug>.md` with body
130
+ `{"mode":"append","section":"## Day log","content":"<block>"}`
131
+ (use `PUT` only for the initial-file case).
105
132
 
106
133
  Initial-file template (use only when the GET in step 3 returned 404):
107
134
 
@@ -125,13 +152,15 @@ Do not invent a thesis the data does not support.)
125
152
 
126
153
  ## Day log
127
154
 
155
+ <!-- one block per missing `complete: true` day in `days[]`, oldest first -->
128
156
  ### <YYYY-MM-DD>
129
157
  - visits: <meaningfulVisits> (<meaningfulForegroundSec / 60>m foreground)
130
158
  - new domains: <newDomains.join(", ")>
131
159
  - agent observation: <one neutral sentence about the day's shape>
132
160
  ```
133
161
 
134
- Per-day append shape:
162
+ Per-day append shape (one block per missing `complete: true` day,
163
+ **oldest first**):
135
164
 
136
165
  ```markdown
137
166
  ### <YYYY-MM-DD>
@@ -178,13 +207,15 @@ write and enqueued this event.
178
207
  - Sources read (domain labels only, never URLs)
179
208
  - Open questions
180
209
  - Status (active / paused / concluded based on cluster status)
181
- 4. Write the note to:
210
+ 4. Write the note to the best available destination, in priority order
211
+ (each is a fully working target — the local path is a real write, not
212
+ a 403-doomed fallback):
182
213
  - **Obsidian** if `/api/obsidian/*` is configured: PUT to
183
214
  `<vault>/inbox/<slug>-wiki-<YYYY-MM-DD>.md`.
184
215
  - **Notion** if `/api/notion/*` is configured: create a page under
185
216
  the configured "Aitne Inbox" parent.
186
- - **Local context** otherwise:
187
- `PUT /api/context/research/<slug>-wiki.md`.
217
+ - **Local context** (`PUT /api/context/research/<slug>-wiki.md`) as the
218
+ fallback when neither knowledge destination is configured.
188
219
  5. After a successful write — and only then — POST
189
220
  `/api/browser-history/research-clusters/<slug>/wiki-written` so the
190
221
  daemon advances `wikiSummaryWrittenAt`. This is what guards the next
@@ -32,7 +32,7 @@ than missing an ambiguous reply.
32
32
 
33
33
  | Method | Path | Purpose |
34
34
  |---|---|---|
35
- | GET | `/api/browser-history/offers/pending` | List open offers (slug, displayName, kind, offered_at, expires_at). Call FIRST. |
35
+ | GET | `/api/browser-history/offers/pending` | List open offers (slug, displayName, kind, offeredAt, expiresAt). Call FIRST. |
36
36
  | POST | `/api/browser-history/offers/<slug>/accept` | Body `{kind: "research_assist" \| "wiki_summary"}` — dispatch the routine. |
37
37
  | POST | `/api/browser-history/offers/<slug>/decline` | Silence both options for this cluster for 14 days. |
38
38
 
@@ -67,6 +67,11 @@ referenced, or ask:
67
67
 
68
68
  ## Acknowledgement
69
69
 
70
+ For accept, only send the success ack if the response has
71
+ `enqueued:true`. If `enqueued:false` the dispatch did not fire (EventBus
72
+ unwired during the boot window) — tell the owner to retry in a moment
73
+ instead of claiming a result is coming.
74
+
70
75
  Send a one-line ack in the owner's `primaryLanguage` (examples English):
71
76
 
72
77
  - research_assist accepted: "On it — I'll DM the parallel research
@@ -24,22 +24,25 @@ B-4 purchase tokens, or workflow approvals — those live under
24
24
  1. **Localhost only.** `http://127.0.0.1:8321/api/browser-task/*`.
25
25
  2. **POST, ack, end the turn. NEVER poll for completion.** After a
26
26
  successful POST, reply once ("Started — I'll report back when it's
27
- done.") and stop. Do not GET `/:id` in a loop waiting for `completed`,
28
- do not "wait and check", do not re-issue. Ending your turn has zero
29
- effect on the detached task — it keeps running and the daemon DMs the
30
- user the result (`✅ Browser task — report`) or, on any
31
- failure/cancel/timeout, `🟦 Browser task <id> ended: <state>`. A
32
- status GET is allowed ONLY as a single read answering an explicit user
33
- question (see "On-demand status"). Polling re-processes the whole DM
34
- history every loop and burns your per-turn budget for nothing.
27
+ done.") and stop. Do not GET `/:id` in a loop, "wait and check", or
28
+ re-issue. Ending your turn has zero effect on the detached task — it
29
+ keeps running and the daemon DMs the user the result (`✅ Browser task
30
+ — report`) or, on any failure/cancel/timeout, `🟦 Browser task <id>
31
+ ended: <state>`. The only allowed GET is a single on-demand status read
32
+ answering an explicit user question (see "On-demand status").
35
33
  3. **Never echo the `!~xxxxxxxx` final-confirm token.** The daemon DMs it
36
34
  directly when the sub-agent trips the final-confirm gate. The user
37
35
  types it back themselves; the runner consumes the reply. Do not read,
38
36
  log, paraphrase, or relay the token. If the user asks "what was that
39
37
  code?", point them at the original DM with the screenshot — that DM is
40
38
  the only authoritative source.
41
- 4. **Never invent `clarificationId` / `taskId`.** Both are uuid v4 minted
42
- by the daemon; read from GET responses.
39
+ 4. **Never invent the clarification id or the task id.** Both are uuid v4
40
+ minted by the daemon; read them from the daemon's responses, never make
41
+ them up. The POST-create response carries the task uuid as a top-level
42
+ `taskId`; on GET (`/:id` and the list) that same task uuid is the row's
43
+ `id`. The clarification identifier is the clarifications row's `id` on
44
+ the GET response — to answer you send it back as the request-body field
45
+ `clarificationId` on POST `/clarify`.
43
46
  5. **Do not pre-decline based on the URL or site.** Open navigation is
44
47
  the default — the sub-agent decides where to go and the daemon enforces
45
48
  a user-curated hostname denylist plus the payment-path block at
@@ -73,26 +76,29 @@ Body:
73
76
  dropped both on 2026-05-27 (open navigation). Legacy callers passing
74
77
  them are silently ignored, not rejected.
75
78
  - `scheduleAt` (ISO 8601) — defer to later; respects quiet hours.
76
- Response is `{ status:"scheduled", scheduledFor, scheduleRowId }`.
79
+ Response is `202` with `{ taskId, status:"scheduled", scheduledFor,
80
+ scheduleRowId }` (`scheduledFor` is epoch-ms; `taskId` is the same
81
+ pre-generated id you use for status GETs).
77
82
  - `requireFinalConfirm` (default `true`) — keep `true` unless the user
78
83
  explicitly asks to skip the gate for a reversible flow.
79
84
 
80
- Immediate response carries `taskId`, `status`, and `queueState`. **Then
81
- acknowledge once and end the turn.** If `queueState.waitingForSlot ===
82
- true`, the global cap is full — say so once ("queued behind N task(s);
83
- I'll start it when a slot opens") and still end the turn. The daemon DMs
84
- the user when it promotes, and again when it finishes.
85
+ Immediate response carries `taskId`, `status`, and `queueState`; then ack
86
+ once and stop (Hard rule 2). If `queueState.waitingForSlot === true`, the
87
+ global cap is full — say so once ("queued behind N task(s); I'll start it
88
+ when a slot opens"). The daemon DMs the user on promote and on finish.
85
89
 
86
90
  ## Relaying a clarification — `awaiting_user`
87
91
 
88
- The sub-agent may DM the user a question + screenshot via the originating
89
- channel. **The daemon authors that DM; you do not, and you do not poll for
90
- it to appear.** You act only when the user comes back with an answer:
92
+ The daemon DMs the user a question + screenshot via the originating
93
+ channel (you do not author it, and per Hard rule 2 you do not poll for it
94
+ to appear). You act only when the user comes back with an answer:
91
95
 
92
96
  1. `GET /api/browser-task?state=awaiting_user` — find the parked task.
93
97
  Usually one; if several, match topic or ask which.
94
98
  2. `GET /api/browser-task/<taskId>` — read the open `clarifications` row
95
- (`resolved:0`) for `clarificationId`.
99
+ (`resolved:false`). The GET response exposes each clarification row's
100
+ identifier as `id`; to answer, POST `/clarify` with that value in the
101
+ request-body field `clarificationId`.
96
102
  3. `POST /api/browser-task/<taskId>/clarify` with `{clarificationId,
97
103
  answer}` (user reply verbatim), then ack briefly and end the turn —
98
104
  the runner resumes on its own.
@@ -116,22 +122,18 @@ If (and only if) the user explicitly asks how a task is going, do a
116
122
  user names), then `GET /api/browser-task/<taskId>` and report `state`, the
117
123
  last `actionLog` entry, and `queueState` if pending. States:
118
124
 
119
- - `pending` — queued (see `queueState`); `running` — sub-agent acting.
120
- - `awaiting_user` — relay via the `/clarify` round-trip above.
121
- - `final_confirm` gated on a `!~xxxxxxxx` token. The daemon DMs the
122
- screenshot + token and consumes the user's reply **before you see it**.
123
- Do nothing; if the user pings you, point them at that DM.
125
+ - `pending` — queued; read `queueState` for position. `running` — acting.
126
+ - `awaiting_user` / `final_confirm` — relay rules are Hard rule 3 + the
127
+ clarify section; here just report the state.
124
128
  - `completed` — the daemon already DMed the full `✅ Browser task —
125
129
  report`. Don't re-post; if asked "what did it find?", quote the
126
130
  `report` field verbatim (don't paraphrase).
127
131
  - `failed` / `timeout` / `cancelled` / `abandoned` — terminal; the daemon
128
- already DMed `🟦 Browser task <id> ended: <state>`. `outcome_detail`
129
- carries the reason (`queue_timeout`, `daemon_restarted`,
130
- `backend_unavailable`, `tool_loop_detected`, `ask_user_without_yield`,
131
- `blocked_request_spike`, `budget_exceeded`, `max_turns_exceeded`,
132
- `runner_unavailable`, …).
132
+ already DMed `🟦 Browser task <id> ended: <state>`. `outcomeDetail`
133
+ carries the reason (e.g. `queue_timeout`, `budget_exceeded`,
134
+ `tool_loop_detected`) — quote it verbatim.
133
135
 
134
- ## Force-stop — "stop" / "cancel" / "abort" / "止めて"
136
+ ## Force-stop — "stop" / "cancel" / "abort"
135
137
 
136
138
  When the user signals stop, find the task (same identification path as
137
139
  status), then `POST /api/browser-task/<taskId>/cancel` with optional