@akagilnc/pi-workflow-roles 0.1.3652 → 0.1.3663
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 +1100 -1256
- 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 +1936 -2189
- package/dist/public-cli/notary-run.js +20 -5
- package/dist/public-cli/post-admission.js +61 -42
- package/dist/public-cli/run-lifecycle.js +39 -20
- 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/notary-run.ts +18 -6
- package/src/public-cli/post-admission.ts +78 -37
- package/src/public-cli/run-lifecycle.ts +46 -27
- 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
|
}
|
|
@@ -4102,6 +4102,13 @@ function instructResumeHandbookRead(prompt, engineMaterial) {
|
|
|
4102
4102
|
return line2;
|
|
4103
4103
|
}).join("\n");
|
|
4104
4104
|
}
|
|
4105
|
+
function appendResumeMaterialReread(prompt, materialPath) {
|
|
4106
|
+
const instruction = resumeRereadInstruction(materialPath, false);
|
|
4107
|
+
const lines = prompt.split("\n");
|
|
4108
|
+
if (lines.includes(instruction)) return prompt;
|
|
4109
|
+
return prompt.length === 0 ? instruction : `${prompt}
|
|
4110
|
+
${instruction}`;
|
|
4111
|
+
}
|
|
4105
4112
|
function selectResumeContinuationPrompt(message, engineMaterial) {
|
|
4106
4113
|
const base = message !== void 0 ? message : RESUME_TRANSPORT_ENVELOPE;
|
|
4107
4114
|
return instructResumeHandbookRead(
|
|
@@ -4636,21 +4643,38 @@ async function findLatestRunIdForSeatTicket(input) {
|
|
|
4636
4643
|
}
|
|
4637
4644
|
return best;
|
|
4638
4645
|
}
|
|
4646
|
+
async function collectBookRunTicketNumbers(input) {
|
|
4647
|
+
const ledgerHome = resolveActivationLedgerHome(input.home);
|
|
4648
|
+
const runsDir = join11(
|
|
4649
|
+
activationBookDirectory(ledgerHome, input.bookKey),
|
|
4650
|
+
"runs"
|
|
4651
|
+
);
|
|
4652
|
+
let entries;
|
|
4653
|
+
try {
|
|
4654
|
+
entries = await readdir2(runsDir);
|
|
4655
|
+
} catch (error) {
|
|
4656
|
+
if (errorCodeOf2(error) === "ENOENT") return /* @__PURE__ */ new Set();
|
|
4657
|
+
throw error;
|
|
4658
|
+
}
|
|
4659
|
+
const known = /* @__PURE__ */ new Set();
|
|
4660
|
+
for (const entry of entries) {
|
|
4661
|
+
const ticketNumber = await readRunTicketNumber(join11(runsDir, entry));
|
|
4662
|
+
if (ticketNumber !== void 0) known.add(ticketNumber);
|
|
4663
|
+
}
|
|
4664
|
+
return known;
|
|
4665
|
+
}
|
|
4639
4666
|
function parsePersistedTicketIdentity(record4) {
|
|
4640
4667
|
const correlationId = typeof record4.correlationId === "string" && record4.correlationId.trim() !== "" ? record4.correlationId : void 0;
|
|
4641
4668
|
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
4669
|
return {
|
|
4644
4670
|
...correlationId === void 0 ? {} : { correlationId },
|
|
4645
|
-
...ticketNumber === void 0 ? {} : { ticketNumber }
|
|
4646
|
-
...ticketResolution === void 0 ? {} : { ticketResolution }
|
|
4671
|
+
...ticketNumber === void 0 ? {} : { ticketNumber }
|
|
4647
4672
|
};
|
|
4648
4673
|
}
|
|
4649
4674
|
function restoredTicketFields(fields) {
|
|
4650
4675
|
return {
|
|
4651
4676
|
...fields.correlationId === void 0 ? {} : { correlationId: fields.correlationId },
|
|
4652
|
-
...fields.ticketNumber === void 0 ? {} : { ticketNumber: fields.ticketNumber }
|
|
4653
|
-
...fields.ticketResolution === void 0 ? {} : { ticketResolution: fields.ticketResolution }
|
|
4677
|
+
...fields.ticketNumber === void 0 ? {} : { ticketNumber: fields.ticketNumber }
|
|
4654
4678
|
};
|
|
4655
4679
|
}
|
|
4656
4680
|
async function loadResumableRunRecord(home, runId, authority) {
|
|
@@ -4686,7 +4710,6 @@ async function loadResumableRunRecord(home, runId, authority) {
|
|
|
4686
4710
|
let derived;
|
|
4687
4711
|
let correlationId;
|
|
4688
4712
|
let ticketNumber;
|
|
4689
|
-
let ticketResolution;
|
|
4690
4713
|
let prNumber;
|
|
4691
4714
|
let repository;
|
|
4692
4715
|
let repositoryDisplay;
|
|
@@ -4800,7 +4823,6 @@ async function loadResumableRunRecord(home, runId, authority) {
|
|
|
4800
4823
|
const fromAdmitted = parsePersistedTicketIdentity(record4);
|
|
4801
4824
|
correlationId = fromAdmitted.correlationId;
|
|
4802
4825
|
ticketNumber = fromAdmitted.ticketNumber;
|
|
4803
|
-
ticketResolution = fromAdmitted.ticketResolution;
|
|
4804
4826
|
}
|
|
4805
4827
|
} catch (error) {
|
|
4806
4828
|
if (error instanceof CliUsageError) throw error;
|
|
@@ -4823,13 +4845,10 @@ async function loadResumableRunRecord(home, runId, authority) {
|
|
|
4823
4845
|
...typeof rec.thinking === "string" ? { thinking: rec.thinking } : {}
|
|
4824
4846
|
};
|
|
4825
4847
|
}
|
|
4826
|
-
if (correlationId === void 0 || ticketNumber === void 0
|
|
4848
|
+
if (correlationId === void 0 || ticketNumber === void 0) {
|
|
4827
4849
|
const fromInvocation = parsePersistedTicketIdentity(rec);
|
|
4828
4850
|
if (correlationId === void 0) correlationId = fromInvocation.correlationId;
|
|
4829
4851
|
if (ticketNumber === void 0) ticketNumber = fromInvocation.ticketNumber;
|
|
4830
|
-
if (ticketResolution === void 0) {
|
|
4831
|
-
ticketResolution = fromInvocation.ticketResolution;
|
|
4832
|
-
}
|
|
4833
4852
|
}
|
|
4834
4853
|
}
|
|
4835
4854
|
} catch (error) {
|
|
@@ -4859,7 +4878,6 @@ async function loadResumableRunRecord(home, runId, authority) {
|
|
|
4859
4878
|
...derived === void 0 ? {} : { derived },
|
|
4860
4879
|
...correlationId === void 0 ? {} : { correlationId },
|
|
4861
4880
|
...ticketNumber === void 0 ? {} : { ticketNumber },
|
|
4862
|
-
...ticketResolution === void 0 ? {} : { ticketResolution },
|
|
4863
4881
|
...prNumber === void 0 ? {} : { prNumber },
|
|
4864
4882
|
...repository === void 0 ? {} : { repository },
|
|
4865
4883
|
...repositoryDisplay === void 0 ? {} : { repositoryDisplay },
|
|
@@ -5031,16 +5049,16 @@ async function requireRunDirectory(candidate, display) {
|
|
|
5031
5049
|
{ cause: error }
|
|
5032
5050
|
);
|
|
5033
5051
|
}
|
|
5034
|
-
let
|
|
5052
|
+
let stat3;
|
|
5035
5053
|
try {
|
|
5036
|
-
|
|
5054
|
+
stat3 = await lstat2(real);
|
|
5037
5055
|
} catch (error) {
|
|
5038
5056
|
throw new NotarySourceRunError(
|
|
5039
5057
|
`notary --source-run is not a readable run directory: ${display}`,
|
|
5040
5058
|
{ cause: error }
|
|
5041
5059
|
);
|
|
5042
5060
|
}
|
|
5043
|
-
if (!
|
|
5061
|
+
if (!stat3.isDirectory()) {
|
|
5044
5062
|
throw new NotarySourceRunError(
|
|
5045
5063
|
`notary --source-run must be a run directory: ${display}`
|
|
5046
5064
|
);
|
|
@@ -6182,7 +6200,6 @@ __export(invocation_exports, {
|
|
|
6182
6200
|
recordEffectiveInvocationModel: () => recordEffectiveInvocationModel,
|
|
6183
6201
|
recordLaunchedPiIdentity: () => recordLaunchedPiIdentity,
|
|
6184
6202
|
recordLaunchedRolePackageIdentity: () => recordLaunchedRolePackageIdentity,
|
|
6185
|
-
recordTrueUnboundTicketResolution: () => recordTrueUnboundTicketResolution,
|
|
6186
6203
|
requireAuthorityRef: () => requireAuthorityRef,
|
|
6187
6204
|
resolveDoctorCaseRunsPath: () => resolveDoctorCaseRunsPath,
|
|
6188
6205
|
resolveGitHubRemoteRepository: () => resolveGitHubRemoteRepository
|
|
@@ -6317,11 +6334,6 @@ async function bindAdmittedTicketNumber(admitted, ticketNumber) {
|
|
|
6317
6334
|
if (!Number.isSafeInteger(ticketNumber) || ticketNumber < 1) {
|
|
6318
6335
|
throw new Error(`bindAdmittedTicketNumber requires a safe positive integer, got ${String(ticketNumber)}`);
|
|
6319
6336
|
}
|
|
6320
|
-
if (admitted.ticketResolution === "true-unbound") {
|
|
6321
|
-
throw new Error(
|
|
6322
|
-
"bindAdmittedTicketNumber refuses to replace durable true-unbound ticket resolution"
|
|
6323
|
-
);
|
|
6324
|
-
}
|
|
6325
6337
|
if (admitted.ticketNumber !== void 0) {
|
|
6326
6338
|
if (admitted.ticketNumber === ticketNumber) return;
|
|
6327
6339
|
throw new Error(
|
|
@@ -6339,26 +6351,6 @@ async function bindAdmittedTicketNumber(admitted, ticketNumber) {
|
|
|
6339
6351
|
"utf8"
|
|
6340
6352
|
);
|
|
6341
6353
|
}
|
|
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
6354
|
async function recordLaunchedPiIdentity(runDirectory, identity) {
|
|
6363
6355
|
await mergeInvocationIdentityPage(runDirectory, {
|
|
6364
6356
|
piExecutable: identity.executable,
|
|
@@ -9270,859 +9262,253 @@ var init_config = __esm({
|
|
|
9270
9262
|
}
|
|
9271
9263
|
});
|
|
9272
9264
|
|
|
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
|
-
);
|
|
9265
|
+
// src/ticket-provenance-contracts.ts
|
|
9266
|
+
function isRecord11(value) {
|
|
9267
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
9268
|
+
}
|
|
9269
|
+
function projectTicketProvenanceDiagnostic(value) {
|
|
9270
|
+
if (!isRecord11(value)) return void 0;
|
|
9271
|
+
if (value.recordClass !== TICKET_PROVENANCE_RECORD_CLASS_DIAGNOSTIC) {
|
|
9272
|
+
return void 0;
|
|
9314
9273
|
}
|
|
9315
|
-
if (
|
|
9316
|
-
|
|
9317
|
-
if (record4.assertion === "ticket" && typeof n === "number" && Number.isSafeInteger(n) && n >= 1) {
|
|
9318
|
-
return { kind: "ticket", ticketNumber: n };
|
|
9274
|
+
if (typeof value.diagnosticKind !== "string" || !DIAGNOSTIC_KINDS.has(value.diagnosticKind)) {
|
|
9275
|
+
return void 0;
|
|
9319
9276
|
}
|
|
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})`);
|
|
9277
|
+
if (typeof value.cause !== "string" || value.cause.length === 0) {
|
|
9278
|
+
return void 0;
|
|
9329
9279
|
}
|
|
9330
|
-
|
|
9331
|
-
|
|
9332
|
-
throw new Error(`diarist resolve-ticket method material is empty (${methodPath})`);
|
|
9280
|
+
if (typeof value.recordedAt !== "string" || value.recordedAt.length === 0) {
|
|
9281
|
+
return void 0;
|
|
9333
9282
|
}
|
|
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
|
-
);
|
|
9283
|
+
return {
|
|
9284
|
+
recordClass: TICKET_PROVENANCE_RECORD_CLASS_DIAGNOSTIC,
|
|
9285
|
+
diagnosticKind: value.diagnosticKind,
|
|
9286
|
+
cause: value.cause,
|
|
9287
|
+
recordedAt: value.recordedAt,
|
|
9288
|
+
...typeof value.reason === "string" ? { reason: value.reason } : {}
|
|
9404
9289
|
};
|
|
9405
9290
|
}
|
|
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
|
-
);
|
|
9291
|
+
function projectTicketProvenanceEntry(value) {
|
|
9292
|
+
if (!isRecord11(value)) return void 0;
|
|
9293
|
+
if (value.recordClass === TICKET_PROVENANCE_RECORD_CLASS_DIAGNOSTIC) {
|
|
9294
|
+
return void 0;
|
|
9420
9295
|
}
|
|
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
|
-
);
|
|
9296
|
+
if (!isRecord11(value.basis)) return void 0;
|
|
9297
|
+
if (typeof value.basis.method !== "string" || !BASIS_METHODS.has(value.basis.method)) {
|
|
9298
|
+
return void 0;
|
|
9436
9299
|
}
|
|
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
|
-
);
|
|
9300
|
+
if (typeof value.sourceKind !== "string" || !SOURCE_KINDS.has(value.sourceKind)) {
|
|
9301
|
+
return void 0;
|
|
9442
9302
|
}
|
|
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";
|
|
9303
|
+
if (!isRecord11(value.sourceRef)) return void 0;
|
|
9304
|
+
if (typeof value.transcript !== "string" || value.transcript.length === 0) {
|
|
9305
|
+
return void 0;
|
|
9475
9306
|
}
|
|
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);
|
|
9307
|
+
if (typeof value.timestamp !== "string" || value.timestamp.length === 0) {
|
|
9308
|
+
return void 0;
|
|
9487
9309
|
}
|
|
9488
|
-
|
|
9310
|
+
const basis = {
|
|
9311
|
+
method: value.basis.method,
|
|
9312
|
+
...Array.isArray(value.basis.anchors) ? {
|
|
9313
|
+
anchors: value.basis.anchors.filter(
|
|
9314
|
+
(item) => typeof item === "string"
|
|
9315
|
+
)
|
|
9316
|
+
} : {},
|
|
9317
|
+
...typeof value.basis.note === "string" ? { note: value.basis.note } : {}
|
|
9318
|
+
};
|
|
9319
|
+
const sourceRef = {
|
|
9320
|
+
...typeof value.sourceRef.sessionFile === "string" ? { sessionFile: value.sourceRef.sessionFile } : {},
|
|
9321
|
+
...typeof value.sourceRef.entryId === "string" || typeof value.sourceRef.entryId === "number" ? { entryId: value.sourceRef.entryId } : {},
|
|
9322
|
+
...typeof value.sourceRef.path === "string" ? { path: value.sourceRef.path } : {},
|
|
9323
|
+
...typeof value.sourceRef.url === "string" ? { url: value.sourceRef.url } : {}
|
|
9324
|
+
};
|
|
9325
|
+
return {
|
|
9326
|
+
basis,
|
|
9327
|
+
sourceKind: value.sourceKind,
|
|
9328
|
+
sourceRef,
|
|
9329
|
+
transcript: value.transcript,
|
|
9330
|
+
timestamp: value.timestamp
|
|
9331
|
+
};
|
|
9489
9332
|
}
|
|
9490
|
-
var
|
|
9491
|
-
var
|
|
9492
|
-
"src/
|
|
9333
|
+
var TICKET_PROVENANCE_KIND, TICKET_PROVENANCE_HUMAN_VIEW, TICKET_PROVENANCE_OFFERED_WATERMARK, TICKET_PROVENANCE_RECORD_CLASS_DIAGNOSTIC, SOURCE_KINDS, BASIS_METHODS, DIAGNOSTIC_KINDS;
|
|
9334
|
+
var init_ticket_provenance_contracts = __esm({
|
|
9335
|
+
"src/ticket-provenance-contracts.ts"() {
|
|
9493
9336
|
"use strict";
|
|
9494
|
-
|
|
9337
|
+
TICKET_PROVENANCE_KIND = "ticket-provenance";
|
|
9338
|
+
TICKET_PROVENANCE_HUMAN_VIEW = "\u8D77\u5C45\u5F55.md";
|
|
9339
|
+
TICKET_PROVENANCE_OFFERED_WATERMARK = "offered-identities.jsonl";
|
|
9340
|
+
TICKET_PROVENANCE_RECORD_CLASS_DIAGNOSTIC = "diagnostic";
|
|
9341
|
+
SOURCE_KINDS = /* @__PURE__ */ new Set([
|
|
9342
|
+
"cc-session",
|
|
9343
|
+
"issue-body-comment",
|
|
9344
|
+
"adr-decision-key",
|
|
9345
|
+
"ticket-decree-block"
|
|
9346
|
+
]);
|
|
9347
|
+
BASIS_METHODS = /* @__PURE__ */ new Set(["llm-semantic"]);
|
|
9348
|
+
DIAGNOSTIC_KINDS = /* @__PURE__ */ new Set([
|
|
9349
|
+
"collector-failed",
|
|
9350
|
+
"issue-source-failed",
|
|
9351
|
+
"quote-verify-failed"
|
|
9352
|
+
]);
|
|
9495
9353
|
}
|
|
9496
9354
|
});
|
|
9497
9355
|
|
|
9498
|
-
// src/
|
|
9499
|
-
|
|
9500
|
-
|
|
9501
|
-
|
|
9502
|
-
|
|
9503
|
-
|
|
9504
|
-
|
|
9505
|
-
if (q.length >= minLength) out.push(q);
|
|
9356
|
+
// src/ticket-provenance.ts
|
|
9357
|
+
import { createHash as createHash5 } from "node:crypto";
|
|
9358
|
+
import { appendFileSync as appendFileSync2, existsSync as existsSync5, mkdirSync as mkdirSync3, readFileSync as readFileSync2, writeFileSync as writeFileSync3 } from "node:fs";
|
|
9359
|
+
import { join as join16 } from "node:path";
|
|
9360
|
+
function ticketProvenanceSubject(ticketNumber) {
|
|
9361
|
+
if (!Number.isSafeInteger(ticketNumber) || ticketNumber < 1) {
|
|
9362
|
+
throw new Error(`ticket-provenance subject requires a positive ticket number, got ${String(ticketNumber)}`);
|
|
9506
9363
|
}
|
|
9507
|
-
return
|
|
9364
|
+
return String(ticketNumber);
|
|
9508
9365
|
}
|
|
9509
|
-
function
|
|
9510
|
-
const
|
|
9511
|
-
const
|
|
9512
|
-
|
|
9513
|
-
|
|
9514
|
-
|
|
9515
|
-
|
|
9516
|
-
|
|
9517
|
-
|
|
9518
|
-
|
|
9519
|
-
|
|
9366
|
+
function ticketProvenanceEntryIdentity(input) {
|
|
9367
|
+
const ref = input.sourceRef;
|
|
9368
|
+
const refKey = [
|
|
9369
|
+
ref.sessionFile ?? "",
|
|
9370
|
+
ref.entryId === void 0 ? "" : String(ref.entryId),
|
|
9371
|
+
ref.path ?? "",
|
|
9372
|
+
ref.url ?? ""
|
|
9373
|
+
].join("");
|
|
9374
|
+
const material = [
|
|
9375
|
+
String(input.ticketNumber),
|
|
9376
|
+
input.sourceKind,
|
|
9377
|
+
refKey,
|
|
9378
|
+
input.transcript
|
|
9379
|
+
].join("\0");
|
|
9380
|
+
return createHash5("sha256").update(material, "utf8").digest("hex");
|
|
9381
|
+
}
|
|
9382
|
+
function appendTicketProvenanceEntry(input) {
|
|
9383
|
+
const subject = ticketProvenanceSubject(input.ticketNumber);
|
|
9384
|
+
const identity = ticketProvenanceEntryIdentity({
|
|
9520
9385
|
ticketNumber: input.ticketNumber,
|
|
9521
|
-
|
|
9522
|
-
|
|
9386
|
+
sourceKind: input.entry.sourceKind,
|
|
9387
|
+
sourceRef: input.entry.sourceRef,
|
|
9388
|
+
transcript: input.entry.transcript
|
|
9389
|
+
});
|
|
9390
|
+
return sitianReport({
|
|
9391
|
+
level: "event",
|
|
9392
|
+
kind: TICKET_PROVENANCE_KIND,
|
|
9393
|
+
identity,
|
|
9394
|
+
subject,
|
|
9395
|
+
cwd: input.cwd,
|
|
9396
|
+
...input.home === void 0 ? {} : { home: input.home },
|
|
9397
|
+
host: input.host ?? "diarist",
|
|
9398
|
+
source: input.source ?? "diarist",
|
|
9399
|
+
payload: input.entry,
|
|
9400
|
+
raw: input.entry.sourceRef.sessionFile !== void 0 && input.entry.sourceRef.entryId !== void 0 ? {
|
|
9401
|
+
sessionFile: input.entry.sourceRef.sessionFile,
|
|
9402
|
+
entryId: input.entry.sourceRef.entryId
|
|
9403
|
+
} : void 0
|
|
9404
|
+
});
|
|
9523
9405
|
}
|
|
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
|
-
}
|
|
9406
|
+
function resolveTicketProvenanceVolume(ticketNumber, cwd, home) {
|
|
9407
|
+
const path = resolveSitianRecordPath({
|
|
9408
|
+
level: "event",
|
|
9409
|
+
kind: TICKET_PROVENANCE_KIND,
|
|
9410
|
+
subject: ticketProvenanceSubject(ticketNumber),
|
|
9411
|
+
cwd,
|
|
9412
|
+
...home === void 0 ? {} : { home }
|
|
9413
|
+
});
|
|
9550
9414
|
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
|
-
}
|
|
9415
|
+
recordFile: path.recordFile,
|
|
9416
|
+
volumeDir: path.sessionDir,
|
|
9417
|
+
humanViewFile: join16(path.sessionDir, TICKET_PROVENANCE_HUMAN_VIEW),
|
|
9418
|
+
offeredWatermarkFile: join16(path.sessionDir, TICKET_PROVENANCE_OFFERED_WATERMARK)
|
|
9563
9419
|
};
|
|
9564
9420
|
}
|
|
9565
|
-
|
|
9566
|
-
|
|
9567
|
-
|
|
9568
|
-
|
|
9569
|
-
|
|
9570
|
-
|
|
9421
|
+
function readOfferedIdentities(ticketNumber, cwd, home) {
|
|
9422
|
+
const { offeredWatermarkFile } = resolveTicketProvenanceVolume(ticketNumber, cwd, home);
|
|
9423
|
+
if (!existsSync5(offeredWatermarkFile)) return /* @__PURE__ */ new Set();
|
|
9424
|
+
let text;
|
|
9425
|
+
try {
|
|
9426
|
+
text = readFileSync2(offeredWatermarkFile, "utf8");
|
|
9427
|
+
} catch (error) {
|
|
9428
|
+
throw new TicketProvenanceWatermarkError(
|
|
9429
|
+
"unreadable",
|
|
9430
|
+
`ticket-provenance offered watermark unreadable (${offeredWatermarkFile})`,
|
|
9431
|
+
{ cause: error }
|
|
9432
|
+
);
|
|
9571
9433
|
}
|
|
9572
|
-
|
|
9573
|
-
|
|
9574
|
-
|
|
9575
|
-
|
|
9576
|
-
|
|
9577
|
-
|
|
9578
|
-
|
|
9579
|
-
|
|
9580
|
-
|
|
9581
|
-
throw new
|
|
9434
|
+
const seen = /* @__PURE__ */ new Set();
|
|
9435
|
+
const lines = text.split("\n");
|
|
9436
|
+
for (let index = 0; index < lines.length; index += 1) {
|
|
9437
|
+
const trimmed = lines[index].trim();
|
|
9438
|
+
if (!trimmed) continue;
|
|
9439
|
+
let parsed;
|
|
9440
|
+
try {
|
|
9441
|
+
parsed = JSON.parse(trimmed);
|
|
9442
|
+
} catch (error) {
|
|
9443
|
+
throw new TicketProvenanceWatermarkError(
|
|
9444
|
+
"malformed-json",
|
|
9445
|
+
`ticket-provenance offered watermark malformed JSON at line ${index + 1} (${offeredWatermarkFile})`,
|
|
9446
|
+
{ cause: error }
|
|
9447
|
+
);
|
|
9582
9448
|
}
|
|
9583
|
-
|
|
9584
|
-
|
|
9585
|
-
|
|
9586
|
-
|
|
9587
|
-
|
|
9449
|
+
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed) || typeof parsed.identity !== "string" || parsed.identity.length === 0) {
|
|
9450
|
+
throw new TicketProvenanceWatermarkError(
|
|
9451
|
+
"bad-shape",
|
|
9452
|
+
`ticket-provenance offered watermark bad shape at line ${index + 1} (${offeredWatermarkFile})`
|
|
9453
|
+
);
|
|
9454
|
+
}
|
|
9455
|
+
seen.add(parsed.identity);
|
|
9588
9456
|
}
|
|
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;
|
|
9457
|
+
return seen;
|
|
9599
9458
|
}
|
|
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;
|
|
9459
|
+
function recordOfferedIdentities(input) {
|
|
9460
|
+
if (input.identities.length === 0) return;
|
|
9461
|
+
const { volumeDir, offeredWatermarkFile } = resolveTicketProvenanceVolume(
|
|
9462
|
+
input.ticketNumber,
|
|
9463
|
+
input.cwd,
|
|
9464
|
+
input.home
|
|
9465
|
+
);
|
|
9466
|
+
const already = new Set(readOfferedIdentities(input.ticketNumber, input.cwd, input.home));
|
|
9467
|
+
const rows = [];
|
|
9468
|
+
for (const identity of input.identities) {
|
|
9469
|
+
if (identity.length === 0 || already.has(identity)) continue;
|
|
9470
|
+
rows.push(`${JSON.stringify({ identity })}
|
|
9471
|
+
`);
|
|
9472
|
+
already.add(identity);
|
|
9641
9473
|
}
|
|
9474
|
+
if (rows.length === 0) return;
|
|
9475
|
+
mkdirSync3(volumeDir, { recursive: true });
|
|
9476
|
+
appendFileSync2(offeredWatermarkFile, rows.join(""), "utf8");
|
|
9642
9477
|
}
|
|
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 };
|
|
9478
|
+
async function readTicketProvenance(ticketNumber, cwd, home) {
|
|
9479
|
+
const { recordFile } = resolveTicketProvenanceVolume(ticketNumber, cwd, home);
|
|
9480
|
+
const { records: records2 } = await readSitianRecords(recordFile);
|
|
9481
|
+
const entries = [];
|
|
9482
|
+
const diagnostics = [];
|
|
9483
|
+
let skipped = 0;
|
|
9484
|
+
for (const record4 of records2) {
|
|
9485
|
+
if (record4.kind !== TICKET_PROVENANCE_KIND) {
|
|
9486
|
+
skipped += 1;
|
|
9487
|
+
continue;
|
|
9488
|
+
}
|
|
9489
|
+
const diagnostic = projectTicketProvenanceDiagnostic(record4.payload);
|
|
9490
|
+
if (diagnostic !== void 0) {
|
|
9491
|
+
diagnostics.push(diagnostic);
|
|
9492
|
+
continue;
|
|
9493
|
+
}
|
|
9494
|
+
const entry = projectTicketProvenanceEntry(record4.payload);
|
|
9495
|
+
if (entry === void 0) {
|
|
9496
|
+
skipped += 1;
|
|
9497
|
+
continue;
|
|
9498
|
+
}
|
|
9499
|
+
entries.push(entry);
|
|
9666
9500
|
}
|
|
9501
|
+
return { entries, diagnostics, records: records2, recordFile, skipped };
|
|
9667
9502
|
}
|
|
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);
|
|
9503
|
+
function markdownFenceFor(text) {
|
|
9504
|
+
let longest = 0;
|
|
9505
|
+
const runs = text.match(/`+/g);
|
|
9506
|
+
if (runs !== null) {
|
|
9507
|
+
for (const run of runs) {
|
|
9508
|
+
if (run.length > longest) longest = run.length;
|
|
9509
|
+
}
|
|
9680
9510
|
}
|
|
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));
|
|
9511
|
+
return "`".repeat(Math.max(3, longest + 1));
|
|
10126
9512
|
}
|
|
10127
9513
|
function renderTicketProvenanceMarkdown(input) {
|
|
10128
9514
|
const lines = [
|
|
@@ -10224,203 +9610,86 @@ function writeTicketProvenanceHumanView(input) {
|
|
|
10224
9610
|
ticketNumber: input.ticketNumber,
|
|
10225
9611
|
entries: input.entries
|
|
10226
9612
|
});
|
|
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;
|
|
10316
|
-
}
|
|
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
|
-
});
|
|
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
|
-
};
|
|
9613
|
+
writeFileSync3(volume.humanViewFile, md, "utf8");
|
|
9614
|
+
return volume.humanViewFile;
|
|
10353
9615
|
}
|
|
10354
|
-
var
|
|
10355
|
-
|
|
9616
|
+
var TicketProvenanceWatermarkError;
|
|
9617
|
+
var init_ticket_provenance = __esm({
|
|
9618
|
+
"src/ticket-provenance.ts"() {
|
|
10356
9619
|
"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
9620
|
init_sitian_facade();
|
|
9621
|
+
init_ticket_provenance_contracts();
|
|
9622
|
+
TicketProvenanceWatermarkError = class extends Error {
|
|
9623
|
+
code = "ticket-provenance-watermark";
|
|
9624
|
+
reason;
|
|
9625
|
+
constructor(reason, message, options) {
|
|
9626
|
+
super(message, options);
|
|
9627
|
+
this.name = "TicketProvenanceWatermarkError";
|
|
9628
|
+
this.reason = reason;
|
|
9629
|
+
}
|
|
9630
|
+
};
|
|
10363
9631
|
}
|
|
10364
9632
|
});
|
|
10365
9633
|
|
|
10366
9634
|
// 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
|
-
|
|
9635
|
+
import { existsSync as existsSync6 } from "node:fs";
|
|
9636
|
+
function instructionTicketTokens(instruction) {
|
|
9637
|
+
const tokens = /* @__PURE__ */ new Set();
|
|
9638
|
+
for (const run of instruction.match(/\d+/g) ?? []) {
|
|
9639
|
+
if (run.startsWith("0")) continue;
|
|
9640
|
+
const parsed = Number(run);
|
|
9641
|
+
if (!Number.isSafeInteger(parsed) || parsed < 1) continue;
|
|
9642
|
+
tokens.add(parsed);
|
|
9643
|
+
}
|
|
9644
|
+
return [...tokens];
|
|
9645
|
+
}
|
|
9646
|
+
async function resolveKnownTicketNumber(input) {
|
|
9647
|
+
const tokens = instructionTicketTokens(input.instruction);
|
|
9648
|
+
if (tokens.length === 0) return void 0;
|
|
9649
|
+
const known = [];
|
|
9650
|
+
let runTickets;
|
|
9651
|
+
for (const token of tokens) {
|
|
9652
|
+
const volume = resolveTicketProvenanceVolume(
|
|
9653
|
+
token,
|
|
9654
|
+
input.projectRoot,
|
|
9655
|
+
input.home
|
|
10387
9656
|
);
|
|
10388
|
-
|
|
10389
|
-
|
|
10390
|
-
|
|
10391
|
-
return { kind: "failed", error };
|
|
9657
|
+
if (existsSync6(volume.volumeDir)) {
|
|
9658
|
+
known.push(token);
|
|
9659
|
+
continue;
|
|
10392
9660
|
}
|
|
10393
|
-
|
|
9661
|
+
if (runTickets === void 0) {
|
|
9662
|
+
runTickets = await readBookRunTickets(input);
|
|
9663
|
+
}
|
|
9664
|
+
if (runTickets.has(token)) known.push(token);
|
|
10394
9665
|
}
|
|
9666
|
+
return known.length === 1 ? known[0] : void 0;
|
|
10395
9667
|
}
|
|
10396
|
-
function
|
|
10397
|
-
|
|
10398
|
-
|
|
10399
|
-
|
|
10400
|
-
}
|
|
10401
|
-
|
|
10402
|
-
|
|
10403
|
-
await bindAdmittedTicketNumber(admitted, resolution.ticketNumber);
|
|
10404
|
-
} else {
|
|
10405
|
-
await recordTrueUnboundTicketResolution(admitted);
|
|
9668
|
+
async function readBookRunTickets(input) {
|
|
9669
|
+
let bookKey;
|
|
9670
|
+
try {
|
|
9671
|
+
bookKey = input.bookKey ?? resolveBookKeyFromGit(input.projectRoot);
|
|
9672
|
+
} catch (error) {
|
|
9673
|
+
if (error instanceof ActivationGitRepositoryRequiredError) return /* @__PURE__ */ new Set();
|
|
9674
|
+
throw error;
|
|
10406
9675
|
}
|
|
9676
|
+
return await collectBookRunTicketNumbers({ home: input.home, bookKey });
|
|
10407
9677
|
}
|
|
10408
|
-
async function
|
|
10409
|
-
if (
|
|
10410
|
-
|
|
9678
|
+
async function bindReusedTicketNumber(admitted, ticketNumber) {
|
|
9679
|
+
if (ticketNumber === void 0) return;
|
|
9680
|
+
if (admitted.ticketNumber !== void 0) return;
|
|
9681
|
+
await bindAdmittedTicketNumber(admitted, ticketNumber);
|
|
10411
9682
|
}
|
|
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;
|
|
9683
|
+
async function resolveSeatTicketBinding(admitted, env) {
|
|
9684
|
+
if (admitted.ticketNumber !== void 0) return admitted.ticketNumber;
|
|
9685
|
+
const ticketNumber = await resolveKnownTicketNumber({
|
|
9686
|
+
instruction: admitted.instruction,
|
|
9687
|
+
projectRoot: admitted.projectRoot,
|
|
9688
|
+
home: env.home,
|
|
9689
|
+
bookKey: admitted.bookKey
|
|
9690
|
+
});
|
|
9691
|
+
await bindReusedTicketNumber(admitted, ticketNumber);
|
|
9692
|
+
return ticketNumber;
|
|
10424
9693
|
}
|
|
10425
9694
|
async function tryResumeSameTicketSeatRun(input) {
|
|
10426
9695
|
if (input.freshSummons === true) return void 0;
|
|
@@ -10441,22 +9710,58 @@ var init_seat_ticket_binding = __esm({
|
|
|
10441
9710
|
"src/public-cli/seat-ticket-binding.ts"() {
|
|
10442
9711
|
"use strict";
|
|
10443
9712
|
init_activation_ledger_git();
|
|
10444
|
-
|
|
10445
|
-
init_diarist();
|
|
9713
|
+
init_ticket_provenance();
|
|
10446
9714
|
init_invocation();
|
|
10447
9715
|
init_run_lifecycle();
|
|
10448
9716
|
}
|
|
10449
9717
|
});
|
|
10450
9718
|
|
|
9719
|
+
// src/public-cli/case-dossier-delivery.ts
|
|
9720
|
+
import { stat as stat2 } from "node:fs/promises";
|
|
9721
|
+
async function describeDossierFile(path) {
|
|
9722
|
+
try {
|
|
9723
|
+
const stats = await stat2(path);
|
|
9724
|
+
if (!stats.isFile()) return `\u4E0D\u53EF\u8BFB\uFF08\u975E\u666E\u901A\u6587\u4EF6\uFF09\uFF1A${path}`;
|
|
9725
|
+
return path;
|
|
9726
|
+
} catch (error) {
|
|
9727
|
+
const code = error.code;
|
|
9728
|
+
if (code === "ENOENT") return `\u5C1A\u672A\u751F\u6210\uFF1A${path}`;
|
|
9729
|
+
return `\u4E0D\u53EF\u8BFB\uFF08${code ?? "\u672A\u77E5\u9519\u8BEF"}\uFF09\uFF1A${path}`;
|
|
9730
|
+
}
|
|
9731
|
+
}
|
|
9732
|
+
async function projectCaseDossierPointerSection(input) {
|
|
9733
|
+
if (input.ticketNumber === void 0) return void 0;
|
|
9734
|
+
const volume = resolveTicketProvenanceVolume(
|
|
9735
|
+
input.ticketNumber,
|
|
9736
|
+
input.projectRoot,
|
|
9737
|
+
input.home
|
|
9738
|
+
);
|
|
9739
|
+
return [
|
|
9740
|
+
CASE_DOSSIER_SECTION_HEADING,
|
|
9741
|
+
"",
|
|
9742
|
+
`\u7968\u53F7\uFF1A#${input.ticketNumber}`,
|
|
9743
|
+
`\u4EBA\u8BFB\u89C6\u56FE\uFF1A${await describeDossierFile(volume.humanViewFile)}`,
|
|
9744
|
+
`\u8BB0\u5F55\u5377\u5B97\uFF1A${await describeDossierFile(volume.recordFile)}`
|
|
9745
|
+
].join("\n");
|
|
9746
|
+
}
|
|
9747
|
+
var CASE_DOSSIER_SECTION_HEADING;
|
|
9748
|
+
var init_case_dossier_delivery = __esm({
|
|
9749
|
+
"src/public-cli/case-dossier-delivery.ts"() {
|
|
9750
|
+
"use strict";
|
|
9751
|
+
init_ticket_provenance();
|
|
9752
|
+
CASE_DOSSIER_SECTION_HEADING = "## \u672C\u7968\u8D77\u5C45\u5F55\uFF08\u7CFB\u7EDF\u968F\u6848\u63D0\u4F9B\uFF09";
|
|
9753
|
+
}
|
|
9754
|
+
});
|
|
9755
|
+
|
|
10451
9756
|
// src/host-transition-prior-native.ts
|
|
10452
|
-
import { access as
|
|
10453
|
-
import { dirname as dirname9, join as
|
|
9757
|
+
import { access as access2, readdir as readdir3 } from "node:fs/promises";
|
|
9758
|
+
import { dirname as dirname9, join as join17 } from "node:path";
|
|
10454
9759
|
function isEnoent2(error) {
|
|
10455
9760
|
return typeof error === "object" && error !== null && error.code === "ENOENT";
|
|
10456
9761
|
}
|
|
10457
9762
|
async function listPiNativeRecordPaths(sessionFile) {
|
|
10458
9763
|
try {
|
|
10459
|
-
await
|
|
9764
|
+
await access2(sessionFile);
|
|
10460
9765
|
return [sessionFile];
|
|
10461
9766
|
} catch (error) {
|
|
10462
9767
|
if (isEnoent2(error)) return [];
|
|
@@ -10475,9 +9780,9 @@ async function listSitianRecordPaths(sessionParent) {
|
|
|
10475
9780
|
const recordPaths = [];
|
|
10476
9781
|
for (const entry of entries) {
|
|
10477
9782
|
if (!entry.isDirectory()) continue;
|
|
10478
|
-
const recordFile =
|
|
9783
|
+
const recordFile = join17(sessionRoot, entry.name, "records.jsonl");
|
|
10479
9784
|
try {
|
|
10480
|
-
await
|
|
9785
|
+
await access2(recordFile);
|
|
10481
9786
|
recordPaths.push(recordFile);
|
|
10482
9787
|
} catch (error) {
|
|
10483
9788
|
if (!isEnoent2(error)) throw error;
|
|
@@ -10737,7 +10042,7 @@ var init_gatekeeper_role = __esm({
|
|
|
10737
10042
|
});
|
|
10738
10043
|
|
|
10739
10044
|
// src/run-terminal-artifacts.ts
|
|
10740
|
-
import { basename as basename6, dirname as dirname10, join as
|
|
10045
|
+
import { basename as basename6, dirname as dirname10, join as join18 } from "node:path";
|
|
10741
10046
|
function runIdFromRunDirectory(runDirectory) {
|
|
10742
10047
|
const name = basename6(runDirectory);
|
|
10743
10048
|
const at = name.lastIndexOf("@");
|
|
@@ -11159,7 +10464,7 @@ var init_ledger_session_read = __esm({
|
|
|
11159
10464
|
|
|
11160
10465
|
// src/analyst-gate-cycles-read.ts
|
|
11161
10466
|
import { readdir as readdir4 } from "node:fs/promises";
|
|
11162
|
-
import { join as
|
|
10467
|
+
import { join as join19 } from "node:path";
|
|
11163
10468
|
function isRecord15(value) {
|
|
11164
10469
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
11165
10470
|
}
|
|
@@ -11420,7 +10725,7 @@ async function readAnalystGateCyclesFromAuditorRoles(auditorRolesDirectory, opti
|
|
|
11420
10725
|
throw error;
|
|
11421
10726
|
}
|
|
11422
10727
|
for (const name of names) {
|
|
11423
|
-
const path =
|
|
10728
|
+
const path = join19(directory, name);
|
|
11424
10729
|
const sessionPath = name.endsWith(".pointer.json") ? await resolveOfficerSessionFromPointerFile(path) : path;
|
|
11425
10730
|
if (sessionPath === void 0) continue;
|
|
11426
10731
|
const classified = await classifyAuditorVolume(sessionPath);
|
|
@@ -11459,22 +10764,22 @@ var init_analyst_gate_cycles_read = __esm({
|
|
|
11459
10764
|
// src/session-opening-materials.ts
|
|
11460
10765
|
import { existsSync as existsSync7 } from "node:fs";
|
|
11461
10766
|
import { readFile as readFile12 } from "node:fs/promises";
|
|
11462
|
-
import { dirname as dirname11, join as
|
|
11463
|
-
import { fileURLToPath
|
|
10767
|
+
import { dirname as dirname11, join as join20 } from "node:path";
|
|
10768
|
+
import { fileURLToPath, pathToFileURL as pathToFileURL2 } from "node:url";
|
|
11464
10769
|
function resolvePackageRootDir(moduleUrl = import.meta.url) {
|
|
11465
|
-
let dir = dirname11(
|
|
10770
|
+
let dir = dirname11(fileURLToPath(moduleUrl));
|
|
11466
10771
|
for (let i = 0; i < 8; i += 1) {
|
|
11467
|
-
if (existsSync7(
|
|
10772
|
+
if (existsSync7(join20(dir, "package.json")) && existsSync7(join20(dir, "souls"))) {
|
|
11468
10773
|
return dir;
|
|
11469
10774
|
}
|
|
11470
10775
|
const parent = dirname11(dir);
|
|
11471
10776
|
if (parent === dir) break;
|
|
11472
10777
|
dir = parent;
|
|
11473
10778
|
}
|
|
11474
|
-
return
|
|
10779
|
+
return fileURLToPath(new URL("..", moduleUrl));
|
|
11475
10780
|
}
|
|
11476
10781
|
async function readPackageMaterial(relativePath) {
|
|
11477
|
-
return readFile12(
|
|
10782
|
+
return readFile12(fileURLToPath(new URL(relativePath, packageRootUrl)), "utf8");
|
|
11478
10783
|
}
|
|
11479
10784
|
async function joinPackageMaterials(relativePaths) {
|
|
11480
10785
|
const chunks = [];
|
|
@@ -11671,75 +10976,400 @@ function createPiJudgeAuditor() {
|
|
|
11671
10976
|
});
|
|
11672
10977
|
};
|
|
11673
10978
|
}
|
|
11674
|
-
var init_judge_auditor = __esm({
|
|
11675
|
-
"src/judge-auditor.ts"() {
|
|
11676
|
-
"use strict";
|
|
11677
|
-
init_compliance_transport();
|
|
11678
|
-
init_auditor_dossier_tool();
|
|
11679
|
-
init_dossier_resolution();
|
|
10979
|
+
var init_judge_auditor = __esm({
|
|
10980
|
+
"src/judge-auditor.ts"() {
|
|
10981
|
+
"use strict";
|
|
10982
|
+
init_compliance_transport();
|
|
10983
|
+
init_auditor_dossier_tool();
|
|
10984
|
+
init_dossier_resolution();
|
|
10985
|
+
}
|
|
10986
|
+
});
|
|
10987
|
+
|
|
10988
|
+
// src/upstream-error-testimony.ts
|
|
10989
|
+
function isNonSuccessHttpStatus(status) {
|
|
10990
|
+
return typeof status === "number" && (status < 200 || status >= 300);
|
|
10991
|
+
}
|
|
10992
|
+
function hasUpstreamErrorTestimony(input) {
|
|
10993
|
+
if (isNonSuccessHttpStatus(input.httpStatus)) return true;
|
|
10994
|
+
return Array.isArray(input.diagnostics) && input.diagnostics.length > 0;
|
|
10995
|
+
}
|
|
10996
|
+
function projectConfirmedRemotePayload(input) {
|
|
10997
|
+
return {
|
|
10998
|
+
...input.body === void 0 ? {} : { body: input.body },
|
|
10999
|
+
...input.code === void 0 ? {} : { code: input.code },
|
|
11000
|
+
...input.errno === void 0 ? {} : { errno: input.errno }
|
|
11001
|
+
};
|
|
11002
|
+
}
|
|
11003
|
+
var init_upstream_error_testimony = __esm({
|
|
11004
|
+
"src/upstream-error-testimony.ts"() {
|
|
11005
|
+
"use strict";
|
|
11006
|
+
}
|
|
11007
|
+
});
|
|
11008
|
+
|
|
11009
|
+
// src/pi/known-failure.ts
|
|
11010
|
+
function nonEmptyString(value) {
|
|
11011
|
+
return typeof value === "string" && value.trim() !== "" ? value : void 0;
|
|
11012
|
+
}
|
|
11013
|
+
function sessionStopDetails(input) {
|
|
11014
|
+
const details = {};
|
|
11015
|
+
const errorMessage = nonEmptyString(input.errorMessage);
|
|
11016
|
+
if (errorMessage !== void 0) details.errorMessage = errorMessage;
|
|
11017
|
+
const api = nonEmptyString(input.api);
|
|
11018
|
+
if (api !== void 0) details.api = api;
|
|
11019
|
+
const rawStopReason = nonEmptyString(input.rawStopReason);
|
|
11020
|
+
if (rawStopReason !== void 0) details.rawStopReason = rawStopReason;
|
|
11021
|
+
const testimony = hasUpstreamErrorTestimony(input);
|
|
11022
|
+
if (testimony) {
|
|
11023
|
+
const provider = nonEmptyString(input.provider);
|
|
11024
|
+
if (provider !== void 0) details.provider = provider;
|
|
11025
|
+
const model = nonEmptyString(input.model);
|
|
11026
|
+
if (model !== void 0) details.model = model;
|
|
11027
|
+
}
|
|
11028
|
+
if (typeof input.httpStatus === "number") details.httpStatus = input.httpStatus;
|
|
11029
|
+
if (input.diagnostics !== void 0) details.diagnostics = input.diagnostics;
|
|
11030
|
+
if (testimony) Object.assign(details, projectConfirmedRemotePayload(input));
|
|
11031
|
+
return details;
|
|
11032
|
+
}
|
|
11033
|
+
function knownFailureFromProviderStop(input) {
|
|
11034
|
+
if (input.stopReason !== "error" && input.stopReason !== "aborted") return void 0;
|
|
11035
|
+
const diagnostic = nonEmptyString(input.errorMessage);
|
|
11036
|
+
const details = sessionStopDetails(input);
|
|
11037
|
+
return {
|
|
11038
|
+
cause: hasUpstreamErrorTestimony(input) ? "provider" : "unrecognized",
|
|
11039
|
+
...diagnostic === void 0 ? {} : { diagnostic },
|
|
11040
|
+
...Object.keys(details).length === 0 ? {} : { details }
|
|
11041
|
+
};
|
|
11042
|
+
}
|
|
11043
|
+
var init_known_failure = __esm({
|
|
11044
|
+
"src/pi/known-failure.ts"() {
|
|
11045
|
+
"use strict";
|
|
11046
|
+
init_upstream_error_testimony();
|
|
11047
|
+
init_upstream_error_testimony();
|
|
11048
|
+
}
|
|
11049
|
+
});
|
|
11050
|
+
|
|
11051
|
+
// src/adr-path-refs.ts
|
|
11052
|
+
function extractReferencedAdrPaths(text) {
|
|
11053
|
+
const seen = /* @__PURE__ */ new Set();
|
|
11054
|
+
const paths = [];
|
|
11055
|
+
for (const match of text.matchAll(ADR_PATH_IN_BODY)) {
|
|
11056
|
+
const path = match[0];
|
|
11057
|
+
if (seen.has(path)) continue;
|
|
11058
|
+
seen.add(path);
|
|
11059
|
+
paths.push(path);
|
|
11060
|
+
}
|
|
11061
|
+
return Object.freeze(paths);
|
|
11062
|
+
}
|
|
11063
|
+
var ADR_PATH_IN_BODY;
|
|
11064
|
+
var init_adr_path_refs = __esm({
|
|
11065
|
+
"src/adr-path-refs.ts"() {
|
|
11066
|
+
"use strict";
|
|
11067
|
+
ADR_PATH_IN_BODY = /docs\/adr\/(?:[A-Za-z0-9][A-Za-z0-9._-]*\/)*[A-Za-z0-9][A-Za-z0-9._-]*\.md/g;
|
|
11068
|
+
}
|
|
11069
|
+
});
|
|
11070
|
+
|
|
11071
|
+
// src/reviewer-git-snapshot.ts
|
|
11072
|
+
function parseReviewerRefSnapshot(raw) {
|
|
11073
|
+
const refs = {};
|
|
11074
|
+
for (const line2 of raw.split("\n")) {
|
|
11075
|
+
if (!line2) continue;
|
|
11076
|
+
const fields = line2.split("\0");
|
|
11077
|
+
if (fields.length !== 5 || !fields[0] || !fields[1] || !fields[3]) {
|
|
11078
|
+
throw new Error(`Malformed Git ref snapshot line: ${line2}`);
|
|
11079
|
+
}
|
|
11080
|
+
const peeledCommitId = fields[3] === "commit" ? fields[1] : fields[4] === "commit" && fields[2] ? fields[2] : null;
|
|
11081
|
+
refs[fields[0]] = Object.freeze({
|
|
11082
|
+
objectId: fields[1],
|
|
11083
|
+
peeledCommitId
|
|
11084
|
+
});
|
|
11085
|
+
}
|
|
11086
|
+
return refs;
|
|
11087
|
+
}
|
|
11088
|
+
function reviewerRefSnapshotArgs() {
|
|
11089
|
+
return ["for-each-ref", "--format=%(refname)%00%(objectname)%00%(*objectname)%00%(objecttype)%00%(*objecttype)", ...REVIEW_REF_PREFIXES];
|
|
11090
|
+
}
|
|
11091
|
+
function immutableReviewerRefs(refs) {
|
|
11092
|
+
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 })])));
|
|
11093
|
+
}
|
|
11094
|
+
function sameReviewerPinnedTarget(actual, expected) {
|
|
11095
|
+
return actual.repositoryRoot === expected.repositoryRoot && actual.objectFormat === expected.objectFormat && actual.targetHead === expected.targetHead;
|
|
11096
|
+
}
|
|
11097
|
+
var REVIEW_REF_PREFIXES;
|
|
11098
|
+
var init_reviewer_git_snapshot = __esm({
|
|
11099
|
+
"src/reviewer-git-snapshot.ts"() {
|
|
11100
|
+
"use strict";
|
|
11101
|
+
REVIEW_REF_PREFIXES = ["refs/heads", "refs/tags", "refs/remotes"];
|
|
11102
|
+
}
|
|
11103
|
+
});
|
|
11104
|
+
|
|
11105
|
+
// src/reviewer-preflight-error.ts
|
|
11106
|
+
var ReviewerCorrectablePreflightError;
|
|
11107
|
+
var init_reviewer_preflight_error = __esm({
|
|
11108
|
+
"src/reviewer-preflight-error.ts"() {
|
|
11109
|
+
"use strict";
|
|
11110
|
+
ReviewerCorrectablePreflightError = class extends Error {
|
|
11111
|
+
constructor(code, diagnostic = `${code} constraint failed`, options) {
|
|
11112
|
+
super(`${code}: ${diagnostic}`, options);
|
|
11113
|
+
this.code = code;
|
|
11114
|
+
this.diagnostic = diagnostic;
|
|
11115
|
+
this.name = "ReviewerCorrectablePreflightError";
|
|
11116
|
+
}
|
|
11117
|
+
code;
|
|
11118
|
+
diagnostic;
|
|
11119
|
+
};
|
|
11120
|
+
}
|
|
11121
|
+
});
|
|
11122
|
+
|
|
11123
|
+
// src/reviewer-pinned-git.ts
|
|
11124
|
+
import { execFile as execFile3 } from "node:child_process";
|
|
11125
|
+
import { access as access3, realpath as realpath6 } from "node:fs/promises";
|
|
11126
|
+
import { promisify as promisify3 } from "node:util";
|
|
11127
|
+
async function execGit(args, options) {
|
|
11128
|
+
try {
|
|
11129
|
+
return await execFileAsync3("git", args, {
|
|
11130
|
+
...options,
|
|
11131
|
+
env: { ...process.env, LC_ALL: "C" }
|
|
11132
|
+
});
|
|
11133
|
+
} catch (error) {
|
|
11134
|
+
const source = error;
|
|
11135
|
+
const wrapped = new Error("git process failed", { cause: error });
|
|
11136
|
+
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 ?? "") });
|
|
11137
|
+
throw wrapped;
|
|
11138
|
+
}
|
|
11139
|
+
}
|
|
11140
|
+
function exitCode(error) {
|
|
11141
|
+
const code = typeof error === "object" && error !== null ? error.code : void 0;
|
|
11142
|
+
return typeof code === "number" ? code : void 0;
|
|
11143
|
+
}
|
|
11144
|
+
function gitStderr(error) {
|
|
11145
|
+
if (typeof error !== "object" || error === null) return "";
|
|
11146
|
+
const stderr = error.stderr;
|
|
11147
|
+
return typeof stderr === "string" ? stderr : "";
|
|
11148
|
+
}
|
|
11149
|
+
function isConfirmedMissingOriginRemote(error) {
|
|
11150
|
+
return /No such remote ['"]origin['"]/.test(gitStderr(error));
|
|
11151
|
+
}
|
|
11152
|
+
function isConfirmedPinnedPathAbsent(error, path) {
|
|
11153
|
+
const stderr = gitStderr(error);
|
|
11154
|
+
const quoted = `'${path}'`;
|
|
11155
|
+
return stderr.includes(`path ${quoted} does not exist in `) || stderr.includes(`path ${quoted} exists on disk, but not in `);
|
|
11156
|
+
}
|
|
11157
|
+
async function repositoryIsAvailable(root) {
|
|
11158
|
+
try {
|
|
11159
|
+
await access3(`${root}/.git`);
|
|
11160
|
+
return { available: true };
|
|
11161
|
+
} catch (cause) {
|
|
11162
|
+
return { available: false, cause };
|
|
11163
|
+
}
|
|
11164
|
+
}
|
|
11165
|
+
function shortNameFromPinnedRef(refName) {
|
|
11166
|
+
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;
|
|
11167
|
+
const trimmed = short.trim();
|
|
11168
|
+
return trimmed === "" ? void 0 : trimmed;
|
|
11169
|
+
}
|
|
11170
|
+
function branchNamesAtPinnedHead(pin) {
|
|
11171
|
+
const names = /* @__PURE__ */ new Set();
|
|
11172
|
+
for (const [refName, entry] of Object.entries(pin.refs)) {
|
|
11173
|
+
if (entry.peeledCommitId !== pin.targetHead) continue;
|
|
11174
|
+
if (!refName.startsWith("refs/heads/") && !refName.startsWith("refs/remotes/")) continue;
|
|
11175
|
+
const short = shortNameFromPinnedRef(refName);
|
|
11176
|
+
if (short !== void 0) names.add(short);
|
|
11680
11177
|
}
|
|
11681
|
-
|
|
11682
|
-
|
|
11683
|
-
// src/upstream-error-testimony.ts
|
|
11684
|
-
function isNonSuccessHttpStatus(status) {
|
|
11685
|
-
return typeof status === "number" && (status < 200 || status >= 300);
|
|
11178
|
+
return Object.freeze([...names]);
|
|
11686
11179
|
}
|
|
11687
|
-
function
|
|
11688
|
-
|
|
11689
|
-
return
|
|
11180
|
+
async function gitText(root, args) {
|
|
11181
|
+
const { stdout } = await execGit(["-C", root, ...args], { encoding: "utf8" });
|
|
11182
|
+
return stdout.trim();
|
|
11690
11183
|
}
|
|
11691
|
-
function
|
|
11692
|
-
|
|
11693
|
-
|
|
11694
|
-
|
|
11695
|
-
|
|
11184
|
+
async function createReviewerPinnedGitReader(root = process.cwd()) {
|
|
11185
|
+
const discoveredRoot = await gitText(root, ["rev-parse", "--show-toplevel"]);
|
|
11186
|
+
const repositoryRoot = await realpath6(discoveredRoot);
|
|
11187
|
+
const objectFormat = await gitText(repositoryRoot, ["rev-parse", "--show-object-format"]);
|
|
11188
|
+
if (objectFormat !== "sha1" && objectFormat !== "sha256") throw new Error("Unsupported Git object format");
|
|
11189
|
+
const oidWidth = objectFormat === "sha1" ? 40 : 64;
|
|
11190
|
+
const targetHead = await gitText(repositoryRoot, ["rev-parse", "HEAD^{commit}"]);
|
|
11191
|
+
const reachableCommitIds = Object.freeze((await gitText(repositoryRoot, ["rev-list", targetHead])).split("\n").filter(Boolean));
|
|
11192
|
+
const refs = parseReviewerRefSnapshot(await gitText(repositoryRoot, reviewerRefSnapshotArgs()));
|
|
11193
|
+
const pin = immutableReviewerPin({ repositoryRoot, objectFormat, targetHead, refs });
|
|
11194
|
+
const invalid = (code, diagnostic, cause) => {
|
|
11195
|
+
throw new ReviewerCorrectablePreflightError(code, diagnostic, cause === void 0 ? void 0 : { cause });
|
|
11196
|
+
};
|
|
11197
|
+
const symbolic = (base) => {
|
|
11198
|
+
const selected = Object.hasOwn(refs, base) ? base : (() => {
|
|
11199
|
+
const candidates = [`refs/heads/${base}`, `refs/tags/${base}`, `refs/remotes/${base}`].filter((name) => Object.hasOwn(refs, name));
|
|
11200
|
+
if (candidates.length > 1) invalid("base-invalid", "base revision is ambiguous across pinned refs");
|
|
11201
|
+
return candidates[0];
|
|
11202
|
+
})();
|
|
11203
|
+
if (selected === void 0) return void 0;
|
|
11204
|
+
const commit = refs[selected]?.peeledCommitId;
|
|
11205
|
+
if (commit === null) invalid("base-invalid", "base revision ref must resolve to a commit");
|
|
11206
|
+
return commit ?? void 0;
|
|
11696
11207
|
};
|
|
11208
|
+
return Object.freeze({
|
|
11209
|
+
pin,
|
|
11210
|
+
async snapshot() {
|
|
11211
|
+
const liveObjectFormat = await gitText(repositoryRoot, ["rev-parse", "--show-object-format"]);
|
|
11212
|
+
if (liveObjectFormat !== "sha1" && liveObjectFormat !== "sha256") throw new Error("Unsupported Git object format");
|
|
11213
|
+
return immutableReviewerPin({ repositoryRoot, objectFormat: liveObjectFormat, targetHead: await gitText(repositoryRoot, ["rev-parse", "HEAD^{commit}"]), refs: parseReviewerRefSnapshot(await gitText(repositoryRoot, reviewerRefSnapshotArgs())) });
|
|
11214
|
+
},
|
|
11215
|
+
async resolve(base) {
|
|
11216
|
+
if (!/^[A-Za-z0-9._/~^+-]+$/.test(base) || base.startsWith("-") || base.includes("..") || base.includes("@{")) {
|
|
11217
|
+
invalid("base-invalid", "base revision syntax is invalid or uses a forbidden revision form");
|
|
11218
|
+
}
|
|
11219
|
+
let commit;
|
|
11220
|
+
const headExpression = /^HEAD((?:~[0-9]+|\^[0-9]+)*)$/.exec(base);
|
|
11221
|
+
if (headExpression) {
|
|
11222
|
+
try {
|
|
11223
|
+
commit = await gitText(repositoryRoot, ["rev-parse", "--verify", `${targetHead}${headExpression[1]}^{commit}`]);
|
|
11224
|
+
} catch (error) {
|
|
11225
|
+
if (exitCode(error) === 128) {
|
|
11226
|
+
const repository = await repositoryIsAvailable(repositoryRoot);
|
|
11227
|
+
if (repository.available) invalid("base-invalid", "base revision HEAD ancestry expression must resolve to a reachable commit", error);
|
|
11228
|
+
}
|
|
11229
|
+
throw error;
|
|
11230
|
+
}
|
|
11231
|
+
} else if (new RegExp(`^[0-9a-f]{${oidWidth}}$`).test(base)) commit = base;
|
|
11232
|
+
else if (new RegExp(`^[0-9a-f]{4,${oidWidth - 1}}$`).test(base) && !(objectFormat === "sha256" && base.length === 40)) {
|
|
11233
|
+
const matches = reachableCommitIds.filter((candidate) => candidate.startsWith(base));
|
|
11234
|
+
if (matches.length !== 1) invalid("base-invalid", "base revision abbreviation must identify exactly one reachable commit");
|
|
11235
|
+
commit = matches[0];
|
|
11236
|
+
} else commit = symbolic(base);
|
|
11237
|
+
if (commit === void 0) invalid("base-invalid", "base revision must name an existing pinned ref or reachable commit");
|
|
11238
|
+
try {
|
|
11239
|
+
commit = await gitText(repositoryRoot, ["rev-parse", "--verify", `${commit}^{commit}`]);
|
|
11240
|
+
} catch (error) {
|
|
11241
|
+
if (exitCode(error) === 128) {
|
|
11242
|
+
const repository = await repositoryIsAvailable(repositoryRoot);
|
|
11243
|
+
if (repository.available) invalid("base-invalid", "base revision must resolve to an existing commit", error);
|
|
11244
|
+
}
|
|
11245
|
+
throw error;
|
|
11246
|
+
}
|
|
11247
|
+
try {
|
|
11248
|
+
await gitText(repositoryRoot, ["merge-base", "--is-ancestor", commit, targetHead]);
|
|
11249
|
+
} catch (error) {
|
|
11250
|
+
if (exitCode(error) === 1) invalid("base-invalid", "base revision must be an ancestor of the pinned target", error);
|
|
11251
|
+
throw error;
|
|
11252
|
+
}
|
|
11253
|
+
return commit;
|
|
11254
|
+
},
|
|
11255
|
+
async range(base) {
|
|
11256
|
+
let mergeBase;
|
|
11257
|
+
try {
|
|
11258
|
+
mergeBase = await gitText(repositoryRoot, ["merge-base", base, targetHead]);
|
|
11259
|
+
} catch (error) {
|
|
11260
|
+
if (exitCode(error) === 1) {
|
|
11261
|
+
invalid("range-invalid", "review range requires a common ancestor for base and pinned target", error);
|
|
11262
|
+
}
|
|
11263
|
+
throw error;
|
|
11264
|
+
}
|
|
11265
|
+
if (!mergeBase) invalid("range-invalid", "review range requires a common ancestor for base and pinned target");
|
|
11266
|
+
const diffCommand = `git diff ${mergeBase}...${targetHead}`;
|
|
11267
|
+
const [{ stdout: diff }, commitsText] = await Promise.all([
|
|
11268
|
+
execGit(["-C", repositoryRoot, "diff", `${mergeBase}...${targetHead}`], { encoding: "buffer", maxBuffer: 64 * 1024 * 1024 }),
|
|
11269
|
+
gitText(repositoryRoot, ["rev-list", "--reverse", `${mergeBase}..${targetHead}`])
|
|
11270
|
+
]);
|
|
11271
|
+
if (diff.length === 0) invalid("range-invalid", "review range must contain a non-empty diff between base and pinned target");
|
|
11272
|
+
return Object.freeze({ base: mergeBase, target: targetHead, diffCommand, diffSha256: sha256Hex(Uint8Array.from(diff)), commits: Object.freeze(commitsText ? commitsText.split("\n") : []) });
|
|
11273
|
+
},
|
|
11274
|
+
async featureTokens() {
|
|
11275
|
+
const names = /* @__PURE__ */ new Set();
|
|
11276
|
+
for (const [refName, entry] of Object.entries(pin.refs)) {
|
|
11277
|
+
if (entry.peeledCommitId !== targetHead) continue;
|
|
11278
|
+
const short = shortNameFromPinnedRef(refName);
|
|
11279
|
+
if (short !== void 0) names.add(short);
|
|
11280
|
+
}
|
|
11281
|
+
return Object.freeze([...names]);
|
|
11282
|
+
},
|
|
11283
|
+
async listSpecCandidatePaths() {
|
|
11284
|
+
const roots = ["docs", "specs", ".scratch"];
|
|
11285
|
+
const text = await gitText(repositoryRoot, [
|
|
11286
|
+
"ls-tree",
|
|
11287
|
+
"-r",
|
|
11288
|
+
"--name-only",
|
|
11289
|
+
targetHead,
|
|
11290
|
+
"--",
|
|
11291
|
+
...roots
|
|
11292
|
+
]);
|
|
11293
|
+
return Object.freeze(text === "" ? [] : text.split("\n").filter((line2) => line2.length > 0));
|
|
11294
|
+
},
|
|
11295
|
+
async originRepository() {
|
|
11296
|
+
let remoteUrl;
|
|
11297
|
+
try {
|
|
11298
|
+
remoteUrl = await gitText(repositoryRoot, ["remote", "get-url", "origin"]);
|
|
11299
|
+
} catch (error) {
|
|
11300
|
+
if (isConfirmedMissingOriginRemote(error)) return void 0;
|
|
11301
|
+
throw error;
|
|
11302
|
+
}
|
|
11303
|
+
return parseGitHubOriginRemote(remoteUrl);
|
|
11304
|
+
},
|
|
11305
|
+
async commitMessagesNewestFirst(base) {
|
|
11306
|
+
const text = await gitText(repositoryRoot, [
|
|
11307
|
+
"log",
|
|
11308
|
+
"--format=%s",
|
|
11309
|
+
`${base}..${targetHead}`
|
|
11310
|
+
]);
|
|
11311
|
+
return Object.freeze(text === "" ? [] : text.split("\n"));
|
|
11312
|
+
},
|
|
11313
|
+
async readPinnedText(path) {
|
|
11314
|
+
if (path.length === 0 || path.startsWith("/") || path.includes("\0") || path.split("/").some((part) => part === ".." || part === "")) {
|
|
11315
|
+
return void 0;
|
|
11316
|
+
}
|
|
11317
|
+
try {
|
|
11318
|
+
const { stdout } = await execGit(
|
|
11319
|
+
["-C", repositoryRoot, "show", `${targetHead}:${path}`],
|
|
11320
|
+
{ encoding: "utf8", maxBuffer: 8 * 1024 * 1024 }
|
|
11321
|
+
);
|
|
11322
|
+
return stdout;
|
|
11323
|
+
} catch (error) {
|
|
11324
|
+
if (isConfirmedPinnedPathAbsent(error, path)) return void 0;
|
|
11325
|
+
throw error;
|
|
11326
|
+
}
|
|
11327
|
+
}
|
|
11328
|
+
});
|
|
11697
11329
|
}
|
|
11698
|
-
|
|
11699
|
-
|
|
11700
|
-
|
|
11330
|
+
function parseGitHubOriginRemote(remoteUrl) {
|
|
11331
|
+
const trimmed = remoteUrl.trim();
|
|
11332
|
+
if (trimmed.length === 0) return void 0;
|
|
11333
|
+
const scp = /^git@github\.com:([^/\s]+)\/([^/\s]+?)(?:\.git)?$/i.exec(trimmed);
|
|
11334
|
+
if (scp) return normalizeOrigin(scp[1], scp[2]);
|
|
11335
|
+
const ssh = /^ssh:\/\/git@github\.com\/([^/\s]+)\/([^/\s]+?)(?:\.git)?\/?$/i.exec(trimmed);
|
|
11336
|
+
if (ssh) return normalizeOrigin(ssh[1], ssh[2]);
|
|
11337
|
+
let parsed;
|
|
11338
|
+
try {
|
|
11339
|
+
parsed = new URL(trimmed);
|
|
11340
|
+
} catch {
|
|
11341
|
+
return void 0;
|
|
11701
11342
|
}
|
|
11702
|
-
|
|
11703
|
-
|
|
11704
|
-
|
|
11705
|
-
|
|
11706
|
-
return
|
|
11343
|
+
if (!/^github\.com$/i.test(parsed.hostname)) return void 0;
|
|
11344
|
+
if (parsed.search !== "" || parsed.hash !== "") return void 0;
|
|
11345
|
+
const parts = parsed.pathname.split("/").filter((p) => p.length > 0);
|
|
11346
|
+
if (parts.length !== 2) return void 0;
|
|
11347
|
+
return normalizeOrigin(parts[0], parts[1]);
|
|
11707
11348
|
}
|
|
11708
|
-
function
|
|
11709
|
-
const
|
|
11710
|
-
const
|
|
11711
|
-
if (
|
|
11712
|
-
|
|
11713
|
-
|
|
11714
|
-
const rawStopReason = nonEmptyString(input.rawStopReason);
|
|
11715
|
-
if (rawStopReason !== void 0) details.rawStopReason = rawStopReason;
|
|
11716
|
-
const testimony = hasUpstreamErrorTestimony(input);
|
|
11717
|
-
if (testimony) {
|
|
11718
|
-
const provider = nonEmptyString(input.provider);
|
|
11719
|
-
if (provider !== void 0) details.provider = provider;
|
|
11720
|
-
const model = nonEmptyString(input.model);
|
|
11721
|
-
if (model !== void 0) details.model = model;
|
|
11722
|
-
}
|
|
11723
|
-
if (typeof input.httpStatus === "number") details.httpStatus = input.httpStatus;
|
|
11724
|
-
if (input.diagnostics !== void 0) details.diagnostics = input.diagnostics;
|
|
11725
|
-
if (testimony) Object.assign(details, projectConfirmedRemotePayload(input));
|
|
11726
|
-
return details;
|
|
11349
|
+
function normalizeOrigin(ownerRaw, repoRaw) {
|
|
11350
|
+
const owner = ownerRaw.trim();
|
|
11351
|
+
const repo = stripGitSuffix2(repoRaw.trim());
|
|
11352
|
+
if (owner.length === 0 || repo.length === 0) return void 0;
|
|
11353
|
+
if (/[/?#@\\]/.test(owner) || /[/?#@\\]/.test(repo)) return void 0;
|
|
11354
|
+
return Object.freeze({ owner, repo });
|
|
11727
11355
|
}
|
|
11728
|
-
function
|
|
11729
|
-
|
|
11730
|
-
const diagnostic = nonEmptyString(input.errorMessage);
|
|
11731
|
-
const details = sessionStopDetails(input);
|
|
11732
|
-
return {
|
|
11733
|
-
cause: hasUpstreamErrorTestimony(input) ? "provider" : "unrecognized",
|
|
11734
|
-
...diagnostic === void 0 ? {} : { diagnostic },
|
|
11735
|
-
...Object.keys(details).length === 0 ? {} : { details }
|
|
11736
|
-
};
|
|
11356
|
+
function stripGitSuffix2(name) {
|
|
11357
|
+
return name.toLowerCase().endsWith(".git") ? name.slice(0, -4) : name;
|
|
11737
11358
|
}
|
|
11738
|
-
var
|
|
11739
|
-
|
|
11359
|
+
var execFileAsync3, immutableReviewerPin;
|
|
11360
|
+
var init_reviewer_pinned_git = __esm({
|
|
11361
|
+
"src/reviewer-pinned-git.ts"() {
|
|
11740
11362
|
"use strict";
|
|
11741
|
-
|
|
11742
|
-
|
|
11363
|
+
init_reviewer_git_snapshot();
|
|
11364
|
+
init_sha256();
|
|
11365
|
+
init_reviewer_preflight_error();
|
|
11366
|
+
execFileAsync3 = promisify3(execFile3);
|
|
11367
|
+
immutableReviewerPin = (pin) => Object.freeze({
|
|
11368
|
+
repositoryRoot: pin.repositoryRoot,
|
|
11369
|
+
objectFormat: pin.objectFormat,
|
|
11370
|
+
targetHead: pin.targetHead,
|
|
11371
|
+
refs: immutableReviewerRefs(pin.refs)
|
|
11372
|
+
});
|
|
11743
11373
|
}
|
|
11744
11374
|
});
|
|
11745
11375
|
|
|
@@ -12113,12 +11743,12 @@ var init_reviewer_dispatch = __esm({
|
|
|
12113
11743
|
// src/public-cli/reviewer-dispatch-rejection.ts
|
|
12114
11744
|
import { writeFileSync as writeFileSync4 } from "node:fs";
|
|
12115
11745
|
import { readFile as readFile13, unlink as unlink3 } from "node:fs/promises";
|
|
12116
|
-
import { join as
|
|
11746
|
+
import { join as join21 } from "node:path";
|
|
12117
11747
|
function isReviewerPreflightViolation(value) {
|
|
12118
11748
|
return typeof value === "string" && REVIEWER_PREFLIGHT_VIOLATIONS.includes(value);
|
|
12119
11749
|
}
|
|
12120
11750
|
function reviewerDispatchRejectionPath(runDirectory) {
|
|
12121
|
-
return
|
|
11751
|
+
return join21(runDirectory, REVIEWER_DISPATCH_REJECTION_FILE);
|
|
12122
11752
|
}
|
|
12123
11753
|
function recordReviewerDispatchRejectionSync(runDirectory, rejection) {
|
|
12124
11754
|
writeFileSync4(
|
|
@@ -13284,7 +12914,7 @@ var init_collector_ledger = __esm({
|
|
|
13284
12914
|
// src/package-resources/method-skill.ts
|
|
13285
12915
|
import { createHash as createHash7 } from "node:crypto";
|
|
13286
12916
|
import { readFile as readFile14, realpath as realpath7 } from "node:fs/promises";
|
|
13287
|
-
import { join as
|
|
12917
|
+
import { join as join22 } from "node:path";
|
|
13288
12918
|
function gitBlobOid(bytes) {
|
|
13289
12919
|
const body = typeof bytes === "string" ? Buffer.from(bytes, "utf8") : Buffer.from(bytes);
|
|
13290
12920
|
const header = Buffer.from(`blob ${body.byteLength}\0`, "utf8");
|
|
@@ -13301,10 +12931,10 @@ function packagedMethodSkillRelativeDirectory(name) {
|
|
|
13301
12931
|
return `${METHOD_SKILL_RELATIVE_ROOT}/${name}`;
|
|
13302
12932
|
}
|
|
13303
12933
|
function resolvePackagedMethodSkillRoot(packageRoot, name) {
|
|
13304
|
-
return
|
|
12934
|
+
return join22(packageRoot, packagedMethodSkillRelativeDirectory(name));
|
|
13305
12935
|
}
|
|
13306
12936
|
function resolvePackagedMethodSkillPath(packageRoot, name) {
|
|
13307
|
-
return
|
|
12937
|
+
return join22(resolvePackagedMethodSkillRoot(packageRoot, name), "SKILL.md");
|
|
13308
12938
|
}
|
|
13309
12939
|
function isRecord17(value) {
|
|
13310
12940
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -13398,8 +13028,8 @@ function parseProvenance(raw, expectedName) {
|
|
|
13398
13028
|
}
|
|
13399
13029
|
async function loadPackagedMethodSkillMaterial(packageRoot, name) {
|
|
13400
13030
|
const rootDirectory = resolvePackagedMethodSkillRoot(packageRoot, name);
|
|
13401
|
-
const skillPathConfigured =
|
|
13402
|
-
const provenancePath =
|
|
13031
|
+
const skillPathConfigured = join22(rootDirectory, "SKILL.md");
|
|
13032
|
+
const provenancePath = join22(rootDirectory, "provenance.json");
|
|
13403
13033
|
let provenanceRaw;
|
|
13404
13034
|
try {
|
|
13405
13035
|
provenanceRaw = await readFile14(provenancePath, "utf8");
|
|
@@ -13416,7 +13046,7 @@ async function loadPackagedMethodSkillMaterial(packageRoot, name) {
|
|
|
13416
13046
|
}
|
|
13417
13047
|
const provenance = parseProvenance(provenanceJson, name);
|
|
13418
13048
|
for (const [rel, expected] of Object.entries(provenance.files)) {
|
|
13419
|
-
const absolute =
|
|
13049
|
+
const absolute = join22(rootDirectory, rel);
|
|
13420
13050
|
let bytes;
|
|
13421
13051
|
try {
|
|
13422
13052
|
bytes = await readFile14(absolute);
|
|
@@ -13932,7 +13562,7 @@ var init_terminal = __esm({
|
|
|
13932
13562
|
// src/public-cli/settlement.ts
|
|
13933
13563
|
import { randomUUID as randomUUID3 } from "node:crypto";
|
|
13934
13564
|
import { appendFile as appendFile2, readFile as readFile15, readdir as readdir5, writeFile as writeFile6 } from "node:fs/promises";
|
|
13935
|
-
import { dirname as dirname12, join as
|
|
13565
|
+
import { dirname as dirname12, join as join23 } from "node:path";
|
|
13936
13566
|
function sealedLedgerHome(admitted) {
|
|
13937
13567
|
return homeFromRunDirectory(admitted.runDirectory);
|
|
13938
13568
|
}
|
|
@@ -14328,7 +13958,7 @@ async function readSessionProviderStop(sessionFile) {
|
|
|
14328
13958
|
}
|
|
14329
13959
|
}
|
|
14330
13960
|
async function readBoundEvidenceChildKnownFailure(sessionFile) {
|
|
14331
|
-
const childDirectory =
|
|
13961
|
+
const childDirectory = join23(dirname12(sessionFile), "evidence-children");
|
|
14332
13962
|
let names;
|
|
14333
13963
|
try {
|
|
14334
13964
|
names = await readdir5(childDirectory);
|
|
@@ -14339,7 +13969,7 @@ async function readBoundEvidenceChildKnownFailure(sessionFile) {
|
|
|
14339
13969
|
for (const file of names.filter((name) => name.endsWith(".jsonl")).sort().reverse()) {
|
|
14340
13970
|
let entries;
|
|
14341
13971
|
try {
|
|
14342
|
-
entries = await readBoundSessionEntries(
|
|
13972
|
+
entries = await readBoundSessionEntries(join23(childDirectory, file));
|
|
14343
13973
|
} catch (error) {
|
|
14344
13974
|
throw sessionReadFailure(error, "failed to read discovered evidence-child session");
|
|
14345
13975
|
}
|
|
@@ -14393,7 +14023,7 @@ async function loadBoundAuditorVolumes(sessionFile) {
|
|
|
14393
14023
|
latestParentUserIndex = i;
|
|
14394
14024
|
break;
|
|
14395
14025
|
}
|
|
14396
|
-
const childDirectories = [
|
|
14026
|
+
const childDirectories = [join23(dirname12(sessionFile), "auditor-roles")];
|
|
14397
14027
|
const valid = [];
|
|
14398
14028
|
let sawAnyDirectory = false;
|
|
14399
14029
|
for (const childDirectory of childDirectories) {
|
|
@@ -14408,7 +14038,7 @@ async function loadBoundAuditorVolumes(sessionFile) {
|
|
|
14408
14038
|
for (const file of names.filter((name) => name.endsWith(".jsonl")).sort().reverse()) {
|
|
14409
14039
|
let entries;
|
|
14410
14040
|
try {
|
|
14411
|
-
entries = await readBoundSessionEntries(
|
|
14041
|
+
entries = await readBoundSessionEntries(join23(childDirectory, file));
|
|
14412
14042
|
} catch (error) {
|
|
14413
14043
|
throw sessionReadFailure(error, "failed to read discovered auditor session");
|
|
14414
14044
|
}
|
|
@@ -14908,8 +14538,8 @@ function projectTerminalGateFact(rounds) {
|
|
|
14908
14538
|
};
|
|
14909
14539
|
}
|
|
14910
14540
|
async function extractGateFactFromSessionDirectory(sessionDirectory, options = {}) {
|
|
14911
|
-
const directories = [
|
|
14912
|
-
const parentSessionFile = options.parentSessionFile ??
|
|
14541
|
+
const directories = [join23(sessionDirectory, "auditor-roles")];
|
|
14542
|
+
const parentSessionFile = options.parentSessionFile ?? join23(sessionDirectory, "session.jsonl");
|
|
14913
14543
|
const rounds = await readAnalystGateCyclesFromAuditorRoles(directories, {
|
|
14914
14544
|
parentSessionFile
|
|
14915
14545
|
});
|
|
@@ -15007,8 +14637,8 @@ async function extractNavigatorFactFromAdmittedSession(sessionFile) {
|
|
|
15007
14637
|
async function publishJudgeArtifacts(admitted, roleOutcome, coordinates) {
|
|
15008
14638
|
await appendRunAttemptHistory({ role: admitted.role, runId: admitted.runId, sessionFile: coordinates.sessionFile }, roleOutcome);
|
|
15009
14639
|
const artifactsDir = await ensureRunArtifactsDir(admitted.runDirectory);
|
|
15010
|
-
const reportPath =
|
|
15011
|
-
const evidencePath =
|
|
14640
|
+
const reportPath = join23(artifactsDir, "report.json");
|
|
14641
|
+
const evidencePath = join23(artifactsDir, "evidence.json");
|
|
15012
14642
|
await writeFile6(
|
|
15013
14643
|
reportPath,
|
|
15014
14644
|
`${JSON.stringify(
|
|
@@ -15098,8 +14728,8 @@ async function trySettleJudgeTerminalResult(admitted, authority) {
|
|
|
15098
14728
|
async function publishDoctorArtifacts(admitted, roleOutcome, coordinates, options = {}) {
|
|
15099
14729
|
await appendRunAttemptHistory({ role: admitted.role, runId: admitted.runId, sessionFile: coordinates.sessionFile }, roleOutcome);
|
|
15100
14730
|
const artifactsDir = await ensureRunArtifactsDir(admitted.runDirectory);
|
|
15101
|
-
const reportPath =
|
|
15102
|
-
const evidencePath =
|
|
14731
|
+
const reportPath = join23(artifactsDir, "report.json");
|
|
14732
|
+
const evidencePath = join23(artifactsDir, "evidence.json");
|
|
15103
14733
|
await writeFile6(
|
|
15104
14734
|
reportPath,
|
|
15105
14735
|
`${JSON.stringify(
|
|
@@ -15332,7 +14962,7 @@ function uniqueFailureFallbackDirs(runDirectory, baseDir) {
|
|
|
15332
14962
|
return dirs;
|
|
15333
14963
|
}
|
|
15334
14964
|
async function resolveFailureArtifactsBase(runDirectory) {
|
|
15335
|
-
const artifactsDir =
|
|
14965
|
+
const artifactsDir = join23(runDirectory, "artifacts");
|
|
15336
14966
|
try {
|
|
15337
14967
|
await ensureRunArtifactsDir(runDirectory);
|
|
15338
14968
|
return { baseDir: artifactsDir };
|
|
@@ -15348,7 +14978,7 @@ async function writeFailureJsonRetainingCause(preferredCandidates, uniqueFallbac
|
|
|
15348
14978
|
const candidates = [
|
|
15349
14979
|
...preferredCandidates,
|
|
15350
14980
|
// One unique name per fallback dir — collisions on fixed names cannot exhaust this.
|
|
15351
|
-
...uniqueFallbackDirs.map((dir) =>
|
|
14981
|
+
...uniqueFallbackDirs.map((dir) => join23(dir, `${stem}.${randomUUID3()}.json`))
|
|
15352
14982
|
];
|
|
15353
14983
|
for (let i = 0; i < candidates.length; i += 1) {
|
|
15354
14984
|
const path = candidates[i];
|
|
@@ -15393,26 +15023,26 @@ async function publishFailureArtifacts(admitted, failure2, authority) {
|
|
|
15393
15023
|
} catch (error) {
|
|
15394
15024
|
priorIssues.push(publicationAttemptFromError(sessionFile, error));
|
|
15395
15025
|
}
|
|
15396
|
-
const underArtifacts = baseDir ===
|
|
15026
|
+
const underArtifacts = baseDir === join23(admitted.runDirectory, "artifacts");
|
|
15397
15027
|
const uniqueFallbackDirs = uniqueFailureFallbackDirs(
|
|
15398
15028
|
admitted.runDirectory,
|
|
15399
15029
|
baseDir
|
|
15400
15030
|
);
|
|
15401
15031
|
const errorCandidates = underArtifacts ? [
|
|
15402
|
-
|
|
15403
|
-
|
|
15404
|
-
|
|
15032
|
+
join23(baseDir, "error.json"),
|
|
15033
|
+
join23(baseDir, "error.settlement.json"),
|
|
15034
|
+
join23(admitted.runDirectory, "error.settlement.json")
|
|
15405
15035
|
] : [
|
|
15406
|
-
|
|
15407
|
-
|
|
15036
|
+
join23(baseDir, "error.settlement.json"),
|
|
15037
|
+
join23(baseDir, "error.json")
|
|
15408
15038
|
];
|
|
15409
15039
|
const evidenceCandidates = underArtifacts ? [
|
|
15410
|
-
|
|
15411
|
-
|
|
15412
|
-
|
|
15040
|
+
join23(baseDir, "evidence.json"),
|
|
15041
|
+
join23(baseDir, "evidence.settlement.json"),
|
|
15042
|
+
join23(admitted.runDirectory, "evidence.settlement.json")
|
|
15413
15043
|
] : [
|
|
15414
|
-
|
|
15415
|
-
|
|
15044
|
+
join23(baseDir, "evidence.settlement.json"),
|
|
15045
|
+
join23(baseDir, "evidence.json")
|
|
15416
15046
|
];
|
|
15417
15047
|
const errorPayloadBase = {
|
|
15418
15048
|
kind: "error",
|
|
@@ -15683,7 +15313,7 @@ var init_settlement = __esm({
|
|
|
15683
15313
|
import { constants as fsConstants } from "node:fs";
|
|
15684
15314
|
import { randomUUID as randomUUID4 } from "node:crypto";
|
|
15685
15315
|
import { lstat as lstat5, mkdir as mkdir4, open as open2 } from "node:fs/promises";
|
|
15686
|
-
import { join as
|
|
15316
|
+
import { join as join24 } from "node:path";
|
|
15687
15317
|
function presentTerminal(terminal, io) {
|
|
15688
15318
|
if (terminal.roleOutcome.kind === "failure" || terminal.roleOutcome.kind === "no_receipt") {
|
|
15689
15319
|
presentFailureTerminal(terminal, io);
|
|
@@ -15702,7 +15332,7 @@ async function finalizeExceptionRunBestEffort(runDirectory, io) {
|
|
|
15702
15332
|
}
|
|
15703
15333
|
}
|
|
15704
15334
|
function runArtifactsDirectory(runDirectory) {
|
|
15705
|
-
return
|
|
15335
|
+
return join24(runDirectory, "artifacts");
|
|
15706
15336
|
}
|
|
15707
15337
|
async function ensureRealArtifactsDirectory(runDirectory) {
|
|
15708
15338
|
const runStat = await lstat5(runDirectory);
|
|
@@ -15785,7 +15415,7 @@ function jsonSafeReplacer() {
|
|
|
15785
15415
|
}
|
|
15786
15416
|
async function retainDispatchError(admitted, principalAuthority, sessionAppender, attempt, error) {
|
|
15787
15417
|
const artifactsDir = await ensureRealArtifactsDirectory(admitted.runDirectory);
|
|
15788
|
-
const filePath =
|
|
15418
|
+
const filePath = join24(
|
|
15789
15419
|
artifactsDir,
|
|
15790
15420
|
`dispatch-error-attempt-${attempt}-${randomUUID4()}.json`
|
|
15791
15421
|
);
|
|
@@ -16034,10 +15664,16 @@ var init_auto_resume = __esm({
|
|
|
16034
15664
|
// src/public-cli/post-admission.ts
|
|
16035
15665
|
import { randomUUID as randomUUID5 } from "node:crypto";
|
|
16036
15666
|
import { readFile as readFile16, writeFile as writeFile7 } from "node:fs/promises";
|
|
16037
|
-
import { isAbsolute as isAbsolute7, join as
|
|
15667
|
+
import { isAbsolute as isAbsolute7, join as join25, resolve as resolve12 } from "node:path";
|
|
15668
|
+
function appendContinuationSection(continuation, section) {
|
|
15669
|
+
const prompt = `${continuation.prompt}
|
|
15670
|
+
|
|
15671
|
+
${section}`;
|
|
15672
|
+
return continuation.kind === "initial" ? { kind: "initial", prompt } : { kind: "resume", prompt };
|
|
15673
|
+
}
|
|
16038
15674
|
async function readInvocationHost(runDirectory) {
|
|
16039
15675
|
try {
|
|
16040
|
-
const raw = JSON.parse(await readFile16(
|
|
15676
|
+
const raw = JSON.parse(await readFile16(join25(runDirectory, "invocation.json"), "utf8"));
|
|
16041
15677
|
return typeof raw.host === "string" && raw.host.trim() !== "" ? raw.host : void 0;
|
|
16042
15678
|
} catch (error) {
|
|
16043
15679
|
if (error.code === "ENOENT") return void 0;
|
|
@@ -16112,18 +15748,14 @@ async function dispatchPostAdmissionTurn(input) {
|
|
|
16112
15748
|
let previousHost;
|
|
16113
15749
|
const liveHost = env.host;
|
|
16114
15750
|
const principalCoordinates = admitted.principal === void 0 ? void 0 : env.principalAuthority.decode(admitted.principal);
|
|
16115
|
-
let
|
|
15751
|
+
let hostTransition;
|
|
16116
15752
|
try {
|
|
16117
15753
|
previousHost = await readInvocationHost(admitted.runDirectory);
|
|
16118
|
-
|
|
15754
|
+
hostTransition = previousHost !== void 0 && liveHost !== void 0 && principalCoordinates !== void 0 ? await projectHostTransitionPriorNative({
|
|
16119
15755
|
previousHost,
|
|
16120
15756
|
liveHost,
|
|
16121
15757
|
piSessionFile: principalCoordinates.sessionFile
|
|
16122
15758
|
}) : void 0;
|
|
16123
|
-
turnRequest = env.signal === void 0 ? request : { ...request, signal: env.signal };
|
|
16124
|
-
if (hostTransition !== void 0) {
|
|
16125
|
-
turnRequest = { ...turnRequest, hostTransition };
|
|
16126
|
-
}
|
|
16127
15759
|
} catch (error) {
|
|
16128
15760
|
return await presentControlledFailure(
|
|
16129
15761
|
admitted,
|
|
@@ -16158,6 +15790,24 @@ async function dispatchPostAdmissionTurn(input) {
|
|
|
16158
15790
|
);
|
|
16159
15791
|
}
|
|
16160
15792
|
}
|
|
15793
|
+
let turnRequest = env.signal === void 0 ? request : { ...request, signal: env.signal };
|
|
15794
|
+
if (hostTransition !== void 0) {
|
|
15795
|
+
turnRequest = { ...turnRequest, hostTransition };
|
|
15796
|
+
}
|
|
15797
|
+
const dossierSection = await projectCaseDossierPointerSection({
|
|
15798
|
+
ticketNumber: admitted.ticketNumber,
|
|
15799
|
+
projectRoot: admitted.projectRoot,
|
|
15800
|
+
home: env.home
|
|
15801
|
+
});
|
|
15802
|
+
if (dossierSection !== void 0) {
|
|
15803
|
+
turnRequest = {
|
|
15804
|
+
...turnRequest,
|
|
15805
|
+
continuation: appendContinuationSection(
|
|
15806
|
+
turnRequest.continuation,
|
|
15807
|
+
dossierSection
|
|
15808
|
+
)
|
|
15809
|
+
};
|
|
15810
|
+
}
|
|
16161
15811
|
let result;
|
|
16162
15812
|
try {
|
|
16163
15813
|
result = await env.roleTurnHost.executeTurn(turnRequest);
|
|
@@ -16177,7 +15827,7 @@ async function dispatchPostAdmissionTurn(input) {
|
|
|
16177
15827
|
}
|
|
16178
15828
|
try {
|
|
16179
15829
|
await writeFile7(
|
|
16180
|
-
|
|
15830
|
+
join25(admitted.runDirectory, "stderr.log"),
|
|
16181
15831
|
result.stderr,
|
|
16182
15832
|
"utf8"
|
|
16183
15833
|
);
|
|
@@ -16243,16 +15893,24 @@ async function dispatchPostAdmissionTurn(input) {
|
|
|
16243
15893
|
}
|
|
16244
15894
|
}
|
|
16245
15895
|
function resumeTurnRequestProjectionOptions(admitted, request, env, summonsPrepared) {
|
|
15896
|
+
const engineMaterial = engineSessionMaterialFromOptions({
|
|
15897
|
+
...env.engine === void 0 ? {} : { engine: env.engine },
|
|
15898
|
+
packageRoot: env.packageRoot
|
|
15899
|
+
});
|
|
16246
15900
|
let prompt;
|
|
16247
15901
|
if (request.message !== void 0) {
|
|
16248
|
-
if (summonsPrepared !== void 0) {
|
|
16249
|
-
prompt =
|
|
16250
|
-
|
|
16251
|
-
|
|
16252
|
-
|
|
16253
|
-
|
|
16254
|
-
|
|
16255
|
-
|
|
15902
|
+
if (summonsPrepared !== void 0 && summonsPrepared.attachments.length > 0) {
|
|
15903
|
+
prompt = instructResumeHandbookRead(
|
|
15904
|
+
buildInstructionTransportPrompt(
|
|
15905
|
+
{
|
|
15906
|
+
instruction: request.message,
|
|
15907
|
+
instructionEmpty: false,
|
|
15908
|
+
attachments: summonsPrepared.attachments
|
|
15909
|
+
},
|
|
15910
|
+
engineMaterial
|
|
15911
|
+
),
|
|
15912
|
+
engineMaterial
|
|
15913
|
+
);
|
|
16256
15914
|
} else {
|
|
16257
15915
|
prompt = buildResumeContinuationPrompt({
|
|
16258
15916
|
packageRoot: env.packageRoot,
|
|
@@ -16261,9 +15919,10 @@ function resumeTurnRequestProjectionOptions(admitted, request, env, summonsPrepa
|
|
|
16261
15919
|
});
|
|
16262
15920
|
}
|
|
16263
15921
|
} else if (summonsPrepared !== void 0) {
|
|
16264
|
-
prompt =
|
|
16265
|
-
|
|
16266
|
-
|
|
15922
|
+
prompt = instructResumeHandbookRead(
|
|
15923
|
+
buildInstructionTransportPrompt(summonsPrepared, engineMaterial),
|
|
15924
|
+
engineMaterial
|
|
15925
|
+
);
|
|
16267
15926
|
} else {
|
|
16268
15927
|
prompt = buildResumeContinuationPrompt({
|
|
16269
15928
|
packageRoot: env.packageRoot,
|
|
@@ -16286,7 +15945,7 @@ function resumeTurnRequestProjectionOptions(admitted, request, env, summonsPrepa
|
|
|
16286
15945
|
}
|
|
16287
15946
|
function isAlreadyFrozenSummonsAttachment(runDirectory, attachmentPath) {
|
|
16288
15947
|
const absolute = isAbsolute7(attachmentPath) ? attachmentPath : resolve12(attachmentPath);
|
|
16289
|
-
return pathContainedIn(
|
|
15948
|
+
return pathContainedIn(join25(runDirectory, "attachments"), absolute);
|
|
16290
15949
|
}
|
|
16291
15950
|
async function prepareSummonsResumeMaterials(runDirectory, summons) {
|
|
16292
15951
|
if (summons === void 0) return void 0;
|
|
@@ -16578,6 +16237,8 @@ var init_post_admission = __esm({
|
|
|
16578
16237
|
init_cli_errors();
|
|
16579
16238
|
init_invocation();
|
|
16580
16239
|
init_activation_ledger_topology();
|
|
16240
|
+
init_engine_material();
|
|
16241
|
+
init_case_dossier_delivery();
|
|
16581
16242
|
init_host_transition_prior_native();
|
|
16582
16243
|
init_public_run_credentials();
|
|
16583
16244
|
init_run_lifecycle();
|
|
@@ -16622,6 +16283,7 @@ __export(notary_run_exports, {
|
|
|
16622
16283
|
runPublicNotary: () => runPublicNotary,
|
|
16623
16284
|
runPublicNotaryResume: () => runPublicNotaryResume
|
|
16624
16285
|
});
|
|
16286
|
+
import { existsSync as existsSync9 } from "node:fs";
|
|
16625
16287
|
function buildNotaryTurnRequest(admitted, options) {
|
|
16626
16288
|
return projectRoleTurnRequest(
|
|
16627
16289
|
admitted,
|
|
@@ -16763,14 +16425,19 @@ async function runPublicNotaryResume(request, env, io) {
|
|
|
16763
16425
|
}
|
|
16764
16426
|
return loaded;
|
|
16765
16427
|
},
|
|
16766
|
-
buildTurnRequest: (admitted, effective) =>
|
|
16767
|
-
|
|
16768
|
-
//「重新读」candidate line, no engine handbook packaging.
|
|
16769
|
-
buildNotaryTurnRequest(
|
|
16428
|
+
buildTurnRequest: (admitted, effective) => {
|
|
16429
|
+
const projection = resumeTurnRequestProjectionOptions(
|
|
16770
16430
|
admitted,
|
|
16771
|
-
|
|
16772
|
-
|
|
16773
|
-
|
|
16431
|
+
effective,
|
|
16432
|
+
env
|
|
16433
|
+
);
|
|
16434
|
+
const candidatePath = gateSubmissionCandidatePath(admitted.sourceRunPath);
|
|
16435
|
+
const prompt = existsSync9(candidatePath) ? appendResumeMaterialReread(projection.continuation.prompt, candidatePath) : projection.continuation.prompt;
|
|
16436
|
+
return buildNotaryTurnRequest(admitted, {
|
|
16437
|
+
...projection,
|
|
16438
|
+
continuation: { kind: "resume", prompt }
|
|
16439
|
+
});
|
|
16440
|
+
},
|
|
16774
16441
|
adapters: notaryAdapters(),
|
|
16775
16442
|
...env.engine === void 0 ? {} : { effectiveEngine: env.engine }
|
|
16776
16443
|
});
|
|
@@ -16778,6 +16445,7 @@ async function runPublicNotaryResume(request, env, io) {
|
|
|
16778
16445
|
var init_notary_run = __esm({
|
|
16779
16446
|
"src/public-cli/notary-run.ts"() {
|
|
16780
16447
|
"use strict";
|
|
16448
|
+
init_auditor_dossier_tool();
|
|
16781
16449
|
init_notary_source_run();
|
|
16782
16450
|
init_engine_material();
|
|
16783
16451
|
init_cli_errors();
|
|
@@ -16820,11 +16488,11 @@ async function runPublicInspector(argv, env, io, parseInspectorArgv2) {
|
|
|
16820
16488
|
throw error;
|
|
16821
16489
|
}
|
|
16822
16490
|
const projectRoot = parsed.project ?? env.cwd;
|
|
16823
|
-
const
|
|
16824
|
-
parsed.instruction,
|
|
16491
|
+
const reusedTicketNumber = await resolveKnownTicketNumber({
|
|
16492
|
+
instruction: parsed.instruction,
|
|
16825
16493
|
projectRoot,
|
|
16826
|
-
env
|
|
16827
|
-
);
|
|
16494
|
+
home: env.home
|
|
16495
|
+
});
|
|
16828
16496
|
const parentRunPath = parentRunPathFromGatePointerInstruction(parsed.instruction);
|
|
16829
16497
|
if (parentRunPath !== void 0) {
|
|
16830
16498
|
const summons = {
|
|
@@ -16892,7 +16560,7 @@ async function runPublicInspector(argv, env, io, parseInspectorArgv2) {
|
|
|
16892
16560
|
request: turnRequest,
|
|
16893
16561
|
adapters: inspectorAdapters({
|
|
16894
16562
|
beforeDispatch: async (admittedSeat) => {
|
|
16895
|
-
await
|
|
16563
|
+
await bindReusedTicketNumber(admittedSeat, reusedTicketNumber);
|
|
16896
16564
|
}
|
|
16897
16565
|
}),
|
|
16898
16566
|
...env.engine === void 0 ? {} : { effectiveEngine: env.engine }
|
|
@@ -17075,7 +16743,7 @@ async function runPublicInstructionSeat(argv, env, io, role, parseArgv) {
|
|
|
17075
16743
|
let auditorSubject;
|
|
17076
16744
|
let auditorSourceRun;
|
|
17077
16745
|
let auditorSourceTicket;
|
|
17078
|
-
let
|
|
16746
|
+
let reusedTicketNumber;
|
|
17079
16747
|
const projectRoot = parsed.project ?? env.cwd;
|
|
17080
16748
|
if (role === "auditor") {
|
|
17081
16749
|
if (parsed.subject !== "judge" && parsed.subject !== "doctor") {
|
|
@@ -17111,11 +16779,11 @@ async function runPublicInstructionSeat(argv, env, io, role, parseArgv) {
|
|
|
17111
16779
|
return { exitCode: 2 };
|
|
17112
16780
|
}
|
|
17113
16781
|
} else {
|
|
17114
|
-
|
|
17115
|
-
parsed.instruction,
|
|
16782
|
+
reusedTicketNumber = await resolveKnownTicketNumber({
|
|
16783
|
+
instruction: parsed.instruction,
|
|
17116
16784
|
projectRoot,
|
|
17117
|
-
env
|
|
17118
|
-
);
|
|
16785
|
+
home: env.home
|
|
16786
|
+
});
|
|
17119
16787
|
}
|
|
17120
16788
|
const summons = {
|
|
17121
16789
|
instruction: parsed.instruction,
|
|
@@ -17141,24 +16809,21 @@ async function runPublicInstructionSeat(argv, env, io, role, parseArgv) {
|
|
|
17141
16809
|
})
|
|
17142
16810
|
});
|
|
17143
16811
|
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
|
-
}
|
|
16812
|
+
} else if (reusedTicketNumber !== void 0) {
|
|
16813
|
+
const resumed = await tryResumeSameTicketSeatRun({
|
|
16814
|
+
home: env.home,
|
|
16815
|
+
projectRoot,
|
|
16816
|
+
role,
|
|
16817
|
+
ticketNumber: reusedTicketNumber,
|
|
16818
|
+
freshSummons: env.freshSummons,
|
|
16819
|
+
summons,
|
|
16820
|
+
resume: (runId, materials) => runPublicInstructionSeatResume(
|
|
16821
|
+
{ runId, ...materials === void 0 ? {} : { summons: materials } },
|
|
16822
|
+
env,
|
|
16823
|
+
io
|
|
16824
|
+
)
|
|
16825
|
+
});
|
|
16826
|
+
if (resumed !== void 0) return resumed;
|
|
17162
16827
|
}
|
|
17163
16828
|
let admitted;
|
|
17164
16829
|
try {
|
|
@@ -17216,8 +16881,8 @@ async function runPublicInstructionSeat(argv, env, io, role, parseArgv) {
|
|
|
17216
16881
|
beforeDispatch: async (admittedSeat) => {
|
|
17217
16882
|
if (auditorSourceTicket !== void 0) {
|
|
17218
16883
|
await bindAdmittedTicketNumber(admittedSeat, auditorSourceTicket);
|
|
17219
|
-
} else
|
|
17220
|
-
await
|
|
16884
|
+
} else {
|
|
16885
|
+
await bindReusedTicketNumber(admittedSeat, reusedTicketNumber);
|
|
17221
16886
|
}
|
|
17222
16887
|
}
|
|
17223
16888
|
}),
|
|
@@ -17470,8 +17135,8 @@ __export(public_role_summons_exports, {
|
|
|
17470
17135
|
summonGateOfficer: () => summonGateOfficer,
|
|
17471
17136
|
summonPublicRole: () => summonPublicRole
|
|
17472
17137
|
});
|
|
17473
|
-
import { existsSync as
|
|
17474
|
-
import { join as
|
|
17138
|
+
import { existsSync as existsSync10 } from "node:fs";
|
|
17139
|
+
import { join as join26 } from "node:path";
|
|
17475
17140
|
function createCapturingIo() {
|
|
17476
17141
|
const chunks = [];
|
|
17477
17142
|
return {
|
|
@@ -17494,7 +17159,7 @@ function parentDir(path) {
|
|
|
17494
17159
|
function walkPackageRoot(start) {
|
|
17495
17160
|
let dir = start;
|
|
17496
17161
|
for (let i = 0; i < 12; i += 1) {
|
|
17497
|
-
if (
|
|
17162
|
+
if (existsSync10(join26(dir, "package.json")) && existsSync10(join26(dir, "souls"))) {
|
|
17498
17163
|
return dir;
|
|
17499
17164
|
}
|
|
17500
17165
|
const parent = parentDir(dir);
|
|
@@ -17610,7 +17275,7 @@ async function createSummonEnv(options) {
|
|
|
17610
17275
|
async function summonPublicRole(options) {
|
|
17611
17276
|
const packageRoot = resolveSummonsPackageRoot(options.packageRoot);
|
|
17612
17277
|
const home = await resolveSummonHome(options);
|
|
17613
|
-
const agentDir = options.agentDir ?? process.env.PI_CODING_AGENT_DIR ??
|
|
17278
|
+
const agentDir = options.agentDir ?? process.env.PI_CODING_AGENT_DIR ?? join26(home, ".pi", "agent");
|
|
17614
17279
|
const {
|
|
17615
17280
|
loadCredentialProviders: loadCredentialProviders2,
|
|
17616
17281
|
loadPublicCliConfig: loadPublicCliConfig2,
|
|
@@ -18076,11 +17741,11 @@ var init_navigator_session_contracts = __esm({
|
|
|
18076
17741
|
|
|
18077
17742
|
// src/archivist-record-topology.ts
|
|
18078
17743
|
import { createHash as createHash8 } from "node:crypto";
|
|
18079
|
-
import { join as
|
|
17744
|
+
import { join as join27 } from "node:path";
|
|
18080
17745
|
function subjectKeyedRecordDirectory(input) {
|
|
18081
17746
|
const ledgerHome = input.parentSessionFile !== void 0 && input.parentSessionFile.length > 0 ? resolveActivationLedgerHomeForPath(input.parentSessionFile) : resolveActivationLedgerHome(input.home);
|
|
18082
17747
|
const digest = createHash8("sha256").update(input.subject).digest("hex").slice(0, 32);
|
|
18083
|
-
return
|
|
17748
|
+
return join27(
|
|
18084
17749
|
activationBookDirectory(ledgerHome, resolveBookKeyFromGit(input.cwd)),
|
|
18085
17750
|
input.kind,
|
|
18086
17751
|
digest
|
|
@@ -18104,13 +17769,13 @@ __export(archivist_record_entry_exports, {
|
|
|
18104
17769
|
createRecordSessionOpen: () => createRecordSessionOpen,
|
|
18105
17770
|
subjectKeyedRecordDirectory: () => subjectKeyedRecordDirectory
|
|
18106
17771
|
});
|
|
18107
|
-
import { existsSync as
|
|
18108
|
-
import { dirname as dirname13, resolve as resolve13, join as
|
|
17772
|
+
import { existsSync as existsSync11, mkdirSync as mkdirSync4, readFileSync as readFileSync3, realpathSync as realpathSync2, writeFileSync as writeFileSync5 } from "node:fs";
|
|
17773
|
+
import { dirname as dirname13, resolve as resolve13, join as join28 } from "node:path";
|
|
18109
17774
|
import { SessionManager } from "@earendil-works/pi-coding-agent";
|
|
18110
17775
|
function readCurrentSession(sessionDir) {
|
|
18111
|
-
const ledger =
|
|
17776
|
+
const ledger = join28(sessionDir, CURRENT_SESSION_LEDGER);
|
|
18112
17777
|
try {
|
|
18113
|
-
const value = JSON.parse(
|
|
17778
|
+
const value = JSON.parse(readFileSync3(ledger, "utf8"));
|
|
18114
17779
|
if (typeof value !== "object" || value === null || typeof value.sessionFile !== "string" || value.sessionFile.length === 0) {
|
|
18115
17780
|
throw new Error("sessionFile is missing");
|
|
18116
17781
|
}
|
|
@@ -18123,7 +17788,7 @@ function readCurrentSession(sessionDir) {
|
|
|
18123
17788
|
}
|
|
18124
17789
|
}
|
|
18125
17790
|
function writeCurrentSession(sessionDir, sessionFile) {
|
|
18126
|
-
const ledger =
|
|
17791
|
+
const ledger = join28(sessionDir, CURRENT_SESSION_LEDGER);
|
|
18127
17792
|
try {
|
|
18128
17793
|
writeFileSync5(ledger, `${JSON.stringify({ sessionFile })}
|
|
18129
17794
|
`, { flag: "wx" });
|
|
@@ -18184,10 +17849,10 @@ function createRecordSessionOpen(options) {
|
|
|
18184
17849
|
return { session: SessionManager.inMemory(cwd), resumed: false };
|
|
18185
17850
|
} else {
|
|
18186
17851
|
const parentResolved = resolve13(parentFile);
|
|
18187
|
-
sessionDir = physicallyContainedIn(ledgerHome, parentResolved) ?
|
|
17852
|
+
sessionDir = physicallyContainedIn(ledgerHome, parentResolved) ? join28(dirname13(parentResolved), options.kind) : join28(activationBookDirectory(ledgerHome, resolveBookKeyFromGit(cwd)), options.kind);
|
|
18188
17853
|
parentSession = parentFile;
|
|
18189
17854
|
}
|
|
18190
|
-
const nestAlreadyExists =
|
|
17855
|
+
const nestAlreadyExists = existsSync11(sessionDir);
|
|
18191
17856
|
ensureRealDirectoryTree(ledgerHome, sessionDir);
|
|
18192
17857
|
const mayResumeSameNest = options.subject !== void 0 || options.kind === WORKER_SUBMISSION_GATE_KIND;
|
|
18193
17858
|
if (mayResumeSameNest && nestAlreadyExists) {
|
|
@@ -18205,7 +17870,7 @@ function createRecordSessionOpen(options) {
|
|
|
18205
17870
|
);
|
|
18206
17871
|
if (session.isPersisted()) {
|
|
18207
17872
|
const file = session.getSessionFile();
|
|
18208
|
-
if (file !== void 0 && !
|
|
17873
|
+
if (file !== void 0 && !existsSync11(file)) {
|
|
18209
17874
|
const header = session.getHeader();
|
|
18210
17875
|
if (header !== null && header.type === "session") {
|
|
18211
17876
|
writeFileSync5(file, `${JSON.stringify(header)}
|
|
@@ -18223,7 +17888,7 @@ function createRecordSession(options) {
|
|
|
18223
17888
|
return createRecordSessionOpen(options).session;
|
|
18224
17889
|
}
|
|
18225
17890
|
function bookDirectOfficerRunPointer(options) {
|
|
18226
|
-
const nest =
|
|
17891
|
+
const nest = join28(dirname13(options.parentSessionFile), "auditor-roles");
|
|
18227
17892
|
mkdirSync4(nest, { recursive: true });
|
|
18228
17893
|
const pointer = {
|
|
18229
17894
|
version: 1,
|
|
@@ -18233,7 +17898,7 @@ function bookDirectOfficerRunPointer(options) {
|
|
|
18233
17898
|
...options.runDirectory !== void 0 && options.runDirectory.trim() !== "" ? { runDirectory: options.runDirectory } : {}
|
|
18234
17899
|
};
|
|
18235
17900
|
writeFileSync5(
|
|
18236
|
-
|
|
17901
|
+
join28(nest, `${options.officer}-${Date.now().toString(36)}.pointer.json`),
|
|
18237
17902
|
`${JSON.stringify(pointer)}
|
|
18238
17903
|
`,
|
|
18239
17904
|
"utf8"
|
|
@@ -20810,6 +20475,185 @@ var init_diarist_role = __esm({
|
|
|
20810
20475
|
}
|
|
20811
20476
|
});
|
|
20812
20477
|
|
|
20478
|
+
// src/diarist-mechanical.ts
|
|
20479
|
+
function extractCornerQuotes(text, minLength = DEFAULT_QUOTE_MIN) {
|
|
20480
|
+
const out = [];
|
|
20481
|
+
const re = /「([^」]+)」/g;
|
|
20482
|
+
let match;
|
|
20483
|
+
while ((match = re.exec(text)) !== null) {
|
|
20484
|
+
const q = match[1].trim();
|
|
20485
|
+
if (q.length >= minLength) out.push(q);
|
|
20486
|
+
}
|
|
20487
|
+
return out;
|
|
20488
|
+
}
|
|
20489
|
+
function buildDiaristAnchors(input) {
|
|
20490
|
+
const fromBody = input.ticketBody === void 0 ? [] : extractCornerQuotes(input.ticketBody);
|
|
20491
|
+
const quotes = [...fromBody, ...input.extraQuotes ?? []];
|
|
20492
|
+
const seen = /* @__PURE__ */ new Set();
|
|
20493
|
+
const uniqueQuotes = [];
|
|
20494
|
+
for (const q of quotes) {
|
|
20495
|
+
if (seen.has(q)) continue;
|
|
20496
|
+
seen.add(q);
|
|
20497
|
+
uniqueQuotes.push(q);
|
|
20498
|
+
}
|
|
20499
|
+
return {
|
|
20500
|
+
ticketNumber: input.ticketNumber,
|
|
20501
|
+
quotes: uniqueQuotes
|
|
20502
|
+
};
|
|
20503
|
+
}
|
|
20504
|
+
function verifyQuotesVerbatim(sourceText, quotes) {
|
|
20505
|
+
const failed2 = [];
|
|
20506
|
+
for (const q of quotes) {
|
|
20507
|
+
if (q.length === 0) continue;
|
|
20508
|
+
if (!sourceText.includes(q)) failed2.push(q);
|
|
20509
|
+
}
|
|
20510
|
+
if (failed2.length === 0) return { ok: true };
|
|
20511
|
+
return { ok: false, failedQuotes: failed2 };
|
|
20512
|
+
}
|
|
20513
|
+
function blockToLlmEntry(block, input) {
|
|
20514
|
+
const verify = verifyQuotesVerbatim(block.transcript, input.quotes);
|
|
20515
|
+
if (!verify.ok) {
|
|
20516
|
+
return {
|
|
20517
|
+
ok: false,
|
|
20518
|
+
failedQuotes: verify.failedQuotes,
|
|
20519
|
+
cause: `verbatim verify failed: ${verify.failedQuotes.join(" | ")}`
|
|
20520
|
+
};
|
|
20521
|
+
}
|
|
20522
|
+
const anchorNotes = [`#${input.anchors.ticketNumber}`];
|
|
20523
|
+
const seen = new Set(anchorNotes);
|
|
20524
|
+
for (const q of [...input.anchors.quotes, ...input.quotes]) {
|
|
20525
|
+
if (seen.has(q)) continue;
|
|
20526
|
+
seen.add(q);
|
|
20527
|
+
anchorNotes.push(q);
|
|
20528
|
+
if (anchorNotes.length >= 12) break;
|
|
20529
|
+
}
|
|
20530
|
+
return {
|
|
20531
|
+
ok: true,
|
|
20532
|
+
entry: {
|
|
20533
|
+
basis: {
|
|
20534
|
+
method: "llm-semantic",
|
|
20535
|
+
anchors: anchorNotes,
|
|
20536
|
+
...input.note === void 0 ? {} : { note: input.note }
|
|
20537
|
+
},
|
|
20538
|
+
sourceKind: block.sourceKind,
|
|
20539
|
+
sourceRef: block.sourceRef,
|
|
20540
|
+
transcript: block.transcript,
|
|
20541
|
+
timestamp: block.timestamp
|
|
20542
|
+
}
|
|
20543
|
+
};
|
|
20544
|
+
}
|
|
20545
|
+
var DEFAULT_QUOTE_MIN;
|
|
20546
|
+
var init_diarist_mechanical = __esm({
|
|
20547
|
+
"src/diarist-mechanical.ts"() {
|
|
20548
|
+
"use strict";
|
|
20549
|
+
init_activation_ledger_topology();
|
|
20550
|
+
DEFAULT_QUOTE_MIN = 6;
|
|
20551
|
+
}
|
|
20552
|
+
});
|
|
20553
|
+
|
|
20554
|
+
// src/diarist.ts
|
|
20555
|
+
import { readFileSync as readFileSync4 } from "node:fs";
|
|
20556
|
+
function blockEntryIdentity(ticketNumber, block) {
|
|
20557
|
+
return ticketProvenanceEntryIdentity({
|
|
20558
|
+
ticketNumber,
|
|
20559
|
+
sourceKind: block.sourceKind,
|
|
20560
|
+
sourceRef: block.sourceRef,
|
|
20561
|
+
transcript: block.transcript
|
|
20562
|
+
});
|
|
20563
|
+
}
|
|
20564
|
+
function loadDiaristSourceCatalog(path) {
|
|
20565
|
+
const parsed = JSON.parse(readFileSync4(path, "utf8"));
|
|
20566
|
+
if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
20567
|
+
throw new Error(`diarist source catalog is not an object (${path})`);
|
|
20568
|
+
}
|
|
20569
|
+
const record4 = parsed;
|
|
20570
|
+
if (typeof record4.ticketNumber !== "number" || typeof record4.cwd !== "string") {
|
|
20571
|
+
throw new Error(`diarist source catalog is missing ticket coordinates (${path})`);
|
|
20572
|
+
}
|
|
20573
|
+
if (!Array.isArray(record4.candidates)) {
|
|
20574
|
+
throw new Error(`diarist source catalog is missing candidates (${path})`);
|
|
20575
|
+
}
|
|
20576
|
+
return parsed;
|
|
20577
|
+
}
|
|
20578
|
+
async function commitDiaristSelections(input) {
|
|
20579
|
+
const { ticketNumber, cwd } = input.catalog;
|
|
20580
|
+
const homeOpt = input.catalog.home === void 0 ? {} : { home: input.catalog.home };
|
|
20581
|
+
const volumePaths = ensureTicketProvenanceVolume(ticketNumber, cwd, input.catalog.home);
|
|
20582
|
+
const anchors = buildDiaristAnchors({ ticketNumber });
|
|
20583
|
+
const before = await readTicketProvenance(ticketNumber, cwd, input.catalog.home);
|
|
20584
|
+
let acceptedRows = 0;
|
|
20585
|
+
let rejectedQuotes = 0;
|
|
20586
|
+
let unknownCandidate = false;
|
|
20587
|
+
for (const selection of input.selections) {
|
|
20588
|
+
const block = input.catalog.candidates[selection.candidateIndex];
|
|
20589
|
+
if (block === void 0) {
|
|
20590
|
+
unknownCandidate = true;
|
|
20591
|
+
continue;
|
|
20592
|
+
}
|
|
20593
|
+
const projected = blockToLlmEntry(block, {
|
|
20594
|
+
anchors,
|
|
20595
|
+
quotes: selection.quotes,
|
|
20596
|
+
...selection.note === void 0 ? {} : { note: selection.note }
|
|
20597
|
+
});
|
|
20598
|
+
if (!projected.ok) {
|
|
20599
|
+
rejectedQuotes += 1;
|
|
20600
|
+
appendQuoteVerifyFailureDiagnostic({
|
|
20601
|
+
ticketNumber,
|
|
20602
|
+
cwd,
|
|
20603
|
+
...homeOpt,
|
|
20604
|
+
cause: projected.cause
|
|
20605
|
+
});
|
|
20606
|
+
continue;
|
|
20607
|
+
}
|
|
20608
|
+
appendTicketProvenanceEntry({
|
|
20609
|
+
ticketNumber,
|
|
20610
|
+
cwd,
|
|
20611
|
+
...homeOpt,
|
|
20612
|
+
entry: projected.entry,
|
|
20613
|
+
source: "diarist"
|
|
20614
|
+
});
|
|
20615
|
+
acceptedRows += 1;
|
|
20616
|
+
}
|
|
20617
|
+
const identities = input.catalog.candidates.map(
|
|
20618
|
+
(block) => blockEntryIdentity(ticketNumber, block)
|
|
20619
|
+
);
|
|
20620
|
+
const alreadyWatermarked = readOfferedIdentities(ticketNumber, cwd, input.catalog.home);
|
|
20621
|
+
const watermarked = identities.filter((identity) => !alreadyWatermarked.has(identity)).length;
|
|
20622
|
+
recordOfferedIdentities({ ticketNumber, cwd, ...homeOpt, identities });
|
|
20623
|
+
const volume = await readTicketProvenance(ticketNumber, cwd, input.catalog.home);
|
|
20624
|
+
const humanViewFile = writeTicketProvenanceHumanView({
|
|
20625
|
+
ticketNumber,
|
|
20626
|
+
cwd,
|
|
20627
|
+
...homeOpt,
|
|
20628
|
+
entries: volume.entries
|
|
20629
|
+
});
|
|
20630
|
+
return {
|
|
20631
|
+
ticketNumber,
|
|
20632
|
+
offered: input.catalog.candidates.length,
|
|
20633
|
+
appended: volume.entries.length - before.entries.length,
|
|
20634
|
+
rejectedQuotes,
|
|
20635
|
+
watermarked,
|
|
20636
|
+
volumeRecordFile: volumePaths.recordFile,
|
|
20637
|
+
humanViewFile,
|
|
20638
|
+
collectorStatus: input.catalog.candidates.length === 0 ? "skipped-no-fresh" : acceptedRows > 0 ? "ok" : input.selections.length === 0 ? "empty-selection" : "nothing-appended",
|
|
20639
|
+
failureCauses: [
|
|
20640
|
+
...unknownCandidate ? ["unknown-candidate"] : [],
|
|
20641
|
+
...rejectedQuotes > 0 ? ["quote-verify-rejected"] : []
|
|
20642
|
+
]
|
|
20643
|
+
};
|
|
20644
|
+
}
|
|
20645
|
+
var init_diarist = __esm({
|
|
20646
|
+
"src/diarist.ts"() {
|
|
20647
|
+
"use strict";
|
|
20648
|
+
init_adr_path_refs();
|
|
20649
|
+
init_collector_github();
|
|
20650
|
+
init_diarist_mechanical();
|
|
20651
|
+
init_reviewer_pinned_git();
|
|
20652
|
+
init_ticket_provenance();
|
|
20653
|
+
init_sitian_facade();
|
|
20654
|
+
}
|
|
20655
|
+
});
|
|
20656
|
+
|
|
20813
20657
|
// src/navigator-role.ts
|
|
20814
20658
|
var NAVIGATOR_TOOL_SPEC;
|
|
20815
20659
|
var init_navigator_role = __esm({
|
|
@@ -21344,11 +21188,11 @@ var init_reviewer_role = __esm({
|
|
|
21344
21188
|
});
|
|
21345
21189
|
|
|
21346
21190
|
// src/worker-submission-gates.ts
|
|
21347
|
-
import { execFileSync as
|
|
21348
|
-
import { existsSync as
|
|
21191
|
+
import { execFileSync as execFileSync3 } from "node:child_process";
|
|
21192
|
+
import { existsSync as existsSync12, lstatSync as lstatSync3, readdirSync as readdirSync2, readFileSync as readFileSync5, rmdirSync, rmSync } from "node:fs";
|
|
21349
21193
|
import { resolve as resolve18 } from "node:path";
|
|
21350
21194
|
function git2(cwd, args) {
|
|
21351
|
-
return
|
|
21195
|
+
return execFileSync3("git", args, {
|
|
21352
21196
|
cwd,
|
|
21353
21197
|
encoding: "utf8",
|
|
21354
21198
|
stdio: ["ignore", "pipe", "pipe"],
|
|
@@ -21356,7 +21200,7 @@ function git2(cwd, args) {
|
|
|
21356
21200
|
}).trim();
|
|
21357
21201
|
}
|
|
21358
21202
|
function gitFile(file, args) {
|
|
21359
|
-
return
|
|
21203
|
+
return execFileSync3("git", ["config", "--file", file, ...args], {
|
|
21360
21204
|
encoding: "utf8",
|
|
21361
21205
|
stdio: ["ignore", "pipe", "pipe"],
|
|
21362
21206
|
env: { ...process.env, GIT_DIR: void 0, GIT_WORK_TREE: void 0, GIT_COMMON_DIR: void 0 }
|
|
@@ -21366,7 +21210,7 @@ function statusOf(error) {
|
|
|
21366
21210
|
return typeof error === "object" && error !== null && "status" in error ? error.status : void 0;
|
|
21367
21211
|
}
|
|
21368
21212
|
function tryGetAll(file, key) {
|
|
21369
|
-
if (!
|
|
21213
|
+
if (!existsSync12(file)) return [];
|
|
21370
21214
|
try {
|
|
21371
21215
|
const out = gitFile(file, ["--get-all", key]);
|
|
21372
21216
|
return out.length === 0 ? [] : out.split("\n");
|
|
@@ -21376,8 +21220,8 @@ function tryGetAll(file, key) {
|
|
|
21376
21220
|
}
|
|
21377
21221
|
}
|
|
21378
21222
|
function ownedHook(path) {
|
|
21379
|
-
if (!
|
|
21380
|
-
return
|
|
21223
|
+
if (!existsSync12(path)) return false;
|
|
21224
|
+
return readFileSync5(path, "utf8").includes(HOOK_MARKER);
|
|
21381
21225
|
}
|
|
21382
21226
|
function escapeGitConfigValueRegex(value) {
|
|
21383
21227
|
return value.replace(/[\\^$.*+?()[\]{}|]/g, "\\$&");
|
|
@@ -21403,11 +21247,11 @@ function rmOwnedDir(dir) {
|
|
|
21403
21247
|
const hookPath = resolve18(dir, HOOK_FILE);
|
|
21404
21248
|
if (!ownedHook(hookPath)) return;
|
|
21405
21249
|
rmSync(hookPath, { force: true });
|
|
21406
|
-
if (
|
|
21250
|
+
if (existsSync12(dir) && readdirSync2(dir).length === 0) rmdirSync(dir);
|
|
21407
21251
|
}
|
|
21408
21252
|
function linkedGitDirs(commonDir) {
|
|
21409
21253
|
const root = resolve18(commonDir, "worktrees");
|
|
21410
|
-
if (!
|
|
21254
|
+
if (!existsSync12(root)) return [];
|
|
21411
21255
|
return readdirSync2(root).map((name) => resolve18(root, name)).filter((dir) => lstatSync3(dir).isDirectory());
|
|
21412
21256
|
}
|
|
21413
21257
|
function uninstallPackageWorkerHooks(cwd) {
|
|
@@ -23660,7 +23504,7 @@ __export(in_process_session_exports, {
|
|
|
23660
23504
|
});
|
|
23661
23505
|
import { mkdtemp as mkdtemp2, rm as rm2 } from "node:fs/promises";
|
|
23662
23506
|
import { tmpdir as tmpdir2 } from "node:os";
|
|
23663
|
-
import { join as
|
|
23507
|
+
import { join as join30 } from "node:path";
|
|
23664
23508
|
import {
|
|
23665
23509
|
createAgentSession,
|
|
23666
23510
|
DefaultResourceLoader,
|
|
@@ -23783,7 +23627,7 @@ async function openPiInProcessSession(options) {
|
|
|
23783
23627
|
let scratchDir;
|
|
23784
23628
|
let resolvedAgentDir = options.agentDir;
|
|
23785
23629
|
if (resolvedAgentDir === void 0) {
|
|
23786
|
-
scratchDir = await mkdtemp2(
|
|
23630
|
+
scratchDir = await mkdtemp2(join30(options.credentialScratchParent ?? tmpdir2(), "ak-institutional-"));
|
|
23787
23631
|
resolvedAgentDir = scratchDir;
|
|
23788
23632
|
}
|
|
23789
23633
|
try {
|
|
@@ -24479,7 +24323,7 @@ var init_reviewer_child_executor = __esm({
|
|
|
24479
24323
|
import { spawn as spawn4 } from "node:child_process";
|
|
24480
24324
|
import { mkdtemp as mkdtemp3, rm as rm3 } from "node:fs/promises";
|
|
24481
24325
|
import { tmpdir as tmpdir3 } from "node:os";
|
|
24482
|
-
import { join as
|
|
24326
|
+
import { join as join31 } from "node:path";
|
|
24483
24327
|
async function runCommand(command, args, options = {}) {
|
|
24484
24328
|
return await new Promise((resolve19, reject) => {
|
|
24485
24329
|
const child = spawn4(command, args, { ...options.cwd === void 0 ? {} : { cwd: options.cwd }, stdio: ["ignore", "pipe", "pipe"], signal: options.signal });
|
|
@@ -24528,8 +24372,8 @@ async function prepareSnapshot(accepted, signal, dependencies) {
|
|
|
24528
24372
|
if (!sameReviewerPinnedTarget({ repositoryRoot: accepted.repositoryRoot, objectFormat, targetHead }, accepted)) throw new Error("Accepted Reviewer target identity no longer matches the repository");
|
|
24529
24373
|
await git3(accepted.repositoryRoot, ["cat-file", "-e", `${targetHead}^{commit}`], signal);
|
|
24530
24374
|
dependencies.fault?.("mirror.before-create");
|
|
24531
|
-
mirrorRoot = await mkdtemp3(
|
|
24532
|
-
const mirrorPath =
|
|
24375
|
+
mirrorRoot = await mkdtemp3(join31(tmpdir3(), "ak-reviewer-snapshot-"));
|
|
24376
|
+
const mirrorPath = join31(mirrorRoot, "repository.git");
|
|
24533
24377
|
dependencies.fault?.("mirror.create");
|
|
24534
24378
|
await runCommand("git", ["init", "--bare", `--object-format=${accepted.objectFormat}`, mirrorPath], signal === void 0 ? {} : { signal });
|
|
24535
24379
|
await git3(mirrorPath, ["fetch", "--no-tags", accepted.repositoryRoot, targetHead], signal);
|
|
@@ -24546,7 +24390,7 @@ async function prepareClone(snapshot, signal, dependencies) {
|
|
|
24546
24390
|
const target = { repositoryRoot: snapshot.repositoryRoot, objectFormat: snapshot.objectFormat, targetHead: snapshot.targetHead, refs: { ...snapshot.refs } };
|
|
24547
24391
|
try {
|
|
24548
24392
|
dependencies.fault?.("workspace.before-create");
|
|
24549
|
-
workspace = await mkdtemp3(
|
|
24393
|
+
workspace = await mkdtemp3(join31(tmpdir3(), "ak-reviewer-leg-"));
|
|
24550
24394
|
dependencies.fault?.("workspace.init");
|
|
24551
24395
|
await git3(workspace, ["init", `--object-format=${snapshot.objectFormat}`, "--initial-branch=ak-reviewer-unborn"], signal);
|
|
24552
24396
|
dependencies.fault?.("workspace.fetch");
|
|
@@ -24748,7 +24592,7 @@ var init_reviewer_agent = __esm({
|
|
|
24748
24592
|
|
|
24749
24593
|
// src/acp-host/production-host.ts
|
|
24750
24594
|
import { readFile as readFile20 } from "node:fs/promises";
|
|
24751
|
-
import { fileURLToPath as
|
|
24595
|
+
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
24752
24596
|
|
|
24753
24597
|
// src/canonical-skill-binding.ts
|
|
24754
24598
|
import { readFile, realpath } from "node:fs/promises";
|
|
@@ -24962,9 +24806,9 @@ init_auditor_soul();
|
|
|
24962
24806
|
init_session_opening_materials();
|
|
24963
24807
|
|
|
24964
24808
|
// src/acp-host/description.ts
|
|
24965
|
-
import { join as
|
|
24809
|
+
import { join as join32 } from "node:path";
|
|
24966
24810
|
function resolveAcpBinary(description, operatorHome) {
|
|
24967
|
-
return
|
|
24811
|
+
return join32(operatorHome, ...description.binaryFromHome);
|
|
24968
24812
|
}
|
|
24969
24813
|
function acpStdioArgs(description, model) {
|
|
24970
24814
|
const { prefix, suffix, modelFlag, thinkingFlag } = description.argv;
|
|
@@ -24985,8 +24829,8 @@ init_role_runtime();
|
|
|
24985
24829
|
import { randomUUID as randomUUID6 } from "node:crypto";
|
|
24986
24830
|
import { mkdir as mkdir5, readFile as readFile18, writeFile as writeFile8 } from "node:fs/promises";
|
|
24987
24831
|
import { createServer } from "node:net";
|
|
24988
|
-
import { basename as basename7, dirname as dirname17, join as
|
|
24989
|
-
import { fileURLToPath as
|
|
24832
|
+
import { basename as basename7, dirname as dirname17, join as join33 } from "node:path";
|
|
24833
|
+
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
24990
24834
|
|
|
24991
24835
|
// src/acp-host/role-turn-host.ts
|
|
24992
24836
|
init_agent_start_materials();
|
|
@@ -25352,7 +25196,7 @@ async function prepareAcpRoleEnvelope(options) {
|
|
|
25352
25196
|
const raw = await readFile18(method.path, "utf8");
|
|
25353
25197
|
methodSkills.set(name, { path: method.path, body: stripSkillFrontmatter(raw).trim() });
|
|
25354
25198
|
}
|
|
25355
|
-
let sessionFile = options.sessionFile ??
|
|
25199
|
+
let sessionFile = options.sessionFile ?? join33(request.runDirectory, "session", "session.jsonl");
|
|
25356
25200
|
await mkdir5(dirname17(sessionFile), { recursive: true });
|
|
25357
25201
|
if (request.continuation.kind !== "resume") {
|
|
25358
25202
|
try {
|
|
@@ -25676,7 +25520,7 @@ async function prepareAcpRoleEnvelope(options) {
|
|
|
25676
25520
|
});
|
|
25677
25521
|
}
|
|
25678
25522
|
await listen(server, options.socketPath);
|
|
25679
|
-
const relay =
|
|
25523
|
+
const relay = fileURLToPath2(new URL("./mcp-relay.mjs", import.meta.url));
|
|
25680
25524
|
let disposed = false;
|
|
25681
25525
|
let priorAkRoleRunDir;
|
|
25682
25526
|
let priorAkRoleCourtAttempt;
|
|
@@ -25817,9 +25661,9 @@ async function prepareAcpRoleEnvelope(options) {
|
|
|
25817
25661
|
|
|
25818
25662
|
// src/acp-host/session-identity.ts
|
|
25819
25663
|
import { mkdir as mkdir6, readFile as readFile19, rename, writeFile as writeFile9 } from "node:fs/promises";
|
|
25820
|
-
import { dirname as dirname18, join as
|
|
25664
|
+
import { dirname as dirname18, join as join34 } from "node:path";
|
|
25821
25665
|
function createAcpSessionIdentityAuthority(authority, sessionBindingFile) {
|
|
25822
|
-
const bindingPath = (principal) =>
|
|
25666
|
+
const bindingPath = (principal) => join34(authority.decode(principal).sessionDirectory, sessionBindingFile);
|
|
25823
25667
|
return {
|
|
25824
25668
|
resolveSessionFile(principal) {
|
|
25825
25669
|
return authority.decode(principal).sessionFile;
|
|
@@ -25848,7 +25692,7 @@ function createAcpSessionIdentityAuthority(authority, sessionBindingFile) {
|
|
|
25848
25692
|
}
|
|
25849
25693
|
|
|
25850
25694
|
// src/acp-host/production-host.ts
|
|
25851
|
-
var navigatorRoutePlaybookPath =
|
|
25695
|
+
var navigatorRoutePlaybookPath = fileURLToPath3(
|
|
25852
25696
|
new URL("../../resources/navigator-route-playbook.md", import.meta.url)
|
|
25853
25697
|
);
|
|
25854
25698
|
function createAcpRoleRuntimeDependencies(packageRoot) {
|