@vibe-commit/capture 0.9.0 → 0.11.0

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 (88) hide show
  1. package/README.md +49 -1
  2. package/dist/agent_hooks.js +2 -2
  3. package/dist/cli.d.ts +35 -0
  4. package/dist/cli.js +412 -0
  5. package/dist/cli.js.map +1 -0
  6. package/dist/commands/backfill.js +19 -2
  7. package/dist/commands/backfill.js.map +1 -1
  8. package/dist/commands/finalize.d.ts +37 -1
  9. package/dist/commands/finalize.js +131 -29
  10. package/dist/commands/finalize.js.map +1 -1
  11. package/dist/commands/status.js +7 -0
  12. package/dist/commands/status.js.map +1 -1
  13. package/dist/commands/status_machine.js +5 -0
  14. package/dist/commands/status_machine.js.map +1 -1
  15. package/dist/commands/upload_worker.d.ts +63 -0
  16. package/dist/commands/upload_worker.js +336 -0
  17. package/dist/commands/upload_worker.js.map +1 -0
  18. package/dist/commands/why.d.ts +19 -1
  19. package/dist/commands/why.js +35 -3
  20. package/dist/commands/why.js.map +1 -1
  21. package/dist/commit_files.d.ts +64 -0
  22. package/dist/commit_files.js +83 -0
  23. package/dist/commit_files.js.map +1 -0
  24. package/dist/copy/strings.d.ts +34 -14
  25. package/dist/copy/strings.js +51 -14
  26. package/dist/copy/strings.js.map +1 -1
  27. package/dist/drain.d.ts +68 -0
  28. package/dist/drain.js +234 -0
  29. package/dist/drain.js.map +1 -0
  30. package/dist/firing.d.ts +169 -0
  31. package/dist/firing.js +334 -0
  32. package/dist/firing.js.map +1 -0
  33. package/dist/hooks/entry.d.ts +171 -26
  34. package/dist/hooks/entry.js +335 -507
  35. package/dist/hooks/entry.js.map +1 -1
  36. package/dist/hooks/fire_lock.d.ts +36 -87
  37. package/dist/hooks/fire_lock.js +40 -99
  38. package/dist/hooks/fire_lock.js.map +1 -1
  39. package/dist/hooks/post_commit.d.ts +11 -0
  40. package/dist/hooks/post_commit.js +16 -8
  41. package/dist/hooks/post_commit.js.map +1 -1
  42. package/dist/identity.d.ts +32 -0
  43. package/dist/identity.js +38 -0
  44. package/dist/identity.js.map +1 -0
  45. package/dist/index.d.ts +3 -17
  46. package/dist/index.js +59 -450
  47. package/dist/index.js.map +1 -1
  48. package/dist/paths.d.ts +18 -0
  49. package/dist/paths.js +31 -0
  50. package/dist/paths.js.map +1 -1
  51. package/dist/pending_prune.d.ts +2 -2
  52. package/dist/pending_prune.js +2 -2
  53. package/dist/policy.d.ts +17 -0
  54. package/dist/policy.js +7 -0
  55. package/dist/policy.js.map +1 -1
  56. package/dist/post.d.ts +63 -4
  57. package/dist/post.js +76 -24
  58. package/dist/post.js.map +1 -1
  59. package/dist/replay.d.ts +167 -0
  60. package/dist/replay.js +301 -0
  61. package/dist/replay.js.map +1 -0
  62. package/dist/session_targets.d.ts +12 -0
  63. package/dist/session_targets.js +6 -1
  64. package/dist/session_targets.js.map +1 -1
  65. package/dist/spool.d.ts +55 -21
  66. package/dist/spool.js +182 -38
  67. package/dist/spool.js.map +1 -1
  68. package/dist/spool_union.d.ts +18 -2
  69. package/dist/spool_union.js +23 -2
  70. package/dist/spool_union.js.map +1 -1
  71. package/dist/state.js +21 -14
  72. package/dist/state.js.map +1 -1
  73. package/dist/stdin.d.ts +2 -0
  74. package/dist/stdin.js +13 -0
  75. package/dist/stdin.js.map +1 -0
  76. package/dist/uploader_status.d.ts +34 -0
  77. package/dist/uploader_status.js +25 -0
  78. package/dist/uploader_status.js.map +1 -0
  79. package/dist/uploader_view.d.ts +39 -0
  80. package/dist/uploader_view.js +106 -0
  81. package/dist/uploader_view.js.map +1 -0
  82. package/dist/verbs.d.ts +11 -0
  83. package/dist/verbs.js +13 -0
  84. package/dist/verbs.js.map +1 -0
  85. package/dist/version.d.ts +1 -1
  86. package/dist/version.js +1 -1
  87. package/dist/version.js.map +1 -1
  88. package/package.json +2 -2
package/dist/paths.js CHANGED
@@ -234,6 +234,37 @@ export function sessionsRoot(home) {
234
234
  export function sessionTargetsPath(home, sessionId) {
235
235
  return join(targetsDir(home), `${sanitise(sessionId)}.targets`);
236
236
  }
237
+ /**
238
+ * U3 — a session's FIRING LOG: one line per hook that ended a turn, appended by the hook and replayed by the upload worker
239
+ * (`firing.ts`). Beside the session's target record, never under a repo digest: a firing belongs to the SESSION, and the repos it
240
+ * touches are named inside the line. `.firings.jsonl` is not `.json`, for the reason the whole directory is (`targetsDir`).
241
+ */
242
+ export function sessionFiringsPath(home, sessionId) {
243
+ return join(targetsDir(home), `${sanitise(sessionId)}.firings.jsonl`);
244
+ }
245
+ /** U3 — the worker's progress through `sessionFiringsPath`, written only under the session's writer lock. */
246
+ export function sessionFiringsCursorPath(home, sessionId) {
247
+ return join(targetsDir(home), `${sanitise(sessionId)}.firings.cursor`);
248
+ }
249
+ /** U5 — the machine-wide upload worker's lock for ONE identity (`identity.ts`). Beside the session records; neither a `.targets` nor a `.json`; the status file is `.status` for the same reason. */
250
+ export function uploaderLockPath(home, identity) {
251
+ return join(targetsDir(home), `uploader.${identity.slice(0, 32)}.lock`);
252
+ }
253
+ /** U5 — what the worker reports about itself, for `status` and the hook's notices: counts and classes, never a body, a path or a credential. */
254
+ export function uploaderStatusPath(home, identity) {
255
+ return join(targetsDir(home), `uploader.${identity.slice(0, 32)}.status`);
256
+ }
257
+ /**
258
+ * U3 — `<repo digest>/<session>.live`: the HOOK-only liveness stamp (`firing.ts`). Beside the session's state file, with an extension
259
+ * that is neither `.json` nor `.jsonl`, so no scan of state files (`lastSendForRepo`, `stuckForRepo`) takes it for a session.
260
+ * Null on no repo, for the reason `sessionStatePath` is.
261
+ */
262
+ export function sessionLivePath(home, key) {
263
+ const dir = repoSessionsDir(home, key.repoKey);
264
+ if (dir === null)
265
+ return null;
266
+ return join(dir, `${sanitise(key.sessionId)}.live`);
267
+ }
237
268
  /** Which work tree a state digest names — written by `spool.ts` when a commit is spooled. Null for no repo key. */
238
269
  export function repoKeyNotePath(home, repoKey) {
239
270
  if (repoKey === "")
package/dist/paths.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"paths.js","sourceRoot":"","sources":["../src/paths.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"paths.js","sourceRoot":"","sources":["../src/paths.ts"],"names":[],"mappings":"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"}
@@ -15,8 +15,8 @@
15
15
  * ## The rule
16
16
  * - TTL 7 days, STRICTLY older. A file is EXPIRED when its mtime AND the `observedAt` of every line are past it. A legacy
17
17
  * 0.4.0 line has no `observedAt`; the mtime ages it. ⛔ NEVER the line's `at` (the committer date — settable).
18
- * - WHOLE FILES ONLY, and only `*.pending.jsonl`. Survivors are never rewritten (`appendPending` is an unlocked
19
- * read-modify-write, so a rewrite could race it). `.spool.jsonl` (real, attributed commits), rewrites and state files are
18
+ * - WHOLE FILES ONLY, and only `*.pending.jsonl`. Survivors are never rewritten (a rewrite could race the
19
+ * appender; since U2 `appendPending` is a real append, but a prune that rewrote would still lose a line landing mid-write). `.spool.jsonl` (real, attributed commits), rewrites and state files are
20
20
  * never touched.
21
21
  * - At most 50 files per call. Called from the Stop and SessionEnd hooks only — not `post-commit` (it runs under git) and
22
22
  * not `status` (readers stay read-only).
@@ -15,8 +15,8 @@
15
15
  * ## The rule
16
16
  * - TTL 7 days, STRICTLY older. A file is EXPIRED when its mtime AND the `observedAt` of every line are past it. A legacy
17
17
  * 0.4.0 line has no `observedAt`; the mtime ages it. ⛔ NEVER the line's `at` (the committer date — settable).
18
- * - WHOLE FILES ONLY, and only `*.pending.jsonl`. Survivors are never rewritten (`appendPending` is an unlocked
19
- * read-modify-write, so a rewrite could race it). `.spool.jsonl` (real, attributed commits), rewrites and state files are
18
+ * - WHOLE FILES ONLY, and only `*.pending.jsonl`. Survivors are never rewritten (a rewrite could race the
19
+ * appender; since U2 `appendPending` is a real append, but a prune that rewrote would still lose a line landing mid-write). `.spool.jsonl` (real, attributed commits), rewrites and state files are
20
20
  * never touched.
21
21
  * - At most 50 files per call. Called from the Stop and SessionEnd hooks only — not `post-commit` (it runs under git) and
22
22
  * not `status` (readers stay read-only).
package/dist/policy.d.ts CHANGED
@@ -240,6 +240,23 @@ export declare function planChunk(cutter: RecordCutter, from: number, eof: numbe
240
240
  export declare function splitPoint(cutter: RecordCutter, from: number, to: number): number | null;
241
241
  /** Undelivered bytes currently held. */
242
242
  export declare function pendingBytes(state: FileState): number;
243
+ /**
244
+ * U4, trap 1 — WHAT A REPLAYED FIRING SHOULD DO. `nextSpan` reads `sentOffset > eof` as "the file was replaced" and returns `from: 0`, which
245
+ * is right for a hook (its `eof` is the file's size NOW) and WRONG for a firing replayed late: a firing older than a `finalize`, a backfill
246
+ * or a later firing's delivery carries an `eof` BEHIND `sentOffset`, and handing that to `nextSpan` would re-send the whole session from
247
+ * byte 0 and fork the version. So a replay compares with the file's REAL size:
248
+ * - `realSize < sentOffset`: the file really shrank (a rotation). Deliver to `realSize`; `nextSpan` resyncs from 0, as it always did.
249
+ * - `firingEof <= sentOffset`: this firing's bytes are already delivered. A no-op, and it is also what makes a duplicate firing (Cursor
250
+ * double-fires) free.
251
+ * - otherwise deliver to `min(firingEof, realSize)`: never past what the file holds now (a truncation since the hook fired).
252
+ */
253
+ export type ReplayDecision = {
254
+ readonly kind: "noop";
255
+ } | {
256
+ readonly kind: "deliver";
257
+ readonly eof: number;
258
+ };
259
+ export declare function replayDecision(sentOffset: number, firingEof: number, realSize: number): ReplayDecision;
243
260
  /**
244
261
  * The span the next attempt should carry: everything from the offset to `eof`.
245
262
  *
package/dist/policy.js CHANGED
@@ -231,6 +231,13 @@ export function pendingBytes(state) {
231
231
  return 0;
232
232
  return state.backlog[state.backlog.length - 1].to - state.backlog[0].from;
233
233
  }
234
+ export function replayDecision(sentOffset, firingEof, realSize) {
235
+ if (realSize < sentOffset)
236
+ return { kind: "deliver", eof: realSize };
237
+ if (firingEof <= sentOffset)
238
+ return { kind: "noop" };
239
+ return { kind: "deliver", eof: Math.min(firingEof, realSize) };
240
+ }
234
241
  /**
235
242
  * The span the next attempt should carry: everything from the offset to `eof`.
236
243
  *
@@ -1 +1 @@
1
- {"version":3,"file":"policy.js","sourceRoot":"","sources":["../src/policy.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"policy.js","sourceRoot":"","sources":["../src/policy.ts"],"names":[],"mappings":"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"}
package/dist/post.d.ts CHANGED
@@ -132,6 +132,11 @@ export interface IngestDelta {
132
132
  * (`match_kind` is in the primary key and the history is append-only).
133
133
  */
134
134
  readonly inferredRewrites?: readonly string[];
135
+ /**
136
+ * E8 — the byte length of the body trailer that carries the commits' changed-file list (`commit_files.ts`). ⛔ A NUMBER ONLY:
137
+ * the paths are in the body, never a header. Sent only together with `x-commits`, and only when the trailer really is on the body.
138
+ */
139
+ readonly commitFilesLength?: number;
135
140
  }
136
141
  /**
137
142
  * Build the request headers.
@@ -280,6 +285,11 @@ export type SendOutcome = {
280
285
  * credential-meta sidecar so state 5 can warn before the 365-day cap; it changes no disposition.
281
286
  */
282
287
  readonly credentialExpires?: string | null;
288
+ /**
289
+ * U5: `Retry-After` as MILLISECONDS, from the delta-seconds form only (a non-negative integer). `null` when absent, an HTTP-date, or malformed:
290
+ * the upload worker then uses its own backoff. A hook never reads it.
291
+ */
292
+ readonly retryAfterMs?: number | null;
283
293
  /**
284
294
  * `X-Grant-Epoch` (slice 2, `CR-259`): the version of the user's account grants, on every credential-lane ingest 2xx and on a
285
295
  * grants refusal. `null` when absent (a server that predates it) or not a non-negative integer.
@@ -328,6 +338,12 @@ export declare function parseGrantEpoch(raw: string | null): number | null;
328
338
  * must read as "the server did not say", never as a date in 1970.
329
339
  */
330
340
  export declare function parseCredentialExpires(raw: string | null): string | null;
341
+ /**
342
+ * `Retry-After` → milliseconds, for the delta-seconds form ONLY: ASCII digits, nothing else. An HTTP-date, a negative number, a fraction, a sign or
343
+ * anything with a unit is `null`, and the caller falls back to its own backoff. Capped at one day so a hostile value cannot overflow a timer.
344
+ * NEVER THROWS.
345
+ */
346
+ export declare function parseRetryAfterMs(raw: string | null): number | null;
331
347
  /**
332
348
  * One attempt. No retry, no backoff, no classification — `CR-018` owns all three.
333
349
  *
@@ -355,10 +371,25 @@ export declare function send(url: string, headers: Record<string, string>, body:
355
371
  * anything. No copy path and no header ever carries it.
356
372
  */
357
373
  export declare function credentialFingerprint(credential: IngestCredential): string;
374
+ /**
375
+ * U4 — WHY nothing was sent, when it was not simply "the offset is at EOF". `nothing-to-send` has always meant five different things, and a
376
+ * caller that treats them alike (the upload worker's cursor) would call a lost lock or a failed read "caught up" and skip bytes. Absent: the
377
+ * offset really is at EOF (or there is no span). Optional, so every existing `kind` comparison is unchanged.
378
+ */
379
+ export type NothingWhy =
380
+ /** The caller's heartbeat said the session lock is no longer ours: nothing was sent or written. */
381
+ "lock-lost"
382
+ /** The span could not be read (a vanished file, a cutter that threw): the next firing retries it. */
383
+ | "read-failed"
384
+ /** An unterminated record at EOF that may still be growing: left for the next event. */
385
+ | "unterminated"
386
+ /** The ledger could not be written ahead of the send (U1): no request was made. */
387
+ | "unwritable";
358
388
  export type Delivery =
359
389
  /** The offset is already at EOF. No request was made and none was needed. */
360
390
  {
361
391
  readonly kind: "nothing-to-send";
392
+ readonly why?: NothingWhy;
362
393
  }
363
394
  /** A `fatal` class fired earlier for this credential. No request was made. */
364
395
  | {
@@ -400,6 +431,8 @@ export type Delivery =
400
431
  readonly inferredSetAsidePairs: number;
401
432
  /** `X-Credential-Expires` from the 2xx that delivered this, or `null`/absent. See `SendOutcome`. */
402
433
  readonly credentialExpires?: string | null;
434
+ /** U5: the server's `Retry-After` in ms, on a `later` that carried a valid one. The worker waits at least this long. */
435
+ readonly retryAfterMs?: number;
403
436
  /**
404
437
  * `conversation_id` from a 2xx, ONLY when the caller opted in. See `SendOutcome`.
405
438
  *
@@ -425,6 +458,12 @@ export type Delivery =
425
458
  readonly more?: boolean;
426
459
  };
427
460
  export interface DeliveryContext {
461
+ /**
462
+ * E8 — this delivery is to a GRANTED REPOSITORY, so the changed-file list of the commits it reports may ride in the body
463
+ * trailer (`commit_files.ts`). ⛔ Default OFF: a context that does not say so sends no file name. Set only where the target is
464
+ * a granted repo (never a folder, which has no commits anyway), on the main stream only.
465
+ */
466
+ readonly commitFiles?: boolean;
428
467
  readonly home: string;
429
468
  readonly env: NodeJS.ProcessEnv;
430
469
  readonly url: string;
@@ -501,8 +540,11 @@ export interface DeliveryContext {
501
540
  readonly final?: boolean;
502
541
  /**
503
542
  * ⛔ **IS THIS DELIVERY A HOOK'S?** REQUIRED, with no default, so no caller can be a hook by omission or a non-hook by
504
- * accident. Only a hook's write is evidence that the session is alive, so only a hook stamps `SessionState.liveAt`;
543
+ * accident. Only a hook's write is evidence that the session is alive, so only a hook stamps `SessionState.liveAt` with "now";
505
544
  * `vibecommit finalize` delivers through the same function and must leave it exactly as it found it (VG review 2, D2).
545
+ * ⚠ A REPLAY of a recorded firing (U4: the upload worker, and `finalize`/`backfill` replaying before they close, U5b) runs `byHook: false`
546
+ * and DOES stamp `liveAt`, but with `liveAtMs` (the moment the HOOK fired, merged by `max`), never "now". The value is still the hook's
547
+ * time, so the rule above holds; only who writes it has changed, and `finalize` leaves the stamp as it found it after the replay.
506
548
  */
507
549
  readonly byHook: boolean;
508
550
  /**
@@ -526,11 +568,28 @@ export interface DeliveryContext {
526
568
  };
527
569
  /**
528
570
  * C25 — THE CALLER'S LOCK HEARTBEAT, called right BEFORE every request this delivery makes (the first attempt of a delta, its
529
- * lean retry, each halving of a 413). `true`: the session's writer lock is still ours and was just re-stamped. `false`: it is
530
- * not, and NO request is made and nothing is persisted: the delivery returns `nothing-to-send` and the caller, which asked
531
- * the question, knows why. Set by `finalize` and `backfill` only; a hook is ended by its own watchdog and sets none.
571
+ * lean retry, each halving of a 413) AND right BEFORE every write that follows a response (U1): the state save, and the spool
572
+ * drops that come with it. `true`: the session's writer lock is still ours and was just re-stamped. `false`: it is not, and NO
573
+ * request is made and nothing is persisted: the delivery returns `nothing-to-send` and the caller, which asked the question,
574
+ * knows why. The second beat is the one that matters after a laptop sleep: a request can outlive the lock's stale bound, another
575
+ * writer can reclaim the session meanwhile, and the waking holder's save would overwrite that writer's newer state and rewind
576
+ * `seq`. Set by `finalize`, `backfill` and the upload worker; a hook is ended by its own watchdog and sets none.
532
577
  */
533
578
  readonly beforeRequest?: () => boolean;
579
+ /**
580
+ * U5 — **ONE DELTA PER CALL.** The upload worker serves one delta and then the next session (plan §3.3 fairness), and sleeps between requests
581
+ * (D9 pacing), neither of which `deliver`'s loop over deltas can do. Set, `deliver` returns after the first delta that moved the offset
582
+ * with bytes still owed, marked `more`; the caller calls again. A hook, `finalize` and `backfill` set nothing and loop to EOF as before.
583
+ */
584
+ readonly oneDelta?: true;
585
+ /**
586
+ * U4 — **THE UPLOAD WORKER'S LIVENESS STAMP**, epoch ms: the moment the hook it is replaying fired (`firing.at`). A hook delivery stamps
587
+ * `SessionState.liveAt` with `nowMs` (`byHook`); the worker runs `byHook: false` (it must not stamp "now": a late stamp would keep a
588
+ * session live past its real end) and passes this instead, merged with the stored value by `max`, so it stamps on every attempt, `later`
589
+ * included, as a hook does, in the one save with no crash gap between two writes. An old-channel `post-commit` reads only this
590
+ * field, so it is what keeps a session live for it after the worker's lag. Ignored when `byHook` is set.
591
+ */
592
+ readonly liveAtMs?: number;
534
593
  }
535
594
  /**
536
595
  * Send the undelivered span of one transcript file, in deltas — PR 4a.
package/dist/post.js CHANGED
@@ -23,6 +23,7 @@ import { UNKNOWN_AGENT_ID } from "./agents/types.js";
23
23
  import { noteGrantEpoch, recordRefused } from "./consent.js";
24
24
  import { headerSafe, sessionIdSafe } from "./header_safety.js";
25
25
  import { recordInferredSkipped } from "./inferred_tally.js";
26
+ import { COMMIT_FILES_HEADER, planTrailer } from "./commit_files.js";
26
27
  import { clearOrgPending, markOrgPending } from "./org_pending.js";
27
28
  import { MAX_DELTA_FRAME_BYTES, MAX_DELTA_RAW_BYTES, REPOSITORY_EXCLUDED, classify, markDelivered, markHeld, markSkipped, nextSpan, planChunk, resolveCaps, splitPoint, } from "./policy.js";
28
29
  import { fileState, isStopped, loadSessionState, saveSessionState, withFileState, } from "./state.js";
@@ -197,6 +198,10 @@ export function buildIngestHeaders(credential, delta) {
197
198
  // empty. `parseRewritePairs` drops silently on a wrong separator, a third
198
199
  // colon-field, a bad sha or a self-pair, so the spelling is fixed by
199
200
  // `capSuccessors` and asserted literally by the wire cell.
201
+ // E8: the trailer's length, only beside the commits it describes (the server keys it by those shas).
202
+ if (headers["x-commits"] !== undefined && delta.commitFilesLength !== undefined && delta.commitFilesLength > 0) {
203
+ headers[COMMIT_FILES_HEADER] = String(delta.commitFilesLength);
204
+ }
200
205
  if (delta.rewrites !== undefined && delta.rewrites.length > 0) {
201
206
  headers["x-rewrites"] = delta.rewrites.join(",");
202
207
  }
@@ -222,6 +227,7 @@ export const LEAN_OMIT_HEADERS = new Set([
222
227
  "x-head-branch",
223
228
  "x-commits",
224
229
  "x-commit-attributions",
230
+ COMMIT_FILES_HEADER,
225
231
  "x-rewrites",
226
232
  "x-rewrites-inferred",
227
233
  ]);
@@ -445,6 +451,19 @@ export function parseCredentialExpires(raw) {
445
451
  return null;
446
452
  return Number.isFinite(Date.parse(value)) ? value : null;
447
453
  }
454
+ /**
455
+ * `Retry-After` → milliseconds, for the delta-seconds form ONLY: ASCII digits, nothing else. An HTTP-date, a negative number, a fraction, a sign or
456
+ * anything with a unit is `null`, and the caller falls back to its own backoff. Capped at one day so a hostile value cannot overflow a timer.
457
+ * NEVER THROWS.
458
+ */
459
+ export function parseRetryAfterMs(raw) {
460
+ if (raw === null)
461
+ return null;
462
+ const value = raw.trim();
463
+ if (!/^\d{1,9}$/.test(value))
464
+ return null;
465
+ return Math.min(Number(value), 86_400) * 1000;
466
+ }
448
467
  /** `X-Rewrites-Inferred-Stored` → a non-negative integer, or `null` for absent/malformed. NEVER THROWS. */
449
468
  function parseInferredStored(raw) {
450
469
  if (raw === null)
@@ -487,6 +506,7 @@ export async function send(url, headers, body, timeoutMs, options = {}) {
487
506
  inferredStored: parseInferredStored(res.headers.get("x-rewrites-inferred-stored")),
488
507
  credentialExpires: parseCredentialExpires(res.headers.get("x-credential-expires")),
489
508
  grantEpoch: parseGrantEpoch(res.headers.get("x-grant-epoch")),
509
+ retryAfterMs: parseRetryAfterMs(res.headers.get("retry-after")),
490
510
  };
491
511
  }
492
512
  catch {
@@ -540,7 +560,14 @@ async function attemptSend(ctx, agent, seq, span, body, lean,
540
560
  // sealing before the rest of the span has arrived would seal a poorer turn (`finalize.ts`'s docblock). The commits,
541
561
  // rewrites and head describe the END of the session, and `capture_commits`' PK admits one row per (capture, sha), so they
542
562
  // ride on one delta and not on every one. A delta that is not the last sends none of them, and the spool keeps them.
543
- isLast = true) {
563
+ isLast = true,
564
+ // E8: the compressed-frame ceiling the trailer must still fit under; without it no trailer is attempted.
565
+ frameBytes) {
566
+ // ⛔ ALL OR NOTHING (`commit_files.ts`): the trailer and `x-commit-files-length` go together or neither does; `planTrailer` is the
567
+ // one place the conditions live (granted repo, the delta that carries `x-commits`, never lean, still one frame).
568
+ const planned = planTrailer({ granted: ctx.commitFiles === true, isLast, lean, frameBytes, commits: ctx.commits }, body);
569
+ const sendBody = planned === null ? body : planned.body;
570
+ const commitFilesLength = planned === null ? undefined : planned.length;
544
571
  const full = buildIngestHeaders(ctx.credential, {
545
572
  sessionId: ctx.sessionId,
546
573
  seq,
@@ -553,6 +580,7 @@ isLast = true) {
553
580
  commits: isLast ? ctx.commits : undefined,
554
581
  rewrites: isLast ? ctx.rewrites : undefined,
555
582
  inferredRewrites: isLast ? ctx.inferredRewrites : undefined,
583
+ commitFilesLength,
556
584
  });
557
585
  const headers = lean ? leanHeaders(full) : full;
558
586
  const badHeader = firstUnsafeHeader(headers);
@@ -566,7 +594,7 @@ isLast = true) {
566
594
  return { kind: "unsafe", header: "" };
567
595
  return {
568
596
  kind: "sent",
569
- outcome: await send(ctx.url, headers, body, ctx.timeoutMs, { readConversationId: ctx.readConversationId === true }),
597
+ outcome: await send(ctx.url, headers, sendBody, ctx.timeoutMs, { readConversationId: ctx.readConversationId === true }),
570
598
  };
571
599
  }
572
600
  /**
@@ -596,6 +624,9 @@ isLast = true) {
596
624
  * persist `lean: true` going forward, which `current.lean` would not yet say.
597
625
  */
598
626
  function refuse(ctx, key, session, current, span, caps, disposition, lean) {
627
+ // U1: this writes, and may follow a request. A lost lock writes nothing.
628
+ if (ctx.beforeRequest !== undefined && !ctx.beforeRequest())
629
+ return { kind: "nothing-to-send", why: "lock-lost" };
599
630
  const next = disposition === "fatal"
600
631
  ? {
601
632
  ...withFileState(session, ctx.fileKey, { ...markHeld(current, span, ctx.nowMs, caps), lean }),
@@ -618,6 +649,8 @@ function refuse(ctx, key, session, current, span, caps, disposition, lean) {
618
649
  * in-process, within the same call.
619
650
  */
620
651
  function holdLean(ctx, key, session, current, span, caps) {
652
+ if (ctx.beforeRequest !== undefined && !ctx.beforeRequest())
653
+ return { kind: "nothing-to-send", why: "lock-lost" }; // U1: see `refuse`
621
654
  const next = withFileState(session, ctx.fileKey, { ...markHeld(current, span, ctx.nowMs, caps), lean: true });
622
655
  saveSessionState(ctx.home, key, next);
623
656
  return { kind: "attempted", disposition: "later", detail: null, finalAck: null, inferredStored: null, inferredSetAsidePairs: 0 };
@@ -655,7 +688,7 @@ async function deliverChunk(ctx, eof, readBody, cutter) {
655
688
  // written) and an unsafe session id refused ("never") before the per-request beat below, so a holder that stalled past its lock's
656
689
  // bound could otherwise write several skips with nobody checking it still owned the session. No request, no write.
657
690
  if (ctx.beforeRequest !== undefined && !ctx.beforeRequest())
658
- return { kind: "nothing-to-send" };
691
+ return { kind: "nothing-to-send", why: "lock-lost" };
659
692
  const session = loadSessionState(ctx.home, key);
660
693
  if (isStopped(session, credentialFingerprint(ctx.credential)))
661
694
  return { kind: "stopped" };
@@ -683,14 +716,14 @@ async function deliverChunk(ctx, eof, readBody, cutter) {
683
716
  const plan = planChunk(cutter, span.from, span.to, limits.rawBytes);
684
717
  // An unterminated record longer than the limit, still at EOF: it may be growing. Leave it for the next event.
685
718
  if (plan.kind === "wait")
686
- return { kind: "nothing-to-send" };
719
+ return { kind: "nothing-to-send", why: "unterminated" };
687
720
  if (plan.kind === "oversize")
688
721
  return recordTooLarge(ctx, key, session, current, { from: span.from, to: plan.to }, caps);
689
722
  span = { from: span.from, to: plan.to };
690
723
  }
691
724
  let body = readBody(span.from, span.to);
692
725
  if (body === null)
693
- return { kind: "nothing-to-send" };
726
+ return { kind: "nothing-to-send", why: "read-failed" };
694
727
  if (cutter !== undefined) {
695
728
  while (body.length > limits.frameBytes) {
696
729
  const at = splitPoint(cutter, span.from, span.to);
@@ -699,21 +732,22 @@ async function deliverChunk(ctx, eof, readBody, cutter) {
699
732
  span = { from: span.from, to: at };
700
733
  body = readBody(span.from, span.to);
701
734
  if (body === null)
702
- return { kind: "nothing-to-send" };
735
+ return { kind: "nothing-to-send", why: "read-failed" };
703
736
  }
704
737
  }
705
738
  // An empty span (a `final` with nothing new) is the last delta by definition.
706
739
  let isLast = cutter === undefined || span.to >= eof || span.to === span.from;
707
- // `seq` is claimed BEFORE the attempt and persisted by the SWITCH below (every ordinary disposition —
708
- // "ok"/"later"/"never"/"fatal" — builds `next` from `{ ...session, seq, … }`), so it is monotonic per
709
- // session across retries once a request was actually classified. A seq reused after a failure would read
710
- // server-side as a replay of a delta that is not the same bytes.
740
+ // `seq` is claimed BEFORE the attempt and PERSISTED BEFORE THE FIRST REQUEST (U1, below), so a process killed while the
741
+ // request is in flight cannot leave `session.seq` behind what the server holds. Persisting it only after the response (the
742
+ // SWITCH below still writes it again, with the outcome) was the hole: a kill mid-request left the old `seq` on disk, the next
743
+ // send reused it with a GROWN span, the server answered "replay" (a no-op 2xx) and the client advanced `sentOffset` past bytes
744
+ // the server never applied: silent loss. A hook killed by its agent had it; a long-lived worker's in-flight window makes it
745
+ // common. A seq reused after a failure would read server-side as a replay of a delta that is not the same bytes.
711
746
  //
712
- // ⚠ `refuse()` and `holdLean()` below do NOT persist it — they build `next` from `session` alone, so a
713
- // pre-send refusal or a hook's first hold leaves `session.seq` exactly where it was. That is harmless: a
714
- // request classified `refuse`/`holdLean` never reached `send()` at all (a bad session id, an unsafe
715
- // credential, or the first 431 a hook defers on), so the server never saw THIS seq either — reusing it on
716
- // the next real attempt is not a replay of anything, because nothing was sent under it.
747
+ // ⚠ `refuse()`, `holdLean()` and `holdSpan()` below build `next` from `session` alone, so they write the OLD `seq` back over
748
+ // the ahead-of-send one. That is harmless: each runs after a request the server REFUSED before applying anything (a 431
749
+ // before the handler, a 413 before the body is read) or before any request at all (a bad session id, an unsafe credential),
750
+ // so the server never recorded THIS seq, and reusing it is not a replay of anything.
717
751
  //
718
752
  // Claimed ONCE even across a `finalize` lean retry below: both attempts, if there are two, carry the same
719
753
  // bytes at the same offset, so they are one logical delivery that happened to need its headers shed, not two.
@@ -744,8 +778,13 @@ async function deliverChunk(ctx, eof, readBody, cutter) {
744
778
  // which nobody can debug.
745
779
  let lean = current.lean;
746
780
  if (ctx.beforeRequest !== undefined && !ctx.beforeRequest())
747
- return { kind: "nothing-to-send" };
748
- let attempt = await attemptSend(withinBudget(ctx), agent, seq, span, body, lean, isLast);
781
+ return { kind: "nothing-to-send", why: "lock-lost" };
782
+ // ⛔ U1 (SC-2): WRITE `seq` AHEAD OF THE SEND, after the beat above so a lost lock writes nothing. Fail closed: if the state cannot
783
+ // be written, the request is not made, because a send whose `seq` is not on disk is the silent-loss shape. The 431 retry and
784
+ // every 413 half below reuse this `seq` (the server applied none of them), so once is enough.
785
+ if (!saveSessionState(ctx.home, key, { ...session, seq }))
786
+ return { kind: "nothing-to-send", why: "unwritable" };
787
+ let attempt = await attemptSend(withinBudget(ctx), agent, seq, span, body, lean, isLast, limits.frameBytes);
749
788
  if (attempt.kind === "unsafe") {
750
789
  return refuse(ctx, key, session, current, span, caps, attempt.header === "authorization" ? "fatal" : "never", lean);
751
790
  }
@@ -775,7 +814,7 @@ async function deliverChunk(ctx, eof, readBody, cutter) {
775
814
  // ⛔ A lock lost between the 431 and its retry stops here with NOTHING persisted: the first attempt recorded nothing either, so
776
815
  // the span is simply unsent and whoever holds the session now resends it.
777
816
  if (ctx.beforeRequest !== undefined && !ctx.beforeRequest())
778
- return { kind: "nothing-to-send" };
817
+ return { kind: "nothing-to-send", why: "lock-lost" };
779
818
  attempt = await attemptSend(withinBudget(ctx), agent, seq, span, body, lean, isLast);
780
819
  if (attempt.kind === "unsafe") {
781
820
  // Unreachable in practice — every lean header is already proven safe, or
@@ -816,17 +855,27 @@ async function deliverChunk(ctx, eof, readBody, cutter) {
816
855
  isLast = false;
817
856
  const half = readBody(span.from, span.to);
818
857
  if (half === null)
819
- return { kind: "nothing-to-send" };
858
+ return { kind: "nothing-to-send", why: "read-failed" };
820
859
  if (ctx.beforeRequest !== undefined && !ctx.beforeRequest())
821
- return { kind: "nothing-to-send" };
860
+ return { kind: "nothing-to-send", why: "lock-lost" };
822
861
  attempt = await attemptSend(withinBudget(ctx), agent, seq, span, half, lean, false);
823
862
  if (attempt.kind === "unsafe") {
824
863
  return refuse(ctx, key, session, current, span, caps, attempt.header === "authorization" ? "fatal" : "never", lean);
825
864
  }
826
865
  outcome = attempt.outcome;
827
866
  }
867
+ // ⛔ U1 (SC-3): A BEAT BEFORE ANYTHING IS PERSISTED. The lock was last stamped before the request; after a laptop sleep another writer
868
+ // may have reclaimed it and written newer state, and the save (and the spool drops) below would overwrite it and rewind `seq`.
869
+ // A lost lock persists nothing: the response is dropped, the offset stays, and the new holder re-sends from where its state says
870
+ // (an idempotent re-send on the server, mcp #165). Hooks hold their lock for the whole call and set no beat.
871
+ if (ctx.beforeRequest !== undefined && !ctx.beforeRequest())
872
+ return { kind: "nothing-to-send", why: "lock-lost" };
828
873
  const disposition = classify(outcome);
829
- let next = ctx.byHook ? { ...session, seq, liveAt: ctx.nowMs } : { ...session, seq };
874
+ let next = ctx.byHook
875
+ ? { ...session, seq, liveAt: ctx.nowMs }
876
+ : ctx.liveAtMs !== undefined
877
+ ? { ...session, seq, liveAt: Math.max(session.liveAt ?? 0, ctx.liveAtMs) }
878
+ : { ...session, seq };
830
879
  let inferredSetAsidePairs = 0;
831
880
  switch (disposition) {
832
881
  case "ok":
@@ -1032,6 +1081,7 @@ async function deliverChunk(ctx, eof, readBody, cutter) {
1032
1081
  ? { conversationId: outcome.conversationId }
1033
1082
  : {}),
1034
1083
  ...(outcome.kind === "unreachable" ? { unreachable: true } : {}),
1084
+ ...(outcome.kind === "response" && disposition === "later" && typeof outcome.retryAfterMs === "number" ? { retryAfterMs: outcome.retryAfterMs } : {}),
1035
1085
  // PR 4a: a 413 that no split could shrink was skipped by the `never` arm above; say so, so the caller can count it.
1036
1086
  ...(splitTooLarge && disposition === "never" ? { recordsTooLarge: 1 } : {}),
1037
1087
  };
@@ -1047,9 +1097,11 @@ function recordTooLarge(ctx, key, session, current, span, caps) {
1047
1097
  }
1048
1098
  /**
1049
1099
  * PR 4a — out of hook budget in the middle of a 413 split: hold the span the failed request covered, as a `later` does. The
1050
- * `seq` is not persisted for the same reason the split reuses it: the 413 was refused before the server applied it.
1100
+ * The old `seq` is written back for the same reason the split reuses it: the 413 was refused before the server applied it.
1051
1101
  */
1052
1102
  function holdSpan(ctx, key, session, current, span, caps, lean) {
1103
+ if (ctx.beforeRequest !== undefined && !ctx.beforeRequest())
1104
+ return { kind: "nothing-to-send", why: "lock-lost" }; // U1: see `refuse`
1053
1105
  saveSessionState(ctx.home, key, withFileState(session, ctx.fileKey, { ...markHeld(current, span, ctx.nowMs, caps), lean }));
1054
1106
  return { kind: "attempted", disposition: "later", detail: null, finalAck: null, inferredStored: null, inferredSetAsidePairs: 0 };
1055
1107
  }
@@ -1116,7 +1168,7 @@ export async function deliver(ctx, eof, readBody, cutter) {
1116
1168
  catch {
1117
1169
  // The cutter reads the file and a read can fail. That must read as "could not tell where the record ends", never as
1118
1170
  // "it does not end" (which would skip a record). Nothing was persisted for this delta, so the next event retries it.
1119
- delivery = { kind: "nothing-to-send" };
1171
+ delivery = { kind: "nothing-to-send", why: "read-failed" };
1120
1172
  }
1121
1173
  if (delivery.kind !== "attempted")
1122
1174
  return last === null ? delivery : carry(last);
@@ -1140,7 +1192,7 @@ export async function deliver(ctx, eof, readBody, cutter) {
1140
1192
  const tailSkipped = delivery.recordsTooLarge !== undefined && after >= eof && ctx.final === true;
1141
1193
  if (after >= eof && !tailSkipped)
1142
1194
  return carry(delivery);
1143
- if (budgetLeftMs(ctx) < MIN_NEXT_DELTA_BUDGET_MS)
1195
+ if (ctx.oneDelta === true || budgetLeftMs(ctx) < MIN_NEXT_DELTA_BUDGET_MS)
1144
1196
  return carry(delivery, true);
1145
1197
  last = delivery;
1146
1198
  chunkCtx = {