instar 1.3.335 → 1.3.336

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.
@@ -59,6 +59,20 @@ export interface HttpLiveTailTransportDeps {
59
59
  fetchImpl?: typeof fetch;
60
60
  /** How recent a successful broadcast counts as "reachable". Default = 60s. */
61
61
  reachabilityWindowMs?: number;
62
+ /**
63
+ * Per-request abort timeout (P19 brake — a hung socket must not hold a
64
+ * flush open indefinitely). Default 30s: sized ABOVE the fleet's documented
65
+ * 5–40s receiver-stall envelope (the #874 reviewer's sizing rationale) so a
66
+ * slow-but-alive standby is not converted into "unreachable".
67
+ */
68
+ requestTimeoutMs?: number;
69
+ /**
70
+ * Coarse-reminder interval for the per-peer failure log gate (P19 brake).
71
+ * Default 360: with #867's per-topic backoff the attempt rate is bounded,
72
+ * but N topics against one down peer still meant N lines per backoff window
73
+ * — the gate collapses that to first/Nth/recovery per peer.
74
+ */
75
+ failureLogEveryN?: number;
62
76
  now?: () => number;
63
77
  logger?: (msg: string) => void;
64
78
  }
@@ -73,7 +87,12 @@ export declare class HttpLiveTailTransport {
73
87
  private readonly d;
74
88
  private lastBroadcastOkAt;
75
89
  private readonly windowMs;
90
+ private readonly requestTimeoutMs;
91
+ /** State-change failure logging (first/Nth/recovery) — never per-attempt. */
92
+ private readonly logGate;
76
93
  constructor(deps: HttpLiveTailTransportDeps);
94
+ private logFailure;
95
+ private logSuccess;
77
96
  private now;
78
97
  private log;
79
98
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"HttpLiveTailTransport.d.ts","sourceRoot":"","sources":["../../src/core/HttpLiveTailTransport.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAIH,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAE/D,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,4DAA4D;IAC5D,GAAG,EAAE,MAAM,CAAC;IACZ,6EAA6E;IAC7E,mBAAmB,EAAE,MAAM,CAAC;CAC7B;AAED,qFAAqF;AACrF,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,sBAAsB,CAAC;IAC5B,2EAA2E;IAC3E,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,yBAAyB;IACxC,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,yFAAyF;IACzF,KAAK,EAAE,MAAM,YAAY,EAAE,CAAC;IAC5B,yEAAyE;IACzE,YAAY,EAAE,MAAM,MAAM,CAAC;IAC3B;;;OAGG;IACH,UAAU,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,kBAAkB,EAAE,MAAM,KAAK,sBAAsB,CAAC;IACpF,iDAAiD;IACjD,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;IACzB,8EAA8E;IAC9E,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;CAChC;AAED,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,gFAAgF;IAChF,GAAG,EAAE,MAAM,CAAC;IACZ,qDAAqD;IACrD,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,qBAAa,qBAAqB;IAChC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAA4B;IAC9C,OAAO,CAAC,iBAAiB,CAAK;IAC9B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;gBAEtB,IAAI,EAAE,yBAAyB;IAK3C,OAAO,CAAC,GAAG;IAGX,OAAO,CAAC,GAAG;IAIX;;;;OAIG;IACG,SAAS,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO,CAAC,OAAO,CAAC;IAsC5D,uFAAuF;IACvF,WAAW,IAAI,OAAO;CAGvB"}
1
+ {"version":3,"file":"HttpLiveTailTransport.d.ts","sourceRoot":"","sources":["../../src/core/HttpLiveTailTransport.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAKH,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAE/D,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,4DAA4D;IAC5D,GAAG,EAAE,MAAM,CAAC;IACZ,6EAA6E;IAC7E,mBAAmB,EAAE,MAAM,CAAC;CAC7B;AAED,qFAAqF;AACrF,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,sBAAsB,CAAC;IAC5B,2EAA2E;IAC3E,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,yBAAyB;IACxC,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,yFAAyF;IACzF,KAAK,EAAE,MAAM,YAAY,EAAE,CAAC;IAC5B,yEAAyE;IACzE,YAAY,EAAE,MAAM,MAAM,CAAC;IAC3B;;;OAGG;IACH,UAAU,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,kBAAkB,EAAE,MAAM,KAAK,sBAAsB,CAAC;IACpF,iDAAiD;IACjD,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;IACzB,8EAA8E;IAC9E,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B;;;;;OAKG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;;;;OAKG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;CAChC;AAED,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,gFAAgF;IAChF,GAAG,EAAE,MAAM,CAAC;IACZ,qDAAqD;IACrD,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,qBAAa,qBAAqB;IAChC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAA4B;IAC9C,OAAO,CAAC,iBAAiB,CAAK;IAC9B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAS;IAC1C,6EAA6E;IAC7E,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAqB;gBAEjC,IAAI,EAAE,yBAAyB;IAO3C,OAAO,CAAC,UAAU;IAIlB,OAAO,CAAC,UAAU;IAKlB,OAAO,CAAC,GAAG;IAGX,OAAO,CAAC,GAAG;IAIX;;;;OAIG;IACG,SAAS,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO,CAAC,OAAO,CAAC;IA4C5D,uFAAuF;IACvF,WAAW,IAAI,OAAO;CAGvB"}
@@ -28,14 +28,30 @@
28
28
  * redact→encrypt→post logic is unit-testable without a network or real keys.
29
29
  */
30
30
  import { signRequest } from '../server/machineAuth.js';
31
+ import { PeerFailureLogGate } from './PeerFailureLogGate.js';
31
32
  import { redactForLiveTail } from './liveTailRedaction.js';
32
33
  export class HttpLiveTailTransport {
33
34
  d;
34
35
  lastBroadcastOkAt = 0;
35
36
  windowMs;
37
+ requestTimeoutMs;
38
+ /** State-change failure logging (first/Nth/recovery) — never per-attempt. */
39
+ logGate;
36
40
  constructor(deps) {
37
41
  this.d = deps;
38
42
  this.windowMs = deps.reachabilityWindowMs ?? 60_000;
43
+ this.requestTimeoutMs = deps.requestTimeoutMs ?? 30_000;
44
+ this.logGate = new PeerFailureLogGate(deps.failureLogEveryN ?? 360);
45
+ }
46
+ logFailure(key, detail) {
47
+ const line = this.logGate.failed(key, detail);
48
+ if (line)
49
+ this.log(line);
50
+ }
51
+ logSuccess(key) {
52
+ const line = this.logGate.succeeded(key);
53
+ if (line)
54
+ this.log(line);
39
55
  }
40
56
  now() {
41
57
  return (this.d.now ?? Date.now)();
@@ -73,14 +89,19 @@ export class HttpLiveTailTransport {
73
89
  method: 'POST',
74
90
  headers: { 'Content-Type': 'application/json', ...headers },
75
91
  body: JSON.stringify(body),
92
+ // P19 brake: a hung socket aborts instead of holding the flush open.
93
+ signal: AbortSignal.timeout(this.requestTimeoutMs),
76
94
  });
77
- if (res && res.ok)
95
+ if (res && res.ok) {
78
96
  anyOk = true;
79
- else
80
- this.log(`peer ${peer.machineId} rejected flush seq=${flush.seq} (status ${res?.status})`);
97
+ this.logSuccess(`live-tail to ${peer.machineId}`);
98
+ }
99
+ else {
100
+ this.logFailure(`live-tail to ${peer.machineId}`, `status ${res?.status} (seq=${flush.seq})`);
101
+ }
81
102
  }
82
103
  catch (err) {
83
- this.log(`broadcast to ${peer.machineId} failed: ${err instanceof Error ? err.message : String(err)}`);
104
+ this.logFailure(`live-tail to ${peer.machineId}`, err instanceof Error ? err.message : String(err));
84
105
  }
85
106
  }));
86
107
  if (anyOk)
@@ -1 +1 @@
1
- {"version":3,"file":"HttpLiveTailTransport.js","sourceRoot":"","sources":["../../src/core/HttpLiveTailTransport.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"HttpLiveTailTransport.js","sourceRoot":"","sources":["../../src/core/HttpLiveTailTransport.ts"],"names":[],"mappings":"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"}
@@ -40,12 +40,31 @@ export interface ReplyMarkerTransportDeps {
40
40
  /** Monotonic per-request sequence for machine-auth replay protection. */
41
41
  nextSequence: () => number;
42
42
  fetchImpl?: typeof fetch;
43
+ /**
44
+ * Per-request abort timeout (P19 brake — a hung socket must not hold the
45
+ * reply-commit path open). Default 30s: sized ABOVE the fleet's documented
46
+ * 5–40s receiver-stall envelope (the #874 reviewer's sizing rationale — a
47
+ * slow-but-alive peer must not read as unreachable).
48
+ */
49
+ requestTimeoutMs?: number;
50
+ /**
51
+ * Coarse-reminder interval for the per-peer failure log gate (P19 brake).
52
+ * Default 50 — markers flow at REPLY cadence (not a fixed 5s tick), so the
53
+ * reminder lands roughly every 50 failed replies; first-failure and
54
+ * recovery lines carry the state changes regardless.
55
+ */
56
+ failureLogEveryN?: number;
43
57
  logger?: (msg: string) => void;
44
58
  }
45
59
  export declare class ReplyMarkerTransport {
46
60
  private readonly d;
61
+ private readonly requestTimeoutMs;
62
+ /** State-change failure logging (first/Nth/recovery) — never per-attempt. */
63
+ private readonly logGate;
47
64
  constructor(deps: ReplyMarkerTransportDeps);
48
65
  private log;
66
+ private logFailure;
67
+ private logSuccess;
49
68
  /**
50
69
  * POST the marker to every standby peer over the signed channel. Resolves true
51
70
  * if at least one peer accepted (a live medium carried it); false if none was
@@ -1 +1 @@
1
- {"version":3,"file":"ReplyMarkerTransport.d.ts","sourceRoot":"","sources":["../../src/core/ReplyMarkerTransport.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAIH,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,4DAA4D;IAC5D,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB;AAED,MAAM,WAAW,wBAAwB;IACvC,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,2EAA2E;IAC3E,KAAK,EAAE,MAAM,eAAe,EAAE,CAAC;IAC/B,yEAAyE;IACzE,YAAY,EAAE,MAAM,MAAM,CAAC;IAC3B,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;IACzB,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;CAChC;AAED,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,QAAQ,CAAC,CAAC,CAA2B;gBAEjC,IAAI,EAAE,wBAAwB;IAI1C,OAAO,CAAC,GAAG;IAIX;;;;;;OAMG;IACG,SAAS,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC;CAwBvD"}
1
+ {"version":3,"file":"ReplyMarkerTransport.d.ts","sourceRoot":"","sources":["../../src/core/ReplyMarkerTransport.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAKH,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,4DAA4D;IAC5D,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB;AAED,MAAM,WAAW,wBAAwB;IACvC,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,2EAA2E;IAC3E,KAAK,EAAE,MAAM,eAAe,EAAE,CAAC;IAC/B,yEAAyE;IACzE,YAAY,EAAE,MAAM,MAAM,CAAC;IAC3B,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;IACzB;;;;;OAKG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B;;;;;OAKG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;CAChC;AAED,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,QAAQ,CAAC,CAAC,CAA2B;IAC7C,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAS;IAC1C,6EAA6E;IAC7E,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAqB;gBAEjC,IAAI,EAAE,wBAAwB;IAM1C,OAAO,CAAC,GAAG;IAIX,OAAO,CAAC,UAAU;IAIlB,OAAO,CAAC,UAAU;IAKlB;;;;;;OAMG;IACG,SAAS,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC;CA8BvD"}
@@ -21,14 +21,30 @@
21
21
  * injected for testability.
22
22
  */
23
23
  import { signRequest } from '../server/machineAuth.js';
24
+ import { PeerFailureLogGate } from './PeerFailureLogGate.js';
24
25
  export class ReplyMarkerTransport {
25
26
  d;
27
+ requestTimeoutMs;
28
+ /** State-change failure logging (first/Nth/recovery) — never per-attempt. */
29
+ logGate;
26
30
  constructor(deps) {
27
31
  this.d = deps;
32
+ this.requestTimeoutMs = deps.requestTimeoutMs ?? 30_000;
33
+ this.logGate = new PeerFailureLogGate(deps.failureLogEveryN ?? 50);
28
34
  }
29
35
  log(m) {
30
36
  this.d.logger?.(`[reply-marker] ${m}`);
31
37
  }
38
+ logFailure(key, detail) {
39
+ const line = this.logGate.failed(key, detail);
40
+ if (line)
41
+ this.log(line);
42
+ }
43
+ logSuccess(key) {
44
+ const line = this.logGate.succeeded(key);
45
+ if (line)
46
+ this.log(line);
47
+ }
32
48
  /**
33
49
  * POST the marker to every standby peer over the signed channel. Resolves true
34
50
  * if at least one peer accepted (a live medium carried it); false if none was
@@ -50,14 +66,19 @@ export class ReplyMarkerTransport {
50
66
  method: 'POST',
51
67
  headers: { 'Content-Type': 'application/json', ...headers },
52
68
  body: JSON.stringify(body),
69
+ // P19 brake: a hung socket aborts instead of holding the reply-commit path.
70
+ signal: AbortSignal.timeout(this.requestTimeoutMs),
53
71
  });
54
- if (res && res.ok)
72
+ if (res && res.ok) {
55
73
  anyOk = true;
56
- else
57
- this.log(`peer ${peer.machineId} rejected marker ${marker.dedupeKey} (status ${res?.status})`);
74
+ this.logSuccess(`marker to ${peer.machineId}`);
75
+ }
76
+ else {
77
+ this.logFailure(`marker to ${peer.machineId}`, `status ${res?.status} (marker ${marker.dedupeKey})`);
78
+ }
58
79
  }
59
80
  catch (err) {
60
- this.log(`broadcast to ${peer.machineId} failed: ${err instanceof Error ? err.message : String(err)}`);
81
+ this.logFailure(`marker to ${peer.machineId}`, err instanceof Error ? err.message : String(err));
61
82
  }
62
83
  }));
63
84
  return anyOk;
@@ -1 +1 @@
1
- {"version":3,"file":"ReplyMarkerTransport.js","sourceRoot":"","sources":["../../src/core/ReplyMarkerTransport.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AA2BvD,MAAM,OAAO,oBAAoB;IACd,CAAC,CAA2B;IAE7C,YAAY,IAA8B;QACxC,IAAI,CAAC,CAAC,GAAG,IAAI,CAAC;IAChB,CAAC;IAEO,GAAG,CAAC,CAAS;QACnB,IAAI,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,kBAAkB,CAAC,EAAE,CAAC,CAAC;IACzC,CAAC;IAED;;;;;;OAMG;IACH,KAAK,CAAC,SAAS,CAAC,MAAmB;QACjC,MAAM,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC;QAC7B,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC;QACpC,MAAM,SAAS,GAAG,IAAI,CAAC,CAAC,CAAC,SAAS,IAAI,KAAK,CAAC;QAC5C,IAAI,KAAK,GAAG,KAAK,CAAC;QAClB,MAAM,OAAO,CAAC,GAAG,CACf,KAAK,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;YACvB,IAAI,CAAC;gBACH,MAAM,IAAI,GAAG,EAAE,MAAM,EAAE,CAAC;gBACxB,MAAM,OAAO,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC,CAAC,aAAa,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,YAAY,EAAE,CAAC,CAAC;gBACrG,MAAM,GAAG,GAAG,MAAM,SAAS,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,qBAAqB,EAAE;oBAC/E,MAAM,EAAE,MAAM;oBACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,GAAG,OAAO,EAAE;oBAC3D,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;iBAC3B,CAAC,CAAC;gBACH,IAAI,GAAG,IAAK,GAAgB,CAAC,EAAE;oBAAE,KAAK,GAAG,IAAI,CAAC;;oBACzC,IAAI,CAAC,GAAG,CAAC,QAAQ,IAAI,CAAC,SAAS,oBAAoB,MAAM,CAAC,SAAS,YAAa,GAAgB,EAAE,MAAM,GAAG,CAAC,CAAC;YACpH,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,IAAI,CAAC,GAAG,CAAC,gBAAgB,IAAI,CAAC,SAAS,YAAY,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YACzG,CAAC;QACH,CAAC,CAAC,CACH,CAAC;QACF,OAAO,KAAK,CAAC;IACf,CAAC;CACF"}
1
+ {"version":3,"file":"ReplyMarkerTransport.js","sourceRoot":"","sources":["../../src/core/ReplyMarkerTransport.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.335",
3
+ "version": "1.3.336",
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-06T03:50:02.661Z",
5
- "instarVersion": "1.3.335",
4
+ "generatedAt": "2026-06-06T03:58:05.940Z",
5
+ "instarVersion": "1.3.336",
6
6
  "entryCount": 199,
7
7
  "entries": {
8
8
  "hook:session-start": {
@@ -0,0 +1,45 @@
1
+ # Upgrade Guide — vNEXT
2
+
3
+ <!-- assembled-by: assemble-next-md -->
4
+ <!-- bump: patch -->
5
+
6
+ ## What Changed
7
+
8
+ Audit fix #5 under "No Unbounded Loops" (P19), completing the mesh-transport
9
+ brake set #874 started: `HttpLiveTailTransport` (conversation-tail streaming)
10
+ and `ReplyMarkerTransport` (cross-machine "already answered" markers) get
11
+ `AbortSignal.timeout` on their fetches (30s default — the #874 reviewer's
12
+ stall-envelope sizing, applied from the start) and `PeerFailureLogGate`
13
+ state-change failure logging (first / every-Nth / recovery; previously one
14
+ line per failed attempt, and silent for non-ok responses). Verified: neither
15
+ transport feeds lease renewal/suspend (`isReachable()`'s only consumer is the
16
+ lease wire), so the timeout carries zero authority coupling. The reviewer
17
+ confirmed the marker-drop trade-off under a 30s abort is pre-accepted by the
18
+ marker's documented design (fire-and-forget; provider redelivery + dedup gate
19
+ + synced ledger are the backstops).
20
+
21
+ ## What to Tell Your User
22
+
23
+ If you run me on more than one machine: the last two machine-to-machine sync
24
+ channels now have the same protections as the rest — a stuck network
25
+ connection can't silently jam them, and a down machine produces a handful of
26
+ meaningful log lines instead of one per failed attempt. All four cross-machine
27
+ wires now follow the loop-safety standard.
28
+
29
+ ## Summary of New Capabilities
30
+
31
+ - Hung-socket protection + bounded failure logging on the live-tail and
32
+ reply-marker transports (no configuration needed; recovery and
33
+ rejecting-peer visibility included).
34
+
35
+ ## Evidence
36
+
37
+ CMT-1109 audit, mechanical completion of the #874 pattern (line-level
38
+ CONCUR-reviewed tonight) on two lower-blast-radius transports. Focused
39
+ adversarial second-pass: CONCUR on all probes (Two-Generals widening
40
+ pre-accepted by design — broadcast is void-discarded at its only callsite;
41
+ gate memory peer-bounded; alternating ok/fail chatter is diagnostic at reply
42
+ cadence; local encryptFor throws disambiguate via error detail). Tests: 6 new
43
+ green (AbortSignal pins both transports; P19 bounds — 25 failed flushes → 3
44
+ lines, 12 rejected markers → 2 lines; recovery-once; steady-success silence)
45
+ + pre-existing transport suites untouched and green; tsc clean.
@@ -0,0 +1,43 @@
1
+ # Side-Effects Review — Sibling-Transport Brakes
2
+
3
+ **Version / slug:** `sibling-transport-brakes`
4
+ **Date:** `2026-06-06`
5
+ **Author:** `Echo (instar-dev agent, autonomous session per Justin's direction)`
6
+ **Second-pass reviewer:** `focused adversarial reviewer subagent — CONCUR on all four probes (the #874 pattern itself carries tonight's line-level CONCUR)`
7
+
8
+ ## Summary of the change
9
+
10
+ The #874 brake pattern applied verbatim to the two remaining mesh transports: `HttpLiveTailTransport` and `ReplyMarkerTransport` get `AbortSignal.timeout` (30s default, the #874-corrected sizing above the fleet's 5–40s receiver-stall envelope) on their fetches, and `PeerFailureLogGate` state-change failure logging (live-tail N=360; reply-marker N=50 for reply cadence) replacing per-attempt lines, with non-ok responses now gated-logged. Files: both transports, one test file.
11
+
12
+ ## Decision-point inventory
13
+
14
+ - Both transports' `broadcast()` — **modify (bounded)** — same requests, same return semantics; failures abort at the timeout instead of hanging; logging gated.
15
+
16
+ ## 1. Over-block / 2. Under-block
17
+
18
+ (a) A 30s abort can drop a reply-marker a slower wait might have delivered — widening the marker's documented Two-Generals residual. Reviewer-traced: `broadcast()`'s return is void-discarded at its ONLY callsite (fire-and-forget by design); provider redelivery + the dedup gate + git-committed ledger state are the explicit backstops. Pre-accepted, not new risk. (b) Perfectly alternating ok/fail logs one transition pair per cycle — at reply cadence this is bounded and is diagnostic signal for a genuinely unstable peer (reviewer: not a blocker; an across-resets suppressor would mask real instability). (c) A local `encryptFor` throw logs under the peer's key — imprecise label, but the error detail (the real exception message) disambiguates and the operational meaning ("this peer's flush did not deliver") is identical. (d) Remaining audit item is the SessionRouter design <!-- tracked: CMT-1109 -->.
19
+
20
+ ## 3. Level-of-abstraction fit / 4. Signal vs authority
21
+
22
+ Brakes in the transports that generate the cost; cadence stays with callers; reuses the canonical gate class rather than re-implementing. **Signal-only** per `docs/signal-vs-authority.md`: log shaping + failure-timing bounds. Critically verified: neither transport feeds lease renewal/suspend (`.isReachable()`'s only src consumer is `LeaseCoordinator` via the LEASE transport) — the #874 reviewer's false-self-suspend concern structurally cannot apply here.
23
+
24
+ ## 5. Interactions
25
+
26
+ - **Exactly-once (the marker's job):** unchanged — the timeout affects only the best-effort fast path; the dedup gate and ledger sync carry correctness (reviewer probe 1).
27
+ - **#867's per-topic backoff:** composes — backoff bounds live-tail attempt RATE per topic; the gate bounds LOG volume per peer across topics.
28
+ - **Old format pins:** none — pre-existing transport suites pass untouched.
29
+ - **Node engines / AbortSignal-vs-test-clocks:** identical to #874 (verified there; same package.json).
30
+
31
+ ## 6. External surfaces / 7. Rollback
32
+
33
+ Logs only; no API/schema/config/persistent state; no migration (in-code defaults). Rollback = revert; the hang exposure and per-attempt logging return.
34
+
35
+ ## Conclusion
36
+
37
+ Completes the mesh-transport brake set: all four cross-machine wires (lease #874, heartbeat #881, live-tail and reply-marker here) now carry P19's brakes. Mechanical extension of a twice-validated pattern, with the one novel risk (marker-drop under timeout) traced to a documented, backstopped design acceptance.
38
+
39
+ ---
40
+
41
+ ## Phase 5 — Second-pass review (cross-machine exactly-once adjacency → performed)
42
+
43
+ A focused adversarial pass probed only what is novel beyond #874's reviewed pattern: (1) the Two-Generals widening from a 30s marker abort — traced `broadcast()`'s only callsite (void-discarded, fire-and-forget, comment-documented backstops): pre-accepted by design; (2) gate key granularity + alternating ok/fail behavior — peer-bounded memory, transition chatter acceptable-and-diagnostic at reply cadence; (3) local `encryptFor` throws misattributed to the peer — disambiguated by the error detail, operationally equivalent; (4) ran the new + pre-existing transport suites (15/15) and tsc (clean). **Verdict: CONCUR.**