@akagilnc/pi-workflow-roles 0.1.3280 → 0.1.3353
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 +5 -5
- package/README.zh-CN.md +5 -5
- package/dist/audit-escalation.js +31 -4
- package/dist/gatekeeper-role.js +25 -4
- package/dist/grok/production-host.js +1167 -862
- package/dist/inspector-contracts.js +5 -2
- package/dist/notary-contracts.js +16 -5
- package/dist/packaged-role-registry.js +0 -7
- package/dist/public-cli/main.js +867 -757
- package/package.json +1 -1
- package/src/audit-escalation.ts +52 -8
- package/src/collector-ledger.ts +309 -74
- package/src/collector-receipt.ts +0 -1
- package/src/collector-role.ts +21 -14
- package/src/diarist-mechanical.ts +16 -5
- package/src/gatekeeper-role.ts +33 -4
- package/src/grok/role-envelope.ts +68 -52
- package/src/inspector-contracts.ts +6 -3
- package/src/inspector-role.ts +5 -2
- package/src/notary-contracts.ts +20 -5
- package/src/notary-role.ts +2 -2
- package/src/packaged-role-registry.ts +0 -12
- package/src/public-cli/cli.ts +50 -125
- package/src/public-cli/coder-run.ts +5 -19
- package/src/public-cli/collector-run.ts +65 -21
- package/src/public-cli/countersign-run.ts +14 -40
- package/src/public-cli/doctor-run.ts +50 -6
- package/src/public-cli/fixer-run.ts +5 -19
- package/src/public-cli/gleaner-left-run.ts +14 -40
- package/src/public-cli/inspector-run.ts +51 -7
- package/src/public-cli/instruction-seat-run.ts +27 -0
- package/src/public-cli/judge-run.ts +11 -36
- package/src/public-cli/merger-run.ts +5 -19
- package/src/public-cli/notary-run.ts +54 -5
- package/src/public-cli/option-definitions.ts +3 -3
- package/src/public-cli/post-admission.ts +76 -0
- package/src/public-cli/reviewer-run.ts +5 -19
- package/src/public-cli/run-lifecycle.ts +342 -107
- package/src/public-cli/settlement.ts +134 -71
- package/src/role-runtime.ts +18 -1
- package/src/submission-ledger.ts +55 -5
|
@@ -2697,11 +2697,14 @@ var notaryOutputSchema = withInfrastructureFailureDeclaration(
|
|
|
2697
2697
|
openToolObject(
|
|
2698
2698
|
Type10.Object({
|
|
2699
2699
|
status: Type10.Unknown({
|
|
2700
|
-
description: "pass | bounce \u2014 \u5F62\u72B6\u6307\u5F15\uFF0C\u975E schema \u95F8"
|
|
2700
|
+
description: "pass | bounce | escalate \u2014 \u5F62\u72B6\u6307\u5F15\uFF0C\u975E schema \u95F8"
|
|
2701
2701
|
}),
|
|
2702
2702
|
findings: Type10.Unknown({
|
|
2703
|
-
description: "string[] findings\uFF0C\u968F pass \u6216
|
|
2704
|
-
})
|
|
2703
|
+
description: "string[] findings\uFF0C\u968F pass\u3001bounce \u6216 escalate \u7559\u5B58"
|
|
2704
|
+
}),
|
|
2705
|
+
reason: Type10.Optional(Type10.Unknown({
|
|
2706
|
+
description: "status \u4E3A escalate \u65F6\u7684\u4E0A\u5448\u7406\u7531"
|
|
2707
|
+
}))
|
|
2705
2708
|
})
|
|
2706
2709
|
)
|
|
2707
2710
|
);
|
|
@@ -2726,6 +2729,9 @@ function projectLawfulNotaryOutput(value) {
|
|
|
2726
2729
|
if (!Array.isArray(clone.findings)) clone.findings = asStringArray2(clone.findings);
|
|
2727
2730
|
return clone;
|
|
2728
2731
|
}
|
|
2732
|
+
if (status === "escalate") {
|
|
2733
|
+
return structuredClone(value);
|
|
2734
|
+
}
|
|
2729
2735
|
return void 0;
|
|
2730
2736
|
}
|
|
2731
2737
|
function retainNotarySubmission(value) {
|
|
@@ -2805,7 +2811,7 @@ function validateRecordedInspectorOutput(value) {
|
|
|
2805
2811
|
} catch {
|
|
2806
2812
|
throw new Error("Inspector output has no execution discriminator");
|
|
2807
2813
|
}
|
|
2808
|
-
if (status === "pass" || status === "bounce") {
|
|
2814
|
+
if (status === "pass" || status === "bounce" || status === "escalate") {
|
|
2809
2815
|
return value;
|
|
2810
2816
|
}
|
|
2811
2817
|
throw new Error("Inspector output has no execution discriminator");
|
|
@@ -4982,9 +4988,23 @@ function buildAuditEscalationResult(decision, deliveredOutput) {
|
|
|
4982
4988
|
if (Object.hasOwn(decision, "decisionGate")) {
|
|
4983
4989
|
auditOwned.auditDecisionGate = decision.decisionGate;
|
|
4984
4990
|
}
|
|
4991
|
+
if (Object.hasOwn(decision, "reason") && decision.reason !== void 0) {
|
|
4992
|
+
auditOwned.reason = decision.reason;
|
|
4993
|
+
}
|
|
4994
|
+
if (Object.hasOwn(decision, "officer") && decision.officer !== void 0) {
|
|
4995
|
+
auditOwned.officer = decision.officer;
|
|
4996
|
+
}
|
|
4997
|
+
if (Object.hasOwn(decision, "findings") && decision.findings !== void 0) {
|
|
4998
|
+
auditOwned.findings = decision.findings;
|
|
4999
|
+
}
|
|
4985
5000
|
const deliveredFields = deliveredOutput !== void 0 && deliveredOutput !== null && typeof deliveredOutput === "object" && !Array.isArray(deliveredOutput) ? { ...deliveredOutput } : {};
|
|
4986
5001
|
delete deliveredFields.conflicts;
|
|
4987
5002
|
delete deliveredFields.auditDecisionGate;
|
|
5003
|
+
if (Object.hasOwn(decision, "officer")) {
|
|
5004
|
+
delete deliveredFields.reason;
|
|
5005
|
+
delete deliveredFields.officer;
|
|
5006
|
+
delete deliveredFields.findings;
|
|
5007
|
+
}
|
|
4988
5008
|
const result2 = {
|
|
4989
5009
|
...deliveredFields,
|
|
4990
5010
|
...auditOwned
|
|
@@ -4996,11 +5016,20 @@ function isAuditEscalationProjection(value) {
|
|
|
4996
5016
|
if (!isAuditEscalationResult(value)) return false;
|
|
4997
5017
|
return AUDIT_ESCALATION_LIVE_REGISTRY.has(value);
|
|
4998
5018
|
}
|
|
4999
|
-
function humanDecisionText(result2) {
|
|
5000
|
-
const
|
|
5019
|
+
function humanDecisionText(decision, result2) {
|
|
5020
|
+
const officer = Object.hasOwn(decision, "officer") ? decision.officer : void 0;
|
|
5021
|
+
const lines = [
|
|
5022
|
+
officer === void 0 ? "Human decision required: compliance audit escalation." : `Human decision required: ${officer} escalation.`
|
|
5023
|
+
];
|
|
5024
|
+
if (officer !== void 0 && typeof result2.reason === "string") {
|
|
5025
|
+
lines.push(`Reason: ${result2.reason}`);
|
|
5026
|
+
}
|
|
5001
5027
|
if (Array.isArray(result2.conflicts)) {
|
|
5002
5028
|
lines.push("Conflicts:", ...result2.conflicts.map((conflict) => `- ${conflict}`));
|
|
5003
5029
|
}
|
|
5030
|
+
if (officer !== void 0 && Array.isArray(result2.findings) && result2.findings.length > 0) {
|
|
5031
|
+
lines.push("Findings:", ...result2.findings.map((finding2) => `- ${finding2}`));
|
|
5032
|
+
}
|
|
5004
5033
|
const gate = result2.auditDecisionGate;
|
|
5005
5034
|
if (gate !== null && typeof gate === "object" && !Array.isArray(gate)) {
|
|
5006
5035
|
const record4 = gate;
|
|
@@ -5014,7 +5043,7 @@ function humanDecisionText(result2) {
|
|
|
5014
5043
|
function projectAuditEscalation(decision, deliveredOutput) {
|
|
5015
5044
|
const details = buildAuditEscalationResult(decision, deliveredOutput);
|
|
5016
5045
|
return {
|
|
5017
|
-
content: [{ type: "text", text: humanDecisionText(details) }],
|
|
5046
|
+
content: [{ type: "text", text: humanDecisionText(decision, details) }],
|
|
5018
5047
|
details,
|
|
5019
5048
|
terminate: true,
|
|
5020
5049
|
...decision.usage === void 0 ? {} : { usage: decision.usage }
|
|
@@ -6370,18 +6399,6 @@ init_activation_ledger_topology();
|
|
|
6370
6399
|
import { chmod, open, readdir as readdir2, readFile as readFile10, unlink as unlink2, writeFile as writeFile6 } from "node:fs/promises";
|
|
6371
6400
|
import { join as join15 } from "node:path";
|
|
6372
6401
|
|
|
6373
|
-
// src/public-cli/invocation.ts
|
|
6374
|
-
init_activation_ledger_topology();
|
|
6375
|
-
init_activation_ledger_git();
|
|
6376
|
-
import {
|
|
6377
|
-
lstat,
|
|
6378
|
-
mkdir as mkdir2,
|
|
6379
|
-
readFile as readFile9,
|
|
6380
|
-
realpath as realpath3,
|
|
6381
|
-
writeFile as writeFile5
|
|
6382
|
-
} from "node:fs/promises";
|
|
6383
|
-
import { basename as basename4, isAbsolute as isAbsolute3, join as join14, resolve as resolve11, sep as sep3 } from "node:path";
|
|
6384
|
-
|
|
6385
6402
|
// src/collector-config.ts
|
|
6386
6403
|
import { createHash as createHash6 } from "node:crypto";
|
|
6387
6404
|
import { readFile as readFile8 } from "node:fs/promises";
|
|
@@ -6456,6 +6473,18 @@ async function loadCollectorManifest(path) {
|
|
|
6456
6473
|
return { requests, canonicalJson: canonicalJson2, digest: createHash6("sha256").update(canonicalJson2).digest("hex"), sourcePath: path };
|
|
6457
6474
|
}
|
|
6458
6475
|
|
|
6476
|
+
// src/public-cli/invocation.ts
|
|
6477
|
+
init_activation_ledger_topology();
|
|
6478
|
+
init_activation_ledger_git();
|
|
6479
|
+
import {
|
|
6480
|
+
lstat,
|
|
6481
|
+
mkdir as mkdir2,
|
|
6482
|
+
readFile as readFile9,
|
|
6483
|
+
realpath as realpath3,
|
|
6484
|
+
writeFile as writeFile5
|
|
6485
|
+
} from "node:fs/promises";
|
|
6486
|
+
import { basename as basename4, isAbsolute as isAbsolute3, join as join14, resolve as resolve11, sep as sep3 } from "node:path";
|
|
6487
|
+
|
|
6459
6488
|
// src/public-cli/option-definitions.ts
|
|
6460
6489
|
var SHARED_PROJECT_SEMANTICS = {
|
|
6461
6490
|
id: "project",
|
|
@@ -6819,7 +6848,7 @@ var ROLE_COMMAND_HELP = {
|
|
|
6819
6848
|
},
|
|
6820
6849
|
collector: {
|
|
6821
6850
|
command: "collector",
|
|
6822
|
-
summary: "Collect GitHub PR review evidence
|
|
6851
|
+
summary: "Collect GitHub PR review evidence.",
|
|
6823
6852
|
usage: ["ak-role collector --pr <number> [options] [instruction]"],
|
|
6824
6853
|
examples: [
|
|
6825
6854
|
"ak-role collector --pr 42 --repo owner/repository",
|
|
@@ -6828,7 +6857,7 @@ var ROLE_COMMAND_HELP = {
|
|
|
6828
6857
|
},
|
|
6829
6858
|
doctor: {
|
|
6830
6859
|
command: "doctor",
|
|
6831
|
-
summary: "Diagnose one retained case
|
|
6860
|
+
summary: "Diagnose one retained case.",
|
|
6832
6861
|
usage: ["ak-role doctor --issue <number> [options] [instruction]"],
|
|
6833
6862
|
examples: [
|
|
6834
6863
|
'ak-role doctor --issue 115 "Diagnose this retained case."'
|
|
@@ -6925,7 +6954,7 @@ var SUPPORT_COMMAND_HELP = {
|
|
|
6925
6954
|
},
|
|
6926
6955
|
resume: {
|
|
6927
6956
|
command: "resume",
|
|
6928
|
-
summary: "Resume a role run under the live seat table (model/host/engine); session principal must still exist.",
|
|
6957
|
+
summary: "Resume a role run under the live seat table (model/host/engine); session principal must still exist. [message] applies only to seats that accept caller instruction; Notary/\u7B26\u5B9D\u90CE must omit message and derives evidence from the existing source-run/dossier binding.",
|
|
6929
6958
|
usage: ["ak-role resume <runId> [message]"],
|
|
6930
6959
|
examples: [
|
|
6931
6960
|
"ak-role resume 01abc\u2026",
|
|
@@ -8379,6 +8408,208 @@ import { Value as Value5 } from "typebox/value";
|
|
|
8379
8408
|
// src/submission-ledger.ts
|
|
8380
8409
|
init_activation_ledger_topology();
|
|
8381
8410
|
|
|
8411
|
+
// src/gatekeeper-role.ts
|
|
8412
|
+
import { Type as Type16 } from "typebox";
|
|
8413
|
+
var INSPECTOR_OUTPUT_TOOL = INSPECTOR_OUTPUT_TOOL_NAME;
|
|
8414
|
+
var NOTARY_OUTPUT_TOOL = "ak_notary_output";
|
|
8415
|
+
var SUBJECT_TOOL = "ak_gatekeeper_subject";
|
|
8416
|
+
function gateSeatLabel(stage) {
|
|
8417
|
+
switch (stage) {
|
|
8418
|
+
case "gatekeeper":
|
|
8419
|
+
return "\u95E8\u4E0B\u7701";
|
|
8420
|
+
case "inspector":
|
|
8421
|
+
return "\u5BDF\u9662";
|
|
8422
|
+
case "notary":
|
|
8423
|
+
return "\u7B26\u5B9D\u90CE";
|
|
8424
|
+
}
|
|
8425
|
+
}
|
|
8426
|
+
var GatekeeperEscalationError = class extends Error {
|
|
8427
|
+
gatekeeper;
|
|
8428
|
+
constructor(gatekeeper) {
|
|
8429
|
+
super(`\u95E8\u4E0B\u7701${gateSeatLabel(gatekeeper.officer)}\u4E0A\u5448`);
|
|
8430
|
+
this.name = "GatekeeperEscalationError";
|
|
8431
|
+
this.gatekeeper = gatekeeper;
|
|
8432
|
+
}
|
|
8433
|
+
};
|
|
8434
|
+
var officerDecisionSchema = openToolObject(Type16.Object({
|
|
8435
|
+
status: Type16.Unknown({ description: "pass | bounce | escalate \u2014 \u5F62\u72B6\u6307\u5F15\uFF0C\u975E schema \u95F8" }),
|
|
8436
|
+
reason: Type16.Optional(Type16.Unknown({ description: "status \u4E3A escalate \u65F6\u7684\u7406\u7531" })),
|
|
8437
|
+
findings: Type16.Unknown({ description: "string[] findings\uFF0C\u968F pass\u3001bounce \u6216 escalate \u7559\u5B58" })
|
|
8438
|
+
}));
|
|
8439
|
+
var GATEKEEPER_TOOL_SPEC = {
|
|
8440
|
+
name: GATEKEEPER_OUTPUT_TOOL_NAME,
|
|
8441
|
+
label: "\u95E8\u4E0B\u7701\u51B3\u8BAE",
|
|
8442
|
+
description: "\u95E8\u4E0B\u7701\u7EC8\u5C40\u51B3\u8BAE\uFF0C\u72B6\u6001\u4E3A dispatch \u6216 pass\u3002",
|
|
8443
|
+
promptSnippet: "\u95E8\u4E0B\u7701\u51B3\u8BAE",
|
|
8444
|
+
parameters: gatekeeperOutputSchema
|
|
8445
|
+
};
|
|
8446
|
+
function result(content, details) {
|
|
8447
|
+
return { content: [{ type: "text", text: content }], details };
|
|
8448
|
+
}
|
|
8449
|
+
function subjectTool(subject) {
|
|
8450
|
+
return {
|
|
8451
|
+
name: SUBJECT_TOOL,
|
|
8452
|
+
description: "\u8BFB\u53D6\u5DF2\u53D7\u7406\u5377\u5B97\uFF1B\u53EA\u4F9B\u53D6\u9605\uFF0C\u4E0D\u8BC4\u5224\u4E0D\u6539\u52A8\u3002",
|
|
8453
|
+
parameters: Type16.Object({}, { additionalProperties: false }),
|
|
8454
|
+
async execute() {
|
|
8455
|
+
return result(JSON.stringify(subject), subject);
|
|
8456
|
+
}
|
|
8457
|
+
};
|
|
8458
|
+
}
|
|
8459
|
+
function createOfficerDecisionTool(name) {
|
|
8460
|
+
return {
|
|
8461
|
+
name,
|
|
8462
|
+
description: "\u63D0\u4EA4\u4E00\u4EFD typed pass/bounce/escalate \u51B3\u8BAE\u3002",
|
|
8463
|
+
parameters: officerDecisionSchema,
|
|
8464
|
+
async execute(_id, args) {
|
|
8465
|
+
return result(`\u5DF2\u6536 ${String(args?.status)}`, args);
|
|
8466
|
+
}
|
|
8467
|
+
};
|
|
8468
|
+
}
|
|
8469
|
+
function createGatekeeperOutputTool() {
|
|
8470
|
+
return {
|
|
8471
|
+
name: GATEKEEPER_OUTPUT_TOOL_NAME,
|
|
8472
|
+
description: "\u63D0\u4EA4\u95E8\u4E0B\u7701\u6D3E\u5B98\u51B3\u5B9A\u3002",
|
|
8473
|
+
parameters: gatekeeperDecisionSchema,
|
|
8474
|
+
async execute(_id, args) {
|
|
8475
|
+
return result(`\u5DF2\u6536 ${String(args?.status)}`, args);
|
|
8476
|
+
}
|
|
8477
|
+
};
|
|
8478
|
+
}
|
|
8479
|
+
async function defaultLoadSoul(role) {
|
|
8480
|
+
return loadGatekeeperSessionMaterials(role);
|
|
8481
|
+
}
|
|
8482
|
+
function failureReason(error) {
|
|
8483
|
+
if (error instanceof AggregateError) return error.errors.map(failureReason).join("; ");
|
|
8484
|
+
return error instanceof Error ? `${error.name}: ${error.message}` : String(error);
|
|
8485
|
+
}
|
|
8486
|
+
function asStringArray3(value) {
|
|
8487
|
+
if (!Array.isArray(value)) return [];
|
|
8488
|
+
return value.filter((item) => typeof item === "string");
|
|
8489
|
+
}
|
|
8490
|
+
var MISSING_ARGUMENTS_SUBMISSION = Object.freeze({ missing: "arguments" });
|
|
8491
|
+
function isRecord11(value) {
|
|
8492
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
8493
|
+
}
|
|
8494
|
+
function retainedSubmission(decision) {
|
|
8495
|
+
return decision === void 0 || isRecord11(decision) && Object.keys(decision).length === 0 ? MISSING_ARGUMENTS_SUBMISSION : decision;
|
|
8496
|
+
}
|
|
8497
|
+
function noUsableReleaseFailure(stage, decision) {
|
|
8498
|
+
return {
|
|
8499
|
+
status: "transport_failure",
|
|
8500
|
+
stage,
|
|
8501
|
+
reason: stage === "gatekeeper" ? "decision \u65E0\u663E\u5F0F dispatch" : "decision \u65E0\u663E\u5F0F pass/bounce/escalate",
|
|
8502
|
+
submission: retainedSubmission(decision)
|
|
8503
|
+
};
|
|
8504
|
+
}
|
|
8505
|
+
function readRecord(value) {
|
|
8506
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) return void 0;
|
|
8507
|
+
return value;
|
|
8508
|
+
}
|
|
8509
|
+
function projectProvinceDecision(decision) {
|
|
8510
|
+
const projected = projectLawfulGatekeeperOutput(decision);
|
|
8511
|
+
if (projected === void 0) return noUsableReleaseFailure("gatekeeper", decision);
|
|
8512
|
+
if (projected.status === "dispatch") {
|
|
8513
|
+
return { status: "dispatch", officer: projected.officer };
|
|
8514
|
+
}
|
|
8515
|
+
return { status: "pass", findings: projected.findings ?? [] };
|
|
8516
|
+
}
|
|
8517
|
+
function projectOfficerDecision(officer, decision) {
|
|
8518
|
+
const record4 = readRecord(decision);
|
|
8519
|
+
if (record4 === void 0) return noUsableReleaseFailure(officer, decision);
|
|
8520
|
+
if (record4.status === "bounce") {
|
|
8521
|
+
return {
|
|
8522
|
+
status: "bounce",
|
|
8523
|
+
officer,
|
|
8524
|
+
disposition: "rewrite",
|
|
8525
|
+
findings: asStringArray3(record4.findings),
|
|
8526
|
+
submission: retainedSubmission(decision)
|
|
8527
|
+
};
|
|
8528
|
+
}
|
|
8529
|
+
if (record4.status === "pass") {
|
|
8530
|
+
return {
|
|
8531
|
+
status: "pass",
|
|
8532
|
+
officer,
|
|
8533
|
+
findings: asStringArray3(record4.findings)
|
|
8534
|
+
};
|
|
8535
|
+
}
|
|
8536
|
+
if (record4.status === "escalate") {
|
|
8537
|
+
return {
|
|
8538
|
+
status: "escalate",
|
|
8539
|
+
officer,
|
|
8540
|
+
...Object.hasOwn(record4, "reason") ? { reason: record4.reason } : {},
|
|
8541
|
+
findings: record4.findings,
|
|
8542
|
+
submission: retainedSubmission(decision)
|
|
8543
|
+
};
|
|
8544
|
+
}
|
|
8545
|
+
return noUsableReleaseFailure(officer, decision);
|
|
8546
|
+
}
|
|
8547
|
+
async function runGatekeeper(options) {
|
|
8548
|
+
const loadSoul = options.loadSoul ?? defaultLoadSoul;
|
|
8549
|
+
let provinceRun;
|
|
8550
|
+
try {
|
|
8551
|
+
provinceRun = await executeAuditorChild({
|
|
8552
|
+
context: options.context,
|
|
8553
|
+
roleLabel: "Gatekeeper",
|
|
8554
|
+
gateSeat: "gatekeeper",
|
|
8555
|
+
systemPrompt: await loadSoul("gatekeeper"),
|
|
8556
|
+
prompt: "\u5377\u5B97\u5DF2\u53D7\u7406\u3002",
|
|
8557
|
+
tool: createGatekeeperOutputTool(),
|
|
8558
|
+
dossierTool: subjectTool(options.subject),
|
|
8559
|
+
...options.signal === void 0 ? {} : { signal: options.signal },
|
|
8560
|
+
...options.runDirectory === void 0 ? {} : { runDirectory: options.runDirectory }
|
|
8561
|
+
});
|
|
8562
|
+
} catch (error) {
|
|
8563
|
+
return { status: "transport_failure", stage: "gatekeeper", reason: failureReason(error) };
|
|
8564
|
+
}
|
|
8565
|
+
if (provinceRun.noReceiptLifecycle !== void 0) {
|
|
8566
|
+
return { status: "no_receipt", stage: "gatekeeper", reason: `${gateSeatLabel("gatekeeper")}\u672A\u4EA7\u751F\u5DF2\u63A5\u53D7\u56DE\u6267\u5373\u6563\u5C40`, facts: provinceRun.noReceiptLifecycle };
|
|
8567
|
+
}
|
|
8568
|
+
const province = projectProvinceDecision(provinceRun.decision);
|
|
8569
|
+
if (province.status !== "dispatch") return province;
|
|
8570
|
+
const officer = province.officer;
|
|
8571
|
+
try {
|
|
8572
|
+
const roleLabel = officer === "inspector" ? "Inspector" : "Notary";
|
|
8573
|
+
const officerRun = await executeAuditorChild({
|
|
8574
|
+
context: options.context,
|
|
8575
|
+
roleLabel,
|
|
8576
|
+
gateSeat: officer,
|
|
8577
|
+
systemPrompt: await loadSoul(officer),
|
|
8578
|
+
prompt: "\u5377\u5B97\u5DF2\u53D7\u7406\u3002",
|
|
8579
|
+
tool: createOfficerDecisionTool(officer === "inspector" ? INSPECTOR_OUTPUT_TOOL : NOTARY_OUTPUT_TOOL),
|
|
8580
|
+
dossierTool: subjectTool(options.subject),
|
|
8581
|
+
...options.signal === void 0 ? {} : { signal: options.signal },
|
|
8582
|
+
...options.runDirectory === void 0 ? {} : { runDirectory: options.runDirectory }
|
|
8583
|
+
});
|
|
8584
|
+
if (officerRun.noReceiptLifecycle !== void 0) {
|
|
8585
|
+
return { status: "no_receipt", stage: officer, reason: `${gateSeatLabel(officer)}\u672A\u4EA7\u751F\u5DF2\u63A5\u53D7\u56DE\u6267\u5373\u6563\u5C40`, facts: officerRun.noReceiptLifecycle };
|
|
8586
|
+
}
|
|
8587
|
+
return projectOfficerDecision(officer, officerRun.decision);
|
|
8588
|
+
} catch (error) {
|
|
8589
|
+
return { status: "transport_failure", stage: officer, reason: failureReason(error) };
|
|
8590
|
+
}
|
|
8591
|
+
}
|
|
8592
|
+
async function requireGatekeeperPass(options) {
|
|
8593
|
+
const gatekeeper = await runGatekeeper({
|
|
8594
|
+
context: options.context,
|
|
8595
|
+
subject: options.subject,
|
|
8596
|
+
...options.signal === void 0 ? {} : { signal: options.signal }
|
|
8597
|
+
});
|
|
8598
|
+
if (gatekeeper.status === "pass") return;
|
|
8599
|
+
if (gatekeeper.status === "transport_failure") {
|
|
8600
|
+
const error = new Error(`\u95E8\u4E0B\u7701 transport_failure\uFF08${gatekeeper.stage}\uFF09\uFF1A${gatekeeper.reason}`);
|
|
8601
|
+
error.stage = gatekeeper.stage;
|
|
8602
|
+
error.reason = gatekeeper.reason;
|
|
8603
|
+
if (gatekeeper.submission !== void 0) error.submission = gatekeeper.submission;
|
|
8604
|
+
options.hostActions.failInfrastructure(error, options.context, options.toolCallId);
|
|
8605
|
+
}
|
|
8606
|
+
if (gatekeeper.status === "escalate") {
|
|
8607
|
+
throw new GatekeeperEscalationError(gatekeeper);
|
|
8608
|
+
}
|
|
8609
|
+
options.hostActions.bindSubmissionNonPass(options.toolCallId, gatekeeper);
|
|
8610
|
+
throw new GatekeeperDecisionError(gatekeeper);
|
|
8611
|
+
}
|
|
8612
|
+
|
|
8382
8613
|
// src/run-terminal-artifacts.ts
|
|
8383
8614
|
import { basename as basename6, dirname as dirname13, join as join20 } from "node:path";
|
|
8384
8615
|
function runIdFromRunDirectory(runDirectory) {
|
|
@@ -8399,8 +8630,16 @@ function runIdentity(context) {
|
|
|
8399
8630
|
if (typeof headerId === "string" && headerId.length > 0) return headerId;
|
|
8400
8631
|
throw new Error("\u63D0\u4EA4\u8D26\u9700\u8981\u5DF2\u53D7\u7406\u7684 run \u8EAB\u4EFD");
|
|
8401
8632
|
}
|
|
8633
|
+
function latestUserAttemptId(entries) {
|
|
8634
|
+
const ordered = [...entries];
|
|
8635
|
+
for (let index = ordered.length - 1; index >= 0; index -= 1) {
|
|
8636
|
+
const entry = ordered[index];
|
|
8637
|
+
if (entry?.message?.role === "user" && typeof entry.id === "string") return entry.id;
|
|
8638
|
+
}
|
|
8639
|
+
return void 0;
|
|
8640
|
+
}
|
|
8402
8641
|
function attemptIdentity(context, runId) {
|
|
8403
|
-
return context.sessionManager.getHeader?.()?.id ?? context.sessionManager.getLeafId?.() ?? `${runId}:initial`;
|
|
8642
|
+
return latestUserAttemptId(context.sessionManager.getEntries?.() ?? []) ?? context.sessionManager.getHeader?.()?.id ?? context.sessionManager.getLeafId?.() ?? `${runId}:initial`;
|
|
8404
8643
|
}
|
|
8405
8644
|
function submissionRecordFile(cwd, runId, home) {
|
|
8406
8645
|
const ledgerHome = resolveActivationLedgerHome(home);
|
|
@@ -8529,6 +8768,12 @@ function createSubmissionLedgerHost(host, outputTools, failInfrastructure2 = (er
|
|
|
8529
8768
|
const append = (event) => appendFor(state, context, runId, attemptId, event);
|
|
8530
8769
|
if (state.sealed) throw new Error("\u63D0\u4EA4\u8D26\u5DF2\u5C01\u8D26");
|
|
8531
8770
|
append({ type: "candidate", attemptId, toolCallId, toolName: tool2.name, sequence: ++state.sequence });
|
|
8771
|
+
const projectOfficerEscalation = (officer, original, deliveredOutput = original) => projectAuditEscalation({
|
|
8772
|
+
...original,
|
|
8773
|
+
status: "escalate",
|
|
8774
|
+
officer,
|
|
8775
|
+
reason: original.reason === void 0 ? `\u95E8\u4E0B\u7701${officer}\u4E0A\u5448\uFF08\u539F\u5377\u672A\u9644 reason\uFF09` : original.reason
|
|
8776
|
+
}, deliveredOutput);
|
|
8532
8777
|
let result2;
|
|
8533
8778
|
try {
|
|
8534
8779
|
failOnInfrastructureFailureDeclaration(
|
|
@@ -8544,7 +8789,14 @@ function createSubmissionLedgerHost(host, outputTools, failInfrastructure2 = (er
|
|
|
8544
8789
|
);
|
|
8545
8790
|
result2 = await tool2.execute(toolCallId, params, signal, update, context);
|
|
8546
8791
|
} catch (error) {
|
|
8547
|
-
if (
|
|
8792
|
+
if (error instanceof GatekeeperEscalationError) {
|
|
8793
|
+
const decision = error.gatekeeper;
|
|
8794
|
+
result2 = projectOfficerEscalation(
|
|
8795
|
+
error.gatekeeper.officer,
|
|
8796
|
+
decision,
|
|
8797
|
+
params
|
|
8798
|
+
);
|
|
8799
|
+
} else if (isCorrectableExecuteError(error)) {
|
|
8548
8800
|
append({
|
|
8549
8801
|
type: "outcome",
|
|
8550
8802
|
attemptId,
|
|
@@ -8553,6 +8805,7 @@ function createSubmissionLedgerHost(host, outputTools, failInfrastructure2 = (er
|
|
|
8553
8805
|
code: "typed-bounce",
|
|
8554
8806
|
diagnostic: error instanceof Error ? error.message : String(error)
|
|
8555
8807
|
});
|
|
8808
|
+
throw error;
|
|
8556
8809
|
} else {
|
|
8557
8810
|
append({
|
|
8558
8811
|
type: "outcome",
|
|
@@ -8561,8 +8814,12 @@ function createSubmissionLedgerHost(host, outputTools, failInfrastructure2 = (er
|
|
|
8561
8814
|
outcome: "infrastructure",
|
|
8562
8815
|
diagnostic: error instanceof Error ? error.message : String(error)
|
|
8563
8816
|
});
|
|
8817
|
+
throw error;
|
|
8564
8818
|
}
|
|
8565
|
-
|
|
8819
|
+
}
|
|
8820
|
+
if ((role === "inspector" || role === "notary") && typeof result2.details === "object" && result2.details !== null && !Array.isArray(result2.details) && result2.details.status === "escalate") {
|
|
8821
|
+
const details = result2.details;
|
|
8822
|
+
result2 = projectOfficerEscalation(role, details);
|
|
8566
8823
|
}
|
|
8567
8824
|
if (isAuditEscalationProjection(result2.details)) {
|
|
8568
8825
|
const candidates2 = rounds.get(attemptId) ?? [];
|
|
@@ -8606,463 +8863,62 @@ function createSubmissionLedgerHost(host, outputTools, failInfrastructure2 = (er
|
|
|
8606
8863
|
};
|
|
8607
8864
|
}
|
|
8608
8865
|
|
|
8609
|
-
// src/
|
|
8610
|
-
import
|
|
8611
|
-
var causeSchema = Type16.Object({
|
|
8612
|
-
identity: Type16.String({ minLength: 1 }),
|
|
8613
|
-
name: Type16.String({ minLength: 1 }),
|
|
8614
|
-
message: Type16.String(),
|
|
8615
|
-
evidenceId: Type16.Optional(Type16.String({ minLength: 1 }))
|
|
8616
|
-
}, { additionalProperties: false });
|
|
8617
|
-
var activationTraceRecordSchema = Type16.Object({
|
|
8618
|
-
role: Type16.String({ minLength: 1 }),
|
|
8619
|
-
stageId: Type16.String({ pattern: "^[a-z][a-z0-9-]*$" }),
|
|
8620
|
-
status: Type16.Literal("failed"),
|
|
8621
|
-
timestamp: Type16.String({ format: "date-time" }),
|
|
8622
|
-
cause: causeSchema
|
|
8623
|
-
}, { additionalProperties: false });
|
|
8624
|
-
var activationCauseEvidence = 0;
|
|
8625
|
-
var retainedActivationCauses = /* @__PURE__ */ new Map();
|
|
8626
|
-
function namedActivationCause(error) {
|
|
8627
|
-
const evidenceId = `activation-cause-${++activationCauseEvidence}`;
|
|
8628
|
-
retainedActivationCauses.set(evidenceId, error);
|
|
8629
|
-
if (error instanceof Error) {
|
|
8630
|
-
const code = error.code;
|
|
8631
|
-
const name = error.name || "Error";
|
|
8632
|
-
return { identity: typeof code === "string" && code.length > 0 ? code : name, name, message: error.message, evidenceId };
|
|
8633
|
-
}
|
|
8634
|
-
let message;
|
|
8635
|
-
try {
|
|
8636
|
-
message = typeof error === "string" ? error : JSON.stringify(error) ?? String(error);
|
|
8637
|
-
return { identity: "UnknownThrownCause", name: "UnknownThrownCause", message, evidenceId };
|
|
8638
|
-
} catch {
|
|
8639
|
-
return { identity: "UnknownThrownCause", name: "UnknownThrownCause", message: String(error), evidenceId };
|
|
8640
|
-
}
|
|
8641
|
-
}
|
|
8642
|
-
|
|
8643
|
-
// src/role-runtime.ts
|
|
8644
|
-
init_activation_ledger_topology();
|
|
8866
|
+
// src/collector-ledger.ts
|
|
8867
|
+
import Value3 from "typebox/value";
|
|
8645
8868
|
|
|
8646
|
-
// src/
|
|
8647
|
-
|
|
8648
|
-
|
|
8649
|
-
|
|
8650
|
-
|
|
8651
|
-
|
|
8652
|
-
|
|
8653
|
-
|
|
8654
|
-
|
|
8655
|
-
|
|
8656
|
-
|
|
8657
|
-
|
|
8658
|
-
// src/activation-ledger-session.ts
|
|
8659
|
-
init_activation_ledger_topology();
|
|
8660
|
-
import {
|
|
8661
|
-
lstatSync as lstatSync2,
|
|
8662
|
-
realpathSync as realpathSync3,
|
|
8663
|
-
statSync as statSync3,
|
|
8664
|
-
writeFileSync as writeFileSync4
|
|
8665
|
-
} from "node:fs";
|
|
8666
|
-
import { isAbsolute as isAbsolute5, resolve as resolve14 } from "node:path";
|
|
8667
|
-
var ActivationSessionFileMissingError = class extends Error {
|
|
8668
|
-
code = "AK_ACTIVATION_SESSION_FILE_MISSING";
|
|
8669
|
-
path;
|
|
8670
|
-
constructor(path, options) {
|
|
8671
|
-
super(
|
|
8672
|
-
`Workflow role activation durable session file does not exist: ${path}`,
|
|
8673
|
-
options?.cause === void 0 ? void 0 : { cause: options.cause }
|
|
8674
|
-
);
|
|
8675
|
-
this.name = "ActivationSessionFileMissingError";
|
|
8676
|
-
this.path = path;
|
|
8677
|
-
}
|
|
8678
|
-
};
|
|
8679
|
-
function materializeDeferredSessionFile(sessionManager, resolvedFile) {
|
|
8680
|
-
const header = sessionManager.getHeader?.();
|
|
8681
|
-
if (header === null || header === void 0 || header.type !== "session") {
|
|
8682
|
-
throw new ActivationSessionFileMissingError(resolvedFile);
|
|
8683
|
-
}
|
|
8684
|
-
try {
|
|
8685
|
-
writeFileSync4(resolvedFile, `${JSON.stringify(header)}
|
|
8686
|
-
`, { flag: "wx" });
|
|
8687
|
-
} catch (error) {
|
|
8688
|
-
if (errnoCode(error) !== "EEXIST") {
|
|
8689
|
-
throw new Error(
|
|
8690
|
-
`Workflow role activation failed to materialize durable session file (${resolvedFile}): ${errorText(error)}`,
|
|
8691
|
-
{ cause: error }
|
|
8692
|
-
);
|
|
8693
|
-
}
|
|
8694
|
-
}
|
|
8695
|
-
if (typeof sessionManager.setSessionFile === "function") {
|
|
8696
|
-
sessionManager.setSessionFile(resolvedFile);
|
|
8697
|
-
}
|
|
8698
|
-
}
|
|
8699
|
-
function durableSessionPointer(sessionManager) {
|
|
8700
|
-
const file = sessionManager.getSessionFile?.();
|
|
8701
|
-
if (typeof file !== "string" || file.length === 0) {
|
|
8702
|
-
throw new Error(
|
|
8703
|
-
"Workflow role activation requires a durable Pi session file principal (getSessionFile); directory-only or --no-session invocations are rejected"
|
|
8704
|
-
);
|
|
8705
|
-
}
|
|
8706
|
-
if (!isAbsolute5(file)) {
|
|
8707
|
-
throw new Error(
|
|
8708
|
-
`Workflow role activation requires an absolute durable session file path; got relative path: ${file}`
|
|
8709
|
-
);
|
|
8710
|
-
}
|
|
8711
|
-
const resolvedFile = resolve14(file);
|
|
8712
|
-
try {
|
|
8713
|
-
lstatSync2(resolvedFile);
|
|
8714
|
-
} catch (error) {
|
|
8715
|
-
if (errnoCode(error) !== "ENOENT") {
|
|
8716
|
-
throw new Error(
|
|
8717
|
-
`Workflow role activation failed to stat durable session file (${resolvedFile}): ${errorText(error)}`,
|
|
8718
|
-
{ cause: error }
|
|
8719
|
-
);
|
|
8720
|
-
}
|
|
8721
|
-
try {
|
|
8722
|
-
materializeDeferredSessionFile(sessionManager, resolvedFile);
|
|
8723
|
-
} catch (materializeError) {
|
|
8724
|
-
if (materializeError instanceof ActivationSessionFileMissingError) {
|
|
8725
|
-
throw new ActivationSessionFileMissingError(resolvedFile, { cause: error });
|
|
8869
|
+
// src/collector-evidence.ts
|
|
8870
|
+
import { createHash as createHash8 } from "node:crypto";
|
|
8871
|
+
var COLLECTOR_ELIGIBILITY_MS = 15 * 60 * 1e3;
|
|
8872
|
+
function createSystemCollectorClock() {
|
|
8873
|
+
const start = process.hrtime.bigint();
|
|
8874
|
+
return {
|
|
8875
|
+
wallNow: () => /* @__PURE__ */ new Date(),
|
|
8876
|
+
monoNow: () => Number(process.hrtime.bigint() - start) / 1e6,
|
|
8877
|
+
sleep: (ms, signal) => new Promise((resolve17, reject) => {
|
|
8878
|
+
if (signal?.aborted) {
|
|
8879
|
+
reject(signal.reason ?? new Error("aborted"));
|
|
8880
|
+
return;
|
|
8726
8881
|
}
|
|
8727
|
-
|
|
8728
|
-
|
|
8729
|
-
|
|
8730
|
-
|
|
8731
|
-
|
|
8732
|
-
|
|
8733
|
-
|
|
8734
|
-
|
|
8735
|
-
}
|
|
8736
|
-
let info;
|
|
8737
|
-
try {
|
|
8738
|
-
info = statSync3(realFile);
|
|
8739
|
-
} catch (error) {
|
|
8740
|
-
throw new Error(
|
|
8741
|
-
`Workflow role activation failed to stat durable session file (${realFile}): ${errorText(error)}`,
|
|
8742
|
-
{ cause: error }
|
|
8743
|
-
);
|
|
8744
|
-
}
|
|
8745
|
-
if (info.isDirectory()) {
|
|
8746
|
-
throw new Error(
|
|
8747
|
-
`Workflow role activation durable session principal must be a file, not a directory: ${realFile}`
|
|
8748
|
-
);
|
|
8749
|
-
}
|
|
8750
|
-
if (!info.isFile()) {
|
|
8751
|
-
throw new Error(
|
|
8752
|
-
`Workflow role activation durable session principal is not a regular file: ${realFile}`
|
|
8753
|
-
);
|
|
8754
|
-
}
|
|
8755
|
-
return { kind: "session-file", path: realFile };
|
|
8882
|
+
const timer = setTimeout(resolve17, ms);
|
|
8883
|
+
const onAbort = () => {
|
|
8884
|
+
clearTimeout(timer);
|
|
8885
|
+
reject(signal?.reason ?? new Error("aborted"));
|
|
8886
|
+
};
|
|
8887
|
+
signal?.addEventListener("abort", onAbort, { once: true });
|
|
8888
|
+
})
|
|
8889
|
+
};
|
|
8756
8890
|
}
|
|
8757
|
-
|
|
8758
|
-
|
|
8759
|
-
|
|
8760
|
-
|
|
8761
|
-
|
|
8762
|
-
|
|
8763
|
-
"event",
|
|
8764
|
-
"role",
|
|
8765
|
-
"observedAt",
|
|
8766
|
-
"bookKey",
|
|
8767
|
-
"session",
|
|
8768
|
-
"correlation"
|
|
8769
|
-
]);
|
|
8770
|
-
function correlationIdentityFromEnv(env = process.env) {
|
|
8771
|
-
const raw = env.AK_CORRELATION_ID;
|
|
8772
|
-
if (typeof raw === "string" && raw.trim().length > 0) {
|
|
8773
|
-
return { kind: "caller", id: raw };
|
|
8891
|
+
function sha256Text(text) {
|
|
8892
|
+
return createHash8("sha256").update(text, "utf8").digest("hex");
|
|
8893
|
+
}
|
|
8894
|
+
function computeWindowRelation(authoritativeTime, activationTime, deadlineTime) {
|
|
8895
|
+
if (authoritativeTime === void 0 || authoritativeTime === null || authoritativeTime.length === 0) {
|
|
8896
|
+
return "uncertain";
|
|
8774
8897
|
}
|
|
8775
|
-
|
|
8898
|
+
const ms = Date.parse(authoritativeTime);
|
|
8899
|
+
if (!Number.isFinite(ms)) return "uncertain";
|
|
8900
|
+
const activationMs = activationTime.getTime();
|
|
8901
|
+
const deadlineMs = deadlineTime.getTime();
|
|
8902
|
+
if (ms < activationMs) return "before";
|
|
8903
|
+
if (ms <= deadlineMs) return "within";
|
|
8904
|
+
return "after";
|
|
8776
8905
|
}
|
|
8777
|
-
function
|
|
8778
|
-
|
|
8779
|
-
event: ACCEPTED_ACTIVATION_EVENT,
|
|
8780
|
-
role: input.role,
|
|
8781
|
-
observedAt: input.observedAt,
|
|
8782
|
-
bookKey: input.bookKey,
|
|
8783
|
-
session: { kind: "session-file", path: input.session.path },
|
|
8784
|
-
correlation: input.correlation.kind === "caller" ? { kind: "caller", id: input.correlation.id } : { kind: "absent" }
|
|
8785
|
-
};
|
|
8786
|
-
return Object.fromEntries(
|
|
8787
|
-
ACCEPTED_ACTIVATION_FACT_KEYS.map((key) => [key, closed[key]])
|
|
8788
|
-
);
|
|
8906
|
+
function stableId(kind, githubId) {
|
|
8907
|
+
return `${kind}:${githubId}`;
|
|
8789
8908
|
}
|
|
8790
|
-
function
|
|
8791
|
-
return
|
|
8909
|
+
function versionDigest(parts) {
|
|
8910
|
+
return sha256Text(JSON.stringify(parts));
|
|
8792
8911
|
}
|
|
8793
|
-
function
|
|
8794
|
-
return `${
|
|
8795
|
-
`;
|
|
8912
|
+
function evidenceIdFor(kind, versionId) {
|
|
8913
|
+
return sha256Text(`${kind}:${versionId}`).slice(0, 16);
|
|
8796
8914
|
}
|
|
8797
|
-
function
|
|
8798
|
-
|
|
8799
|
-
|
|
8800
|
-
|
|
8801
|
-
|
|
8802
|
-
|
|
8803
|
-
|
|
8804
|
-
const resolvedHome = resolve15(options.ledgerHome);
|
|
8805
|
-
const parent = dirname14(resolvedLedger);
|
|
8806
|
-
ensureRealDirectoryTree(resolvedHome, parent);
|
|
8807
|
-
assertLedgerFileInsideHome(resolvedLedger, resolvedHome);
|
|
8808
|
-
if (typeof constants.O_NOFOLLOW !== "number") {
|
|
8809
|
-
throw new ActivationLedgerError(
|
|
8810
|
-
"activation ledger append requires O_NOFOLLOW open-flag support (anti-symlink TOCTOU protection must not be silently dropped); refusing to append"
|
|
8811
|
-
);
|
|
8812
|
-
}
|
|
8813
|
-
const bytes = Buffer.isBuffer(line2) ? line2 : Buffer.from(line2);
|
|
8814
|
-
let ledgerFd;
|
|
8815
|
-
let primaryFailure;
|
|
8816
|
-
try {
|
|
8817
|
-
try {
|
|
8818
|
-
ledgerFd = openSync(resolvedLedger, ACTIVATION_LEDGER_APPEND_OPEN_FLAGS, 420);
|
|
8819
|
-
} catch (error) {
|
|
8820
|
-
throw new ActivationLedgerError(
|
|
8821
|
-
`activation ledger failed to open ledger file (${resolvedLedger}): ${errorText(error)}`,
|
|
8822
|
-
{ cause: error }
|
|
8823
|
-
);
|
|
8824
|
-
}
|
|
8825
|
-
let opened;
|
|
8826
|
-
try {
|
|
8827
|
-
opened = fstatSync(ledgerFd);
|
|
8828
|
-
} catch (error) {
|
|
8829
|
-
throw new ActivationLedgerError(
|
|
8830
|
-
`activation ledger failed to fstat ledger file (${resolvedLedger}): ${errorText(error)}`,
|
|
8831
|
-
{ cause: error }
|
|
8832
|
-
);
|
|
8833
|
-
}
|
|
8834
|
-
if (!opened.isFile()) {
|
|
8835
|
-
throw new ActivationLedgerError(
|
|
8836
|
-
`activation ledger is not a regular file: ${resolvedLedger}`
|
|
8837
|
-
);
|
|
8838
|
-
}
|
|
8839
|
-
const written = writeSync(ledgerFd, bytes, 0, bytes.length, null);
|
|
8840
|
-
if (written !== bytes.length) {
|
|
8841
|
-
throw new ActivationLedgerError(
|
|
8842
|
-
`activation ledger short write: wrote ${written} of ${bytes.length} bytes to ${resolvedLedger}`
|
|
8843
|
-
);
|
|
8844
|
-
}
|
|
8845
|
-
} catch (error) {
|
|
8846
|
-
primaryFailure = error;
|
|
8847
|
-
}
|
|
8848
|
-
if (ledgerFd !== void 0) {
|
|
8849
|
-
try {
|
|
8850
|
-
closeSync(ledgerFd);
|
|
8851
|
-
} catch (closeFailure) {
|
|
8852
|
-
if (primaryFailure !== void 0) {
|
|
8853
|
-
throw new AggregateError(
|
|
8854
|
-
[primaryFailure, closeFailure],
|
|
8855
|
-
"activation ledger operation and close failed",
|
|
8856
|
-
{ cause: primaryFailure }
|
|
8857
|
-
);
|
|
8858
|
-
}
|
|
8859
|
-
throw closeFailure;
|
|
8860
|
-
}
|
|
8861
|
-
}
|
|
8862
|
-
if (primaryFailure !== void 0) throw primaryFailure;
|
|
8863
|
-
}
|
|
8864
|
-
function appendAcceptedActivationFact(ledgerPath, fact, options) {
|
|
8865
|
-
appendActivationLedgerLine(
|
|
8866
|
-
ledgerPath,
|
|
8867
|
-
Buffer.from(serializeAcceptedActivationFact(fact), "utf8"),
|
|
8868
|
-
{ ledgerHome: options.ledgerHome }
|
|
8869
|
-
);
|
|
8870
|
-
}
|
|
8871
|
-
function appendAcceptedActivationToBook(options) {
|
|
8872
|
-
appendAcceptedActivationFact(
|
|
8873
|
-
activationWaitingLedgerPath(options.ledgerHome, options.fact.bookKey),
|
|
8874
|
-
options.fact,
|
|
8875
|
-
{ ledgerHome: options.ledgerHome }
|
|
8876
|
-
);
|
|
8877
|
-
}
|
|
8878
|
-
|
|
8879
|
-
// src/stderr-jsonl.ts
|
|
8880
|
-
import { writeSync as writeSync2 } from "node:fs";
|
|
8881
|
-
var STDERR_JSONL_WRITE_RETRY_LIMIT = 100;
|
|
8882
|
-
function writeStderrJsonlRecord(record4, write = writeSync2) {
|
|
8883
|
-
const bytes = Buffer.from(`${JSON.stringify(record4)}
|
|
8884
|
-
`);
|
|
8885
|
-
let offset = 0;
|
|
8886
|
-
let retries = 0;
|
|
8887
|
-
while (offset < bytes.length) {
|
|
8888
|
-
try {
|
|
8889
|
-
const written = write(2, bytes, offset, bytes.length - offset);
|
|
8890
|
-
if (written <= 0) throw new Error("stderr JSONL write made no progress");
|
|
8891
|
-
offset += written;
|
|
8892
|
-
retries = 0;
|
|
8893
|
-
} catch (error) {
|
|
8894
|
-
const code = error.code;
|
|
8895
|
-
if ((code === "EAGAIN" || code === "EINTR") && retries++ < STDERR_JSONL_WRITE_RETRY_LIMIT) continue;
|
|
8896
|
-
throw error;
|
|
8897
|
-
}
|
|
8898
|
-
}
|
|
8899
|
-
}
|
|
8900
|
-
|
|
8901
|
-
// src/tool-execution-observation.ts
|
|
8902
|
-
import { writeSync as writeSync3 } from "node:fs";
|
|
8903
|
-
import { Type as Type17 } from "typebox";
|
|
8904
|
-
import { Value as Value3 } from "typebox/value";
|
|
8905
|
-
var TOOL_EXECUTION_UPDATE_THROTTLE_MS = 3e4;
|
|
8906
|
-
var observationBase = {
|
|
8907
|
-
role: Type17.String({ minLength: 1 }),
|
|
8908
|
-
toolCallId: Type17.String({ minLength: 1 }),
|
|
8909
|
-
toolName: Type17.String({ minLength: 1 }),
|
|
8910
|
-
timestamp: Type17.String({ format: "date-time" })
|
|
8911
|
-
};
|
|
8912
|
-
var toolExecutionObservationRecordSchema = Type17.Union([
|
|
8913
|
-
Type17.Object({
|
|
8914
|
-
...observationBase,
|
|
8915
|
-
event: Type17.Literal("tool_execution_start")
|
|
8916
|
-
}, { additionalProperties: true }),
|
|
8917
|
-
Type17.Object({
|
|
8918
|
-
...observationBase,
|
|
8919
|
-
event: Type17.Literal("tool_execution_update")
|
|
8920
|
-
}, { additionalProperties: true }),
|
|
8921
|
-
Type17.Object({
|
|
8922
|
-
...observationBase,
|
|
8923
|
-
event: Type17.Literal("tool_execution_end"),
|
|
8924
|
-
isError: Type17.Boolean()
|
|
8925
|
-
}, { additionalProperties: true })
|
|
8926
|
-
]);
|
|
8927
|
-
function validateToolExecutionObservationRecord(record4) {
|
|
8928
|
-
if (!Value3.Check(toolExecutionObservationRecordSchema, record4)) {
|
|
8929
|
-
throw new TypeError("Tool execution observation record does not match its contract");
|
|
8930
|
-
}
|
|
8931
|
-
return record4;
|
|
8932
|
-
}
|
|
8933
|
-
function writeToolExecutionObservationRecord(record4, write = writeSync3) {
|
|
8934
|
-
writeStderrJsonlRecord(validateToolExecutionObservationRecord(record4), write);
|
|
8935
|
-
}
|
|
8936
|
-
function isProducingToolUpdate(partialResult) {
|
|
8937
|
-
if (partialResult == null) return false;
|
|
8938
|
-
if (typeof partialResult !== "object") return true;
|
|
8939
|
-
const content = partialResult.content;
|
|
8940
|
-
if (!Array.isArray(content)) return true;
|
|
8941
|
-
if (content.length === 0) return false;
|
|
8942
|
-
return content.some((part) => {
|
|
8943
|
-
if (typeof part !== "object" || part === null) return true;
|
|
8944
|
-
const text = part.text;
|
|
8945
|
-
if (typeof text === "string") return text.length > 0;
|
|
8946
|
-
return true;
|
|
8947
|
-
});
|
|
8948
|
-
}
|
|
8949
|
-
function systemToolExecutionObservationMonoNow() {
|
|
8950
|
-
return performance.now();
|
|
8951
|
-
}
|
|
8952
|
-
function createToolExecutionObservationFace(options) {
|
|
8953
|
-
const states = /* @__PURE__ */ new Map();
|
|
8954
|
-
async function emit(record4) {
|
|
8955
|
-
await options.write(validateToolExecutionObservationRecord(record4));
|
|
8956
|
-
}
|
|
8957
|
-
function activeRole() {
|
|
8958
|
-
if (!options.admitted()) return void 0;
|
|
8959
|
-
const role = options.role();
|
|
8960
|
-
return role === void 0 || role === "" ? void 0 : role;
|
|
8961
|
-
}
|
|
8962
|
-
return {
|
|
8963
|
-
reset() {
|
|
8964
|
-
states.clear();
|
|
8965
|
-
},
|
|
8966
|
-
async onStart(event) {
|
|
8967
|
-
const role = activeRole();
|
|
8968
|
-
if (role === void 0) return;
|
|
8969
|
-
states.set(event.toolCallId, { lastUpdateEmitMonoMs: void 0 });
|
|
8970
|
-
await emit({
|
|
8971
|
-
event: "tool_execution_start",
|
|
8972
|
-
role,
|
|
8973
|
-
toolCallId: event.toolCallId,
|
|
8974
|
-
toolName: event.toolName,
|
|
8975
|
-
timestamp: options.clock()
|
|
8976
|
-
});
|
|
8977
|
-
},
|
|
8978
|
-
async onUpdate(event) {
|
|
8979
|
-
const role = activeRole();
|
|
8980
|
-
if (role === void 0) return;
|
|
8981
|
-
if (!isProducingToolUpdate(event.partialResult)) return;
|
|
8982
|
-
const now = options.monoNow();
|
|
8983
|
-
const state = states.get(event.toolCallId) ?? { lastUpdateEmitMonoMs: void 0 };
|
|
8984
|
-
if (state.lastUpdateEmitMonoMs !== void 0 && now - state.lastUpdateEmitMonoMs < TOOL_EXECUTION_UPDATE_THROTTLE_MS) {
|
|
8985
|
-
return;
|
|
8986
|
-
}
|
|
8987
|
-
state.lastUpdateEmitMonoMs = now;
|
|
8988
|
-
states.set(event.toolCallId, state);
|
|
8989
|
-
await emit({
|
|
8990
|
-
event: "tool_execution_update",
|
|
8991
|
-
role,
|
|
8992
|
-
toolCallId: event.toolCallId,
|
|
8993
|
-
toolName: event.toolName,
|
|
8994
|
-
timestamp: options.clock()
|
|
8995
|
-
});
|
|
8996
|
-
},
|
|
8997
|
-
async onEnd(event) {
|
|
8998
|
-
const role = activeRole();
|
|
8999
|
-
if (role === void 0) return;
|
|
9000
|
-
states.delete(event.toolCallId);
|
|
9001
|
-
await emit({
|
|
9002
|
-
event: "tool_execution_end",
|
|
9003
|
-
role,
|
|
9004
|
-
toolCallId: event.toolCallId,
|
|
9005
|
-
toolName: event.toolName,
|
|
9006
|
-
timestamp: options.clock(),
|
|
9007
|
-
isError: event.isError
|
|
9008
|
-
});
|
|
9009
|
-
}
|
|
9010
|
-
};
|
|
9011
|
-
}
|
|
9012
|
-
|
|
9013
|
-
// src/collector-evidence.ts
|
|
9014
|
-
import { createHash as createHash8 } from "node:crypto";
|
|
9015
|
-
var COLLECTOR_ELIGIBILITY_MS = 15 * 60 * 1e3;
|
|
9016
|
-
function createSystemCollectorClock() {
|
|
9017
|
-
const start = process.hrtime.bigint();
|
|
9018
|
-
return {
|
|
9019
|
-
wallNow: () => /* @__PURE__ */ new Date(),
|
|
9020
|
-
monoNow: () => Number(process.hrtime.bigint() - start) / 1e6,
|
|
9021
|
-
sleep: (ms, signal) => new Promise((resolve17, reject) => {
|
|
9022
|
-
if (signal?.aborted) {
|
|
9023
|
-
reject(signal.reason ?? new Error("aborted"));
|
|
9024
|
-
return;
|
|
9025
|
-
}
|
|
9026
|
-
const timer = setTimeout(resolve17, ms);
|
|
9027
|
-
const onAbort = () => {
|
|
9028
|
-
clearTimeout(timer);
|
|
9029
|
-
reject(signal?.reason ?? new Error("aborted"));
|
|
9030
|
-
};
|
|
9031
|
-
signal?.addEventListener("abort", onAbort, { once: true });
|
|
9032
|
-
})
|
|
9033
|
-
};
|
|
9034
|
-
}
|
|
9035
|
-
function sha256Text(text) {
|
|
9036
|
-
return createHash8("sha256").update(text, "utf8").digest("hex");
|
|
9037
|
-
}
|
|
9038
|
-
function computeWindowRelation(authoritativeTime, activationTime, deadlineTime) {
|
|
9039
|
-
if (authoritativeTime === void 0 || authoritativeTime === null || authoritativeTime.length === 0) {
|
|
9040
|
-
return "uncertain";
|
|
9041
|
-
}
|
|
9042
|
-
const ms = Date.parse(authoritativeTime);
|
|
9043
|
-
if (!Number.isFinite(ms)) return "uncertain";
|
|
9044
|
-
const activationMs = activationTime.getTime();
|
|
9045
|
-
const deadlineMs = deadlineTime.getTime();
|
|
9046
|
-
if (ms < activationMs) return "before";
|
|
9047
|
-
if (ms <= deadlineMs) return "within";
|
|
9048
|
-
return "after";
|
|
9049
|
-
}
|
|
9050
|
-
function stableId(kind, githubId) {
|
|
9051
|
-
return `${kind}:${githubId}`;
|
|
9052
|
-
}
|
|
9053
|
-
function versionDigest(parts) {
|
|
9054
|
-
return sha256Text(JSON.stringify(parts));
|
|
9055
|
-
}
|
|
9056
|
-
function evidenceIdFor(kind, versionId) {
|
|
9057
|
-
return sha256Text(`${kind}:${versionId}`).slice(0, 16);
|
|
9058
|
-
}
|
|
9059
|
-
function normalizeAuthenticatedUserEvidence(user, observedAt) {
|
|
9060
|
-
const login = user.login.toLowerCase();
|
|
9061
|
-
const rawId = user.raw?.id;
|
|
9062
|
-
const stableNumericOrStringId = typeof rawId === "number" || typeof rawId === "string" ? rawId : void 0;
|
|
9063
|
-
const retainedRaw = { login };
|
|
9064
|
-
if (stableNumericOrStringId !== void 0) {
|
|
9065
|
-
retainedRaw.id = stableNumericOrStringId;
|
|
8915
|
+
function normalizeAuthenticatedUserEvidence(user, observedAt) {
|
|
8916
|
+
const login = user.login.toLowerCase();
|
|
8917
|
+
const rawId = user.raw?.id;
|
|
8918
|
+
const stableNumericOrStringId = typeof rawId === "number" || typeof rawId === "string" ? rawId : void 0;
|
|
8919
|
+
const retainedRaw = { login };
|
|
8920
|
+
if (stableNumericOrStringId !== void 0) {
|
|
8921
|
+
retainedRaw.id = stableNumericOrStringId;
|
|
9066
8922
|
}
|
|
9067
8923
|
const contentDigest = versionDigest({
|
|
9068
8924
|
login,
|
|
@@ -9296,28 +9152,25 @@ function assignWindowRelations(records2, activationTime, deadlineTime) {
|
|
|
9296
9152
|
}
|
|
9297
9153
|
}
|
|
9298
9154
|
|
|
9299
|
-
// src/collector-ledger.ts
|
|
9300
|
-
import Value4 from "typebox/value";
|
|
9301
|
-
|
|
9302
9155
|
// src/collector-tool-schemas.ts
|
|
9303
|
-
import { Type as
|
|
9304
|
-
var collectorObserveArgsSchema =
|
|
9305
|
-
var collectorRequestArgsSchema =
|
|
9306
|
-
requestId:
|
|
9307
|
-
snapshotId:
|
|
9156
|
+
import { Type as Type17 } from "typebox";
|
|
9157
|
+
var collectorObserveArgsSchema = Type17.Object({}, { additionalProperties: false });
|
|
9158
|
+
var collectorRequestArgsSchema = Type17.Object({
|
|
9159
|
+
requestId: Type17.String({ minLength: 1, description: "\u914D\u7F6E\u8BF7\u6C42\u8EAB\u4EFD" }),
|
|
9160
|
+
snapshotId: Type17.String({ minLength: 1, description: "\u6700\u65B0\u7559\u5B58\u89C2\u5BDF\u5FEB\u7167" })
|
|
9308
9161
|
}, { additionalProperties: false });
|
|
9309
|
-
var collectorReadArgsSchema =
|
|
9310
|
-
evidenceId:
|
|
9162
|
+
var collectorReadArgsSchema = Type17.Object({
|
|
9163
|
+
evidenceId: Type17.String({ minLength: 1, description: "observe \u8FD4\u56DE\u7684\u6750\u6599\u8BC1\u636E id\uFF08evidenceId\uFF09" })
|
|
9311
9164
|
}, { additionalProperties: false });
|
|
9312
|
-
var collectorWaitArgsSchema =
|
|
9313
|
-
durationMs:
|
|
9165
|
+
var collectorWaitArgsSchema = Type17.Object({
|
|
9166
|
+
durationMs: Type17.Integer({ minimum: 1, maximum: COLLECTOR_ELIGIBILITY_MS, description: "\u7B49\u5F85\u6BEB\u79D2\uFF1B\u5355\u6B21\u4E0A\u9650\u4E94\u5206\u949F\u4E14\u4E0D\u8D85\u5269\u4F59\u8D44\u683C" })
|
|
9314
9167
|
}, { additionalProperties: false });
|
|
9315
|
-
var collectorFindingArgsSchema =
|
|
9316
|
-
evidenceId:
|
|
9317
|
-
category:
|
|
9168
|
+
var collectorFindingArgsSchema = Type17.Object({
|
|
9169
|
+
evidenceId: Type17.String({ minLength: 1, description: "observe \u8FD4\u56DE\u7684\u6750\u6599\u8BC1\u636E id\uFF08evidenceId\uFF09" }),
|
|
9170
|
+
category: Type17.Optional(Type17.String({ minLength: 1, maxLength: 200, description: "\u8BE5 finding \u7684\u7B80\u77ED\u5F52\u7C7B\u6807\u7B7E\uFF1B\u9700\u8981\u5934\u90E8\u4E4B\u5916\u7684\u6B63\u6587\u65F6\u5148\u7528 ak_collector_read \u5F00\u5377\u518D\u5224\u8BFB\uFF0C\u4E0D\u5F97\u8A8A\u5199\u8BC4\u8BBA\u6B63\u6587" }))
|
|
9318
9171
|
}, { additionalProperties: false });
|
|
9319
|
-
var collectorOutputBaseSchema =
|
|
9320
|
-
findings:
|
|
9172
|
+
var collectorOutputBaseSchema = Type17.Object({
|
|
9173
|
+
findings: Type17.Optional(Type17.Array(collectorFindingArgsSchema, {
|
|
9321
9174
|
description: "\u672C\u6B21\u6536\u96C6\u5230\u7684\u9010\u6761 findings\uFF1B\u96F6 finding \u7684\u6A21\u677F\u901A\u77E5\u4E0D\u5F97\u8FDB\u5165\u3002\u6B63\u5E38\u5B8C\u5DE5\u65E0 finding \u65F6\u7701\u7565\u3002"
|
|
9322
9175
|
}))
|
|
9323
9176
|
}, { additionalProperties: true, description: "\u6B63\u5E38\u5B8C\u5DE5\u63D0\u4EA4\u7A7A\u5BF9\u8C61 {}\uFF1B\u4EC5\u5728\u57FA\u7840\u8BBE\u65BD\u771F\u5B9E\u5931\u8D25\u65F6\u624D\u586B\u5199 infrastructureFailure\uFF0C\u65E0\u5931\u8D25\u65F6\u5FC5\u987B\u7701\u7565\u8BE5\u5B57\u6BB5\u3002" });
|
|
@@ -9351,13 +9204,20 @@ function projectObserveContextView(modelView) {
|
|
|
9351
9204
|
evidence: modelView.evidence.map((entry) => entry.body === void 0 ? entry : { ...entry, body: utf8SafePrefix(entry.body, COLLECTOR_OBSERVE_BODY_HEAD_BYTES) })
|
|
9352
9205
|
};
|
|
9353
9206
|
}
|
|
9207
|
+
var COLLECTOR_ACTIVATION_ENTRY_TYPE = "ak-collector-activation";
|
|
9208
|
+
var COLLECTOR_SNAPSHOT_ENTRY_TYPE = "ak-collector-snapshot";
|
|
9209
|
+
var COLLECTOR_REQUEST_ENTRY_TYPE = "ak-collector-request";
|
|
9210
|
+
var COLLECTOR_WAIT_ENTRY_TYPE = "ak-collector-wait";
|
|
9354
9211
|
function isOperationalTool(name) {
|
|
9355
9212
|
return COLLECTOR_OPERATIONAL_TOOLS.includes(name);
|
|
9356
9213
|
}
|
|
9357
|
-
function createCollectorLedger(config) {
|
|
9214
|
+
function createCollectorLedger(config, options) {
|
|
9215
|
+
const clock = options?.clock;
|
|
9216
|
+
const journal = options?.journal;
|
|
9358
9217
|
let fatal2 = false;
|
|
9359
9218
|
let fatalReason;
|
|
9360
|
-
let
|
|
9219
|
+
let outputCandidate = false;
|
|
9220
|
+
let pendingOutputCallId;
|
|
9361
9221
|
let activationTime;
|
|
9362
9222
|
let deadlineTime;
|
|
9363
9223
|
let activationMono;
|
|
@@ -9395,14 +9255,14 @@ function createCollectorLedger(config) {
|
|
|
9395
9255
|
evidenceById.set(record4.evidenceId, record4);
|
|
9396
9256
|
return record4;
|
|
9397
9257
|
};
|
|
9398
|
-
const monoNowOrThrow = (
|
|
9399
|
-
const pastCutoff = (
|
|
9258
|
+
const monoNowOrThrow = (clock2) => clock2.monoNow();
|
|
9259
|
+
const pastCutoff = (clock2) => {
|
|
9400
9260
|
if (deadlineMono === void 0) return false;
|
|
9401
|
-
return monoNowOrThrow(
|
|
9261
|
+
return monoNowOrThrow(clock2) >= deadlineMono;
|
|
9402
9262
|
};
|
|
9403
|
-
const remainingMs = (
|
|
9263
|
+
const remainingMs = (clock2) => {
|
|
9404
9264
|
if (deadlineMono === void 0) return COLLECTOR_ELIGIBILITY_MS;
|
|
9405
|
-
return Math.max(0, deadlineMono - monoNowOrThrow(
|
|
9265
|
+
return Math.max(0, deadlineMono - monoNowOrThrow(clock2));
|
|
9406
9266
|
};
|
|
9407
9267
|
const prIdentity = (pr) => `${pr.state}|${pr.headOid}|${pr.updatedAt ?? ""}`;
|
|
9408
9268
|
const fetchObserveSurfaces = async (transport, observedAt, signal) => {
|
|
@@ -9444,6 +9304,172 @@ function createCollectorLedger(config) {
|
|
|
9444
9304
|
});
|
|
9445
9305
|
return { user, prInitial, reviews, reactions, issueComments, reviewComments, prTerminal };
|
|
9446
9306
|
};
|
|
9307
|
+
const appendJournal = (customType, data) => {
|
|
9308
|
+
journal?.append(customType, data);
|
|
9309
|
+
};
|
|
9310
|
+
const bindDeadlineMonoFromWall = () => {
|
|
9311
|
+
if (clock === void 0 || activationTime === void 0 || deadlineTime === void 0) return;
|
|
9312
|
+
const wallNow = clock.wallNow().getTime();
|
|
9313
|
+
const monoNow = clock.monoNow();
|
|
9314
|
+
activationMono = monoNow - (wallNow - activationTime.getTime());
|
|
9315
|
+
deadlineMono = monoNow + (deadlineTime.getTime() - wallNow);
|
|
9316
|
+
};
|
|
9317
|
+
const rebindSnapshotCompletedMono = (snapshot) => {
|
|
9318
|
+
const copy = { ...snapshot, evidenceIds: [...snapshot.evidenceIds] };
|
|
9319
|
+
if (deadlineTime !== void 0 && deadlineMono !== void 0 && copy.completedAt !== void 0) {
|
|
9320
|
+
const completedWall = new Date(copy.completedAt).getTime();
|
|
9321
|
+
copy.completedMono = deadlineMono + (completedWall - deadlineTime.getTime());
|
|
9322
|
+
}
|
|
9323
|
+
return copy;
|
|
9324
|
+
};
|
|
9325
|
+
const commitActivationWindow = (nextActivation, nextDeadline) => {
|
|
9326
|
+
if (activationTime !== void 0) return;
|
|
9327
|
+
activationTime = nextActivation;
|
|
9328
|
+
deadlineTime = nextDeadline;
|
|
9329
|
+
bindDeadlineMonoFromWall();
|
|
9330
|
+
};
|
|
9331
|
+
const recoverAmbiguousRequestLosses = (snapshotId, observedRecords) => {
|
|
9332
|
+
for (const failure2 of transportFailures) {
|
|
9333
|
+
if (failure2.recovered || failure2.kind !== "ambiguous_request_loss") continue;
|
|
9334
|
+
if (failure2.marker === void 0 || failure2.requestId === void 0) continue;
|
|
9335
|
+
const found = observedRecords.find(
|
|
9336
|
+
(record4) => record4.kind === "issue_comment" && record4.authorLogin === requesterLogin && typeof record4.body === "string" && record4.body.includes(failure2.marker)
|
|
9337
|
+
);
|
|
9338
|
+
if (found === void 0) continue;
|
|
9339
|
+
failure2.recovered = true;
|
|
9340
|
+
const attempt = attempts.find(
|
|
9341
|
+
(item) => item.status === "ambiguous_loss" && item.requestId === failure2.requestId && item.marker === failure2.marker
|
|
9342
|
+
);
|
|
9343
|
+
if (attempt !== void 0) {
|
|
9344
|
+
attempt.status = "recovered";
|
|
9345
|
+
attempt.commentEvidenceId = found.evidenceId;
|
|
9346
|
+
attempt.recoverySnapshotId = snapshotId;
|
|
9347
|
+
}
|
|
9348
|
+
}
|
|
9349
|
+
};
|
|
9350
|
+
const finalizeObservedSnapshot = (snapshot) => {
|
|
9351
|
+
if (requesterLogin === void 0) {
|
|
9352
|
+
for (const id of snapshot.evidenceIds) {
|
|
9353
|
+
const record4 = evidenceById.get(id);
|
|
9354
|
+
if (record4?.kind === "authenticated_user" && record4.authorLogin !== void 0) {
|
|
9355
|
+
requesterLogin = record4.authorLogin.toLowerCase();
|
|
9356
|
+
break;
|
|
9357
|
+
}
|
|
9358
|
+
}
|
|
9359
|
+
}
|
|
9360
|
+
const stored = rebindSnapshotCompletedMono(snapshot);
|
|
9361
|
+
snapshots.push(stored);
|
|
9362
|
+
latestCompleteSnapshotId = stored.snapshotId;
|
|
9363
|
+
const observedRecords = stored.evidenceIds.flatMap((id) => {
|
|
9364
|
+
const record4 = evidenceById.get(id);
|
|
9365
|
+
return record4 === void 0 ? [] : [record4];
|
|
9366
|
+
});
|
|
9367
|
+
recoverAmbiguousRequestLosses(stored.snapshotId, observedRecords);
|
|
9368
|
+
observedGeneration = mutationGeneration;
|
|
9369
|
+
if (finalObservationRequired && stored.completedMono !== void 0 && deadlineMono !== void 0 && stored.completedMono >= deadlineMono) {
|
|
9370
|
+
finalObservationCompleted = true;
|
|
9371
|
+
} else if (clock !== void 0 && deadlineMono !== void 0 && clock.monoNow() >= deadlineMono && stored.completedMono !== void 0 && stored.completedMono >= deadlineMono) {
|
|
9372
|
+
finalObservationRequired = true;
|
|
9373
|
+
finalObservationCompleted = true;
|
|
9374
|
+
}
|
|
9375
|
+
return stored;
|
|
9376
|
+
};
|
|
9377
|
+
const commitObservedSnapshot = (snapshot, evidenceRecords) => {
|
|
9378
|
+
for (const record4 of evidenceRecords) {
|
|
9379
|
+
storeEvidence(record4);
|
|
9380
|
+
}
|
|
9381
|
+
return finalizeObservedSnapshot(snapshot);
|
|
9382
|
+
};
|
|
9383
|
+
const commitRequestAttempt = (attempt, attemptKey, commentEvidence) => {
|
|
9384
|
+
if (commentEvidence !== void 0) {
|
|
9385
|
+
storeEvidence(commentEvidence);
|
|
9386
|
+
}
|
|
9387
|
+
const existing = attempts.find((item) => item.attemptId === attempt.attemptId);
|
|
9388
|
+
if (existing === void 0) {
|
|
9389
|
+
attempts.push({ ...attempt });
|
|
9390
|
+
attemptKeys.add(attemptKey);
|
|
9391
|
+
} else {
|
|
9392
|
+
Object.assign(existing, attempt);
|
|
9393
|
+
}
|
|
9394
|
+
if (attempt.status === "ambiguous_loss" && !transportFailures.some((failure2) => failure2.requestId === attempt.requestId && failure2.observedHead === attempt.observedHead)) {
|
|
9395
|
+
transportFailures.push({
|
|
9396
|
+
failureId: sha256Text(`loss:${attempt.attemptId}`).slice(0, 16),
|
|
9397
|
+
kind: "ambiguous_request_loss",
|
|
9398
|
+
message: attempt.responseDiagnostics ?? "ambiguous request loss",
|
|
9399
|
+
requestId: attempt.requestId,
|
|
9400
|
+
observedHead: attempt.observedHead,
|
|
9401
|
+
marker: attempt.marker,
|
|
9402
|
+
recovered: false
|
|
9403
|
+
});
|
|
9404
|
+
}
|
|
9405
|
+
if (attempt.status === "succeeded" || attempt.status === "ambiguous_loss") {
|
|
9406
|
+
mutationGeneration += 1;
|
|
9407
|
+
finalObservationCompleted = false;
|
|
9408
|
+
}
|
|
9409
|
+
};
|
|
9410
|
+
const commitWaitRecord = (wait) => {
|
|
9411
|
+
waits.push({ ...wait });
|
|
9412
|
+
if (wait.cutoffReached) finalObservationRequired = true;
|
|
9413
|
+
mutationGeneration += 1;
|
|
9414
|
+
finalObservationCompleted = false;
|
|
9415
|
+
};
|
|
9416
|
+
const replayDossierEntries = (entries) => {
|
|
9417
|
+
const orderedEntries = Array.from(entries);
|
|
9418
|
+
const finalRequestStatus = /* @__PURE__ */ new Map();
|
|
9419
|
+
for (const raw of orderedEntries) {
|
|
9420
|
+
if (typeof raw !== "object" || raw === null) continue;
|
|
9421
|
+
const entry = raw;
|
|
9422
|
+
if (entry.type !== "custom" || entry.customType !== COLLECTOR_REQUEST_ENTRY_TYPE || typeof entry.data !== "object" || entry.data === null) continue;
|
|
9423
|
+
const attempt = entry.data.attempt;
|
|
9424
|
+
if (attempt?.attemptId !== void 0) finalRequestStatus.set(attempt.attemptId, attempt.status);
|
|
9425
|
+
}
|
|
9426
|
+
for (const raw of orderedEntries) {
|
|
9427
|
+
if (typeof raw !== "object" || raw === null) continue;
|
|
9428
|
+
const entry = raw;
|
|
9429
|
+
if (entry.type !== "custom" || typeof entry.data !== "object" || entry.data === null) continue;
|
|
9430
|
+
const data = entry.data;
|
|
9431
|
+
if (entry.customType === COLLECTOR_ACTIVATION_ENTRY_TYPE) {
|
|
9432
|
+
if (typeof data.activationTime === "string" && typeof data.deadlineTime === "string") {
|
|
9433
|
+
commitActivationWindow(new Date(data.activationTime), new Date(data.deadlineTime));
|
|
9434
|
+
}
|
|
9435
|
+
continue;
|
|
9436
|
+
}
|
|
9437
|
+
if (entry.customType === COLLECTOR_SNAPSHOT_ENTRY_TYPE) {
|
|
9438
|
+
const snapshot = data.snapshot;
|
|
9439
|
+
if (snapshot?.snapshotId === void 0 || !Array.isArray(data.evidence)) continue;
|
|
9440
|
+
commitObservedSnapshot(snapshot, data.evidence);
|
|
9441
|
+
continue;
|
|
9442
|
+
}
|
|
9443
|
+
if (entry.customType === COLLECTOR_REQUEST_ENTRY_TYPE) {
|
|
9444
|
+
const attempt = data.attempt;
|
|
9445
|
+
if (attempt?.attemptId === void 0) continue;
|
|
9446
|
+
const attemptKey = typeof data.attemptKey === "string" ? data.attemptKey : [config.repository.canonical, String(config.prNumber), attempt.observedHead, attempt.requestId].join("|");
|
|
9447
|
+
const commentEvidence = data.commentEvidence;
|
|
9448
|
+
const replayAttempt = attempt.status === "started" && finalRequestStatus.get(attempt.attemptId) === "started" ? {
|
|
9449
|
+
...attempt,
|
|
9450
|
+
status: "ambiguous_loss",
|
|
9451
|
+
responseDiagnostics: "request interrupted after dispatch before completion was recorded"
|
|
9452
|
+
} : attempt;
|
|
9453
|
+
commitRequestAttempt(replayAttempt, attemptKey, commentEvidence);
|
|
9454
|
+
continue;
|
|
9455
|
+
}
|
|
9456
|
+
if (entry.customType === COLLECTOR_WAIT_ENTRY_TYPE) {
|
|
9457
|
+
const wait = data.waitRecord;
|
|
9458
|
+
if (wait?.waitId === void 0) continue;
|
|
9459
|
+
commitWaitRecord(wait);
|
|
9460
|
+
}
|
|
9461
|
+
}
|
|
9462
|
+
};
|
|
9463
|
+
if (options?.dossierEntries !== void 0) {
|
|
9464
|
+
replayDossierEntries(options.dossierEntries);
|
|
9465
|
+
}
|
|
9466
|
+
if (clock !== void 0 && deadlineMono !== void 0 && clock.monoNow() >= deadlineMono) {
|
|
9467
|
+
finalObservationRequired = true;
|
|
9468
|
+
const lastSnap = snapshots.find((item) => item.snapshotId === latestCompleteSnapshotId);
|
|
9469
|
+
if (lastSnap?.completedMono !== void 0 && lastSnap.completedMono >= deadlineMono) {
|
|
9470
|
+
finalObservationCompleted = true;
|
|
9471
|
+
}
|
|
9472
|
+
}
|
|
9447
9473
|
const ledger = {
|
|
9448
9474
|
get config() {
|
|
9449
9475
|
return config;
|
|
@@ -9454,8 +9480,8 @@ function createCollectorLedger(config) {
|
|
|
9454
9480
|
get fatalReason() {
|
|
9455
9481
|
return fatalReason;
|
|
9456
9482
|
},
|
|
9457
|
-
get
|
|
9458
|
-
return
|
|
9483
|
+
get outputCandidate() {
|
|
9484
|
+
return outputCandidate || pendingOutputCallId !== void 0;
|
|
9459
9485
|
},
|
|
9460
9486
|
get activationRecorded() {
|
|
9461
9487
|
return activationTime !== void 0;
|
|
@@ -9495,18 +9521,30 @@ function createCollectorLedger(config) {
|
|
|
9495
9521
|
},
|
|
9496
9522
|
latchFatal,
|
|
9497
9523
|
assertNotFatal,
|
|
9498
|
-
recordActivation(
|
|
9524
|
+
recordActivation(clock2) {
|
|
9499
9525
|
assertNotFatal();
|
|
9500
9526
|
if (activationTime !== void 0) return;
|
|
9501
|
-
activationTime =
|
|
9502
|
-
activationMono =
|
|
9527
|
+
activationTime = clock2.wallNow();
|
|
9528
|
+
activationMono = clock2.monoNow();
|
|
9503
9529
|
deadlineTime = new Date(activationTime.getTime() + COLLECTOR_ELIGIBILITY_MS);
|
|
9504
9530
|
deadlineMono = activationMono + COLLECTOR_ELIGIBILITY_MS;
|
|
9531
|
+
appendJournal(COLLECTOR_ACTIVATION_ENTRY_TYPE, {
|
|
9532
|
+
activationTime: activationTime.toISOString(),
|
|
9533
|
+
deadlineTime: deadlineTime.toISOString()
|
|
9534
|
+
});
|
|
9535
|
+
},
|
|
9536
|
+
recordOutputCandidate() {
|
|
9537
|
+
assertNotFatal();
|
|
9538
|
+
outputCandidate = true;
|
|
9505
9539
|
},
|
|
9506
9540
|
beginOperational(toolName, toolCallId) {
|
|
9507
9541
|
assertNotFatal();
|
|
9508
|
-
if (
|
|
9509
|
-
throw
|
|
9542
|
+
if (toolName !== COLLECTOR_OUTPUT_TOOL && (outputCandidate || pendingOutputCallId !== void 0)) {
|
|
9543
|
+
throw new Error("\u901A\u8FDB\u53F8\u5DF2\u4EA7\u51FA\u8F93\u51FA\u5019\u9009\uFF0C\u672C\u5C40\u4E0D\u518D\u53D7\u7406\u64CD\u4F5C");
|
|
9544
|
+
}
|
|
9545
|
+
if (toolName === COLLECTOR_OUTPUT_TOOL) {
|
|
9546
|
+
pendingOutputCallId = toolCallId;
|
|
9547
|
+
return;
|
|
9510
9548
|
}
|
|
9511
9549
|
if (activeOperationalCallId === toolCallId) {
|
|
9512
9550
|
return;
|
|
@@ -9514,28 +9552,23 @@ function createCollectorLedger(config) {
|
|
|
9514
9552
|
if (activeOperationalCallId !== void 0) {
|
|
9515
9553
|
throw latchFatal("\u901A\u8FDB\u53F8\u64CD\u4F5C\u8C03\u7528\u5DF2\u5728\u8FDB\u884C");
|
|
9516
9554
|
}
|
|
9517
|
-
if (toolName === COLLECTOR_OUTPUT_TOOL) {
|
|
9518
|
-
return;
|
|
9519
|
-
}
|
|
9520
9555
|
if (!isOperationalTool(toolName)) {
|
|
9521
9556
|
throw latchFatal(`\u672A\u77E5\u901A\u8FDB\u53F8\u5DE5\u5177 ${toolName}`);
|
|
9522
9557
|
}
|
|
9523
9558
|
activeOperationalCallId = toolCallId;
|
|
9524
9559
|
},
|
|
9525
9560
|
completeOperational(toolCallId) {
|
|
9561
|
+
if (pendingOutputCallId === toolCallId) {
|
|
9562
|
+
pendingOutputCallId = void 0;
|
|
9563
|
+
}
|
|
9526
9564
|
if (activeOperationalCallId === toolCallId) {
|
|
9527
9565
|
activeOperationalCallId = void 0;
|
|
9528
9566
|
}
|
|
9529
9567
|
},
|
|
9530
|
-
markOutputAccepted() {
|
|
9531
|
-
assertNotFatal();
|
|
9532
|
-
if (outputAccepted) throw latchFatal("\u901A\u8FDB\u53F8\u56DE\u6267\u4E3A\u552F\u4E00\u7EC8\u5C40");
|
|
9533
|
-
outputAccepted = true;
|
|
9534
|
-
},
|
|
9535
9568
|
noteCutoffObserved() {
|
|
9536
9569
|
finalObservationRequired = true;
|
|
9537
9570
|
},
|
|
9538
|
-
assertOutputObservationLaw(
|
|
9571
|
+
assertOutputObservationLaw(clock2) {
|
|
9539
9572
|
assertNotFatal();
|
|
9540
9573
|
if (activationTime === void 0 || deadlineTime === void 0 || deadlineMono === void 0) {
|
|
9541
9574
|
throw new Error("\u901A\u8FDB\u53F8\u56DE\u6267\u9700\u8981\u6FC0\u6D3B\u65F6\u95F4\u7EBF");
|
|
@@ -9552,7 +9585,7 @@ function createCollectorLedger(config) {
|
|
|
9552
9585
|
if (snapshot === void 0 || !snapshot.complete) {
|
|
9553
9586
|
throw new Error("\u901A\u8FDB\u53F8\u7EC8\u5C40\u5FEB\u7167\u7F3A\u5931\u6216\u4E0D\u5B8C\u6574");
|
|
9554
9587
|
}
|
|
9555
|
-
const mono = monoNowOrThrow(
|
|
9588
|
+
const mono = monoNowOrThrow(clock2);
|
|
9556
9589
|
const atOrAfterCutoff = mono >= deadlineMono;
|
|
9557
9590
|
if (atOrAfterCutoff) {
|
|
9558
9591
|
finalObservationRequired = true;
|
|
@@ -9564,7 +9597,7 @@ function createCollectorLedger(config) {
|
|
|
9564
9597
|
finalObservationCompleted = true;
|
|
9565
9598
|
}
|
|
9566
9599
|
},
|
|
9567
|
-
async observe(transport,
|
|
9600
|
+
async observe(transport, clock2, signal) {
|
|
9568
9601
|
assertNotFatal();
|
|
9569
9602
|
if (activationTime === void 0) {
|
|
9570
9603
|
throw latchFatal("\u901A\u8FDB\u53F8\u89C2\u5BDF\u9700\u8981\u6FC0\u6D3B");
|
|
@@ -9573,8 +9606,8 @@ function createCollectorLedger(config) {
|
|
|
9573
9606
|
const abortMessage = signal.reason instanceof Error ? signal.reason.message : String(signal.reason ?? "\u5DF2\u4E2D\u6B62");
|
|
9574
9607
|
throw latchFatal(`\u901A\u8FDB\u53F8\u89C2\u5BDF\u5931\u8D25\uFF1A${abortMessage}`, signal.reason);
|
|
9575
9608
|
}
|
|
9576
|
-
const observedAt =
|
|
9577
|
-
const cutoff = pastCutoff(
|
|
9609
|
+
const observedAt = clock2.wallNow().toISOString();
|
|
9610
|
+
const cutoff = pastCutoff(clock2);
|
|
9578
9611
|
if (cutoff) {
|
|
9579
9612
|
finalObservationRequired = true;
|
|
9580
9613
|
}
|
|
@@ -9593,8 +9626,8 @@ function createCollectorLedger(config) {
|
|
|
9593
9626
|
const message = error instanceof Error ? error.message : "\u672A\u77E5\u5931\u8D25";
|
|
9594
9627
|
throw latchFatal(`\u901A\u8FDB\u53F8\u89C2\u5BDF\u5931\u8D25\uFF1A${message}`, error);
|
|
9595
9628
|
}
|
|
9596
|
-
const firstObservedAt =
|
|
9597
|
-
const firstObservedMono = monoNowOrThrow(
|
|
9629
|
+
const firstObservedAt = clock2.wallNow().toISOString();
|
|
9630
|
+
const firstObservedMono = monoNowOrThrow(clock2);
|
|
9598
9631
|
const pr = surfaces.prTerminal;
|
|
9599
9632
|
const { user, reviews, reactions, issueComments, reviewComments } = surfaces;
|
|
9600
9633
|
requesterLogin = user.login.toLowerCase();
|
|
@@ -9638,29 +9671,11 @@ function createCollectorLedger(config) {
|
|
|
9638
9671
|
}
|
|
9639
9672
|
return stored;
|
|
9640
9673
|
});
|
|
9641
|
-
const completedAt =
|
|
9642
|
-
const completedMono =
|
|
9674
|
+
const completedAt = clock2.wallNow().toISOString();
|
|
9675
|
+
const completedMono = clock2.monoNow();
|
|
9643
9676
|
const snapshotId = sha256Text(
|
|
9644
9677
|
`${completedAt}:${pr.headOid}:${storedIds.join(",")}`
|
|
9645
9678
|
).slice(0, 16);
|
|
9646
|
-
for (const failure2 of transportFailures) {
|
|
9647
|
-
if (failure2.recovered || failure2.kind !== "ambiguous_request_loss") continue;
|
|
9648
|
-
if (failure2.marker === void 0 || failure2.requestId === void 0) continue;
|
|
9649
|
-
const found = storedRecords.find(
|
|
9650
|
-
(record4) => record4.kind === "issue_comment" && record4.authorLogin === requesterLogin && typeof record4.body === "string" && record4.body.includes(failure2.marker)
|
|
9651
|
-
);
|
|
9652
|
-
if (found) {
|
|
9653
|
-
failure2.recovered = true;
|
|
9654
|
-
const attempt = attempts.find(
|
|
9655
|
-
(item) => item.status === "ambiguous_loss" && item.requestId === failure2.requestId && item.marker === failure2.marker
|
|
9656
|
-
);
|
|
9657
|
-
if (attempt) {
|
|
9658
|
-
attempt.status = "recovered";
|
|
9659
|
-
attempt.commentEvidenceId = found.evidenceId;
|
|
9660
|
-
attempt.recoverySnapshotId = snapshotId;
|
|
9661
|
-
}
|
|
9662
|
-
}
|
|
9663
|
-
}
|
|
9664
9679
|
const snapshot = {
|
|
9665
9680
|
snapshotId,
|
|
9666
9681
|
observedAt,
|
|
@@ -9676,28 +9691,38 @@ function createCollectorLedger(config) {
|
|
|
9676
9691
|
pageDiagnostics,
|
|
9677
9692
|
normalizedByteLength
|
|
9678
9693
|
};
|
|
9679
|
-
|
|
9680
|
-
|
|
9681
|
-
observedGeneration = mutationGeneration;
|
|
9682
|
-
if (finalObservationRequired && completedMono >= (deadlineMono ?? 0)) {
|
|
9683
|
-
finalObservationCompleted = true;
|
|
9684
|
-
} else if (cutoff) {
|
|
9685
|
-
finalObservationCompleted = true;
|
|
9694
|
+
if (cutoff) {
|
|
9695
|
+
finalObservationRequired = true;
|
|
9686
9696
|
}
|
|
9697
|
+
const committed = finalizeObservedSnapshot(snapshot);
|
|
9698
|
+
appendJournal(COLLECTOR_SNAPSHOT_ENTRY_TYPE, {
|
|
9699
|
+
snapshot: committed,
|
|
9700
|
+
evidence: committed.evidenceIds.flatMap((id) => {
|
|
9701
|
+
const record4 = evidenceById.get(id);
|
|
9702
|
+
return record4 === void 0 ? [] : [record4];
|
|
9703
|
+
})
|
|
9704
|
+
});
|
|
9687
9705
|
const modelView = buildObserveModelView({
|
|
9688
|
-
snapshot,
|
|
9689
|
-
records:
|
|
9706
|
+
snapshot: committed,
|
|
9707
|
+
records: committed.evidenceIds.flatMap((id) => {
|
|
9708
|
+
const record4 = evidenceById.get(id);
|
|
9709
|
+
return record4 === void 0 ? [] : [record4];
|
|
9710
|
+
}),
|
|
9690
9711
|
requesterLogin,
|
|
9691
9712
|
attempts
|
|
9692
9713
|
});
|
|
9693
|
-
return {
|
|
9714
|
+
return {
|
|
9715
|
+
snapshot: committed,
|
|
9716
|
+
modelView,
|
|
9717
|
+
contextView: projectObserveContextView(modelView)
|
|
9718
|
+
};
|
|
9694
9719
|
},
|
|
9695
|
-
async request(input, transport,
|
|
9720
|
+
async request(input, transport, clock2, signal) {
|
|
9696
9721
|
assertNotFatal();
|
|
9697
9722
|
if (activationTime === void 0 || deadlineTime === void 0) {
|
|
9698
9723
|
throw latchFatal("\u901A\u8FDB\u53F8\u8BF7\u6C42\u9700\u8981\u6FC0\u6D3B");
|
|
9699
9724
|
}
|
|
9700
|
-
if (pastCutoff(
|
|
9725
|
+
if (pastCutoff(clock2)) {
|
|
9701
9726
|
finalObservationRequired = true;
|
|
9702
9727
|
throw latchFatal("\u901A\u8FDB\u53F8\u8BF7\u6C42\u4E0D\u5728\u8D44\u683C\u622A\u6B62\u524D");
|
|
9703
9728
|
}
|
|
@@ -9744,7 +9769,7 @@ function createCollectorLedger(config) {
|
|
|
9744
9769
|
`\u901A\u8FDB\u53F8\u8FDB\u7A0B\u5185\u8BF7\u6C42 "${request.id}" \u5728 HEAD ${snapshot.headOid} \u7684 attempt \u5DF2\u7528`
|
|
9745
9770
|
);
|
|
9746
9771
|
}
|
|
9747
|
-
const startedAt =
|
|
9772
|
+
const startedAt = clock2.wallNow().toISOString();
|
|
9748
9773
|
const attemptId = sha256Text(`${attemptKey}:${startedAt}`).slice(0, 16);
|
|
9749
9774
|
const attempt = {
|
|
9750
9775
|
attemptId,
|
|
@@ -9756,8 +9781,11 @@ function createCollectorLedger(config) {
|
|
|
9756
9781
|
startedAt,
|
|
9757
9782
|
status: "started"
|
|
9758
9783
|
};
|
|
9759
|
-
|
|
9760
|
-
|
|
9784
|
+
commitRequestAttempt(attempt, attemptKey, void 0);
|
|
9785
|
+
appendJournal(COLLECTOR_REQUEST_ENTRY_TYPE, {
|
|
9786
|
+
attempt: { ...attempt },
|
|
9787
|
+
attemptKey
|
|
9788
|
+
});
|
|
9761
9789
|
const result2 = await transport.createIssueComment({
|
|
9762
9790
|
owner: config.repository.owner,
|
|
9763
9791
|
repo: config.repository.repo,
|
|
@@ -9765,14 +9793,25 @@ function createCollectorLedger(config) {
|
|
|
9765
9793
|
body,
|
|
9766
9794
|
...signal === void 0 ? {} : { signal }
|
|
9767
9795
|
});
|
|
9768
|
-
|
|
9769
|
-
|
|
9796
|
+
const journalRequest = (commentEvidence) => {
|
|
9797
|
+
const attemptKey2 = [
|
|
9798
|
+
config.repository.canonical,
|
|
9799
|
+
String(config.prNumber),
|
|
9800
|
+
attempt.observedHead,
|
|
9801
|
+
attempt.requestId
|
|
9802
|
+
].join("|");
|
|
9803
|
+
appendJournal(COLLECTOR_REQUEST_ENTRY_TYPE, {
|
|
9804
|
+
attempt: { ...attempt },
|
|
9805
|
+
attemptKey: attemptKey2,
|
|
9806
|
+
commentEvidence
|
|
9807
|
+
});
|
|
9808
|
+
};
|
|
9770
9809
|
if (result2.kind === "success") {
|
|
9771
|
-
const record4 =
|
|
9772
|
-
normalizeIssueCommentEvidence(result2.comment, startedAt)
|
|
9773
|
-
);
|
|
9810
|
+
const record4 = normalizeIssueCommentEvidence(result2.comment, startedAt);
|
|
9774
9811
|
attempt.status = "succeeded";
|
|
9775
9812
|
attempt.commentEvidenceId = record4.evidenceId;
|
|
9813
|
+
commitRequestAttempt(attempt, attemptKey, record4);
|
|
9814
|
+
journalRequest(record4);
|
|
9776
9815
|
return {
|
|
9777
9816
|
status: "succeeded",
|
|
9778
9817
|
attemptId,
|
|
@@ -9785,15 +9824,8 @@ function createCollectorLedger(config) {
|
|
|
9785
9824
|
if (result2.kind === "ambiguous_loss") {
|
|
9786
9825
|
attempt.status = "ambiguous_loss";
|
|
9787
9826
|
attempt.responseDiagnostics = result2.diagnostics;
|
|
9788
|
-
|
|
9789
|
-
|
|
9790
|
-
kind: "ambiguous_request_loss",
|
|
9791
|
-
message: result2.diagnostics,
|
|
9792
|
-
requestId: request.id,
|
|
9793
|
-
observedHead: snapshot.headOid,
|
|
9794
|
-
marker,
|
|
9795
|
-
recovered: false
|
|
9796
|
-
});
|
|
9827
|
+
commitRequestAttempt(attempt, attemptKey, void 0);
|
|
9828
|
+
journalRequest(void 0);
|
|
9797
9829
|
return {
|
|
9798
9830
|
status: "ambiguous_loss",
|
|
9799
9831
|
attemptId,
|
|
@@ -9805,9 +9837,11 @@ function createCollectorLedger(config) {
|
|
|
9805
9837
|
}
|
|
9806
9838
|
attempt.status = "rejected";
|
|
9807
9839
|
attempt.responseDiagnostics = result2.diagnostics;
|
|
9840
|
+
commitRequestAttempt(attempt, attemptKey, void 0);
|
|
9841
|
+
journalRequest(void 0);
|
|
9808
9842
|
throw latchFatal(`\u901A\u8FDB\u53F8\u8BF7\u6C42\u88AB\u62D2\uFF1A${result2.diagnostics}`);
|
|
9809
9843
|
},
|
|
9810
|
-
async wait(input,
|
|
9844
|
+
async wait(input, clock2, signal) {
|
|
9811
9845
|
assertNotFatal();
|
|
9812
9846
|
if (activationTime === void 0) {
|
|
9813
9847
|
throw latchFatal("\u901A\u8FDB\u53F8\u7B49\u5F85\u9700\u8981\u6FC0\u6D3B");
|
|
@@ -9820,25 +9854,22 @@ function createCollectorLedger(config) {
|
|
|
9820
9854
|
`\u901A\u8FDB\u53F8\u7B49\u5F85 durationMs \u81F3\u591A\u4E3A ${COLLECTOR_ELIGIBILITY_MS}`
|
|
9821
9855
|
);
|
|
9822
9856
|
}
|
|
9823
|
-
if (pastCutoff(
|
|
9857
|
+
if (pastCutoff(clock2)) {
|
|
9824
9858
|
finalObservationRequired = true;
|
|
9825
9859
|
throw latchFatal("\u901A\u8FDB\u53F8\u7B49\u5F85\u4E0D\u5728\u8D44\u683C\u622A\u6B62\u524D");
|
|
9826
9860
|
}
|
|
9827
|
-
const remaining = remainingMs(
|
|
9861
|
+
const remaining = remainingMs(clock2);
|
|
9828
9862
|
const COLLECTOR_SINGLE_WAIT_MAX_MS = 3e5;
|
|
9829
9863
|
const effectiveMs = Math.min(
|
|
9830
9864
|
input.durationMs,
|
|
9831
9865
|
remaining,
|
|
9832
9866
|
COLLECTOR_SINGLE_WAIT_MAX_MS
|
|
9833
9867
|
);
|
|
9834
|
-
const startedAt =
|
|
9868
|
+
const startedAt = clock2.wallNow().toISOString();
|
|
9835
9869
|
const waitId = sha256Text(`wait:${startedAt}:${effectiveMs}`).slice(0, 16);
|
|
9836
|
-
await
|
|
9837
|
-
const endedAt =
|
|
9838
|
-
const cutoffReached = pastCutoff(
|
|
9839
|
-
if (cutoffReached) finalObservationRequired = true;
|
|
9840
|
-
mutationGeneration += 1;
|
|
9841
|
-
finalObservationCompleted = false;
|
|
9870
|
+
await clock2.sleep(effectiveMs, signal);
|
|
9871
|
+
const endedAt = clock2.wallNow().toISOString();
|
|
9872
|
+
const cutoffReached = pastCutoff(clock2);
|
|
9842
9873
|
const record4 = {
|
|
9843
9874
|
waitId,
|
|
9844
9875
|
requestedMs: input.durationMs,
|
|
@@ -9847,13 +9878,16 @@ function createCollectorLedger(config) {
|
|
|
9847
9878
|
endedAt,
|
|
9848
9879
|
cutoffReached
|
|
9849
9880
|
};
|
|
9850
|
-
|
|
9881
|
+
commitWaitRecord(record4);
|
|
9882
|
+
appendJournal(COLLECTOR_WAIT_ENTRY_TYPE, {
|
|
9883
|
+
waitRecord: record4
|
|
9884
|
+
});
|
|
9851
9885
|
return {
|
|
9852
9886
|
waitId,
|
|
9853
9887
|
requestedMs: input.durationMs,
|
|
9854
9888
|
effectiveMs,
|
|
9855
9889
|
cutoffReached,
|
|
9856
|
-
remainingMsAfter: remainingMs(
|
|
9890
|
+
remainingMsAfter: remainingMs(clock2)
|
|
9857
9891
|
};
|
|
9858
9892
|
},
|
|
9859
9893
|
getSnapshot(snapshotId) {
|
|
@@ -9922,6 +9956,410 @@ function buildObserveModelView(input) {
|
|
|
9922
9956
|
};
|
|
9923
9957
|
}
|
|
9924
9958
|
|
|
9959
|
+
// src/activation-trace.ts
|
|
9960
|
+
import { Type as Type18 } from "typebox";
|
|
9961
|
+
var causeSchema = Type18.Object({
|
|
9962
|
+
identity: Type18.String({ minLength: 1 }),
|
|
9963
|
+
name: Type18.String({ minLength: 1 }),
|
|
9964
|
+
message: Type18.String(),
|
|
9965
|
+
evidenceId: Type18.Optional(Type18.String({ minLength: 1 }))
|
|
9966
|
+
}, { additionalProperties: false });
|
|
9967
|
+
var activationTraceRecordSchema = Type18.Object({
|
|
9968
|
+
role: Type18.String({ minLength: 1 }),
|
|
9969
|
+
stageId: Type18.String({ pattern: "^[a-z][a-z0-9-]*$" }),
|
|
9970
|
+
status: Type18.Literal("failed"),
|
|
9971
|
+
timestamp: Type18.String({ format: "date-time" }),
|
|
9972
|
+
cause: causeSchema
|
|
9973
|
+
}, { additionalProperties: false });
|
|
9974
|
+
var activationCauseEvidence = 0;
|
|
9975
|
+
var retainedActivationCauses = /* @__PURE__ */ new Map();
|
|
9976
|
+
function namedActivationCause(error) {
|
|
9977
|
+
const evidenceId = `activation-cause-${++activationCauseEvidence}`;
|
|
9978
|
+
retainedActivationCauses.set(evidenceId, error);
|
|
9979
|
+
if (error instanceof Error) {
|
|
9980
|
+
const code = error.code;
|
|
9981
|
+
const name = error.name || "Error";
|
|
9982
|
+
return { identity: typeof code === "string" && code.length > 0 ? code : name, name, message: error.message, evidenceId };
|
|
9983
|
+
}
|
|
9984
|
+
let message;
|
|
9985
|
+
try {
|
|
9986
|
+
message = typeof error === "string" ? error : JSON.stringify(error) ?? String(error);
|
|
9987
|
+
return { identity: "UnknownThrownCause", name: "UnknownThrownCause", message, evidenceId };
|
|
9988
|
+
} catch {
|
|
9989
|
+
return { identity: "UnknownThrownCause", name: "UnknownThrownCause", message: String(error), evidenceId };
|
|
9990
|
+
}
|
|
9991
|
+
}
|
|
9992
|
+
|
|
9993
|
+
// src/role-runtime.ts
|
|
9994
|
+
init_activation_ledger_topology();
|
|
9995
|
+
|
|
9996
|
+
// src/activation-ledger.ts
|
|
9997
|
+
init_activation_ledger_topology();
|
|
9998
|
+
init_activation_ledger_git();
|
|
9999
|
+
import {
|
|
10000
|
+
constants,
|
|
10001
|
+
closeSync,
|
|
10002
|
+
fstatSync,
|
|
10003
|
+
openSync,
|
|
10004
|
+
writeSync
|
|
10005
|
+
} from "node:fs";
|
|
10006
|
+
import { dirname as dirname14, isAbsolute as isAbsolute6, resolve as resolve15 } from "node:path";
|
|
10007
|
+
|
|
10008
|
+
// src/activation-ledger-session.ts
|
|
10009
|
+
init_activation_ledger_topology();
|
|
10010
|
+
import {
|
|
10011
|
+
lstatSync as lstatSync2,
|
|
10012
|
+
realpathSync as realpathSync3,
|
|
10013
|
+
statSync as statSync3,
|
|
10014
|
+
writeFileSync as writeFileSync4
|
|
10015
|
+
} from "node:fs";
|
|
10016
|
+
import { isAbsolute as isAbsolute5, resolve as resolve14 } from "node:path";
|
|
10017
|
+
var ActivationSessionFileMissingError = class extends Error {
|
|
10018
|
+
code = "AK_ACTIVATION_SESSION_FILE_MISSING";
|
|
10019
|
+
path;
|
|
10020
|
+
constructor(path, options) {
|
|
10021
|
+
super(
|
|
10022
|
+
`Workflow role activation durable session file does not exist: ${path}`,
|
|
10023
|
+
options?.cause === void 0 ? void 0 : { cause: options.cause }
|
|
10024
|
+
);
|
|
10025
|
+
this.name = "ActivationSessionFileMissingError";
|
|
10026
|
+
this.path = path;
|
|
10027
|
+
}
|
|
10028
|
+
};
|
|
10029
|
+
function materializeDeferredSessionFile(sessionManager, resolvedFile) {
|
|
10030
|
+
const header = sessionManager.getHeader?.();
|
|
10031
|
+
if (header === null || header === void 0 || header.type !== "session") {
|
|
10032
|
+
throw new ActivationSessionFileMissingError(resolvedFile);
|
|
10033
|
+
}
|
|
10034
|
+
try {
|
|
10035
|
+
writeFileSync4(resolvedFile, `${JSON.stringify(header)}
|
|
10036
|
+
`, { flag: "wx" });
|
|
10037
|
+
} catch (error) {
|
|
10038
|
+
if (errnoCode(error) !== "EEXIST") {
|
|
10039
|
+
throw new Error(
|
|
10040
|
+
`Workflow role activation failed to materialize durable session file (${resolvedFile}): ${errorText(error)}`,
|
|
10041
|
+
{ cause: error }
|
|
10042
|
+
);
|
|
10043
|
+
}
|
|
10044
|
+
}
|
|
10045
|
+
if (typeof sessionManager.setSessionFile === "function") {
|
|
10046
|
+
sessionManager.setSessionFile(resolvedFile);
|
|
10047
|
+
}
|
|
10048
|
+
}
|
|
10049
|
+
function durableSessionPointer(sessionManager) {
|
|
10050
|
+
const file = sessionManager.getSessionFile?.();
|
|
10051
|
+
if (typeof file !== "string" || file.length === 0) {
|
|
10052
|
+
throw new Error(
|
|
10053
|
+
"Workflow role activation requires a durable Pi session file principal (getSessionFile); directory-only or --no-session invocations are rejected"
|
|
10054
|
+
);
|
|
10055
|
+
}
|
|
10056
|
+
if (!isAbsolute5(file)) {
|
|
10057
|
+
throw new Error(
|
|
10058
|
+
`Workflow role activation requires an absolute durable session file path; got relative path: ${file}`
|
|
10059
|
+
);
|
|
10060
|
+
}
|
|
10061
|
+
const resolvedFile = resolve14(file);
|
|
10062
|
+
try {
|
|
10063
|
+
lstatSync2(resolvedFile);
|
|
10064
|
+
} catch (error) {
|
|
10065
|
+
if (errnoCode(error) !== "ENOENT") {
|
|
10066
|
+
throw new Error(
|
|
10067
|
+
`Workflow role activation failed to stat durable session file (${resolvedFile}): ${errorText(error)}`,
|
|
10068
|
+
{ cause: error }
|
|
10069
|
+
);
|
|
10070
|
+
}
|
|
10071
|
+
try {
|
|
10072
|
+
materializeDeferredSessionFile(sessionManager, resolvedFile);
|
|
10073
|
+
} catch (materializeError) {
|
|
10074
|
+
if (materializeError instanceof ActivationSessionFileMissingError) {
|
|
10075
|
+
throw new ActivationSessionFileMissingError(resolvedFile, { cause: error });
|
|
10076
|
+
}
|
|
10077
|
+
throw materializeError;
|
|
10078
|
+
}
|
|
10079
|
+
}
|
|
10080
|
+
let realFile;
|
|
10081
|
+
try {
|
|
10082
|
+
realFile = realpathSync3(resolvedFile);
|
|
10083
|
+
} catch (error) {
|
|
10084
|
+
throw new ActivationSessionFileMissingError(resolvedFile, { cause: error });
|
|
10085
|
+
}
|
|
10086
|
+
let info;
|
|
10087
|
+
try {
|
|
10088
|
+
info = statSync3(realFile);
|
|
10089
|
+
} catch (error) {
|
|
10090
|
+
throw new Error(
|
|
10091
|
+
`Workflow role activation failed to stat durable session file (${realFile}): ${errorText(error)}`,
|
|
10092
|
+
{ cause: error }
|
|
10093
|
+
);
|
|
10094
|
+
}
|
|
10095
|
+
if (info.isDirectory()) {
|
|
10096
|
+
throw new Error(
|
|
10097
|
+
`Workflow role activation durable session principal must be a file, not a directory: ${realFile}`
|
|
10098
|
+
);
|
|
10099
|
+
}
|
|
10100
|
+
if (!info.isFile()) {
|
|
10101
|
+
throw new Error(
|
|
10102
|
+
`Workflow role activation durable session principal is not a regular file: ${realFile}`
|
|
10103
|
+
);
|
|
10104
|
+
}
|
|
10105
|
+
return { kind: "session-file", path: realFile };
|
|
10106
|
+
}
|
|
10107
|
+
|
|
10108
|
+
// src/activation-ledger.ts
|
|
10109
|
+
init_activation_ledger_topology();
|
|
10110
|
+
var ACTIVATION_LEDGER_APPEND_OPEN_FLAGS = constants.O_APPEND | constants.O_CREAT | constants.O_WRONLY | constants.O_NOFOLLOW;
|
|
10111
|
+
var ACCEPTED_ACTIVATION_EVENT = "accepted-activation";
|
|
10112
|
+
var ACCEPTED_ACTIVATION_FACT_KEYS = Object.freeze([
|
|
10113
|
+
"event",
|
|
10114
|
+
"role",
|
|
10115
|
+
"observedAt",
|
|
10116
|
+
"bookKey",
|
|
10117
|
+
"session",
|
|
10118
|
+
"correlation"
|
|
10119
|
+
]);
|
|
10120
|
+
function correlationIdentityFromEnv(env = process.env) {
|
|
10121
|
+
const raw = env.AK_CORRELATION_ID;
|
|
10122
|
+
if (typeof raw === "string" && raw.trim().length > 0) {
|
|
10123
|
+
return { kind: "caller", id: raw };
|
|
10124
|
+
}
|
|
10125
|
+
return { kind: "absent" };
|
|
10126
|
+
}
|
|
10127
|
+
function projectAcceptedActivationFact(input) {
|
|
10128
|
+
const closed = {
|
|
10129
|
+
event: ACCEPTED_ACTIVATION_EVENT,
|
|
10130
|
+
role: input.role,
|
|
10131
|
+
observedAt: input.observedAt,
|
|
10132
|
+
bookKey: input.bookKey,
|
|
10133
|
+
session: { kind: "session-file", path: input.session.path },
|
|
10134
|
+
correlation: input.correlation.kind === "caller" ? { kind: "caller", id: input.correlation.id } : { kind: "absent" }
|
|
10135
|
+
};
|
|
10136
|
+
return Object.fromEntries(
|
|
10137
|
+
ACCEPTED_ACTIVATION_FACT_KEYS.map((key) => [key, closed[key]])
|
|
10138
|
+
);
|
|
10139
|
+
}
|
|
10140
|
+
function buildAcceptedActivationFact(input) {
|
|
10141
|
+
return projectAcceptedActivationFact(input);
|
|
10142
|
+
}
|
|
10143
|
+
function serializeAcceptedActivationFact(fact) {
|
|
10144
|
+
return `${JSON.stringify(projectAcceptedActivationFact(fact))}
|
|
10145
|
+
`;
|
|
10146
|
+
}
|
|
10147
|
+
function appendActivationLedgerLine(ledgerPath, line2, options) {
|
|
10148
|
+
if (!isAbsolute6(options.ledgerHome)) {
|
|
10149
|
+
throw new ActivationLedgerError(
|
|
10150
|
+
`activation ledger home must be absolute: ${options.ledgerHome}`
|
|
10151
|
+
);
|
|
10152
|
+
}
|
|
10153
|
+
const resolvedLedger = resolve15(ledgerPath);
|
|
10154
|
+
const resolvedHome = resolve15(options.ledgerHome);
|
|
10155
|
+
const parent = dirname14(resolvedLedger);
|
|
10156
|
+
ensureRealDirectoryTree(resolvedHome, parent);
|
|
10157
|
+
assertLedgerFileInsideHome(resolvedLedger, resolvedHome);
|
|
10158
|
+
if (typeof constants.O_NOFOLLOW !== "number") {
|
|
10159
|
+
throw new ActivationLedgerError(
|
|
10160
|
+
"activation ledger append requires O_NOFOLLOW open-flag support (anti-symlink TOCTOU protection must not be silently dropped); refusing to append"
|
|
10161
|
+
);
|
|
10162
|
+
}
|
|
10163
|
+
const bytes = Buffer.isBuffer(line2) ? line2 : Buffer.from(line2);
|
|
10164
|
+
let ledgerFd;
|
|
10165
|
+
let primaryFailure;
|
|
10166
|
+
try {
|
|
10167
|
+
try {
|
|
10168
|
+
ledgerFd = openSync(resolvedLedger, ACTIVATION_LEDGER_APPEND_OPEN_FLAGS, 420);
|
|
10169
|
+
} catch (error) {
|
|
10170
|
+
throw new ActivationLedgerError(
|
|
10171
|
+
`activation ledger failed to open ledger file (${resolvedLedger}): ${errorText(error)}`,
|
|
10172
|
+
{ cause: error }
|
|
10173
|
+
);
|
|
10174
|
+
}
|
|
10175
|
+
let opened;
|
|
10176
|
+
try {
|
|
10177
|
+
opened = fstatSync(ledgerFd);
|
|
10178
|
+
} catch (error) {
|
|
10179
|
+
throw new ActivationLedgerError(
|
|
10180
|
+
`activation ledger failed to fstat ledger file (${resolvedLedger}): ${errorText(error)}`,
|
|
10181
|
+
{ cause: error }
|
|
10182
|
+
);
|
|
10183
|
+
}
|
|
10184
|
+
if (!opened.isFile()) {
|
|
10185
|
+
throw new ActivationLedgerError(
|
|
10186
|
+
`activation ledger is not a regular file: ${resolvedLedger}`
|
|
10187
|
+
);
|
|
10188
|
+
}
|
|
10189
|
+
const written = writeSync(ledgerFd, bytes, 0, bytes.length, null);
|
|
10190
|
+
if (written !== bytes.length) {
|
|
10191
|
+
throw new ActivationLedgerError(
|
|
10192
|
+
`activation ledger short write: wrote ${written} of ${bytes.length} bytes to ${resolvedLedger}`
|
|
10193
|
+
);
|
|
10194
|
+
}
|
|
10195
|
+
} catch (error) {
|
|
10196
|
+
primaryFailure = error;
|
|
10197
|
+
}
|
|
10198
|
+
if (ledgerFd !== void 0) {
|
|
10199
|
+
try {
|
|
10200
|
+
closeSync(ledgerFd);
|
|
10201
|
+
} catch (closeFailure) {
|
|
10202
|
+
if (primaryFailure !== void 0) {
|
|
10203
|
+
throw new AggregateError(
|
|
10204
|
+
[primaryFailure, closeFailure],
|
|
10205
|
+
"activation ledger operation and close failed",
|
|
10206
|
+
{ cause: primaryFailure }
|
|
10207
|
+
);
|
|
10208
|
+
}
|
|
10209
|
+
throw closeFailure;
|
|
10210
|
+
}
|
|
10211
|
+
}
|
|
10212
|
+
if (primaryFailure !== void 0) throw primaryFailure;
|
|
10213
|
+
}
|
|
10214
|
+
function appendAcceptedActivationFact(ledgerPath, fact, options) {
|
|
10215
|
+
appendActivationLedgerLine(
|
|
10216
|
+
ledgerPath,
|
|
10217
|
+
Buffer.from(serializeAcceptedActivationFact(fact), "utf8"),
|
|
10218
|
+
{ ledgerHome: options.ledgerHome }
|
|
10219
|
+
);
|
|
10220
|
+
}
|
|
10221
|
+
function appendAcceptedActivationToBook(options) {
|
|
10222
|
+
appendAcceptedActivationFact(
|
|
10223
|
+
activationWaitingLedgerPath(options.ledgerHome, options.fact.bookKey),
|
|
10224
|
+
options.fact,
|
|
10225
|
+
{ ledgerHome: options.ledgerHome }
|
|
10226
|
+
);
|
|
10227
|
+
}
|
|
10228
|
+
|
|
10229
|
+
// src/stderr-jsonl.ts
|
|
10230
|
+
import { writeSync as writeSync2 } from "node:fs";
|
|
10231
|
+
var STDERR_JSONL_WRITE_RETRY_LIMIT = 100;
|
|
10232
|
+
function writeStderrJsonlRecord(record4, write = writeSync2) {
|
|
10233
|
+
const bytes = Buffer.from(`${JSON.stringify(record4)}
|
|
10234
|
+
`);
|
|
10235
|
+
let offset = 0;
|
|
10236
|
+
let retries = 0;
|
|
10237
|
+
while (offset < bytes.length) {
|
|
10238
|
+
try {
|
|
10239
|
+
const written = write(2, bytes, offset, bytes.length - offset);
|
|
10240
|
+
if (written <= 0) throw new Error("stderr JSONL write made no progress");
|
|
10241
|
+
offset += written;
|
|
10242
|
+
retries = 0;
|
|
10243
|
+
} catch (error) {
|
|
10244
|
+
const code = error.code;
|
|
10245
|
+
if ((code === "EAGAIN" || code === "EINTR") && retries++ < STDERR_JSONL_WRITE_RETRY_LIMIT) continue;
|
|
10246
|
+
throw error;
|
|
10247
|
+
}
|
|
10248
|
+
}
|
|
10249
|
+
}
|
|
10250
|
+
|
|
10251
|
+
// src/tool-execution-observation.ts
|
|
10252
|
+
import { writeSync as writeSync3 } from "node:fs";
|
|
10253
|
+
import { Type as Type19 } from "typebox";
|
|
10254
|
+
import { Value as Value4 } from "typebox/value";
|
|
10255
|
+
var TOOL_EXECUTION_UPDATE_THROTTLE_MS = 3e4;
|
|
10256
|
+
var observationBase = {
|
|
10257
|
+
role: Type19.String({ minLength: 1 }),
|
|
10258
|
+
toolCallId: Type19.String({ minLength: 1 }),
|
|
10259
|
+
toolName: Type19.String({ minLength: 1 }),
|
|
10260
|
+
timestamp: Type19.String({ format: "date-time" })
|
|
10261
|
+
};
|
|
10262
|
+
var toolExecutionObservationRecordSchema = Type19.Union([
|
|
10263
|
+
Type19.Object({
|
|
10264
|
+
...observationBase,
|
|
10265
|
+
event: Type19.Literal("tool_execution_start")
|
|
10266
|
+
}, { additionalProperties: true }),
|
|
10267
|
+
Type19.Object({
|
|
10268
|
+
...observationBase,
|
|
10269
|
+
event: Type19.Literal("tool_execution_update")
|
|
10270
|
+
}, { additionalProperties: true }),
|
|
10271
|
+
Type19.Object({
|
|
10272
|
+
...observationBase,
|
|
10273
|
+
event: Type19.Literal("tool_execution_end"),
|
|
10274
|
+
isError: Type19.Boolean()
|
|
10275
|
+
}, { additionalProperties: true })
|
|
10276
|
+
]);
|
|
10277
|
+
function validateToolExecutionObservationRecord(record4) {
|
|
10278
|
+
if (!Value4.Check(toolExecutionObservationRecordSchema, record4)) {
|
|
10279
|
+
throw new TypeError("Tool execution observation record does not match its contract");
|
|
10280
|
+
}
|
|
10281
|
+
return record4;
|
|
10282
|
+
}
|
|
10283
|
+
function writeToolExecutionObservationRecord(record4, write = writeSync3) {
|
|
10284
|
+
writeStderrJsonlRecord(validateToolExecutionObservationRecord(record4), write);
|
|
10285
|
+
}
|
|
10286
|
+
function isProducingToolUpdate(partialResult) {
|
|
10287
|
+
if (partialResult == null) return false;
|
|
10288
|
+
if (typeof partialResult !== "object") return true;
|
|
10289
|
+
const content = partialResult.content;
|
|
10290
|
+
if (!Array.isArray(content)) return true;
|
|
10291
|
+
if (content.length === 0) return false;
|
|
10292
|
+
return content.some((part) => {
|
|
10293
|
+
if (typeof part !== "object" || part === null) return true;
|
|
10294
|
+
const text = part.text;
|
|
10295
|
+
if (typeof text === "string") return text.length > 0;
|
|
10296
|
+
return true;
|
|
10297
|
+
});
|
|
10298
|
+
}
|
|
10299
|
+
function systemToolExecutionObservationMonoNow() {
|
|
10300
|
+
return performance.now();
|
|
10301
|
+
}
|
|
10302
|
+
function createToolExecutionObservationFace(options) {
|
|
10303
|
+
const states = /* @__PURE__ */ new Map();
|
|
10304
|
+
async function emit(record4) {
|
|
10305
|
+
await options.write(validateToolExecutionObservationRecord(record4));
|
|
10306
|
+
}
|
|
10307
|
+
function activeRole() {
|
|
10308
|
+
if (!options.admitted()) return void 0;
|
|
10309
|
+
const role = options.role();
|
|
10310
|
+
return role === void 0 || role === "" ? void 0 : role;
|
|
10311
|
+
}
|
|
10312
|
+
return {
|
|
10313
|
+
reset() {
|
|
10314
|
+
states.clear();
|
|
10315
|
+
},
|
|
10316
|
+
async onStart(event) {
|
|
10317
|
+
const role = activeRole();
|
|
10318
|
+
if (role === void 0) return;
|
|
10319
|
+
states.set(event.toolCallId, { lastUpdateEmitMonoMs: void 0 });
|
|
10320
|
+
await emit({
|
|
10321
|
+
event: "tool_execution_start",
|
|
10322
|
+
role,
|
|
10323
|
+
toolCallId: event.toolCallId,
|
|
10324
|
+
toolName: event.toolName,
|
|
10325
|
+
timestamp: options.clock()
|
|
10326
|
+
});
|
|
10327
|
+
},
|
|
10328
|
+
async onUpdate(event) {
|
|
10329
|
+
const role = activeRole();
|
|
10330
|
+
if (role === void 0) return;
|
|
10331
|
+
if (!isProducingToolUpdate(event.partialResult)) return;
|
|
10332
|
+
const now = options.monoNow();
|
|
10333
|
+
const state = states.get(event.toolCallId) ?? { lastUpdateEmitMonoMs: void 0 };
|
|
10334
|
+
if (state.lastUpdateEmitMonoMs !== void 0 && now - state.lastUpdateEmitMonoMs < TOOL_EXECUTION_UPDATE_THROTTLE_MS) {
|
|
10335
|
+
return;
|
|
10336
|
+
}
|
|
10337
|
+
state.lastUpdateEmitMonoMs = now;
|
|
10338
|
+
states.set(event.toolCallId, state);
|
|
10339
|
+
await emit({
|
|
10340
|
+
event: "tool_execution_update",
|
|
10341
|
+
role,
|
|
10342
|
+
toolCallId: event.toolCallId,
|
|
10343
|
+
toolName: event.toolName,
|
|
10344
|
+
timestamp: options.clock()
|
|
10345
|
+
});
|
|
10346
|
+
},
|
|
10347
|
+
async onEnd(event) {
|
|
10348
|
+
const role = activeRole();
|
|
10349
|
+
if (role === void 0) return;
|
|
10350
|
+
states.delete(event.toolCallId);
|
|
10351
|
+
await emit({
|
|
10352
|
+
event: "tool_execution_end",
|
|
10353
|
+
role,
|
|
10354
|
+
toolCallId: event.toolCallId,
|
|
10355
|
+
toolName: event.toolName,
|
|
10356
|
+
timestamp: options.clock(),
|
|
10357
|
+
isError: event.isError
|
|
10358
|
+
});
|
|
10359
|
+
}
|
|
10360
|
+
};
|
|
10361
|
+
}
|
|
10362
|
+
|
|
9925
10363
|
// src/collector-identity.ts
|
|
9926
10364
|
function identityKey(identity) {
|
|
9927
10365
|
if (identity === null) return "unassigned";
|
|
@@ -10047,7 +10485,6 @@ function fail4(message) {
|
|
|
10047
10485
|
}
|
|
10048
10486
|
function buildCollectorReceipt(ledger, candidateRaw, clock) {
|
|
10049
10487
|
ledger.assertNotFatal();
|
|
10050
|
-
if (ledger.outputAccepted) fail4("Collector output is singleton");
|
|
10051
10488
|
if (ledger.unresolvedTransportFailure) fail4("Collector cannot output while a transport failure is unrecovered");
|
|
10052
10489
|
if (ledger.latestCompleteSnapshotId === void 0) fail4("Collector output requires a complete final snapshot");
|
|
10053
10490
|
if (ledger.activationTime === void 0 || ledger.deadlineTime === void 0) fail4("Collector output requires activation timeline");
|
|
@@ -10251,10 +10688,13 @@ function createCollectorRoleRuntime(pi, dependencies, hostActions) {
|
|
|
10251
10688
|
reason: `\u901A\u8FDB\u53F8\u7981\u7528\u5DE5\u5177 ${event.toolName}`
|
|
10252
10689
|
};
|
|
10253
10690
|
}
|
|
10254
|
-
if (
|
|
10691
|
+
if (event.toolName === COLLECTOR_OUTPUT_TOOL) {
|
|
10692
|
+
activation.ledger.beginOperational(COLLECTOR_OUTPUT_TOOL, event.toolCallId);
|
|
10693
|
+
}
|
|
10694
|
+
if (activation.ledger.outputCandidate && event.toolName !== COLLECTOR_OUTPUT_TOOL) {
|
|
10255
10695
|
return {
|
|
10256
10696
|
block: true,
|
|
10257
|
-
reason: "\
|
|
10697
|
+
reason: "\u901A\u8FDB\u53F8\u5DF2\u4EA7\u51FA\u8F93\u51FA\u5019\u9009\uFF0C\u672C\u5C40\u4E0D\u518D\u53D7\u7406\u64CD\u4F5C"
|
|
10258
10698
|
};
|
|
10259
10699
|
}
|
|
10260
10700
|
return void 0;
|
|
@@ -10265,7 +10705,7 @@ function createCollectorRoleRuntime(pi, dependencies, hostActions) {
|
|
|
10265
10705
|
});
|
|
10266
10706
|
pi.on("session_shutdown", () => {
|
|
10267
10707
|
if (activation === void 0) return;
|
|
10268
|
-
if (
|
|
10708
|
+
if (activation.ledger.fatal) {
|
|
10269
10709
|
if (process.exitCode === void 0 || process.exitCode === 0) {
|
|
10270
10710
|
process.exitCode = 1;
|
|
10271
10711
|
}
|
|
@@ -10433,8 +10873,7 @@ function createCollectorRoleRuntime(pi, dependencies, hostActions) {
|
|
|
10433
10873
|
params,
|
|
10434
10874
|
activation.clock
|
|
10435
10875
|
);
|
|
10436
|
-
activation.ledger.
|
|
10437
|
-
activation.ledger.completeOperational(toolCallId);
|
|
10876
|
+
activation.ledger.recordOutputCandidate();
|
|
10438
10877
|
const acceptedDetails = receipt;
|
|
10439
10878
|
return {
|
|
10440
10879
|
content: [{
|
|
@@ -10449,6 +10888,8 @@ function createCollectorRoleRuntime(pi, dependencies, hostActions) {
|
|
|
10449
10888
|
hostActions.failInfrastructure(error, ctx, toolCallId);
|
|
10450
10889
|
}
|
|
10451
10890
|
throw error;
|
|
10891
|
+
} finally {
|
|
10892
|
+
activation.ledger.completeOperational(toolCallId);
|
|
10452
10893
|
}
|
|
10453
10894
|
}
|
|
10454
10895
|
});
|
|
@@ -10462,7 +10903,7 @@ function createCollectorRoleRuntime(pi, dependencies, hostActions) {
|
|
|
10462
10903
|
`Collector supports only print or json mode (got ${ctx.mode})`
|
|
10463
10904
|
);
|
|
10464
10905
|
}
|
|
10465
|
-
if (event.reason === "
|
|
10906
|
+
if (event.reason === "fork" || event.reason === "reload") {
|
|
10466
10907
|
throw new Error(
|
|
10467
10908
|
`Collector does not support session_start reason ${event.reason}`
|
|
10468
10909
|
);
|
|
@@ -10529,11 +10970,14 @@ function createCollectorRoleRuntime(pi, dependencies, hostActions) {
|
|
|
10529
10970
|
}
|
|
10530
10971
|
const clock = dependencies.createClock?.() ?? createSystemCollectorClock();
|
|
10531
10972
|
const transport = dependencies.createTransport();
|
|
10532
|
-
const ledger =
|
|
10533
|
-
repository,
|
|
10534
|
-
|
|
10535
|
-
|
|
10536
|
-
|
|
10973
|
+
const ledger = dependencies.createLedger(
|
|
10974
|
+
{ repository, prNumber, manifest },
|
|
10975
|
+
clock,
|
|
10976
|
+
ctx
|
|
10977
|
+
);
|
|
10978
|
+
if (ledger.activationRecorded) {
|
|
10979
|
+
firstDispatchDone = true;
|
|
10980
|
+
}
|
|
10537
10981
|
activation = {
|
|
10538
10982
|
soul,
|
|
10539
10983
|
repository,
|
|
@@ -10702,7 +11146,7 @@ function createNotaryRoleRuntime(pi, dependencies, host) {
|
|
|
10702
11146
|
pi.registerTool({
|
|
10703
11147
|
name: NOTARY_OUTPUT_TOOL_NAME,
|
|
10704
11148
|
label: "\u7B26\u5B9D\u90CE\u8F93\u51FA",
|
|
10705
|
-
description: "\u63D0\u4EA4\u5F15\u6587\u4FDD\u771F\u4E0E\u7968\u9762\u5BF9\u9F50\u7684 typed pass/bounce \u51B3\u8BAE\u3002",
|
|
11149
|
+
description: "\u63D0\u4EA4\u5F15\u6587\u4FDD\u771F\u4E0E\u7968\u9762\u5BF9\u9F50\u7684 typed pass/bounce/escalate \u51B3\u8BAE\u3002",
|
|
10706
11150
|
promptSnippet: "\u63D0\u4EA4\u7B26\u5B9D\u90CE\u51B3\u8BAE",
|
|
10707
11151
|
parameters: notaryOutputSchema,
|
|
10708
11152
|
async execute(toolCallId, parameters, _signal, _onUpdate, ctx) {
|
|
@@ -10745,24 +11189,24 @@ function createNotaryRoleRuntime(pi, dependencies, host) {
|
|
|
10745
11189
|
}
|
|
10746
11190
|
|
|
10747
11191
|
// src/countersign-role.ts
|
|
10748
|
-
import { Type as
|
|
11192
|
+
import { Type as Type20 } from "typebox";
|
|
10749
11193
|
var countersignVerdictSchema = withInfrastructureFailureDeclaration(
|
|
10750
|
-
|
|
11194
|
+
Type20.Object(
|
|
10751
11195
|
{
|
|
10752
11196
|
countersignStatus: stringEnum(["converged", "continue", "escalate"], { description: "converged | continue | escalate" }),
|
|
10753
|
-
fix:
|
|
10754
|
-
|
|
10755
|
-
{ summary:
|
|
11197
|
+
fix: Type20.Optional(
|
|
11198
|
+
Type20.Object(
|
|
11199
|
+
{ summary: Type20.String({ minLength: 1, description: "\u9000\u56DE\u6458\u8981" }) },
|
|
10756
11200
|
{ additionalProperties: false, description: "\u9000\u56DE\u8BF4\u660E" }
|
|
10757
11201
|
)
|
|
10758
11202
|
),
|
|
10759
|
-
note:
|
|
10760
|
-
evidence:
|
|
10761
|
-
decisionGate:
|
|
10762
|
-
|
|
11203
|
+
note: Type20.Optional(Type20.String({ minLength: 1, description: "\u9644\u6CE8" })),
|
|
11204
|
+
evidence: Type20.Optional(Type20.Unknown({ description: "\u7559\u5B58\u8BC1\u636E" })),
|
|
11205
|
+
decisionGate: Type20.Optional(
|
|
11206
|
+
Type20.Object(
|
|
10763
11207
|
{
|
|
10764
|
-
question:
|
|
10765
|
-
options:
|
|
11208
|
+
question: Type20.String({ minLength: 1 }),
|
|
11209
|
+
options: Type20.Array(Type20.String({ minLength: 1 }), { minItems: 1 })
|
|
10766
11210
|
},
|
|
10767
11211
|
{ additionalProperties: false, description: "\u9700\u965B\u4E0B\u5904\u7F6E\u7684\u95EE\u9898\u4E0E\u9009\u9879" }
|
|
10768
11212
|
)
|
|
@@ -10781,18 +11225,18 @@ var COUNTERSIGN_TOOL_SPEC = {
|
|
|
10781
11225
|
};
|
|
10782
11226
|
|
|
10783
11227
|
// src/gleaner-left-role.ts
|
|
10784
|
-
import { Type as
|
|
11228
|
+
import { Type as Type21 } from "typebox";
|
|
10785
11229
|
var gleanerLeftOutputSchema = withInfrastructureFailureDeclaration(
|
|
10786
11230
|
openToolObject(
|
|
10787
|
-
|
|
10788
|
-
status:
|
|
11231
|
+
Type21.Object({
|
|
11232
|
+
status: Type21.Unknown({
|
|
10789
11233
|
description: "completed \u2014 \u5F62\u72B6\u6307\u5F15\uFF0C\u975E schema \u95F8"
|
|
10790
11234
|
}),
|
|
10791
|
-
findings:
|
|
10792
|
-
|
|
11235
|
+
findings: Type21.Array(
|
|
11236
|
+
Type21.Object(
|
|
10793
11237
|
{
|
|
10794
|
-
pointer:
|
|
10795
|
-
statement:
|
|
11238
|
+
pointer: Type21.String({ description: "\u6587\u4EF6/\u884C\u6307\u9488" }),
|
|
11239
|
+
statement: Type21.String({ description: "\u7591\u70B9\u9648\u8FF0" })
|
|
10796
11240
|
},
|
|
10797
11241
|
{ additionalProperties: true, description: "\u4E00\u6761\u5F39\u7AE0" }
|
|
10798
11242
|
),
|
|
@@ -10810,208 +11254,30 @@ var GLEANER_LEFT_TOOL_SPEC = {
|
|
|
10810
11254
|
};
|
|
10811
11255
|
|
|
10812
11256
|
// src/inspector-role.ts
|
|
10813
|
-
import { Type as
|
|
11257
|
+
import { Type as Type22 } from "typebox";
|
|
10814
11258
|
var inspectorOutputSchema = withInfrastructureFailureDeclaration(
|
|
10815
11259
|
openToolObject(
|
|
10816
|
-
|
|
10817
|
-
status:
|
|
10818
|
-
description: "pass | bounce \u2014 \u5F62\u72B6\u6307\u5F15\uFF0C\u975E schema \u95F8"
|
|
11260
|
+
Type22.Object({
|
|
11261
|
+
status: Type22.Unknown({
|
|
11262
|
+
description: "pass | bounce | escalate \u2014 \u5F62\u72B6\u6307\u5F15\uFF0C\u975E schema \u95F8"
|
|
10819
11263
|
}),
|
|
10820
|
-
findings:
|
|
11264
|
+
findings: Type22.Unknown({
|
|
10821
11265
|
description: "\u968F\u4EA4\u5377\u7559\u5B58\u7684\u95EE\u9898\u8BB0\u5F55"
|
|
10822
|
-
})
|
|
11266
|
+
}),
|
|
11267
|
+
reason: Type22.Optional(Type22.Unknown({
|
|
11268
|
+
description: "status \u4E3A escalate \u65F6\u7684\u4E0A\u5448\u7406\u7531"
|
|
11269
|
+
}))
|
|
10823
11270
|
})
|
|
10824
11271
|
)
|
|
10825
11272
|
);
|
|
10826
11273
|
var INSPECTOR_TOOL_SPEC = {
|
|
10827
11274
|
name: INSPECTOR_OUTPUT_TOOL_NAME,
|
|
10828
11275
|
label: "\u5BDF\u9662\u8F93\u51FA",
|
|
10829
|
-
description: "\u5BDF\u9662\u7EC8\u5C40\u56DE\u6267\uFF0C\u72B6\u6001\u4E3A pass \u6216
|
|
11276
|
+
description: "\u5BDF\u9662\u7EC8\u5C40\u56DE\u6267\uFF0C\u72B6\u6001\u4E3A pass\u3001bounce \u6216 escalate\u3002",
|
|
10830
11277
|
promptSnippet: "\u5BDF\u9662\u7EC8\u5C40\u56DE\u6267",
|
|
10831
11278
|
parameters: inspectorOutputSchema
|
|
10832
11279
|
};
|
|
10833
11280
|
|
|
10834
|
-
// src/gatekeeper-role.ts
|
|
10835
|
-
import { Type as Type22 } from "typebox";
|
|
10836
|
-
var INSPECTOR_OUTPUT_TOOL = INSPECTOR_OUTPUT_TOOL_NAME;
|
|
10837
|
-
var NOTARY_OUTPUT_TOOL = "ak_notary_output";
|
|
10838
|
-
var SUBJECT_TOOL = "ak_gatekeeper_subject";
|
|
10839
|
-
function gateSeatLabel(stage) {
|
|
10840
|
-
switch (stage) {
|
|
10841
|
-
case "gatekeeper":
|
|
10842
|
-
return "\u95E8\u4E0B\u7701";
|
|
10843
|
-
case "inspector":
|
|
10844
|
-
return "\u5BDF\u9662";
|
|
10845
|
-
case "notary":
|
|
10846
|
-
return "\u7B26\u5B9D\u90CE";
|
|
10847
|
-
}
|
|
10848
|
-
}
|
|
10849
|
-
var officerDecisionSchema = openToolObject(Type22.Object({
|
|
10850
|
-
status: Type22.Unknown({ description: "pass | bounce \u2014 \u5F62\u72B6\u6307\u5F15\uFF0C\u975E schema \u95F8" }),
|
|
10851
|
-
findings: Type22.Unknown({ description: "string[] findings\uFF0C\u968F pass \u6216 bounce \u7559\u5B58" })
|
|
10852
|
-
}));
|
|
10853
|
-
var GATEKEEPER_TOOL_SPEC = {
|
|
10854
|
-
name: GATEKEEPER_OUTPUT_TOOL_NAME,
|
|
10855
|
-
label: "\u95E8\u4E0B\u7701\u51B3\u8BAE",
|
|
10856
|
-
description: "\u95E8\u4E0B\u7701\u7EC8\u5C40\u51B3\u8BAE\uFF0C\u72B6\u6001\u4E3A dispatch \u6216 pass\u3002",
|
|
10857
|
-
promptSnippet: "\u95E8\u4E0B\u7701\u51B3\u8BAE",
|
|
10858
|
-
parameters: gatekeeperOutputSchema
|
|
10859
|
-
};
|
|
10860
|
-
function result(content, details) {
|
|
10861
|
-
return { content: [{ type: "text", text: content }], details };
|
|
10862
|
-
}
|
|
10863
|
-
function subjectTool(subject) {
|
|
10864
|
-
return {
|
|
10865
|
-
name: SUBJECT_TOOL,
|
|
10866
|
-
description: "\u8BFB\u53D6\u5DF2\u53D7\u7406\u5377\u5B97\uFF1B\u53EA\u4F9B\u53D6\u9605\uFF0C\u4E0D\u8BC4\u5224\u4E0D\u6539\u52A8\u3002",
|
|
10867
|
-
parameters: Type22.Object({}, { additionalProperties: false }),
|
|
10868
|
-
async execute() {
|
|
10869
|
-
return result(JSON.stringify(subject), subject);
|
|
10870
|
-
}
|
|
10871
|
-
};
|
|
10872
|
-
}
|
|
10873
|
-
function createOfficerDecisionTool(name) {
|
|
10874
|
-
return {
|
|
10875
|
-
name,
|
|
10876
|
-
description: "\u63D0\u4EA4\u4E00\u4EFD typed pass/bounce \u51B3\u8BAE\u3002",
|
|
10877
|
-
parameters: officerDecisionSchema,
|
|
10878
|
-
async execute(_id, args) {
|
|
10879
|
-
return result(`\u5DF2\u6536 ${String(args?.status)}`, args);
|
|
10880
|
-
}
|
|
10881
|
-
};
|
|
10882
|
-
}
|
|
10883
|
-
function createGatekeeperOutputTool() {
|
|
10884
|
-
return {
|
|
10885
|
-
name: GATEKEEPER_OUTPUT_TOOL_NAME,
|
|
10886
|
-
description: "\u63D0\u4EA4\u95E8\u4E0B\u7701\u6D3E\u5B98\u51B3\u5B9A\u3002",
|
|
10887
|
-
parameters: gatekeeperDecisionSchema,
|
|
10888
|
-
async execute(_id, args) {
|
|
10889
|
-
return result(`\u5DF2\u6536 ${String(args?.status)}`, args);
|
|
10890
|
-
}
|
|
10891
|
-
};
|
|
10892
|
-
}
|
|
10893
|
-
async function defaultLoadSoul(role) {
|
|
10894
|
-
return loadGatekeeperSessionMaterials(role);
|
|
10895
|
-
}
|
|
10896
|
-
function failureReason(error) {
|
|
10897
|
-
if (error instanceof AggregateError) return error.errors.map(failureReason).join("; ");
|
|
10898
|
-
return error instanceof Error ? `${error.name}: ${error.message}` : String(error);
|
|
10899
|
-
}
|
|
10900
|
-
function asStringArray3(value) {
|
|
10901
|
-
if (!Array.isArray(value)) return [];
|
|
10902
|
-
return value.filter((item) => typeof item === "string");
|
|
10903
|
-
}
|
|
10904
|
-
var MISSING_ARGUMENTS_SUBMISSION = Object.freeze({ missing: "arguments" });
|
|
10905
|
-
function isRecord11(value) {
|
|
10906
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
10907
|
-
}
|
|
10908
|
-
function retainedSubmission(decision) {
|
|
10909
|
-
return decision === void 0 || isRecord11(decision) && Object.keys(decision).length === 0 ? MISSING_ARGUMENTS_SUBMISSION : decision;
|
|
10910
|
-
}
|
|
10911
|
-
function noUsableReleaseFailure(stage, decision) {
|
|
10912
|
-
return {
|
|
10913
|
-
status: "transport_failure",
|
|
10914
|
-
stage,
|
|
10915
|
-
reason: stage === "gatekeeper" ? "decision \u65E0\u663E\u5F0F dispatch" : "decision \u65E0\u663E\u5F0F pass/bounce",
|
|
10916
|
-
submission: retainedSubmission(decision)
|
|
10917
|
-
};
|
|
10918
|
-
}
|
|
10919
|
-
function readRecord(value) {
|
|
10920
|
-
if (typeof value !== "object" || value === null || Array.isArray(value)) return void 0;
|
|
10921
|
-
return value;
|
|
10922
|
-
}
|
|
10923
|
-
function projectProvinceDecision(decision) {
|
|
10924
|
-
const projected = projectLawfulGatekeeperOutput(decision);
|
|
10925
|
-
if (projected === void 0) return noUsableReleaseFailure("gatekeeper", decision);
|
|
10926
|
-
if (projected.status === "dispatch") {
|
|
10927
|
-
return { status: "dispatch", officer: projected.officer };
|
|
10928
|
-
}
|
|
10929
|
-
return { status: "pass", findings: projected.findings ?? [] };
|
|
10930
|
-
}
|
|
10931
|
-
function projectOfficerDecision(officer, decision) {
|
|
10932
|
-
const record4 = readRecord(decision);
|
|
10933
|
-
if (record4 === void 0) return noUsableReleaseFailure(officer, decision);
|
|
10934
|
-
if (record4.status === "bounce") {
|
|
10935
|
-
return {
|
|
10936
|
-
status: "bounce",
|
|
10937
|
-
officer,
|
|
10938
|
-
disposition: "rewrite",
|
|
10939
|
-
findings: asStringArray3(record4.findings),
|
|
10940
|
-
submission: retainedSubmission(decision)
|
|
10941
|
-
};
|
|
10942
|
-
}
|
|
10943
|
-
if (record4.status === "pass") {
|
|
10944
|
-
return {
|
|
10945
|
-
status: "pass",
|
|
10946
|
-
officer,
|
|
10947
|
-
findings: asStringArray3(record4.findings)
|
|
10948
|
-
};
|
|
10949
|
-
}
|
|
10950
|
-
return noUsableReleaseFailure(officer, decision);
|
|
10951
|
-
}
|
|
10952
|
-
async function runGatekeeper(options) {
|
|
10953
|
-
const loadSoul = options.loadSoul ?? defaultLoadSoul;
|
|
10954
|
-
let provinceRun;
|
|
10955
|
-
try {
|
|
10956
|
-
provinceRun = await executeAuditorChild({
|
|
10957
|
-
context: options.context,
|
|
10958
|
-
roleLabel: "Gatekeeper",
|
|
10959
|
-
gateSeat: "gatekeeper",
|
|
10960
|
-
systemPrompt: await loadSoul("gatekeeper"),
|
|
10961
|
-
prompt: "\u5377\u5B97\u5DF2\u53D7\u7406\u3002",
|
|
10962
|
-
tool: createGatekeeperOutputTool(),
|
|
10963
|
-
dossierTool: subjectTool(options.subject),
|
|
10964
|
-
...options.signal === void 0 ? {} : { signal: options.signal },
|
|
10965
|
-
...options.runDirectory === void 0 ? {} : { runDirectory: options.runDirectory }
|
|
10966
|
-
});
|
|
10967
|
-
} catch (error) {
|
|
10968
|
-
return { status: "transport_failure", stage: "gatekeeper", reason: failureReason(error) };
|
|
10969
|
-
}
|
|
10970
|
-
if (provinceRun.noReceiptLifecycle !== void 0) {
|
|
10971
|
-
return { status: "no_receipt", stage: "gatekeeper", reason: `${gateSeatLabel("gatekeeper")}\u672A\u4EA7\u751F\u5DF2\u63A5\u53D7\u56DE\u6267\u5373\u6563\u5C40`, facts: provinceRun.noReceiptLifecycle };
|
|
10972
|
-
}
|
|
10973
|
-
const province = projectProvinceDecision(provinceRun.decision);
|
|
10974
|
-
if (province.status !== "dispatch") return province;
|
|
10975
|
-
const officer = province.officer;
|
|
10976
|
-
try {
|
|
10977
|
-
const roleLabel = officer === "inspector" ? "Inspector" : "Notary";
|
|
10978
|
-
const officerRun = await executeAuditorChild({
|
|
10979
|
-
context: options.context,
|
|
10980
|
-
roleLabel,
|
|
10981
|
-
gateSeat: officer,
|
|
10982
|
-
systemPrompt: await loadSoul(officer),
|
|
10983
|
-
prompt: "\u5377\u5B97\u5DF2\u53D7\u7406\u3002",
|
|
10984
|
-
tool: createOfficerDecisionTool(officer === "inspector" ? INSPECTOR_OUTPUT_TOOL : NOTARY_OUTPUT_TOOL),
|
|
10985
|
-
dossierTool: subjectTool(options.subject),
|
|
10986
|
-
...options.signal === void 0 ? {} : { signal: options.signal },
|
|
10987
|
-
...options.runDirectory === void 0 ? {} : { runDirectory: options.runDirectory }
|
|
10988
|
-
});
|
|
10989
|
-
if (officerRun.noReceiptLifecycle !== void 0) {
|
|
10990
|
-
return { status: "no_receipt", stage: officer, reason: `${gateSeatLabel(officer)}\u672A\u4EA7\u751F\u5DF2\u63A5\u53D7\u56DE\u6267\u5373\u6563\u5C40`, facts: officerRun.noReceiptLifecycle };
|
|
10991
|
-
}
|
|
10992
|
-
return projectOfficerDecision(officer, officerRun.decision);
|
|
10993
|
-
} catch (error) {
|
|
10994
|
-
return { status: "transport_failure", stage: officer, reason: failureReason(error) };
|
|
10995
|
-
}
|
|
10996
|
-
}
|
|
10997
|
-
async function requireGatekeeperPass(options) {
|
|
10998
|
-
const gatekeeper = await runGatekeeper({
|
|
10999
|
-
context: options.context,
|
|
11000
|
-
subject: options.subject,
|
|
11001
|
-
...options.signal === void 0 ? {} : { signal: options.signal }
|
|
11002
|
-
});
|
|
11003
|
-
if (gatekeeper.status === "pass") return;
|
|
11004
|
-
if (gatekeeper.status === "transport_failure") {
|
|
11005
|
-
const error = new Error(`\u95E8\u4E0B\u7701 transport_failure\uFF08${gatekeeper.stage}\uFF09\uFF1A${gatekeeper.reason}`);
|
|
11006
|
-
error.stage = gatekeeper.stage;
|
|
11007
|
-
error.reason = gatekeeper.reason;
|
|
11008
|
-
if (gatekeeper.submission !== void 0) error.submission = gatekeeper.submission;
|
|
11009
|
-
options.hostActions.failInfrastructure(error, options.context, options.toolCallId);
|
|
11010
|
-
}
|
|
11011
|
-
options.hostActions.bindSubmissionNonPass(options.toolCallId, gatekeeper);
|
|
11012
|
-
throw new GatekeeperDecisionError(gatekeeper);
|
|
11013
|
-
}
|
|
11014
|
-
|
|
11015
11281
|
// src/navigator-role.ts
|
|
11016
11282
|
var NAVIGATOR_TOOL_SPEC = {
|
|
11017
11283
|
name: NAVIGATOR_OUTPUT_TOOL_NAME,
|
|
@@ -11027,25 +11293,37 @@ init_upstream_error_testimony();
|
|
|
11027
11293
|
|
|
11028
11294
|
// src/public-cli/settlement.ts
|
|
11029
11295
|
var NAVIGATOR_POST_ROLE_GRACE_MS = 1e4;
|
|
11030
|
-
function
|
|
11296
|
+
function defaultNavigatorGraceSleep() {
|
|
11297
|
+
let timer;
|
|
11298
|
+
const sleep = ((ms) => new Promise((resolve17) => {
|
|
11299
|
+
timer = setTimeout(() => {
|
|
11300
|
+
timer = void 0;
|
|
11301
|
+
resolve17();
|
|
11302
|
+
}, ms);
|
|
11303
|
+
}));
|
|
11304
|
+
sleep.cancel = () => {
|
|
11305
|
+
if (timer !== void 0) {
|
|
11306
|
+
clearTimeout(timer);
|
|
11307
|
+
timer = void 0;
|
|
11308
|
+
}
|
|
11309
|
+
};
|
|
11310
|
+
return sleep;
|
|
11311
|
+
}
|
|
11312
|
+
function raceNavigatorGrace(work, graceMs = NAVIGATOR_POST_ROLE_GRACE_MS, sleep = defaultNavigatorGraceSleep()) {
|
|
11031
11313
|
return new Promise((resolve17, reject) => {
|
|
11032
11314
|
let settled = false;
|
|
11315
|
+
const finish = (action) => {
|
|
11316
|
+
if (settled) return;
|
|
11317
|
+
settled = true;
|
|
11318
|
+
sleep.cancel?.();
|
|
11319
|
+
action();
|
|
11320
|
+
};
|
|
11033
11321
|
void work.then(
|
|
11034
|
-
(value) => {
|
|
11035
|
-
|
|
11036
|
-
settled = true;
|
|
11037
|
-
resolve17({ status: "done", value });
|
|
11038
|
-
},
|
|
11039
|
-
(error) => {
|
|
11040
|
-
if (settled) return;
|
|
11041
|
-
settled = true;
|
|
11042
|
-
reject(error);
|
|
11043
|
-
}
|
|
11322
|
+
(value) => finish(() => resolve17({ status: "done", value })),
|
|
11323
|
+
(error) => finish(() => reject(error))
|
|
11044
11324
|
);
|
|
11045
11325
|
void sleep(graceMs).then(() => {
|
|
11046
|
-
|
|
11047
|
-
settled = true;
|
|
11048
|
-
resolve17({ status: "timeout" });
|
|
11326
|
+
finish(() => resolve17({ status: "timeout" }));
|
|
11049
11327
|
});
|
|
11050
11328
|
});
|
|
11051
11329
|
}
|
|
@@ -13148,6 +13426,20 @@ function createRoleRuntimeExtension(dependencies) {
|
|
|
13148
13426
|
}
|
|
13149
13427
|
return dependencies.createCollectorTransport();
|
|
13150
13428
|
},
|
|
13429
|
+
createLedger(config, collectorClock, context) {
|
|
13430
|
+
const append = context.sessionManager?.appendCustomEntry;
|
|
13431
|
+
return createCollectorLedger(config, {
|
|
13432
|
+
clock: collectorClock,
|
|
13433
|
+
...append === void 0 ? {} : {
|
|
13434
|
+
journal: {
|
|
13435
|
+
append(customType, data) {
|
|
13436
|
+
context.sessionManager?.appendCustomEntry?.(customType, data);
|
|
13437
|
+
}
|
|
13438
|
+
}
|
|
13439
|
+
},
|
|
13440
|
+
dossierEntries: context.sessionManager?.getEntries?.() ?? []
|
|
13441
|
+
});
|
|
13442
|
+
},
|
|
13151
13443
|
...dependencies.createCollectorClock === void 0 ? {} : { createClock: dependencies.createCollectorClock },
|
|
13152
13444
|
...dependencies.collectorPackageExtensionPath === void 0 ? {} : {
|
|
13153
13445
|
packageExtensionPath: dependencies.collectorPackageExtensionPath
|
|
@@ -14115,8 +14407,8 @@ async function prepareGrokRoleEnvelope(options) {
|
|
|
14115
14407
|
rejection = value;
|
|
14116
14408
|
},
|
|
14117
14409
|
capabilities: {
|
|
14118
|
-
skillExpansion(
|
|
14119
|
-
return buildGrokSkillExpansion(methodSkills,
|
|
14410
|
+
skillExpansion(prompt) {
|
|
14411
|
+
return buildGrokSkillExpansion(methodSkills, prompt);
|
|
14120
14412
|
}
|
|
14121
14413
|
},
|
|
14122
14414
|
registerFlag(name, definition) {
|
|
@@ -14448,54 +14740,67 @@ async function prepareGrokRoleEnvelope(options) {
|
|
|
14448
14740
|
};
|
|
14449
14741
|
return { accepted: false, failure: failure2 };
|
|
14450
14742
|
};
|
|
14451
|
-
|
|
14452
|
-
|
|
14453
|
-
|
|
14454
|
-
|
|
14455
|
-
|
|
14456
|
-
|
|
14457
|
-
|
|
14458
|
-
|
|
14459
|
-
|
|
14460
|
-
|
|
14461
|
-
|
|
14462
|
-
|
|
14743
|
+
try {
|
|
14744
|
+
await emit("session_start", { reason: request.continuation.kind });
|
|
14745
|
+
const inputResults = await emit("input", { text: request.continuation.prompt, source: "interactive" });
|
|
14746
|
+
let prompt = request.continuation.prompt;
|
|
14747
|
+
for (const value of inputResults) {
|
|
14748
|
+
if (typeof value !== "object" || value === null) continue;
|
|
14749
|
+
const record4 = value;
|
|
14750
|
+
if (record4.action === "transform" && typeof record4.text === "string") prompt = record4.text;
|
|
14751
|
+
}
|
|
14752
|
+
if (typeof prompt === "string" && prompt.trim() !== "") {
|
|
14753
|
+
sessionEntries.push({
|
|
14754
|
+
type: "message",
|
|
14755
|
+
message: { role: "user", content: prompt }
|
|
14756
|
+
});
|
|
14757
|
+
}
|
|
14758
|
+
const basePrompt = await loadMainRoleSessionMaterials(request.activation.role);
|
|
14759
|
+
const methodPrompt = (await Promise.all(request.methods.map(({ path }) => readFile13(path, "utf8")))).join("\n\n");
|
|
14760
|
+
const promptResults = await emit("before_agent_start", {
|
|
14761
|
+
prompt,
|
|
14762
|
+
systemPrompt: [basePrompt, methodPrompt].filter(Boolean).join("\n\n"),
|
|
14763
|
+
systemPromptOptions: {}
|
|
14463
14764
|
});
|
|
14765
|
+
const systemPromptBody = [...promptResults].reverse().find((value) => typeof value === "object" && value !== null && "systemPrompt" in value && typeof value.systemPrompt === "string")?.systemPrompt ?? [basePrompt, methodPrompt].filter(Boolean).join("\n\n");
|
|
14766
|
+
const readingMaterials = [];
|
|
14767
|
+
for (const value of promptResults) {
|
|
14768
|
+
if (typeof value !== "object" || value === null) continue;
|
|
14769
|
+
if (!("readingMaterial" in value)) continue;
|
|
14770
|
+
const material = value.readingMaterial;
|
|
14771
|
+
if (material !== void 0) readingMaterials.push(material);
|
|
14772
|
+
}
|
|
14773
|
+
priorAkRoleRunDir = process.env.AK_ROLE_RUN_DIR;
|
|
14774
|
+
process.env.AK_ROLE_RUN_DIR = request.runDirectory;
|
|
14775
|
+
runDirInjected = true;
|
|
14776
|
+
return {
|
|
14777
|
+
mcpServers: [{
|
|
14778
|
+
name: `ak-${request.activation.role}`,
|
|
14779
|
+
command: process.execPath,
|
|
14780
|
+
args: [relay],
|
|
14781
|
+
env: [
|
|
14782
|
+
{ name: "AK_GROK_MCP_SOCKET", value: options.socketPath },
|
|
14783
|
+
{ name: "AK_GROK_MCP_TOKEN", value: token }
|
|
14784
|
+
]
|
|
14785
|
+
}],
|
|
14786
|
+
systemPrompt: { body: systemPromptBody, materials: readingMaterials },
|
|
14787
|
+
prompt,
|
|
14788
|
+
abortSignal: hostAbort.signal,
|
|
14789
|
+
closeRound,
|
|
14790
|
+
dispose
|
|
14791
|
+
};
|
|
14792
|
+
} catch (error) {
|
|
14793
|
+
try {
|
|
14794
|
+
await dispose();
|
|
14795
|
+
} catch (cleanupFailure) {
|
|
14796
|
+
throw new AggregateError(
|
|
14797
|
+
[error, cleanupFailure],
|
|
14798
|
+
"prepareGrokRoleEnvelope activation failed and its dispose cleanup also failed",
|
|
14799
|
+
{ cause: error }
|
|
14800
|
+
);
|
|
14801
|
+
}
|
|
14802
|
+
throw error;
|
|
14464
14803
|
}
|
|
14465
|
-
const basePrompt = await loadMainRoleSessionMaterials(request.activation.role);
|
|
14466
|
-
const methodPrompt = (await Promise.all(request.methods.map(({ path }) => readFile13(path, "utf8")))).join("\n\n");
|
|
14467
|
-
const promptResults = await emit("before_agent_start", {
|
|
14468
|
-
prompt,
|
|
14469
|
-
systemPrompt: [basePrompt, methodPrompt].filter(Boolean).join("\n\n"),
|
|
14470
|
-
systemPromptOptions: {}
|
|
14471
|
-
});
|
|
14472
|
-
const systemPromptBody = [...promptResults].reverse().find((value) => typeof value === "object" && value !== null && "systemPrompt" in value && typeof value.systemPrompt === "string")?.systemPrompt ?? [basePrompt, methodPrompt].filter(Boolean).join("\n\n");
|
|
14473
|
-
const readingMaterials = [];
|
|
14474
|
-
for (const value of promptResults) {
|
|
14475
|
-
if (typeof value !== "object" || value === null) continue;
|
|
14476
|
-
if (!("readingMaterial" in value)) continue;
|
|
14477
|
-
const material = value.readingMaterial;
|
|
14478
|
-
if (material !== void 0) readingMaterials.push(material);
|
|
14479
|
-
}
|
|
14480
|
-
priorAkRoleRunDir = process.env.AK_ROLE_RUN_DIR;
|
|
14481
|
-
process.env.AK_ROLE_RUN_DIR = request.runDirectory;
|
|
14482
|
-
runDirInjected = true;
|
|
14483
|
-
return {
|
|
14484
|
-
mcpServers: [{
|
|
14485
|
-
name: `ak-${request.activation.role}`,
|
|
14486
|
-
command: process.execPath,
|
|
14487
|
-
args: [relay],
|
|
14488
|
-
env: [
|
|
14489
|
-
{ name: "AK_GROK_MCP_SOCKET", value: options.socketPath },
|
|
14490
|
-
{ name: "AK_GROK_MCP_TOKEN", value: token }
|
|
14491
|
-
]
|
|
14492
|
-
}],
|
|
14493
|
-
systemPrompt: { body: systemPromptBody, materials: readingMaterials },
|
|
14494
|
-
prompt,
|
|
14495
|
-
abortSignal: hostAbort.signal,
|
|
14496
|
-
closeRound,
|
|
14497
|
-
dispose
|
|
14498
|
-
};
|
|
14499
14804
|
}
|
|
14500
14805
|
|
|
14501
14806
|
// src/grok/session-identity.ts
|