instar 1.3.365 → 1.3.367

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 (70) hide show
  1. package/dist/commands/server.d.ts.map +1 -1
  2. package/dist/commands/server.js +200 -1
  3. package/dist/commands/server.js.map +1 -1
  4. package/dist/config/ConfigDefaults.d.ts.map +1 -1
  5. package/dist/config/ConfigDefaults.js +18 -0
  6. package/dist/config/ConfigDefaults.js.map +1 -1
  7. package/dist/core/IntentTestHarness.d.ts +27 -0
  8. package/dist/core/IntentTestHarness.d.ts.map +1 -1
  9. package/dist/core/IntentTestHarness.js +91 -0
  10. package/dist/core/IntentTestHarness.js.map +1 -1
  11. package/dist/core/MeshRpc.d.ts +8 -0
  12. package/dist/core/MeshRpc.d.ts.map +1 -1
  13. package/dist/core/MeshRpc.js +6 -1
  14. package/dist/core/MeshRpc.js.map +1 -1
  15. package/dist/core/PeerPresencePuller.d.ts +6 -0
  16. package/dist/core/PeerPresencePuller.d.ts.map +1 -1
  17. package/dist/core/PeerPresencePuller.js +5 -0
  18. package/dist/core/PeerPresencePuller.js.map +1 -1
  19. package/dist/core/PeerVisibilityGuard.d.ts +83 -0
  20. package/dist/core/PeerVisibilityGuard.d.ts.map +1 -0
  21. package/dist/core/PeerVisibilityGuard.js +204 -0
  22. package/dist/core/PeerVisibilityGuard.js.map +1 -0
  23. package/dist/core/PendingPullLedger.d.ts +129 -0
  24. package/dist/core/PendingPullLedger.d.ts.map +1 -0
  25. package/dist/core/PendingPullLedger.js +239 -0
  26. package/dist/core/PendingPullLedger.js.map +1 -0
  27. package/dist/core/PostUpdateMigrator.d.ts.map +1 -1
  28. package/dist/core/PostUpdateMigrator.js +20 -0
  29. package/dist/core/PostUpdateMigrator.js.map +1 -1
  30. package/dist/core/WorkingSetManifest.d.ts +2 -0
  31. package/dist/core/WorkingSetManifest.d.ts.map +1 -1
  32. package/dist/core/WorkingSetManifest.js +13 -1
  33. package/dist/core/WorkingSetManifest.js.map +1 -1
  34. package/dist/core/WorkingSetPull.d.ts +157 -0
  35. package/dist/core/WorkingSetPull.d.ts.map +1 -0
  36. package/dist/core/WorkingSetPull.js +546 -0
  37. package/dist/core/WorkingSetPull.js.map +1 -0
  38. package/dist/core/WorkingSetPullCoordinator.d.ts +134 -0
  39. package/dist/core/WorkingSetPullCoordinator.d.ts.map +1 -0
  40. package/dist/core/WorkingSetPullCoordinator.js +306 -0
  41. package/dist/core/WorkingSetPullCoordinator.js.map +1 -0
  42. package/dist/core/types.d.ts +43 -1
  43. package/dist/core/types.d.ts.map +1 -1
  44. package/dist/core/types.js.map +1 -1
  45. package/dist/redteam/ScenarioPack.d.ts +30 -3
  46. package/dist/redteam/ScenarioPack.d.ts.map +1 -1
  47. package/dist/redteam/ScenarioPack.js +46 -1
  48. package/dist/redteam/ScenarioPack.js.map +1 -1
  49. package/dist/scaffold/templates.d.ts.map +1 -1
  50. package/dist/scaffold/templates.js +4 -0
  51. package/dist/scaffold/templates.js.map +1 -1
  52. package/dist/server/AgentServer.d.ts +3 -0
  53. package/dist/server/AgentServer.d.ts.map +1 -1
  54. package/dist/server/AgentServer.js +1 -0
  55. package/dist/server/AgentServer.js.map +1 -1
  56. package/dist/server/routes.d.ts +5 -0
  57. package/dist/server/routes.d.ts.map +1 -1
  58. package/dist/server/routes.js +47 -1
  59. package/dist/server/routes.js.map +1 -1
  60. package/package.json +1 -1
  61. package/src/data/builtin-manifest.json +64 -64
  62. package/src/data/state-coherence-registry.json +48 -12
  63. package/src/scaffold/templates.ts +4 -0
  64. package/upgrades/{1.3.365.md → 1.3.366.md} +35 -0
  65. package/upgrades/1.3.367.md +134 -0
  66. package/upgrades/side-effects/intent-llm-judge.md +94 -0
  67. package/upgrades/side-effects/working-set-ci-absorb.md +29 -0
  68. package/upgrades/side-effects/working-set-parity-absorb.md +35 -0
  69. package/upgrades/side-effects/working-set-pull-p22a.md +121 -0
  70. package/upgrades/side-effects/working-set-trigger-p22b.md +115 -0
@@ -0,0 +1,204 @@
1
+ /**
2
+ * PeerVisibilityGuard — P2.2 rider (WORKING-SET-HANDOFF-SPEC §3.6): improper
3
+ * revocations and silently-missing peers must surface LOUDLY.
4
+ *
5
+ * Earned 2026-06-06: the Mini was revoked with NO `revokedBy`/`revokeReason`
6
+ * (a write that bypassed `revokeMachine()`), making it invisible to the mesh
7
+ * for ~10 hours while it held a topic's entire overnight working set.
8
+ *
9
+ * Two detections, both HYGIENE SIGNALS (they detect sloppy state, not
10
+ * malicious action — populated fields are NOT authenticated and must never
11
+ * be read as "this revocation is legitimate"):
12
+ *
13
+ * 1. `detectImproperRevocations(registry)` — a PURE helper (deliberately NOT
14
+ * inside `loadRegistry()`, a hot dependency-free read called 41+ times
15
+ * per boot): an entry with `revokedAt` set but `revokedBy`/`revokeReason`
16
+ * missing. The consumer surfaces findings via the agent-health attention
17
+ * lane, deduped ACROSS boots keyed on the entry's `revokedAt` (a
18
+ * crash-loop cannot re-spam it).
19
+ *
20
+ * 2. Peer-disappearance notice — pool transitions from N≥2 online to fewer
21
+ * and stays past a 30-min grace → ONE agent-health notice naming the
22
+ * machine + last known reason, and — when pending-pulls reference it —
23
+ * the stranded topic working sets. Coalesced per machine per episode;
24
+ * FLAP-BOUNDED: 3 episodes for one machine in 24h collapses to a single
25
+ * "machine X is flapping" notice (Bounded Notification Surface). Clears
26
+ * silently on stable re-peer.
27
+ */
28
+ import fs from 'node:fs';
29
+ import path from 'node:path';
30
+ export const DEFAULT_DISAPPEARANCE_GRACE_MS = 30 * 60 * 1000;
31
+ export const FLAP_EPISODE_LIMIT = 3;
32
+ export const FLAP_WINDOW_MS = 24 * 60 * 60 * 1000;
33
+ /**
34
+ * PURE: entries revoked without authorship/reason — the §3.6 hygiene signal.
35
+ * Never inside loadRegistry(); the consumer (boot/refresh path) calls this.
36
+ */
37
+ export function detectImproperRevocations(registry) {
38
+ const out = [];
39
+ for (const [machineId, entry] of Object.entries(registry.machines ?? {})) {
40
+ const e = entry;
41
+ if (!e.revokedAt)
42
+ continue;
43
+ const missing = [];
44
+ if (!e.revokedBy)
45
+ missing.push('revokedBy');
46
+ if (!e.revokeReason)
47
+ missing.push('revokeReason');
48
+ if (missing.length) {
49
+ out.push({
50
+ machineId,
51
+ ...(e.nickname ? { nickname: e.nickname } : {}),
52
+ revokedAt: e.revokedAt,
53
+ missing,
54
+ });
55
+ }
56
+ }
57
+ return out;
58
+ }
59
+ export class PeerVisibilityGuard {
60
+ d;
61
+ stateFile;
62
+ state = null;
63
+ /** In-memory per-episode tracking (a notice fires once per episode). */
64
+ missing = new Map();
65
+ constructor(config) {
66
+ this.d = config;
67
+ this.stateFile = path.join(config.stateDir, 'state', 'coherence-journal', 'visibility-guard.json');
68
+ }
69
+ /**
70
+ * §3.6.1 — call on boot + registry refresh with the loaded registry.
71
+ * Surfaces each improper revocation ONCE across boots (keyed on revokedAt).
72
+ */
73
+ checkRevocations(registry) {
74
+ const found = detectImproperRevocations(registry);
75
+ const st = this.loadState();
76
+ const fresh = found.filter((f) => !st.surfacedRevocations.includes(f.revokedAt));
77
+ for (const f of fresh) {
78
+ st.surfacedRevocations.push(f.revokedAt);
79
+ this.safeNotify({
80
+ kind: 'improper-revocation',
81
+ machineId: f.machineId,
82
+ title: `Machine ${f.nickname ?? f.machineId} was revoked without ${f.missing.join('/')}`,
83
+ body: `${f.nickname ?? f.machineId} is marked revoked (at ${f.revokedAt}) but the revocation ` +
84
+ `carries no ${f.missing.join(' or ')} — it did not go through revokeMachine(). ` +
85
+ `HYGIENE SIGNAL ONLY: this detects a sloppy revocation, not a malicious one (and a ` +
86
+ `populated field would not prove legitimacy either). If this machine should be in the ` +
87
+ `pool, un-revoke it; its working sets are unreachable until then.`,
88
+ });
89
+ }
90
+ if (fresh.length)
91
+ this.persist(st);
92
+ return found;
93
+ }
94
+ /**
95
+ * §3.6.2 — call on a presence cadence with the CURRENT online view.
96
+ * `expected` = machines that should be online (active, not revoked, not
97
+ * self); `online` = machines recorded this pass.
98
+ */
99
+ async checkDisappearances(expected, online) {
100
+ const nowMs = (this.d.now?.() ?? new Date()).getTime();
101
+ const grace = this.d.graceMs ?? DEFAULT_DISAPPEARANCE_GRACE_MS;
102
+ const st = this.loadState();
103
+ let dirty = false;
104
+ for (const machineId of expected) {
105
+ if (machineId === this.d.selfMachineId)
106
+ continue;
107
+ if (online.has(machineId)) {
108
+ // Stable re-peer → episode closes SILENTLY (§3.6.2).
109
+ if (this.missing.delete(machineId))
110
+ this.d.logger?.(`peer ${machineId} re-peered`);
111
+ continue;
112
+ }
113
+ let tracker = this.missing.get(machineId);
114
+ if (!tracker) {
115
+ tracker = { missingSinceMs: nowMs, noticed: false };
116
+ this.missing.set(machineId, tracker);
117
+ }
118
+ if (tracker.noticed || nowMs - tracker.missingSinceMs < grace)
119
+ continue;
120
+ // Episode confirmed past grace — flap accounting first.
121
+ const episodes = (st.episodes[machineId] ?? []).filter((iso) => nowMs - new Date(iso).getTime() < FLAP_WINDOW_MS);
122
+ episodes.push(new Date(nowMs).toISOString());
123
+ st.episodes[machineId] = episodes;
124
+ dirty = true;
125
+ tracker.noticed = true;
126
+ if (episodes.length > FLAP_EPISODE_LIMIT) {
127
+ if (!st.flapNotified[machineId]) {
128
+ st.flapNotified[machineId] = true;
129
+ this.safeNotify({
130
+ kind: 'peer-flapping',
131
+ machineId,
132
+ title: `Machine ${machineId} is flapping`,
133
+ body: `${machineId} has dropped off the mesh ${episodes.length} times in 24h. ` +
134
+ `Collapsing to this single notice — no further per-episode messages until ` +
135
+ `it stabilizes (Bounded Notification Surface).`,
136
+ });
137
+ }
138
+ continue;
139
+ }
140
+ // Flap-notified machines that stabilized under the limit get re-armed.
141
+ if (st.flapNotified[machineId] && episodes.length <= FLAP_EPISODE_LIMIT) {
142
+ delete st.flapNotified[machineId];
143
+ }
144
+ let stranded = [];
145
+ try {
146
+ stranded = (await this.d.strandedTopicsFor?.(machineId)) ?? [];
147
+ }
148
+ catch { /* @silent-fallback-ok: the stranded-topics enrichment is best-effort; the disappearance notice itself must still fire (WORKING-SET-HANDOFF-SPEC §3.6) */
149
+ }
150
+ const strandedLine = stranded.length
151
+ ? ` Topic working set(s) stranded on it: ${stranded.join(', ')} — recover by bringing it back / un-revoking; the pending fetch re-fires automatically on its return.`
152
+ : '';
153
+ this.safeNotify({
154
+ kind: 'peer-missing',
155
+ machineId,
156
+ title: `Machine ${machineId} has been unreachable for 30+ minutes`,
157
+ body: `${machineId} should be in the pool but has not answered the presence pull past the ` +
158
+ `grace window.${strandedLine}`,
159
+ });
160
+ }
161
+ if (dirty)
162
+ this.persist(st);
163
+ }
164
+ // ---- durable dedupe state -------------------------------------------------
165
+ loadState() {
166
+ if (this.state)
167
+ return this.state;
168
+ try {
169
+ const parsed = JSON.parse(fs.readFileSync(this.stateFile, 'utf-8'));
170
+ if (parsed?.version === 1) {
171
+ this.state = {
172
+ version: 1,
173
+ surfacedRevocations: Array.isArray(parsed.surfacedRevocations) ? parsed.surfacedRevocations : [],
174
+ episodes: parsed.episodes && typeof parsed.episodes === 'object' ? parsed.episodes : {},
175
+ flapNotified: parsed.flapNotified && typeof parsed.flapNotified === 'object' ? parsed.flapNotified : {},
176
+ };
177
+ return this.state;
178
+ }
179
+ }
180
+ catch { /* @silent-fallback-ok: absent/corrupt guard state only weakens notice dedupe (worst case one repeat notice) — never a failure (WORKING-SET-HANDOFF-SPEC §3.6) */
181
+ }
182
+ this.state = { version: 1, surfacedRevocations: [], episodes: {}, flapNotified: {} };
183
+ return this.state;
184
+ }
185
+ persist(st) {
186
+ try {
187
+ fs.mkdirSync(path.dirname(this.stateFile), { recursive: true });
188
+ const tmp = `${this.stateFile}.tmp-${process.pid}`;
189
+ fs.writeFileSync(tmp, JSON.stringify(st, null, 2));
190
+ fs.renameSync(tmp, this.stateFile);
191
+ }
192
+ catch (e) { /* @silent-fallback-ok: a failed dedupe persist risks one repeat notice after restart, never a lost detection (WORKING-SET-HANDOFF-SPEC §3.6) */
193
+ this.d.logger?.(`guard state persist failed: ${e instanceof Error ? e.message : String(e)}`);
194
+ }
195
+ }
196
+ safeNotify(notice) {
197
+ try {
198
+ this.d.notify(notice);
199
+ }
200
+ catch { /* @silent-fallback-ok: a notify-consumer failure must never break the guard's detection loop (WORKING-SET-HANDOFF-SPEC §3.6) */
201
+ }
202
+ }
203
+ }
204
+ //# sourceMappingURL=PeerVisibilityGuard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PeerVisibilityGuard.js","sourceRoot":"","sources":["../../src/core/PeerVisibilityGuard.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,129 @@
1
+ /**
2
+ * PendingPullLedger — P2.2 of multi-machine coherence: the durable record of
3
+ * working-set pulls that could not complete because the producer was
4
+ * offline / unreachable / revoked / mid-run. The EXO case, solved: the
5
+ * request survives restarts and re-fires the moment the peer returns.
6
+ *
7
+ * Spec: docs/specs/WORKING-SET-HANDOFF-SPEC.md §3.4.
8
+ *
9
+ * SINGLE-WRITER DISCIPLINE (the topic-flood-#3 lesson, applied at birth):
10
+ * SIX mutators can overlap on one tick (onAccepted scheduler, reappearance
11
+ * re-arm, run-stopped re-arm, attempt/breaker update, reflex route, TTL
12
+ * sweep). ALL mutations route through ONE serialized `mutate(fn)` funnel —
13
+ * an in-process async queue, so read-modify-write never interleaves — with
14
+ * temp-file + atomic-rename persistence.
15
+ *
16
+ * PARSE-FAILURE POSTURE (the flood's second root): a corrupt/unparseable
17
+ * ledger is NEVER read as "no pending pulls" — the file is quarantined
18
+ * aside (`.corrupt-<ts>`), ONE notice fires through the injected
19
+ * `onCorrupt` seam ("pending-pull ledger unreadable — stranded-recovery
20
+ * records may be lost"), and a fresh ledger starts.
21
+ *
22
+ * Store path: `state/coherence-journal/pending-pulls.json` — registered in
23
+ * the State-Coherence Registry (machine-local; the records describe THIS
24
+ * machine's outstanding fetches).
25
+ */
26
+ export declare const PENDING_PULLS_FILENAME = "pending-pulls.json";
27
+ export declare const DEFAULT_PENDING_PULL_TTL_DAYS = 7;
28
+ /** Per-record attempt cap — the (peer,topic,epoch) breaker (§3.4). */
29
+ export declare const DEFAULT_ATTEMPT_CAP = 6;
30
+ export type PendingPullReason = 'peer-offline' | 'peer-unreachable' | 'peer-revoked' | 'live-source' | 'busy-exhausted';
31
+ export interface PendingPullRecord {
32
+ topic: number;
33
+ epoch: number;
34
+ nominee: string;
35
+ reason: PendingPullReason;
36
+ createdAt: string;
37
+ attempts: number;
38
+ lastAttemptAt: string | null;
39
+ }
40
+ export interface PendingPullLedgerConfig {
41
+ /** Absolute path to the agent's `.instar/` directory. */
42
+ stateDir: string;
43
+ ttlDays?: number;
44
+ attemptCap?: number;
45
+ now?: () => Date;
46
+ /**
47
+ * Fired ONCE per corrupt-quarantine episode (agent-health lane upstream).
48
+ * Never throws into the ledger.
49
+ */
50
+ onCorrupt?: (quarantinedPath: string) => void;
51
+ /**
52
+ * Fired once per record on TTL expiry — "topic T's working set on
53
+ * <machine> was never recovered" (§3.4). Never throws into the ledger.
54
+ */
55
+ onExpired?: (record: PendingPullRecord) => void;
56
+ logger?: (msg: string) => void;
57
+ }
58
+ export declare class PendingPullLedger {
59
+ private readonly file;
60
+ private readonly ttlMs;
61
+ private readonly attemptCap;
62
+ private readonly now;
63
+ private readonly onCorrupt?;
64
+ private readonly onExpired?;
65
+ private readonly logger;
66
+ /** The serialized mutate() funnel — read-modify-write never interleaves. */
67
+ private queue;
68
+ /** In-memory truth between mutations (loaded once, kept current). */
69
+ private records;
70
+ private corruptNotified;
71
+ constructor(config: PendingPullLedgerConfig);
72
+ /**
73
+ * File (or refresh) a pending pull. Idempotent on (topic, epoch, nominee):
74
+ * an existing record keeps its createdAt/attempts; only `reason` refreshes.
75
+ */
76
+ file_(rec: {
77
+ topic: number;
78
+ epoch: number;
79
+ nominee: string;
80
+ reason: PendingPullReason;
81
+ }): Promise<void>;
82
+ /**
83
+ * Record a GENUINE failed attempt (offline / unreachable / refused /
84
+ * verify-failed). `busy` responses MUST NOT come through here — busy is
85
+ * retry-without-penalty (§3.2); a throttled drain must never exhaust the
86
+ * very records it exists to recover.
87
+ */
88
+ recordAttempt(topic: number, epoch: number, nominee: string): Promise<void>;
89
+ /** A completed pull clears its record. */
90
+ clear(topic: number, epoch: number, nominee: string): Promise<void>;
91
+ /**
92
+ * Supersession (§3.4): a newer epoch for the topic clears ALL records for
93
+ * that topic with `epoch < newEpoch`, across all nominees — a partial clear
94
+ * must never strand a sibling record.
95
+ */
96
+ supersede(topic: number, newEpoch: number): Promise<void>;
97
+ /**
98
+ * TTL sweep: expire records older than ttlDays — each surfaced ONCE via
99
+ * onExpired ("never recovered"), then removed. Run on a slow cadence by the
100
+ * caller (it is one of the six mutators, so it rides the funnel too).
101
+ * Returns the expired records.
102
+ */
103
+ sweepExpired(): Promise<PendingPullRecord[]>;
104
+ /**
105
+ * The records eligible to re-fire for a returning peer — the staggered
106
+ * drain reads this (most-recent-epoch-first; the drain itself enforces
107
+ * rearmConcurrency). Records at/over the attempt cap are excluded (the
108
+ * breaker; a NEW epoch files a NEW record, so an old exhausted breaker
109
+ * never suppresses a fresh, warranted pull).
110
+ */
111
+ pendingForPeer(nominee: string): Promise<PendingPullRecord[]>;
112
+ /** All records for a topic (the run-stopped re-arm + reflex route read this). */
113
+ pendingForTopic(topic: number): Promise<PendingPullRecord[]>;
114
+ /** Every record, including breaker-exhausted ones (observability). */
115
+ all(): Promise<PendingPullRecord[]>;
116
+ /**
117
+ * Serialize a read-modify-write. The fn receives the current records array
118
+ * (mutable) and returns the next one; persistence is temp-file + atomic
119
+ * rename. Errors persist nothing and propagate to THIS caller only — the
120
+ * queue itself never wedges.
121
+ */
122
+ private mutate;
123
+ private read;
124
+ /** Load from memory or disk. Corrupt disk → quarantine + notice + fresh. */
125
+ private readUnqueued;
126
+ private quarantineCorrupt;
127
+ private persist;
128
+ }
129
+ //# sourceMappingURL=PendingPullLedger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PendingPullLedger.d.ts","sourceRoot":"","sources":["../../src/core/PendingPullLedger.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAKH,eAAO,MAAM,sBAAsB,uBAAuB,CAAC;AAC3D,eAAO,MAAM,6BAA6B,IAAI,CAAC;AAC/C,sEAAsE;AACtE,eAAO,MAAM,mBAAmB,IAAI,CAAC;AAErC,MAAM,MAAM,iBAAiB,GACzB,cAAc,GACd,kBAAkB,GAClB,cAAc,GACd,aAAa,GACb,gBAAgB,CAAC;AAErB,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,iBAAiB,CAAC;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B;AAED,MAAM,WAAW,uBAAuB;IACtC,yDAAyD;IACzD,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,GAAG,CAAC,EAAE,MAAM,IAAI,CAAC;IACjB;;;OAGG;IACH,SAAS,CAAC,EAAE,CAAC,eAAe,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9C;;;OAGG;IACH,SAAS,CAAC,EAAE,CAAC,MAAM,EAAE,iBAAiB,KAAK,IAAI,CAAC;IAChD,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;CAChC;AAWD,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAS;IAC9B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;IAC/B,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAa;IACjC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAsB;IACjD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAiC;IAC5D,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAwB;IAE/C,4EAA4E;IAC5E,OAAO,CAAC,KAAK,CAAuC;IACpD,qEAAqE;IACrE,OAAO,CAAC,OAAO,CAAoC;IACnD,OAAO,CAAC,eAAe,CAAS;gBAEpB,MAAM,EAAE,uBAAuB;IAY3C;;;OAGG;IACG,KAAK,CAAC,GAAG,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,iBAAiB,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAkB7G;;;;;OAKG;IACG,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAWjF,0CAA0C;IACpC,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAMzE;;;;OAIG;IACG,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAM/D;;;;;OAKG;IACG,YAAY,IAAI,OAAO,CAAC,iBAAiB,EAAE,CAAC;IAqBlD;;;;;;OAMG;IACG,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,EAAE,CAAC;IAOnE,iFAAiF;IAC3E,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,EAAE,CAAC;IAKlE,sEAAsE;IAChE,GAAG,IAAI,OAAO,CAAC,iBAAiB,EAAE,CAAC;IAMzC;;;;;OAKG;IACH,OAAO,CAAC,MAAM;YAeA,IAAI;IAOlB,4EAA4E;IAC5E,OAAO,CAAC,YAAY;IA8BpB,OAAO,CAAC,iBAAiB;IAgBzB,OAAO,CAAC,OAAO;CAQhB"}
@@ -0,0 +1,239 @@
1
+ /**
2
+ * PendingPullLedger — P2.2 of multi-machine coherence: the durable record of
3
+ * working-set pulls that could not complete because the producer was
4
+ * offline / unreachable / revoked / mid-run. The EXO case, solved: the
5
+ * request survives restarts and re-fires the moment the peer returns.
6
+ *
7
+ * Spec: docs/specs/WORKING-SET-HANDOFF-SPEC.md §3.4.
8
+ *
9
+ * SINGLE-WRITER DISCIPLINE (the topic-flood-#3 lesson, applied at birth):
10
+ * SIX mutators can overlap on one tick (onAccepted scheduler, reappearance
11
+ * re-arm, run-stopped re-arm, attempt/breaker update, reflex route, TTL
12
+ * sweep). ALL mutations route through ONE serialized `mutate(fn)` funnel —
13
+ * an in-process async queue, so read-modify-write never interleaves — with
14
+ * temp-file + atomic-rename persistence.
15
+ *
16
+ * PARSE-FAILURE POSTURE (the flood's second root): a corrupt/unparseable
17
+ * ledger is NEVER read as "no pending pulls" — the file is quarantined
18
+ * aside (`.corrupt-<ts>`), ONE notice fires through the injected
19
+ * `onCorrupt` seam ("pending-pull ledger unreadable — stranded-recovery
20
+ * records may be lost"), and a fresh ledger starts.
21
+ *
22
+ * Store path: `state/coherence-journal/pending-pulls.json` — registered in
23
+ * the State-Coherence Registry (machine-local; the records describe THIS
24
+ * machine's outstanding fetches).
25
+ */
26
+ import fs from 'node:fs';
27
+ import path from 'node:path';
28
+ export const PENDING_PULLS_FILENAME = 'pending-pulls.json';
29
+ export const DEFAULT_PENDING_PULL_TTL_DAYS = 7;
30
+ /** Per-record attempt cap — the (peer,topic,epoch) breaker (§3.4). */
31
+ export const DEFAULT_ATTEMPT_CAP = 6;
32
+ function recordKey(r) {
33
+ return `${r.topic}:${r.epoch}:${r.nominee}`;
34
+ }
35
+ export class PendingPullLedger {
36
+ file;
37
+ ttlMs;
38
+ attemptCap;
39
+ now;
40
+ onCorrupt;
41
+ onExpired;
42
+ logger;
43
+ /** The serialized mutate() funnel — read-modify-write never interleaves. */
44
+ queue = Promise.resolve();
45
+ /** In-memory truth between mutations (loaded once, kept current). */
46
+ records = null;
47
+ corruptNotified = false;
48
+ constructor(config) {
49
+ this.file = path.join(config.stateDir, 'state', 'coherence-journal', PENDING_PULLS_FILENAME);
50
+ this.ttlMs = (config.ttlDays ?? DEFAULT_PENDING_PULL_TTL_DAYS) * 24 * 60 * 60 * 1000;
51
+ this.attemptCap = config.attemptCap ?? DEFAULT_ATTEMPT_CAP;
52
+ this.now = config.now ?? (() => new Date());
53
+ this.onCorrupt = config.onCorrupt;
54
+ this.onExpired = config.onExpired;
55
+ this.logger = config.logger ?? (() => { });
56
+ }
57
+ // ---- public API (every mutation rides the funnel) ------------------------
58
+ /**
59
+ * File (or refresh) a pending pull. Idempotent on (topic, epoch, nominee):
60
+ * an existing record keeps its createdAt/attempts; only `reason` refreshes.
61
+ */
62
+ async file_(rec) {
63
+ await this.mutate((records) => {
64
+ const key = recordKey(rec);
65
+ const existing = records.find((r) => recordKey(r) === key);
66
+ if (existing) {
67
+ existing.reason = rec.reason;
68
+ return records;
69
+ }
70
+ records.push({
71
+ ...rec,
72
+ createdAt: this.now().toISOString(),
73
+ attempts: 0,
74
+ lastAttemptAt: null,
75
+ });
76
+ return records;
77
+ });
78
+ }
79
+ /**
80
+ * Record a GENUINE failed attempt (offline / unreachable / refused /
81
+ * verify-failed). `busy` responses MUST NOT come through here — busy is
82
+ * retry-without-penalty (§3.2); a throttled drain must never exhaust the
83
+ * very records it exists to recover.
84
+ */
85
+ async recordAttempt(topic, epoch, nominee) {
86
+ await this.mutate((records) => {
87
+ const r = records.find((x) => x.topic === topic && x.epoch === epoch && x.nominee === nominee);
88
+ if (r) {
89
+ r.attempts += 1;
90
+ r.lastAttemptAt = this.now().toISOString();
91
+ }
92
+ return records;
93
+ });
94
+ }
95
+ /** A completed pull clears its record. */
96
+ async clear(topic, epoch, nominee) {
97
+ await this.mutate((records) => records.filter((r) => !(r.topic === topic && r.epoch === epoch && r.nominee === nominee)));
98
+ }
99
+ /**
100
+ * Supersession (§3.4): a newer epoch for the topic clears ALL records for
101
+ * that topic with `epoch < newEpoch`, across all nominees — a partial clear
102
+ * must never strand a sibling record.
103
+ */
104
+ async supersede(topic, newEpoch) {
105
+ await this.mutate((records) => records.filter((r) => !(r.topic === topic && r.epoch < newEpoch)));
106
+ }
107
+ /**
108
+ * TTL sweep: expire records older than ttlDays — each surfaced ONCE via
109
+ * onExpired ("never recovered"), then removed. Run on a slow cadence by the
110
+ * caller (it is one of the six mutators, so it rides the funnel too).
111
+ * Returns the expired records.
112
+ */
113
+ async sweepExpired() {
114
+ const expired = [];
115
+ await this.mutate((records) => {
116
+ const nowMs = this.now().getTime();
117
+ const kept = [];
118
+ for (const r of records) {
119
+ const age = nowMs - new Date(r.createdAt).getTime();
120
+ if (age > this.ttlMs)
121
+ expired.push(r);
122
+ else
123
+ kept.push(r);
124
+ }
125
+ for (const r of expired) {
126
+ try {
127
+ this.onExpired?.(r);
128
+ }
129
+ catch { /* @silent-fallback-ok: an expiry-notice consumer failure must never block the sweep itself (WORKING-SET-HANDOFF-SPEC §3.4) */
130
+ }
131
+ }
132
+ return kept;
133
+ });
134
+ return expired;
135
+ }
136
+ /**
137
+ * The records eligible to re-fire for a returning peer — the staggered
138
+ * drain reads this (most-recent-epoch-first; the drain itself enforces
139
+ * rearmConcurrency). Records at/over the attempt cap are excluded (the
140
+ * breaker; a NEW epoch files a NEW record, so an old exhausted breaker
141
+ * never suppresses a fresh, warranted pull).
142
+ */
143
+ async pendingForPeer(nominee) {
144
+ const records = await this.read();
145
+ return records
146
+ .filter((r) => r.nominee === nominee && r.attempts < this.attemptCap)
147
+ .sort((a, b) => b.epoch - a.epoch);
148
+ }
149
+ /** All records for a topic (the run-stopped re-arm + reflex route read this). */
150
+ async pendingForTopic(topic) {
151
+ const records = await this.read();
152
+ return records.filter((r) => r.topic === topic && r.attempts < this.attemptCap);
153
+ }
154
+ /** Every record, including breaker-exhausted ones (observability). */
155
+ async all() {
156
+ return [...(await this.read())];
157
+ }
158
+ // ---- the funnel -----------------------------------------------------------
159
+ /**
160
+ * Serialize a read-modify-write. The fn receives the current records array
161
+ * (mutable) and returns the next one; persistence is temp-file + atomic
162
+ * rename. Errors persist nothing and propagate to THIS caller only — the
163
+ * queue itself never wedges.
164
+ */
165
+ mutate(fn) {
166
+ const run = this.queue.then(async () => {
167
+ const before = await this.readUnqueued();
168
+ const next = fn(before);
169
+ this.persist(next);
170
+ this.records = next;
171
+ return next;
172
+ });
173
+ // The queue continues even when one mutation throws (error isolated to caller).
174
+ this.queue = run.catch(() => { });
175
+ return run;
176
+ }
177
+ async read() {
178
+ // Reads ride the funnel too — a read mid-mutation would see torn state.
179
+ const run = this.queue.then(() => this.readUnqueued());
180
+ this.queue = run.catch(() => { });
181
+ return run;
182
+ }
183
+ /** Load from memory or disk. Corrupt disk → quarantine + notice + fresh. */
184
+ readUnqueued() {
185
+ if (this.records)
186
+ return this.records;
187
+ let raw;
188
+ try {
189
+ raw = fs.readFileSync(this.file, 'utf-8');
190
+ }
191
+ catch { /* @silent-fallback-ok: ledger absent = genuinely empty (first boot) — distinct from corrupt, which quarantines below (WORKING-SET-HANDOFF-SPEC §3.4) */
192
+ this.records = [];
193
+ return this.records;
194
+ }
195
+ try {
196
+ const parsed = JSON.parse(raw);
197
+ if (!parsed || parsed.version !== 1 || !Array.isArray(parsed.records)) {
198
+ throw new Error('shape mismatch');
199
+ }
200
+ this.records = parsed.records.filter((r) => typeof r?.topic === 'number' &&
201
+ typeof r?.epoch === 'number' &&
202
+ typeof r?.nominee === 'string' &&
203
+ typeof r?.attempts === 'number');
204
+ return this.records;
205
+ }
206
+ catch {
207
+ // NEVER read corrupt as empty-silently: quarantine + one notice + fresh.
208
+ this.quarantineCorrupt();
209
+ this.records = [];
210
+ return this.records;
211
+ }
212
+ }
213
+ quarantineCorrupt() {
214
+ const quarantined = `${this.file}.corrupt-${this.now().getTime()}`;
215
+ try {
216
+ fs.renameSync(this.file, quarantined);
217
+ }
218
+ catch { /* @silent-fallback-ok: quarantine rename can lose a race with another process; the notice below still fires once (WORKING-SET-HANDOFF-SPEC §3.4) */
219
+ }
220
+ this.logger(`pending-pull ledger unreadable — quarantined to ${path.basename(quarantined)}`);
221
+ if (!this.corruptNotified) {
222
+ this.corruptNotified = true;
223
+ try {
224
+ this.onCorrupt?.(quarantined);
225
+ }
226
+ catch { /* @silent-fallback-ok: a corrupt-notice consumer failure must never block ledger recovery (WORKING-SET-HANDOFF-SPEC §3.4) */
227
+ }
228
+ }
229
+ }
230
+ persist(records) {
231
+ const dir = path.dirname(this.file);
232
+ fs.mkdirSync(dir, { recursive: true });
233
+ const tmp = `${this.file}.tmp-${process.pid}`;
234
+ const body = { version: 1, records };
235
+ fs.writeFileSync(tmp, JSON.stringify(body, null, 2));
236
+ fs.renameSync(tmp, this.file);
237
+ }
238
+ }
239
+ //# sourceMappingURL=PendingPullLedger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PendingPullLedger.js","sourceRoot":"","sources":["../../src/core/PendingPullLedger.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"PostUpdateMigrator.d.ts","sourceRoot":"","sources":["../../src/core/PostUpdateMigrator.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"PostUpdateMigrator.d.ts","sourceRoot":"","sources":["../../src/core/PostUpdateMigrator.ts"],"names":[],"mappings":"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"}