@afokapu/atdd-flow 0.3.80 → 0.3.81
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.
- package/package.json +1 -1
- package/src/stale-main-recovery.ts +14 -4
package/package.json
CHANGED
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
import { createHash } from "node:crypto";
|
|
12
12
|
import { mkdir, readFile, rename, rm, writeFile } from "node:fs/promises";
|
|
13
13
|
import { basename, dirname, join, resolve } from "node:path";
|
|
14
|
+
import { isDeepStrictEqual } from "node:util";
|
|
14
15
|
import { type Runtime, type Seat, runOutput, yaml } from "./core";
|
|
15
16
|
import type { HandoverReplacementRequest, LiveSourceProof } from "./handover";
|
|
16
17
|
|
|
@@ -48,6 +49,7 @@ type Recorded = { session: string; sessionPath: string; locator: { session: stri
|
|
|
48
49
|
type Source = HandoverReplacementRequest["source"];
|
|
49
50
|
type Target = HandoverReplacementRequest["target"];
|
|
50
51
|
type PriorReceipt = {
|
|
52
|
+
handover_replacement?: { request?: unknown };
|
|
51
53
|
schema?: string; seat?: string; pi_session?: string; pi_session_path?: string; herdr_session?: string; pane?: string;
|
|
52
54
|
mode?: string; authorized_by?: string; authorization?: string;
|
|
53
55
|
target?: { cwd?: string; pi_session?: string; pi_session_path?: string; herdr_session?: string; pane?: string };
|
|
@@ -288,14 +290,22 @@ export async function backupIsTranscriptPrefix(backup: { path?: string; sha256?:
|
|
|
288
290
|
} catch { return false; }
|
|
289
291
|
}
|
|
290
292
|
|
|
291
|
-
|
|
293
|
+
const atReceiptPlacement = (placement: { herdr_session: string; pane: string }, receipt: PriorReceipt) =>
|
|
294
|
+
placement.herdr_session === receipt.herdr_session && placement.pane === receipt.pane;
|
|
295
|
+
|
|
296
|
+
/** A launcher receipt's own launch request: the active request is exactly the request embedded in the receipt and targets the receipt placement. */
|
|
297
|
+
function isEmbeddedLaunchRequest(request: HandoverReplacementRequest, receipt: PriorReceipt) {
|
|
298
|
+
return receipt.schema === LAUNCH_RECEIPT_SCHEMA && isDeepStrictEqual(request, receipt.handover_replacement?.request) && atReceiptPlacement(request.target, receipt);
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
/** An existing stale active request must be for the recorded Pi and retain the retired placement: both ends at it, or the launch request embedded in the launcher receipt. */
|
|
292
302
|
async function priorRequestIsRetiredLineage(file: string, receipt: PriorReceipt) {
|
|
293
303
|
let bytes: string;
|
|
294
304
|
try { bytes = await readFile(file, "utf8"); } catch { return true; }
|
|
295
305
|
try {
|
|
296
|
-
const
|
|
297
|
-
|
|
298
|
-
|
|
306
|
+
const request = yaml.parse<HandoverReplacementRequest>(bytes), { source, target } = request;
|
|
307
|
+
const samePi = source.pi_session === receipt.pi_session && source.pi_session_path === receipt.pi_session_path;
|
|
308
|
+
return samePi && ((atReceiptPlacement(source, receipt) && atReceiptPlacement(target, receipt)) || isEmbeddedLaunchRequest(request, receipt));
|
|
299
309
|
} catch { return false; }
|
|
300
310
|
}
|
|
301
311
|
|