mercury-agent 0.24.3-beta.2 → 0.24.3-beta.3
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.
- package/docs/behavior-layers.md +12 -0
- package/docs/configuration.md +20 -10
- package/docs/goals/whatsapp-bot-hardening/open-threads.md +2 -0
- package/docs/pending-verification.md +62 -0
- package/docs/permissions.md +1 -1
- package/docs/plans/monitoring-1005/decisions.md +2 -2
- package/docs/plans/monitoring-1005/plan.md +8 -26
- package/docs/plans/tagula-client-1008/briefs/S1.md +78 -0
- package/docs/plans/tagula-client-1008/briefs/S10.md +77 -0
- package/docs/plans/tagula-client-1008/briefs/S2.md +78 -0
- package/docs/plans/tagula-client-1008/briefs/S3.md +77 -0
- package/docs/plans/tagula-client-1008/briefs/S4.md +77 -0
- package/docs/plans/tagula-client-1008/briefs/S5.md +78 -0
- package/docs/plans/tagula-client-1008/briefs/S6.md +77 -0
- package/docs/plans/tagula-client-1008/briefs/S7.md +76 -0
- package/docs/plans/tagula-client-1008/briefs/S8.md +77 -0
- package/docs/plans/tagula-client-1008/briefs/S9.md +77 -0
- package/docs/plans/tagula-client-1008/decisions.md +7 -0
- package/docs/plans/tagula-client-1008/plan.md +186 -0
- package/docs/plans/tagula-client-1008/sessions/S1.md +52 -0
- package/docs/plans/tagula-client-1008/sessions/S10.md +61 -0
- package/docs/plans/tagula-client-1008/sessions/S2.md +51 -0
- package/docs/plans/tagula-client-1008/sessions/S3.md +46 -0
- package/docs/plans/tagula-client-1008/sessions/S5.md +54 -0
- package/docs/plans/tagula-client-1008/sessions/S6.md +53 -0
- package/docs/plans/tagula-client-1008/sessions/S7.md +46 -0
- package/docs/profile-guide.md +21 -3
- package/examples/extensions/archive/README.md +15 -2
- package/examples/extensions/archive/backends/drive.ts +34 -4
- package/examples/extensions/archive/gc.ts +57 -2
- package/examples/extensions/archive/index.ts +46 -8
- package/examples/extensions/overview/actions.ts +4 -1
- package/package.json +1 -1
- package/resources/skills/recall/SKILL.md +1 -1
- package/src/adapters/whatsapp-media.ts +38 -9
- package/src/agent/container-entry.ts +43 -0
- package/src/agent/container-runner.ts +140 -33
- package/src/config-file.ts +6 -1
- package/src/config.ts +13 -0
- package/src/core/api-types.ts +6 -0
- package/src/core/api.ts +13 -1
- package/src/core/caller-token.ts +13 -3
- package/src/core/direct-send.ts +3 -1
- package/src/core/operator-alerts.ts +78 -18
- package/src/core/reply-language.ts +168 -0
- package/src/core/routes/messages.ts +13 -4
- package/src/core/runtime.ts +78 -5
- package/src/core/task-sender.ts +16 -13
- package/src/ops/shadow-snapshot.ts +20 -0
- package/src/preflight/checks/roundtrip.ts +2 -1
- package/src/storage/db.ts +105 -6
- package/src/storage/pi-auth.ts +176 -17
- package/src/types.ts +11 -8
- package/docs/plans/monitoring-1005/briefs/S10.md +0 -72
- package/docs/plans/monitoring-1005/briefs/S11.md +0 -75
- package/docs/plans/monitoring-1005/briefs/S13.md +0 -77
package/docs/behavior-layers.md
CHANGED
|
@@ -36,6 +36,13 @@ the repo, after a pi upgrade.
|
|
|
36
36
|
## Delivery ("[reply] … [/reply] — only the span inside is sent";
|
|
37
37
|
pi-jsonl-parser.ts extractReplyEnvelope honours it,
|
|
38
38
|
a reply with no markers is sent whole)
|
|
39
|
+
## Staying silent ("asked not to reply → the whole reply is
|
|
40
|
+
NO_UPDATE; never explain the silence" — unconditional,
|
|
41
|
+
chat and scheduled runs; SILENCE_REPLY, pinned to the
|
|
42
|
+
host's NO_OUTPUT_SENTINEL by tests/mercury-additions.test.ts)
|
|
43
|
+
## Reply language ("answer in the language of the message you are answering;
|
|
44
|
+
another only on request or when the space names one";
|
|
45
|
+
unconditional, explains the <reply_language> tag below)
|
|
39
46
|
## Character (heading + "Always follow it" + "only the owner can change it"
|
|
40
47
|
— unconditional, it is the reader instruction for 3c;
|
|
41
48
|
the mrctl character/prefs procedure under it
|
|
@@ -110,6 +117,9 @@ Built by `buildPrompt()` in `container-entry.ts`:
|
|
|
110
117
|
<reply_anchor>…</reply_anchor> swipe-replies only
|
|
111
118
|
<the prompt> chat message, or the task prompt, plus any
|
|
112
119
|
before_container promptAppend (e.g. a digest)
|
|
120
|
+
<reply_language>he</reply_language> host-detected language of what the person wrote
|
|
121
|
+
(runtime.ts, src/core/reply-language.ts); only for
|
|
122
|
+
a non-Latin script it can name, never stored
|
|
113
123
|
```
|
|
114
124
|
|
|
115
125
|
A scheduled task uses exactly the same assembly; its prompt row is "the
|
|
@@ -187,7 +197,9 @@ Everything else is opt-in by instruction.
|
|
|
187
197
|
| Kind of rule | Put it in | Not in |
|
|
188
198
|
|---|---|---|
|
|
189
199
|
| Who the bot is in this space, register, what it covers, sourcing and accuracy standard, formats, when it stays silent | space `AGENTS.md` | preferences (500-char blocks in the user prompt, no structure, easy to contradict) |
|
|
200
|
+
| How the bot stays silent (the `NO_UPDATE` reply, and never explaining the silence) | the platform block (`## Staying silent`, layer 2) | space `AGENTS.md` (opt-in per space: the 26 spaces that never named it explained their silence to the group) |
|
|
190
201
|
| A procedure: when it runs, what it produces, where it goes | the task prompt (`tasks/*.md` in a space profile) | `AGENTS.md` (a task prompt never repeats an editorial rule; `AGENTS.md` never describes a schedule) |
|
|
202
|
+
| Which language a reply is written in by default (the message's own) | the platform block (`## Reply language`, layer 2) + the host's `<reply_language>` tag | the Bot Character (left out of `persona.exclusive` spaces and absent on a deployment with none: 0 of 392 Tagula prompts carried it) |
|
|
191
203
|
| A one-line behavioural setting a space admin may change from chat (`language`, `timezone`) | preference | `AGENTS.md` (would need a deploy to change) |
|
|
192
204
|
| Voice that must hold across all spaces of one deployment | Bot Character | every space's `AGENTS.md` (drifts) |
|
|
193
205
|
| Deterministic business logic, credentials, anything with numbers or dates | a capability / engine / extension, returning structured facts | prompt prose ("compute the day name yourself") |
|
package/docs/configuration.md
CHANGED
|
@@ -252,18 +252,28 @@ switch gates the missed-run reports described above.
|
|
|
252
252
|
alerts:
|
|
253
253
|
enabled: true # default: true
|
|
254
254
|
cooldown_ms: 21600000 # 60000 – 604800000 (default: 6h)
|
|
255
|
+
recipients: # optional; extra audiences, in addition to the admins
|
|
256
|
+
- ops-team # a space id: every conversation linked to it
|
|
255
257
|
```
|
|
256
258
|
|
|
257
|
-
Env equivalents: **`MERCURY_ALERTS_ENABLED`**, **`MERCURY_ALERTS_COOLDOWN_MS
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
259
|
+
Env equivalents: **`MERCURY_ALERTS_ENABLED`**, **`MERCURY_ALERTS_COOLDOWN_MS`**,
|
|
260
|
+
**`MERCURY_ALERTS_RECIPIENTS`** (comma-separated).
|
|
261
|
+
|
|
262
|
+
- **Recipients** are the ids listed in `permissions.admins` (`MERCURY_ADMINS`)
|
|
263
|
+
and `dm_auto_space.admin_ids` (`MERCURY_DM_AUTO_SPACE_ADMIN_IDS`), plus every
|
|
264
|
+
entry of `alerts.recipients`. An `alerts.recipients` entry is a space id (the
|
|
265
|
+
alert goes to every conversation linked to that space, e.g. a staff group) or
|
|
266
|
+
a person id (resolved like an admin). Use it rather than adding a space id to
|
|
267
|
+
`permissions.admins`: that list also makes each entry an admin member of every
|
|
268
|
+
space. An id is alerted only when it resolves to an existing space **with a
|
|
269
|
+
linked conversation**, i.e. a chat Mercury can actually send into; an alert
|
|
270
|
+
never creates a space. An admin whose DM is also linked to a recipient space
|
|
271
|
+
is told once, through the space. With nothing reachable the alert has nowhere
|
|
272
|
+
to go — Mercury logs that fact at ERROR and leaves the cooldown unclaimed, so
|
|
273
|
+
the next failure tries again.
|
|
274
|
+
- **Startup check.** At boot Mercury logs `Operator alerts will reach no one: …`
|
|
275
|
+
at ERROR when no configured admin or recipient resolves to a deliverable
|
|
276
|
+
conversation, so the gap shows up before the first outage rather than during it.
|
|
267
277
|
- **Channel** is the ordinary adapter outbox, the same path scheduled-task
|
|
268
278
|
failures use. It carries no agent run and no LLM, so it still works when the
|
|
269
279
|
agent's own credential is what died.
|
|
@@ -423,3 +423,5 @@ carries) and the bridge forwards it — the two-line change this note predicted.
|
|
|
423
423
|
The other `isMention` site (`discord-native.ts:346`) is history fetch, not
|
|
424
424
|
ingress. 2 regression tests in `tests/discord-bridge.test.ts`. No Discord space
|
|
425
425
|
is linked on this bot, so this is verified by test, not live.
|
|
426
|
+
|
|
427
|
+
- **Deploy pending (2026-10-08):** the box runs `6ddb895`; `dev` carries `933dafa` (heartbeat locale). 118 English "⏳ Processing…" notices went out in Hebrew spaces this week. Sync with `~/sync-mercury.sh` in a gap, then confirm the next notice reads "⏳ עובד על זה…".
|
|
@@ -2360,3 +2360,65 @@ The ⏳ heartbeat now uses the space's `messages.locale`; `main`, `tel-aviv-flat
|
|
|
2360
2360
|
Host-only (`src/core/routes/links.ts`, not baked): it rides whatever restart deploys `mrctl-links-admin-commands`.
|
|
2361
2361
|
|
|
2362
2362
|
- [ ] MANUAL-VERIFY(2026-10-05): On the box that runs M1.2, the global admin creates `mrctl links create <mgmt> '*' --level read --note "probe-note" --disclosure "probe-disclosure"`. Then, in another space, ask that space's admin's bot "who can access this space?": the reply names the management space and the disclosure, and never says "probe-note". The owner's own `mrctl links list` still shows `note: probe-note`. Revoke the probe link afterwards.
|
|
2363
|
+
|
|
2364
|
+
## Plan tagula-client-1008 / S1
|
|
2365
|
+
|
|
2366
|
+
Archive shadow fix (`shadow-rehearsal-archive-reconcile-deletes-live-drive-files`). Restart-only: `src/ops/shadow-snapshot.ts` is host code, and the archive extension reaches a box as the installed snapshot that a restart refreshes. Nothing is baked into the image.
|
|
2367
|
+
|
|
2368
|
+
- [ ] MANUAL-VERIFY(2026-10-08): On the Tagula box after the restart, `grep -c orphansRefused /root/<project>/.mercury/extensions/archive/gc.ts` prints at least 1. That is the installed copy, not the repo.
|
|
2369
|
+
- [ ] MANUAL-VERIFY(2026-10-08): On the Tagula box, the next live `archive-reconcile` logs `missing=32` for `tagula-management` and no other space reports missing files. No `reconcile refused` line appears for any space; if one does, read its counts before anything else.
|
|
2370
|
+
- [ ] MANUAL-VERIFY(2026-10-08): The next shadow snapshot on a Drive-backed box: the last `MERCURY_ARCHIVE_BACKEND=` line of the shadow's `.env` is `local`, and the last `MERCURY_ARCHIVE_LOCAL_DIR=` points inside the snapshot. After `shadow up`, the shadow's journal shows `[archive] ready — backend=local (shadow: …`. The live space's Drive archive folder has the same file count before and after the rehearsal.
|
|
2371
|
+
- [ ] MANUAL-VERIFY(2026-10-08): Read the Drive activity log for the archive folder around 2026-10-08 01:21–01:26 IDT. Confirm that the deletes of the 32 `tagula-management` files came from the shadow runs. Write the result into the post-mortem.
|
|
2372
|
+
- [ ] MANUAL-VERIFY(2026-10-08): Recover the 32 lost `tagula-management` files on the box (read-only listing of the Drive folder against the manifest hashes, then rebuild from the space folder, `backups/` and other Drive copies by hash). Afterwards the live reconcile reports fewer than 32 missing.
|
|
2373
|
+
|
|
2374
|
+
## Plan tagula-client-1008 / S3
|
|
2375
|
+
|
|
2376
|
+
`oauth-token-handed-to-container-can-expire-or-be-rotated-mid-run`: restart only (`src/storage/pi-auth.ts` and `src/agent/container-runner.ts` are host-side, not baked).
|
|
2377
|
+
|
|
2378
|
+
- [ ] MANUAL-VERIFY(2026-10-08): After the restart that deploys this, on each bot (both run on the long-lived `MERCURY_ANTHROPIC_OAUTH_TOKEN`): the next turn succeeds, and `journalctl --user -u mercury --since <restart>` has **no** `Refreshing anthropic oauth token ahead of expiry` and no `running consumer(s) still hold it` lines. The env token must bypass `auth.json` entirely.
|
|
2379
|
+
|
|
2380
|
+
## Plan tagula-client-1008 / S5
|
|
2381
|
+
|
|
2382
|
+
- [ ] MANUAL-VERIFY(2026-10-08): After the Tagula box runs this fix, the owner adds `alerts: { recipients: [tagula-management] }` to `mercury.yaml` (restart needed: config is read at startup). The journal after the restart has `Operator alerts have a delivery path recipients=1` (or more), not `Operator alerts will reach no one`.
|
|
2383
|
+
- [ ] MANUAL-VERIFY(2026-10-08): The next operator alert on the Tagula box (credential failure, extension task failure, partial delivery) arrives in the `tagula-management` WhatsApp group, and the journal shows `Operator alerted` / `Credential failure alerted to operators`, not `could not tell an operator`.
|
|
2384
|
+
- [ ] MANUAL-VERIFY(2026-10-08): On this box (`~/whatsapp-bot`), after the next restart the journal has `Operator alerts have a delivery path`. If it says `will reach no one` instead, the owner's DM is not linked to a space here either.
|
|
2385
|
+
|
|
2386
|
+
## Plan tagula-client-1008 / S6
|
|
2387
|
+
|
|
2388
|
+
`mrctl-recall-is-gated-on-the-compact-permission`: host-only (`src/core/routes/messages.ts`) plus the recall skill, which is re-copied at startup. A restart deploys it on each box.
|
|
2389
|
+
|
|
2390
|
+
- [ ] MANUAL-VERIFY(2026-10-08): After the restart on the Tagula box, a client (a `member`) asks the bot about something from an earlier article. The host log for that run has no `Permission denied … permission=compact` (or `=prompt`) line, and the trace shows `mrctl recall` returning messages, not a 403. Grep the installed skill: `grep -c "Requires \`prompt\`" <project>/.mercury/global/skills/recall/SKILL.md` prints 1.
|
|
2391
|
+
|
|
2392
|
+
## Plan tagula-client-1008 / S10
|
|
2393
|
+
|
|
2394
|
+
Image rebuild (`src/agent/container-entry.ts` is baked), then restart; verify the derived image is built before testing.
|
|
2395
|
+
|
|
2396
|
+
- [ ] MANUAL-VERIFY(2026-10-08): `docker run --rm --entrypoint grep <derived ext image> -c "## Staying silent" /app/src/agent/container-entry.ts` prints 1 (fix `chat-silence-sentinel-is-never-taught-so-the-model-explains-its-silence`).
|
|
2397
|
+
- [ ] MANUAL-VERIFY(2026-10-08): In a Tagula group whose `AGENTS.md` does not mention `NO_UPDATE`, one person writes to another and asks the bot not to answer: nothing is sent to the group, and the journal shows `Chat turn answered with silence` for that run.
|
|
2398
|
+
- [ ] MANUAL-VERIFY(2026-10-10): Same image: `docker run --rm --entrypoint grep <derived ext image> -c "nothing to add" /app/src/agent/container-entry.ts` prints 0, and `-c "Never use it in place of an answer"` prints 1 (fix `silence-rule-lets-the-model-drop-a-direct-answer`).
|
|
2399
|
+
- [ ] MANUAL-VERIFY(2026-10-10): In a DM, ask the bot a plain question ("did today's article go out?"): it answers, and the journal has no `Chat turn answered with silence` line for that run. Then read that line's daily count for a few days after the deploy: frequent silence means the model is dodging (D-018).
|
|
2400
|
+
|
|
2401
|
+
## Plan tagula-client-1008 / S2
|
|
2402
|
+
|
|
2403
|
+
Image rebuild (`src/agent/container-entry.ts` is baked), then restart; the host hint and the drift metric are in `src/core/runtime.ts` and go live with the restart.
|
|
2404
|
+
|
|
2405
|
+
- [ ] MANUAL-VERIFY(2026-10-10): `docker run --rm --entrypoint grep <derived ext image> -c "## Reply language" /app/src/agent/container-entry.ts` prints 1 (fix `reply-language-drifts-to-english-on-hebrew-input`).
|
|
2406
|
+
- [ ] MANUAL-VERIFY(2026-10-10): Send the bot a Hebrew question that takes many tool calls (for example a lookup across several sites). The reply is in Hebrew, and the run's trace shows the prompt ending in `<reply_language>he</reply_language>`.
|
|
2407
|
+
- [ ] MANUAL-VERIFY(2026-10-10): In `main`, write one message in English: the reply is in English and the journal has no `Reply language drifted` line for it.
|
|
2408
|
+
- [ ] MANUAL-VERIFY(2026-10-10): A week after the deploy, count `Reply language drifted` lines in the journal against the Hebrew-input runs. Close or act on `docs/bugs/reply-language-drift-gets-no-rewrite.md` from that number.
|
|
2409
|
+
- [ ] MANUAL-VERIFY(2026-10-10): On the Tagula box, after its next deploy: the same count, by space (aggregate only). Before the fix it was 25 of 168.
|
|
2410
|
+
|
|
2411
|
+
## mrctl recall scoped to the run's conversation (`2f5b62b` + `mrctl-recall-scope-admits-legacy-and-departed-conversation-rows` + `mrctl-recall-space-level-rows-ignore-who-actually-received-them`, local `dev`, unpushed 2026-10-09)
|
|
2412
|
+
|
|
2413
|
+
- [ ] MANUAL-VERIFY(2026-10-09): Push local `dev` to `origin/dev` once the owner approves. It carries `a1b11d9` (recall opened to members) together with its fixes `2f5b62b`, the `mrctl-recall-scope-admits-legacy-and-departed-conversation-rows` squash and the `mrctl-recall-space-level-rows-ignore-who-actually-received-them` squash; push all four together or not at all.
|
|
2414
|
+
- [ ] MANUAL-VERIFY(2026-10-09): Deploy is **not** restart-only. (1) `src/types.ts` is a baked file (a type-only edit, but release-gate §1 classes it as image): rebuild with `container/build.sh`, then restart. (2) `searchMessages` changed its positional signature, and `overview` is not in `src/extensions/catalog.ts`, so a restart does not refresh an installed copy. An old `actions.ts` passes `limit` as the scope: it fails closed, but the operator search quietly breaks. Wherever `overview` is installed (likely the Tagula box; not on this box), refresh it and check: `grep -c "q, null, limit" <project>/.mercury/extensions/overview/actions.ts` prints 1.
|
|
2415
|
+
- [ ] MANUAL-VERIFY(2026-10-09): After the deploy, in a space with a group and a **non-silent** task: let one scheduled post go out, then as a member in that group ask the bot to recall a word from it. It should find it. `SELECT count(*) FROM message_deliveries` is above 0.
|
|
2416
|
+
- [ ] MANUAL-VERIFY(2026-10-09): Same box, a space with a **silent** task that has run since the deploy: as a member, ask the bot to recall a word from that task's output. It should find nothing.
|
|
2417
|
+
- [ ] MANUAL-VERIFY(2026-10-09): Scheduled posts sent **before** this deploy have no delivery record, so members can no longer recall them. This is the accepted cost of failing closed, not a regression.
|
|
2418
|
+
- [ ] MANUAL-VERIFY(2026-10-09): After the deploy, in a space linking an admin DM and a group: the admin first writes a made-up word in the DM (it must be written **after** the deploy; a pre-2026-09-12 word would pass or fail for the wrong reason). Then, as a member in the group, ask the bot to recall that word. It should find nothing. Then ask for a word said in the group after the deploy; it should find it.
|
|
2419
|
+
- [ ] MANUAL-VERIFY(2026-10-09): Same space, as a member in the group, ask the bot to recall a word that appears only in the admin's DM from **before** 2026-09-12 (`SELECT content FROM messages WHERE space_id='<space>' AND conversation IS NULL AND role='user' LIMIT 5` finds one). It should find nothing.
|
|
2420
|
+
|
|
2421
|
+
## Plan tagula-client-1008 / S7
|
|
2422
|
+
|
|
2423
|
+
- [ ] MANUAL-VERIFY(2026-10-10): On a console box (Tagula), in a space whose Anthropic grant was revoked: send one message. The user should get the "session expired / reconnect" reply, not "Something went wrong", and the operator should get one 🚨 DM naming `MERCURY_ANTHROPIC_OAUTH_TOKEN (console credential blob)`. A second message within the cooldown should send no second DM.
|
|
2424
|
+
- [ ] MANUAL-VERIFY(2026-10-10): After reconnecting in the console, the next message should get a normal answer, and a later revoke should alert again without waiting for the cooldown.
|
package/docs/permissions.md
CHANGED
|
@@ -36,7 +36,7 @@ Custom roles can be created by assigning permissions to any role name.
|
|
|
36
36
|
|
|
37
37
|
| Permission | Description |
|
|
38
38
|
|------------|-------------|
|
|
39
|
-
| `prompt` | Send messages to the assistant |
|
|
39
|
+
| `prompt` | Send messages to the assistant, and let it search the stored history its run already sees (`mrctl recall`, `GET /api/messages/search`): in a space linking several conversations, the run's own conversation plus the space's own rows, never another conversation or a scheduled-task prompt |
|
|
40
40
|
| `stop` | Abort running agent and clear queue |
|
|
41
41
|
| `compact` | Reset session boundary (fresh context) |
|
|
42
42
|
| `tasks.list` | View scheduled tasks |
|
|
@@ -6,5 +6,5 @@
|
|
|
6
6
|
|----|--------|----------|---------|--------|----------|
|
|
7
7
|
| Q1 | S1 | Do you approve the Goal of `docs/backlog/healthchecks-whatsapp-relay.md` (Phase 1: one DM per real up/down transition of a Tagula healthchecks.io check, sent through the home bot's `/api/send`; no reminders; the home project is not covered)? `/f-feature-planning` on a backlog doc goes straight to Architecture. | approve / feedback: … | | |
|
|
8
8
|
| Q2 | S5 | Which Telegram bot does the daily digest send through: the one healthchecks.io already uses, or a new dedicated bot? A new token is a secret, and it must be mirrored into a gitignored local file in the same sitting (global secrets rule). | reuse / new | | |
|
|
9
|
-
| Q3 | S13 | Lane: does Avishai Tsabari own `src/core/runtime.ts` (landed commits in the last 14 d, none in flight)? | ours / theirs / split | | |
|
|
10
|
-
| Q4 | S11 | Lane: does Avishai Tsabari own `src/agent/container-entry.ts` (landed commits in the last 14 d, none in flight)? | ours / theirs / split | | |
|
|
9
|
+
| Q3 | S13 | Lane: does Avishai Tsabari own `src/core/runtime.ts` (landed commits in the last 14 d, none in flight)? | ours / theirs / split | moot — S13 moved to plan tagula-client-1008 with `--drop`; the lane is measured there (no open PR, no live branch in the file; Avishai's last edits landed) | 2026-10-08 (Claude, on the owner's instruction to decide) |
|
|
10
|
+
| Q4 | S11 | Lane: does Avishai Tsabari own `src/agent/container-entry.ts` (landed commits in the last 14 d, none in flight)? | ours / theirs / split | moot — S11 moved to plan tagula-client-1008 with `--drop`; the lane is measured there (no open PR, no live branch in the file; Avishai's last edits landed) | 2026-10-08 (Claude, on the owner's instruction to decide) |
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Plan: monitoring-1005
|
|
2
2
|
|
|
3
3
|
**Status**: Active
|
|
4
|
-
**Created**: 2026-10-05 **Last updated**: 2026-10-
|
|
4
|
+
**Created**: 2026-10-05 **Last updated**: 2026-10-08
|
|
5
5
|
**Landing mode**: pr
|
|
6
6
|
**Max width**: 4
|
|
7
7
|
**Inputs**: build monitoring — live-bot failure monitoring: healthchecks-whatsapp-relay, box-watchdog, run-outcome-counters, operator-alert-ping-mirror, daily-ops-digest-via-telegram, space-probe-harness addendum, and bugs whatsapp-messages-sent-while-offline-are-dropped-forever, queued-whatsapp-send-is-reported-as-delivered, health-reports-every-adapter-as-up, whatsapp-logged-out-socket-leaves-the-process-up-and-mute, console-oauth-invalid-grant-reaches-no-operator, third-party-apps-400-is-retried-and-shown-as-try-again, service-unit-never-restarts-a-hung-process, scheduled-run-over-cloud-quota-posts-the-quota-text-as-output
|
|
@@ -26,10 +26,7 @@
|
|
|
26
26
|
| S7 | bug | queued-whatsapp-send-is-reported-as-delivered | docs/bugs/queued-whatsapp-send-is-reported-as-delivered.md | /f-bug-fix queued-whatsapp-send-is-reported-as-delivered | 1 | — |
|
|
27
27
|
| S8 | bug | whatsapp-logged-out-socket-leaves-the-process-up-and-mute | docs/bugs/whatsapp-logged-out-socket-leaves-the-process-up-and-mute.md | /f-bug-fix whatsapp-logged-out-socket-leaves-the-process-up-and-mute | 2 | — |
|
|
28
28
|
| S9 | bug | whatsapp-messages-sent-while-offline-are-dropped-forever | docs/bugs/whatsapp-messages-sent-while-offline-are-dropped-forever.md | /f-bug-fix whatsapp-messages-sent-while-offline-are-dropped-forever | 3 | — |
|
|
29
|
-
| S10 | bug | console-oauth-invalid-grant-reaches-no-operator | docs/bugs/console-oauth-invalid-grant-reaches-no-operator.md | /f-bug-fix console-oauth-invalid-grant-reaches-no-operator | 1 | — |
|
|
30
|
-
| S11 | bug | third-party-apps-400-is-retried-and-shown-as-try-again | docs/bugs/third-party-apps-400-is-retried-and-shown-as-try-again.md | /f-bug-fix third-party-apps-400-is-retried-and-shown-as-try-again | 1 | Q4 |
|
|
31
29
|
| S12 | bug | service-unit-never-restarts-a-hung-process | docs/bugs/service-unit-never-restarts-a-hung-process.md | /f-bug-fix service-unit-never-restarts-a-hung-process | 1 | — |
|
|
32
|
-
| S13 | bug | scheduled-run-over-cloud-quota-posts-the-quota-text-as-output | docs/bugs/scheduled-run-over-cloud-quota-posts-the-quota-text-as-output.md | /f-bug-fix scheduled-run-over-cloud-quota-posts-the-quota-text-as-output | 2 | Q3 |
|
|
33
30
|
|
|
34
31
|
> Kind ∈ `feature` | `bug` | `refactor` | `plan` (a Round 0 planning session) | `story` (from `--goal`; runs `/f-feature-dev`).
|
|
35
32
|
> Needs = decision IDs from `decisions.md` that must be answered before this session may launch, or `—`.
|
|
@@ -41,12 +38,12 @@
|
|
|
41
38
|
|------|----|------|-------|
|
|
42
39
|
| S7 | S8 | start-after | file: src/adapters/whatsapp.ts (both predicted) |
|
|
43
40
|
| S8 | S9 | start-after | file: src/adapters/whatsapp.ts (both predicted) |
|
|
44
|
-
| S7 | S13 | start-after | file: src/core/task-scheduler.ts (both predicted) |
|
|
45
41
|
| S7 | S6 | merge-after | semantic: the relay treats a 2xx from /api/send as delivered, which holds only once a queued send answers 202 queued (user) |
|
|
46
42
|
|
|
47
43
|
> Kind ∈ `start-after` (To may not launch until From is landed) | `merge-after` (To may launch now, may not land until From is landed).
|
|
48
44
|
> Basis starts with `file:` (inferred from the collision map) or `semantic:` (asked) — never mixed in one row.
|
|
49
45
|
> Semantic edges: asked 2026-10-05, answer `S6 after S7`.
|
|
46
|
+
> Rebuild 2026-10-08 (`--drop S10 S11 S13`): the three moved to plan `tagula-client-1008`, which owns the files they share with its higher-priority sessions. That plan's S9 (formerly S13 here) now carries a cross-plan `start-after` edge onto this plan's S7 for `src/core/task-scheduler.ts`.
|
|
50
47
|
> S7 → S9 is implied by the chain through S8 and is not written separately.
|
|
51
48
|
|
|
52
49
|
## Rounds
|
|
@@ -60,7 +57,7 @@
|
|
|
60
57
|
| S3 | plan run-outcome-counters | — |
|
|
61
58
|
| S4 | plan operator-alert-ping-mirror | — |
|
|
62
59
|
| S5 | plan daily-ops-digest-via-telegram, after Q2 | — |
|
|
63
|
-
| — | owner answers decisions.md Q1–Q4 | S1, S5
|
|
60
|
+
| — | owner answers decisions.md Q1–Q2 (Q3, Q4 moot since 2026-10-08) | S1, S5 |
|
|
64
61
|
|
|
65
62
|
> S2–S5 are ideas, so they get planning sessions only. Their implementation sessions are planned once their Architecture exists: `--add` them in a `--rebuild`, or put them in a follow-up plan.
|
|
66
63
|
|
|
@@ -69,8 +66,6 @@
|
|
|
69
66
|
| Session | Item | Predicted surfaces (count) |
|
|
70
67
|
|---------|------|----------------------------|
|
|
71
68
|
| S7 | queued-whatsapp-send-is-reported-as-delivered | 4 |
|
|
72
|
-
| S10 | console-oauth-invalid-grant-reaches-no-operator | 1 |
|
|
73
|
-
| S11 | third-party-apps-400-is-retried-and-shown-as-try-again | 2 |
|
|
74
69
|
| S12 | service-unit-never-restarts-a-hung-process | 2 |
|
|
75
70
|
|
|
76
71
|
### Round 2
|
|
@@ -78,7 +73,6 @@
|
|
|
78
73
|
| Session | Item | Predicted surfaces (count) |
|
|
79
74
|
|---------|------|----------------------------|
|
|
80
75
|
| S8 | whatsapp-logged-out-socket-leaves-the-process-up-and-mute | 1 |
|
|
81
|
-
| S13 | scheduled-run-over-cloud-quota-posts-the-quota-text-as-output | 2 |
|
|
82
76
|
|
|
83
77
|
### Round 3
|
|
84
78
|
|
|
@@ -99,7 +93,6 @@
|
|
|
99
93
|
| File | Sessions |
|
|
100
94
|
|------|----------|
|
|
101
95
|
| src/adapters/whatsapp.ts | S7, S8, S9 |
|
|
102
|
-
| src/core/task-scheduler.ts | S7, S13 |
|
|
103
96
|
|
|
104
97
|
## Predicted surfaces
|
|
105
98
|
|
|
@@ -130,25 +123,11 @@
|
|
|
130
123
|
|
|
131
124
|
- src/adapters/whatsapp.ts
|
|
132
125
|
|
|
133
|
-
### S10
|
|
134
|
-
|
|
135
|
-
- src/agent/container-runner.ts
|
|
136
|
-
|
|
137
|
-
### S11
|
|
138
|
-
|
|
139
|
-
- src/agent/container-entry.ts
|
|
140
|
-
- src/agent/pi-failure-class.ts
|
|
141
|
-
|
|
142
126
|
### S12
|
|
143
127
|
|
|
144
128
|
- src/cli/service-unit.ts
|
|
145
129
|
- src/main.ts
|
|
146
130
|
|
|
147
|
-
### S13
|
|
148
|
-
|
|
149
|
-
- src/core/runtime.ts
|
|
150
|
-
- src/core/task-scheduler.ts
|
|
151
|
-
|
|
152
131
|
## Adjudicated overlaps
|
|
153
132
|
|
|
154
133
|
> Pre-answers for the execution commands' preflight overlap prompt. Scoped to exact branch + file pairs on branches that belong to NO active plan (a hand-opened worktree, another contributor). A branch of a sibling plan's session is never listed here — it becomes a cross-plan edge instead.
|
|
@@ -168,8 +147,8 @@
|
|
|
168
147
|
|
|
169
148
|
| File / area | Author | Basis |
|
|
170
149
|
|-------------|--------|-------|
|
|
171
|
-
| src/core/runtime.ts | Avishai Tsabari | landed commits in 14 d (`21ea163` 09-28, `b866976` 10-01, `a6aa018` 10-05); lane Q3 (S13) |
|
|
172
|
-
| src/agent/container-entry.ts | Avishai Tsabari | landed commits in 14 d; lane Q4 (S11) |
|
|
150
|
+
| src/core/runtime.ts | Avishai Tsabari | landed commits in 14 d (`21ea163` 09-28, `b866976` 10-01, `a6aa018` 10-05); lane Q3 (S13; moved to plan tagula-client-1008 on 2026-10-08) |
|
|
151
|
+
| src/agent/container-entry.ts | Avishai Tsabari | landed commits in 14 d; lane Q4 (S11; moved to plan tagula-client-1008 on 2026-10-08) |
|
|
173
152
|
| src/core/operator-alerts.ts | Avishai Tsabari | landed commits in 14 d. No session predicts it yet; S4's implementation will, so re-measure at `--rebuild` |
|
|
174
153
|
|
|
175
154
|
> Avishai's live item at build time was `host-notices-are-english-in-hebrew-spaces` (promoted to debug on `origin/dev` `200cd25`; it names `src/core/handler.ts` and `src/core/system-messages.ts`). Neither intersects this plan.
|
|
@@ -180,3 +159,6 @@
|
|
|
180
159
|
|------|--------|------|
|
|
181
160
|
| health-reports-every-adapter-as-up | the WhatsApp half is fixed on local `dev` as `6cf4ea7` (`/health` reads `getQrStatus()`), but the bug doc is still `Open` and was never archived. The rest (`queuedOutbound`, `lastCloseReason`) needs its own decision: close the doc with those fields as residuals, or narrow it. The idea `dashboard-adapter-status-is-frozen-true` (`d426fb7`) is the sibling surface. | docs/bugs/health-reports-every-adapter-as-up.md |
|
|
182
161
|
| space-probe-harness | the idea says "deliberately not now". It waits on rehearsal-bench M2.2 (`simulateIngress`) and on tagula-agents settling its probe shape. The 2026-10-05 cross-bot WhatsApp probe addendum also needs S2 (box-watchdog) to exist as the reader. | docs/ideas/space-probe-harness.md |
|
|
162
|
+
| S10 console-oauth-invalid-grant-reaches-no-operator | dropped by user — moved to plan tagula-client-1008 (2026-10-08) | docs/bugs/console-oauth-invalid-grant-reaches-no-operator.md |
|
|
163
|
+
| S11 third-party-apps-400-is-retried-and-shown-as-try-again | dropped by user — moved to plan tagula-client-1008 (2026-10-08) | docs/bugs/third-party-apps-400-is-retried-and-shown-as-try-again.md |
|
|
164
|
+
| S13 scheduled-run-over-cloud-quota-posts-the-quota-text-as-output | dropped by user — moved to plan tagula-client-1008 (2026-10-08) | docs/bugs/scheduled-run-over-cloud-quota-posts-the-quota-text-as-output.md |
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# Brief S1 — A shadow rehearsal's archive reconcile deletes the live bot's archived files on Drive
|
|
2
|
+
|
|
3
|
+
**Plan**: docs/plans/tagula-client-1008/plan.md **Session**: S1 **Round**: 1 **Kind**: bug
|
|
4
|
+
**Item slug**: shadow-rehearsal-archive-reconcile-deletes-live-drive-files
|
|
5
|
+
|
|
6
|
+
> The only file this session reads from the plan. Self-contained: it never points at a sibling's brief. The `**Item slug**:` line is the key the execution commands grep for to detect that a brief is active — keep it exactly in that shape.
|
|
7
|
+
|
|
8
|
+
## Launch
|
|
9
|
+
|
|
10
|
+
/f-ops-plan work tagula-client-1008 S1
|
|
11
|
+
|
|
12
|
+
## Run
|
|
13
|
+
|
|
14
|
+
/f-bug-fix shadow-rehearsal-archive-reconcile-deletes-live-drive-files
|
|
15
|
+
|
|
16
|
+
## Owned surfaces (predicted)
|
|
17
|
+
|
|
18
|
+
- src/ops/shadow-snapshot.ts
|
|
19
|
+
- examples/extensions/archive/gc.ts
|
|
20
|
+
- examples/extensions/archive/index.ts
|
|
21
|
+
|
|
22
|
+
## Do not touch
|
|
23
|
+
|
|
24
|
+
- src/agent/container-entry.ts (owned by S2 this plan)
|
|
25
|
+
- src/core/runtime.ts (owned by S2 this plan)
|
|
26
|
+
- src/agent/container-runner.ts (owned by S3 this plan)
|
|
27
|
+
- src/storage/pi-auth.ts (owned by S3 this plan)
|
|
28
|
+
- src/agent/user-error-messages.ts (owned by S4 this plan)
|
|
29
|
+
- src/core/handler.ts (owned by S4 this plan)
|
|
30
|
+
- src/core/runtime.ts (owned by S4 this plan)
|
|
31
|
+
- src/core/system-messages.ts (owned by S4 this plan)
|
|
32
|
+
- src/core/direct-send.ts (owned by S5 this plan)
|
|
33
|
+
- src/core/operator-alerts.ts (owned by S5 this plan)
|
|
34
|
+
- src/core/permissions.ts (owned by S6 this plan)
|
|
35
|
+
- src/core/routes/messages.ts (owned by S6 this plan)
|
|
36
|
+
- src/storage/db.ts (owned by S6 this plan)
|
|
37
|
+
- src/agent/container-runner.ts (owned by S7 this plan)
|
|
38
|
+
- src/agent/container-entry.ts (owned by S8 this plan)
|
|
39
|
+
- src/agent/pi-failure-class.ts (owned by S8 this plan)
|
|
40
|
+
- src/core/runtime.ts (owned by S9 this plan)
|
|
41
|
+
- src/core/task-scheduler.ts (owned by S9 this plan)
|
|
42
|
+
|
|
43
|
+
## Edges
|
|
44
|
+
|
|
45
|
+
- start-after: none (satisfied — `next` launched you)
|
|
46
|
+
- merge-after: none
|
|
47
|
+
|
|
48
|
+
## Overlap verdicts
|
|
49
|
+
|
|
50
|
+
none
|
|
51
|
+
|
|
52
|
+
> The command's preflight overlap check treats a hit whose branch AND every shared file match a verdict line as answered (c), prints one `PLAN-PASSED(overlap): …` line, and carries it into the final report. Any other hit prompts as usual. The merge-time check is never waived.
|
|
53
|
+
|
|
54
|
+
## Decisions answered
|
|
55
|
+
|
|
56
|
+
- none
|
|
57
|
+
|
|
58
|
+
## Session notes
|
|
59
|
+
|
|
60
|
+
- Major, and it repeats on every Drive-backed rehearsal: until this lands, nobody runs `mercury shadow up` on a Drive-backed box.
|
|
61
|
+
- The doc's fix draft is defence in depth. Do all of: a shadow never runs the archive's drain or reconcile jobs (or the snapshot override points the backend at the shadow root), `reconcileSpace` refuses to delete against a missing or empty manifest or above a small fraction, and each orphan deletion is logged as it happens.
|
|
62
|
+
- The archive extension reaches the box as an installed snapshot under `.mercury/extensions/`, not through the image. Verify a deploy against the installed copy (CLAUDE.local.md Gotchas).
|
|
63
|
+
- Recovering the 32 lost `tagula-management` files and reading the Drive activity log are box work, not this session's. Write them as MANUAL-VERIFY lines.
|
|
64
|
+
|
|
65
|
+
## Ledger rules
|
|
66
|
+
|
|
67
|
+
- `docs/ROADMAP.md`: never edit. Your command writes `docs/pending-updates/shadow-rehearsal-archive-reconcile-deletes-live-drive-files.md` as usual.
|
|
68
|
+
- `docs/pending-verification.md`: append only under `## Plan tagula-client-1008 / S1`. Every live check this session cannot run goes here, in the working language, one line each.
|
|
69
|
+
- Any goal's `decisions.md`: never edit; put decisions in your log's "Siblings must know".
|
|
70
|
+
- The Tagula box is read-only from this session (CLAUDE.local.md "Tagula box"): aggregate output only, no client conversation content in any doc.
|
|
71
|
+
|
|
72
|
+
## Environment
|
|
73
|
+
|
|
74
|
+
- Read `CLAUDE.md` → Worktree Setup and Gotchas before opening the worktree. Nothing from them is copied here.
|
|
75
|
+
|
|
76
|
+
## Report
|
|
77
|
+
|
|
78
|
+
Your command's final report is appended to `docs/plans/tagula-client-1008/sessions/S1.md` by its report step (path resolved through `.claude/scripts/resolve-docs-root.sh docs/plans/probe.md` — in a public repo the plan folder lives only in the primary checkout, and an append into a missing directory must fail loudly, never create one inside the worktree). `work` verifies the append.
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# Brief S10 — the chat silence sentinel is never taught, so the model explains its silence to the group
|
|
2
|
+
|
|
3
|
+
**Plan**: docs/plans/tagula-client-1008/plan.md **Session**: S10 **Round**: 1 **Kind**: bug
|
|
4
|
+
**Item slug**: chat-silence-sentinel-is-never-taught-so-the-model-explains-its-silence
|
|
5
|
+
|
|
6
|
+
> The only file this session reads from the plan. Self-contained: it never points at a sibling's brief. The `**Item slug**:` line is the key the execution commands grep for to detect that a brief is active — keep it exactly in that shape.
|
|
7
|
+
|
|
8
|
+
## Launch
|
|
9
|
+
|
|
10
|
+
/f-ops-plan work tagula-client-1008 S10
|
|
11
|
+
|
|
12
|
+
## Run
|
|
13
|
+
|
|
14
|
+
/f-bug-fix chat-silence-sentinel-is-never-taught-so-the-model-explains-its-silence
|
|
15
|
+
|
|
16
|
+
## Owned surfaces (predicted)
|
|
17
|
+
|
|
18
|
+
- src/agent/container-entry.ts
|
|
19
|
+
- src/core/task-output.ts (read for the sentinel constant; edit only if the test needs an export)
|
|
20
|
+
|
|
21
|
+
## Do not touch
|
|
22
|
+
|
|
23
|
+
- src/ops/shadow-snapshot.ts (owned by S1 this plan)
|
|
24
|
+
- examples/extensions/archive/gc.ts (owned by S1 this plan)
|
|
25
|
+
- examples/extensions/archive/index.ts (owned by S1 this plan)
|
|
26
|
+
- src/core/runtime.ts (owned by S2, S4 and S9 this plan; the `chatSilence` branch works and is not this fix)
|
|
27
|
+
- src/agent/container-runner.ts (owned by S3 and S7 this plan)
|
|
28
|
+
- src/storage/pi-auth.ts (owned by S3 this plan)
|
|
29
|
+
- src/agent/user-error-messages.ts (owned by S4 this plan)
|
|
30
|
+
- src/core/handler.ts (owned by S4 this plan)
|
|
31
|
+
- src/core/system-messages.ts (owned by S4 this plan)
|
|
32
|
+
- src/core/direct-send.ts (owned by S5 this plan)
|
|
33
|
+
- src/core/operator-alerts.ts (owned by S5 this plan)
|
|
34
|
+
- src/core/permissions.ts (owned by S6 this plan)
|
|
35
|
+
- src/core/routes/messages.ts (owned by S6 this plan)
|
|
36
|
+
- src/storage/db.ts (owned by S6 this plan)
|
|
37
|
+
- src/agent/pi-failure-class.ts (owned by S8 this plan)
|
|
38
|
+
- src/core/task-scheduler.ts (owned by S9 this plan)
|
|
39
|
+
- `src/agent/container-entry.ts` is also predicted by S2 and S8, and both start after you (owner, 2026-10-08). Keep the change to one preamble rule and its test. Under "Siblings must know", name where the rule sits and the constant it is built from: S2's post-check runs after the silence check you teach.
|
|
40
|
+
- Not ours: `src/agent/container-entry.ts` (Avishai Tsabari, landed commits in the last 14 d). Lane Q1 answered `ours`. Re-check with `/f-ops-plan next tagula-client-1008`.
|
|
41
|
+
|
|
42
|
+
## Edges
|
|
43
|
+
|
|
44
|
+
- start-after: none (satisfied — `next` launched you)
|
|
45
|
+
- merge-after: none
|
|
46
|
+
|
|
47
|
+
## Overlap verdicts
|
|
48
|
+
|
|
49
|
+
none
|
|
50
|
+
|
|
51
|
+
> The command's preflight overlap check treats a hit whose branch AND every shared file match a verdict line as answered (c), prints one `PLAN-PASSED(overlap): …` line, and carries it into the final report. Any other hit prompts as usual. The merge-time check is never waived.
|
|
52
|
+
|
|
53
|
+
## Decisions answered
|
|
54
|
+
|
|
55
|
+
- Q1 (lane, Avishai Tsabari): ours. No open PR or live branch of his in these files except `origin/fix-group-voice-notes` (`runtime.ts`, `db.ts`, idle since 2026-09-28); the merge-time overlap check still runs.
|
|
56
|
+
|
|
57
|
+
## Session notes
|
|
58
|
+
|
|
59
|
+
- Added 2026-10-08 from Avishai's addendum to the guy-pishkin outage note (`inbox/_archive/2026-10-08-1130-…`). The fix is one platform-preamble rule: when asked not to reply, or with nothing to add, the whole reply is `NO_UPDATE`, and the reason for staying silent never goes to the chat. Build the prompt text from `NO_OUTPUT_SENTINEL` and test it against `isSilenceSentinel`, so the two spellings can't drift.
|
|
60
|
+
- Move the ownership in `docs/profile-guide.md` §Silence and `docs/behavior-layers.md`: the platform teaches the mechanism, and a profile only says when to be silent.
|
|
61
|
+
- No host-side English/first-person *drop* filter (the bug's Notes say why, measured). S2's post-check does **not** cover this leak, contrary to an earlier note: it would rewrite the explanation into Hebrew. The rule covers scheduled runs too (local task 850). A log-only narration detector is the safety net; land it here or write it down as a follow-up.
|
|
62
|
+
- `container-entry.ts` is baked into the image, so the deploy is a rebuild. The live check, one line in pending-verification: in a Tagula group, ask the bot not to answer, and confirm nothing is sent and the journal logs the chat-silence line.
|
|
63
|
+
|
|
64
|
+
## Ledger rules
|
|
65
|
+
|
|
66
|
+
- `docs/ROADMAP.md`: never edit. Your command writes `docs/pending-updates/chat-silence-sentinel-is-never-taught-so-the-model-explains-its-silence.md` as usual.
|
|
67
|
+
- `docs/pending-verification.md`: append only under `## Plan tagula-client-1008 / S10`. Every live check this session cannot run goes here, in the working language, one line each.
|
|
68
|
+
- Any goal's `decisions.md`: never edit; put decisions in your log's "Siblings must know".
|
|
69
|
+
- The Tagula box is read-only from this session (CLAUDE.local.md "Tagula box"): aggregate output only, no client conversation content in any doc.
|
|
70
|
+
|
|
71
|
+
## Environment
|
|
72
|
+
|
|
73
|
+
- Read `CLAUDE.md` → Worktree Setup and Gotchas before opening the worktree. Nothing from them is copied here.
|
|
74
|
+
|
|
75
|
+
## Report
|
|
76
|
+
|
|
77
|
+
Your command's final report is appended to `docs/plans/tagula-client-1008/sessions/S10.md` by its report step (path resolved through `.claude/scripts/resolve-docs-root.sh docs/plans/probe.md` — in a public repo the plan folder lives only in the primary checkout, and an append into a missing directory must fail loudly, never create one inside the worktree). `work` verifies the append.
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# Brief S2 — The reply drifts to English when the user writes in Hebrew
|
|
2
|
+
|
|
3
|
+
**Plan**: docs/plans/tagula-client-1008/plan.md **Session**: S2 **Round**: 2 **Kind**: bug
|
|
4
|
+
**Item slug**: reply-language-drifts-to-english-on-hebrew-input
|
|
5
|
+
|
|
6
|
+
> The only file this session reads from the plan. Self-contained: it never points at a sibling's brief. The `**Item slug**:` line is the key the execution commands grep for to detect that a brief is active — keep it exactly in that shape.
|
|
7
|
+
|
|
8
|
+
## Launch
|
|
9
|
+
|
|
10
|
+
/f-ops-plan work tagula-client-1008 S2
|
|
11
|
+
|
|
12
|
+
## Run
|
|
13
|
+
|
|
14
|
+
/f-bug-fix reply-language-drifts-to-english-on-hebrew-input
|
|
15
|
+
|
|
16
|
+
## Owned surfaces (predicted)
|
|
17
|
+
|
|
18
|
+
- src/agent/container-entry.ts
|
|
19
|
+
- src/core/runtime.ts
|
|
20
|
+
|
|
21
|
+
## Do not touch
|
|
22
|
+
|
|
23
|
+
- src/ops/shadow-snapshot.ts (owned by S1 this plan)
|
|
24
|
+
- examples/extensions/archive/gc.ts (owned by S1 this plan)
|
|
25
|
+
- examples/extensions/archive/index.ts (owned by S1 this plan)
|
|
26
|
+
- src/agent/container-runner.ts (owned by S3 this plan)
|
|
27
|
+
- src/storage/pi-auth.ts (owned by S3 this plan)
|
|
28
|
+
- src/agent/user-error-messages.ts (owned by S4 this plan)
|
|
29
|
+
- src/core/handler.ts (owned by S4 this plan)
|
|
30
|
+
- src/core/system-messages.ts (owned by S4 this plan)
|
|
31
|
+
- src/core/direct-send.ts (owned by S5 this plan)
|
|
32
|
+
- src/core/operator-alerts.ts (owned by S5 this plan)
|
|
33
|
+
- src/core/permissions.ts (owned by S6 this plan)
|
|
34
|
+
- src/core/routes/messages.ts (owned by S6 this plan)
|
|
35
|
+
- src/storage/db.ts (owned by S6 this plan)
|
|
36
|
+
- src/agent/container-runner.ts (owned by S7 this plan)
|
|
37
|
+
- src/agent/pi-failure-class.ts (owned by S8 this plan)
|
|
38
|
+
- src/core/task-scheduler.ts (owned by S9 this plan)
|
|
39
|
+
- `src/agent/container-entry.ts` is also predicted by S10 and S8. S10 landed before you (one silence rule in the same preamble): rebase, read its "Siblings must know", and place your rule beside it. S8 starts after you; list any rename under "Siblings must know".
|
|
40
|
+
- `src/core/runtime.ts` is also predicted by S4, S9. The file edges order you; stay inside your bug's region and list any rename under "Siblings must know".
|
|
41
|
+
- Not ours: `src/agent/container-entry.ts` (Avishai Tsabari, landed commits in the last 14 d); `src/core/runtime.ts` (Avishai Tsabari, landed commits in the last 14 d). Lane Q1 answered `ours`. Re-check with `/f-ops-plan next tagula-client-1008`.
|
|
42
|
+
|
|
43
|
+
## Edges
|
|
44
|
+
|
|
45
|
+
- start-after: S10 — satisfied, `next` launched you
|
|
46
|
+
- merge-after: none
|
|
47
|
+
|
|
48
|
+
## Overlap verdicts
|
|
49
|
+
|
|
50
|
+
none
|
|
51
|
+
|
|
52
|
+
> The command's preflight overlap check treats a hit whose branch AND every shared file match a verdict line as answered (c), prints one `PLAN-PASSED(overlap): …` line, and carries it into the final report. Any other hit prompts as usual. The merge-time check is never waived.
|
|
53
|
+
|
|
54
|
+
## Decisions answered
|
|
55
|
+
|
|
56
|
+
- Q1 (lane, Avishai Tsabari): ours. No open PR or live branch of his in these files except `origin/fix-group-voice-notes` (`runtime.ts`, `db.ts`, idle since 2026-09-28); the merge-time overlap check still runs.
|
|
57
|
+
|
|
58
|
+
## Session notes
|
|
59
|
+
|
|
60
|
+
- Read `docs/profile-guide.md`, `docs/behavior-layers.md` and `docs/skills-guide.md` before changing any prompt layer (CLAUDE.md Conventions). The doc argues the rule is a platform rule, so it belongs in the preamble, plus a host-side reply-language hint placed after the user's text.
|
|
61
|
+
- `src/agent/container-entry.ts` is baked into the agent image, so the deploy is an image rebuild, not a restart. Say so in `Deploy needs:`.
|
|
62
|
+
- The post-check judges each message's language, not the space's, and never rewrites a reply that explains why the bot is silent (it runs after the `NO_UPDATE` check). Both constraints and their evidence are in the bug doc's Notes, added 2026-10-08.
|
|
63
|
+
- S4 and S9 start after you on `runtime.ts`, and S8 on `container-entry.ts`. Keep your `runtime.ts` change to the message-assembly region, and list any helper you move under "Siblings must know".
|
|
64
|
+
|
|
65
|
+
## Ledger rules
|
|
66
|
+
|
|
67
|
+
- `docs/ROADMAP.md`: never edit. Your command writes `docs/pending-updates/reply-language-drifts-to-english-on-hebrew-input.md` as usual.
|
|
68
|
+
- `docs/pending-verification.md`: append only under `## Plan tagula-client-1008 / S2`. Every live check this session cannot run goes here, in the working language, one line each.
|
|
69
|
+
- Any goal's `decisions.md`: never edit; put decisions in your log's "Siblings must know".
|
|
70
|
+
- The Tagula box is read-only from this session (CLAUDE.local.md "Tagula box"): aggregate output only, no client conversation content in any doc.
|
|
71
|
+
|
|
72
|
+
## Environment
|
|
73
|
+
|
|
74
|
+
- Read `CLAUDE.md` → Worktree Setup and Gotchas before opening the worktree. Nothing from them is copied here.
|
|
75
|
+
|
|
76
|
+
## Report
|
|
77
|
+
|
|
78
|
+
Your command's final report is appended to `docs/plans/tagula-client-1008/sessions/S2.md` by its report step (path resolved through `.claude/scripts/resolve-docs-root.sh docs/plans/probe.md` — in a public repo the plan folder lives only in the primary checkout, and an append into a missing directory must fail loudly, never create one inside the worktree). `work` verifies the append.
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# Brief S3 — OAuth access token handed to a container can expire or be rotated mid-run
|
|
2
|
+
|
|
3
|
+
**Plan**: docs/plans/tagula-client-1008/plan.md **Session**: S3 **Round**: 1 **Kind**: bug
|
|
4
|
+
**Item slug**: oauth-token-handed-to-container-can-expire-or-be-rotated-mid-run
|
|
5
|
+
|
|
6
|
+
> The only file this session reads from the plan. Self-contained: it never points at a sibling's brief. The `**Item slug**:` line is the key the execution commands grep for to detect that a brief is active — keep it exactly in that shape.
|
|
7
|
+
|
|
8
|
+
## Launch
|
|
9
|
+
|
|
10
|
+
/f-ops-plan work tagula-client-1008 S3
|
|
11
|
+
|
|
12
|
+
## Run
|
|
13
|
+
|
|
14
|
+
/f-bug-fix oauth-token-handed-to-container-can-expire-or-be-rotated-mid-run
|
|
15
|
+
|
|
16
|
+
## Owned surfaces (predicted)
|
|
17
|
+
|
|
18
|
+
- src/agent/container-runner.ts
|
|
19
|
+
- src/storage/pi-auth.ts
|
|
20
|
+
|
|
21
|
+
## Do not touch
|
|
22
|
+
|
|
23
|
+
- src/ops/shadow-snapshot.ts (owned by S1 this plan)
|
|
24
|
+
- examples/extensions/archive/gc.ts (owned by S1 this plan)
|
|
25
|
+
- examples/extensions/archive/index.ts (owned by S1 this plan)
|
|
26
|
+
- src/agent/container-entry.ts (owned by S2 this plan)
|
|
27
|
+
- src/core/runtime.ts (owned by S2 this plan)
|
|
28
|
+
- src/agent/user-error-messages.ts (owned by S4 this plan)
|
|
29
|
+
- src/core/handler.ts (owned by S4 this plan)
|
|
30
|
+
- src/core/runtime.ts (owned by S4 this plan)
|
|
31
|
+
- src/core/system-messages.ts (owned by S4 this plan)
|
|
32
|
+
- src/core/direct-send.ts (owned by S5 this plan)
|
|
33
|
+
- src/core/operator-alerts.ts (owned by S5 this plan)
|
|
34
|
+
- src/core/permissions.ts (owned by S6 this plan)
|
|
35
|
+
- src/core/routes/messages.ts (owned by S6 this plan)
|
|
36
|
+
- src/storage/db.ts (owned by S6 this plan)
|
|
37
|
+
- src/agent/container-entry.ts (owned by S8 this plan)
|
|
38
|
+
- src/agent/pi-failure-class.ts (owned by S8 this plan)
|
|
39
|
+
- src/core/runtime.ts (owned by S9 this plan)
|
|
40
|
+
- src/core/task-scheduler.ts (owned by S9 this plan)
|
|
41
|
+
- `src/agent/container-runner.ts` is also predicted by S7. The file edges order you; stay inside your bug's region and list any rename under "Siblings must know".
|
|
42
|
+
|
|
43
|
+
## Edges
|
|
44
|
+
|
|
45
|
+
- start-after: none (satisfied — `next` launched you)
|
|
46
|
+
- merge-after: none
|
|
47
|
+
|
|
48
|
+
## Overlap verdicts
|
|
49
|
+
|
|
50
|
+
none
|
|
51
|
+
|
|
52
|
+
> The command's preflight overlap check treats a hit whose branch AND every shared file match a verdict line as answered (c), prints one `PLAN-PASSED(overlap): …` line, and carries it into the final report. Any other hit prompts as usual. The merge-time check is never waived.
|
|
53
|
+
|
|
54
|
+
## Decisions answered
|
|
55
|
+
|
|
56
|
+
- none
|
|
57
|
+
|
|
58
|
+
## Session notes
|
|
59
|
+
|
|
60
|
+
- Fix Mercury's half (a), the spawn path with no expiry margin. The second refresher (b), the kulmus helper on the Tagula box, lives outside this repo. Say in the report what the box side must change.
|
|
61
|
+
- Mind the trap the doc names: refreshing early rotates the chain and revokes the token any in-flight run holds. Prove whether Anthropic revokes on refresh before relying on it. A mid-run 401 retry that re-reads the host's current token (Avishai's request 1) also covers that case.
|
|
62
|
+
- S7 starts after you on `container-runner.ts`. Name anything you rename in `refreshAnthropicOAuth`'s area under "Siblings must know".
|
|
63
|
+
|
|
64
|
+
## Ledger rules
|
|
65
|
+
|
|
66
|
+
- `docs/ROADMAP.md`: never edit. Your command writes `docs/pending-updates/oauth-token-handed-to-container-can-expire-or-be-rotated-mid-run.md` as usual.
|
|
67
|
+
- `docs/pending-verification.md`: append only under `## Plan tagula-client-1008 / S3`. Every live check this session cannot run goes here, in the working language, one line each.
|
|
68
|
+
- Any goal's `decisions.md`: never edit; put decisions in your log's "Siblings must know".
|
|
69
|
+
- The Tagula box is read-only from this session (CLAUDE.local.md "Tagula box"): aggregate output only, no client conversation content in any doc.
|
|
70
|
+
|
|
71
|
+
## Environment
|
|
72
|
+
|
|
73
|
+
- Read `CLAUDE.md` → Worktree Setup and Gotchas before opening the worktree. Nothing from them is copied here.
|
|
74
|
+
|
|
75
|
+
## Report
|
|
76
|
+
|
|
77
|
+
Your command's final report is appended to `docs/plans/tagula-client-1008/sessions/S3.md` by its report step (path resolved through `.claude/scripts/resolve-docs-root.sh docs/plans/probe.md` — in a public repo the plan folder lives only in the primary checkout, and an append into a missing directory must fail loudly, never create one inside the worktree). `work` verifies the append.
|