@astrosheep/keiyaku 2.9.2 → 2.9.4
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/build/.tsbuildinfo +1 -1
- package/build/agents/call-terms.js +13 -94
- package/build/agents/harness/activity-values.js +16 -0
- package/build/agents/harness/event-persistence.js +218 -0
- package/build/agents/harness/execution-handle.js +25 -222
- package/build/agents/harness/index.js +3 -1
- package/build/agents/harness/outcome.js +47 -4
- package/build/agents/harness/projection.js +42 -59
- package/build/agents/harness/provider-adapter.js +58 -0
- package/build/agents/harness/router.js +11 -187
- package/build/agents/harness/runtime.js +17 -4
- package/build/agents/harness/session.js +15 -0
- package/build/agents/launch-snapshot/model.js +15 -236
- package/build/agents/launch-snapshot/parse-helpers.js +114 -0
- package/build/agents/launch-snapshot/resolve.js +17 -43
- package/build/agents/opencode-sdk.js +45 -12
- package/build/agents/providers/claude-agent-sdk/adapter.js +6 -17
- package/build/agents/providers/claude-agent-sdk/registration.js +214 -0
- package/build/agents/providers/claude-agent-sdk/session-schema.js +2 -0
- package/build/agents/providers/codex-app-server/adapter.js +50 -53
- package/build/agents/providers/codex-app-server/events.js +67 -11
- package/build/agents/providers/codex-app-server/identity.js +1 -0
- package/build/agents/providers/codex-app-server/policy.js +29 -0
- package/build/agents/providers/codex-app-server/registration.js +248 -0
- package/build/agents/providers/codex-app-server/session-schema.js +6 -0
- package/build/agents/providers/codex-app-server/session.js +23 -17
- package/build/agents/providers/codex-app-server/terms.js +1 -0
- package/build/agents/providers/opencode-sdk/adapter.js +94 -50
- package/build/agents/providers/opencode-sdk/events.js +8 -4
- package/build/agents/providers/opencode-sdk/registration.js +135 -0
- package/build/agents/providers/opencode-sdk/session-schema.js +2 -0
- package/build/agents/providers/opencode-sdk/session.js +21 -14
- package/build/agents/providers/opencode-sdk/terms.js +1 -0
- package/build/agents/providers/pi/adapter.js +36 -30
- package/build/agents/providers/pi/registration.js +145 -0
- package/build/agents/providers/pi/session-schema.js +6 -0
- package/build/agents/providers/pi/terms.js +1 -0
- package/build/agents/providers/registration.js +7 -0
- package/build/agents/providers/registry.js +76 -0
- package/build/agents/selector.js +2 -29
- package/build/agents/types.js +8 -0
- package/build/artifact-directories.js +22 -0
- package/build/cli/commands/akuma/akuma/handler.js +1 -1
- package/build/cli/commands/akuma/view/handler.js +5 -4
- package/build/cli/commands/akuma.js +6 -0
- package/build/cli/commands/contract/amend/handler.js +8 -2
- package/build/cli/commands/contract/arc/handler.js +7 -1
- package/build/cli/commands/contract/bind/handler.js +4 -3
- package/build/cli/commands/contract/bind/meta.js +34 -7
- package/build/cli/commands/contract/forfeit/handler.js +4 -4
- package/build/cli/commands/contract/log/handler.js +3 -3
- package/build/cli/commands/contract/petition/handler.js +4 -6
- package/build/cli/commands/contract/renew/handler.js +20 -6
- package/build/cli/commands/contract/renew/meta.js +5 -4
- package/build/cli/commands/metadata.js +58 -0
- package/build/cli/commands/projection/call/handler.js +6 -5
- package/build/cli/commands/projection/kill/handler.js +16 -32
- package/build/cli/commands/projection/shared.js +28 -0
- package/build/cli/commands/projection/status/handler.js +1 -1
- package/build/cli/commands/projection/tell/handler.js +14 -30
- package/build/cli/commands/projection/wait/handler.js +45 -22
- package/build/cli/commands/projection/wait/meta.js +7 -2
- package/build/cli/commands/registry.js +2 -54
- package/build/cli/commands/shared.js +10 -7
- package/build/cli/commands/skills/install/handler.js +2 -5
- package/build/cli/commands/skills/skills/handler.js +1 -1
- package/build/cli/commands/task/add/handler.js +5 -13
- package/build/cli/commands/task/catalog.js +2 -2
- package/build/cli/commands/task/done/handler.js +4 -8
- package/build/cli/commands/task/drop/handler.js +3 -6
- package/build/cli/commands/task/ls/handler.js +3 -5
- package/build/cli/commands/task/shared.js +14 -4
- package/build/cli/commands/task/{view → show}/handler.js +7 -8
- package/build/cli/commands/task/show/meta.js +8 -0
- package/build/cli/commands/task/start/handler.js +3 -6
- package/build/cli/commands/task/stop/handler.js +4 -8
- package/build/cli/commands/task/task/handler.js +1 -1
- package/build/cli/commands/task/update/handler.js +4 -8
- package/build/cli/completion.js +1 -1
- package/build/cli/flags.js +19 -3
- package/build/cli/help.js +4 -11
- package/build/cli/index.js +57 -83
- package/build/cli/missing-subcommand.js +7 -0
- package/build/cli/parse-flags.js +14 -5
- package/build/cli/parse-metadata.js +3 -3
- package/build/cli/parse-selectors.js +1 -1
- package/build/cli/parse.js +21 -0
- package/build/cli/projection-address.js +7 -12
- package/build/cli/render/address.js +41 -37
- package/build/cli/render/arc.js +24 -12
- package/build/cli/render/call.js +11 -5
- package/build/cli/render/errors.js +36 -1
- package/build/cli/render/format.js +4 -0
- package/build/cli/render/kanshi.js +6 -12
- package/build/cli/render/kill.js +9 -0
- package/build/cli/render/misc.js +55 -12
- package/build/cli/render/petition.js +20 -15
- package/build/cli/render/projection-activity.js +3 -0
- package/build/cli/render/shared.js +60 -21
- package/build/cli/render/skills.js +10 -0
- package/build/cli/render/status.js +37 -14
- package/build/cli/render/success-response.js +77 -0
- package/build/cli/render/task.js +54 -14
- package/build/cli/render/tell.js +5 -0
- package/build/cli/render/terminal-failure.js +58 -0
- package/build/cli/render/types.js +1 -0
- package/build/cli/render/wait.js +38 -36
- package/build/cli/types.js +1 -1
- package/build/config/akuma-loader.js +0 -5
- package/build/config/env-keys.js +1 -1
- package/build/config/provider-policy-ownership.js +3 -32
- package/build/config/settings/disease.js +8 -1
- package/build/config/settings/loader.js +11 -3
- package/build/config/settings/provider-instance-fields.js +51 -0
- package/build/config/settings/schema.js +6 -176
- package/build/core/addressing.js +66 -16
- package/build/core/amend.js +135 -18
- package/build/core/arc.js +19 -67
- package/build/core/bind.js +82 -35
- package/build/core/call/call.js +15 -9
- package/build/core/call/context.js +6 -51
- package/build/core/call/execution.js +21 -22
- package/build/core/call/prompt.js +14 -1
- package/build/core/command-markdown.js +45 -0
- package/build/core/context.js +13 -7
- package/build/core/contract-view.js +20 -3
- package/build/core/draft.js +123 -16
- package/build/core/forfeit.js +5 -2
- package/build/core/hints.js +1 -75
- package/build/core/identifier-slug.js +66 -0
- package/build/core/ids.js +25 -11
- package/build/core/ledger.js +20 -68
- package/build/core/markdown/parser.js +0 -68
- package/build/core/markdown/render.js +68 -0
- package/build/core/markdown/sections.js +2 -1
- package/build/core/outcome-base.js +4 -0
- package/build/core/projection/generation/database.js +2 -38
- package/build/core/projection/generation/model.js +42 -1
- package/build/core/{projection-generation-continuation.js → projection/generation/projection-generation-continuation.js} +3 -3
- package/build/core/{projection-generation-execution.js → projection/generation/projection-generation-execution.js} +19 -49
- package/build/core/{projection-generation-identity.js → projection/generation/projection-generation-identity.js} +2 -2
- package/build/core/{projection-generation-launcher.js → projection/generation/projection-generation-launcher.js} +5 -3
- package/build/core/{projection-generation-process.js → projection/generation/projection-generation-process.js} +2 -1
- package/build/core/{projection-generation-runner.js → projection/generation/projection-generation-runner.js} +18 -3
- package/build/core/projection/generation/store.js +2 -2
- package/build/core/projection/generation/transitions.js +1 -1
- package/build/core/projection/index.js +27 -0
- package/build/core/{projection-activity.js → projection/projection-activity.js} +12 -0
- package/build/core/{projection-alias.js → projection/projection-alias.js} +14 -19
- package/build/core/projection/projection-coordinate.js +61 -0
- package/build/core/{projection-core.js → projection/projection-core.js} +9 -9
- package/build/core/{projection-execution-observer.js → projection/projection-execution-observer.js} +2 -57
- package/build/core/{projection-identity.js → projection/projection-identity.js} +1 -1
- package/build/core/{projection-kill.js → projection/projection-kill.js} +1 -1
- package/build/core/{projection-life-observer.js → projection/projection-life-observer.js} +1 -1
- package/build/core/{projection-mint.js → projection/projection-mint.js} +10 -10
- package/build/core/{projection-status.js → projection/projection-status.js} +98 -25
- package/build/core/projection/projection-terminal-failure.js +104 -0
- package/build/core/projection/projection-wait.js +278 -0
- package/build/core/projection/projection-wake.js +203 -0
- package/build/core/provider-loader-ports.js +4 -0
- package/build/core/ref-log.js +65 -40
- package/build/core/registry.js +63 -10
- package/build/core/renew-session.js +128 -0
- package/build/core/renew.js +426 -99
- package/build/core/scope.js +143 -66
- package/build/core/seal.js +139 -35
- package/build/core/{claim-delivery.js → settlement/claim-delivery.js} +9 -14
- package/build/core/{claim.js → settlement/claim.js} +32 -8
- package/build/core/settlement/index.js +19 -0
- package/build/core/{petition-claim-gates.js → settlement/petition-claim-gates.js} +22 -18
- package/build/core/{petition-forfeit.js → settlement/petition-forfeit.js} +2 -2
- package/build/core/{petition-head-guard.js → settlement/petition-head-guard.js} +2 -2
- package/build/core/settlement/petition-io.js +1 -0
- package/build/core/{petition-preview.js → settlement/petition-preview.js} +1 -1
- package/build/core/{petition.js → settlement/petition.js} +12 -10
- package/build/core/settlement/queue-read-model.js +143 -0
- package/build/core/settlement/queue-seat-allocation.js +156 -0
- package/build/core/settlement/queue.js +6 -0
- package/build/core/settlement/settlement.js +295 -0
- package/build/core/{verdict.js → settlement/verdict.js} +9 -37
- package/build/core/status/board.js +24 -23
- package/build/core/status/ledger-batch.js +158 -0
- package/build/core/status/reconciliation.js +10 -4
- package/build/core/stored-agent-event.js +3 -0
- package/build/core/task/board.js +40 -4
- package/build/core/task/commands.js +30 -21
- package/build/core/task/index.js +12 -0
- package/build/core/task/settlement-git.js +157 -65
- package/build/core/task/settlement-policy.js +54 -24
- package/build/core/task/task-contract.js +370 -0
- package/build/core/{task-doctor.js → task/task-doctor.js} +1 -1
- package/build/core/{task-git-actor.js → task/task-git-actor.js} +5 -10
- package/build/core/{task-git-runtime.js → task/task-git-runtime.js} +3 -3
- package/build/core/{task-git-store.js → task/task-git-store.js} +92 -29
- package/build/core/task/task-repository.js +1 -0
- package/build/core/{task-store-repository.js → task/task-store-repository.js} +5 -4
- package/build/core/task/task-store.js +1 -0
- package/build/core/{task-worktree.js → task/task-worktree.js} +2 -1
- package/build/core/task/task.js +5 -0
- package/build/core/task/tree.js +37 -0
- package/build/core/task/validation.js +5 -2
- package/build/core/transcripts.js +15 -3
- package/build/core/worktree-path.js +43 -28
- package/build/flow-error.js +85 -39
- package/build/fs/durability.js +27 -0
- package/build/fs/path-coordinate.js +16 -0
- package/build/generated/version.js +3 -2
- package/build/git/branches.js +2 -1
- package/build/git/core.js +106 -2
- package/build/git/path-coordinate.js +17 -0
- package/build/git/refs.js +57 -0
- package/build/git/streaming-batch.js +301 -0
- package/build/git/worktree.js +65 -0
- package/build/index.js +3 -3
- package/build/keiyaku.js +2 -36
- package/package.json +4 -10
- package/skills/keiyaku/SKILL.md +3 -2
- package/skills/keiyaku-akuma/SKILL.md +10 -6
- package/skills/keiyaku-task/SKILL.md +1 -1
- package/skills/keiyaku-workflow/SKILL.md +25 -4
- package/build/agents/providers/codex-sdk.js +0 -329
- package/build/cli/commands/task/view/meta.js +0 -8
- package/build/core/command-io.js +0 -174
- package/build/core/path-coordinate.js +0 -27
- package/build/core/petition-claim.js +0 -117
- package/build/core/petition-run.js +0 -83
- package/build/core/projection-coordinate.js +0 -63
- package/build/core/projection-wait.js +0 -165
- package/build/core/projection-wake.js +0 -136
- package/build/core/queue.js +0 -343
- package/build/core/task-contract.js +0 -237
- package/build/core/task.js +0 -4
- /package/build/{core/task-repository.js → agents/launch-snapshot/types.js} +0 -0
- /package/build/{core/task-store.js → agents/providers/claude-agent-sdk/terms.js} +0 -0
- /package/build/core/{projection-generation-runtime.js → projection/generation/projection-generation-runtime.js} +0 -0
- /package/build/core/{projection-life-protocol.js → projection/projection-life-protocol.js} +0 -0
- /package/build/core/{projection-runner-lock.js → projection/projection-runner-lock.js} +0 -0
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import * as path from "node:path";
|
|
2
|
+
import { ProjectionStateError } from "../atomic-publish.js";
|
|
3
|
+
import { createGit, isGitExecutableUnavailable, NOT_GIT_REPOSITORY_PATTERNS, } from "../../git/core.js";
|
|
4
|
+
import { normalizeFilesystemCoordinate } from "../../fs/path-coordinate.js";
|
|
5
|
+
import { gitCommonRootPath, resolveGitCommonRoot } from "../../git/path-coordinate.js";
|
|
6
|
+
/**
|
|
7
|
+
* Resolve projection storage root and authority from one Git probe.
|
|
8
|
+
*
|
|
9
|
+
* A non-bare repository uses the parent of its absolute common Git directory,
|
|
10
|
+
* so every linked worktree shares one coordinate. Repo-free callers retain the
|
|
11
|
+
* existing cwd-local authority until its replacement is legislated.
|
|
12
|
+
*/
|
|
13
|
+
export async function resolveProjectionCoordinate(cwd) {
|
|
14
|
+
cwd = normalizeFilesystemCoordinate(cwd);
|
|
15
|
+
const git = createGit(cwd);
|
|
16
|
+
let response;
|
|
17
|
+
try {
|
|
18
|
+
response = await git.raw([
|
|
19
|
+
"rev-parse",
|
|
20
|
+
"--is-bare-repository",
|
|
21
|
+
"--path-format=absolute",
|
|
22
|
+
"--git-common-dir",
|
|
23
|
+
]);
|
|
24
|
+
}
|
|
25
|
+
catch (error) {
|
|
26
|
+
if (isGitExecutableUnavailable(error)) {
|
|
27
|
+
return { physicalRoot: cwd, authority: { kind: "user" } };
|
|
28
|
+
}
|
|
29
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
30
|
+
if (NOT_GIT_REPOSITORY_PATTERNS.some((pattern) => message.includes(pattern))) {
|
|
31
|
+
return { physicalRoot: cwd, authority: { kind: "user" } };
|
|
32
|
+
}
|
|
33
|
+
throw new ProjectionStateError(`cannot resolve projection repository coordinate: ${message}`);
|
|
34
|
+
}
|
|
35
|
+
const [bare, commonDir] = response.trim().split(/\r?\n/);
|
|
36
|
+
const stableRoot = commonDir === undefined ? undefined : gitCommonRootPath(commonDir);
|
|
37
|
+
if (bare !== "false" || !commonDir || !stableRoot || !path.isAbsolute(stableRoot)) {
|
|
38
|
+
return { physicalRoot: cwd, authority: { kind: "user" } };
|
|
39
|
+
}
|
|
40
|
+
let physicalRoot;
|
|
41
|
+
try {
|
|
42
|
+
physicalRoot = await resolveGitCommonRoot(commonDir);
|
|
43
|
+
}
|
|
44
|
+
catch (error) {
|
|
45
|
+
throw new ProjectionStateError(`cannot resolve projection repository root ${stableRoot}`, { cause: error });
|
|
46
|
+
}
|
|
47
|
+
return {
|
|
48
|
+
physicalRoot,
|
|
49
|
+
authority: { kind: "repository", stableRoot: physicalRoot },
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Select the filesystem authority for repository projection state.
|
|
54
|
+
*
|
|
55
|
+
* A non-bare repository uses the parent of its absolute common Git directory,
|
|
56
|
+
* so every linked worktree shares one coordinate. Repo-free callers retain the
|
|
57
|
+
* existing cwd-local authority until its replacement is legislated.
|
|
58
|
+
*/
|
|
59
|
+
export async function projectionCoordinateRoot(cwd) {
|
|
60
|
+
return (await resolveProjectionCoordinate(cwd)).physicalRoot;
|
|
61
|
+
}
|
|
@@ -1,25 +1,25 @@
|
|
|
1
1
|
import * as fs from "node:fs";
|
|
2
2
|
import * as path from "node:path";
|
|
3
|
-
import { isErrnoException } from "
|
|
3
|
+
import { isErrnoException } from "../../errno.js";
|
|
4
4
|
import { projectionCoordinateRoot } from "./projection-coordinate.js";
|
|
5
|
-
import { ProjectionStateError, } from "
|
|
6
|
-
export { atomicPublishFile, ProjectionStateError, randomHex8 } from "
|
|
7
|
-
export { isTellCausallyConsumed, } from "./
|
|
8
|
-
export { claimAllInbox, claimFencedTells, claimTellToInflight, demoteSubmittedTellsForReplay, listTellIds, markTellConsumed, markTellSubmitted, readTellOriginal, readTellSubmitted, snapshotPendingTells, writeInboxTell, } from "./
|
|
5
|
+
import { ProjectionStateError, } from "../atomic-publish.js";
|
|
6
|
+
export { atomicPublishFile, ProjectionStateError, randomHex8 } from "../atomic-publish.js";
|
|
7
|
+
export { isTellCausallyConsumed, } from "./tell/model.js";
|
|
8
|
+
export { claimAllInbox, claimFencedTells, claimTellToInflight, demoteSubmittedTellsForReplay, listTellIds, markTellConsumed, markTellSubmitted, readTellOriginal, readTellSubmitted, snapshotPendingTells, writeInboxTell, } from "./tell/store.js";
|
|
9
9
|
/** Relative segments for `.keiyaku/projection`. */
|
|
10
10
|
export const PROJECTION_ROOT_SEGMENTS = [".keiyaku", "projection"];
|
|
11
11
|
export const PROJECTION_ID_PATTERN = /^[a-zA-Z0-9]+(?:[.-][a-zA-Z0-9]+)*\/[0-9a-f]{8}$/;
|
|
12
12
|
export function isProjectionId(value) {
|
|
13
13
|
return PROJECTION_ID_PATTERN.test(value);
|
|
14
14
|
}
|
|
15
|
-
export function projectionRoot(cwd) {
|
|
16
|
-
return path.join(projectionCoordinateRoot(cwd), ...PROJECTION_ROOT_SEGMENTS);
|
|
15
|
+
export async function projectionRoot(cwd) {
|
|
16
|
+
return path.join(await projectionCoordinateRoot(cwd), ...PROJECTION_ROOT_SEGMENTS);
|
|
17
17
|
}
|
|
18
|
-
export function projectionDir(cwd, id) {
|
|
18
|
+
export async function projectionDir(cwd, id) {
|
|
19
19
|
if (!isProjectionId(id))
|
|
20
20
|
throw new ProjectionStateError(`invalid projection id: ${id}`);
|
|
21
21
|
const [akuma, hex] = id.split("/");
|
|
22
|
-
return path.join(projectionRoot(cwd), akuma, hex);
|
|
22
|
+
return path.join(await projectionRoot(cwd), akuma, hex);
|
|
23
23
|
}
|
|
24
24
|
export function encodeProjectionJson(value) {
|
|
25
25
|
return `${JSON.stringify(value)}\n`;
|
package/build/core/{projection-execution-observer.js → projection/projection-execution-observer.js}
RENAMED
|
@@ -1,59 +1,5 @@
|
|
|
1
|
-
import { claimAllInbox,
|
|
2
|
-
import { openProjectionTellObserver, } from "./
|
|
3
|
-
function frameTellBodies(projectionDirectory, tellIds) {
|
|
4
|
-
const originals = tellIds.map((tellId) => readTellOriginal(projectionDirectory, "inflight", tellId));
|
|
5
|
-
const frames = originals
|
|
6
|
-
.map((original, index) => `--- tell ${tellIds[index]} ---\n${original.text}`)
|
|
7
|
-
.join("\n\n");
|
|
8
|
-
const effort = originals.reduce((value, original) => original.effort ?? value, undefined);
|
|
9
|
-
return { frames, ...(effort ? { effort } : {}) };
|
|
10
|
-
}
|
|
11
|
-
function operatorBodyForContinuation(prompt, tellFrames, sessionContinuationPromptPrefix) {
|
|
12
|
-
return sessionContinuationPromptPrefix === undefined
|
|
13
|
-
? `${prompt}\n\n${tellFrames}`
|
|
14
|
-
: `${sessionContinuationPromptPrefix}${tellFrames}`;
|
|
15
|
-
}
|
|
16
|
-
/** Tier-2 boundary snapshot. No tells leaves prompt byte-identical. */
|
|
17
|
-
export function snapshotReplayPrompt(projectionDirectory, prompt, tellFence, executionId, options = {}) {
|
|
18
|
-
const tellIds = claimFencedTells(projectionDirectory, tellFence, executionId);
|
|
19
|
-
if (tellIds.length === 0)
|
|
20
|
-
return { prompt, tellIds };
|
|
21
|
-
const { frames, effort } = frameTellBodies(projectionDirectory, tellIds);
|
|
22
|
-
const nextPrompt = operatorBodyForContinuation(prompt, frames, options.sessionContinuationPromptPrefix);
|
|
23
|
-
return { prompt: nextPrompt, tellIds, ...(effort ? { effort } : {}) };
|
|
24
|
-
}
|
|
25
|
-
/** Tier-2 has no steer acknowledgement: actual driver start is its ordinal-zero submission point. */
|
|
26
|
-
export function markReplayStarted(projectionDirectory, executionId, tellIds) {
|
|
27
|
-
for (const tellId of tellIds) {
|
|
28
|
-
if (listTellIds(projectionDirectory, "inflight").includes(tellId)) {
|
|
29
|
-
markTellSubmitted(projectionDirectory, tellId, { executionId, fence: { kind: "ordinal", ordinal: 0 } });
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
/** A successful replay terminal is checkpoint ordinal one; failures intentionally do not consume. */
|
|
34
|
-
export function markReplayCompleted(projectionDirectory, executionId) {
|
|
35
|
-
for (const tellId of listTellIds(projectionDirectory, "submitted")) {
|
|
36
|
-
const submitted = readTellSubmitted(projectionDirectory, tellId);
|
|
37
|
-
if (submitted.executionId === executionId && submitted.fence && isTellCausallyConsumed(submitted.fence, { kind: "ordinal", ordinal: 1 })) {
|
|
38
|
-
markTellConsumed(projectionDirectory, tellId);
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
/**
|
|
43
|
-
* Tier-2's only submission acknowledgement. A created driver is deliberately
|
|
44
|
-
* insufficient: observe the first provider event, or a successful completion
|
|
45
|
-
* from a provider that emitted no events.
|
|
46
|
-
*/
|
|
47
|
-
export function createReplayRunStartGate(projectionDirectory, executionId, tellIds) {
|
|
48
|
-
let started = false;
|
|
49
|
-
const start = () => {
|
|
50
|
-
if (started)
|
|
51
|
-
return;
|
|
52
|
-
markReplayStarted(projectionDirectory, executionId, tellIds);
|
|
53
|
-
started = true;
|
|
54
|
-
};
|
|
55
|
-
return { observeProviderEvent: start, observeSuccessfulCompletion: start };
|
|
56
|
-
}
|
|
1
|
+
import { claimAllInbox, listTellIds, markTellSubmitted, markTellConsumed, readTellSubmitted, readTellOriginal, isTellCausallyConsumed, appendGenerationEvent, } from "./projection-core.js";
|
|
2
|
+
import { openProjectionTellObserver, } from "./tell/database.js";
|
|
57
3
|
const LIVE_TELL_DELIVERY_THROTTLE_MS = 200;
|
|
58
4
|
function submitEligible(projectionDirectory, executionId, control, requireInbox, submitting, observer, pendingCompletionEvidence) {
|
|
59
5
|
if (requireInbox && !observer?.hasInbox())
|
|
@@ -232,7 +178,6 @@ export function createProjectionExecutionObserver(input, dependencies = {}) {
|
|
|
232
178
|
let closed = false;
|
|
233
179
|
const observer = {
|
|
234
180
|
onEvent(event) {
|
|
235
|
-
input.replayStartGate?.observeProviderEvent();
|
|
236
181
|
appendEvent(input.projectionDirectory, input.executionId, event);
|
|
237
182
|
},
|
|
238
183
|
onCheckpoint(control, checkpoint) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { openProjectionGenerationStoreReadOnly, } from "./
|
|
1
|
+
import { openProjectionGenerationStoreReadOnly, } from "./generation/store.js";
|
|
2
2
|
/** Read the immutable projection identity from the heart database. */
|
|
3
3
|
export function readProjectionIdentity(projectionDirectory) {
|
|
4
4
|
const heart = openProjectionGenerationStoreReadOnly(projectionDirectory);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { openProjectionGenerationStore } from "./
|
|
1
|
+
import { openProjectionGenerationStore } from "./generation/store.js";
|
|
2
2
|
import { observeProjectionRunnerLock } from "./projection-runner-lock.js";
|
|
3
3
|
function settleReleasedLeash(store, projectionDirectory, executionId) {
|
|
4
4
|
const observation = observeProjectionRunnerLock(projectionDirectory);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { openProjectionGenerationStoreReadOnly, } from "./
|
|
1
|
+
import { openProjectionGenerationStoreReadOnly, } from "./generation/store.js";
|
|
2
2
|
import { deriveProjectionLife, selectCurrentGeneration, } from "./projection-life-protocol.js";
|
|
3
3
|
import { observeProjectionRunnerLock } from "./projection-runner-lock.js";
|
|
4
4
|
function errorDetail(error) {
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import * as fs from "node:fs";
|
|
2
2
|
import * as path from "node:path";
|
|
3
|
-
import { isErrnoException } from "
|
|
4
|
-
import { ProjectionStateError, randomHex8 } from "
|
|
3
|
+
import { isErrnoException } from "../../errno.js";
|
|
4
|
+
import { ProjectionStateError, randomHex8 } from "../atomic-publish.js";
|
|
5
5
|
import { isoFromNowMs, PROJECTION_ROOT_SEGMENTS, projectionDir, projectionRoot, } from "./projection-core.js";
|
|
6
|
-
import { parseExecutionAuthoritySelection, parseExecutionPact, parseExecutionPactFields, } from "
|
|
7
|
-
import { openProjectionGenerationStore } from "./
|
|
6
|
+
import { parseExecutionAuthoritySelection, parseExecutionPact, parseExecutionPactFields, } from "../execution-pact.js";
|
|
7
|
+
import { openProjectionGenerationStore } from "./generation/store.js";
|
|
8
8
|
import { initializeProjectionRunnerLockDatabase } from "./projection-runner-lock.js";
|
|
9
9
|
export class ProjectionMintCollisionError extends Error {
|
|
10
10
|
code = "PROJECTION_MINT_COLLISION";
|
|
@@ -38,7 +38,7 @@ function removeEmptyAkumaRoot(dir) {
|
|
|
38
38
|
* Validate mint inputs that can fail, then reserve one private staging directory.
|
|
39
39
|
* Dot-prefixed staging is never a published projection address.
|
|
40
40
|
*/
|
|
41
|
-
function reserveProjectionDirectory(input) {
|
|
41
|
+
async function reserveProjectionDirectory(input) {
|
|
42
42
|
const slug = assertMintSlug(input.slug);
|
|
43
43
|
if (!Number.isInteger(input.pid) || input.pid < 0) {
|
|
44
44
|
throw new ProjectionStateError("projection pid must be a non-negative integer");
|
|
@@ -50,7 +50,7 @@ function reserveProjectionDirectory(input) {
|
|
|
50
50
|
if (!Number.isInteger(maxAttempts) || maxAttempts < 1) {
|
|
51
51
|
throw new ProjectionStateError("maxAttempts must be a positive integer");
|
|
52
52
|
}
|
|
53
|
-
const root = projectionRoot(input.cwd);
|
|
53
|
+
const root = await projectionRoot(input.cwd);
|
|
54
54
|
fs.mkdirSync(root, { recursive: true });
|
|
55
55
|
const akumaRoot = path.join(root, slug);
|
|
56
56
|
const createdAkumaRoot = !fs.existsSync(akumaRoot);
|
|
@@ -63,7 +63,7 @@ function reserveProjectionDirectory(input) {
|
|
|
63
63
|
throw new ProjectionStateError(`projection id random segment must be 8 hex chars, got ${hex}`);
|
|
64
64
|
}
|
|
65
65
|
const id = `${slug}/${hex}`;
|
|
66
|
-
const dir = projectionDir(input.cwd, id);
|
|
66
|
+
const dir = await projectionDir(input.cwd, id);
|
|
67
67
|
const stagingDir = path.join(akumaRoot, `.mint-${hex}`);
|
|
68
68
|
if (fs.existsSync(dir))
|
|
69
69
|
continue;
|
|
@@ -132,7 +132,7 @@ function publishReservedProjection(pact, reserved) {
|
|
|
132
132
|
* Mint a user-authority projection directory.
|
|
133
133
|
* Order (closed): validate → reserve staging → heart + leash → atomic rename.
|
|
134
134
|
*/
|
|
135
|
-
export function mintProjection(input) {
|
|
135
|
+
export async function mintProjection(input) {
|
|
136
136
|
const authority = parseExecutionAuthoritySelection(input.authority, "projection identity", "user");
|
|
137
137
|
const fields = parseExecutionPactFields(buildMintPactFields(input));
|
|
138
138
|
const pact = parseExecutionPact({
|
|
@@ -146,7 +146,7 @@ export function mintProjection(input) {
|
|
|
146
146
|
workspaceRoot: fields.workspaceRoot,
|
|
147
147
|
...(fields.effectivePolicy !== undefined ? { effectivePolicy: fields.effectivePolicy } : {}),
|
|
148
148
|
});
|
|
149
|
-
const reserved = reserveProjectionDirectory(input);
|
|
149
|
+
const reserved = await reserveProjectionDirectory(input);
|
|
150
150
|
return publishReservedProjection(pact, reserved);
|
|
151
151
|
}
|
|
152
152
|
/**
|
|
@@ -156,7 +156,7 @@ export function mintProjection(input) {
|
|
|
156
156
|
export async function mintRepositoryProjection(input) {
|
|
157
157
|
parseExecutionAuthoritySelection(input.authority, "projection identity", "repository");
|
|
158
158
|
const fields = parseExecutionPactFields(buildMintPactFields(input));
|
|
159
|
-
const reserved = reserveProjectionDirectory(input);
|
|
159
|
+
const reserved = await reserveProjectionDirectory(input);
|
|
160
160
|
const pact = parseExecutionPact({
|
|
161
161
|
version: fields.version,
|
|
162
162
|
pid: fields.pid,
|
|
@@ -1,19 +1,20 @@
|
|
|
1
1
|
import * as fs from "node:fs";
|
|
2
2
|
import * as path from "node:path";
|
|
3
|
-
import { isErrnoException } from "
|
|
3
|
+
import { isErrnoException } from "../../errno.js";
|
|
4
4
|
import { executionEventsPath, isProjectionId, projectionRoot, } from "./projection-core.js";
|
|
5
5
|
import { readProjectionAlias } from "./projection-alias.js";
|
|
6
|
-
import { ProjectionStateError } from "
|
|
7
|
-
import {
|
|
6
|
+
import { ProjectionStateError } from "../atomic-publish.js";
|
|
7
|
+
import { foldPublicProjectionActivity, } from "./projection-activity.js";
|
|
8
8
|
import { readProjectionIdentity } from "./projection-identity.js";
|
|
9
|
-
import { readProjectionTellCounts } from "./
|
|
10
|
-
import {
|
|
11
|
-
import { PROJECTION_ADOPTION_TIMEOUT_MS } from "./projection-generation-launcher.js";
|
|
9
|
+
import { readProjectionTellCounts } from "./tell/store.js";
|
|
10
|
+
import { ProjectionGenerationStoreError, } from "./generation/store.js";
|
|
11
|
+
import { PROJECTION_ADOPTION_TIMEOUT_MS } from "./generation/projection-generation-launcher.js";
|
|
12
12
|
import { observeProjectionLifeSnapshot } from "./projection-life-observer.js";
|
|
13
13
|
import { selectCurrentGeneration } from "./projection-life-protocol.js";
|
|
14
|
-
import { invalidActivityEventDiagnostic, selectValidStoredAgentEvents } from "
|
|
14
|
+
import { invalidActivityEventDiagnostic, selectValidStoredAgentEvents } from "../stored-agent-event.js";
|
|
15
|
+
import { worktreeContainsCoordinate } from "../worktree-path.js";
|
|
16
|
+
import { projectTerminalFailure, } from "./projection-terminal-failure.js";
|
|
15
17
|
const MAX_STATUS_FILE_BYTES = 256 * 1024;
|
|
16
|
-
export const DEFAULT_PROJECTION_STATUS_ROW_BUDGET = 20;
|
|
17
18
|
const STATUS_GROUP = {
|
|
18
19
|
"startup-timeout": 0,
|
|
19
20
|
lost: 0,
|
|
@@ -63,9 +64,7 @@ export function prioritizeProjectionStatusRows(rows, showAll) {
|
|
|
63
64
|
const ordered = [...rows].sort(compareProjectionStatusRows);
|
|
64
65
|
if (showAll)
|
|
65
66
|
return { rows: ordered };
|
|
66
|
-
const
|
|
67
|
-
let terminalBudget = Math.max(0, DEFAULT_PROJECTION_STATUS_ROW_BUDGET - protectedCount);
|
|
68
|
-
const visible = [];
|
|
67
|
+
const visible = ordered.filter((row) => !isOmissibleProjectionStatusState(row.state));
|
|
69
68
|
const byState = {
|
|
70
69
|
failed: 0,
|
|
71
70
|
dead: 0,
|
|
@@ -74,12 +73,6 @@ export function prioritizeProjectionStatusRows(rows, showAll) {
|
|
|
74
73
|
dismissed: 0,
|
|
75
74
|
};
|
|
76
75
|
for (const row of ordered) {
|
|
77
|
-
if (STATUS_GROUP[row.state] < 2 || terminalBudget > 0) {
|
|
78
|
-
visible.push(row);
|
|
79
|
-
if (STATUS_GROUP[row.state] >= 2)
|
|
80
|
-
terminalBudget -= 1;
|
|
81
|
-
continue;
|
|
82
|
-
}
|
|
83
76
|
if (isOmissibleProjectionStatusState(row.state))
|
|
84
77
|
byState[row.state] += 1;
|
|
85
78
|
}
|
|
@@ -97,10 +90,9 @@ class ProjectionStatusFileError extends Error {
|
|
|
97
90
|
}
|
|
98
91
|
}
|
|
99
92
|
function oversizedProjectionFileDiagnostic(filePath) {
|
|
100
|
-
const label = path.basename(filePath);
|
|
101
93
|
return {
|
|
102
94
|
kind: "oversized-projection-file",
|
|
103
|
-
|
|
95
|
+
fileName: path.basename(filePath),
|
|
104
96
|
};
|
|
105
97
|
}
|
|
106
98
|
function recordProjectionStatusFileError(error, diagnostics) {
|
|
@@ -268,7 +260,7 @@ function readActivityFacts(projectionDir, executionId, nowMs, diagnostics, fallb
|
|
|
268
260
|
diagnostics.push(invalidActivity);
|
|
269
261
|
const activityAtMs = latestValidEventAtMs(events) ?? fallbackAtMs;
|
|
270
262
|
return {
|
|
271
|
-
...(events.length > 0 ? { activity:
|
|
263
|
+
...(events.length > 0 ? { activity: foldPublicProjectionActivity(events) } : {}),
|
|
272
264
|
...(activityAtMs !== undefined
|
|
273
265
|
? {
|
|
274
266
|
activityAtMs,
|
|
@@ -304,11 +296,17 @@ function readProjectionRow(projectionDir, id, alias, nowMs) {
|
|
|
304
296
|
? Date.parse(adoptedAt)
|
|
305
297
|
: Number.NaN;
|
|
306
298
|
const activityFacts = readActivityFacts(projectionDir, life.executionId, nowMs, diagnostics, Number.isFinite(adoptedAtMs) ? adoptedAtMs : undefined);
|
|
299
|
+
const mintedAtMs = Date.parse(identityFacts.mintedAt ?? "");
|
|
300
|
+
const displayAgeMs = activityFacts.activityAgeMs
|
|
301
|
+
?? (Number.isFinite(mintedAtMs) ? Math.max(0, nowMs - mintedAtMs) : undefined);
|
|
307
302
|
if (life.phase === "unknown" && life.diagnostic) {
|
|
308
303
|
diagnostics.push({ kind: "unknown-lifecycle", detail: life.diagnostic });
|
|
309
304
|
}
|
|
310
305
|
const phase = life.phase;
|
|
311
306
|
const state = phase === "active" || phase === "quiescent" ? "out" : phase;
|
|
307
|
+
const terminalFailure = current?.verdict
|
|
308
|
+
? projectTerminalFailure(current.verdict.facts.state, current.verdict.facts)
|
|
309
|
+
: undefined;
|
|
312
310
|
return {
|
|
313
311
|
id,
|
|
314
312
|
...(alias ? { alias } : {}),
|
|
@@ -319,12 +317,14 @@ function readProjectionRow(projectionDir, id, alias, nowMs) {
|
|
|
319
317
|
mintedAt: identityFacts.mintedAt,
|
|
320
318
|
...(identityFacts.workspaceRoot ? { workspaceRoot: identityFacts.workspaceRoot } : {}),
|
|
321
319
|
...activityFacts,
|
|
320
|
+
...(displayAgeMs !== undefined ? { activityAgeMs: displayAgeMs } : {}),
|
|
321
|
+
...(terminalFailure ? { terminalFailure } : {}),
|
|
322
322
|
tellCounts,
|
|
323
323
|
diagnostics,
|
|
324
324
|
};
|
|
325
325
|
}
|
|
326
|
-
export function readProjectionStatusBoard(cwd, nowMs, options = {}) {
|
|
327
|
-
const root = projectionRoot(cwd);
|
|
326
|
+
export async function readProjectionStatusBoard(cwd, nowMs, options = {}) {
|
|
327
|
+
const root = await projectionRoot(cwd);
|
|
328
328
|
try {
|
|
329
329
|
if (!fs.lstatSync(root).isDirectory())
|
|
330
330
|
return null;
|
|
@@ -349,7 +349,7 @@ export function readProjectionStatusBoard(cwd, nowMs, options = {}) {
|
|
|
349
349
|
for (const alias of fs.readdirSync(aliasRoot).sort()) {
|
|
350
350
|
if (alias.startsWith("."))
|
|
351
351
|
continue;
|
|
352
|
-
const id = readProjectionAlias(cwd, alias);
|
|
352
|
+
const id = await readProjectionAlias(cwd, alias);
|
|
353
353
|
if (id)
|
|
354
354
|
aliases.set(id, alias);
|
|
355
355
|
}
|
|
@@ -382,10 +382,83 @@ export function readProjectionStatusBoard(cwd, nowMs, options = {}) {
|
|
|
382
382
|
catch {
|
|
383
383
|
continue;
|
|
384
384
|
}
|
|
385
|
-
if (isProjectionGenerationSchemaV1Residue(dir))
|
|
386
|
-
continue;
|
|
387
385
|
rows.push(readProjectionRow(dir, id, aliases.get(id), nowMs));
|
|
388
386
|
}
|
|
389
387
|
}
|
|
390
388
|
return rows.length > 0 ? prioritizeProjectionStatusRows(rows, options.showAll === true) : null;
|
|
391
389
|
}
|
|
390
|
+
/**
|
|
391
|
+
* Renew-only lifecycle guard. Immutable identity is checked before lifecycle,
|
|
392
|
+
* so an unrelated or unattributable projection cannot block a commission.
|
|
393
|
+
*/
|
|
394
|
+
export async function hasStrandableProjectionGeneration(input) {
|
|
395
|
+
const root = await projectionRoot(input.cwd);
|
|
396
|
+
let akumas;
|
|
397
|
+
try {
|
|
398
|
+
if (!fs.lstatSync(root).isDirectory())
|
|
399
|
+
return false;
|
|
400
|
+
akumas = fs.readdirSync(root);
|
|
401
|
+
}
|
|
402
|
+
catch (error) {
|
|
403
|
+
if (isErrnoException(error) && error.code === "ENOENT")
|
|
404
|
+
return false;
|
|
405
|
+
throw error;
|
|
406
|
+
}
|
|
407
|
+
for (const akuma of akumas.sort()) {
|
|
408
|
+
if (akuma.startsWith("."))
|
|
409
|
+
continue;
|
|
410
|
+
const akumaDir = path.join(root, akuma);
|
|
411
|
+
try {
|
|
412
|
+
if (!fs.lstatSync(akumaDir).isDirectory())
|
|
413
|
+
continue;
|
|
414
|
+
}
|
|
415
|
+
catch {
|
|
416
|
+
continue;
|
|
417
|
+
}
|
|
418
|
+
let hexes;
|
|
419
|
+
try {
|
|
420
|
+
hexes = fs.readdirSync(akumaDir);
|
|
421
|
+
}
|
|
422
|
+
catch {
|
|
423
|
+
continue;
|
|
424
|
+
}
|
|
425
|
+
for (const hex of hexes.sort()) {
|
|
426
|
+
const projectionId = `${akuma}/${hex}`;
|
|
427
|
+
const projectionDir = path.join(akumaDir, hex);
|
|
428
|
+
if (!isProjectionId(projectionId))
|
|
429
|
+
continue;
|
|
430
|
+
try {
|
|
431
|
+
if (!fs.lstatSync(projectionDir).isDirectory())
|
|
432
|
+
continue;
|
|
433
|
+
}
|
|
434
|
+
catch {
|
|
435
|
+
continue;
|
|
436
|
+
}
|
|
437
|
+
let identity;
|
|
438
|
+
try {
|
|
439
|
+
identity = readProjectionIdentity(projectionDir);
|
|
440
|
+
}
|
|
441
|
+
catch {
|
|
442
|
+
// Corrupt identity has no trustworthy commission/worktree join and
|
|
443
|
+
// therefore cannot become a repository-wide renew interlock.
|
|
444
|
+
continue;
|
|
445
|
+
}
|
|
446
|
+
if (identity.binding.kind !== "commission"
|
|
447
|
+
|| identity.binding.commissionId !== input.commissionId
|
|
448
|
+
|| !worktreeContainsCoordinate(input.deliveryWorktree, identity.workspaceRoot)) {
|
|
449
|
+
continue;
|
|
450
|
+
}
|
|
451
|
+
const phase = observeProjectionLifeSnapshot(projectionDir, {
|
|
452
|
+
nowMs: input.nowMs,
|
|
453
|
+
startupTimeoutMs: PROJECTION_ADOPTION_TIMEOUT_MS,
|
|
454
|
+
}).life.phase;
|
|
455
|
+
if (phase === "active"
|
|
456
|
+
|| phase === "minting"
|
|
457
|
+
|| phase === "startup-timeout"
|
|
458
|
+
|| phase === "unknown") {
|
|
459
|
+
return true;
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
return false;
|
|
464
|
+
}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { constants as osConstants } from "node:os";
|
|
2
|
+
import { RESPONSE_ARTIFACT_ID_RE } from "../response-artifact-id.js";
|
|
3
|
+
import { OUTCOME_ERROR_VERSION } from "../../agents/types.js";
|
|
4
|
+
const HARNESS_FAILURE_CODES = new Set([
|
|
5
|
+
"SUBAGENT_TIMEOUT",
|
|
6
|
+
"SUBAGENT_NON_ZERO_EXIT",
|
|
7
|
+
"SUBAGENT_SPAWN_ERROR",
|
|
8
|
+
"SUBAGENT_EXEC_ERROR",
|
|
9
|
+
"SUBAGENT_PROVIDER_UNAVAILABLE",
|
|
10
|
+
]);
|
|
11
|
+
const SYSTEM_SIGNALS = new Set(Object.keys(osConstants.signals));
|
|
12
|
+
function objectValue(value) {
|
|
13
|
+
return value !== null && typeof value === "object" && !Array.isArray(value)
|
|
14
|
+
? value
|
|
15
|
+
: undefined;
|
|
16
|
+
}
|
|
17
|
+
function failureCode(value) {
|
|
18
|
+
return typeof value === "string" && HARNESS_FAILURE_CODES.has(value)
|
|
19
|
+
? value
|
|
20
|
+
: undefined;
|
|
21
|
+
}
|
|
22
|
+
function nonNegativeNumber(value) {
|
|
23
|
+
return typeof value === "number" && Number.isSafeInteger(value) && value >= 0
|
|
24
|
+
? value
|
|
25
|
+
: undefined;
|
|
26
|
+
}
|
|
27
|
+
function exitCode(value) {
|
|
28
|
+
return typeof value === "number" && Number.isSafeInteger(value) ? value : undefined;
|
|
29
|
+
}
|
|
30
|
+
function signal(value) {
|
|
31
|
+
return typeof value === "string" && SYSTEM_SIGNALS.has(value)
|
|
32
|
+
? value
|
|
33
|
+
: undefined;
|
|
34
|
+
}
|
|
35
|
+
function artifactId(source) {
|
|
36
|
+
for (const value of [source.artifactId, source.sourceArtifactId]) {
|
|
37
|
+
if (typeof value === "string" && RESPONSE_ARTIFACT_ID_RE.test(value))
|
|
38
|
+
return value;
|
|
39
|
+
}
|
|
40
|
+
return undefined;
|
|
41
|
+
}
|
|
42
|
+
function providerFailureCause(value) {
|
|
43
|
+
const source = objectValue(value);
|
|
44
|
+
return source?.kind === "rate_limit_exhausted"
|
|
45
|
+
? { kind: "rate_limit_exhausted" }
|
|
46
|
+
: undefined;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Convert artifact-rich verdict facts into the strict public allowlist. Raw
|
|
50
|
+
* messages, output, diagnostics, sessions, provider payloads, and unknown
|
|
51
|
+
* strings have no path through this function.
|
|
52
|
+
*/
|
|
53
|
+
export function projectTerminalFailure(state, facts) {
|
|
54
|
+
if (state !== "failed" && state !== "lost-runner" && state !== "launch-failed")
|
|
55
|
+
return undefined;
|
|
56
|
+
const source = objectValue(facts);
|
|
57
|
+
if (!source)
|
|
58
|
+
return undefined;
|
|
59
|
+
const error = objectValue(source.error);
|
|
60
|
+
const publicArtifactId = artifactId(source);
|
|
61
|
+
// Runner verdict authority wins classification even when harness evidence is
|
|
62
|
+
// also attached to the verdict.
|
|
63
|
+
if (state === "launch-failed" || state === "lost-runner") {
|
|
64
|
+
const phase = state === "lost-runner"
|
|
65
|
+
? "adoption"
|
|
66
|
+
: source.stage === "spawn" ? "launch" : "adoption";
|
|
67
|
+
const code = phase === "launch"
|
|
68
|
+
? "SUBAGENT_SPAWN_ERROR"
|
|
69
|
+
: "SUBAGENT_EXEC_ERROR";
|
|
70
|
+
const timeoutMs = nonNegativeNumber(error?.timeoutMs ?? source.timeoutMs);
|
|
71
|
+
const publicExitCode = exitCode(error?.exitCode ?? source.exitCode);
|
|
72
|
+
const publicSignal = signal(error?.signal ?? source.signal);
|
|
73
|
+
return {
|
|
74
|
+
class: "runner",
|
|
75
|
+
code,
|
|
76
|
+
phase,
|
|
77
|
+
...(timeoutMs !== undefined ? { timeoutMs } : {}),
|
|
78
|
+
...(publicExitCode !== undefined ? { exitCode: publicExitCode } : {}),
|
|
79
|
+
...(publicSignal ? { signal: publicSignal } : {}),
|
|
80
|
+
...(publicArtifactId ? { artifactId: publicArtifactId } : {}),
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
if (error?.version !== OUTCOME_ERROR_VERSION)
|
|
84
|
+
return undefined;
|
|
85
|
+
const publicSignal = signal(error?.signal ?? source.signal);
|
|
86
|
+
const publicExitCode = exitCode(error?.exitCode ?? source.exitCode);
|
|
87
|
+
const code = failureCode(error?.code ?? source.code)
|
|
88
|
+
?? (publicSignal ? "SUBAGENT_EXEC_ERROR" : undefined)
|
|
89
|
+
?? (publicExitCode !== undefined ? "SUBAGENT_NON_ZERO_EXIT" : undefined);
|
|
90
|
+
if (!code || code === "SUBAGENT_SPAWN_ERROR")
|
|
91
|
+
return undefined;
|
|
92
|
+
const timeoutMs = nonNegativeNumber(error?.timeoutMs ?? source.timeoutMs);
|
|
93
|
+
const publicCause = providerFailureCause(error?.publicCause);
|
|
94
|
+
return {
|
|
95
|
+
class: "harness",
|
|
96
|
+
code,
|
|
97
|
+
phase: source.phase === "adoption" ? "adoption" : "runtime",
|
|
98
|
+
...(timeoutMs !== undefined ? { timeoutMs } : {}),
|
|
99
|
+
...(publicExitCode !== undefined ? { exitCode: publicExitCode } : {}),
|
|
100
|
+
...(publicSignal ? { signal: publicSignal } : {}),
|
|
101
|
+
...(publicArtifactId ? { artifactId: publicArtifactId } : {}),
|
|
102
|
+
...(publicCause ? { publicCause } : {}),
|
|
103
|
+
};
|
|
104
|
+
}
|