@groundnuty/macf-channel-server 0.2.37 → 0.2.39

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.
@@ -45,7 +45,8 @@ export type CollisionResult = {
45
45
  * squatter that motivated this), so a versioned incoming takes it over.
46
46
  *
47
47
  * Quadrant (incoming × existing-alive), assuming the existing peer answers
48
- * `/health` (dead takeover regardless):
48
+ * `/health` on every re-confirm ping (dead, OR alive-then-dead flicker per the
49
+ * just-killed-port race groundnuty/macf#553 → takeover regardless):
49
50
  *
50
51
  * incoming versioned, existing unversioned → takeover (takeover_unversioned_existing)
51
52
  * incoming versioned, existing older → takeover (takeover_newer_version)
@@ -63,6 +64,14 @@ export type CollisionResult = {
63
64
  * over the existing ping→decide→register sequence — two racing newer instances
64
65
  * degrade to the same race the current `variable_exists` check already has.
65
66
  *
67
+ * Complementary staleness signal (DR-031, groundnuty/macf#568): when the quadrant
68
+ * above would ABORT against a /health-answering peer but that peer's registry
69
+ * `last_heartbeat` has aged past the TTL, the entry is taken over anyway — the
70
+ * stale heartbeat is a SECOND, version-independent liveness signal that resolves
71
+ * the just-killed-port ambiguity (#553) toward "dead". It is purely additive: it
72
+ * only ever turns a would-abort into a takeover, never the reverse, and a fresh or
73
+ * absent heartbeat leaves the quadrant's decision exactly as-is.
74
+ *
66
75
  * @param incomingVersion this instance's channel-server version (PACKAGE_VERSION).
67
76
  */
68
77
  export declare function checkCollision(name: string, registry: Registry, certPaths: {
@@ -1 +1 @@
1
- {"version":3,"file":"collision.d.ts","sourceRoot":"","sources":["../src/collision.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACjE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,EAAE,SAAS,EAAiB,MAAM,uBAAuB,CAAC;AAKjE,qBAAa,cAAe,SAAQ,SAAS;gBAC/B,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM;CAQrD;AAED;;;;;;;GAOG;AACH,qBAAa,iBAAkB,SAAQ,SAAS;gBAClC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,GAAG,IAAI;CAYpD;AAID;;0EAE0E;AAC1E,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACjC;AAkFD,MAAM,MAAM,eAAe,GACvB;IAAE,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAA;CAAE,GAC/B;IAAE,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,SAAS,CAAA;CAAE,GAC7D;IAAE,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,SAAS,CAAA;CAAE,CAAC;AAE/D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,wBAAsB,cAAc,CAClC,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,QAAQ,EAClB,SAAS,EAAE;IACT,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;CAC/B,EACD,eAAe,EAAE,MAAM,EACvB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,eAAe,CAAC,CA4E1B"}
1
+ {"version":3,"file":"collision.d.ts","sourceRoot":"","sources":["../src/collision.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACjE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,EAAE,SAAS,EAAwD,MAAM,uBAAuB,CAAC;AAKxG,qBAAa,cAAe,SAAQ,SAAS;gBAC/B,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM;CAQrD;AAED;;;;;;;GAOG;AACH,qBAAa,iBAAkB,SAAQ,SAAS;gBAClC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,GAAG,IAAI;CAYpD;AA2BD;;0EAE0E;AAC1E,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACjC;AA2GD,MAAM,MAAM,eAAe,GACvB;IAAE,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAA;CAAE,GAC/B;IAAE,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,SAAS,CAAA;CAAE,GAC7D;IAAE,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,SAAS,CAAA;CAAE,CAAC;AAE/D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AACH,wBAAsB,cAAc,CAClC,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,QAAQ,EAClB,SAAS,EAAE;IACT,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;CAC/B,EACD,eAAe,EAAE,MAAM,EACvB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,eAAe,CAAC,CAmH1B"}
package/dist/collision.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { request } from 'node:https';
2
2
  import { readFileSync } from 'node:fs';
3
- import { MacfError, compareSemver } from '@groundnuty/macf-core';
3
+ import { MacfError, compareSemver, isStaleEntry, DEFAULT_REGISTRY_TTL_MS } from '@groundnuty/macf-core';
4
4
  /** Matches a parseable `x.y.z` (optional leading `v`) version string. */
5
5
  const VERSION_PATTERN = /^v?\d+\.\d+\.\d+$/;
6
6
  export class CollisionError extends MacfError {
@@ -30,6 +30,26 @@ export class RegisterRaceError extends MacfError {
30
30
  }
31
31
  }
32
32
  const HEALTH_PING_TIMEOUT_MS = 5000;
33
+ /**
34
+ * Liveness re-confirmation against the just-killed-port race (groundnuty/macf#553).
35
+ *
36
+ * A killed channel server's listening socket can momentarily still accept a
37
+ * TCP/TLS connection and answer ONE `/health` 2xx during the narrow window
38
+ * before the OS finishes releasing the port. Trusting that single 2xx
39
+ * mis-classifies a just-killed prior instance as `alive`, and the #424 version
40
+ * quadrant then aborts the restart against a doomed peer — stranding the slot
41
+ * until a manual registry delete.
42
+ *
43
+ * To be robust we require HEALTH_CONFIRM_ATTEMPTS *consecutive* 2xx answers
44
+ * (HEALTH_CONFIRM_DELAY_MS apart). Any failed attempt short-circuits to dead →
45
+ * the caller takes over the slot. A genuinely-live peer answers every attempt →
46
+ * still alive → still aborts (no groundnuty/macf#424 regression). Bounded: at
47
+ * most HEALTH_CONFIRM_ATTEMPTS pings and (HEALTH_CONFIRM_ATTEMPTS - 1) delays of
48
+ * added startup latency, paid only when the first ping is alive.
49
+ */
50
+ const HEALTH_CONFIRM_ATTEMPTS = 2;
51
+ const HEALTH_CONFIRM_DELAY_MS = 300;
52
+ const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
33
53
  /**
34
54
  * Ping an agent's /health endpoint via mTLS.
35
55
  * Returns `{ alive, version }`: alive iff the agent responds 2xx; version is
@@ -100,6 +120,26 @@ function pingHealth(host, port, caCertPath, agentCertPath, agentKeyPath, timeout
100
120
  req.end();
101
121
  });
102
122
  }
123
+ /**
124
+ * Classify the existing peer's liveness, robust to the just-killed-port race
125
+ * (groundnuty/macf#553). Pings `/health` up to HEALTH_CONFIRM_ATTEMPTS times,
126
+ * waiting HEALTH_CONFIRM_DELAY_MS between attempts. The FIRST non-alive answer
127
+ * short-circuits to dead (`{ alive:false, version:null }`), so a flickering
128
+ * just-killed peer is treated as dead → the caller takes over the slot. Only a
129
+ * peer that answers 2xx on EVERY attempt is classified alive; the returned
130
+ * version is that of the final (still-answering) ping, feeding the #424 quadrant.
131
+ */
132
+ async function confirmLiveness(host, port, caCertPath, agentCertPath, agentKeyPath) {
133
+ let result = { alive: false, version: null };
134
+ for (let attempt = 0; attempt < HEALTH_CONFIRM_ATTEMPTS; attempt += 1) {
135
+ if (attempt > 0)
136
+ await sleep(HEALTH_CONFIRM_DELAY_MS);
137
+ result = await pingHealth(host, port, caCertPath, agentCertPath, agentKeyPath);
138
+ if (!result.alive)
139
+ return { alive: false, version: null };
140
+ }
141
+ return result;
142
+ }
103
143
  /**
104
144
  * Check if an agent is already registered and alive.
105
145
  *
@@ -114,7 +154,8 @@ function pingHealth(host, port, caCertPath, agentCertPath, agentKeyPath, timeout
114
154
  * squatter that motivated this), so a versioned incoming takes it over.
115
155
  *
116
156
  * Quadrant (incoming × existing-alive), assuming the existing peer answers
117
- * `/health` (dead takeover regardless):
157
+ * `/health` on every re-confirm ping (dead, OR alive-then-dead flicker per the
158
+ * just-killed-port race groundnuty/macf#553 → takeover regardless):
118
159
  *
119
160
  * incoming versioned, existing unversioned → takeover (takeover_unversioned_existing)
120
161
  * incoming versioned, existing older → takeover (takeover_newer_version)
@@ -132,6 +173,14 @@ function pingHealth(host, port, caCertPath, agentCertPath, agentKeyPath, timeout
132
173
  * over the existing ping→decide→register sequence — two racing newer instances
133
174
  * degrade to the same race the current `variable_exists` check already has.
134
175
  *
176
+ * Complementary staleness signal (DR-031, groundnuty/macf#568): when the quadrant
177
+ * above would ABORT against a /health-answering peer but that peer's registry
178
+ * `last_heartbeat` has aged past the TTL, the entry is taken over anyway — the
179
+ * stale heartbeat is a SECOND, version-independent liveness signal that resolves
180
+ * the just-killed-port ambiguity (#553) toward "dead". It is purely additive: it
181
+ * only ever turns a would-abort into a takeover, never the reverse, and a fresh or
182
+ * absent heartbeat leaves the quadrant's decision exactly as-is.
183
+ *
135
184
  * @param incomingVersion this instance's channel-server version (PACKAGE_VERSION).
136
185
  */
137
186
  export async function checkCollision(name, registry, certPaths, incomingVersion, logger) {
@@ -147,7 +196,11 @@ export async function checkCollision(name, registry, certPaths, incomingVersion,
147
196
  port: existing.port,
148
197
  instance_id: existing.instance_id,
149
198
  });
150
- const { alive, version: existingVersion } = await pingHealth(existing.host, existing.port, certPaths.caCertPath, certPaths.agentCertPath, certPaths.agentKeyPath);
199
+ // Liveness is re-confirmed across HEALTH_CONFIRM_ATTEMPTS pings to defeat the
200
+ // just-killed-port race (groundnuty/macf#553): a single momentary 2xx from a
201
+ // dying prior instance must NOT count as alive. A confirmed-live peer then
202
+ // flows into the unchanged #424 version quadrant below.
203
+ const { alive, version: existingVersion } = await confirmLiveness(existing.host, existing.port, certPaths.caCertPath, certPaths.agentCertPath, certPaths.agentKeyPath);
151
204
  if (alive) {
152
205
  const versionTakeoverDisabled = process.env['MACF_NO_VERSION_TAKEOVER'] === '1';
153
206
  const incomingVersioned = VERSION_PATTERN.test(incomingVersion);
@@ -194,6 +247,39 @@ export async function checkCollision(name, registry, certPaths, incomingVersion,
194
247
  });
195
248
  if (takeover)
196
249
  return { action: 'takeover', previous: existing };
250
+ // DR-031 (groundnuty/macf#568) — COMPLEMENTARY staleness override. PURELY
251
+ // ADDITIVE and ONE-DIRECTIONAL: it can only turn a would-ABORT into a
252
+ // takeover, never the reverse. The #424 version quadrant + #553 confirmLiveness
253
+ // above are byte-for-byte unchanged; we only reach here when that quadrant
254
+ // already decided to ABORT against a peer that answered /health on EVERY
255
+ // confirm ping. The registry heartbeat (#589) re-stamps `last_heartbeat` on a
256
+ // coarse cadence, so an entry whose heartbeat aged past the TTL is almost
257
+ // certainly a DEAD instance whose freed/recycled port merely still answers (the
258
+ // #553 just-killed-port race, or a zombie squatting the port) — the stale
259
+ // signal resolves that ambiguity toward "dead → take over", exactly as the
260
+ // dead-`/health` path below already does (which likewise ignores the version
261
+ // policy). Safety: this can ONLY add a takeover, never block one — a FRESH
262
+ // heartbeat leaves the abort exactly as the quadrant decided, and an ABSENT or
263
+ // unparseable `last_heartbeat` is NEVER stale (`isStaleEntry` returns false), so
264
+ // pre-DR-031 entries and heartbeat-disabled-but-live instances take the
265
+ // unchanged path. A genuinely-live instance keeps its heartbeat fresh (it beats
266
+ // every cadence) and registration itself writes no heartbeat — so the only way
267
+ // to be stale here is to have beaten once and then stopped (the ungraceful
268
+ // death this backstops). The TTL slack (3× the 5-min cadence) prevents a
269
+ // healthy-but-briefly-unlucky instance from being judged stale.
270
+ if (isStaleEntry(existing, DEFAULT_REGISTRY_TTL_MS, Date.now())) {
271
+ logger.warn('collision_check', {
272
+ result: 'takeover_stale_heartbeat',
273
+ agent: name,
274
+ prior_basis: basis,
275
+ incoming_version: incomingVersion,
276
+ existing_version: existingVersion,
277
+ last_heartbeat: existing.last_heartbeat ?? null,
278
+ host: existing.host,
279
+ port: existing.port,
280
+ });
281
+ return { action: 'takeover', previous: existing };
282
+ }
197
283
  return { action: 'abort', existing };
198
284
  }
199
285
  logger.info('collision_check', {
@@ -1 +1 @@
1
- {"version":3,"file":"collision.js","sourceRoot":"","sources":["../src/collision.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"collision.js","sourceRoot":"","sources":["../src/collision.ts"],"names":[],"mappings":"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"}
@@ -184,6 +184,83 @@ export declare function backfillProcessed(edges: readonly CommsLedgerEdge[], rec
184
184
  * read, not the authoritative write.
185
185
  */
186
186
  export declare function mergeLedgers(contents: readonly string[]): CommsLedgerEdge[];
187
+ /** Receipt-sink filename (sibling of `channel.log`); the local turn-receipt log. */
188
+ export declare const RECEIPT_SINK_FILENAME = "processed-receipts.jsonl";
189
+ /**
190
+ * Derive the receipt-sink path from the channel-server's `logPath` (`MACF_LOG_PATH`),
191
+ * as a sibling file in the same `.macf/logs/` directory — parallel to
192
+ * `ledgerPathFromLog`. `undefined` when no log path is configured (then
193
+ * `last_processed` is null: there is no sink to read). This is the SAME path the
194
+ * `emit-turn-receipt.sh` hook writes to (`$(dirname MACF_LOG_PATH)/<filename>`).
195
+ */
196
+ export declare function receiptSinkPathFromLog(logPath: string | undefined): string | undefined;
197
+ /**
198
+ * One local turn-receipt line, written by `emit-turn-receipt.sh` (one per routed
199
+ * marker the agent processed in a turn). The compact wire form is exactly
200
+ * `{"ts":<epoch-ms>,"run_id":"<run_id>","agent":"<agent>"}`.
201
+ */
202
+ export declare const ProcessedReceiptSchema: z.ZodObject<{
203
+ ts: z.ZodNumber;
204
+ run_id: z.ZodString;
205
+ agent: z.ZodString;
206
+ }, z.core.$strip>;
207
+ export type ProcessedReceipt = z.infer<typeof ProcessedReceiptSchema>;
208
+ /** The `/health` `last_processed` self-report shape (DR-030 passive-Processed tier). */
209
+ export interface LastProcessedReport {
210
+ /** ISO-8601 timestamp of the most-recent turn-receipt (null if none/unparseable). */
211
+ readonly at: string | null;
212
+ /**
213
+ * GitHub anchor (owner/repo#N). Always `null` for the receipt sink — a turn
214
+ * receipt carries no github_anchor. The field stays in the shape for back-compat
215
+ * with the schema (and a future ledger-join view that could populate it).
216
+ */
217
+ readonly anchor: string | null;
218
+ /** now − ts, clamped ≥ 0; null when `at` is absent or `ts` is non-finite. */
219
+ readonly age_ms: number | null;
220
+ /**
221
+ * The receipt's `run_id` — THE `--inject` CONTRACT. An injector routes a prompt
222
+ * carrying a known `run_id` in its `[macf-route:<run_id>:<agent>]` marker, lets
223
+ * the agent process it in a turn, then reads `/health` and matches this
224
+ * `correlation_token` to confirm ITS OWN message was processed.
225
+ */
226
+ readonly correlation_token: string | null;
227
+ }
228
+ /**
229
+ * Parse a receipt-sink file's text into receipts, tolerantly: blank + malformed
230
+ * lines (incl. a torn final line mid-append) are skipped, never fatal — a corrupt
231
+ * line must not blind the read. Same posture as `mergeLedgers`.
232
+ */
233
+ export declare function parseReceipts(content: string): ProcessedReceipt[];
234
+ /**
235
+ * Select the most-recent receipt (max `ts`), or null when there are none.
236
+ * Single-pass max-`ts` (not a sort) — cheap on the infrequent `/health` path. On
237
+ * equal `ts`, the first-seen wins (a benign tie). Max-`ts` (rather than just the
238
+ * last line) is robust to out-of-order lines under clock skew.
239
+ */
240
+ export declare function selectLastReceipt(receipts: readonly ProcessedReceipt[]): ProcessedReceipt | null;
241
+ /**
242
+ * Map a selected receipt (or null) into the `last_processed` `/health` shape.
243
+ * `at` ← ISO-8601 of the receipt's epoch-ms `ts`; `correlation_token` ← `run_id`
244
+ * (the `--inject` contract); `anchor` ← null (the sink carries no github_anchor);
245
+ * `age_ms` ← now − ts, clamped ≥ 0. A non-finite `ts` yields `at: null` + `age_ms: null`.
246
+ */
247
+ export declare function mapReceiptToLastProcessed(receipt: ProcessedReceipt | null, now: number): LastProcessedReport | null;
248
+ /**
249
+ * Read the agent's most-recent turn-receipt from the receipt sink and map it to
250
+ * the `/health` `last_processed` self-report. NEVER throws — an unset/missing/
251
+ * unreadable/garbage sink (or any read/parse error) degrades to `null`, so it can
252
+ * never break `/health`. Inject `readReceipts` in tests to skip the file entirely.
253
+ *
254
+ * Perf: reads the whole jsonl on each call. A `/health` ping is infrequent and the
255
+ * sink is operator-rotated like the ledger (see `ROTATION_POLICY`), so a bounded
256
+ * full read is fine; a tail-scan optimisation is possible if it ever grows unbounded.
257
+ */
258
+ export declare function readLastProcessed(opts: {
259
+ readonly logPath?: string | undefined;
260
+ readonly receiptSinkPath?: string | undefined;
261
+ readonly now: number;
262
+ readonly readReceipts?: () => readonly ProcessedReceipt[];
263
+ }): LastProcessedReport | null;
187
264
  /**
188
265
  * Rotation/retention policy (DR-025 §"Costs", "no silent caps"):
189
266
  *
@@ -1 +1 @@
1
- {"version":3,"file":"comms-ledger.d.ts","sourceRoot":"","sources":["../src/comms-ledger.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH;;;;GAIG;AACH,eAAO,MAAM,gBAAgB;;;;;;;;EAU3B,CAAC;AACH,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAE1D,eAAO,MAAM,kBAAkB;;;EAAkC,CAAC;AAClE,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAE9D,eAAO,MAAM,oBAAoB;;;EAA2B,CAAC;AAC7D,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAElE;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAahC,CAAC;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAEpE,2DAA2D;AAC3D,eAAO,MAAM,kBAAkB,MAAM,CAAC;AAEtC;;;;;;GAMG;AACH,wBAAgB,aAAa,CAC3B,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EAC/B,GAAG,GAAE,MAA2B,GAC/B,MAAM,CAUR;AAED,+EAA+E;AAC/E,eAAO,MAAM,qBAAqB,uBAAuB,CAAC;AAE1D;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAGjF;AAED,MAAM,WAAW,WAAW;IAC1B;;;;;;;;;OASG;IACH,QAAQ,CAAC,UAAU,EAAE,CAAC,IAAI,EAAE,eAAe,KAAK,IAAI,CAAC;IACrD,yEAAyE;IACzE,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;CACnC;AASD;;;;;;;;;;;;GAYG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE;IACtC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACtC,oDAAoD;IACpD,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC1C,GAAG,WAAW,CAkBd;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,SAAS,eAAe,EAAE,EACjC,WAAW,EAAE,WAAW,CAAC,MAAM,CAAC,EAChC,KAAK,EAAE,CAAC,IAAI,EAAE,eAAe,KAAK,MAAM,GACvC,eAAe,EAAE,CAInB;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,GAAG,eAAe,EAAE,CAW3E;AAYD;;;;;;;;;GASG;AACH,eAAO,MAAM,eAAe,EAAG,4CAAqD,CAAC"}
1
+ {"version":3,"file":"comms-ledger.d.ts","sourceRoot":"","sources":["../src/comms-ledger.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { appendFileSync, existsSync, mkdirSync, writeFileSync } from 'node:fs';
1
+ import { appendFileSync, existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
2
2
  import { dirname, join } from 'node:path';
3
3
  import { z } from 'zod';
4
4
  /**
@@ -210,6 +210,138 @@ function safeJson(line) {
210
210
  return '{}';
211
211
  }
212
212
  }
213
+ // --- DR-030 phase-1 (groundnuty/macf#568): last_processed via the RECEIPT SINK ---
214
+ //
215
+ // The `/health` `last_processed` field is the agent's passive-Processed
216
+ // self-report: "I processed a routed coordination message at time T", proven
217
+ // LOCALLY with no synthetic injection (DR-030 §3 "Passive-Processed tier").
218
+ //
219
+ // THE LOCAL "PROCESSED" SOURCE IS THE RECEIPT SINK, not the comms-ledger.
220
+ // When the router injects a prompt it appends a `[macf-route:<run_id>:<agent>]`
221
+ // marker (macf-actions#45); the `emit-turn-receipt.sh` UserPromptSubmit hook
222
+ // fires when that prompt is submitted AS A TURN and — alongside the OTLP
223
+ // `turn_processed` span (which feeds Tempo + the #444 reconciler) — appends one
224
+ // receipt line per marker to `processed-receipts.jsonl` (a sibling of
225
+ // `channel.log`, see `receiptSinkPathFromLog`). THAT local append is the proof a
226
+ // turn happened, and it is what this reader surfaces — making the passive tier a
227
+ // real LOCAL self-report rather than a Tempo-only one (the keystone of #568).
228
+ //
229
+ // Why NOT the comms-ledger's `processed` field: every edge site writes
230
+ // `processed: null` — the delivery≠turn join is a DERIVED view (`backfillProcessed`
231
+ // / the #444 reconciler), never written back to the append-only ledger (DR-025).
232
+ // So a `recv` + `processed:true` edge never exists on disk and a ledger scan is
233
+ // always null. The ledger stays the authoritative edge record; this sink is the
234
+ // separate, purpose-built local "I took a turn" proof.
235
+ /** Receipt-sink filename (sibling of `channel.log`); the local turn-receipt log. */
236
+ export const RECEIPT_SINK_FILENAME = 'processed-receipts.jsonl';
237
+ /**
238
+ * Derive the receipt-sink path from the channel-server's `logPath` (`MACF_LOG_PATH`),
239
+ * as a sibling file in the same `.macf/logs/` directory — parallel to
240
+ * `ledgerPathFromLog`. `undefined` when no log path is configured (then
241
+ * `last_processed` is null: there is no sink to read). This is the SAME path the
242
+ * `emit-turn-receipt.sh` hook writes to (`$(dirname MACF_LOG_PATH)/<filename>`).
243
+ */
244
+ export function receiptSinkPathFromLog(logPath) {
245
+ if (!logPath)
246
+ return undefined;
247
+ return join(dirname(logPath), RECEIPT_SINK_FILENAME);
248
+ }
249
+ /**
250
+ * One local turn-receipt line, written by `emit-turn-receipt.sh` (one per routed
251
+ * marker the agent processed in a turn). The compact wire form is exactly
252
+ * `{"ts":<epoch-ms>,"run_id":"<run_id>","agent":"<agent>"}`.
253
+ */
254
+ export const ProcessedReceiptSchema = z.object({
255
+ /** Epoch milliseconds at which the routed prompt was submitted as a turn. */
256
+ ts: z.number(),
257
+ /** The router run id from the `[macf-route:<run_id>:<agent>]` marker. */
258
+ run_id: z.string().min(1),
259
+ /** The kebab agent name from the marker. */
260
+ agent: z.string().min(1),
261
+ });
262
+ /**
263
+ * Parse a receipt-sink file's text into receipts, tolerantly: blank + malformed
264
+ * lines (incl. a torn final line mid-append) are skipped, never fatal — a corrupt
265
+ * line must not blind the read. Same posture as `mergeLedgers`.
266
+ */
267
+ export function parseReceipts(content) {
268
+ const out = [];
269
+ for (const raw of content.split('\n')) {
270
+ const line = raw.trim();
271
+ if (!line)
272
+ continue;
273
+ let json;
274
+ try {
275
+ json = JSON.parse(line);
276
+ }
277
+ catch {
278
+ continue;
279
+ }
280
+ const parsed = ProcessedReceiptSchema.safeParse(json);
281
+ if (parsed.success)
282
+ out.push(parsed.data);
283
+ }
284
+ return out;
285
+ }
286
+ /**
287
+ * Select the most-recent receipt (max `ts`), or null when there are none.
288
+ * Single-pass max-`ts` (not a sort) — cheap on the infrequent `/health` path. On
289
+ * equal `ts`, the first-seen wins (a benign tie). Max-`ts` (rather than just the
290
+ * last line) is robust to out-of-order lines under clock skew.
291
+ */
292
+ export function selectLastReceipt(receipts) {
293
+ let best = null;
294
+ for (const r of receipts) {
295
+ if (best === null || r.ts > best.ts)
296
+ best = r;
297
+ }
298
+ return best;
299
+ }
300
+ /**
301
+ * Map a selected receipt (or null) into the `last_processed` `/health` shape.
302
+ * `at` ← ISO-8601 of the receipt's epoch-ms `ts`; `correlation_token` ← `run_id`
303
+ * (the `--inject` contract); `anchor` ← null (the sink carries no github_anchor);
304
+ * `age_ms` ← now − ts, clamped ≥ 0. A non-finite `ts` yields `at: null` + `age_ms: null`.
305
+ */
306
+ export function mapReceiptToLastProcessed(receipt, now) {
307
+ if (receipt === null)
308
+ return null;
309
+ const finite = Number.isFinite(receipt.ts);
310
+ return {
311
+ at: finite ? new Date(receipt.ts).toISOString() : null,
312
+ anchor: null,
313
+ age_ms: finite ? Math.max(0, Math.floor(now - receipt.ts)) : null,
314
+ correlation_token: receipt.run_id,
315
+ };
316
+ }
317
+ /**
318
+ * Read the agent's most-recent turn-receipt from the receipt sink and map it to
319
+ * the `/health` `last_processed` self-report. NEVER throws — an unset/missing/
320
+ * unreadable/garbage sink (or any read/parse error) degrades to `null`, so it can
321
+ * never break `/health`. Inject `readReceipts` in tests to skip the file entirely.
322
+ *
323
+ * Perf: reads the whole jsonl on each call. A `/health` ping is infrequent and the
324
+ * sink is operator-rotated like the ledger (see `ROTATION_POLICY`), so a bounded
325
+ * full read is fine; a tail-scan optimisation is possible if it ever grows unbounded.
326
+ */
327
+ export function readLastProcessed(opts) {
328
+ try {
329
+ let receipts;
330
+ if (opts.readReceipts) {
331
+ receipts = opts.readReceipts();
332
+ }
333
+ else {
334
+ const path = opts.receiptSinkPath ?? receiptSinkPathFromLog(opts.logPath);
335
+ if (!path || !existsSync(path))
336
+ return null;
337
+ receipts = parseReceipts(readFileSync(path, 'utf8'));
338
+ }
339
+ return mapReceiptToLastProcessed(selectLastReceipt(receipts), opts.now);
340
+ }
341
+ catch {
342
+ return null;
343
+ }
344
+ }
213
345
  /**
214
346
  * Rotation/retention policy (DR-025 §"Costs", "no silent caps"):
215
347
  *
@@ -1 +1 @@
1
- {"version":3,"file":"comms-ledger.js","sourceRoot":"","sources":["../src/comms-ledger.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"comms-ledger.js","sourceRoot":"","sources":["../src/comms-ledger.ts"],"names":[],"mappings":"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"}
package/dist/health.d.ts CHANGED
@@ -1,3 +1,107 @@
1
- import type { HealthState } from '@groundnuty/macf-core';
2
- export declare function createHealthState(agentName: string, agentType: string): HealthState;
1
+ import type { HealthResponse, HealthState } from '@groundnuty/macf-core';
2
+ import { type ProcessedReceipt } from './comms-ledger.js';
3
+ /**
4
+ * Hard version contract for the `/health` body SHAPE (DR-006 watchdog request,
5
+ * macf-devops-toolkit#115). A consumer asserts `health_schema_version === <known>`
6
+ * and refuses an unknown, so it fails LOUD on ANY breaking change to the
7
+ * `/health` shape — including a same-name SEMANTIC change (e.g. `last_processed.age_ms`
8
+ * meaning, an `at` rename) that additive-optional + presence-checks silently miss.
9
+ * BUMP on any breaking change to the `/health` shape; additive-optional fields do NOT
10
+ * bump it. Distinct from the package `version` (which bumps on every cs release).
11
+ */
12
+ export declare const HEALTH_SCHEMA_VERSION = 1;
13
+ /** The DR-030 `/health` `state` object shape (non-null), derived from the schema. */
14
+ type TurnStateReport = NonNullable<HealthResponse['state']>;
15
+ /**
16
+ * Parse a leaf-cert PEM and return its `notAfter` as an ISO-8601 string, or
17
+ * `null` if the PEM can't be parsed. DR-030 §4 per-agent `cert_expiry`
18
+ * self-report (an expired leaf = silent off-channels; thresholds — warn <30d
19
+ * / crit <7d — are the consumer's call). Uses `node:crypto` (zero-dep):
20
+ * `@peculiar/x509` is only needed to *create* X.509, not to read one.
21
+ */
22
+ export declare function leafCertExpiry(pem: string): string | null;
23
+ /**
24
+ * Map a parsed turn-state marker into the `/health` `state` object, computing
25
+ * `elapsed_ms` against `now` (so it stays fresh through a long, e.g. 20-minute,
26
+ * tool wait). Lenient by construction: the marker is written by an external hook,
27
+ * so any missing/wrong-typed field degrades to `null` rather than throwing, and a
28
+ * marker missing the required `status`/`turn_number` shape maps to `state: null`.
29
+ *
30
+ * elapsed_ms = status === 'busy' ? max(0, now − started_at) : 0
31
+ */
32
+ export declare function mapTurnStateMarker(raw: unknown, now: number): TurnStateReport | null;
33
+ /**
34
+ * Compute the static parts of the `otel` self-report from `process.env`.
35
+ *
36
+ * `endpoint_is_canonical` is **env-driven by design** — we deliberately do NOT
37
+ * hardcode the monitoring-VM host in channel-server code (it would drift the day
38
+ * the fleet's canonical endpoint moves). Instead "canonical" means "the live
39
+ * `OTEL_EXPORTER_OTLP_ENDPOINT` equals `MACF_OTEL_ENDPOINT`", the same env that
40
+ * `macf init`/`update` bake as the canonical default. So: false when no endpoint
41
+ * is set, false when `MACF_OTEL_ENDPOINT` is unset (nothing to be canonical
42
+ * against), false when they differ, true only when they're set + equal.
43
+ */
44
+ export declare function computeOtelEndpointInfo(env: NodeJS.ProcessEnv): {
45
+ readonly endpoint: string | null;
46
+ readonly endpoint_is_canonical: boolean;
47
+ };
48
+ /** Parse `host`/`port` from an OTLP endpoint URL; `null` if unparseable. */
49
+ export declare function parseEndpointHostPort(endpoint: string): {
50
+ readonly host: string;
51
+ readonly port: number;
52
+ } | null;
53
+ export interface OtelReachabilityProbe {
54
+ /** The cached reachability result (default `false` until the first probe completes). */
55
+ readonly get: () => boolean;
56
+ /** Run a single probe now and update the cache (awaitable; used by tests). */
57
+ readonly runOnce: () => Promise<void>;
58
+ /** Kick off an immediate probe + start the periodic interval (no-op if no endpoint). */
59
+ readonly start: () => void;
60
+ /** Clear the periodic interval (idempotent). */
61
+ readonly stop: () => void;
62
+ }
63
+ /**
64
+ * A cached, periodic OTLP-reachability probe. `getHealth()` is synchronous and
65
+ * can't await a TCP connect, so reachability is computed out-of-band on an
66
+ * interval and read from a cached boolean. The interval is `unref()`'d so it
67
+ * never keeps the process alive, and is also clearable via `stop()` on shutdown.
68
+ * The probe is injectable for testing (no real network in unit tests).
69
+ */
70
+ export declare function createOtelReachabilityProbe(endpoint: string | null, opts?: {
71
+ readonly intervalMs?: number;
72
+ readonly timeoutMs?: number;
73
+ readonly probe?: (host: string, port: number, timeoutMs: number) => Promise<boolean>;
74
+ }): OtelReachabilityProbe;
75
+ /** Optional self-report inputs for the DR-030 mesh-layer `/health` extension. */
76
+ export interface HealthStateOpts {
77
+ /** The registration instance id (registry/health staleness disambiguator). */
78
+ readonly instanceId?: string;
79
+ /** Path to the agent's leaf cert, for the `cert_expiry` self-report. */
80
+ readonly certPath?: string;
81
+ /**
82
+ * Path to the turn-state marker file. Defaults to
83
+ * `${MACF_WORKSPACE_DIR}/.macf/turn-state.json`; injectable for testing.
84
+ */
85
+ readonly turnStatePath?: string;
86
+ /** Injectable OTLP-reachability probe (testing — avoids real network). */
87
+ readonly otelProbe?: (host: string, port: number, timeoutMs: number) => Promise<boolean>;
88
+ /** Override the OTLP-reachability probe interval (testing); default 30s. */
89
+ readonly otelProbeIntervalMs?: number;
90
+ /**
91
+ * Channel-server log path (`MACF_LOG_PATH`); the turn-receipt sink lives at a
92
+ * sibling `processed-receipts.jsonl` in the same directory. Source for the
93
+ * DR-030 `last_processed` passive-receipt self-report (the server passes
94
+ * `config.logPath`). When unset (and no `processedReader`), `last_processed`
95
+ * is null — no sink to read.
96
+ */
97
+ readonly logPath?: string;
98
+ /**
99
+ * Injectable turn-receipt reader for `last_processed` (testing — avoids a real
100
+ * on-disk receipt sink). Takes precedence over `logPath`-derived file reads
101
+ * when set.
102
+ */
103
+ readonly processedReader?: () => readonly ProcessedReceipt[];
104
+ }
105
+ export declare function createHealthState(agentName: string, agentType: string, opts?: HealthStateOpts): HealthState;
106
+ export {};
3
107
  //# sourceMappingURL=health.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"health.d.ts","sourceRoot":"","sources":["../src/health.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAkB,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAQzE,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,WAAW,CA4BnF"}
1
+ {"version":3,"file":"health.d.ts","sourceRoot":"","sources":["../src/health.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACzE,OAAO,EAAqB,KAAK,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAE7E;;;;;;;;GAQG;AACH,eAAO,MAAM,qBAAqB,IAAI,CAAC;AAEvC,qFAAqF;AACrF,KAAK,eAAe,GAAG,WAAW,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC;AAU5D;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAMzD;AAuCD;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,eAAe,GAAG,IAAI,CA6BpF;AAID;;;;;;;;;;GAUG;AACH,wBAAgB,uBAAuB,CACrC,GAAG,EAAE,MAAM,CAAC,UAAU,GACrB;IAAE,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,QAAQ,CAAC,qBAAqB,EAAE,OAAO,CAAA;CAAE,CAO/E;AAED,4EAA4E;AAC5E,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,MAAM,GACf;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAWzD;AAuBD,MAAM,WAAW,qBAAqB;IACpC,wFAAwF;IACxF,QAAQ,CAAC,GAAG,EAAE,MAAM,OAAO,CAAC;IAC5B,8EAA8E;IAC9E,QAAQ,CAAC,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACtC,wFAAwF;IACxF,QAAQ,CAAC,KAAK,EAAE,MAAM,IAAI,CAAC;IAC3B,gDAAgD;IAChD,QAAQ,CAAC,IAAI,EAAE,MAAM,IAAI,CAAC;CAC3B;AAED;;;;;;GAMG;AACH,wBAAgB,2BAA2B,CACzC,QAAQ,EAAE,MAAM,GAAG,IAAI,EACvB,IAAI,GAAE;IACJ,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;CACjF,GACL,qBAAqB,CAwCvB;AAED,iFAAiF;AACjF,MAAM,WAAW,eAAe;IAC9B,8EAA8E;IAC9E,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,wEAAwE;IACxE,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B;;;OAGG;IACH,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,0EAA0E;IAC1E,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IACzF,4EAA4E;IAC5E,QAAQ,CAAC,mBAAmB,CAAC,EAAE,MAAM,CAAC;IACtC;;;;;;OAMG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B;;;;OAIG;IACH,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,SAAS,gBAAgB,EAAE,CAAC;CAC9D;AAED,wBAAgB,iBAAiB,CAC/B,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,IAAI,GAAE,eAAoB,GACzB,WAAW,CAsEb"}