@akagilnc/pi-workflow-roles 0.1.3565 → 0.1.3621

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 (142) hide show
  1. package/README.md +4 -1
  2. package/README.zh-CN.md +1 -1
  3. package/dist/acp-host/production-host.js +18477 -8099
  4. package/dist/analyst-gate-cycles-read.js +387 -0
  5. package/dist/archivist-record-entry.js +22 -1
  6. package/dist/audit-escalation.js +6 -0
  7. package/dist/auditor-soul.js +74 -0
  8. package/dist/collector-config.js +86 -0
  9. package/dist/collector-evidence.js +316 -0
  10. package/dist/collector-github.js +527 -0
  11. package/dist/collector-ledger.js +853 -0
  12. package/dist/collector-tool-schemas.js +33 -0
  13. package/dist/compliance-transport.js +104 -52
  14. package/dist/diarist-contracts.js +72 -0
  15. package/dist/diarist-mechanical.js +411 -0
  16. package/dist/diarist-ticket-resolution.js +177 -0
  17. package/dist/diarist.js +311 -0
  18. package/dist/doctor-auditor.js +25 -0
  19. package/dist/doctor-contracts.js +2 -0
  20. package/dist/doctor-evidence.js +142 -0
  21. package/dist/gatekeeper-role.js +104 -81
  22. package/dist/host-transition-prior-native.js +78 -0
  23. package/dist/institutional-resolution.js +1 -95
  24. package/dist/judge-auditor.js +26 -0
  25. package/dist/ledger-session-read.js +227 -0
  26. package/dist/merger-git-state.js +78 -0
  27. package/dist/navigator-attendance.js +15 -7
  28. package/dist/navigator-public-session.js +170 -0
  29. package/dist/navigator-session-contracts.js +36 -40
  30. package/dist/notary-source-run.js +122 -0
  31. package/dist/package-contracts/auditor-output.js +66 -0
  32. package/dist/package-contracts/evidence-child-output.js +34 -0
  33. package/dist/package-contracts/judge-output.js +2 -0
  34. package/dist/package-contracts/terminating-tools.js +44 -3
  35. package/dist/package-resources/method-skill.js +254 -0
  36. package/dist/packaged-role-registry.js +56 -0
  37. package/dist/pi/durable-principal.js +61 -0
  38. package/dist/pi/in-process-session.js +25 -6
  39. package/dist/pi/known-failure.js +52 -0
  40. package/dist/pi/role-turn-host.js +430 -0
  41. package/dist/public-cli/auto-resume.js +414 -0
  42. package/dist/public-cli/cli-errors.js +8 -0
  43. package/dist/public-cli/cli-io.js +1 -0
  44. package/dist/public-cli/command-renderer.js +5 -0
  45. package/dist/public-cli/doctor-run.js +84 -0
  46. package/dist/public-cli/inspector-run.js +136 -0
  47. package/dist/public-cli/instruction-seat-run.js +256 -0
  48. package/dist/public-cli/invocation.js +2225 -0
  49. package/dist/public-cli/judge-run.js +118 -0
  50. package/dist/public-cli/load-production-acp-host.js +40 -0
  51. package/dist/public-cli/main.js +1511 -1124
  52. package/dist/public-cli/notary-run.js +161 -0
  53. package/dist/public-cli/option-definitions.js +1192 -0
  54. package/dist/public-cli/post-admission.js +667 -0
  55. package/dist/public-cli/public-run-credentials.js +49 -0
  56. package/dist/public-cli/registry.js +8 -2
  57. package/dist/public-cli/reviewer-dispatch-rejection.js +77 -0
  58. package/dist/public-cli/run-lifecycle.js +1344 -0
  59. package/dist/public-cli/seat-ticket-binding.js +113 -0
  60. package/dist/public-cli/settlement.js +3441 -0
  61. package/dist/public-cli/terminal.js +135 -0
  62. package/dist/public-cli/turn-request.js +25 -0
  63. package/dist/public-role-summons.js +301 -0
  64. package/dist/receipt-delivery-policy.js +10 -0
  65. package/dist/reviewer-child-executor.js +80 -8
  66. package/dist/reviewer-execution-ledger.js +2 -1
  67. package/dist/run-terminal-artifacts.js +195 -0
  68. package/dist/run-ticket-number.js +40 -0
  69. package/dist/session-assistant-usage.js +107 -0
  70. package/dist/shape-unreadable-failure.js +34 -0
  71. package/dist/submission-errors.js +3 -0
  72. package/dist/submission-ledger.js +388 -0
  73. package/dist/ticket-provenance-contracts.js +115 -0
  74. package/dist/ticket-provenance.js +340 -0
  75. package/extensions/role-runtime.ts +8 -0
  76. package/package.json +1 -1
  77. package/resources/diarist-collect.md +6 -10
  78. package/scripts/build-package.mjs +2 -1
  79. package/souls/diarist.md +9 -0
  80. package/souls/doctor-auditor.md +1 -0
  81. package/souls/evidence-child.md +1 -0
  82. package/src/acp-host/production-host.ts +4 -0
  83. package/src/acp-host/role-envelope.ts +4 -3
  84. package/src/acp-host/role-turn-host.ts +9 -1
  85. package/src/analyst-gate-cycles-read.ts +37 -2
  86. package/src/archivist-record-entry.ts +45 -1
  87. package/src/audit-escalation.ts +17 -0
  88. package/src/auditor-role.ts +22 -0
  89. package/src/auditor-soul.ts +42 -0
  90. package/src/compliance-transport.ts +177 -66
  91. package/src/diarist-contracts.ts +88 -0
  92. package/src/diarist-role.ts +60 -0
  93. package/src/diarist.ts +253 -179
  94. package/src/doctor-auditor.ts +10 -14
  95. package/src/doctor-contracts.ts +1 -0
  96. package/src/doctor-role.ts +2 -2
  97. package/src/evidence-child-role.ts +22 -0
  98. package/src/gatekeeper-pass-envelope.ts +109 -0
  99. package/src/gatekeeper-role.ts +145 -104
  100. package/src/host-contracts.ts +15 -2
  101. package/src/institutional-resolution.ts +8 -163
  102. package/src/judge-auditor.ts +10 -15
  103. package/src/judge-role.ts +8 -0
  104. package/src/navigator-attendance.ts +25 -9
  105. package/src/navigator-public-session.ts +217 -0
  106. package/src/navigator-session-contracts.ts +61 -54
  107. package/src/notary-source-run.ts +3 -1
  108. package/src/package-contracts/auditor-output.ts +82 -0
  109. package/src/package-contracts/evidence-child-output.ts +51 -0
  110. package/src/package-contracts/judge-output.ts +1 -0
  111. package/src/package-contracts/reviewer-output.ts +2 -2
  112. package/src/package-contracts/terminating-tools.ts +53 -3
  113. package/src/packaged-role-registry.ts +63 -0
  114. package/src/pi/adapter.ts +2 -1
  115. package/src/pi/in-process-session.ts +38 -12
  116. package/src/pi/role-turn-host.ts +42 -0
  117. package/src/public-cli/cli.ts +43 -6
  118. package/src/public-cli/countersign-run.ts +9 -129
  119. package/src/public-cli/diarist-run.ts +312 -0
  120. package/src/public-cli/instruction-seat-run.ts +289 -50
  121. package/src/public-cli/invocation.ts +87 -25
  122. package/src/public-cli/option-definitions.ts +79 -0
  123. package/src/public-cli/post-admission.ts +9 -3
  124. package/src/public-cli/registry.ts +7 -1
  125. package/src/public-cli/run-lifecycle.ts +53 -6
  126. package/src/public-cli/settlement.ts +170 -7
  127. package/src/public-cli/terminal.ts +4 -1
  128. package/src/public-role-summons.ts +431 -0
  129. package/src/receipt-delivery-policy.ts +10 -0
  130. package/src/reviewer-agent.ts +1 -1
  131. package/src/reviewer-child-executor.ts +114 -12
  132. package/src/reviewer-execution-ledger.ts +3 -2
  133. package/src/role-runtime.ts +275 -23
  134. package/src/session-assistant-usage.ts +119 -0
  135. package/src/session-opening-materials.ts +1 -1
  136. package/src/shape-unreadable-failure.ts +49 -0
  137. package/src/submission-errors.ts +3 -0
  138. package/src/ticket-provenance-contracts.ts +1 -0
  139. package/src/ticket-provenance.ts +0 -23
  140. package/dist/evidence-child-executor.js +0 -829
  141. package/src/diarist-llm-collector.ts +0 -324
  142. package/src/evidence-child-executor.ts +0 -1140
@@ -0,0 +1,33 @@
1
+ import { Type } from "typebox";
2
+ import { COLLECTOR_ELIGIBILITY_MS } from "./collector-evidence.js";
3
+ import { withInfrastructureFailureDeclaration } from "./package-contracts/terminating-infrastructure.js";
4
+ export const collectorObserveArgsSchema = Type.Object({}, { additionalProperties: false });
5
+ export const collectorRequestArgsSchema = Type.Object({
6
+ requestId: Type.String({ minLength: 1, description: "配置请求身份" }),
7
+ snapshotId: Type.String({ minLength: 1, description: "最新留存观察快照" }),
8
+ }, { additionalProperties: false });
9
+ export const collectorReadArgsSchema = Type.Object({
10
+ evidenceId: Type.String({ minLength: 1, description: "observe 返回的材料证据 id(evidenceId)" }),
11
+ }, { additionalProperties: false });
12
+ export const collectorWaitArgsSchema = Type.Object({
13
+ durationMs: Type.Integer({ minimum: 1, maximum: COLLECTOR_ELIGIBILITY_MS, description: "等待毫秒;单次上限五分钟且不超剩余资格" }),
14
+ }, { additionalProperties: false });
15
+ /**
16
+ * #641 chain①: the collector LLM does the splitting/classification (#245:
17
+ * 他自己就是llm为什么不能读不能拆). Findings are submitted as pointer refs into
18
+ * the stored evidence; the runtime enriches each with the machine pointer
19
+ * (repo/PR/comment id/url/author/kind/时间) and validates resolvability.
20
+ * Category is a short LLM classification label, never a body transcription.
21
+ */
22
+ export const collectorFindingArgsSchema = Type.Object({
23
+ evidenceId: Type.String({ minLength: 1, description: "observe 返回的材料证据 id(evidenceId)" }),
24
+ category: Type.Optional(Type.String({ minLength: 1, maxLength: 200, description: "该 finding 的简短归类标签;需要头部之外的正文时先用 ak_collector_read 开卷再判读,不得誊写评论正文" })),
25
+ }, { additionalProperties: false });
26
+ export const collectorOutputBaseSchema = Type.Object({
27
+ findings: Type.Optional(Type.Array(collectorFindingArgsSchema, {
28
+ description: "本次收集到的逐条 findings;零 finding 的模板通知不得进入。正常完工无 finding 时省略。",
29
+ })),
30
+ }, { additionalProperties: true, description: "正常完工提交空对象 {};仅在基础设施真实失败时才填写 infrastructureFailure,无失败时必须省略该字段。" });
31
+ /** Runtime owns the observed evidence; the model submits findings and signals sole-final submission. */
32
+ export const collectorOutputArgsSchema = withInfrastructureFailureDeclaration(collectorOutputBaseSchema);
33
+ collectorOutputArgsSchema.required = [];
@@ -1,8 +1,6 @@
1
1
  import { Type } from "typebox";
2
- import {
3
- executeAuditorChild
4
- } from "./evidence-child-executor.js";
5
- import { createAuditorDossierTool } from "./auditor-dossier-tool.js";
2
+ import { auditorRunDirectory } from "./auditor-dossier-tool.js";
3
+ import { retainedShapeUnreadable } from "./shape-unreadable-failure.js";
6
4
  class ComplianceCandidateUnreadableError extends Error {
7
5
  observation;
8
6
  candidate;
@@ -20,43 +18,39 @@ const AUDITOR_DOSSIER_PROMPT = "\u672C run \u5377\u5B97\u5DF2\u5C31\u7EEA\u3002"
20
18
  const nonblank = Type.String({ minLength: 1, pattern: "\\S" });
21
19
  const decisionGateSchema = Type.Object({ question: nonblank, options: Type.Array(nonblank, { minItems: 1 }) }, { additionalProperties: false });
22
20
  const complianceDecisionSchema = Type.Object({ status: Type.Unknown({ description: "pass | revise | escalate \u2014 \u5F62\u72B6\u6307\u5F15\uFF0C\u975E schema \u95F8" }), violations: Type.Array(nonblank, { description: "\u89C2\u5BDF\u5230\u7684\u5408\u89C4\u8FDD\u89C4" }), conflicts: Type.Array(nonblank, { description: "\u672A\u51B3\u6743\u5A01\u6216\u6267\u884C\u51B2\u7A81" }), decisionGate: Type.Union([decisionGateSchema, Type.Null()], { description: "\u5347\u7EA7\u95EE\u9898\u4E0E\u53EF\u9009\u9009\u9879" }) }, { additionalProperties: true, required: [] });
23
- function createComplianceDecisionTool(name, description) {
24
- return { name, description, parameters: complianceDecisionSchema, async execute(_id, params) {
25
- return { content: [{ type: "text", text: "\u5BA1\u8BA1\u51B3\u8BAE\u5DF2\u6536" }], details: params, terminate: true };
26
- } };
27
- }
28
21
  const COMPLIANCE_RESPONSE_ENTRY_TYPE = "ak_compliance_response";
29
22
  const AUDITOR_PARENT_ATTEMPT_BINDING_ENTRY_TYPE = "ak_auditor_parent_attempt_binding";
30
23
  const AUDITOR_COMPLIANCE_FAILURE_ENTRY_TYPE = "ak_auditor_compliance_failure";
31
- import { attachDirectErrnoCode, sitianReport } from "./sitian-facade.js";
32
24
  class ComplianceResponseRetentionError extends Error {
33
25
  constructor(message, options) {
34
26
  super(message, options);
35
27
  this.name = "ComplianceResponseRetentionError";
36
- attachDirectErrnoCode(this, options?.cause);
37
- }
38
- }
39
- function retainComplianceResponse(context, response) {
40
- try {
41
- sitianReport({
42
- level: "event",
43
- kind: "auditor",
44
- cwd: context.cwd,
45
- sessionParent: context.sessionManager.getSessionFile(),
46
- payload: { version: 1, response },
47
- source: "compliance-transport"
48
- });
49
- } catch (error) {
50
- throw new ComplianceResponseRetentionError(
51
- `compliance response retention failed: ${error instanceof Error ? error.message : String(error)}`,
52
- { cause: error }
53
- );
54
28
  }
55
29
  }
56
30
  function readListField(value) {
57
31
  return Array.isArray(value) ? value : value === void 0 ? [] : [value];
58
32
  }
33
+ function tryReadComplianceCandidate(arguments_, usage) {
34
+ if (typeof arguments_ !== "object" || arguments_ === null || Array.isArray(arguments_)) {
35
+ return void 0;
36
+ }
37
+ const args = arguments_;
38
+ const status = args.status;
39
+ if (status === "pass") return { status, ...usage === void 0 ? {} : { usage } };
40
+ if (status === "revise") return { status, violations: readListField(args.violations), ...usage === void 0 ? {} : { usage } };
41
+ if (status === "escalate") {
42
+ return {
43
+ status,
44
+ ...Object.hasOwn(args, "conflicts") ? { conflicts: args.conflicts } : {},
45
+ ...Object.hasOwn(args, "decisionGate") ? { decisionGate: args.decisionGate } : {},
46
+ ...usage === void 0 ? {} : { usage }
47
+ };
48
+ }
49
+ return void 0;
50
+ }
59
51
  function readComplianceCandidate(arguments_, usage) {
52
+ const projected = tryReadComplianceCandidate(arguments_, usage);
53
+ if (projected !== void 0) return projected;
60
54
  if (typeof arguments_ !== "object" || arguments_ === null || Array.isArray(arguments_)) {
61
55
  throw new ComplianceCandidateUnreadableError(
62
56
  { kind: "non-object-arguments", type: arguments_ === null ? "null" : Array.isArray(arguments_) ? "array" : typeof arguments_ },
@@ -64,38 +58,96 @@ function readComplianceCandidate(arguments_, usage) {
64
58
  usage
65
59
  );
66
60
  }
67
- const args = arguments_;
68
- const status = args.status;
69
- if (status === "pass") return { status, ...usage === void 0 ? {} : { usage } };
70
- if (status === "revise") return { status, violations: readListField(args.violations), ...usage === void 0 ? {} : { usage } };
71
- if (status === "escalate") return { status, ...Object.hasOwn(args, "conflicts") ? { conflicts: args.conflicts } : {}, ...Object.hasOwn(args, "decisionGate") ? { decisionGate: args.decisionGate } : {}, ...usage === void 0 ? {} : { usage } };
61
+ const status = arguments_.status;
72
62
  throw new ComplianceCandidateUnreadableError(
73
63
  { kind: "object-status-unreadable", status: status === void 0 ? "missing" : "unknown" },
74
64
  arguments_,
75
65
  usage
76
66
  );
77
67
  }
78
- async function runComplianceAudit(options) {
79
- const prompt = options.serializedInput ?? AUDITOR_DOSSIER_PROMPT;
80
- const receipt = await executeAuditorChild({
81
- tool: options.tool,
82
- dossierTool: createAuditorDossierTool(options.runDirectory),
83
- systemPrompt: options.systemPrompt,
84
- prompt,
85
- roleLabel: options.roleLabel,
86
- context: options.context,
87
- retainResponse: (response) => retainComplianceResponse(options.context, response),
88
- ...options.runDirectory === void 0 ? {} : { runDirectory: options.runDirectory },
89
- ...options.signal === void 0 ? {} : { signal: options.signal }
90
- });
91
- if (receipt.noReceiptLifecycle !== void 0) {
68
+ async function usageFromSummonedSession(summoned) {
69
+ const { usageFromPublicSummon } = await import("./session-assistant-usage.js");
70
+ return usageFromPublicSummon(summoned);
71
+ }
72
+ function observationFromUnreadableCandidate(candidate) {
73
+ if (typeof candidate !== "object" || candidate === null || Array.isArray(candidate)) {
74
+ return {
75
+ kind: "non-object-arguments",
76
+ type: candidate === null ? "null" : Array.isArray(candidate) ? "array" : typeof candidate
77
+ };
78
+ }
79
+ const status = candidate.status;
80
+ return {
81
+ kind: "object-status-unreadable",
82
+ status: status === void 0 ? "missing" : "unknown"
83
+ };
84
+ }
85
+ function unreadableDecision(candidate, usage) {
86
+ return {
87
+ status: "unreadable",
88
+ observation: observationFromUnreadableCandidate(candidate),
89
+ candidate,
90
+ ...usage === void 0 ? {} : { usage }
91
+ };
92
+ }
93
+ async function projectAuditorTerminal(summoned) {
94
+ const outcome = summoned.terminal?.roleOutcome;
95
+ if (outcome === void 0) {
96
+ throw new Error(`Auditor public summon produced no terminal (exit ${summoned.exitCode})`);
97
+ }
98
+ const usage = await usageFromSummonedSession(summoned);
99
+ if (outcome.kind === "no_receipt") {
100
+ const { status: _ignored, kind: _kind, role: _role, decisiveFacts: _facts, ...facts } = outcome;
92
101
  return {
93
102
  status: "no-receipt",
94
- ...receipt.noReceiptLifecycle,
95
- ...receipt.response.usage === void 0 ? {} : { usage: receipt.response.usage }
103
+ ...facts,
104
+ ...usage === void 0 ? {} : { usage }
96
105
  };
97
106
  }
98
- return readComplianceCandidate(receipt.decision, receipt.response.usage);
107
+ if (outcome.kind === "failure") {
108
+ const shape = retainedShapeUnreadable(outcome.decisiveFacts);
109
+ if (shape !== void 0) {
110
+ return unreadableDecision(shape.candidate, usage);
111
+ }
112
+ throw new Error(outcome.diagnostic);
113
+ }
114
+ if (outcome.kind === "accepted") {
115
+ const candidate = {
116
+ status: outcome.status,
117
+ ...outcome.decisiveFacts
118
+ };
119
+ const projected = tryReadComplianceCandidate(candidate, usage);
120
+ if (projected !== void 0) return projected;
121
+ return unreadableDecision(candidate, usage);
122
+ }
123
+ throw new Error("Auditor public summon returned unusable terminal kind");
124
+ }
125
+ async function runComplianceAudit(options) {
126
+ const runDirectory = options.runDirectory ?? auditorRunDirectory(options.context);
127
+ if (runDirectory === void 0) {
128
+ throw new Error("Compliance audit requires a parent run directory pointer");
129
+ }
130
+ const subject = options.subject;
131
+ const summon = options.summonAuditor ?? (async (auditSubject, sourceRunDirectory, auditSignal) => {
132
+ const { summonPublicRole } = await import("./public-role-summons.js");
133
+ const { homeFromRunDirectory } = await import("./activation-ledger-topology.js");
134
+ const home = homeFromRunDirectory(sourceRunDirectory);
135
+ return await summonPublicRole({
136
+ role: "auditor",
137
+ argv: [
138
+ "--subject",
139
+ auditSubject,
140
+ "--source-run",
141
+ sourceRunDirectory,
142
+ AUDITOR_DOSSIER_PROMPT
143
+ ],
144
+ cwd: options.context.cwd ?? process.cwd(),
145
+ home,
146
+ ...auditSignal === void 0 ? {} : { signal: auditSignal }
147
+ });
148
+ });
149
+ const summoned = await summon(subject, runDirectory, options.signal);
150
+ return await projectAuditorTerminal(summoned);
99
151
  }
100
152
  export {
101
153
  AUDITOR_COMPLIANCE_FAILURE_ENTRY_TYPE,
@@ -105,7 +157,7 @@ export {
105
157
  ComplianceCandidateUnreadableError,
106
158
  ComplianceResponseRetentionError,
107
159
  complianceDecisionSchema,
108
- createComplianceDecisionTool,
109
160
  readComplianceCandidate,
110
- runComplianceAudit
161
+ runComplianceAudit,
162
+ tryReadComplianceCandidate
111
163
  };
@@ -0,0 +1,72 @@
1
+ /**
2
+ * Public 起居郎 (diarist) terminating receipt contracts — ADR 0075 `diarist-is-role`.
3
+ * Lawful explicit release: completed, with empty or nonempty selections.
4
+ * Machine facts about the volume come from the mechanical sitian seam, never
5
+ * from model self-report (锚定宪法); this module owns the receipt shape only.
6
+ */
7
+ export const DIARIST_OUTPUT_TOOL_NAME = "ak_diarist_output";
8
+ export const DIARIST_ACCEPTED_TEXT = "起居郎回执已接受";
9
+ /** Internal transport: frozen candidate-catalog path for this turn's ticket. */
10
+ export const DIARIST_SOURCES_FLAG = {
11
+ name: "ak-diarist-sources",
12
+ definition: {
13
+ description: "Frozen per-ticket source catalog the diarist selects from",
14
+ type: "string",
15
+ },
16
+ };
17
+ export function validateRecordedDiaristOutput(value) {
18
+ if (value === null || typeof value !== "object" || Array.isArray(value)) {
19
+ throw new Error("Diarist output has no execution discriminator");
20
+ }
21
+ let status;
22
+ try {
23
+ status = value.status;
24
+ }
25
+ catch {
26
+ throw new Error("Diarist output has no execution discriminator");
27
+ }
28
+ if (status === "completed") {
29
+ return value;
30
+ }
31
+ throw new Error("Diarist output has no execution discriminator");
32
+ }
33
+ /**
34
+ * Lenient projection of submitted selections (第 0 条: shape is not an admission
35
+ * gate). Rows that carry no usable candidateIndex are dropped from the commit,
36
+ * never bounced back at the role.
37
+ */
38
+ export function projectDiaristSelections(value) {
39
+ const rows = value?.selections;
40
+ if (!Array.isArray(rows))
41
+ return [];
42
+ const out = [];
43
+ for (const row of rows) {
44
+ if (row === null || typeof row !== "object" || Array.isArray(row))
45
+ continue;
46
+ const record = row;
47
+ const index = record.candidateIndex;
48
+ if (typeof index !== "number" || !Number.isInteger(index) || index < 0)
49
+ continue;
50
+ const quotes = Array.isArray(record.quotes)
51
+ ? record.quotes.filter((q) => typeof q === "string" && q.length > 0)
52
+ : [];
53
+ out.push({
54
+ candidateIndex: index,
55
+ quotes,
56
+ ...(typeof record.note === "string" ? { note: record.note } : {}),
57
+ });
58
+ }
59
+ return out;
60
+ }
61
+ /** Machine-facing facts from an accepted receipt. Submitted rows retained as-is. */
62
+ export function diaristDecisiveFacts(output) {
63
+ const facts = { status: output.status };
64
+ const selections = output.selections;
65
+ if (Array.isArray(selections))
66
+ facts.selections = selections;
67
+ // Mechanical sitian facts recorded by the envelope at accept time.
68
+ const sitian = output.sitian;
69
+ if (sitian !== undefined)
70
+ facts.sitian = sitian;
71
+ return facts;
72
+ }