mercury-agent 0.24.2-beta.0 → 0.24.2
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/README.md +1 -1
- package/docs/auth/whatsapp.md +6 -4
- package/docs/configuration.md +5 -0
- package/docs/container-lifecycle.md +2 -2
- package/docs/goals/rehearsal-bench/roadmap.md +1 -1
- package/docs/goals/space-links/roadmap.md +1 -1
- package/docs/live-testing.md +34 -3
- package/docs/pending-verification.md +162 -0
- package/docs/plans/{flat-0916 → archive/2026-09-28-flat-0916}/plan.md +4 -4
- package/docs/plans/archive/2026-10-02-media-bugs-0928/briefs/S1.md +59 -0
- package/docs/plans/archive/2026-10-02-media-bugs-0928/briefs/S2.md +64 -0
- package/docs/plans/archive/2026-10-02-media-bugs-0928/briefs/S3.md +61 -0
- package/docs/plans/archive/2026-10-02-media-bugs-0928/decisions.md +6 -0
- package/docs/plans/archive/2026-10-02-media-bugs-0928/plan.md +111 -0
- package/docs/plans/archive/2026-10-02-media-bugs-0928/sessions/S1.md +34 -0
- package/docs/plans/archive/2026-10-02-media-bugs-0928/sessions/S2.md +43 -0
- package/docs/plans/archive/2026-10-02-media-bugs-0928/sessions/S3.md +35 -0
- package/docs/plans/{sensitive-bugs-0922 → archive/2026-10-02-sensitive-bugs-0922}/plan.md +2 -2
- package/docs/plans/archive/2026-10-02-sensitive-bugs-0922/sessions/S1.md +35 -0
- package/docs/plans/archive/2026-10-02-sensitive-bugs-0922/sessions/S2.md +30 -0
- package/docs/plans/archive/2026-10-02-sensitive-bugs-0922/sessions/S3.md +39 -0
- package/docs/plans/archive/2026-10-02-sensitive-bugs-0922/sessions/S4.md +38 -0
- package/docs/plans/archive/2026-10-02-sensitive-bugs-0922/sessions/S5.md +37 -0
- package/docs/plans/general-0928/briefs/S1.md +66 -0
- package/docs/plans/general-0928/briefs/S2.md +64 -0
- package/docs/plans/general-0928/briefs/S3.md +58 -0
- package/docs/plans/general-0928/briefs/S4.md +58 -0
- package/docs/plans/general-0928/briefs/S5.md +58 -0
- package/docs/plans/general-0928/decisions.md +8 -0
- package/docs/plans/general-0928/plan.md +107 -0
- package/docs/plans/search-bugs-0930/briefs/S1.md +73 -0
- package/docs/plans/search-bugs-0930/briefs/S2.md +75 -0
- package/docs/plans/search-bugs-0930/briefs/S3.md +77 -0
- package/docs/plans/search-bugs-0930/briefs/S4.md +75 -0
- package/docs/plans/search-bugs-0930/briefs/S5.md +74 -0
- package/docs/plans/search-bugs-0930/briefs/S6.md +77 -0
- package/docs/plans/search-bugs-0930/decisions.md +8 -0
- package/docs/plans/search-bugs-0930/plan.md +165 -0
- package/docs/plans/search-bugs-0930/sessions/S1.md +28 -0
- package/docs/plans/search-bugs-0930/sessions/S2.md +27 -0
- package/docs/plans/search-bugs-0930/sessions/S3.md +40 -0
- package/docs/plans/search-bugs-0930/sessions/S5.md +39 -0
- package/docs/plans/search-bugs-0930/sessions/S6.md +37 -0
- package/docs/plans/search-quality-0930/briefs/S12.md +69 -0
- package/docs/plans/search-quality-0930/briefs/S7.md +76 -0
- package/docs/plans/search-quality-0930/briefs/S9.md +68 -0
- package/docs/plans/search-quality-0930/decisions.md +11 -0
- package/docs/plans/search-quality-0930/plan.md +107 -0
- package/docs/plans/unattended-1003/briefs/S1.md +92 -0
- package/docs/plans/unattended-1003/briefs/S2.md +92 -0
- package/docs/plans/unattended-1003/briefs/S3.md +90 -0
- package/docs/plans/unattended-1003/briefs/S4.md +92 -0
- package/docs/plans/unattended-1003/briefs/S5.md +92 -0
- package/docs/plans/unattended-1003/briefs/S6.md +94 -0
- package/docs/plans/unattended-1003/briefs/S7.md +92 -0
- package/docs/plans/unattended-1003/briefs/S8.md +90 -0
- package/docs/plans/unattended-1003/briefs/S9.md +92 -0
- package/docs/plans/unattended-1003/decisions.md +7 -0
- package/docs/plans/unattended-1003/plan.md +153 -0
- package/docs/scheduler.md +5 -1
- package/docs/web-search.md +13 -7
- package/examples/extensions/napkin/distill-input.ts +27 -6
- package/examples/extensions/napkin/prompts/kb-distillation.md +3 -1
- package/examples/extensions/pinchtab/bin/pinchtab_ensure +129 -0
- package/examples/extensions/pinchtab/bin/pinchtab_nav +50 -0
- package/examples/extensions/pinchtab/bin/pinchtab_session_inject.cjs +184 -0
- package/examples/extensions/pinchtab/index.ts +41 -237
- package/examples/extensions/pinchtab/skill/SKILL.md +7 -110
- package/examples/extensions/web-search/brave.ts +396 -18
- package/examples/extensions/web-search/index.ts +122 -22
- package/examples/extensions/web-search/ledger.ts +156 -0
- package/examples/extensions/web-search/skill/SKILL.md +30 -6
- package/examples/extensions/web-search/skill/references/zap.md +148 -0
- package/examples/profiles/football-reporter/config.yaml +11 -2
- package/examples/profiles/tel-aviv-flat-search/config.yaml +3 -2
- package/package.json +4 -4
- package/src/adapters/whatsapp-media.ts +262 -40
- package/src/adapters/whatsapp.ts +1 -1
- package/src/agent/container-entry.ts +348 -36
- package/src/agent/container-error.ts +39 -2
- package/src/agent/container-runner.ts +162 -23
- package/src/agent/pi-failure-class.ts +36 -6
- package/src/agent/pi-jsonl-parser.ts +151 -33
- package/src/agent/provider-auth-rejection.ts +279 -0
- package/src/agent/user-error-messages.ts +26 -0
- package/src/bridges/discord.ts +7 -0
- package/src/bridges/slack.ts +13 -1
- package/src/bridges/teams.ts +29 -16
- package/src/bridges/telegram.ts +13 -0
- package/src/bridges/whatsapp.ts +6 -0
- package/src/cli/mercury.ts +85 -0
- package/src/cli/mrctl-http.ts +67 -0
- package/src/cli/mrctl.ts +14 -12
- package/src/config.ts +5 -3
- package/src/core/api-types.ts +5 -0
- package/src/core/api.ts +9 -1
- package/src/core/auth.ts +1 -1
- package/src/core/caller-token.ts +32 -1
- package/src/core/handler.ts +11 -1
- package/src/core/media.ts +216 -16
- package/src/core/operator-alerts.ts +204 -4
- package/src/core/outbox.ts +125 -12
- package/src/core/routes/capability.ts +2 -2
- package/src/core/routes/config-builtin.ts +27 -0
- package/src/core/routes/console.ts +7 -0
- package/src/core/routes/dashboard.ts +10 -0
- package/src/core/routes/tasks.ts +11 -0
- package/src/core/runtime.ts +455 -70
- package/src/core/space-links.ts +273 -0
- package/src/core/system-messages.ts +45 -2
- package/src/core/task-scheduler.ts +115 -5
- package/src/env-dump/build-deps.ts +2 -55
- package/src/extensions/catalog.ts +5 -3
- package/src/extensions/context.ts +4 -0
- package/src/extensions/image-builder.ts +265 -65
- package/src/extensions/reserved.ts +6 -0
- package/src/extensions/types.ts +16 -0
- package/src/ops/shadow-diff.ts +1027 -0
- package/src/preflight/binary-version.ts +103 -0
- package/src/preflight/build-deps.ts +2 -0
- package/src/preflight/checks/credential.ts +16 -9
- package/src/preflight/checks/host-deps.ts +107 -10
- package/src/preflight/deps.ts +5 -0
- package/src/profile/space-profile.ts +21 -0
- package/src/server.ts +56 -1
- package/src/storage/db.ts +553 -0
- package/src/storage/pi-auth.ts +92 -8
- package/src/text/reporter-lint.ts +77 -30
- package/docs/plans/flat-0916/briefs/S1.md +0 -55
- package/docs/plans/flat-0916/briefs/S2.md +0 -55
- /package/docs/plans/{flat-0916 → archive/2026-09-28-flat-0916}/decisions.md +0 -0
- /package/docs/plans/{sensitive-bugs-0922 → archive/2026-10-02-sensitive-bugs-0922}/briefs/S1.md +0 -0
- /package/docs/plans/{sensitive-bugs-0922 → archive/2026-10-02-sensitive-bugs-0922}/briefs/S2.md +0 -0
- /package/docs/plans/{sensitive-bugs-0922 → archive/2026-10-02-sensitive-bugs-0922}/briefs/S3.md +0 -0
- /package/docs/plans/{sensitive-bugs-0922 → archive/2026-10-02-sensitive-bugs-0922}/briefs/S4.md +0 -0
- /package/docs/plans/{sensitive-bugs-0922 → archive/2026-10-02-sensitive-bugs-0922}/briefs/S5.md +0 -0
- /package/docs/plans/{sensitive-bugs-0922 → archive/2026-10-02-sensitive-bugs-0922}/decisions.md +0 -0
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
# Plan: media-bugs-0928
|
|
2
|
+
|
|
3
|
+
**Status**: Archived
|
|
4
|
+
**Created**: 2026-09-28 **Last updated**: 2026-10-02
|
|
5
|
+
**Landing mode**: pr
|
|
6
|
+
**Max width**: 4
|
|
7
|
+
**Inputs**: media-bugs-0928 outbox-scan-drops-files-whose-mtime-predates-the-run url-bridges-drop-over-limit-attachments-without-a-note media-download-buffers-before-size-check-without-content-length (the implementation half of the 2026-09-28 general-priorities scan, split out of `general-0928` so these three launch now instead of waiting behind its five-session Round 0)
|
|
8
|
+
**Me**: saharw01, Saharw01@gmail.com (also 92163791+saharw01@users.noreply.github.com, avishailevi2@gmail.com)
|
|
9
|
+
|
|
10
|
+
> Written by `/f-ops-plan` build (and `--rebuild`) and `archive` only. Nothing perishable lives here — no base sha, no other author's file list, no story counts; `next` measures those every time it runs. `plan-state.sh` parses the tables below by their header row, so keep the column order.
|
|
11
|
+
|
|
12
|
+
> **Why this batch.** Three moderate, general (every-space) bugs on the file path in and out of a run, all of CLAUDE.md's "a limit the actor cannot read is a trap" / "absent allows" shape: a file the agent put in `outbox/` is silently not sent while the model says "attached" (S1); an over-limit or over-quota attachment on Slack / Telegram / Discord / Teams / quoted WhatsApp is dropped with only a log line (S2); a chunked download with no `Content-Length` is buffered whole before the size check (S3). None needs a decision. S2 and S3 share `src/core/media.ts` — the S2 doc says one `/f-bug-fix` could take both; they are chained instead so each post-mortem stays about one defect.
|
|
13
|
+
|
|
14
|
+
## Items
|
|
15
|
+
|
|
16
|
+
| ID | Kind | Slug | Doc | Command | Round | Needs |
|
|
17
|
+
|----|------|------|-----|---------|-------|-------|
|
|
18
|
+
| S1 | bug | outbox-scan-drops-files-whose-mtime-predates-the-run | docs/bugs/outbox-scan-drops-files-whose-mtime-predates-the-run.md | /f-bug-fix outbox-scan-drops-files-whose-mtime-predates-the-run | 1 | — |
|
|
19
|
+
| S2 | bug | url-bridges-drop-over-limit-attachments-without-a-note | docs/bugs/url-bridges-drop-over-limit-attachments-without-a-note.md | /f-bug-fix url-bridges-drop-over-limit-attachments-without-a-note | 1 | — |
|
|
20
|
+
| S3 | bug | media-download-buffers-before-size-check-without-content-length | docs/bugs/media-download-buffers-before-size-check-without-content-length.md | /f-bug-fix media-download-buffers-before-size-check-without-content-length | 2 | — |
|
|
21
|
+
|
|
22
|
+
> Kind ∈ `feature` | `bug` | `refactor` | `plan` (a Round 0 planning session) | `story` (from `--goal`; runs `/f-feature-dev`).
|
|
23
|
+
> Needs = decision IDs from `decisions.md` that must be answered before this session may launch, or `—`.
|
|
24
|
+
> IDs are never renumbered; `--drop` moves a row to Deferred, `--add` takes the next unused ID.
|
|
25
|
+
|
|
26
|
+
## Edges
|
|
27
|
+
|
|
28
|
+
| From | To | Kind | Basis |
|
|
29
|
+
|------|----|------|-------|
|
|
30
|
+
| S2 | S3 | start-after | file: src/core/media.ts (both predicted) |
|
|
31
|
+
|
|
32
|
+
> Kind ∈ `start-after` (To may not launch until From is landed) | `merge-after` (To may launch now, may not land until From is landed).
|
|
33
|
+
> Basis starts with `file:` (inferred from the collision map) or `semantic:` (asked) — never mixed in one row.
|
|
34
|
+
> From may name a session of ANOTHER active plan as `{plan-slug}/S{n}` — always `start-after`, always `file:`; resolved at `next` time by deriving that plan's state.
|
|
35
|
+
> Semantic edges asked 2026-09-28: none among these three (owner). Cross-plan: none — `sensitive-bugs-0922` S2–S5 predict `src/core/runtime.ts` and `tests/sensitive-guard-*`; `bench-patterns-0915` S11/S12 (the `scripts/absent-allows-*` and `tests/inventories/*` owners) are landed. `general-0928` predicts nothing yet; its video implementation will take a `start-after` onto S3 at its `--rebuild` (`src/adapters/whatsapp-media.ts`).
|
|
36
|
+
|
|
37
|
+
## Rounds
|
|
38
|
+
|
|
39
|
+
### Round 0 — unblock
|
|
40
|
+
|
|
41
|
+
| Session | Action | Clears |
|
|
42
|
+
|---------|--------|--------|
|
|
43
|
+
| — | owner commits this plan folder before the first launch (session logs are written into it) | the `sessions/` logs have a tracked home |
|
|
44
|
+
|
|
45
|
+
### Round 1
|
|
46
|
+
|
|
47
|
+
| Session | Item | Predicted surfaces (count) |
|
|
48
|
+
|---------|------|----------------------------|
|
|
49
|
+
| S1 | outbox-scan-drops-files-whose-mtime-predates-the-run | 2 |
|
|
50
|
+
| S2 | url-bridges-drop-over-limit-attachments-without-a-note | 7 |
|
|
51
|
+
|
|
52
|
+
### Round 2
|
|
53
|
+
|
|
54
|
+
| Session | Item | Predicted surfaces (count) |
|
|
55
|
+
|---------|------|----------------------------|
|
|
56
|
+
| S3 | media-download-buffers-before-size-check-without-content-length | 4 |
|
|
57
|
+
|
|
58
|
+
## Collision map
|
|
59
|
+
|
|
60
|
+
> Whole files, predicted; `docs/` and infrastructure paths are excluded exactly as `overlap-check.sh` excludes them (2 such paths ignored: `docs/bugs` from S2, `docs/ideas/url-download-drops-not-reported-to-agent.md` from S3). Directory-only predictions (`src/bridges`, `src/adapters`) were narrowed to the files each doc names.
|
|
61
|
+
|
|
62
|
+
| File | Sessions |
|
|
63
|
+
|------|----------|
|
|
64
|
+
| src/core/media.ts | S2, S3 |
|
|
65
|
+
|
|
66
|
+
## Predicted surfaces
|
|
67
|
+
|
|
68
|
+
### S1
|
|
69
|
+
|
|
70
|
+
- src/agent/container-runner.ts
|
|
71
|
+
- src/core/outbox.ts
|
|
72
|
+
|
|
73
|
+
### S2
|
|
74
|
+
|
|
75
|
+
- src/bridges/discord.ts
|
|
76
|
+
- src/bridges/slack.ts
|
|
77
|
+
- src/bridges/teams.ts
|
|
78
|
+
- src/bridges/telegram.ts
|
|
79
|
+
- src/bridges/whatsapp.ts
|
|
80
|
+
- src/core/media.ts
|
|
81
|
+
- tests/inventories/host-limits.ts
|
|
82
|
+
|
|
83
|
+
### S3
|
|
84
|
+
|
|
85
|
+
- scripts/absent-allows-baseline.json
|
|
86
|
+
- scripts/check-absent-allows.ts
|
|
87
|
+
- src/adapters/whatsapp-media.ts
|
|
88
|
+
- src/core/media.ts
|
|
89
|
+
|
|
90
|
+
## Adjudicated overlaps
|
|
91
|
+
|
|
92
|
+
> 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.
|
|
93
|
+
|
|
94
|
+
| Session | Branch (not in this plan) | Files | Verdict | Decided |
|
|
95
|
+
|---------|---------------------------|-------|---------|---------|
|
|
96
|
+
|
|
97
|
+
## Not ours
|
|
98
|
+
|
|
99
|
+
> Last measurement (`git log --since=14.days`, authors not in `Me`), 2026-09-28 on `origin/dev`. Re-measured on every `next`; this table is the snapshot the briefs were written from. Nothing below intersects any session's predicted surfaces.
|
|
100
|
+
|
|
101
|
+
| File / area | Author | Basis |
|
|
102
|
+
|-------------|--------|-------|
|
|
103
|
+
| examples/extensions/office-365-mail/, tests/office-365-mail-extension.test.ts | avishai tsabari | 14-day log, no intersection |
|
|
104
|
+
| src/cli/build-context.ts, src/cli/mercury.ts, tests/build-context.test.ts, tests/container-copy-list-closure.test.ts | avishai tsabari | 14-day log, no intersection |
|
|
105
|
+
| src/storage/db.ts, tests/archive-queue.test.ts, tests/shadow-snapshot.test.ts | avishai tsabari | 14-day log, no intersection |
|
|
106
|
+
| package.json, bun.lock, tsconfig.examples.json | avishai tsabari / dependabot[bot] | 14-day log; lockfiles are excluded from the collision map |
|
|
107
|
+
|
|
108
|
+
## Deferred
|
|
109
|
+
|
|
110
|
+
| Item | Reason | Home |
|
|
111
|
+
|------|--------|------|
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
## Launched — 2026-09-29T15:10Z
|
|
2
|
+
Branch: worktree-fix-outbox-scan-drops-files-whose-mtime-predates-the-run
|
|
3
|
+
|
|
4
|
+
## Report — 2026-09-30T08:08Z
|
|
5
|
+
Outcome: blocked
|
|
6
|
+
Delivered: —
|
|
7
|
+
Blocked-on: owner push approval — squashed to local dev as 5348136, not pushed (CLAUDE.local.md)
|
|
8
|
+
Deploy needs: restart
|
|
9
|
+
Files changed:
|
|
10
|
+
- docs/debug/moderate/2026-09-30-outbox-scan-drops-files-whose-mtime-predates-the-run.md
|
|
11
|
+
- docs/debug/outbox-scan-drops-files-whose-mtime-predates-the-run.md
|
|
12
|
+
- src/agent/container-runner.ts
|
|
13
|
+
- src/core/outbox.ts
|
|
14
|
+
- tests/fixtures/release-gate/regression-map.json
|
|
15
|
+
- tests/outbox.test.ts
|
|
16
|
+
Siblings must know:
|
|
17
|
+
- `scanOutbox` now returns `{ files, skipped }` (was `EgressFile[]`); new export `outboxSkipNotice(skipped)`.
|
|
18
|
+
- dev carries a pre-existing red test from S2: `moderate/2026-09-29-url-bridges-drop-over-limit-attachments-without-a-note.md` has no `Gate check:` line and no row in tests/fixtures/release-gate/regression-map.json.
|
|
19
|
+
- Residual (runtime.ts, owned by sensitive-bugs-0922): an after_container hook that replaces the reply (longview) drops the skip notice.
|
|
20
|
+
--- final report (verbatim) ---
|
|
21
|
+
~~~
|
|
22
|
+
Fixed: outbox-scan-drops-files-whose-mtime-predates-the-run (moderate). Squashed to local dev as 5348136; NOT pushed.
|
|
23
|
+
Files: src/core/outbox.ts, src/agent/container-runner.ts, tests/outbox.test.ts,
|
|
24
|
+
tests/fixtures/release-gate/regression-map.json, post-mortem at
|
|
25
|
+
docs/debug/moderate/2026-09-30-outbox-scan-drops-files-whose-mtime-predates-the-run.md.
|
|
26
|
+
- Freshness is max(mtime, ctime), so cp -p / cp -a / rsync -a / mv / tar x copies are sent.
|
|
27
|
+
- A fresh entry that is not sent (over 25 MB, unreadable, a link or folder) adds "(X was not sent: …)" to the reply; dotfiles are logged only.
|
|
28
|
+
- lstat, never stat: links are never followed (they resolve on the host).
|
|
29
|
+
- The scanOutbox suite (describe.skip since the initial release) runs again; negative-tested (mtime-only → cp -p/mv red; stat → symlink red).
|
|
30
|
+
Gate: 6200 pass / 1 fail, the one fail pre-existing on dev (S2's post-mortem has no Gate check line).
|
|
31
|
+
Deploy: restart only — neither file is a Dockerfile COPY source.
|
|
32
|
+
ARCHITECTURE.md: no update needed.
|
|
33
|
+
Residuals (in the post-mortem): longview-style reply-replacing hooks drop the notice (runtime.ts); the agent's platform intro (container-entry.ts, image-baked) names neither the size cap nor the plain-files rule.
|
|
34
|
+
~~~
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
## Launched — 2026-09-29T15:11Z
|
|
2
|
+
Branch: worktree-fix-url-bridges-drop-over-limit-attachments-without-a-note
|
|
3
|
+
|
|
4
|
+
## Report — 2026-09-30T08:01Z
|
|
5
|
+
Outcome: delivered
|
|
6
|
+
Delivered: —
|
|
7
|
+
Blocked-on: —
|
|
8
|
+
Deploy needs: restart
|
|
9
|
+
Files changed:
|
|
10
|
+
- docs/debug/moderate/2026-09-29-url-bridges-drop-over-limit-attachments-without-a-note.md
|
|
11
|
+
- docs/debug/url-bridges-drop-over-limit-attachments-without-a-note.md
|
|
12
|
+
- docs/ideas/url-download-drops-not-reported-to-agent.md
|
|
13
|
+
- docs/pending-verification.md
|
|
14
|
+
- src/bridges/discord.ts
|
|
15
|
+
- src/bridges/slack.ts
|
|
16
|
+
- src/bridges/teams.ts
|
|
17
|
+
- src/bridges/telegram.ts
|
|
18
|
+
- src/bridges/whatsapp.ts
|
|
19
|
+
- src/core/media.ts
|
|
20
|
+
- tests/bridge-limit-drops.test.ts
|
|
21
|
+
- tests/inventories/host-limits.ts
|
|
22
|
+
- tests/inventory-host-limits.test.ts
|
|
23
|
+
Siblings must know:
|
|
24
|
+
- S3: all three size checks in `downloadMediaFromUrl` (src/core/media.ts) now call `options.onSkipped({ reason: "too_large", sizeBytes, maxBytes })`. When you bound the `arrayBuffer()` read, the check that fires mid-stream must keep that call, or `tests/bridge-limit-drops.test.ts` ("buffered length over the limit") goes red.
|
|
25
|
+
- S3: residual handed over: `QUOTED_DOWNLOAD_TYPES` in src/adapters/whatsapp-media.ts is private, so the WhatsApp quoted over-quota note fires even for a video or sticker that would never be downloaded. Exporting a predicate there and checking it in src/bridges/whatsapp.ts closes it.
|
|
26
|
+
- Delivered is local only: f83fd59 on local `dev`, not pushed (push awaits owner approval). This session reads `delivered` until `dev` is pushed, then `landed`.
|
|
27
|
+
--- final report (verbatim) ---
|
|
28
|
+
~~~
|
|
29
|
+
Fixed url-bridges-drop-over-limit-attachments-without-a-note, squash-merged into local dev as f83fd59 (not pushed).
|
|
30
|
+
|
|
31
|
+
- src/core/media.ts: the three size checks in downloadMediaFromUrl report too_large through onSkipped.
|
|
32
|
+
- src/bridges/telegram.ts: the getFile over-limit leg reports too_large; the quota branch reports quota.
|
|
33
|
+
- src/bridges/slack.ts, discord.ts: the quota branch reports quota; Slack shares one attachmentUrl helper.
|
|
34
|
+
- src/bridges/teams.ts: now enforces the quota (isOverQuota) and reports it.
|
|
35
|
+
- src/bridges/whatsapp.ts: the quoted-media quota branch reports quota (once per message).
|
|
36
|
+
- tests/bridge-limit-drops.test.ts: new; negative-tested per file.
|
|
37
|
+
- tests/inventories/host-limits.ts + inventory test: maxDiskMb / mediaMaxSizeMb name their reader; no none readers remain.
|
|
38
|
+
- Post-mortem: docs/debug/moderate/2026-09-29-url-bridges-drop-over-limit-attachments-without-a-note.md
|
|
39
|
+
- Gate on the branch: 16/16 links, 6163 pass / 9 skip / 0 fail; affected tests on dev after squash: 126 pass / 0 fail.
|
|
40
|
+
- ARCHITECTURE.md: no update needed.
|
|
41
|
+
- Deploy: restart only (no baked file). MANUAL-VERIFY under "## Plan media-bugs-0928 / S2".
|
|
42
|
+
- Residuals: WhatsApp quoted video/sticker over quota gets a quota note (needs S3's file); download_failed still silent (docs/ideas/url-download-drops-not-reported-to-agent.md).
|
|
43
|
+
~~~
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
## Launched — 2026-09-30T08:46Z
|
|
2
|
+
Branch: worktree-fix-media-download-buffers-before-size-check-without-content-length
|
|
3
|
+
|
|
4
|
+
## Report — 2026-09-30T09:09Z
|
|
5
|
+
Outcome: delivered
|
|
6
|
+
Delivered: —
|
|
7
|
+
Blocked-on: —
|
|
8
|
+
Deploy needs: restart
|
|
9
|
+
Files changed:
|
|
10
|
+
- docs/bugs/whatsapp-media-download-buffers-before-size-check-without-file-length.md
|
|
11
|
+
- docs/debug/media-download-buffers-before-size-check-without-content-length.md
|
|
12
|
+
- docs/debug/moderate/2026-09-30-media-download-buffers-before-size-check-without-content-length.md
|
|
13
|
+
- scripts/absent-allows-baseline.json
|
|
14
|
+
- src/core/media.ts
|
|
15
|
+
- tests/bridge-limit-drops.test.ts
|
|
16
|
+
- tests/inventories/host-limits.ts
|
|
17
|
+
- tests/media.test.ts
|
|
18
|
+
Siblings must know:
|
|
19
|
+
- `downloadMediaFromUrl` (src/core/media.ts) now reads through the exported `readBodyCapped(response, maxBytes)`. A drop that stops mid-stream calls `onSkipped({ reason: "too_large", maxBytes })` with NO `sizeBytes`, because the real size is unknown, so the note reads "unknown size, limit X".
|
|
20
|
+
- Bun's fetch has no backpressure. A body reader that stops without `cancel()` keeps buffering (measured ~1 GB for a 512 MB body). Any other capped read must cancel explicitly.
|
|
21
|
+
- The absent-allows ratchet DOES count src/adapters/whatsapp-media.ts (baseline 2); the brief's "skips src/adapters/" was wrong. That twin is filed as docs/bugs/whatsapp-media-download-buffers-before-size-check-without-file-length.md.
|
|
22
|
+
- Owner-approved edit to S2's tests/inventories/host-limits.ts: the mediaMaxSizeMb needle is now `if (total > maxBytes) {`.
|
|
23
|
+
- Delivered is local only: 61f9fb7 on local `dev`, not pushed (push awaits owner approval).
|
|
24
|
+
--- final report (verbatim) ---
|
|
25
|
+
~~~
|
|
26
|
+
Fixed: URL media download buffered the whole body when Content-Length was absent.
|
|
27
|
+
Commit 61f9fb7 on local dev (not pushed). Gate in worktree: bun run check 16/16 links, 6206 pass / 0 fail.
|
|
28
|
+
Files: src/core/media.ts (readBodyCapped, streamed + cancel() past cap; declared sizes kept as early exits whose absence falls through),
|
|
29
|
+
scripts/absent-allows-baseline.json (media.ts row removed, 2 -> 0), tests/media.test.ts (unit + end-to-end chunked tests, negative-tested twice),
|
|
30
|
+
tests/bridge-limit-drops.test.ts (no sizeBytes on a mid-stream drop), tests/inventories/host-limits.ts (needle, owner-approved),
|
|
31
|
+
docs/bugs/whatsapp-media-download-buffers-before-size-check-without-file-length.md (residual).
|
|
32
|
+
Post-mortem: docs/debug/moderate/2026-09-30-media-download-buffers-before-size-check-without-content-length.md
|
|
33
|
+
ARCHITECTURE.md: no change needed.
|
|
34
|
+
Deviation from /f-bug-fix: promotion and squash commits kept local per CLAUDE.local.md (no push without approval).
|
|
35
|
+
~~~
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Plan: sensitive-bugs-0922
|
|
2
2
|
|
|
3
|
-
**Status**:
|
|
4
|
-
**Created**: 2026-09-22 **Last updated**: 2026-
|
|
3
|
+
**Status**: Archived
|
|
4
|
+
**Created**: 2026-09-22 **Last updated**: 2026-10-02
|
|
5
5
|
**Landing mode**: pr
|
|
6
6
|
**Max width**: 4
|
|
7
7
|
**Inputs**: sensitive-bugs-0922 sensitive-guard-replay-runs-with-the-yes-messages-reply-metadata sensitive-guard-replay-loses-the-dropped-attachment-note sensitive-gate-is-checked-before-the-space-queue scheduled-run-skipped-by-sensitive-deny-has-no-reader sensitive-guard-axis-coverage-gaps (the four bugs bench-patterns-0915 S6 filed, plus the open drop-note bug; split out of the p0-plan-0922 rebuild)
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
## Launched — 2026-09-28T11:50Z
|
|
2
|
+
Branch: worktree-fix-sensitive-guard-replay-runs-with-the-yes-messages-reply-metadata
|
|
3
|
+
|
|
4
|
+
## Report — 2026-09-28T12:18Z
|
|
5
|
+
Outcome: delivered
|
|
6
|
+
Delivered: —
|
|
7
|
+
Blocked-on: —
|
|
8
|
+
Deploy needs: restart
|
|
9
|
+
Files changed:
|
|
10
|
+
- docs/bugs/sensitive-guard-replay-runs-with-the-yes-messages-reply-metadata.md
|
|
11
|
+
- docs/debug/moderate/2026-09-28-sensitive-guard-replay-runs-with-the-yes-messages-reply-metadata.md
|
|
12
|
+
- src/core/runtime.ts
|
|
13
|
+
- tests/fixtures/release-gate/regression-map.json
|
|
14
|
+
- tests/inventories/guard-axes.ts
|
|
15
|
+
- tests/sensitive-guard-replay.test.ts
|
|
16
|
+
Siblings must know:
|
|
17
|
+
- `PendingSensitiveEntry` (src/core/runtime.ts) now = { prompt, at, attachments?, replyMeta?: PendingReplyMeta, replyFlags?: PendingReplyFlags }. S2 adds `droppedAttachments?` as one more optional field, with one more refuse-whole block in `readPendingSensitive`.
|
|
18
|
+
- `checkSensitiveConnectionGuard(spaceId, prompt, callerId, audience, turn)` — `turn` is { attachments, replyMeta, replyFlags } (required). The `yes` arm returns `{ action: "proceed", replay: PendingSensitiveEntry }`; `replayPrompt` / `replayAttachments` are gone. handleRawInput reads `replay.*`.
|
|
19
|
+
- Absent fields on a stored row are ABSENT on replay, never borrowed from the `yes`; absent `replyFlags` fails closed (isReplyToBot true). A row with `replyMeta` but no `replyFlags` is refused.
|
|
20
|
+
- tests/inventories/guard-axes.ts: replay-meta × L1 is now `lit` citing tests/sensitive-guard-replay.test.ts, L2 `shared` with L1; the B2 const was removed. Each sibling rewrites its own cells there when its bug archives.
|
|
21
|
+
- Squash is on LOCAL dev only (0d5720b), not pushed — plan-state reads landed only once it reaches origin/dev.
|
|
22
|
+
--- final report (verbatim) ---
|
|
23
|
+
~~~
|
|
24
|
+
Fixed: sensitive-guard-replay-runs-with-the-yes-messages-reply-metadata (moderate).
|
|
25
|
+
Squash commit 0d5720b on local dev (not pushed; push awaits owner approval).
|
|
26
|
+
Files: src/core/runtime.ts, tests/sensitive-guard-replay.test.ts, tests/inventories/guard-axes.ts,
|
|
27
|
+
tests/fixtures/release-gate/regression-map.json, bug doc -> docs/debug/moderate/2026-09-28-….md.
|
|
28
|
+
The pending entry stores the blocked turn's replyMeta + replyFlags; the yes replays the entry whole.
|
|
29
|
+
Absent flags fail closed (isolating); malformed fields refuse the row whole.
|
|
30
|
+
Gate: bun run check — 16/16 links pass, 6124 pass / 0 fail. Negative controls: yes-metadata swap -> 5 red;
|
|
31
|
+
absent-flags default false -> 2 red.
|
|
32
|
+
Deviation: promotion commit on dev was refused by the auto-mode classifier (another session's staged
|
|
33
|
+
work in the shared index); the bug-doc move rode the fix branch instead.
|
|
34
|
+
Deploy needs: restart (runtime.ts not baked; no version change).
|
|
35
|
+
~~~
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
## Launched — 2026-09-29T15:12Z
|
|
2
|
+
Branch: worktree-fix-sensitive-guard-replay-loses-the-dropped-attachment-note
|
|
3
|
+
|
|
4
|
+
## Report — 2026-09-30T08:10Z
|
|
5
|
+
Outcome: blocked
|
|
6
|
+
Delivered: —
|
|
7
|
+
Blocked-on: owner approval to push dev (8161c5f and promotion a7a704a are local only)
|
|
8
|
+
Deploy needs: restart
|
|
9
|
+
Files changed:
|
|
10
|
+
- src/core/runtime.ts
|
|
11
|
+
- tests/sensitive-guard-replay-drop-note.test.ts
|
|
12
|
+
- tests/inventories/guard-axes.ts
|
|
13
|
+
- tests/fixtures/release-gate/regression-map.json
|
|
14
|
+
- docs/debug/minor/2026-09-29-sensitive-guard-replay-loses-the-dropped-attachment-note.md
|
|
15
|
+
Siblings must know:
|
|
16
|
+
- PendingSensitiveEntry gains optional droppedAttachments (DroppedAttachment[]), read by readDroppedAttachments (refuse-whole; reason set derived from the union via Record<DroppedAttachment["reason"], true>)
|
|
17
|
+
- the guard's `turn` argument now requires droppedAttachments; the writer stores it only when non-empty and only if the reader accepts it
|
|
18
|
+
- dropNote in handleRawInput is now built AFTER the guard (replay list + the current message's own)
|
|
19
|
+
- guard-axes L1 attachments cell is `lit`, citing the replay and replay-drop-note tests
|
|
20
|
+
- gate on dev @ 8161c5f: 15/16 links; the one test red is inherited from f83fd59 — moderate/2026-09-29-url-bridges-drop-over-limit-attachments-without-a-note.md has no regression-map row
|
|
21
|
+
--- final report (verbatim) ---
|
|
22
|
+
~~~
|
|
23
|
+
S2 sensitive-guard-replay-loses-the-dropped-attachment-note — fixed, squash-merged to local dev as 8161c5f (not pushed).
|
|
24
|
+
Fix: the blocked turn's dropped-attachment list is stored with the pending entry (validated both ways, refuse-whole) and the replay's note is built after the guard from that list plus the yes's own. Pre-fix rows replay with no note.
|
|
25
|
+
Tests: tests/sensitive-guard-replay-drop-note.test.ts, 15 tests, 4 negative controls red when the fix is removed.
|
|
26
|
+
Gate: 15/16 PASS; test 6179 pass / 1 fail — inherited regression-map gap for the url-bridges post-mortem (f83fd59).
|
|
27
|
+
Post-mortem: docs/debug/minor/2026-09-29-sensitive-guard-replay-loses-the-dropped-attachment-note.md
|
|
28
|
+
Deploy: restart only (runtime.ts is not baked; no version change).
|
|
29
|
+
Push: awaiting owner approval.
|
|
30
|
+
~~~
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
## Launched — 2026-09-30T08:46Z
|
|
2
|
+
Branch: worktree-fix-sensitive-gate-is-checked-before-the-space-queue
|
|
3
|
+
|
|
4
|
+
## Report — 2026-09-30T09:06Z
|
|
5
|
+
Outcome: blocked
|
|
6
|
+
Delivered: —
|
|
7
|
+
Blocked-on: owner approval to push dev (85e408b promotion and c7760d8 fix are local only)
|
|
8
|
+
Deploy needs: restart
|
|
9
|
+
Files changed:
|
|
10
|
+
- docs/bugs/sensitive-gate-that-appears-while-a-turn-waits-is-never-confirmed.md
|
|
11
|
+
- docs/debug/moderate/2026-09-30-sensitive-gate-is-checked-before-the-space-queue.md
|
|
12
|
+
- docs/debug/sensitive-gate-is-checked-before-the-space-queue.md
|
|
13
|
+
- docs/pending-verification.md
|
|
14
|
+
- src/core/runtime.ts
|
|
15
|
+
- tests/fixtures/release-gate/regression-map.json
|
|
16
|
+
- tests/inventories/guard-axes.ts
|
|
17
|
+
- tests/inventory-guard-axes.test.ts
|
|
18
|
+
- tests/sensitive-guard-audience.test.ts
|
|
19
|
+
- tests/sensitive-guard-replay-drop-note.test.ts
|
|
20
|
+
- tests/sensitive-guard-replay.test.ts
|
|
21
|
+
Siblings must know:
|
|
22
|
+
- executePrompt(spaceId, prompt, source, callerId, admission, attachments?, …): new REQUIRED 5th arg `admission: SensitiveAdmission` ({kind:"policy"} | {kind:"consent", consentKey, admittedAt}); any positional executePrompt mock must add an `_admission` param (replay + drop-note mocks already do)
|
|
23
|
+
- executePrompt now returns ContainerResult | SensitiveDequeueDenial ({sensitiveDenied: string}); narrow with isSensitiveDequeueDenial()
|
|
24
|
+
- the dequeue hook is recheckSensitiveAtDequeue(spaceId, callerId, admission), first statement of executePrompt's queue.enqueue callback: this is where the deferred `sensitive-opt-out-should-deny-not-block` idea hooks the policy half at use time
|
|
25
|
+
- S4 (scheduled-run-skipped-by-sensitive-deny-has-no-reader): there are now TWO scheduler skip sites, both logger.warn only: the pre-queue gate ("Scheduled task skipped: sensitive connections are not enabled…") and the dequeue skip ("Scheduled task skipped at dequeue: …"); both return undefined. Give both the same reader.
|
|
26
|
+
- guard-axes: check-use is lit on L1/L3 (audience suite), shared on L2; the anti-vacuity pin in tests/inventory-guard-axes.test.ts now pins B3's L3 skip-visibility cell, so S4 must move it again when B3 closes
|
|
27
|
+
- new open bug filed: docs/bugs/sensitive-gate-that-appears-while-a-turn-waits-is-never-confirmed.md (minor; an ungated admission whose gate appears in the queue is never asked for consent)
|
|
28
|
+
--- final report (verbatim) ---
|
|
29
|
+
~~~
|
|
30
|
+
S3 sensitive-gate-is-checked-before-the-space-queue: fixed, squash-merged to local dev as c7760d8 (not pushed; promotion 85e408b also local).
|
|
31
|
+
Fix: the guard and the scheduler pass what admitted the turn (policy, or consent key + admittedAt) to executePrompt as a literal. recheckSensitiveAtDequeue re-asks policy (and consent, for consent admissions) as the first step of the queue callback. Interactive turns get the existing disabled/cancelled text; scheduled runs are skipped like the pre-queue gate; nothing re-warns.
|
|
32
|
+
Tests: 8 new in tests/sensitive-guard-audience.test.ts (queue held by a blocker). Removing the re-check turns 5 red; reading the TTL at Date.now turns the age-out test red.
|
|
33
|
+
Scope growth: replay and drop-note test mocks gained an _admission param (replay.test.ts was Do-not-touch; owner approved in-session). guard-axes inventory and its test updated.
|
|
34
|
+
Gate: bun run check 16/16 links, 6210 pass / 0 fail.
|
|
35
|
+
Post-mortem: docs/debug/moderate/2026-09-30-sensitive-gate-is-checked-before-the-space-queue.md
|
|
36
|
+
Residual filed: docs/bugs/sensitive-gate-that-appears-while-a-turn-waits-is-never-confirmed.md
|
|
37
|
+
Deploy: restart only (release-gate §1 class code; no baked file, no version change).
|
|
38
|
+
Push: awaiting owner approval.
|
|
39
|
+
~~~
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
## Launched — 2026-09-30T14:29Z
|
|
2
|
+
Branch: worktree-fix-scheduled-run-skipped-by-sensitive-deny-has-no-reader
|
|
3
|
+
|
|
4
|
+
## Report — 2026-10-01T14:00Z
|
|
5
|
+
Outcome: blocked
|
|
6
|
+
Delivered: —
|
|
7
|
+
Blocked-on: owner approval to push dev (40c4d2e promotion and 8d7b6d3 fix are local only)
|
|
8
|
+
Deploy needs: restart
|
|
9
|
+
Files changed:
|
|
10
|
+
- docs/debug/minor/2026-09-30-scheduled-run-skipped-by-sensitive-deny-has-no-reader.md
|
|
11
|
+
- docs/debug/scheduled-run-skipped-by-sensitive-deny-has-no-reader.md
|
|
12
|
+
- docs/pending-verification.md
|
|
13
|
+
- src/core/operator-alerts.ts
|
|
14
|
+
- src/core/runtime.ts
|
|
15
|
+
- src/core/system-messages.ts
|
|
16
|
+
- tests/connection-health.test.ts
|
|
17
|
+
- tests/fixtures/release-gate/regression-map.json
|
|
18
|
+
- tests/inventories/guard-axes.ts
|
|
19
|
+
- tests/inventory-guard-axes.test.ts
|
|
20
|
+
- tests/operator-alerts.test.ts
|
|
21
|
+
- tests/pi-auth.test.ts
|
|
22
|
+
- tests/scheduler-missed-runs.test.ts
|
|
23
|
+
- tests/sensitive-guard-audience.test.ts
|
|
24
|
+
Siblings must know:
|
|
25
|
+
- CredentialAlertSink has a new required method taskBlocked(alert: TaskBlockedAlert); every fake sink must add it (pi-auth, connection-health, scheduler-missed-runs, sensitive-guard-audience already do)
|
|
26
|
+
- the audience suite's createRuntime now sets taskNotifyOnFailure: true and afterEach unregisters the alert sink; captureBlockedAlerts() records taskBlocked and throws on taskFailed
|
|
27
|
+
- guard-axes: L3 skip-visibility is now lit (audience + operator-alerts suites); the anti-vacuity pin moved to B4's relink cells on L1 and L3. S5 must move it again when B4 closes
|
|
28
|
+
- residual (recorded in the post-mortem, not filed): one notice per skip with no cooldown, so a short-cron task in a blocked group DMs the operator every run
|
|
29
|
+
--- final report (verbatim) ---
|
|
30
|
+
~~~
|
|
31
|
+
S4 scheduled-run-skipped-by-sensitive-deny-has-no-reader: fixed, squash-merged to local dev as 8d7b6d3 (not pushed; promotion 40c4d2e also local).
|
|
32
|
+
Fix: new operator-alert kind taskBlocked (src/core/operator-alerts.ts, message alert_task_blocked_sensitive in en/he: "skipped, not failed"). runtime.announceTaskBlocked(task, stage) is called from both scheduler skip sites, the pre-queue gate and the dequeue re-check. They are mutually exclusive, so one skip gives one notice, ▶ included. Honours scheduling.notify_on_failure. Goes to operators only, never the space.
|
|
33
|
+
Tests: audience suite has gate/dequeue exactly-one, plus enabled, unchanged-queue and notify-off negative controls; operator-alerts has the text and the alerts-off case. Deleting either call site turns its test red.
|
|
34
|
+
Gate: bun run check 16/16 links, 6274 pass / 0 fail.
|
|
35
|
+
Post-mortem: docs/debug/minor/2026-09-30-scheduled-run-skipped-by-sensitive-deny-has-no-reader.md
|
|
36
|
+
Deploy: restart only (release-gate §1 class code; no baked file, no version change).
|
|
37
|
+
Push: awaiting owner approval.
|
|
38
|
+
~~~
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
## Launched — 2026-10-02T18:28Z
|
|
2
|
+
Branch: worktree-fix-sensitive-guard-axis-coverage-gaps
|
|
3
|
+
|
|
4
|
+
## Report — 2026-10-02T18:47Z
|
|
5
|
+
Outcome: delivered
|
|
6
|
+
Delivered: —
|
|
7
|
+
Blocked-on: —
|
|
8
|
+
Deploy needs: none
|
|
9
|
+
Files changed:
|
|
10
|
+
- docs/debug/minor/2026-10-02-sensitive-guard-axis-coverage-gaps.md
|
|
11
|
+
- docs/debug/sensitive-guard-axis-coverage-gaps.md
|
|
12
|
+
- src/core/runtime.ts
|
|
13
|
+
- tests/inventories/guard-axes.ts
|
|
14
|
+
- tests/inventory-guard-axes.test.ts
|
|
15
|
+
- tests/sensitive-guard-audience.test.ts
|
|
16
|
+
- tests/sensitive-guard-scope.test.ts
|
|
17
|
+
Siblings must know:
|
|
18
|
+
- tests/inventories/guard-axes.ts has no `none` cell left; a new guard gap needs a filed bug and a `none` cell citing it
|
|
19
|
+
--- final report (verbatim) ---
|
|
20
|
+
~~~
|
|
21
|
+
Fixed: sensitive-guard-axis-coverage-gaps (minor; tests and comments only).
|
|
22
|
+
Squashed into LOCAL dev as 8475267. NOT pushed, by owner instruction ("archive
|
|
23
|
+
and squash-merge locally"). Lands when dev is pushed.
|
|
24
|
+
|
|
25
|
+
- relink x L1 / L3, /chat route x L2 (caller, conversation, origin), principal x L3:
|
|
26
|
+
each a test with a negative control, each mutation-tested red.
|
|
27
|
+
- cell 3 (manual trigger x L3) was already closed on dev; no duplicate added.
|
|
28
|
+
- tests/inventories/guard-axes.ts: six B4 cells rewritten to `lit` with tests;
|
|
29
|
+
the closure pin replaced by a closed-cells pin.
|
|
30
|
+
- src/core/runtime.ts: four comments name the console's
|
|
31
|
+
PUT /api/console/spaces/:id/config as the out-of-band writer (comment-only diff).
|
|
32
|
+
- Post-mortem: docs/debug/minor/2026-10-02-sensitive-guard-axis-coverage-gaps.md
|
|
33
|
+
- Gate: bun run check, 16/16 links, 6393 pass / 0 fail.
|
|
34
|
+
- Claim commit 74041b8 (docs-only) was pushed to origin/dev from a scratch
|
|
35
|
+
worktree under the claim-push exception.
|
|
36
|
+
- Deploy: none (no behaviour change; nothing baked).
|
|
37
|
+
~~~
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# Brief S1 — video understanding — a global extension that watches and listens
|
|
2
|
+
|
|
3
|
+
**Plan**: docs/plans/general-0928/plan.md **Session**: S1 **Round**: 0 **Kind**: plan
|
|
4
|
+
**Item slug**: video-understanding-extension
|
|
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 general-0928 S1
|
|
11
|
+
|
|
12
|
+
## Run
|
|
13
|
+
|
|
14
|
+
/f-feature-planning video-understanding-extension
|
|
15
|
+
|
|
16
|
+
## Scope notes
|
|
17
|
+
|
|
18
|
+
Plan the Goal + Architecture into `docs/backlog/video-understanding-extension.md` under **Q2**, and settle every open question in the idea with the owner (hook vs skill, where the frame leg runs, the free-tier warning, the quoted-video cap, the `voice-transcribe` factoring, who owns `yt-dlp`, on-demand `mrctl media fetch`, video listings).
|
|
19
|
+
|
|
20
|
+
**Q2 shapes the architecture — three legs, one result:**
|
|
21
|
+
- **Default leg (always available, no key):** ffmpeg samples frames (contact sheets with burned-in timestamps) and they go to the space's **configured model leg**. If that is a host-side or nested call it must follow CLAUDE.md's pi-spawn rule (own the whole system prompt, the space's own leg, a row in `tests/inventories/pi-spawns.ts`) and the single-thread rule (a bound and a log line). Subscription OAuth only — never an Anthropic API key (owner rule).
|
|
22
|
+
- **Optional video leg:** a **global** key for a native-video model (Gemini). Configured → it runs too.
|
|
23
|
+
- **Optional audio leg:** a **global** STT key (reuse `voice-transcribe`'s providers, do not fork them).
|
|
24
|
+
- **Consolidation:** when more than one leg ran, one `[Video]` block merges them; each leg that failed or was not configured is named, so "I could not process the video" is a real sentence. Decide whether the legs run in parallel and how the merge is done (host-side text merge vs one consolidating model call).
|
|
25
|
+
|
|
26
|
+
It is a **general** extension (every space), not a flat-search feature. The flat profile's "you cannot watch videos" paragraph is revised as part of it, but the flat space is on hold, so that edit is low-priority. Accept S2's `is_video` + stream URL as an input (merge-after S2).
|
|
27
|
+
|
|
28
|
+
## Owned surfaces (predicted)
|
|
29
|
+
|
|
30
|
+
- none yet — this session writes `docs/backlog/video-understanding-extension.md` (promoted from `docs/ideas/video-understanding-extension.md`); its Architecture is what `--rebuild` will measure.
|
|
31
|
+
|
|
32
|
+
## Do not touch
|
|
33
|
+
|
|
34
|
+
- the other four ideas of this plan and their backlog docs (owned by their own planning sessions this plan)
|
|
35
|
+
- `src/`, `tests/`, `examples/` — a planning session writes no code
|
|
36
|
+
- Not ours: see plan.md "Not ours" (nothing intersects). Re-check with `/f-ops-plan next general-0928`.
|
|
37
|
+
|
|
38
|
+
## Edges
|
|
39
|
+
|
|
40
|
+
- start-after: none (satisfied — `next` launched you)
|
|
41
|
+
- merge-after: land only after S2 is landed. Check with `/f-ops-plan next general-0928` before approving the doc.
|
|
42
|
+
|
|
43
|
+
## Overlap verdicts
|
|
44
|
+
|
|
45
|
+
none
|
|
46
|
+
|
|
47
|
+
> 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.
|
|
48
|
+
|
|
49
|
+
## Decisions answered
|
|
50
|
+
|
|
51
|
+
- Q2: default = frames to the space's configured model; optional global video/audio keys add legs, consolidated into one result (owner, 2026-09-28).
|
|
52
|
+
|
|
53
|
+
## Ledger rules
|
|
54
|
+
|
|
55
|
+
> Kind `plan`: you share the primary checkout with sibling planning sessions — touch only your item's doc and the idea it promotes; `/f-feature-planning`'s ROADMAP row is fine; run no git write command at all (`add`, `commit`, `stash`, `checkout`, `pull`) — `next` hands the owner one commit line for Round 0.
|
|
56
|
+
|
|
57
|
+
- `docs/pending-verification.md`: a planning session adds no lines.
|
|
58
|
+
- Any goal's `decisions.md`: never edit; put decisions in your item's own doc.
|
|
59
|
+
|
|
60
|
+
## Environment
|
|
61
|
+
|
|
62
|
+
- Read `CLAUDE.md` → Gotchas, and `docs/profile-guide.md` / `docs/behavior-layers.md` / `docs/skills-guide.md` if the design adds a skill or a profile rule. Nothing from them is copied here.
|
|
63
|
+
|
|
64
|
+
## Report
|
|
65
|
+
|
|
66
|
+
`/f-feature-planning` has no report step — `/f-ops-plan work` backfills `docs/plans/general-0928/sessions/S1.md` (path resolved through `.claude/scripts/resolve-docs-root.sh docs/plans/probe.md`): `delivered` once the backlog doc predicts surfaces, else `blocked` with the open question.
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# Brief S2 — marketplace / social listing reader
|
|
2
|
+
|
|
3
|
+
**Plan**: docs/plans/general-0928/plan.md **Session**: S2 **Round**: 0 **Kind**: plan
|
|
4
|
+
**Item slug**: marketplace-listing-reader
|
|
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 general-0928 S2
|
|
11
|
+
|
|
12
|
+
## Run
|
|
13
|
+
|
|
14
|
+
/f-feature-planning marketplace-listing-reader
|
|
15
|
+
|
|
16
|
+
## Scope notes
|
|
17
|
+
|
|
18
|
+
Plan **first** in this plan — S1, S4 and S5 build against the contract you write. Goal + Architecture into `docs/backlog/marketplace-listing-reader.md`, under **Q1**.
|
|
19
|
+
|
|
20
|
+
**Q1 shapes the architecture:** the default path reads **public** data only (Facebook `og:*` + JSON-LD via the crawler UA, yad2 page JSON, a generic OpenGraph / JSON-LD / schema.org fallback) and must be decent on its own — the fix for `docs/bugs/facebook-listing-read-drops-data-the-page-already-carries.md` (a price in `og:description` reported as "no price"; a video listing read as "ILS"). Leave a **named seam** where an optional per-space logged-in session (S5) plugs in later to fill gated fields (more photos, phone behind a click); `missing[]` must say "behind login" for exactly those fields, so the upgrade is visible.
|
|
21
|
+
|
|
22
|
+
**Scope the owner asked about, 2026-09-28:** "improvement in interaction with Facebook and social media in general". Decide with the owner whether the capability is a *listing* reader or a general **social-link reader** (a Facebook post / group post / page, an Instagram or X link: author, text, time, media, `is_video`) with a listing as one record type. The feed-watch social-sources goal (`docs/goals/feed-watch-social-sources/`, incl. `blocked-sources-research.md`) is prior art for what each platform serves without a login — read it; do not re-probe what it already measured.
|
|
23
|
+
|
|
24
|
+
Return `is_video` + the stream URL for S1. Record the contract precisely — three sibling planning sessions read it.
|
|
25
|
+
|
|
26
|
+
## Owned surfaces (predicted)
|
|
27
|
+
|
|
28
|
+
- none yet — this session writes `docs/backlog/marketplace-listing-reader.md` (promoted from `docs/ideas/marketplace-listing-reader.md`); its Architecture is what `--rebuild` will measure.
|
|
29
|
+
|
|
30
|
+
## Do not touch
|
|
31
|
+
|
|
32
|
+
- the other four ideas of this plan and their backlog docs (owned by their own planning sessions this plan)
|
|
33
|
+
- `src/`, `tests/`, `examples/` — a planning session writes no code
|
|
34
|
+
- Not ours: see plan.md "Not ours" (nothing intersects). Re-check with `/f-ops-plan next general-0928`.
|
|
35
|
+
|
|
36
|
+
## Edges
|
|
37
|
+
|
|
38
|
+
- start-after: none (satisfied — `next` launched you)
|
|
39
|
+
- merge-after: none
|
|
40
|
+
|
|
41
|
+
## Overlap verdicts
|
|
42
|
+
|
|
43
|
+
none
|
|
44
|
+
|
|
45
|
+
> 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.
|
|
46
|
+
|
|
47
|
+
## Decisions answered
|
|
48
|
+
|
|
49
|
+
- Q1: public-data default that is decent alone; optional per-space login upgrades it (owner, 2026-09-28).
|
|
50
|
+
|
|
51
|
+
## Ledger rules
|
|
52
|
+
|
|
53
|
+
> Kind `plan`: you share the primary checkout with sibling planning sessions — touch only your item's doc and the idea it promotes; `/f-feature-planning`'s ROADMAP row is fine; run no git write command at all (`add`, `commit`, `stash`, `checkout`, `pull`) — `next` hands the owner one commit line for Round 0.
|
|
54
|
+
|
|
55
|
+
- `docs/pending-verification.md`: a planning session adds no lines.
|
|
56
|
+
- Any goal's `decisions.md`: never edit; put decisions in your item's own doc.
|
|
57
|
+
|
|
58
|
+
## Environment
|
|
59
|
+
|
|
60
|
+
- Read `CLAUDE.md` → Gotchas, and `docs/profile-guide.md` / `docs/behavior-layers.md` / `docs/skills-guide.md` if the design adds a skill or a profile rule. Nothing from them is copied here.
|
|
61
|
+
|
|
62
|
+
## Report
|
|
63
|
+
|
|
64
|
+
`/f-feature-planning` has no report step — `/f-ops-plan work` backfills `docs/plans/general-0928/sessions/S2.md` (path resolved through `.claude/scripts/resolve-docs-root.sh docs/plans/probe.md`): `delivered` once the backlog doc predicts surfaces, else `blocked` with the open question.
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# Brief S3 — WhatsApp outbound queue survives a restart
|
|
2
|
+
|
|
3
|
+
**Plan**: docs/plans/general-0928/plan.md **Session**: S3 **Round**: 0 **Kind**: plan
|
|
4
|
+
**Item slug**: whatsapp-outbound-queue-survives-restart
|
|
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 general-0928 S3
|
|
11
|
+
|
|
12
|
+
## Run
|
|
13
|
+
|
|
14
|
+
/f-feature-planning whatsapp-outbound-queue-survives-restart
|
|
15
|
+
|
|
16
|
+
## Scope notes
|
|
17
|
+
|
|
18
|
+
Goal + Architecture into `docs/backlog/whatsapp-outbound-queue-survives-restart.md`. The named residual of `orphaned-run-recovery` (archived 2026-09-25): a send queued while the socket is down returns a synthetic `queued-…` id, the journal row closes, and a restart loses the text. Settle the idea's open question (a typed "queued, not delivered" return vs the id's shape) and apply CLAUDE.md's gotcha "a flag sampled before an `await` is a guard, not a handler" and "any early return between an irreversible step and its persist loses whatever that step consumed". Independent of S1/S2/S4/S5 — no edges.
|
|
19
|
+
|
|
20
|
+
## Owned surfaces (predicted)
|
|
21
|
+
|
|
22
|
+
- none yet — this session writes `docs/backlog/whatsapp-outbound-queue-survives-restart.md` (promoted from `docs/ideas/whatsapp-outbound-queue-survives-restart.md`); its Architecture is what `--rebuild` will measure.
|
|
23
|
+
|
|
24
|
+
## Do not touch
|
|
25
|
+
|
|
26
|
+
- the other four ideas of this plan and their backlog docs (owned by their own planning sessions this plan)
|
|
27
|
+
- `src/`, `tests/`, `examples/` — a planning session writes no code
|
|
28
|
+
- Not ours: see plan.md "Not ours" (nothing intersects). Re-check with `/f-ops-plan next general-0928`.
|
|
29
|
+
|
|
30
|
+
## Edges
|
|
31
|
+
|
|
32
|
+
- start-after: none (satisfied — `next` launched you)
|
|
33
|
+
- merge-after: none
|
|
34
|
+
|
|
35
|
+
## Overlap verdicts
|
|
36
|
+
|
|
37
|
+
none
|
|
38
|
+
|
|
39
|
+
> 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.
|
|
40
|
+
|
|
41
|
+
## Decisions answered
|
|
42
|
+
|
|
43
|
+
- none
|
|
44
|
+
|
|
45
|
+
## Ledger rules
|
|
46
|
+
|
|
47
|
+
> Kind `plan`: you share the primary checkout with sibling planning sessions — touch only your item's doc and the idea it promotes; `/f-feature-planning`'s ROADMAP row is fine; run no git write command at all (`add`, `commit`, `stash`, `checkout`, `pull`) — `next` hands the owner one commit line for Round 0.
|
|
48
|
+
|
|
49
|
+
- `docs/pending-verification.md`: a planning session adds no lines.
|
|
50
|
+
- Any goal's `decisions.md`: never edit; put decisions in your item's own doc.
|
|
51
|
+
|
|
52
|
+
## Environment
|
|
53
|
+
|
|
54
|
+
- Read `CLAUDE.md` → Gotchas, and `docs/profile-guide.md` / `docs/behavior-layers.md` / `docs/skills-guide.md` if the design adds a skill or a profile rule. Nothing from them is copied here.
|
|
55
|
+
|
|
56
|
+
## Report
|
|
57
|
+
|
|
58
|
+
`/f-feature-planning` has no report step — `/f-ops-plan work` backfills `docs/plans/general-0928/sessions/S3.md` (path resolved through `.claude/scripts/resolve-docs-root.sh docs/plans/probe.md`): `delivered` once the backlog doc predicts surfaces, else `blocked` with the open question.
|