@aitne-sh/aitne 0.1.12 → 0.1.13

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 (139) hide show
  1. package/agent-assets/agent-profiles/background-task.md +8 -1
  2. package/agent-assets/agent-profiles/routine-fetch-window.md +11 -0
  3. package/agent-assets/agents/evening-review/agent.md +6 -2
  4. package/agent-assets/agents/lesson-maintenance/agent.md +56 -0
  5. package/agent-assets/agents/morning-routine/agent.md +7 -2
  6. package/agent-assets/agents/source-librarian/agent.md +51 -0
  7. package/agent-assets/docs/concepts/agent-day.md +15 -15
  8. package/agent-assets/docs/concepts/auth-health.md +10 -7
  9. package/agent-assets/docs/concepts/backends-and-tiers.md +21 -13
  10. package/agent-assets/docs/concepts/costs-and-quotas.md +10 -10
  11. package/agent-assets/docs/concepts/delegated-mode.md +18 -18
  12. package/agent-assets/docs/concepts/memory-model.md +25 -24
  13. package/agent-assets/docs/concepts/observations.md +27 -19
  14. package/agent-assets/docs/concepts/process-keys.md +25 -26
  15. package/agent-assets/docs/concepts/routines.md +18 -17
  16. package/agent-assets/docs/concepts/safety-and-execution.md +20 -17
  17. package/agent-assets/docs/concepts/safety-model.md +16 -15
  18. package/agent-assets/docs/concepts/skills.md +7 -4
  19. package/agent-assets/docs/features/integrations/browser-history.md +52 -47
  20. package/agent-assets/docs/features/integrations/calendar.md +7 -7
  21. package/agent-assets/docs/features/integrations/git.md +15 -13
  22. package/agent-assets/docs/features/integrations/github.md +12 -10
  23. package/agent-assets/docs/features/integrations/mail.md +47 -45
  24. package/agent-assets/docs/features/integrations/notion.md +15 -11
  25. package/agent-assets/docs/features/integrations/obsidian.md +27 -23
  26. package/agent-assets/docs/features/lifestyle/git.md +7 -8
  27. package/agent-assets/docs/features/lifestyle/reading.md +11 -8
  28. package/agent-assets/docs/features/lifestyle/receipts.md +21 -22
  29. package/agent-assets/docs/features/lifestyle/travel-bookings.md +9 -9
  30. package/agent-assets/docs/features/memory-files/agent-journal.md +12 -10
  31. package/agent-assets/docs/features/memory-files/agent-lessons.md +46 -21
  32. package/agent-assets/docs/features/memory-files/projects.md +13 -14
  33. package/agent-assets/docs/features/memory-files/roadmap.md +16 -15
  34. package/agent-assets/docs/features/memory-files/schedule.md +10 -10
  35. package/agent-assets/docs/features/memory-files/today.md +18 -18
  36. package/agent-assets/docs/features/memory-files/user-profile.md +17 -17
  37. package/agent-assets/docs/features/messaging/bang-commands.md +15 -15
  38. package/agent-assets/docs/features/messaging/dashboard-chat.md +7 -6
  39. package/agent-assets/docs/features/messaging/discord.md +7 -5
  40. package/agent-assets/docs/features/messaging/overview.md +14 -14
  41. package/agent-assets/docs/features/messaging/pairing-and-magic-phrase.md +12 -12
  42. package/agent-assets/docs/features/messaging/slack.md +9 -8
  43. package/agent-assets/docs/features/messaging/telegram.md +7 -7
  44. package/agent-assets/docs/features/messaging/whatsapp.md +6 -6
  45. package/agent-assets/docs/features/operations/activity-and-conversations.md +9 -9
  46. package/agent-assets/docs/features/operations/approvals.md +13 -12
  47. package/agent-assets/docs/features/operations/backend-routing.md +38 -37
  48. package/agent-assets/docs/features/operations/browser-tasks.md +63 -57
  49. package/agent-assets/docs/features/operations/cost-tracking.md +5 -5
  50. package/agent-assets/docs/features/operations/managed-chromium.md +23 -22
  51. package/agent-assets/docs/features/operations/notifications.md +15 -15
  52. package/agent-assets/docs/features/operations/quiet-hours.md +14 -15
  53. package/agent-assets/docs/features/operations/schedule-approaching.md +16 -14
  54. package/agent-assets/docs/features/routines/activity-scan.md +14 -11
  55. package/agent-assets/docs/features/routines/custom-routines.md +9 -7
  56. package/agent-assets/docs/features/routines/evening-review.md +6 -7
  57. package/agent-assets/docs/features/routines/morning-routine.md +22 -21
  58. package/agent-assets/docs/features/routines/weekly-review.md +57 -51
  59. package/agent-assets/docs/features/wiki/commands.md +27 -21
  60. package/agent-assets/docs/features/wiki/cost-and-approval.md +28 -23
  61. package/agent-assets/docs/features/wiki/dashboard.md +21 -23
  62. package/agent-assets/docs/features/wiki/overview.md +17 -25
  63. package/agent-assets/docs/features/wiki/search.md +15 -17
  64. package/agent-assets/docs/features/wiki/workspaces.md +55 -56
  65. package/agent-assets/docs/getting-started/01-what-is-this.md +3 -4
  66. package/agent-assets/docs/getting-started/02-first-steps.md +12 -13
  67. package/agent-assets/docs/getting-started/03-what-can-this-do.md +7 -7
  68. package/agent-assets/docs/getting-started/04-first-day.md +4 -5
  69. package/agent-assets/docs/glossary.md +17 -16
  70. package/agent-assets/docs/guides/add-a-custom-routine.md +17 -12
  71. package/agent-assets/docs/guides/backup-and-restore.md +19 -16
  72. package/agent-assets/docs/guides/budget-and-cost-for-wiki.md +55 -62
  73. package/agent-assets/docs/guides/build-your-wiki.md +11 -12
  74. package/agent-assets/docs/guides/change-which-model-handles-x.md +30 -28
  75. package/agent-assets/docs/guides/connect-a-new-mail-account.md +30 -29
  76. package/agent-assets/docs/guides/explore-with-trace-and-connect.md +30 -32
  77. package/agent-assets/docs/guides/import-knowledge-file.md +9 -10
  78. package/agent-assets/docs/guides/install-and-run.md +9 -10
  79. package/agent-assets/docs/guides/maintain-wiki-health.md +10 -10
  80. package/agent-assets/docs/guides/migrate-machines.md +16 -14
  81. package/agent-assets/docs/guides/multiple-wikis-for-multiple-domains.md +11 -12
  82. package/agent-assets/docs/guides/pause-the-agent.md +25 -25
  83. package/agent-assets/docs/guides/reinstall-cleanly.md +13 -12
  84. package/agent-assets/docs/guides/setup-wizard.md +9 -11
  85. package/agent-assets/docs/guides/switch-default-backend.md +9 -9
  86. package/agent-assets/docs/guides/use-an-existing-obsidian-vault.md +9 -11
  87. package/agent-assets/docs/pages/activity.md +76 -0
  88. package/agent-assets/docs/pages/agents.md +78 -0
  89. package/agent-assets/docs/pages/analytics.md +70 -0
  90. package/agent-assets/docs/pages/browser.md +73 -0
  91. package/agent-assets/docs/pages/chat.md +67 -0
  92. package/agent-assets/docs/pages/connections.md +78 -0
  93. package/agent-assets/docs/pages/git.md +73 -0
  94. package/agent-assets/docs/pages/knowledge.md +75 -0
  95. package/agent-assets/docs/pages/overview.md +90 -0
  96. package/agent-assets/docs/pages/reading.md +65 -0
  97. package/agent-assets/docs/pages/settings.md +77 -0
  98. package/agent-assets/docs/pages/tasks.md +74 -0
  99. package/agent-assets/docs/pages/wiki.md +73 -0
  100. package/agent-assets/docs/reference/api.md +18 -17
  101. package/agent-assets/docs/reference/cli-commands.md +13 -10
  102. package/agent-assets/docs/reference/config.md +40 -35
  103. package/agent-assets/docs/reference/disallowed-tools.md +18 -17
  104. package/agent-assets/docs/reference/keyboard-shortcuts.md +6 -8
  105. package/agent-assets/docs/reference/knowledge-layout.md +10 -10
  106. package/agent-assets/docs/reference/process-keys.md +20 -22
  107. package/agent-assets/docs/reference/skills.md +18 -16
  108. package/agent-assets/docs/troubleshooting/auth-failed.md +13 -11
  109. package/agent-assets/docs/troubleshooting/dashboard-shows-degraded.md +10 -10
  110. package/agent-assets/docs/troubleshooting/fallback-keeps-firing.md +26 -24
  111. package/agent-assets/docs/troubleshooting/messaging-not-pairing.md +8 -9
  112. package/agent-assets/docs/troubleshooting/morning-routine-didnt-run.md +19 -18
  113. package/agent-assets/docs/troubleshooting/observation-not-detected.md +14 -15
  114. package/agent-assets/docs/troubleshooting/quota-exhausted.md +28 -26
  115. package/agent-assets/docs/troubleshooting/wiki-ingest-full-blocked.md +35 -34
  116. package/agent-assets/docs/troubleshooting/wiki-write-failed.md +21 -24
  117. package/agent-assets/skills/agent-create/SKILL.md +39 -5
  118. package/agent-assets/skills/background-task/SKILL.md +9 -4
  119. package/agent-assets/skills/board/SKILL.md +8 -9
  120. package/agent-assets/skills/browser-task/SKILL.md +2 -0
  121. package/agent-assets/skills/context/seeds/file-responsibilities.seed.json +2 -1
  122. package/agent-assets/skills/schedule/SKILL.md +6 -5
  123. package/agent-assets/skills/sources/SKILL.md +68 -0
  124. package/agent-assets/skills/sources/curation.json +21 -0
  125. package/agent-assets/skills/sources/seeds/filing-rules.seed.json +25 -0
  126. package/agent-assets/skills/sources/seeds/source-collections.seed.json +20 -0
  127. package/agent-assets/skills/task/SKILL.md +5 -2
  128. package/agent-assets/task-flows/background_task.md +29 -3
  129. package/agent-assets/task-flows/message.received.dm.md +1 -1
  130. package/agent-assets/task-flows/routine.activity_scan.md +17 -2
  131. package/agent-assets/task-flows/routine.evening_review.md +72 -11
  132. package/agent-assets/task-flows/routine.fetch_window.md +21 -0
  133. package/agent-assets/task-flows/routine.monthly_review.md +3 -1
  134. package/agent-assets/task-flows/routine.morning_routine_today.md +26 -7
  135. package/agent-assets/task-flows/routine.source_maintenance.md +50 -0
  136. package/agent-assets/task-flows/scheduled.dm.md +8 -3
  137. package/agent-assets/templates/_manifest.json +1 -0
  138. package/agent-assets/templates/knowledge/sources/_index.md +19 -0
  139. package/package.json +4 -4
@@ -16,7 +16,6 @@ summary: |
16
16
  This entry tells you how to clear each branch.
17
17
  section: troubleshooting
18
18
  tags:
19
- - troubleshooting
20
19
  - wiki
21
20
  - cost
22
21
  - git
@@ -29,7 +28,7 @@ ask_examples:
29
28
  - What does "Sent for approval" mean after !compile full?
30
29
  locale: en-US
31
30
  created: 2026-05-12
32
- updated: 2026-05-28
31
+ updated: 2026-07-01
33
32
  keywords:
34
33
  - wiki compile blocked
35
34
  - compile cost gate
@@ -57,8 +56,8 @@ ui_anchors:
57
56
 
58
57
  ## What You See
59
58
 
60
- You ran `!compile full` and the bang reply was one of these. Jump to the
61
- matching section:
59
+ You ran `!compile full` and it stopped before doing anything, with one of
60
+ these replies. Jump to the section that matches what you saw:
62
61
 
63
62
  - **"the external vault has uncommitted changes"** — the git pre-compile
64
63
  gate. See [Uncommitted Changes](#uncommitted-changes).
@@ -74,20 +73,20 @@ The full reply is:
74
73
  > Cannot run `!compile full` — the external vault has uncommitted
75
74
  > changes. Please commit or stash first. Dirty paths: …
76
75
 
77
- This is the **git pre-compile gate** firing. Before a full rebuild,
78
- Aitne wants to take a clean pre-compile snapshot commit so you can revert
79
- the whole compile in one step. It refuses to start on an external
80
- git-tracked vault whose working tree is dirty, because that snapshot
81
- would no longer be a clean baseline.
76
+ This is the **git pre-compile gate**. Before a full rebuild, Aitne makes a
77
+ clean snapshot commit of your vault, so you can undo the whole compile in
78
+ one step later. It will not start when a git-tracked external vault still
79
+ has uncommitted changes (a "dirty" working tree), because that snapshot
80
+ would no longer be a clean baseline to revert to.
82
81
 
83
82
  To proceed:
84
83
 
85
84
  1. `git -C <vault> status` — review the dirty paths Aitne listed.
86
85
  2. Commit or stash them: `git add -A && git commit -m "wip"` or
87
86
  `git stash -u`.
88
- 3. Re-run `!compile full`. On a clean tree Aitne commits the snapshot
89
- itself (`aitne wiki: pre-compile snapshot <ts>`) before the compile
90
- starts, and the reply echoes the short SHA.
87
+ 3. Re-run `!compile full`. On a clean tree Aitne makes the snapshot commit
88
+ for you (`aitne wiki: pre-compile snapshot <ts>`) before the compile
89
+ starts, and the reply shows its short SHA.
91
90
 
92
91
  If you don't want the auto-commit, turn off **Auto-commit before
93
92
  `!compile full`** on `/settings/wiki` (the toggle only appears for
@@ -105,9 +104,10 @@ The full reply ends with:
105
104
  > Sent for approval. Open `/settings/wiki` → Approvals to confirm and the
106
105
  > compile will start.
107
106
 
108
- This is the **cost gate**. Before running, Aitne estimates the compile
109
- cost (pure on-disk arithmetic no agent session is spent). The estimate
110
- DM looks like this:
107
+ This is the **cost gate**. Before running, Aitne estimates what the compile
108
+ will cost. This estimate is just arithmetic over the files on disk it
109
+ does not spend an agent session to work it out. The estimate DM looks like
110
+ this:
111
111
 
112
112
  ```
113
113
  Full compile estimate for `my-wiki`:
@@ -117,13 +117,13 @@ Full compile estimate for `my-wiki`:
117
117
  - approval threshold: $2.00
118
118
  ```
119
119
 
120
- If the **pessimistic** bound (`2× expected`) exceeds the per-workspace
121
- approval threshold (default **$2.00**), the compile is queued for
122
- approval instead of running.
120
+ If the **pessimistic** figure (`2× expected`) is above the per-workspace
121
+ approval threshold (default **$2.00**), the compile waits for your approval
122
+ instead of running right away.
123
123
 
124
124
  ### Approve or Deny
125
125
 
126
- The queued request shows up as a **pending approval** on the dashboard.
126
+ The waiting request shows up as a **pending approval** on the dashboard.
127
127
  Open the dashboard overview (the home page `/`, also reached via the
128
128
  `/approvals` shortcut) and use the **pending approvals** card:
129
129
 
@@ -140,21 +140,22 @@ request.
140
140
  You have three levers, all on `/settings/wiki`:
141
141
 
142
142
  - **Raise the threshold.** The **Approval threshold for `!compile full`**
143
- field controls when a compile queues for approval. Bump it if routine
144
- recompiles keep stalling on a confirmation you'd always grant.
143
+ field decides when a compile has to wait for approval. Raise it if
144
+ routine recompiles keep stalling on a confirmation you would always say
145
+ yes to.
145
146
  - **Use a cheaper model.** In the **Commands & models** section, point
146
147
  `wiki.compile` at a lite-tier model. It defaults to the medium tier
147
- (Claude Sonnet 5), whose per-token cost is the dominant variable in
148
- the estimate.
148
+ (Claude Sonnet 5), and the model's per-token price is the biggest factor
149
+ in the estimate.
149
150
  - **Trim the raw layer.** The estimate scans `10_raw/` and approximates
150
- tokens per file from on-disk content, so the cost tracks the actual
151
- size of what you're compiling. Compiling fewer or shorter raw notes
152
- lowers the bound directly.
151
+ the tokens in each file from its on-disk content, so the cost tracks the
152
+ actual size of what you are compiling. Fewer or shorter raw notes lower
153
+ the estimate directly.
153
154
 
154
- > The estimate is a heuristic (≈4 chars per token for prose, denser for
155
- > CJK), bracketed `0.5×`–`2×`. It is intentionally cheap rather than
156
- > exact — close enough to gate spend without burning a session to
157
- > measure it.
155
+ > The estimate is a rough rule of thumb (≈4 characters per token for
156
+ > prose, denser for CJK), bracketed `0.5×`–`2×`. It is deliberately cheap
157
+ > rather than exact — close enough to gate spending without burning a
158
+ > session just to measure it.
158
159
 
159
160
  ## Not Enabled
160
161
 
@@ -163,11 +164,11 @@ If the reply is:
163
164
  > Wiki is not enabled. Open `/settings/wiki` and enable the internal
164
165
  > wiki workspace first.
165
166
 
166
- you have no active workspace row. On `/settings/wiki`, either click
167
+ you have no active workspace yet. On `/settings/wiki`, either click
167
168
  **Enable internal wiki** to create the built-in workspace, or point Aitne
168
- at an existing folder with **Use this folder** (after the path probe
169
+ at an existing folder with **Use this folder** (once the path check
169
170
  passes). Then re-run `!compile full`.
170
171
 
171
172
  If the workspace exists but is archived, the page shows a **This wiki is
172
- archived** card — click **Re-activate wiki** there before any `!compile`
173
- command will run.
173
+ archived** card — click **Re-activate wiki** there first. No `!compile`
174
+ command will run until you do.
@@ -14,9 +14,7 @@ summary: |
14
14
  filesystem permission vs. the Obsidian CLI fallback path.
15
15
  section: wiki-write-failed
16
16
  tags:
17
- - troubleshooting
18
17
  - wiki
19
- - obsidian
20
18
  - integrations
21
19
  status: stable
22
20
  ask_examples:
@@ -25,7 +23,7 @@ ask_examples:
25
23
  - How do I retry the write-strategy probe?
26
24
  locale: en-US
27
25
  created: 2026-05-12
28
- updated: 2026-06-11
26
+ updated: 2026-07-01
29
27
  keywords:
30
28
  - wiki write failed
31
29
  - wiki API failure
@@ -46,31 +44,30 @@ related:
46
44
 
47
45
  ## What You See
48
46
 
49
- A wiki bang command (`!ingest`, `!compile`) reports a write failure in
50
- the daemon log, or the `GET /api/wiki/:workspace/health` endpoint
51
- (surfaced behind the dashboard's write-strategy badge) reports a
52
- non-`fs` strategy with `cliAvailable: false`.
47
+ A wiki bang command (`!ingest` or `!compile`) reports a write failure in
48
+ the daemon log. Or the wiki health check — `GET /api/wiki/:workspace/health`,
49
+ shown behind the dashboard's write-strategy badge reports a strategy other
50
+ than `fs`, with `cliAvailable: false`.
53
51
 
54
52
  ## Quick Checklist
55
53
 
56
- 1. **Internal mode?** Internal workspaces always write via the local
57
- filesystem. If you see EPERM there, the underlying issue is
58
- `dataDir` permissions — fix those rather than thinking the wiki
59
- is the problem.
54
+ 1. **Internal mode?** Internal workspaces always write to the local
55
+ filesystem. If you see EPERM there, the real problem is `dataDir`
56
+ permissions — fix those, not the wiki.
60
57
  2. **External mode + `write_strategy=fs`?** The filesystem rejected
61
58
  the write. Common causes:
62
- - iCloud sandbox (most frequent on macOS).
63
- - Read-only volume / snapshot mount.
64
- - Filesystem ACL on the parent directory.
65
- 3. **External mode + `write_strategy=cli`?** The probe already fell
66
- back to the Obsidian CLI but the CLI is unavailable. See the CLI
67
- checklist below.
59
+ - iCloud sandbox (the most frequent one on macOS).
60
+ - A read-only volume or snapshot mount.
61
+ - A filesystem ACL (access-control list) on the parent directory.
62
+ 3. **External mode + `write_strategy=cli`?** The write probe already
63
+ fell back to the Obsidian CLI, but the CLI is unavailable. See the
64
+ CLI checklist below.
68
65
 
69
66
  ## The CLI Fallback Path
70
67
 
71
- When direct fs writes fail with `EPERM` / `EACCES` / `EROFS` /
72
- `EBUSY`, Aitne falls back to the official Obsidian CLI (1.12+).
73
- Requirements:
68
+ When a direct filesystem write fails with `EPERM` / `EACCES` / `EROFS` /
69
+ `EBUSY`, Aitne falls back to the official Obsidian CLI (1.12 or later).
70
+ For that fallback to work, you need:
74
71
 
75
72
  - Obsidian installed (1.12 or later).
76
73
  - **Settings → General → Command line interface** enabled inside
@@ -89,10 +86,10 @@ If any of these is missing, the daemon surfaces a structured error:
89
86
 
90
87
  ## Force a Re-Probe
91
88
 
92
- The resolved strategy (`fs` or `cli`) is cached on the workspace row so
93
- later writes skip the probe. If you've fixed the underlying issue
94
- (granted iCloud permission, mounted the disk read-write) but the cached
95
- strategy is still `cli`, force a fresh probe:
89
+ Once a strategy (`fs` or `cli`) is resolved, Aitne caches it on the
90
+ workspace row so later writes can skip the probe. If you've fixed the
91
+ underlying problem (granted iCloud permission, remounted the disk
92
+ read-write) but the cached strategy is still `cli`, force a fresh probe:
96
93
 
97
94
  1. Open **Settings → Wiki** (`/settings/wiki`) and edit the external
98
95
  workspace.
@@ -52,6 +52,9 @@ curl -s -X POST http://localhost:8321/api/agents \
52
52
  "timezone": "Asia/Tokyo"
53
53
  },
54
54
  "backend": { "tier": "medium" },
55
+ "success_criteria": [
56
+ { "id": "triage-note", "kind": "file_exists", "target": "notes/inbox-triage-{date}.md" }
57
+ ],
55
58
  "prompt": "<the detailed agent definition — see below>"
56
59
  }'
57
60
  ```
@@ -107,8 +110,15 @@ Fields:
107
110
  separate skill copy). **Declare every playbook you name in the prompt's
108
111
  `# Important`** — a bare mention is not injected on its own. An unknown slug is
109
112
  rejected as `invalid_definition` on field `playbooks`.
113
+ - **`success_criteria`** — optional array of deterministic post-run checks; their
114
+ hit rate is the Agent's dashboard quality metric. **Derive 1–3 from the prompt's
115
+ `# Output` contract** (see "Success criteria" below); omitting them when the
116
+ prompt has an `# Output` section returns a `no_success_criteria` warning.
110
117
  - **`prompt`** — the Agent's instructions (the Markdown body). **This is the most
111
- important field. Write it in detail.**
118
+ important field. Write it in detail.** An empty or stub body (`"placeholder"`,
119
+ `"TODO"`, …) is rejected as `invalid_definition` on field `prompt` — the Agent
120
+ would skip every run as ambiguous. Never create now to fill the prompt in
121
+ later; clarify the task with the user first.
112
122
 
113
123
  ## Writing the `prompt` — the Agent has NO memory of why it exists
114
124
 
@@ -150,13 +160,36 @@ includes DMing the user, also set `schedule.defer_in_quiet_hours: true` so a
150
160
  firing inside quiet hours waits for the window's end instead of producing a
151
161
  message that would be held anyway.
152
162
 
163
+ ## Success criteria — derive them from `# Output`
164
+
165
+ `success_criteria` are deterministic checks the daemon evaluates after every
166
+ firing; their hit rate is the Agent's dashboard quality metric — without them
167
+ the Agent has **no quality signal**. Derive 1–3 mechanically from the `# Output`
168
+ contract at creation time:
169
+
170
+ - Writes a dated note → `{ "id": "note-exists", "kind": "file_exists",
171
+ "target": "notes/<name>-{date}.md" }`. Targets are vault-relative; `{date}`
172
+ (the agent-day, resolved at eval time) is the only placeholder.
173
+ - Populates a note with N sections → `{ "id": "sections-filled",
174
+ "kind": "file_section_count", "target": "…", "heading_level": 2, "min": N }` —
175
+ counts headings of exactly `heading_level`.
176
+ - DMs the user → `{ "id": "dm-delivered", "kind": "notification_log",
177
+ "notification_type": "agent", "delivered_within_minutes": M }` — size `M` to
178
+ the run (30–60 typical). Caveat: matching is install-wide within the window
179
+ (ANY delivered `"agent"` notification counts, not just this Agent's), so
180
+ prefer the file-based kinds whenever the output also lands in a file.
181
+
182
+ `id` values must be unique within the Agent (duplicates are rejected as
183
+ `invalid_definition` on `success_criteria[i].id`).
184
+
153
185
  ## Responses & errors
154
186
 
155
187
  - `201 { "status": "created", "slug": "…" }` — the Agent is live; its recurring
156
188
  schedule is paired and it will fire on the next matching tick. The response may
157
- also carry `warnings[]` (non-blocking authoring lint — e.g. an empty prompt, a
158
- missing `# Instruction` section, or a playbook you named but didn't declare);
159
- the Agent is still created, but fix the flagged issues and re-save its `agent.md`.
189
+ also carry `warnings[]` (non-blocking authoring lint — e.g. a missing
190
+ `# Instruction` section, a playbook you named but didn't declare, or an
191
+ `# Output` contract with no `success_criteria`); the Agent is still created,
192
+ but fix the flagged issues and re-save its `agent.md`.
160
193
  - `400 one_shot_not_supported` — the schedule was not `cron`/`recurring`. Use the
161
194
  `schedule` skill for one-time tasks.
162
195
  - `400 invalid_recurrence` — a `kind:"recurring"` schedule carried a malformed
@@ -168,7 +201,8 @@ message that would be held anyway.
168
201
  `issues[]` (each `{ field, message }`); the post-write cross-check (loader
169
202
  rejects the freshly written file) returns `slug` + a single `detail` string
170
203
  (or `null`). Read `issues[]` if present, else fall back to `detail`, fix the
171
- reported field(s), and resubmit.
204
+ reported field(s), and resubmit. An empty/placeholder `prompt` also lands
205
+ here — get the real task from the user, never retry with another stub.
172
206
 
173
207
  Read `Read`-only files you reference in the prompt to confirm they exist before
174
208
  creating the Agent.
@@ -54,8 +54,9 @@ Resolve ambiguity with the user now, then encode all of:
54
54
  reads right if it's sent directly.
55
55
  - **Notification policy + criteria** — see below; for `if_significant` the
56
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).
57
+ - **Expected output** — 1–5 concretely verifiable requirements (a per-repo
58
+ table, a ranked list, a one-paragraph verdict). The worker verifies its
59
+ result against these line-by-line before finishing.
59
60
 
60
61
  The worker can read owner memory itself to fill in preferences, so you need
61
62
  only supply the *task-specific* inputs above. **Promoting an inline task?**
@@ -83,7 +84,7 @@ in the daily digest and the user can pull it (see "Filed results" below).
83
84
  |---|---|---|
84
85
  | POST | `/api/background-task` | Create + dispatch, or schedule (`scheduleAt`). |
85
86
  | 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
+ | GET | `/api/background-task/:id` | The artifact — verbatim `report`, `draft`, `notify`, `verification`, clarifications. |
87
88
  | POST | `/api/background-task/:id/cancel` | Force-stop. |
88
89
 
89
90
  Clarifications are answered with the **`background-task-reply`** skill.
@@ -130,6 +131,8 @@ Body:
130
131
  The eventual *result delivery* is what respects quiet hours, not the run.
131
132
  `202` with `{ taskId, status:"scheduled", scheduledFor, scheduleRowId }`.
132
133
  A time more than 60s in the past is rejected `400`.
134
+ - `origin` — Task Board provenance: `"user"` when the user asked for this
135
+ work, `"agent"` (default) for your own initiative.
133
136
 
134
137
  Immediate response carries `taskId` and `status`. Then ack once and stop
135
138
  (Hard rule 2).
@@ -154,7 +157,9 @@ curl --silent --fail http://localhost:8321/api/background-task/<taskId>
154
157
 
155
158
  `report` is the full, unparaphrased result. Quote from it; don't invent
156
159
  detail. If you lack the `taskId`, list `state=completed` and match by
157
- `title`.
160
+ `title`. The worker's `verification` checklist rides along — on
161
+ `outcomeDetail` `completed_with_gaps` it shows which requirements fell
162
+ short.
158
163
 
159
164
  ## Filed results — the "did that monitor ever run?" pull
160
165
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: board
3
- description: Read-only Task Board — list everything in motion (recurring DMs, Agents, app-fetch, reminders, background/browser/research) via GET /api/tasks, and preview a delete's blast radius via GET /api/tasks/impact. For writes use the `task` skill.
3
+ description: Read-only Task Board — list everything in motion (recurring DMs, Agents, app-fetch, automation triggers, reminders, background/browser work) via GET /api/tasks, and preview a delete's blast radius via GET /api/tasks/impact. For writes use the `task` skill.
4
4
  allowed-tools:
5
5
  - Bash(curl *)
6
6
  - Read
@@ -11,8 +11,9 @@ allowed-tools:
11
11
  One place to answer two questions the user actually asks:
12
12
 
13
13
  1. **"What do I have running / set up?"** — a single inventory across every
14
- creation path (recurring DMs, Agents, app-fetch managed tasks, pending
15
- one-off reminders, and in-flight background / browser / research work).
14
+ creation path (recurring DMs, Agents, app-fetch managed tasks, automation
15
+ triggers, pending one-off reminders, and in-flight background / browser
16
+ work).
16
17
  2. **"What breaks if I delete / change X?"** — the blast radius, with each
17
18
  affected row labelled by its real cascade.
18
19
 
@@ -40,10 +41,10 @@ Returns `{ items, total, generatedAt }`. Each item:
40
41
 
41
42
  | Field | Meaning |
42
43
  |---|---|
43
- | `ref` | typed handle — `rs:<id>` (recurring DM), `mt_<n>` (app-fetch), `agent:<slug>`, `as:<id>` (one-off reminder), `bt:<id>` (background), `bx:<id>` (browser), `cluster:<slug>` (research) |
44
+ | `ref` | typed handle — `rs:<id>` (recurring DM), `mt_<n>` (app-fetch), `agent:<slug>`, `trigger:<id>` (automation trigger), `as:<id>` (one-off reminder), `bt:<id>` (background), `bx:<id>` (browser) |
44
45
  | `title` | human label — passed through verbatim from the owning row |
45
- | `kind` | `dm` / `agent` / `app_fetch` / `reminder` / `background` / `browser` / `research` |
46
- | `status` | `active` / `paused` / `pending` / a fulfiller state (`running`, `awaiting_user`, …) |
46
+ | `kind` | `dm` / `agent` / `app_fetch` / `trigger` / `reminder` / `background` / `browser` |
47
+ | `status` | `active` / `paused` / `pending` / `running` (incl. an Agent with a turn in flight) / a fulfiller state (`awaiting_user`, …) |
47
48
  | `cadence` | human schedule label, or null for one-shot work |
48
49
  | `fulfilledBy` | typed ref of the row that actually executes (for `app_fetch`, its `rs:` schedule) |
49
50
  | `origin` | `system` / `user` / `agent` |
@@ -87,7 +88,5 @@ specialised skills (`agent-create`, `managed-tasks`, `schedule`,
87
88
 
88
89
  1. **Localhost only.** `http://localhost:8321/api/tasks*`.
89
90
  2. **Read-only.** This skill issues only GETs. Never mutate from here.
90
- 3. **Never reactivate a muted/concluded research cluster** by listing it the
91
- board only surfaces active/dormant clusters and `impact` never changes status.
92
- 4. **Never read or relay a browser-task final-confirm token.** The board surfaces
91
+ 3. **Never read or relay a browser-task final-confirm token.** The board surfaces
93
92
  only safe fields (`status`/`ref`); a pending `!~xxxxxxxx` token is never shown.
@@ -81,6 +81,8 @@ Body:
81
81
  pre-generated id you use for status GETs).
82
82
  - `requireFinalConfirm` (default `true`) — keep `true` unless the user
83
83
  explicitly asks to skip the gate for a reversible flow.
84
+ - `origin` — Task Board provenance: `"user"` when the user asked for this
85
+ work, `"agent"` (default) for your own initiative.
84
86
 
85
87
  Immediate response carries `taskId`, `status`, and `queueState`; then ack
86
88
  once and stop (Hard rule 2). If `queueState.waitingForSlot === true`, the
@@ -8,6 +8,7 @@
8
8
  { "path": "journal/monthly/*.md", "purpose": "monthly review snapshots (YYYY-MM)", "sections": [{ "heading": "## Theme", "contains": "the month's overall theme" }] },
9
9
  { "path": "policies/*.md", "purpose": "user-controlled policy files", "sections": [{ "heading": "## Why", "contains": "rationale for the rule" }, { "heading": "## How", "contains": "concrete rule shape" }] },
10
10
  { "path": "identity/*.md", "purpose": "user identity and preferences dictionary", "sections": [{ "heading": "## Identity", "contains": "name role tz" }] },
11
- { "path": "journal/agent.md", "purpose": "agent-owned weekly + monthly self-critique", "sections": [{ "heading": "## Weekly", "contains": "what worked, what slipped, improvements" }] }
11
+ { "path": "journal/agent.md", "purpose": "agent-owned weekly + monthly self-critique", "sections": [{ "heading": "## Weekly", "contains": "what worked, what slipped, improvements" }] },
12
+ { "path": "knowledge/sources/*/*.md", "purpose": "source-document cards: summaries of user-sent files (PDF/PPTX/docs) stored in the source library; write via the sources skill", "sections": [{ "heading": "# <Title>", "contains": "summary + source_id frontmatter + project link" }] }
12
13
  ]
13
14
  }
@@ -30,10 +30,9 @@ user but compound into duplicate DMs/notifications at fire time.
30
30
  the conversation made moot. Else `GET
31
31
  /api/schedule?status=pending,running` for one within ±15 min with a
32
32
  matching `description`; if found, skip or PATCH.
33
- 3. **Recurring check.** `GET /api/recurring-schedules?enabled=true` to
34
- confirm no recurring rule/Agent already covers this cadence (e.g. a
35
- daily 09:00 inbox triage, or the morning briefing). If covered, skip.
36
- (How recurring work/DMs are created — see "Recurring" below.)
33
+ 3. **Recurring check.** `GET /api/recurring-schedules?enabled=true&includeClaimed=true`
34
+ confirm no recurring rule/Agent covers this cadence (a `claimedByAgentSlug`
35
+ row is Agent-owned and counts). If covered, skip (see "Recurring" below).
37
36
  4. **`confirm_dedup_key` check (mandatory for `confirm:` sub-flow rows
38
37
  only).** When scheduling a `dm_session` row with
39
38
  `taskContext.sub_flow="confirm"`, run the dedup pre-check + shape
@@ -222,7 +221,9 @@ model, batch) are in the errors reference below.
222
221
  (its fire time can track quiet-hours; PATCH/DELETE edit it). The morning
223
222
  briefing is one of these.
224
223
 
225
- `GET /api/recurring-schedules` stays read-only for the dedup pre-check.
224
+ `GET /api/recurring-schedules` stays read-only for the dedup pre-check; `includeClaimed=true`
225
+ keeps Agent-claimed (`claimedByAgentSlug`) + trigger-owned (`claimedByTriggerId`) rows visible.
226
+ Writes on claimed rows: **409** → `/api/agents/<slug>`; trigger-owned → `/api/triggers/<id>`.
226
227
 
227
228
  ### recurrenceRule grammar — the shared recurrence engine
228
229
 
@@ -0,0 +1,68 @@
1
+ ---
2
+ name: sources
3
+ description: Load to manage the durable source library (user-sent PDFs/PPTX/docs) — list unfiled sources, file them as knowledge/sources/ cards, promote images, or send a stored source back. SKIP for delivering files you generated this turn (attach) or general vault edits (context).
4
+ allowed-tools:
5
+ - Bash(curl *)
6
+ - Bash(unzip *)
7
+ - Read
8
+ - Write
9
+ ---
10
+
11
+ # Source library
12
+
13
+ Document attachments the user sends (PDF, PPTX, DOCX, XLSX, ODT) are captured automatically into a durable library the moment they arrive — they survive chat pruning. Each source is a ledger row (`src_…` id) plus the original bytes. Your job is the *organization* layer: write a markdown **card** for each source under `knowledge/sources/<collection>/`, link it to projects, and keep the collections tidy.
14
+
15
+ - **Bash is limited to `curl` and `unzip`, literal arguments only.** No `$VAR` / `$(...)` / pipes / chained commands — anything else is silently denied. Pre-compute values and write literals.
16
+ - Cards are written via the `context` API (this skill shows the calls); the library API below only records metadata and bindings.
17
+
18
+ ## API (all on `http://localhost:8321`)
19
+
20
+ | Verb | Purpose |
21
+ |---|---|
22
+ | `GET /api/sources?status=unfiled` | List sources awaiting filing (also `filed`, `archived`; `limit`/`offset`). |
23
+ | `GET /api/sources/<id>` | One source's metadata (filename, mime, size, caption, provenance, cardPath). |
24
+ | `GET /api/sources/<id>/file` | The original bytes. Save to the workdir: `curl -s -o ./src-deck.pdf http://localhost:8321/api/sources/<id>/file` |
25
+ | `POST /api/sources/promote` | Capture a chat attachment the auto-capture skipped (images, audio): `{"attachmentId":"<uuid>","caption":"…"}`. Returns the `src_…` id (`deduped:true` if already stored). |
26
+ | `PATCH /api/sources/<id>` | Record the filing: `{"cardPath":"knowledge/sources/<collection>/<slug>.md"}` (implies `status:"filed"`). Also `{"status":"archived"}` for junk, `{"caption":"…"}`. |
27
+ | `POST /api/sources/<id>/export` | Copy the original binary into the user's external Obsidian vault: `{"target":"obsidian"}`. Lands at `sources/<file>` with a companion note embedding it (`{"note":false}` to skip). 409 if no external vault is configured. For **Notion**, there is no binary path — create a page from the card markdown via `POST /api/notion/pages` instead. |
28
+
29
+ Errors use the standard agent-error envelope; `404 sources.not_found` means a stale id — re-list. Never DELETE a source; archive instead (deletion is owner-only).
30
+
31
+ ## Filing a source (the core loop)
32
+
33
+ 1. `GET /api/sources?status=unfiled` — pick a source.
34
+ 2. Understand it. PDFs: fetch the bytes to the workdir and `Read` the file directly. PPTX/DOCX are zip archives of XML — best-effort text peek with `unzip -p ./src-deck.pptx ppt/slides/slide1.xml` (one file per call, no pipes; read the text between the XML tags in the output). If `unzip` is unavailable on this platform, fall back to filename + caption — they often suffice.
35
+ 3. Choose a collection per the taxonomy below (create a new one only when nothing fits).
36
+ 4. Write the card:
37
+
38
+ ```bash
39
+ curl -s -X PUT http://localhost:8321/api/context/knowledge/sources/acme-launch/pitch-deck.md \
40
+ -H "Content-Type: application/json" \
41
+ -d '{"content":"---\ntype: source\nowner: agent\nupdated: 2026-07-01\nsource_id: src_1234\nmime: application/pdf\nreceived: 2026-07-01\nprovenance: user_telegram\n---\n# Acme launch pitch deck\n\nOne-paragraph summary of what the document contains and why the user sent it.\n\nProject: [[acme-launch]]\n"}'
42
+ ```
43
+
44
+ 5. Bind it: `curl -s -X PATCH http://localhost:8321/api/sources/src_1234 -H "Content-Type: application/json" -d '{"cardPath":"knowledge/sources/acme-launch/pitch-deck.md"}'`
45
+ 6. If the source belongs to a project, add a `- [[knowledge/sources/acme-launch/pitch-deck|Pitch deck]]` line under a `## Sources` heading in `plans/projects/<slug>.md` (PATCH, append mode).
46
+ 7. Keep `knowledge/sources/_index.md` current: one line per collection with a one-phrase scope.
47
+
48
+ ## Reorganizing
49
+
50
+ Move a card = PUT the card at the new path, DELETE the old path (`curl -X DELETE http://localhost:8321/api/context/knowledge/sources/old/card.md`), then PATCH the source's `cardPath`. Deletes are snapshotted — recoverable. Merge singleton collections into broader ones; split collections past ~15 cards.
51
+
52
+ ## Sending a source back to the user
53
+
54
+ Fetch the bytes to the workdir, then deliver through the outbound endpoint (see the `attach` skill for limits):
55
+
56
+ ```bash
57
+ curl -s -o ./src-deck.pdf http://localhost:8321/api/sources/src_1234/file
58
+ curl -s -X POST http://localhost:8321/api/chat/outbound-attachments \
59
+ -H "X-Filename: pitch-deck.pdf" -F "file=@./src-deck.pdf"
60
+ ```
61
+
62
+ ## Collection taxonomy (auto-curated)
63
+
64
+ <!-- CURATION:knowledge_layout id="source-collections" -->
65
+
66
+ ## Filing conventions (auto-curated)
67
+
68
+ <!-- CURATION:convention_notes id="filing-rules" -->
@@ -0,0 +1,21 @@
1
+ {
2
+ "version": 1,
3
+ "sections": [
4
+ {
5
+ "id": "source-collections",
6
+ "kind": "knowledge_layout",
7
+ "anchor": "<!-- CURATION:knowledge_layout id=\"source-collections\" -->",
8
+ "human_label": "Source collection taxonomy",
9
+ "description": "Current collections under knowledge/sources/ and what belongs in each",
10
+ "scope_paths": ["knowledge/sources/**"]
11
+ },
12
+ {
13
+ "id": "filing-rules",
14
+ "kind": "convention_notes",
15
+ "anchor": "<!-- CURATION:convention_notes id=\"filing-rules\" -->",
16
+ "human_label": "Source filing conventions",
17
+ "description": "Card slug grammar, card body shape, and project cross-linking rules",
18
+ "scope_paths": ["knowledge/sources/**"]
19
+ }
20
+ ]
21
+ }
@@ -0,0 +1,25 @@
1
+ {
2
+ "kind": "convention_notes",
3
+ "notes": [
4
+ {
5
+ "topic": "Card slug",
6
+ "rule": "Lowercase [a-z0-9._-], descriptive of the document content, not the filename (strip dates/version noise unless meaningful).",
7
+ "example": "knowledge/sources/acme-launch/pitch-deck.md for 'Acme_Pitch_FINAL_v3 (2).pdf'"
8
+ },
9
+ {
10
+ "topic": "One card per source",
11
+ "rule": "Exactly one card per src_ id; on dedup (same file re-sent) update the existing card's `updated:` instead of writing a second card.",
12
+ "example": "receive_count > 1 on GET /api/sources/<id> means the user re-sent the same bytes"
13
+ },
14
+ {
15
+ "topic": "Collection choice",
16
+ "rule": "Prefer a collection matching an active project slug; use a topical collection for project-less documents; reserve `inbox` for the genuinely unclassifiable.",
17
+ "example": "a tax PDF with no project goes to knowledge/sources/finance/, not inbox"
18
+ },
19
+ {
20
+ "topic": "Project cross-link",
21
+ "rule": "When a source supports a project, the project file gets a `## Sources` bullet linking the card — the card alone is not discoverable from the project side.",
22
+ "example": "plans/projects/acme-launch.md gains: - [[knowledge/sources/acme-launch/pitch-deck|Pitch deck]]"
23
+ }
24
+ ]
25
+ }
@@ -0,0 +1,20 @@
1
+ {
2
+ "kind": "knowledge_layout",
3
+ "files": [
4
+ {
5
+ "path": "knowledge/sources/_index.md",
6
+ "purpose": "Directory of collections — one line per collection with its one-phrase scope",
7
+ "sections": [
8
+ { "heading": "## Collections", "contains": "bullet list: - [[<collection>]] — what belongs there" }
9
+ ]
10
+ },
11
+ {
12
+ "path": "knowledge/sources/*/*.md",
13
+ "purpose": "One card per stored source document; collections usually mirror an active project slug from plans/projects/",
14
+ "sections": [
15
+ { "heading": "# <Title>", "contains": "H1 naming the document in plain words" },
16
+ { "heading": "(body)", "contains": "one-paragraph summary, why the user sent it, and a Project: [[<slug>]] link when one applies" }
17
+ ]
18
+ }
19
+ ]
20
+ }
@@ -44,8 +44,11 @@ the front door; the specialised skills are the manual.
44
44
  ## Edit / delete — `PATCH` / `DELETE /api/tasks/<ref>`
45
45
 
46
46
  Address the row by its typed `ref` from the board (`rs:<id>`, `mt_<n>`,
47
- `agent:<slug>`, `as:<id>`). PATCH forwards your patch body to the owning edit
48
- endpoint; DELETE forwards to the owning delete (cascade preserved).
47
+ `agent:<slug>`, `as:<id>`, `trigger:<id>`). PATCH forwards your patch body to
48
+ the owning edit endpoint; DELETE forwards to the owning delete (cascade
49
+ preserved). A `trigger:` write routes to `/api/triggers/<id>` (Approve tier;
50
+ `401` = needs the dashboard's authorization; no facade create kind) and its
51
+ delete removes the paired recurring schedule too.
49
52
 
50
53
  ```bash
51
54
  curl --silent --fail -X PATCH -H 'Content-Type: application/json' \
@@ -44,8 +44,8 @@ notification policy. Read it carefully and satisfy it end to end.
44
44
 
45
45
  ## Finishing — the artifact (read this carefully)
46
46
 
47
- `finish(result, draft, notify, significance?)` is the only thing the
48
- owner ever sees the effect of. Each field has a distinct job:
47
+ `finish(result, draft, notify, verification, significance?)` is the only
48
+ thing the owner ever sees the effect of. Each field has a distinct job:
49
49
 
50
50
  - **`result`** — the FULL, verbatim outcome: every finding, number, URL,
51
51
  id, quote. This is persisted unchanged and is what a precise follow-up
@@ -67,15 +67,41 @@ owner ever sees the effect of. Each field has a distinct job:
67
67
  the brief. If the criteria are not met, `notify = false`.
68
68
  - `silent` → `notify = false`.
69
69
  - When you are on `always` and unsure, prefer `true`.
70
+ - **`verification`** *(required)* — your self-verification checklist: 1–10
71
+ `{requirement, met, evidence}` items (see "Self-verification before
72
+ finish" below). Any `met=false` automatically appends a gap disclosure
73
+ to your `draft` and records the completion as `completed_with_gaps` —
74
+ you do not need to (and cannot) hide a gap.
70
75
  - **`significance`** *(optional)* — one line on why notify is true/false
71
76
  ("2 repos red" / "no criteria met"). Used for the audit + the
72
77
  filed-results digest.
73
78
 
79
+ ## Self-verification before finish
80
+
81
+ Before calling `finish`, verify your own result against the brief:
82
+
83
+ 1. **Derive a checklist** from the brief's **Expected output** section
84
+ (fallback: the Objective) — 1–10 concrete requirements, each stated in
85
+ ≤300 chars.
86
+ 2. **Verify each item against your ACTUAL result**, not your intent.
87
+ `evidence` must point at something real in `result` ("table has one
88
+ row per repo, all 6 listed"), never a restatement of the requirement.
89
+ 3. **If a requirement is unmet and you have turn budget left, attempt the
90
+ repair FIRST** — go back, gather what is missing, then re-verify.
91
+ 4. Finish with `met=false` only when you genuinely cannot fix it (source
92
+ unavailable, out of scope, budget exhausted). Say what is missing and
93
+ why in `evidence`.
94
+
95
+ Never claim `met=true` your evidence does not support: any unmet item is
96
+ disclosed to the owner automatically, but a false "met" is a silent lie
97
+ the owner will act on.
98
+
74
99
  ## Typical loop
75
100
 
76
101
  ```
77
102
  1. (optional) read_memory(...) # pull owner context you need
78
103
  2. WebSearch / WebFetch / reason # do the actual work
79
104
  3. (only if blocked) ask_user(...) # then STOP this turn
80
- 4. finish(result=<full>, draft=<summary>, notify=<policy eval>, significance=<one line>)
105
+ 4. self-verify vs the brief's Expected output; repair gaps if budget remains
106
+ 5. finish(result=<full>, draft=<summary>, notify=<policy eval>, verification=<checklist>, significance=<one line>)
81
107
  ```