@cotal-ai/connector-core 0.69.0 → 0.70.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.
@@ -1 +1 @@
1
- {"version":3,"file":"docs-bundle.generated.js","sourceRoot":"","sources":["../src/docs-bundle.generated.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"docs-bundle.generated.js","sourceRoot":"","sources":["../src/docs-bundle.generated.ts"],"names":[],"mappings":"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"}
@@ -42,10 +42,10 @@ export interface WalPending {
42
42
  /**
43
43
  * The frame's parts, FROZEN at transition 1 beside the id and `E` that identify them.
44
44
  *
45
- * Without this the WAL froze what NAMES a frame and not the frame: a restart holding
46
- * `sent_unacked` recovered the id and the expectation and had nothing to re-publish, so
45
+ * Without this the WAL would freeze what NAMES a frame and not the frame: a restart holding
46
+ * `sent_unacked` would recover the id and the expectation and have nothing to re-publish, so
47
47
  * "retry the same frame after a crash" — the one thing this file exists to make possible —
48
- * could not be performed from the document. The write-ahead rule requires it and it was absent.
48
+ * could not be performed from the document. The write-ahead rule requires it.
49
49
  *
50
50
  * It is the parts and not a rendered message because `multicastExpecting` builds the envelope
51
51
  * (`ts`, `from`, `space`) at publish time; storing that too would freeze a second copy of fields
@@ -76,10 +76,9 @@ export interface WalDoc {
76
76
  gen: number;
77
77
  /**
78
78
  * The space this WAL belongs to — stored because it is a PATH COMPONENT and a path component is
79
- * not a trusted input. `principal` and `threadId` were verified on
80
- * load and `space` was not, so a WAL copied or mis-resolved between two space directories under
81
- * the same principal and thread LOADED, and one space's frontier was adopted as another's. Two
82
- * thirds of a three-part guard is not the guard.
79
+ * not a trusted input. Verifying only `principal` and `threadId` on load would let a WAL copied
80
+ * or mis-resolved between two space directories under the same principal and thread LOAD, and
81
+ * adopt one space's frontier as another's. Two thirds of a three-part guard is not the guard.
83
82
  */
84
83
  space: string;
85
84
  epoch: string;
@@ -123,9 +122,8 @@ export declare class WalStaleWriterError extends Error {
123
122
  *
124
123
  * **Exported so a test can drive the shipped flags rather than recompose them.** A cell that builds
125
124
  * `O_WRONLY | O_CREAT | O_EXCL | O_NOFOLLOW` itself is testing a COPY of this rule: it stays green
126
- * while the production open drifts or loses a flag. That is not hypothetical here — the first
127
- * version of those cells did exactly that, and a mutation reverting the real open to `"w"` left the
128
- * suite fully green. Driving this function is what makes the mutation land.
125
+ * while the production open drifts or loses a flag, so a mutation reverting the real open to `"w"`
126
+ * leaves it green. Driving this function is what makes the mutation land.
129
127
  *
130
128
  * `O_EXCL` refuses a pre-existing file rather than adopting it — which matters because `"w"` does
131
129
  * NOT re-chmod an existing inode, so an adopted 0644 temp would carry its mode onto the renamed WAL
@@ -140,16 +138,14 @@ export declare class EventWal {
140
138
  *
141
139
  * Without it, two concurrent `beginSend` calls both read `this.doc.pending === null` before either
142
140
  * durable replace finishes — the guard is an in-memory read that is NOT atomic with the write
143
- * across its `await` points. Reviewers reproduced the split: one call fulfils, one rejects, and
144
- * the process is left holding `pending.id === "A"` in memory while the disk says `"B"`. Recovery
145
- * would then resume the frame on disk while the live emitter retries the other, which breaks the
146
- * one thing this file exists to guarantee — that `id` and `E` are frozen and agreed.
141
+ * across its `await` points. The split leaves one call fulfilled, one rejected, and the process
142
+ * holding `pending.id === "A"` in memory while the disk says `"B"`. Recovery would then resume
143
+ * the frame on disk while the live emitter retries the other, which breaks the one thing this
144
+ * file exists to guarantee — that `id` and `E` are frozen and agreed.
147
145
  *
148
- * A per-instance chain is sufficient and honest about its scope, and the scope is narrower than it
149
- * once claimed: it serializes THIS INSTANCE's callers. It does nothing about a SECOND `EventWal`
150
- * on the same file, in this process or another — the chain is per object, so two objects are two
151
- * chains and both of them "succeed". That gap was described here as "solved upstream by the
152
- * principal-level lock" while no lock was ever acquired. Two things close it now, and neither is
146
+ * The chain serializes THIS INSTANCE's callers and nothing more. It does nothing about a SECOND
147
+ * `EventWal` on the same file, in this process or another — the chain is per object, so two
148
+ * objects are two chains and both of them "succeed". Two things close that gap, and neither is
153
149
  * this chain: `acquirePrincipalLock` refuses a second emitter for the principal at start, and
154
150
  * {@link EventWal.assertNotClobbering} refuses a stale handle's write even when it got past that.
155
151
  */
@@ -189,11 +185,11 @@ export declare class EventWal {
189
185
  /**
190
186
  * Bind the PRINCIPAL-scoped subject frontier this thread publishes onto.
191
187
  *
192
- * **THE TIP IS NOT THIS THREAD'S TO REMEMBER, AND THAT IS THE WHOLE CORRECTION.**
188
+ * **THE TIP IS NOT THIS THREAD'S TO REMEMBER.**
193
189
  * `frontier.lastSubjectSeq` records the last sequence THIS thread was assigned, which is a true
194
- * fact about this log and was mistaken for the subject's tip. The subject is per principal, so a
195
- * second session of the same agent opened virgin, expected an empty subject its own predecessor
196
- * had filled, and halted forever. Once bound, the bound record is authoritative for the
190
+ * fact about this log and not the subject's tip. The subject is per principal, so a second
191
+ * session of the same agent reading its own virgin log would expect an empty subject its own
192
+ * predecessor had filled, and halt forever. Once bound, the bound record is authoritative for the
197
193
  * expectation and this document's own number is history.
198
194
  *
199
195
  * Called once, by {@link AguiEmitter.start}, which is the only thing that drives a WAL toward a
@@ -205,14 +201,12 @@ export declare class EventWal {
205
201
  /**
206
202
  * The sequence a publish must expect, which is the SUBJECT's tip and not this thread's.
207
203
  *
208
- * **UNBOUND IT THROWS, AND AN EARLIER VERSION OF THIS RETURNED THIS DOCUMENT'S OWN LAST ACK.**
209
- * That number is the defect's own shape: per session, while the subject is per principal. The
210
- * argument for returning it was that no shipped path can reach it, because
211
- * {@link AguiEmitter.start} is the only route from a log to a publish and it binds before the
212
- * emitter exists. The argument was true, and it is the same argument the released seam shipped
213
- * on: two correct components with an assumption standing where a guard belongs, recorded in
214
- * prose. So the assumption is a guard now. A caller that drives a log toward a publish without a
215
- * frontier fails here rather than republishing an expectation that was never the subject's.
204
+ * **UNBOUND IT THROWS**, and it never falls back to this document's own last ack: that number is
205
+ * per session, while the subject is per principal. No shipped path reaches the unbound case,
206
+ * because {@link AguiEmitter.start} is the only route from a log to a publish and it binds before
207
+ * the emitter exists, and the throw makes that a guard rather than an assumption recorded in
208
+ * prose. A caller that drives a log toward a publish without a frontier fails here rather than
209
+ * republishing an expectation that was never the subject's.
216
210
  */
217
211
  get expectedTip(): number;
218
212
  /** Transition 1 — record the frame, with `id` and `E` frozen, BEFORE any publish. */
@@ -261,24 +255,24 @@ export declare class EventWal {
261
255
  * (that message has landed); the only window where it is dangerous is exactly the window this
262
256
  * file holds it in, between transition 1 and the ack.
263
257
  *
264
- * So the residual a reviewer raised as "gated on a local disk read rather than mesh access" is
265
- * gated on a read OF THIS FILE. A world-readable WAL would convert a property the design credits
266
- * to entropy into one credited to filesystem luck. Under our own rules the attack yields a LOUD
267
- * halt rather than silent loss — a duplicate ack on a retry fails loud with the frontier and
268
- * cursor unmoved — so this is denial of service, not corruption. Closing it by construction is
269
- * cheap enough that naming it as an accepted residual would be the worse trade.
258
+ * So the exposure is gated on a local read OF THIS FILE rather than on mesh access. A
259
+ * world-readable WAL would convert a property the design credits to entropy into one credited to
260
+ * filesystem luck. Under our own rules the attack yields a LOUD halt rather than silent loss — a
261
+ * duplicate ack on a retry fails loud with the frontier and cursor unmoved — so this is denial of
262
+ * service, not corruption. Closing it by construction is cheap enough that naming it as an
263
+ * accepted residual would be the worse trade.
270
264
  */
271
265
  private write;
272
266
  /**
273
267
  * Refuse to replace a document this handle did not read.
274
268
  *
275
- * **THE FAILURE THIS EXISTS FOR WAS EXECUTED, NOT IMAGINED.** Two `EventWal` objects were opened
276
- * on one file. A ran the full cycle and folded a frontier of `{seq:1, lastSubjectSeq:5}`. B, whose
277
- * in-memory document was frozen back at the pending write, then called `recordAck(99)` and
278
- * `fold()` — both SUCCEEDED, each replacing the whole file, and the WAL came back up claiming a
279
- * durable tip of 99: a subject sequence the broker never assigned. The next publish freezes
280
- * `E := 99` against a stream whose real tip is 5, so the emitter either CAS-halts forever or
281
- * recovers a frontier that never existed. Nothing about that is loud; it reads as a healthy WAL.
269
+ * **THE FAILURE THIS EXISTS FOR.** Two `EventWal` objects are open on one file. A runs the full
270
+ * cycle and folds a frontier of `{seq:1, lastSubjectSeq:5}`. B, whose in-memory document is
271
+ * frozen back at the pending write, then calls `recordAck(99)` and `fold()` — without this check
272
+ * both SUCCEED, each replacing the whole file, and the WAL comes back up claiming a durable tip
273
+ * of 99: a subject sequence the broker never assigned. The next publish freezes `E := 99`
274
+ * against a stream whose real tip is 5, so the emitter either CAS-halts forever or recovers a
275
+ * frontier that never existed. Nothing about that is loud; it reads as a healthy WAL.
282
276
  *
283
277
  * The per-instance `serialize` chain cannot see it (two instances, two chains) and neither can the
284
278
  * principal lock (B's handle predates any lock B would take, and a lock is not held against a
@@ -1 +1 @@
1
- {"version":3,"file":"event-wal.d.ts","sourceRoot":"","sources":["../src/event-wal.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"event-wal.d.ts","sourceRoot":"","sources":["../src/event-wal.ts"],"names":[],"mappings":"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"}
package/dist/event-wal.js CHANGED
@@ -9,7 +9,7 @@
9
9
  * THE ORDERING RULE THE WHOLE DESIGN RESTS ON. Transition 1 records `sent_unacked` and only THEN
10
10
  * publishes; transition 2 records `acked` on a NON-duplicate ack, durably, BEFORE the frontier
11
11
  * moves; transition 3 folds the frontier and clears pending. The `acked` state looks redundant
12
- * until you remove it: an earlier draft committed the cursor and then unlinked pending, on the
12
+ * until you remove it: committing the cursor and then unlinking pending looks safe on the
13
13
  * reasoning that a crash between them would "re-publish, and CAS or in-window dedupe absorbs it".
14
14
  * That is false under these same rules. Pending still holds the PRE-STORE `E`, the tip has moved to
15
15
  * `E+1`, so recovery takes a CAS loss — which is fail-loud — and the emitter wedges FOREVER on a
@@ -100,9 +100,8 @@ function docGeneration(path, doc) {
100
100
  *
101
101
  * **Exported so a test can drive the shipped flags rather than recompose them.** A cell that builds
102
102
  * `O_WRONLY | O_CREAT | O_EXCL | O_NOFOLLOW` itself is testing a COPY of this rule: it stays green
103
- * while the production open drifts or loses a flag. That is not hypothetical here — the first
104
- * version of those cells did exactly that, and a mutation reverting the real open to `"w"` left the
105
- * suite fully green. Driving this function is what makes the mutation land.
103
+ * while the production open drifts or loses a flag, so a mutation reverting the real open to `"w"`
104
+ * leaves it green. Driving this function is what makes the mutation land.
106
105
  *
107
106
  * `O_EXCL` refuses a pre-existing file rather than adopting it — which matters because `"w"` does
108
107
  * NOT re-chmod an existing inode, so an adopted 0644 temp would carry its mode onto the renamed WAL
@@ -125,23 +124,23 @@ export async function openExclusiveNoFollow(path) {
125
124
  * Named relations rather than one compound boolean: an operator who cannot see WHICH relation broke
126
125
  * cannot act on it, and a single fused check gives a mutation only one cell to kill.
127
126
  *
128
- * **THERE IS DELIBERATELY NO `sourceCursor` RELATION HERE, AND THAT IS A CORRECTION.**
129
- * An earlier version asserted `pending.sourceCursor >= frontier.sourceCursor` using string `<`.
127
+ * **THERE IS DELIBERATELY NO `sourceCursor` RELATION HERE.**
130
128
  * A cursor is **OPAQUE** — `DurableSource` defines it per source and states that a caller "never
131
129
  * parses it". `JsonlFileSource` happens to emit `dev:ino:offset:seal`, and lexicographic order is
132
- * NOT offset order once the digit width changes, so that check was wrong in BOTH directions:
130
+ * NOT offset order once the digit width changes, so `pending.sourceCursor >= frontier.sourceCursor`
131
+ * by string `<` is wrong in BOTH directions:
133
132
  *
134
- * frontier offset 8, acked pending offset 45 → REFUSED a healthy WAL ("45" < "8")
135
- * frontier offset 170, acked pending offset 98 → ACCEPTED a mixed-vintage one ("98" > "170")
133
+ * frontier offset 8, acked pending offset 45 → REFUSES a healthy WAL ("45" < "8")
134
+ * frontier offset 170, acked pending offset 98 → ACCEPTS a mixed-vintage one ("98" > "170")
136
135
  *
137
136
  * The first wedges recovery on ordinary source growth across any digit boundary — on the exact
138
137
  * crash window the `acked` state exists to survive. The second silently admits the mixed vintage
139
- * the relation was written to refuse. Found independently by two reviewers, then reproduced here.
138
+ * it is meant to refuse.
140
139
  *
141
- * The root cause is not the operator; it is that **ordering an opaque value requires parsing it**,
142
- * and parsing it would bind this WAL to one source's format — breaking the abstraction the moment
143
- * a store-backed source uses something else (OpenCode's `part.id`, a rollout path, an API token).
144
- * So the relation is not fixed, it is REMOVED: it cannot be stated correctly at this layer.
140
+ * Changing the operator does not help: **ordering an opaque value requires parsing it**, and
141
+ * parsing it would bind this WAL to one source's format — breaking the abstraction the moment a
142
+ * store-backed source uses something else (OpenCode's `part.id`, a rollout path, an API token).
143
+ * The relation cannot be stated correctly at this layer, so it is not stated at all.
145
144
  *
146
145
  * What remains is sufficient and well-defined, because it uses the WAL's OWN monotonic counters
147
146
  * rather than a foreign key: an acked frame must be exactly the frontier's successor, and its
@@ -151,15 +150,11 @@ export async function openExclusiveNoFollow(path) {
151
150
  function assertPendingVintage(path, p, f) {
152
151
  // ── RELATIONS THAT HOLD FOR *EITHER* TAG ──
153
152
  //
154
- // These were previously checked ONLY for `acked`, which left `sent_unacked` — the crash window
155
- // transition 1 exists to survive — almost unguarded. Documents with `E` disagreeing with the
156
- // frontier's tip, or a `seq` that is not the frontier's successor, LOADED and would then retry a
157
- // frozen expectation that cannot be the honest successor of this frontier: a permanent CAS halt,
158
- // or a publish at the wrong stream position, with no loud corrupt at open.
159
- //
160
- // The asymmetry was mine: I wrote three named relations for the path that has already succeeded
161
- // and almost none for the path that is still in flight. Found by fmae-rev-sec, reproduced by
162
- // fmae-rev-eng and fmae-rev-wal, then here.
153
+ // `sent_unacked` is the crash window transition 1 exists to survive, so it is held to these as
154
+ // strictly as `acked`. A document with `E` disagreeing with the frontier's tip, or a `seq` that is
155
+ // not the frontier's successor, would otherwise LOAD and then retry a frozen expectation that
156
+ // cannot be the honest successor of this frontier: a permanent CAS halt, or a publish at the
157
+ // wrong stream position, with no loud corrupt at open.
163
158
  if (p.E !== f.lastSubjectSeq)
164
159
  throw new WalCorruptError(path, "pending.E === frontier.lastSubjectSeq", `pending.E=${p.E} frontier.lastSubjectSeq=${f.lastSubjectSeq} — the frozen expectation is not ` +
165
160
  `the tip this WAL believes, so retrying it can only CAS-halt or append at the wrong position`);
@@ -179,7 +174,7 @@ function assertPendingVintage(path, p, f) {
179
174
  `vintage than the acked frame, so its sourceCursor may already have passed events that were ` +
180
175
  `never published; resuming would drop them with no gap for a consumer to see`);
181
176
  // NO sourceCursor comparison — see the note above. The cursor is opaque; ordering it here is not
182
- // a thing this layer can do correctly, and doing it with string `<` was wrong in both directions.
177
+ // a thing this layer can do correctly.
183
178
  }
184
179
  /**
185
180
  * Validate a persisted bracket state, or refuse it.
@@ -258,10 +253,10 @@ function parseDoc(path, raw, space, threadId, principal) {
258
253
  throw new WalCorruptError(path, "frontier.sourceCursor is a string or absent", typeof f.sourceCursor);
259
254
  // A NONZERO FRONTIER MUST CARRY THE POSITION IT WAS DERIVED FROM.
260
255
  //
261
- // This guard was omitted on the reasoning that no shipped transition can produce a nonzero
262
- // frontier without a cursor — which is exactly backwards. A recovery component must refuse the
263
- // states its own writer CANNOT produce, because those are precisely the states corruption
264
- // produces. The happy path is not the input domain.
256
+ // No shipped transition produces a nonzero frontier without a cursor, and that is the reason to
257
+ // check for one rather than a reason to skip it. A recovery component must refuse the states its
258
+ // own writer CANNOT produce, because those are precisely the states corruption produces. The
259
+ // happy path is not the input domain.
265
260
  //
266
261
  // The cost of accepting it is silent loss, and it is not theoretical: the emitter resumes by
267
262
  // reading forward from this cursor, and `read(undefined)` does not resume — it ADOPTS AT THE
@@ -284,12 +279,10 @@ function parseDoc(path, raw, space, threadId, principal) {
284
279
  // reclassifies "we may have published and do not know" as "we have nothing in flight", which is
285
280
  // the one downgrade a write-ahead log must never make on its own authority.
286
281
  //
287
- // ONE check, not two. The first version guarded the absent key with `hasOwnProperty` AND the
288
- // shape with a `typeof`, and the mutation proof caught the redundancy: deleting the
289
- // `hasOwnProperty` half killed nothing, because an absent key is `undefined` and the shape check
290
- // already refuses it with the same invariant. Two mechanisms preventing one outcome means a cell
291
- // asserting that outcome proves neither of them — so the belt came off and the cells now bite on
292
- // the one guard that does the work.
282
+ // ONE check, not two. An absent key is `undefined`, and the shape check refuses it with the same
283
+ // invariant, so a separate `hasOwnProperty` guard would be a second mechanism preventing one
284
+ // outcome, and a cell asserting that outcome would prove neither of them. The cells bite on the
285
+ // one guard that does the work.
293
286
  if (doc.pending !== null && typeof doc.pending !== "object")
294
287
  throw new WalCorruptError(path, "pending is present (null or an object)", doc.pending === undefined ? "the key is absent, which is not the same as null" : typeof doc.pending);
295
288
  let pending = null;
@@ -300,11 +293,11 @@ function parseDoc(path, raw, space, threadId, principal) {
300
293
  if (typeof p.id !== "string" || p.id.length === 0)
301
294
  throw new WalCorruptError(path, "pending.id is a non-empty string", String(p.id));
302
295
  // ...and it must satisfy the WIRE grammar, not merely be a string. `beginSend` validates with
303
- // `assertIdToken` on the way IN; open accepted anything non-empty on the way OUT — so a corrupted
304
- // or hand-edited id (`"has.dots"`) was ADOPTED at recovery and then rejected by
305
- // `multicastExpecting` on every republish attempt. That turns disk corruption into a permanent
306
- // runtime wedge instead of a refusal at open, which inverts this file's posture. Validated with
307
- // the SHIPPED grammar rather than a second copy that could drift from it.
296
+ // `assertIdToken` on the way IN, and open checks the same on the way OUT: a corrupted or
297
+ // hand-edited id (`"has.dots"`) ADOPTED at recovery would be rejected by `multicastExpecting` on
298
+ // every republish attempt. That turns disk corruption into a permanent runtime wedge instead of
299
+ // a refusal at open, which inverts this file's posture. Validated with the SHIPPED grammar
300
+ // rather than a second copy that could drift from it.
308
301
  try {
309
302
  assertIdToken(p.id, "event WAL pending.id");
310
303
  }
@@ -364,16 +357,14 @@ export class EventWal {
364
357
  *
365
358
  * Without it, two concurrent `beginSend` calls both read `this.doc.pending === null` before either
366
359
  * durable replace finishes — the guard is an in-memory read that is NOT atomic with the write
367
- * across its `await` points. Reviewers reproduced the split: one call fulfils, one rejects, and
368
- * the process is left holding `pending.id === "A"` in memory while the disk says `"B"`. Recovery
369
- * would then resume the frame on disk while the live emitter retries the other, which breaks the
370
- * one thing this file exists to guarantee — that `id` and `E` are frozen and agreed.
360
+ * across its `await` points. The split leaves one call fulfilled, one rejected, and the process
361
+ * holding `pending.id === "A"` in memory while the disk says `"B"`. Recovery would then resume
362
+ * the frame on disk while the live emitter retries the other, which breaks the one thing this
363
+ * file exists to guarantee — that `id` and `E` are frozen and agreed.
371
364
  *
372
- * A per-instance chain is sufficient and honest about its scope, and the scope is narrower than it
373
- * once claimed: it serializes THIS INSTANCE's callers. It does nothing about a SECOND `EventWal`
374
- * on the same file, in this process or another — the chain is per object, so two objects are two
375
- * chains and both of them "succeed". That gap was described here as "solved upstream by the
376
- * principal-level lock" while no lock was ever acquired. Two things close it now, and neither is
365
+ * The chain serializes THIS INSTANCE's callers and nothing more. It does nothing about a SECOND
366
+ * `EventWal` on the same file, in this process or another — the chain is per object, so two
367
+ * objects are two chains and both of them "succeed". Two things close that gap, and neither is
377
368
  * this chain: `acquirePrincipalLock` refuses a second emitter for the principal at start, and
378
369
  * {@link EventWal.assertNotClobbering} refuses a stale handle's write even when it got past that.
379
370
  */
@@ -424,11 +415,11 @@ export class EventWal {
424
415
  if (bytes !== undefined) {
425
416
  // FATAL UTF-8 — never `readFile(path, "utf8")`. Node's default decoder SUBSTITUTES U+FFFD for
426
417
  // invalid bytes, so a corrupted file arrives as a changed-but-parseable document: a single raw
427
- // 0xff inside the epoch string loaded cleanly with `epoch` silently rewritten. For a file whose
418
+ // 0xff inside the epoch string loads cleanly with `epoch` silently rewritten. For a file whose
428
419
  // whole posture is that every unreadable state fails loud, "quietly altered and accepted" is
429
420
  // the one outcome it must not produce — the identity bytes recovery depends on would be the
430
- // decoder's invention. `JsonlFileSource` in this same package already decodes fatally for
431
- // exactly this class; this is that rule applied where it was missing, not a new one.
421
+ // decoder's invention. `JsonlFileSource` in this same package decodes fatally for exactly
422
+ // this class, and this is the same rule.
432
423
  try {
433
424
  raw = new TextDecoder("utf-8", { fatal: true }).decode(bytes);
434
425
  }
@@ -470,11 +461,11 @@ export class EventWal {
470
461
  /**
471
462
  * Bind the PRINCIPAL-scoped subject frontier this thread publishes onto.
472
463
  *
473
- * **THE TIP IS NOT THIS THREAD'S TO REMEMBER, AND THAT IS THE WHOLE CORRECTION.**
464
+ * **THE TIP IS NOT THIS THREAD'S TO REMEMBER.**
474
465
  * `frontier.lastSubjectSeq` records the last sequence THIS thread was assigned, which is a true
475
- * fact about this log and was mistaken for the subject's tip. The subject is per principal, so a
476
- * second session of the same agent opened virgin, expected an empty subject its own predecessor
477
- * had filled, and halted forever. Once bound, the bound record is authoritative for the
466
+ * fact about this log and not the subject's tip. The subject is per principal, so a second
467
+ * session of the same agent reading its own virgin log would expect an empty subject its own
468
+ * predecessor had filled, and halt forever. Once bound, the bound record is authoritative for the
478
469
  * expectation and this document's own number is history.
479
470
  *
480
471
  * Called once, by {@link AguiEmitter.start}, which is the only thing that drives a WAL toward a
@@ -493,23 +484,20 @@ export class EventWal {
493
484
  if (this.subject)
494
485
  throw new Error(`event WAL ${this.path}: a DIFFERENT subject frontier is already bound`);
495
486
  this.subject = frontier;
496
- // NO SEEDING HERE, and the first version of this method did it here and was wrong. The upgrade
497
- // case is a NEW thread whose own log is virgin while the sequence sits in a PREVIOUS thread's
498
- // log, so seeding from `this` document recovers nothing in exactly the case that matters. That
499
- // recovery belongs to whoever can see every thread log of the principal, which is the record's
500
- // own `open`.
487
+ // NO SEEDING HERE. The upgrade case is a NEW thread whose own log is virgin while the sequence
488
+ // sits in a PREVIOUS thread's log, so seeding from `this` document recovers nothing in exactly
489
+ // the case that matters. That recovery belongs to whoever can see every thread log of the
490
+ // principal, which is the record's own `open`.
501
491
  }
502
492
  /**
503
493
  * The sequence a publish must expect, which is the SUBJECT's tip and not this thread's.
504
494
  *
505
- * **UNBOUND IT THROWS, AND AN EARLIER VERSION OF THIS RETURNED THIS DOCUMENT'S OWN LAST ACK.**
506
- * That number is the defect's own shape: per session, while the subject is per principal. The
507
- * argument for returning it was that no shipped path can reach it, because
508
- * {@link AguiEmitter.start} is the only route from a log to a publish and it binds before the
509
- * emitter exists. The argument was true, and it is the same argument the released seam shipped
510
- * on: two correct components with an assumption standing where a guard belongs, recorded in
511
- * prose. So the assumption is a guard now. A caller that drives a log toward a publish without a
512
- * frontier fails here rather than republishing an expectation that was never the subject's.
495
+ * **UNBOUND IT THROWS**, and it never falls back to this document's own last ack: that number is
496
+ * per session, while the subject is per principal. No shipped path reaches the unbound case,
497
+ * because {@link AguiEmitter.start} is the only route from a log to a publish and it binds before
498
+ * the emitter exists, and the throw makes that a guard rather than an assumption recorded in
499
+ * prose. A caller that drives a log toward a publish without a frontier fails here rather than
500
+ * republishing an expectation that was never the subject's.
513
501
  */
514
502
  get expectedTip() {
515
503
  if (!this.subject)
@@ -523,11 +511,10 @@ export class EventWal {
523
511
  return this.serialize(async () => {
524
512
  if (this.doc.pending)
525
513
  throw new Error(`event WAL ${this.path}: a frame is already pending; one emit unit is one pending frame`);
526
- // THE SAME GRAMMAR THE WIRE USES, not a restatement of it. `beginSend` previously accepted ids
527
- // (" ", a newline, 65 chars, dots) that `multicastExpecting`'s `assertIdToken` rejects — so T1
528
- // could freeze an id on disk that can NEVER publish, wedging the emitter until an abandon. The
529
- // id is supposed to be one token on the wire and in the WAL; importing the check is what makes
530
- // that true rather than asserted.
514
+ // THE SAME GRAMMAR THE WIRE USES, not a restatement of it. An id that `multicastExpecting`'s
515
+ // `assertIdToken` rejects (" ", a newline, 65 chars, dots) would let T1 freeze an id on disk
516
+ // that can NEVER publish, wedging the emitter until an abandon. The id is one token on the wire
517
+ // and in the WAL; importing the check is what makes that true rather than asserted.
531
518
  assertIdToken(frame.id, "event WAL pending id");
532
519
  if (frame.E !== this.expectedTip)
533
520
  throw new Error(`event WAL ${this.path}: E=${frame.E} is not the subject's tip ${this.expectedTip}`);
@@ -550,26 +537,24 @@ export class EventWal {
550
537
  const p = this.doc.pending;
551
538
  if (!p || p.state !== "sent_unacked")
552
539
  throw new Error(`event WAL ${this.path}: no sent_unacked frame to ack`);
553
- // VALIDATE BEFORE THE DURABLE WRITE. `recordAck(-1)` was accepted, `fold()` then persisted
554
- // `frontier.lastSubjectSeq = -1`, and the NEXT open refused the file — a single bad ack durably
555
- // bricked the WAL while every call reported success. Fail-closed has to happen before the write,
556
- // not on the boot after it.
540
+ // VALIDATE BEFORE THE DURABLE WRITE. An accepted `recordAck(-1)` would let `fold()` persist
541
+ // `frontier.lastSubjectSeq = -1`, and the NEXT open would refuse the file — a single bad ack
542
+ // durably bricking the WAL while every call reported success. Fail-closed has to happen before
543
+ // the write, not on the boot after it.
557
544
  if (!isSafeNonNegInt(ackSeq))
558
545
  throw new Error(`event WAL ${this.path}: ackSeq must be a safe non-negative integer, got ${String(ackSeq)}`);
559
546
  if (ackSeq <= this.expectedTip)
560
547
  throw new Error(`event WAL ${this.path}: ackSeq=${ackSeq} is not ahead of the subject's tip ${this.expectedTip}`);
561
548
  // TWO RULES ABOUT THE NEXT TWO LINES, AND THEY ARE KEPT TOGETHER SO NO PROSE SITS BETWEEN THEM.
562
549
  //
563
- // A STALE WRITER MAY NOT TOUCH THE SHARED RECORD AT ALL, and the refusal is here rather than
564
- // inside `write` because making the unbound expectation throw surfaced that it could. The
565
- // generation guard used to run in `write`, which is AFTER the record moves, so a handle whose
566
- // file had been rewritten underneath it advanced the principal's tip and only then learned it
567
- // was not allowed to write. The record is shared by every thread of the principal; a refusal
568
- // that arrives after the mutation refuses the wrong thing.
550
+ // A STALE WRITER MAY NOT TOUCH THE SHARED RECORD AT ALL, so the refusal runs here and not only
551
+ // inside `write`, which is AFTER the record moves: there, a handle whose file had been rewritten
552
+ // underneath it would advance the principal's tip and only then learn it was not allowed to
553
+ // write. The record is shared by every thread of the principal; a refusal that arrives after
554
+ // the mutation refuses the wrong thing.
569
555
  //
570
- // THEN THE SHARED RECORD ADVANCES FIRST, and the crash window between these two lines was
571
- // written backwards here until somebody executed it. What a crash between them actually leaves
572
- // is the record AHEAD of this log: the frame landed, the record took the sequence the broker
556
+ // THEN THE SHARED RECORD ADVANCES FIRST. What a crash between these two lines leaves is the
557
+ // record AHEAD of this log: the frame landed, the record took the sequence the broker
573
558
  // assigned it, and the log still holds that frame as `sent_unacked` with its `E` frozen at the
574
559
  // tip BEFORE it. The next start republishes the frozen expectation, the subject has already
575
560
  // passed it, and a single-replica stream evaluates the expectation BEFORE the dedup cache, so
@@ -586,14 +571,13 @@ export class EventWal {
586
571
  // of this principal reads its expectation from. Both orders fail closed. Only one of them fails
587
572
  // closed on a value the whole principal reads.
588
573
  //
589
- // A LOCAL, NOT `this.subject?.advance(ackSeq)`. The optional call was not a hole: `expectedTip`
590
- // above throws when nothing is bound, so an unbound log never reaches this statement, and that
591
- // was measured rather than assumed. It is the wrong SHAPE all the same, and this file already
592
- // has the counterexample: `abandon`'s optional call shipped on the identical argument until the
593
- // argument stopped being true. A comment claiming the line above throws cannot survive that
594
- // line being moved or deleted; a local the compiler checks can. The refusal below is therefore
595
- // unreachable by construction and NO CELL GRADES IT, which is said here rather than registered
596
- // as a mutant that could only ever survive.
574
+ // A LOCAL, NOT `this.subject?.advance(ackSeq)`. `expectedTip` above throws when nothing is
575
+ // bound, so an unbound log never reaches this statement, but an optional call would be the
576
+ // wrong SHAPE all the same: it leans on that line staying above this one, and a comment
577
+ // claiming the line above throws cannot survive that line being moved or deleted; a local the
578
+ // compiler checks can. The refusal below is therefore unreachable by construction and NO CELL
579
+ // GRADES IT, which is said here rather than registered as a mutant that could only ever
580
+ // survive.
597
581
  const subject = this.subject;
598
582
  if (!subject)
599
583
  throw new Error(`event WAL ${this.path}: no subject frontier is bound, so this ack has no shared record to advance`);
@@ -651,11 +635,10 @@ export class EventWal {
651
635
  // goes with it. Leaving it standing would make the next thread expect a tip the subject no
652
636
  // longer has, which is this defect's mirror image: the same permanent halt from the other side.
653
637
  //
654
- // REQUIRED, NEVER `this.subject?.reset()`. That optional call was the last silent degradation
655
- // in this file: with no record bound it cleared the log's half and reported a completed
656
- // abandonment, leaving the shared half standing. This method's own contract above is that
657
- // partial abandonment is not a state, and an optional call is how a partial one gets reported
658
- // as whole.
638
+ // REQUIRED, NEVER `this.subject?.reset()`. With no record bound, an optional call would clear
639
+ // the log's half and report a completed abandonment, leaving the shared half standing. This
640
+ // method's own contract above is that partial abandonment is not a state, and an optional call
641
+ // is how a partial one gets reported as whole.
659
642
  await this.assertNotClobbering();
660
643
  if (!this.subject)
661
644
  throw new Error(`event WAL ${this.path}: no subject frontier is bound, so an abandonment here would clear ` +
@@ -687,33 +670,31 @@ export class EventWal {
687
670
  * (that message has landed); the only window where it is dangerous is exactly the window this
688
671
  * file holds it in, between transition 1 and the ack.
689
672
  *
690
- * So the residual a reviewer raised as "gated on a local disk read rather than mesh access" is
691
- * gated on a read OF THIS FILE. A world-readable WAL would convert a property the design credits
692
- * to entropy into one credited to filesystem luck. Under our own rules the attack yields a LOUD
693
- * halt rather than silent loss — a duplicate ack on a retry fails loud with the frontier and
694
- * cursor unmoved — so this is denial of service, not corruption. Closing it by construction is
695
- * cheap enough that naming it as an accepted residual would be the worse trade.
673
+ * So the exposure is gated on a local read OF THIS FILE rather than on mesh access. A
674
+ * world-readable WAL would convert a property the design credits to entropy into one credited to
675
+ * filesystem luck. Under our own rules the attack yields a LOUD halt rather than silent loss — a
676
+ * duplicate ack on a retry fails loud with the frontier and cursor unmoved — so this is denial of
677
+ * service, not corruption. Closing it by construction is cheap enough that naming it as an
678
+ * accepted residual would be the worse trade.
696
679
  */
697
680
  async write(next) {
698
681
  // NOBODY ELSE HAS WRITTEN THIS FILE SINCE THIS HANDLE READ IT. Checked FIRST, because every
699
682
  // line below replaces the document wholesale.
700
683
  await this.assertNotClobbering();
701
684
  const stamped = { ...next, gen: this.doc.gen + 1 };
702
- // The temp name is RANDOM per write, and the open is EXCLUSIVE and NON-FOLLOWING.
703
- //
704
- // The previous version derived the name from `path` + `pid` — predictable — and used
705
- // `open(tmp, "w", 0o600)`. Both halves were exploitable and both were reproduced:
685
+ // The temp name is RANDOM per write, and the open is EXCLUSIVE and NON-FOLLOWING, because a
686
+ // predictable name (`path` + `pid`) opened with `open(tmp, "w", 0o600)` is exploitable twice:
706
687
  // - `open(…, "w")` does not re-chmod an EXISTING inode; the mode argument applies only on
707
- // create. A planted 0644 temp therefore survived as the WAL's mode, and the file holding
708
- // `pending.id` — a pre-publication secret by this class's own argument — ended up
709
- // world-readable while a comment three lines up claimed 0600.
710
- // - `"w"` follows symlinks. A symlink planted at the predicted name made the next transition
711
- // truncate and overwrite an arbitrary file the process could open. One plant, one write.
712
- // Found by fmae-rev-sec, reproduced independently by fmae-rev-eng and fmae-rev-wal, then here.
688
+ // create. A planted 0644 temp would survive as the WAL's mode, and the file holding
689
+ // `pending.id` — a pre-publication secret by this class's own argument — would end up
690
+ // world-readable.
691
+ // - `"w"` follows symlinks. A symlink planted at the predicted name would make the next
692
+ // transition truncate and overwrite an arbitrary file the process could open. One plant,
693
+ // one write.
713
694
  //
714
695
  // O_EXCL makes a pre-existing temp a hard failure rather than something to adopt; O_NOFOLLOW
715
- // refuses a symlink outright; the random suffix removes the predictability that made planting
716
- // reliable; and 0600 comes from the CREATE flags, which is the only place it can come from —
696
+ // refuses a symlink outright; the random suffix removes the predictability that planting
697
+ // relies on; and 0600 comes from the CREATE flags, which is the only place it can come from —
717
698
  // `rename` preserves the inode's mode, so there is no post-rename chmod here and this comment
718
699
  // does not claim one. The suite asserts the mode on the surviving file, which is where the
719
700
  // guarantee has to hold; the code's part is refusing to adopt an existing inode at all.
@@ -739,13 +720,13 @@ export class EventWal {
739
720
  /**
740
721
  * Refuse to replace a document this handle did not read.
741
722
  *
742
- * **THE FAILURE THIS EXISTS FOR WAS EXECUTED, NOT IMAGINED.** Two `EventWal` objects were opened
743
- * on one file. A ran the full cycle and folded a frontier of `{seq:1, lastSubjectSeq:5}`. B, whose
744
- * in-memory document was frozen back at the pending write, then called `recordAck(99)` and
745
- * `fold()` — both SUCCEEDED, each replacing the whole file, and the WAL came back up claiming a
746
- * durable tip of 99: a subject sequence the broker never assigned. The next publish freezes
747
- * `E := 99` against a stream whose real tip is 5, so the emitter either CAS-halts forever or
748
- * recovers a frontier that never existed. Nothing about that is loud; it reads as a healthy WAL.
723
+ * **THE FAILURE THIS EXISTS FOR.** Two `EventWal` objects are open on one file. A runs the full
724
+ * cycle and folds a frontier of `{seq:1, lastSubjectSeq:5}`. B, whose in-memory document is
725
+ * frozen back at the pending write, then calls `recordAck(99)` and `fold()` — without this check
726
+ * both SUCCEED, each replacing the whole file, and the WAL comes back up claiming a durable tip
727
+ * of 99: a subject sequence the broker never assigned. The next publish freezes `E := 99`
728
+ * against a stream whose real tip is 5, so the emitter either CAS-halts forever or recovers a
729
+ * frontier that never existed. Nothing about that is loud; it reads as a healthy WAL.
749
730
  *
750
731
  * The per-instance `serialize` chain cannot see it (two instances, two chains) and neither can the
751
732
  * principal lock (B's handle predates any lock B would take, and a lock is not held against a