@akagilnc/pi-workflow-roles 0.1.3932 → 0.1.3975
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/CLAUDE.md +1 -1
- package/dist/acp-host/production-host.js +2389 -6018
- package/dist/analyst-gate-cycles-read.js +15 -19
- package/dist/audit-escalation.js +16 -46
- package/dist/auditor-dossier-tool.js +7 -62
- package/dist/collector-identity.js +0 -157
- package/dist/collector-ledger.js +2 -42
- package/dist/compliance-transport.js +40 -14
- package/dist/diarist-contracts.js +2 -40
- package/dist/doctor-contracts.js +39 -108
- package/dist/doctor-evidence.js +1 -5
- package/dist/engine-detour-tool.js +1 -1
- package/dist/gatekeeper-role.js +49 -38
- package/dist/headless-host/production-host.js +4814 -8450
- package/dist/host-contracts.js +0 -5
- package/dist/merger-contracts.js +4 -6
- package/dist/navigator-attendance.js +30 -52
- package/dist/navigator-invocation-identity.js +0 -1
- package/dist/navigator-public-session.js +2 -1
- package/dist/notary-contracts.js +4 -10
- package/dist/package-contracts/auditor-output.js +5 -23
- package/dist/package-contracts/fixer-output.js +25 -49
- package/dist/package-contracts/gatekeeper-output.js +3 -13
- package/dist/package-contracts/navigator-output.js +4 -7
- package/dist/package-contracts/reviewer-output.js +1 -95
- package/dist/package-contracts/terminating-tools.js +33 -144
- package/dist/package-contracts/worker-output.js +1 -3
- package/dist/public-cli/auto-resume.js +30 -68
- package/dist/public-cli/case-dossier-delivery.js +5 -17
- package/dist/public-cli/diarist-run.js +9 -4
- package/dist/public-cli/inspector-run.js +2 -8
- package/dist/public-cli/instruction-seat-run.js +3 -7
- package/dist/public-cli/invocation.js +5 -2
- package/dist/public-cli/main.js +6068 -6964
- package/dist/public-cli/notary-run.js +1 -8
- package/dist/public-cli/post-admission.js +314 -113
- package/dist/public-cli/run-lifecycle.js +14 -38
- package/dist/public-cli/settlement.js +209 -390
- package/dist/public-cli/terminal.js +51 -45
- package/dist/public-role-summons.js +1 -12
- package/dist/reviewer-dispatch.js +12 -258
- package/dist/submission-correctable-error.js +0 -12
- package/dist/submission-errors.js +6 -1
- package/dist/submission-ledger.js +125 -168
- package/dist/ticket-provenance-contracts.js +2 -49
- package/dist/ticket-provenance.js +82 -31
- package/extensions/role-runtime.ts +1 -6
- package/package.json +1 -1
- package/resources/836-deleted-machine-instruction-inventory.md +18 -0
- package/src/acp-host/role-turn-host.ts +8 -3
- package/src/analyst-gate-cycles-read.ts +17 -29
- package/src/audit-escalation.ts +20 -50
- package/src/auditor-dossier-tool.ts +5 -103
- package/src/canonical-skill-binding.ts +3 -2
- package/src/collector-identity.ts +0 -179
- package/src/collector-ledger.ts +3 -46
- package/src/collector-role.ts +32 -61
- package/src/collector-tool-schemas.ts +20 -14
- package/src/compliance-transport.ts +55 -17
- package/src/countersign-role.ts +17 -8
- package/src/diarist-contracts.ts +3 -36
- package/src/diarist-role.ts +13 -7
- package/src/diarist.ts +4 -16
- package/src/doctor-contracts.ts +73 -94
- package/src/doctor-evidence.ts +1 -1
- package/src/doctor-role.ts +3 -3
- package/src/engine-detour-tool.ts +4 -1
- package/src/external-host-turn-loop.ts +9 -3
- package/src/gatekeeper-pass-envelope.ts +7 -12
- package/src/gatekeeper-role.ts +56 -50
- package/src/gleaner-left-role.ts +4 -2
- package/src/headless-host/role-turn-host.ts +4 -5
- package/src/host-contracts.ts +3 -8
- package/src/judge-role.ts +19 -13
- package/src/merger-contracts.ts +10 -6
- package/src/merger-role.ts +1 -5
- package/src/navigator-attendance.ts +37 -74
- package/src/navigator-invocation-identity.ts +0 -6
- package/src/navigator-public-session.ts +2 -1
- package/src/notary-contracts.ts +7 -10
- package/src/package-contracts/auditor-output.ts +4 -21
- package/src/package-contracts/fixer-output.ts +34 -52
- package/src/package-contracts/gatekeeper-output.ts +5 -22
- package/src/package-contracts/navigator-output.ts +7 -7
- package/src/package-contracts/reviewer-output.ts +2 -150
- package/src/package-contracts/terminating-tools.ts +32 -147
- package/src/package-contracts/worker-output.ts +0 -1
- package/src/pi/adapter.ts +3 -8
- package/src/public-cli/auto-resume.ts +41 -94
- package/src/public-cli/case-dossier-delivery.ts +5 -15
- package/src/public-cli/countersign-run.ts +14 -6
- package/src/public-cli/diarist-run.ts +11 -9
- package/src/public-cli/inspector-run.ts +2 -18
- package/src/public-cli/instruction-seat-run.ts +3 -17
- package/src/public-cli/invocation.ts +5 -2
- package/src/public-cli/merger-run.ts +1 -1
- package/src/public-cli/notary-run.ts +1 -18
- package/src/public-cli/post-admission.ts +385 -115
- package/src/public-cli/run-lifecycle.ts +13 -44
- package/src/public-cli/settlement.ts +314 -562
- package/src/public-cli/terminal.ts +66 -72
- package/src/public-role-summons.ts +5 -30
- package/src/reviewer-dispatch.ts +29 -331
- package/src/reviewer-role.ts +16 -83
- package/src/role-envelope.ts +16 -24
- package/src/role-runtime-dependencies.ts +1 -6
- package/src/role-runtime.ts +65 -201
- package/src/submission-correctable-error.ts +0 -14
- package/src/submission-errors.ts +6 -1
- package/src/submission-ledger.ts +187 -187
- package/src/ticket-provenance-contracts.ts +4 -60
- package/src/ticket-provenance.ts +98 -32
- package/src/worker-role.ts +35 -36
- package/dist/activation-ledger-session.js +0 -105
- package/dist/activation-ledger.js +0 -139
- package/dist/activation-trace.js +0 -33
- package/dist/atomic-write.js +0 -23
- package/dist/auditor-role.js +0 -12
- package/dist/canonical-skill-binding.js +0 -61
- package/dist/collector-handbook.js +0 -142
- package/dist/collector-receipt.js +0 -107
- package/dist/collector-role.js +0 -566
- package/dist/collector-tool-schemas.js +0 -107
- package/dist/countersign-role.js +0 -28
- package/dist/diarist-role.js +0 -44
- package/dist/diarist.js +0 -66
- package/dist/doctor-role.js +0 -75
- package/dist/fixer-bash-seatbelt.js +0 -13
- package/dist/gatekeeper-pass-envelope.js +0 -77
- package/dist/gleaner-left-role.js +0 -26
- package/dist/inspector-role.js +0 -29
- package/dist/judge-role.js +0 -104
- package/dist/merger-role.js +0 -55
- package/dist/navigator-role.js +0 -12
- package/dist/notary-role.js +0 -134
- package/dist/oauth-keepalive.js +0 -158
- package/dist/pi/adapter.js +0 -223
- package/dist/reviewer-agent.js +0 -122
- package/dist/reviewer-child-executor.js +0 -194
- package/dist/reviewer-construction.js +0 -103
- package/dist/reviewer-execution-ledger.js +0 -166
- package/dist/reviewer-failure-diagnostic.js +0 -17
- package/dist/reviewer-role.js +0 -159
- package/dist/reviewer-scope-prompt.js +0 -21
- package/dist/reviewer-settlement.js +0 -66
- package/dist/reviewer-workspace.js +0 -132
- package/dist/role-runtime.js +0 -1604
- package/dist/stderr-jsonl.js +0 -26
- package/dist/tool-execution-observation.js +0 -141
- package/dist/worker-role.js +0 -345
- package/dist/worker-submission-gates.js +0 -305
- package/src/collector-receipt.ts +0 -140
- package/src/diagnostic-tail.ts +0 -18
- package/src/reviewer-agent.ts +0 -135
- package/src/reviewer-child-executor.ts +0 -252
- package/src/reviewer-construction.ts +0 -195
- package/src/reviewer-execution-ledger.ts +0 -212
- package/src/reviewer-failure-diagnostic.ts +0 -18
- package/src/reviewer-scope-prompt.ts +0 -24
- package/src/reviewer-settlement.ts +0 -74
- package/src/reviewer-workspace.ts +0 -105
- package/src/shape-unreadable-failure.ts +0 -49
package/dist/doctor-contracts.js
CHANGED
|
@@ -6,64 +6,45 @@ const DOCTOR_EVIDENCE_TOOL_NAME = "ak_doctor_evidence";
|
|
|
6
6
|
const DOCTOR_OUTPUT_TOOL_NAME = "ak_doctor_output";
|
|
7
7
|
const DOCTOR_ACCEPTED_TEXT = "\u592A\u533B\u7F72\u56DE\u6267\u5DF2\u63A5\u53D7";
|
|
8
8
|
const DOCTOR_ACCEPTED_AUDIT_NO_RECEIPT_TEXT = "\u592A\u533B\u7F72\u56DE\u6267\u5DF2\u63A5\u53D7\uFF1B\u5BA1\u8BA1\u65E0\u56DE\u6267";
|
|
9
|
-
const DOCTOR_OUTPUT_TOOL_DESCRIPTION = "\u63D0\u4EA4\u552F\u4E00\u7EC8\u5C40\u5355\u6848\u8BC1\u8BCD\uFF1Bcompleted \u5141\u8BB8\u7A7A findings\
|
|
9
|
+
const DOCTOR_OUTPUT_TOOL_DESCRIPTION = "\u63D0\u4EA4\u552F\u4E00\u7EC8\u5C40\u5355\u6848\u8BC1\u8BCD\uFF1Bcompleted \u5141\u8BB8\u7A7A findings\u3002";
|
|
10
10
|
const DOCTOR_TARGET_KINDS = ["law", "gate", "template", "station", "seat"];
|
|
11
|
-
const nonblank = Type.String(
|
|
12
|
-
const
|
|
13
|
-
const
|
|
14
|
-
const guardrail = Type.Object({ answer: Type.Boolean(), evidenceIds, explanation: nonblank }, { additionalProperties: false });
|
|
11
|
+
const nonblank = Type.Optional(Type.String());
|
|
12
|
+
const evidenceIds = Type.Optional(Type.Array(Type.String()));
|
|
13
|
+
const guardrail = Type.Object({ answer: Type.Optional(Type.Boolean()), evidenceIds, explanation: nonblank }, { additionalProperties: true });
|
|
15
14
|
const lastRealBite = Type.Union([
|
|
16
|
-
Type.Object({ kind: Type.Literal("actual"), targetKey: nonblank, evidenceId: nonblank }, { additionalProperties:
|
|
17
|
-
Type.Object({ kind: Type.Literal("noRealBite"), targetKey: nonblank, eligibleEvidenceIds: evidenceIds }, { additionalProperties:
|
|
15
|
+
Type.Object({ kind: Type.Optional(Type.Literal("actual")), targetKey: nonblank, evidenceId: nonblank }, { additionalProperties: true }),
|
|
16
|
+
Type.Object({ kind: Type.Optional(Type.Literal("noRealBite")), targetKey: nonblank, eligibleEvidenceIds: evidenceIds }, { additionalProperties: true })
|
|
18
17
|
]);
|
|
19
18
|
const assetKinds = DOCTOR_TARGET_KINDS;
|
|
20
19
|
const findingBody = {
|
|
21
20
|
evidenceIds,
|
|
22
|
-
disposition: Type.Union([Type.Literal("keep"), Type.Literal("thin"), Type.Literal("delete")]),
|
|
23
|
-
guardrails: Type.Object({ reproducibleFailure: guardrail, owningSeamOrInvariant: guardrail, deletionOrSimplificationSuffices: guardrail }, { additionalProperties: true }),
|
|
24
|
-
prescription: Type.Object({ kind: Type.Union([Type.Literal("retain"), Type.Literal("delete"), Type.Literal("simplify"), Type.Literal("patch"), Type.Literal("addMechanism")]), recommendation: nonblank, necessityExplanation:
|
|
25
|
-
lastRealBite
|
|
21
|
+
disposition: Type.Optional(Type.Union([Type.Literal("keep"), Type.Literal("thin"), Type.Literal("delete")])),
|
|
22
|
+
guardrails: Type.Optional(Type.Object({ reproducibleFailure: guardrail, owningSeamOrInvariant: guardrail, deletionOrSimplificationSuffices: guardrail }, { additionalProperties: true })),
|
|
23
|
+
prescription: Type.Optional(Type.Object({ kind: Type.Optional(Type.Union([Type.Literal("retain"), Type.Literal("delete"), Type.Literal("simplify"), Type.Literal("patch"), Type.Literal("addMechanism")])), recommendation: nonblank, necessityExplanation: nonblank }, { additionalProperties: true })),
|
|
24
|
+
lastRealBite: Type.Optional(lastRealBite)
|
|
26
25
|
};
|
|
27
26
|
const finding = Type.Union([
|
|
28
|
-
Type.Object({ targetKey: nonblank, observation: nonblank, evidenceIds }, { additionalProperties:
|
|
29
|
-
Type.Object({ targetKey: nonblank, targetKind: Type.Union(assetKinds.map((kind) => Type.Literal(kind))), assetEvidence: Type.Object({ targetKey: nonblank, targetKind: Type.Union(assetKinds.map((kind) => Type.Literal(kind))), evidenceId: nonblank }, { additionalProperties:
|
|
27
|
+
Type.Object({ targetKey: nonblank, observation: nonblank, evidenceIds }, { additionalProperties: true }),
|
|
28
|
+
Type.Object({ targetKey: nonblank, targetKind: Type.Optional(Type.Union(assetKinds.map((kind) => Type.Literal(kind)))), assetEvidence: Type.Optional(Type.Object({ targetKey: nonblank, targetKind: Type.Optional(Type.Union(assetKinds.map((kind) => Type.Literal(kind)))), evidenceId: nonblank }, { additionalProperties: true })), ...findingBody }, { additionalProperties: true })
|
|
30
29
|
]);
|
|
31
|
-
const caseIdentity = Type.Object({ issueNumber: Type.Integer(
|
|
32
|
-
const
|
|
33
|
-
invocations: count,
|
|
34
|
-
legs: count,
|
|
35
|
-
modelApiTurns: count,
|
|
36
|
-
outputTokens: count,
|
|
37
|
-
toolCalls: count,
|
|
38
|
-
retries: Type.Object({ count: Type.Integer({ minimum: 0 }), sources: Type.Array(nonblank), evidence: Type.Literal("literal run-dir naming") }, { additionalProperties: false }),
|
|
39
|
-
statuses: Type.Array(Type.Object({ source: nonblank, status: nonblank }, { additionalProperties: false })),
|
|
40
|
-
commits: Type.Array(Type.Object({ source: nonblank, commit: nonblank }, { additionalProperties: false })),
|
|
41
|
-
sessions: Type.Array(Type.Union([
|
|
42
|
-
Type.Object({ source: nonblank, startedAt: nonblank, endedAt: nonblank, wallMilliseconds: Type.Number({ minimum: 0 }), completion: Type.Literal("accepted") }, { additionalProperties: false }),
|
|
43
|
-
Type.Object({ source: nonblank, startedAt: Type.Optional(nonblank), endedAt: Type.Optional(nonblank), wallMilliseconds: Type.Optional(Type.Number({ minimum: 0 })), completion: Type.Literal("incomplete"), degradationReason: Type.Optional(nonblank) }, { additionalProperties: false })
|
|
44
|
-
])),
|
|
45
|
-
outputBytes: Type.Object({ count: Type.Integer({ minimum: 0 }), sources: Type.Array(nonblank), payload: Type.Literal("raw JSONL bytes"), providerWireBytes: Type.Literal("unavailable") }, { additionalProperties: false })
|
|
46
|
-
}, { additionalProperties: false });
|
|
30
|
+
const caseIdentity = Type.Object({ issueNumber: Type.Optional(Type.Integer()), runsPath: nonblank }, { additionalProperties: true });
|
|
31
|
+
const DOCTOR_STATUS_DESCRIPTION = "completed | refused \u2014 \u5F62\u72B6\u6307\u5F15\uFF0C\u975E schema \u95F8\uFF1Bcompleted \u5141\u8BB8\u7A7A findings\uFF1Brefused \u4EC5\u5F53\u8BC1\u636E\u4E0D\u8DB3\u4EE5\u652F\u6491\u5982\u5B9E\u6848\u8BC1\u8BCD";
|
|
47
32
|
const doctorSubmissionVariants = Type.Union([
|
|
48
33
|
Type.Object({
|
|
49
|
-
status: Type.
|
|
34
|
+
status: Type.Unknown({ description: DOCTOR_STATUS_DESCRIPTION }),
|
|
50
35
|
case: Type.Unsafe({ ...caseIdentity, description: "\u7559\u5B58\u592A\u533B\u7F72\u6848\u8EAB\u4EFD" }),
|
|
51
36
|
findings: Type.Array(finding, { description: "\u53EF\u7A7A\u6216\u4EC5\u542B\u975E\u5904\u65B9\u6848\u89C2\u5BDF\uFF1B\u7F3A\u53EF\u590D\u7528\u8D44\u4EA7\u6216 bounded-bite \u8BC1\u636E\u53EA\u6392\u9664\u5BF9\u5E94\u8D44\u4EA7\u5904\u65B9" })
|
|
52
37
|
}, { additionalProperties: false, description: "\u5355\u6848\u8BC1\u8BCD\uFF0C\u4E0D\u8981\u6C42\u4EFB\u4F55\u5904\u65B9\u6216\u53EF\u590D\u7528 finding" }),
|
|
53
38
|
Type.Object({
|
|
54
|
-
status: Type.
|
|
55
|
-
reason: Type.String({
|
|
56
|
-
missingEvidence: Type.Array(Type.Object({ need: nonblank, targetKeys:
|
|
39
|
+
status: Type.Unknown({ description: DOCTOR_STATUS_DESCRIPTION }),
|
|
40
|
+
reason: Type.String({ description: "\u8BC1\u636E\u4E0D\u8DB3\u4EE5\u652F\u6491\u5982\u5B9E\u8BC1\u8BCD\u7684\u539F\u56E0" }),
|
|
41
|
+
missingEvidence: Type.Array(Type.Object({ need: nonblank, targetKeys: evidenceIds }, { additionalProperties: true }), { description: "\u5982\u5B9E\u8BC1\u8BCD\u6240\u9700\u800C\u5C1A\u7F3A\u7684\u8BC1\u636E" })
|
|
57
42
|
}, { additionalProperties: false, description: "\u8BC1\u636E\u4E0D\u8DB3\u4EE5\u652F\u6491\u5982\u5B9E\u6848\u8BC1\u8BCD" })
|
|
58
43
|
]);
|
|
59
44
|
const doctorSubmissionSchema = withInfrastructureFailureDeclaration(
|
|
60
45
|
openToolObjectFromUnion(doctorSubmissionVariants)
|
|
61
46
|
);
|
|
62
|
-
const
|
|
63
|
-
Type.Object({ status: Type.Literal("completed"), case: caseIdentity, findings: Type.Array(finding), cost }, { additionalProperties: false }),
|
|
64
|
-
doctorSubmissionVariants.anyOf[1]
|
|
65
|
-
]);
|
|
66
|
-
const doctorEvidenceReadSchema = Type.Object({ evidenceId: Type.String({ minLength: 1, description: "\u5F85\u8BFB\u7559\u5B58\u8BC1\u636E\u6807\u8BC6" }), offset: Type.Optional(Type.Integer({ minimum: 0, description: "\u8D77\u59CB\u5B57\u8282\u504F\u79FB\uFF08\u4ECE 0 \u8BA1\uFF09" })), limit: Type.Optional(Type.Integer({ minimum: 1, maximum: 4096, description: "\u8FD4\u56DE\u5B57\u8282\u4E0A\u9650" })) }, { additionalProperties: false });
|
|
47
|
+
const doctorEvidenceReadSchema = Type.Object({ evidenceId: Type.String({ minLength: 1, description: "\u5F85\u8BFB\u7559\u5B58\u8BC1\u636E\u6807\u8BC6" }), offset: Type.Optional(Type.Integer({ minimum: 0, description: "\u8D77\u59CB\u5B57\u8282\u504F\u79FB\uFF08\u4ECE 0 \u8BA1\uFF09" })), limit: Type.Optional(Type.Integer({ minimum: 1, description: "\u8FD4\u56DE\u5B57\u8282\u6570\uFF08\u65E0\u4E0A\u9650\uFF09" })) }, { additionalProperties: true });
|
|
67
48
|
class DoctorSubmissionContractError extends Error {
|
|
68
49
|
name = "DoctorSubmissionContractError";
|
|
69
50
|
}
|
|
@@ -79,15 +60,10 @@ function read(value, key) {
|
|
|
79
60
|
}
|
|
80
61
|
}
|
|
81
62
|
function validateDoctorSubmissionShape(value) {
|
|
82
|
-
const status = read(value, "status");
|
|
83
|
-
if (status !== "completed" && status !== "refused") throw new DoctorSubmissionContractError("\u592A\u533B\u7F72\u4EA4\u5377\u65E0\u5DF2\u8BC6\u522B\u7684\u6267\u884C\u72B6\u6001");
|
|
84
63
|
return value;
|
|
85
64
|
}
|
|
86
65
|
function validateRecordedDoctorOutput(value) {
|
|
87
|
-
|
|
88
|
-
const status = read(output, "status");
|
|
89
|
-
if (status === "completed" && read(output, "cost") === void 0) throw new DoctorSubmissionContractError("completed \u592A\u533B\u7F72\u56DE\u6267\u7F3A\u5C11 runtime \u6301\u6709\u7684 cost \u8BC1\u8BCD");
|
|
90
|
-
return output;
|
|
66
|
+
return value;
|
|
91
67
|
}
|
|
92
68
|
class DoctorEvidenceStore {
|
|
93
69
|
constructor(patient) {
|
|
@@ -97,12 +73,16 @@ class DoctorEvidenceStore {
|
|
|
97
73
|
patient;
|
|
98
74
|
entries;
|
|
99
75
|
coverage = /* @__PURE__ */ new Map();
|
|
100
|
-
|
|
76
|
+
// #836 A6.5: no 4096 hard cap — limit only bounds the requested window when provided.
|
|
77
|
+
read(evidenceId, offset = 0, limit) {
|
|
101
78
|
const entry = this.entries.get(evidenceId);
|
|
102
79
|
if (!entry) throw new Error(`\u8BC1\u636E ID \u672A\u51C6\u5165\uFF1A${evidenceId}`);
|
|
103
|
-
if (!Number.isInteger(offset) || offset < 0
|
|
80
|
+
if (!Number.isInteger(offset) || offset < 0) throw new Error("\u8BC1\u636E\u5206\u9875\u53C2\u6570\u65E0\u6548");
|
|
104
81
|
if (offset > entry.contentLength) throw new Error("\u8BC1\u636E offset \u8D85\u51FA\u5185\u5BB9");
|
|
105
|
-
const
|
|
82
|
+
const window = limit === void 0 ? entry.contentLength - offset : !Number.isInteger(limit) || limit < 1 ? (() => {
|
|
83
|
+
throw new Error("\u8BC1\u636E\u5206\u9875\u53C2\u6570\u65E0\u6548");
|
|
84
|
+
})() : limit;
|
|
85
|
+
const end = Math.min(entry.contentLength, offset + window);
|
|
106
86
|
const ranges = [...this.coverage.get(evidenceId) ?? [], [offset, end]].sort((a, b) => a[0] - b[0]);
|
|
107
87
|
const merged = [];
|
|
108
88
|
for (const range of ranges) {
|
|
@@ -111,7 +91,16 @@ class DoctorEvidenceStore {
|
|
|
111
91
|
else merged.push([...range]);
|
|
112
92
|
}
|
|
113
93
|
this.coverage.set(evidenceId, merged);
|
|
114
|
-
return {
|
|
94
|
+
return {
|
|
95
|
+
evidenceId,
|
|
96
|
+
kind: entry.kind,
|
|
97
|
+
offset,
|
|
98
|
+
content: entry.content.slice(offset, end),
|
|
99
|
+
nextOffset: end < entry.contentLength ? end : null,
|
|
100
|
+
contentLength: entry.contentLength,
|
|
101
|
+
byteLength: entry.byteLength,
|
|
102
|
+
sha256: entry.sha256
|
|
103
|
+
};
|
|
115
104
|
}
|
|
116
105
|
hasRead(id) {
|
|
117
106
|
const entry = this.entries.get(id);
|
|
@@ -122,65 +111,8 @@ class DoctorEvidenceStore {
|
|
|
122
111
|
return [...this.coverage.keys()].sort().map((evidenceId) => ({ evidenceId, fullyRead: this.hasRead(evidenceId) }));
|
|
123
112
|
}
|
|
124
113
|
}
|
|
125
|
-
function validateDoctorOutput(value,
|
|
126
|
-
|
|
127
|
-
const lawfulTargets = /* @__PURE__ */ new Set(["case", ...patient.cost.invocations.sources]);
|
|
128
|
-
const assertTarget = (targetKey) => {
|
|
129
|
-
if (typeof targetKey === "string" && !lawfulTargets.has(targetKey)) throw new DoctorSubmissionContractError(`targetKey \u4E0D\u662F\u5408\u6CD5\u6848\u76EE\u6807\uFF1A${targetKey}`);
|
|
130
|
-
};
|
|
131
|
-
const readCitations = (ids, label) => {
|
|
132
|
-
if (!Array.isArray(ids)) return;
|
|
133
|
-
for (const id of ids) if (typeof id === "string" && (!store.entries.has(id) || !store.hasRead(id))) throw new DoctorSubmissionContractError(`${label} \u987B\u5F15\u7528\u5DF2\u51C6\u5165/\u5DF2\u8BFB\u8BC1\u636E\uFF1A${id}`);
|
|
134
|
-
};
|
|
135
|
-
if (read(output, "status") === "refused") {
|
|
136
|
-
const missingEvidence = read(output, "missingEvidence");
|
|
137
|
-
if (Array.isArray(missingEvidence)) for (const missing of missingEvidence) {
|
|
138
|
-
const targets = read(missing, "targetKeys");
|
|
139
|
-
if (Array.isArray(targets)) for (const target of targets) assertTarget(target);
|
|
140
|
-
}
|
|
141
|
-
return output;
|
|
142
|
-
}
|
|
143
|
-
const identity = read(output, "case");
|
|
144
|
-
const issueNumber = read(identity, "issueNumber");
|
|
145
|
-
const runsPath = read(identity, "runsPath");
|
|
146
|
-
if (issueNumber !== void 0 && issueNumber !== patient.identity.issueNumber || runsPath !== void 0 && runsPath !== patient.identity.runsPath) throw new DoctorSubmissionContractError("\u592A\u533B\u7F72\u4EA4\u5377 case \u987B\u7B49\u4E8E\u5DF2\u6FC0\u6D3B\u6848\u8EAB\u4EFD");
|
|
147
|
-
const findings = read(output, "findings");
|
|
148
|
-
if (!Array.isArray(findings)) return output;
|
|
149
|
-
for (const finding2 of findings) {
|
|
150
|
-
const targetKey = read(finding2, "targetKey");
|
|
151
|
-
readCitations(read(finding2, "evidenceIds"), "finding");
|
|
152
|
-
const assetEvidence = read(finding2, "assetEvidence");
|
|
153
|
-
if (!isRecord(assetEvidence)) {
|
|
154
|
-
assertTarget(targetKey);
|
|
155
|
-
continue;
|
|
156
|
-
}
|
|
157
|
-
const assetTargetKey = read(assetEvidence, "targetKey");
|
|
158
|
-
const assetTargetKind = read(assetEvidence, "targetKind");
|
|
159
|
-
const assetEvidenceId = read(assetEvidence, "evidenceId");
|
|
160
|
-
if (typeof assetTargetKey === "string" && assetTargetKey !== targetKey) throw new DoctorSubmissionContractError("\u7C7B\u578B\u5316\u8D44\u4EA7\u8BC1\u636E\u987B\u786E\u7ACB finding \u7684 targetKey");
|
|
161
|
-
if (typeof assetTargetKind === "string" && assetTargetKind !== read(finding2, "targetKind")) throw new DoctorSubmissionContractError("\u7C7B\u578B\u5316\u8D44\u4EA7\u8BC1\u636E\u987B\u786E\u7ACB finding \u7684 targetKind");
|
|
162
|
-
if (typeof assetEvidenceId === "string") readCitations([assetEvidenceId], "asset evidence");
|
|
163
|
-
const guardrails = read(finding2, "guardrails");
|
|
164
|
-
for (const key of ["reproducibleFailure", "owningSeamOrInvariant", "deletionOrSimplificationSuffices"]) readCitations(read(read(guardrails, key), "evidenceIds"), "guardrail");
|
|
165
|
-
const bite = read(finding2, "lastRealBite");
|
|
166
|
-
const biteKind = read(bite, "kind");
|
|
167
|
-
if (biteKind !== "actual" && biteKind !== "noRealBite") continue;
|
|
168
|
-
if (read(bite, "targetKey") !== targetKey) throw new DoctorSubmissionContractError("lastRealBite \u76EE\u6807\u4E0D\u5339\u914D");
|
|
169
|
-
if (biteKind === "actual") {
|
|
170
|
-
const evidenceId = read(bite, "evidenceId");
|
|
171
|
-
const entry = typeof evidenceId === "string" ? store.entries.get(evidenceId) : void 0;
|
|
172
|
-
if (!entry || entry.kind !== "session" || !store.hasRead(entry.id)) throw new DoctorSubmissionContractError("actual bite \u987B\u5F15\u7528\u5DF2\u51C6\u5165/\u5DF2\u8BFB\u7684\u7559\u5B58 session");
|
|
173
|
-
} else {
|
|
174
|
-
const eligible = patient.evidence.map((entry) => entry.id).sort();
|
|
175
|
-
const ids = read(bite, "eligibleEvidenceIds");
|
|
176
|
-
if (Array.isArray(ids)) {
|
|
177
|
-
const claimed = ids.filter((id) => typeof id === "string").sort();
|
|
178
|
-
if (canonicalJson(claimed) !== canonicalJson(eligible)) throw new DoctorSubmissionContractError("noRealBite \u987B\u8BC1\u660E\u5B8C\u6574\u7684\u5355\u6848\u5408\u683C\u8BC1\u636E\u5168\u96C6");
|
|
179
|
-
readCitations(eligible, "noRealBite");
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
return output;
|
|
114
|
+
function validateDoctorOutput(value, _patient, _store) {
|
|
115
|
+
return validateDoctorSubmissionShape(value);
|
|
184
116
|
}
|
|
185
117
|
export {
|
|
186
118
|
DOCTOR_ACCEPTED_AUDIT_NO_RECEIPT_TEXT,
|
|
@@ -192,7 +124,6 @@ export {
|
|
|
192
124
|
DoctorEvidenceStore,
|
|
193
125
|
DoctorSubmissionContractError,
|
|
194
126
|
doctorEvidenceReadSchema,
|
|
195
|
-
doctorOutputSchema,
|
|
196
127
|
doctorSubmissionSchema,
|
|
197
128
|
validateDoctorOutput,
|
|
198
129
|
validateDoctorSubmissionShape,
|
package/dist/doctor-evidence.js
CHANGED
|
@@ -86,14 +86,10 @@ function deriveSession(content, id) {
|
|
|
86
86
|
if (facts.commit && facts.commit !== observedCommit) {
|
|
87
87
|
commits.push({ source: id, commit: facts.commit });
|
|
88
88
|
observedCommit = facts.commit;
|
|
89
|
-
}
|
|
90
|
-
statuses.length = 0;
|
|
89
|
+
} /* #836 B10.3: do not wipe earlier statuses or invent a code status sentence */
|
|
91
90
|
if (facts.status !== undefined) {
|
|
92
91
|
statuses.push({ source: id, status: facts.status });
|
|
93
92
|
}
|
|
94
|
-
else {
|
|
95
|
-
statuses.push({ source: id, status: "terminating receipt has no receipt-level status" });
|
|
96
|
-
}
|
|
97
93
|
}
|
|
98
94
|
}
|
|
99
95
|
const acceptedAt = accepted && timestamp(accepted);
|
|
@@ -13,7 +13,7 @@ const engineDetourArgsSchema = Type.Object(
|
|
|
13
13
|
description: "\u9996\u9879\u4E3A PATH \u4E2D\u7684\u53EF\u6267\u884C\u6587\u4EF6\uFF0C\u5176\u4F59\u9879\u4E3A\u53C2\u6570\u3002"
|
|
14
14
|
})
|
|
15
15
|
},
|
|
16
|
-
{ additionalProperties:
|
|
16
|
+
{ additionalProperties: true }
|
|
17
17
|
);
|
|
18
18
|
function isCallerCancellation(error, signal) {
|
|
19
19
|
if (signal?.aborted === true) return true;
|
package/dist/gatekeeper-role.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { auditorRunDirectory
|
|
1
|
+
import { auditorRunDirectory } from "./auditor-dossier-tool.js";
|
|
2
2
|
import { GatekeeperDecisionError } from "./submission-errors.js";
|
|
3
3
|
import { INSPECTOR_OUTPUT_TOOL_NAME } from "./inspector-contracts.js";
|
|
4
4
|
import { GATEKEEPER_OUTPUT_TOOL_NAME, gatekeeperDecisionSchema, gatekeeperOutputSchema, } from "./package-contracts/gatekeeper-output.js";
|
|
@@ -51,19 +51,12 @@ function failureReason(error) {
|
|
|
51
51
|
return error.errors.map(failureReason).join("; ");
|
|
52
52
|
return error instanceof Error ? `${error.name}: ${error.message}` : String(error);
|
|
53
53
|
}
|
|
54
|
-
/** Serializable stand-in when the child tool call had no arguments object. */
|
|
55
|
-
export const MISSING_ARGUMENTS_SUBMISSION = Object.freeze({ missing: "arguments" });
|
|
56
54
|
function isRecord(value) {
|
|
57
55
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
58
56
|
}
|
|
59
|
-
/**
|
|
57
|
+
/** Original decision bytes — no sentinel replacement (#836). */
|
|
60
58
|
function retainedReceipt(decision) {
|
|
61
|
-
|
|
62
|
-
// Through the real provider adapter an undefined root argument arrives as an
|
|
63
|
-
// empty object after serialization; that must also project a missing-args fact.
|
|
64
|
-
return decision === undefined || (isRecord(decision) && Object.keys(decision).length === 0)
|
|
65
|
-
? MISSING_ARGUMENTS_SUBMISSION
|
|
66
|
-
: decision;
|
|
59
|
+
return decision;
|
|
67
60
|
}
|
|
68
61
|
function readRecord(value) {
|
|
69
62
|
if (typeof value !== "object" || value === null || Array.isArray(value))
|
|
@@ -92,63 +85,85 @@ function projectOfficerDecision(officer, decision, fallbackStatus) {
|
|
|
92
85
|
}
|
|
93
86
|
/**
|
|
94
87
|
* Project a public-role terminal onto the gate queue surface.
|
|
95
|
-
*
|
|
96
|
-
*
|
|
88
|
+
* Host failure stays failure; recorded officer payloads ride beside it (#836 A.3).
|
|
89
|
+
* Multiple recorded payloads are all kept — code does not pick last-wins.
|
|
97
90
|
*/
|
|
91
|
+
function officerPayloads(terminal) {
|
|
92
|
+
const outcome = terminal?.roleOutcome;
|
|
93
|
+
if (outcome !== undefined && (outcome.kind === "accepted" || outcome.kind === "audit_escalation")) {
|
|
94
|
+
return outcome.payloads ?? terminal?.submissions ?? [];
|
|
95
|
+
}
|
|
96
|
+
if (outcome?.kind === "failure")
|
|
97
|
+
return outcome.payloads ?? terminal?.submissions ?? [];
|
|
98
|
+
return terminal?.submissions ?? [];
|
|
99
|
+
}
|
|
100
|
+
function projectOfficerPayloads(officer, payloads, fallbackStatus) {
|
|
101
|
+
if (payloads.length === 0) {
|
|
102
|
+
return projectOfficerDecision(officer, undefined, fallbackStatus);
|
|
103
|
+
}
|
|
104
|
+
// Present every recorded payload; queue only the latest conclusion so a reask
|
|
105
|
+
// can converge (#836 呈现 ≠ 排队).
|
|
106
|
+
const queued = projectOfficerDecision(officer, payloads[payloads.length - 1], fallbackStatus);
|
|
107
|
+
if (payloads.length === 1)
|
|
108
|
+
return queued;
|
|
109
|
+
if (queued.status === "pass"
|
|
110
|
+
|| queued.status === "bounce"
|
|
111
|
+
|| queued.status === "escalate"
|
|
112
|
+
|| queued.status === "needs_reask") {
|
|
113
|
+
return { ...queued, receipt: payloads };
|
|
114
|
+
}
|
|
115
|
+
return queued;
|
|
116
|
+
}
|
|
98
117
|
function projectOfficerTerminal(officer, summoned) {
|
|
99
118
|
const terminal = summoned.terminal;
|
|
100
119
|
const outcome = terminal?.roleOutcome;
|
|
120
|
+
const recorded = officerPayloads(terminal);
|
|
101
121
|
if (outcome === undefined) {
|
|
102
|
-
const detail = summoned.stderr
|
|
122
|
+
const detail = summoned.stderr ?? "";
|
|
103
123
|
return {
|
|
104
124
|
status: "transport_failure",
|
|
105
125
|
stage: officer,
|
|
106
|
-
reason: detail
|
|
126
|
+
reason: detail.length > 0
|
|
107
127
|
? `${gateSeatLabel(officer)} public summon exit ${summoned.exitCode}: ${detail}`
|
|
108
128
|
: `${gateSeatLabel(officer)} public summon produced no terminal (exit ${summoned.exitCode})`,
|
|
109
|
-
submission: summoned,
|
|
129
|
+
submission: recorded.length > 0 ? recorded : summoned,
|
|
110
130
|
};
|
|
111
131
|
}
|
|
112
132
|
if (outcome.kind === "no_receipt") {
|
|
113
133
|
return {
|
|
114
134
|
status: "no_receipt",
|
|
115
135
|
stage: officer,
|
|
116
|
-
reason:
|
|
136
|
+
reason: typeof outcome.status === "string" && outcome.status.length > 0
|
|
137
|
+
? outcome.status
|
|
138
|
+
: "no_receipt",
|
|
117
139
|
facts: outcome,
|
|
118
140
|
};
|
|
119
141
|
}
|
|
120
142
|
if (outcome.kind === "failure") {
|
|
121
|
-
// Real provider/engine/disk failure — keep loud. Not a shape judgment.
|
|
122
143
|
return {
|
|
123
144
|
status: "transport_failure",
|
|
124
145
|
stage: officer,
|
|
125
146
|
reason: outcome.diagnostic,
|
|
126
|
-
submission: outcome.decisiveFacts,
|
|
147
|
+
submission: recorded.length > 0 ? recorded : outcome.decisiveFacts,
|
|
127
148
|
};
|
|
128
149
|
}
|
|
129
150
|
if (outcome.kind === "audit_escalation") {
|
|
130
|
-
// Residual/compliance escalate face: queue as escalate, receipt as written.
|
|
131
|
-
// Nested officer escalate itself seals accepted+status escalate (no rewrite).
|
|
132
151
|
return {
|
|
133
152
|
status: "escalate",
|
|
134
153
|
officer,
|
|
135
|
-
receipt:
|
|
154
|
+
receipt: recorded.length === 1 ? recorded[0] : recorded,
|
|
136
155
|
};
|
|
137
156
|
}
|
|
138
157
|
if (outcome.kind === "accepted") {
|
|
139
|
-
//
|
|
140
|
-
//
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
return projectOfficerDecision(officer, facts, outcome.status);
|
|
144
|
-
}
|
|
145
|
-
return projectOfficerDecision(officer, { status: outcome.status });
|
|
158
|
+
// outcome.status is the fixture/compat leaf: production settlement leaves
|
|
159
|
+
// it undefined once payloads are recorded, so this only matters when a
|
|
160
|
+
// caller still supplies status without any recorded payload (#836 hang).
|
|
161
|
+
return projectOfficerPayloads(officer, recorded, outcome.status);
|
|
146
162
|
}
|
|
147
|
-
// Unknown terminal kind: still not a shape judgment — ask the speaker again.
|
|
148
163
|
return {
|
|
149
164
|
status: "needs_reask",
|
|
150
165
|
officer,
|
|
151
|
-
receipt: retainedReceipt(outcome),
|
|
166
|
+
receipt: recorded.length > 0 ? recorded : retainedReceipt(outcome),
|
|
152
167
|
};
|
|
153
168
|
}
|
|
154
169
|
/**
|
|
@@ -173,15 +188,12 @@ export async function projectGatekeeperRun(options) {
|
|
|
173
188
|
},
|
|
174
189
|
};
|
|
175
190
|
}
|
|
176
|
-
// #
|
|
177
|
-
//
|
|
178
|
-
// not ride this path: submission body goes verbatim on gateReviewInstruction (#786).
|
|
179
|
-
persistGateSubmissionCandidate(runDirectory, options.context);
|
|
180
|
-
const submission = readLatestSubmissionArguments(options.context);
|
|
191
|
+
// #836: officers receive the whole parent run directory pointer and find the
|
|
192
|
+
// submission themselves — code no longer picks latest toolCall leaf (A7.1–A7.3).
|
|
181
193
|
let summoned;
|
|
182
194
|
try {
|
|
183
195
|
const summon = options.summonOfficer
|
|
184
|
-
?? (async (nextOfficer, sourceRunDirectory, officerSignal, reask
|
|
196
|
+
?? (async (nextOfficer, sourceRunDirectory, officerSignal, reask) => {
|
|
185
197
|
const { summonGateOfficer } = await import("./public-role-summons.js");
|
|
186
198
|
return summonGateOfficer({
|
|
187
199
|
officer: nextOfficer,
|
|
@@ -189,14 +201,13 @@ export async function projectGatekeeperRun(options) {
|
|
|
189
201
|
cwd: options.context.cwd ?? process.cwd(),
|
|
190
202
|
...(officerSignal === undefined ? {} : { signal: officerSignal }),
|
|
191
203
|
...(reask === undefined ? {} : { reask }),
|
|
192
|
-
...(nextSubmission === undefined ? {} : { submission: nextSubmission }),
|
|
193
204
|
...(options.home === undefined ? {} : { home: options.home }),
|
|
194
205
|
...(options.packageRoot === undefined ? {} : { packageRoot: options.packageRoot }),
|
|
195
206
|
...(options.roleTurnHost === undefined ? {} : { roleTurnHost: options.roleTurnHost }),
|
|
196
207
|
...(options.createRunId === undefined ? {} : { createRunId: options.createRunId }),
|
|
197
208
|
});
|
|
198
209
|
});
|
|
199
|
-
summoned = await summon(officer, runDirectory, options.signal, options.reask
|
|
210
|
+
summoned = await summon(officer, runDirectory, options.signal, options.reask);
|
|
200
211
|
}
|
|
201
212
|
catch (error) {
|
|
202
213
|
return {
|