@akagilnc/pi-workflow-roles 0.1.3572 → 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.
- package/dist/acp-host/production-host.js +20239 -10556
- package/dist/analyst-gate-cycles-read.js +387 -0
- package/dist/archivist-record-entry.js +22 -1
- package/dist/audit-escalation.js +6 -0
- package/dist/auditor-soul.js +74 -0
- package/dist/collector-config.js +86 -0
- package/dist/collector-evidence.js +316 -0
- package/dist/collector-github.js +527 -0
- package/dist/collector-ledger.js +853 -0
- package/dist/collector-tool-schemas.js +33 -0
- package/dist/compliance-transport.js +104 -52
- package/dist/diarist-mechanical.js +411 -0
- package/dist/diarist-ticket-resolution.js +177 -0
- package/dist/diarist.js +311 -0
- package/dist/doctor-auditor.js +25 -0
- package/dist/doctor-contracts.js +2 -0
- package/dist/doctor-evidence.js +142 -0
- package/dist/gatekeeper-role.js +104 -81
- package/dist/host-transition-prior-native.js +78 -0
- package/dist/institutional-resolution.js +1 -95
- package/dist/judge-auditor.js +26 -0
- package/dist/ledger-session-read.js +227 -0
- package/dist/merger-git-state.js +78 -0
- package/dist/navigator-attendance.js +15 -7
- package/dist/navigator-public-session.js +170 -0
- package/dist/navigator-session-contracts.js +36 -40
- package/dist/notary-source-run.js +122 -0
- package/dist/package-contracts/auditor-output.js +66 -0
- package/dist/package-contracts/evidence-child-output.js +34 -0
- package/dist/package-contracts/judge-output.js +2 -0
- package/dist/package-contracts/terminating-tools.js +25 -2
- package/dist/package-resources/method-skill.js +254 -0
- package/dist/packaged-role-registry.js +36 -0
- package/dist/pi/durable-principal.js +61 -0
- package/dist/pi/in-process-session.js +25 -6
- package/dist/pi/known-failure.js +52 -0
- package/dist/pi/role-turn-host.js +430 -0
- package/dist/public-cli/auto-resume.js +414 -0
- package/dist/public-cli/cli-errors.js +8 -0
- package/dist/public-cli/cli-io.js +1 -0
- package/dist/public-cli/command-renderer.js +5 -0
- package/dist/public-cli/doctor-run.js +84 -0
- package/dist/public-cli/inspector-run.js +136 -0
- package/dist/public-cli/instruction-seat-run.js +256 -0
- package/dist/public-cli/invocation.js +2225 -0
- package/dist/public-cli/judge-run.js +118 -0
- package/dist/public-cli/load-production-acp-host.js +40 -0
- package/dist/public-cli/main.js +1140 -652
- package/dist/public-cli/notary-run.js +161 -0
- package/dist/public-cli/option-definitions.js +1192 -0
- package/dist/public-cli/post-admission.js +667 -0
- package/dist/public-cli/public-run-credentials.js +49 -0
- package/dist/public-cli/registry.js +4 -1
- package/dist/public-cli/reviewer-dispatch-rejection.js +77 -0
- package/dist/public-cli/run-lifecycle.js +1344 -0
- package/dist/public-cli/seat-ticket-binding.js +113 -0
- package/dist/public-cli/settlement.js +3441 -0
- package/dist/public-cli/terminal.js +135 -0
- package/dist/public-cli/turn-request.js +25 -0
- package/dist/public-role-summons.js +301 -0
- package/dist/receipt-delivery-policy.js +10 -0
- package/dist/reviewer-child-executor.js +80 -8
- package/dist/reviewer-execution-ledger.js +2 -1
- package/dist/run-terminal-artifacts.js +195 -0
- package/dist/run-ticket-number.js +40 -0
- package/dist/session-assistant-usage.js +107 -0
- package/dist/shape-unreadable-failure.js +34 -0
- package/dist/submission-errors.js +3 -0
- package/dist/submission-ledger.js +388 -0
- package/dist/ticket-provenance-contracts.js +115 -0
- package/dist/ticket-provenance.js +340 -0
- package/extensions/role-runtime.ts +7 -0
- package/package.json +1 -1
- package/scripts/build-package.mjs +2 -1
- package/souls/doctor-auditor.md +1 -0
- package/souls/evidence-child.md +1 -0
- package/src/acp-host/production-host.ts +3 -0
- package/src/acp-host/role-envelope.ts +2 -2
- package/src/acp-host/role-turn-host.ts +9 -1
- package/src/analyst-gate-cycles-read.ts +37 -2
- package/src/archivist-record-entry.ts +45 -1
- package/src/audit-escalation.ts +17 -0
- package/src/auditor-role.ts +22 -0
- package/src/auditor-soul.ts +42 -0
- package/src/compliance-transport.ts +177 -66
- package/src/doctor-auditor.ts +10 -14
- package/src/doctor-contracts.ts +1 -0
- package/src/doctor-role.ts +2 -2
- package/src/evidence-child-role.ts +22 -0
- package/src/gatekeeper-pass-envelope.ts +109 -0
- package/src/gatekeeper-role.ts +145 -104
- package/src/host-contracts.ts +9 -1
- package/src/institutional-resolution.ts +8 -163
- package/src/judge-auditor.ts +10 -15
- package/src/judge-role.ts +8 -0
- package/src/navigator-attendance.ts +25 -9
- package/src/navigator-public-session.ts +217 -0
- package/src/navigator-session-contracts.ts +61 -54
- package/src/notary-source-run.ts +3 -1
- package/src/package-contracts/auditor-output.ts +82 -0
- package/src/package-contracts/evidence-child-output.ts +51 -0
- package/src/package-contracts/judge-output.ts +1 -0
- package/src/package-contracts/reviewer-output.ts +2 -2
- package/src/package-contracts/terminating-tools.ts +31 -1
- package/src/packaged-role-registry.ts +43 -0
- package/src/pi/adapter.ts +2 -1
- package/src/pi/in-process-session.ts +38 -12
- package/src/pi/role-turn-host.ts +34 -0
- package/src/public-cli/cli.ts +14 -6
- package/src/public-cli/instruction-seat-run.ts +289 -50
- package/src/public-cli/invocation.ts +66 -25
- package/src/public-cli/option-definitions.ts +61 -0
- package/src/public-cli/post-admission.ts +7 -1
- package/src/public-cli/registry.ts +4 -1
- package/src/public-cli/run-lifecycle.ts +22 -3
- package/src/public-cli/settlement.ts +120 -5
- package/src/public-cli/terminal.ts +2 -0
- package/src/public-role-summons.ts +431 -0
- package/src/receipt-delivery-policy.ts +10 -0
- package/src/reviewer-agent.ts +1 -1
- package/src/reviewer-child-executor.ts +114 -12
- package/src/reviewer-execution-ledger.ts +3 -2
- package/src/role-runtime.ts +158 -17
- package/src/session-assistant-usage.ts +119 -0
- package/src/session-opening-materials.ts +1 -1
- package/src/shape-unreadable-failure.ts +49 -0
- package/src/submission-errors.ts +3 -0
- package/dist/evidence-child-executor.js +0 -829
- package/src/evidence-child-executor.ts +0 -1140
|
@@ -16,7 +16,7 @@ import {
|
|
|
16
16
|
resolveActivationLedgerHome,
|
|
17
17
|
} from "./activation-ledger-topology.ts";
|
|
18
18
|
import type { HostContext } from "./host-contracts.ts";
|
|
19
|
-
import { createNativeNavigatorSessionFactory } from "./
|
|
19
|
+
import { createNativeNavigatorSessionFactory } from "./navigator-public-session.ts";
|
|
20
20
|
import {
|
|
21
21
|
NAVIGATOR_DEFAULT_MODEL,
|
|
22
22
|
NAVIGATOR_PREPARE_TOOL_NAME,
|
|
@@ -78,7 +78,9 @@ export function resolveNavigatorAuthorityMaterial(
|
|
|
78
78
|
return undefined;
|
|
79
79
|
}
|
|
80
80
|
|
|
81
|
-
|
|
81
|
+
/** Every public role is a lawful navigator route target (#675 — no nested-only seats). */
|
|
82
|
+
export const NAVIGATOR_TARGETS = PACKAGED_ROLE_REGISTRY
|
|
83
|
+
.map(({ role, phases }) => ({ role, phases }));
|
|
82
84
|
|
|
83
85
|
export type NavigatorTargetRole = PackagedRole;
|
|
84
86
|
export type NavigatorPhase = "plan" | "apply" | null;
|
|
@@ -591,11 +593,7 @@ export function createNavigatorAttendance(options: NavigatorAttendanceOptions) {
|
|
|
591
593
|
const modelPromise = (async () => {
|
|
592
594
|
try {
|
|
593
595
|
// Same resolution authority as createNativeNavigatorSessionFactory (#590).
|
|
594
|
-
const resolved = await resolveNavigatorSeatSelection(
|
|
595
|
-
options.context,
|
|
596
|
-
options.modelSettingPath,
|
|
597
|
-
options.modelSettingPath ?? navigatorModelSettingPath(),
|
|
598
|
-
);
|
|
596
|
+
const resolved = await resolveNavigatorSeatSelection(options.context);
|
|
599
597
|
return resolved.configuredLabel;
|
|
600
598
|
} catch (error) {
|
|
601
599
|
if (error instanceof NavigatorUnavailableError) throw error;
|
|
@@ -735,6 +733,14 @@ export function createNavigatorAttendance(options: NavigatorAttendanceOptions) {
|
|
|
735
733
|
return;
|
|
736
734
|
}
|
|
737
735
|
if (promptFailure !== undefined) throw promptFailure;
|
|
736
|
+
const sessionNoReceipt = activeSession.noReceipt?.();
|
|
737
|
+
if (sessionNoReceipt !== undefined) {
|
|
738
|
+
// This session already settled without an accepted receipt on its own
|
|
739
|
+
// budget; one more prompt opens an independent summon, not a delivery
|
|
740
|
+
// request on the settled session (#675).
|
|
741
|
+
delivery.recordNestedNoReceipt(sessionNoReceipt);
|
|
742
|
+
return;
|
|
743
|
+
}
|
|
738
744
|
if (deliveryRequest && output === undefined) delivery.recordDeliveryRequest();
|
|
739
745
|
};
|
|
740
746
|
await promptAllowingRejectedPrepare(request, false);
|
|
@@ -831,6 +837,8 @@ export function createNavigatorAttendance(options: NavigatorAttendanceOptions) {
|
|
|
831
837
|
};
|
|
832
838
|
|
|
833
839
|
async function settleOnce(settlement: NavigatorSettlement): Promise<void> {
|
|
840
|
+
// Dispose during post-role grace must ignore late completion entirely (#675).
|
|
841
|
+
if (disposed) return;
|
|
834
842
|
const invocationId = activeInvocationId ?? invocationPrincipal;
|
|
835
843
|
let report: NavigatorReport;
|
|
836
844
|
if (settlement.kind === "human_decision" || settlement.kind === "role_infrastructure_failure") {
|
|
@@ -876,8 +884,10 @@ export function createNavigatorAttendance(options: NavigatorAttendanceOptions) {
|
|
|
876
884
|
// table. After selection (speculative or rebound), advice is passed
|
|
877
885
|
// through as-is (ADR 0010 / ADR 0061: caller may ignore).
|
|
878
886
|
if (selected?.candidate.next !== undefined && !selected.matchedToSettlement) {
|
|
887
|
+
if (disposed) return;
|
|
879
888
|
prepareBoundSettlement = settlement;
|
|
880
889
|
prepared = await prepare();
|
|
890
|
+
if (disposed) return;
|
|
881
891
|
selected = selectNavigatorCandidate(prepared, settlement);
|
|
882
892
|
}
|
|
883
893
|
// Budget exhaustion is affirmative typed no-advice; malformed submitted
|
|
@@ -933,10 +943,16 @@ export function createNavigatorAttendance(options: NavigatorAttendanceOptions) {
|
|
|
933
943
|
...(report.routePlaybookReadFailure === undefined ? {} : { routePlaybookReadFailure: report.routePlaybookReadFailure }),
|
|
934
944
|
...(report.arrivalMessage === undefined ? {} : { arrivalMessage: report.arrivalMessage }),
|
|
935
945
|
};
|
|
936
|
-
// Dispose during post-role grace must ignore late completion (ADR 0052 / #106).
|
|
946
|
+
// Dispose during post-role grace must ignore late completion (ADR 0052 / #106 / #675).
|
|
937
947
|
// Every settled disposition (recommendation | no-advice | unavailable | arrival) is affirmative.
|
|
938
|
-
|
|
948
|
+
// Only the disposed bit is typed authority to drop — never match free-text Error.message.
|
|
949
|
+
if (disposed) return;
|
|
950
|
+
try {
|
|
939
951
|
await options.onEvent(event, report);
|
|
952
|
+
} catch (error) {
|
|
953
|
+
// Race: dispose landed between the check and onEvent; drop only then.
|
|
954
|
+
if (disposed) return;
|
|
955
|
+
throw error;
|
|
940
956
|
}
|
|
941
957
|
preparation = undefined;
|
|
942
958
|
sessionReady = undefined;
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Navigator attendance session factory (#675 r3).
|
|
3
|
+
* Each prepare turn uses the public navigator activation path (summonPublicRole) —
|
|
4
|
+
* same seat table and shared envelope as `ak-role navigator`.
|
|
5
|
+
* Archivist createRecordSession only books route-memory nest under the parent;
|
|
6
|
+
* no openPiInProcessSession second lifecycle / no agentDir patch on the old path.
|
|
7
|
+
*/
|
|
8
|
+
import { sitianReport } from "./sitian-facade.ts";
|
|
9
|
+
import {
|
|
10
|
+
NavigatorUnavailableError,
|
|
11
|
+
navigatorProviderFailureFromDiagnostics,
|
|
12
|
+
navigatorProviderFailureFromError,
|
|
13
|
+
navigatorProviderFailureFromStatus,
|
|
14
|
+
navigatorUnavailableError,
|
|
15
|
+
parseNavigatorModelSetting,
|
|
16
|
+
resolveNavigatorSeatSelection,
|
|
17
|
+
type NavigatorProviderFailureFact,
|
|
18
|
+
type NavigatorSessionFactory,
|
|
19
|
+
} from "./navigator-session-contracts.ts";
|
|
20
|
+
import type { NoReceiptLifecycleFacts } from "./receipt-delivery-policy.ts";
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Classify public-navigator failure terminal from structured decisiveFacts only
|
|
24
|
+
* (httpStatus / diagnostics / secondaryEvidence on the terminal) — same fields
|
|
25
|
+
* settlement already stamps from typed HTTP observation / provider stop.
|
|
26
|
+
*/
|
|
27
|
+
function providerFailureFromPublicTerminal(outcome: {
|
|
28
|
+
readonly cause: string;
|
|
29
|
+
readonly diagnostic: string;
|
|
30
|
+
readonly decisiveFacts: Readonly<Record<string, unknown>>;
|
|
31
|
+
}): NavigatorProviderFailureFact {
|
|
32
|
+
const facts = outcome.decisiveFacts;
|
|
33
|
+
const secondary =
|
|
34
|
+
typeof facts.secondaryEvidence === "object" && facts.secondaryEvidence !== null
|
|
35
|
+
? (facts.secondaryEvidence as Record<string, unknown>)
|
|
36
|
+
: undefined;
|
|
37
|
+
const httpStatus =
|
|
38
|
+
typeof secondary?.httpStatus === "number"
|
|
39
|
+
? secondary.httpStatus
|
|
40
|
+
: typeof facts.httpStatus === "number"
|
|
41
|
+
? facts.httpStatus
|
|
42
|
+
: typeof facts.errorCode === "number"
|
|
43
|
+
? facts.errorCode
|
|
44
|
+
: undefined;
|
|
45
|
+
const fromStatus = navigatorProviderFailureFromStatus(httpStatus);
|
|
46
|
+
if (fromStatus !== undefined) return fromStatus;
|
|
47
|
+
const diagnostics = secondary?.diagnostics ?? facts.diagnostics;
|
|
48
|
+
const fromDiagnostics = navigatorProviderFailureFromDiagnostics(diagnostics);
|
|
49
|
+
if (fromDiagnostics !== undefined) return fromDiagnostics;
|
|
50
|
+
const fromCode = navigatorProviderFailureFromError({
|
|
51
|
+
code: secondary?.code ?? facts.errorCode,
|
|
52
|
+
});
|
|
53
|
+
if (fromCode !== undefined) return fromCode;
|
|
54
|
+
if (outcome.cause === "provider") return { source: "transport", cause: "transport" };
|
|
55
|
+
return { source: "session", cause: "session" };
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export function createNativeNavigatorSessionFactory(): NavigatorSessionFactory {
|
|
59
|
+
return async ({ context, subject, tool }) => {
|
|
60
|
+
const resolved = await resolveNavigatorSeatSelection(context);
|
|
61
|
+
let thinkingLevel = resolved.thinkingLevel;
|
|
62
|
+
|
|
63
|
+
// Archivist nest for attendance route memory only (ADR 0018 / 0065) — not a session open.
|
|
64
|
+
const { createRecordSession } = await import("./archivist-record-entry.ts");
|
|
65
|
+
const sessionManager = createRecordSession({
|
|
66
|
+
cwd: context.cwd,
|
|
67
|
+
kind: "navigator",
|
|
68
|
+
subject,
|
|
69
|
+
parent: context.sessionManager,
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
let providerFailure: NavigatorProviderFailureFact | undefined;
|
|
73
|
+
let noReceipt: NoReceiptLifecycleFacts | undefined;
|
|
74
|
+
let disposed = false;
|
|
75
|
+
let inFlightPrompt: Promise<unknown> | undefined;
|
|
76
|
+
|
|
77
|
+
const resolveHome = async (): Promise<string | undefined> => {
|
|
78
|
+
const parentFile = context.sessionManager?.getSessionFile?.();
|
|
79
|
+
if (typeof parentFile === "string" && parentFile.trim() !== "") {
|
|
80
|
+
try {
|
|
81
|
+
const { tryHomeFromAkRolesPath, homeFromRunDirectory } = await import(
|
|
82
|
+
"./activation-ledger-topology.ts"
|
|
83
|
+
);
|
|
84
|
+
const fromParent = tryHomeFromAkRolesPath(parentFile);
|
|
85
|
+
if (fromParent !== undefined && fromParent.length > 0) return fromParent;
|
|
86
|
+
const runDir = parentFile.replace(/\/session\/session\.jsonl$/, "");
|
|
87
|
+
if (runDir !== parentFile) {
|
|
88
|
+
try {
|
|
89
|
+
return homeFromRunDirectory(runDir);
|
|
90
|
+
} catch {
|
|
91
|
+
// fall through
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
} catch {
|
|
95
|
+
// fall through
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
const envHome = process.env.HOME;
|
|
99
|
+
return typeof envHome === "string" && envHome.trim() !== "" ? envHome : undefined;
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
return {
|
|
103
|
+
prompt: async (text) => {
|
|
104
|
+
if (disposed) {
|
|
105
|
+
throw navigatorUnavailableError("session", new Error("Navigator attendance was disposed"));
|
|
106
|
+
}
|
|
107
|
+
providerFailure = undefined;
|
|
108
|
+
noReceipt = undefined;
|
|
109
|
+
const run = (async () => {
|
|
110
|
+
try {
|
|
111
|
+
const { summonPublicRole } = await import("./public-role-summons.ts");
|
|
112
|
+
const home = await resolveHome();
|
|
113
|
+
// Public activation — same face as `ak-role navigator <instruction>` (#675).
|
|
114
|
+
const summoned = await summonPublicRole({
|
|
115
|
+
role: "navigator",
|
|
116
|
+
argv: [text],
|
|
117
|
+
cwd: context.cwd,
|
|
118
|
+
...(home === undefined ? {} : { home }),
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
const outcome = summoned.terminal?.roleOutcome;
|
|
122
|
+
if (outcome === undefined) {
|
|
123
|
+
const detail = summoned.stderr?.trim() || `exit ${summoned.exitCode}`;
|
|
124
|
+
providerFailure = { source: "transport", cause: "transport" };
|
|
125
|
+
throw navigatorUnavailableError(
|
|
126
|
+
"transport",
|
|
127
|
+
new Error(`Navigator public summon produced no terminal (${detail})`),
|
|
128
|
+
);
|
|
129
|
+
}
|
|
130
|
+
if (outcome.kind === "failure") {
|
|
131
|
+
providerFailure = providerFailureFromPublicTerminal(outcome);
|
|
132
|
+
throw navigatorUnavailableError(
|
|
133
|
+
providerFailure.source,
|
|
134
|
+
new Error(outcome.diagnostic),
|
|
135
|
+
providerFailure.cause,
|
|
136
|
+
);
|
|
137
|
+
}
|
|
138
|
+
if (outcome.kind === "no_receipt") {
|
|
139
|
+
// The nested session spent its own delivery budget; attendance settles
|
|
140
|
+
// no-receipt on these facts instead of opening another summon (#675).
|
|
141
|
+
noReceipt = outcome;
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
if (outcome.kind !== "accepted") {
|
|
145
|
+
providerFailure = { source: "session", cause: "session" };
|
|
146
|
+
throw navigatorUnavailableError(
|
|
147
|
+
"session",
|
|
148
|
+
new Error("Navigator public summon returned unusable terminal"),
|
|
149
|
+
);
|
|
150
|
+
}
|
|
151
|
+
const candidates = outcome.decisiveFacts.candidates;
|
|
152
|
+
if (!Array.isArray(candidates)) {
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
// Rejoin attendance prepare tool sink (same candidate shape as public advice).
|
|
156
|
+
await tool.execute(
|
|
157
|
+
"navigator-public-prepare",
|
|
158
|
+
{ candidates },
|
|
159
|
+
undefined,
|
|
160
|
+
undefined,
|
|
161
|
+
context as never,
|
|
162
|
+
);
|
|
163
|
+
} catch (error) {
|
|
164
|
+
if (error instanceof NavigatorUnavailableError) throw error;
|
|
165
|
+
const fact = navigatorProviderFailureFromError(error);
|
|
166
|
+
providerFailure = fact ?? { source: "transport", cause: "transport" };
|
|
167
|
+
throw navigatorUnavailableError(providerFailure.source, error, providerFailure.cause);
|
|
168
|
+
}
|
|
169
|
+
})();
|
|
170
|
+
inFlightPrompt = run;
|
|
171
|
+
try {
|
|
172
|
+
await run;
|
|
173
|
+
} finally {
|
|
174
|
+
if (inFlightPrompt === run) inFlightPrompt = undefined;
|
|
175
|
+
}
|
|
176
|
+
},
|
|
177
|
+
providerFailure: () => providerFailure,
|
|
178
|
+
noReceipt: () => noReceipt,
|
|
179
|
+
appendEntry: (customType, data) => {
|
|
180
|
+
sessionManager.appendCustomEntry(customType, data);
|
|
181
|
+
try {
|
|
182
|
+
sitianReport({
|
|
183
|
+
level: "event",
|
|
184
|
+
kind: "attendance",
|
|
185
|
+
cwd: context.cwd,
|
|
186
|
+
sessionParent: sessionManager.getSessionFile(),
|
|
187
|
+
payload: { customType, data },
|
|
188
|
+
source: "navigator-public-session",
|
|
189
|
+
});
|
|
190
|
+
} catch {
|
|
191
|
+
// best-effort
|
|
192
|
+
}
|
|
193
|
+
},
|
|
194
|
+
entries: () => sessionManager.getEntries(),
|
|
195
|
+
setModel: async (next, nextThinking) => {
|
|
196
|
+
let nextParsed: ReturnType<typeof parseNavigatorModelSetting>;
|
|
197
|
+
try {
|
|
198
|
+
nextParsed = parseNavigatorModelSetting(next);
|
|
199
|
+
} catch (error) {
|
|
200
|
+
throw navigatorUnavailableError("model", error);
|
|
201
|
+
}
|
|
202
|
+
// No live provider session is pinned here: every prompt is an independent
|
|
203
|
+
// public summon whose nested CLI reads the current seat table (#675 验收②
|
|
204
|
+
// / #617 DK-3). A seat edit between prepares therefore applies on the next
|
|
205
|
+
// summon — it is never an unavailable session.
|
|
206
|
+
thinkingLevel = nextThinking ?? nextParsed.thinkingLevel;
|
|
207
|
+
},
|
|
208
|
+
getThinkingLevel: () => thinkingLevel,
|
|
209
|
+
recordPointer: () => sessionManager.getSessionDir(),
|
|
210
|
+
dispose: async () => {
|
|
211
|
+
disposed = true;
|
|
212
|
+
const pending = inFlightPrompt;
|
|
213
|
+
if (pending !== undefined) await pending.catch(() => undefined);
|
|
214
|
+
},
|
|
215
|
+
};
|
|
216
|
+
};
|
|
217
|
+
}
|
|
@@ -10,12 +10,9 @@ import type { ToolDefinition } from "@earendil-works/pi-coding-agent";
|
|
|
10
10
|
import { Type } from "typebox";
|
|
11
11
|
import { Value } from "typebox/value";
|
|
12
12
|
|
|
13
|
-
import { auditorRunDirectory } from "./auditor-dossier-tool.ts";
|
|
14
13
|
import type { HostContext, HostInstitutionalModelSelection } from "./host-contracts.ts";
|
|
15
|
-
import {
|
|
16
|
-
|
|
17
|
-
readInstitutionalSeatSelection,
|
|
18
|
-
} from "./institutional-resolution.ts";
|
|
14
|
+
import type { NoReceiptLifecycleFacts } from "./receipt-delivery-policy.ts";
|
|
15
|
+
|
|
19
16
|
|
|
20
17
|
export const NAVIGATOR_PREPARE_TOOL_NAME = "ak_navigator_prepare" as const;
|
|
21
18
|
export const NAVIGATOR_DEFAULT_MODEL = "openai-codex/gpt-5.6-luna:max" as const;
|
|
@@ -162,6 +159,12 @@ export type NavigatorPreparationSession = {
|
|
|
162
159
|
appendEntry(customType: string, data: unknown): void;
|
|
163
160
|
entries(): readonly unknown[];
|
|
164
161
|
providerFailure?(): NavigatorProviderFailureFact | undefined;
|
|
162
|
+
/**
|
|
163
|
+
* Facts of a nested session that already settled without an accepted receipt.
|
|
164
|
+
* Present means its own delivery budget is spent — another prompt would open an
|
|
165
|
+
* independent summon rather than press the session that owes the receipt.
|
|
166
|
+
*/
|
|
167
|
+
noReceipt?(): NoReceiptLifecycleFacts | undefined;
|
|
165
168
|
setModel?(model: string, thinkingLevel?: string): Promise<void>;
|
|
166
169
|
getThinkingLevel?(): string | undefined;
|
|
167
170
|
recordPointer(): string;
|
|
@@ -204,6 +207,7 @@ export async function writeNavigatorModelSetting(model: string, path = navigator
|
|
|
204
207
|
export function parseNavigatorModelSetting(value: string): {
|
|
205
208
|
provider: string;
|
|
206
209
|
model: string;
|
|
210
|
+
/** Host thinking passthrough — omit when bare provider/model (#675 ⑥). */
|
|
207
211
|
thinkingLevel?: string;
|
|
208
212
|
} {
|
|
209
213
|
const slash = value.indexOf("/");
|
|
@@ -216,68 +220,71 @@ export function parseNavigatorModelSetting(value: string): {
|
|
|
216
220
|
const suffix = colon < 0 ? undefined : modelWithThinking.slice(colon + 1);
|
|
217
221
|
const model = colon < 0 ? modelWithThinking : modelWithThinking.slice(0, colon);
|
|
218
222
|
if (model === "") throw new Error("Navigator model setting must include a model");
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
+
if (suffix !== undefined && suffix.trim() === "") {
|
|
224
|
+
throw new Error("Navigator model setting thinking suffix must be non-blank");
|
|
225
|
+
}
|
|
226
|
+
return {
|
|
227
|
+
provider,
|
|
228
|
+
model,
|
|
229
|
+
...(suffix === undefined ? {} : { thinkingLevel: suffix }),
|
|
230
|
+
};
|
|
223
231
|
}
|
|
224
232
|
|
|
225
233
|
/**
|
|
226
|
-
*
|
|
227
|
-
*
|
|
234
|
+
* Navigator model selection from the public seat table only (#675 / #617 DK-3).
|
|
235
|
+
* No legacy navigator-model.json fallback — missing seat is a real model failure.
|
|
236
|
+
* Host/engine axes ride the shared public summons path; attendance open consumes
|
|
237
|
+
* model/thinking here and defers host selection to the shared envelope when present.
|
|
228
238
|
*/
|
|
229
239
|
export async function resolveNavigatorSeatSelection(
|
|
230
240
|
context: HostContext,
|
|
231
|
-
modelSettingPath: string | undefined,
|
|
232
|
-
defaultModelSettingPath: string,
|
|
233
241
|
): Promise<{ selection: HostInstitutionalModelSelection; configuredLabel: string; thinkingLevel?: string }> {
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
242
|
+
try {
|
|
243
|
+
const { loadPublicCliConfig } = await import("./public-cli/config.ts");
|
|
244
|
+
const { seatModelOnly } = await import("./public-cli/registry.ts");
|
|
245
|
+
const { packageMachineHome } = await import("./activation-ledger-topology.ts");
|
|
246
|
+
const homeCandidate = (context as unknown as { home?: unknown }).home;
|
|
247
|
+
const envHome = process.env.HOME;
|
|
248
|
+
// Prefer explicit context home, then process HOME (hermetic tests), never
|
|
249
|
+
// jump straight to the real machine home when a temp HOME is armed.
|
|
250
|
+
const home =
|
|
251
|
+
typeof homeCandidate === "string"
|
|
252
|
+
? homeCandidate
|
|
253
|
+
: typeof envHome === "string" && envHome.trim() !== ""
|
|
254
|
+
? envHome
|
|
255
|
+
: packageMachineHome();
|
|
256
|
+
const config = await loadPublicCliConfig(home);
|
|
257
|
+
const modelOnly = seatModelOnly(config.seats.navigator);
|
|
258
|
+
// Seat table is the only model authority — no legacy navigator-model.json.
|
|
259
|
+
// Bare missing seat uses the package default constant (not a file path).
|
|
260
|
+
if (modelOnly === undefined) {
|
|
261
|
+
const parsed = parseNavigatorModelSetting(NAVIGATOR_DEFAULT_MODEL);
|
|
238
262
|
return {
|
|
239
263
|
selection: {
|
|
240
|
-
provider:
|
|
241
|
-
model:
|
|
242
|
-
...(
|
|
264
|
+
provider: parsed.provider,
|
|
265
|
+
model: parsed.model,
|
|
266
|
+
...(parsed.thinkingLevel === undefined ? {} : { thinking: parsed.thinkingLevel }),
|
|
243
267
|
},
|
|
244
|
-
configuredLabel:
|
|
245
|
-
|
|
246
|
-
: `${selection.provider}/${selection.model}:${selection.thinking}`,
|
|
247
|
-
...(selection.thinking === undefined ? {} : { thinkingLevel: selection.thinking }),
|
|
268
|
+
configuredLabel: NAVIGATOR_DEFAULT_MODEL,
|
|
269
|
+
...(parsed.thinkingLevel === undefined ? {} : { thinkingLevel: parsed.thinkingLevel }),
|
|
248
270
|
};
|
|
249
|
-
} catch (error) {
|
|
250
|
-
if (
|
|
251
|
-
error instanceof InstitutionalResolutionError
|
|
252
|
-
&& (error.reason === "missing-page" || error.reason === "missing-seat")
|
|
253
|
-
) {
|
|
254
|
-
// documented bare-seam fallback
|
|
255
|
-
} else {
|
|
256
|
-
throw error instanceof NavigatorUnavailableError
|
|
257
|
-
? error
|
|
258
|
-
: navigatorUnavailableError("model", error);
|
|
259
|
-
}
|
|
260
271
|
}
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
272
|
+
// Host params passthrough only — no map/validate/default (#675 ⑥).
|
|
273
|
+
const thinkingRaw = modelOnly.thinking;
|
|
274
|
+
const configuredLabel =
|
|
275
|
+
thinkingRaw === undefined
|
|
276
|
+
? `${modelOnly.provider}/${modelOnly.model}`
|
|
277
|
+
: `${modelOnly.provider}/${modelOnly.model}:${thinkingRaw}`;
|
|
278
|
+
return {
|
|
279
|
+
selection: {
|
|
280
|
+
provider: modelOnly.provider,
|
|
281
|
+
model: modelOnly.model,
|
|
282
|
+
...(thinkingRaw === undefined ? {} : { thinking: thinkingRaw }),
|
|
283
|
+
},
|
|
284
|
+
configuredLabel,
|
|
285
|
+
...(thinkingRaw === undefined ? {} : { thinkingLevel: thinkingRaw }),
|
|
286
|
+
};
|
|
265
287
|
} catch (error) {
|
|
266
288
|
throw navigatorUnavailableError("model", error);
|
|
267
289
|
}
|
|
268
|
-
let parsed: ReturnType<typeof parseNavigatorModelSetting>;
|
|
269
|
-
try {
|
|
270
|
-
parsed = parseNavigatorModelSetting(configured);
|
|
271
|
-
} catch (error) {
|
|
272
|
-
throw navigatorUnavailableError("model", error);
|
|
273
|
-
}
|
|
274
|
-
return {
|
|
275
|
-
selection: {
|
|
276
|
-
provider: parsed.provider,
|
|
277
|
-
model: parsed.model,
|
|
278
|
-
...(parsed.thinkingLevel === undefined ? {} : { thinking: parsed.thinkingLevel }),
|
|
279
|
-
},
|
|
280
|
-
configuredLabel: configured,
|
|
281
|
-
...(parsed.thinkingLevel === undefined ? {} : { thinkingLevel: parsed.thinkingLevel }),
|
|
282
|
-
};
|
|
283
290
|
}
|
package/src/notary-source-run.ts
CHANGED
|
@@ -15,8 +15,10 @@ import {
|
|
|
15
15
|
import type { NotarySourceRunLocator } from "./notary-contracts.ts";
|
|
16
16
|
import { readRoleRunIdentity } from "./public-cli/run-lifecycle.ts";
|
|
17
17
|
|
|
18
|
+
// Run directory leaf: <runId>@<role>. Production uses uuidv7 runIds; offline tracers
|
|
19
|
+
// may use deterministic non-uuid leaves. Role token stays identifier-shaped.
|
|
18
20
|
const RUN_DIR_NAME =
|
|
19
|
-
/^([
|
|
21
|
+
/^([A-Za-z0-9][A-Za-z0-9._-]*)@([A-Za-z][A-Za-z0-9_-]*)$/;
|
|
20
22
|
|
|
21
23
|
export class NotarySourceRunError extends Error {
|
|
22
24
|
constructor(message: string, options?: ErrorOptions) {
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public Auditor (审刑院) terminating receipt contracts (#675).
|
|
3
|
+
* Lawful explicit releases: pass | revise | escalate.
|
|
4
|
+
*/
|
|
5
|
+
import { Type } from "typebox";
|
|
6
|
+
|
|
7
|
+
import { openToolObject } from "../open-tool-schema.ts";
|
|
8
|
+
import { withInfrastructureFailureDeclaration } from "./terminating-infrastructure.ts";
|
|
9
|
+
|
|
10
|
+
export const AUDITOR_OUTPUT_TOOL_NAME = "ak_auditor_output" as const;
|
|
11
|
+
export const AUDITOR_ACCEPTED_TEXT = "审刑院回执已接受";
|
|
12
|
+
|
|
13
|
+
export const auditorOutputSchema = withInfrastructureFailureDeclaration(
|
|
14
|
+
openToolObject(
|
|
15
|
+
Type.Object({
|
|
16
|
+
status: Type.Unknown({
|
|
17
|
+
description: "pass | revise | escalate — 形状指引,非 schema 闸",
|
|
18
|
+
}),
|
|
19
|
+
violations: Type.Optional(Type.Unknown({
|
|
20
|
+
description: "status 为 revise 时的违规条目",
|
|
21
|
+
})),
|
|
22
|
+
conflicts: Type.Optional(Type.Unknown({
|
|
23
|
+
description: "status 为 escalate 时的冲突",
|
|
24
|
+
})),
|
|
25
|
+
decisionGate: Type.Optional(Type.Unknown({
|
|
26
|
+
description: "status 为 escalate 时的决策闸",
|
|
27
|
+
})),
|
|
28
|
+
}),
|
|
29
|
+
),
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
export type AuditorOutput =
|
|
33
|
+
| { readonly status: "pass" }
|
|
34
|
+
| { readonly status: "revise"; readonly violations?: unknown }
|
|
35
|
+
| {
|
|
36
|
+
readonly status: "escalate";
|
|
37
|
+
readonly conflicts?: unknown;
|
|
38
|
+
readonly decisionGate?: unknown;
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
42
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export function projectLawfulAuditorOutput(value: unknown): AuditorOutput | undefined {
|
|
46
|
+
if (!isRecord(value)) return undefined;
|
|
47
|
+
if (value.status === "pass") return { status: "pass" };
|
|
48
|
+
if (value.status === "revise") {
|
|
49
|
+
return {
|
|
50
|
+
status: "revise",
|
|
51
|
+
...(Object.hasOwn(value, "violations") ? { violations: value.violations } : {}),
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
if (value.status === "escalate") {
|
|
55
|
+
return {
|
|
56
|
+
status: "escalate",
|
|
57
|
+
...(Object.hasOwn(value, "conflicts") ? { conflicts: value.conflicts } : {}),
|
|
58
|
+
...(Object.hasOwn(value, "decisionGate") ? { decisionGate: value.decisionGate } : {}),
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
return undefined;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export function validateRecordedAuditorOutput(value: unknown): AuditorOutput {
|
|
65
|
+
const projected = projectLawfulAuditorOutput(value);
|
|
66
|
+
if (projected === undefined) {
|
|
67
|
+
throw new Error("Auditor output has no recognized execution discriminator");
|
|
68
|
+
}
|
|
69
|
+
return projected;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export function auditorDecisiveFacts(output: AuditorOutput): Record<string, unknown> {
|
|
73
|
+
const facts: Record<string, unknown> = { status: output.status };
|
|
74
|
+
if (output.status === "revise" && output.violations !== undefined) {
|
|
75
|
+
facts.violations = output.violations;
|
|
76
|
+
}
|
|
77
|
+
if (output.status === "escalate") {
|
|
78
|
+
if (output.conflicts !== undefined) facts.conflicts = output.conflicts;
|
|
79
|
+
if (output.decisionGate !== undefined) facts.decisionGate = output.decisionGate;
|
|
80
|
+
}
|
|
81
|
+
return facts;
|
|
82
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public Evidence-Child terminating receipt contracts (#675).
|
|
3
|
+
* One report body; shape is not an admission gate (ADR 0055).
|
|
4
|
+
*/
|
|
5
|
+
import { Type } from "typebox";
|
|
6
|
+
|
|
7
|
+
import { openToolObject } from "../open-tool-schema.ts";
|
|
8
|
+
import { withInfrastructureFailureDeclaration } from "./terminating-infrastructure.ts";
|
|
9
|
+
|
|
10
|
+
export const EVIDENCE_CHILD_OUTPUT_TOOL_NAME = "ak_evidence_child_output" as const;
|
|
11
|
+
export const EVIDENCE_CHILD_ACCEPTED_TEXT = "取证回执已接受";
|
|
12
|
+
|
|
13
|
+
export const evidenceChildOutputSchema = withInfrastructureFailureDeclaration(
|
|
14
|
+
openToolObject(
|
|
15
|
+
Type.Object({
|
|
16
|
+
report: Type.Unknown({
|
|
17
|
+
description: "取证报告正文 — 形状指引,非 schema 闸",
|
|
18
|
+
}),
|
|
19
|
+
}),
|
|
20
|
+
),
|
|
21
|
+
);
|
|
22
|
+
|
|
23
|
+
/** Report body retained as delivered — no type/blank/field-presence reshape (ADR 0055 / §0). */
|
|
24
|
+
export type EvidenceChildOutput = { readonly report: unknown };
|
|
25
|
+
|
|
26
|
+
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
27
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export function projectLawfulEvidenceChildOutput(
|
|
31
|
+
value: unknown,
|
|
32
|
+
): EvidenceChildOutput | undefined {
|
|
33
|
+
// No field-presence gate (ADR 0055 / CLAUDE.md §0 / #675). Retain delivered bytes:
|
|
34
|
+
// report key when present, otherwise the whole object as the report body.
|
|
35
|
+
if (!isRecord(value)) return undefined;
|
|
36
|
+
return { report: Object.hasOwn(value, "report") ? value.report : value };
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export function validateRecordedEvidenceChildOutput(value: unknown): EvidenceChildOutput {
|
|
40
|
+
const projected = projectLawfulEvidenceChildOutput(value);
|
|
41
|
+
if (projected === undefined) {
|
|
42
|
+
throw new Error("Evidence-child output is not an object");
|
|
43
|
+
}
|
|
44
|
+
return projected;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export function evidenceChildDecisiveFacts(
|
|
48
|
+
output: EvidenceChildOutput,
|
|
49
|
+
): Record<string, unknown> {
|
|
50
|
+
return { report: output.report };
|
|
51
|
+
}
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
export const JUDGE_OUTPUT_TOOL_NAME = "ak_judge_output";
|
|
5
5
|
export const JUDGE_ACCEPTED_TEXT = "大理寺回执已接受";
|
|
6
6
|
export const JUDGE_ACCEPTED_AUDIT_NO_RECEIPT_TEXT = "大理寺回执已接受;审计无回执";
|
|
7
|
+
export const JUDGE_ACCEPTED_AUDIT_UNREADABLE_TEXT = "大理寺回执已接受;审计形状不可读";
|
|
7
8
|
|
|
8
9
|
export type JudgeClass = {
|
|
9
10
|
name: string;
|
|
@@ -10,8 +10,8 @@ export type ReviewerAmendments = Readonly<Partial<Record<"standards" | "spec", s
|
|
|
10
10
|
export type ReviewerIntent =
|
|
11
11
|
| Readonly<{ status: "completed"; amendments?: ReviewerAmendments }>
|
|
12
12
|
| Readonly<{ status: "refused"; diagnostic: string; amendments?: ReviewerAmendments }>;
|
|
13
|
-
/** Child report
|
|
14
|
-
export type VerbatimChildReport = Readonly<{ text:
|
|
13
|
+
/** Child report body retained as delivered — no type/blank reshape (ADR 0031 / 0055 / #675). */
|
|
14
|
+
export type VerbatimChildReport = Readonly<{ text: unknown }>;
|
|
15
15
|
/** Prompt projection on the receipt face is plain text (ADR 0031). */
|
|
16
16
|
export type ReviewerReceiptPrompt = Readonly<{ text: string }>;
|
|
17
17
|
/** Canonical Skill content on the receipt face is plain text (ADR 0031/0032). */
|