@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.
- package/README.md +0 -2
- package/dist/acp-host/production-host.js +1056 -1236
- package/dist/public-cli/case-dossier-delivery.js +43 -0
- package/dist/public-cli/inspector-run.js +9 -6
- package/dist/public-cli/instruction-seat-run.js +24 -24
- package/dist/public-cli/invocation.js +2 -24
- package/dist/public-cli/main.js +1876 -2159
- package/dist/public-cli/post-admission.js +38 -12
- package/dist/public-cli/run-lifecycle.js +25 -14
- package/dist/public-cli/seat-ticket-binding.js +93 -70
- package/package.json +1 -1
- package/src/public-cli/case-dossier-delivery.ts +51 -0
- package/src/public-cli/countersign-run.ts +14 -17
- package/src/public-cli/diarist-run.ts +11 -13
- package/src/public-cli/inspector-run.ts +9 -10
- package/src/public-cli/instruction-seat-run.ts +28 -35
- package/src/public-cli/invocation.ts +4 -46
- package/src/public-cli/post-admission.ts +41 -6
- package/src/public-cli/run-lifecycle.ts +29 -21
- package/src/public-cli/seat-ticket-binding.ts +108 -104
- package/dist/diarist-ticket-resolution.js +0 -177
- package/resources/diarist-resolve-ticket.md +0 -39
- package/src/diarist-ticket-resolution.ts +0 -302
|
@@ -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
|
|
1120
|
-
return
|
|
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
|
|
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
|
|
5045
|
+
let stat3;
|
|
5035
5046
|
try {
|
|
5036
|
-
|
|
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 (!
|
|
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/
|
|
9274
|
-
|
|
9275
|
-
|
|
9276
|
-
|
|
9277
|
-
function
|
|
9278
|
-
|
|
9279
|
-
|
|
9280
|
-
|
|
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 (
|
|
9316
|
-
|
|
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
|
-
|
|
9321
|
-
|
|
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
|
-
|
|
9331
|
-
|
|
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
|
-
|
|
9335
|
-
|
|
9336
|
-
|
|
9337
|
-
|
|
9338
|
-
|
|
9339
|
-
|
|
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
|
-
|
|
9407
|
-
if (
|
|
9408
|
-
|
|
9409
|
-
|
|
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
|
-
|
|
9422
|
-
|
|
9423
|
-
|
|
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 (!
|
|
9438
|
-
|
|
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
|
|
9444
|
-
|
|
9445
|
-
|
|
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
|
-
|
|
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
|
|
9491
|
-
var
|
|
9492
|
-
"src/
|
|
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
|
-
|
|
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/
|
|
9499
|
-
|
|
9500
|
-
|
|
9501
|
-
|
|
9502
|
-
|
|
9503
|
-
|
|
9504
|
-
|
|
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
|
|
9357
|
+
return String(ticketNumber);
|
|
9508
9358
|
}
|
|
9509
|
-
function
|
|
9510
|
-
const
|
|
9511
|
-
const
|
|
9512
|
-
|
|
9513
|
-
|
|
9514
|
-
|
|
9515
|
-
|
|
9516
|
-
|
|
9517
|
-
|
|
9518
|
-
|
|
9519
|
-
|
|
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
|
-
|
|
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
|
|
9525
|
-
const
|
|
9526
|
-
|
|
9527
|
-
|
|
9528
|
-
|
|
9529
|
-
|
|
9530
|
-
|
|
9531
|
-
|
|
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
|
-
|
|
9552
|
-
|
|
9553
|
-
|
|
9554
|
-
|
|
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
|
-
|
|
9566
|
-
|
|
9567
|
-
|
|
9568
|
-
|
|
9569
|
-
|
|
9570
|
-
|
|
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
|
-
|
|
9575
|
-
|
|
9576
|
-
|
|
9577
|
-
|
|
9578
|
-
|
|
9579
|
-
|
|
9580
|
-
|
|
9581
|
-
throw new
|
|
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
|
-
|
|
9584
|
-
|
|
9585
|
-
|
|
9586
|
-
|
|
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
|
|
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
|
-
|
|
9601
|
-
|
|
9602
|
-
|
|
9603
|
-
|
|
9604
|
-
|
|
9605
|
-
|
|
9606
|
-
|
|
9607
|
-
|
|
9608
|
-
|
|
9609
|
-
|
|
9610
|
-
|
|
9611
|
-
|
|
9612
|
-
|
|
9613
|
-
|
|
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
|
|
9644
|
-
const
|
|
9645
|
-
|
|
9646
|
-
|
|
9647
|
-
|
|
9648
|
-
|
|
9649
|
-
const
|
|
9650
|
-
|
|
9651
|
-
|
|
9652
|
-
|
|
9653
|
-
|
|
9654
|
-
|
|
9655
|
-
|
|
9656
|
-
|
|
9657
|
-
|
|
9658
|
-
|
|
9659
|
-
|
|
9660
|
-
|
|
9661
|
-
|
|
9662
|
-
|
|
9663
|
-
|
|
9664
|
-
|
|
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
|
|
9669
|
-
|
|
9670
|
-
const
|
|
9671
|
-
|
|
9672
|
-
|
|
9673
|
-
|
|
9674
|
-
|
|
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
|
|
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
|
-
|
|
10355
|
-
|
|
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
|
-
|
|
10368
|
-
|
|
10369
|
-
|
|
10370
|
-
|
|
10371
|
-
|
|
10372
|
-
|
|
10373
|
-
|
|
10374
|
-
|
|
10375
|
-
|
|
10376
|
-
|
|
10377
|
-
|
|
10378
|
-
|
|
10379
|
-
|
|
10380
|
-
|
|
10381
|
-
|
|
10382
|
-
|
|
10383
|
-
|
|
10384
|
-
|
|
10385
|
-
|
|
10386
|
-
|
|
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
|
-
|
|
10389
|
-
|
|
10390
|
-
|
|
10391
|
-
return { kind: "failed", error };
|
|
9650
|
+
if (existsSync6(volume.volumeDir)) {
|
|
9651
|
+
known.push(token);
|
|
9652
|
+
continue;
|
|
10392
9653
|
}
|
|
10393
|
-
|
|
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
|
|
10397
|
-
|
|
10398
|
-
|
|
10399
|
-
|
|
10400
|
-
}
|
|
10401
|
-
|
|
10402
|
-
|
|
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
|
|
10409
|
-
if (
|
|
10410
|
-
|
|
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
|
|
10414
|
-
|
|
10415
|
-
|
|
10416
|
-
|
|
10417
|
-
|
|
10418
|
-
admitted.
|
|
10419
|
-
|
|
10420
|
-
|
|
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
|
-
|
|
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
|
|
10453
|
-
import { dirname as dirname9, join as
|
|
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
|
|
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 =
|
|
9776
|
+
const recordFile = join17(sessionRoot, entry.name, "records.jsonl");
|
|
10479
9777
|
try {
|
|
10480
|
-
await
|
|
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
|
|
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
|
|
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 =
|
|
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
|
|
11463
|
-
import { fileURLToPath
|
|
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(
|
|
10763
|
+
let dir = dirname11(fileURLToPath(moduleUrl));
|
|
11466
10764
|
for (let i = 0; i < 8; i += 1) {
|
|
11467
|
-
if (existsSync7(
|
|
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
|
|
10772
|
+
return fileURLToPath(new URL("..", moduleUrl));
|
|
11475
10773
|
}
|
|
11476
10774
|
async function readPackageMaterial(relativePath) {
|
|
11477
|
-
return readFile12(
|
|
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
|
|
11688
|
-
|
|
11689
|
-
return
|
|
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
|
|
11692
|
-
return
|
|
11693
|
-
|
|
11694
|
-
|
|
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
|
-
|
|
11699
|
-
|
|
11700
|
-
|
|
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
|
|
11709
|
-
const
|
|
11710
|
-
const
|
|
11711
|
-
|
|
11712
|
-
|
|
11713
|
-
|
|
11714
|
-
const
|
|
11715
|
-
|
|
11716
|
-
|
|
11717
|
-
|
|
11718
|
-
const
|
|
11719
|
-
if (
|
|
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
|
-
|
|
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
|
|
11729
|
-
|
|
11730
|
-
|
|
11731
|
-
|
|
11732
|
-
|
|
11733
|
-
|
|
11734
|
-
|
|
11735
|
-
|
|
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
|
-
|
|
11739
|
-
"
|
|
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
|
-
|
|
11742
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
12927
|
+
return join22(packageRoot, packagedMethodSkillRelativeDirectory(name));
|
|
13305
12928
|
}
|
|
13306
12929
|
function resolvePackagedMethodSkillPath(packageRoot, name) {
|
|
13307
|
-
return
|
|
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 =
|
|
13402
|
-
const provenancePath =
|
|
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 =
|
|
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
|
|
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 =
|
|
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(
|
|
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 = [
|
|
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(
|
|
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 = [
|
|
14912
|
-
const parentSessionFile = options.parentSessionFile ??
|
|
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 =
|
|
15011
|
-
const evidencePath =
|
|
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 =
|
|
15102
|
-
const evidencePath =
|
|
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 =
|
|
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) =>
|
|
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 ===
|
|
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
|
-
|
|
15403
|
-
|
|
15404
|
-
|
|
15025
|
+
join23(baseDir, "error.json"),
|
|
15026
|
+
join23(baseDir, "error.settlement.json"),
|
|
15027
|
+
join23(admitted.runDirectory, "error.settlement.json")
|
|
15405
15028
|
] : [
|
|
15406
|
-
|
|
15407
|
-
|
|
15029
|
+
join23(baseDir, "error.settlement.json"),
|
|
15030
|
+
join23(baseDir, "error.json")
|
|
15408
15031
|
];
|
|
15409
15032
|
const evidenceCandidates = underArtifacts ? [
|
|
15410
|
-
|
|
15411
|
-
|
|
15412
|
-
|
|
15033
|
+
join23(baseDir, "evidence.json"),
|
|
15034
|
+
join23(baseDir, "evidence.settlement.json"),
|
|
15035
|
+
join23(admitted.runDirectory, "evidence.settlement.json")
|
|
15413
15036
|
] : [
|
|
15414
|
-
|
|
15415
|
-
|
|
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
|
|
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
|
|
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 =
|
|
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
|
|
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(
|
|
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
|
|
15744
|
+
let hostTransition;
|
|
16116
15745
|
try {
|
|
16117
15746
|
previousHost = await readInvocationHost(admitted.runDirectory);
|
|
16118
|
-
|
|
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
|
-
|
|
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(
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
|
17146
|
-
|
|
17147
|
-
|
|
17148
|
-
|
|
17149
|
-
|
|
17150
|
-
|
|
17151
|
-
|
|
17152
|
-
|
|
17153
|
-
summons,
|
|
17154
|
-
|
|
17155
|
-
|
|
17156
|
-
|
|
17157
|
-
|
|
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
|
|
17220
|
-
await
|
|
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
|
|
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(
|
|
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 ??
|
|
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
|
|
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
|
|
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
|
|
18108
|
-
import { dirname as dirname13, resolve as resolve13, join as
|
|
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 =
|
|
17752
|
+
const ledger = join28(sessionDir, CURRENT_SESSION_LEDGER);
|
|
18112
17753
|
try {
|
|
18113
|
-
const value = JSON.parse(
|
|
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 =
|
|
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) ?
|
|
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 =
|
|
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
|
-
|
|
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
|
|
21348
|
-
import { existsSync as existsSync11, lstatSync as lstatSync3, readdirSync as readdirSync2, readFileSync as
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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(
|
|
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
|
|
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(
|
|
24532
|
-
const mirrorPath =
|
|
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(
|
|
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
|
|
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
|
|
24785
|
+
import { join as join32 } from "node:path";
|
|
24966
24786
|
function resolveAcpBinary(description, operatorHome) {
|
|
24967
|
-
return
|
|
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
|
|
24989
|
-
import { fileURLToPath as
|
|
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 ??
|
|
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 =
|
|
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
|
|
25640
|
+
import { dirname as dirname18, join as join34 } from "node:path";
|
|
25821
25641
|
function createAcpSessionIdentityAuthority(authority, sessionBindingFile) {
|
|
25822
|
-
const bindingPath = (principal) =>
|
|
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 =
|
|
25671
|
+
var navigatorRoutePlaybookPath = fileURLToPath3(
|
|
25852
25672
|
new URL("../../resources/navigator-route-playbook.md", import.meta.url)
|
|
25853
25673
|
);
|
|
25854
25674
|
function createAcpRoleRuntimeDependencies(packageRoot) {
|