switchroom 0.19.22 → 0.19.24
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/dist/agent-scheduler/index.js +5 -2
- package/dist/auth-broker/index.js +95 -2
- package/dist/cli/notion-write-pretool.mjs +5 -2
- package/dist/cli/switchroom.js +749 -357
- package/dist/host-control/main.js +96 -3
- package/dist/vault/approvals/kernel-server.js +98 -5
- package/dist/vault/broker/server.js +98 -5
- package/package.json +5 -4
- package/profiles/_base/start.sh.hbs +101 -0
- package/profiles/_shared/agent-self-service.md.hbs +64 -109
- package/profiles/_shared/delegation-golden-rule.md.hbs +5 -5
- package/profiles/_shared/dev-protocol.md.hbs +12 -42
- package/profiles/_shared/execution-discipline.md.hbs +7 -14
- package/profiles/coding/CLAUDE.md.hbs +0 -6
- package/profiles/default/CLAUDE.md.hbs +21 -50
- package/skills/dev-protocol/SKILL.md +97 -107
- package/skills/switchroom-release/SKILL.md +2 -1
- package/telegram-plugin/bunfig.toml +10 -0
- package/telegram-plugin/dist/gateway/gateway.js +267 -52
- package/telegram-plugin/gateway/backstop-delivery.ts +97 -16
- package/telegram-plugin/gateway/captured-answer-resume.ts +46 -17
- package/telegram-plugin/gateway/gateway.ts +43 -42
- package/telegram-plugin/gateway/latest-turn-lookup.ts +60 -0
- package/telegram-plugin/gateway/outbound-send-path.ts +61 -22
- package/telegram-plugin/gateway/stream-render.ts +6 -0
- package/telegram-plugin/gateway/subagent-handback-marker.ts +1 -1
- package/telegram-plugin/gateway/turn-end.ts +1 -1
- package/telegram-plugin/gateway/turn-record-status.ts +19 -0
- package/telegram-plugin/gateway/turns-jsonl-rotate.ts +65 -0
- package/telegram-plugin/reply-owner-resolve.ts +110 -9
- package/telegram-plugin/send-gate-degraded.test.ts +45 -16
- package/telegram-plugin/send-gate.ts +185 -24
- package/telegram-plugin/tests/activity-card-send-gate.test.ts +9 -9
- package/telegram-plugin/tests/agent-state-dir-preload.test.ts +33 -0
- package/telegram-plugin/tests/backstop-delivery.test.ts +204 -7
- package/telegram-plugin/tests/backstop-readback-probe.test.ts +12 -0
- package/telegram-plugin/tests/captured-answer-resume.test.ts +104 -0
- package/telegram-plugin/tests/latest-turn-lookup.test.ts +77 -0
- package/telegram-plugin/tests/narrative-lane-golden.test.ts +23 -1
- package/telegram-plugin/tests/reply-owner-resolve.test.ts +531 -0
- package/telegram-plugin/tests/send-reply-golden.test.ts +296 -28
- package/telegram-plugin/tests/stream-controller-send-gate.test.ts +134 -28
- package/telegram-plugin/tests/stream-render-golden.test.ts +25 -3
- package/telegram-plugin/tests/turns-jsonl-rotate.test.ts +92 -1
- package/vendor/hindsight-memory/scripts/drain_pending.py +113 -11
- package/vendor/hindsight-memory/scripts/lib/pending.py +802 -65
- package/vendor/hindsight-memory/scripts/lib/retain_split.py +54 -7
- package/vendor/hindsight-memory/scripts/tests/test_pending_drops.py +1445 -11
- package/vendor/hindsight-memory/scripts/tests/test_retain_split.py +78 -6
- package/vendor/hindsight-memory/tests/test_drain_pending.py +17 -2
- package/vendor/hindsight-memory/tests/test_pending.py +12 -4
|
@@ -13,51 +13,14 @@ description: >
|
|
|
13
13
|
|
|
14
14
|
# Development Protocol — the playbook
|
|
15
15
|
|
|
16
|
-
The always-loaded CLAUDE.md "Development Protocol" section
|
|
17
|
-
This skill
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
- **Read the real source.** The repo's source files at the current HEAD — not
|
|
25
|
-
build artifacts (`dist/`, generated files, caches), not your memory of the
|
|
26
|
-
code, not the task description's paraphrase. If a claim matters, open the
|
|
27
|
-
file.
|
|
28
|
-
- **Verify the root cause, not the first plausible cause.** Reproduce or trace
|
|
29
|
-
the failure to a specific mechanism before fixing. "This line looks wrong"
|
|
30
|
-
is a lead; the fix ships only when you can say *why* it produced the
|
|
31
|
-
observed symptom.
|
|
32
|
-
- **Report contradicting evidence.** If what you find contradicts the task
|
|
33
|
-
description, the ticket, or your own working theory — say so explicitly and
|
|
34
|
-
stop to re-plan. Never force-fit evidence to the plan you already had.
|
|
35
|
-
- **Cite everything.** Claims about the codebase carry `file:line`, commit
|
|
36
|
-
hashes, or PR numbers. "The scaffold appends fragments at
|
|
37
|
-
`src/agents/scaffold.ts:4113`" is a claim; "the scaffold appends fragments
|
|
38
|
-
somewhere" is not.
|
|
39
|
-
|
|
40
|
-
## 2. Clarify vs proceed
|
|
41
|
-
|
|
42
|
-
- **Infer first.** Most questions are answerable from the codebase, git
|
|
43
|
-
history, existing tests, or docs. Exhaust those before asking.
|
|
44
|
-
- **One question at a time.** If genuinely unsure after inferring, ask the
|
|
45
|
-
single question whose answer unblocks the most work. Phrase it as a
|
|
46
|
-
decision with a default: state what you found, the 2–3 viable options, which
|
|
47
|
-
you'd pick and why, and ask for confirmation — e.g. *"The config loader
|
|
48
|
-
supports both YAML and JSON overlays; the task says 'config file' without
|
|
49
|
-
specifying. I'd extend the YAML path since all existing overlays are YAML
|
|
50
|
-
(src/config/merge.ts:88) — confirm, or should JSON be covered too?"* Never
|
|
51
|
-
send a questionnaire.
|
|
52
|
-
- **Phase discipline.** Clarify during *planning*. Once the plan is agreed,
|
|
53
|
-
execute autonomously: make the reasonable call on small ambiguities, record
|
|
54
|
-
the assumption in your report, and keep moving. Mid-execution questions are
|
|
55
|
-
reserved for discoveries that invalidate the plan.
|
|
56
|
-
|
|
57
|
-
## 3. Design-align on larger tasks
|
|
58
|
-
|
|
59
|
-
**Classify the task first.** Treat it as "larger" (design-align before
|
|
60
|
-
implementing) when ANY of these hold:
|
|
16
|
+
The always-loaded CLAUDE.md "Development Protocol" section carries the
|
|
17
|
+
judgement criteria. This skill carries the parts that are *this fleet's
|
|
18
|
+
specific opinion* — the ones you would get wrong by defaulting to generic
|
|
19
|
+
good practice, because our answer differs from the obvious one.
|
|
20
|
+
|
|
21
|
+
## 1. Is this a "larger" task? (decides whether you design-align first)
|
|
22
|
+
|
|
23
|
+
Treat it as larger — design report before implementing — when ANY of these hold:
|
|
61
24
|
|
|
62
25
|
- It changes a public interface, schema, config shape, or on-disk format.
|
|
63
26
|
- It cuts across 3+ modules or touches a load-bearing invariant.
|
|
@@ -67,65 +30,92 @@ implementing) when ANY of these hold:
|
|
|
67
30
|
("add flag Y").
|
|
68
31
|
- It will land as more than one PR.
|
|
69
32
|
|
|
70
|
-
Small, single-concern, obvious-approach changes skip straight to
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
- **
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
33
|
+
Small, single-concern, obvious-approach changes skip straight to the pipeline.
|
|
34
|
+
Design-aligning a one-liner is its own failure mode.
|
|
35
|
+
|
|
36
|
+
## 2. Design report + red-team (larger tasks only)
|
|
37
|
+
|
|
38
|
+
The report states what exists today **with citations**, what will change, the
|
|
39
|
+
chosen approach, the alternatives you rejected and why, and the PR staging
|
|
40
|
+
plan. Get alignment before implementing.
|
|
41
|
+
|
|
42
|
+
Then red-team your own plan item by item. Each item gets a verdict —
|
|
43
|
+
`SOUND`, `RISK`, or `WRONG` — backed by evidence you can point at (a file you
|
|
44
|
+
read, a test you ran, documented behaviour), not intuition. Fix every `WRONG`
|
|
45
|
+
and address every `RISK` before starting. A red-team that returns all-`SOUND`
|
|
46
|
+
on a non-trivial plan is a red-team you didn't actually do.
|
|
47
|
+
|
|
48
|
+
## 3. Ask one question, as a decision with a default
|
|
49
|
+
|
|
50
|
+
If you're genuinely blocked after inferring from code and history, don't send
|
|
51
|
+
a questionnaire. State what you found, the 2–3 viable options, which you'd
|
|
52
|
+
pick and why, and ask for confirmation:
|
|
53
|
+
|
|
54
|
+
> "The config loader supports both YAML and JSON overlays; the task says
|
|
55
|
+
> 'config file' without specifying. I'd extend the YAML path since all
|
|
56
|
+
> existing overlays are YAML (`src/config/merge.ts:88`) — confirm, or should
|
|
57
|
+
> JSON be covered too?"
|
|
58
|
+
|
|
59
|
+
Clarify during *planning*. Once the plan is agreed, execute autonomously:
|
|
60
|
+
make the reasonable call on small ambiguities, record the assumption in your
|
|
61
|
+
report, keep moving. Mid-execution questions are reserved for discoveries
|
|
62
|
+
that invalidate the plan.
|
|
63
|
+
|
|
64
|
+
## 4. Adversarial review — bounded on purpose
|
|
65
|
+
|
|
66
|
+
Dispatch the review to a **fresh** pass or sub-agent; the coder cannot review
|
|
67
|
+
its own work in-context. Structure it:
|
|
68
|
+
|
|
69
|
+
- **Input:** the full diff, the task statement, and the design report if one exists.
|
|
70
|
+
- **Charge:** *find reasons this change is wrong* — correctness, missed edge
|
|
71
|
+
cases, untested behaviour, inconsistency with surrounding code, docs drift,
|
|
72
|
+
security or data-loss risk.
|
|
73
|
+
- **Output:** a findings list, each with a severity, the evidence (`file:line`),
|
|
74
|
+
and a concrete fix.
|
|
75
|
+
|
|
76
|
+
**The severity gate — this is the fleet-specific part.** The old rule was
|
|
77
|
+
"fix ALL findings including lows, then re-review". That is a loop generator by
|
|
78
|
+
construction: an adversarial reviewer always surfaces lows (that is its job),
|
|
79
|
+
fixing lows produces a new diff, and a new diff earned another re-review. It
|
|
80
|
+
produced PRs going four rounds where the last round's only finding was an
|
|
81
|
+
inaccurate doc comment. So:
|
|
82
|
+
|
|
83
|
+
- **Blockers and majors block the merge.** Fix them.
|
|
84
|
+
- **Lows do NOT block.** File a low as a follow-up issue rather than fixing it
|
|
85
|
+
now. Filing is mandatory — an unfiled low is a dropped bug, and there is no
|
|
86
|
+
human team to catch it later.
|
|
87
|
+
- **Fix what blocks, then merge on CI green.**
|
|
88
|
+
- **Do not count review rounds, and do not run a mandatory re-review pass.**
|
|
89
|
+
Verifying your own fix is part of making it, not a separate step. Counting
|
|
90
|
+
rounds was itself a loop driver: it made the review process the subject of
|
|
91
|
+
the work instead of the change.
|
|
92
|
+
|
|
93
|
+
If a finding is genuinely invalid, rebut it with evidence in writing; silence
|
|
94
|
+
is not a rebuttal.
|
|
95
|
+
|
|
96
|
+
## 5. Non-obvious pipeline rules
|
|
97
|
+
|
|
98
|
+
- **CI is the full-suite authority.** Local scoped tests are a fast filter,
|
|
99
|
+
never the merge evidence. Never claim done off a local run alone.
|
|
100
|
+
- **`main` is behind a merge queue: `gh pr merge` ENQUEUES, it does not
|
|
101
|
+
merge.** The command exits 0 and the PR stays `OPEN`. The queue then re-runs
|
|
102
|
+
all seven required contexts on its own `gh-readonly-queue/main/pr-<n>-<sha>`
|
|
103
|
+
ref before landing anything, so "green on the PR" is necessary but not
|
|
104
|
+
sufficient. Never report a PR merged off that exit code — poll until its
|
|
105
|
+
state is `MERGED` and the commit is an ancestor of `origin/main`. Two flags
|
|
106
|
+
to know: `--delete-branch` is **rejected outright** while the queue is on
|
|
107
|
+
(delete the branch after it lands), and `--subject` is ignored, since the
|
|
108
|
+
queue composes the merge commit from the PR title plus `(#<pr>)` — so the PR
|
|
109
|
+
title is the commit title, write it accordingly. An entry stuck in
|
|
110
|
+
`AWAITING_CHECKS` means a required workflow is not listening for
|
|
111
|
+
`merge_group`; `.github/MERGE-QUEUE.md` owns that failure mode and the
|
|
112
|
+
invariants that prevent it.
|
|
113
|
+
- **A test that wouldn't fail on the bug it guards is not a test.** Assert the
|
|
114
|
+
observable outcome, not that the code path executed.
|
|
115
|
+
- **Prefer a deterministic mechanism over prompt discipline.** If a check, a
|
|
116
|
+
hook, a schema, or a lint gate can enforce the guarantee, write that instead
|
|
117
|
+
of a convention — conventions demonstrably fail here.
|
|
118
|
+
- **Never go dark, and never foreground-watch over 30 seconds.** Builds, CI
|
|
119
|
+
waits, and deploys run in the background with a notification. Batch related
|
|
120
|
+
findings into one substantive update rather than five fragments. Cap
|
|
121
|
+
parallel sub-agents at 15.
|
|
@@ -100,7 +100,8 @@ The tag push triggers `docker-images` and `release`. `release` internally waits
|
|
|
100
100
|
|
|
101
101
|
### Gate B — the release pipeline (`release.yml`)
|
|
102
102
|
- `gh run list --workflow=release.yml --limit 1` — wait for `completed` / `success`. Expect ~25-30 minutes: four native build legs plus the wait on `docker-images`.
|
|
103
|
-
- Its jobs, in order: `guard` (release exists + held out of `latest`) → `build` ×4 → `bundle` → `publish` (attach) → `images-gate` (wait on docker-images) → `npm` → `finalize` (un-draft). A red job anywhere leaves the release a **draft** and npm **unpublished** — which is the correct, recoverable state.
|
|
103
|
+
- Its jobs, in order: `guard` (release exists + held out of `latest`) → `build` ×4 → `bundle` → `publish` (attach) → `images-gate` (wait on docker-images) → `npm` → `finalize` (un-draft) → `images-latest` (promote `:vX.Y.Z` → `:latest`). A red job anywhere leaves the release a **draft** and npm **unpublished** — which is the correct, recoverable state.
|
|
104
|
+
- `images-latest` is why a tag push no longer moves the `:latest` image tag by itself (#3685). If that last job is the one that failed, every other leg shipped and only the image tag lags: re-run it with `gh workflow run promote.yml -f from=vX.Y.Z -f to=latest`. Don't roll the fleet off `:latest` until it is green — `docker manifest inspect ghcr.io/switchroom/switchroom-agent:latest` should report the same digest as `:vX.Y.Z`.
|
|
104
105
|
- Verify the release page actually has assets **and is no longer a draft**:
|
|
105
106
|
```bash
|
|
106
107
|
gh release view vX.Y.Z -R switchroom/switchroom --json isDraft,assets \
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# bun test configuration for runs whose CWD is telegram-plugin/ — CI's
|
|
2
|
+
# `bun-test-run` job (scripts/bun-test-ci.sh) and `bun run --cwd telegram-plugin`.
|
|
3
|
+
#
|
|
4
|
+
# bun reads the bunfig.toml in its CWD only, so this file exists purely to load
|
|
5
|
+
# the same state-dir hermeticity preload as the repo-root bunfig.toml. Keep the
|
|
6
|
+
# two in sync; `npm run lint:agent-state-dir-hermeticity` fails if either stops
|
|
7
|
+
# loading the guard. Rationale for the guard itself lives in
|
|
8
|
+
# tests/vitest-setup/agent-state-dir-guard.mjs.
|
|
9
|
+
[test]
|
|
10
|
+
preload = ["../tests/vitest-setup/agent-state-dir-guard.mjs"]
|