@akagilnc/pi-workflow-roles 0.1.3644 → 0.1.3652
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/dist/acp-host/production-host.js +3089 -2187
- package/dist/activation-ledger-session.js +105 -0
- package/dist/activation-ledger.js +139 -0
- package/dist/activation-trace.js +33 -0
- package/dist/agent-start-materials.js +11 -0
- package/dist/audit-escalation.js +5 -5
- package/dist/auditor-role.js +12 -0
- package/dist/canonical-skill-binding.js +64 -0
- package/dist/collector-identity.js +151 -0
- package/dist/collector-receipt.js +95 -0
- package/dist/collector-role.js +441 -0
- package/dist/compliance-transport.js +11 -57
- package/dist/countersign-role.js +28 -0
- package/dist/diarist-contracts.js +0 -12
- package/dist/diarist-role.js +29 -0
- package/dist/doctor-contracts.js +0 -2
- package/dist/doctor-role.js +74 -0
- package/dist/fixer-bash-seatbelt.js +13 -0
- package/dist/gatekeeper-pass-envelope.js +72 -0
- package/dist/gleaner-left-contracts.js +0 -7
- package/dist/gleaner-left-role.js +26 -0
- package/dist/inspector-contracts.js +0 -4
- package/dist/inspector-role.js +29 -0
- package/dist/judge-role.js +106 -0
- package/dist/merger-role.js +66 -0
- package/dist/navigator-public-session.js +1 -5
- package/dist/navigator-role.js +12 -0
- package/dist/notary-contracts.js +0 -18
- package/dist/notary-role.js +137 -0
- package/dist/oauth-keepalive.js +158 -0
- package/dist/package-contracts/auditor-output.js +0 -13
- package/dist/package-contracts/gatekeeper-output.js +0 -10
- package/dist/package-contracts/judge-output.js +0 -2
- package/dist/package-contracts/navigator-output.js +0 -4
- package/dist/package-contracts/terminating-tools.js +2 -16
- package/dist/packaged-role-registry.js +1 -18
- package/dist/pi/adapter.js +211 -0
- package/dist/pi/role-turn-host.js +0 -2
- package/dist/public-cli/instruction-seat-run.js +2 -6
- package/dist/public-cli/invocation.js +0 -7
- package/dist/public-cli/main.js +138 -735
- package/dist/public-cli/option-definitions.js +0 -14
- package/dist/public-cli/registry.js +1 -2
- package/dist/public-cli/run-lifecycle.js +1 -3
- package/dist/public-cli/settlement.js +66 -537
- package/dist/public-role-summons.js +0 -14
- package/dist/reviewer-child-executor.js +163 -70
- package/dist/reviewer-construction.js +2 -2
- package/dist/reviewer-role.js +159 -0
- package/dist/reviewer-settlement.js +66 -0
- package/dist/role-runtime.js +1394 -0
- package/dist/stderr-jsonl.js +26 -0
- package/dist/tool-execution-observation.js +141 -0
- package/dist/worker-role.js +343 -0
- package/dist/worker-submission-gates.js +305 -0
- package/extensions/role-runtime.ts +1 -2
- package/package.json +1 -1
- package/src/acp-host/production-host.ts +0 -1
- package/src/audit-escalation.ts +9 -9
- package/src/compliance-transport.ts +28 -94
- package/src/diarist-contracts.ts +0 -12
- package/src/doctor-contracts.ts +0 -1
- package/src/doctor-role.ts +2 -2
- package/src/gleaner-left-contracts.ts +0 -9
- package/src/host-contracts.ts +0 -2
- package/src/inspector-contracts.ts +0 -8
- package/src/judge-role.ts +4 -5
- package/src/navigator-public-session.ts +4 -5
- package/src/notary-contracts.ts +0 -18
- package/src/package-contracts/auditor-output.ts +0 -11
- package/src/package-contracts/gatekeeper-output.ts +0 -11
- package/src/package-contracts/judge-output.ts +0 -1
- package/src/package-contracts/navigator-output.ts +0 -3
- package/src/package-contracts/terminating-tools.ts +1 -19
- package/src/packaged-role-registry.ts +1 -19
- package/src/pi/role-turn-host.ts +0 -2
- package/src/public-cli/cli.ts +1 -5
- package/src/public-cli/instruction-seat-run.ts +5 -14
- package/src/public-cli/invocation.ts +3 -21
- package/src/public-cli/option-definitions.ts +0 -16
- package/src/public-cli/registry.ts +1 -2
- package/src/public-cli/run-lifecycle.ts +0 -6
- package/src/public-cli/settlement.ts +58 -572
- package/src/public-cli/terminal.ts +0 -1
- package/src/public-role-summons.ts +0 -15
- package/src/reviewer-child-executor.ts +199 -98
- package/src/reviewer-construction.ts +3 -3
- package/src/role-runtime.ts +1 -33
- package/dist/package-contracts/evidence-child-output.js +0 -34
- package/souls/evidence-child.md +0 -1
- package/src/evidence-child-role.ts +0 -22
- package/src/package-contracts/evidence-child-output.ts +0 -51
|
@@ -13,7 +13,6 @@ import { isAuditEscalationResult } from "../audit-escalation.js";
|
|
|
13
13
|
import { AUDITOR_SOUL_ROLES } from "../auditor-soul.js";
|
|
14
14
|
import { DOCTOR_AUDIT_TOOL_NAME } from "../doctor-auditor.js";
|
|
15
15
|
import { JUDGE_AUDIT_TOOL_NAME } from "../judge-auditor.js";
|
|
16
|
-
import { stampShapeUnreadableDetails } from "../shape-unreadable-failure.js";
|
|
17
16
|
import { knownFailureFromProviderStop } from "../pi/known-failure.js";
|
|
18
17
|
import { readReviewerDispatchRejection } from "./reviewer-dispatch-rejection.js";
|
|
19
18
|
import { RESUME_TRANSPORT_ENVELOPE, isV1ResumableProvider, readLatestTypedProviderHttpObservation, readTypedHttp429Observation, } from "./run-lifecycle.js";
|
|
@@ -23,21 +22,20 @@ import { AUDITOR_COMPLIANCE_FAILURE_ENTRY_TYPE, AUDITOR_PARENT_ATTEMPT_BINDING_E
|
|
|
23
22
|
import { COLLECTOR_OBSERVE_TOOL, COLLECTOR_READ_TOOL, COLLECTOR_REQUEST_TOOL, COLLECTOR_WAIT_TOOL, } from "../collector-ledger.js";
|
|
24
23
|
import { ENGINE_DETOUR_TOOL_NAME } from "../engine-detour.js";
|
|
25
24
|
import { JUDGE_OUTPUT_TOOL_NAME, } from "../package-contracts/judge-output.js";
|
|
26
|
-
import { COLLECTOR_OUTPUT_TOOL,
|
|
27
|
-
import { CODER_OUTPUT_TOOL_NAME, FIXER_OUTPUT_TOOL_NAME,
|
|
25
|
+
import { COLLECTOR_OUTPUT_TOOL, } from "../package-contracts/collector-output.js";
|
|
26
|
+
import { CODER_OUTPUT_TOOL_NAME, FIXER_OUTPUT_TOOL_NAME, } from "../package-contracts/worker-output.js";
|
|
28
27
|
import { validateAcceptedDetails } from "../package-contracts/terminating-tools.js";
|
|
29
|
-
import { DOCTOR_OUTPUT_TOOL_NAME,
|
|
30
|
-
import { REVIEWER_OUTPUT_TOOL_NAME,
|
|
31
|
-
import { MERGER_OUTPUT_TOOL_NAME,
|
|
32
|
-
import { NOTARY_OUTPUT_TOOL_NAME,
|
|
33
|
-
import { COUNTERSIGN_OUTPUT_TOOL_NAME,
|
|
34
|
-
import { GLEANER_LEFT_OUTPUT_TOOL_NAME,
|
|
35
|
-
import { DIARIST_OUTPUT_TOOL_NAME,
|
|
36
|
-
import { INSPECTOR_OUTPUT_TOOL_NAME,
|
|
37
|
-
import { GATEKEEPER_OUTPUT_TOOL_NAME,
|
|
38
|
-
import { NAVIGATOR_OUTPUT_TOOL_NAME,
|
|
39
|
-
import { AUDITOR_OUTPUT_TOOL_NAME,
|
|
40
|
-
import { EVIDENCE_CHILD_OUTPUT_TOOL_NAME, evidenceChildDecisiveFacts, validateRecordedEvidenceChildOutput, } from "../package-contracts/evidence-child-output.js";
|
|
28
|
+
import { DOCTOR_OUTPUT_TOOL_NAME, } from "../doctor-contracts.js";
|
|
29
|
+
import { REVIEWER_OUTPUT_TOOL_NAME, } from "../package-contracts/reviewer-output.js";
|
|
30
|
+
import { MERGER_OUTPUT_TOOL_NAME, } from "../merger-contracts.js";
|
|
31
|
+
import { NOTARY_OUTPUT_TOOL_NAME, } from "../notary-contracts.js";
|
|
32
|
+
import { COUNTERSIGN_OUTPUT_TOOL_NAME, } from "../countersign-contracts.js";
|
|
33
|
+
import { GLEANER_LEFT_OUTPUT_TOOL_NAME, } from "../gleaner-left-contracts.js";
|
|
34
|
+
import { DIARIST_OUTPUT_TOOL_NAME, } from "../diarist-contracts.js";
|
|
35
|
+
import { INSPECTOR_OUTPUT_TOOL_NAME, } from "../inspector-contracts.js";
|
|
36
|
+
import { GATEKEEPER_OUTPUT_TOOL_NAME, } from "../package-contracts/gatekeeper-output.js";
|
|
37
|
+
import { NAVIGATOR_OUTPUT_TOOL_NAME, } from "../package-contracts/navigator-output.js";
|
|
38
|
+
import { AUDITOR_OUTPUT_TOOL_NAME, } from "../package-contracts/auditor-output.js";
|
|
41
39
|
import { observePackagedMethodSkillInvocation, } from "../package-resources/method-skill.js";
|
|
42
40
|
import { classifyPackagedRoleTerminalResult, findLatestDurablePackagedRoleTerminal, hasNavigatorInfrastructureFailureBase, isAcceptedPackagedRoleTerminalResult, isReceiptSettlementBindingClear, NAVIGATOR_INVOCATION_ENTRY, parseInvocationMarkerIdentity, } from "../navigator-invocation-identity.js";
|
|
43
41
|
import { NO_RECEIPT_LIFECYCLE_ENTRY_TYPE, parseNoReceiptLifecycleFacts } from "../receipt-delivery-policy.js";
|
|
@@ -843,7 +841,7 @@ function typedFailedTerminatingToolKnownFailure(entries) {
|
|
|
843
841
|
// Durable details already carry fact + typed evidence from envelope one-shot projection (#475).
|
|
844
842
|
// Do not re-parse retained compliance responses here.
|
|
845
843
|
// Host infrastructure must NOT map to cause=output — that cause is reserved for
|
|
846
|
-
//
|
|
844
|
+
// role-output failures (isError residual / no sealed receipt), not host infra.
|
|
847
845
|
const details = isRecord(message.details) ? message.details : classification.fact;
|
|
848
846
|
return {
|
|
849
847
|
cause: "activation",
|
|
@@ -1058,304 +1056,12 @@ function auditNoReceiptDecisiveFact(candidate) {
|
|
|
1058
1056
|
return {};
|
|
1059
1057
|
}
|
|
1060
1058
|
}
|
|
1061
|
-
/**
|
|
1062
|
-
function
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
return {};
|
|
1066
|
-
if (typeof projected.value !== "object" || projected.value === null || Array.isArray(projected.value)) {
|
|
1067
|
-
return { auditUnreadable: projected.value };
|
|
1068
|
-
}
|
|
1069
|
-
return { auditUnreadable: projected.value };
|
|
1070
|
-
}
|
|
1071
|
-
/** Countersign terminal projection — escalate keeps decisionGate; continue keeps fix (#572 / ADR 0074). */
|
|
1072
|
-
function countersignDecisiveFacts(verdict, countersignStatus) {
|
|
1073
|
-
const facts = { countersignStatus };
|
|
1074
|
-
if (countersignStatus === "continue") {
|
|
1075
|
-
const fix = safelyRead(verdict, "fix");
|
|
1076
|
-
if (fix.readable && isRecord(fix.value)) {
|
|
1077
|
-
const summary = safelyRead(fix.value, "summary");
|
|
1078
|
-
if (summary.readable && typeof summary.value === "string") {
|
|
1079
|
-
facts.fixSummary = summary.value;
|
|
1080
|
-
}
|
|
1081
|
-
}
|
|
1082
|
-
}
|
|
1083
|
-
if (countersignStatus === "escalate") {
|
|
1084
|
-
const gate = safelyRead(verdict, "decisionGate");
|
|
1085
|
-
if (gate.readable && isRecord(gate.value)) {
|
|
1086
|
-
const question = safelyRead(gate.value, "question");
|
|
1087
|
-
const options = safelyRead(gate.value, "options");
|
|
1088
|
-
if (question.readable && typeof question.value === "string") {
|
|
1089
|
-
facts.decisionQuestion = question.value;
|
|
1090
|
-
}
|
|
1091
|
-
if (options.readable && Array.isArray(options.value)) {
|
|
1092
|
-
facts.decisionOptions = [...options.value];
|
|
1093
|
-
}
|
|
1094
|
-
}
|
|
1095
|
-
}
|
|
1096
|
-
const note = safelyRead(verdict, "note");
|
|
1097
|
-
if (note.readable && note.value !== undefined)
|
|
1098
|
-
facts.note = note.value;
|
|
1099
|
-
const evidence = safelyRead(verdict, "evidence");
|
|
1100
|
-
if (evidence.readable && evidence.value !== undefined)
|
|
1101
|
-
facts.evidence = evidence.value;
|
|
1102
|
-
return facts;
|
|
1103
|
-
}
|
|
1104
|
-
function judgeDecisiveFacts(verdict, judgeStatus) {
|
|
1105
|
-
const facts = {
|
|
1106
|
-
judgeStatus,
|
|
1107
|
-
...auditNoReceiptDecisiveFact(verdict),
|
|
1108
|
-
...auditUnreadableDecisiveFact(verdict),
|
|
1109
|
-
};
|
|
1110
|
-
const statusBase = judgeStatus;
|
|
1111
|
-
if (statusBase === "continue") {
|
|
1112
|
-
const fix = safelyRead(verdict, "fix");
|
|
1113
|
-
if (fix.readable && isRecord(fix.value)) {
|
|
1114
|
-
const summary = safelyRead(fix.value, "summary");
|
|
1115
|
-
if (summary.readable && typeof summary.value === "string") {
|
|
1116
|
-
facts.fixSummary = summary.value;
|
|
1117
|
-
}
|
|
1118
|
-
}
|
|
1119
|
-
const classes = safelyRead(verdict, "classes");
|
|
1120
|
-
if (classes.readable && Array.isArray(classes.value)) {
|
|
1121
|
-
try {
|
|
1122
|
-
facts.classes = classes.value.map((entry) => {
|
|
1123
|
-
if (!isRecord(entry))
|
|
1124
|
-
throw new Error("unreadable Judge class");
|
|
1125
|
-
return {
|
|
1126
|
-
name: entry.name,
|
|
1127
|
-
owner: entry.owner,
|
|
1128
|
-
boundary: entry.boundary,
|
|
1129
|
-
disposition: entry.disposition,
|
|
1130
|
-
};
|
|
1131
|
-
});
|
|
1132
|
-
facts.classCount = classes.value.length;
|
|
1133
|
-
}
|
|
1134
|
-
catch {
|
|
1135
|
-
// Optional class material is omitted as a unit when any row is unreadable.
|
|
1136
|
-
}
|
|
1137
|
-
}
|
|
1138
|
-
}
|
|
1139
|
-
if (statusBase === "escalate") {
|
|
1140
|
-
const gate = safelyRead(verdict, "decisionGate");
|
|
1141
|
-
if (gate.readable && isRecord(gate.value)) {
|
|
1142
|
-
const question = safelyRead(gate.value, "question");
|
|
1143
|
-
const options = safelyRead(gate.value, "options");
|
|
1144
|
-
if (question.readable && typeof question.value === "string") {
|
|
1145
|
-
facts.decisionQuestion = question.value;
|
|
1146
|
-
}
|
|
1147
|
-
if (options.readable && Array.isArray(options.value)) {
|
|
1148
|
-
facts.decisionOptions = [...options.value];
|
|
1149
|
-
}
|
|
1150
|
-
}
|
|
1151
|
-
}
|
|
1152
|
-
const note = safelyRead(verdict, "note");
|
|
1153
|
-
if (note.readable && note.value !== undefined)
|
|
1154
|
-
facts.note = note.value;
|
|
1155
|
-
const evidence = safelyRead(verdict, "evidence");
|
|
1156
|
-
if (evidence.readable && evidence.value !== undefined)
|
|
1157
|
-
facts.evidence = evidence.value;
|
|
1158
|
-
return facts;
|
|
1159
|
-
}
|
|
1160
|
-
function coderDecisiveFacts(output) {
|
|
1161
|
-
const candidate = output;
|
|
1162
|
-
const status = safelyRead(candidate, "status");
|
|
1163
|
-
const facts = {};
|
|
1164
|
-
if (status.readable && typeof status.value === "string")
|
|
1165
|
-
facts.coderStatus = status.value;
|
|
1166
|
-
const statusBase = status.readable && typeof status.value === "string"
|
|
1167
|
-
? (status.value)
|
|
1168
|
-
: undefined;
|
|
1169
|
-
const remainingScope = safelyRead(candidate, "remainingScope");
|
|
1170
|
-
if (statusBase === "unfinished" && remainingScope.readable && typeof remainingScope.value === "string")
|
|
1171
|
-
facts.remainingScope = remainingScope.value;
|
|
1172
|
-
const reason = safelyRead(candidate, "reason");
|
|
1173
|
-
if (statusBase === "unfinished" && reason.readable && typeof reason.value === "string" && reason.value.trim().length > 0) {
|
|
1174
|
-
facts.reason = reason.value;
|
|
1175
|
-
}
|
|
1176
|
-
const report = safelyRead(candidate, "report");
|
|
1177
|
-
if (report.readable && typeof report.value === "string")
|
|
1178
|
-
facts.reportPresent = report.value.trim().length > 0;
|
|
1179
|
-
return facts;
|
|
1180
|
-
}
|
|
1181
|
-
function fixerDecisiveFacts(output) {
|
|
1182
|
-
const candidate = output;
|
|
1183
|
-
const status = safelyRead(candidate, "status");
|
|
1184
|
-
const facts = {};
|
|
1185
|
-
if (status.readable && typeof status.value === "string")
|
|
1186
|
-
facts.fixerStatus = status.value;
|
|
1187
|
-
const statusBase = status.readable && typeof status.value === "string"
|
|
1188
|
-
? (status.value)
|
|
1189
|
-
: undefined;
|
|
1190
|
-
const remainingScope = safelyRead(candidate, "remainingScope");
|
|
1191
|
-
if ((statusBase === "unfinished" || statusBase === "refused") && remainingScope.readable && typeof remainingScope.value === "string")
|
|
1192
|
-
facts.remainingScope = remainingScope.value;
|
|
1193
|
-
const reason = safelyRead(candidate, "reason");
|
|
1194
|
-
if (statusBase === "unfinished" && reason.readable && typeof reason.value === "string" && reason.value.trim().length > 0) {
|
|
1195
|
-
facts.reason = reason.value;
|
|
1196
|
-
}
|
|
1197
|
-
const blockerRead = safelyRead(candidate, "blocker");
|
|
1198
|
-
if (statusBase === "refused" && blockerRead.readable && isRecord(blockerRead.value)) {
|
|
1199
|
-
const cause = safelyRead(blockerRead.value, "cause");
|
|
1200
|
-
if (cause.readable && typeof cause.value === "string")
|
|
1201
|
-
facts.blockerCause = cause.value;
|
|
1202
|
-
const prerequisiteId = safelyRead(blockerRead.value, "prerequisiteId");
|
|
1203
|
-
if (cause.readable && cause.value === "prerequisite_unmet" && prerequisiteId.readable && typeof prerequisiteId.value === "string")
|
|
1204
|
-
facts.prerequisiteId = prerequisiteId.value;
|
|
1205
|
-
}
|
|
1206
|
-
const classResults = safelyRead(candidate, "classResults");
|
|
1207
|
-
if (classResults.readable && Array.isArray(classResults.value)) {
|
|
1208
|
-
const rows = [];
|
|
1209
|
-
const blockers = [];
|
|
1210
|
-
try {
|
|
1211
|
-
for (const entry of classResults.value) {
|
|
1212
|
-
if (!isRecord(entry))
|
|
1213
|
-
throw new Error("unreadable class result");
|
|
1214
|
-
const name = safelyRead(entry, "name");
|
|
1215
|
-
const disposition = safelyRead(entry, "disposition");
|
|
1216
|
-
if (!name.readable || !disposition.readable)
|
|
1217
|
-
throw new Error("unreadable class result");
|
|
1218
|
-
rows.push({ name: name.value, disposition: disposition.value });
|
|
1219
|
-
const blocker = safelyRead(entry, "blocker");
|
|
1220
|
-
if (disposition.value === "refused" && blocker.readable && isRecord(blocker.value))
|
|
1221
|
-
blockers.push(blocker.value);
|
|
1222
|
-
}
|
|
1223
|
-
facts.classResultCount = rows.length;
|
|
1224
|
-
facts.classDispositions = rows;
|
|
1225
|
-
const causes = blockers.flatMap((blocker) => {
|
|
1226
|
-
const cause = safelyRead(blocker, "cause");
|
|
1227
|
-
return cause.readable && typeof cause.value === "string" ? [cause.value] : [];
|
|
1228
|
-
});
|
|
1229
|
-
if (causes.length > 0)
|
|
1230
|
-
facts.blockerCauses = causes;
|
|
1231
|
-
const prerequisiteIds = blockers.flatMap((blocker) => {
|
|
1232
|
-
const cause = safelyRead(blocker, "cause");
|
|
1233
|
-
const id = safelyRead(blocker, "prerequisiteId");
|
|
1234
|
-
return cause.readable && cause.value === "prerequisite_unmet" && id.readable && typeof id.value === "string" ? [id.value] : [];
|
|
1235
|
-
});
|
|
1236
|
-
if (prerequisiteIds.length > 0)
|
|
1237
|
-
facts.prerequisiteIds = prerequisiteIds;
|
|
1238
|
-
}
|
|
1239
|
-
catch {
|
|
1240
|
-
// Optional class projection is omitted as a unit when any row is unreadable.
|
|
1241
|
-
}
|
|
1242
|
-
}
|
|
1243
|
-
const report = safelyRead(candidate, "report");
|
|
1244
|
-
if (report.readable && typeof report.value === "string")
|
|
1245
|
-
facts.reportPresent = report.value.trim().length > 0;
|
|
1246
|
-
return facts;
|
|
1247
|
-
}
|
|
1248
|
-
function collectorDecisiveFacts(receipt) {
|
|
1249
|
-
const candidate = receipt;
|
|
1250
|
-
const facts = {};
|
|
1251
|
-
for (const key of ["repository", "prNumber", "targetHead", "manifestDigest"]) {
|
|
1252
|
-
const value = safelyRead(candidate, key);
|
|
1253
|
-
if (value.readable && value.value !== undefined)
|
|
1254
|
-
facts[key] = value.value;
|
|
1255
|
-
}
|
|
1256
|
-
const groups = safelyRead(candidate, "groups");
|
|
1257
|
-
if (groups.readable && Array.isArray(groups.value)) {
|
|
1258
|
-
try {
|
|
1259
|
-
facts.groups = groups.value.map((group) => {
|
|
1260
|
-
if (!isRecord(group))
|
|
1261
|
-
throw new Error("unreadable Collector group");
|
|
1262
|
-
const identity = safelyRead(group, "identity");
|
|
1263
|
-
const attendance = safelyRead(group, "attendance");
|
|
1264
|
-
const materials = safelyRead(group, "materials");
|
|
1265
|
-
const findings = safelyRead(group, "findings");
|
|
1266
|
-
if (!identity.readable || !attendance.readable ||
|
|
1267
|
-
!materials.readable || !Array.isArray(materials.value) ||
|
|
1268
|
-
!findings.readable || !Array.isArray(findings.value)) {
|
|
1269
|
-
throw new Error("unreadable Collector group");
|
|
1270
|
-
}
|
|
1271
|
-
return {
|
|
1272
|
-
identity: identity.value,
|
|
1273
|
-
attendance: attendance.value,
|
|
1274
|
-
materialCount: materials.value.length,
|
|
1275
|
-
findingCount: findings.value.length,
|
|
1276
|
-
};
|
|
1277
|
-
});
|
|
1278
|
-
}
|
|
1279
|
-
catch { /* omit unreadable optional projection */ }
|
|
1280
|
-
}
|
|
1281
|
-
return facts;
|
|
1282
|
-
}
|
|
1283
|
-
function doctorDecisiveFacts(output) {
|
|
1284
|
-
const candidate = output;
|
|
1285
|
-
const status = safelyRead(candidate, "status");
|
|
1286
|
-
const facts = {
|
|
1059
|
+
/** Keep optional auditNoReceipt parallel fact when present on sealed details. */
|
|
1060
|
+
function withAuditNoReceiptFacts(candidate) {
|
|
1061
|
+
return {
|
|
1062
|
+
...candidate,
|
|
1287
1063
|
...auditNoReceiptDecisiveFact(candidate),
|
|
1288
|
-
...auditUnreadableDecisiveFact(candidate),
|
|
1289
1064
|
};
|
|
1290
|
-
if (status.readable && typeof status.value === "string")
|
|
1291
|
-
facts.doctorStatus = status.value;
|
|
1292
|
-
const statusBase = status.readable && typeof status.value === "string"
|
|
1293
|
-
? (status.value)
|
|
1294
|
-
: undefined;
|
|
1295
|
-
if (statusBase === "refused") {
|
|
1296
|
-
const reason = safelyRead(candidate, "reason");
|
|
1297
|
-
if (reason.readable && reason.value !== undefined)
|
|
1298
|
-
facts.reason = reason.value;
|
|
1299
|
-
const missing = safelyRead(candidate, "missingEvidence");
|
|
1300
|
-
if (missing.readable && Array.isArray(missing.value))
|
|
1301
|
-
facts.missingEvidenceCount = missing.value.length;
|
|
1302
|
-
return facts;
|
|
1303
|
-
}
|
|
1304
|
-
const caseValue = safelyRead(candidate, "case");
|
|
1305
|
-
if (caseValue.readable && isRecord(caseValue.value)) {
|
|
1306
|
-
const issueNumber = safelyRead(caseValue.value, "issueNumber");
|
|
1307
|
-
const runsPath = safelyRead(caseValue.value, "runsPath");
|
|
1308
|
-
if (issueNumber.readable && issueNumber.value !== undefined)
|
|
1309
|
-
facts.issueNumber = issueNumber.value;
|
|
1310
|
-
if (runsPath.readable && runsPath.value !== undefined)
|
|
1311
|
-
facts.runsPath = runsPath.value;
|
|
1312
|
-
}
|
|
1313
|
-
const findings = safelyRead(candidate, "findings");
|
|
1314
|
-
if (findings.readable && Array.isArray(findings.value))
|
|
1315
|
-
facts.findingsCount = findings.value.length;
|
|
1316
|
-
return facts;
|
|
1317
|
-
}
|
|
1318
|
-
function reviewerAxes(value) {
|
|
1319
|
-
if (!isRecord(value))
|
|
1320
|
-
return [];
|
|
1321
|
-
return ["standards", "spec"].filter((axis) => {
|
|
1322
|
-
const projected = safelyRead(value, axis);
|
|
1323
|
-
return projected.readable && projected.value !== undefined;
|
|
1324
|
-
});
|
|
1325
|
-
}
|
|
1326
|
-
function reviewerDecisiveFacts(output) {
|
|
1327
|
-
const candidate = output;
|
|
1328
|
-
const status = safelyRead(candidate, "status");
|
|
1329
|
-
const outcomes = safelyRead(candidate, "outcomes");
|
|
1330
|
-
const reports = safelyRead(candidate, "reports");
|
|
1331
|
-
const amendments = safelyRead(candidate, "amendments");
|
|
1332
|
-
const axes = reviewerAxes(outcomes.readable ? outcomes.value : undefined);
|
|
1333
|
-
const reportAxes = reviewerAxes(reports.readable ? reports.value : undefined);
|
|
1334
|
-
// Typed presence only — never copy amendment prose into public facts.
|
|
1335
|
-
const amendmentAxes = reviewerAxes(amendments.readable ? amendments.value : undefined);
|
|
1336
|
-
const acceptedBatch = safelyRead(candidate, "acceptedBatch");
|
|
1337
|
-
const specDisposition = safelyRead(candidate, "specDisposition");
|
|
1338
|
-
const facts = {
|
|
1339
|
-
axes,
|
|
1340
|
-
reportAxes,
|
|
1341
|
-
amendmentAxes,
|
|
1342
|
-
acceptedBatchPresent: acceptedBatch.readable && acceptedBatch.value !== undefined,
|
|
1343
|
-
...auditNoReceiptDecisiveFact(candidate),
|
|
1344
|
-
};
|
|
1345
|
-
if (status.readable && typeof status.value === "string")
|
|
1346
|
-
facts.reviewerStatus = status.value;
|
|
1347
|
-
if (specDisposition.readable &&
|
|
1348
|
-
(specDisposition.value === "launched" || specDisposition.value === "skipped-missing")) {
|
|
1349
|
-
facts.specDisposition = specDisposition.value;
|
|
1350
|
-
}
|
|
1351
|
-
const diagnostic = safelyRead(candidate, "diagnostic");
|
|
1352
|
-
const statusBase = status.readable && typeof status.value === "string"
|
|
1353
|
-
? (status.value)
|
|
1354
|
-
: undefined;
|
|
1355
|
-
if (statusBase === "refused" && diagnostic.readable) {
|
|
1356
|
-
facts.diagnosticPresent = typeof diagnostic.value === "string" && diagnostic.value.trim().length > 0;
|
|
1357
|
-
}
|
|
1358
|
-
return facts;
|
|
1359
1065
|
}
|
|
1360
1066
|
/**
|
|
1361
1067
|
* ADR 0037: a shape-valid Collector receipt may still name the wrong live target.
|
|
@@ -2057,7 +1763,8 @@ export async function readLawfulJudgeRoleOutcome(admitted, authority) {
|
|
|
2057
1763
|
kind: "accepted",
|
|
2058
1764
|
role: "judge",
|
|
2059
1765
|
status: sealed.status,
|
|
2060
|
-
|
|
1766
|
+
// #757: sealed details pass through (judgeStatus already on the receipt).
|
|
1767
|
+
decisiveFacts: withAuditNoReceiptFacts(details),
|
|
2061
1768
|
};
|
|
2062
1769
|
}
|
|
2063
1770
|
// Non-final: consume ledger audit-escalation projection (no JSONL accepted rebuild).
|
|
@@ -2114,17 +1821,11 @@ async function settleLawfulCoderTerminalResult(admitted, authority, options = {}
|
|
|
2114
1821
|
const ledgerOutcome = await closedLedgerOutcome(admitted, "coder");
|
|
2115
1822
|
if (ledgerOutcome === undefined)
|
|
2116
1823
|
return undefined;
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
kind: "accepted",
|
|
2123
|
-
role: "coder",
|
|
2124
|
-
status: ledgerOutcome.status,
|
|
2125
|
-
decisiveFacts: coderDecisiveFacts(output),
|
|
2126
|
-
};
|
|
2127
|
-
}
|
|
1824
|
+
// #757: sealed facts pass through — no shape re-project / field drop.
|
|
1825
|
+
const roleOutcome = ledgerOutcome;
|
|
1826
|
+
const output = ledgerOutcome.kind === "accepted"
|
|
1827
|
+
? ledgerOutcome.decisiveFacts
|
|
1828
|
+
: undefined;
|
|
2128
1829
|
const coordinates = coordinatesFromAdmitted(authority, admitted);
|
|
2129
1830
|
const entries = await readLawfulSettlementEntries(coordinates.sessionFile) ?? [];
|
|
2130
1831
|
const navigator = extractNavigatorFact(entries);
|
|
@@ -2242,17 +1943,11 @@ async function settleLawfulFixerTerminalResult(admitted, authority, options) {
|
|
|
2242
1943
|
const ledgerOutcome = await closedLedgerOutcome(admitted, "fixer");
|
|
2243
1944
|
if (ledgerOutcome === undefined)
|
|
2244
1945
|
return undefined;
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
|
|
2248
|
-
|
|
2249
|
-
|
|
2250
|
-
kind: "accepted",
|
|
2251
|
-
role: "fixer",
|
|
2252
|
-
status: ledgerOutcome.status,
|
|
2253
|
-
decisiveFacts: fixerDecisiveFacts(output),
|
|
2254
|
-
};
|
|
2255
|
-
}
|
|
1946
|
+
// #757: sealed facts pass through — no shape re-project / field drop.
|
|
1947
|
+
const roleOutcome = ledgerOutcome;
|
|
1948
|
+
const output = ledgerOutcome.kind === "accepted"
|
|
1949
|
+
? ledgerOutcome.decisiveFacts
|
|
1950
|
+
: undefined;
|
|
2256
1951
|
const coordinates = coordinatesFromAdmitted(authority, admitted);
|
|
2257
1952
|
const { sessionDirectory, sessionFile } = coordinates;
|
|
2258
1953
|
const entries = await readLawfulSettlementEntries(sessionFile) ?? [];
|
|
@@ -2351,13 +2046,15 @@ async function settleLawfulCollectorTerminalResult(admitted, authority) {
|
|
|
2351
2046
|
}
|
|
2352
2047
|
return undefined;
|
|
2353
2048
|
}
|
|
2354
|
-
|
|
2049
|
+
// #757: sealed facts pass through — no groups rebuild / field drop.
|
|
2050
|
+
// ADR 0037 identity binding stays (external admitted facts, not shape).
|
|
2051
|
+
const receipt = roleOutcome.decisiveFacts;
|
|
2355
2052
|
assertCollectorReceiptMatchesAdmitted(receipt, admitted);
|
|
2356
2053
|
const accepted = {
|
|
2357
2054
|
kind: "accepted",
|
|
2358
2055
|
role: "collector",
|
|
2359
2056
|
status: roleOutcome.status,
|
|
2360
|
-
decisiveFacts:
|
|
2057
|
+
decisiveFacts: { ...roleOutcome.decisiveFacts },
|
|
2361
2058
|
};
|
|
2362
2059
|
const navigator = extractNavigatorFact(entries);
|
|
2363
2060
|
const artifacts = await publishCollectorArtifacts(admitted, accepted, coordinates, { collectorReceipt: receipt });
|
|
@@ -2431,14 +2128,15 @@ async function settleLawfulDoctorTerminalResult(admitted, authority) {
|
|
|
2431
2128
|
runId: admitted.runId,
|
|
2432
2129
|
}, sessionDirectory);
|
|
2433
2130
|
}
|
|
2434
|
-
|
|
2131
|
+
// #757: sealed facts pass through — no validateRecordedDoctorOutput shape gate.
|
|
2132
|
+
const output = sealed.decisiveFacts;
|
|
2435
2133
|
const roleOutcome = {
|
|
2436
2134
|
kind: "accepted",
|
|
2437
2135
|
role: "doctor",
|
|
2438
2136
|
status: sealed.status,
|
|
2439
|
-
decisiveFacts:
|
|
2137
|
+
decisiveFacts: { ...sealed.decisiveFacts },
|
|
2440
2138
|
};
|
|
2441
|
-
// Bind completed receipt case identity to the admitted Issue evidence case.
|
|
2139
|
+
// Bind completed receipt case identity to the admitted Issue evidence case (external fact).
|
|
2442
2140
|
if (String(output.status) === "completed") {
|
|
2443
2141
|
const completedCase = output.case;
|
|
2444
2142
|
if (completedCase.issueNumber !== admitted.caseIdentity.issueNumber ||
|
|
@@ -2495,50 +2193,33 @@ async function settleLawfulSeatAcceptedTerminalResult(admitted, authority, spec,
|
|
|
2495
2193
|
}, sessionDirectory);
|
|
2496
2194
|
}
|
|
2497
2195
|
if (roleOutcome?.role !== spec.role) {
|
|
2498
|
-
// No
|
|
2499
|
-
//
|
|
2196
|
+
// No sealed ledger outcome for this seat/court. Prefer a real isError residual
|
|
2197
|
+
// (transport/lifecycle failure). Accepted-once without seal is absence — seal is
|
|
2198
|
+
// the sole acceptance authority (#637); do not promote session bytes to success.
|
|
2500
2199
|
// Bounded to the current attempt so multi-attempt resume timeout/no-output
|
|
2501
2200
|
// is not masked by a prior residual (#599 / #633).
|
|
2502
2201
|
const scanStart = currentAttemptStartIndex(entries);
|
|
2503
|
-
let acceptedNonUsable;
|
|
2504
2202
|
for (let index = entries.length - 1; index >= scanStart; index -= 1) {
|
|
2505
2203
|
const message = entries[index]?.message;
|
|
2506
2204
|
if (message?.role !== "toolResult")
|
|
2507
2205
|
continue;
|
|
2508
2206
|
const residual = boundErroredToolCandidate(entries, index, message, spec.toolName);
|
|
2509
2207
|
if (residual !== undefined) {
|
|
2208
|
+
// isError residual: retain candidate bytes as details (no shape stamp).
|
|
2209
|
+
const details = isRecord(residual.candidate)
|
|
2210
|
+
? residual.candidate
|
|
2211
|
+
: { candidate: residual.candidate };
|
|
2510
2212
|
return settleFailureTerminalResult(admitted, {
|
|
2511
2213
|
cause: "output",
|
|
2512
2214
|
diagnostic: residual.diagnostic,
|
|
2513
|
-
details
|
|
2215
|
+
details,
|
|
2514
2216
|
}, authority);
|
|
2515
2217
|
}
|
|
2516
|
-
if (acceptedNonUsable === undefined &&
|
|
2517
|
-
message.toolName === spec.toolName &&
|
|
2518
|
-
isAcceptedPackagedRoleTerminalResult(message)) {
|
|
2519
|
-
// Accepted once but not a lawful seat release — hold as fallback.
|
|
2520
|
-
if (!spec.tryAcceptDetails(message.details)) {
|
|
2521
|
-
acceptedNonUsable = message.details;
|
|
2522
|
-
}
|
|
2523
|
-
}
|
|
2524
|
-
}
|
|
2525
|
-
if (acceptedNonUsable !== undefined) {
|
|
2526
|
-
return settleFailureTerminalResult(admitted, {
|
|
2527
|
-
cause: "output",
|
|
2528
|
-
diagnostic: spec.nonUsableDiagnostic,
|
|
2529
|
-
details: stampShapeUnreadableDetails(acceptedNonUsable),
|
|
2530
|
-
}, authority);
|
|
2531
2218
|
}
|
|
2532
2219
|
return undefined;
|
|
2533
2220
|
}
|
|
2534
|
-
|
|
2535
|
-
|
|
2536
|
-
cause: "output",
|
|
2537
|
-
diagnostic: spec.nonUsableDiagnostic,
|
|
2538
|
-
details: stampShapeUnreadableDetails(roleOutcome.decisiveFacts),
|
|
2539
|
-
}, authority);
|
|
2540
|
-
}
|
|
2541
|
-
const acceptedOutcome = spec.projectAccepted(roleOutcome);
|
|
2221
|
+
// Sealed ledger outcome: pass through full decisiveFacts (#757).
|
|
2222
|
+
const acceptedOutcome = roleOutcome;
|
|
2542
2223
|
const navigator = extractNavigatorFact(entries);
|
|
2543
2224
|
return withOptionalGateProjection({
|
|
2544
2225
|
roleOutcome: acceptedOutcome,
|
|
@@ -2547,33 +2228,11 @@ async function settleLawfulSeatAcceptedTerminalResult(admitted, authority, spec,
|
|
|
2547
2228
|
runId: admitted.runId,
|
|
2548
2229
|
}, sessionDirectory);
|
|
2549
2230
|
}
|
|
2550
|
-
function tryAcceptWithValidator(validate) {
|
|
2551
|
-
return (details) => {
|
|
2552
|
-
try {
|
|
2553
|
-
validate(details);
|
|
2554
|
-
return true;
|
|
2555
|
-
}
|
|
2556
|
-
catch {
|
|
2557
|
-
return false;
|
|
2558
|
-
}
|
|
2559
|
-
};
|
|
2560
|
-
}
|
|
2561
2231
|
async function settleLawfulNotaryTerminalResult(admitted, authority, scope) {
|
|
2232
|
+
// #757: default sealed pass-through — no projectAccepted identity wrapper.
|
|
2562
2233
|
return settleLawfulSeatAcceptedTerminalResult(admitted, authority, {
|
|
2563
2234
|
role: "notary",
|
|
2564
2235
|
toolName: NOTARY_OUTPUT_TOOL_NAME,
|
|
2565
|
-
nonUsableDiagnostic: "符宝郎回执无显式 pass/bounce/escalate",
|
|
2566
|
-
tryAcceptDetails: tryAcceptWithValidator(validateRecordedNotaryOutput),
|
|
2567
|
-
projectAccepted: (sealed) => {
|
|
2568
|
-
const output = validateRecordedNotaryOutput(sealed.decisiveFacts);
|
|
2569
|
-
const accepted = {
|
|
2570
|
-
kind: "accepted",
|
|
2571
|
-
role: "notary",
|
|
2572
|
-
status: sealed.status,
|
|
2573
|
-
decisiveFacts: notaryDecisiveFacts(output),
|
|
2574
|
-
};
|
|
2575
|
-
return accepted;
|
|
2576
|
-
},
|
|
2577
2236
|
}, scope);
|
|
2578
2237
|
}
|
|
2579
2238
|
/** Settle a lawful Notary Terminal from the admitted session. */
|
|
@@ -2592,18 +2251,6 @@ async function settleLawfulCountersignTerminalResult(admitted, authority, scope)
|
|
|
2592
2251
|
return settleLawfulSeatAcceptedTerminalResult(admitted, authority, {
|
|
2593
2252
|
role: "countersign",
|
|
2594
2253
|
toolName: COUNTERSIGN_OUTPUT_TOOL_NAME,
|
|
2595
|
-
nonUsableDiagnostic: "给事中回执无显式 署/封驳/上呈",
|
|
2596
|
-
tryAcceptDetails: tryAcceptWithValidator(validateRecordedCountersignOutput),
|
|
2597
|
-
projectAccepted: (sealed) => {
|
|
2598
|
-
const verdict = validateRecordedCountersignOutput(sealed.decisiveFacts);
|
|
2599
|
-
const accepted = {
|
|
2600
|
-
kind: "accepted",
|
|
2601
|
-
role: "countersign",
|
|
2602
|
-
status: sealed.status,
|
|
2603
|
-
decisiveFacts: countersignDecisiveFacts(verdict, sealed.status),
|
|
2604
|
-
};
|
|
2605
|
-
return accepted;
|
|
2606
|
-
},
|
|
2607
2254
|
}, scope);
|
|
2608
2255
|
}
|
|
2609
2256
|
/** Settle a lawful Countersign Terminal from the admitted session. */
|
|
@@ -2622,18 +2269,6 @@ async function settleLawfulGleanerLeftTerminalResult(admitted, authority, scope)
|
|
|
2622
2269
|
return settleLawfulSeatAcceptedTerminalResult(admitted, authority, {
|
|
2623
2270
|
role: "gleaner-left",
|
|
2624
2271
|
toolName: GLEANER_LEFT_OUTPUT_TOOL_NAME,
|
|
2625
|
-
nonUsableDiagnostic: "左拾遗回执无显式 completed",
|
|
2626
|
-
tryAcceptDetails: tryAcceptWithValidator(validateRecordedGleanerLeftOutput),
|
|
2627
|
-
projectAccepted: (sealed) => {
|
|
2628
|
-
const output = validateRecordedGleanerLeftOutput(sealed.decisiveFacts);
|
|
2629
|
-
const accepted = {
|
|
2630
|
-
kind: "accepted",
|
|
2631
|
-
role: "gleaner-left",
|
|
2632
|
-
status: sealed.status,
|
|
2633
|
-
decisiveFacts: gleanerLeftDecisiveFacts(output),
|
|
2634
|
-
};
|
|
2635
|
-
return accepted;
|
|
2636
|
-
},
|
|
2637
2272
|
}, scope);
|
|
2638
2273
|
}
|
|
2639
2274
|
/** Settle a lawful Gleaner-Left Terminal from the admitted session. */
|
|
@@ -2652,18 +2287,6 @@ async function settleLawfulDiaristTerminalResult(admitted, authority, scope) {
|
|
|
2652
2287
|
return settleLawfulSeatAcceptedTerminalResult(admitted, authority, {
|
|
2653
2288
|
role: "diarist",
|
|
2654
2289
|
toolName: DIARIST_OUTPUT_TOOL_NAME,
|
|
2655
|
-
nonUsableDiagnostic: "起居郎回执无显式 completed",
|
|
2656
|
-
tryAcceptDetails: tryAcceptWithValidator(validateRecordedDiaristOutput),
|
|
2657
|
-
projectAccepted: (sealed) => {
|
|
2658
|
-
const output = validateRecordedDiaristOutput(sealed.decisiveFacts);
|
|
2659
|
-
const accepted = {
|
|
2660
|
-
kind: "accepted",
|
|
2661
|
-
role: "diarist",
|
|
2662
|
-
status: sealed.status,
|
|
2663
|
-
decisiveFacts: diaristDecisiveFacts(output),
|
|
2664
|
-
};
|
|
2665
|
-
return accepted;
|
|
2666
|
-
},
|
|
2667
2290
|
}, scope);
|
|
2668
2291
|
}
|
|
2669
2292
|
/** Try to settle a lawful Diarist Terminal; undefined only for genuine absence. */
|
|
@@ -2674,18 +2297,6 @@ async function settleLawfulInspectorTerminalResult(admitted, authority, scope) {
|
|
|
2674
2297
|
return settleLawfulSeatAcceptedTerminalResult(admitted, authority, {
|
|
2675
2298
|
role: "inspector",
|
|
2676
2299
|
toolName: INSPECTOR_OUTPUT_TOOL_NAME,
|
|
2677
|
-
nonUsableDiagnostic: "察院回执无显式 pass/bounce/escalate",
|
|
2678
|
-
tryAcceptDetails: tryAcceptWithValidator(validateRecordedInspectorOutput),
|
|
2679
|
-
projectAccepted: (sealed) => {
|
|
2680
|
-
const output = validateRecordedInspectorOutput(sealed.decisiveFacts);
|
|
2681
|
-
const accepted = {
|
|
2682
|
-
kind: "accepted",
|
|
2683
|
-
role: "inspector",
|
|
2684
|
-
status: sealed.status,
|
|
2685
|
-
decisiveFacts: inspectorDecisiveFacts(output),
|
|
2686
|
-
};
|
|
2687
|
-
return accepted;
|
|
2688
|
-
},
|
|
2689
2300
|
}, scope);
|
|
2690
2301
|
}
|
|
2691
2302
|
export async function trySettleInspectorTerminalResult(admitted, authority, scope) {
|
|
@@ -2695,18 +2306,6 @@ async function settleLawfulGatekeeperTerminalResult(admitted, authority, scope)
|
|
|
2695
2306
|
return settleLawfulSeatAcceptedTerminalResult(admitted, authority, {
|
|
2696
2307
|
role: "gatekeeper",
|
|
2697
2308
|
toolName: GATEKEEPER_OUTPUT_TOOL_NAME,
|
|
2698
|
-
nonUsableDiagnostic: "门下省决议无显式 dispatch/pass",
|
|
2699
|
-
tryAcceptDetails: tryAcceptWithValidator(validateRecordedGatekeeperOutput),
|
|
2700
|
-
projectAccepted: (sealed) => {
|
|
2701
|
-
const output = validateRecordedGatekeeperOutput(sealed.decisiveFacts);
|
|
2702
|
-
const accepted = {
|
|
2703
|
-
kind: "accepted",
|
|
2704
|
-
role: "gatekeeper",
|
|
2705
|
-
status: output.status,
|
|
2706
|
-
decisiveFacts: gatekeeperDecisiveFacts(output),
|
|
2707
|
-
};
|
|
2708
|
-
return accepted;
|
|
2709
|
-
},
|
|
2710
2309
|
}, scope);
|
|
2711
2310
|
}
|
|
2712
2311
|
/** Try to settle a lawful Gatekeeper Terminal; undefined only for genuine absence. */
|
|
@@ -2717,18 +2316,6 @@ async function settleLawfulNavigatorTerminalResult(admitted, authority, scope) {
|
|
|
2717
2316
|
return settleLawfulSeatAcceptedTerminalResult(admitted, authority, {
|
|
2718
2317
|
role: "navigator",
|
|
2719
2318
|
toolName: NAVIGATOR_OUTPUT_TOOL_NAME,
|
|
2720
|
-
nonUsableDiagnostic: "游奕使回执无显式路线建议",
|
|
2721
|
-
tryAcceptDetails: tryAcceptWithValidator(validateRecordedNavigatorOutput),
|
|
2722
|
-
projectAccepted: (sealed) => {
|
|
2723
|
-
const output = validateRecordedNavigatorOutput(sealed.decisiveFacts);
|
|
2724
|
-
const accepted = {
|
|
2725
|
-
kind: "accepted",
|
|
2726
|
-
role: "navigator",
|
|
2727
|
-
status: "advice",
|
|
2728
|
-
decisiveFacts: navigatorDecisiveFacts(output),
|
|
2729
|
-
};
|
|
2730
|
-
return accepted;
|
|
2731
|
-
},
|
|
2732
2319
|
}, scope);
|
|
2733
2320
|
}
|
|
2734
2321
|
/** Try to settle a lawful Navigator Terminal; undefined only for genuine absence. */
|
|
@@ -2739,49 +2326,11 @@ async function settleLawfulAuditorTerminalResult(admitted, authority, scope) {
|
|
|
2739
2326
|
return settleLawfulSeatAcceptedTerminalResult(admitted, authority, {
|
|
2740
2327
|
role: "auditor",
|
|
2741
2328
|
toolName: AUDITOR_OUTPUT_TOOL_NAME,
|
|
2742
|
-
nonUsableDiagnostic: "审刑院回执无显式 pass/bounce/escalate",
|
|
2743
|
-
// Only pass/bounce/escalate are lawful releases. Unreadable mystery status
|
|
2744
|
-
// fails closed with candidate retained for parent ComplianceCandidateUnreadableError.
|
|
2745
|
-
tryAcceptDetails: (details) => projectLawfulAuditorOutput(details) !== undefined,
|
|
2746
|
-
projectAccepted: (sealed) => {
|
|
2747
|
-
const lawful = projectLawfulAuditorOutput(sealed.decisiveFacts);
|
|
2748
|
-
if (lawful === undefined) {
|
|
2749
|
-
throw new Error("auditor projectAccepted requires lawful pass/bounce/escalate");
|
|
2750
|
-
}
|
|
2751
|
-
const accepted = {
|
|
2752
|
-
kind: "accepted",
|
|
2753
|
-
role: "auditor",
|
|
2754
|
-
status: lawful.status,
|
|
2755
|
-
decisiveFacts: auditorDecisiveFacts(lawful),
|
|
2756
|
-
};
|
|
2757
|
-
return accepted;
|
|
2758
|
-
},
|
|
2759
2329
|
}, scope);
|
|
2760
2330
|
}
|
|
2761
2331
|
export async function trySettleAuditorTerminalResult(admitted, authority, scope) {
|
|
2762
2332
|
return settleLawfulAuditorTerminalResult(admitted, authority, scope);
|
|
2763
2333
|
}
|
|
2764
|
-
async function settleLawfulEvidenceChildTerminalResult(admitted, authority, scope) {
|
|
2765
|
-
return settleLawfulSeatAcceptedTerminalResult(admitted, authority, {
|
|
2766
|
-
role: "evidence-child",
|
|
2767
|
-
toolName: EVIDENCE_CHILD_OUTPUT_TOOL_NAME,
|
|
2768
|
-
nonUsableDiagnostic: "取证回执无报告正文",
|
|
2769
|
-
tryAcceptDetails: tryAcceptWithValidator(validateRecordedEvidenceChildOutput),
|
|
2770
|
-
projectAccepted: (sealed) => {
|
|
2771
|
-
const output = validateRecordedEvidenceChildOutput(sealed.decisiveFacts);
|
|
2772
|
-
const accepted = {
|
|
2773
|
-
kind: "accepted",
|
|
2774
|
-
role: "evidence-child",
|
|
2775
|
-
status: "report",
|
|
2776
|
-
decisiveFacts: evidenceChildDecisiveFacts(output),
|
|
2777
|
-
};
|
|
2778
|
-
return accepted;
|
|
2779
|
-
},
|
|
2780
|
-
}, scope);
|
|
2781
|
-
}
|
|
2782
|
-
export async function trySettleEvidenceChildTerminalResult(admitted, authority, scope) {
|
|
2783
|
-
return settleLawfulEvidenceChildTerminalResult(admitted, authority, scope);
|
|
2784
|
-
}
|
|
2785
2334
|
/** Try to settle a lawful Coder Terminal; undefined only for genuine absence. */
|
|
2786
2335
|
export async function trySettleCoderTerminalResult(admitted, authority, options = {}) {
|
|
2787
2336
|
return settleLawfulCoderTerminalResult(admitted, authority, options);
|
|
@@ -2870,12 +2419,13 @@ async function settleLawfulReviewerTerminalResult(admitted, authority, options)
|
|
|
2870
2419
|
const coordinates = coordinatesFromAdmitted(authority, admitted);
|
|
2871
2420
|
const { sessionDirectory, sessionFile } = coordinates;
|
|
2872
2421
|
const entries = await readLawfulSettlementEntries(sessionFile) ?? [];
|
|
2873
|
-
|
|
2422
|
+
// #757: sealed facts pass through — no validateRuntimeReviewerReceipt shape gate.
|
|
2423
|
+
const receipt = sealed.decisiveFacts;
|
|
2874
2424
|
const roleOutcome = {
|
|
2875
2425
|
kind: "accepted",
|
|
2876
2426
|
role: "reviewer",
|
|
2877
2427
|
status: sealed.status,
|
|
2878
|
-
decisiveFacts:
|
|
2428
|
+
decisiveFacts: { ...sealed.decisiveFacts },
|
|
2879
2429
|
};
|
|
2880
2430
|
const navigator = extractNavigatorFact(entries);
|
|
2881
2431
|
const methodInvocations = extractReviewerMethodInvocations(entries, {
|
|
@@ -2908,24 +2458,6 @@ export async function settleReviewerTerminalResult(admitted, authority, options)
|
|
|
2908
2458
|
export async function trySettleReviewerTerminalResult(admitted, authority, options) {
|
|
2909
2459
|
return settleLawfulReviewerTerminalResult(admitted, authority, options);
|
|
2910
2460
|
}
|
|
2911
|
-
function mergerDecisiveFacts(output) {
|
|
2912
|
-
const candidate = output;
|
|
2913
|
-
const facts = {};
|
|
2914
|
-
const status = safelyRead(candidate, "status");
|
|
2915
|
-
const attemptId = safelyRead(candidate, "attemptId");
|
|
2916
|
-
if (status.readable && typeof status.value === "string")
|
|
2917
|
-
facts.mergerStatus = status.value;
|
|
2918
|
-
if (attemptId.readable && attemptId.value !== undefined)
|
|
2919
|
-
facts.attemptId = attemptId.value;
|
|
2920
|
-
const statusBase = status.readable && typeof status.value === "string"
|
|
2921
|
-
? (status.value)
|
|
2922
|
-
: undefined;
|
|
2923
|
-
const decisiveKey = statusBase === "completed" ? "mergeCommitId" : "diagnosis";
|
|
2924
|
-
const decisive = safelyRead(candidate, decisiveKey);
|
|
2925
|
-
if (decisive.readable && decisive.value !== undefined)
|
|
2926
|
-
facts[decisiveKey] = decisive.value;
|
|
2927
|
-
return facts;
|
|
2928
|
-
}
|
|
2929
2461
|
/**
|
|
2930
2462
|
* Observe forced Merger resolving-merge-conflicts Skill expansions from the session.
|
|
2931
2463
|
* Expansion evidence is package-path only; ambient home locations never count.
|
|
@@ -3015,32 +2547,29 @@ async function settleLawfulMergerTerminalResult(admitted, authority, options) {
|
|
|
3015
2547
|
? safelyRead(residual.candidate, "attemptId")
|
|
3016
2548
|
: { readable: true, value: undefined };
|
|
3017
2549
|
// Admitted-attempt identity binding only (ADR 0037) — not sole-final cardinality.
|
|
2550
|
+
// isError residual with matching attemptId is incomplete; no shape re-judge (#757).
|
|
3018
2551
|
if (!attemptId.readable || attemptId.value !== admitted.runId)
|
|
3019
2552
|
continue;
|
|
3020
|
-
|
|
3021
|
-
|
|
3022
|
-
|
|
3023
|
-
|
|
3024
|
-
|
|
3025
|
-
|
|
3026
|
-
|
|
3027
|
-
|
|
3028
|
-
|
|
3029
|
-
|
|
3030
|
-
navigator: { disposition: "no-advice" },
|
|
3031
|
-
artifacts: [],
|
|
3032
|
-
runId: admitted.runId,
|
|
3033
|
-
};
|
|
3034
|
-
}
|
|
2553
|
+
return {
|
|
2554
|
+
roleOutcome: buildResidualIncompleteTerminalOutcome({
|
|
2555
|
+
role: "merger",
|
|
2556
|
+
candidate: residual.candidate,
|
|
2557
|
+
diagnostic: residual.diagnostic,
|
|
2558
|
+
}),
|
|
2559
|
+
navigator: { disposition: "no-advice" },
|
|
2560
|
+
artifacts: [],
|
|
2561
|
+
runId: admitted.runId,
|
|
2562
|
+
};
|
|
3035
2563
|
}
|
|
3036
2564
|
return undefined;
|
|
3037
2565
|
}
|
|
3038
|
-
|
|
2566
|
+
// #757: sealed facts pass through — no validateMergerOutput shape gate.
|
|
2567
|
+
const output = roleOutcome.decisiveFacts;
|
|
3039
2568
|
const accepted = {
|
|
3040
2569
|
kind: "accepted",
|
|
3041
2570
|
role: "merger",
|
|
3042
2571
|
status: roleOutcome.status,
|
|
3043
|
-
decisiveFacts:
|
|
2572
|
+
decisiveFacts: { ...roleOutcome.decisiveFacts },
|
|
3044
2573
|
};
|
|
3045
2574
|
const methodInvocations = extractMergerMethodInvocations(entries, {
|
|
3046
2575
|
allowedLocations: [
|