@junghanacs/entwurf 0.30.0 → 0.31.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 (69) hide show
  1. package/AGENTS.md +1 -0
  2. package/CHANGELOG.md +229 -0
  3. package/DELIVERY.md +1 -0
  4. package/README.md +49 -4
  5. package/VERIFY.md +23 -4
  6. package/demo/README.md +1 -1
  7. package/docs/acp-backend-rail.md +111 -18
  8. package/docs/setup-clean-host.md +104 -4
  9. package/mcp/entwurf-bridge/dist/mcp/entwurf-bridge/src/index.js +7 -7
  10. package/mcp/entwurf-bridge/dist/pi-extensions/entwurf-capabilities.json +1 -0
  11. package/mcp/entwurf-bridge/dist/pi-extensions/lib/acp/backend-adapter.js +43 -0
  12. package/mcp/entwurf-bridge/dist/pi-extensions/lib/entwurf-deliverability.js +7 -1
  13. package/mcp/entwurf-bridge/dist/pi-extensions/lib/fresh-call-composition.js +34 -3
  14. package/mcp/entwurf-bridge/dist/pi-extensions/lib/meta-sender-identity.js +7 -1
  15. package/mcp/entwurf-bridge/dist/pi-extensions/lib/meta-session.js +28 -2
  16. package/mcp/entwurf-bridge/dist/pi-extensions/lib/mux-fresh-call.js +30 -2
  17. package/mcp/entwurf-bridge/dist/pi-extensions/lib/pi-durable-fresh-preflight.js +92 -0
  18. package/mcp/entwurf-bridge/dist/pi-extensions/lib/pi-durable-runtime.js +288 -0
  19. package/mcp/entwurf-bridge/dist/pi-extensions/meta-bridge-pi-durable.js +744 -0
  20. package/mcp/entwurf-bridge/src/index.ts +7 -7
  21. package/mcp/entwurf-bridge/tsconfig.build.json +8 -1
  22. package/package.json +15 -12
  23. package/pi/entwurf-capabilities.json +1 -0
  24. package/pi/pi-durable/bootstrap.mjs +281 -0
  25. package/pi/pi-durable/overlay/runtime-contacts.patch +91 -0
  26. package/pi/pi-durable/overlay/upstream-pin.json +16 -0
  27. package/pi-extensions/lib/acp/backend-adapter.ts +68 -0
  28. package/pi-extensions/lib/acp/backend.ts +41 -5
  29. package/pi-extensions/lib/entwurf-deliverability.ts +7 -1
  30. package/pi-extensions/lib/fresh-call-composition.ts +42 -7
  31. package/pi-extensions/lib/meta-sender-identity.ts +7 -1
  32. package/pi-extensions/lib/meta-session.ts +28 -2
  33. package/pi-extensions/lib/mux-fresh-call.ts +34 -2
  34. package/pi-extensions/lib/pi-durable-fresh-preflight.ts +113 -0
  35. package/pi-extensions/lib/pi-durable-runtime.ts +384 -0
  36. package/pi-extensions/meta-bridge-pi-durable.ts +1020 -0
  37. package/run.sh +214 -36
  38. package/scripts/check-fresh-call-dispatch.ts +18 -0
  39. package/scripts/check-gate-qualification.ts +4 -2
  40. package/scripts/check-herdr-plugin-build.ts +159 -57
  41. package/scripts/check-pi-durable-contact.ts +834 -0
  42. package/scripts/check-pi-durable-receive.ts +1116 -0
  43. package/scripts/check-pi-durable-send.ts +1661 -0
  44. package/scripts/fixtures/herdr-supply.json +8 -8
  45. package/scripts/lib/pi-durable-fresh-live-receipts.ts +139 -0
  46. package/scripts/lib/pi-durable-r1.ts +100 -0
  47. package/scripts/lib/pi-durable-reap.ts +27 -0
  48. package/scripts/lib/pi-durable-receive.ts +137 -0
  49. package/scripts/mutants/acp-prompt-lifecycle.json +2 -2
  50. package/scripts/mutants/acp-vendor-rejection.json +62 -0
  51. package/scripts/mutants/control-send-receipt.json +1 -1
  52. package/scripts/mutants/copilot-birth.json +2 -2
  53. package/scripts/mutants/herdr-plugin-build.json +11 -0
  54. package/scripts/mutants/herdr-supply.json +3 -3
  55. package/scripts/mutants/meta-hook-session-switch.json +4 -2
  56. package/scripts/mutants/mux-fresh-call.json +69 -3
  57. package/scripts/mutants/omp-birth.json +2 -2
  58. package/scripts/mutants/omp-fresh.json +6 -4
  59. package/scripts/mutants/pack-install.json +3 -3
  60. package/scripts/mutants/pi-durable.json +390 -0
  61. package/scripts/mutants/pi-floor.json +2 -2
  62. package/scripts/pi-durable-contact-host.mjs +105 -0
  63. package/scripts/pi-durable-receive-host.mjs +127 -0
  64. package/scripts/pi-durable-send-host.mjs +213 -0
  65. package/scripts/smoke-acp-raw-turn-live.ts +1 -1
  66. package/scripts/smoke-herdr-fresh-call-live.ts +21 -7
  67. package/scripts/smoke-pi-durable-fresh-live.ts +624 -0
  68. package/scripts/smoke-setup-verdict.sh +21 -2
  69. package/scripts/tsconfig.json +1 -0
@@ -53,6 +53,20 @@ const COMPILED_ENTRY = path.join("mcp", "entwurf-bridge", "dist", "mcp", "entwur
53
53
  const COMMIT_A = "a".repeat(40);
54
54
  const COMMIT_B = "b".repeat(40);
55
55
 
56
+ // Fixture inputs, not registry assertions. The npm coherence check reads this checkout's
57
+ // package.json, so its version is input; neither an unpublished version nor the committed
58
+ // carrier may choose which source these deterministic cells exercise. No network is used.
59
+ const FIXTURE_VERSION = (JSON.parse(fs.readFileSync(path.join(REPO, "package.json"), "utf8")) as { version: string })
60
+ .version;
61
+ const FIXTURE_NPM_LOCK = Object.freeze({
62
+ source: "npm",
63
+ name: PACKAGE,
64
+ version: FIXTURE_VERSION,
65
+ integrity: `sha512-${createHash("sha512").update("hpb-npm-fixture").digest("base64")}`,
66
+ });
67
+ const FIXTURE_OTHER_INTEGRITY = `sha512-${createHash("sha512").update("hpb-npm-other-fixture").digest("base64")}`;
68
+ const FIXTURE_CHECKOUT_LOCK = Object.freeze({ source: "herdr-checkout", repository: "junghan0611/entwurf" });
69
+
56
70
  interface SpawnResult {
57
71
  status: number | null;
58
72
  stdout: string;
@@ -175,9 +189,10 @@ function tree(root: string): string[] {
175
189
  */
176
190
  function fixtureAcquire(opts: { activate: "absent" | "incapable" | "recorder"; log?: string; fail?: boolean }) {
177
191
  return ({ identity, prefix }: AcquireArgs) => {
192
+ const version = identity.version ?? FIXTURE_VERSION;
178
193
  const root = path.join(prefix, "node_modules", PACKAGE);
179
194
  fs.mkdirSync(path.join(root, path.dirname(COMPILED_ENTRY)), { recursive: true });
180
- fs.writeFileSync(path.join(root, "package.json"), `${JSON.stringify({ name: PACKAGE, version: "0.21.0" })}\n`);
195
+ fs.writeFileSync(path.join(root, "package.json"), `${JSON.stringify({ name: PACKAGE, version })}\n`);
181
196
  fs.writeFileSync(path.join(root, COMPILED_ENTRY), "// compiled entry fixture\n");
182
197
  const bin = path.join(prefix, "node_modules", ".bin");
183
198
  fs.mkdirSync(bin, { recursive: true });
@@ -208,7 +223,7 @@ function fixtureAcquire(opts: { activate: "absent" | "incapable" | "recorder"; l
208
223
  .update(identity.commit ?? "x")
209
224
  .digest("hex")}`,
210
225
  packageName: PACKAGE,
211
- packageVersion: "0.21.0",
226
+ packageVersion: version,
212
227
  };
213
228
  };
214
229
  }
@@ -249,6 +264,9 @@ function drive(
249
264
  spawn,
250
265
  write: (t: string) => (out += t),
251
266
  progress,
267
+ // Existing gate-only seam. Production still reads the committed lock, and its
268
+ // real source/coherence is independently checked by check-herdr-runtime-bootstrap.
269
+ readRuntimeLock: () => FIXTURE_NPM_LOCK,
252
270
  ...deps,
253
271
  });
254
272
  return { code, refusal: null, out, progress: progressLines };
@@ -408,57 +426,121 @@ function drive(
408
426
 
409
427
  // ── 6. the two-stage journey, as the RUNNER composes it ────────────────────────
410
428
  {
411
- const env = world("two-stage");
429
+ // Declared axes: both closed sources × {initial A, widened A, changed B, repeated B}.
430
+ // npm identity is the unchanged lock, not a commit; checkout identity IS the commit.
431
+ const cells = [FIXTURE_NPM_LOCK, FIXTURE_CHECKOUT_LOCK].map((lock) => {
432
+ const env = world(`two-stage-${lock.source}`);
433
+ const log = path.join(env.HOME as string, "argv.log");
434
+ let acquisitions = 0;
435
+ const counted = (args: AcquireArgs) => {
436
+ acquisitions++;
437
+ return fixtureAcquire({ activate: "recorder", log })(args);
438
+ };
439
+ const stages = [COMMIT_A, COMMIT_A, COMMIT_B, COMMIT_B].map((commit, index) => {
440
+ const rows: Record<string, string> = { pi: "current (v8) (/home/u/.pi)" };
441
+ if (index > 0) rows.claude = "current (v5) (/home/u/.claude)";
442
+ const result = drive(env, listing(rows), {
443
+ acquire: counted,
444
+ readRuntimeLock: () => lock,
445
+ resolveCommit: () => commit,
446
+ });
447
+ return { code: result.code, acquisitions };
448
+ });
449
+ const calls = fs.readFileSync(log, "utf8").trim().split("\n");
450
+ const { artifactIdentity: identity } = JSON.parse(fs.readFileSync(journalPathOf(env), "utf8")) as {
451
+ artifactIdentity: Record<string, string>;
452
+ };
453
+ const expectedCounts = lock.source === "npm" ? [1, 1, 1, 1] : [1, 1, 2, 2];
454
+ const exactIdentity =
455
+ lock.source === "npm"
456
+ ? identity.name === PACKAGE &&
457
+ identity.version === FIXTURE_VERSION &&
458
+ identity.expectedIntegrity === FIXTURE_NPM_LOCK.integrity
459
+ : identity.repository === FIXTURE_CHECKOUT_LOCK.repository &&
460
+ identity.commit === COMMIT_B &&
461
+ identity.packageName === PACKAGE &&
462
+ identity.packageVersion === FIXTURE_VERSION;
463
+ return {
464
+ source: lock.source,
465
+ stages,
466
+ calls,
467
+ identity,
468
+ passed:
469
+ stages.every((stage) => stage.code === 0) &&
470
+ JSON.stringify(stages.map((stage) => stage.acquisitions)) === JSON.stringify(expectedCounts) &&
471
+ JSON.stringify(calls) === JSON.stringify(["pi", "pi,claude-code", "pi,claude-code", "pi,claude-code"]) &&
472
+ identity.kind === lock.source &&
473
+ exactIdentity,
474
+ };
475
+ });
476
+ ok(
477
+ "[QK:HPB-SEQUENTIAL-TWO-STAGE] both closed sources hand down `{pi}` then the widened `{pi, claude-code}` " +
478
+ "on every reinstall, never OpenCode. An unchanged npm lock acquires once; checkout acquires again ONLY " +
479
+ "when A becomes B, and repeated B acquires nothing. Counts are exact at EACH step, not an aggregate lower " +
480
+ "bound. Installed identity must retain the input kind and its exact version/integrity or commit/completeness. " +
481
+ "The real writer bytes are HAC-TWO-STAGE-ADD-ONLY; this cell owns runner composition. " +
482
+ `Fixture identities do not claim registry acceptance (cells=${JSON.stringify(cells)})`,
483
+ cells.length === 2 && cells.every((cell) => cell.passed),
484
+ );
485
+ }
486
+
487
+ // ── 5b. the production default reader composes with the committed lock ─────────
488
+ {
489
+ // Independent input oracle: read the committed JSON directly, not the runtime reader
490
+ // whose invocation this cell certifies. All acquisition/activation bytes remain fixture.
491
+ const committed = JSON.parse(fs.readFileSync(path.join(PLUGIN_DIR, "runtime-lock.json"), "utf8")) as
492
+ | { source: "npm"; name: string; version: string; integrity: string }
493
+ | { source: "herdr-checkout"; repository: string };
494
+ const env = world("default-lock-reader");
412
495
  const log = path.join(env.HOME as string, "argv.log");
413
496
  let acquisitions = 0;
414
- const counted = (args: AcquireArgs) => {
415
- acquisitions++;
416
- return fixtureAcquire({ activate: "recorder", log })(args);
417
- };
418
- const stage1 = drive(env, listing({ pi: "current (v8) (/home/u/.pi)" }), {
419
- acquire: counted,
420
- resolveCommit: () => COMMIT_A,
421
- });
422
- const stage2 = drive(env, listing({ pi: "current (v8) (/home/u/.pi)", claude: "current (v5) (/home/u/.claude)" }), {
423
- acquire: counted,
497
+ const acquire = fixtureAcquire({ activate: "recorder", log });
498
+ const result = drive(env, listing({ pi: "current (v8) (/home/u/.pi)" }), {
499
+ readRuntimeLock: undefined,
424
500
  resolveCommit: () => COMMIT_A,
501
+ acquire: (args: AcquireArgs) => {
502
+ acquisitions++;
503
+ return acquire(args);
504
+ },
425
505
  });
426
- const stage3 = drive(env, listing({ pi: "current (v8) (/home/u/.pi)", claude: "current (v5) (/home/u/.claude)" }), {
427
- acquire: counted,
428
- resolveCommit: () => COMMIT_B,
429
- });
430
- const calls = fs.readFileSync(log, "utf8").trim().split("\n");
431
- const journal = JSON.parse(fs.readFileSync(journalPathOf(env), "utf8")) as {
432
- artifactIdentity: { commit: string };
433
- };
506
+ const journal = fs.existsSync(journalPathOf(env))
507
+ ? (JSON.parse(fs.readFileSync(journalPathOf(env), "utf8")) as { artifactIdentity: Record<string, string> })
508
+ : null;
509
+ const identity = journal?.artifactIdentity;
510
+ const exactIdentity =
511
+ identity !== undefined &&
512
+ identity.kind === committed.source &&
513
+ (committed.source === "npm"
514
+ ? identity.name === committed.name &&
515
+ identity.version === committed.version &&
516
+ identity.expectedIntegrity === committed.integrity
517
+ : identity.repository === committed.repository &&
518
+ identity.commit === COMMIT_A &&
519
+ identity.packageName === PACKAGE &&
520
+ identity.packageVersion === FIXTURE_VERSION);
434
521
  ok(
435
- "[QK:HPB-SEQUENTIAL-TWO-STAGE] the sequence a real operator performs, as the runner composes it: `{pi}` first, " +
436
- "then `{pi, claude-code}` after they integrated Claude Code, then a NEW commit of the same package version. " +
437
- "The unchanged commit acquires nothing while still reconciling the widened set; the new commit reinstalls. " +
438
- "OpenCode is present in every listing and appears in NO activation argv — the bytes those activations write " +
439
- "are `check-herdr-activation`'s HAC-TWO-STAGE-ADD-ONLY, which drives the real Pi writers; what this cell owns " +
440
- `is what the runner hands down (codes=${stage1.code}/${stage2.code}/${stage3.code} acquisitions=${acquisitions} calls=${JSON.stringify(calls)} commit=${journal.artifactIdentity.commit.slice(0, 8)})`,
441
- stage1.code === 0 &&
442
- stage2.code === 0 &&
443
- stage3.code === 0 &&
444
- acquisitions === 2 &&
445
- JSON.stringify(calls) === JSON.stringify(["pi", "pi,claude-code", "pi,claude-code"]) &&
446
- !calls.some((c) => c.includes("opencode")) &&
447
- journal.artifactIdentity.commit === COMMIT_B,
522
+ "[QK:HPB-DEFAULT-LOCK-READ] without a reader override, runBuild reads this plugin's committed lock " +
523
+ "from PLUGIN_DIR, not the repository root or a synthetic fixture. The acquired identity retains the " +
524
+ "independently read source and exact artifact fields; installed activation still runs once for pi. " +
525
+ `This is composition proof, not registry acquisition (code=${result.code} refusal=${result.refusal} acquisitions=${acquisitions} identity=${JSON.stringify(identity)})`,
526
+ result.code === 0 &&
527
+ acquisitions === 1 &&
528
+ exactIdentity &&
529
+ fs.existsSync(log) &&
530
+ fs.readFileSync(log, "utf8") === "pi\n",
448
531
  );
449
532
  }
450
533
 
451
534
  // ── 6a. the authority check happens BEFORE any runtime work ───────────────────
452
535
  {
453
- const IDENTITY = (commit: string) => ({
454
- kind: "herdr-checkout",
455
- repository: "junghan0611/entwurf",
456
- commit,
457
- packageName: PACKAGE,
458
- packageVersion: "0.21.0",
459
- observedDigest: `sha256-${createHash("sha256").update(commit).digest("hex")}`,
536
+ const IDENTITY = (seed: string) => ({
537
+ kind: "npm",
538
+ name: PACKAGE,
539
+ version: FIXTURE_VERSION,
540
+ expectedIntegrity: FIXTURE_NPM_LOCK.integrity,
541
+ observedDigest: `sha256-${createHash("sha256").update(seed).digest("hex")}`,
460
542
  });
461
- /** A host that already has a runtime at commit A and a ledger that says so. */
543
+ /** A host with the explicit npm fixture installed and a ledger describing it. */
462
544
  const seeded = (tag: string, backends: string[]): NodeJS.ProcessEnv => {
463
545
  const env = world(tag);
464
546
  const log = path.join(env.HOME as string, "argv.log");
@@ -468,12 +550,17 @@ function drive(
468
550
  });
469
551
  const states: Record<string, string> = {};
470
552
  for (const b of backends) states[b] = "active";
553
+ const artifactIdentity = (
554
+ JSON.parse(fs.readFileSync(journalPathOf(env), "utf8")) as {
555
+ artifactIdentity: Record<string, unknown>;
556
+ }
557
+ ).artifactIdentity;
471
558
  activation.writeLedger(
472
559
  activation.resolveActivationLayout(env),
473
560
  activation.ledgerBody({
474
561
  phase: "active",
475
562
  runtimeRoot: activeDirOf(env),
476
- artifactIdentity: IDENTITY(COMMIT_A),
563
+ artifactIdentity,
477
564
  roots: activation.resolveComponentRoots(env),
478
565
  states,
479
566
  }),
@@ -518,21 +605,22 @@ function drive(
518
605
  const emptiedDirSeen = treeDigest(oracleRoot) !== oracleBase;
519
606
  const oracleHonest = sameTree && sameLengthEditSeen && restored && modeSeen && emptiedDirSeen;
520
607
 
521
- // (a) a SOURCE switch: the committed lock would now name npm over a checkout-sourced activation.
608
+ // (a) a SOURCE switch: the committed lock would name checkout over the active npm runtime.
522
609
  // (a) is asked of the SHARED authority directly: the runner reads its lock from the committed
523
610
  // file, and this gate does not add a seam that would let any caller choose the source.
524
611
  const src = seeded("plan-source", ["pi"]);
525
612
  const srcBefore = snapshot(src);
526
613
  const srcRefusal = refusalOf(() =>
527
614
  runner.certifyActivationPlan(src, {
528
- lock: { source: "npm", name: PACKAGE, version: "0.21.0", integrity: "sha512-x" },
615
+ lock: { source: "herdr-checkout", repository: "junghan0611/entwurf" },
529
616
  checkoutRoot: fixtureCheckoutRoot(),
530
617
  requested: ["pi"],
618
+ resolveCommit: () => COMMIT_A,
531
619
  }),
532
620
  );
533
621
  const srcUnchanged = unchanged(src, srcBefore);
534
622
 
535
- // (b) a new commit whose request DROPS a backend the ledger holds.
623
+ // (b) a changed npm integrity whose request DROPS a backend the ledger holds.
536
624
  const drop = seeded("plan-drop", ["pi", "claude-code"]);
537
625
  const dropBefore = snapshot(drop);
538
626
  let dropAcquired = 0;
@@ -541,6 +629,7 @@ function drive(
541
629
  dropAcquired++;
542
630
  return fixtureAcquire({ activate: "recorder", log: path.join(drop.HOME as string, "argv.log") })(args);
543
631
  },
632
+ readRuntimeLock: () => ({ ...FIXTURE_NPM_LOCK, integrity: FIXTURE_OTHER_INTEGRITY }),
544
633
  resolveCommit: () => COMMIT_B,
545
634
  });
546
635
 
@@ -549,7 +638,17 @@ function drive(
549
638
  const tornLedger = activation.resolveActivationLayout(torn).ledgerPath;
550
639
  fs.writeFileSync(
551
640
  tornLedger,
552
- `${JSON.stringify({ ...(JSON.parse(fs.readFileSync(tornLedger, "utf8")) as Record<string, unknown>), artifactIdentity: IDENTITY(COMMIT_B) }, null, 2)}\n`,
641
+ `${JSON.stringify(
642
+ {
643
+ ...(JSON.parse(fs.readFileSync(tornLedger, "utf8")) as Record<string, unknown>),
644
+ artifactIdentity: {
645
+ ...IDENTITY(COMMIT_B),
646
+ expectedIntegrity: FIXTURE_OTHER_INTEGRITY,
647
+ },
648
+ },
649
+ null,
650
+ 2,
651
+ )}\n`,
553
652
  );
554
653
  const tornBefore = snapshot(torn);
555
654
  let tornAcquired = 0;
@@ -561,14 +660,13 @@ function drive(
561
660
  resolveCommit: () => COMMIT_A,
562
661
  });
563
662
 
564
- // (d) the LEGAL case still passes: same source, new commit, request covers the ledger. The
565
- // authority is asked on the PRE-install state, which is the only state it is ever asked about.
663
+ // (d) the LEGAL case still passes: same exact npm source and lock, request covers the ledger.
664
+ // The authority is asked on the PRE-install state, which is the only state it is ever asked about.
566
665
  const legal = seeded("plan-legal", ["pi"]);
567
666
  const legalPlan = runner.certifyActivationPlan(legal, {
568
- lock: { source: "herdr-checkout", repository: "junghan0611/entwurf" },
569
- checkoutRoot: fixtureCheckoutRoot(),
667
+ lock: FIXTURE_NPM_LOCK,
668
+ checkoutRoot: REPO,
570
669
  requested: ["pi"],
571
- resolveCommit: () => COMMIT_B,
572
670
  });
573
671
  const legalDrive = drive(legal, listing({ pi: "current (v8) (/home/u/.pi)" }), {
574
672
  acquire: fixtureAcquire({ activate: "recorder", log: path.join(legal.HOME as string, "argv.log") }),
@@ -577,7 +675,7 @@ function drive(
577
675
 
578
676
  ok(
579
677
  "[QK:HPB-PRE-BOOTSTRAP-AUTHORITY] the activation authority is asked BEFORE any runtime work, through the SAME " +
580
- "shipped functions the installed verb runs: a source switch, a new commit whose request drops an activated " +
678
+ "shipped functions the installed verb runs: a source switch, a request that drops an activated " +
581
679
  "backend, and a ledger that already disagrees with the runtime standing there are each refused with the " +
582
680
  "runtime tree, its journal, our cache, the ledger and the activation log ALL byte-identical and the " +
583
681
  "acquisition never called. The first cut bootstrapped first and let the installed verb refuse afterwards, " +
@@ -596,7 +694,7 @@ function drive(
596
694
  tornAcquired === 0 &&
597
695
  unchanged(torn, tornBefore) &&
598
696
  legalDrive.code === 0 &&
599
- legalPlan.disposition === "rebind",
697
+ legalPlan.disposition === "match",
600
698
  );
601
699
  }
602
700
 
@@ -607,15 +705,19 @@ function drive(
607
705
  const commits = [COMMIT_A, COMMIT_B, COMMIT_B];
608
706
  let call = 0;
609
707
  const moving = () => commits[Math.min(call++, commits.length - 1)] as string;
708
+ // Candidate source is a closed, retained branch. This test seam does not expose a caller input:
709
+ // production `runBuild` reads only the committed lock, while the gate drives the branch whose
710
+ // identity can move between D1 and D2.
610
711
  const drifted = drive(env, listing({ pi: "current (v8) (/home/u/.pi)" }), {
611
712
  acquire: fixtureAcquire({ activate: "recorder", log }),
713
+ readRuntimeLock: () => FIXTURE_CHECKOUT_LOCK,
612
714
  resolveCommit: moving,
613
715
  });
614
716
  const journal = JSON.parse(fs.readFileSync(journalPathOf(env), "utf8")) as { artifactIdentity: { commit: string } };
615
717
  const activated = fs.existsSync(log) ? fs.readFileSync(log, "utf8").trim() : "";
616
718
  ok(
617
719
  "[QK:HPB-BOOTSTRAP-IDENTITY-EXACT] the artifact that lands must be EXACTLY the one the authority check admitted: " +
618
- "when the source moves between the judgement and the install, the run refuses by name instead of handing the " +
720
+ "when the candidate source moves between the judgement and the install, the run refuses by name instead of handing the " +
619
721
  "installed activation verb a different artifact than the one this build was cleared to place — the verb would " +
620
722
  "then re-judge, and pass or fail on a question nobody asked. The refusal is honest about what did happen: the " +
621
723
  `runtime was replaced, and NO activation ran (refusal=${drifted.refusal} landed=${journal.artifactIdentity.commit.slice(0, 8)} admitted=${COMMIT_A.slice(0, 8)} activations=${JSON.stringify(activated)})`,
@@ -709,7 +811,7 @@ function drive(
709
811
  ok(
710
812
  "[QK:HPB-PROGRESS-NAMED-SEQUENCE] a build narrates the five steps IN ORDER and names the long one — herdr pipes " +
711
813
  "both of this process's streams into a buffer it DISCARDS on success (`src/cli/plugin.rs:1328-1373` @ c77af189), " +
712
- "so an operator who has just answered the install prompt sees nothing at all through a multi-minute `npm pack` " +
814
+ "so an operator who has just answered the install prompt sees nothing at all through a multi-minute registry fetch " +
713
815
  "and reads it as a hang. The sequence is reported, not logged: each step names the work about to start, the " +
714
816
  "acquisition step says out loud that silence is expected and which source it is reaching for, and a run with " +
715
817
  "nothing to activate takes exactly ONE step and then closes — it must not narrate work it never did. " +
@@ -721,7 +823,7 @@ function drive(
721
823
  full.progress[0].includes("integration status") &&
722
824
  full.progress[1].includes("pi, claude-code") &&
723
825
  longStep.includes("long step") &&
724
- longStep.includes(COMMIT_A.slice(0, 8)) &&
826
+ longStep.includes(`${PACKAGE}@${FIXTURE_VERSION}`) &&
725
827
  full.progress[3].includes("what landed") &&
726
828
  full.progress[4].includes("wiring pi, claude-code") &&
727
829
  full.progress[5].startsWith("done: ") &&