@akagilnc/pi-workflow-roles 0.1.5068 → 0.1.5096

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 (80) hide show
  1. package/dist/acp-host/production-host.js +429 -383
  2. package/dist/atomic-write.js +13 -19
  3. package/dist/auditor-soul.js +2 -1
  4. package/dist/compliance-transport.js +3 -2
  5. package/dist/countersign-contracts.js +2 -2
  6. package/dist/doctor-contracts.js +1 -1
  7. package/dist/gatekeeper-role.js +14 -35
  8. package/dist/headless-host/production-host.js +461 -415
  9. package/dist/inspector-contracts.js +5 -2
  10. package/dist/merger-contracts.js +1 -1
  11. package/dist/migrate-book-topology.js +49 -33
  12. package/dist/navigator-attendance.js +28 -143
  13. package/dist/navigator-invocation-identity.js +2 -0
  14. package/dist/navigator-public-session.js +13 -1
  15. package/dist/navigator-work-base.js +113 -0
  16. package/dist/notary-contracts.js +0 -2
  17. package/dist/open-tool-schema.js +4 -1
  18. package/dist/package-contracts/fixer-output.js +1 -1
  19. package/dist/package-contracts/gatekeeper-output.js +1 -1
  20. package/dist/package-contracts/judge-output.js +2 -2
  21. package/dist/package-contracts/navigator-output.js +1 -1
  22. package/dist/package-contracts/terminating-infrastructure.js +7 -4
  23. package/dist/packaged-role-registry.js +9 -5
  24. package/dist/public-cli/countersign-run.js +1 -1
  25. package/dist/public-cli/invocation.js +6 -3
  26. package/dist/public-cli/main.js +78 -41
  27. package/dist/public-cli/settlement.js +20 -1
  28. package/dist/receipt-delivery-policy.js +9 -2
  29. package/dist/review-submission.js +19 -8
  30. package/dist/submission-errors.js +17 -0
  31. package/dist/submission-ledger.js +18 -6
  32. package/docs/adr/0057-schema-narrowing-cuts-the-required-set-not-the-declared-set.md +9 -0
  33. package/extensions/role-runtime.ts +0 -27
  34. package/package.json +2 -1
  35. package/resources/836-deleted-machine-instruction-inventory.md +3 -3
  36. package/resources/collector-bot-handbook.md +4 -0
  37. package/resources/navigator-route-playbook.md +4 -6
  38. package/scripts/build-package.mjs +4 -0
  39. package/souls/coder-output-guide.md +1 -0
  40. package/src/auditor-soul.ts +2 -1
  41. package/src/collector-role.ts +6 -7
  42. package/src/collector-tool-schemas.ts +5 -5
  43. package/src/compliance-transport.ts +3 -2
  44. package/src/countersign-contracts.ts +2 -2
  45. package/src/countersign-role.ts +3 -7
  46. package/src/diarist-role.ts +2 -2
  47. package/src/doctor-contracts.ts +1 -1
  48. package/src/gatekeeper-role.ts +15 -36
  49. package/src/gleaner-left-role.ts +2 -2
  50. package/src/inspector-contracts.ts +5 -2
  51. package/src/inspector-role.ts +1 -1
  52. package/src/judge-role.ts +14 -22
  53. package/src/merger-contracts.ts +1 -1
  54. package/src/navigator-attendance.ts +38 -164
  55. package/src/navigator-invocation-identity.ts +2 -0
  56. package/src/navigator-public-session.ts +17 -1
  57. package/src/navigator-role.ts +4 -0
  58. package/src/navigator-session-contracts.ts +2 -0
  59. package/src/navigator-work-base.ts +123 -0
  60. package/src/notary-contracts.ts +0 -4
  61. package/src/open-tool-schema.ts +9 -4
  62. package/src/package-contracts/fixer-output.ts +1 -1
  63. package/src/package-contracts/gatekeeper-output.ts +3 -3
  64. package/src/package-contracts/judge-output.ts +2 -4
  65. package/src/package-contracts/navigator-output.ts +1 -1
  66. package/src/package-contracts/terminating-infrastructure.ts +12 -10
  67. package/src/packaged-role-registry.ts +5 -1
  68. package/src/public-cli/countersign-run.ts +1 -1
  69. package/src/public-cli/invocation.ts +6 -3
  70. package/src/public-cli/settlement.ts +21 -0
  71. package/src/receipt-delivery-policy.ts +9 -1
  72. package/src/review-submission.ts +24 -10
  73. package/src/reviewer-role.ts +3 -3
  74. package/src/role-runtime-dependencies.ts +1 -5
  75. package/src/role-runtime.ts +61 -63
  76. package/src/secretariat-role.ts +3 -3
  77. package/src/submission-errors.ts +16 -0
  78. package/src/submission-gate.ts +2 -1
  79. package/src/submission-ledger.ts +23 -11
  80. package/src/worker-role.ts +7 -9
@@ -1,23 +1,17 @@
1
- /**
2
- * Same-directory temp + rename atomic file replace.
3
- * Shared primitive for ledger-adjacent typed pages (analyst metrics, etc.).
4
- * Does not open/truncate an existing destination inode, so hard-linked twins
5
- * keep prior bytes until the directory entry is swapped.
6
- * Parent directory must already exist — callers that write under the package
7
- * ledger home own confinement via ensureRealDirectoryTree (ADR 0038).
8
- */
9
1
  import { randomUUID } from "node:crypto";
10
2
  import { rename, rm, writeFile } from "node:fs/promises";
11
3
  import { dirname, join } from "node:path";
12
- export async function writeFileAtomically(destination, contents) {
13
- const parent = dirname(destination);
14
- const temporary = join(parent, `.atomic-write-${randomUUID()}.tmp`);
15
- try {
16
- await writeFile(temporary, contents);
17
- await rename(temporary, destination);
18
- }
19
- catch (error) {
20
- await rm(temporary, { force: true }).catch(() => undefined);
21
- throw error;
22
- }
4
+ async function writeFileAtomically(destination, contents) {
5
+ const parent = dirname(destination);
6
+ const temporary = join(parent, `.atomic-write-${randomUUID()}.tmp`);
7
+ try {
8
+ await writeFile(temporary, contents);
9
+ await rename(temporary, destination);
10
+ } catch (error) {
11
+ await rm(temporary, { force: true }).catch(() => void 0);
12
+ throw error;
13
+ }
23
14
  }
15
+ export {
16
+ writeFileAtomically
17
+ };
@@ -36,8 +36,9 @@ export const AUDITOR_SESSION_MATERIALS = {
36
36
  "souls/judge-auditor.md",
37
37
  "souls/audit-law.md",
38
38
  "souls/quality-law.md",
39
+ "docs/adr/0057-schema-narrowing-cuts-the-required-set-not-the-declared-set.md",
39
40
  ],
40
- doctor: ["CLAUDE.md", "souls/doctor-auditor.md"],
41
+ doctor: ["CLAUDE.md", "souls/doctor-auditor.md", "docs/adr/0057-schema-narrowing-cuts-the-required-set-not-the-declared-set.md"],
41
42
  };
42
43
  export function isAuditorSoulRole(value) {
43
44
  return typeof value === "string" && Object.hasOwn(AUDITOR_SESSION_MATERIALS, value);
@@ -1,5 +1,6 @@
1
1
  import { auditorRunDirectory } from "./auditor-dossier-tool.js";
2
- import { OFFICER_CONCLUSION_REASK } from "./gatekeeper-role.js";
2
+ import { officerConclusionReask } from "./gatekeeper-role.js";
3
+ import { receivedDiscriminator } from "./submission-errors.js";
3
4
  import { coalesceSubmissionRows } from "./public-cli/terminal.js";
4
5
  import { readableGateItem } from "./readable-gate-item.js";
5
6
  const AUDITOR_DOSSIER_PROMPT = "\u5377\u5B97\u6307\u9488\uFF1A";
@@ -122,7 +123,7 @@ async function runComplianceAudit(options) {
122
123
  const summoned = await summon(subject, runDirectory, options.signal, reask, submission);
123
124
  const decision = await projectAuditorTerminal(summoned);
124
125
  if (decision.status === "received") {
125
- reask = OFFICER_CONCLUSION_REASK;
126
+ reask = officerConclusionReask(receivedDiscriminator(decision.reply, "status"));
126
127
  continue;
127
128
  }
128
129
  return decision;
@@ -1,4 +1,4 @@
1
- import { REVIEW_SUBMISSION_OUTPUT_TOOL_NAME } from "./review-submission.js";
1
+ import { REVIEW_QUEUE_STATUSES, REVIEW_SUBMISSION_OUTPUT_TOOL_NAME } from "./review-submission.js";
2
2
  const COUNTERSIGN_OUTPUT_TOOL_NAME = REVIEW_SUBMISSION_OUTPUT_TOOL_NAME;
3
3
  function validateRecordedCountersignOutput(verdict) {
4
4
  if (verdict === null || typeof verdict !== "object" || Array.isArray(verdict)) {
@@ -13,7 +13,7 @@ function validateRecordedCountersignOutput(verdict) {
13
13
  if (typeof status !== "string") {
14
14
  throw new Error("Countersign verdict has no execution discriminator");
15
15
  }
16
- if (["converged", "continue", "escalate"].includes(status)) {
16
+ if (REVIEW_QUEUE_STATUSES.has(status)) {
17
17
  return verdict;
18
18
  }
19
19
  throw new Error("Countersign verdict has no execution discriminator");
@@ -27,7 +27,7 @@ const finding = Type.Union([
27
27
  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 })
28
28
  ]);
29
29
  const caseIdentity = Type.Object({ issueNumber: Type.Optional(Type.Integer()), runsPath: nonblank }, { additionalProperties: true });
30
- 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";
30
+ const DOCTOR_STATUS_DESCRIPTION = "completed | refused\u3002completed \u5141\u8BB8\u7A7A findings\uFF1Brefused \u4EC5\u5F53\u8BC1\u636E\u4E0D\u8DB3\u4EE5\u652F\u6491\u5982\u5B9E\u6848\u8BC1\u8BCD";
31
31
  const doctorSubmissionVariants = Type.Union([
32
32
  Type.Object({
33
33
  status: Type.Unknown({ description: DOCTOR_STATUS_DESCRIPTION }),
@@ -1,9 +1,9 @@
1
1
  import { auditorRunDirectory } from "./auditor-dossier-tool.js";
2
2
  import { packagedGateStageLabel } from "./packaged-role-registry.js";
3
- import { GatekeeperDecisionError } from "./submission-errors.js";
3
+ import { GatekeeperDecisionError, receivedDiscriminator, unreadableDiscriminatorNotice } from "./submission-errors.js";
4
4
  import { INSPECTOR_OUTPUT_TOOL_NAME } from "./inspector-contracts.js";
5
- import { REVIEW_SUBMISSION_OUTPUT_TOOL_NAME } from "./review-submission.js";
6
- import { GATEKEEPER_OUTPUT_TOOL_NAME, gatekeeperDecisionSchema, gatekeeperOutputSchema, } from "./package-contracts/gatekeeper-output.js";
5
+ import { REVIEW_QUEUE_STATUSES, REVIEW_SUBMISSION_OUTPUT_TOOL_NAME } from "./review-submission.js";
6
+ import { GATEKEEPER_OUTPUT_TOOL_NAME, gatekeeperOutputSchema, } from "./package-contracts/gatekeeper-output.js";
7
7
  import { runIdFromRunDirectory } from "./run-terminal-artifacts.js";
8
8
  export const INSPECTOR_OUTPUT_TOOL = INSPECTOR_OUTPUT_TOOL_NAME;
9
9
  export const NOTARY_OUTPUT_TOOL = REVIEW_SUBMISSION_OUTPUT_TOOL_NAME;
@@ -31,24 +31,10 @@ export { GatekeeperDecisionError } from "./submission-errors.js";
31
31
  export const GATEKEEPER_TOOL_SPEC = {
32
32
  name: GATEKEEPER_OUTPUT_TOOL_NAME,
33
33
  label: "门下省决议",
34
- description: "门下省终局决议,状态为 dispatch 或 pass。",
34
+ description: "门下省终局决议。status 为 dispatch 或 pass。",
35
35
  promptSnippet: "门下省决议",
36
36
  parameters: gatekeeperOutputSchema,
37
37
  };
38
- function result(content, details) {
39
- return { content: [{ type: "text", text: content }], details };
40
- }
41
- /** Gatekeeper province decision tool — open transport; package-contract projection owns legality. */
42
- export function createGatekeeperOutputTool() {
43
- return {
44
- name: GATEKEEPER_OUTPUT_TOOL_NAME,
45
- description: "提交门下省派官决定。",
46
- parameters: gatekeeperDecisionSchema,
47
- async execute(_id, args) {
48
- return result(`已收 ${String(args?.status)}`, args);
49
- },
50
- };
51
- }
52
38
  function failureReason(error) {
53
39
  if (error instanceof AggregateError)
54
40
  return error.errors.map(failureReason).join("; ");
@@ -73,15 +59,9 @@ function readRecord(value) {
73
59
  * `fallbackStatus` is the terminal outcome.status when the receipt body has no status key
74
60
  * (keeps missing-args sentinel intact as the receipt).
75
61
  */
76
- /** Map the shared review verdict onto the gate queue words (#1028). */
62
+ /** Map the shared review verdict onto the gate queue words (#1028 / #1055). */
77
63
  function reviewQueueStatus(status) {
78
- if (status === "converged")
79
- return "converged";
80
- if (status === "continue")
81
- return "continue";
82
- if (status === "escalate")
83
- return "escalate";
84
- return undefined;
64
+ return REVIEW_QUEUE_STATUSES.has(status) ? status : undefined;
85
65
  }
86
66
  function projectOfficerDecision(officer, decision, fallbackStatus) {
87
67
  const receipt = retainedReceipt(decision);
@@ -95,7 +75,7 @@ function projectOfficerDecision(officer, decision, fallbackStatus) {
95
75
  if (queueStatus === "continue" || queueStatus === "escalate") {
96
76
  return { status: queueStatus, officer, receipt };
97
77
  }
98
- return { status: "needs_reask", officer, receipt };
78
+ return { status: "needs_reask", officer, receipt, receivedStatus: status };
99
79
  }
100
80
  /**
101
81
  * This-court officer payloads for the parent return path (#879).
@@ -209,22 +189,21 @@ function projectOfficerTerminal(officer, summoned) {
209
189
  // lacking its own status, never substitute for a missing receipt.
210
190
  return withOfficerRunId(projectOfficerPayloads(officer, thisCourt, outcome.status), summoned);
211
191
  }
192
+ const receipt = thisCourt.length > 0 ? thisCourt[thisCourt.length - 1] : retainedReceipt(outcome);
212
193
  return withOfficerRunId({
213
194
  status: "needs_reask",
214
195
  officer,
215
196
  // This-court receipt only (#879).
216
- receipt: thisCourt.length > 0 ? thisCourt[thisCourt.length - 1] : retainedReceipt(outcome),
197
+ receipt,
198
+ receivedStatus: receivedDiscriminator(receipt, "status"),
217
199
  }, summoned);
218
200
  }
219
201
  /**
220
- * Plain-language re-ask when the officer conclusion is not converged|continue|escalate.
221
- * Not a packaged engine handbook line (#755 exception for 读不出三态).
222
- * Every review officer uses the same `status` field and three queue words (#1028).
202
+ * Officer conclusion was missing or not a queue word (#1055).
203
+ * `received` is the status value only, not the rest of the receipt.
223
204
  */
224
- export const OFFICER_CONCLUSION_REASK = "上次交卷的 status 不是 converged、continue、escalate 三态之一。请重新输出,status 写明其一;continue 或 escalate 的话就是给对方看的原文。";
225
- /** Pick the re-ask line for the officer under review. */
226
- export function officerConclusionReask(officer) {
227
- return OFFICER_CONCLUSION_REASK;
205
+ export function officerConclusionReask(received) {
206
+ return unreadableDiscriminatorNotice("status", received);
228
207
  }
229
208
  /**
230
209
  * Summon (via injected seam) + project. Default summonGateOfficer drive lives