instar 1.3.272 → 1.3.274

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/dist/commands/server.d.ts.map +1 -1
  2. package/dist/commands/server.js +70 -0
  3. package/dist/commands/server.js.map +1 -1
  4. package/dist/core/MachinePoolRegistry.d.ts +3 -0
  5. package/dist/core/MachinePoolRegistry.d.ts.map +1 -1
  6. package/dist/core/MachinePoolRegistry.js +1 -0
  7. package/dist/core/MachinePoolRegistry.js.map +1 -1
  8. package/dist/core/PlacementExecutor.d.ts.map +1 -1
  9. package/dist/core/PlacementExecutor.js +28 -6
  10. package/dist/core/PlacementExecutor.js.map +1 -1
  11. package/dist/core/PostUpdateMigrator.d.ts.map +1 -1
  12. package/dist/core/PostUpdateMigrator.js +26 -1
  13. package/dist/core/PostUpdateMigrator.js.map +1 -1
  14. package/dist/core/SessionManager.d.ts.map +1 -1
  15. package/dist/core/SessionManager.js +7 -3
  16. package/dist/core/SessionManager.js.map +1 -1
  17. package/dist/core/types.d.ts +21 -0
  18. package/dist/core/types.d.ts.map +1 -1
  19. package/dist/core/types.js.map +1 -1
  20. package/dist/monitoring/SessionReaper.d.ts +19 -0
  21. package/dist/monitoring/SessionReaper.d.ts.map +1 -1
  22. package/dist/monitoring/SessionReaper.js +57 -0
  23. package/dist/monitoring/SessionReaper.js.map +1 -1
  24. package/dist/scaffold/templates.d.ts.map +1 -1
  25. package/dist/scaffold/templates.js +2 -0
  26. package/dist/scaffold/templates.js.map +1 -1
  27. package/package.json +1 -1
  28. package/src/data/builtin-manifest.json +20 -20
  29. package/src/scaffold/templates.ts +2 -0
  30. package/upgrades/1.3.273.md +52 -0
  31. package/upgrades/1.3.274.md +47 -0
  32. package/upgrades/side-effects/post-transfer-session-closeout.md +116 -0
  33. package/upgrades/side-effects/quota-aware-placement.md +99 -0
@@ -1 +1 @@
1
- {"version":3,"file":"templates.js","sourceRoot":"","sources":["../../src/scaffold/templates.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"templates.js","sourceRoot":"","sources":["../../src/scaffold/templates.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "instar",
3
- "version": "1.3.272",
3
+ "version": "1.3.274",
4
4
  "description": "Coherence infrastructure for self-evolving AI agents — on the Claude Code or Codex subscription you already have.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "$schema": "./builtin-manifest.schema.json",
3
3
  "schemaVersion": 1,
4
- "generatedAt": "2026-06-05T07:17:46.846Z",
5
- "instarVersion": "1.3.272",
4
+ "generatedAt": "2026-06-05T07:46:09.205Z",
5
+ "instarVersion": "1.3.274",
6
6
  "entryCount": 198,
7
7
  "entries": {
8
8
  "hook:session-start": {
@@ -11,7 +11,7 @@
11
11
  "domain": "identity",
12
12
  "sourcePath": "src/core/PostUpdateMigrator.ts",
13
13
  "installedPath": ".instar/hooks/instar/session-start.sh",
14
- "contentHash": "19d5f542d77a72d0df01407d083920148cf587463267dce415a1302cda5e93f4",
14
+ "contentHash": "3ded8ee5789307525929dba01a9550a49570129bce2db0d1d5c1f989ad6dbb3e",
15
15
  "since": "2025-01-01"
16
16
  },
17
17
  "hook:dangerous-command-guard": {
@@ -20,7 +20,7 @@
20
20
  "domain": "safety",
21
21
  "sourcePath": "src/core/PostUpdateMigrator.ts",
22
22
  "installedPath": ".instar/hooks/instar/dangerous-command-guard.sh",
23
- "contentHash": "19d5f542d77a72d0df01407d083920148cf587463267dce415a1302cda5e93f4",
23
+ "contentHash": "3ded8ee5789307525929dba01a9550a49570129bce2db0d1d5c1f989ad6dbb3e",
24
24
  "since": "2025-01-01"
25
25
  },
26
26
  "hook:grounding-before-messaging": {
@@ -29,7 +29,7 @@
29
29
  "domain": "safety",
30
30
  "sourcePath": "src/core/PostUpdateMigrator.ts",
31
31
  "installedPath": ".instar/hooks/instar/grounding-before-messaging.sh",
32
- "contentHash": "19d5f542d77a72d0df01407d083920148cf587463267dce415a1302cda5e93f4",
32
+ "contentHash": "3ded8ee5789307525929dba01a9550a49570129bce2db0d1d5c1f989ad6dbb3e",
33
33
  "since": "2025-01-01"
34
34
  },
35
35
  "hook:compaction-recovery": {
@@ -38,7 +38,7 @@
38
38
  "domain": "identity",
39
39
  "sourcePath": "src/core/PostUpdateMigrator.ts",
40
40
  "installedPath": ".instar/hooks/instar/compaction-recovery.sh",
41
- "contentHash": "19d5f542d77a72d0df01407d083920148cf587463267dce415a1302cda5e93f4",
41
+ "contentHash": "3ded8ee5789307525929dba01a9550a49570129bce2db0d1d5c1f989ad6dbb3e",
42
42
  "since": "2025-01-01"
43
43
  },
44
44
  "hook:external-operation-gate": {
@@ -47,7 +47,7 @@
47
47
  "domain": "safety",
48
48
  "sourcePath": "src/core/PostUpdateMigrator.ts",
49
49
  "installedPath": ".instar/hooks/instar/external-operation-gate.js",
50
- "contentHash": "19d5f542d77a72d0df01407d083920148cf587463267dce415a1302cda5e93f4",
50
+ "contentHash": "3ded8ee5789307525929dba01a9550a49570129bce2db0d1d5c1f989ad6dbb3e",
51
51
  "since": "2025-01-01"
52
52
  },
53
53
  "hook:deferral-detector": {
@@ -56,7 +56,7 @@
56
56
  "domain": "safety",
57
57
  "sourcePath": "src/core/PostUpdateMigrator.ts",
58
58
  "installedPath": ".instar/hooks/instar/deferral-detector.js",
59
- "contentHash": "19d5f542d77a72d0df01407d083920148cf587463267dce415a1302cda5e93f4",
59
+ "contentHash": "3ded8ee5789307525929dba01a9550a49570129bce2db0d1d5c1f989ad6dbb3e",
60
60
  "since": "2025-01-01"
61
61
  },
62
62
  "hook:self-stop-guard": {
@@ -65,7 +65,7 @@
65
65
  "domain": "coherence",
66
66
  "sourcePath": "src/core/PostUpdateMigrator.ts",
67
67
  "installedPath": ".instar/hooks/instar/self-stop-guard.js",
68
- "contentHash": "19d5f542d77a72d0df01407d083920148cf587463267dce415a1302cda5e93f4",
68
+ "contentHash": "3ded8ee5789307525929dba01a9550a49570129bce2db0d1d5c1f989ad6dbb3e",
69
69
  "since": "2025-01-01"
70
70
  },
71
71
  "hook:post-action-reflection": {
@@ -74,7 +74,7 @@
74
74
  "domain": "evolution",
75
75
  "sourcePath": "src/core/PostUpdateMigrator.ts",
76
76
  "installedPath": ".instar/hooks/instar/post-action-reflection.js",
77
- "contentHash": "19d5f542d77a72d0df01407d083920148cf587463267dce415a1302cda5e93f4",
77
+ "contentHash": "3ded8ee5789307525929dba01a9550a49570129bce2db0d1d5c1f989ad6dbb3e",
78
78
  "since": "2025-01-01"
79
79
  },
80
80
  "hook:external-communication-guard": {
@@ -83,7 +83,7 @@
83
83
  "domain": "safety",
84
84
  "sourcePath": "src/core/PostUpdateMigrator.ts",
85
85
  "installedPath": ".instar/hooks/instar/external-communication-guard.js",
86
- "contentHash": "19d5f542d77a72d0df01407d083920148cf587463267dce415a1302cda5e93f4",
86
+ "contentHash": "3ded8ee5789307525929dba01a9550a49570129bce2db0d1d5c1f989ad6dbb3e",
87
87
  "since": "2025-01-01"
88
88
  },
89
89
  "hook:scope-coherence-collector": {
@@ -92,7 +92,7 @@
92
92
  "domain": "coherence",
93
93
  "sourcePath": "src/core/PostUpdateMigrator.ts",
94
94
  "installedPath": ".instar/hooks/instar/scope-coherence-collector.js",
95
- "contentHash": "19d5f542d77a72d0df01407d083920148cf587463267dce415a1302cda5e93f4",
95
+ "contentHash": "3ded8ee5789307525929dba01a9550a49570129bce2db0d1d5c1f989ad6dbb3e",
96
96
  "since": "2025-01-01"
97
97
  },
98
98
  "hook:scope-coherence-checkpoint": {
@@ -101,7 +101,7 @@
101
101
  "domain": "coherence",
102
102
  "sourcePath": "src/core/PostUpdateMigrator.ts",
103
103
  "installedPath": ".instar/hooks/instar/scope-coherence-checkpoint.js",
104
- "contentHash": "19d5f542d77a72d0df01407d083920148cf587463267dce415a1302cda5e93f4",
104
+ "contentHash": "3ded8ee5789307525929dba01a9550a49570129bce2db0d1d5c1f989ad6dbb3e",
105
105
  "since": "2025-01-01"
106
106
  },
107
107
  "hook:free-text-guard": {
@@ -110,7 +110,7 @@
110
110
  "domain": "safety",
111
111
  "sourcePath": "src/core/PostUpdateMigrator.ts",
112
112
  "installedPath": ".instar/hooks/instar/free-text-guard.sh",
113
- "contentHash": "19d5f542d77a72d0df01407d083920148cf587463267dce415a1302cda5e93f4",
113
+ "contentHash": "3ded8ee5789307525929dba01a9550a49570129bce2db0d1d5c1f989ad6dbb3e",
114
114
  "since": "2025-01-01"
115
115
  },
116
116
  "hook:claim-intercept": {
@@ -119,7 +119,7 @@
119
119
  "domain": "coherence",
120
120
  "sourcePath": "src/core/PostUpdateMigrator.ts",
121
121
  "installedPath": ".instar/hooks/instar/claim-intercept.js",
122
- "contentHash": "19d5f542d77a72d0df01407d083920148cf587463267dce415a1302cda5e93f4",
122
+ "contentHash": "3ded8ee5789307525929dba01a9550a49570129bce2db0d1d5c1f989ad6dbb3e",
123
123
  "since": "2025-01-01"
124
124
  },
125
125
  "hook:claim-intercept-response": {
@@ -128,7 +128,7 @@
128
128
  "domain": "coherence",
129
129
  "sourcePath": "src/core/PostUpdateMigrator.ts",
130
130
  "installedPath": ".instar/hooks/instar/claim-intercept-response.js",
131
- "contentHash": "19d5f542d77a72d0df01407d083920148cf587463267dce415a1302cda5e93f4",
131
+ "contentHash": "3ded8ee5789307525929dba01a9550a49570129bce2db0d1d5c1f989ad6dbb3e",
132
132
  "since": "2025-01-01"
133
133
  },
134
134
  "hook:stop-gate-router": {
@@ -137,7 +137,7 @@
137
137
  "domain": "safety",
138
138
  "sourcePath": "src/core/PostUpdateMigrator.ts",
139
139
  "installedPath": ".instar/hooks/instar/stop-gate-router.js",
140
- "contentHash": "19d5f542d77a72d0df01407d083920148cf587463267dce415a1302cda5e93f4",
140
+ "contentHash": "3ded8ee5789307525929dba01a9550a49570129bce2db0d1d5c1f989ad6dbb3e",
141
141
  "since": "2025-01-01"
142
142
  },
143
143
  "hook:auto-approve-permissions": {
@@ -146,7 +146,7 @@
146
146
  "domain": "safety",
147
147
  "sourcePath": "src/core/PostUpdateMigrator.ts",
148
148
  "installedPath": ".instar/hooks/instar/auto-approve-permissions.js",
149
- "contentHash": "19d5f542d77a72d0df01407d083920148cf587463267dce415a1302cda5e93f4",
149
+ "contentHash": "3ded8ee5789307525929dba01a9550a49570129bce2db0d1d5c1f989ad6dbb3e",
150
150
  "since": "2025-01-01"
151
151
  },
152
152
  "job:health-check": {
@@ -1506,7 +1506,7 @@
1506
1506
  "type": "subsystem",
1507
1507
  "domain": "sessions",
1508
1508
  "sourcePath": "src/core/SessionManager.ts",
1509
- "contentHash": "a81bb8757e0c6d92510d7ca7d0b6dc4975b11f21ec8d7664616d0bc07fcfbc93",
1509
+ "contentHash": "632f0930e03da8cfe8b7df7ec72e256d2606230b21f84fb277c677a0572e042a",
1510
1510
  "since": "2025-01-01"
1511
1511
  },
1512
1512
  "subsystem:auto-updater": {
@@ -1530,7 +1530,7 @@
1530
1530
  "type": "subsystem",
1531
1531
  "domain": "updates",
1532
1532
  "sourcePath": "src/core/PostUpdateMigrator.ts",
1533
- "contentHash": "19d5f542d77a72d0df01407d083920148cf587463267dce415a1302cda5e93f4",
1533
+ "contentHash": "3ded8ee5789307525929dba01a9550a49570129bce2db0d1d5c1f989ad6dbb3e",
1534
1534
  "since": "2025-01-01"
1535
1535
  },
1536
1536
  "subsystem:scheduler": {
@@ -455,6 +455,8 @@ This routes feedback to the Instar maintainers automatically. Valid types: \`bug
455
455
  **Multi-Machine Session Pool (active-active — spread conversations across machines)** — The longer arc beyond one-awake-machine: with the pool enabled I run conversations across ALL my machines at once and can MOVE a conversation between them. Ships DARK behind \`multiMachine.sessionPool.stage\` (default 'dark'); a single-machine agent is a no-op.
456
456
  - **See the pool:** the **Machines tab** in the dashboard, or \`curl -H "Authorization: Bearer $AUTH" http://localhost:${port}/pool\` → which machine is the router ("dispatcher") + every machine's nickname, hardware, online status, load, and clock-skew status.
457
457
  - **Every session, every machine:** the dashboard sessions list shows ALL sessions across the pool, each tagged with the machine it runs on. API: \`curl -H "Authorization: Bearer $AUTH" "http://localhost:${port}/sessions?scope=pool"\` → \`{ sessions: [...each with machineId/machineNickname...], pool: { peersOk, failed } }\`. An unreachable peer degrades to a \`failed\` entry — local sessions always answer.
458
+ - **Post-transfer closeout (automatic):** when a topic moves to another machine, the OLD machine's session for it is closed automatically (immediately on an explicit "move", or within ~2 reaper ticks for any other path) — no duplicate sessions doing duplicate work. The close is recorded in the reap-log with reason "topic moved to <machine>"; protected sessions are never auto-closed.
459
+ - **Quota-aware placement (automatic):** capacity heartbeats carry each machine's LLM-account quota state, and placement avoids machines whose account is currently rate-limited/blocked (no more topics placed onto a silent machine). A hard pin still wins (flagged \`pinned-machine-quota-blocked\`); if EVERY machine is blocked, placement proceeds least-loaded with \`all-machines-quota-blocked\` flagged. \`GET /pool\` shows each machine's \`quotaState\`.
458
460
  - **Machine nicknames** are the user-facing handle (auto-assigned, editable). Rename: \`curl -X PATCH -H "Authorization: Bearer $AUTH" http://localhost:${port}/pool/machines/MACHINE_ID -H 'Content-Type: application/json' -d '{"nickname":"the mini"}'\` (or inline on the Machines tab).
459
461
  - **Which machine + WHY (never guess):** \`curl -H "Authorization: Bearer $AUTH" "http://localhost:${port}/pool/placement?topic=N"\` → the owning machine + nickname, the **reason** (\`pinned\` = a deliberate move vs \`placed\` = load-balanced vs \`unowned\`), and the lease-holder. Answerable from ANY machine (a standby proxies to the holder, whose pin store is authoritative). Use this instead of inferring placement from a hostname — running ON a machine does NOT mean a topic was deliberately moved there.
460
462
  - **Reliable transfer (phrasing-independent):** \`curl -X POST -H "Authorization: Bearer $AUTH" http://localhost:${port}/pool/transfer -H 'Content-Type: application/json' -d '{"topic":N,"to":"<nickname|machineId>"}'\` → runs the same validated planner as "move this to <nickname>" but deterministically (no NL recognition). 404 unknown machine · 409 rate-limited · 409 \`needsConfirmation\` for an offline target (re-send with \`"confirm":true\`). This is the lever to call directly when a natural-language move didn't catch.
@@ -0,0 +1,52 @@
1
+ # Upgrade Guide — vNEXT
2
+
3
+ <!-- assembled-by: assemble-next-md -->
4
+ <!-- bump: patch -->
5
+
6
+ ## What Changed
7
+
8
+ When a conversation (topic) moves from one machine to another in the
9
+ multi-machine session pool, the OLD machine's session for that topic is now
10
+ closed automatically — previously it lingered indefinitely, doing duplicate
11
+ work alongside the new machine's session (the operator-named duplicate-sessions
12
+ issue).
13
+
14
+ Two layers:
15
+
16
+ 1. **Immediate** — an explicit "move this to X" closes the local session the
17
+ moment the move executes (the user's command is the authority; protected
18
+ sessions are never auto-closed; the close is silent since the user already
19
+ got the "Moving…" confirmation).
20
+ 2. **Standing invariant** — the SessionReaper closes any topic-bound session
21
+ whose topic the ownership registry shows owned by ANOTHER machine, after a
22
+ 2-tick (~4 min) dwell that absorbs in-progress transfers. This covers
23
+ failovers and automatic re-placements. The close goes through the existing
24
+ guarded terminate authority: a KEEP-guard veto is audited and retried, never
25
+ forced. Works even when the duplicate is BUSY — busy-on-a-duplicate is the
26
+ bug.
27
+
28
+ Every close (and every refusal) lands in the reap-log with reason "topic moved
29
+ to <machine>". Config: `monitoring.sessionReaper.topicMovedCloseout` (default
30
+ true; inert on single-machine installs) + `topicMovedConfirmTicks` (default 2).
31
+
32
+ ## What to Tell Your User
33
+
34
+ When you move a conversation to another machine, the machine you left now
35
+ cleans up after itself — no more duplicate sessions quietly doing the same
36
+ work twice. If you ever wonder where a session went, the reap-log says exactly
37
+ why ("topic moved to Laptop").
38
+
39
+ ## Summary of New Capabilities
40
+
41
+ - Explicit topic moves immediately close the old machine's session.
42
+ - A reaper rule guarantees eventual closeout for failover/re-placement paths.
43
+ - `monitoring.sessionReaper.topicMovedCloseout` / `topicMovedConfirmTicks` config.
44
+ - Reap-log + audit rows (`rule: 'topic-moved-away'`) for full traceability.
45
+ - CLAUDE.md template + migration so agents explain auto-closed sessions correctly.
46
+
47
+ ## Evidence
48
+
49
+ `tests/unit/session-reaper-topic-moved.test.ts` (9 — including closing a BUSY
50
+ duplicate, churn-resets-dwell, guard-veto-retry, dry-run, budgets, all inert
51
+ paths) + 3 migration tests; full reaper family regression 65/65 green; tsc +
52
+ lint clean.
@@ -0,0 +1,47 @@
1
+ # Upgrade Guide — vNEXT
2
+
3
+ <!-- assembled-by: assemble-next-md -->
4
+ <!-- bump: patch -->
5
+
6
+ ## What Changed
7
+
8
+ The multi-machine session pool no longer places conversations onto a machine
9
+ whose LLM account is rate-limited or quota-blocked. Each machine's 30-second
10
+ capacity heartbeat now self-reports a `quotaState` (provider block in effect,
11
+ or the 5-hour window ≥95% — read strictly from that machine's OWN quota
12
+ tracker), and the placement engine:
13
+
14
+ - drops quota-blocked machines from the candidate pool (new placements,
15
+ soft preferences, AND stickiness — a conversation currently on a machine
16
+ that becomes blocked moves off it on the next message);
17
+ - still honors an explicit hard pin to a blocked machine (the user's command
18
+ wins), flagged `pinned-machine-quota-blocked` so the user can be told why
19
+ it's quiet;
20
+ - falls back to least-loaded-among-blocked when EVERY machine is blocked,
21
+ flagged `all-machines-quota-blocked`.
22
+
23
+ Older machines that don't report the field are treated as not blocked —
24
+ mixed-version pools behave exactly as before. `GET /pool` shows each
25
+ machine's `quotaState`.
26
+
27
+ ## What to Tell Your User
28
+
29
+ Your messages stop landing on a machine whose AI account has hit its limit —
30
+ the pool quietly routes conversations to a machine that can actually answer.
31
+ The only way to stay on a rate-limited machine is to have pinned the
32
+ conversation there yourself, and then I can tell you exactly why it's quiet
33
+ and when the limit resets.
34
+
35
+ ## Summary of New Capabilities
36
+
37
+ - Per-machine `quotaState` in capacity heartbeats + `GET /pool`.
38
+ - Placement avoids quota-blocked machines; blocked owners lose stickiness.
39
+ - Hard pins win with a `pinned-machine-quota-blocked` flag; all-blocked
40
+ pools place least-loaded with `all-machines-quota-blocked`.
41
+
42
+ ## Evidence
43
+
44
+ `tests/unit/PlacementExecutor.test.ts` +8 (including the verbatim incident
45
+ case — a quota-blocked current owner loses stickiness) with all 29
46
+ pre-existing placement tests green; `tests/unit/MachinePoolRegistry.test.ts`
47
+ +1 (passthrough + clears on a quota-free heartbeat). tsc + lint clean.
@@ -0,0 +1,116 @@
1
+ # Side-Effects Review — Post-transfer session closeout
2
+
3
+ **Version / slug:** `post-transfer-session-closeout`
4
+ **Date:** `2026-06-05`
5
+ **Author:** `echo`
6
+ **Second-pass reviewer:** `not required` (kill-path change, but every kill goes through the existing terminate authority; every boundary side test-pinned; inert single-machine)
7
+
8
+ ## Summary of the change
9
+
10
+ Two halves closing the operator-named duplicate-sessions gap: (A) the transfer
11
+ handler immediately closes the local topic session when the user explicitly
12
+ moves a topic to another machine (operator origin, protected-skipped, silent
13
+ recovery-bounce disposition); (B) a SessionReaper rule closes any topic-bound
14
+ session whose topic the ownership registry shows OWNED BY ANOTHER MACHINE,
15
+ after a 2-tick dwell, through the guarded autonomous terminate (vetoes audited
16
+ + retried). New `topicOwnerElsewhere` reaper dep late-binds the pool objects;
17
+ config `monitoring.sessionReaper.topicMovedCloseout` (default true) +
18
+ `topicMovedConfirmTicks` (default 2).
19
+
20
+ ## Decision-point inventory
21
+
22
+ 1. Plan is `transfer` to another machine vs `noop`/self → immediate close vs
23
+ none. Covered by the rule conditions + transfer tests from #790 (noop paths
24
+ unchanged).
25
+ 2. Session protected → immediate close skipped (and the sweeper's guard veto
26
+ path). Pinned via reaper-family protected test + the explicit skip.
27
+ 3. Topic owned elsewhere vs by-self vs unowned vs no binding vs dep absent →
28
+ sweeper fires vs inert. All five pinned.
29
+ 4. Dwell below/at threshold; churn reset. Pinned.
30
+ 5. killsEnabled (enabled/dryRun/auto-disabled) → terminate vs `would-reap`
31
+ audit. Pinned.
32
+ 6. Guard veto → `reap-skipped-topic-moved` + retry. Pinned.
33
+ 7. Per-tick + hourly budgets. Pinned (per-tick), hourly shares the existing
34
+ tested budget mechanism.
35
+
36
+ ## 1. Over-block
37
+
38
+ The rule only ever closes MORE sessions, never keeps one it shouldn't — the
39
+ risk axis is over-KILLING, addressed in Under-block. No legitimate
40
+ operation is rejected; single-machine installs are bit-identical in behavior
41
+ (dep absent → rule unreachable).
42
+
43
+ ## 2. Under-block (over-kill risk — the one that matters)
44
+
45
+ - **Wrong-owner false positive:** the ownership registry is the same source
46
+ routing already trusts; a 2-tick dwell absorbs CAS churn mid-transfer, and
47
+ churn RESETS the dwell (test-pinned). Worst case (registry wrong for >2
48
+ ticks): the session closes while the registry routes messages to the other
49
+ machine anyway — the close follows the routing truth, not vice versa.
50
+ - **In-flight work on the duplicate:** deliberately closable — duplicate work
51
+ is the bug (operator's words). The sweeper still honors KEEP-guard vetoes
52
+ (retry, not force); the immediate half is the user's explicit command.
53
+ - **Protected sessions:** never auto-closed on either half.
54
+ - **Half A races the release CAS:** the close is fired after the release
55
+ attempt regardless of CAS outcome — but only when `plan.action ===
56
+ 'transfer'`, which already passed the planner's owner/pin checks; a failed
57
+ CAS still means the user commanded the move, and the pin routes the next
58
+ message away from this machine.
59
+
60
+ ## 3. Level-of-abstraction fit
61
+
62
+ The immediate half lives in the one handler that executes user moves; the
63
+ invariant lives in the reaper — the component whose job is "sessions that
64
+ should not be running, aren't" — via an injected signal, keeping
65
+ SessionReaper free of pool imports (fully unit-testable, same pattern as
66
+ every other dep). The terminate authority remains the single kill funnel.
67
+
68
+ ## 4. Signal vs authority compliance
69
+
70
+ **Required reference:** [docs/signal-vs-authority.md](../../docs/signal-vs-authority.md)
71
+
72
+ The sweeper REQUESTS kills through the guarded authority (autonomous origin —
73
+ vetoes win). The immediate half uses operator origin, which is the documented
74
+ user-command bypass; the terminateSession doc comment is updated to name this
75
+ second stamp site, and protected sessions are excluded before the call so the
76
+ bypass never reaches them on this path.
77
+
78
+ ## 5. Interactions
79
+
80
+ - ReapGuard/ReapAuthority untouched — same funnel, same vetoes.
81
+ - Reap-log + §P3 notifier: sweeper closes are `terminal` (one honest "session
82
+ was shut down — topic moved to X" notice via the existing reapNotify);
83
+ Half A is `recovery-bounce` (silent — the user just got "Moving…").
84
+ - Ownership registry is read-only here (ownerOf) — no new writers.
85
+ - The dep's try/catch absorbs the construction-order TDZ window (reaper is
86
+ built before the mesh block wires the registry) — rule inert until wired.
87
+
88
+ ## 6. External surfaces
89
+
90
+ Two config keys (defaults preserve behavior except the new closeout itself,
91
+ which is the fix). New audit rows (`rule: 'topic-moved-away'`,
92
+ `reap-skipped-topic-moved`). CLAUDE.md template line + idempotent append
93
+ migration. No routes, no schema.
94
+
95
+ ## 7. Rollback cost
96
+
97
+ `monitoring.sessionReaper.topicMovedCloseout: false` is an instant per-agent
98
+ off-switch; full revert restores the old lingering behavior. No state.
99
+
100
+ ## Conclusion
101
+
102
+ The operator-named duplicate-session bug closed at both speeds — instantly on
103
+ the explicit command, eventually-but-guaranteed everywhere else — without a
104
+ single new kill path outside the existing authority.
105
+
106
+ ## Second-pass review (if required)
107
+
108
+ Not required — see header.
109
+
110
+ ## Evidence pointers
111
+
112
+ - `tests/unit/session-reaper-topic-moved.test.ts` (9) — incl. the headline
113
+ "closes a BUSY duplicate" case.
114
+ - `tests/unit/PostUpdateMigrator-poolSessionsVisibility.test.ts` (+3).
115
+ - Reaper family regression 65/65 green; tsc clean.
116
+ - `docs/specs/post-transfer-session-closeout.md` + `.eli16.md`.
@@ -0,0 +1,99 @@
1
+ # Side-Effects Review — Quota-aware placement
2
+
3
+ **Version / slug:** `quota-aware-placement`
4
+ **Date:** `2026-06-05`
5
+ **Author:** `echo`
6
+ **Second-pass reviewer:** `not required` (pure-function gate + additive optional field; absent field = bit-identical behavior; every boundary side test-pinned)
7
+
8
+ ## Summary of the change
9
+
10
+ Capacity heartbeats self-report a per-machine `quotaState` (from THIS
11
+ machine's own QuotaTracker: provider block active OR 5-hour ≥95%), the
12
+ registry passes it through to `MachineCapacity`, and `PlacementExecutor`
13
+ drops quota-blocked machines from the candidate pool — with a
14
+ place-somewhere fallback when ALL are blocked (`all-machines-quota-blocked`)
15
+ and a pin-wins exception (`pinned-machine-quota-blocked`).
16
+
17
+ ## Decision-point inventory
18
+
19
+ 1. Heartbeat quota computation: block active / 5h exhausted / neither /
20
+ tracker absent / tracker throws. All produce defined outputs (blocked /
21
+ blocked / not-blocked / omitted / omitted); the omitted side = not blocked.
22
+ 2. Gate: blocked machine vs not vs absent-field vs `blocked:false`. All four
23
+ pinned.
24
+ 3. All-blocked fallback vs some-unblocked. Both pinned.
25
+ 4. Hard pin to blocked (honored+flagged) vs soft preference (degrades) vs
26
+ sticky owner blocked (loses stickiness — the incident case). All pinned.
27
+ 5. Pin path capability check preserved (never capability-blind). Pinned.
28
+
29
+ ## 1. Over-block
30
+
31
+ A quota-blocked machine still serves: hard pins, the all-blocked fallback,
32
+ and every EXISTING session (placement only affects new/re-placements — the
33
+ gate cannot strand a running conversation). A false `blocked: true`
34
+ self-report (tracker over-reporting) shifts new placements to peers, which is
35
+ exactly the desired degraded behavior; the worst case equals today's behavior
36
+ when all machines report blocked.
37
+
38
+ ## 2. Under-block
39
+
40
+ - A false `blocked: false` (stale tracker file) reproduces today's behavior —
41
+ never worse than the status quo.
42
+ - The signal refreshes every 30s heartbeat; a block that begins mid-window is
43
+ seen at most 30s late.
44
+ - A topic already on a machine that becomes blocked moves only on its NEXT
45
+ message (placement is per-message by design) — no proactive eviction here.
46
+
47
+ ## 3. Level-of-abstraction fit
48
+
49
+ The quota READ lives on the machine that owns the account (heartbeat
50
+ producer); the DECISION lives in the one pure placement function every
51
+ placement flows through; the registry is a dumb passthrough. No new
52
+ cross-machine channel — the signal rides the existing heartbeat.
53
+
54
+ ## 4. Signal vs authority compliance
55
+
56
+ **Required reference:** [docs/signal-vs-authority.md](../../docs/signal-vs-authority.md)
57
+
58
+ The gate redirects NEW placements only; it never kills, blocks a message, or
59
+ overrides the user (pin wins). Failure modes degrade to current behavior
60
+ (absent/unknown = not blocked); the heartbeat computation is try/caught with
61
+ an explicit unknown ≠ blocked rule.
62
+
63
+ ## 5. Interactions
64
+
65
+ - Stickiness intentionally weakened for blocked owners — that IS the incident
66
+ fix; hysteresis still applies among unblocked candidates.
67
+ - The gemini quota-conflation lesson honored: each machine reads only its own
68
+ QuotaTracker — no cross-machine quota file reads.
69
+ - Mixed-version pools safe: older machines simply omit the field.
70
+ - `GET /pool` and the Machines tab now show `quotaState` (additive).
71
+
72
+ ## 6. External surfaces
73
+
74
+ One optional field on `MachineCapacity`/`HeartbeatObservation` (additive,
75
+ visible in `GET /pool`). No config, no routes, no migration (absence =
76
+ default). CLAUDE.md template line + idempotent append migration.
77
+
78
+ ## 7. Rollback cost
79
+
80
+ Trivial — revert the PR; the field disappears from heartbeats and the gate
81
+ from decide(). No state, no schema.
82
+
83
+ ## Conclusion
84
+
85
+ The quota-blind placement hole closed at the pure-function layer with
86
+ strictly-degrading failure modes: every uncertain case behaves exactly like
87
+ today.
88
+
89
+ ## Second-pass review (if required)
90
+
91
+ Not required — see header.
92
+
93
+ ## Evidence pointers
94
+
95
+ - `tests/unit/PlacementExecutor.test.ts` (+8, incl. the verbatim incident
96
+ case: a blocked current owner loses stickiness).
97
+ - `tests/unit/MachinePoolRegistry.test.ts` (+1 passthrough + clears-on-next-heartbeat).
98
+ - 29 pre-existing placement tests green; tsc + lint clean.
99
+ - `docs/specs/quota-aware-placement.md` + `.eli16.md`.