@sagentlab/navarch-runtime 0.1.62 → 0.1.64
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 +4 -4
- package/dist/cli.cjs +41 -6
- package/dist/config.cjs +27 -8
- package/dist/machine-store.cjs +5 -6
- package/dist/session.cjs +9 -38
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -30,7 +30,7 @@ Before generating the command, prepare the machine:
|
|
|
30
30
|
- install Node.js 20 or later (the standard installation includes `npm` and
|
|
31
31
|
`npx`) and Git;
|
|
32
32
|
- install the coding-agent CLI selected in Navarch — `claude`, `codex`,
|
|
33
|
-
`gemini`, `opencode`,
|
|
33
|
+
`gemini`, `opencode`, `dsh` for the default ACP integration, or `qoder` — and complete its normal authentication flow; and
|
|
34
34
|
- for Docker-backed sessions, install and start Docker and use an image that
|
|
35
35
|
contains the selected agent CLI and the repository toolchain, with provider
|
|
36
36
|
credentials supplied through the approved machine or project configuration.
|
|
@@ -45,7 +45,7 @@ node --version # 20 or later
|
|
|
45
45
|
npm --version
|
|
46
46
|
npx --version
|
|
47
47
|
git --version
|
|
48
|
-
codex --version # or: claude / gemini / opencode / dsh --version
|
|
48
|
+
codex --version # or: claude / gemini / opencode / qoder / dsh --version
|
|
49
49
|
```
|
|
50
50
|
|
|
51
51
|
Every command above must succeed before the long-running worker starts. See
|
|
@@ -157,7 +157,7 @@ The from-source flow — `git clone` + `./install.sh` + `node bin/navarch.cjs
|
|
|
157
157
|
| `connect --token <t> --name <n> [--agent claude-code\|codex\|gemini\|opencode\|acp\|qoder] [--project <id>] […]` | Connects this machine to one project, saves its local agent choice, and prints the token once. |
|
|
158
158
|
| `start [--agent claude-code\|codex\|gemini\|opencode\|acp\|qoder]` | Runs the daemon. A start-time agent choice overrides the saved choice. |
|
|
159
159
|
| `supervise [--agent claude-code\|codex\|gemini\|opencode\|acp\|qoder]` | Runs the daemon under the update supervisor, enabling drain-safe automatic updates and rollback. |
|
|
160
|
-
| `doctor` | Prints resolved config + Docker/registration status; no side effects. |
|
|
160
|
+
| `doctor [--agent claude-code\|codex\|gemini\|opencode\|acp\|qoder]` | Prints resolved config + Docker/registration status; no side effects. |
|
|
161
161
|
|
|
162
162
|
### Running multiple agents on one machine
|
|
163
163
|
|
|
@@ -370,7 +370,7 @@ unchanged across the deployment.
|
|
|
370
370
|
| `NAVARCH_SANDBOX_EGRESS_NETWORK` | _(unset)_ | Docker network that enforces a profile's egress allowlist. Docker cannot filter by domain itself, so an allowlist profile without this fails closed to `--network=none` and records the denial. |
|
|
371
371
|
| `NAVARCH_DOCKER_IMAGE` | `ghcr.io/sagentlab/navarch-sandbox-agent:0.1.0` | Version-pinned per-session image with Node 20, git, GitHub CLI, ripgrep, jq, SSH, and Claude Code 2.1.218. Override with an image tag or digest you control. |
|
|
372
372
|
| `NAVARCH_AGENT` | saved choice, then `claude-code` | Local choice of agent adapter: `claude-code`, `codex`, `gemini`, `opencode`, `acp`, or `qoder`. Overrides the choice saved by `connect`/`register`; `start --agent` has highest priority. |
|
|
373
|
-
| `NAVARCH_RUNTIMES` | resolved local agent choice | Comma list of installed/authenticated adapters advertised to dispatch. Unpinned tasks run on the preferred agent; a task runtime pin selects the matching adapter. |
|
|
373
|
+
| `NAVARCH_RUNTIMES` | resolved local agent choice | Comma list of installed/authenticated adapters advertised to dispatch. Unpinned tasks run on the preferred agent; a task runtime pin selects the matching adapter. Unrecognized ids are dropped with a warning that names them, so a typo cannot silently shrink the advertised set. |
|
|
374
374
|
| `NAVARCH_UPDATE_CHANNEL` | `stable` | Release channel advertised by the worker (`stable` or `canary`); the server-managed machine channel remains authoritative. |
|
|
375
375
|
| `NAVARCH_AUTO_UPDATE` | on under `supervise` | Set `off`, `false`, or `0` to report releases without staging or activating them. Automatic activation is always off under plain `start`. |
|
|
376
376
|
| `NAVARCH_CLAUDE_BIN` | `claude` | Path/name of the Claude Code CLI binary. |
|
package/dist/cli.cjs
CHANGED
|
@@ -20,6 +20,8 @@ const supervisor_cjs_1 = require("./supervisor.cjs");
|
|
|
20
20
|
const worktree_janitor_cjs_1 = require("./worktree-janitor.cjs");
|
|
21
21
|
const log = (0, logger_cjs_1.createLogger)("cli");
|
|
22
22
|
const PACKAGE_NAME = "@sagentlab/navarch-runtime";
|
|
23
|
+
/** Accepted `--agent` ids as usage metavariables, generated from one source of truth. */
|
|
24
|
+
const AGENT_TYPE_USAGE = config_cjs_1.RUNTIME_AGENT_TYPES.join("|");
|
|
23
25
|
/**
|
|
24
26
|
* Exit code for "this machine's identity is gone". Deliberately outside the
|
|
25
27
|
* supervisor's restart codes (75 update, 76 remote restart): respawning cannot
|
|
@@ -78,10 +80,32 @@ function agentFromFlag(flags) {
|
|
|
78
80
|
if (value === undefined)
|
|
79
81
|
return undefined;
|
|
80
82
|
if (!(0, config_cjs_1.isRuntimeAgentType)(value)) {
|
|
81
|
-
throw new Error(
|
|
83
|
+
throw new Error(`--agent must be one of ${formatChoices(config_cjs_1.RUNTIME_AGENT_TYPES)}.`);
|
|
82
84
|
}
|
|
83
85
|
return value;
|
|
84
86
|
}
|
|
87
|
+
/** `'a', 'b', or 'c'` — one prose list for every place the accepted ids are shown. */
|
|
88
|
+
function formatChoices(values) {
|
|
89
|
+
const quoted = values.map((value) => `'${value}'`);
|
|
90
|
+
const last = quoted.at(-1) ?? "";
|
|
91
|
+
if (quoted.length < 2)
|
|
92
|
+
return last;
|
|
93
|
+
return `${quoted.slice(0, -1).join(", ")}, or ${last}`;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* A typo in NAVARCH_RUNTIMES must not silently shrink the advertised adapter
|
|
97
|
+
* set, so name every dropped id on stderr. Runs once per top-level command (not
|
|
98
|
+
* per config load) to avoid duplicate lines when start/supervise/doctor resolve
|
|
99
|
+
* the identity and reload config. A supervised worker inherits NAVARCH_RUNTIMES
|
|
100
|
+
* from the `supervise` parent that already warned, so it stays quiet.
|
|
101
|
+
*/
|
|
102
|
+
function warnUnknownRuntimes(config) {
|
|
103
|
+
const unknown = config.unknownRuntimes;
|
|
104
|
+
if (config.supervised || unknown.length === 0)
|
|
105
|
+
return;
|
|
106
|
+
log.warn(`NAVARCH_RUNTIMES ignores unrecognized adapter id(s): ${unknown.join(", ")}. ` +
|
|
107
|
+
`Known adapters: ${config_cjs_1.RUNTIME_AGENT_TYPES.join(", ")}.`);
|
|
108
|
+
}
|
|
85
109
|
/** Saved pins only apply to the adapter they were selected for. */
|
|
86
110
|
function modelFromFlags(flags, agentType, identity) {
|
|
87
111
|
const model = flags.model ?? (identity?.agent_type === agentType ? identity.model : undefined);
|
|
@@ -116,6 +140,7 @@ function parseArgs(argv) {
|
|
|
116
140
|
*/
|
|
117
141
|
async function registerCommand(flags) {
|
|
118
142
|
const config = configFromFlags(flags);
|
|
143
|
+
warnUnknownRuntimes(config);
|
|
119
144
|
const apiBase = flags["api-base"] ?? config.apiBase;
|
|
120
145
|
const enrollmentToken = flags.token ?? process.env.NAVARCH_ENROLLMENT_TOKEN;
|
|
121
146
|
const name = flags.name ?? process.env.NAVARCH_MACHINE_NAME;
|
|
@@ -166,6 +191,7 @@ async function registerCommand(flags) {
|
|
|
166
191
|
*/
|
|
167
192
|
async function connectCommand(flags) {
|
|
168
193
|
const config = configFromFlags(flags);
|
|
194
|
+
warnUnknownRuntimes(config);
|
|
169
195
|
const apiBase = flags["api-base"] ?? config.apiBase;
|
|
170
196
|
const enrollmentToken = flags.token ?? process.env.NAVARCH_ENROLLMENT_TOKEN;
|
|
171
197
|
const name = flags.name ?? process.env.NAVARCH_MACHINE_NAME;
|
|
@@ -209,6 +235,7 @@ async function startCommand(flags) {
|
|
|
209
235
|
const baseConfig = configFromFlags(flags);
|
|
210
236
|
const identity = await (0, machine_store_cjs_1.resolveMachineIdentity)(baseConfig.configDir, baseConfig.apiBase);
|
|
211
237
|
const config = configFromFlags(flags, identity);
|
|
238
|
+
warnUnknownRuntimes(config);
|
|
212
239
|
const api = new api_cjs_1.NavarchApiClient({ baseUrl: identity.api_base, token: identity.token });
|
|
213
240
|
const capacity = new capacity_cjs_1.CapacityTracker(config.maxSessions);
|
|
214
241
|
const runtimeShutdown = new AbortController();
|
|
@@ -287,6 +314,7 @@ async function superviseCommand(flags) {
|
|
|
287
314
|
const baseConfig = configFromFlags(flags);
|
|
288
315
|
const identity = await (0, machine_store_cjs_1.resolveMachineIdentity)(baseConfig.configDir, baseConfig.apiBase);
|
|
289
316
|
const config = configFromFlags(flags, identity);
|
|
317
|
+
warnUnknownRuntimes(config);
|
|
290
318
|
// Resolve and pin the adapter before spawning the worker. The supervisor
|
|
291
319
|
// passes machine credentials through the environment, so the child no
|
|
292
320
|
// longer reads machine.json for identity fields (including agent_type).
|
|
@@ -325,8 +353,15 @@ async function doctorCommand(flags) {
|
|
|
325
353
|
}
|
|
326
354
|
if (identity)
|
|
327
355
|
config = configFromFlags(flags, identity);
|
|
356
|
+
warnUnknownRuntimes(config);
|
|
328
357
|
}
|
|
329
358
|
catch (err) {
|
|
359
|
+
// The typo may be why the config is unusable (e.g. `opencode,gemni` on a
|
|
360
|
+
// guarded host leaves only OpenCode), so still name it.
|
|
361
|
+
warnUnknownRuntimes({
|
|
362
|
+
supervised: process.env.NAVARCH_SUPERVISED === "1",
|
|
363
|
+
unknownRuntimes: (0, config_cjs_1.unknownRuntimeIds)(process.env),
|
|
364
|
+
});
|
|
330
365
|
console.log(`config: UNUSABLE — ${err instanceof Error ? err.message : String(err)}`);
|
|
331
366
|
process.exitCode = 1;
|
|
332
367
|
return;
|
|
@@ -353,12 +388,12 @@ function helpText() {
|
|
|
353
388
|
|
|
354
389
|
Usage:
|
|
355
390
|
navarch-runtime register --token <enrollment-token> --name <machine-name> \\
|
|
356
|
-
[--config-dir <path>] [--agent
|
|
391
|
+
[--config-dir <path>] [--agent ${AGENT_TYPE_USAGE}] [--model <model>] [--capabilities a,b] [--max-sessions N] [--owner-zone z] [--api-base url]
|
|
357
392
|
navarch-runtime connect --token <enrollment-token> --name <machine-name> \\
|
|
358
|
-
[--config-dir <path>] [--agent
|
|
359
|
-
navarch-runtime start [--config-dir <path>] [--agent
|
|
360
|
-
navarch-runtime supervise [--config-dir <path>] [--agent
|
|
361
|
-
navarch-runtime doctor [--config-dir <path>]
|
|
393
|
+
[--config-dir <path>] [--agent ${AGENT_TYPE_USAGE}] [--model <model>] [--project <project-id>] [--capabilities a,b] [--max-sessions N] [--api-base url]
|
|
394
|
+
navarch-runtime start [--config-dir <path>] [--agent ${AGENT_TYPE_USAGE}] [--model <model>]
|
|
395
|
+
navarch-runtime supervise [--config-dir <path>] [--agent ${AGENT_TYPE_USAGE}] [--model <model>]
|
|
396
|
+
navarch-runtime doctor [--config-dir <path>] [--agent ${AGENT_TYPE_USAGE}]
|
|
362
397
|
navarch-runtime code-graph --query <symbol-or-file> [--mode search|callers|callees|impact] [--commit HEAD] [--depth 1..5] [--repo <path>]
|
|
363
398
|
|
|
364
399
|
Use a different --config-dir (or NAVARCH_CONFIG_DIR) for every agent instance.
|
package/dist/config.cjs
CHANGED
|
@@ -3,8 +3,9 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.OPENCODE_HOST_GUARD_MESSAGE = exports.DEFAULT_SANDBOX_IMAGE = void 0;
|
|
6
|
+
exports.OPENCODE_HOST_GUARD_MESSAGE = exports.RUNTIME_AGENT_TYPES = exports.DEFAULT_SANDBOX_IMAGE = void 0;
|
|
7
7
|
exports.isRuntimeAgentType = isRuntimeAgentType;
|
|
8
|
+
exports.unknownRuntimeIds = unknownRuntimeIds;
|
|
8
9
|
exports.opencodeBlockedOnHost = opencodeBlockedOnHost;
|
|
9
10
|
exports.loadRuntimeConfig = loadRuntimeConfig;
|
|
10
11
|
const node_path_1 = __importDefault(require("node:path"));
|
|
@@ -12,13 +13,26 @@ const node_os_1 = __importDefault(require("node:os"));
|
|
|
12
13
|
const sandbox_profile_cjs_1 = require("./sandbox-profile.cjs");
|
|
13
14
|
/** Published image containing git, GitHub CLI, and the pinned Claude Code CLI. */
|
|
14
15
|
exports.DEFAULT_SANDBOX_IMAGE = "ghcr.io/sagentlab/navarch-sandbox-agent:0.1.0";
|
|
16
|
+
/**
|
|
17
|
+
* Adapter ids the runtime accepts for `NAVARCH_AGENT` / `--agent`, in display
|
|
18
|
+
* order. `NAVARCH_RUNTIMES` is validated against this same list, and the CLI
|
|
19
|
+
* usage/error copy is generated from it so the advertised set cannot drift.
|
|
20
|
+
*/
|
|
21
|
+
exports.RUNTIME_AGENT_TYPES = [
|
|
22
|
+
"claude-code",
|
|
23
|
+
"codex",
|
|
24
|
+
"gemini",
|
|
25
|
+
"opencode",
|
|
26
|
+
"acp",
|
|
27
|
+
"qoder",
|
|
28
|
+
];
|
|
15
29
|
function isRuntimeAgentType(value) {
|
|
16
|
-
return
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
30
|
+
return typeof value === "string" && exports.RUNTIME_AGENT_TYPES.includes(value);
|
|
31
|
+
}
|
|
32
|
+
/** Unrecognized ids in NAVARCH_RUNTIMES, deduplicated, in the order given. */
|
|
33
|
+
function unknownRuntimeIds(env) {
|
|
34
|
+
const ids = envList(env, "NAVARCH_RUNTIMES", []);
|
|
35
|
+
return [...new Set(ids.filter((runtime) => !isRuntimeAgentType(runtime)))];
|
|
22
36
|
}
|
|
23
37
|
function envInt(env, name, fallback) {
|
|
24
38
|
const raw = env[name];
|
|
@@ -82,7 +96,11 @@ function loadRuntimeConfig(env = process.env) {
|
|
|
82
96
|
// Multiple sessions share one machine; keeping each agent inside its own
|
|
83
97
|
// worktree is the safe default, so disabling is the explicit opt-out.
|
|
84
98
|
const worktreeGuard = !["off", "false", "0"].includes(env.NAVARCH_WORKTREE_GUARD ?? "");
|
|
85
|
-
const
|
|
99
|
+
const requestedRuntimeIds = envList(env, "NAVARCH_RUNTIMES", [requestedAgentType]);
|
|
100
|
+
// Keep unknown ids visible so a typo surfaces (CLI warns) instead of the
|
|
101
|
+
// machine quietly shrinking the adapters it advertises.
|
|
102
|
+
const unknownRuntimes = unknownRuntimeIds(env);
|
|
103
|
+
const requestedRuntimes = requestedRuntimeIds.filter(isRuntimeAgentType);
|
|
86
104
|
// OpenCode's CLI cannot express the host worktree boundary, so its adapter
|
|
87
105
|
// fails closed there (adapters/opencode.cts). Advertising it anyway meant
|
|
88
106
|
// the machine claimed OpenCode tasks it could only fail, one lease at a
|
|
@@ -114,6 +132,7 @@ function loadRuntimeConfig(env = process.env) {
|
|
|
114
132
|
worktreeStaleAfterMs: envInt(env, "NAVARCH_WORKTREE_STALE_AFTER_MS", 24 * 60 * 60 * 1000),
|
|
115
133
|
agentType,
|
|
116
134
|
runtimes: runtimes.length > 0 ? runtimes : [agentType],
|
|
135
|
+
unknownRuntimes,
|
|
117
136
|
claudeBin: env.NAVARCH_CLAUDE_BIN ?? "claude",
|
|
118
137
|
claudeExtraArgs: envList(env, "NAVARCH_CLAUDE_EXTRA_ARGS", []),
|
|
119
138
|
codexBin: env.NAVARCH_CODEX_BIN ?? "codex",
|
package/dist/machine-store.cjs
CHANGED
|
@@ -8,6 +8,7 @@ exports.loadMachineIdentity = loadMachineIdentity;
|
|
|
8
8
|
exports.resolveMachineIdentity = resolveMachineIdentity;
|
|
9
9
|
const node_fs_1 = require("node:fs");
|
|
10
10
|
const node_path_1 = __importDefault(require("node:path"));
|
|
11
|
+
const config_cjs_1 = require("./config.cjs");
|
|
11
12
|
function storePath(configDir) {
|
|
12
13
|
return node_path_1.default.join(configDir, "machine.json");
|
|
13
14
|
}
|
|
@@ -48,12 +49,10 @@ async function resolveMachineIdentity(configDir, apiBaseFallback) {
|
|
|
48
49
|
token: envToken,
|
|
49
50
|
name: process.env.NAVARCH_MACHINE_NAME ?? envId,
|
|
50
51
|
api_base: process.env.NAVARCH_API_BASE ?? apiBaseFallback,
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
process.env.NAVARCH_AGENT === "acp" ||
|
|
56
|
-
process.env.NAVARCH_AGENT === "qoder"
|
|
52
|
+
// Validate against the one accepted adapter list so a new adapter cannot
|
|
53
|
+
// be added to `--agent`/NAVARCH_AGENT while this env-based identity path
|
|
54
|
+
// silently drops it.
|
|
55
|
+
agent_type: (0, config_cjs_1.isRuntimeAgentType)(process.env.NAVARCH_AGENT)
|
|
57
56
|
? process.env.NAVARCH_AGENT
|
|
58
57
|
: undefined,
|
|
59
58
|
};
|
package/dist/session.cjs
CHANGED
|
@@ -94,7 +94,7 @@ async function runSession(deps, claimed, sessionId) {
|
|
|
94
94
|
await api
|
|
95
95
|
.completeLease(leaseId, {
|
|
96
96
|
status: "failed",
|
|
97
|
-
report:
|
|
97
|
+
report: failureSummary,
|
|
98
98
|
failure_summary: failureSummary,
|
|
99
99
|
failed_before_start: true,
|
|
100
100
|
evidence_urls: [],
|
|
@@ -174,7 +174,7 @@ async function runClaimedSession(deps, claimed, sessionId, lifecycle) {
|
|
|
174
174
|
const failureSummary = `Project ${task.project_id} has no GitHub repository URL. Set it in Project settings before dispatching work.`;
|
|
175
175
|
await api.completeLease(leaseId, {
|
|
176
176
|
status: "failed",
|
|
177
|
-
report:
|
|
177
|
+
report: failureSummary,
|
|
178
178
|
failure_summary: failureSummary,
|
|
179
179
|
failed_before_start: true,
|
|
180
180
|
evidence_urls: [],
|
|
@@ -296,7 +296,7 @@ async function runClaimedSession(deps, claimed, sessionId, lifecycle) {
|
|
|
296
296
|
await api
|
|
297
297
|
.completeLease(leaseId, {
|
|
298
298
|
status: "failed",
|
|
299
|
-
report:
|
|
299
|
+
report: "Docker sandbox unavailable on this machine.",
|
|
300
300
|
failure_summary: "Docker sandbox unavailable on this machine.",
|
|
301
301
|
failed_before_start: true,
|
|
302
302
|
evidence_urls: [],
|
|
@@ -634,9 +634,7 @@ async function runClaimedSession(deps, claimed, sessionId, lifecycle) {
|
|
|
634
634
|
const redactedReport = (0, redact_cjs_1.redactText)(mapping.reportSummary, knownSecrets);
|
|
635
635
|
const completion = {
|
|
636
636
|
status: mapping.leaseOutcome,
|
|
637
|
-
report:
|
|
638
|
-
? verificationFailureReport(task.task_type, redactedReport, mapping.exitStatus)
|
|
639
|
-
: redactedReport,
|
|
637
|
+
report: redactedReport,
|
|
640
638
|
evidence_urls: mapping.evidenceUrls,
|
|
641
639
|
...(deliveryFailureSummary
|
|
642
640
|
? { failure_summary: (0, redact_cjs_1.redactText)(deliveryFailureSummary, knownSecrets) }
|
|
@@ -698,9 +696,9 @@ async function runClaimedSession(deps, claimed, sessionId, lifecycle) {
|
|
|
698
696
|
await api.completeLease(leaseId, {
|
|
699
697
|
...completion,
|
|
700
698
|
status: "failed",
|
|
701
|
-
report:
|
|
699
|
+
report: remediable
|
|
702
700
|
? redactedRejection
|
|
703
|
-
: `${redactedRejection}\n\n---\n\n${completion.report}`,
|
|
701
|
+
: `${redactedRejection}\n\n---\n\n${completion.report}`,
|
|
704
702
|
failure_summary: redactedRejection,
|
|
705
703
|
exit_status: "failed",
|
|
706
704
|
});
|
|
@@ -732,9 +730,9 @@ async function runClaimedSession(deps, claimed, sessionId, lifecycle) {
|
|
|
732
730
|
await api
|
|
733
731
|
.completeLease(leaseId, {
|
|
734
732
|
status: "failed",
|
|
735
|
-
report:
|
|
733
|
+
report: lastCompletion
|
|
736
734
|
? `${lastCompletion.report}\n\n---\n\n${failureSummary}`
|
|
737
|
-
: failureSummary,
|
|
735
|
+
: failureSummary,
|
|
738
736
|
failure_summary: failureSummary,
|
|
739
737
|
failed_before_start: !adapterStarted,
|
|
740
738
|
evidence_urls: lastCompletion?.evidence_urls ?? [],
|
|
@@ -815,33 +813,6 @@ function sumReportedUsage(attempts, key) {
|
|
|
815
813
|
});
|
|
816
814
|
return reported.length > 0 ? reported.reduce((sum, value) => sum + value, 0) : undefined;
|
|
817
815
|
}
|
|
818
|
-
/**
|
|
819
|
-
* The control plane refuses to release a verify lease whose failed completion
|
|
820
|
-
* does not open with `Verification verdict: FAIL` or `BLOCKED`
|
|
821
|
-
* (verification_verdict_invalid), and that gate applies to runtime-authored
|
|
822
|
-
* failure reports too. When the report carries no usable verdict — the agent
|
|
823
|
-
* exited non-zero, or opened with PASS despite the failed outcome — label it
|
|
824
|
-
* BLOCKED: the failure prevented an acceptance decision. Without this, the
|
|
825
|
-
* failure completion is itself rejected, the session crashes, and the lease
|
|
826
|
-
* dangles until expiry.
|
|
827
|
-
*
|
|
828
|
-
* A `killed` or `crashed` exit is left unlabelled: the control plane accepts
|
|
829
|
-
* those verdict-less as the runtime's own failure and routes them through
|
|
830
|
-
* failure attribution (an infrastructure retry). A BLOCKED label there would
|
|
831
|
-
* misreport a transient timeout as a verifier verdict and escalate it to a
|
|
832
|
-
* human; the control plane discards such a label, so posting it only muddies
|
|
833
|
-
* the session report.
|
|
834
|
-
*/
|
|
835
|
-
function verificationFailureReport(taskType, report, exitStatus) {
|
|
836
|
-
if (taskType !== "verify")
|
|
837
|
-
return report;
|
|
838
|
-
if (exitStatus === "killed" || exitStatus === "crashed")
|
|
839
|
-
return report;
|
|
840
|
-
const verdict = (0, exit_conditions_cjs_1.leadingVerificationVerdict)(report);
|
|
841
|
-
if (verdict === "fail" || verdict === "blocked")
|
|
842
|
-
return report;
|
|
843
|
-
return `Verification verdict: BLOCKED — the session ended before verification reached an acceptance decision.\n\n${report}`;
|
|
844
|
-
}
|
|
845
816
|
/** Rejection codes another agent turn in the same worktree can plausibly fix. */
|
|
846
817
|
const REMEDIABLE_REJECTION_CODES = new Set([
|
|
847
818
|
"review_fix_required",
|
|
@@ -871,7 +842,7 @@ const REMEDIABLE_REJECTION_CODES = new Set([
|
|
|
871
842
|
// `Verification verdict:` line only has to restate its report; the
|
|
872
843
|
// rejection prose spells out the exact format. Failed outcomes never reach
|
|
873
844
|
// remediation (see the leaseOutcome === "completed" gate) — their reports
|
|
874
|
-
// are
|
|
845
|
+
// are recorded as session failures when the verifier supplied no verdict.
|
|
875
846
|
"verification_verdict_invalid",
|
|
876
847
|
]);
|
|
877
848
|
/**
|
package/package.json
CHANGED