instar 1.3.510 → 1.3.511

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.
@@ -0,0 +1,88 @@
1
+ # Side-Effects Review — WS4.3 read-side: GET /jobs?scope=pool + divergence detector
2
+
3
+ **Version / slug:** `multi-machine-seamlessness-ws43-jobs-pool-read`
4
+ **Date:** `2026-06-12`
5
+ **Author:** `Instar Agent (echo)`
6
+ **Second-pass reviewer:** `workflow adversarial reviewer (CONCUR — 1 LOW fixed)`
7
+
8
+ ## Summary of the change
9
+
10
+ The read-side of WS4.3 (MULTI-MACHINE-SEAMLESSNESS-SPEC §WS4.3): `GET /jobs?scope=pool`
11
+ merges every online peer's jobs into one view (which machine runs each job),
12
+ mirroring the proven `sessions?scope=pool` / WS4.1 `attention?scope=pool` family —
13
+ per-peer 5s timeout, `pool.failed[]` markers (never a 500), offline-peer skip, 3s
14
+ short-TTL cache, machine tagging. Plus an observe-only F8 placement-divergence
15
+ detector. Files: `src/server/routes.ts` (route + `jobsPoolMerge` + `detectJobDivergences`),
16
+ `src/scaffold/templates.ts` + `src/core/PostUpdateMigrator.ts` (Agent Awareness +
17
+ Migration Parity). The role-guard-at-spawn and journal-lease cutover are SEPARATE
18
+ follow-up slices (not in this PR). <!-- tracked: CMT-1416 -->
19
+
20
+ ## Decision-point inventory
21
+
22
+ - `GET /jobs?scope=pool` merge — **add** — read-only aggregation; never mutates a
23
+ job, never gates; tolerant fan-out.
24
+ - `detectJobDivergences` — **add** — observe-only signal in `pool.divergences[]`;
25
+ flags ONLY `declared>0 && running===0` (a machine that should run jobs but isn't).
26
+
27
+ ---
28
+
29
+ ## 1. Over-block
30
+ No block/allow surface — read-only. The divergence detector after the LOW fix flags
31
+ ONLY the real case (declares N>0, runs 0). A machine declaring 0 jobs is NOT flagged
32
+ (was self-noise — fixed: a scheduler-less/dispatcher-only machine legitimately has none).
33
+
34
+ ## 2. Under-block
35
+ Capacity carries no declared-job count, so divergence is derived from each machine's
36
+ own `/jobs` reply (declared = jobs returned, running = `runsOnThisMachine===true`
37
+ count). A machine that is DOWN (no reply) is in `pool.failed[]`, not `divergences` —
38
+ so a fully-dark machine's jobs aren't flagged as "running 0" (correct; it's a
39
+ reachability failure, surfaced separately). No fabricated counts.
40
+
41
+ ## 3. Level-of-abstraction fit
42
+ Right layer — mirrors the sessions/attention pool-scope route code exactly (same
43
+ fan-out/timeout/failed/cache/tag shape); the divergence helper is a pure function
44
+ over the merged replies.
45
+
46
+ ## 4. Signal vs authority compliance
47
+ Compliant — pure read + an observe-only signal. Gates nothing.
48
+
49
+ ## 5. Interactions
50
+ - Plain `GET /jobs` is byte-for-byte unchanged (`{jobs,queue}`; no `pool` object, no
51
+ machine tags) — only `?scope=pool` adds them.
52
+ - The cache key is fixed (`'jobs'`) and read/written only inside `jobsPoolMerge`;
53
+ there are no status/scope variants to cross-contaminate (stronger isolation than
54
+ attention's status-keyed cache).
55
+ - Peers are called WITHOUT `scope` → no recursive fan-out storm.
56
+
57
+ ## 6. External surfaces
58
+ - New query mode on an existing route; old callers (no `?scope=pool`) unaffected.
59
+ - Calls each peer's `GET /jobs` with the agent bearer (same pattern as
60
+ sessions/attention pool scope). An old peer returns its local jobs → merges fine.
61
+
62
+ ## Framework generality
63
+ No framework-launch abstraction touched (this is a read/merge route only; no change
64
+ to `frameworkSessionLaunch.ts`). The job model is framework-agnostic; the merge tags
65
+ machines, not frameworks. N/A beyond that.
66
+
67
+ ## 7. Multi-machine posture (Cross-Machine Coherence)
68
+ **proxied-on-read** — fans out to peers per request (cached 3s), each job tagged with
69
+ its owning machine; consults the pool registry's online flag to skip dark peers
70
+ cheaply. No replication, no durable cross-machine state in this slice. Phase-C clean:
71
+ per-online-peer fan-out, O(jobs) divergence, no 2-peer assumption.
72
+
73
+ ## 8. Rollback cost
74
+ Trivial: additive scope branch; reverting restores today's local-only `GET /jobs`.
75
+ No durable state; the CLAUDE.md migrator bullet is idempotent (content-sniffed).
76
+
77
+ ---
78
+
79
+ ## Second-pass review
80
+
81
+ Workflow adversarial reviewer: **CONCUR** (tscClean, testsPass; all 7 audit points
82
+ verified incl. tolerant fan-out, back-compat, cache isolation, observe-only +
83
+ no-fabricated-count divergence, non-recursive peers, awareness+migration parity,
84
+ tests proven failing pre-change). One **LOW**: a scheduler-less/no-jobs machine
85
+ self-flagged a "declares 0 jobs while online" divergence (self-noise). **FIXED**:
86
+ the detector now flags ONLY `declared>0 && running===0`; the 0-jobs case is dropped
87
+ (legitimate, not a divergence), and its test now asserts NO divergence for a
88
+ zero-jobs peer.