@bridge_gpt/mcp-server 0.2.66 → 0.2.68
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 +421 -83
- package/build/agent-capabilities/probes.js +15 -5
- package/build/agent-launchers/claude-executor-adapter.js +70 -16
- package/build/agent-launchers/executor-adapter.js +7 -4
- package/build/agents.generated.js +22 -2
- package/build/bitbucket-workspace-remote.js +136 -0
- package/build/bootstrap-project-identity.js +24 -0
- package/build/bounded-wait.js +67 -10
- package/build/bridge-permissions.js +829 -0
- package/build/claude-settings.js +18 -0
- package/build/cli-help.js +21 -0
- package/build/command-assets-doctor.js +24 -70
- package/build/command-provisioning.js +29 -5
- package/build/commands.generated.js +12 -12
- package/build/conductor/bridge-api-client.js +857 -1
- package/build/conductor/bring-up-facts.js +1 -1
- package/build/conductor/command-drift-production.js +92 -0
- package/build/conductor/command-drift.js +89 -0
- package/build/conductor/doctor.js +72 -29
- package/build/conductor/epic-branch-ci-inspection.js +1375 -0
- package/build/conductor/epic-implementer-cli.js +98 -28
- package/build/conductor/errors.js +4 -3
- package/build/conductor/gate-discovery.js +890 -0
- package/build/conductor/guided-repair.js +6 -2
- package/build/conductor/hook-runtime-qualification.js +1 -1
- package/build/conductor/install-doctor.js +15 -3
- package/build/conductor/json-output.js +63 -0
- package/build/conductor/merge-execution-contract.js +27 -8
- package/build/conductor/merge-execution-eligibility.js +3 -2
- package/build/conductor/pr-ci-producer.js +1 -1
- package/build/conductor/readiness-cli.js +113 -12
- package/build/conductor/readiness-sections.js +410 -9
- package/build/conductor/readiness.js +388 -33
- package/build/conductor/recovery-cli.js +310 -12
- package/build/conductor/recovery-operations.js +167 -3
- package/build/conductor/repair-contract.js +54 -3
- package/build/conductor/repository-workflow-remedy.js +125 -0
- package/build/conductor/tools.js +2 -2
- package/build/conductor-bundle-artifacts.js +8 -0
- package/build/connect-bitbucket-api.js +41 -6
- package/build/connect-bitbucket.js +106 -33
- package/build/credential-store.js +207 -47
- package/build/docs.generated.js +62 -3
- package/build/doctor.js +92 -1
- package/build/drive-epic-key.js +6 -5
- package/build/drive-epic.js +129 -61
- package/build/epic-coherence-input.js +2 -1
- package/build/epic-coherence-input.test-fixtures.js +4 -3
- package/build/epic-implementer-bin.js +1379 -28
- package/build/epic-implementer-bundle-cli.js +2 -2
- package/build/epic-workarounds-path.js +39 -0
- package/build/executor/cli.js +33 -2
- package/build/executor/completion-contract.js +66 -10
- package/build/executor/completion-supervision.js +4 -0
- package/build/executor/deps.js +4 -1
- package/build/executor/env.js +19 -0
- package/build/executor/gate-qualification-job.js +499 -0
- package/build/executor/guarded-fast-forward-push.js +129 -0
- package/build/executor/heartbeat.js +1 -1
- package/build/executor/http-client.js +20 -0
- package/build/executor/integration-job.js +122 -8
- package/build/executor/job-errors.js +33 -1
- package/build/executor/job-runner.js +813 -87
- package/build/executor/likely-tests.js +290 -0
- package/build/executor/live-worker-registry.js +1 -1
- package/build/executor/observation.js +37 -3
- package/build/executor/packaged-recipe.js +106 -0
- package/build/executor/permissions.js +115 -28
- package/build/executor/platform.js +1 -1
- package/build/executor/preflight.js +112 -26
- package/build/executor/process-containment.js +36 -12
- package/build/executor/process.js +15 -7
- package/build/executor/prompt-spec.js +33 -1
- package/build/executor/recently-failed-tests-file.js +71 -0
- package/build/executor/reconcile-overlap-job.js +41 -23
- package/build/executor/required-verification.js +1 -1
- package/build/executor/required-work-ledger.js +111 -18
- package/build/executor/resume-pre-spawn.js +2 -0
- package/build/executor/retirement.js +69 -0
- package/build/executor/runner.js +122 -13
- package/build/executor/service-unit.js +7 -1
- package/build/executor/test-clock.js +15 -0
- package/build/executor/types.js +32 -0
- package/build/executor/viewer-tabs.js +58 -8
- package/build/executor/worker-command.js +23 -7
- package/build/executor/worker-diagnostics.js +37 -0
- package/build/executor/worker-finalization.js +113 -34
- package/build/executor/worker-guard-hook.js +316 -58
- package/build/executor/worker-log.js +4 -3
- package/build/executor/worker-verification-guidance.js +37 -0
- package/build/executor/worktree.js +166 -8
- package/build/first-build-advisory.js +97 -0
- package/build/generated-assets-advisory.js +14 -0
- package/build/generated-assets-catalog.js +66 -0
- package/build/generated-assets-context.js +46 -0
- package/build/generated-assets-dependencies.js +26 -0
- package/build/generated-assets-doctor.js +50 -0
- package/build/generated-assets-health.js +65 -0
- package/build/generated-assets-host.js +17 -0
- package/build/generated-assets-inventory.js +17 -0
- package/build/generated-assets-paths.js +60 -0
- package/build/generated-assets-publisher.js +133 -0
- package/build/generated-assets-remedy.js +25 -0
- package/build/generated-assets-repair.js +72 -0
- package/build/generated-assets-session.js +71 -0
- package/build/generated-assets-test-support.js +35 -0
- package/build/index.js +1224 -1054
- package/build/init.js +54 -177
- package/build/install-bridge-conductor-gate.js +1372 -0
- package/build/install-bridge-conductor.js +296 -41
- package/build/install-bridge.js +547 -40
- package/build/mcp-install-state.js +50 -4
- package/build/merge-workflow-install.js +3 -4
- package/build/phase-context-git-probe.js +68 -0
- package/build/phase-result-artifacts.js +173 -5
- package/build/pipeline-utils.js +6 -2
- package/build/pipelines.generated.js +34 -160
- package/build/plan-execution-ledger.js +2 -32
- package/build/plane/alembic-head.js +12 -3
- package/build/plane/base-worktree-guard.js +147 -0
- package/build/plane/cli.js +217 -17
- package/build/plane/code-snapshot.js +468 -0
- package/build/plane/defaults.js +48 -3
- package/build/plane/endpoint.js +41 -0
- package/build/plane/manifest.js +136 -2
- package/build/plane/member-roster.js +94 -19
- package/build/plane/preflight.js +83 -2
- package/build/plane/process-cwd.js +67 -0
- package/build/plane/restart.js +542 -0
- package/build/plane/shutdown.js +31 -0
- package/build/plane/status.js +143 -8
- package/build/plane/supervisor.js +586 -179
- package/build/plane/types.js +54 -2
- package/build/printed-remedy-commands.js +52 -0
- package/build/readiness-check.js +1 -1
- package/build/readme.generated.js +1 -1
- package/build/repair-assets.js +93 -0
- package/build/review-generation.js +22 -0
- package/build/run-unit-tests-launcher.js +130 -49
- package/build/secret-redaction.js +33 -0
- package/build/setup-epic.js +152 -22
- package/build/sfcc/config.js +9 -0
- package/build/sfcc/credentials.js +100 -38
- package/build/sfcc/hostname.js +67 -0
- package/build/sfcc/permissions.js +17 -13
- package/build/sfcc/register.js +1 -1
- package/build/sfcc/tool-wrapper.js +39 -43
- package/build/sfcc/write-grants.js +17 -11
- package/build/sfcc/write-result.js +4 -3
- package/build/sfcc/writes-site-preference.js +20 -8
- package/build/start-tickets-prereqs.js +70 -16
- package/build/start-tickets.js +208 -36
- package/build/tool-error-envelope.js +61 -0
- package/build/tool-surface-gating.js +36 -0
- package/build/upgrade-cli.js +55 -1
- package/build/version.generated.js +3 -3
- package/build/visual-diff.js +22 -1
- package/build/worker-guard-hook-bin.js +4 -6
- package/build/worker-guard-hook-main.js +47 -0
- package/build/worktree-core.js +145 -6
- package/docs/EPIC-IMPLEMENTER-INSTALL.md +867 -0
- package/docs/EPIC-IMPLEMENTER.md +728 -0
- package/docs/install/mcp-tool-integrations.md +24 -15
- package/docs/install/sfcc-integration.md +12 -4
- package/package.json +3 -3
- package/pipelines/greenfield-setup.json +4 -128
- package/pipelines/implement-ticket.json +3 -2
- package/pipelines/plan-epic.json +0 -5
- package/pipelines/review-ticket.json +1 -1
- package/docs/CONDUCTOR.md +0 -605
- package/pipelines/idea-to-pr.json +0 -49
|
@@ -6,8 +6,8 @@
|
|
|
6
6
|
* inside `build/pipelines.generated.js`. `mcp_server/src/` does not exist there,
|
|
7
7
|
* so an instruction that told the agent to "call `validateConductorBundleInputs`"
|
|
8
8
|
* would be referencing a path only this repository has. This subcommand is the
|
|
9
|
-
* reachable surface,
|
|
10
|
-
*
|
|
9
|
+
* reachable surface, the same way `setup-epic` is a command rather than
|
|
10
|
+
* hand-rolled HTTP calls.
|
|
11
11
|
*
|
|
12
12
|
* It holds no policy of its own: it parses argv, delegates to
|
|
13
13
|
* `conductor-bundle-artifacts.ts`, and prints a JSON envelope. All I/O is behind
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The one TypeScript spelling of the Epic Implementer workaround folder (BAPI-1399).
|
|
3
|
+
*
|
|
4
|
+
* A worker that defers a MINOR requirement behind a guarded workaround commits a
|
|
5
|
+
* record at `.bridge/epic-workarounds/<TICKET>.md` on its ticket branch. While
|
|
6
|
+
* that folder exists on the epic head, the integration pull request stays in
|
|
7
|
+
* draft: the reconciler's coordinator withholds `mark_ready`
|
|
8
|
+
* (`api/library/epic_implementer/integration_completion.py`), and the local actor
|
|
9
|
+
* re-checks the folder before it takes a pull request out of draft
|
|
10
|
+
* (`executor/integration-job.ts`). Nothing about a workaround is stored in the
|
|
11
|
+
* database or in run state; the hold is worked out from the folder at the exact
|
|
12
|
+
* epic head every time.
|
|
13
|
+
*
|
|
14
|
+
* Python declares the same value once, beside its directory-listing helper in
|
|
15
|
+
* `api/library/github/github_webhooks_lib.py`. The static test
|
|
16
|
+
* `tests/pytest/static/test_epic_workarounds_path_pin.py` fails if any consumer
|
|
17
|
+
* spells the path differently or drops it.
|
|
18
|
+
*/
|
|
19
|
+
import { TICKET_KEY_PATTERN } from "./ticket-key-utils.js";
|
|
20
|
+
/** The workaround folder, repository-relative, with its trailing slash. */
|
|
21
|
+
export const EPIC_WORKAROUNDS_DIR = ".bridge/epic-workarounds/";
|
|
22
|
+
/** The folder without its trailing slash: the form a contents API path takes. */
|
|
23
|
+
export const EPIC_WORKAROUNDS_DIR_PATH = EPIC_WORKAROUNDS_DIR.slice(0, -1);
|
|
24
|
+
/** A ticket key: the canonical grammar the Epic Implementer accepts everywhere else. */
|
|
25
|
+
const TICKET_KEY_RE = TICKET_KEY_PATTERN;
|
|
26
|
+
/** Upper bound on a ticket key, so a pasted blob is never a path segment. */
|
|
27
|
+
const MAX_TICKET_KEY_CHARS = 64;
|
|
28
|
+
/**
|
|
29
|
+
* The record path for one ticket, `.bridge/epic-workarounds/<TICKET>.md`, or
|
|
30
|
+
* `null` when the key is not a valid ticket key. A key is never sanitized into a
|
|
31
|
+
* path: anything that is not exactly a key is refused.
|
|
32
|
+
*/
|
|
33
|
+
export function epicWorkaroundRecordPath(ticketKey) {
|
|
34
|
+
if (typeof ticketKey !== "string")
|
|
35
|
+
return null;
|
|
36
|
+
if (ticketKey.length > MAX_TICKET_KEY_CHARS || !TICKET_KEY_RE.test(ticketKey))
|
|
37
|
+
return null;
|
|
38
|
+
return `${EPIC_WORKAROUNDS_DIR}${ticketKey}.md`;
|
|
39
|
+
}
|
package/build/executor/cli.js
CHANGED
|
@@ -22,6 +22,35 @@ import { startExecutorSleepAssertion } from "./platform.js";
|
|
|
22
22
|
import { runExecutor } from "./runner.js";
|
|
23
23
|
import { runExecutorWatchCli } from "./watch-cli.js";
|
|
24
24
|
import { removeRunExecutorRecordIfOwned } from "../executor-launch.js";
|
|
25
|
+
/** Register an optional parent watch without making the timer a process owner. */
|
|
26
|
+
export function registerExecutorParentWatch(pid, onGone, seams = {
|
|
27
|
+
setInterval: (callback, ms) => setInterval(callback, ms),
|
|
28
|
+
clearInterval: (handle) => clearInterval(handle),
|
|
29
|
+
signalZero: (parentPid) => process.kill(parentPid, 0),
|
|
30
|
+
}) {
|
|
31
|
+
let disposed = false;
|
|
32
|
+
let notified = false;
|
|
33
|
+
const timer = seams.setInterval(() => {
|
|
34
|
+
if (disposed || notified)
|
|
35
|
+
return;
|
|
36
|
+
try {
|
|
37
|
+
seams.signalZero(pid);
|
|
38
|
+
}
|
|
39
|
+
catch (error) {
|
|
40
|
+
if (error.code === "ESRCH") {
|
|
41
|
+
notified = true;
|
|
42
|
+
onGone();
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}, 5_000);
|
|
46
|
+
timer.unref?.();
|
|
47
|
+
return () => {
|
|
48
|
+
if (disposed)
|
|
49
|
+
return;
|
|
50
|
+
disposed = true;
|
|
51
|
+
seams.clearInterval(timer);
|
|
52
|
+
};
|
|
53
|
+
}
|
|
25
54
|
/** Fixed executor timing/behavior defaults. */
|
|
26
55
|
const DEFAULT_POLL_INTERVAL_MS = 15_000;
|
|
27
56
|
const DEFAULT_HEARTBEAT_INTERVAL_MS = 60_000;
|
|
@@ -37,9 +66,10 @@ const DEFAULT_JOB_TIMEOUT_SECONDS = 20 * 60;
|
|
|
37
66
|
export const DEFAULT_MAX_CONCURRENT = 1;
|
|
38
67
|
export function getExecutorUsage() {
|
|
39
68
|
return [
|
|
40
|
-
"Usage: mcp-server executor --repo <name> [--repo <name> ...]
|
|
69
|
+
"Usage: mcp-server executor --repo <name> [--repo <name> ...]",
|
|
70
|
+
" (--epic-run-id <id> | --repo-wide) [options]",
|
|
41
71
|
"",
|
|
42
|
-
"Runs the Epic
|
|
72
|
+
"Runs the Epic Implementer local executor: poll → claim → spawn → heartbeat.",
|
|
43
73
|
"",
|
|
44
74
|
"Options:",
|
|
45
75
|
" --repo <name> Repo to serve (repeatable).",
|
|
@@ -421,6 +451,7 @@ export async function runExecutorCli(argv, overrides = {}) {
|
|
|
421
451
|
const createIntegrationClient = overrides.createIntegrationClient ?? createIntegrationActionHttpClient;
|
|
422
452
|
const runnerSeams = {
|
|
423
453
|
onSignal: overrides.onSignal ?? defaultSignalRegistrar,
|
|
454
|
+
watchParent: registerExecutorParentWatch,
|
|
424
455
|
// BAPI-1279 — on a terminal exit, delete the launcher record drive-epic
|
|
425
456
|
// wrote for this run, but only if it still names THIS instance (its id, and
|
|
426
457
|
// this process or the relay that started it). Advisory: a failure here
|
|
@@ -53,6 +53,37 @@ export const SUPPORTED_COMPLETION_RUNTIME = {
|
|
|
53
53
|
platform: "darwin-arm64",
|
|
54
54
|
event_schema: "claude-stream-json.lifecycle.v1",
|
|
55
55
|
};
|
|
56
|
+
/** Oldest Claude CLI version whose lifecycle events were measured. */
|
|
57
|
+
export const MIN_CLI_VERSION = "2.1.282";
|
|
58
|
+
/** The four platform ids `<process.platform>-<process.arch>` the executor can produce. */
|
|
59
|
+
export const SUPPORTED_PLATFORMS = ["darwin-arm64", "darwin-x64", "linux-x64", "linux-arm64"];
|
|
60
|
+
/** Names the lifecycle parser version. A constant, never a probed value. */
|
|
61
|
+
export const EVENT_SCHEMA = "claude-stream-json.lifecycle.v1";
|
|
62
|
+
const CLI_VERSION_RE = /^(0|[1-9][0-9]{0,3})\.(0|[1-9][0-9]{0,3})\.(0|[1-9][0-9]{0,5})(?: \(Claude Code\))?$/;
|
|
63
|
+
/**
|
|
64
|
+
* Parse `major.minor.patch` with an optional exact ` (Claude Code)` suffix into its
|
|
65
|
+
* numeric triple. Prereleases, whitespace, non-numeric segments, leading zeros, and
|
|
66
|
+
* non-strings are `null`. Mirror of `normalize_cli_version` in the Python contract.
|
|
67
|
+
*/
|
|
68
|
+
export function parseCliVersion(value) {
|
|
69
|
+
if (typeof value !== "string")
|
|
70
|
+
return null;
|
|
71
|
+
const match = CLI_VERSION_RE.exec(value);
|
|
72
|
+
return match ? [Number(match[1]), Number(match[2]), Number(match[3])] : null;
|
|
73
|
+
}
|
|
74
|
+
/** The normalized `major.minor.patch` text, or `null` when the version is not strict. */
|
|
75
|
+
export function normalizeCliVersion(value) {
|
|
76
|
+
const parsed = parseCliVersion(value);
|
|
77
|
+
return parsed ? parsed.join(".") : null;
|
|
78
|
+
}
|
|
79
|
+
/** Is version triple `a` at or above `b`? */
|
|
80
|
+
export function cliVersionAtLeast(a, b) {
|
|
81
|
+
for (let i = 0; i < 3; i += 1) {
|
|
82
|
+
if (a[i] !== b[i])
|
|
83
|
+
return a[i] > b[i];
|
|
84
|
+
}
|
|
85
|
+
return true;
|
|
86
|
+
}
|
|
56
87
|
export const EVIDENCE_VALUES = ["sufficient", "insufficient"];
|
|
57
88
|
export const INSUFFICIENT_REASON_VALUES = [
|
|
58
89
|
"no_init_event",
|
|
@@ -200,6 +231,10 @@ export const COMPLETION_CAUSE_VALUES = [
|
|
|
200
231
|
"cleanup_unconfirmed",
|
|
201
232
|
"verification_runner_unavailable",
|
|
202
233
|
];
|
|
234
|
+
export const END_CAUSE_VALUES = [
|
|
235
|
+
"worker_exit", "completion_window", "job_timeout", "executor_abort",
|
|
236
|
+
"executor_shutdown", "server_stop", "lease_lost",
|
|
237
|
+
];
|
|
203
238
|
export const MAX_TASKS = 64;
|
|
204
239
|
export const MAX_DENIALS = 32;
|
|
205
240
|
export const MAX_IDENTIFIER_CHARS = 128;
|
|
@@ -239,13 +274,23 @@ export function isCoveredJobType(jobType) {
|
|
|
239
274
|
export function claimRequiresCompletionEvidence(requiredCapabilities) {
|
|
240
275
|
return Array.isArray(requiredCapabilities) && requiredCapabilities.includes(COMPLETION_EVIDENCE_CAPABILITY);
|
|
241
276
|
}
|
|
277
|
+
/**
|
|
278
|
+
* True for the measured baseline or a newer supported runtime: adapter `claude`, the
|
|
279
|
+
* lifecycle event schema, a closed platform id, and a strict numeric version at or
|
|
280
|
+
* above {@link MIN_CLI_VERSION}. Mirror of `runtime_matches_supported` in Python.
|
|
281
|
+
*/
|
|
242
282
|
export function runtimeMatchesSupported(runtime) {
|
|
243
283
|
if (!runtime)
|
|
244
284
|
return false;
|
|
285
|
+
const version = parseCliVersion(runtime.cli_version);
|
|
286
|
+
const minimum = parseCliVersion(MIN_CLI_VERSION);
|
|
245
287
|
return (runtime.adapter === SUPPORTED_COMPLETION_RUNTIME.adapter &&
|
|
246
|
-
runtime.
|
|
247
|
-
runtime.platform ===
|
|
248
|
-
runtime.
|
|
288
|
+
runtime.event_schema === EVENT_SCHEMA &&
|
|
289
|
+
typeof runtime.platform === "string" &&
|
|
290
|
+
SUPPORTED_PLATFORMS.includes(runtime.platform) &&
|
|
291
|
+
version !== null &&
|
|
292
|
+
minimum !== null &&
|
|
293
|
+
cliVersionAtLeast(version, minimum));
|
|
249
294
|
}
|
|
250
295
|
export function unresolvedRequiredTasks(envelope) {
|
|
251
296
|
return envelope.tasks.filter((t) => t.required && !TASK_RESOLVING_STATES.has(t.state));
|
|
@@ -318,16 +363,25 @@ export function deriveCompletionCause(envelope) {
|
|
|
318
363
|
if (blocking.length > 0 && envelope.evidence === "sufficient" && blocking.some((d) => d.result_after_denial)) {
|
|
319
364
|
return "permission_stop";
|
|
320
365
|
}
|
|
321
|
-
if (envelope.cleanup.verdict !== "confirmed" || envelope.cleanup.survivors !== 0)
|
|
322
|
-
return "cleanup_unconfirmed";
|
|
323
366
|
const unresolved = envelope.tasks.some((t) => t.required && !TASK_RESOLVING_STATES.has(t.state));
|
|
324
|
-
|
|
367
|
+
const requiredWorkIncomplete = blocking.length > 0 ||
|
|
325
368
|
envelope.evidence !== "sufficient" ||
|
|
326
369
|
envelope.execution !== "complete" ||
|
|
327
370
|
unresolved ||
|
|
328
|
-
envelope.verification === "incomplete"
|
|
329
|
-
|
|
371
|
+
envelope.verification === "incomplete";
|
|
372
|
+
// One exception to cleanup precedence: a completed sweep with no survivor and
|
|
373
|
+
// exactly the single reason `ownership_unverifiable` yields to unfinished
|
|
374
|
+
// work. Exact array checks, so a mixed list (e.g. with `not_run`) never does.
|
|
375
|
+
const narrowCleanupUncertainty = envelope.cleanup.verdict === "unconfirmed" &&
|
|
376
|
+
envelope.cleanup.survivors === 0 &&
|
|
377
|
+
envelope.cleanup.reasons.length === 1 &&
|
|
378
|
+
envelope.cleanup.reasons[0] === "ownership_unverifiable";
|
|
379
|
+
if ((envelope.cleanup.verdict !== "confirmed" || envelope.cleanup.survivors !== 0) &&
|
|
380
|
+
!(narrowCleanupUncertainty && requiredWorkIncomplete)) {
|
|
381
|
+
return "cleanup_unconfirmed";
|
|
330
382
|
}
|
|
383
|
+
if (requiredWorkIncomplete)
|
|
384
|
+
return "required_work_incomplete";
|
|
331
385
|
if (envelope.verification === "unavailable")
|
|
332
386
|
return "verification_runner_unavailable";
|
|
333
387
|
if (envelope.verification === "failed")
|
|
@@ -366,7 +420,9 @@ export function buildNotLaunchedEnvelope(input) {
|
|
|
366
420
|
binding: { ...input.binding },
|
|
367
421
|
session_id: null,
|
|
368
422
|
evidence: "insufficient",
|
|
369
|
-
insufficient_reasons:
|
|
423
|
+
insufficient_reasons: input.unsupportedRuntime
|
|
424
|
+
? ["worker_not_launched", "unsupported_runtime"]
|
|
425
|
+
: ["worker_not_launched"],
|
|
370
426
|
execution: "unknown",
|
|
371
427
|
verification: input.verification,
|
|
372
428
|
finalization: "unknown",
|
|
@@ -381,7 +437,7 @@ export function buildNotLaunchedEnvelope(input) {
|
|
|
381
437
|
denials: [],
|
|
382
438
|
missing_capabilities: [],
|
|
383
439
|
results_seen: 0,
|
|
384
|
-
cause: null,
|
|
440
|
+
cause: input.unsupportedRuntime ? "unsupported_completion_evidence" : null,
|
|
385
441
|
...(input.verificationFacts ? { verification_facts: input.verificationFacts } : {}),
|
|
386
442
|
};
|
|
387
443
|
}
|
|
@@ -228,6 +228,10 @@ export function finalizationFacts(outcome) {
|
|
|
228
228
|
// and neither push nor PR is inferred satisfied.
|
|
229
229
|
case "WorkerFinalizationPublicationUnverified":
|
|
230
230
|
return { verdict: "unknown", pushSatisfied: false, prSatisfied: false };
|
|
231
|
+
// BAPI-1357: the origin lookup could not be trusted, so the branch was not
|
|
232
|
+
// observed missing either. Unknown, and neither obligation is inferred met.
|
|
233
|
+
case "WorkerFinalizationOriginUnverifiable":
|
|
234
|
+
return { verdict: "unknown", pushSatisfied: false, prSatisfied: false };
|
|
231
235
|
default:
|
|
232
236
|
return { verdict: "unknown", pushSatisfied: false, prSatisfied: false };
|
|
233
237
|
}
|
package/build/executor/deps.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { recordProvisionedAssets } from "../generated-assets-inventory.js";
|
|
1
2
|
/**
|
|
2
3
|
* Default (production) executor dependencies (BAPI-534, TDD §7).
|
|
3
4
|
*
|
|
@@ -70,6 +71,7 @@ export function createDefaultExecutorDeps() {
|
|
|
70
71
|
cwd: options?.cwd,
|
|
71
72
|
env: options?.env,
|
|
72
73
|
timeout: options?.timeoutMs,
|
|
74
|
+
signal: options?.signal,
|
|
73
75
|
maxBuffer: MAX_COMMAND_BUFFER,
|
|
74
76
|
encoding: "utf8",
|
|
75
77
|
shell: false,
|
|
@@ -78,7 +80,7 @@ export function createDefaultExecutorDeps() {
|
|
|
78
80
|
}
|
|
79
81
|
catch (err) {
|
|
80
82
|
const e = err;
|
|
81
|
-
const exitCode = typeof e.code === "number" ? e.code : 1;
|
|
83
|
+
const exitCode = e.killed || e.code === "ABORT_ERR" ? 124 : typeof e.code === "number" ? e.code : 1;
|
|
82
84
|
return { stdout: e.stdout ?? "", stderr: e.stderr ?? "", exitCode };
|
|
83
85
|
}
|
|
84
86
|
},
|
|
@@ -137,6 +139,7 @@ export function createDefaultExecutorDeps() {
|
|
|
137
139
|
},
|
|
138
140
|
};
|
|
139
141
|
},
|
|
142
|
+
recordPackagedAssets: recordProvisionedAssets,
|
|
140
143
|
readFile: (filePath) => readFile(filePath, "utf-8"),
|
|
141
144
|
writeFile: (filePath, data) => writeFile(filePath, data, "utf-8"),
|
|
142
145
|
appendFile: (filePath, data) => appendFile(filePath, data, "utf-8"),
|
package/build/executor/env.js
CHANGED
|
@@ -329,3 +329,22 @@ export function buildExecutorBaseWorkerEnv(parentEnv, options = {}) {
|
|
|
329
329
|
// per call site.
|
|
330
330
|
return env;
|
|
331
331
|
}
|
|
332
|
+
/**
|
|
333
|
+
* The environment for a headless agent run that is not a worker job, such as the
|
|
334
|
+
* executor's deny-enforcement probe (BAPI-1386).
|
|
335
|
+
*
|
|
336
|
+
* The probe must see what a worker sees. Spawned from an executor that is itself
|
|
337
|
+
* running inside a Claude session, it would otherwise inherit that session's
|
|
338
|
+
* nested-session variables, and the CLI can refuse to start a tool call there. So
|
|
339
|
+
* this reuses the worker allowlist and worker-injected defaults behind
|
|
340
|
+
* {@link buildExecutorBaseWorkerEnv} rather than keeping a deny-list of Claude
|
|
341
|
+
* variable names, which would go stale with every CLI release. No job-specific
|
|
342
|
+
* option is set: the result carries no branch, base, scope, or correction marker.
|
|
343
|
+
*
|
|
344
|
+
* Applied only where the executor builds the deny probe's context. The shared
|
|
345
|
+
* `runHeadless()` passes its supplied environment through unchanged, so standalone
|
|
346
|
+
* capability probes are not filtered.
|
|
347
|
+
*/
|
|
348
|
+
export function buildHeadlessAgentEnv(parentEnv) {
|
|
349
|
+
return buildExecutorBaseWorkerEnv(parentEnv);
|
|
350
|
+
}
|