@akagilnc/pi-workflow-roles 0.1.4802 → 0.1.4874
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 +19434 -18218
- package/dist/analyst-book-key.js +63 -0
- package/dist/analyst-cohort.js +167 -0
- package/dist/analyst-entry.js +320 -0
- package/dist/analyst-index.js +247 -0
- package/dist/analyst-ledger.js +561 -0
- package/dist/analyst-median.js +16 -0
- package/dist/analyst-metric-families/acceptance-success-rework.js +249 -0
- package/dist/analyst-metric-families/b2-frame-buckets-actions.js +189 -0
- package/dist/analyst-metric-families/gate-cycles.js +77 -0
- package/dist/analyst-metric-families/leg-wall-clock.js +56 -0
- package/dist/analyst-metric-families/round-timeline.js +126 -0
- package/dist/analyst-metric-families.js +23 -0
- package/dist/analyst-metric-family.js +11 -0
- package/dist/analyst-model-groups.js +135 -0
- package/dist/analyst-page.js +182 -0
- package/dist/atomic-write.js +23 -0
- package/dist/auditor-soul.js +1 -1
- package/dist/countersign-contracts.js +0 -2
- package/dist/diarist-contracts.js +0 -1
- package/dist/doctor-contracts.js +2 -2
- package/dist/gatekeeper-role.js +15 -16
- package/dist/gleaner-left-contracts.js +0 -2
- package/dist/headless-host/production-host.js +16967 -15749
- package/dist/host-contracts.js +0 -4
- package/dist/inspector-contracts.js +0 -2
- package/dist/institutional-resolution.js +4 -2
- package/dist/merger-contracts.js +0 -2
- package/dist/migrate-book-topology.js +3908 -3089
- package/dist/navigator-public-session.js +4 -3
- package/dist/notary-contracts.js +0 -2
- package/dist/package-contracts/auditor-output.js +0 -1
- package/dist/package-contracts/collector-output.js +0 -2
- package/dist/package-contracts/fixer-output.js +0 -2
- package/dist/package-contracts/gatekeeper-output.js +0 -2
- package/dist/package-contracts/judge-output.js +0 -2
- package/dist/package-contracts/navigator-output.js +0 -2
- package/dist/package-contracts/reviewer-output.js +0 -2
- package/dist/package-contracts/terminating-tools.js +32 -92
- package/dist/package-contracts/worker-output.js +0 -4
- package/dist/packaged-role-registry.js +518 -36
- package/dist/pi/role-turn-host.js +2 -1
- package/dist/public-cli/analyst-run.js +185 -0
- package/dist/public-cli/cli.js +885 -0
- package/dist/public-cli/config.js +12 -9
- package/dist/public-cli/countersign-run.js +4 -311
- package/dist/public-cli/instruction-seat-run.js +628 -158
- package/dist/public-cli/invocation.js +806 -1550
- package/dist/public-cli/main.js +6962 -9882
- package/dist/public-cli/option-definitions.js +51 -99
- package/dist/public-cli/post-admission.js +30 -2
- package/dist/public-cli/run-lifecycle.js +234 -353
- package/dist/public-cli/seat-ticket-binding.js +6 -0
- package/dist/public-cli/settlement.js +261 -675
- package/dist/public-cli/turn-request.js +76 -0
- package/dist/public-role-summons.js +38 -112
- package/dist/role-activation-flags.js +23 -45
- package/dist/secretariat-contracts.js +0 -2
- package/dist/session-identity.js +17 -8
- package/dist/session-opening-materials.js +3 -2
- package/extensions/role-runtime.ts +6 -80
- package/package.json +1 -1
- package/src/acp-host/role-turn-host.ts +4 -1
- package/src/analyst-metric-families/acceptance-success-rework.ts +3 -2
- package/src/auditor-role.ts +1 -2
- package/src/auditor-soul.ts +1 -1
- package/src/collector-role.ts +2 -2
- package/src/countersign-contracts.ts +0 -1
- package/src/countersign-role.ts +1 -1
- package/src/diarist-contracts.ts +0 -1
- package/src/diarist-role.ts +0 -1
- package/src/doctor-auditor.ts +1 -2
- package/src/doctor-contracts.ts +1 -1
- package/src/doctor-role.ts +3 -2
- package/src/external-host-turn-loop.ts +1 -1
- package/src/factory-board.ts +10 -7
- package/src/gatekeeper-role.ts +16 -10
- package/src/gleaner-left-contracts.ts +0 -1
- package/src/gleaner-left-role.ts +0 -1
- package/src/headless-host/role-turn-host.ts +7 -1
- package/src/host-contracts.ts +10 -6
- package/src/inspector-contracts.ts +0 -1
- package/src/inspector-role.ts +0 -2
- package/src/institutional-resolution.ts +6 -4
- package/src/judge-role.ts +3 -3
- package/src/merger-contracts.ts +0 -1
- package/src/merger-role.ts +2 -2
- package/src/navigator-public-session.ts +7 -6
- package/src/navigator-work-context.ts +6 -8
- package/src/notary-contracts.ts +0 -1
- package/src/notary-role.ts +2 -3
- package/src/package-contracts/auditor-output.ts +0 -1
- package/src/package-contracts/collector-output.ts +0 -1
- package/src/package-contracts/fixer-output.ts +0 -1
- package/src/package-contracts/gatekeeper-output.ts +0 -1
- package/src/package-contracts/judge-output.ts +0 -1
- package/src/package-contracts/navigator-output.ts +0 -1
- package/src/package-contracts/reviewer-output.ts +0 -1
- package/src/package-contracts/terminating-tools.ts +27 -99
- package/src/package-contracts/worker-output.ts +0 -2
- package/src/packaged-role-registry.ts +604 -35
- package/src/pi/role-turn-host.ts +2 -1
- package/src/public-cli/cli.ts +64 -259
- package/src/public-cli/config.ts +18 -10
- package/src/public-cli/countersign-run.ts +14 -449
- package/src/public-cli/instruction-seat-run.ts +758 -277
- package/src/public-cli/invocation.ts +1097 -2051
- package/src/public-cli/option-definitions.ts +62 -127
- package/src/public-cli/post-admission.ts +47 -2
- package/src/public-cli/run-lifecycle.ts +303 -613
- package/src/public-cli/seat-ticket-binding.ts +6 -0
- package/src/public-cli/settlement.ts +399 -1185
- package/src/public-cli/turn-request.ts +92 -1
- package/src/public-role-summons.ts +44 -128
- package/src/reviewer-role.ts +3 -2
- package/src/role-activation-flags.ts +20 -41
- package/src/role-runtime-dependencies.ts +25 -26
- package/src/role-runtime.ts +121 -232
- package/src/secretariat-contracts.ts +0 -1
- package/src/secretariat-role.ts +0 -2
- package/src/session-identity.ts +23 -8
- package/src/session-opening-materials.ts +2 -1
- package/src/worker-role.ts +3 -4
- package/dist/doctor-auditor.js +0 -25
- package/dist/public-cli/diarist-run.js +0 -130
- package/dist/public-cli/doctor-run.js +0 -87
- package/dist/public-cli/inspector-run.js +0 -151
- package/dist/public-cli/judge-run.js +0 -114
- package/dist/public-cli/notary-run.js +0 -174
- package/dist/public-cli/reviewer-run.js +0 -339
- package/src/public-cli/coder-run.ts +0 -255
- package/src/public-cli/collector-run.ts +0 -189
- package/src/public-cli/diarist-run.ts +0 -233
- package/src/public-cli/doctor-run.ts +0 -167
- package/src/public-cli/fixer-run.ts +0 -265
- package/src/public-cli/gleaner-left-run.ts +0 -167
- package/src/public-cli/inspector-run.ts +0 -261
- package/src/public-cli/judge-run.ts +0 -196
- package/src/public-cli/merger-run.ts +0 -294
- package/src/public-cli/notary-run.ts +0 -279
- package/src/public-cli/reviewer-run.ts +0 -480
- package/src/public-cli/secretariat-run.ts +0 -265
package/src/diarist-role.ts
CHANGED
package/src/doctor-auditor.ts
CHANGED
|
@@ -10,8 +10,7 @@ import {
|
|
|
10
10
|
resolveAuditDossier,
|
|
11
11
|
} from "./dossier-resolution.ts";
|
|
12
12
|
import type { HostContext } from "./host-contracts.ts";
|
|
13
|
-
|
|
14
|
-
export const DOCTOR_AUDIT_TOOL_NAME = "ak_doctor_audit_decision";
|
|
13
|
+
export { DOCTOR_AUDIT_TOOL_NAME } from "./doctor-contracts.ts";
|
|
15
14
|
|
|
16
15
|
export type DoctorAuditOptions = {
|
|
17
16
|
context: HostContext;
|
package/src/doctor-contracts.ts
CHANGED
|
@@ -5,7 +5,7 @@ import { withTerminatingOutputDeclarations } from "./package-contracts/terminati
|
|
|
5
5
|
|
|
6
6
|
export const DOCTOR_EVIDENCE_TOOL_NAME = "ak_doctor_evidence";
|
|
7
7
|
export const DOCTOR_OUTPUT_TOOL_NAME = "ak_doctor_output";
|
|
8
|
-
export const
|
|
8
|
+
export const DOCTOR_AUDIT_TOOL_NAME = "ak_doctor_audit_decision";
|
|
9
9
|
export const DOCTOR_ACCEPTED_AUDIT_NO_RECEIPT_TEXT = "太医署回执已接受;审计无回执";
|
|
10
10
|
export const DOCTOR_OUTPUT_TOOL_DESCRIPTION = "提交唯一终局单案证词;completed 允许空 findings。";
|
|
11
11
|
export const DOCTOR_TARGET_KINDS = ["law", "gate", "template", "station", "seat"] as const;
|
package/src/doctor-role.ts
CHANGED
|
@@ -3,7 +3,8 @@ import { disposeComplianceDecision } from "./audit-escalation.ts";
|
|
|
3
3
|
import { ComplianceResponseRetentionError, type ComplianceDecision } from "./compliance-transport.ts";
|
|
4
4
|
import { GatekeeperDecisionError } from "./submission-errors.ts";
|
|
5
5
|
import { DOCTOR_CANDIDATE_ENTRY_TYPE } from "./dossier-resolution.ts";
|
|
6
|
-
import {
|
|
6
|
+
import { packagedRoleAcceptedText } from "./packaged-role-registry.ts";
|
|
7
|
+
import { DOCTOR_ACCEPTED_AUDIT_NO_RECEIPT_TEXT, DOCTOR_EVIDENCE_TOOL_NAME, DOCTOR_OUTPUT_TOOL_DESCRIPTION, DOCTOR_OUTPUT_TOOL_NAME, DoctorEvidenceStore, doctorEvidenceReadSchema, doctorSubmissionSchema, validateDoctorOutput, type DoctorCase } from "./doctor-contracts.ts";
|
|
7
8
|
|
|
8
9
|
import { sitianReport } from "./sitian-facade.ts";
|
|
9
10
|
|
|
@@ -36,7 +37,7 @@ export function createDoctorRoleRuntime(pi: RoleHost, dependencies: DoctorRoleDe
|
|
|
36
37
|
let activation: { soul: string; patient: DoctorCase; store: DoctorEvidenceStore } | undefined; let registered = false; pi.registerFlag(DOCTOR_CASE_FLAG.name, DOCTOR_CASE_FLAG.definition);
|
|
37
38
|
return { async activate() { const path = pi.getFlag(DOCTOR_CASE_FLAG.name); if (typeof path !== "string" || !path.trim()) throw new Error("Doctor requires --ak-doctor-case"); const soul = (await dependencies.loadSoul()).trim(); if (!soul) throw new Error("Doctor soul is empty"); const patient = await dependencies.loadCase(path); activation = { soul, patient, store: new DoctorEvidenceStore(patient) };
|
|
38
39
|
if (!registered) { registered = true; pi.registerTool({ name: DOCTOR_EVIDENCE_TOOL_NAME, label: "太医署证据", description: "分页读取留存的 Pi session 字节。", parameters: doctorEvidenceReadSchema, async execute(_id: string, params: { evidenceId: string; offset?: number; limit?: number }) { if (!activation) throw new Error("太医署未激活"); const details = activation.store.read(params.evidenceId, params.offset, params.limit); return { content: [{ type: "text" as const, text: JSON.stringify(details) }], details }; } });
|
|
39
|
-
pi.registerTool({ name: DOCTOR_OUTPUT_TOOL_NAME, label: "太医署输出", description: DOCTOR_OUTPUT_TOOL_DESCRIPTION, parameters: doctorSubmissionSchema, async execute(id: string, params: unknown, signal: AbortSignal | undefined, _update: unknown, ctx: HostContext): Promise<HostToolResult<unknown>> { if (!activation) throw new Error("太医署未激活"); const active = activation; const testimony = validateDoctorOutput(params, active.patient, active.store); try { appendCandidate(ctx, { version: 1, testimony, cost: active.patient.cost, readRecord: active.store.readRecord(), patientIdentity: active.patient.identity }); } catch (error) { host.failInfrastructure(error, ctx, id); } let audit: ComplianceDecision; try { audit = await dependencies.auditCompliance(signal === undefined ? { context: ctx } : { context: ctx, signal }); } catch (error) { host.failInfrastructure(error, ctx, id); } const acceptedDetails = testimony; return disposeComplianceDecision<HostToolResult<unknown>>(audit, { pass: (usage) => ({ content: [{ type: "text" as const, text:
|
|
40
|
+
pi.registerTool({ name: DOCTOR_OUTPUT_TOOL_NAME, label: "太医署输出", description: DOCTOR_OUTPUT_TOOL_DESCRIPTION, parameters: doctorSubmissionSchema, async execute(id: string, params: unknown, signal: AbortSignal | undefined, _update: unknown, ctx: HostContext): Promise<HostToolResult<unknown>> { if (!activation) throw new Error("太医署未激活"); const active = activation; const testimony = validateDoctorOutput(params, active.patient, active.store); try { appendCandidate(ctx, { version: 1, testimony, cost: active.patient.cost, readRecord: active.store.readRecord(), patientIdentity: active.patient.identity }); } catch (error) { host.failInfrastructure(error, ctx, id); } let audit: ComplianceDecision; try { audit = await dependencies.auditCompliance(signal === undefined ? { context: ctx } : { context: ctx, signal }); } catch (error) { host.failInfrastructure(error, ctx, id); } const acceptedDetails = testimony; return disposeComplianceDecision<HostToolResult<unknown>>(audit, { pass: (usage) => ({ content: [{ type: "text" as const, text: packagedRoleAcceptedText("doctor") }], details: acceptedDetails, terminate: true as const, ...(usage === undefined ? {} : { usage }) }), noReceipt: (auditNoReceipt, usageProjection) => { try { appendCandidate(ctx, { version: 1, testimony, cost: active.patient.cost, auditNoReceipt, readRecord: active.store.readRecord(), patientIdentity: active.patient.identity }); } catch (error) { host.failInfrastructure(error, ctx, id); } return { content: [{ type: "text" as const, text: DOCTOR_ACCEPTED_AUDIT_NO_RECEIPT_TEXT }], details: acceptedDetails, terminate: true as const, ...usageProjection }; }, received: () => { throw new Error("审刑院非三态应交 runComplianceAudit 重问说话者"); }, bounce: (violations) => { throw new GatekeeperDecisionError({ status: "bounce", officer: "auditor", receipt: violations }); }, escalate: (result) => result, transportFailure: (facts) => { host.failInfrastructure(Object.assign(new Error(facts.diagnostic), { name: "ComplianceTransportFailure", ...(facts.submissions === undefined && facts.terminal === undefined ? {} : { submission: facts.submissions ?? facts.terminal }) }), ctx, id); } }, acceptedDetails); } });
|
|
40
41
|
pi.on("before_agent_start", (event) => { if (!activation) throw new Error("太医署未激活"); const catalog = { version: activation.patient.version, identity: activation.patient.identity, admittedMetrics: { cost: activation.patient.cost }, lawfulTargetKeys: ["case", ...activation.patient.cost.invocations.sources], evidence: activation.patient.evidence.map(({ id, kind, sha256, byteLength, contentLength }) => ({ id, kind, sha256, byteLength, contentLength })) }; return { systemPrompt: `${event.systemPrompt}\n\n<doctor_soul>\n${activation.soul}\n</doctor_soul>\n\n<doctor_case>\n${JSON.stringify(catalog)}\n</doctor_case>` }; }); }
|
|
41
42
|
const required = [DOCTOR_EVIDENCE_TOOL_NAME, DOCTOR_OUTPUT_TOOL_NAME]; const names = pi.getAllTools().map((tool) => tool.name); for (const name of required) if (names.filter((item) => item === name).length !== 1) throw new Error(`Doctor required tool collision or missing: ${name}`); pi.setActiveTools(required); const active = pi.getActiveTools?.() ?? required; if (active.length !== 2 || !required.every((name) => active.includes(name))) throw new Error("Doctor active tool narrowing failed"); } };
|
|
42
43
|
}
|
|
@@ -9,7 +9,7 @@ import type {
|
|
|
9
9
|
RoleTurnRequest,
|
|
10
10
|
RoleTurnResult,
|
|
11
11
|
} from "./host-contracts.ts";
|
|
12
|
-
import { isOfficerReviewSeat } from "./
|
|
12
|
+
import { isOfficerReviewSeat } from "./packaged-role-registry.ts";
|
|
13
13
|
|
|
14
14
|
export const EXTERNAL_ROLE_TURN_ROUND_LIMIT = 8 as const;
|
|
15
15
|
|
package/src/factory-board.ts
CHANGED
|
@@ -20,6 +20,7 @@ import { randomUUID } from "node:crypto";
|
|
|
20
20
|
import { lstat, mkdir, realpath, rename, rm, writeFile } from "node:fs/promises";
|
|
21
21
|
import { basename, dirname, join, relative, resolve, sep } from "node:path";
|
|
22
22
|
|
|
23
|
+
import { packagedBoardPlacement } from "./packaged-role-registry.ts";
|
|
23
24
|
import {
|
|
24
25
|
formatDurationZh,
|
|
25
26
|
formatLocalDateTime,
|
|
@@ -187,16 +188,18 @@ function placeTicket(prepared: PreparedTicket): BoardPlacement {
|
|
|
187
188
|
const sorted = sortRunsByStart(prepared.runs);
|
|
188
189
|
const latest = sorted.at(-1)!;
|
|
189
190
|
if (latest.station === "unknown") return "unknown";
|
|
190
|
-
|
|
191
|
+
// ADR 0053: marshal-driven runs land in 尚书省. Marshal is not a packaged seat.
|
|
192
|
+
if (latest.station === "marshal") return "marshal";
|
|
193
|
+
const placement = packagedBoardPlacement(latest.station);
|
|
194
|
+
if (placement === "judge-history") {
|
|
191
195
|
// Unknown history never counts as construction evidence.
|
|
192
|
-
const started = sorted.some((run) =>
|
|
196
|
+
const started = sorted.some((run) => {
|
|
197
|
+
if (run.station === "unknown") return false;
|
|
198
|
+
return packagedBoardPlacement(run.station) !== "judge-history";
|
|
199
|
+
});
|
|
193
200
|
return started ? "marshal" : "court";
|
|
194
201
|
}
|
|
195
|
-
if (
|
|
196
|
-
if (latest.station === "fixer" || latest.station === "reviewer") return "marshal";
|
|
197
|
-
// ADR 0053: marshal-driven runs land in 尚书省 once the seat ships (station maps now).
|
|
198
|
-
if (latest.station === "marshal") return "marshal";
|
|
199
|
-
if (latest.station === "collector") return "collector";
|
|
202
|
+
if (placement !== undefined) return placement;
|
|
200
203
|
return `other:${latest.station}`;
|
|
201
204
|
}
|
|
202
205
|
|
package/src/gatekeeper-role.ts
CHANGED
|
@@ -2,6 +2,7 @@ import type { ExtensionContext } from "@earendil-works/pi-coding-agent";
|
|
|
2
2
|
import type { HostContext } from "./host-contracts.ts";
|
|
3
3
|
|
|
4
4
|
import { auditorRunDirectory } from "./auditor-dossier-tool.ts";
|
|
5
|
+
import { packagedGateDecision, packagedGateStageLabel } from "./packaged-role-registry.ts";
|
|
5
6
|
import type { NoReceiptLifecycleFacts } from "./receipt-delivery-policy.ts";
|
|
6
7
|
import { GatekeeperDecisionError } from "./submission-errors.ts";
|
|
7
8
|
import { INSPECTOR_OUTPUT_TOOL_NAME } from "./inspector-contracts.ts";
|
|
@@ -82,18 +83,21 @@ export type GatekeeperNonPassResult = Extract<
|
|
|
82
83
|
>;
|
|
83
84
|
|
|
84
85
|
function gateSeatLabel(stage: GateOfficer): string {
|
|
85
|
-
|
|
86
|
-
if (stage === "auditor") return "审刑院";
|
|
87
|
-
if (stage === "countersign") return "给事中";
|
|
88
|
-
return "符宝郎";
|
|
86
|
+
return packagedGateStageLabel(stage) ?? stage;
|
|
89
87
|
}
|
|
90
88
|
|
|
89
|
+
/** Subject kind → review officer. One table; default is notary. */
|
|
90
|
+
const GATE_OFFICER_BY_SUBJECT = {
|
|
91
|
+
worker_completion: "inspector",
|
|
92
|
+
judge_compliance: "auditor",
|
|
93
|
+
judge_draft: "notary",
|
|
94
|
+
countersign_verdict: "notary",
|
|
95
|
+
secretariat_verdict: "countersign",
|
|
96
|
+
} as const satisfies Record<GatekeeperSubject["kind"], GateOfficer>;
|
|
97
|
+
|
|
91
98
|
/** Subject kind → review officer (#753 countersign/notary, #756 judge/auditor + worker/inspector, #969 secretariat/countersign). */
|
|
92
99
|
export function gateOfficerForSubject(subject: GatekeeperSubject): GateOfficer {
|
|
93
|
-
|
|
94
|
-
if (subject.kind === "judge_compliance") return "auditor";
|
|
95
|
-
if (subject.kind === "secretariat_verdict") return "countersign";
|
|
96
|
-
return "notary";
|
|
100
|
+
return GATE_OFFICER_BY_SUBJECT[subject.kind];
|
|
97
101
|
}
|
|
98
102
|
|
|
99
103
|
export { GatekeeperDecisionError } from "./submission-errors.ts";
|
|
@@ -222,7 +226,7 @@ function projectOfficerDecision(
|
|
|
222
226
|
const record = readRecord(decision);
|
|
223
227
|
// 给事中: only countersignStatus, strict three-word map; never generic status,
|
|
224
228
|
// never unmapped raw word, never fallbackStatus (#969 / ADR 0040/0055).
|
|
225
|
-
if (officer === "countersign") {
|
|
229
|
+
if (packagedGateDecision(officer) === "countersign-status") {
|
|
226
230
|
const countersignStatus =
|
|
227
231
|
record !== undefined && typeof record.countersignStatus === "string"
|
|
228
232
|
? record.countersignStatus
|
|
@@ -417,7 +421,9 @@ export const COUNTERSIGN_CONCLUSION_REASK =
|
|
|
417
421
|
|
|
418
422
|
/** Pick the re-ask line for the officer under review. */
|
|
419
423
|
export function officerConclusionReask(officer: GateOfficer): string {
|
|
420
|
-
return officer === "countersign"
|
|
424
|
+
return packagedGateDecision(officer) === "countersign-status"
|
|
425
|
+
? COUNTERSIGN_CONCLUSION_REASK
|
|
426
|
+
: OFFICER_CONCLUSION_REASK;
|
|
421
427
|
}
|
|
422
428
|
|
|
423
429
|
/**
|
|
@@ -5,7 +5,6 @@
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
export const GLEANER_LEFT_OUTPUT_TOOL_NAME = "ak_gleaner_left_output";
|
|
8
|
-
export const GLEANER_LEFT_ACCEPTED_TEXT = "左拾遗回执已接受";
|
|
9
8
|
|
|
10
9
|
/** Internal transport: comparison-base revision for the unanchored merge-candidate diff. */
|
|
11
10
|
export const GLEANER_LEFT_BASE_FLAG = {
|
package/src/gleaner-left-role.ts
CHANGED
|
@@ -464,7 +464,13 @@ export function createHeadlessRoleTurnHost(config: HeadlessRoleTurnHostConfig):
|
|
|
464
464
|
let outcome: RoleTurnResult = failure("session", "HeadlessNoOutcome", "no-outcome");
|
|
465
465
|
try {
|
|
466
466
|
// Claude mints a package UUID for --session-id; codex waits for thread.started.
|
|
467
|
-
|
|
467
|
+
// Public explicit resume already read the stored native id. Auto-resume omits it.
|
|
468
|
+
const explicitHostSessionId = request.continuation.kind === "resume"
|
|
469
|
+
? request.continuation.hostSessionId
|
|
470
|
+
: undefined;
|
|
471
|
+
let sessionId = explicitHostSessionId !== undefined && explicitHostSessionId !== ""
|
|
472
|
+
? explicitHostSessionId
|
|
473
|
+
: await config.sessionIdentity.load(request.principal);
|
|
468
474
|
let sessionKind: "new" | "resume" =
|
|
469
475
|
request.continuation.kind === "resume" && sessionId !== undefined && sessionId !== ""
|
|
470
476
|
? "resume"
|
package/src/host-contracts.ts
CHANGED
|
@@ -140,7 +140,16 @@ export type RoleTurnActivation =
|
|
|
140
140
|
|
|
141
141
|
export type RoleTurnContinuation =
|
|
142
142
|
| { readonly kind: "initial"; readonly prompt: string }
|
|
143
|
-
| {
|
|
143
|
+
| {
|
|
144
|
+
readonly kind: "resume";
|
|
145
|
+
readonly prompt: string;
|
|
146
|
+
/**
|
|
147
|
+
* Stored native host session/thread id for a public explicit resume.
|
|
148
|
+
* Absent on in-call auto-resume and in-gate retries; those still load
|
|
149
|
+
* through the host adapter. Never the package run id.
|
|
150
|
+
*/
|
|
151
|
+
readonly hostSessionId?: string;
|
|
152
|
+
};
|
|
144
153
|
|
|
145
154
|
/** Seat model consumed by the turn host (provider/model/thinking). */
|
|
146
155
|
export type RoleTurnModelConfig = {
|
|
@@ -162,11 +171,6 @@ export type RoleTurnHostTransition = {
|
|
|
162
171
|
readonly priorNativePaths: readonly string[];
|
|
163
172
|
};
|
|
164
173
|
|
|
165
|
-
/** Gate review officers (台院 / 符宝郎 / 审刑院). Single authority for seat checks. */
|
|
166
|
-
export function isOfficerReviewSeat(role: string): boolean {
|
|
167
|
-
return role === "notary" || role === "inspector" || role === "auditor";
|
|
168
|
-
}
|
|
169
|
-
|
|
170
174
|
/** One main-session turn request over the host-neutral execution seam. */
|
|
171
175
|
export type RoleTurnRequest = {
|
|
172
176
|
readonly principal: DurablePrincipal;
|
package/src/inspector-role.ts
CHANGED
|
@@ -4,14 +4,12 @@ import { Type } from "typebox";
|
|
|
4
4
|
import { openToolObject } from "./open-tool-schema.ts";
|
|
5
5
|
import { withTerminatingOutputDeclarations } from "./package-contracts/terminating-infrastructure.ts";
|
|
6
6
|
import {
|
|
7
|
-
INSPECTOR_ACCEPTED_TEXT,
|
|
8
7
|
INSPECTOR_OUTPUT_TOOL_NAME,
|
|
9
8
|
validateRecordedInspectorOutput,
|
|
10
9
|
type InspectorOutput,
|
|
11
10
|
} from "./inspector-contracts.ts";
|
|
12
11
|
|
|
13
12
|
export {
|
|
14
|
-
INSPECTOR_ACCEPTED_TEXT,
|
|
15
13
|
INSPECTOR_OUTPUT_TOOL_NAME,
|
|
16
14
|
};
|
|
17
15
|
export { INSPECTOR_OUTPUT_TOOL_NAME as INSPECTOR_OUTPUT_TOOL };
|
|
@@ -5,10 +5,11 @@
|
|
|
5
5
|
* is the live public seat table (model/host/engine).
|
|
6
6
|
*/
|
|
7
7
|
import type {
|
|
8
|
-
GateOfficerSeat,
|
|
9
8
|
PublicCliConfig,
|
|
10
9
|
SeatModelConfig,
|
|
11
10
|
} from "./public-cli/config.ts";
|
|
11
|
+
import type { PublicConfigurableSeat } from "./public-cli/registry.ts";
|
|
12
|
+
import { packagedModelParent } from "./packaged-role-registry.ts";
|
|
12
13
|
import { seatModelOnly } from "./public-cli/registry.ts";
|
|
13
14
|
|
|
14
15
|
/**
|
|
@@ -29,16 +30,17 @@ export type ConfiguredProvinceOfficerResolution = {
|
|
|
29
30
|
*/
|
|
30
31
|
export function resolveConfiguredProvinceOfficer(
|
|
31
32
|
config: PublicCliConfig,
|
|
32
|
-
officer:
|
|
33
|
+
officer: PublicConfigurableSeat,
|
|
33
34
|
): ConfiguredProvinceOfficerResolution {
|
|
34
35
|
const ownModel = seatModelOnly(config.seats[officer]);
|
|
35
36
|
if (ownModel !== undefined) {
|
|
36
37
|
return { selection: ownModel, source: "persistent" };
|
|
37
38
|
}
|
|
38
|
-
|
|
39
|
+
const parent = packagedModelParent(officer);
|
|
40
|
+
if (parent === undefined) {
|
|
39
41
|
return { source: "unconfigured" };
|
|
40
42
|
}
|
|
41
|
-
const gatekeeperModel = seatModelOnly(config.seats
|
|
43
|
+
const gatekeeperModel = seatModelOnly(config.seats[parent]);
|
|
42
44
|
if (gatekeeperModel !== undefined) {
|
|
43
45
|
return { selection: gatekeeperModel, source: "inherit-gatekeeper" };
|
|
44
46
|
}
|
package/src/judge-role.ts
CHANGED
|
@@ -4,8 +4,8 @@ import { Type, type Static } from "typebox";
|
|
|
4
4
|
import { withTerminatingOutputDeclarations } from "./package-contracts/terminating-infrastructure.ts";
|
|
5
5
|
import { ParentQueueReaskError } from "./submission-errors.ts";
|
|
6
6
|
|
|
7
|
+
import { packagedRoleAcceptedText } from "./packaged-role-registry.ts";
|
|
7
8
|
import {
|
|
8
|
-
JUDGE_ACCEPTED_TEXT,
|
|
9
9
|
JUDGE_OUTPUT_TOOL_NAME,
|
|
10
10
|
validateAcceptedJudgeDetails,
|
|
11
11
|
type JudgeVerdict,
|
|
@@ -107,7 +107,7 @@ export function createJudgeRoleRuntime(
|
|
|
107
107
|
// Parent escalate → throw to caller as-is; officers do not attend (#753 / #756).
|
|
108
108
|
const verdict = validateVerdict(parameters);
|
|
109
109
|
return {
|
|
110
|
-
content: [{ type: "text" as const, text:
|
|
110
|
+
content: [{ type: "text" as const, text: packagedRoleAcceptedText("judge") }],
|
|
111
111
|
details: verdict,
|
|
112
112
|
terminate: true as const,
|
|
113
113
|
};
|
|
@@ -138,7 +138,7 @@ export function createJudgeRoleRuntime(
|
|
|
138
138
|
submission: parameters,
|
|
139
139
|
});
|
|
140
140
|
return {
|
|
141
|
-
content: [{ type: "text" as const, text:
|
|
141
|
+
content: [{ type: "text" as const, text: packagedRoleAcceptedText("judge") }],
|
|
142
142
|
details: verdict,
|
|
143
143
|
terminate: true as const,
|
|
144
144
|
};
|
package/src/merger-contracts.ts
CHANGED
|
@@ -34,7 +34,6 @@ export type MergerOutput =
|
|
|
34
34
|
| { status: "completed"; attemptId: string; report: string; mergeCommitId: string }
|
|
35
35
|
| { status: "escalate"; attemptId: string; diagnosis: string; report: string };
|
|
36
36
|
export const MERGER_OUTPUT_TOOL_NAME = "ak_merger_output";
|
|
37
|
-
export const MERGER_ACCEPTED_TEXT = "合并回执已接受";
|
|
38
37
|
|
|
39
38
|
const record = (v: unknown): v is Record<string, unknown> => typeof v === "object" && v !== null && !Array.isArray(v);
|
|
40
39
|
const blank = (v: unknown) => typeof v !== "string" || v.trim().length === 0;
|
package/src/merger-role.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { RoleHost, HostContext } from "./host-contracts.ts";
|
|
2
|
+
import { packagedRoleAcceptedText } from "./packaged-role-registry.ts";
|
|
2
3
|
import {
|
|
3
|
-
MERGER_ACCEPTED_TEXT,
|
|
4
4
|
MERGER_OUTPUT_TOOL_NAME,
|
|
5
5
|
mergerOutputSchema,
|
|
6
6
|
validateMergerInput,
|
|
@@ -40,7 +40,7 @@ export function createMergerRoleRuntime(pi: RoleHost, dependencies: MergerRoleDe
|
|
|
40
40
|
name: MERGER_OUTPUT_TOOL_NAME, label: "合并输出", description: "提交合并结果;输出分支为 completed 与 escalate。", promptSnippet: "提交合并结果", parameters: mergerOutputSchema,
|
|
41
41
|
async execute(_id: string, params: unknown, _signal: AbortSignal | undefined, _update: unknown, _ctx: HostContext) {
|
|
42
42
|
if (!activation) throw new Error("校书郎未激活");
|
|
43
|
-
return { content: [{ type: "text" as const, text:
|
|
43
|
+
return { content: [{ type: "text" as const, text: packagedRoleAcceptedText("merger") }], details: params, terminate: true as const };
|
|
44
44
|
},
|
|
45
45
|
});
|
|
46
46
|
pi.on("before_agent_start", (event) => {
|
|
@@ -22,6 +22,7 @@ import type { NoReceiptLifecycleFacts } from "./receipt-delivery-policy.ts";
|
|
|
22
22
|
import { runDirectoryFromHostContext, type HostContext } from "./host-contracts.ts";
|
|
23
23
|
import type { PublicSummonResult } from "./public-role-summons.ts";
|
|
24
24
|
import { CliUsageError } from "./public-cli/cli-errors.ts";
|
|
25
|
+
import { isNavigatorSeat } from "./packaged-role-registry.ts";
|
|
25
26
|
|
|
26
27
|
/**
|
|
27
28
|
* Ledger process home for navigator attendance: admitted HostContext.runDirectory
|
|
@@ -76,16 +77,16 @@ export function readNavigatorHostRunPointer(entries: readonly unknown[]): string
|
|
|
76
77
|
|
|
77
78
|
/**
|
|
78
79
|
* Typed preflight via public CLI load path: can this run reopen as navigator?
|
|
79
|
-
* CliUsageError (code AK_ROLE_USAGE) from
|
|
80
|
-
* unknown id
|
|
81
|
-
* Other throws propagate. Never reads stderr prose.
|
|
80
|
+
* CliUsageError (code AK_ROLE_USAGE) from loadResumablePublicRole means
|
|
81
|
+
* unknown id or principal unavailable — not resumable. Any other disk role
|
|
82
|
+
* is not this navigator host run. Other throws propagate. Never reads stderr prose.
|
|
82
83
|
*/
|
|
83
84
|
export async function navigatorHostRunResumable(home: string, runId: string): Promise<boolean> {
|
|
84
85
|
const { piDurablePrincipalAuthority } = await import("./pi/durable-principal.ts");
|
|
85
|
-
const {
|
|
86
|
+
const { loadResumablePublicRole } = await import("./public-cli/run-lifecycle.ts");
|
|
86
87
|
try {
|
|
87
|
-
const loaded = await
|
|
88
|
-
return loaded.admitted.role
|
|
88
|
+
const loaded = await loadResumablePublicRole(home, runId, piDurablePrincipalAuthority);
|
|
89
|
+
return isNavigatorSeat(loaded.admitted.role);
|
|
89
90
|
} catch (error) {
|
|
90
91
|
if (error instanceof CliUsageError) return false;
|
|
91
92
|
throw error;
|
|
@@ -17,7 +17,7 @@ import {
|
|
|
17
17
|
type NavigatorWorkContext,
|
|
18
18
|
} from "./navigator-attendance.ts";
|
|
19
19
|
import { loadNotarySourceRunLocator } from "./notary-source-run.ts";
|
|
20
|
-
import { packagedRoleInputFlag } from "./packaged-role-registry.ts";
|
|
20
|
+
import { packagedNavigatorSubject, packagedRoleInputFlag } from "./packaged-role-registry.ts";
|
|
21
21
|
import { loadAdmittedJudgeRequest } from "./public-cli/invocation.ts";
|
|
22
22
|
|
|
23
23
|
export type NavigatorWorkContextLoaderOptions = {
|
|
@@ -44,7 +44,8 @@ export async function loadNavigatorWorkContext(
|
|
|
44
44
|
options: NavigatorWorkContextLoaderOptions,
|
|
45
45
|
): Promise<NavigatorWorkContext> {
|
|
46
46
|
const reference = navigatorInputReference(options.getFlag, options.role);
|
|
47
|
-
const
|
|
47
|
+
const subjectMode = packagedNavigatorSubject(options.role);
|
|
48
|
+
const input = reference === undefined || subjectMode === "case" || subjectMode === "source-run"
|
|
48
49
|
? undefined
|
|
49
50
|
: await readFile(reference, "utf8");
|
|
50
51
|
const subjectRoot = subjectPath(reference ?? options.context.sessionManager.getSessionDir(), options.context.cwd);
|
|
@@ -53,12 +54,12 @@ export async function loadNavigatorWorkContext(
|
|
|
53
54
|
: navigatorSubjectKeyForInput(subjectRoot, reference, options.context.cwd);
|
|
54
55
|
let subject = input ?? `work subject: ${subjectKey}`;
|
|
55
56
|
let subjectProvenance: NavigatorSubjectProvenance = input === undefined ? "placeholder" : "role_input";
|
|
56
|
-
if (
|
|
57
|
+
if (subjectMode === "case" && reference !== undefined) {
|
|
57
58
|
const patient = await loadDoctorCase(reference);
|
|
58
59
|
subject = JSON.stringify({ identity: patient.identity, cost: patient.cost });
|
|
59
60
|
subjectProvenance = "role_input";
|
|
60
61
|
}
|
|
61
|
-
if (
|
|
62
|
+
if (subjectMode === "source-run" && reference !== undefined) {
|
|
62
63
|
const locator = await loadNotarySourceRunLocator(reference);
|
|
63
64
|
subject = JSON.stringify({ sourceRun: locator });
|
|
64
65
|
subjectProvenance = "role_input";
|
|
@@ -68,10 +69,7 @@ export async function loadNavigatorWorkContext(
|
|
|
68
69
|
const currentSessionDir = options.context.sessionManager.getSessionDir();
|
|
69
70
|
const isBoundPublicRun = publicRunDir !== undefined
|
|
70
71
|
&& resolve(currentSessionDir) === resolve(publicRunDir, "session");
|
|
71
|
-
if (
|
|
72
|
-
options.role === "judge" &&
|
|
73
|
-
isBoundPublicRun
|
|
74
|
-
) {
|
|
72
|
+
if (subjectMode === "public-instruction" && isBoundPublicRun) {
|
|
75
73
|
let admitted;
|
|
76
74
|
try {
|
|
77
75
|
admitted = await loadAdmittedJudgeRequest(publicRunDir);
|
package/src/notary-contracts.ts
CHANGED
|
@@ -9,7 +9,6 @@ import { openToolObject } from "./open-tool-schema.ts";
|
|
|
9
9
|
import { withTerminatingOutputDeclarations } from "./package-contracts/terminating-infrastructure.ts";
|
|
10
10
|
|
|
11
11
|
export const NOTARY_OUTPUT_TOOL_NAME = "ak_notary_output";
|
|
12
|
-
export const NOTARY_ACCEPTED_TEXT = "符宝郎回执已接受";
|
|
13
12
|
export const NOTARY_SOURCE_RUN_FLAG = {
|
|
14
13
|
name: "ak-notary-source-run",
|
|
15
14
|
definition: {
|
package/src/notary-role.ts
CHANGED
|
@@ -6,8 +6,8 @@ import type { RoleHost, HostContext, HostToolResult } from "./host-contracts.ts"
|
|
|
6
6
|
* This module keeps evidence assembly + projection only.
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
+
import { packagedRoleAcceptedText } from "./packaged-role-registry.ts";
|
|
9
10
|
import {
|
|
10
|
-
NOTARY_ACCEPTED_TEXT,
|
|
11
11
|
NOTARY_OUTPUT_TOOL_NAME,
|
|
12
12
|
NOTARY_SOURCE_RUN_FLAG,
|
|
13
13
|
NOTARY_TICKET_FLAG,
|
|
@@ -16,7 +16,6 @@ import {
|
|
|
16
16
|
} from "./notary-contracts.ts";
|
|
17
17
|
|
|
18
18
|
export {
|
|
19
|
-
NOTARY_ACCEPTED_TEXT,
|
|
20
19
|
NOTARY_OUTPUT_TOOL_NAME,
|
|
21
20
|
NOTARY_SOURCE_RUN_FLAG,
|
|
22
21
|
NOTARY_TICKET_FLAG,
|
|
@@ -171,7 +170,7 @@ export function createNotaryRoleRuntime(
|
|
|
171
170
|
// #753: handler only records — params as submitted, no findings/disposition rewrite.
|
|
172
171
|
// #541 infra declaration + sole-final barrier are ledger-owned (#575).
|
|
173
172
|
return {
|
|
174
|
-
content: [{ type: "text" as const, text:
|
|
173
|
+
content: [{ type: "text" as const, text: packagedRoleAcceptedText("notary") }],
|
|
175
174
|
details: parameters,
|
|
176
175
|
terminate: true as const,
|
|
177
176
|
};
|
|
@@ -8,7 +8,6 @@ import { openToolObject } from "../open-tool-schema.ts";
|
|
|
8
8
|
import { withTerminatingOutputDeclarations } from "./terminating-infrastructure.ts";
|
|
9
9
|
|
|
10
10
|
export const AUDITOR_OUTPUT_TOOL_NAME = "ak_auditor_output" as const;
|
|
11
|
-
export const AUDITOR_ACCEPTED_TEXT = "审刑院回执已接受";
|
|
12
11
|
|
|
13
12
|
export const auditorOutputSchema = withTerminatingOutputDeclarations(
|
|
14
13
|
openToolObject(
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
/** Package-owned Collector receipt leaf — no role registration surface. */
|
|
2
2
|
|
|
3
3
|
export const COLLECTOR_OUTPUT_TOOL = "ak_collector_output";
|
|
4
|
-
export const COLLECTOR_ACCEPTED_TEXT = "通进司回执已接受";
|
|
5
4
|
export const COLLECTOR_HOST = "github.com";
|
|
6
5
|
|
|
7
6
|
export type CollectorIdentityGroup = {
|
|
@@ -3,7 +3,6 @@ import { openToolObjectFromUnion } from "../open-tool-schema.ts";
|
|
|
3
3
|
import { withTerminatingOutputDeclarations } from "./terminating-infrastructure.ts";
|
|
4
4
|
|
|
5
5
|
export const FIXER_OUTPUT_TOOL_NAME = "ak_fixer_output";
|
|
6
|
-
export const FIXER_ACCEPTED_TEXT = "修内司回执已接受";
|
|
7
6
|
|
|
8
7
|
// #836 r16 class 1: these are LLM/human-read narrative content — the candidate
|
|
9
8
|
// row lands on the ledger as submitted (src/submission-ledger.ts:351-390) and no
|
|
@@ -9,7 +9,6 @@ import { openToolObject } from "../open-tool-schema.ts";
|
|
|
9
9
|
import { withTerminatingOutputDeclarations } from "./terminating-infrastructure.ts";
|
|
10
10
|
|
|
11
11
|
export const GATEKEEPER_OUTPUT_TOOL_NAME = "ak_gatekeeper_output";
|
|
12
|
-
export const GATEKEEPER_ACCEPTED_TEXT = "门下省决议已受理";
|
|
13
12
|
|
|
14
13
|
/** Same open decision shape the province uses inside audit sessions. */
|
|
15
14
|
export const gatekeeperDecisionSchema = openToolObject(
|
|
@@ -11,7 +11,6 @@ import { openToolObject } from "../open-tool-schema.ts";
|
|
|
11
11
|
import { withTerminatingOutputDeclarations } from "./terminating-infrastructure.ts";
|
|
12
12
|
|
|
13
13
|
export const NAVIGATOR_OUTPUT_TOOL_NAME = "ak_navigator_output";
|
|
14
|
-
export const NAVIGATOR_ACCEPTED_TEXT = "游奕使建议已受理";
|
|
15
14
|
|
|
16
15
|
export const navigatorOutputSchema = withTerminatingOutputDeclarations(
|
|
17
16
|
openToolObject(
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
/** Package-owned Reviewer intent — original role payload only (#836 删 8). */
|
|
2
2
|
|
|
3
3
|
export const REVIEWER_OUTPUT_TOOL_NAME = "ak_reviewer_output";
|
|
4
|
-
export const REVIEWER_ACCEPTED_TEXT = "御史台回执已接受";
|
|
5
4
|
|
|
6
5
|
/** Seat-owned per-lens finding body text (completeness / correctness). */
|
|
7
6
|
export type ReviewerAmendments = Readonly<
|