@akagilnc/pi-workflow-roles 0.1.5365 → 0.1.5375
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 +5585 -5655
- package/dist/activation-ledger-git.js +2 -2
- package/dist/activation-ledger-topology.js +1 -7
- package/dist/analyst-entry.js +4 -8
- package/dist/analyst-gate-cycles-read.js +3 -11
- package/dist/analyst-index.js +3 -9
- package/dist/analyst-ledger.js +1 -11
- package/dist/analyst-metric-families/acceptance-success-rework.js +1 -3
- package/dist/analyst-metric-families/round-timeline.js +1 -3
- package/dist/analyst-page.js +2 -2
- package/dist/archivist-record-topology.js +2 -2
- package/dist/audit-escalation.js +2 -1
- package/dist/auditor-soul.js +2 -1
- package/dist/collector-config.js +6 -8
- package/dist/compliance-transport.js +2 -1
- package/dist/countersign-contracts.js +2 -1
- package/dist/diarist-contracts.js +3 -2
- package/dist/doctor-contracts.js +1 -3
- package/dist/doctor-evidence.js +7 -8
- package/dist/dossier-resolution.js +1 -3
- package/dist/engine-detour-usage.js +1 -3
- package/dist/gatekeeper-role.js +2 -9
- package/dist/gleaner-left-contracts.js +2 -1
- package/dist/headless-host/description.js +14 -17
- package/dist/headless-host/production-host.js +1665 -1737
- package/dist/host-session-record.js +3 -2
- package/dist/inspector-contracts.js +2 -1
- package/dist/ledger-session-read.js +1 -3
- package/dist/merger-contracts.js +9 -9
- package/dist/migrate-book-topology.js +348 -314
- package/dist/navigator-attendance.js +9 -11
- package/dist/navigator-invocation-identity.js +3 -2
- package/dist/navigator-public-session.js +3 -5
- package/dist/navigator-session-contracts.js +8 -10
- package/dist/navigator-work-base.js +5 -8
- package/dist/notary-contracts.js +3 -5
- package/dist/package-contracts/auditor-output.js +1 -3
- package/dist/package-contracts/fixer-packet.js +3 -6
- package/dist/package-contracts/gatekeeper-output.js +1 -3
- package/dist/package-contracts/navigator-output.js +8 -8
- package/dist/package-contracts/terminating-infrastructure.js +5 -9
- package/dist/package-contracts/terminating-tools.js +4 -3
- package/dist/public-cli/analyst-run.js +3 -2
- package/dist/public-cli/auto-resume.js +4 -9
- package/dist/public-cli/cli.js +66 -64
- package/dist/public-cli/config.js +12 -11
- package/dist/public-cli/countersign-run.js +1 -3
- package/dist/public-cli/host-providers.js +7 -14
- package/dist/public-cli/instruction-seat-run.js +69 -43
- package/dist/public-cli/invocation.js +141 -136
- package/dist/public-cli/main.js +1919 -1968
- package/dist/public-cli/post-admission.js +89 -89
- package/dist/public-cli/role-seat-runtime.js +29 -0
- package/dist/public-cli/run-lifecycle.js +20 -32
- package/dist/public-cli/settlement.js +10 -26
- package/dist/public-cli/turn-request.js +14 -0
- package/dist/public-role-summons.js +23 -35
- package/dist/receipt-delivery-policy.js +1 -3
- package/dist/role-run-placement.js +7 -5
- package/dist/role-run-relocation.js +12 -19
- package/dist/run-terminal-artifacts.js +1 -11
- package/dist/run-ticket-number.js +2 -4
- package/dist/session-assistant-usage.js +2 -1
- package/dist/session-dialogue.js +1 -14
- package/dist/sitian-reader.js +2 -4
- package/dist/submission-correctable-error.js +2 -1
- package/dist/submission-errors.js +2 -1
- package/dist/submission-gate.js +2 -1
- package/dist/submission-ledger.js +4 -5
- package/dist/ticket-provenance-contracts.js +1 -3
- package/dist/ticket-provenance.js +2 -1
- package/dist/typed-provider-http.js +4 -7
- package/dist/unknown-value.js +28 -0
- package/dist/user-dialogue-stdin.js +2 -1
- package/package.json +1 -1
- package/src/acp-host/role-turn-host.ts +4 -2
- package/src/activation-ledger-git.ts +3 -2
- package/src/activation-ledger-topology.ts +4 -12
- package/src/analyst-entry.ts +3 -11
- package/src/analyst-gate-cycles-read.ts +3 -15
- package/src/analyst-index.ts +3 -13
- package/src/analyst-ledger.ts +2 -16
- package/src/analyst-metric-families/acceptance-success-rework.ts +2 -4
- package/src/analyst-metric-families/round-timeline.ts +2 -4
- package/src/analyst-page.ts +2 -2
- package/src/archivist-record-topology.ts +2 -2
- package/src/audit-escalation.ts +2 -1
- package/src/auditor-soul.ts +3 -1
- package/src/book-topology-migration-placement.ts +8 -21
- package/src/book-topology-migrators-t11.ts +16 -15
- package/src/book-topology-mixed-volume-migrators.ts +3 -6
- package/src/book-topology-record-class-migrators.ts +7 -10
- package/src/book-topology-runs-migrator.ts +4 -3
- package/src/collector-config.ts +7 -9
- package/src/compliance-transport.ts +2 -1
- package/src/countersign-contracts.ts +2 -1
- package/src/diarist-contracts.ts +3 -2
- package/src/doctor-contracts.ts +3 -1
- package/src/doctor-evidence.ts +8 -7
- package/src/doctor-role.ts +4 -2
- package/src/dossier-resolution.ts +2 -4
- package/src/engine-detour-tool.ts +0 -2
- package/src/engine-detour-usage.ts +2 -4
- package/src/external-host-turn-loop.ts +3 -1
- package/src/factory-board.ts +1 -8
- package/src/gatekeeper-role.ts +2 -10
- package/src/gleaner-left-contracts.ts +3 -1
- package/src/headless-host/description.ts +15 -18
- package/src/headless-host/role-turn-host.ts +10 -9
- package/src/host-session-record.ts +4 -2
- package/src/inspector-contracts.ts +2 -1
- package/src/ledger-session-read.ts +2 -5
- package/src/merger-contracts.ts +10 -9
- package/src/navigator-attendance.ts +10 -12
- package/src/navigator-invocation-identity.ts +3 -2
- package/src/navigator-public-session.ts +4 -6
- package/src/navigator-session-contracts.ts +8 -11
- package/src/navigator-work-base.ts +5 -8
- package/src/navigator-work-context.ts +2 -1
- package/src/notary-contracts.ts +4 -6
- package/src/oauth-keepalive.ts +5 -18
- package/src/package-contracts/auditor-output.ts +2 -4
- package/src/package-contracts/fixer-packet.ts +4 -6
- package/src/package-contracts/gatekeeper-output.ts +2 -4
- package/src/package-contracts/judge-output.ts +0 -1
- package/src/package-contracts/navigator-output.ts +8 -8
- package/src/package-contracts/terminating-infrastructure.ts +6 -20
- package/src/package-contracts/terminating-tools.ts +8 -12
- package/src/pi/adapter.ts +0 -1
- package/src/pi/role-turn-host.ts +0 -1
- package/src/public-cli/analyst-run.ts +4 -2
- package/src/public-cli/auto-resume.ts +5 -12
- package/src/public-cli/cli.ts +77 -83
- package/src/public-cli/config.ts +16 -27
- package/src/public-cli/countersign-run.ts +2 -4
- package/src/public-cli/host-providers.ts +10 -27
- package/src/public-cli/instruction-seat-run.ts +87 -58
- package/src/public-cli/invocation.ts +159 -172
- package/src/public-cli/post-admission.ts +115 -103
- package/src/public-cli/role-seat-runtime.ts +72 -0
- package/src/public-cli/run-lifecycle.ts +27 -67
- package/src/public-cli/settlement.ts +11 -33
- package/src/public-cli/terminal.ts +2 -17
- package/src/public-cli/turn-request.ts +26 -0
- package/src/public-role-summons.ts +24 -48
- package/src/receipt-delivery-policy.ts +1 -4
- package/src/reviewer-role.ts +0 -1
- package/src/role-envelope.ts +5 -3
- package/src/role-run-placement.ts +9 -10
- package/src/role-run-relocation.ts +13 -23
- package/src/role-runtime.ts +9 -15
- package/src/run-terminal-artifacts.ts +2 -16
- package/src/run-ticket-number.ts +4 -10
- package/src/session-assistant-usage.ts +3 -1
- package/src/session-dialogue.ts +1 -4
- package/src/session-identity.ts +0 -1
- package/src/sitian-reader.ts +2 -4
- package/src/submission-correctable-error.ts +3 -1
- package/src/submission-errors.ts +2 -1
- package/src/submission-gate.ts +3 -1
- package/src/submission-ledger.ts +5 -6
- package/src/ticket-provenance-contracts.ts +1 -4
- package/src/ticket-provenance.ts +3 -1
- package/src/ticket-snapshot.ts +2 -4
- package/src/ticket-trajectory.ts +1 -8
- package/src/typed-provider-http.ts +5 -15
- package/src/unknown-value.ts +34 -0
- package/src/user-dialogue-stdin.ts +3 -1
- package/src/worker-role.ts +2 -5
- package/src/worker-submission-gates.ts +5 -7
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { createHash } from "node:crypto";
|
|
2
1
|
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
3
2
|
import { homedir } from "node:os";
|
|
4
3
|
import { dirname, join, resolve } from "node:path";
|
|
@@ -35,6 +34,8 @@ import { issueRoot, subjectPath } from "./work-subject-identity.js";
|
|
|
35
34
|
import { createReceiptDeliveryPolicy, NO_RECEIPT_LIFECYCLE_ENTRY_TYPE } from "./receipt-delivery-policy.js";
|
|
36
35
|
import { navigatorProseFromUnknown } from "./package-contracts/navigator-output.js";
|
|
37
36
|
import { persistNavigatorWorkBase } from "./navigator-work-base.js";
|
|
37
|
+
import { sha256Hex } from "./sha256.js";
|
|
38
|
+
import { isRecord } from "./unknown-value.js";
|
|
38
39
|
const NAVIGATOR_EVENT_TYPE = "ak-navigator-attendance";
|
|
39
40
|
function resolveNavigatorAuthorityMaterial(roleInput, fileAuthority) {
|
|
40
41
|
if (roleInput !== void 0 && roleInput.trim() !== "") return roleInput;
|
|
@@ -53,27 +54,24 @@ const unavailableKeys = /* @__PURE__ */ new Set(["context", "session", "model",
|
|
|
53
54
|
function unavailableKey(value) {
|
|
54
55
|
return typeof value === "string" && unavailableKeys.has(value) ? value : void 0;
|
|
55
56
|
}
|
|
56
|
-
function exactRecord(value) {
|
|
57
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
58
|
-
}
|
|
59
57
|
function rejectedPrepareReason(entries, start) {
|
|
60
58
|
const recent = entries.slice(start);
|
|
61
59
|
const prepareCalls = /* @__PURE__ */ new Set();
|
|
62
60
|
for (const entry of recent) {
|
|
63
|
-
if (!
|
|
61
|
+
if (!isRecord(entry) || entry.type !== "message" || !isRecord(entry.message) || entry.message.role !== "assistant" || !Array.isArray(entry.message.content)) continue;
|
|
64
62
|
for (const part of entry.message.content) {
|
|
65
|
-
if (
|
|
63
|
+
if (isRecord(part) && part.type === "toolCall" && part.name === NAVIGATOR_PREPARE_TOOL_NAME && typeof part.id === "string") prepareCalls.add(part.id);
|
|
66
64
|
}
|
|
67
65
|
}
|
|
68
66
|
let reason;
|
|
69
67
|
for (const entry of recent) {
|
|
70
|
-
if (!
|
|
68
|
+
if (!isRecord(entry) || entry.type !== "message" || !isRecord(entry.message) || entry.message.role !== "toolResult" || entry.message.isError !== true) continue;
|
|
71
69
|
const callId = entry.message.toolCallId;
|
|
72
70
|
if (entry.message.toolName !== NAVIGATOR_PREPARE_TOOL_NAME || typeof callId !== "string" || !prepareCalls.has(callId)) {
|
|
73
71
|
return void 0;
|
|
74
72
|
}
|
|
75
73
|
const content = entry.message.content;
|
|
76
|
-
const text = Array.isArray(content) ? content.flatMap((part) =>
|
|
74
|
+
const text = Array.isArray(content) ? content.flatMap((part) => isRecord(part) && typeof part.text === "string" ? [part.text] : []).join("") : typeof content === "string" ? content : "";
|
|
77
75
|
if (text.trim() !== "") reason = text.trim();
|
|
78
76
|
}
|
|
79
77
|
return reason;
|
|
@@ -86,7 +84,7 @@ function navigatorSubjectKey(subjectRoot, subject, provenance = "role_input") {
|
|
|
86
84
|
if (provenance === "placeholder") return subjectRoot;
|
|
87
85
|
const normalized = subject.trim().replace(/\s+/g, " ");
|
|
88
86
|
if (normalized === "") return subjectRoot;
|
|
89
|
-
return `${subjectRoot}#${
|
|
87
|
+
return `${subjectRoot}#${sha256Hex(normalized).slice(0, 32)}`;
|
|
90
88
|
}
|
|
91
89
|
function navigatorSubjectKeyForInput(subjectRoot, reference, cwd = process.cwd()) {
|
|
92
90
|
if (issueRoot(subjectRoot) !== void 0 || !subjectRoot.includes("/.ak/work/")) return subjectRoot;
|
|
@@ -308,10 +306,10 @@ function createNavigatorAttendance(options) {
|
|
|
308
306
|
return void 0;
|
|
309
307
|
}
|
|
310
308
|
const nativeFailure = [...activeSession.entries()].reverse().find((entry) => {
|
|
311
|
-
if (!
|
|
309
|
+
if (!isRecord(entry) || entry.type !== "message" || !isRecord(entry.message)) return false;
|
|
312
310
|
return entry.message.role === "assistant" && typeof entry.message.errorMessage === "string" && entry.message.errorMessage.trim() !== "";
|
|
313
311
|
});
|
|
314
|
-
const nativeMessage =
|
|
312
|
+
const nativeMessage = isRecord(nativeFailure) && isRecord(nativeFailure.message) ? nativeFailure.message : void 0;
|
|
315
313
|
const errorMessage = nativeMessage !== void 0 && typeof nativeMessage.errorMessage === "string" ? nativeMessage.errorMessage : "Navigator did not submit direction advice";
|
|
316
314
|
const providerFailure = activeSession.providerFailure?.();
|
|
317
315
|
const source = providerFailure?.source ?? "unknown";
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { LEGACY_REVIEW_OUTPUT_ROLES, PACKAGED_ROLE_REGISTRY } from "./packaged-role-registry.js";
|
|
2
2
|
import { isUuidV7, uuidv7 } from "./uuidv7.js";
|
|
3
|
+
import { isRecord } from "./unknown-value.js";
|
|
3
4
|
import { workSubjectKeysEqual } from "./work-subject-identity.js";
|
|
4
5
|
const NAVIGATOR_INVOCATION_ENTRY = "ak-navigator-invocation";
|
|
5
6
|
const NAVIGATOR_ROUTE_PLAYBOOK_FAILURE_ENTRY = "ak-navigator-route-playbook-failure";
|
|
@@ -34,7 +35,7 @@ function extractInfrastructureFailureEvidence(error) {
|
|
|
34
35
|
return evidence;
|
|
35
36
|
}
|
|
36
37
|
function hasNavigatorInfrastructureFailureBase(value) {
|
|
37
|
-
if (
|
|
38
|
+
if (!isRecord(value)) return false;
|
|
38
39
|
const record = value;
|
|
39
40
|
for (const key of NAVIGATOR_INFRASTRUCTURE_FAILURE_KEYS) {
|
|
40
41
|
if (!Object.hasOwn(record, key)) return false;
|
|
@@ -56,7 +57,7 @@ function invocationPhaseFromUnknown(value) {
|
|
|
56
57
|
return void 0;
|
|
57
58
|
}
|
|
58
59
|
function parseInvocationMarkerIdentity(data) {
|
|
59
|
-
if (
|
|
60
|
+
if (!isRecord(data)) return void 0;
|
|
60
61
|
const record = data;
|
|
61
62
|
const invocationId = record.invocationId;
|
|
62
63
|
if (typeof invocationId !== "string") return void 0;
|
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
attachWorkContextPointer,
|
|
16
16
|
navigatorWorkContextFile
|
|
17
17
|
} from "./navigator-work-base.js";
|
|
18
|
+
import { isRecord } from "./unknown-value.js";
|
|
18
19
|
async function resolveNavigatorLedgerHome(context) {
|
|
19
20
|
const { tryHomeFromAkRolesPath } = await import("./activation-ledger-topology.js");
|
|
20
21
|
const runDirectory = runDirectoryFromHostContext(context);
|
|
@@ -30,9 +31,6 @@ async function resolveNavigatorLedgerHome(context) {
|
|
|
30
31
|
return void 0;
|
|
31
32
|
}
|
|
32
33
|
const NAVIGATOR_HOST_RUN_POINTER_ENTRY = "ak-navigator-host-run";
|
|
33
|
-
function exactRecord(value) {
|
|
34
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
35
|
-
}
|
|
36
34
|
function runIdFromNavigatorDirectory(runDirectory) {
|
|
37
35
|
const entry = basename(runDirectory);
|
|
38
36
|
const suffix = "@navigator";
|
|
@@ -43,10 +41,10 @@ function runIdFromNavigatorDirectory(runDirectory) {
|
|
|
43
41
|
function readNavigatorHostRunPointer(entries) {
|
|
44
42
|
for (let index = entries.length - 1; index >= 0; index -= 1) {
|
|
45
43
|
const entry = entries[index];
|
|
46
|
-
if (!
|
|
44
|
+
if (!isRecord(entry)) continue;
|
|
47
45
|
if (entry.type === "custom" && entry.customType === NAVIGATOR_HOST_RUN_POINTER_ENTRY) {
|
|
48
46
|
const data = entry.data;
|
|
49
|
-
if (
|
|
47
|
+
if (isRecord(data) && typeof data.runId === "string" && data.runId.trim() !== "") {
|
|
50
48
|
return data.runId.trim();
|
|
51
49
|
}
|
|
52
50
|
}
|
|
@@ -3,6 +3,7 @@ import { homedir } from "node:os";
|
|
|
3
3
|
import { dirname, join } from "node:path";
|
|
4
4
|
import { Type } from "typebox";
|
|
5
5
|
import { Value } from "typebox/value";
|
|
6
|
+
import { isRecord, errorText, isEnoent } from "./unknown-value.js";
|
|
6
7
|
const NAVIGATOR_PREPARE_TOOL_NAME = "ak_navigator_prepare";
|
|
7
8
|
const NAVIGATOR_UNAVAILABLE_KEYS = /* @__PURE__ */ new Set([
|
|
8
9
|
"context",
|
|
@@ -30,12 +31,9 @@ class NavigatorUnavailableError extends Error {
|
|
|
30
31
|
}
|
|
31
32
|
}
|
|
32
33
|
function navigatorUnavailableError(source, error, cause = source) {
|
|
33
|
-
const message =
|
|
34
|
+
const message = errorText(error);
|
|
34
35
|
return error instanceof NavigatorUnavailableError ? error : new NavigatorUnavailableError(source, message, cause, error);
|
|
35
36
|
}
|
|
36
|
-
function exactRecord(value) {
|
|
37
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
38
|
-
}
|
|
39
37
|
function navigatorProviderFailureFromStatus(status) {
|
|
40
38
|
if (status === 401 || status === 403) return { source: "auth", cause: "auth" };
|
|
41
39
|
if (status === 429) return { source: "quota", cause: "quota" };
|
|
@@ -57,7 +55,7 @@ function navigatorProviderFailureFromError(error) {
|
|
|
57
55
|
if (cursor instanceof NavigatorUnavailableError) {
|
|
58
56
|
return { source: cursor.unavailableSource, cause: cursor.unavailableCause };
|
|
59
57
|
}
|
|
60
|
-
if (!
|
|
58
|
+
if (!isRecord(cursor)) {
|
|
61
59
|
cursor = cursor instanceof Error ? cursor.cause : void 0;
|
|
62
60
|
continue;
|
|
63
61
|
}
|
|
@@ -75,13 +73,13 @@ function navigatorProviderFailureFromError(error) {
|
|
|
75
73
|
function navigatorProviderFailureFromDiagnostics(diagnostics) {
|
|
76
74
|
if (!Array.isArray(diagnostics)) return void 0;
|
|
77
75
|
for (const diagnostic of diagnostics) {
|
|
78
|
-
if (!
|
|
76
|
+
if (!isRecord(diagnostic)) continue;
|
|
79
77
|
if (diagnostic.type === "provider_transport_failure") return { source: "transport", cause: "transport" };
|
|
80
|
-
if (
|
|
78
|
+
if (isRecord(diagnostic.error)) {
|
|
81
79
|
const fromCode = navigatorProviderFailureFromCode(diagnostic.error.code);
|
|
82
80
|
if (fromCode !== void 0) return fromCode;
|
|
83
81
|
}
|
|
84
|
-
if (
|
|
82
|
+
if (isRecord(diagnostic.details)) {
|
|
85
83
|
const status = typeof diagnostic.details.status === "number" ? diagnostic.details.status : typeof diagnostic.details.statusCode === "number" ? diagnostic.details.statusCode : void 0;
|
|
86
84
|
const fromStatus = navigatorProviderFailureFromStatus(status);
|
|
87
85
|
if (fromStatus !== void 0) return fromStatus;
|
|
@@ -142,12 +140,12 @@ function navigatorModelSettingPath() {
|
|
|
142
140
|
async function readNavigatorModelSetting(path = navigatorModelSettingPath()) {
|
|
143
141
|
try {
|
|
144
142
|
const raw = JSON.parse(await readFile(path, "utf8"));
|
|
145
|
-
if (!
|
|
143
|
+
if (!isRecord(raw) || typeof raw.model !== "string" || raw.model.trim() === "") {
|
|
146
144
|
throw new Error("Navigator model setting is malformed");
|
|
147
145
|
}
|
|
148
146
|
return raw.model;
|
|
149
147
|
} catch (error) {
|
|
150
|
-
if (error
|
|
148
|
+
if (isEnoent(error)) {
|
|
151
149
|
throw new Error("Navigator model setting is missing");
|
|
152
150
|
}
|
|
153
151
|
throw error;
|
|
@@ -2,6 +2,7 @@ import { existsSync, realpathSync } from "node:fs";
|
|
|
2
2
|
import { readFile } from "node:fs/promises";
|
|
3
3
|
import { basename, dirname, join, resolve } from "node:path";
|
|
4
4
|
import { writeFileAtomically } from "./atomic-write.js";
|
|
5
|
+
import { isEnoent, isRecord } from "./unknown-value.js";
|
|
5
6
|
const NAVIGATOR_WORK_CONTEXT_BASENAME = "work-context.json";
|
|
6
7
|
function navigatorWorkContextFile(sessionDir) {
|
|
7
8
|
return join(sessionDir, NAVIGATOR_WORK_CONTEXT_BASENAME);
|
|
@@ -32,9 +33,7 @@ async function persistNavigatorWorkBase(sessionDir, body) {
|
|
|
32
33
|
const current = await readFile(path, "utf8");
|
|
33
34
|
if (current === next) return path;
|
|
34
35
|
} catch (error) {
|
|
35
|
-
if (!(error
|
|
36
|
-
throw error;
|
|
37
|
-
}
|
|
36
|
+
if (!isEnoent(error)) throw error;
|
|
38
37
|
}
|
|
39
38
|
await writeFileAtomically(path, next);
|
|
40
39
|
return path;
|
|
@@ -46,9 +45,7 @@ async function readNavigatorWorkBase(path) {
|
|
|
46
45
|
try {
|
|
47
46
|
text = await readFile(canonical, "utf8");
|
|
48
47
|
} catch (error) {
|
|
49
|
-
if (error
|
|
50
|
-
return void 0;
|
|
51
|
-
}
|
|
48
|
+
if (isEnoent(error)) return void 0;
|
|
52
49
|
throw error;
|
|
53
50
|
}
|
|
54
51
|
let parsed;
|
|
@@ -57,7 +54,7 @@ async function readNavigatorWorkBase(path) {
|
|
|
57
54
|
} catch {
|
|
58
55
|
return void 0;
|
|
59
56
|
}
|
|
60
|
-
if (
|
|
57
|
+
if (!isRecord(parsed)) return void 0;
|
|
61
58
|
const record = parsed;
|
|
62
59
|
if (typeof record.subject !== "string" || typeof record.authority !== "string") return void 0;
|
|
63
60
|
if (record.authority.trim() === "") return void 0;
|
|
@@ -68,7 +65,7 @@ function jsonObjectFromPrompt(prompt) {
|
|
|
68
65
|
if (!head.startsWith("{")) return void 0;
|
|
69
66
|
try {
|
|
70
67
|
const parsed = JSON.parse(head);
|
|
71
|
-
if (
|
|
68
|
+
if (!isRecord(parsed)) return void 0;
|
|
72
69
|
return parsed;
|
|
73
70
|
} catch {
|
|
74
71
|
return void 0;
|
package/dist/notary-contracts.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { REVIEW_SUBMISSION_OUTPUT_TOOL_NAME, reviewSubmissionSchema } from "./review-submission.js";
|
|
2
|
+
import { isRecord } from "./unknown-value.js";
|
|
2
3
|
const NOTARY_OUTPUT_TOOL_NAME = REVIEW_SUBMISSION_OUTPUT_TOOL_NAME;
|
|
3
4
|
const NOTARY_SOURCE_RUN_FLAG = {
|
|
4
5
|
name: "ak-notary-source-run",
|
|
@@ -15,11 +16,8 @@ const NOTARY_TICKET_FLAG = {
|
|
|
15
16
|
}
|
|
16
17
|
};
|
|
17
18
|
const notaryOutputSchema = reviewSubmissionSchema;
|
|
18
|
-
function isRecord(value) {
|
|
19
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
20
|
-
}
|
|
21
19
|
function projectLawfulNotaryOutput(value) {
|
|
22
|
-
return
|
|
20
|
+
return isRecord(value) ? value : void 0;
|
|
23
21
|
}
|
|
24
22
|
function retainNotarySubmission(value) {
|
|
25
23
|
if (value === void 0) return { missing: "arguments" };
|
|
@@ -30,7 +28,7 @@ function retainNotarySubmission(value) {
|
|
|
30
28
|
}
|
|
31
29
|
}
|
|
32
30
|
function validateRecordedNotaryOutput(value) {
|
|
33
|
-
if (
|
|
31
|
+
if (!isRecord(value)) {
|
|
34
32
|
throw new Error("Notary output is not an object");
|
|
35
33
|
}
|
|
36
34
|
return value;
|
|
@@ -3,11 +3,9 @@
|
|
|
3
3
|
* Lawful explicit releases: converged | continue | escalate.
|
|
4
4
|
*/
|
|
5
5
|
import { REVIEW_SUBMISSION_OUTPUT_TOOL_NAME, reviewSubmissionSchema } from "../review-submission.js";
|
|
6
|
+
import { isRecord } from "../unknown-value.js";
|
|
6
7
|
export const AUDITOR_OUTPUT_TOOL_NAME = REVIEW_SUBMISSION_OUTPUT_TOOL_NAME;
|
|
7
8
|
export const auditorOutputSchema = reviewSubmissionSchema;
|
|
8
|
-
function isRecord(value) {
|
|
9
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
10
|
-
}
|
|
11
9
|
/** #836: no field drop — original object is the receipt. */
|
|
12
10
|
export function projectLawfulAuditorOutput(value) {
|
|
13
11
|
return isRecord(value) ? value : undefined;
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { Type } from "typebox";
|
|
2
2
|
import { Value } from "typebox/value";
|
|
3
|
+
import { isRecord } from "../unknown-value.js";
|
|
3
4
|
const FIXER_PREREQUISITE_ID_PATTERN = "^[A-Za-z0-9][A-Za-z0-9._-]*$";
|
|
4
5
|
const fixerPrerequisiteSchema = Type.Object({
|
|
5
6
|
id: Type.String({ pattern: FIXER_PREREQUISITE_ID_PATTERN }),
|
|
6
7
|
requirement: Type.String({ pattern: "\\S" })
|
|
7
|
-
}
|
|
8
|
+
});
|
|
8
9
|
const fixerPrerequisitesSchema = Type.Array(fixerPrerequisiteSchema);
|
|
9
10
|
function causeMessage(cause) {
|
|
10
11
|
if (cause instanceof Error) return cause.message;
|
|
@@ -32,13 +33,9 @@ function fail(cause) {
|
|
|
32
33
|
function parseFailure(value) {
|
|
33
34
|
if (!Array.isArray(value)) fail(new Error("Fixer prerequisites must be a JSON array"));
|
|
34
35
|
for (const entry of value) {
|
|
35
|
-
if (
|
|
36
|
+
if (!isRecord(entry)) {
|
|
36
37
|
fail(new Error("Fixer prerequisite entry must be an object with id and requirement fields"));
|
|
37
38
|
}
|
|
38
|
-
const keys = Object.keys(entry);
|
|
39
|
-
if (keys.length !== 2 || !keys.includes("id") || !keys.includes("requirement")) {
|
|
40
|
-
fail(new Error("Fixer prerequisite entry fields must be exactly id and requirement"));
|
|
41
|
-
}
|
|
42
39
|
if (typeof entry.id !== "string" || !new RegExp(FIXER_PREREQUISITE_ID_PATTERN).test(entry.id)) {
|
|
43
40
|
fail(new Error(`Fixer prerequisite id violates pattern ${FIXER_PREREQUISITE_ID_PATTERN}`));
|
|
44
41
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Type } from "typebox";
|
|
2
2
|
import { openToolObject } from "../open-tool-schema.js";
|
|
3
3
|
import { withTerminatingOutputDeclarations } from "./terminating-infrastructure.js";
|
|
4
|
+
import { isRecord } from "../unknown-value.js";
|
|
4
5
|
const GATEKEEPER_OUTPUT_TOOL_NAME = "ak_gatekeeper_output";
|
|
5
6
|
const gatekeeperDecisionSchema = openToolObject(
|
|
6
7
|
Type.Object({
|
|
@@ -18,9 +19,6 @@ const gatekeeperDecisionSchema = openToolObject(
|
|
|
18
19
|
const gatekeeperOutputSchema = withTerminatingOutputDeclarations(
|
|
19
20
|
gatekeeperDecisionSchema
|
|
20
21
|
);
|
|
21
|
-
function isRecord(value) {
|
|
22
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
23
|
-
}
|
|
24
22
|
function asStringArray(value) {
|
|
25
23
|
if (!Array.isArray(value)) return [];
|
|
26
24
|
return value.filter((item) => typeof item === "string");
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Type } from "typebox";
|
|
2
|
+
import { isRecord } from "../unknown-value.js";
|
|
2
3
|
import { openToolObject } from "../open-tool-schema.js";
|
|
3
4
|
import { withTerminatingOutputDeclarations } from "./terminating-infrastructure.js";
|
|
4
5
|
const NAVIGATOR_OUTPUT_TOOL_NAME = "ak_navigator_output";
|
|
@@ -14,18 +15,17 @@ const navigatorOutputSchema = withTerminatingOutputDeclarations(
|
|
|
14
15
|
function projectLawfulNavigatorOutput(value) {
|
|
15
16
|
if (value === void 0 || value === null) return void 0;
|
|
16
17
|
if (typeof value === "string") return { prose: value };
|
|
17
|
-
if (
|
|
18
|
-
|
|
19
|
-
if (
|
|
20
|
-
|
|
21
|
-
return { prose: typeof record.prose === "string" ? record.prose : String(record.prose) };
|
|
18
|
+
if (isRecord(value)) {
|
|
19
|
+
if (typeof value.prose === "string") return { prose: value.prose };
|
|
20
|
+
if (value.prose !== void 0 && value.prose !== null) {
|
|
21
|
+
return { prose: typeof value.prose === "string" ? value.prose : String(value.prose) };
|
|
22
22
|
}
|
|
23
|
-
const keys = Object.keys(
|
|
23
|
+
const keys = Object.keys(value);
|
|
24
24
|
if (keys.length === 0) return { prose: "" };
|
|
25
25
|
try {
|
|
26
|
-
return { prose: JSON.stringify(
|
|
26
|
+
return { prose: JSON.stringify(value) };
|
|
27
27
|
} catch {
|
|
28
|
-
return { prose: String(
|
|
28
|
+
return { prose: String(value) };
|
|
29
29
|
}
|
|
30
30
|
}
|
|
31
31
|
return { prose: String(value) };
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Type } from "typebox";
|
|
2
|
+
import { isRecord } from "../unknown-value.js";
|
|
2
3
|
const INFRASTRUCTURE_FAILURE_DECLARATION_KEY = "infrastructureFailure";
|
|
3
4
|
const INFRASTRUCTURE_FAILURE_DIAGNOSTIC_KEY = "diagnostic";
|
|
4
5
|
const infrastructureFailureNested = Type.Object(
|
|
@@ -37,15 +38,10 @@ function withTerminatingOutputDeclarations(schema) {
|
|
|
37
38
|
return object;
|
|
38
39
|
}
|
|
39
40
|
function isInfrastructureFailureDeclaration(parameters) {
|
|
40
|
-
if (
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
if (!Object.hasOwn(record, INFRASTRUCTURE_FAILURE_DECLARATION_KEY)) return false;
|
|
45
|
-
const declaration = record[INFRASTRUCTURE_FAILURE_DECLARATION_KEY];
|
|
46
|
-
if (declaration === null || typeof declaration !== "object" || Array.isArray(declaration)) {
|
|
47
|
-
return false;
|
|
48
|
-
}
|
|
41
|
+
if (!isRecord(parameters)) return false;
|
|
42
|
+
if (!Object.hasOwn(parameters, INFRASTRUCTURE_FAILURE_DECLARATION_KEY)) return false;
|
|
43
|
+
const declaration = parameters[INFRASTRUCTURE_FAILURE_DECLARATION_KEY];
|
|
44
|
+
if (!isRecord(declaration)) return false;
|
|
49
45
|
const diagnostic = declaration[INFRASTRUCTURE_FAILURE_DIAGNOSTIC_KEY];
|
|
50
46
|
return typeof diagnostic === "string" && diagnostic.trim().length > 0;
|
|
51
47
|
}
|
|
@@ -19,6 +19,7 @@ import { INSPECTOR_OUTPUT_TOOL_NAME, validateRecordedInspectorOutput } from "../
|
|
|
19
19
|
import { DIARIST_OUTPUT_TOOL_NAME, validateRecordedDiaristOutput } from "../diarist-contracts.js";
|
|
20
20
|
import { SECRETARIAT_OUTPUT_TOOL_NAME } from "../secretariat-contracts.js";
|
|
21
21
|
import { CODER_OUTPUT_TOOL_NAME, FIXER_OUTPUT_TOOL_NAME, validateAcceptedWorkerDetails, } from "./worker-output.js";
|
|
22
|
+
import { isRecord } from "../unknown-value.js";
|
|
22
23
|
export { CODER_OUTPUT_TOOL_NAME, COLLECTOR_OUTPUT_TOOL, FIXER_OUTPUT_TOOL_NAME, JUDGE_OUTPUT_TOOL_NAME, REVIEWER_OUTPUT_TOOL_NAME, MERGER_OUTPUT_TOOL_NAME, validateReviewerIntent, validateAcceptedWorkerDetails, validateDoctorSubmissionShape, validateRecordedDoctorOutput, validateMergerOutput, validateRecordedNotaryOutput, validateRecordedCountersignOutput, validateRecordedGleanerLeftOutput, validateRecordedInspectorOutput, validateRecordedGatekeeperOutput, validateRecordedNavigatorOutput, validateRecordedAuditorOutput, validateRecordedDiaristOutput, };
|
|
23
24
|
export const TERMINATING_TOOL_NAMES = [...new Set([
|
|
24
25
|
...PACKAGED_ROLE_REGISTRY.map((entry) => entry.outputTool),
|
|
@@ -39,7 +40,7 @@ export class AcceptedDetailsContractError extends CorrectableSubmissionError {
|
|
|
39
40
|
* Callers that need a typed view may still cast; code must not bounce on status.
|
|
40
41
|
*/
|
|
41
42
|
export function validateAcceptedDetails(_toolName, details) {
|
|
42
|
-
if (
|
|
43
|
+
if (isRecord(details)) {
|
|
43
44
|
return details;
|
|
44
45
|
}
|
|
45
46
|
// Non-object payload still records as empty object rather than rejecting.
|
|
@@ -85,8 +86,8 @@ export function deepEqual(a, b) {
|
|
|
85
86
|
return false;
|
|
86
87
|
return a.every((item, index) => deepEqual(item, b[index]));
|
|
87
88
|
}
|
|
88
|
-
if (
|
|
89
|
-
if (
|
|
89
|
+
if (isRecord(a)) {
|
|
90
|
+
if (!isRecord(b))
|
|
90
91
|
return false;
|
|
91
92
|
const aKeys = Object.keys(a).sort();
|
|
92
93
|
const bKeys = Object.keys(b).sort();
|
|
@@ -20,6 +20,7 @@ import { exactUtf8 } from "../exact-utf8.js";
|
|
|
20
20
|
import { readOrComputeAnalystIssuePage, runAnalyst, analystSweepModeInputSchema, AnalystIssueComputeError, } from "../analyst-entry.js";
|
|
21
21
|
import { CliUsageError } from "./cli-errors.js";
|
|
22
22
|
import { presentControlledFailure, presentStructuralRejection } from "./settlement.js";
|
|
23
|
+
import { errorText } from "../unknown-value.js";
|
|
23
24
|
/**
|
|
24
25
|
* Resolve the issue-query book from cwd git common-dir (same owner as record layer).
|
|
25
26
|
* Non-git cwd fails loud — bare / --ticket both require a book identity.
|
|
@@ -63,7 +64,7 @@ export async function buildAnalystIssueModeInputFromPublicArgv(parsed, _ledgerHo
|
|
|
63
64
|
}
|
|
64
65
|
/**
|
|
65
66
|
* Attachment JSON → library AnalystSweepModeInput via the sole schema (#337).
|
|
66
|
-
* No parallel hand shape; rejects missing
|
|
67
|
+
* No parallel hand shape; rejects missing or wrong-type fields only.
|
|
67
68
|
*/
|
|
68
69
|
export function parseAnalystSweepModeInputFromJsonValue(value) {
|
|
69
70
|
if (!Value.Check(analystSweepModeInputSchema, value)) {
|
|
@@ -94,7 +95,7 @@ export async function buildAnalystSweepModeInputFromAttachmentPaths(attachmentPa
|
|
|
94
95
|
text = exactUtf8(bytes, "analyst sweep attachment");
|
|
95
96
|
}
|
|
96
97
|
catch (error) {
|
|
97
|
-
const detail =
|
|
98
|
+
const detail = errorText(error);
|
|
98
99
|
throw new CliUsageError(detail, { cause: error });
|
|
99
100
|
}
|
|
100
101
|
let parsed;
|
|
@@ -22,6 +22,7 @@ import { processCancelSignalName } from "./process-cancel.js";
|
|
|
22
22
|
import { isLawfulTypedTerminalOutcome, formatTerminalResult } from "./terminal.js";
|
|
23
23
|
import { attachRecordedSubmissions, presentFailureTerminal, resolveControlledFailureResumeObservation, } from "./settlement.js";
|
|
24
24
|
import { serializeThrownValue } from "../serialize-thrown-value.js";
|
|
25
|
+
import { errorText, isEnoent } from "../unknown-value.js";
|
|
25
26
|
const dummyIo = { stdout: () => { }, stderr: () => { } };
|
|
26
27
|
/**
|
|
27
28
|
* Persist run-state after a host-turn result, outside the retried dispatch try.
|
|
@@ -83,7 +84,7 @@ async function finalizeExceptionRunBestEffort(runDirectory, io) {
|
|
|
83
84
|
export class TurnDispatchedFailure extends Error {
|
|
84
85
|
name = "TurnDispatchedFailure";
|
|
85
86
|
constructor(cause) {
|
|
86
|
-
super(`settlement failed after the host turn genuinely started: ${
|
|
87
|
+
super(`settlement failed after the host turn genuinely started: ${errorText(cause)}`, { cause });
|
|
87
88
|
}
|
|
88
89
|
}
|
|
89
90
|
/** Session custom-entry type carrying the pointer to one dispatch error file. */
|
|
@@ -111,7 +112,7 @@ export async function ensureRealArtifactsDirectory(runDirectory) {
|
|
|
111
112
|
}
|
|
112
113
|
}
|
|
113
114
|
catch (error) {
|
|
114
|
-
if (!
|
|
115
|
+
if (!isEnoent(error))
|
|
115
116
|
throw error;
|
|
116
117
|
await mkdir(artifactsDir, { recursive: true });
|
|
117
118
|
const created = await lstat(artifactsDir);
|
|
@@ -121,12 +122,6 @@ export async function ensureRealArtifactsDirectory(runDirectory) {
|
|
|
121
122
|
}
|
|
122
123
|
return artifactsDir;
|
|
123
124
|
}
|
|
124
|
-
/** ENOENT identity shared with settlement.ts's hardened audit-artifact path. */
|
|
125
|
-
function isMissingPathError(error) {
|
|
126
|
-
return (error instanceof Error &&
|
|
127
|
-
"code" in error &&
|
|
128
|
-
error.code === "ENOENT");
|
|
129
|
-
}
|
|
130
125
|
/** Cycle- and bigint-safe JSON replacer so serialization itself cannot drop data. */
|
|
131
126
|
function jsonSafeReplacer() {
|
|
132
127
|
const seen = new WeakSet();
|
|
@@ -155,7 +150,7 @@ function jsonSafeReplacer() {
|
|
|
155
150
|
* + O_NOFOLLOW where the platform provides it (a planted symlink is never
|
|
156
151
|
* followed) — mirrors settlement.ts's own hardened artifact writers.
|
|
157
152
|
*/
|
|
158
|
-
async function writeHardenedArtifactFile(artifactsDir, namePrefix, payload) {
|
|
153
|
+
export async function writeHardenedArtifactFile(artifactsDir, namePrefix, payload) {
|
|
159
154
|
const filePath = join(artifactsDir, `${namePrefix}-${randomUUID()}.json`);
|
|
160
155
|
const body = `${JSON.stringify(payload, jsonSafeReplacer(), 2)}\n`;
|
|
161
156
|
const noFollowFlag = typeof fsConstants.O_NOFOLLOW === "number" ? fsConstants.O_NOFOLLOW : 0;
|