litmus-cli 1.4.88 → 1.4.90

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,4 +1,5 @@
1
1
  import fs from "fs";
2
+ import lockfile from "proper-lockfile";
2
3
  import os from "os";
3
4
  import path from "path";
4
5
  import { clearOwnedNotice, isOwnedNoticeFile, recordOwnedNotice } from "./notice-ownership.js";
@@ -116,21 +117,46 @@ function listShadowIds() {
116
117
  /** Record the last chain position the SERVER has (written after each
117
118
  * successful upload), so a replacement watcher whose activity.jsonl is gone
118
119
  * continues the chain instead of forking a second genesis. */
119
- export function writeShadowChainCursor(assessmentId, seq, hash) {
120
+ function chainCursorPath(assessmentId, tokenHash) {
120
121
  const dir = shadowDirFor(assessmentId);
121
- if (!dir)
122
+ if (!dir || (tokenHash !== undefined && !/^[a-f0-9]{64}$/.test(tokenHash)))
123
+ return null;
124
+ return path.join(dir, tokenHash ? `chain-${tokenHash}.json` : "chain.json");
125
+ }
126
+ export async function writeShadowChainCursor(assessmentId, seq, hash, tokenHash) {
127
+ const file = chainCursorPath(assessmentId, tokenHash);
128
+ if (!file)
122
129
  return;
130
+ const dir = path.dirname(file);
131
+ let release;
123
132
  try {
124
- atomicWrite(path.join(dir, "chain.json"), JSON.stringify({ seq, hash, updatedAt: new Date().toISOString() }));
133
+ fs.mkdirSync(dir, { recursive: true });
134
+ // A retiring watcher can still receive its HTTP receipt after its successor.
135
+ // Serialize read/compare/publish across processes, not just HTTP requests in
136
+ // one watcher. The heartbeat lease permits recovery after a killed writer.
137
+ release = await lockfile.lock(file, {
138
+ realpath: false, stale: 10000, update: 2000,
139
+ retries: { retries: 120, factor: 1, minTimeout: 100, maxTimeout: 100 },
140
+ });
141
+ const previous = readShadowChainCursor(assessmentId, tokenHash);
142
+ if (previous && previous.seq >= seq)
143
+ return;
144
+ atomicWrite(file, JSON.stringify({ seq, hash, updatedAt: new Date().toISOString() }));
125
145
  }
126
146
  catch { /* best effort */ }
147
+ finally {
148
+ try {
149
+ await release?.();
150
+ }
151
+ catch { /* best effort */ }
152
+ }
127
153
  }
128
- export function readShadowChainCursor(assessmentId) {
129
- const dir = shadowDirFor(assessmentId);
130
- if (!dir)
154
+ export function readShadowChainCursor(assessmentId, tokenHash) {
155
+ const file = chainCursorPath(assessmentId, tokenHash);
156
+ if (!file)
131
157
  return null;
132
158
  try {
133
- const parsed = JSON.parse(fs.readFileSync(path.join(dir, "chain.json"), "utf8"));
159
+ const parsed = JSON.parse(fs.readFileSync(file, "utf8"));
134
160
  if (typeof parsed.seq !== "number" || typeof parsed.hash !== "string" || !parsed.hash)
135
161
  return null;
136
162
  return parsed;
@@ -1 +1 @@
1
- {"version":3,"file":"shadow.js","sourceRoot":"","sources":["../../src/lib/shadow.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"shadow.js","sourceRoot":"","sources":["../../src/lib/shadow.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env node
2
+ import { ActivityOutbox, activityReceiptMatches } from "./activity-outbox.js";
2
3
  import { relocateNoticeOwnership } from "./notice-ownership.js";
3
4
  import { collectProjectSnapshot } from "./project-snapshot.js";
4
5
  import { watchProjectRoot, SNAPSHOT_REPAIR_GUIDANCE } from "./project-root.js";
@@ -272,7 +273,14 @@ try {
272
273
  catch { /* config not available */ }
273
274
  let uploadConfig = null;
274
275
  let uploadBuffer = [];
275
- const MAX_BUFFER_SIZE = 10000;
276
+ // A folder may be reused for another invitation. Never send a previous token's
277
+ // queued capture under the new candidate's credentials.
278
+ let outboxName = `upload-outbox-${crypto.createHash("sha256").update(litmusConfig?.token ?? "").digest("hex")}`;
279
+ let activityOutbox = new ActivityOutbox(path.join(path.dirname(activityLogPath), outboxName));
280
+ let uploadInFlight = null;
281
+ let volatileBatch = null;
282
+ let retryBatch = null;
283
+ let uploadRetryTimer = null;
276
284
  if (litmusConfig && litmusConfig.token && litmusConfig.backendUrl) {
277
285
  uploadConfig = { token: litmusConfig.token, backendUrl: litmusConfig.backendUrl };
278
286
  process.stderr.write("[watcher] upload enabled\n");
@@ -299,13 +307,47 @@ if (litmusConfig?.assessmentId) {
299
307
  * During normal operation the returned promise is ignored (fire-and-forget).
300
308
  */
301
309
  function uploadEvents() {
302
- if (!uploadConfig || uploadBuffer.length === 0)
310
+ if (uploadInFlight)
311
+ return uploadInFlight;
312
+ if (uploadRetryTimer) {
313
+ clearTimeout(uploadRetryTimer);
314
+ uploadRetryTimer = null;
315
+ }
316
+ if (!uploadConfig)
317
+ return Promise.resolve();
318
+ let batch = volatileBatch ?? retryBatch;
319
+ try {
320
+ if (!batch) {
321
+ // Disk-refused events retain their legacy log recovery path. Do not
322
+ // later copy them into the spool without a matching durable log marker.
323
+ if (uploadBuffer.length) {
324
+ volatileBatch = { uploadId: crypto.randomUUID(), events: uploadBuffer.splice(0, 100) };
325
+ batch = volatileBatch;
326
+ }
327
+ else
328
+ batch = activityOutbox.next();
329
+ }
330
+ }
331
+ catch (error) {
332
+ process.stderr.write(`[watcher] cannot persist activity upload: ${error}\n`);
333
+ // Preserve the pre-existing best-effort live channel when disk is full or
334
+ // unavailable. This stable in-memory batch can retry, although no software
335
+ // can make it survive process death while storage itself is refusing writes.
336
+ if (uploadBuffer.length) {
337
+ volatileBatch = { uploadId: crypto.randomUUID(), events: uploadBuffer.splice(0, 100) };
338
+ batch = volatileBatch;
339
+ }
340
+ }
341
+ if (!batch)
303
342
  return Promise.resolve();
304
- const events = uploadBuffer.splice(0); // take all, clear buffer
305
- const body = JSON.stringify({ events });
343
+ if (batch !== volatileBatch)
344
+ retryBatch = batch;
345
+ const events = batch.events;
346
+ const body = JSON.stringify(batch);
306
347
  const url = new URL(`${uploadConfig.backendUrl}/cli/activity`);
307
348
  const reqFn = url.protocol === "https:" ? https.request : http.request;
308
- return new Promise((resolve) => {
349
+ let retryDelay = 60000;
350
+ uploadInFlight = new Promise((resolve) => {
309
351
  const req = reqFn(url, {
310
352
  method: "POST",
311
353
  headers: {
@@ -324,15 +366,16 @@ function uploadEvents() {
324
366
  // Buffer the chunks and decode once at end — per-chunk `toString()`
325
367
  // corrupts UTF-8 split across TCP boundaries.
326
368
  const responseChunks = [];
369
+ // A response can break after headers without emitting request.error or
370
+ // response.end. Release the single-flight slot while retaining the batch.
371
+ res.once("aborted", () => { resolve(); });
372
+ res.once("error", () => { resolve(); });
327
373
  res.on("data", (chunk) => { responseChunks.push(chunk); });
328
- res.on("end", () => {
374
+ res.on("end", async () => {
329
375
  const responseData = Buffer.concat(responseChunks).toString("utf8");
330
376
  if (res.statusCode >= 500) {
331
377
  process.stderr.write(`[watcher] upload failed (will retry): ${res.statusCode}\n`);
332
- uploadBuffer = events.concat(uploadBuffer);
333
- if (uploadBuffer.length > MAX_BUFFER_SIZE) {
334
- uploadBuffer = uploadBuffer.slice(-MAX_BUFFER_SIZE);
335
- }
378
+ // Immutable batch remains on disk for retry.
336
379
  }
337
380
  else if (res.statusCode >= 400) {
338
381
  process.stderr.write(`[watcher] upload rejected: ${res.statusCode}\n`);
@@ -366,21 +409,41 @@ function uploadEvents() {
366
409
  catch { /* not JSON; nothing to act on */ }
367
410
  }
368
411
  else {
369
- // ENG-1453: record the chain position the server just acknowledged,
370
- // outside the repo. A replacement watcher whose activity.jsonl was
371
- // wiped resumes from here instead of forking a second genesis chain.
372
- if (litmusConfig) {
373
- let ackSeq = -1;
374
- let ackHash = "";
375
- for (const e of events) {
376
- if (typeof e._seq === "number" && e._seq > ackSeq && typeof e._hash === "string") {
377
- ackSeq = e._seq;
378
- ackHash = e._hash;
379
- }
412
+ let acknowledged = false;
413
+ try {
414
+ const receipt = JSON.parse(responseData);
415
+ if (!activityReceiptMatches(batch, receipt)) {
416
+ resolve();
417
+ return;
380
418
  }
381
- if (ackSeq >= 0 && ackHash)
382
- writeShadowChainCursor(litmusConfig.assessmentId, ackSeq, ackHash);
419
+ // Persist the off-repo acknowledgement before dropping its spool.
420
+ // The spool also retains a token-scoped checkpoint for a crash
421
+ // between its own append and the async activity-log write.
422
+ if (litmusConfig) {
423
+ let ackSeq = -1, ackHash = "";
424
+ for (const e of events)
425
+ if (typeof e._seq === "number" && e._seq > ackSeq && typeof e._hash === "string") {
426
+ ackSeq = e._seq;
427
+ ackHash = e._hash;
428
+ }
429
+ if (ackSeq >= 0 && ackHash)
430
+ await writeShadowChainCursor(litmusConfig.assessmentId, ackSeq, ackHash, outboxName.slice("upload-outbox-".length));
431
+ }
432
+ if (batch === volatileBatch) {
433
+ acknowledged = receipt.uploadId === batch.uploadId && receipt.processed === batch.events.length;
434
+ if (acknowledged)
435
+ volatileBatch = null;
436
+ }
437
+ else
438
+ acknowledged = activityOutbox.acknowledge(batch, receipt);
383
439
  }
440
+ catch { /* retain for retry */ }
441
+ if (!acknowledged) {
442
+ resolve();
443
+ return;
444
+ }
445
+ retryBatch = null;
446
+ retryDelay = 5000;
384
447
  // Parse response for server signals (e.g., pending questions)
385
448
  try {
386
449
  const body = JSON.parse(responseData);
@@ -412,15 +475,22 @@ function uploadEvents() {
412
475
  });
413
476
  req.on("error", () => {
414
477
  // Network error — retry on next heartbeat
415
- uploadBuffer = events.concat(uploadBuffer);
416
- if (uploadBuffer.length > MAX_BUFFER_SIZE) {
417
- uploadBuffer = uploadBuffer.slice(-MAX_BUFFER_SIZE);
418
- }
478
+ // Keep the same durable batch/id after ambiguous network failure.
419
479
  resolve();
420
480
  });
421
481
  req.on("timeout", () => { req.destroy(); });
422
482
  req.end(body);
483
+ }).finally(() => {
484
+ uploadInFlight = null;
485
+ // Drain a backlog below the shared 20/min rate bucket. Refusals retain the
486
+ // batch and back off, rather than retrying a five-minute heartbeat forever.
487
+ if (!shuttingDown)
488
+ uploadRetryTimer = setTimeout(() => {
489
+ uploadRetryTimer = null;
490
+ void uploadEvents();
491
+ }, retryDelay).unref();
423
492
  });
493
+ return uploadInFlight;
424
494
  }
425
495
  // ── Ignore patterns ──────────────────────────────────────────────
426
496
  const IGNORED = [
@@ -477,36 +547,60 @@ let preChainBuffer = [];
477
547
  /** Set when shutdown arrives inside the chain-start window: this process
478
548
  * NEVER does chain math — an incumbent may still own the tail. */
479
549
  let chainAbandoned = false;
480
- function writeUnchained(event) {
481
- log.write(JSON.stringify(event) + "\n");
482
- if (uploadConfig && uploadBuffer.length < MAX_BUFFER_SIZE) {
483
- uploadBuffer.push(event);
550
+ function writeUnchained(event, chained = false) {
551
+ const hashEvent = () => {
552
+ delete event._hash;
553
+ event._hash = crypto.createHash("sha256").update(JSON.stringify(event)).digest("hex");
554
+ };
555
+ if (uploadConfig)
556
+ event._durableUpload = true;
557
+ if (chained)
558
+ hashEvent();
559
+ if (uploadConfig) {
560
+ try {
561
+ activityOutbox.append(event);
562
+ }
563
+ catch (error) {
564
+ // A failed spool append is NOT durably owned. Keep the older log-flush
565
+ // fallback and include the final ownership marker in the chain hash.
566
+ delete event._durableUpload;
567
+ if (chained)
568
+ hashEvent();
569
+ uploadBuffer.push(event);
570
+ process.stderr.write(`[watcher] activity spool unavailable; retaining in memory: ${error}\n`);
571
+ }
484
572
  }
573
+ log.write(JSON.stringify(event) + "\n");
485
574
  }
486
575
  function writeChained(event) {
487
576
  event._seq = nextSeq++;
488
577
  event._prevHash = prevHash;
489
- const hash = crypto.createHash("sha256").update(JSON.stringify(event)).digest("hex");
490
- event._hash = hash;
491
- prevHash = hash;
492
- writeUnchained(event);
578
+ writeUnchained(event, true);
579
+ prevHash = event._hash;
493
580
  }
494
581
  function startChain() {
495
582
  if (chainAbandoned || preChainBuffer === null)
496
583
  return;
497
- const chainStart = resumeChainFromLog(activityLogPath);
584
+ let chainStart;
585
+ try {
586
+ const acknowledged = litmusConfig ? readShadowChainCursor(litmusConfig.assessmentId, outboxName.slice("upload-outbox-".length)) : null;
587
+ chainStart = activityOutbox.resumeChain(resumeChainFromLog(activityLogPath), acknowledged ?? undefined);
588
+ }
589
+ catch (error) {
590
+ // Preserve capture without asserting a chain continuity we cannot prove.
591
+ process.stderr.write(`[watcher] cannot safely resume activity chain: ${error}\n`);
592
+ abandonChainAndDrain();
593
+ return;
594
+ }
498
595
  prevHash = chainStart.prevHash;
499
596
  nextSeq = chainStart.nextSeq;
500
- // ENG-1453: a genesis resume with no local log usually means the repo's
501
- // .litmus was wiped, not that this is a fresh assessment. Continue from
502
- // the last server-acknowledged position instead of forking the chain.
503
- if (nextSeq === 0 && litmusConfig) {
504
- const cursor = readShadowChainCursor(litmusConfig.assessmentId);
505
- if (cursor) {
506
- prevHash = cursor.hash;
507
- nextSeq = cursor.seq + 1;
508
- process.stderr.write(`[watcher] chain resumed from shadow cursor at seq ${cursor.seq}\n`);
509
- }
597
+ // Older checkpoints have no invitation/token binding. An empty local log
598
+ // cannot prove they belong to this candidate, so preserve capture unchained
599
+ // instead of claiming continuity with another invitation's history.
600
+ if (nextSeq === 0 && litmusConfig && readShadowChainCursor(litmusConfig.assessmentId)) {
601
+ process.stderr.write("[watcher] legacy chain checkpoint has no invitation binding; continuing capture without a resumed chain\n");
602
+ abandonChainAndDrain();
603
+ return;
510
604
  }
511
605
  const queued = preChainBuffer;
512
606
  preChainBuffer = null;
@@ -813,6 +907,12 @@ async function selfHealConfig(reason) {
813
907
  }
814
908
  let healed = false;
815
909
  if (restored && restoredFrom) {
910
+ // A token change is a different upload identity. Never carry this
911
+ // watcher's old queue into another invitation during shadow recovery.
912
+ if (uploadConfig && restored.token !== uploadConfig.token) {
913
+ process.stderr.write("[watcher] refused config recovery for a different assessment token\n");
914
+ return;
915
+ }
816
916
  try {
817
917
  // The directory may have moved while the server fetch was in flight.
818
918
  if (reportProjectRootProblem())
@@ -820,6 +920,10 @@ async function selfHealConfig(reason) {
820
920
  await writeConfig(projectDir, restored); // re-mirrors the shadow too
821
921
  litmusConfig = restored;
822
922
  if (restored.token && restored.backendUrl) {
923
+ if (!uploadConfig) {
924
+ outboxName = `upload-outbox-${crypto.createHash("sha256").update(restored.token).digest("hex")}`;
925
+ activityOutbox = new ActivityOutbox(path.join(path.dirname(activityLogPath), outboxName));
926
+ }
823
927
  uploadConfig = { token: restored.token, backendUrl: restored.backendUrl };
824
928
  }
825
929
  shadowAssessmentId = restored.assessmentId;
@@ -1427,6 +1531,7 @@ function reportProjectRootProblem() {
1427
1531
  noticeProjectKey = fs.realpathSync(relocated);
1428
1532
  projectDir = relocated;
1429
1533
  activityLogPath = path.join(relocated, path.relative(oldRoot, activityLogPath));
1534
+ activityOutbox.relocate(path.join(path.dirname(activityLogPath), outboxName));
1430
1535
  if (noncePath)
1431
1536
  noncePath = path.join(relocated, path.relative(oldRoot, noncePath));
1432
1537
  pidFilePath = path.join(path.dirname(activityLogPath), "tracker.pid");
@@ -1657,6 +1762,10 @@ function shutdown() {
1657
1762
  if (shuttingDown)
1658
1763
  return;
1659
1764
  shuttingDown = true;
1765
+ if (uploadRetryTimer) {
1766
+ clearTimeout(uploadRetryTimer);
1767
+ uploadRetryTimer = null;
1768
+ }
1660
1769
  // A shutdown inside the chain-start window (doctor stopping a watcher it
1661
1770
  // just spawned) must not drop the buffered events — but it must not start
1662
1771
  // the chain either, because an incumbent may still own the tail. Drain