@akagilnc/pi-workflow-roles 0.1.3652 → 0.1.3661

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.
@@ -1116,8 +1116,8 @@ var init_durable_principal = __esm({
1116
1116
  async isAvailable(principal) {
1117
1117
  const { sessionFile } = this.decode(principal);
1118
1118
  try {
1119
- const stat2 = await lstat(sessionFile);
1120
- return stat2.isFile() && !stat2.isSymbolicLink();
1119
+ const stat3 = await lstat(sessionFile);
1120
+ return stat3.isFile() && !stat3.isSymbolicLink();
1121
1121
  } catch {
1122
1122
  return false;
1123
1123
  }
@@ -4636,21 +4636,38 @@ async function findLatestRunIdForSeatTicket(input) {
4636
4636
  }
4637
4637
  return best;
4638
4638
  }
4639
+ async function collectBookRunTicketNumbers(input) {
4640
+ const ledgerHome = resolveActivationLedgerHome(input.home);
4641
+ const runsDir = join11(
4642
+ activationBookDirectory(ledgerHome, input.bookKey),
4643
+ "runs"
4644
+ );
4645
+ let entries;
4646
+ try {
4647
+ entries = await readdir2(runsDir);
4648
+ } catch (error) {
4649
+ if (errorCodeOf2(error) === "ENOENT") return /* @__PURE__ */ new Set();
4650
+ throw error;
4651
+ }
4652
+ const known = /* @__PURE__ */ new Set();
4653
+ for (const entry of entries) {
4654
+ const ticketNumber = await readRunTicketNumber(join11(runsDir, entry));
4655
+ if (ticketNumber !== void 0) known.add(ticketNumber);
4656
+ }
4657
+ return known;
4658
+ }
4639
4659
  function parsePersistedTicketIdentity(record4) {
4640
4660
  const correlationId = typeof record4.correlationId === "string" && record4.correlationId.trim() !== "" ? record4.correlationId : void 0;
4641
4661
  const ticketNumber = typeof record4.ticketNumber === "number" && Number.isSafeInteger(record4.ticketNumber) && record4.ticketNumber >= 1 ? record4.ticketNumber : void 0;
4642
- const ticketResolution = record4.ticketResolution === "true-unbound" ? "true-unbound" : void 0;
4643
4662
  return {
4644
4663
  ...correlationId === void 0 ? {} : { correlationId },
4645
- ...ticketNumber === void 0 ? {} : { ticketNumber },
4646
- ...ticketResolution === void 0 ? {} : { ticketResolution }
4664
+ ...ticketNumber === void 0 ? {} : { ticketNumber }
4647
4665
  };
4648
4666
  }
4649
4667
  function restoredTicketFields(fields) {
4650
4668
  return {
4651
4669
  ...fields.correlationId === void 0 ? {} : { correlationId: fields.correlationId },
4652
- ...fields.ticketNumber === void 0 ? {} : { ticketNumber: fields.ticketNumber },
4653
- ...fields.ticketResolution === void 0 ? {} : { ticketResolution: fields.ticketResolution }
4670
+ ...fields.ticketNumber === void 0 ? {} : { ticketNumber: fields.ticketNumber }
4654
4671
  };
4655
4672
  }
4656
4673
  async function loadResumableRunRecord(home, runId, authority) {
@@ -4686,7 +4703,6 @@ async function loadResumableRunRecord(home, runId, authority) {
4686
4703
  let derived;
4687
4704
  let correlationId;
4688
4705
  let ticketNumber;
4689
- let ticketResolution;
4690
4706
  let prNumber;
4691
4707
  let repository;
4692
4708
  let repositoryDisplay;
@@ -4800,7 +4816,6 @@ async function loadResumableRunRecord(home, runId, authority) {
4800
4816
  const fromAdmitted = parsePersistedTicketIdentity(record4);
4801
4817
  correlationId = fromAdmitted.correlationId;
4802
4818
  ticketNumber = fromAdmitted.ticketNumber;
4803
- ticketResolution = fromAdmitted.ticketResolution;
4804
4819
  }
4805
4820
  } catch (error) {
4806
4821
  if (error instanceof CliUsageError) throw error;
@@ -4823,13 +4838,10 @@ async function loadResumableRunRecord(home, runId, authority) {
4823
4838
  ...typeof rec.thinking === "string" ? { thinking: rec.thinking } : {}
4824
4839
  };
4825
4840
  }
4826
- if (correlationId === void 0 || ticketNumber === void 0 || ticketResolution === void 0) {
4841
+ if (correlationId === void 0 || ticketNumber === void 0) {
4827
4842
  const fromInvocation = parsePersistedTicketIdentity(rec);
4828
4843
  if (correlationId === void 0) correlationId = fromInvocation.correlationId;
4829
4844
  if (ticketNumber === void 0) ticketNumber = fromInvocation.ticketNumber;
4830
- if (ticketResolution === void 0) {
4831
- ticketResolution = fromInvocation.ticketResolution;
4832
- }
4833
4845
  }
4834
4846
  }
4835
4847
  } catch (error) {
@@ -4859,7 +4871,6 @@ async function loadResumableRunRecord(home, runId, authority) {
4859
4871
  ...derived === void 0 ? {} : { derived },
4860
4872
  ...correlationId === void 0 ? {} : { correlationId },
4861
4873
  ...ticketNumber === void 0 ? {} : { ticketNumber },
4862
- ...ticketResolution === void 0 ? {} : { ticketResolution },
4863
4874
  ...prNumber === void 0 ? {} : { prNumber },
4864
4875
  ...repository === void 0 ? {} : { repository },
4865
4876
  ...repositoryDisplay === void 0 ? {} : { repositoryDisplay },
@@ -5031,16 +5042,16 @@ async function requireRunDirectory(candidate, display) {
5031
5042
  { cause: error }
5032
5043
  );
5033
5044
  }
5034
- let stat2;
5045
+ let stat3;
5035
5046
  try {
5036
- stat2 = await lstat2(real);
5047
+ stat3 = await lstat2(real);
5037
5048
  } catch (error) {
5038
5049
  throw new NotarySourceRunError(
5039
5050
  `notary --source-run is not a readable run directory: ${display}`,
5040
5051
  { cause: error }
5041
5052
  );
5042
5053
  }
5043
- if (!stat2.isDirectory()) {
5054
+ if (!stat3.isDirectory()) {
5044
5055
  throw new NotarySourceRunError(
5045
5056
  `notary --source-run must be a run directory: ${display}`
5046
5057
  );
@@ -6182,7 +6193,6 @@ __export(invocation_exports, {
6182
6193
  recordEffectiveInvocationModel: () => recordEffectiveInvocationModel,
6183
6194
  recordLaunchedPiIdentity: () => recordLaunchedPiIdentity,
6184
6195
  recordLaunchedRolePackageIdentity: () => recordLaunchedRolePackageIdentity,
6185
- recordTrueUnboundTicketResolution: () => recordTrueUnboundTicketResolution,
6186
6196
  requireAuthorityRef: () => requireAuthorityRef,
6187
6197
  resolveDoctorCaseRunsPath: () => resolveDoctorCaseRunsPath,
6188
6198
  resolveGitHubRemoteRepository: () => resolveGitHubRemoteRepository
@@ -6317,11 +6327,6 @@ async function bindAdmittedTicketNumber(admitted, ticketNumber) {
6317
6327
  if (!Number.isSafeInteger(ticketNumber) || ticketNumber < 1) {
6318
6328
  throw new Error(`bindAdmittedTicketNumber requires a safe positive integer, got ${String(ticketNumber)}`);
6319
6329
  }
6320
- if (admitted.ticketResolution === "true-unbound") {
6321
- throw new Error(
6322
- "bindAdmittedTicketNumber refuses to replace durable true-unbound ticket resolution"
6323
- );
6324
- }
6325
6330
  if (admitted.ticketNumber !== void 0) {
6326
6331
  if (admitted.ticketNumber === ticketNumber) return;
6327
6332
  throw new Error(
@@ -6339,26 +6344,6 @@ async function bindAdmittedTicketNumber(admitted, ticketNumber) {
6339
6344
  "utf8"
6340
6345
  );
6341
6346
  }
6342
- async function recordTrueUnboundTicketResolution(admitted) {
6343
- if (admitted.ticketNumber !== void 0) {
6344
- throw new Error(
6345
- `recordTrueUnboundTicketResolution refuses to overwrite ticket #${admitted.ticketNumber}`
6346
- );
6347
- }
6348
- if (admitted.ticketResolution === "true-unbound") return;
6349
- admitted.ticketResolution = "true-unbound";
6350
- await mergeInvocationIdentityPage(admitted.runDirectory, {
6351
- ticketResolution: "true-unbound"
6352
- });
6353
- const admittedPath = admitted.admittedRequestPath;
6354
- const current = JSON.parse(await readFile9(admittedPath, "utf8"));
6355
- await writeFile4(
6356
- admittedPath,
6357
- `${JSON.stringify({ ...current, ticketResolution: "true-unbound" }, null, 2)}
6358
- `,
6359
- "utf8"
6360
- );
6361
- }
6362
6347
  async function recordLaunchedPiIdentity(runDirectory, identity) {
6363
6348
  await mergeInvocationIdentityPage(runDirectory, {
6364
6349
  piExecutable: identity.executable,
@@ -9270,859 +9255,253 @@ var init_config = __esm({
9270
9255
  }
9271
9256
  });
9272
9257
 
9273
- // src/diarist-ticket-resolution.ts
9274
- import { existsSync as existsSync5, readFileSync as readFileSync2 } from "node:fs";
9275
- import { join as join16 } from "node:path";
9276
- import { fileURLToPath } from "node:url";
9277
- function resolveDiaristResolveTicketMethodPath(packageRoot = fileURLToPath(new URL("..", import.meta.url))) {
9278
- return join16(packageRoot, DIARIST_RESOLVE_TICKET_METHOD_RELATIVE);
9279
- }
9280
- function instructionContainsTicketNumber(instruction, ticketNumber) {
9281
- if (!Number.isSafeInteger(ticketNumber) || ticketNumber < 1) return false;
9282
- return new RegExp(`(?<!\\d)${String(ticketNumber)}(?!\\d)`).test(instruction);
9283
- }
9284
- function parseDiaristTicketResolverStdout(stdout) {
9285
- const trimmed = stdout.trim();
9286
- if (trimmed.length === 0) {
9287
- throw new DiaristTicketResolutionError(
9288
- "empty-stdout",
9289
- "diarist ticket resolver stdout is empty"
9290
- );
9291
- }
9292
- let parsed;
9293
- try {
9294
- parsed = JSON.parse(trimmed);
9295
- } catch (error) {
9296
- throw new DiaristTicketResolutionError(
9297
- "unparseable-json",
9298
- "diarist ticket resolver stdout is not JSON",
9299
- { cause: error }
9300
- );
9301
- }
9302
- if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
9303
- throw new DiaristTicketResolutionError(
9304
- "not-object",
9305
- "diarist ticket resolver stdout must be one JSON object"
9306
- );
9307
- }
9308
- const record4 = parsed;
9309
- if (!Object.prototype.hasOwnProperty.call(record4, "assertion")) {
9310
- throw new DiaristTicketResolutionError(
9311
- "assertion-missing",
9312
- "diarist ticket resolver stdout missing assertion"
9313
- );
9258
+ // src/ticket-provenance-contracts.ts
9259
+ function isRecord11(value) {
9260
+ return typeof value === "object" && value !== null && !Array.isArray(value);
9261
+ }
9262
+ function projectTicketProvenanceDiagnostic(value) {
9263
+ if (!isRecord11(value)) return void 0;
9264
+ if (value.recordClass !== TICKET_PROVENANCE_RECORD_CLASS_DIAGNOSTIC) {
9265
+ return void 0;
9314
9266
  }
9315
- if (record4.assertion === "true-unbound") return { kind: "true-unbound" };
9316
- const n = record4.ticketNumber;
9317
- if (record4.assertion === "ticket" && typeof n === "number" && Number.isSafeInteger(n) && n >= 1) {
9318
- return { kind: "ticket", ticketNumber: n };
9267
+ if (typeof value.diagnosticKind !== "string" || !DIAGNOSTIC_KINDS.has(value.diagnosticKind)) {
9268
+ return void 0;
9319
9269
  }
9320
- throw new DiaristTicketResolutionError(
9321
- "assertion-uninterpretable",
9322
- "diarist ticket resolver assertion is not ticket|true-unbound with safe ticketNumber"
9323
- );
9324
- }
9325
- function createHermesDiaristTicketResolver(options = {}) {
9326
- const methodPath = resolveDiaristResolveTicketMethodPath(options.packageRoot);
9327
- if (!existsSync5(methodPath)) {
9328
- throw new Error(`diarist resolve-ticket method material missing (${methodPath})`);
9270
+ if (typeof value.cause !== "string" || value.cause.length === 0) {
9271
+ return void 0;
9329
9272
  }
9330
- const method = readFileSync2(methodPath, "utf8");
9331
- if (method.trim().length === 0) {
9332
- throw new Error(`diarist resolve-ticket method material is empty (${methodPath})`);
9273
+ if (typeof value.recordedAt !== "string" || value.recordedAt.length === 0) {
9274
+ return void 0;
9333
9275
  }
9334
- const executable = options.executable ?? "hermes";
9335
- return async (input) => {
9336
- const argv = [
9337
- executable,
9338
- "chat",
9339
- "--query-file",
9340
- ENGINE_DETOUR_STAGED_PROMPT_TOKEN,
9341
- "-Q",
9342
- "--no-restore-cwd",
9343
- "--ignore-rules",
9344
- "-t",
9345
- HERMES_RESOLVER_TOOLSET
9346
- ];
9347
- let result;
9348
- try {
9349
- result = await runEngineDetourOnce({
9350
- argv,
9351
- stagedPrompt: JSON.stringify({ method, instruction: input.instruction }),
9352
- cwd: options.cwd ?? process.cwd(),
9353
- ...options.env === void 0 ? {} : { env: options.env },
9354
- ...input.signal === void 0 ? {} : { signal: input.signal }
9355
- });
9356
- } catch (error) {
9357
- throw new DiaristTicketResolutionError(
9358
- "engine-failed",
9359
- "diarist ticket resolver engine failed to launch",
9360
- { cause: error }
9361
- );
9362
- }
9363
- if (result.code !== 0) {
9364
- throw new DiaristTicketResolutionError(
9365
- "engine-failed",
9366
- `diarist ticket resolver engine exited ${result.code}: ${result.stderr.slice(0, 500)}`
9367
- );
9368
- }
9369
- return parseDiaristTicketResolverStdout(result.stdout);
9370
- };
9371
- }
9372
- function createGhTicketExistenceChecker(options) {
9373
- const runner = options?.runner ?? createGhApiRunner();
9374
- return async (input) => {
9375
- const projected = await projectGhIssueBody(runner, {
9376
- owner: input.owner,
9377
- repo: input.repo,
9378
- ticketNumber: input.ticketNumber,
9379
- ...input.signal === void 0 ? {} : { signal: input.signal }
9380
- });
9381
- if (projected.status === "available") return true;
9382
- if (projected.status === "unavailable" && projected.reason === "http-non-2xx" && projected.httpStatus === 404) {
9383
- return false;
9384
- }
9385
- if (projected.status === "unavailable" && projected.reason === "pull-request") {
9386
- throw new DiaristTicketResolutionError(
9387
- "ticket-is-pull-request",
9388
- `ticket #${input.ticketNumber} resolves to a pull request, not an issue`,
9389
- { cause: projected }
9390
- );
9391
- }
9392
- if (projected.status === "unavailable") {
9393
- throw new DiaristTicketResolutionError(
9394
- "ticket-unavailable",
9395
- `ticket verification unavailable for ${input.owner}/${input.repo}#${input.ticketNumber}`,
9396
- { cause: projected }
9397
- );
9398
- }
9399
- throw new DiaristTicketResolutionError(
9400
- "ticket-invalid",
9401
- `ticket verification returned an invalid issue payload for ${input.owner}/${input.repo}#${input.ticketNumber}`,
9402
- { cause: projected }
9403
- );
9276
+ return {
9277
+ recordClass: TICKET_PROVENANCE_RECORD_CLASS_DIAGNOSTIC,
9278
+ diagnosticKind: value.diagnosticKind,
9279
+ cause: value.cause,
9280
+ recordedAt: value.recordedAt,
9281
+ ...typeof value.reason === "string" ? { reason: value.reason } : {}
9404
9282
  };
9405
9283
  }
9406
- async function verifyDiaristTicketAssertion(input) {
9407
- if (input.assertion.kind === "true-unbound") return input.assertion;
9408
- const n = input.assertion.ticketNumber;
9409
- if (!instructionContainsTicketNumber(input.instruction, n)) {
9410
- throw new DiaristTicketResolutionError(
9411
- "number-not-in-instruction",
9412
- `diarist ticket assertion #${n} complete decimal number does not appear in accepted instruction`
9413
- );
9414
- }
9415
- if (input.origin === void 0) {
9416
- throw new DiaristTicketResolutionError(
9417
- "origin-unresolved",
9418
- `diarist ticket assertion #${n} requires a resolvable github.com origin remote`
9419
- );
9284
+ function projectTicketProvenanceEntry(value) {
9285
+ if (!isRecord11(value)) return void 0;
9286
+ if (value.recordClass === TICKET_PROVENANCE_RECORD_CLASS_DIAGNOSTIC) {
9287
+ return void 0;
9420
9288
  }
9421
- let exists;
9422
- try {
9423
- exists = await input.checkExistence({
9424
- owner: input.origin.owner,
9425
- repo: input.origin.repo,
9426
- ticketNumber: n,
9427
- ...input.signal === void 0 ? {} : { signal: input.signal }
9428
- });
9429
- } catch (error) {
9430
- if (error instanceof DiaristTicketResolutionError) throw error;
9431
- throw new DiaristTicketResolutionError(
9432
- "ticket-unavailable",
9433
- `diarist ticket assertion #${n} live verification failed`,
9434
- { cause: error }
9435
- );
9289
+ if (!isRecord11(value.basis)) return void 0;
9290
+ if (typeof value.basis.method !== "string" || !BASIS_METHODS.has(value.basis.method)) {
9291
+ return void 0;
9436
9292
  }
9437
- if (!exists) {
9438
- throw new DiaristTicketResolutionError(
9439
- "ticket-missing",
9440
- `diarist ticket assertion #${n} does not exist as a live issue on ${input.origin.owner}/${input.origin.repo}`
9441
- );
9293
+ if (typeof value.sourceKind !== "string" || !SOURCE_KINDS.has(value.sourceKind)) {
9294
+ return void 0;
9442
9295
  }
9443
- return input.assertion;
9444
- }
9445
- async function resolveDiaristTicketFromInstruction(input) {
9446
- const assertion = await input.resolver({
9447
- instruction: input.instruction,
9448
- ...input.signal === void 0 ? {} : { signal: input.signal }
9449
- });
9450
- return verifyDiaristTicketAssertion({
9451
- assertion,
9452
- instruction: input.instruction,
9453
- origin: input.origin,
9454
- checkExistence: input.checkExistence,
9455
- ...input.signal === void 0 ? {} : { signal: input.signal }
9456
- });
9457
- }
9458
- var DIARIST_RESOLVE_TICKET_METHOD_RELATIVE, DiaristTicketResolutionError, HERMES_RESOLVER_TOOLSET;
9459
- var init_diarist_ticket_resolution = __esm({
9460
- "src/diarist-ticket-resolution.ts"() {
9461
- "use strict";
9462
- init_collector_github();
9463
- init_engine_detour();
9464
- DIARIST_RESOLVE_TICKET_METHOD_RELATIVE = "resources/diarist-resolve-ticket.md";
9465
- DiaristTicketResolutionError = class extends Error {
9466
- code = "diarist-ticket-resolution";
9467
- reason;
9468
- constructor(reason, message, options) {
9469
- super(message, options);
9470
- this.name = "DiaristTicketResolutionError";
9471
- this.reason = reason;
9472
- }
9473
- };
9474
- HERMES_RESOLVER_TOOLSET = "context_engine";
9296
+ if (!isRecord11(value.sourceRef)) return void 0;
9297
+ if (typeof value.transcript !== "string" || value.transcript.length === 0) {
9298
+ return void 0;
9475
9299
  }
9476
- });
9477
-
9478
- // src/adr-path-refs.ts
9479
- function extractReferencedAdrPaths(text) {
9480
- const seen = /* @__PURE__ */ new Set();
9481
- const paths = [];
9482
- for (const match of text.matchAll(ADR_PATH_IN_BODY)) {
9483
- const path = match[0];
9484
- if (seen.has(path)) continue;
9485
- seen.add(path);
9486
- paths.push(path);
9300
+ if (typeof value.timestamp !== "string" || value.timestamp.length === 0) {
9301
+ return void 0;
9487
9302
  }
9488
- return Object.freeze(paths);
9303
+ const basis = {
9304
+ method: value.basis.method,
9305
+ ...Array.isArray(value.basis.anchors) ? {
9306
+ anchors: value.basis.anchors.filter(
9307
+ (item) => typeof item === "string"
9308
+ )
9309
+ } : {},
9310
+ ...typeof value.basis.note === "string" ? { note: value.basis.note } : {}
9311
+ };
9312
+ const sourceRef = {
9313
+ ...typeof value.sourceRef.sessionFile === "string" ? { sessionFile: value.sourceRef.sessionFile } : {},
9314
+ ...typeof value.sourceRef.entryId === "string" || typeof value.sourceRef.entryId === "number" ? { entryId: value.sourceRef.entryId } : {},
9315
+ ...typeof value.sourceRef.path === "string" ? { path: value.sourceRef.path } : {},
9316
+ ...typeof value.sourceRef.url === "string" ? { url: value.sourceRef.url } : {}
9317
+ };
9318
+ return {
9319
+ basis,
9320
+ sourceKind: value.sourceKind,
9321
+ sourceRef,
9322
+ transcript: value.transcript,
9323
+ timestamp: value.timestamp
9324
+ };
9489
9325
  }
9490
- var ADR_PATH_IN_BODY;
9491
- var init_adr_path_refs = __esm({
9492
- "src/adr-path-refs.ts"() {
9326
+ var TICKET_PROVENANCE_KIND, TICKET_PROVENANCE_HUMAN_VIEW, TICKET_PROVENANCE_OFFERED_WATERMARK, TICKET_PROVENANCE_RECORD_CLASS_DIAGNOSTIC, SOURCE_KINDS, BASIS_METHODS, DIAGNOSTIC_KINDS;
9327
+ var init_ticket_provenance_contracts = __esm({
9328
+ "src/ticket-provenance-contracts.ts"() {
9493
9329
  "use strict";
9494
- ADR_PATH_IN_BODY = /docs\/adr\/(?:[A-Za-z0-9][A-Za-z0-9._-]*\/)*[A-Za-z0-9][A-Za-z0-9._-]*\.md/g;
9330
+ TICKET_PROVENANCE_KIND = "ticket-provenance";
9331
+ TICKET_PROVENANCE_HUMAN_VIEW = "\u8D77\u5C45\u5F55.md";
9332
+ TICKET_PROVENANCE_OFFERED_WATERMARK = "offered-identities.jsonl";
9333
+ TICKET_PROVENANCE_RECORD_CLASS_DIAGNOSTIC = "diagnostic";
9334
+ SOURCE_KINDS = /* @__PURE__ */ new Set([
9335
+ "cc-session",
9336
+ "issue-body-comment",
9337
+ "adr-decision-key",
9338
+ "ticket-decree-block"
9339
+ ]);
9340
+ BASIS_METHODS = /* @__PURE__ */ new Set(["llm-semantic"]);
9341
+ DIAGNOSTIC_KINDS = /* @__PURE__ */ new Set([
9342
+ "collector-failed",
9343
+ "issue-source-failed",
9344
+ "quote-verify-failed"
9345
+ ]);
9495
9346
  }
9496
9347
  });
9497
9348
 
9498
- // src/diarist-mechanical.ts
9499
- function extractCornerQuotes(text, minLength = DEFAULT_QUOTE_MIN) {
9500
- const out = [];
9501
- const re = /「([^」]+)」/g;
9502
- let match;
9503
- while ((match = re.exec(text)) !== null) {
9504
- const q = match[1].trim();
9505
- if (q.length >= minLength) out.push(q);
9349
+ // src/ticket-provenance.ts
9350
+ import { createHash as createHash5 } from "node:crypto";
9351
+ import { appendFileSync as appendFileSync2, existsSync as existsSync5, mkdirSync as mkdirSync3, readFileSync as readFileSync2, writeFileSync as writeFileSync3 } from "node:fs";
9352
+ import { join as join16 } from "node:path";
9353
+ function ticketProvenanceSubject(ticketNumber) {
9354
+ if (!Number.isSafeInteger(ticketNumber) || ticketNumber < 1) {
9355
+ throw new Error(`ticket-provenance subject requires a positive ticket number, got ${String(ticketNumber)}`);
9506
9356
  }
9507
- return out;
9357
+ return String(ticketNumber);
9508
9358
  }
9509
- function buildDiaristAnchors(input) {
9510
- const fromBody = input.ticketBody === void 0 ? [] : extractCornerQuotes(input.ticketBody);
9511
- const quotes = [...fromBody, ...input.extraQuotes ?? []];
9512
- const seen = /* @__PURE__ */ new Set();
9513
- const uniqueQuotes = [];
9514
- for (const q of quotes) {
9515
- if (seen.has(q)) continue;
9516
- seen.add(q);
9517
- uniqueQuotes.push(q);
9518
- }
9519
- return {
9359
+ function ticketProvenanceEntryIdentity(input) {
9360
+ const ref = input.sourceRef;
9361
+ const refKey = [
9362
+ ref.sessionFile ?? "",
9363
+ ref.entryId === void 0 ? "" : String(ref.entryId),
9364
+ ref.path ?? "",
9365
+ ref.url ?? ""
9366
+ ].join("");
9367
+ const material = [
9368
+ String(input.ticketNumber),
9369
+ input.sourceKind,
9370
+ refKey,
9371
+ input.transcript
9372
+ ].join("\0");
9373
+ return createHash5("sha256").update(material, "utf8").digest("hex");
9374
+ }
9375
+ function appendTicketProvenanceEntry(input) {
9376
+ const subject = ticketProvenanceSubject(input.ticketNumber);
9377
+ const identity = ticketProvenanceEntryIdentity({
9520
9378
  ticketNumber: input.ticketNumber,
9521
- quotes: uniqueQuotes
9522
- };
9379
+ sourceKind: input.entry.sourceKind,
9380
+ sourceRef: input.entry.sourceRef,
9381
+ transcript: input.entry.transcript
9382
+ });
9383
+ return sitianReport({
9384
+ level: "event",
9385
+ kind: TICKET_PROVENANCE_KIND,
9386
+ identity,
9387
+ subject,
9388
+ cwd: input.cwd,
9389
+ ...input.home === void 0 ? {} : { home: input.home },
9390
+ host: input.host ?? "diarist",
9391
+ source: input.source ?? "diarist",
9392
+ payload: input.entry,
9393
+ raw: input.entry.sourceRef.sessionFile !== void 0 && input.entry.sourceRef.entryId !== void 0 ? {
9394
+ sessionFile: input.entry.sourceRef.sessionFile,
9395
+ entryId: input.entry.sourceRef.entryId
9396
+ } : void 0
9397
+ });
9523
9398
  }
9524
- function verifyQuotesVerbatim(sourceText, quotes) {
9525
- const failed2 = [];
9526
- for (const q of quotes) {
9527
- if (q.length === 0) continue;
9528
- if (!sourceText.includes(q)) failed2.push(q);
9529
- }
9530
- if (failed2.length === 0) return { ok: true };
9531
- return { ok: false, failedQuotes: failed2 };
9532
- }
9533
- function blockToLlmEntry(block, input) {
9534
- const verify = verifyQuotesVerbatim(block.transcript, input.quotes);
9535
- if (!verify.ok) {
9536
- return {
9537
- ok: false,
9538
- failedQuotes: verify.failedQuotes,
9539
- cause: `verbatim verify failed: ${verify.failedQuotes.join(" | ")}`
9540
- };
9541
- }
9542
- const anchorNotes = [`#${input.anchors.ticketNumber}`];
9543
- const seen = new Set(anchorNotes);
9544
- for (const q of [...input.anchors.quotes, ...input.quotes]) {
9545
- if (seen.has(q)) continue;
9546
- seen.add(q);
9547
- anchorNotes.push(q);
9548
- if (anchorNotes.length >= 12) break;
9549
- }
9399
+ function resolveTicketProvenanceVolume(ticketNumber, cwd, home) {
9400
+ const path = resolveSitianRecordPath({
9401
+ level: "event",
9402
+ kind: TICKET_PROVENANCE_KIND,
9403
+ subject: ticketProvenanceSubject(ticketNumber),
9404
+ cwd,
9405
+ ...home === void 0 ? {} : { home }
9406
+ });
9550
9407
  return {
9551
- ok: true,
9552
- entry: {
9553
- basis: {
9554
- method: "llm-semantic",
9555
- anchors: anchorNotes,
9556
- ...input.note === void 0 ? {} : { note: input.note }
9557
- },
9558
- sourceKind: block.sourceKind,
9559
- sourceRef: block.sourceRef,
9560
- transcript: block.transcript,
9561
- timestamp: block.timestamp
9562
- }
9408
+ recordFile: path.recordFile,
9409
+ volumeDir: path.sessionDir,
9410
+ humanViewFile: join16(path.sessionDir, TICKET_PROVENANCE_HUMAN_VIEW),
9411
+ offeredWatermarkFile: join16(path.sessionDir, TICKET_PROVENANCE_OFFERED_WATERMARK)
9563
9412
  };
9564
9413
  }
9565
- var DEFAULT_QUOTE_MIN;
9566
- var init_diarist_mechanical = __esm({
9567
- "src/diarist-mechanical.ts"() {
9568
- "use strict";
9569
- init_activation_ledger_topology();
9570
- DEFAULT_QUOTE_MIN = 6;
9414
+ function readOfferedIdentities(ticketNumber, cwd, home) {
9415
+ const { offeredWatermarkFile } = resolveTicketProvenanceVolume(ticketNumber, cwd, home);
9416
+ if (!existsSync5(offeredWatermarkFile)) return /* @__PURE__ */ new Set();
9417
+ let text;
9418
+ try {
9419
+ text = readFileSync2(offeredWatermarkFile, "utf8");
9420
+ } catch (error) {
9421
+ throw new TicketProvenanceWatermarkError(
9422
+ "unreadable",
9423
+ `ticket-provenance offered watermark unreadable (${offeredWatermarkFile})`,
9424
+ { cause: error }
9425
+ );
9571
9426
  }
9572
- });
9573
-
9574
- // src/reviewer-git-snapshot.ts
9575
- function parseReviewerRefSnapshot(raw) {
9576
- const refs = {};
9577
- for (const line2 of raw.split("\n")) {
9578
- if (!line2) continue;
9579
- const fields = line2.split("\0");
9580
- if (fields.length !== 5 || !fields[0] || !fields[1] || !fields[3]) {
9581
- throw new Error(`Malformed Git ref snapshot line: ${line2}`);
9427
+ const seen = /* @__PURE__ */ new Set();
9428
+ const lines = text.split("\n");
9429
+ for (let index = 0; index < lines.length; index += 1) {
9430
+ const trimmed = lines[index].trim();
9431
+ if (!trimmed) continue;
9432
+ let parsed;
9433
+ try {
9434
+ parsed = JSON.parse(trimmed);
9435
+ } catch (error) {
9436
+ throw new TicketProvenanceWatermarkError(
9437
+ "malformed-json",
9438
+ `ticket-provenance offered watermark malformed JSON at line ${index + 1} (${offeredWatermarkFile})`,
9439
+ { cause: error }
9440
+ );
9582
9441
  }
9583
- const peeledCommitId = fields[3] === "commit" ? fields[1] : fields[4] === "commit" && fields[2] ? fields[2] : null;
9584
- refs[fields[0]] = Object.freeze({
9585
- objectId: fields[1],
9586
- peeledCommitId
9587
- });
9442
+ if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed) || typeof parsed.identity !== "string" || parsed.identity.length === 0) {
9443
+ throw new TicketProvenanceWatermarkError(
9444
+ "bad-shape",
9445
+ `ticket-provenance offered watermark bad shape at line ${index + 1} (${offeredWatermarkFile})`
9446
+ );
9447
+ }
9448
+ seen.add(parsed.identity);
9588
9449
  }
9589
- return refs;
9590
- }
9591
- function reviewerRefSnapshotArgs() {
9592
- return ["for-each-ref", "--format=%(refname)%00%(objectname)%00%(*objectname)%00%(objecttype)%00%(*objecttype)", ...REVIEW_REF_PREFIXES];
9593
- }
9594
- function immutableReviewerRefs(refs) {
9595
- return Object.freeze(Object.fromEntries(Object.entries(refs).sort(([a], [b]) => a.localeCompare(b)).map(([name, entry]) => [name, Object.freeze({ objectId: entry.objectId, peeledCommitId: entry.peeledCommitId })])));
9596
- }
9597
- function sameReviewerPinnedTarget(actual, expected) {
9598
- return actual.repositoryRoot === expected.repositoryRoot && actual.objectFormat === expected.objectFormat && actual.targetHead === expected.targetHead;
9450
+ return seen;
9599
9451
  }
9600
- var REVIEW_REF_PREFIXES;
9601
- var init_reviewer_git_snapshot = __esm({
9602
- "src/reviewer-git-snapshot.ts"() {
9603
- "use strict";
9604
- REVIEW_REF_PREFIXES = ["refs/heads", "refs/tags", "refs/remotes"];
9605
- }
9606
- });
9607
-
9608
- // src/reviewer-preflight-error.ts
9609
- var ReviewerCorrectablePreflightError;
9610
- var init_reviewer_preflight_error = __esm({
9611
- "src/reviewer-preflight-error.ts"() {
9612
- "use strict";
9613
- ReviewerCorrectablePreflightError = class extends Error {
9614
- constructor(code, diagnostic = `${code} constraint failed`, options) {
9615
- super(`${code}: ${diagnostic}`, options);
9616
- this.code = code;
9617
- this.diagnostic = diagnostic;
9618
- this.name = "ReviewerCorrectablePreflightError";
9619
- }
9620
- code;
9621
- diagnostic;
9622
- };
9623
- }
9624
- });
9625
-
9626
- // src/reviewer-pinned-git.ts
9627
- import { execFile as execFile3 } from "node:child_process";
9628
- import { access as access2, realpath as realpath6 } from "node:fs/promises";
9629
- import { promisify as promisify3 } from "node:util";
9630
- async function execGit(args, options) {
9631
- try {
9632
- return await execFileAsync3("git", args, {
9633
- ...options,
9634
- env: { ...process.env, LC_ALL: "C" }
9635
- });
9636
- } catch (error) {
9637
- const source = error;
9638
- const wrapped = new Error("git process failed", { cause: error });
9639
- Object.assign(wrapped, { code: source.code ?? null, signal: source.signal ?? null, timedOut: source.killed === true && source.signal === "SIGTERM", aborted: source.name === "AbortError", stderr: String(source.stderr ?? ""), stdout: String(source.stdout ?? "") });
9640
- throw wrapped;
9452
+ function recordOfferedIdentities(input) {
9453
+ if (input.identities.length === 0) return;
9454
+ const { volumeDir, offeredWatermarkFile } = resolveTicketProvenanceVolume(
9455
+ input.ticketNumber,
9456
+ input.cwd,
9457
+ input.home
9458
+ );
9459
+ const already = new Set(readOfferedIdentities(input.ticketNumber, input.cwd, input.home));
9460
+ const rows = [];
9461
+ for (const identity of input.identities) {
9462
+ if (identity.length === 0 || already.has(identity)) continue;
9463
+ rows.push(`${JSON.stringify({ identity })}
9464
+ `);
9465
+ already.add(identity);
9641
9466
  }
9467
+ if (rows.length === 0) return;
9468
+ mkdirSync3(volumeDir, { recursive: true });
9469
+ appendFileSync2(offeredWatermarkFile, rows.join(""), "utf8");
9642
9470
  }
9643
- function exitCode(error) {
9644
- const code = typeof error === "object" && error !== null ? error.code : void 0;
9645
- return typeof code === "number" ? code : void 0;
9646
- }
9647
- function gitStderr(error) {
9648
- if (typeof error !== "object" || error === null) return "";
9649
- const stderr = error.stderr;
9650
- return typeof stderr === "string" ? stderr : "";
9651
- }
9652
- function isConfirmedMissingOriginRemote(error) {
9653
- return /No such remote ['"]origin['"]/.test(gitStderr(error));
9654
- }
9655
- function isConfirmedPinnedPathAbsent(error, path) {
9656
- const stderr = gitStderr(error);
9657
- const quoted = `'${path}'`;
9658
- return stderr.includes(`path ${quoted} does not exist in `) || stderr.includes(`path ${quoted} exists on disk, but not in `);
9659
- }
9660
- async function repositoryIsAvailable(root) {
9661
- try {
9662
- await access2(`${root}/.git`);
9663
- return { available: true };
9664
- } catch (cause) {
9665
- return { available: false, cause };
9471
+ async function readTicketProvenance(ticketNumber, cwd, home) {
9472
+ const { recordFile } = resolveTicketProvenanceVolume(ticketNumber, cwd, home);
9473
+ const { records: records2 } = await readSitianRecords(recordFile);
9474
+ const entries = [];
9475
+ const diagnostics = [];
9476
+ let skipped = 0;
9477
+ for (const record4 of records2) {
9478
+ if (record4.kind !== TICKET_PROVENANCE_KIND) {
9479
+ skipped += 1;
9480
+ continue;
9481
+ }
9482
+ const diagnostic = projectTicketProvenanceDiagnostic(record4.payload);
9483
+ if (diagnostic !== void 0) {
9484
+ diagnostics.push(diagnostic);
9485
+ continue;
9486
+ }
9487
+ const entry = projectTicketProvenanceEntry(record4.payload);
9488
+ if (entry === void 0) {
9489
+ skipped += 1;
9490
+ continue;
9491
+ }
9492
+ entries.push(entry);
9666
9493
  }
9494
+ return { entries, diagnostics, records: records2, recordFile, skipped };
9667
9495
  }
9668
- function shortNameFromPinnedRef(refName) {
9669
- const short = refName.startsWith("refs/heads/") ? refName.slice("refs/heads/".length) : refName.startsWith("refs/tags/") ? refName.slice("refs/tags/".length) : refName.startsWith("refs/remotes/") ? refName.slice("refs/remotes/".length).replace(/^[^/]+\//, "") : refName;
9670
- const trimmed = short.trim();
9671
- return trimmed === "" ? void 0 : trimmed;
9672
- }
9673
- function branchNamesAtPinnedHead(pin) {
9674
- const names = /* @__PURE__ */ new Set();
9675
- for (const [refName, entry] of Object.entries(pin.refs)) {
9676
- if (entry.peeledCommitId !== pin.targetHead) continue;
9677
- if (!refName.startsWith("refs/heads/") && !refName.startsWith("refs/remotes/")) continue;
9678
- const short = shortNameFromPinnedRef(refName);
9679
- if (short !== void 0) names.add(short);
9496
+ function markdownFenceFor(text) {
9497
+ let longest = 0;
9498
+ const runs = text.match(/`+/g);
9499
+ if (runs !== null) {
9500
+ for (const run of runs) {
9501
+ if (run.length > longest) longest = run.length;
9502
+ }
9680
9503
  }
9681
- return Object.freeze([...names]);
9682
- }
9683
- async function gitText(root, args) {
9684
- const { stdout } = await execGit(["-C", root, ...args], { encoding: "utf8" });
9685
- return stdout.trim();
9686
- }
9687
- async function createReviewerPinnedGitReader(root = process.cwd()) {
9688
- const discoveredRoot = await gitText(root, ["rev-parse", "--show-toplevel"]);
9689
- const repositoryRoot = await realpath6(discoveredRoot);
9690
- const objectFormat = await gitText(repositoryRoot, ["rev-parse", "--show-object-format"]);
9691
- if (objectFormat !== "sha1" && objectFormat !== "sha256") throw new Error("Unsupported Git object format");
9692
- const oidWidth = objectFormat === "sha1" ? 40 : 64;
9693
- const targetHead = await gitText(repositoryRoot, ["rev-parse", "HEAD^{commit}"]);
9694
- const reachableCommitIds = Object.freeze((await gitText(repositoryRoot, ["rev-list", targetHead])).split("\n").filter(Boolean));
9695
- const refs = parseReviewerRefSnapshot(await gitText(repositoryRoot, reviewerRefSnapshotArgs()));
9696
- const pin = immutableReviewerPin({ repositoryRoot, objectFormat, targetHead, refs });
9697
- const invalid = (code, diagnostic, cause) => {
9698
- throw new ReviewerCorrectablePreflightError(code, diagnostic, cause === void 0 ? void 0 : { cause });
9699
- };
9700
- const symbolic = (base) => {
9701
- const selected = Object.hasOwn(refs, base) ? base : (() => {
9702
- const candidates = [`refs/heads/${base}`, `refs/tags/${base}`, `refs/remotes/${base}`].filter((name) => Object.hasOwn(refs, name));
9703
- if (candidates.length > 1) invalid("base-invalid", "base revision is ambiguous across pinned refs");
9704
- return candidates[0];
9705
- })();
9706
- if (selected === void 0) return void 0;
9707
- const commit = refs[selected]?.peeledCommitId;
9708
- if (commit === null) invalid("base-invalid", "base revision ref must resolve to a commit");
9709
- return commit ?? void 0;
9710
- };
9711
- return Object.freeze({
9712
- pin,
9713
- async snapshot() {
9714
- const liveObjectFormat = await gitText(repositoryRoot, ["rev-parse", "--show-object-format"]);
9715
- if (liveObjectFormat !== "sha1" && liveObjectFormat !== "sha256") throw new Error("Unsupported Git object format");
9716
- return immutableReviewerPin({ repositoryRoot, objectFormat: liveObjectFormat, targetHead: await gitText(repositoryRoot, ["rev-parse", "HEAD^{commit}"]), refs: parseReviewerRefSnapshot(await gitText(repositoryRoot, reviewerRefSnapshotArgs())) });
9717
- },
9718
- async resolve(base) {
9719
- if (!/^[A-Za-z0-9._/~^+-]+$/.test(base) || base.startsWith("-") || base.includes("..") || base.includes("@{")) {
9720
- invalid("base-invalid", "base revision syntax is invalid or uses a forbidden revision form");
9721
- }
9722
- let commit;
9723
- const headExpression = /^HEAD((?:~[0-9]+|\^[0-9]+)*)$/.exec(base);
9724
- if (headExpression) {
9725
- try {
9726
- commit = await gitText(repositoryRoot, ["rev-parse", "--verify", `${targetHead}${headExpression[1]}^{commit}`]);
9727
- } catch (error) {
9728
- if (exitCode(error) === 128) {
9729
- const repository = await repositoryIsAvailable(repositoryRoot);
9730
- if (repository.available) invalid("base-invalid", "base revision HEAD ancestry expression must resolve to a reachable commit", error);
9731
- }
9732
- throw error;
9733
- }
9734
- } else if (new RegExp(`^[0-9a-f]{${oidWidth}}$`).test(base)) commit = base;
9735
- else if (new RegExp(`^[0-9a-f]{4,${oidWidth - 1}}$`).test(base) && !(objectFormat === "sha256" && base.length === 40)) {
9736
- const matches = reachableCommitIds.filter((candidate) => candidate.startsWith(base));
9737
- if (matches.length !== 1) invalid("base-invalid", "base revision abbreviation must identify exactly one reachable commit");
9738
- commit = matches[0];
9739
- } else commit = symbolic(base);
9740
- if (commit === void 0) invalid("base-invalid", "base revision must name an existing pinned ref or reachable commit");
9741
- try {
9742
- commit = await gitText(repositoryRoot, ["rev-parse", "--verify", `${commit}^{commit}`]);
9743
- } catch (error) {
9744
- if (exitCode(error) === 128) {
9745
- const repository = await repositoryIsAvailable(repositoryRoot);
9746
- if (repository.available) invalid("base-invalid", "base revision must resolve to an existing commit", error);
9747
- }
9748
- throw error;
9749
- }
9750
- try {
9751
- await gitText(repositoryRoot, ["merge-base", "--is-ancestor", commit, targetHead]);
9752
- } catch (error) {
9753
- if (exitCode(error) === 1) invalid("base-invalid", "base revision must be an ancestor of the pinned target", error);
9754
- throw error;
9755
- }
9756
- return commit;
9757
- },
9758
- async range(base) {
9759
- let mergeBase;
9760
- try {
9761
- mergeBase = await gitText(repositoryRoot, ["merge-base", base, targetHead]);
9762
- } catch (error) {
9763
- if (exitCode(error) === 1) {
9764
- invalid("range-invalid", "review range requires a common ancestor for base and pinned target", error);
9765
- }
9766
- throw error;
9767
- }
9768
- if (!mergeBase) invalid("range-invalid", "review range requires a common ancestor for base and pinned target");
9769
- const diffCommand = `git diff ${mergeBase}...${targetHead}`;
9770
- const [{ stdout: diff }, commitsText] = await Promise.all([
9771
- execGit(["-C", repositoryRoot, "diff", `${mergeBase}...${targetHead}`], { encoding: "buffer", maxBuffer: 64 * 1024 * 1024 }),
9772
- gitText(repositoryRoot, ["rev-list", "--reverse", `${mergeBase}..${targetHead}`])
9773
- ]);
9774
- if (diff.length === 0) invalid("range-invalid", "review range must contain a non-empty diff between base and pinned target");
9775
- return Object.freeze({ base: mergeBase, target: targetHead, diffCommand, diffSha256: sha256Hex(Uint8Array.from(diff)), commits: Object.freeze(commitsText ? commitsText.split("\n") : []) });
9776
- },
9777
- async featureTokens() {
9778
- const names = /* @__PURE__ */ new Set();
9779
- for (const [refName, entry] of Object.entries(pin.refs)) {
9780
- if (entry.peeledCommitId !== targetHead) continue;
9781
- const short = shortNameFromPinnedRef(refName);
9782
- if (short !== void 0) names.add(short);
9783
- }
9784
- return Object.freeze([...names]);
9785
- },
9786
- async listSpecCandidatePaths() {
9787
- const roots = ["docs", "specs", ".scratch"];
9788
- const text = await gitText(repositoryRoot, [
9789
- "ls-tree",
9790
- "-r",
9791
- "--name-only",
9792
- targetHead,
9793
- "--",
9794
- ...roots
9795
- ]);
9796
- return Object.freeze(text === "" ? [] : text.split("\n").filter((line2) => line2.length > 0));
9797
- },
9798
- async originRepository() {
9799
- let remoteUrl;
9800
- try {
9801
- remoteUrl = await gitText(repositoryRoot, ["remote", "get-url", "origin"]);
9802
- } catch (error) {
9803
- if (isConfirmedMissingOriginRemote(error)) return void 0;
9804
- throw error;
9805
- }
9806
- return parseGitHubOriginRemote(remoteUrl);
9807
- },
9808
- async commitMessagesNewestFirst(base) {
9809
- const text = await gitText(repositoryRoot, [
9810
- "log",
9811
- "--format=%s",
9812
- `${base}..${targetHead}`
9813
- ]);
9814
- return Object.freeze(text === "" ? [] : text.split("\n"));
9815
- },
9816
- async readPinnedText(path) {
9817
- if (path.length === 0 || path.startsWith("/") || path.includes("\0") || path.split("/").some((part) => part === ".." || part === "")) {
9818
- return void 0;
9819
- }
9820
- try {
9821
- const { stdout } = await execGit(
9822
- ["-C", repositoryRoot, "show", `${targetHead}:${path}`],
9823
- { encoding: "utf8", maxBuffer: 8 * 1024 * 1024 }
9824
- );
9825
- return stdout;
9826
- } catch (error) {
9827
- if (isConfirmedPinnedPathAbsent(error, path)) return void 0;
9828
- throw error;
9829
- }
9830
- }
9831
- });
9832
- }
9833
- function parseGitHubOriginRemote(remoteUrl) {
9834
- const trimmed = remoteUrl.trim();
9835
- if (trimmed.length === 0) return void 0;
9836
- const scp = /^git@github\.com:([^/\s]+)\/([^/\s]+?)(?:\.git)?$/i.exec(trimmed);
9837
- if (scp) return normalizeOrigin(scp[1], scp[2]);
9838
- const ssh = /^ssh:\/\/git@github\.com\/([^/\s]+)\/([^/\s]+?)(?:\.git)?\/?$/i.exec(trimmed);
9839
- if (ssh) return normalizeOrigin(ssh[1], ssh[2]);
9840
- let parsed;
9841
- try {
9842
- parsed = new URL(trimmed);
9843
- } catch {
9844
- return void 0;
9845
- }
9846
- if (!/^github\.com$/i.test(parsed.hostname)) return void 0;
9847
- if (parsed.search !== "" || parsed.hash !== "") return void 0;
9848
- const parts = parsed.pathname.split("/").filter((p) => p.length > 0);
9849
- if (parts.length !== 2) return void 0;
9850
- return normalizeOrigin(parts[0], parts[1]);
9851
- }
9852
- function normalizeOrigin(ownerRaw, repoRaw) {
9853
- const owner = ownerRaw.trim();
9854
- const repo = stripGitSuffix2(repoRaw.trim());
9855
- if (owner.length === 0 || repo.length === 0) return void 0;
9856
- if (/[/?#@\\]/.test(owner) || /[/?#@\\]/.test(repo)) return void 0;
9857
- return Object.freeze({ owner, repo });
9858
- }
9859
- function stripGitSuffix2(name) {
9860
- return name.toLowerCase().endsWith(".git") ? name.slice(0, -4) : name;
9861
- }
9862
- var execFileAsync3, immutableReviewerPin;
9863
- var init_reviewer_pinned_git = __esm({
9864
- "src/reviewer-pinned-git.ts"() {
9865
- "use strict";
9866
- init_reviewer_git_snapshot();
9867
- init_sha256();
9868
- init_reviewer_preflight_error();
9869
- execFileAsync3 = promisify3(execFile3);
9870
- immutableReviewerPin = (pin) => Object.freeze({
9871
- repositoryRoot: pin.repositoryRoot,
9872
- objectFormat: pin.objectFormat,
9873
- targetHead: pin.targetHead,
9874
- refs: immutableReviewerRefs(pin.refs)
9875
- });
9876
- }
9877
- });
9878
-
9879
- // src/ticket-provenance-contracts.ts
9880
- function isRecord11(value) {
9881
- return typeof value === "object" && value !== null && !Array.isArray(value);
9882
- }
9883
- function projectTicketProvenanceDiagnostic(value) {
9884
- if (!isRecord11(value)) return void 0;
9885
- if (value.recordClass !== TICKET_PROVENANCE_RECORD_CLASS_DIAGNOSTIC) {
9886
- return void 0;
9887
- }
9888
- if (typeof value.diagnosticKind !== "string" || !DIAGNOSTIC_KINDS.has(value.diagnosticKind)) {
9889
- return void 0;
9890
- }
9891
- if (typeof value.cause !== "string" || value.cause.length === 0) {
9892
- return void 0;
9893
- }
9894
- if (typeof value.recordedAt !== "string" || value.recordedAt.length === 0) {
9895
- return void 0;
9896
- }
9897
- return {
9898
- recordClass: TICKET_PROVENANCE_RECORD_CLASS_DIAGNOSTIC,
9899
- diagnosticKind: value.diagnosticKind,
9900
- cause: value.cause,
9901
- recordedAt: value.recordedAt,
9902
- ...typeof value.reason === "string" ? { reason: value.reason } : {}
9903
- };
9904
- }
9905
- function projectTicketProvenanceEntry(value) {
9906
- if (!isRecord11(value)) return void 0;
9907
- if (value.recordClass === TICKET_PROVENANCE_RECORD_CLASS_DIAGNOSTIC) {
9908
- return void 0;
9909
- }
9910
- if (!isRecord11(value.basis)) return void 0;
9911
- if (typeof value.basis.method !== "string" || !BASIS_METHODS.has(value.basis.method)) {
9912
- return void 0;
9913
- }
9914
- if (typeof value.sourceKind !== "string" || !SOURCE_KINDS.has(value.sourceKind)) {
9915
- return void 0;
9916
- }
9917
- if (!isRecord11(value.sourceRef)) return void 0;
9918
- if (typeof value.transcript !== "string" || value.transcript.length === 0) {
9919
- return void 0;
9920
- }
9921
- if (typeof value.timestamp !== "string" || value.timestamp.length === 0) {
9922
- return void 0;
9923
- }
9924
- const basis = {
9925
- method: value.basis.method,
9926
- ...Array.isArray(value.basis.anchors) ? {
9927
- anchors: value.basis.anchors.filter(
9928
- (item) => typeof item === "string"
9929
- )
9930
- } : {},
9931
- ...typeof value.basis.note === "string" ? { note: value.basis.note } : {}
9932
- };
9933
- const sourceRef = {
9934
- ...typeof value.sourceRef.sessionFile === "string" ? { sessionFile: value.sourceRef.sessionFile } : {},
9935
- ...typeof value.sourceRef.entryId === "string" || typeof value.sourceRef.entryId === "number" ? { entryId: value.sourceRef.entryId } : {},
9936
- ...typeof value.sourceRef.path === "string" ? { path: value.sourceRef.path } : {},
9937
- ...typeof value.sourceRef.url === "string" ? { url: value.sourceRef.url } : {}
9938
- };
9939
- return {
9940
- basis,
9941
- sourceKind: value.sourceKind,
9942
- sourceRef,
9943
- transcript: value.transcript,
9944
- timestamp: value.timestamp
9945
- };
9946
- }
9947
- var TICKET_PROVENANCE_KIND, TICKET_PROVENANCE_HUMAN_VIEW, TICKET_PROVENANCE_OFFERED_WATERMARK, TICKET_PROVENANCE_RECORD_CLASS_DIAGNOSTIC, SOURCE_KINDS, BASIS_METHODS, DIAGNOSTIC_KINDS;
9948
- var init_ticket_provenance_contracts = __esm({
9949
- "src/ticket-provenance-contracts.ts"() {
9950
- "use strict";
9951
- TICKET_PROVENANCE_KIND = "ticket-provenance";
9952
- TICKET_PROVENANCE_HUMAN_VIEW = "\u8D77\u5C45\u5F55.md";
9953
- TICKET_PROVENANCE_OFFERED_WATERMARK = "offered-identities.jsonl";
9954
- TICKET_PROVENANCE_RECORD_CLASS_DIAGNOSTIC = "diagnostic";
9955
- SOURCE_KINDS = /* @__PURE__ */ new Set([
9956
- "cc-session",
9957
- "issue-body-comment",
9958
- "adr-decision-key",
9959
- "ticket-decree-block"
9960
- ]);
9961
- BASIS_METHODS = /* @__PURE__ */ new Set(["llm-semantic"]);
9962
- DIAGNOSTIC_KINDS = /* @__PURE__ */ new Set([
9963
- "collector-failed",
9964
- "issue-source-failed",
9965
- "quote-verify-failed"
9966
- ]);
9967
- }
9968
- });
9969
-
9970
- // src/ticket-provenance.ts
9971
- import { createHash as createHash5 } from "node:crypto";
9972
- import { appendFileSync as appendFileSync2, existsSync as existsSync6, mkdirSync as mkdirSync3, readFileSync as readFileSync3, writeFileSync as writeFileSync3 } from "node:fs";
9973
- import { join as join17 } from "node:path";
9974
- function ticketProvenanceSubject(ticketNumber) {
9975
- if (!Number.isSafeInteger(ticketNumber) || ticketNumber < 1) {
9976
- throw new Error(`ticket-provenance subject requires a positive ticket number, got ${String(ticketNumber)}`);
9977
- }
9978
- return String(ticketNumber);
9979
- }
9980
- function ticketProvenanceEntryIdentity(input) {
9981
- const ref = input.sourceRef;
9982
- const refKey = [
9983
- ref.sessionFile ?? "",
9984
- ref.entryId === void 0 ? "" : String(ref.entryId),
9985
- ref.path ?? "",
9986
- ref.url ?? ""
9987
- ].join("");
9988
- const material = [
9989
- String(input.ticketNumber),
9990
- input.sourceKind,
9991
- refKey,
9992
- input.transcript
9993
- ].join("\0");
9994
- return createHash5("sha256").update(material, "utf8").digest("hex");
9995
- }
9996
- function appendTicketProvenanceEntry(input) {
9997
- const subject = ticketProvenanceSubject(input.ticketNumber);
9998
- const identity = ticketProvenanceEntryIdentity({
9999
- ticketNumber: input.ticketNumber,
10000
- sourceKind: input.entry.sourceKind,
10001
- sourceRef: input.entry.sourceRef,
10002
- transcript: input.entry.transcript
10003
- });
10004
- return sitianReport({
10005
- level: "event",
10006
- kind: TICKET_PROVENANCE_KIND,
10007
- identity,
10008
- subject,
10009
- cwd: input.cwd,
10010
- ...input.home === void 0 ? {} : { home: input.home },
10011
- host: input.host ?? "diarist",
10012
- source: input.source ?? "diarist",
10013
- payload: input.entry,
10014
- raw: input.entry.sourceRef.sessionFile !== void 0 && input.entry.sourceRef.entryId !== void 0 ? {
10015
- sessionFile: input.entry.sourceRef.sessionFile,
10016
- entryId: input.entry.sourceRef.entryId
10017
- } : void 0
10018
- });
10019
- }
10020
- function resolveTicketProvenanceVolume(ticketNumber, cwd, home) {
10021
- const path = resolveSitianRecordPath({
10022
- level: "event",
10023
- kind: TICKET_PROVENANCE_KIND,
10024
- subject: ticketProvenanceSubject(ticketNumber),
10025
- cwd,
10026
- ...home === void 0 ? {} : { home }
10027
- });
10028
- return {
10029
- recordFile: path.recordFile,
10030
- volumeDir: path.sessionDir,
10031
- humanViewFile: join17(path.sessionDir, TICKET_PROVENANCE_HUMAN_VIEW),
10032
- offeredWatermarkFile: join17(path.sessionDir, TICKET_PROVENANCE_OFFERED_WATERMARK)
10033
- };
10034
- }
10035
- function readOfferedIdentities(ticketNumber, cwd, home) {
10036
- const { offeredWatermarkFile } = resolveTicketProvenanceVolume(ticketNumber, cwd, home);
10037
- if (!existsSync6(offeredWatermarkFile)) return /* @__PURE__ */ new Set();
10038
- let text;
10039
- try {
10040
- text = readFileSync3(offeredWatermarkFile, "utf8");
10041
- } catch (error) {
10042
- throw new TicketProvenanceWatermarkError(
10043
- "unreadable",
10044
- `ticket-provenance offered watermark unreadable (${offeredWatermarkFile})`,
10045
- { cause: error }
10046
- );
10047
- }
10048
- const seen = /* @__PURE__ */ new Set();
10049
- const lines = text.split("\n");
10050
- for (let index = 0; index < lines.length; index += 1) {
10051
- const trimmed = lines[index].trim();
10052
- if (!trimmed) continue;
10053
- let parsed;
10054
- try {
10055
- parsed = JSON.parse(trimmed);
10056
- } catch (error) {
10057
- throw new TicketProvenanceWatermarkError(
10058
- "malformed-json",
10059
- `ticket-provenance offered watermark malformed JSON at line ${index + 1} (${offeredWatermarkFile})`,
10060
- { cause: error }
10061
- );
10062
- }
10063
- if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed) || typeof parsed.identity !== "string" || parsed.identity.length === 0) {
10064
- throw new TicketProvenanceWatermarkError(
10065
- "bad-shape",
10066
- `ticket-provenance offered watermark bad shape at line ${index + 1} (${offeredWatermarkFile})`
10067
- );
10068
- }
10069
- seen.add(parsed.identity);
10070
- }
10071
- return seen;
10072
- }
10073
- function recordOfferedIdentities(input) {
10074
- if (input.identities.length === 0) return;
10075
- const { volumeDir, offeredWatermarkFile } = resolveTicketProvenanceVolume(
10076
- input.ticketNumber,
10077
- input.cwd,
10078
- input.home
10079
- );
10080
- const already = new Set(readOfferedIdentities(input.ticketNumber, input.cwd, input.home));
10081
- const rows = [];
10082
- for (const identity of input.identities) {
10083
- if (identity.length === 0 || already.has(identity)) continue;
10084
- rows.push(`${JSON.stringify({ identity })}
10085
- `);
10086
- already.add(identity);
10087
- }
10088
- if (rows.length === 0) return;
10089
- mkdirSync3(volumeDir, { recursive: true });
10090
- appendFileSync2(offeredWatermarkFile, rows.join(""), "utf8");
10091
- }
10092
- async function readTicketProvenance(ticketNumber, cwd, home) {
10093
- const { recordFile } = resolveTicketProvenanceVolume(ticketNumber, cwd, home);
10094
- const { records: records2 } = await readSitianRecords(recordFile);
10095
- const entries = [];
10096
- const diagnostics = [];
10097
- let skipped = 0;
10098
- for (const record4 of records2) {
10099
- if (record4.kind !== TICKET_PROVENANCE_KIND) {
10100
- skipped += 1;
10101
- continue;
10102
- }
10103
- const diagnostic = projectTicketProvenanceDiagnostic(record4.payload);
10104
- if (diagnostic !== void 0) {
10105
- diagnostics.push(diagnostic);
10106
- continue;
10107
- }
10108
- const entry = projectTicketProvenanceEntry(record4.payload);
10109
- if (entry === void 0) {
10110
- skipped += 1;
10111
- continue;
10112
- }
10113
- entries.push(entry);
10114
- }
10115
- return { entries, diagnostics, records: records2, recordFile, skipped };
10116
- }
10117
- function markdownFenceFor(text) {
10118
- let longest = 0;
10119
- const runs = text.match(/`+/g);
10120
- if (runs !== null) {
10121
- for (const run of runs) {
10122
- if (run.length > longest) longest = run.length;
10123
- }
10124
- }
10125
- return "`".repeat(Math.max(3, longest + 1));
9504
+ return "`".repeat(Math.max(3, longest + 1));
10126
9505
  }
10127
9506
  function renderTicketProvenanceMarkdown(input) {
10128
9507
  const lines = [
@@ -10210,217 +9589,100 @@ function appendQuoteVerifyFailureDiagnostic(input) {
10210
9589
  cwd: input.cwd,
10211
9590
  ...input.home === void 0 ? {} : { home: input.home },
10212
9591
  source: "diarist-quote-verify",
10213
- diagnostic: {
10214
- recordClass: TICKET_PROVENANCE_RECORD_CLASS_DIAGNOSTIC,
10215
- diagnosticKind: "quote-verify-failed",
10216
- cause: input.cause,
10217
- recordedAt
10218
- }
10219
- });
10220
- }
10221
- function writeTicketProvenanceHumanView(input) {
10222
- const volume = ensureTicketProvenanceVolume(input.ticketNumber, input.cwd, input.home);
10223
- const md = renderTicketProvenanceMarkdown({
10224
- ticketNumber: input.ticketNumber,
10225
- entries: input.entries
10226
- });
10227
- writeFileSync3(volume.humanViewFile, md, "utf8");
10228
- return volume.humanViewFile;
10229
- }
10230
- var TicketProvenanceWatermarkError;
10231
- var init_ticket_provenance = __esm({
10232
- "src/ticket-provenance.ts"() {
10233
- "use strict";
10234
- init_sitian_facade();
10235
- init_ticket_provenance_contracts();
10236
- TicketProvenanceWatermarkError = class extends Error {
10237
- code = "ticket-provenance-watermark";
10238
- reason;
10239
- constructor(reason, message, options) {
10240
- super(message, options);
10241
- this.name = "TicketProvenanceWatermarkError";
10242
- this.reason = reason;
10243
- }
10244
- };
10245
- }
10246
- });
10247
-
10248
- // src/diarist.ts
10249
- import { readFileSync as readFileSync4 } from "node:fs";
10250
- import { execFileSync as execFileSync3 } from "node:child_process";
10251
- function resolveDiaristGithubOrigin(projectRoot) {
10252
- let remoteUrl;
10253
- try {
10254
- remoteUrl = execFileSync3("git", ["remote", "get-url", "origin"], {
10255
- cwd: projectRoot,
10256
- encoding: "utf8",
10257
- stdio: ["ignore", "pipe", "pipe"]
10258
- }).trim();
10259
- } catch {
10260
- return void 0;
10261
- }
10262
- if (remoteUrl.length === 0) return void 0;
10263
- return parseGitHubOriginRemote(remoteUrl);
10264
- }
10265
- function blockEntryIdentity(ticketNumber, block) {
10266
- return ticketProvenanceEntryIdentity({
10267
- ticketNumber,
10268
- sourceKind: block.sourceKind,
10269
- sourceRef: block.sourceRef,
10270
- transcript: block.transcript
10271
- });
10272
- }
10273
- function loadDiaristSourceCatalog(path) {
10274
- const parsed = JSON.parse(readFileSync4(path, "utf8"));
10275
- if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
10276
- throw new Error(`diarist source catalog is not an object (${path})`);
10277
- }
10278
- const record4 = parsed;
10279
- if (typeof record4.ticketNumber !== "number" || typeof record4.cwd !== "string") {
10280
- throw new Error(`diarist source catalog is missing ticket coordinates (${path})`);
10281
- }
10282
- if (!Array.isArray(record4.candidates)) {
10283
- throw new Error(`diarist source catalog is missing candidates (${path})`);
10284
- }
10285
- return parsed;
10286
- }
10287
- async function commitDiaristSelections(input) {
10288
- const { ticketNumber, cwd } = input.catalog;
10289
- const homeOpt = input.catalog.home === void 0 ? {} : { home: input.catalog.home };
10290
- const volumePaths = ensureTicketProvenanceVolume(ticketNumber, cwd, input.catalog.home);
10291
- const anchors = buildDiaristAnchors({ ticketNumber });
10292
- const before = await readTicketProvenance(ticketNumber, cwd, input.catalog.home);
10293
- let acceptedRows = 0;
10294
- let rejectedQuotes = 0;
10295
- let unknownCandidate = false;
10296
- for (const selection of input.selections) {
10297
- const block = input.catalog.candidates[selection.candidateIndex];
10298
- if (block === void 0) {
10299
- unknownCandidate = true;
10300
- continue;
10301
- }
10302
- const projected = blockToLlmEntry(block, {
10303
- anchors,
10304
- quotes: selection.quotes,
10305
- ...selection.note === void 0 ? {} : { note: selection.note }
10306
- });
10307
- if (!projected.ok) {
10308
- rejectedQuotes += 1;
10309
- appendQuoteVerifyFailureDiagnostic({
10310
- ticketNumber,
10311
- cwd,
10312
- ...homeOpt,
10313
- cause: projected.cause
10314
- });
10315
- continue;
9592
+ diagnostic: {
9593
+ recordClass: TICKET_PROVENANCE_RECORD_CLASS_DIAGNOSTIC,
9594
+ diagnosticKind: "quote-verify-failed",
9595
+ cause: input.cause,
9596
+ recordedAt
10316
9597
  }
10317
- appendTicketProvenanceEntry({
10318
- ticketNumber,
10319
- cwd,
10320
- ...homeOpt,
10321
- entry: projected.entry,
10322
- source: "diarist"
10323
- });
10324
- acceptedRows += 1;
10325
- }
10326
- const identities = input.catalog.candidates.map(
10327
- (block) => blockEntryIdentity(ticketNumber, block)
10328
- );
10329
- const alreadyWatermarked = readOfferedIdentities(ticketNumber, cwd, input.catalog.home);
10330
- const watermarked = identities.filter((identity) => !alreadyWatermarked.has(identity)).length;
10331
- recordOfferedIdentities({ ticketNumber, cwd, ...homeOpt, identities });
10332
- const volume = await readTicketProvenance(ticketNumber, cwd, input.catalog.home);
10333
- const humanViewFile = writeTicketProvenanceHumanView({
10334
- ticketNumber,
10335
- cwd,
10336
- ...homeOpt,
10337
- entries: volume.entries
10338
9598
  });
10339
- return {
10340
- ticketNumber,
10341
- offered: input.catalog.candidates.length,
10342
- appended: volume.entries.length - before.entries.length,
10343
- rejectedQuotes,
10344
- watermarked,
10345
- volumeRecordFile: volumePaths.recordFile,
10346
- humanViewFile,
10347
- collectorStatus: input.catalog.candidates.length === 0 ? "skipped-no-fresh" : acceptedRows > 0 ? "ok" : input.selections.length === 0 ? "empty-selection" : "nothing-appended",
10348
- failureCauses: [
10349
- ...unknownCandidate ? ["unknown-candidate"] : [],
10350
- ...rejectedQuotes > 0 ? ["quote-verify-rejected"] : []
10351
- ]
10352
- };
10353
9599
  }
10354
- var init_diarist = __esm({
10355
- "src/diarist.ts"() {
9600
+ function writeTicketProvenanceHumanView(input) {
9601
+ const volume = ensureTicketProvenanceVolume(input.ticketNumber, input.cwd, input.home);
9602
+ const md = renderTicketProvenanceMarkdown({
9603
+ ticketNumber: input.ticketNumber,
9604
+ entries: input.entries
9605
+ });
9606
+ writeFileSync3(volume.humanViewFile, md, "utf8");
9607
+ return volume.humanViewFile;
9608
+ }
9609
+ var TicketProvenanceWatermarkError;
9610
+ var init_ticket_provenance = __esm({
9611
+ "src/ticket-provenance.ts"() {
10356
9612
  "use strict";
10357
- init_adr_path_refs();
10358
- init_collector_github();
10359
- init_diarist_mechanical();
10360
- init_reviewer_pinned_git();
10361
- init_ticket_provenance();
10362
9613
  init_sitian_facade();
9614
+ init_ticket_provenance_contracts();
9615
+ TicketProvenanceWatermarkError = class extends Error {
9616
+ code = "ticket-provenance-watermark";
9617
+ reason;
9618
+ constructor(reason, message, options) {
9619
+ super(message, options);
9620
+ this.name = "TicketProvenanceWatermarkError";
9621
+ this.reason = reason;
9622
+ }
9623
+ };
10363
9624
  }
10364
9625
  });
10365
9626
 
10366
9627
  // src/public-cli/seat-ticket-binding.ts
10367
- async function resolveInstructionTicket(instruction, projectRoot, env = {}) {
10368
- const resolver = createHermesDiaristTicketResolver({
10369
- ...env.packageRoot === void 0 ? {} : { packageRoot: env.packageRoot },
10370
- cwd: projectRoot
10371
- });
10372
- const checkExistence = createGhTicketExistenceChecker();
10373
- const origin = resolveDiaristGithubOrigin(projectRoot);
10374
- return resolveDiaristTicketFromInstruction({
10375
- instruction,
10376
- origin,
10377
- resolver,
10378
- checkExistence
10379
- });
10380
- }
10381
- async function probeInstructionTicket(instruction, projectRoot, env = {}) {
10382
- try {
10383
- const resolution = await resolveInstructionTicket(
10384
- instruction,
10385
- projectRoot,
10386
- env
9628
+ import { existsSync as existsSync6 } from "node:fs";
9629
+ function instructionTicketTokens(instruction) {
9630
+ const tokens = /* @__PURE__ */ new Set();
9631
+ for (const run of instruction.match(/\d+/g) ?? []) {
9632
+ if (run.startsWith("0")) continue;
9633
+ const parsed = Number(run);
9634
+ if (!Number.isSafeInteger(parsed) || parsed < 1) continue;
9635
+ tokens.add(parsed);
9636
+ }
9637
+ return [...tokens];
9638
+ }
9639
+ async function resolveKnownTicketNumber(input) {
9640
+ const tokens = instructionTicketTokens(input.instruction);
9641
+ if (tokens.length === 0) return void 0;
9642
+ const known = [];
9643
+ let runTickets;
9644
+ for (const token of tokens) {
9645
+ const volume = resolveTicketProvenanceVolume(
9646
+ token,
9647
+ input.projectRoot,
9648
+ input.home
10387
9649
  );
10388
- return { kind: "resolved", resolution };
10389
- } catch (error) {
10390
- if (error instanceof DiaristTicketResolutionError) {
10391
- return { kind: "failed", error };
9650
+ if (existsSync6(volume.volumeDir)) {
9651
+ known.push(token);
9652
+ continue;
10392
9653
  }
10393
- throw error;
9654
+ if (runTickets === void 0) {
9655
+ runTickets = await readBookRunTickets(input);
9656
+ }
9657
+ if (runTickets.has(token)) known.push(token);
10394
9658
  }
9659
+ return known.length === 1 ? known[0] : void 0;
10395
9660
  }
10396
- function ticketNumberFromProbe(probe) {
10397
- if (probe.kind !== "resolved") return void 0;
10398
- if (probe.resolution.kind !== "ticket") return void 0;
10399
- return probe.resolution.ticketNumber;
10400
- }
10401
- async function applyTicketResolution(admitted, resolution) {
10402
- if (resolution.kind === "ticket") {
10403
- await bindAdmittedTicketNumber(admitted, resolution.ticketNumber);
10404
- } else {
10405
- await recordTrueUnboundTicketResolution(admitted);
9661
+ async function readBookRunTickets(input) {
9662
+ let bookKey;
9663
+ try {
9664
+ bookKey = input.bookKey ?? resolveBookKeyFromGit(input.projectRoot);
9665
+ } catch (error) {
9666
+ if (error instanceof ActivationGitRepositoryRequiredError) return /* @__PURE__ */ new Set();
9667
+ throw error;
10406
9668
  }
9669
+ return await collectBookRunTicketNumbers({ home: input.home, bookKey });
10407
9670
  }
10408
- async function applyInstructionTicketProbe(admitted, probe) {
10409
- if (probe.kind === "failed") throw probe.error;
10410
- await applyTicketResolution(admitted, probe.resolution);
9671
+ async function bindReusedTicketNumber(admitted, ticketNumber) {
9672
+ if (ticketNumber === void 0) return;
9673
+ if (admitted.ticketNumber !== void 0) return;
9674
+ await bindAdmittedTicketNumber(admitted, ticketNumber);
10411
9675
  }
10412
- async function resolveSeatTicketBinding(admitted, env = {}) {
10413
- if (admitted.ticketNumber !== void 0) return void 0;
10414
- if (admitted.ticketResolution === "true-unbound") {
10415
- return { kind: "true-unbound" };
10416
- }
10417
- const resolution = await resolveInstructionTicket(
10418
- admitted.instruction,
10419
- admitted.projectRoot,
10420
- env
10421
- );
10422
- await applyTicketResolution(admitted, resolution);
10423
- return resolution;
9676
+ async function resolveSeatTicketBinding(admitted, env) {
9677
+ if (admitted.ticketNumber !== void 0) return admitted.ticketNumber;
9678
+ const ticketNumber = await resolveKnownTicketNumber({
9679
+ instruction: admitted.instruction,
9680
+ projectRoot: admitted.projectRoot,
9681
+ home: env.home,
9682
+ bookKey: admitted.bookKey
9683
+ });
9684
+ await bindReusedTicketNumber(admitted, ticketNumber);
9685
+ return ticketNumber;
10424
9686
  }
10425
9687
  async function tryResumeSameTicketSeatRun(input) {
10426
9688
  if (input.freshSummons === true) return void 0;
@@ -10441,22 +9703,58 @@ var init_seat_ticket_binding = __esm({
10441
9703
  "src/public-cli/seat-ticket-binding.ts"() {
10442
9704
  "use strict";
10443
9705
  init_activation_ledger_git();
10444
- init_diarist_ticket_resolution();
10445
- init_diarist();
9706
+ init_ticket_provenance();
10446
9707
  init_invocation();
10447
9708
  init_run_lifecycle();
10448
9709
  }
10449
9710
  });
10450
9711
 
9712
+ // src/public-cli/case-dossier-delivery.ts
9713
+ import { stat as stat2 } from "node:fs/promises";
9714
+ async function describeDossierFile(path) {
9715
+ try {
9716
+ const stats = await stat2(path);
9717
+ if (!stats.isFile()) return `\u4E0D\u53EF\u8BFB\uFF08\u975E\u666E\u901A\u6587\u4EF6\uFF09\uFF1A${path}`;
9718
+ return path;
9719
+ } catch (error) {
9720
+ const code = error.code;
9721
+ if (code === "ENOENT") return `\u5C1A\u672A\u751F\u6210\uFF1A${path}`;
9722
+ return `\u4E0D\u53EF\u8BFB\uFF08${code ?? "\u672A\u77E5\u9519\u8BEF"}\uFF09\uFF1A${path}`;
9723
+ }
9724
+ }
9725
+ async function projectCaseDossierPointerSection(input) {
9726
+ if (input.ticketNumber === void 0) return void 0;
9727
+ const volume = resolveTicketProvenanceVolume(
9728
+ input.ticketNumber,
9729
+ input.projectRoot,
9730
+ input.home
9731
+ );
9732
+ return [
9733
+ CASE_DOSSIER_SECTION_HEADING,
9734
+ "",
9735
+ `\u7968\u53F7\uFF1A#${input.ticketNumber}`,
9736
+ `\u4EBA\u8BFB\u89C6\u56FE\uFF1A${await describeDossierFile(volume.humanViewFile)}`,
9737
+ `\u8BB0\u5F55\u5377\u5B97\uFF1A${await describeDossierFile(volume.recordFile)}`
9738
+ ].join("\n");
9739
+ }
9740
+ var CASE_DOSSIER_SECTION_HEADING;
9741
+ var init_case_dossier_delivery = __esm({
9742
+ "src/public-cli/case-dossier-delivery.ts"() {
9743
+ "use strict";
9744
+ init_ticket_provenance();
9745
+ CASE_DOSSIER_SECTION_HEADING = "## \u672C\u7968\u8D77\u5C45\u5F55\uFF08\u7CFB\u7EDF\u968F\u6848\u63D0\u4F9B\uFF09";
9746
+ }
9747
+ });
9748
+
10451
9749
  // src/host-transition-prior-native.ts
10452
- import { access as access3, readdir as readdir3 } from "node:fs/promises";
10453
- import { dirname as dirname9, join as join18 } from "node:path";
9750
+ import { access as access2, readdir as readdir3 } from "node:fs/promises";
9751
+ import { dirname as dirname9, join as join17 } from "node:path";
10454
9752
  function isEnoent2(error) {
10455
9753
  return typeof error === "object" && error !== null && error.code === "ENOENT";
10456
9754
  }
10457
9755
  async function listPiNativeRecordPaths(sessionFile) {
10458
9756
  try {
10459
- await access3(sessionFile);
9757
+ await access2(sessionFile);
10460
9758
  return [sessionFile];
10461
9759
  } catch (error) {
10462
9760
  if (isEnoent2(error)) return [];
@@ -10475,9 +9773,9 @@ async function listSitianRecordPaths(sessionParent) {
10475
9773
  const recordPaths = [];
10476
9774
  for (const entry of entries) {
10477
9775
  if (!entry.isDirectory()) continue;
10478
- const recordFile = join18(sessionRoot, entry.name, "records.jsonl");
9776
+ const recordFile = join17(sessionRoot, entry.name, "records.jsonl");
10479
9777
  try {
10480
- await access3(recordFile);
9778
+ await access2(recordFile);
10481
9779
  recordPaths.push(recordFile);
10482
9780
  } catch (error) {
10483
9781
  if (!isEnoent2(error)) throw error;
@@ -10737,7 +10035,7 @@ var init_gatekeeper_role = __esm({
10737
10035
  });
10738
10036
 
10739
10037
  // src/run-terminal-artifacts.ts
10740
- import { basename as basename6, dirname as dirname10, join as join19 } from "node:path";
10038
+ import { basename as basename6, dirname as dirname10, join as join18 } from "node:path";
10741
10039
  function runIdFromRunDirectory(runDirectory) {
10742
10040
  const name = basename6(runDirectory);
10743
10041
  const at = name.lastIndexOf("@");
@@ -11159,7 +10457,7 @@ var init_ledger_session_read = __esm({
11159
10457
 
11160
10458
  // src/analyst-gate-cycles-read.ts
11161
10459
  import { readdir as readdir4 } from "node:fs/promises";
11162
- import { join as join20 } from "node:path";
10460
+ import { join as join19 } from "node:path";
11163
10461
  function isRecord15(value) {
11164
10462
  return typeof value === "object" && value !== null && !Array.isArray(value);
11165
10463
  }
@@ -11420,7 +10718,7 @@ async function readAnalystGateCyclesFromAuditorRoles(auditorRolesDirectory, opti
11420
10718
  throw error;
11421
10719
  }
11422
10720
  for (const name of names) {
11423
- const path = join20(directory, name);
10721
+ const path = join19(directory, name);
11424
10722
  const sessionPath = name.endsWith(".pointer.json") ? await resolveOfficerSessionFromPointerFile(path) : path;
11425
10723
  if (sessionPath === void 0) continue;
11426
10724
  const classified = await classifyAuditorVolume(sessionPath);
@@ -11459,22 +10757,22 @@ var init_analyst_gate_cycles_read = __esm({
11459
10757
  // src/session-opening-materials.ts
11460
10758
  import { existsSync as existsSync7 } from "node:fs";
11461
10759
  import { readFile as readFile12 } from "node:fs/promises";
11462
- import { dirname as dirname11, join as join21 } from "node:path";
11463
- import { fileURLToPath as fileURLToPath2, pathToFileURL as pathToFileURL2 } from "node:url";
10760
+ import { dirname as dirname11, join as join20 } from "node:path";
10761
+ import { fileURLToPath, pathToFileURL as pathToFileURL2 } from "node:url";
11464
10762
  function resolvePackageRootDir(moduleUrl = import.meta.url) {
11465
- let dir = dirname11(fileURLToPath2(moduleUrl));
10763
+ let dir = dirname11(fileURLToPath(moduleUrl));
11466
10764
  for (let i = 0; i < 8; i += 1) {
11467
- if (existsSync7(join21(dir, "package.json")) && existsSync7(join21(dir, "souls"))) {
10765
+ if (existsSync7(join20(dir, "package.json")) && existsSync7(join20(dir, "souls"))) {
11468
10766
  return dir;
11469
10767
  }
11470
10768
  const parent = dirname11(dir);
11471
10769
  if (parent === dir) break;
11472
10770
  dir = parent;
11473
10771
  }
11474
- return fileURLToPath2(new URL("..", moduleUrl));
10772
+ return fileURLToPath(new URL("..", moduleUrl));
11475
10773
  }
11476
10774
  async function readPackageMaterial(relativePath) {
11477
- return readFile12(fileURLToPath2(new URL(relativePath, packageRootUrl)), "utf8");
10775
+ return readFile12(fileURLToPath(new URL(relativePath, packageRootUrl)), "utf8");
11478
10776
  }
11479
10777
  async function joinPackageMaterials(relativePaths) {
11480
10778
  const chunks = [];
@@ -11678,68 +10976,393 @@ var init_judge_auditor = __esm({
11678
10976
  init_auditor_dossier_tool();
11679
10977
  init_dossier_resolution();
11680
10978
  }
11681
- });
11682
-
11683
- // src/upstream-error-testimony.ts
11684
- function isNonSuccessHttpStatus(status) {
11685
- return typeof status === "number" && (status < 200 || status >= 300);
10979
+ });
10980
+
10981
+ // src/upstream-error-testimony.ts
10982
+ function isNonSuccessHttpStatus(status) {
10983
+ return typeof status === "number" && (status < 200 || status >= 300);
10984
+ }
10985
+ function hasUpstreamErrorTestimony(input) {
10986
+ if (isNonSuccessHttpStatus(input.httpStatus)) return true;
10987
+ return Array.isArray(input.diagnostics) && input.diagnostics.length > 0;
10988
+ }
10989
+ function projectConfirmedRemotePayload(input) {
10990
+ return {
10991
+ ...input.body === void 0 ? {} : { body: input.body },
10992
+ ...input.code === void 0 ? {} : { code: input.code },
10993
+ ...input.errno === void 0 ? {} : { errno: input.errno }
10994
+ };
10995
+ }
10996
+ var init_upstream_error_testimony = __esm({
10997
+ "src/upstream-error-testimony.ts"() {
10998
+ "use strict";
10999
+ }
11000
+ });
11001
+
11002
+ // src/pi/known-failure.ts
11003
+ function nonEmptyString(value) {
11004
+ return typeof value === "string" && value.trim() !== "" ? value : void 0;
11005
+ }
11006
+ function sessionStopDetails(input) {
11007
+ const details = {};
11008
+ const errorMessage = nonEmptyString(input.errorMessage);
11009
+ if (errorMessage !== void 0) details.errorMessage = errorMessage;
11010
+ const api = nonEmptyString(input.api);
11011
+ if (api !== void 0) details.api = api;
11012
+ const rawStopReason = nonEmptyString(input.rawStopReason);
11013
+ if (rawStopReason !== void 0) details.rawStopReason = rawStopReason;
11014
+ const testimony = hasUpstreamErrorTestimony(input);
11015
+ if (testimony) {
11016
+ const provider = nonEmptyString(input.provider);
11017
+ if (provider !== void 0) details.provider = provider;
11018
+ const model = nonEmptyString(input.model);
11019
+ if (model !== void 0) details.model = model;
11020
+ }
11021
+ if (typeof input.httpStatus === "number") details.httpStatus = input.httpStatus;
11022
+ if (input.diagnostics !== void 0) details.diagnostics = input.diagnostics;
11023
+ if (testimony) Object.assign(details, projectConfirmedRemotePayload(input));
11024
+ return details;
11025
+ }
11026
+ function knownFailureFromProviderStop(input) {
11027
+ if (input.stopReason !== "error" && input.stopReason !== "aborted") return void 0;
11028
+ const diagnostic = nonEmptyString(input.errorMessage);
11029
+ const details = sessionStopDetails(input);
11030
+ return {
11031
+ cause: hasUpstreamErrorTestimony(input) ? "provider" : "unrecognized",
11032
+ ...diagnostic === void 0 ? {} : { diagnostic },
11033
+ ...Object.keys(details).length === 0 ? {} : { details }
11034
+ };
11035
+ }
11036
+ var init_known_failure = __esm({
11037
+ "src/pi/known-failure.ts"() {
11038
+ "use strict";
11039
+ init_upstream_error_testimony();
11040
+ init_upstream_error_testimony();
11041
+ }
11042
+ });
11043
+
11044
+ // src/adr-path-refs.ts
11045
+ function extractReferencedAdrPaths(text) {
11046
+ const seen = /* @__PURE__ */ new Set();
11047
+ const paths = [];
11048
+ for (const match of text.matchAll(ADR_PATH_IN_BODY)) {
11049
+ const path = match[0];
11050
+ if (seen.has(path)) continue;
11051
+ seen.add(path);
11052
+ paths.push(path);
11053
+ }
11054
+ return Object.freeze(paths);
11055
+ }
11056
+ var ADR_PATH_IN_BODY;
11057
+ var init_adr_path_refs = __esm({
11058
+ "src/adr-path-refs.ts"() {
11059
+ "use strict";
11060
+ ADR_PATH_IN_BODY = /docs\/adr\/(?:[A-Za-z0-9][A-Za-z0-9._-]*\/)*[A-Za-z0-9][A-Za-z0-9._-]*\.md/g;
11061
+ }
11062
+ });
11063
+
11064
+ // src/reviewer-git-snapshot.ts
11065
+ function parseReviewerRefSnapshot(raw) {
11066
+ const refs = {};
11067
+ for (const line2 of raw.split("\n")) {
11068
+ if (!line2) continue;
11069
+ const fields = line2.split("\0");
11070
+ if (fields.length !== 5 || !fields[0] || !fields[1] || !fields[3]) {
11071
+ throw new Error(`Malformed Git ref snapshot line: ${line2}`);
11072
+ }
11073
+ const peeledCommitId = fields[3] === "commit" ? fields[1] : fields[4] === "commit" && fields[2] ? fields[2] : null;
11074
+ refs[fields[0]] = Object.freeze({
11075
+ objectId: fields[1],
11076
+ peeledCommitId
11077
+ });
11078
+ }
11079
+ return refs;
11080
+ }
11081
+ function reviewerRefSnapshotArgs() {
11082
+ return ["for-each-ref", "--format=%(refname)%00%(objectname)%00%(*objectname)%00%(objecttype)%00%(*objecttype)", ...REVIEW_REF_PREFIXES];
11083
+ }
11084
+ function immutableReviewerRefs(refs) {
11085
+ return Object.freeze(Object.fromEntries(Object.entries(refs).sort(([a], [b]) => a.localeCompare(b)).map(([name, entry]) => [name, Object.freeze({ objectId: entry.objectId, peeledCommitId: entry.peeledCommitId })])));
11086
+ }
11087
+ function sameReviewerPinnedTarget(actual, expected) {
11088
+ return actual.repositoryRoot === expected.repositoryRoot && actual.objectFormat === expected.objectFormat && actual.targetHead === expected.targetHead;
11089
+ }
11090
+ var REVIEW_REF_PREFIXES;
11091
+ var init_reviewer_git_snapshot = __esm({
11092
+ "src/reviewer-git-snapshot.ts"() {
11093
+ "use strict";
11094
+ REVIEW_REF_PREFIXES = ["refs/heads", "refs/tags", "refs/remotes"];
11095
+ }
11096
+ });
11097
+
11098
+ // src/reviewer-preflight-error.ts
11099
+ var ReviewerCorrectablePreflightError;
11100
+ var init_reviewer_preflight_error = __esm({
11101
+ "src/reviewer-preflight-error.ts"() {
11102
+ "use strict";
11103
+ ReviewerCorrectablePreflightError = class extends Error {
11104
+ constructor(code, diagnostic = `${code} constraint failed`, options) {
11105
+ super(`${code}: ${diagnostic}`, options);
11106
+ this.code = code;
11107
+ this.diagnostic = diagnostic;
11108
+ this.name = "ReviewerCorrectablePreflightError";
11109
+ }
11110
+ code;
11111
+ diagnostic;
11112
+ };
11113
+ }
11114
+ });
11115
+
11116
+ // src/reviewer-pinned-git.ts
11117
+ import { execFile as execFile3 } from "node:child_process";
11118
+ import { access as access3, realpath as realpath6 } from "node:fs/promises";
11119
+ import { promisify as promisify3 } from "node:util";
11120
+ async function execGit(args, options) {
11121
+ try {
11122
+ return await execFileAsync3("git", args, {
11123
+ ...options,
11124
+ env: { ...process.env, LC_ALL: "C" }
11125
+ });
11126
+ } catch (error) {
11127
+ const source = error;
11128
+ const wrapped = new Error("git process failed", { cause: error });
11129
+ Object.assign(wrapped, { code: source.code ?? null, signal: source.signal ?? null, timedOut: source.killed === true && source.signal === "SIGTERM", aborted: source.name === "AbortError", stderr: String(source.stderr ?? ""), stdout: String(source.stdout ?? "") });
11130
+ throw wrapped;
11131
+ }
11686
11132
  }
11687
- function hasUpstreamErrorTestimony(input) {
11688
- if (isNonSuccessHttpStatus(input.httpStatus)) return true;
11689
- return Array.isArray(input.diagnostics) && input.diagnostics.length > 0;
11133
+ function exitCode(error) {
11134
+ const code = typeof error === "object" && error !== null ? error.code : void 0;
11135
+ return typeof code === "number" ? code : void 0;
11690
11136
  }
11691
- function projectConfirmedRemotePayload(input) {
11692
- return {
11693
- ...input.body === void 0 ? {} : { body: input.body },
11694
- ...input.code === void 0 ? {} : { code: input.code },
11695
- ...input.errno === void 0 ? {} : { errno: input.errno }
11696
- };
11137
+ function gitStderr(error) {
11138
+ if (typeof error !== "object" || error === null) return "";
11139
+ const stderr = error.stderr;
11140
+ return typeof stderr === "string" ? stderr : "";
11697
11141
  }
11698
- var init_upstream_error_testimony = __esm({
11699
- "src/upstream-error-testimony.ts"() {
11700
- "use strict";
11142
+ function isConfirmedMissingOriginRemote(error) {
11143
+ return /No such remote ['"]origin['"]/.test(gitStderr(error));
11144
+ }
11145
+ function isConfirmedPinnedPathAbsent(error, path) {
11146
+ const stderr = gitStderr(error);
11147
+ const quoted = `'${path}'`;
11148
+ return stderr.includes(`path ${quoted} does not exist in `) || stderr.includes(`path ${quoted} exists on disk, but not in `);
11149
+ }
11150
+ async function repositoryIsAvailable(root) {
11151
+ try {
11152
+ await access3(`${root}/.git`);
11153
+ return { available: true };
11154
+ } catch (cause) {
11155
+ return { available: false, cause };
11701
11156
  }
11702
- });
11703
-
11704
- // src/pi/known-failure.ts
11705
- function nonEmptyString(value) {
11706
- return typeof value === "string" && value.trim() !== "" ? value : void 0;
11707
11157
  }
11708
- function sessionStopDetails(input) {
11709
- const details = {};
11710
- const errorMessage = nonEmptyString(input.errorMessage);
11711
- if (errorMessage !== void 0) details.errorMessage = errorMessage;
11712
- const api = nonEmptyString(input.api);
11713
- if (api !== void 0) details.api = api;
11714
- const rawStopReason = nonEmptyString(input.rawStopReason);
11715
- if (rawStopReason !== void 0) details.rawStopReason = rawStopReason;
11716
- const testimony = hasUpstreamErrorTestimony(input);
11717
- if (testimony) {
11718
- const provider = nonEmptyString(input.provider);
11719
- if (provider !== void 0) details.provider = provider;
11720
- const model = nonEmptyString(input.model);
11721
- if (model !== void 0) details.model = model;
11158
+ function shortNameFromPinnedRef(refName) {
11159
+ const short = refName.startsWith("refs/heads/") ? refName.slice("refs/heads/".length) : refName.startsWith("refs/tags/") ? refName.slice("refs/tags/".length) : refName.startsWith("refs/remotes/") ? refName.slice("refs/remotes/".length).replace(/^[^/]+\//, "") : refName;
11160
+ const trimmed = short.trim();
11161
+ return trimmed === "" ? void 0 : trimmed;
11162
+ }
11163
+ function branchNamesAtPinnedHead(pin) {
11164
+ const names = /* @__PURE__ */ new Set();
11165
+ for (const [refName, entry] of Object.entries(pin.refs)) {
11166
+ if (entry.peeledCommitId !== pin.targetHead) continue;
11167
+ if (!refName.startsWith("refs/heads/") && !refName.startsWith("refs/remotes/")) continue;
11168
+ const short = shortNameFromPinnedRef(refName);
11169
+ if (short !== void 0) names.add(short);
11722
11170
  }
11723
- if (typeof input.httpStatus === "number") details.httpStatus = input.httpStatus;
11724
- if (input.diagnostics !== void 0) details.diagnostics = input.diagnostics;
11725
- if (testimony) Object.assign(details, projectConfirmedRemotePayload(input));
11726
- return details;
11171
+ return Object.freeze([...names]);
11727
11172
  }
11728
- function knownFailureFromProviderStop(input) {
11729
- if (input.stopReason !== "error" && input.stopReason !== "aborted") return void 0;
11730
- const diagnostic = nonEmptyString(input.errorMessage);
11731
- const details = sessionStopDetails(input);
11732
- return {
11733
- cause: hasUpstreamErrorTestimony(input) ? "provider" : "unrecognized",
11734
- ...diagnostic === void 0 ? {} : { diagnostic },
11735
- ...Object.keys(details).length === 0 ? {} : { details }
11173
+ async function gitText(root, args) {
11174
+ const { stdout } = await execGit(["-C", root, ...args], { encoding: "utf8" });
11175
+ return stdout.trim();
11176
+ }
11177
+ async function createReviewerPinnedGitReader(root = process.cwd()) {
11178
+ const discoveredRoot = await gitText(root, ["rev-parse", "--show-toplevel"]);
11179
+ const repositoryRoot = await realpath6(discoveredRoot);
11180
+ const objectFormat = await gitText(repositoryRoot, ["rev-parse", "--show-object-format"]);
11181
+ if (objectFormat !== "sha1" && objectFormat !== "sha256") throw new Error("Unsupported Git object format");
11182
+ const oidWidth = objectFormat === "sha1" ? 40 : 64;
11183
+ const targetHead = await gitText(repositoryRoot, ["rev-parse", "HEAD^{commit}"]);
11184
+ const reachableCommitIds = Object.freeze((await gitText(repositoryRoot, ["rev-list", targetHead])).split("\n").filter(Boolean));
11185
+ const refs = parseReviewerRefSnapshot(await gitText(repositoryRoot, reviewerRefSnapshotArgs()));
11186
+ const pin = immutableReviewerPin({ repositoryRoot, objectFormat, targetHead, refs });
11187
+ const invalid = (code, diagnostic, cause) => {
11188
+ throw new ReviewerCorrectablePreflightError(code, diagnostic, cause === void 0 ? void 0 : { cause });
11189
+ };
11190
+ const symbolic = (base) => {
11191
+ const selected = Object.hasOwn(refs, base) ? base : (() => {
11192
+ const candidates = [`refs/heads/${base}`, `refs/tags/${base}`, `refs/remotes/${base}`].filter((name) => Object.hasOwn(refs, name));
11193
+ if (candidates.length > 1) invalid("base-invalid", "base revision is ambiguous across pinned refs");
11194
+ return candidates[0];
11195
+ })();
11196
+ if (selected === void 0) return void 0;
11197
+ const commit = refs[selected]?.peeledCommitId;
11198
+ if (commit === null) invalid("base-invalid", "base revision ref must resolve to a commit");
11199
+ return commit ?? void 0;
11736
11200
  };
11201
+ return Object.freeze({
11202
+ pin,
11203
+ async snapshot() {
11204
+ const liveObjectFormat = await gitText(repositoryRoot, ["rev-parse", "--show-object-format"]);
11205
+ if (liveObjectFormat !== "sha1" && liveObjectFormat !== "sha256") throw new Error("Unsupported Git object format");
11206
+ return immutableReviewerPin({ repositoryRoot, objectFormat: liveObjectFormat, targetHead: await gitText(repositoryRoot, ["rev-parse", "HEAD^{commit}"]), refs: parseReviewerRefSnapshot(await gitText(repositoryRoot, reviewerRefSnapshotArgs())) });
11207
+ },
11208
+ async resolve(base) {
11209
+ if (!/^[A-Za-z0-9._/~^+-]+$/.test(base) || base.startsWith("-") || base.includes("..") || base.includes("@{")) {
11210
+ invalid("base-invalid", "base revision syntax is invalid or uses a forbidden revision form");
11211
+ }
11212
+ let commit;
11213
+ const headExpression = /^HEAD((?:~[0-9]+|\^[0-9]+)*)$/.exec(base);
11214
+ if (headExpression) {
11215
+ try {
11216
+ commit = await gitText(repositoryRoot, ["rev-parse", "--verify", `${targetHead}${headExpression[1]}^{commit}`]);
11217
+ } catch (error) {
11218
+ if (exitCode(error) === 128) {
11219
+ const repository = await repositoryIsAvailable(repositoryRoot);
11220
+ if (repository.available) invalid("base-invalid", "base revision HEAD ancestry expression must resolve to a reachable commit", error);
11221
+ }
11222
+ throw error;
11223
+ }
11224
+ } else if (new RegExp(`^[0-9a-f]{${oidWidth}}$`).test(base)) commit = base;
11225
+ else if (new RegExp(`^[0-9a-f]{4,${oidWidth - 1}}$`).test(base) && !(objectFormat === "sha256" && base.length === 40)) {
11226
+ const matches = reachableCommitIds.filter((candidate) => candidate.startsWith(base));
11227
+ if (matches.length !== 1) invalid("base-invalid", "base revision abbreviation must identify exactly one reachable commit");
11228
+ commit = matches[0];
11229
+ } else commit = symbolic(base);
11230
+ if (commit === void 0) invalid("base-invalid", "base revision must name an existing pinned ref or reachable commit");
11231
+ try {
11232
+ commit = await gitText(repositoryRoot, ["rev-parse", "--verify", `${commit}^{commit}`]);
11233
+ } catch (error) {
11234
+ if (exitCode(error) === 128) {
11235
+ const repository = await repositoryIsAvailable(repositoryRoot);
11236
+ if (repository.available) invalid("base-invalid", "base revision must resolve to an existing commit", error);
11237
+ }
11238
+ throw error;
11239
+ }
11240
+ try {
11241
+ await gitText(repositoryRoot, ["merge-base", "--is-ancestor", commit, targetHead]);
11242
+ } catch (error) {
11243
+ if (exitCode(error) === 1) invalid("base-invalid", "base revision must be an ancestor of the pinned target", error);
11244
+ throw error;
11245
+ }
11246
+ return commit;
11247
+ },
11248
+ async range(base) {
11249
+ let mergeBase;
11250
+ try {
11251
+ mergeBase = await gitText(repositoryRoot, ["merge-base", base, targetHead]);
11252
+ } catch (error) {
11253
+ if (exitCode(error) === 1) {
11254
+ invalid("range-invalid", "review range requires a common ancestor for base and pinned target", error);
11255
+ }
11256
+ throw error;
11257
+ }
11258
+ if (!mergeBase) invalid("range-invalid", "review range requires a common ancestor for base and pinned target");
11259
+ const diffCommand = `git diff ${mergeBase}...${targetHead}`;
11260
+ const [{ stdout: diff }, commitsText] = await Promise.all([
11261
+ execGit(["-C", repositoryRoot, "diff", `${mergeBase}...${targetHead}`], { encoding: "buffer", maxBuffer: 64 * 1024 * 1024 }),
11262
+ gitText(repositoryRoot, ["rev-list", "--reverse", `${mergeBase}..${targetHead}`])
11263
+ ]);
11264
+ if (diff.length === 0) invalid("range-invalid", "review range must contain a non-empty diff between base and pinned target");
11265
+ return Object.freeze({ base: mergeBase, target: targetHead, diffCommand, diffSha256: sha256Hex(Uint8Array.from(diff)), commits: Object.freeze(commitsText ? commitsText.split("\n") : []) });
11266
+ },
11267
+ async featureTokens() {
11268
+ const names = /* @__PURE__ */ new Set();
11269
+ for (const [refName, entry] of Object.entries(pin.refs)) {
11270
+ if (entry.peeledCommitId !== targetHead) continue;
11271
+ const short = shortNameFromPinnedRef(refName);
11272
+ if (short !== void 0) names.add(short);
11273
+ }
11274
+ return Object.freeze([...names]);
11275
+ },
11276
+ async listSpecCandidatePaths() {
11277
+ const roots = ["docs", "specs", ".scratch"];
11278
+ const text = await gitText(repositoryRoot, [
11279
+ "ls-tree",
11280
+ "-r",
11281
+ "--name-only",
11282
+ targetHead,
11283
+ "--",
11284
+ ...roots
11285
+ ]);
11286
+ return Object.freeze(text === "" ? [] : text.split("\n").filter((line2) => line2.length > 0));
11287
+ },
11288
+ async originRepository() {
11289
+ let remoteUrl;
11290
+ try {
11291
+ remoteUrl = await gitText(repositoryRoot, ["remote", "get-url", "origin"]);
11292
+ } catch (error) {
11293
+ if (isConfirmedMissingOriginRemote(error)) return void 0;
11294
+ throw error;
11295
+ }
11296
+ return parseGitHubOriginRemote(remoteUrl);
11297
+ },
11298
+ async commitMessagesNewestFirst(base) {
11299
+ const text = await gitText(repositoryRoot, [
11300
+ "log",
11301
+ "--format=%s",
11302
+ `${base}..${targetHead}`
11303
+ ]);
11304
+ return Object.freeze(text === "" ? [] : text.split("\n"));
11305
+ },
11306
+ async readPinnedText(path) {
11307
+ if (path.length === 0 || path.startsWith("/") || path.includes("\0") || path.split("/").some((part) => part === ".." || part === "")) {
11308
+ return void 0;
11309
+ }
11310
+ try {
11311
+ const { stdout } = await execGit(
11312
+ ["-C", repositoryRoot, "show", `${targetHead}:${path}`],
11313
+ { encoding: "utf8", maxBuffer: 8 * 1024 * 1024 }
11314
+ );
11315
+ return stdout;
11316
+ } catch (error) {
11317
+ if (isConfirmedPinnedPathAbsent(error, path)) return void 0;
11318
+ throw error;
11319
+ }
11320
+ }
11321
+ });
11322
+ }
11323
+ function parseGitHubOriginRemote(remoteUrl) {
11324
+ const trimmed = remoteUrl.trim();
11325
+ if (trimmed.length === 0) return void 0;
11326
+ const scp = /^git@github\.com:([^/\s]+)\/([^/\s]+?)(?:\.git)?$/i.exec(trimmed);
11327
+ if (scp) return normalizeOrigin(scp[1], scp[2]);
11328
+ const ssh = /^ssh:\/\/git@github\.com\/([^/\s]+)\/([^/\s]+?)(?:\.git)?\/?$/i.exec(trimmed);
11329
+ if (ssh) return normalizeOrigin(ssh[1], ssh[2]);
11330
+ let parsed;
11331
+ try {
11332
+ parsed = new URL(trimmed);
11333
+ } catch {
11334
+ return void 0;
11335
+ }
11336
+ if (!/^github\.com$/i.test(parsed.hostname)) return void 0;
11337
+ if (parsed.search !== "" || parsed.hash !== "") return void 0;
11338
+ const parts = parsed.pathname.split("/").filter((p) => p.length > 0);
11339
+ if (parts.length !== 2) return void 0;
11340
+ return normalizeOrigin(parts[0], parts[1]);
11341
+ }
11342
+ function normalizeOrigin(ownerRaw, repoRaw) {
11343
+ const owner = ownerRaw.trim();
11344
+ const repo = stripGitSuffix2(repoRaw.trim());
11345
+ if (owner.length === 0 || repo.length === 0) return void 0;
11346
+ if (/[/?#@\\]/.test(owner) || /[/?#@\\]/.test(repo)) return void 0;
11347
+ return Object.freeze({ owner, repo });
11737
11348
  }
11738
- var init_known_failure = __esm({
11739
- "src/pi/known-failure.ts"() {
11349
+ function stripGitSuffix2(name) {
11350
+ return name.toLowerCase().endsWith(".git") ? name.slice(0, -4) : name;
11351
+ }
11352
+ var execFileAsync3, immutableReviewerPin;
11353
+ var init_reviewer_pinned_git = __esm({
11354
+ "src/reviewer-pinned-git.ts"() {
11740
11355
  "use strict";
11741
- init_upstream_error_testimony();
11742
- init_upstream_error_testimony();
11356
+ init_reviewer_git_snapshot();
11357
+ init_sha256();
11358
+ init_reviewer_preflight_error();
11359
+ execFileAsync3 = promisify3(execFile3);
11360
+ immutableReviewerPin = (pin) => Object.freeze({
11361
+ repositoryRoot: pin.repositoryRoot,
11362
+ objectFormat: pin.objectFormat,
11363
+ targetHead: pin.targetHead,
11364
+ refs: immutableReviewerRefs(pin.refs)
11365
+ });
11743
11366
  }
11744
11367
  });
11745
11368
 
@@ -12113,12 +11736,12 @@ var init_reviewer_dispatch = __esm({
12113
11736
  // src/public-cli/reviewer-dispatch-rejection.ts
12114
11737
  import { writeFileSync as writeFileSync4 } from "node:fs";
12115
11738
  import { readFile as readFile13, unlink as unlink3 } from "node:fs/promises";
12116
- import { join as join22 } from "node:path";
11739
+ import { join as join21 } from "node:path";
12117
11740
  function isReviewerPreflightViolation(value) {
12118
11741
  return typeof value === "string" && REVIEWER_PREFLIGHT_VIOLATIONS.includes(value);
12119
11742
  }
12120
11743
  function reviewerDispatchRejectionPath(runDirectory) {
12121
- return join22(runDirectory, REVIEWER_DISPATCH_REJECTION_FILE);
11744
+ return join21(runDirectory, REVIEWER_DISPATCH_REJECTION_FILE);
12122
11745
  }
12123
11746
  function recordReviewerDispatchRejectionSync(runDirectory, rejection) {
12124
11747
  writeFileSync4(
@@ -13284,7 +12907,7 @@ var init_collector_ledger = __esm({
13284
12907
  // src/package-resources/method-skill.ts
13285
12908
  import { createHash as createHash7 } from "node:crypto";
13286
12909
  import { readFile as readFile14, realpath as realpath7 } from "node:fs/promises";
13287
- import { join as join23 } from "node:path";
12910
+ import { join as join22 } from "node:path";
13288
12911
  function gitBlobOid(bytes) {
13289
12912
  const body = typeof bytes === "string" ? Buffer.from(bytes, "utf8") : Buffer.from(bytes);
13290
12913
  const header = Buffer.from(`blob ${body.byteLength}\0`, "utf8");
@@ -13301,10 +12924,10 @@ function packagedMethodSkillRelativeDirectory(name) {
13301
12924
  return `${METHOD_SKILL_RELATIVE_ROOT}/${name}`;
13302
12925
  }
13303
12926
  function resolvePackagedMethodSkillRoot(packageRoot, name) {
13304
- return join23(packageRoot, packagedMethodSkillRelativeDirectory(name));
12927
+ return join22(packageRoot, packagedMethodSkillRelativeDirectory(name));
13305
12928
  }
13306
12929
  function resolvePackagedMethodSkillPath(packageRoot, name) {
13307
- return join23(resolvePackagedMethodSkillRoot(packageRoot, name), "SKILL.md");
12930
+ return join22(resolvePackagedMethodSkillRoot(packageRoot, name), "SKILL.md");
13308
12931
  }
13309
12932
  function isRecord17(value) {
13310
12933
  return typeof value === "object" && value !== null && !Array.isArray(value);
@@ -13398,8 +13021,8 @@ function parseProvenance(raw, expectedName) {
13398
13021
  }
13399
13022
  async function loadPackagedMethodSkillMaterial(packageRoot, name) {
13400
13023
  const rootDirectory = resolvePackagedMethodSkillRoot(packageRoot, name);
13401
- const skillPathConfigured = join23(rootDirectory, "SKILL.md");
13402
- const provenancePath = join23(rootDirectory, "provenance.json");
13024
+ const skillPathConfigured = join22(rootDirectory, "SKILL.md");
13025
+ const provenancePath = join22(rootDirectory, "provenance.json");
13403
13026
  let provenanceRaw;
13404
13027
  try {
13405
13028
  provenanceRaw = await readFile14(provenancePath, "utf8");
@@ -13416,7 +13039,7 @@ async function loadPackagedMethodSkillMaterial(packageRoot, name) {
13416
13039
  }
13417
13040
  const provenance = parseProvenance(provenanceJson, name);
13418
13041
  for (const [rel, expected] of Object.entries(provenance.files)) {
13419
- const absolute = join23(rootDirectory, rel);
13042
+ const absolute = join22(rootDirectory, rel);
13420
13043
  let bytes;
13421
13044
  try {
13422
13045
  bytes = await readFile14(absolute);
@@ -13932,7 +13555,7 @@ var init_terminal = __esm({
13932
13555
  // src/public-cli/settlement.ts
13933
13556
  import { randomUUID as randomUUID3 } from "node:crypto";
13934
13557
  import { appendFile as appendFile2, readFile as readFile15, readdir as readdir5, writeFile as writeFile6 } from "node:fs/promises";
13935
- import { dirname as dirname12, join as join24 } from "node:path";
13558
+ import { dirname as dirname12, join as join23 } from "node:path";
13936
13559
  function sealedLedgerHome(admitted) {
13937
13560
  return homeFromRunDirectory(admitted.runDirectory);
13938
13561
  }
@@ -14328,7 +13951,7 @@ async function readSessionProviderStop(sessionFile) {
14328
13951
  }
14329
13952
  }
14330
13953
  async function readBoundEvidenceChildKnownFailure(sessionFile) {
14331
- const childDirectory = join24(dirname12(sessionFile), "evidence-children");
13954
+ const childDirectory = join23(dirname12(sessionFile), "evidence-children");
14332
13955
  let names;
14333
13956
  try {
14334
13957
  names = await readdir5(childDirectory);
@@ -14339,7 +13962,7 @@ async function readBoundEvidenceChildKnownFailure(sessionFile) {
14339
13962
  for (const file of names.filter((name) => name.endsWith(".jsonl")).sort().reverse()) {
14340
13963
  let entries;
14341
13964
  try {
14342
- entries = await readBoundSessionEntries(join24(childDirectory, file));
13965
+ entries = await readBoundSessionEntries(join23(childDirectory, file));
14343
13966
  } catch (error) {
14344
13967
  throw sessionReadFailure(error, "failed to read discovered evidence-child session");
14345
13968
  }
@@ -14393,7 +14016,7 @@ async function loadBoundAuditorVolumes(sessionFile) {
14393
14016
  latestParentUserIndex = i;
14394
14017
  break;
14395
14018
  }
14396
- const childDirectories = [join24(dirname12(sessionFile), "auditor-roles")];
14019
+ const childDirectories = [join23(dirname12(sessionFile), "auditor-roles")];
14397
14020
  const valid = [];
14398
14021
  let sawAnyDirectory = false;
14399
14022
  for (const childDirectory of childDirectories) {
@@ -14408,7 +14031,7 @@ async function loadBoundAuditorVolumes(sessionFile) {
14408
14031
  for (const file of names.filter((name) => name.endsWith(".jsonl")).sort().reverse()) {
14409
14032
  let entries;
14410
14033
  try {
14411
- entries = await readBoundSessionEntries(join24(childDirectory, file));
14034
+ entries = await readBoundSessionEntries(join23(childDirectory, file));
14412
14035
  } catch (error) {
14413
14036
  throw sessionReadFailure(error, "failed to read discovered auditor session");
14414
14037
  }
@@ -14908,8 +14531,8 @@ function projectTerminalGateFact(rounds) {
14908
14531
  };
14909
14532
  }
14910
14533
  async function extractGateFactFromSessionDirectory(sessionDirectory, options = {}) {
14911
- const directories = [join24(sessionDirectory, "auditor-roles")];
14912
- const parentSessionFile = options.parentSessionFile ?? join24(sessionDirectory, "session.jsonl");
14534
+ const directories = [join23(sessionDirectory, "auditor-roles")];
14535
+ const parentSessionFile = options.parentSessionFile ?? join23(sessionDirectory, "session.jsonl");
14913
14536
  const rounds = await readAnalystGateCyclesFromAuditorRoles(directories, {
14914
14537
  parentSessionFile
14915
14538
  });
@@ -15007,8 +14630,8 @@ async function extractNavigatorFactFromAdmittedSession(sessionFile) {
15007
14630
  async function publishJudgeArtifacts(admitted, roleOutcome, coordinates) {
15008
14631
  await appendRunAttemptHistory({ role: admitted.role, runId: admitted.runId, sessionFile: coordinates.sessionFile }, roleOutcome);
15009
14632
  const artifactsDir = await ensureRunArtifactsDir(admitted.runDirectory);
15010
- const reportPath = join24(artifactsDir, "report.json");
15011
- const evidencePath = join24(artifactsDir, "evidence.json");
14633
+ const reportPath = join23(artifactsDir, "report.json");
14634
+ const evidencePath = join23(artifactsDir, "evidence.json");
15012
14635
  await writeFile6(
15013
14636
  reportPath,
15014
14637
  `${JSON.stringify(
@@ -15098,8 +14721,8 @@ async function trySettleJudgeTerminalResult(admitted, authority) {
15098
14721
  async function publishDoctorArtifacts(admitted, roleOutcome, coordinates, options = {}) {
15099
14722
  await appendRunAttemptHistory({ role: admitted.role, runId: admitted.runId, sessionFile: coordinates.sessionFile }, roleOutcome);
15100
14723
  const artifactsDir = await ensureRunArtifactsDir(admitted.runDirectory);
15101
- const reportPath = join24(artifactsDir, "report.json");
15102
- const evidencePath = join24(artifactsDir, "evidence.json");
14724
+ const reportPath = join23(artifactsDir, "report.json");
14725
+ const evidencePath = join23(artifactsDir, "evidence.json");
15103
14726
  await writeFile6(
15104
14727
  reportPath,
15105
14728
  `${JSON.stringify(
@@ -15332,7 +14955,7 @@ function uniqueFailureFallbackDirs(runDirectory, baseDir) {
15332
14955
  return dirs;
15333
14956
  }
15334
14957
  async function resolveFailureArtifactsBase(runDirectory) {
15335
- const artifactsDir = join24(runDirectory, "artifacts");
14958
+ const artifactsDir = join23(runDirectory, "artifacts");
15336
14959
  try {
15337
14960
  await ensureRunArtifactsDir(runDirectory);
15338
14961
  return { baseDir: artifactsDir };
@@ -15348,7 +14971,7 @@ async function writeFailureJsonRetainingCause(preferredCandidates, uniqueFallbac
15348
14971
  const candidates = [
15349
14972
  ...preferredCandidates,
15350
14973
  // One unique name per fallback dir — collisions on fixed names cannot exhaust this.
15351
- ...uniqueFallbackDirs.map((dir) => join24(dir, `${stem}.${randomUUID3()}.json`))
14974
+ ...uniqueFallbackDirs.map((dir) => join23(dir, `${stem}.${randomUUID3()}.json`))
15352
14975
  ];
15353
14976
  for (let i = 0; i < candidates.length; i += 1) {
15354
14977
  const path = candidates[i];
@@ -15393,26 +15016,26 @@ async function publishFailureArtifacts(admitted, failure2, authority) {
15393
15016
  } catch (error) {
15394
15017
  priorIssues.push(publicationAttemptFromError(sessionFile, error));
15395
15018
  }
15396
- const underArtifacts = baseDir === join24(admitted.runDirectory, "artifacts");
15019
+ const underArtifacts = baseDir === join23(admitted.runDirectory, "artifacts");
15397
15020
  const uniqueFallbackDirs = uniqueFailureFallbackDirs(
15398
15021
  admitted.runDirectory,
15399
15022
  baseDir
15400
15023
  );
15401
15024
  const errorCandidates = underArtifacts ? [
15402
- join24(baseDir, "error.json"),
15403
- join24(baseDir, "error.settlement.json"),
15404
- join24(admitted.runDirectory, "error.settlement.json")
15025
+ join23(baseDir, "error.json"),
15026
+ join23(baseDir, "error.settlement.json"),
15027
+ join23(admitted.runDirectory, "error.settlement.json")
15405
15028
  ] : [
15406
- join24(baseDir, "error.settlement.json"),
15407
- join24(baseDir, "error.json")
15029
+ join23(baseDir, "error.settlement.json"),
15030
+ join23(baseDir, "error.json")
15408
15031
  ];
15409
15032
  const evidenceCandidates = underArtifacts ? [
15410
- join24(baseDir, "evidence.json"),
15411
- join24(baseDir, "evidence.settlement.json"),
15412
- join24(admitted.runDirectory, "evidence.settlement.json")
15033
+ join23(baseDir, "evidence.json"),
15034
+ join23(baseDir, "evidence.settlement.json"),
15035
+ join23(admitted.runDirectory, "evidence.settlement.json")
15413
15036
  ] : [
15414
- join24(baseDir, "evidence.settlement.json"),
15415
- join24(baseDir, "evidence.json")
15037
+ join23(baseDir, "evidence.settlement.json"),
15038
+ join23(baseDir, "evidence.json")
15416
15039
  ];
15417
15040
  const errorPayloadBase = {
15418
15041
  kind: "error",
@@ -15683,7 +15306,7 @@ var init_settlement = __esm({
15683
15306
  import { constants as fsConstants } from "node:fs";
15684
15307
  import { randomUUID as randomUUID4 } from "node:crypto";
15685
15308
  import { lstat as lstat5, mkdir as mkdir4, open as open2 } from "node:fs/promises";
15686
- import { join as join25 } from "node:path";
15309
+ import { join as join24 } from "node:path";
15687
15310
  function presentTerminal(terminal, io) {
15688
15311
  if (terminal.roleOutcome.kind === "failure" || terminal.roleOutcome.kind === "no_receipt") {
15689
15312
  presentFailureTerminal(terminal, io);
@@ -15702,7 +15325,7 @@ async function finalizeExceptionRunBestEffort(runDirectory, io) {
15702
15325
  }
15703
15326
  }
15704
15327
  function runArtifactsDirectory(runDirectory) {
15705
- return join25(runDirectory, "artifacts");
15328
+ return join24(runDirectory, "artifacts");
15706
15329
  }
15707
15330
  async function ensureRealArtifactsDirectory(runDirectory) {
15708
15331
  const runStat = await lstat5(runDirectory);
@@ -15785,7 +15408,7 @@ function jsonSafeReplacer() {
15785
15408
  }
15786
15409
  async function retainDispatchError(admitted, principalAuthority, sessionAppender, attempt, error) {
15787
15410
  const artifactsDir = await ensureRealArtifactsDirectory(admitted.runDirectory);
15788
- const filePath = join25(
15411
+ const filePath = join24(
15789
15412
  artifactsDir,
15790
15413
  `dispatch-error-attempt-${attempt}-${randomUUID4()}.json`
15791
15414
  );
@@ -16034,10 +15657,16 @@ var init_auto_resume = __esm({
16034
15657
  // src/public-cli/post-admission.ts
16035
15658
  import { randomUUID as randomUUID5 } from "node:crypto";
16036
15659
  import { readFile as readFile16, writeFile as writeFile7 } from "node:fs/promises";
16037
- import { isAbsolute as isAbsolute7, join as join26, resolve as resolve12 } from "node:path";
15660
+ import { isAbsolute as isAbsolute7, join as join25, resolve as resolve12 } from "node:path";
15661
+ function appendContinuationSection(continuation, section) {
15662
+ const prompt = `${continuation.prompt}
15663
+
15664
+ ${section}`;
15665
+ return continuation.kind === "initial" ? { kind: "initial", prompt } : { kind: "resume", prompt };
15666
+ }
16038
15667
  async function readInvocationHost(runDirectory) {
16039
15668
  try {
16040
- const raw = JSON.parse(await readFile16(join26(runDirectory, "invocation.json"), "utf8"));
15669
+ const raw = JSON.parse(await readFile16(join25(runDirectory, "invocation.json"), "utf8"));
16041
15670
  return typeof raw.host === "string" && raw.host.trim() !== "" ? raw.host : void 0;
16042
15671
  } catch (error) {
16043
15672
  if (error.code === "ENOENT") return void 0;
@@ -16112,18 +15741,14 @@ async function dispatchPostAdmissionTurn(input) {
16112
15741
  let previousHost;
16113
15742
  const liveHost = env.host;
16114
15743
  const principalCoordinates = admitted.principal === void 0 ? void 0 : env.principalAuthority.decode(admitted.principal);
16115
- let turnRequest;
15744
+ let hostTransition;
16116
15745
  try {
16117
15746
  previousHost = await readInvocationHost(admitted.runDirectory);
16118
- const hostTransition = previousHost !== void 0 && liveHost !== void 0 && principalCoordinates !== void 0 ? await projectHostTransitionPriorNative({
15747
+ hostTransition = previousHost !== void 0 && liveHost !== void 0 && principalCoordinates !== void 0 ? await projectHostTransitionPriorNative({
16119
15748
  previousHost,
16120
15749
  liveHost,
16121
15750
  piSessionFile: principalCoordinates.sessionFile
16122
15751
  }) : void 0;
16123
- turnRequest = env.signal === void 0 ? request : { ...request, signal: env.signal };
16124
- if (hostTransition !== void 0) {
16125
- turnRequest = { ...turnRequest, hostTransition };
16126
- }
16127
15752
  } catch (error) {
16128
15753
  return await presentControlledFailure(
16129
15754
  admitted,
@@ -16158,6 +15783,24 @@ async function dispatchPostAdmissionTurn(input) {
16158
15783
  );
16159
15784
  }
16160
15785
  }
15786
+ let turnRequest = env.signal === void 0 ? request : { ...request, signal: env.signal };
15787
+ if (hostTransition !== void 0) {
15788
+ turnRequest = { ...turnRequest, hostTransition };
15789
+ }
15790
+ const dossierSection = await projectCaseDossierPointerSection({
15791
+ ticketNumber: admitted.ticketNumber,
15792
+ projectRoot: admitted.projectRoot,
15793
+ home: env.home
15794
+ });
15795
+ if (dossierSection !== void 0) {
15796
+ turnRequest = {
15797
+ ...turnRequest,
15798
+ continuation: appendContinuationSection(
15799
+ turnRequest.continuation,
15800
+ dossierSection
15801
+ )
15802
+ };
15803
+ }
16161
15804
  let result;
16162
15805
  try {
16163
15806
  result = await env.roleTurnHost.executeTurn(turnRequest);
@@ -16177,7 +15820,7 @@ async function dispatchPostAdmissionTurn(input) {
16177
15820
  }
16178
15821
  try {
16179
15822
  await writeFile7(
16180
- join26(admitted.runDirectory, "stderr.log"),
15823
+ join25(admitted.runDirectory, "stderr.log"),
16181
15824
  result.stderr,
16182
15825
  "utf8"
16183
15826
  );
@@ -16286,7 +15929,7 @@ function resumeTurnRequestProjectionOptions(admitted, request, env, summonsPrepa
16286
15929
  }
16287
15930
  function isAlreadyFrozenSummonsAttachment(runDirectory, attachmentPath) {
16288
15931
  const absolute = isAbsolute7(attachmentPath) ? attachmentPath : resolve12(attachmentPath);
16289
- return pathContainedIn(join26(runDirectory, "attachments"), absolute);
15932
+ return pathContainedIn(join25(runDirectory, "attachments"), absolute);
16290
15933
  }
16291
15934
  async function prepareSummonsResumeMaterials(runDirectory, summons) {
16292
15935
  if (summons === void 0) return void 0;
@@ -16578,6 +16221,7 @@ var init_post_admission = __esm({
16578
16221
  init_cli_errors();
16579
16222
  init_invocation();
16580
16223
  init_activation_ledger_topology();
16224
+ init_case_dossier_delivery();
16581
16225
  init_host_transition_prior_native();
16582
16226
  init_public_run_credentials();
16583
16227
  init_run_lifecycle();
@@ -16820,11 +16464,11 @@ async function runPublicInspector(argv, env, io, parseInspectorArgv2) {
16820
16464
  throw error;
16821
16465
  }
16822
16466
  const projectRoot = parsed.project ?? env.cwd;
16823
- const ticketProbe = await probeInstructionTicket(
16824
- parsed.instruction,
16467
+ const reusedTicketNumber = await resolveKnownTicketNumber({
16468
+ instruction: parsed.instruction,
16825
16469
  projectRoot,
16826
- env
16827
- );
16470
+ home: env.home
16471
+ });
16828
16472
  const parentRunPath = parentRunPathFromGatePointerInstruction(parsed.instruction);
16829
16473
  if (parentRunPath !== void 0) {
16830
16474
  const summons = {
@@ -16892,7 +16536,7 @@ async function runPublicInspector(argv, env, io, parseInspectorArgv2) {
16892
16536
  request: turnRequest,
16893
16537
  adapters: inspectorAdapters({
16894
16538
  beforeDispatch: async (admittedSeat) => {
16895
- await applyInstructionTicketProbe(admittedSeat, ticketProbe);
16539
+ await bindReusedTicketNumber(admittedSeat, reusedTicketNumber);
16896
16540
  }
16897
16541
  }),
16898
16542
  ...env.engine === void 0 ? {} : { effectiveEngine: env.engine }
@@ -17075,7 +16719,7 @@ async function runPublicInstructionSeat(argv, env, io, role, parseArgv) {
17075
16719
  let auditorSubject;
17076
16720
  let auditorSourceRun;
17077
16721
  let auditorSourceTicket;
17078
- let ticketProbe;
16722
+ let reusedTicketNumber;
17079
16723
  const projectRoot = parsed.project ?? env.cwd;
17080
16724
  if (role === "auditor") {
17081
16725
  if (parsed.subject !== "judge" && parsed.subject !== "doctor") {
@@ -17111,11 +16755,11 @@ async function runPublicInstructionSeat(argv, env, io, role, parseArgv) {
17111
16755
  return { exitCode: 2 };
17112
16756
  }
17113
16757
  } else {
17114
- ticketProbe = await probeInstructionTicket(
17115
- parsed.instruction,
16758
+ reusedTicketNumber = await resolveKnownTicketNumber({
16759
+ instruction: parsed.instruction,
17116
16760
  projectRoot,
17117
- env
17118
- );
16761
+ home: env.home
16762
+ });
17119
16763
  }
17120
16764
  const summons = {
17121
16765
  instruction: parsed.instruction,
@@ -17141,24 +16785,21 @@ async function runPublicInstructionSeat(argv, env, io, role, parseArgv) {
17141
16785
  })
17142
16786
  });
17143
16787
  if (resumed !== void 0) return resumed;
17144
- } else {
17145
- const probedTicketNumber = ticketProbe === void 0 ? void 0 : ticketNumberFromProbe(ticketProbe);
17146
- if (probedTicketNumber !== void 0) {
17147
- const resumed = await tryResumeSameTicketSeatRun({
17148
- home: env.home,
17149
- projectRoot,
17150
- role,
17151
- ticketNumber: probedTicketNumber,
17152
- freshSummons: env.freshSummons,
17153
- summons,
17154
- resume: (runId, materials) => runPublicInstructionSeatResume(
17155
- { runId, ...materials === void 0 ? {} : { summons: materials } },
17156
- env,
17157
- io
17158
- )
17159
- });
17160
- if (resumed !== void 0) return resumed;
17161
- }
16788
+ } else if (reusedTicketNumber !== void 0) {
16789
+ const resumed = await tryResumeSameTicketSeatRun({
16790
+ home: env.home,
16791
+ projectRoot,
16792
+ role,
16793
+ ticketNumber: reusedTicketNumber,
16794
+ freshSummons: env.freshSummons,
16795
+ summons,
16796
+ resume: (runId, materials) => runPublicInstructionSeatResume(
16797
+ { runId, ...materials === void 0 ? {} : { summons: materials } },
16798
+ env,
16799
+ io
16800
+ )
16801
+ });
16802
+ if (resumed !== void 0) return resumed;
17162
16803
  }
17163
16804
  let admitted;
17164
16805
  try {
@@ -17216,8 +16857,8 @@ async function runPublicInstructionSeat(argv, env, io, role, parseArgv) {
17216
16857
  beforeDispatch: async (admittedSeat) => {
17217
16858
  if (auditorSourceTicket !== void 0) {
17218
16859
  await bindAdmittedTicketNumber(admittedSeat, auditorSourceTicket);
17219
- } else if (ticketProbe !== void 0) {
17220
- await applyInstructionTicketProbe(admittedSeat, ticketProbe);
16860
+ } else {
16861
+ await bindReusedTicketNumber(admittedSeat, reusedTicketNumber);
17221
16862
  }
17222
16863
  }
17223
16864
  }),
@@ -17471,7 +17112,7 @@ __export(public_role_summons_exports, {
17471
17112
  summonPublicRole: () => summonPublicRole
17472
17113
  });
17473
17114
  import { existsSync as existsSync9 } from "node:fs";
17474
- import { join as join27 } from "node:path";
17115
+ import { join as join26 } from "node:path";
17475
17116
  function createCapturingIo() {
17476
17117
  const chunks = [];
17477
17118
  return {
@@ -17494,7 +17135,7 @@ function parentDir(path) {
17494
17135
  function walkPackageRoot(start) {
17495
17136
  let dir = start;
17496
17137
  for (let i = 0; i < 12; i += 1) {
17497
- if (existsSync9(join27(dir, "package.json")) && existsSync9(join27(dir, "souls"))) {
17138
+ if (existsSync9(join26(dir, "package.json")) && existsSync9(join26(dir, "souls"))) {
17498
17139
  return dir;
17499
17140
  }
17500
17141
  const parent = parentDir(dir);
@@ -17610,7 +17251,7 @@ async function createSummonEnv(options) {
17610
17251
  async function summonPublicRole(options) {
17611
17252
  const packageRoot = resolveSummonsPackageRoot(options.packageRoot);
17612
17253
  const home = await resolveSummonHome(options);
17613
- const agentDir = options.agentDir ?? process.env.PI_CODING_AGENT_DIR ?? join27(home, ".pi", "agent");
17254
+ const agentDir = options.agentDir ?? process.env.PI_CODING_AGENT_DIR ?? join26(home, ".pi", "agent");
17614
17255
  const {
17615
17256
  loadCredentialProviders: loadCredentialProviders2,
17616
17257
  loadPublicCliConfig: loadPublicCliConfig2,
@@ -18076,11 +17717,11 @@ var init_navigator_session_contracts = __esm({
18076
17717
 
18077
17718
  // src/archivist-record-topology.ts
18078
17719
  import { createHash as createHash8 } from "node:crypto";
18079
- import { join as join28 } from "node:path";
17720
+ import { join as join27 } from "node:path";
18080
17721
  function subjectKeyedRecordDirectory(input) {
18081
17722
  const ledgerHome = input.parentSessionFile !== void 0 && input.parentSessionFile.length > 0 ? resolveActivationLedgerHomeForPath(input.parentSessionFile) : resolveActivationLedgerHome(input.home);
18082
17723
  const digest = createHash8("sha256").update(input.subject).digest("hex").slice(0, 32);
18083
- return join28(
17724
+ return join27(
18084
17725
  activationBookDirectory(ledgerHome, resolveBookKeyFromGit(input.cwd)),
18085
17726
  input.kind,
18086
17727
  digest
@@ -18104,13 +17745,13 @@ __export(archivist_record_entry_exports, {
18104
17745
  createRecordSessionOpen: () => createRecordSessionOpen,
18105
17746
  subjectKeyedRecordDirectory: () => subjectKeyedRecordDirectory
18106
17747
  });
18107
- import { existsSync as existsSync10, mkdirSync as mkdirSync4, readFileSync as readFileSync5, realpathSync as realpathSync2, writeFileSync as writeFileSync5 } from "node:fs";
18108
- import { dirname as dirname13, resolve as resolve13, join as join29 } from "node:path";
17748
+ import { existsSync as existsSync10, mkdirSync as mkdirSync4, readFileSync as readFileSync3, realpathSync as realpathSync2, writeFileSync as writeFileSync5 } from "node:fs";
17749
+ import { dirname as dirname13, resolve as resolve13, join as join28 } from "node:path";
18109
17750
  import { SessionManager } from "@earendil-works/pi-coding-agent";
18110
17751
  function readCurrentSession(sessionDir) {
18111
- const ledger = join29(sessionDir, CURRENT_SESSION_LEDGER);
17752
+ const ledger = join28(sessionDir, CURRENT_SESSION_LEDGER);
18112
17753
  try {
18113
- const value = JSON.parse(readFileSync5(ledger, "utf8"));
17754
+ const value = JSON.parse(readFileSync3(ledger, "utf8"));
18114
17755
  if (typeof value !== "object" || value === null || typeof value.sessionFile !== "string" || value.sessionFile.length === 0) {
18115
17756
  throw new Error("sessionFile is missing");
18116
17757
  }
@@ -18123,7 +17764,7 @@ function readCurrentSession(sessionDir) {
18123
17764
  }
18124
17765
  }
18125
17766
  function writeCurrentSession(sessionDir, sessionFile) {
18126
- const ledger = join29(sessionDir, CURRENT_SESSION_LEDGER);
17767
+ const ledger = join28(sessionDir, CURRENT_SESSION_LEDGER);
18127
17768
  try {
18128
17769
  writeFileSync5(ledger, `${JSON.stringify({ sessionFile })}
18129
17770
  `, { flag: "wx" });
@@ -18184,7 +17825,7 @@ function createRecordSessionOpen(options) {
18184
17825
  return { session: SessionManager.inMemory(cwd), resumed: false };
18185
17826
  } else {
18186
17827
  const parentResolved = resolve13(parentFile);
18187
- sessionDir = physicallyContainedIn(ledgerHome, parentResolved) ? join29(dirname13(parentResolved), options.kind) : join29(activationBookDirectory(ledgerHome, resolveBookKeyFromGit(cwd)), options.kind);
17828
+ sessionDir = physicallyContainedIn(ledgerHome, parentResolved) ? join28(dirname13(parentResolved), options.kind) : join28(activationBookDirectory(ledgerHome, resolveBookKeyFromGit(cwd)), options.kind);
18188
17829
  parentSession = parentFile;
18189
17830
  }
18190
17831
  const nestAlreadyExists = existsSync10(sessionDir);
@@ -18223,7 +17864,7 @@ function createRecordSession(options) {
18223
17864
  return createRecordSessionOpen(options).session;
18224
17865
  }
18225
17866
  function bookDirectOfficerRunPointer(options) {
18226
- const nest = join29(dirname13(options.parentSessionFile), "auditor-roles");
17867
+ const nest = join28(dirname13(options.parentSessionFile), "auditor-roles");
18227
17868
  mkdirSync4(nest, { recursive: true });
18228
17869
  const pointer = {
18229
17870
  version: 1,
@@ -18233,7 +17874,7 @@ function bookDirectOfficerRunPointer(options) {
18233
17874
  ...options.runDirectory !== void 0 && options.runDirectory.trim() !== "" ? { runDirectory: options.runDirectory } : {}
18234
17875
  };
18235
17876
  writeFileSync5(
18236
- join29(nest, `${options.officer}-${Date.now().toString(36)}.pointer.json`),
17877
+ join28(nest, `${options.officer}-${Date.now().toString(36)}.pointer.json`),
18237
17878
  `${JSON.stringify(pointer)}
18238
17879
  `,
18239
17880
  "utf8"
@@ -20810,6 +20451,185 @@ var init_diarist_role = __esm({
20810
20451
  }
20811
20452
  });
20812
20453
 
20454
+ // src/diarist-mechanical.ts
20455
+ function extractCornerQuotes(text, minLength = DEFAULT_QUOTE_MIN) {
20456
+ const out = [];
20457
+ const re = /「([^」]+)」/g;
20458
+ let match;
20459
+ while ((match = re.exec(text)) !== null) {
20460
+ const q = match[1].trim();
20461
+ if (q.length >= minLength) out.push(q);
20462
+ }
20463
+ return out;
20464
+ }
20465
+ function buildDiaristAnchors(input) {
20466
+ const fromBody = input.ticketBody === void 0 ? [] : extractCornerQuotes(input.ticketBody);
20467
+ const quotes = [...fromBody, ...input.extraQuotes ?? []];
20468
+ const seen = /* @__PURE__ */ new Set();
20469
+ const uniqueQuotes = [];
20470
+ for (const q of quotes) {
20471
+ if (seen.has(q)) continue;
20472
+ seen.add(q);
20473
+ uniqueQuotes.push(q);
20474
+ }
20475
+ return {
20476
+ ticketNumber: input.ticketNumber,
20477
+ quotes: uniqueQuotes
20478
+ };
20479
+ }
20480
+ function verifyQuotesVerbatim(sourceText, quotes) {
20481
+ const failed2 = [];
20482
+ for (const q of quotes) {
20483
+ if (q.length === 0) continue;
20484
+ if (!sourceText.includes(q)) failed2.push(q);
20485
+ }
20486
+ if (failed2.length === 0) return { ok: true };
20487
+ return { ok: false, failedQuotes: failed2 };
20488
+ }
20489
+ function blockToLlmEntry(block, input) {
20490
+ const verify = verifyQuotesVerbatim(block.transcript, input.quotes);
20491
+ if (!verify.ok) {
20492
+ return {
20493
+ ok: false,
20494
+ failedQuotes: verify.failedQuotes,
20495
+ cause: `verbatim verify failed: ${verify.failedQuotes.join(" | ")}`
20496
+ };
20497
+ }
20498
+ const anchorNotes = [`#${input.anchors.ticketNumber}`];
20499
+ const seen = new Set(anchorNotes);
20500
+ for (const q of [...input.anchors.quotes, ...input.quotes]) {
20501
+ if (seen.has(q)) continue;
20502
+ seen.add(q);
20503
+ anchorNotes.push(q);
20504
+ if (anchorNotes.length >= 12) break;
20505
+ }
20506
+ return {
20507
+ ok: true,
20508
+ entry: {
20509
+ basis: {
20510
+ method: "llm-semantic",
20511
+ anchors: anchorNotes,
20512
+ ...input.note === void 0 ? {} : { note: input.note }
20513
+ },
20514
+ sourceKind: block.sourceKind,
20515
+ sourceRef: block.sourceRef,
20516
+ transcript: block.transcript,
20517
+ timestamp: block.timestamp
20518
+ }
20519
+ };
20520
+ }
20521
+ var DEFAULT_QUOTE_MIN;
20522
+ var init_diarist_mechanical = __esm({
20523
+ "src/diarist-mechanical.ts"() {
20524
+ "use strict";
20525
+ init_activation_ledger_topology();
20526
+ DEFAULT_QUOTE_MIN = 6;
20527
+ }
20528
+ });
20529
+
20530
+ // src/diarist.ts
20531
+ import { readFileSync as readFileSync4 } from "node:fs";
20532
+ function blockEntryIdentity(ticketNumber, block) {
20533
+ return ticketProvenanceEntryIdentity({
20534
+ ticketNumber,
20535
+ sourceKind: block.sourceKind,
20536
+ sourceRef: block.sourceRef,
20537
+ transcript: block.transcript
20538
+ });
20539
+ }
20540
+ function loadDiaristSourceCatalog(path) {
20541
+ const parsed = JSON.parse(readFileSync4(path, "utf8"));
20542
+ if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
20543
+ throw new Error(`diarist source catalog is not an object (${path})`);
20544
+ }
20545
+ const record4 = parsed;
20546
+ if (typeof record4.ticketNumber !== "number" || typeof record4.cwd !== "string") {
20547
+ throw new Error(`diarist source catalog is missing ticket coordinates (${path})`);
20548
+ }
20549
+ if (!Array.isArray(record4.candidates)) {
20550
+ throw new Error(`diarist source catalog is missing candidates (${path})`);
20551
+ }
20552
+ return parsed;
20553
+ }
20554
+ async function commitDiaristSelections(input) {
20555
+ const { ticketNumber, cwd } = input.catalog;
20556
+ const homeOpt = input.catalog.home === void 0 ? {} : { home: input.catalog.home };
20557
+ const volumePaths = ensureTicketProvenanceVolume(ticketNumber, cwd, input.catalog.home);
20558
+ const anchors = buildDiaristAnchors({ ticketNumber });
20559
+ const before = await readTicketProvenance(ticketNumber, cwd, input.catalog.home);
20560
+ let acceptedRows = 0;
20561
+ let rejectedQuotes = 0;
20562
+ let unknownCandidate = false;
20563
+ for (const selection of input.selections) {
20564
+ const block = input.catalog.candidates[selection.candidateIndex];
20565
+ if (block === void 0) {
20566
+ unknownCandidate = true;
20567
+ continue;
20568
+ }
20569
+ const projected = blockToLlmEntry(block, {
20570
+ anchors,
20571
+ quotes: selection.quotes,
20572
+ ...selection.note === void 0 ? {} : { note: selection.note }
20573
+ });
20574
+ if (!projected.ok) {
20575
+ rejectedQuotes += 1;
20576
+ appendQuoteVerifyFailureDiagnostic({
20577
+ ticketNumber,
20578
+ cwd,
20579
+ ...homeOpt,
20580
+ cause: projected.cause
20581
+ });
20582
+ continue;
20583
+ }
20584
+ appendTicketProvenanceEntry({
20585
+ ticketNumber,
20586
+ cwd,
20587
+ ...homeOpt,
20588
+ entry: projected.entry,
20589
+ source: "diarist"
20590
+ });
20591
+ acceptedRows += 1;
20592
+ }
20593
+ const identities = input.catalog.candidates.map(
20594
+ (block) => blockEntryIdentity(ticketNumber, block)
20595
+ );
20596
+ const alreadyWatermarked = readOfferedIdentities(ticketNumber, cwd, input.catalog.home);
20597
+ const watermarked = identities.filter((identity) => !alreadyWatermarked.has(identity)).length;
20598
+ recordOfferedIdentities({ ticketNumber, cwd, ...homeOpt, identities });
20599
+ const volume = await readTicketProvenance(ticketNumber, cwd, input.catalog.home);
20600
+ const humanViewFile = writeTicketProvenanceHumanView({
20601
+ ticketNumber,
20602
+ cwd,
20603
+ ...homeOpt,
20604
+ entries: volume.entries
20605
+ });
20606
+ return {
20607
+ ticketNumber,
20608
+ offered: input.catalog.candidates.length,
20609
+ appended: volume.entries.length - before.entries.length,
20610
+ rejectedQuotes,
20611
+ watermarked,
20612
+ volumeRecordFile: volumePaths.recordFile,
20613
+ humanViewFile,
20614
+ collectorStatus: input.catalog.candidates.length === 0 ? "skipped-no-fresh" : acceptedRows > 0 ? "ok" : input.selections.length === 0 ? "empty-selection" : "nothing-appended",
20615
+ failureCauses: [
20616
+ ...unknownCandidate ? ["unknown-candidate"] : [],
20617
+ ...rejectedQuotes > 0 ? ["quote-verify-rejected"] : []
20618
+ ]
20619
+ };
20620
+ }
20621
+ var init_diarist = __esm({
20622
+ "src/diarist.ts"() {
20623
+ "use strict";
20624
+ init_adr_path_refs();
20625
+ init_collector_github();
20626
+ init_diarist_mechanical();
20627
+ init_reviewer_pinned_git();
20628
+ init_ticket_provenance();
20629
+ init_sitian_facade();
20630
+ }
20631
+ });
20632
+
20813
20633
  // src/navigator-role.ts
20814
20634
  var NAVIGATOR_TOOL_SPEC;
20815
20635
  var init_navigator_role = __esm({
@@ -21344,11 +21164,11 @@ var init_reviewer_role = __esm({
21344
21164
  });
21345
21165
 
21346
21166
  // src/worker-submission-gates.ts
21347
- import { execFileSync as execFileSync4 } from "node:child_process";
21348
- import { existsSync as existsSync11, lstatSync as lstatSync3, readdirSync as readdirSync2, readFileSync as readFileSync6, rmdirSync, rmSync } from "node:fs";
21167
+ import { execFileSync as execFileSync3 } from "node:child_process";
21168
+ import { existsSync as existsSync11, lstatSync as lstatSync3, readdirSync as readdirSync2, readFileSync as readFileSync5, rmdirSync, rmSync } from "node:fs";
21349
21169
  import { resolve as resolve18 } from "node:path";
21350
21170
  function git2(cwd, args) {
21351
- return execFileSync4("git", args, {
21171
+ return execFileSync3("git", args, {
21352
21172
  cwd,
21353
21173
  encoding: "utf8",
21354
21174
  stdio: ["ignore", "pipe", "pipe"],
@@ -21356,7 +21176,7 @@ function git2(cwd, args) {
21356
21176
  }).trim();
21357
21177
  }
21358
21178
  function gitFile(file, args) {
21359
- return execFileSync4("git", ["config", "--file", file, ...args], {
21179
+ return execFileSync3("git", ["config", "--file", file, ...args], {
21360
21180
  encoding: "utf8",
21361
21181
  stdio: ["ignore", "pipe", "pipe"],
21362
21182
  env: { ...process.env, GIT_DIR: void 0, GIT_WORK_TREE: void 0, GIT_COMMON_DIR: void 0 }
@@ -21377,7 +21197,7 @@ function tryGetAll(file, key) {
21377
21197
  }
21378
21198
  function ownedHook(path) {
21379
21199
  if (!existsSync11(path)) return false;
21380
- return readFileSync6(path, "utf8").includes(HOOK_MARKER);
21200
+ return readFileSync5(path, "utf8").includes(HOOK_MARKER);
21381
21201
  }
21382
21202
  function escapeGitConfigValueRegex(value) {
21383
21203
  return value.replace(/[\\^$.*+?()[\]{}|]/g, "\\$&");
@@ -23660,7 +23480,7 @@ __export(in_process_session_exports, {
23660
23480
  });
23661
23481
  import { mkdtemp as mkdtemp2, rm as rm2 } from "node:fs/promises";
23662
23482
  import { tmpdir as tmpdir2 } from "node:os";
23663
- import { join as join31 } from "node:path";
23483
+ import { join as join30 } from "node:path";
23664
23484
  import {
23665
23485
  createAgentSession,
23666
23486
  DefaultResourceLoader,
@@ -23783,7 +23603,7 @@ async function openPiInProcessSession(options) {
23783
23603
  let scratchDir;
23784
23604
  let resolvedAgentDir = options.agentDir;
23785
23605
  if (resolvedAgentDir === void 0) {
23786
- scratchDir = await mkdtemp2(join31(options.credentialScratchParent ?? tmpdir2(), "ak-institutional-"));
23606
+ scratchDir = await mkdtemp2(join30(options.credentialScratchParent ?? tmpdir2(), "ak-institutional-"));
23787
23607
  resolvedAgentDir = scratchDir;
23788
23608
  }
23789
23609
  try {
@@ -24479,7 +24299,7 @@ var init_reviewer_child_executor = __esm({
24479
24299
  import { spawn as spawn4 } from "node:child_process";
24480
24300
  import { mkdtemp as mkdtemp3, rm as rm3 } from "node:fs/promises";
24481
24301
  import { tmpdir as tmpdir3 } from "node:os";
24482
- import { join as join32 } from "node:path";
24302
+ import { join as join31 } from "node:path";
24483
24303
  async function runCommand(command, args, options = {}) {
24484
24304
  return await new Promise((resolve19, reject) => {
24485
24305
  const child = spawn4(command, args, { ...options.cwd === void 0 ? {} : { cwd: options.cwd }, stdio: ["ignore", "pipe", "pipe"], signal: options.signal });
@@ -24528,8 +24348,8 @@ async function prepareSnapshot(accepted, signal, dependencies) {
24528
24348
  if (!sameReviewerPinnedTarget({ repositoryRoot: accepted.repositoryRoot, objectFormat, targetHead }, accepted)) throw new Error("Accepted Reviewer target identity no longer matches the repository");
24529
24349
  await git3(accepted.repositoryRoot, ["cat-file", "-e", `${targetHead}^{commit}`], signal);
24530
24350
  dependencies.fault?.("mirror.before-create");
24531
- mirrorRoot = await mkdtemp3(join32(tmpdir3(), "ak-reviewer-snapshot-"));
24532
- const mirrorPath = join32(mirrorRoot, "repository.git");
24351
+ mirrorRoot = await mkdtemp3(join31(tmpdir3(), "ak-reviewer-snapshot-"));
24352
+ const mirrorPath = join31(mirrorRoot, "repository.git");
24533
24353
  dependencies.fault?.("mirror.create");
24534
24354
  await runCommand("git", ["init", "--bare", `--object-format=${accepted.objectFormat}`, mirrorPath], signal === void 0 ? {} : { signal });
24535
24355
  await git3(mirrorPath, ["fetch", "--no-tags", accepted.repositoryRoot, targetHead], signal);
@@ -24546,7 +24366,7 @@ async function prepareClone(snapshot, signal, dependencies) {
24546
24366
  const target = { repositoryRoot: snapshot.repositoryRoot, objectFormat: snapshot.objectFormat, targetHead: snapshot.targetHead, refs: { ...snapshot.refs } };
24547
24367
  try {
24548
24368
  dependencies.fault?.("workspace.before-create");
24549
- workspace = await mkdtemp3(join32(tmpdir3(), "ak-reviewer-leg-"));
24369
+ workspace = await mkdtemp3(join31(tmpdir3(), "ak-reviewer-leg-"));
24550
24370
  dependencies.fault?.("workspace.init");
24551
24371
  await git3(workspace, ["init", `--object-format=${snapshot.objectFormat}`, "--initial-branch=ak-reviewer-unborn"], signal);
24552
24372
  dependencies.fault?.("workspace.fetch");
@@ -24748,7 +24568,7 @@ var init_reviewer_agent = __esm({
24748
24568
 
24749
24569
  // src/acp-host/production-host.ts
24750
24570
  import { readFile as readFile20 } from "node:fs/promises";
24751
- import { fileURLToPath as fileURLToPath4 } from "node:url";
24571
+ import { fileURLToPath as fileURLToPath3 } from "node:url";
24752
24572
 
24753
24573
  // src/canonical-skill-binding.ts
24754
24574
  import { readFile, realpath } from "node:fs/promises";
@@ -24962,9 +24782,9 @@ init_auditor_soul();
24962
24782
  init_session_opening_materials();
24963
24783
 
24964
24784
  // src/acp-host/description.ts
24965
- import { join as join33 } from "node:path";
24785
+ import { join as join32 } from "node:path";
24966
24786
  function resolveAcpBinary(description, operatorHome) {
24967
- return join33(operatorHome, ...description.binaryFromHome);
24787
+ return join32(operatorHome, ...description.binaryFromHome);
24968
24788
  }
24969
24789
  function acpStdioArgs(description, model) {
24970
24790
  const { prefix, suffix, modelFlag, thinkingFlag } = description.argv;
@@ -24985,8 +24805,8 @@ init_role_runtime();
24985
24805
  import { randomUUID as randomUUID6 } from "node:crypto";
24986
24806
  import { mkdir as mkdir5, readFile as readFile18, writeFile as writeFile8 } from "node:fs/promises";
24987
24807
  import { createServer } from "node:net";
24988
- import { basename as basename7, dirname as dirname17, join as join34 } from "node:path";
24989
- import { fileURLToPath as fileURLToPath3 } from "node:url";
24808
+ import { basename as basename7, dirname as dirname17, join as join33 } from "node:path";
24809
+ import { fileURLToPath as fileURLToPath2 } from "node:url";
24990
24810
 
24991
24811
  // src/acp-host/role-turn-host.ts
24992
24812
  init_agent_start_materials();
@@ -25352,7 +25172,7 @@ async function prepareAcpRoleEnvelope(options) {
25352
25172
  const raw = await readFile18(method.path, "utf8");
25353
25173
  methodSkills.set(name, { path: method.path, body: stripSkillFrontmatter(raw).trim() });
25354
25174
  }
25355
- let sessionFile = options.sessionFile ?? join34(request.runDirectory, "session", "session.jsonl");
25175
+ let sessionFile = options.sessionFile ?? join33(request.runDirectory, "session", "session.jsonl");
25356
25176
  await mkdir5(dirname17(sessionFile), { recursive: true });
25357
25177
  if (request.continuation.kind !== "resume") {
25358
25178
  try {
@@ -25676,7 +25496,7 @@ async function prepareAcpRoleEnvelope(options) {
25676
25496
  });
25677
25497
  }
25678
25498
  await listen(server, options.socketPath);
25679
- const relay = fileURLToPath3(new URL("./mcp-relay.mjs", import.meta.url));
25499
+ const relay = fileURLToPath2(new URL("./mcp-relay.mjs", import.meta.url));
25680
25500
  let disposed = false;
25681
25501
  let priorAkRoleRunDir;
25682
25502
  let priorAkRoleCourtAttempt;
@@ -25817,9 +25637,9 @@ async function prepareAcpRoleEnvelope(options) {
25817
25637
 
25818
25638
  // src/acp-host/session-identity.ts
25819
25639
  import { mkdir as mkdir6, readFile as readFile19, rename, writeFile as writeFile9 } from "node:fs/promises";
25820
- import { dirname as dirname18, join as join35 } from "node:path";
25640
+ import { dirname as dirname18, join as join34 } from "node:path";
25821
25641
  function createAcpSessionIdentityAuthority(authority, sessionBindingFile) {
25822
- const bindingPath = (principal) => join35(authority.decode(principal).sessionDirectory, sessionBindingFile);
25642
+ const bindingPath = (principal) => join34(authority.decode(principal).sessionDirectory, sessionBindingFile);
25823
25643
  return {
25824
25644
  resolveSessionFile(principal) {
25825
25645
  return authority.decode(principal).sessionFile;
@@ -25848,7 +25668,7 @@ function createAcpSessionIdentityAuthority(authority, sessionBindingFile) {
25848
25668
  }
25849
25669
 
25850
25670
  // src/acp-host/production-host.ts
25851
- var navigatorRoutePlaybookPath = fileURLToPath4(
25671
+ var navigatorRoutePlaybookPath = fileURLToPath3(
25852
25672
  new URL("../../resources/navigator-route-playbook.md", import.meta.url)
25853
25673
  );
25854
25674
  function createAcpRoleRuntimeDependencies(packageRoot) {