@akagilnc/pi-workflow-roles 0.1.2521 → 0.1.2653-next.71811ca
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/README.md +129 -39
- package/README.zh-CN.md +128 -39
- package/dist/activation-ledger-topology.js +1 -1
- package/dist/archivist-record-entry.js +47 -26
- package/dist/auditor-dossier-tool.js +3 -1
- package/dist/compliance-transport.js +17 -26
- package/dist/doctor-contracts.js +1 -2
- package/dist/dossier-resolution.js +4 -8
- package/dist/engine-detour-tool.js +33 -8
- package/dist/engine-detour.js +1 -0
- package/dist/evidence-child-executor.js +277 -424
- package/dist/host-contracts.js +22 -0
- package/dist/institutional-resolution.js +88 -0
- package/dist/merger-contracts.js +1 -2
- package/dist/navigator-attendance.js +16 -0
- package/dist/notary-contracts.js +2 -3
- package/dist/package-contracts/fixer-output.js +1 -2
- package/dist/packaged-role-registry.js +102 -9
- package/dist/pi/in-process-session.js +671 -0
- package/dist/public-cli/config.js +7 -5
- package/dist/public-cli/main.js +3767 -4113
- package/dist/reviewer-child-executor.js +6 -1
- package/dist/session-opening-materials.js +10 -38
- package/dist/sitian-appender.js +146 -0
- package/dist/sitian-contracts.js +21 -0
- package/dist/sitian-facade.js +15 -0
- package/dist/sitian-reader.js +52 -0
- package/extensions/role-runtime.ts +9 -7
- package/package.json +5 -5
- package/resources/engines/cursor.md +12 -26
- package/resources/engines/hermes.md +2 -23
- package/resources/engines/opus.md +1 -16
- package/resources/navigator-route-playbook.md +2 -2
- package/scripts/build-package.mjs +0 -1
- package/souls/quality-law.md +1 -1
- package/src/activation-ledger-topology.ts +1 -1
- package/src/archivist-record-entry.ts +57 -45
- package/src/auditor-dossier-tool.ts +4 -2
- package/src/canonical-skill-binding.ts +37 -27
- package/src/collector-role.ts +11 -20
- package/src/collector-tool-schemas.ts +1 -4
- package/src/compliance-transport.ts +19 -44
- package/src/doctor-auditor.ts +1 -5
- package/src/doctor-contracts.ts +1 -4
- package/src/doctor-role.ts +31 -8
- package/src/dossier-resolution.ts +8 -8
- package/src/engine-detour-tool.ts +48 -19
- package/src/engine-detour.ts +3 -0
- package/src/evidence-child-executor.ts +277 -485
- package/src/factory-board.ts +3 -3
- package/src/gatekeeper-role.ts +21 -10
- package/src/host-contracts.ts +386 -0
- package/src/in-process-session.ts +1 -115
- package/src/institutional-resolution.ts +135 -0
- package/src/judge-auditor.ts +1 -5
- package/src/judge-role.ts +37 -51
- package/src/merger-contracts.ts +1 -4
- package/src/merger-role.ts +7 -11
- package/src/navigator-attendance.ts +20 -1
- package/src/notary-contracts.ts +8 -11
- package/src/notary-role.ts +7 -23
- package/src/notary-source-run.ts +4 -3
- package/src/package-contracts/fixer-output.ts +1 -4
- package/src/package-resources/method-skill-binding.ts +10 -34
- package/src/packaged-role-registry.ts +122 -12
- package/src/pi/adapter.ts +192 -0
- package/src/pi/durable-principal.ts +98 -0
- package/src/pi/in-process-session.ts +819 -0
- package/src/pi/known-failure.ts +77 -0
- package/src/pi/pi-normalization.ts +284 -0
- package/src/pi/role-turn-host.ts +459 -0
- package/src/public-cli/auto-resume.ts +42 -44
- package/src/public-cli/cli.ts +171 -257
- package/src/public-cli/coder-run.ts +115 -433
- package/src/public-cli/collector-run.ts +62 -314
- package/src/public-cli/config.ts +7 -5
- package/src/public-cli/doctor-run.ts +41 -52
- package/src/public-cli/fixer-run.ts +122 -427
- package/src/public-cli/invocation.ts +287 -96
- package/src/public-cli/judge-run.ts +92 -422
- package/src/public-cli/merger-run.ts +167 -429
- package/src/public-cli/notary-run.ts +41 -47
- package/src/public-cli/option-definitions.ts +136 -3
- package/src/public-cli/post-admission.ts +497 -0
- package/src/public-cli/public-run-credentials.ts +4 -4
- package/src/public-cli/reviewer-dispatch-rejection.ts +106 -0
- package/src/public-cli/reviewer-run.ts +132 -449
- package/src/public-cli/run-lifecycle.ts +339 -327
- package/src/public-cli/settlement.ts +251 -134
- package/src/public-cli/terminal.ts +3 -9
- package/src/public-cli/turn-request.ts +87 -0
- package/src/reviewer-child-executor.ts +9 -1
- package/src/reviewer-role.ts +11 -20
- package/src/role-runtime.ts +129 -78
- package/src/session-opening-materials.ts +25 -39
- package/src/sitian-appender.ts +171 -0
- package/src/sitian-contracts.ts +106 -0
- package/src/sitian-facade.ts +18 -0
- package/src/sitian-reader.ts +62 -0
- package/src/worker-role.ts +42 -40
- package/src/worker-submission-gates.ts +33 -0
- package/dist/archivist-role-run-coordinates.js +0 -28
- package/dist/package-contracts/terminating-infrastructure.js +0 -90
- package/resources/engines/sonnet.md +0 -27
- package/resources/engines/zcode.md +0 -63
- package/src/archivist-role-run-coordinates.ts +0 -45
- package/src/package-contracts/terminating-infrastructure.ts +0 -132
- package/src/public-cli/explicit-internal.ts +0 -427
- package/src/public-cli/one-shot-dispatch.ts +0 -300
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Package-owned shared infrastructure-failure declaration for every primary
|
|
3
|
-
* packaged-role output tool (#541).
|
|
4
|
-
*
|
|
5
|
-
* One module owns what the judge mandates be shared (not reimplemented per
|
|
6
|
-
* seat): the typed `infrastructureFailure.diagnostic` declaration composed into
|
|
7
|
-
* each output tool's schema, and the single early host `failInfrastructure`
|
|
8
|
-
* call each output `execute` makes before any role business validation / gate /
|
|
9
|
-
* audit / ledger / Git work. The accepted status sets are intentionally NOT
|
|
10
|
-
* extended: an infra declaration fails BEFORE accepted validation, never
|
|
11
|
-
* becomes an accepted receipt. The diagnostic is carried verbatim on the thrown
|
|
12
|
-
* Error so settlement keeps the original cause (kind=failure, exit 1).
|
|
13
|
-
*/
|
|
14
|
-
import { Type } from "typebox";
|
|
15
|
-
export const INFRASTRUCTURE_FAILURE_DECLARATION_KEY = "infrastructureFailure";
|
|
16
|
-
export const INFRASTRUCTURE_FAILURE_DIAGNOSTIC_KEY = "diagnostic";
|
|
17
|
-
/** Shared typed declaration fragment: `infrastructureFailure.diagnostic` = non-empty string. */
|
|
18
|
-
const infrastructureFailureDeclarationSchema = Type.Object({
|
|
19
|
-
[INFRASTRUCTURE_FAILURE_DECLARATION_KEY]: Type.Object({
|
|
20
|
-
[INFRASTRUCTURE_FAILURE_DIAGNOSTIC_KEY]: Type.String({
|
|
21
|
-
minLength: 1,
|
|
22
|
-
description: "非空基础设施失败诊断",
|
|
23
|
-
}),
|
|
24
|
-
}, {
|
|
25
|
-
additionalProperties: true,
|
|
26
|
-
description: "基础设施失败声明",
|
|
27
|
-
}),
|
|
28
|
-
}, { additionalProperties: true });
|
|
29
|
-
/**
|
|
30
|
-
* Compose the shared infrastructure-failure declaration into an open output
|
|
31
|
-
* tool-object schema. Returns an open object (additionalProperties: true,
|
|
32
|
-
* required: []) with the base schema's properties plus the shared declaration.
|
|
33
|
-
* Static typing is preserved on the base (`as S`), so existing
|
|
34
|
-
* `Static<typeof ...>` derived parameter types are unchanged.
|
|
35
|
-
*/
|
|
36
|
-
export function withInfrastructureFailureDeclaration(schema) {
|
|
37
|
-
const baseProperties = schema
|
|
38
|
-
.properties;
|
|
39
|
-
const properties = {
|
|
40
|
-
...(baseProperties ?? {}),
|
|
41
|
-
[INFRASTRUCTURE_FAILURE_DECLARATION_KEY]: infrastructureFailureDeclarationSchema.properties[INFRASTRUCTURE_FAILURE_DECLARATION_KEY],
|
|
42
|
-
};
|
|
43
|
-
const object = Type.Object(properties, { additionalProperties: true });
|
|
44
|
-
object.required = [];
|
|
45
|
-
return object;
|
|
46
|
-
}
|
|
47
|
-
/** Safe recognition of the typed declaration; non-shapes / hostile input fail closed. */
|
|
48
|
-
function isInfrastructureFailureDeclaration(parameters) {
|
|
49
|
-
if (parameters === null ||
|
|
50
|
-
typeof parameters !== "object" ||
|
|
51
|
-
Array.isArray(parameters)) {
|
|
52
|
-
return false;
|
|
53
|
-
}
|
|
54
|
-
const record = parameters;
|
|
55
|
-
if (!Object.hasOwn(record, INFRASTRUCTURE_FAILURE_DECLARATION_KEY))
|
|
56
|
-
return false;
|
|
57
|
-
const declaration = record[INFRASTRUCTURE_FAILURE_DECLARATION_KEY];
|
|
58
|
-
if (declaration === null ||
|
|
59
|
-
typeof declaration !== "object" ||
|
|
60
|
-
Array.isArray(declaration)) {
|
|
61
|
-
return false;
|
|
62
|
-
}
|
|
63
|
-
const diagnostic = declaration[INFRASTRUCTURE_FAILURE_DIAGNOSTIC_KEY];
|
|
64
|
-
return typeof diagnostic === "string" && diagnostic.trim().length > 0;
|
|
65
|
-
}
|
|
66
|
-
/** Non-empty trimmed diagnostic from the declaration, else undefined. */
|
|
67
|
-
function infrastructureFailureDiagnostic(parameters) {
|
|
68
|
-
if (!isInfrastructureFailureDeclaration(parameters))
|
|
69
|
-
return undefined;
|
|
70
|
-
const declaration = parameters[INFRASTRUCTURE_FAILURE_DECLARATION_KEY];
|
|
71
|
-
const diagnostic = declaration[INFRASTRUCTURE_FAILURE_DIAGNOSTIC_KEY];
|
|
72
|
-
return typeof diagnostic === "string" ? diagnostic.trim() : undefined;
|
|
73
|
-
}
|
|
74
|
-
/** diagnostic → Error, name stamped so the host error identity is observable. */
|
|
75
|
-
function infrastructureFailureError(diagnostic) {
|
|
76
|
-
const error = new Error(diagnostic);
|
|
77
|
-
error.name = "InfrastructureFailure";
|
|
78
|
-
return error;
|
|
79
|
-
}
|
|
80
|
-
/**
|
|
81
|
-
* The one early call for every terminating output `execute`: if the parameters
|
|
82
|
-
* carry the infra declaration, hand the diagnostic error to the shared host
|
|
83
|
-
* `failInfrastructure` seam (which aborts the run). No-op otherwise.
|
|
84
|
-
*/
|
|
85
|
-
export function failOnInfrastructureFailureDeclaration(parameters, hostActions, ctx, toolCallId) {
|
|
86
|
-
const diagnostic = infrastructureFailureDiagnostic(parameters);
|
|
87
|
-
if (diagnostic === undefined)
|
|
88
|
-
return;
|
|
89
|
-
hostActions.failInfrastructure(infrastructureFailureError(diagnostic), ctx, toolCallId);
|
|
90
|
-
}
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
# sonnet engine method material
|
|
2
|
-
|
|
3
|
-
This file is packaged technical material for the optional `sonnet` labor engine
|
|
4
|
-
(Claude Code CLI on the host, pinned to the Sonnet model).
|
|
5
|
-
|
|
6
|
-
Before invoking the engine, read `../engine-dispatch.md`, resolving that path
|
|
7
|
-
relative to this note. This note only covers this engine's CLI technical
|
|
8
|
-
parameters.
|
|
9
|
-
|
|
10
|
-
## Invocation
|
|
11
|
-
|
|
12
|
-
Same host CLI as the `opus` engine: the machine entrypoint is `claude`, and all
|
|
13
|
-
CLI mechanics (print mode, `--output-format=stream-json` requiring `--verbose`,
|
|
14
|
-
fd layout, result-row extraction) are documented in `../opus.md` — read that
|
|
15
|
-
note for them; they are not duplicated here.
|
|
16
|
-
|
|
17
|
-
The only difference is the model pin:
|
|
18
|
-
|
|
19
|
-
```bash
|
|
20
|
-
claude -p --model sonnet --verbose --output-format=stream-json "YOUR_LABOR_PROMPT"
|
|
21
|
-
```
|
|
22
|
-
|
|
23
|
-
`--model sonnet` is verified accepted on this host (Claude Code 2.1.233); the
|
|
24
|
-
stream-json init event reports `claude-sonnet-5` (host-verified 2026-08-28).
|
|
25
|
-
|
|
26
|
-
Prefer `claude --help` on the host over any remembered flag set. Do not wrap
|
|
27
|
-
this engine behind `ak-role` flags.
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
# zcode engine method material
|
|
2
|
-
|
|
3
|
-
This file is packaged technical material for the optional `zcode` labor engine
|
|
4
|
-
(Z.AI ZCode agent runtime on the host, GLM Coding Plan models).
|
|
5
|
-
|
|
6
|
-
Before invoking the engine, read `../engine-dispatch.md`, resolving that path
|
|
7
|
-
relative to this note. This note only covers this engine's CLI technical
|
|
8
|
-
parameters.
|
|
9
|
-
|
|
10
|
-
## Invocation (host-verified 2026-08-29)
|
|
11
|
-
|
|
12
|
-
The machine entrypoint is `zcode` (npm `zcode-app-cli`, wraps the official
|
|
13
|
-
ZCode runtime; host has 3.10.1-17 / runtime 0.16.5). Non-interactive labor:
|
|
14
|
-
|
|
15
|
-
```bash
|
|
16
|
-
zcode --prompt 'YOUR_LABOR_PROMPT' --cwd /path/to/worktree
|
|
17
|
-
```
|
|
18
|
-
|
|
19
|
-
`--prompt` defaults to permission mode `yolo` (no TTY permission stalls).
|
|
20
|
-
Useful extras measured from `zcode --help`: `--attach <path>` (repeatable),
|
|
21
|
-
`--mode build|edit|plan|yolo`, `--resume <sess_...>`, `--json` where
|
|
22
|
-
supported. Prefer `zcode --help` on the host over any remembered flag set.
|
|
23
|
-
|
|
24
|
-
## Realm and model traps (host-verified 2026-08-29, all three hit in sequence)
|
|
25
|
-
|
|
26
|
-
- Missing `~/.zcode/cli/config.json` → hard error `Model config is missing`.
|
|
27
|
-
The desktop app's login is NOT shared with the CLI.
|
|
28
|
-
- `zcode login` signs into the **overseas Z.AI realm only**. An account on the
|
|
29
|
-
mainland BigModel realm then fails with
|
|
30
|
-
`[1113][Insufficient balance or no resource package]`.
|
|
31
|
-
- The scaffolded config defaults `model.main` to `zai/glm-5.2`, which is not
|
|
32
|
-
in the coding plan — same 1113 failure even with a valid plan.
|
|
33
|
-
|
|
34
|
-
Working mainland configuration (per official docs
|
|
35
|
-
`docs.bigmodel.cn/cn/coding-plan/quick-start`): in
|
|
36
|
-
`~/.zcode/cli/config.json`, provider kind `anthropic` with
|
|
37
|
-
`baseURL: https://open.bigmodel.cn/api/anthropic`, `options.apiKey` = the
|
|
38
|
-
coding-plan key (host keychain: service `glm-key`, account `akagilnc`), and
|
|
39
|
-
`model.main: zai/glm-5.3`, `model.lite: zai/glm-5.3-flash`. With that config
|
|
40
|
-
the smoke prompt returns normally.
|
|
41
|
-
|
|
42
|
-
## Quota facts (owner-provided, 2026-08-28)
|
|
43
|
-
|
|
44
|
-
Plan quotas are daily and per-model (GLM-5.3 3M/day, Flash 5M/day on the
|
|
45
|
-
current plan; a weekend event granted a larger temporary pool). Whether cached
|
|
46
|
-
tokens count toward quota is unverified.
|
|
47
|
-
|
|
48
|
-
## Lane status: PARKED (host-verified 2026-08-29)
|
|
49
|
-
|
|
50
|
-
The "working" configuration above drew from a new-user gift resource package
|
|
51
|
-
(2M general-model tokens), not from any plan. Once that package expired,
|
|
52
|
-
glm-5.3-flash returns `1113` (insufficient balance) with the same key on BOTH
|
|
53
|
-
the anthropic endpoint and the coding endpoint
|
|
54
|
-
(`open.bigmodel.cn/api/coding/paas/v4`, HTTP 429 + code 1113, probed with a
|
|
55
|
-
minimal request). The ZCode Start/Weekend plan quotas are bound to the desktop
|
|
56
|
-
app's OAuth connection ("Start Plan" connection mode); the CLI's
|
|
57
|
-
`/login bigmodel-coding-plan` OAuth variant hard-fails with
|
|
58
|
-
`BigModel OAuth appSecret is required.` (the client secret ships only inside
|
|
59
|
-
the desktop app; no env override exists — only `BIGMODEL_*_API_BASE_URL`).
|
|
60
|
-
The plan page issues exactly one API key and it is the key tested above.
|
|
61
|
-
|
|
62
|
-
Net: this engine lane has no funded model until a key with actual balance or
|
|
63
|
-
an in-plan API path exists. Do not dispatch `--engine zcode` until then.
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
import { join } from "node:path";
|
|
2
|
-
|
|
3
|
-
import { resolveBookKeyFromGit } from "./activation-ledger-git.ts";
|
|
4
|
-
import {
|
|
5
|
-
activationBookDirectory,
|
|
6
|
-
resolveActivationLedgerHome,
|
|
7
|
-
} from "./activation-ledger-topology.ts";
|
|
8
|
-
|
|
9
|
-
export type RoleRunSessionCoordinates = {
|
|
10
|
-
readonly ledgerHome: string;
|
|
11
|
-
readonly bookKey: string;
|
|
12
|
-
readonly runDirectory: string;
|
|
13
|
-
readonly sessionDirectory: string;
|
|
14
|
-
readonly sessionFile: string;
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* Sole source of public top-level Role run session coordinates.
|
|
19
|
-
* Callers supply identity only; no destination can be injected.
|
|
20
|
-
*/
|
|
21
|
-
export function roleRunSessionCoordinates(options: {
|
|
22
|
-
readonly cwd: string;
|
|
23
|
-
readonly runId: string;
|
|
24
|
-
readonly role: string;
|
|
25
|
-
/** Machine-home identity; not a record destination. */
|
|
26
|
-
readonly home?: string;
|
|
27
|
-
}): RoleRunSessionCoordinates {
|
|
28
|
-
const ledgerHome = resolveActivationLedgerHome(
|
|
29
|
-
options.home === undefined ? undefined : () => options.home!,
|
|
30
|
-
);
|
|
31
|
-
const bookKey = resolveBookKeyFromGit(options.cwd);
|
|
32
|
-
const runDirectory = join(
|
|
33
|
-
activationBookDirectory(ledgerHome, bookKey),
|
|
34
|
-
"runs",
|
|
35
|
-
`${options.runId}@${options.role}`,
|
|
36
|
-
);
|
|
37
|
-
const sessionDirectory = join(runDirectory, "session");
|
|
38
|
-
return {
|
|
39
|
-
ledgerHome,
|
|
40
|
-
bookKey,
|
|
41
|
-
runDirectory,
|
|
42
|
-
sessionDirectory,
|
|
43
|
-
sessionFile: join(sessionDirectory, "session.jsonl"),
|
|
44
|
-
};
|
|
45
|
-
}
|
|
@@ -1,132 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Package-owned shared infrastructure-failure declaration for every primary
|
|
3
|
-
* packaged-role output tool (#541).
|
|
4
|
-
*
|
|
5
|
-
* One module owns what the judge mandates be shared (not reimplemented per
|
|
6
|
-
* seat): the typed `infrastructureFailure.diagnostic` declaration composed into
|
|
7
|
-
* each output tool's schema, and the single early host `failInfrastructure`
|
|
8
|
-
* call each output `execute` makes before any role business validation / gate /
|
|
9
|
-
* audit / ledger / Git work. The accepted status sets are intentionally NOT
|
|
10
|
-
* extended: an infra declaration fails BEFORE accepted validation, never
|
|
11
|
-
* becomes an accepted receipt. The diagnostic is carried verbatim on the thrown
|
|
12
|
-
* Error so settlement keeps the original cause (kind=failure, exit 1).
|
|
13
|
-
*/
|
|
14
|
-
import { Type, type TSchema } from "typebox";
|
|
15
|
-
|
|
16
|
-
export const INFRASTRUCTURE_FAILURE_DECLARATION_KEY =
|
|
17
|
-
"infrastructureFailure" as const;
|
|
18
|
-
export const INFRASTRUCTURE_FAILURE_DIAGNOSTIC_KEY = "diagnostic" as const;
|
|
19
|
-
|
|
20
|
-
/** Shared typed declaration fragment: `infrastructureFailure.diagnostic` = non-empty string. */
|
|
21
|
-
const infrastructureFailureDeclarationSchema = Type.Object(
|
|
22
|
-
{
|
|
23
|
-
[INFRASTRUCTURE_FAILURE_DECLARATION_KEY]: Type.Object(
|
|
24
|
-
{
|
|
25
|
-
[INFRASTRUCTURE_FAILURE_DIAGNOSTIC_KEY]: Type.String({
|
|
26
|
-
minLength: 1,
|
|
27
|
-
description: "非空基础设施失败诊断",
|
|
28
|
-
}),
|
|
29
|
-
},
|
|
30
|
-
{
|
|
31
|
-
additionalProperties: true,
|
|
32
|
-
description: "基础设施失败声明",
|
|
33
|
-
},
|
|
34
|
-
),
|
|
35
|
-
},
|
|
36
|
-
{ additionalProperties: true },
|
|
37
|
-
);
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* Compose the shared infrastructure-failure declaration into an open output
|
|
41
|
-
* tool-object schema. Returns an open object (additionalProperties: true,
|
|
42
|
-
* required: []) with the base schema's properties plus the shared declaration.
|
|
43
|
-
* Static typing is preserved on the base (`as S`), so existing
|
|
44
|
-
* `Static<typeof ...>` derived parameter types are unchanged.
|
|
45
|
-
*/
|
|
46
|
-
export function withInfrastructureFailureDeclaration<
|
|
47
|
-
S extends TSchema & { properties?: Record<string, TSchema> },
|
|
48
|
-
>(schema: S): S {
|
|
49
|
-
const baseProperties = (schema as { properties?: Record<string, TSchema> })
|
|
50
|
-
.properties;
|
|
51
|
-
const properties: Record<string, TSchema> = {
|
|
52
|
-
...(baseProperties ?? {}),
|
|
53
|
-
[INFRASTRUCTURE_FAILURE_DECLARATION_KEY]:
|
|
54
|
-
infrastructureFailureDeclarationSchema.properties[
|
|
55
|
-
INFRASTRUCTURE_FAILURE_DECLARATION_KEY
|
|
56
|
-
],
|
|
57
|
-
};
|
|
58
|
-
const object = Type.Object(properties, { additionalProperties: true });
|
|
59
|
-
(object as unknown as { required: string[] }).required = [];
|
|
60
|
-
return object as unknown as S;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
/** Structural host seam subset shared by every terminating execute path. */
|
|
64
|
-
type TerminatingInfrastructureHostActions<C> = {
|
|
65
|
-
failInfrastructure(error: unknown, ctx: C, toolCallId?: string): never;
|
|
66
|
-
};
|
|
67
|
-
|
|
68
|
-
/** Safe recognition of the typed declaration; non-shapes / hostile input fail closed. */
|
|
69
|
-
function isInfrastructureFailureDeclaration(
|
|
70
|
-
parameters: unknown,
|
|
71
|
-
): boolean {
|
|
72
|
-
if (
|
|
73
|
-
parameters === null ||
|
|
74
|
-
typeof parameters !== "object" ||
|
|
75
|
-
Array.isArray(parameters)
|
|
76
|
-
) {
|
|
77
|
-
return false;
|
|
78
|
-
}
|
|
79
|
-
const record = parameters as Record<string, unknown>;
|
|
80
|
-
if (!Object.hasOwn(record, INFRASTRUCTURE_FAILURE_DECLARATION_KEY)) return false;
|
|
81
|
-
const declaration = record[INFRASTRUCTURE_FAILURE_DECLARATION_KEY];
|
|
82
|
-
if (
|
|
83
|
-
declaration === null ||
|
|
84
|
-
typeof declaration !== "object" ||
|
|
85
|
-
Array.isArray(declaration)
|
|
86
|
-
) {
|
|
87
|
-
return false;
|
|
88
|
-
}
|
|
89
|
-
const diagnostic = (declaration as Record<string, unknown>)[
|
|
90
|
-
INFRASTRUCTURE_FAILURE_DIAGNOSTIC_KEY
|
|
91
|
-
];
|
|
92
|
-
return typeof diagnostic === "string" && diagnostic.trim().length > 0;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
/** Non-empty trimmed diagnostic from the declaration, else undefined. */
|
|
96
|
-
function infrastructureFailureDiagnostic(
|
|
97
|
-
parameters: unknown,
|
|
98
|
-
): string | undefined {
|
|
99
|
-
if (!isInfrastructureFailureDeclaration(parameters)) return undefined;
|
|
100
|
-
const declaration = (parameters as Record<string, unknown>)[
|
|
101
|
-
INFRASTRUCTURE_FAILURE_DECLARATION_KEY
|
|
102
|
-
] as Record<string, unknown>;
|
|
103
|
-
const diagnostic = declaration[INFRASTRUCTURE_FAILURE_DIAGNOSTIC_KEY];
|
|
104
|
-
return typeof diagnostic === "string" ? diagnostic.trim() : undefined;
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
/** diagnostic → Error, name stamped so the host error identity is observable. */
|
|
108
|
-
function infrastructureFailureError(diagnostic: string): Error {
|
|
109
|
-
const error = new Error(diagnostic);
|
|
110
|
-
error.name = "InfrastructureFailure";
|
|
111
|
-
return error;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
/**
|
|
115
|
-
* The one early call for every terminating output `execute`: if the parameters
|
|
116
|
-
* carry the infra declaration, hand the diagnostic error to the shared host
|
|
117
|
-
* `failInfrastructure` seam (which aborts the run). No-op otherwise.
|
|
118
|
-
*/
|
|
119
|
-
export function failOnInfrastructureFailureDeclaration<C>(
|
|
120
|
-
parameters: unknown,
|
|
121
|
-
hostActions: TerminatingInfrastructureHostActions<C>,
|
|
122
|
-
ctx: C,
|
|
123
|
-
toolCallId: string,
|
|
124
|
-
): void {
|
|
125
|
-
const diagnostic = infrastructureFailureDiagnostic(parameters);
|
|
126
|
-
if (diagnostic === undefined) return;
|
|
127
|
-
hostActions.failInfrastructure(
|
|
128
|
-
infrastructureFailureError(diagnostic),
|
|
129
|
-
ctx,
|
|
130
|
-
toolCallId,
|
|
131
|
-
);
|
|
132
|
-
}
|