@akagilnc/pi-workflow-roles 0.1.4977 → 0.1.4989

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.
Files changed (65) hide show
  1. package/dist/acp-host/production-host.js +460 -462
  2. package/dist/analyst-gate-cycles-read.js +16 -11
  3. package/dist/analyst-metric-families/gate-cycles.js +2 -2
  4. package/dist/audit-escalation.js +19 -4
  5. package/dist/compliance-transport.js +2 -2
  6. package/dist/countersign-contracts.js +6 -5
  7. package/dist/doctor-evidence.js +2 -1
  8. package/dist/gatekeeper-role.js +22 -43
  9. package/dist/headless-host/production-host.js +460 -462
  10. package/dist/inspector-contracts.js +3 -2
  11. package/dist/migrate-book-topology.js +59 -54
  12. package/dist/navigator-invocation-identity.js +6 -4
  13. package/dist/notary-contracts.js +3 -19
  14. package/dist/package-contracts/auditor-output.js +4 -19
  15. package/dist/package-contracts/judge-output.js +6 -5
  16. package/dist/package-contracts/terminating-tools.js +9 -3
  17. package/dist/packaged-role-registry.js +10 -12
  18. package/dist/public-cli/countersign-run.js +1 -1
  19. package/dist/public-cli/main.js +95 -87
  20. package/dist/public-cli/option-definitions.js +2 -2
  21. package/dist/public-cli/settlement.js +15 -12
  22. package/dist/review-submission.js +20 -0
  23. package/dist/submission-errors.js +2 -2
  24. package/dist/submission-ledger.js +16 -2
  25. package/package.json +1 -1
  26. package/souls/doctor-auditor.md +1 -1
  27. package/souls/fixer-auditor.md +4 -4
  28. package/souls/gate-output-guide.md +2 -2
  29. package/souls/inspector.md +1 -1
  30. package/souls/judge-auditor.md +2 -2
  31. package/souls/notary.md +1 -1
  32. package/souls/quality-law.md +1 -1
  33. package/src/analyst-gate-cycles-read.ts +17 -9
  34. package/src/analyst-metric-families/gate-cycles.ts +2 -2
  35. package/src/audit-escalation.ts +27 -7
  36. package/src/auditor-role.ts +1 -1
  37. package/src/compliance-transport.ts +7 -7
  38. package/src/countersign-contracts.ts +10 -8
  39. package/src/countersign-role.ts +6 -35
  40. package/src/doctor-evidence.ts +2 -1
  41. package/src/doctor-role.ts +1 -2
  42. package/src/gatekeeper-role.ts +32 -57
  43. package/src/host-contracts.ts +4 -3
  44. package/src/inspector-contracts.ts +7 -6
  45. package/src/inspector-role.ts +3 -20
  46. package/src/judge-role.ts +31 -51
  47. package/src/navigator-invocation-identity.ts +16 -4
  48. package/src/notary-contracts.ts +8 -26
  49. package/src/notary-role.ts +1 -1
  50. package/src/package-contracts/auditor-output.ts +6 -27
  51. package/src/package-contracts/judge-output.ts +10 -8
  52. package/src/package-contracts/terminating-tools.ts +9 -3
  53. package/src/packaged-role-registry.ts +12 -13
  54. package/src/pi/adapter.ts +6 -5
  55. package/src/public-cli/countersign-run.ts +1 -1
  56. package/src/public-cli/option-definitions.ts +2 -2
  57. package/src/public-cli/settlement.ts +18 -15
  58. package/src/review-submission.ts +29 -0
  59. package/src/role-envelope.ts +17 -9
  60. package/src/role-runtime.ts +32 -15
  61. package/src/submission-errors.ts +6 -6
  62. package/src/{gatekeeper-pass-envelope.ts → submission-gate.ts} +29 -16
  63. package/src/submission-ledger.ts +18 -3
  64. package/src/ticket-trajectory.ts +9 -4
  65. package/src/worker-role.ts +19 -5
@@ -8881,12 +8881,43 @@ var init_navigator_output = __esm({
8881
8881
  }
8882
8882
  });
8883
8883
 
8884
+ // src/review-submission.ts
8885
+ var REVIEW_SUBMISSION_OUTPUT_TOOL_NAME, reviewSubmissionSchema;
8886
+ var init_review_submission = __esm({
8887
+ "src/review-submission.ts"() {
8888
+ "use strict";
8889
+ init_build();
8890
+ init_open_tool_schema();
8891
+ init_terminating_infrastructure();
8892
+ REVIEW_SUBMISSION_OUTPUT_TOOL_NAME = "ak_submission_output";
8893
+ reviewSubmissionSchema = withTerminatingOutputDeclarations(
8894
+ openToolObject(
8895
+ typebox_exports.Object({
8896
+ status: typebox_exports.Optional(typebox_exports.Unknown({
8897
+ description: "converged | continue | escalate \u2014 \u975E\u4E09\u6001\u65F6\u8BF7\u91CD\u8BFB\u540E\u91CD\u4EA4\uFF0C\u52FF\u6539\u6807\u3002"
8898
+ })),
8899
+ findings: typebox_exports.Optional(typebox_exports.Unknown({ description: "\u5BA1\u6838\u53D1\u73B0\uFF0C\u539F\u6837\u7559\u5B58" })),
8900
+ reason: typebox_exports.Optional(typebox_exports.Unknown({ description: "\u4E0A\u5448\u7406\u7531" })),
8901
+ violations: typebox_exports.Optional(typebox_exports.Unknown({ description: "\u8FDD\u89C4\u6761\u76EE" })),
8902
+ conflicts: typebox_exports.Optional(typebox_exports.Unknown({ description: "\u5F85\u51B3\u51B2\u7A81" })),
8903
+ fix: typebox_exports.Optional(typebox_exports.Unknown({ description: "continue \u65F6\u7684\u8865\u6551\u8BF4\u660E\uFF1B\u53EF\u5199 summary \u6458\u8981\uFF0C\u5176\u4F59\u5185\u5BB9\u539F\u6837\u7559\u5B58" })),
8904
+ classes: typebox_exports.Optional(typebox_exports.Unknown({ description: "\u5DF2\u88C1\u51B3 finding \u7C7B\uFF1B\u53EF\u8BF4\u660E name\u3001owner\u3001boundary\u3001disposition\uFF0C\u539F\u6837\u7559\u5B58" })),
8905
+ note: typebox_exports.Optional(typebox_exports.Unknown({ description: "\u88C1\u51B3\u9644\u6CE8" })),
8906
+ evidence: typebox_exports.Optional(typebox_exports.Unknown({ description: "\u7559\u5B58\u8BC1\u636E" })),
8907
+ decisionGate: typebox_exports.Optional(typebox_exports.Unknown({ description: "\u9700\u4EBA\u6743\u5A01\u5904\u7F6E\u7684\u95EE\u9898\u4E0E\u9009\u9879\uFF1B\u53EF\u8BF4\u660E question\u3001options\uFF0C\u539F\u6837\u7559\u5B58" }))
8908
+ })
8909
+ )
8910
+ );
8911
+ }
8912
+ });
8913
+
8884
8914
  // src/package-contracts/judge-output.ts
8885
8915
  var JUDGE_OUTPUT_TOOL_NAME;
8886
8916
  var init_judge_output = __esm({
8887
8917
  "src/package-contracts/judge-output.ts"() {
8888
8918
  "use strict";
8889
- JUDGE_OUTPUT_TOOL_NAME = "ak_judge_output";
8919
+ init_review_submission();
8920
+ JUDGE_OUTPUT_TOOL_NAME = REVIEW_SUBMISSION_OUTPUT_TOOL_NAME;
8890
8921
  }
8891
8922
  });
8892
8923
 
@@ -15091,30 +15122,13 @@ var init_merger_contracts = __esm({
15091
15122
  });
15092
15123
 
15093
15124
  // src/notary-contracts.ts
15094
- var NOTARY_OUTPUT_TOOL_NAME, NOTARY_FIXED_KICKOFF, notaryOutputSchema;
15125
+ var NOTARY_OUTPUT_TOOL_NAME, NOTARY_FIXED_KICKOFF;
15095
15126
  var init_notary_contracts = __esm({
15096
15127
  "src/notary-contracts.ts"() {
15097
15128
  "use strict";
15098
- init_build();
15099
- init_open_tool_schema();
15100
- init_terminating_infrastructure();
15101
- NOTARY_OUTPUT_TOOL_NAME = "ak_notary_output";
15129
+ init_review_submission();
15130
+ NOTARY_OUTPUT_TOOL_NAME = REVIEW_SUBMISSION_OUTPUT_TOOL_NAME;
15102
15131
  NOTARY_FIXED_KICKOFF = "\u7B26\u5B9D\u90CE\u6848\u5377\u5DF2\u53D7\u7406\uFF1B\u6765\u6E90 run \u5B9A\u4F4D\u89C1\u4F1A\u8BDD\u6750\u6599\u3002";
15103
- notaryOutputSchema = withTerminatingOutputDeclarations(
15104
- openToolObject(
15105
- typebox_exports.Object({
15106
- status: typebox_exports.Unknown({
15107
- description: "pass | bounce | escalate \u2014 \u5F62\u72B6\u6307\u5F15\uFF0C\u975E schema \u95F8"
15108
- }),
15109
- findings: typebox_exports.Unknown({
15110
- description: "string[] findings\uFF0C\u968F pass\u3001bounce \u6216 escalate \u7559\u5B58"
15111
- }),
15112
- reason: typebox_exports.Optional(typebox_exports.Unknown({
15113
- description: "status \u4E3A escalate \u65F6\u7684\u4E0A\u5448\u7406\u7531"
15114
- }))
15115
- })
15116
- )
15117
- );
15118
15132
  }
15119
15133
  });
15120
15134
 
@@ -15123,7 +15137,8 @@ var COUNTERSIGN_OUTPUT_TOOL_NAME;
15123
15137
  var init_countersign_contracts = __esm({
15124
15138
  "src/countersign-contracts.ts"() {
15125
15139
  "use strict";
15126
- COUNTERSIGN_OUTPUT_TOOL_NAME = "ak_countersign_output";
15140
+ init_review_submission();
15141
+ COUNTERSIGN_OUTPUT_TOOL_NAME = REVIEW_SUBMISSION_OUTPUT_TOOL_NAME;
15127
15142
  }
15128
15143
  });
15129
15144
 
@@ -15141,37 +15156,18 @@ var INSPECTOR_OUTPUT_TOOL_NAME;
15141
15156
  var init_inspector_contracts = __esm({
15142
15157
  "src/inspector-contracts.ts"() {
15143
15158
  "use strict";
15144
- INSPECTOR_OUTPUT_TOOL_NAME = "ak_inspector_output";
15159
+ init_review_submission();
15160
+ INSPECTOR_OUTPUT_TOOL_NAME = REVIEW_SUBMISSION_OUTPUT_TOOL_NAME;
15145
15161
  }
15146
15162
  });
15147
15163
 
15148
15164
  // src/package-contracts/auditor-output.ts
15149
- var AUDITOR_OUTPUT_TOOL_NAME, auditorOutputSchema;
15165
+ var AUDITOR_OUTPUT_TOOL_NAME;
15150
15166
  var init_auditor_output = __esm({
15151
15167
  "src/package-contracts/auditor-output.ts"() {
15152
15168
  "use strict";
15153
- init_build();
15154
- init_open_tool_schema();
15155
- init_terminating_infrastructure();
15156
- AUDITOR_OUTPUT_TOOL_NAME = "ak_auditor_output";
15157
- auditorOutputSchema = withTerminatingOutputDeclarations(
15158
- openToolObject(
15159
- typebox_exports.Object({
15160
- status: typebox_exports.Unknown({
15161
- description: "pass | bounce | escalate \u2014 \u5F62\u72B6\u6307\u5F15\uFF0C\u975E schema \u95F8"
15162
- }),
15163
- violations: typebox_exports.Optional(typebox_exports.Unknown({
15164
- description: "status \u4E3A bounce \u65F6\u7684\u8FDD\u89C4\u6761\u76EE"
15165
- })),
15166
- conflicts: typebox_exports.Optional(typebox_exports.Unknown({
15167
- description: "status \u4E3A escalate \u65F6\u7684\u51B2\u7A81"
15168
- })),
15169
- decisionGate: typebox_exports.Optional(typebox_exports.Unknown({
15170
- description: "status \u4E3A escalate \u65F6\u7684\u51B3\u7B56\u95F8"
15171
- }))
15172
- })
15173
- )
15174
- );
15169
+ init_review_submission();
15170
+ AUDITOR_OUTPUT_TOOL_NAME = REVIEW_SUBMISSION_OUTPUT_TOOL_NAME;
15175
15171
  }
15176
15172
  });
15177
15173
 
@@ -15293,6 +15289,7 @@ var packaged_role_registry_exports = {};
15293
15289
  __export(packaged_role_registry_exports, {
15294
15290
  AUDITOR_PUBLIC_SESSION_MATERIALS: () => AUDITOR_PUBLIC_SESSION_MATERIALS,
15295
15291
  INSPECTOR_SESSION_MATERIALS: () => INSPECTOR_SESSION_MATERIALS,
15292
+ LEGACY_REVIEW_OUTPUT_ROLES: () => LEGACY_REVIEW_OUTPUT_ROLES,
15296
15293
  NOTARY_SESSION_MATERIALS: () => NOTARY_SESSION_MATERIALS,
15297
15294
  PACKAGED_ROLE_REGISTRY: () => PACKAGED_ROLE_REGISTRY,
15298
15295
  PUBLIC_ROLE_RECORDS: () => PUBLIC_ROLE_RECORDS,
@@ -15309,7 +15306,6 @@ __export(packaged_role_registry_exports, {
15309
15306
  packagedBoardPlacement: () => packagedBoardPlacement,
15310
15307
  packagedDurableOfficerEntry: () => packagedDurableOfficerEntry,
15311
15308
  packagedEmitsAuthorityRefs: () => packagedEmitsAuthorityRefs,
15312
- packagedGateDecision: () => packagedGateDecision,
15313
15309
  packagedGateStageLabel: () => packagedGateStageLabel,
15314
15310
  packagedGateSummon: () => packagedGateSummon,
15315
15311
  packagedMethodLoadFailureCause: () => packagedMethodLoadFailureCause,
@@ -15476,14 +15472,7 @@ function packagedGateSummon(role) {
15476
15472
  if (record4 !== void 0 && "gateSummon" in record4) return record4.gateSummon;
15477
15473
  return "pointer";
15478
15474
  }
15479
- function packagedGateDecision(role) {
15480
- const record4 = packagedRoleMetadata(role);
15481
- if (record4 !== void 0 && "gateDecision" in record4 && record4.gateDecision === "countersign-status") {
15482
- return "countersign-status";
15483
- }
15484
- return "three-state";
15485
- }
15486
- var NOTARY_SESSION_MATERIALS, INSPECTOR_SESSION_MATERIALS, AUDITOR_PUBLIC_SESSION_MATERIALS, PUBLIC_ROLE_RECORDS, PACKAGED_ROLE_REGISTRY;
15475
+ var LEGACY_REVIEW_OUTPUT_ROLES, NOTARY_SESSION_MATERIALS, INSPECTOR_SESSION_MATERIALS, AUDITOR_PUBLIC_SESSION_MATERIALS, PUBLIC_ROLE_RECORDS, PACKAGED_ROLE_REGISTRY;
15487
15476
  var init_packaged_role_registry = __esm({
15488
15477
  "src/packaged-role-registry.ts"() {
15489
15478
  "use strict";
@@ -15504,6 +15493,13 @@ var init_packaged_role_registry = __esm({
15504
15493
  init_diarist_contracts();
15505
15494
  init_secretariat_contracts();
15506
15495
  init_judge_auditor();
15496
+ LEGACY_REVIEW_OUTPUT_ROLES = /* @__PURE__ */ new Map([
15497
+ ["ak_judge_output", "judge"],
15498
+ ["ak_notary_output", "notary"],
15499
+ ["ak_countersign_output", "countersign"],
15500
+ ["ak_inspector_output", "inspector"],
15501
+ ["ak_auditor_output", "auditor"]
15502
+ ]);
15507
15503
  NOTARY_SESSION_MATERIALS = [
15508
15504
  "CLAUDE.md",
15509
15505
  "souls/notary.md",
@@ -15545,7 +15541,7 @@ var init_packaged_role_registry = __esm({
15545
15541
  /** Navigator subject is the public admitted instruction when the run is bound. */
15546
15542
  navigatorSubject: "public-instruction",
15547
15543
  activationStage: "load-and-install",
15548
- receiptStatusKey: "judgeStatus",
15544
+ receiptStatusKey: "status",
15549
15545
  sessionMaterials: [
15550
15546
  "CLAUDE.md",
15551
15547
  "souls/judge.md",
@@ -15827,15 +15823,13 @@ var init_packaged_role_registry = __esm({
15827
15823
  outputTool: COUNTERSIGN_OUTPUT_TOOL_NAME,
15828
15824
  settlement: "accepted",
15829
15825
  gateStageLabel: "\u7ED9\u4E8B\u4E2D",
15830
- /** Gate queue reads countersignStatus, not the shared three-state status. */
15831
- gateDecision: "countersign-status",
15832
15826
  /** Gate summon carries the parent payload as the instruction and a parent run id. */
15833
15827
  gateSummon: "parent-instruction",
15834
15828
  activationFlags: [
15835
15829
  { field: "ticketNumber" }
15836
15830
  ],
15837
15831
  activationStage: "load-and-install",
15838
- receiptStatusKey: "countersignStatus",
15832
+ receiptStatusKey: "status",
15839
15833
  // #924: 公用《票面法》三席同装
15840
15834
  sessionMaterials: ["CLAUDE.md", "souls/countersign.md", "souls/ticket-law.md"]
15841
15835
  },
@@ -17885,6 +17879,7 @@ var init_gatekeeper_role = __esm({
17885
17879
  init_packaged_role_registry();
17886
17880
  init_submission_errors();
17887
17881
  init_inspector_contracts();
17882
+ init_review_submission();
17888
17883
  init_gatekeeper_output();
17889
17884
  init_run_terminal_artifacts();
17890
17885
  init_submission_errors();
@@ -18130,7 +18125,8 @@ function validateAcceptedDetails(_toolName, details) {
18130
18125
  function acceptedFacts(toolName, details) {
18131
18126
  const record4 = details;
18132
18127
  const entry = PACKAGED_ROLE_REGISTRY.find((candidate) => candidate.outputTool === toolName);
18133
- const statusKey = entry !== void 0 && "receiptStatusKey" in entry ? entry.receiptStatusKey : "status";
18128
+ const legacyRole = LEGACY_REVIEW_OUTPUT_ROLES.get(toolName);
18129
+ const statusKey = legacyRole === "judge" || legacyRole === "countersign" ? `${legacyRole}Status` : entry !== void 0 && "receiptStatusKey" in entry ? entry.receiptStatusKey : "status";
18134
18130
  const status = typeof record4[statusKey] === "string" ? record4[statusKey] : void 0;
18135
18131
  const commitKey = entry !== void 0 && "receiptCommitKey" in entry ? entry.receiptCommitKey : void 0;
18136
18132
  const commitWhen = entry !== void 0 && "receiptCommitWhen" in entry ? entry.receiptCommitWhen : void 0;
@@ -18161,7 +18157,10 @@ var init_terminating_tools = __esm({
18161
18157
  init_diarist_contracts();
18162
18158
  init_secretariat_contracts();
18163
18159
  init_worker_output();
18164
- TERMINATING_TOOL_NAMES = PACKAGED_ROLE_REGISTRY.map((entry) => entry.outputTool);
18160
+ TERMINATING_TOOL_NAMES = [.../* @__PURE__ */ new Set([
18161
+ ...PACKAGED_ROLE_REGISTRY.map((entry) => entry.outputTool),
18162
+ ...LEGACY_REVIEW_OUTPUT_ROLES.keys()
18163
+ ])];
18165
18164
  AcceptedDetailsContractError = class extends CorrectableSubmissionError {
18166
18165
  code = "accepted_details_contract";
18167
18166
  constructor(message, options) {
@@ -18243,6 +18242,7 @@ function deriveSession(content, id) {
18243
18242
  let accepted, observedCommit, turns = 0, calls = 0, tokens = 0;
18244
18243
  const statuses = [], commits = [];
18245
18244
  for (const row of rows) {
18245
+ if (row.type === "custom" && row.customType === "ak-role-submission-closure" && record3(row.data) && row.data.isError === false && typeof row.data.toolName === "string" && isTerminatingToolName(row.data.toolName)) accepted = row;
18246
18246
  const message = record3(row.message) ? row.message : void 0;
18247
18247
  if (message?.role === "assistant") {
18248
18248
  for (const part of Array.isArray(message.content) ? message.content : []) if (record3(part) && part.type === "toolCall") calls++;
@@ -18260,7 +18260,6 @@ function deriveSession(content, id) {
18260
18260
  if (error instanceof AcceptedDetailsContractError) continue;
18261
18261
  throw error;
18262
18262
  }
18263
- accepted = row;
18264
18263
  const facts = acceptedFacts(message.toolName, details);
18265
18264
  if (facts.commit && facts.commit !== observedCommit) {
18266
18265
  commits.push({ source: id, commit: facts.commit });
@@ -21154,7 +21153,7 @@ var init_option_definitions = __esm({
21154
21153
  },
21155
21154
  inspector: {
21156
21155
  command: "inspector",
21157
- summary: "Direct Inspector (\u53F0\u9662) complexity and test-quality check; pass or bounce.",
21156
+ summary: "Direct Inspector (\u53F0\u9662) complexity and test-quality check; converged, continue, or escalate.",
21158
21157
  usage: ["ak-role inspector [options] [instruction]"],
21159
21158
  examples: [
21160
21159
  'ak-role inspector --attach ./change.patch "Review this material."'
@@ -21178,7 +21177,7 @@ var init_option_definitions = __esm({
21178
21177
  },
21179
21178
  auditor: {
21180
21179
  command: "auditor",
21181
- summary: "Direct Auditor (\u5BA1\u5211\u9662) compliance audit: pass, bounce, or escalate.",
21180
+ summary: "Direct Auditor (\u5BA1\u5211\u9662) compliance audit: converged, continue, or escalate.",
21182
21181
  usage: ["ak-role auditor --subject <judge|doctor> --source-run <runId@role|path> [options] [instruction]"],
21183
21182
  examples: [
21184
21183
  'ak-role auditor --subject judge --source-run 01abc\u2026@judge --attach ./dossier "\u5BA1\uFF1A\u672C run \u662F\u5426\u5408\u89C4\u3002"',
@@ -23611,6 +23610,7 @@ function rowFromPayload(kind, payload, accepted, roleFallback) {
23611
23610
  kind,
23612
23611
  accepted,
23613
23612
  ...Object.hasOwn(payload, "auditReceipt") ? { auditReceipt: payload.auditReceipt } : {},
23613
+ ...Object.hasOwn(payload, "auditOfficer") ? { auditOfficer: payload.auditOfficer } : {},
23614
23614
  ...typeof payload.toolCallId === "string" && payload.toolCallId.length > 0 ? { toolCallId: payload.toolCallId } : {}
23615
23615
  };
23616
23616
  }
@@ -24110,7 +24110,7 @@ function optionalDispatchReason(raw) {
24110
24110
  return raw;
24111
24111
  }
24112
24112
  function isGateTerminatingToolName(toolName) {
24113
- return DISPATCH_TOOLS.has(toolName) || OFFICER_TOOL_TO_FACE[toolName] !== void 0;
24113
+ return toolName === "ak_submission_output" || DISPATCH_TOOLS.has(toolName) || OFFICER_TOOL_TO_FACE[toolName] !== void 0;
24114
24114
  }
24115
24115
  function acceptedGateReceiptIds(rows) {
24116
24116
  const accepted = /* @__PURE__ */ new Set();
@@ -24185,7 +24185,7 @@ function extractAllAcceptedGateToolCalls(rows) {
24185
24185
  }
24186
24186
  return out;
24187
24187
  }
24188
- function projectAcceptedGateCall(filePath, rows, call) {
24188
+ function projectAcceptedGateCall(filePath, rows, call, pointerOfficer) {
24189
24189
  const span = requireAcceptedGateSpan(intervalRowsForGateCall(rows, call.rowIndex), filePath);
24190
24190
  const status = readAcceptedGateStatus(call.args);
24191
24191
  const findings = asFindings(call.args?.findings);
@@ -24212,7 +24212,7 @@ function projectAcceptedGateCall(filePath, rows, call) {
24212
24212
  ...bindingFields
24213
24213
  };
24214
24214
  }
24215
- const officer = OFFICER_TOOL_TO_FACE[call.toolName];
24215
+ const officer = call.toolName === "ak_submission_output" ? pointerOfficer : OFFICER_TOOL_TO_FACE[call.toolName];
24216
24216
  if (officer === void 0) {
24217
24217
  throw new Error(
24218
24218
  `accepted gate receipt has unknown officer tool ${call.toolName} in ${filePath}`
@@ -24230,13 +24230,13 @@ function projectAcceptedGateCall(filePath, rows, call) {
24230
24230
  ...bindingFields
24231
24231
  };
24232
24232
  }
24233
- async function classifyAuditorVolume(filePath) {
24233
+ async function classifyAuditorVolume(filePath, pointerOfficer) {
24234
24234
  const rows = await readLedgerSessionJsonl(filePath);
24235
24235
  const accepted = extractAllAcceptedGateToolCalls(rows);
24236
24236
  if (accepted.length === 0) return [];
24237
24237
  const volumes = [];
24238
24238
  for (const call of accepted) {
24239
- const projected = projectAcceptedGateCall(filePath, rows, call);
24239
+ const projected = call.toolName === "ak_submission_output" && pointerOfficer === void 0 ? void 0 : projectAcceptedGateCall(filePath, rows, call, pointerOfficer);
24240
24240
  if (projected !== void 0) volumes.push(projected);
24241
24241
  }
24242
24242
  return volumes;
@@ -24316,7 +24316,8 @@ async function resolveOfficerSessionFromPointerFile(pointerPath) {
24316
24316
  if (typeof sessionFile !== "string" || sessionFile.trim() === "") {
24317
24317
  throw new Error(`direct officer run pointer missing sessionFile in ${pointerPath}`);
24318
24318
  }
24319
- return sessionFile;
24319
+ const officer = raw.officer === "inspector" || raw.officer === "notary" ? raw.officer : void 0;
24320
+ return { sessionFile, ...officer === void 0 ? {} : { officer } };
24320
24321
  }
24321
24322
  async function readAnalystGateCyclesFromAuditorRoles(auditorRolesDirectory, options = {}) {
24322
24323
  const directories = typeof auditorRolesDirectory === "string" ? [auditorRolesDirectory] : auditorRolesDirectory;
@@ -24336,13 +24337,13 @@ async function readAnalystGateCyclesFromAuditorRoles(auditorRolesDirectory, opti
24336
24337
  for (const name of names) {
24337
24338
  const path = join27(directory, name);
24338
24339
  const fromPointer = name.endsWith(".pointer.json");
24339
- const sessionPath = fromPointer ? await resolveOfficerSessionFromPointerFile(path) : path;
24340
- if (sessionPath === void 0) continue;
24340
+ const pointer = fromPointer ? await resolveOfficerSessionFromPointerFile(path) : void 0;
24341
+ const sessionPath = pointer?.sessionFile ?? path;
24341
24342
  if (fromPointer) {
24342
24343
  if (classifiedOfficerSessions.has(sessionPath)) continue;
24343
24344
  classifiedOfficerSessions.add(sessionPath);
24344
24345
  }
24345
- const classified = await classifyAuditorVolume(sessionPath);
24346
+ const classified = await classifyAuditorVolume(sessionPath, pointer?.officer);
24346
24347
  for (const volume of classified) {
24347
24348
  if (options.parentSessionFile !== void 0 && volume.parentSessionFile !== void 0 && volume.parentSessionFile !== options.parentSessionFile) {
24348
24349
  continue;
@@ -24507,7 +24508,7 @@ function parseInvocationMarkerIdentity(data) {
24507
24508
  }
24508
24509
  function classifyPackagedRoleTerminalResult(message) {
24509
24510
  if (typeof message.toolName !== "string") return { kind: "nonterminal" };
24510
- if (!PACKAGED_ROLE_OUTPUT_TOOLS.has(message.toolName)) return { kind: "nonterminal" };
24511
+ if (!PACKAGED_ROLE_OUTPUT_TOOLS.has(message.toolName) && message.toolName !== "ak_submission_output") return { kind: "nonterminal" };
24511
24512
  const hasInfraBase = hasNavigatorInfrastructureFailureBase(message.details);
24512
24513
  const infraFact = hasInfraBase ? buildNavigatorInfrastructureFailureFact() : void 0;
24513
24514
  if (message.isError === true) {
@@ -24524,12 +24525,14 @@ function durableTerminalAt(entries, index) {
24524
24525
  const entry = entries[index];
24525
24526
  const message = entry?.type === "custom" && entry.customType === "ak-role-submission-closure" ? typeof entry.data === "object" && entry.data !== null ? entry.data : void 0 : entry?.type === "message" && entry.message?.role === "toolResult" ? entry.message : void 0;
24526
24527
  if (typeof message?.toolName !== "string") return void 0;
24527
- const role = PACKAGED_ROLE_OUTPUT_TOOLS.get(message.toolName);
24528
+ const marker = message.toolName === "ak_submission_output" ? entries.slice(0, index).reverse().find(isInvocationMarkerEntry) : void 0;
24529
+ const role = message.toolName === "ak_submission_output" ? parseInvocationMarkerIdentity(marker?.data)?.role ?? "unknown" : PACKAGED_ROLE_OUTPUT_TOOLS.get(message.toolName);
24528
24530
  if (role === void 0) return void 0;
24529
24531
  const classification = classifyPackagedRoleTerminalResult(message);
24530
24532
  if (classification.kind !== "accepted" && classification.kind !== "infrastructure") {
24531
24533
  return void 0;
24532
24534
  }
24535
+ if (entry?.type === "message" && classification.kind === "accepted" && !LEGACY_REVIEW_OUTPUT_ROLES.has(message.toolName)) return void 0;
24533
24536
  return {
24534
24537
  index,
24535
24538
  role,
@@ -24538,6 +24541,9 @@ function durableTerminalAt(entries, index) {
24538
24541
  message
24539
24542
  };
24540
24543
  }
24544
+ function isInvocationMarkerEntry(entry) {
24545
+ return entry?.type === "custom" && entry.customType === NAVIGATOR_INVOCATION_ENTRY;
24546
+ }
24541
24547
  function findLatestDurablePackagedRoleTerminal(entries) {
24542
24548
  for (let i = entries.length - 1; i >= 0; i -= 1) {
24543
24549
  const terminal = durableTerminalAt(entries, i);
@@ -24560,7 +24566,7 @@ var init_navigator_invocation_identity = __esm({
24560
24566
  "reasonCode"
24561
24567
  ];
24562
24568
  PACKAGED_ROLE_OUTPUT_TOOLS = new Map(
24563
- PACKAGED_ROLE_REGISTRY.map((entry) => [entry.outputTool, entry.role])
24569
+ [...PACKAGED_ROLE_REGISTRY.filter((entry) => entry.outputTool !== "ak_submission_output").map((entry) => [entry.outputTool, entry.role]), ...LEGACY_REVIEW_OUTPUT_ROLES]
24564
24570
  );
24565
24571
  }
24566
24572
  });
@@ -24689,7 +24695,10 @@ function roleOutcomeFromRows(role, rows) {
24689
24695
  role,
24690
24696
  status: "audit_escalation",
24691
24697
  payloads,
24692
- ...audited === void 0 ? {} : { decisiveFacts: { auditEscalationReceipt: audited.auditReceipt } }
24698
+ ...audited === void 0 ? {} : { decisiveFacts: {
24699
+ auditEscalationReceipt: audited.auditReceipt,
24700
+ ...Object.hasOwn(audited, "auditOfficer") ? { auditEscalationOfficer: audited.auditOfficer } : {}
24701
+ } }
24693
24702
  };
24694
24703
  }
24695
24704
  return { kind: "accepted", role, payloads };
@@ -26126,15 +26135,14 @@ async function settleLawfulSeatAcceptedTerminalResult(admitted, authority, spec,
26126
26135
  let thisAttemptHasSeatSuccess = false;
26127
26136
  let residual;
26128
26137
  for (let index = entries.length - 1; index >= scanStart; index -= 1) {
26138
+ const entry = entries[index];
26139
+ if (entry?.type === "custom" && entry.customType === "ak-role-submission-closure" && isRecord10(entry.data) && entry.data.toolName === spec.toolName && classifyPackagedRoleTerminalResult(entry.data).kind === "accepted") {
26140
+ thisAttemptHasSeatSuccess = true;
26141
+ }
26129
26142
  const message = entries[index]?.message;
26130
26143
  if (message?.role !== "toolResult") continue;
26131
26144
  if (message.toolName !== spec.toolName) continue;
26132
- if (message.isError === false) {
26133
- if (boundRoleToolCallForResult(entries, index, message, spec.toolName) !== void 0) {
26134
- thisAttemptHasSeatSuccess = true;
26135
- }
26136
- continue;
26137
- }
26145
+ if (message.isError === false) continue;
26138
26146
  if (residual === void 0) {
26139
26147
  residual = boundErroredToolCandidate(
26140
26148
  entries,
@@ -26145,7 +26153,7 @@ async function settleLawfulSeatAcceptedTerminalResult(admitted, authority, spec,
26145
26153
  }
26146
26154
  }
26147
26155
  const roleOutcome = await sealedLedgerOutcome(admitted, spec.role, scope);
26148
- if (roleOutcome !== void 0 && (thisAttemptHasSeatSuccess || residual === void 0)) {
26156
+ if (roleOutcome !== void 0 && (thisAttemptHasSeatSuccess || residual === void 0 || scope?.courtAttemptId !== void 0 && scope.courtAttemptId.length > 0)) {
26149
26157
  const navigator = extractNavigatorFact(entries);
26150
26158
  const artifacts = await publishDeclaredSeatArtifacts(
26151
26159
  admitted,
@@ -28655,7 +28663,7 @@ function isRecord11(value) {
28655
28663
  }
28656
28664
  function isEscalatePayload(payload) {
28657
28665
  if (!isRecord11(payload)) return false;
28658
- return payload.status === "escalate" || payload.countersignStatus === "escalate";
28666
+ return payload.status === "escalate";
28659
28667
  }
28660
28668
  function courtDiaristPayloadRows(roleOutcome, submissions) {
28661
28669
  if (roleOutcome === void 0) return submissions ?? [];
@@ -30887,8 +30895,8 @@ function emptyAccum() {
30887
30895
  function absorbRound(accum, round) {
30888
30896
  accum.rounds += 1;
30889
30897
  accum.wallSum += round.officerWallMs;
30890
- if (round.status === "bounce") accum.bounceCount += 1;
30891
- if (round.status === "pass") accum.passCount += 1;
30898
+ if (round.status === "bounce" || round.status === "continue") accum.bounceCount += 1;
30899
+ if (round.status === "pass" || round.status === "converged") accum.passCount += 1;
30892
30900
  }
30893
30901
  function finishOfficer(officer, accum) {
30894
30902
  return {
@@ -986,7 +986,7 @@ const ROLE_COMMAND_HELP = {
986
986
  },
987
987
  inspector: {
988
988
  command: "inspector",
989
- summary: "Direct Inspector (台院) complexity and test-quality check; pass or bounce.",
989
+ summary: "Direct Inspector (台院) complexity and test-quality check; converged, continue, or escalate.",
990
990
  usage: ["ak-role inspector [options] [instruction]"],
991
991
  examples: [
992
992
  'ak-role inspector --attach ./change.patch "Review this material."',
@@ -1010,7 +1010,7 @@ const ROLE_COMMAND_HELP = {
1010
1010
  },
1011
1011
  auditor: {
1012
1012
  command: "auditor",
1013
- summary: "Direct Auditor (审刑院) compliance audit: pass, bounce, or escalate.",
1013
+ summary: "Direct Auditor (审刑院) compliance audit: converged, continue, or escalate.",
1014
1014
  usage: ["ak-role auditor --subject <judge|doctor> --source-run <runId@role|path> [options] [instruction]"],
1015
1015
  examples: [
1016
1016
  'ak-role auditor --subject judge --source-run 01abc…@judge --attach ./dossier "审:本 run 是否合规。"',
@@ -60,7 +60,10 @@ function roleOutcomeFromRows(role, rows) {
60
60
  const audited = terminal.slice().reverse().find((row) => row.kind === "audit-escalation" && Object.hasOwn(row, "auditReceipt"));
61
61
  return {
62
62
  kind: "audit_escalation", role, status: "audit_escalation", payloads,
63
- ...(audited === undefined ? {} : { decisiveFacts: { auditEscalationReceipt: audited.auditReceipt } }),
63
+ ...(audited === undefined ? {} : { decisiveFacts: {
64
+ auditEscalationReceipt: audited.auditReceipt,
65
+ ...(Object.hasOwn(audited, "auditOfficer") ? { auditEscalationOfficer: audited.auditOfficer } : {}),
66
+ } }),
64
67
  };
65
68
  }
66
69
  return { kind: "accepted", role, payloads };
@@ -2088,10 +2091,9 @@ async function settleLawfulSeatAcceptedTerminalResult(admitted, authority, spec,
2088
2091
  const entries = await readLawfulSettlementEntries(sessionFile) ?? [];
2089
2092
  const submissions = await recordedSubmissionPayloads(admitted, scope);
2090
2093
  // #843: collector shape (ledger closed first) plus current user-turn freshness.
2091
- // A lawful bound non-error seat toolResult (isError === false + one-to-one call
2092
- // bind, same grade as residual) means this turn sealed — a prior bounce residual
2093
- // in the same turn must not outrank it. Missing isError, unbound, or mis-bound
2094
- // results do not establish success and do not reject/abort. A current-attempt
2094
+ // Only the ledger-owned closure establishes this turn's success. A non-error
2095
+ // toolResult may be a candidate whose nested gate continued the conversation.
2096
+ // A current-attempt
2095
2097
  // residual without that success is this turn's own failure and must not be
2096
2098
  // masked by run-scoped stale acceptance (bare resume without courtAttemptId).
2097
2099
  // Same-turn accept-then-bounce keeps the success marker: terminal stays
@@ -2100,24 +2102,25 @@ async function settleLawfulSeatAcceptedTerminalResult(admitted, authority, spec,
2100
2102
  let thisAttemptHasSeatSuccess = false;
2101
2103
  let residual;
2102
2104
  for (let index = entries.length - 1; index >= scanStart; index -= 1) {
2105
+ const entry = entries[index];
2106
+ if (entry?.type === "custom" && entry.customType === "ak-role-submission-closure"
2107
+ && isRecord(entry.data) && entry.data.toolName === spec.toolName
2108
+ && classifyPackagedRoleTerminalResult(entry.data).kind === "accepted") {
2109
+ thisAttemptHasSeatSuccess = true;
2110
+ }
2103
2111
  const message = entries[index]?.message;
2104
2112
  if (message?.role !== "toolResult")
2105
2113
  continue;
2106
2114
  if (message.toolName !== spec.toolName)
2107
2115
  continue;
2108
- if (message.isError === false) {
2109
- if (boundRoleToolCallForResult(entries, index, message, spec.toolName) !==
2110
- undefined) {
2111
- thisAttemptHasSeatSuccess = true;
2112
- }
2116
+ if (message.isError === false)
2113
2117
  continue;
2114
- }
2115
2118
  if (residual === undefined) {
2116
2119
  residual = boundErroredToolCandidate(entries, index, message, spec.toolName);
2117
2120
  }
2118
2121
  }
2119
2122
  const roleOutcome = await sealedLedgerOutcome(admitted, spec.role, scope);
2120
- if (roleOutcome !== undefined && (thisAttemptHasSeatSuccess || residual === undefined)) {
2123
+ if (roleOutcome !== undefined && (thisAttemptHasSeatSuccess || residual === undefined || (scope?.courtAttemptId !== undefined && scope.courtAttemptId.length > 0))) {
2121
2124
  const navigator = extractNavigatorFact(entries);
2122
2125
  const artifacts = await publishDeclaredSeatArtifacts(admitted, roleOutcome, coordinates, entries);
2123
2126
  return withSubmissions(await withOptionalGateProjection({
@@ -0,0 +1,20 @@
1
+ /** One shared terminating receipt contract for review officers (#1028). */
2
+ import { Type } from "typebox";
3
+ import { openToolObject } from "./open-tool-schema.js";
4
+ import { withTerminatingOutputDeclarations } from "./package-contracts/terminating-infrastructure.js";
5
+ export const REVIEW_SUBMISSION_OUTPUT_TOOL_NAME = "ak_submission_output";
6
+ /** Open receipt: the queue reads only status; all other submitted fields ride unchanged. */
7
+ export const reviewSubmissionSchema = withTerminatingOutputDeclarations(openToolObject(Type.Object({
8
+ status: Type.Optional(Type.Unknown({
9
+ description: "converged | continue | escalate — 非三态时请重读后重交,勿改标。",
10
+ })),
11
+ findings: Type.Optional(Type.Unknown({ description: "审核发现,原样留存" })),
12
+ reason: Type.Optional(Type.Unknown({ description: "上呈理由" })),
13
+ violations: Type.Optional(Type.Unknown({ description: "违规条目" })),
14
+ conflicts: Type.Optional(Type.Unknown({ description: "待决冲突" })),
15
+ fix: Type.Optional(Type.Unknown({ description: "continue 时的补救说明;可写 summary 摘要,其余内容原样留存" })),
16
+ classes: Type.Optional(Type.Unknown({ description: "已裁决 finding 类;可说明 name、owner、boundary、disposition,原样留存" })),
17
+ note: Type.Optional(Type.Unknown({ description: "裁决附注" })),
18
+ evidence: Type.Optional(Type.Unknown({ description: "留存证据" })),
19
+ decisionGate: Type.Optional(Type.Unknown({ description: "需人权威处置的问题与选项;可说明 question、options,原样留存" })),
20
+ })));
@@ -1,7 +1,7 @@
1
1
  import { readableGateItem } from "./readable-gate-item.js";
2
2
  /**
3
3
  * Tool-result text the parent model sees (#753 / #750 evidence).
4
- * bounce | escalate → officer receipt verbatim (JSON when structured).
4
+ * continue | escalate → officer receipt verbatim (JSON when structured).
5
5
  * no_receipt → honest lifecycle fact. No findings rewrite, no「(无 findings)」.
6
6
  * #775: structured field content via readableGateItem (DRY with other gate seams).
7
7
  */
@@ -9,7 +9,7 @@ function serializeReceipt(receipt) {
9
9
  return readableGateItem(receipt);
10
10
  }
11
11
  function gatekeeperNonPassMessage(result) {
12
- if (result.status === "bounce" || result.status === "escalate") {
12
+ if (result.status === "continue" || result.status === "escalate") {
13
13
  return serializeReceipt(result.receipt);
14
14
  }
15
15
  if (result.status === "transport_failure") {
@@ -161,6 +161,7 @@ function rowFromPayload(kind, payload, accepted, roleFallback) {
161
161
  kind,
162
162
  accepted,
163
163
  ...(Object.hasOwn(payload, "auditReceipt") ? { auditReceipt: payload.auditReceipt } : {}),
164
+ ...(Object.hasOwn(payload, "auditOfficer") ? { auditOfficer: payload.auditOfficer } : {}),
164
165
  ...(typeof payload.toolCallId === "string" && payload.toolCallId.length > 0
165
166
  ? { toolCallId: payload.toolCallId }
166
167
  : {}),
@@ -445,7 +446,17 @@ export function createSubmissionLedgerHost(host, outputTools, failInfrastructure
445
446
  return {
446
447
  ...host,
447
448
  registerTool(tool) {
448
- const role = outputTools.get(tool.name);
449
+ const registeredRole = outputTools.get(tool.name);
450
+ let role;
451
+ if (typeof registeredRole === "string") {
452
+ role = registeredRole;
453
+ }
454
+ else if (registeredRole !== undefined) {
455
+ const activeRole = host.getFlag("ak-role");
456
+ role = typeof activeRole === "string" && registeredRole.includes(activeRole)
457
+ ? activeRole
458
+ : undefined;
459
+ }
449
460
  if (role === undefined)
450
461
  return host.registerTool(tool);
451
462
  host.registerTool({
@@ -526,11 +537,14 @@ export function createSubmissionLedgerHost(host, outputTools, failInfrastructure
526
537
  ...(audit !== undefined && (Object.hasOwn(audit, "receipt") || Object.hasOwn(audit, "conflicts"))
527
538
  ? { auditReceipt: Object.hasOwn(audit, "receipt") ? audit.receipt : audit.conflicts }
528
539
  : {}),
540
+ ...(audit !== undefined && Object.hasOwn(audit, "officer") ? { auditOfficer: audit.officer } : {}),
529
541
  });
530
542
  await projectClosure(closed, context);
531
543
  return result;
532
544
  }
533
- // Terminating-tool wrap records every call; terminate flag does not withhold params.
545
+ // A continuing gate leaves the candidate recorded but has not accepted it.
546
+ if (result.terminate === false)
547
+ return result;
534
548
  const closed = {
535
549
  role,
536
550
  kind: "accepted",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@akagilnc/pi-workflow-roles",
3
- "version": "0.1.4977",
3
+ "version": "0.1.4989",
4
4
  "description": "Soul-bound workflow roles for Pi",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",
@@ -16,7 +16,7 @@
16
16
  空 findings 是合法结果。completed testimony 的过程成本由 runtime 随后补入,不因
17
17
  候选交卷尚未包含该事实而拒绝。
18
18
 
19
- 合规则 `pass`;缺证或明确违反 Soul 则 `bounce`,逐条指出违反的条目以及你查到的原因;
19
+ 合规则 `converged`;缺证或明确违反 Soul 则 `continue`,逐条指出违反的条目以及你查到的原因;
20
20
  没有具体证据不得连续打回。
21
21
  冲突导致无法判断合规时,提交 `escalate` 并写明问题和可选项。
22
22
 
@@ -16,8 +16,8 @@
16
16
  存在尚未完成的已授权工作,以及据实提交 unfinished,本身均不构成违规;
17
17
  `prerequisite_unmet` 只在处置当下仍缺少已声明的前置产物、决定或状态,
18
18
  且该缺失使剩余派工当前无法合法执行时成立;声明和引用本身不能证明缺失或因果。
19
- 若卷宗可证 authority_violation 为假或与仍可合法执行的工作矛盾,则 bounce。
20
- unfinished 不自动获得 pass;其他 Soul/authority 违反仍照常处置。
19
+ 若卷宗可证 authority_violation 为假或与仍可合法执行的工作矛盾,则 continue。
20
+ unfinished 不自动获得 converged;其他 Soul/authority 违反仍照常处置。
21
21
 
22
22
  工作已完成但方法违规时,应如实交付完成结果、披露违规,只声明当前可证明的
23
23
  验证,不得声称 TDD 或先红后绿。
@@ -25,9 +25,9 @@ unfinished 不自动获得 pass;其他 Soul/authority 违反仍照常处置。
25
25
  复杂度:本次修改是否核过复杂度账(删码/简化优先、三问);该核未核,或核的结论有明确
26
26
  事实反证,均为缺证。
27
27
 
28
- 合规则 `pass`;缺证或明确违反事实 则 `bounce`,逐条指出违反的条目以及你查到的原因;
28
+ 合规则 `converged`;缺证或明确违反事实 则 `continue`,逐条指出违反的条目以及你查到的原因;
29
29
  没有具体证据不得连续打回。
30
- 已如实披露且不可逆的方法违规,不构成 bounce 理由——收卷,违规记录在案,处置权归大理寺。bounce 只用于当下可改的缺陷。
30
+ 已如实披露且不可逆的方法违规,不构成 continue 理由——收卷,违规记录在案,处置权归大理寺。continue 只用于当下可改的缺陷。
31
31
  冲突导致无法判断合规时,提交 `escalate` 并写明问题和可选项。
32
32
 
33
33
  输出调用 `ak_fixer_audit_decision`。