@aitne-sh/aitne 0.1.9 → 0.1.10

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 (153) hide show
  1. package/README.md +36 -6
  2. package/agent-assets/docs/concepts/agent-day.md +2 -2
  3. package/agent-assets/docs/concepts/costs-and-quotas.md +4 -3
  4. package/agent-assets/docs/concepts/delegated-mode.md +5 -5
  5. package/agent-assets/docs/concepts/memory-model.md +6 -3
  6. package/agent-assets/docs/concepts/safety-model.md +19 -16
  7. package/agent-assets/docs/concepts/skills.md +2 -2
  8. package/agent-assets/docs/features/integrations/browser-history.md +9 -8
  9. package/agent-assets/docs/features/integrations/calendar.md +4 -4
  10. package/agent-assets/docs/features/integrations/mail.md +3 -2
  11. package/agent-assets/docs/features/lifestyle/git.md +3 -3
  12. package/agent-assets/docs/features/lifestyle/reading.md +15 -8
  13. package/agent-assets/docs/features/lifestyle/travel-bookings.md +4 -3
  14. package/agent-assets/docs/features/memory-files/agent-journal.md +30 -12
  15. package/agent-assets/docs/features/memory-files/agent-lessons.md +177 -0
  16. package/agent-assets/docs/features/memory-files/projects.md +6 -4
  17. package/agent-assets/docs/features/memory-files/roadmap.md +17 -14
  18. package/agent-assets/docs/features/messaging/overview.md +5 -5
  19. package/agent-assets/docs/features/messaging/telegram.md +10 -9
  20. package/agent-assets/docs/features/operations/activity-and-conversations.md +5 -4
  21. package/agent-assets/docs/features/operations/approvals.md +6 -5
  22. package/agent-assets/docs/features/operations/managed-chromium.md +3 -2
  23. package/agent-assets/docs/features/operations/quiet-hours.md +4 -3
  24. package/agent-assets/docs/features/routines/custom-routines.md +11 -7
  25. package/agent-assets/docs/features/routines/evening-review.md +10 -2
  26. package/agent-assets/docs/features/routines/morning-routine.md +4 -3
  27. package/agent-assets/docs/features/routines/weekly-review.md +6 -0
  28. package/agent-assets/docs/features/wiki/commands.md +4 -4
  29. package/agent-assets/docs/features/wiki/cost-and-approval.md +4 -3
  30. package/agent-assets/docs/features/wiki/dashboard.md +7 -6
  31. package/agent-assets/docs/features/wiki/overview.md +3 -3
  32. package/agent-assets/docs/features/wiki/search.md +5 -5
  33. package/agent-assets/docs/features/wiki/workspaces.md +2 -2
  34. package/agent-assets/docs/getting-started/02-first-steps.md +5 -3
  35. package/agent-assets/docs/getting-started/04-first-day.md +2 -2
  36. package/agent-assets/docs/glossary.md +4 -4
  37. package/agent-assets/docs/guides/budget-and-cost-for-wiki.md +2 -2
  38. package/agent-assets/docs/guides/connect-a-new-mail-account.md +4 -2
  39. package/agent-assets/docs/guides/explore-with-trace-and-connect.md +5 -4
  40. package/agent-assets/docs/guides/install-and-run.md +2 -2
  41. package/agent-assets/docs/guides/maintain-wiki-health.md +2 -2
  42. package/agent-assets/docs/guides/pause-the-agent.md +9 -5
  43. package/agent-assets/docs/guides/setup-wizard.md +8 -5
  44. package/agent-assets/docs/guides/use-an-existing-obsidian-vault.md +6 -6
  45. package/agent-assets/docs/reference/api.md +15 -5
  46. package/agent-assets/docs/reference/cli-commands.md +3 -3
  47. package/agent-assets/docs/reference/config.md +21 -4
  48. package/agent-assets/docs/reference/disallowed-tools.md +6 -4
  49. package/agent-assets/docs/reference/knowledge-layout.md +11 -2
  50. package/agent-assets/docs/reference/process-keys.md +2 -2
  51. package/agent-assets/docs/reference/skills.md +5 -4
  52. package/agent-assets/docs/troubleshooting/auth-failed.md +9 -8
  53. package/agent-assets/docs/troubleshooting/dashboard-shows-degraded.md +16 -9
  54. package/agent-assets/docs/troubleshooting/messaging-not-pairing.md +2 -2
  55. package/agent-assets/docs/troubleshooting/quota-exhausted.md +7 -6
  56. package/agent-assets/skills/agent-actions/SKILL.md +23 -39
  57. package/agent-assets/skills/agent-create/SKILL.md +15 -6
  58. package/agent-assets/skills/attach/SKILL.md +8 -27
  59. package/agent-assets/skills/browser-history/SKILL.md +29 -16
  60. package/agent-assets/skills/browser-history-respond/SKILL.md +6 -1
  61. package/agent-assets/skills/browser-task/SKILL.md +22 -27
  62. package/agent-assets/skills/context/SKILL.md +23 -32
  63. package/agent-assets/skills/context/curation.json +12 -12
  64. package/agent-assets/skills/context/references/api.md +17 -17
  65. package/agent-assets/skills/context/references/required-frontmatter.md +10 -9
  66. package/agent-assets/skills/context/references/snapshot-files.md +12 -11
  67. package/agent-assets/skills/context/seeds/file-responsibilities.seed.json +5 -5
  68. package/agent-assets/skills/context/seeds/frontmatter-requirements.seed.json +3 -3
  69. package/agent-assets/skills/docs-search/SKILL.md +19 -31
  70. package/agent-assets/skills/external-services/SKILL.delegated.claude.md +8 -95
  71. package/agent-assets/skills/external-services/SKILL.delegated.codex.md +8 -94
  72. package/agent-assets/skills/external-services/SKILL.delegated.gemini.md +8 -94
  73. package/agent-assets/skills/external-services/SKILL.native.claude.md +2 -2
  74. package/agent-assets/skills/external-services/references/exec-errors.md +32 -0
  75. package/agent-assets/skills/external-services/references/skills-crud.md +5 -5
  76. package/agent-assets/skills/gmail-lifestyle/SKILL.md +3 -2
  77. package/agent-assets/skills/gmail-lifestyle/references/receipts-api.md +4 -0
  78. package/agent-assets/skills/gmail-lifestyle/references/travel-bookings-api.md +9 -0
  79. package/agent-assets/skills/mail/SKILL.delegated.claude.md +13 -25
  80. package/agent-assets/skills/mail/SKILL.delegated.codex.md +3 -2
  81. package/agent-assets/skills/mail/SKILL.delegated.gemini.md +3 -2
  82. package/agent-assets/skills/mail/SKILL.md +10 -18
  83. package/agent-assets/skills/mail/SKILL.native.claude.md +8 -7
  84. package/agent-assets/skills/mail/SKILL.native.codex.md +1 -1
  85. package/agent-assets/skills/mail/SKILL.native.gemini.md +1 -1
  86. package/agent-assets/skills/mail/references/api.md +6 -1
  87. package/agent-assets/skills/mail/references/examples.md +2 -1
  88. package/agent-assets/skills/managed-tasks/SKILL.md +44 -77
  89. package/agent-assets/skills/managed-tasks/references/errors.md +25 -14
  90. package/agent-assets/skills/managed-tasks/references/output-path.md +33 -17
  91. package/agent-assets/skills/managed-tasks/references/recurrence-rule.md +6 -4
  92. package/agent-assets/skills/management-policy/SKILL.md +10 -11
  93. package/agent-assets/skills/management-policy/references/policy-workflow.md +4 -5
  94. package/agent-assets/skills/notify/SKILL.md +11 -13
  95. package/agent-assets/skills/notify/references/priority.md +28 -25
  96. package/agent-assets/skills/notion/SKILL.delegated.claude.md +1 -1
  97. package/agent-assets/skills/notion/SKILL.delegated.codex.md +1 -1
  98. package/agent-assets/skills/notion/SKILL.delegated.gemini.md +1 -1
  99. package/agent-assets/skills/notion/SKILL.md +17 -17
  100. package/agent-assets/skills/notion/SKILL.native.claude.md +1 -1
  101. package/agent-assets/skills/notion/SKILL.native.codex.md +1 -1
  102. package/agent-assets/skills/notion/SKILL.native.gemini.md +1 -1
  103. package/agent-assets/skills/observations/SKILL.md +5 -20
  104. package/agent-assets/skills/observations/references/fetch-fallback.md +22 -0
  105. package/agent-assets/skills/project-doc/SKILL.md +9 -6
  106. package/agent-assets/skills/project-doc/curation.json +3 -3
  107. package/agent-assets/skills/project-doc/seeds/project-shape.seed.json +2 -2
  108. package/agent-assets/skills/project-doc/seeds/slug-grammar.seed.json +3 -3
  109. package/agent-assets/skills/reading/SKILL.md +8 -42
  110. package/agent-assets/skills/reading/references/reading-taste.md +5 -5
  111. package/agent-assets/skills/roadmap/SKILL.md +3 -19
  112. package/agent-assets/skills/roadmap/references/api.md +16 -6
  113. package/agent-assets/skills/roadmap/references/horizon-tags.md +11 -0
  114. package/agent-assets/skills/roadmap/references/migration.md +8 -6
  115. package/agent-assets/skills/roadmap/references/retention.md +18 -0
  116. package/agent-assets/skills/schedule/SKILL.md +9 -26
  117. package/agent-assets/skills/schedule/references/importance.md +23 -0
  118. package/agent-assets/skills/schedule/references/recurrence-rule.md +6 -4
  119. package/agent-assets/skills/scheduled-managed-task/SKILL.md +34 -37
  120. package/agent-assets/skills/today/SKILL.md +20 -79
  121. package/agent-assets/skills/today/references/today-skeleton.md +66 -0
  122. package/agent-assets/skills/today/seeds/agent-notes-flavors.seed.json +1 -1
  123. package/agent-assets/skills/today/seeds/section-shape.seed.json +6 -6
  124. package/agent-assets/skills/user-interview/SKILL.md +15 -90
  125. package/agent-assets/skills/user-interview/references/op-briefing.md +1 -1
  126. package/agent-assets/skills/user-interview/references/op-dm-handler.md +88 -0
  127. package/agent-assets/skills/user-interview/references/op-morning.md +1 -1
  128. package/agent-assets/skills/user-interview/references/sweep-and-fallback.md +1 -1
  129. package/agent-assets/skills/user-profile/SKILL.md +16 -26
  130. package/agent-assets/skills/user-profile/curation.json +3 -3
  131. package/agent-assets/skills/user-profile/references/character-preferences.md +3 -3
  132. package/agent-assets/skills/wiki/wiki-ask/SKILL.md +1 -1
  133. package/agent-assets/skills/wiki/wiki-compile/SKILL.md +5 -4
  134. package/agent-assets/skills/wiki/wiki-connect/SKILL.md +32 -5
  135. package/agent-assets/skills/wiki/wiki-ingest/SKILL.md +6 -50
  136. package/agent-assets/skills/wiki/wiki-ingest/references/curl-errors.md +58 -0
  137. package/agent-assets/skills/wiki/wiki-lint/SKILL.md +20 -14
  138. package/agent-assets/skills/wiki/wiki-trace/SKILL.md +10 -5
  139. package/agent-assets/skills/wiki/wiki-vault-rules/SKILL.md +2 -0
  140. package/agent-assets/task-flows/_partials/feedback-capture.md +30 -0
  141. package/agent-assets/task-flows/message.received.dm.md +4 -0
  142. package/agent-assets/task-flows/message.received.dm_first.md +4 -0
  143. package/agent-assets/task-flows/routine.evening_review.md +80 -0
  144. package/agent-assets/task-flows/routine.monthly_review.md +72 -0
  145. package/agent-assets/task-flows/routine.weekly_review.md +21 -0
  146. package/agent-assets/task-flows/wiki.trace.md +1 -1
  147. package/bin/aitne.mjs +45 -11
  148. package/package.json +4 -4
  149. package/scripts/commands/doctor.mjs +11 -2
  150. package/scripts/lib/process-identity.d.mts +46 -0
  151. package/scripts/lib/process-identity.mjs +193 -0
  152. package/scripts/lib/read-api-token.mjs +1 -1
  153. package/scripts/start.mjs +14 -4
@@ -23,7 +23,7 @@ ask_examples:
23
23
  - The auth-health pill went red, what now?
24
24
  locale: en-US
25
25
  created: 2026-04-25
26
- updated: 2026-05-28
26
+ updated: 2026-06-07
27
27
  keywords:
28
28
  - auth failed
29
29
  - auth error
@@ -60,8 +60,8 @@ api_endpoints:
60
60
  on a healthy install. Re-paste the key on `/settings/models`.
61
61
  2. **Subscription-fallback login expired** when no API key was
62
62
  registered (the daemon was running on the CLI's local login —
63
- `claude`, `codex login`, `gemini auth` — and that session timed
64
- out). The recommended fix is to register an API key.
63
+ `claude auth login`, `codex login`, `gemini` — and that session
64
+ timed out). The recommended fix is to register an API key.
65
65
  3. **Account-level scope change** at the provider (key disabled,
66
66
  project deleted, billing suspended). For cloud-provider auth
67
67
  (Bedrock / Vertex / Foundry for Claude, Vertex AI for Gemini),
@@ -87,13 +87,14 @@ re-probes immediately — no restart needed.
87
87
  **If the backend is on the subscription fallback:** the recommended
88
88
  fix is to register an API key on `/settings/models`. The same picker
89
89
  also exposes cloud-provider auth — Bedrock / Vertex / Foundry for
90
- Claude, Vertex AI for Gemini. (Codex Azure OpenAI is not offered here;
91
- it needs a `~/.codex/config.toml` the env-mirroring path cannot write,
92
- so Codex stays direct-key only.)
90
+ Claude, Vertex AI for Gemini, and Azure OpenAI for Codex. (Codex Azure
91
+ OpenAI needs a `config.toml` in addition to env vars; the daemon writes
92
+ a managed one under `<dataDir>/codex-home/` and points `CODEX_HOME`
93
+ there, leaving your `~/.codex/` untouched.)
93
94
 
94
95
  If you cannot or do not want to register a key, re-run the
95
- corresponding CLI login (`claude`, `codex login`, `gemini auth`) and
96
- the daemon picks up the new credentials on the next probe. Some
96
+ corresponding CLI login (`claude auth login`, `codex login`, `gemini`)
97
+ and the daemon picks up the new credentials on the next probe. Some
97
98
  backends also expose an in-dashboard device-code recovery flow
98
99
  (`recovery/start` → `recovery/code`) reachable from the pill's
99
100
  recovery hint. Note that subscription auth is not provider-supported
@@ -13,9 +13,8 @@ category: troubleshooting
13
13
  summary: |
14
14
  A red "Daemon degraded" banner appears above every page when the daemon
15
15
  enters degraded mode. This almost always means your Obsidian-style primary
16
- vault is unreachable (path moved, drive unplugged, or not yet seeded), or a
17
- context migration is in progress. While degraded, every context write is
18
- refused with HTTP 503.
16
+ vault is unreachable (path moved, drive unplugged, or not yet seeded). While
17
+ degraded, every context read AND write is refused with HTTP 503.
19
18
  section: troubleshooting
20
19
  status: stable
21
20
  tags:
@@ -29,7 +28,7 @@ ask_examples:
29
28
  - Why are context writes being refused with 503?
30
29
  locale: en-US
31
30
  created: 2026-04-25
32
- updated: 2026-05-28
31
+ updated: 2026-06-07
33
32
  keywords:
34
33
  - degraded
35
34
  - degraded banner
@@ -62,8 +61,10 @@ related:
62
61
  followed by the offending path.
63
62
  - An **Open Management Mode** button on the right of the banner (links to
64
63
  Settings → Management Mode).
65
- - Any routine or skill that writes a context file fails: the context API
66
- returns **HTTP 503** for every `POST`/`PUT`/`PATCH`/`DELETE` while degraded.
64
+ - Any routine or skill that touches a context file fails: while degraded the
65
+ context API returns **HTTP 503** for every request — reads (`GET`) as well as
66
+ writes (`POST`/`PUT`/`PATCH`/`DELETE`) — so the agent never reads or writes a
67
+ stale fallback location.
67
68
 
68
69
  ## What "Degraded" Actually Means
69
70
 
@@ -83,15 +84,21 @@ The `reason` in the banner is one of:
83
84
  | `primary_vault_unreachable` | The configured vault path doesn't exist, isn't a directory, or isn't writable (e.g. an external drive was unplugged). |
84
85
  | `primary_vault_not_configured` | Vault mode is Obsidian but no `primaryVaultPath` is set. |
85
86
  | `primary_vault_missing_content`| The path is reachable but doesn't carry the expected vault markers (it was never seeded / restructured). |
86
- | `migration_in_progress` | A context-vault migration (`/api/setup/migrate-context`) is running. Writes are gated until it finishes; reads still work. This one clears itself. |
87
+
88
+ A context-vault migration (`POST /api/setup/migrate-context`) is a **separate**
89
+ state, not a degraded reason — it does **not** raise this banner. During a
90
+ migration the daemon engages a context-write gate (`migration_in_progress`):
91
+ writes return HTTP 503 while reads still work, `/api/health` stays
92
+ `"status":"ok"`, and the gate clears itself when the migration finishes.
87
93
 
88
94
  ## Diagnostic Steps
89
95
 
90
96
  1. **Read the banner.** The `reason` and `path` tell you most of the story.
91
97
  2. `aitne logs` — look for `Vault health probe entered degraded mode`; the
92
98
  logged `reason` matches the banner.
93
- 3. If the reason is `migration_in_progress`, **wait** — the migration releases
94
- the write gate when it completes; do not restart mid-migration.
99
+ 3. If a context-vault migration is running (write-gate `migration_in_progress`
100
+ rather than the banner), **wait** the migration releases the write gate
101
+ when it completes; do not restart mid-migration.
95
102
  4. Otherwise the issue is your vault path. Confirm it exists and is writable:
96
103
  - `ls -ld "<path-from-banner>"` — the directory must exist.
97
104
  - `df -h "<path-from-banner>"` — confirm the volume is mounted with free
@@ -22,7 +22,7 @@ tags:
22
22
  status: stable
23
23
  locale: en-US
24
24
  created: 2026-04-25
25
- updated: 2026-05-28
25
+ updated: 2026-06-07
26
26
  keywords:
27
27
  - magic phrase
28
28
  - owner channel
@@ -85,7 +85,7 @@ All secrets are single-use and expire after **5 minutes**.
85
85
 
86
86
  ## Diagnostic steps
87
87
 
88
- 1. On `/connections/messaging`, click **Regenerate phrase** (Slack /
88
+ 1. On `/connections/messaging`, click **Generate pairing phrase** (Slack /
89
89
  Discord) or re-open the QR / deep link (Telegram / WhatsApp) so you
90
90
  start a fresh 5-minute window.
91
91
  2. For Slack / Discord, send **only** the four words — no surrounding
@@ -26,7 +26,7 @@ ask_examples:
26
26
  - Why did an autonomous run get skipped for the cost cap?
27
27
  locale: en-US
28
28
  created: 2026-04-25
29
- updated: 2026-05-28
29
+ updated: 2026-06-07
30
30
  keywords:
31
31
  - quota
32
32
  - BackendQuotaError
@@ -54,8 +54,9 @@ related:
54
54
  - Fallback ran the next routine instead of main.
55
55
  - Or: an autonomous run was skipped with reason
56
56
  `autonomous_cost_cap_exceeded` — this is a *separate* safety net
57
- (`autonomousDailyCostCapUsd` / `autonomousMonthlyCostCapUsd`,
58
- default off) that skips only autonomous work, never reactive DMs.
57
+ (`autonomousDailyCostCapUsd`, default off) that skips only autonomous
58
+ work, never reactive DMs. (`autonomousMonthlyCostCapUsd`, also default
59
+ off, is notifications-only — it never skips a run, just alerts.)
59
60
  It is not a provider quota error; raise the cap on `/settings/models`
60
61
  or wait for the next agent day.
61
62
 
@@ -92,9 +93,9 @@ related:
92
93
  account's spending / rate-limit settings. For cloud providers,
93
94
  open the matching console (AWS / GCP / Azure) and check the
94
95
  per-region / per-model quota.
95
- 4. If on the subscription fallback, the backend card shows the
96
- "next reset" timestamp for the rolling window. Consider
97
- registering an API key — see
96
+ 4. If on the subscription fallback, the `BackendQuotaError` message in
97
+ Activity carries the "next reset" timestamp for the rolling window
98
+ (when the provider reports one). Consider registering an API key — see
98
99
  [Costs and Quotas](../concepts/costs-and-quotas.md).
99
100
 
100
101
  ## Confirming the Fix
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: agent-actions
3
- description: Load when the running session needs to write structured metadata into its own `agent_actions` row so daemon-side consumers (morning-routine AgentJournalAppender, anomaly surfacing, audit log) read structured data instead of parsing prose.
3
+ description: Load near the end of a morning-routine / dispatcher session to record dayType, anomalies, inbox stats, and files-touched into your own `agent_actions` row, so daemon-side consumers (morning-routine journal appender, audit log) read structured data instead of parsing prose.
4
4
  allowed-tools:
5
5
  - Bash(curl *)
6
6
  - Read
@@ -41,7 +41,8 @@ header attachment for you — you do not type them. The endpoint returns
41
41
  if no in-flight row matches your session — typically because the row
42
42
  has already settled to a terminal `result`, or because the dispatcher
43
43
  spawned the session without the pre-insert step that the morning
44
- routine's pipeline orchestrator owns. Surface as anomaly and continue.
44
+ routine's pipeline orchestrator owns. Record it in this endpoint's
45
+ `anomalies` field (when accessible) or DM the operator, then continue.
45
46
 
46
47
  ## Metadata shape
47
48
 
@@ -51,12 +52,12 @@ The morning-routine Stage A is the primary caller. Its expected shape:
51
52
 
52
53
  | Field | Type | Purpose |
53
54
  |---|---|---|
54
- | `dayType` | `"weekday" \| "weekend" \| "focus" \| "off"` | The day-type Stage A derived. ⑥ AgentJournalAppender writes this into agent/journal.md's header line. |
55
- | `anomalies` | `string[]` | Free-form anomalies you encountered (e.g. "AgentPlan cardinality mismatch: today.md has 6 rows, batch had 5"). ⑥ surfaces these in agent/journal.md and `pnpm audit` filters on them. |
56
- | `filesTouched` | `string[]` | Paths your turn wrote to (e.g. `context/today.md`, `context/roadmap.md`). |
55
+ | `dayType` | `"weekday" \| "weekend" \| "focus" \| "off"` | The day-type Stage A derived. ⑥ AgentJournalAppender writes this into journal/agent.md's header line. |
56
+ | `anomalies` | `string[]` | Free-form anomalies you encountered (e.g. "AgentPlan cardinality mismatch: today.md has 6 rows, batch had 5"). ⑥ surfaces these in journal/agent.md. |
57
+ | `filesTouched` | `string[]` | Paths your turn wrote to (e.g. `state/today.md`, `plans/roadmap.md`). |
57
58
  | `inboxStats` | `{triaged, movedToScratch, dmConfirmsSent, secretsSkipped}` | Inbox triage counts from Step 4. All keys integers >= 0. `secretsSkipped` is collected but NOT rendered by ⑥; surface secret-skip events through `anomalies` as well so they reach the audit trail. |
58
59
  | `morningChecks` | `string[]` | Short labels for every Step 8 `policies/routines/morning.md` extension check executed (e.g. `"water bottle filled"`). ⑥ joins these with `, ` into the `Checks from routines/morning.md:` bullet. Empty array → renders as `(none)`. |
59
- | `scheduleBatchSize` | `number` | Cardinality you observed when posting to `/api/schedule/batch`. Mirrors what was POSTed so ⑥ can detect cardinality mismatches against today.md. |
60
+ | `scheduleBatchSize` | `number` | Cardinality you observed when posting to `/api/schedule/batch`. Informational metadata mirroring what was POSTed. |
60
61
 
61
62
  The endpoint accepts any well-formed JSON object — these are the keys
62
63
  the morning-routine pipeline consumes. Skills can extend the shape
@@ -71,7 +72,7 @@ curl -s -X PATCH http://localhost:8321/api/agent-actions/self \
71
72
  "metadata": {
72
73
  "dayType": "weekday",
73
74
  "anomalies": [],
74
- "filesTouched": ["context/today.md", "context/roadmap.md"],
75
+ "filesTouched": ["state/today.md", "plans/roadmap.md"],
75
76
  "inboxStats": { "triaged": 4, "movedToScratch": 4, "dmConfirmsSent": 1, "secretsSkipped": 0 },
76
77
  "morningChecks": ["water bottle filled", "calendar synced"],
77
78
  "scheduleBatchSize": 5
@@ -86,37 +87,20 @@ Success (200):
86
87
 
87
88
  ## Errors
88
89
 
89
- Every error response uses the **agent-consumable envelope**:
90
-
91
- ```jsonc
92
- {
93
- "ok": false,
94
- "summary": "Request rejected: agent_actions.session_identity_missing on headers.x-pa-event-correlation-id.",
95
- "errors": [
96
- {
97
- "rowIndex": null,
98
- "code": "agent_actions.session_identity_missing",
99
- "field": "headers.x-pa-event-correlation-id",
100
- "received": "<missing>",
101
- "expected": "x-pa-event-correlation-id and x-process-key headers identifying the running session",
102
- "hint": "The pa-api shim auto-injects these from PA_EVENT_CORRELATION_ID and PA_PROCESS_KEY when running inside a dispatcher-spawned session.",
103
- "skillAnchor": "agent-actions#self-write-auth",
104
- "severity": "error"
105
- }
106
- ],
107
- "retryable": false
108
- }
109
- ```
90
+ Failures return an agent-consumable envelope (`ok:false`) carrying a
91
+ `code`, a `hint`, and a `skillAnchor` back into this skill. The two
92
+ session-state codes below are `retryable:false` — do NOT re-fire; record
93
+ the failure in this endpoint's `anomalies` field (when accessible) or DM
94
+ the operator, then continue. A malformed-body code is retryable — fix the
95
+ body and resend.
110
96
 
111
- ### Codes the endpoint can emit
97
+ Two codes reflect session state you must reason about:
112
98
 
113
- | Code | When | Fix |
114
- |---|---|---|
115
- | `agent_actions.session_identity_missing` | `x-pa-event-correlation-id` or `x-process-key` header is absent / empty. | Running inside a dispatcher-spawned session the pa-api shim attaches both headers from env. If you see this, the session is misconfigured — surface it as an anomaly via `<safety_violation>` and stop. Not retryable in the same turn. |
116
- | `agent_actions.session_row_not_found` | No in-flight `agent_actions` row matches `(event_id, action_type)`. | Either the row has already settled to a terminal result (success/failed/partial) and your PATCH arrived late, or the dispatcher spawned this session without the orchestrator-side pre-insert that the morning-routine pipeline relies on. Either way, the PATCH cannot land — surface as anomaly and continue. Not retryable. |
117
- | `agent_actions.body_not_object` | Request body is not a JSON object. | POST `{"metadata":{…}}`. |
118
- | `agent_actions.metadata_field_invalid` | `metadata` slot is missing, not an object, an array, or carries non-JSON-serialisable values (functions, Symbols, BigInts). | Pass a plain JSON object literal. Arrays go inside named keys (e.g. `anomalies:[…]`). |
119
-
120
- `retryable:false` means the agent should NOT retry the same call; it
121
- should surface the failure as a structured anomaly (via this endpoint's
122
- `anomalies` field when accessible) or DM the operator.
99
+ | Code | When |
100
+ |---|---|
101
+ | `agent_actions.session_identity_missing` | `x-pa-event-correlation-id` or `x-process-key` header is absent / empty the session is misconfigured. The shim normally attaches both from env. |
102
+ | `agent_actions.session_row_not_found` | No in-flight row matches `(event_id, action_type)` either the row already settled to a terminal result and your PATCH arrived late, or the dispatcher spawned the session without the orchestrator-side pre-insert. |
103
+
104
+ A malformed body fails with `agent_actions.body_not_object` (send
105
+ PATCH `{"metadata":{…}}`) or `agent_actions.metadata_field_invalid`
106
+ (pass a plain JSON object; arrays go inside named keys).
@@ -28,7 +28,10 @@ recurring DM with no autonomous work, use `dm_session` (above), not an Agent.
28
28
  ## Before creating — dedup (mandatory)
29
29
 
30
30
  1. `GET /api/agents` — does an enabled Agent already do this on this cadence? If
31
- so, do not create a duplicate (edit it via the dashboard / `PATCH /api/agents/:slug`).
31
+ so, do not create a duplicate. To edit one: `PATCH /api/agents/:slug` only
32
+ toggles `enabled` (field edits return `400 user_agent_edit_via_file`); to
33
+ change a user Agent's prompt/schedule/backend, edit its `agent.md`
34
+ (`PATCH /api/context/policies/agents/<slug>/agent.md`) or the dashboard editor.
32
35
  2. `GET /api/recurring-schedules?enabled=true` — confirm no existing recurring
33
36
  row already covers the cadence.
34
37
 
@@ -54,8 +57,12 @@ curl -s -X POST http://localhost:8321/api/agents \
54
57
  ```
55
58
 
56
59
  Fields:
57
- - **`slug`** — kebab-case, unique, immutable after creation (the `/agents/<slug>` URL).
58
- - **`name`**, **`description`** human labels shown in the dashboard.
60
+ - **`slug`** — kebab-case, must start with a lowercase letter (`^[a-z][a-z0-9-]*`),
61
+ unique, immutable after creation (the `/agents/<slug>` URL). A leading digit or
62
+ hyphen is rejected as `invalid_definition` on field `slug`.
63
+ - **`name`**, **`description`** — required human labels shown in the dashboard; an
64
+ empty/omitted `description` is rejected as `invalid_definition` on field
65
+ `description`.
59
66
  - **`schedule.kind`** — `"recurring"` (structured, preferred) or `"cron"` (raw
60
67
  expression). A `one_shot`/`event` schedule is rejected with
61
68
  `one_shot_not_supported` (use `/schedule` for one-time work). Note:
@@ -77,9 +84,11 @@ Fields:
77
84
  in the resolved timezone (`min hour day-of-month month day-of-week`). Examples:
78
85
  `0 9 * * *` (daily 09:00), `0 8 * * 1` (Mondays 08:00), `0 * * * *` (hourly at
79
86
  :00), `0 */2 * * *` (every 2 hours), `0 18 1 * *` (1st of each month 18:00).
80
- Only cron shapes that map to a recurrence are accepted: minute a single value;
81
- hour a single value or `*` / `*/N`. Sub-hourly steps (`*/30`) and hour
82
- ranges/lists are NOT representable pick one explicit cadence.
87
+ A syntactically-valid cron is accepted at create (`201`, valid row) even if it
88
+ cannot be mapped to a recurrence but a non-mappable shape (sub-hourly steps
89
+ like `*/30`, hour ranges/lists like `9-17`) is never paired and silently never
90
+ fires. Only shapes that map are actually run: minute a single value; hour a
91
+ single value or `*` / `*/N`. Pick one explicit, mappable cadence.
83
92
  - **`schedule.timezone`** — IANA zone; omit to inherit the daemon default.
84
93
  - **`backend`** — optional. `tier` is `lite`/`medium`/`high` (cost/capability knob;
85
94
  the standalone control that works). `process_key` defaults to `agent.task`;
@@ -27,21 +27,7 @@ Only the following tools are available inside this skill. Everything else is den
27
27
  | `Write` | Create the file to upload (text, markdown, CSV, JSON, YAML). |
28
28
  | `Bash(curl *)` | Issue exactly one POST to the daemon per file. |
29
29
 
30
- ### Commands that WILL be denieddo not attempt
31
-
32
- The Claude Code permission classifier blocks these patterns under `dontAsk`. Attempting them wastes a turn and confuses the user.
33
-
34
- - **Any shell expansion of an environment variable**: `$PA_TURN_TOKEN`, `$HOME`, `$(date +%Y)`, `` `whoami` `` — all auto-denied. This is why the turn token is injected by the daemon's curl wrapper instead of being passed inline (see below).
35
- - `ls /tmp/...` / `ls <absolute-path>` — absolute-path listings are auto-denied.
36
- - `cat <file>`, `head`, `tail`, `stat`, `file`, `test -f`, `echo <anything>` — none are on the allowlist.
37
- - Chained commands via `&&`, `||`, `;`, `|` — each segment is evaluated separately; any segment outside the allowlist fails the whole line.
38
- - `python3 ...`, `pandoc`, `node <script>`, `sh -c`, etc. — not on the allowlist. Binary/PDF/chart generation is out of scope for Phase 1; stick to text formats you can `Write`.
39
-
40
- If you *think* you need one of the above, the answer is to pre-compute the value in your reasoning, write it as a literal, and invoke curl once with no substitutions.
41
-
42
- ## Per-turn capability token
43
-
44
- The daemon issues a per-turn token and makes the session's curl wrapper (`.pa/bin/curl`) attach it automatically to requests to `/api/chat/outbound-attachments`. **Do not pass `X-Turn-Token` yourself** — inline `$PA_TURN_TOKEN` expansion is blocked by the permission classifier, and the wrapper already handles this for you.
30
+ - **curl with literal strings only.** No `$VAR` / `$(...)` / backticks / pipes / chained commands (`&&`, `||`, `;`, `|`) the `dontAsk` classifier silently denies them. Pre-compute any value in your reasoning and write it as a literal. The session's curl wrapper (`.pa/bin/curl`) injects `X-Turn-Token` from `PA_TURN_TOKEN` for you — never pass it yourself, and binary/PDF/chart generation (`python3`, `pandoc`, `node`) is out of scope for Phase 1; stick to text formats you can `Write`.
45
31
 
46
32
  If the turn has already ended (or no token was issued), the daemon returns HTTP 403 `missing_turn_token`. Treat that as a terminal signal, not something to retry.
47
33
 
@@ -56,21 +42,19 @@ curl -s -X POST http://localhost:8321/api/chat/outbound-attachments \
56
42
  -H "X-Filename: weekly-summary.md" \
57
43
  -H "X-Caption: Weekly summary" \
58
44
  -F "file=@/tmp/weekly-summary.md"
59
- # → {"id":"<uuid>"} on success
60
- # → {"error":"missing_turn_token"} HTTP 403
61
- # → {"error":"invalid_turn_token"} HTTP 403
62
- # → {"error":"too_large"} HTTP 400
63
- # → {"error":"disallowed_mime"} HTTP 400
64
- # → {"error":"too_many_uploads"} HTTP 429
45
+ # → {"id":"<uuid>"} HTTP 200 — success
46
+ # → 403 — turn token missing/invalid; do not retry (see Errors table)
65
47
  ```
66
48
 
49
+ Errors return the standard agent-error envelope `{ok:false,summary,errors:[{code,field,hint}],retryable,error:<code>}`. Branch on the flat `error` field (a legacy alias for the single issue code); the codes in the Errors table are accurate.
50
+
67
51
  | Header / field | Purpose |
68
52
  |---|---|
69
53
  | `file` (form field, binary) | The bytes to deliver. Stream from a file you just created with `Write`. |
70
54
  | `X-Filename` | Optional. Overrides the filename shown to the user. Literal string — no substitutions. Default: the multipart `filename` parameter. |
71
55
  | `X-Caption` | Optional. ≤ 1024 chars. Literal string — no `$(...)` / backticks. |
72
56
 
73
- > The wrapper silently adds `X-Turn-Token` from `PA_TURN_TOKEN`. Do not add it yourself. If you *do* pass `X-Turn-Token` explicitly (e.g. during local debugging), the wrapper will respect your value and not overwrite it.
57
+ > If you *do* pass `X-Turn-Token` explicitly (e.g. during local debugging), the wrapper respects your value and does not overwrite it.
74
58
 
75
59
  ### Size and type limits (Phase 1)
76
60
 
@@ -84,12 +68,9 @@ Per-turn total across all attachments is capped at **100 MB**; the endpoint retu
84
68
  ## Workflow
85
69
 
86
70
  1. Decide the filename and caption up front (literal strings — no shell interpolation).
87
- 2. Generate the content and write it with the `Write` tool. Use `/tmp/<name>` as the path only every other path (`~/`, session workdir, context dir, `/var/`, `/Users/...`) is denied by the absolute-block layer (`packages/daemon/src/safety/always-disallowed.ts`). Never write into the session workdir or the context dir.
71
+ 2. Generate the content and write it with the `Write` tool. Write scratch files under `/tmp/<name>` the session workdir is re-materialized between turns and the context dir is daemon-owned, so `/tmp` avoids collisions.
88
72
  3. Issue the single curl POST shown above. One file per call.
89
- 4. Branch on the response:
90
- - Success (`{"id": "..."}`) — mention the attachment in your reply, e.g. `"Attached: weekly-summary.md"`. You may discard the id; the daemon links it to your message automatically.
91
- - HTTP 403 (`missing_turn_token` / `invalid_turn_token`) — the turn has already been released or the skill was invoked outside a turn. Do not retry. Fall back to inline paste and tell the user the attachment could not be sent.
92
- - Other errors — follow the table below.
73
+ 4. On success (`{"id": "..."}`) mention the attachment in your reply, e.g. `"Attached: weekly-summary.md"` — you may discard the id; the daemon links it automatically. On any error, follow the Errors table below.
93
74
 
94
75
  Never base-64 embed files into your reply body. Always go through this endpoint.
95
76
 
@@ -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"}' \
@@ -178,13 +189,15 @@ write and enqueued this event.
178
189
  - Sources read (domain labels only, never URLs)
179
190
  - Open questions
180
191
  - Status (active / paused / concluded based on cluster status)
181
- 4. Write the note to:
192
+ 4. Write the note to the best available destination, in priority order
193
+ (each is a fully working target — the local path is a real write, not
194
+ a 403-doomed fallback):
182
195
  - **Obsidian** if `/api/obsidian/*` is configured: PUT to
183
196
  `<vault>/inbox/<slug>-wiki-<YYYY-MM-DD>.md`.
184
197
  - **Notion** if `/api/notion/*` is configured: create a page under
185
198
  the configured "Aitne Inbox" parent.
186
- - **Local context** otherwise:
187
- `PUT /api/context/research/<slug>-wiki.md`.
199
+ - **Local context** (`PUT /api/context/research/<slug>-wiki.md`) as the
200
+ fallback when neither knowledge destination is configured.
188
201
  5. After a successful write — and only then — POST
189
202
  `/api/browser-history/research-clusters/<slug>/wiki-written` so the
190
203
  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,14 +24,12 @@ 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,
@@ -73,26 +71,27 @@ Body:
73
71
  dropped both on 2026-05-27 (open navigation). Legacy callers passing
74
72
  them are silently ignored, not rejected.
75
73
  - `scheduleAt` (ISO 8601) — defer to later; respects quiet hours.
76
- Response is `{ status:"scheduled", scheduledFor, scheduleRowId }`.
74
+ Response is `202` with `{ taskId, status:"scheduled", scheduledFor,
75
+ scheduleRowId }` (`scheduledFor` is epoch-ms; `taskId` is the same
76
+ pre-generated id you use for status GETs).
77
77
  - `requireFinalConfirm` (default `true`) — keep `true` unless the user
78
78
  explicitly asks to skip the gate for a reversible flow.
79
79
 
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.
80
+ Immediate response carries `taskId`, `status`, and `queueState`; then ack
81
+ once and stop (Hard rule 2). If `queueState.waitingForSlot === true`, the
82
+ global cap is full — say so once ("queued behind N task(s); I'll start it
83
+ when a slot opens"). The daemon DMs the user on promote and on finish.
85
84
 
86
85
  ## Relaying a clarification — `awaiting_user`
87
86
 
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:
87
+ The daemon DMs the user a question + screenshot via the originating
88
+ channel (you do not author it, and per Hard rule 2 you do not poll for it
89
+ to appear). You act only when the user comes back with an answer:
91
90
 
92
91
  1. `GET /api/browser-task?state=awaiting_user` — find the parked task.
93
92
  Usually one; if several, match topic or ask which.
94
93
  2. `GET /api/browser-task/<taskId>` — read the open `clarifications` row
95
- (`resolved:0`) for `clarificationId`.
94
+ (`resolved:false`) for `clarificationId`.
96
95
  3. `POST /api/browser-task/<taskId>/clarify` with `{clarificationId,
97
96
  answer}` (user reply verbatim), then ack briefly and end the turn —
98
97
  the runner resumes on its own.
@@ -116,20 +115,16 @@ If (and only if) the user explicitly asks how a task is going, do a
116
115
  user names), then `GET /api/browser-task/<taskId>` and report `state`, the
117
116
  last `actionLog` entry, and `queueState` if pending. States:
118
117
 
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.
118
+ - `pending` — queued; read `queueState` for position. `running` — acting.
119
+ - `awaiting_user` / `final_confirm` — relay rules are Hard rule 3 + the
120
+ clarify section; here just report the state.
124
121
  - `completed` — the daemon already DMed the full `✅ Browser task —
125
122
  report`. Don't re-post; if asked "what did it find?", quote the
126
123
  `report` field verbatim (don't paraphrase).
127
124
  - `failed` / `timeout` / `cancelled` / `abandoned` — terminal; the daemon
128
125
  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`, …).
126
+ carries the reason (e.g. `queue_timeout`, `budget_exceeded`,
127
+ `tool_loop_detected`) — quote it verbatim.
133
128
 
134
129
  ## Force-stop — "stop" / "cancel" / "abort" / "止めて"
135
130