approval-md 0.2.0 → 0.3.0
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 +63 -24
- package/SPEC.md +57 -11
- package/dist/src/channels/contract.d.ts +34 -1
- package/dist/src/channels/contract.js +200 -7
- package/dist/src/channels/contract.js.map +1 -1
- package/dist/src/channels/telegram.d.ts +123 -11
- package/dist/src/channels/telegram.js +218 -23
- package/dist/src/channels/telegram.js.map +1 -1
- package/dist/src/channels/web.d.ts +9 -0
- package/dist/src/channels/web.js +17 -0
- package/dist/src/channels/web.js.map +1 -1
- package/dist/src/cli/amend.js +214 -30
- package/dist/src/cli/amend.js.map +1 -1
- package/dist/src/cli/attest.d.ts +9 -0
- package/dist/src/cli/attest.js +134 -7
- package/dist/src/cli/attest.js.map +1 -1
- package/dist/src/cli/channel-telegram.d.ts +99 -26
- package/dist/src/cli/channel-telegram.js +311 -13
- package/dist/src/cli/channel-telegram.js.map +1 -1
- package/dist/src/cli/channel.d.ts +9 -0
- package/dist/src/cli/channel.js +9 -0
- package/dist/src/cli/channel.js.map +1 -1
- package/dist/src/cli/codex-bridge.d.ts +819 -0
- package/dist/src/cli/codex-bridge.js +1607 -0
- package/dist/src/cli/codex-bridge.js.map +1 -0
- package/dist/src/cli/codex.d.ts +1 -1
- package/dist/src/cli/codex.js +304 -7
- package/dist/src/cli/codex.js.map +1 -1
- package/dist/src/cli/daemon.js +4 -1
- package/dist/src/cli/daemon.js.map +1 -1
- package/dist/src/cli/doctor.js +467 -12
- package/dist/src/cli/doctor.js.map +1 -1
- package/dist/src/cli/execute.js +25 -2
- package/dist/src/cli/execute.js.map +1 -1
- package/dist/src/cli/help.d.ts +6 -2
- package/dist/src/cli/help.js +165 -60
- package/dist/src/cli/help.js.map +1 -1
- package/dist/src/cli/hook-codex.d.ts +49 -1
- package/dist/src/cli/hook-codex.js +60 -1
- package/dist/src/cli/hook-codex.js.map +1 -1
- package/dist/src/cli/hook.d.ts +459 -3
- package/dist/src/cli/hook.js +1062 -114
- package/dist/src/cli/hook.js.map +1 -1
- package/dist/src/cli/import.js +1 -1
- package/dist/src/cli/import.js.map +1 -1
- package/dist/src/cli/main.js +5 -3
- package/dist/src/cli/main.js.map +1 -1
- package/dist/src/cli/policy-apply.d.ts +195 -0
- package/dist/src/cli/policy-apply.js +573 -0
- package/dist/src/cli/policy-apply.js.map +1 -0
- package/dist/src/cli/policy.js +14 -1
- package/dist/src/cli/policy.js.map +1 -1
- package/dist/src/cli/preflight.d.ts +151 -13
- package/dist/src/cli/preflight.js +398 -41
- package/dist/src/cli/preflight.js.map +1 -1
- package/dist/src/cli/sandbox.js +17 -1
- package/dist/src/cli/sandbox.js.map +1 -1
- package/dist/src/cli/scaffold.d.ts +1 -1
- package/dist/src/cli/scaffold.js +1 -1
- package/dist/src/cli/setup-channel.d.ts +9 -0
- package/dist/src/cli/setup-channel.js +28 -1
- package/dist/src/cli/setup-channel.js.map +1 -1
- package/dist/src/cli/setup-common.d.ts +3 -1
- package/dist/src/cli/setup-common.js +3 -2
- package/dist/src/cli/setup-common.js.map +1 -1
- package/dist/src/cli/setup.d.ts +2 -0
- package/dist/src/cli/setup.js +94 -2
- package/dist/src/cli/setup.js.map +1 -1
- package/dist/src/cli/up.js +115 -51
- package/dist/src/cli/up.js.map +1 -1
- package/dist/src/cli/values.js +3 -4
- package/dist/src/cli/values.js.map +1 -1
- package/dist/src/cli/verb-registry.js +174 -9
- package/dist/src/cli/verb-registry.js.map +1 -1
- package/dist/src/cli/wordmark.d.ts +2 -2
- package/dist/src/cli/wordmark.js +2 -2
- package/dist/src/codex/broker.d.ts +229 -0
- package/dist/src/codex/broker.js +548 -0
- package/dist/src/codex/broker.js.map +1 -0
- package/dist/src/codex/runner.d.ts +178 -0
- package/dist/src/codex/runner.js +231 -0
- package/dist/src/codex/runner.js.map +1 -0
- package/dist/src/codex/serve.d.ts +56 -0
- package/dist/src/codex/serve.js +98 -0
- package/dist/src/codex/serve.js.map +1 -0
- package/dist/src/codex/workspace-commit.d.ts +219 -0
- package/dist/src/codex/workspace-commit.js +549 -0
- package/dist/src/codex/workspace-commit.js.map +1 -0
- package/dist/src/core/advance-cycle.d.ts +51 -0
- package/dist/src/core/advance-cycle.js +66 -2
- package/dist/src/core/advance-cycle.js.map +1 -1
- package/dist/src/core/agents-md.d.ts +20 -18
- package/dist/src/core/agents-md.js +33 -31
- package/dist/src/core/agents-md.js.map +1 -1
- package/dist/src/core/attest.d.ts +215 -0
- package/dist/src/core/attest.js +317 -7
- package/dist/src/core/attest.js.map +1 -1
- package/dist/src/core/audit.d.ts +18 -0
- package/dist/src/core/audit.js +13 -0
- package/dist/src/core/audit.js.map +1 -1
- package/dist/src/core/channel-owner.d.ts +213 -0
- package/dist/src/core/channel-owner.js +358 -0
- package/dist/src/core/channel-owner.js.map +1 -0
- package/dist/src/core/command-class.d.ts +154 -0
- package/dist/src/core/command-class.js +673 -20
- package/dist/src/core/command-class.js.map +1 -1
- package/dist/src/core/commit-guard.d.ts +272 -0
- package/dist/src/core/commit-guard.js +424 -0
- package/dist/src/core/commit-guard.js.map +1 -0
- package/dist/src/core/daemon-actor.d.ts +45 -0
- package/dist/src/core/daemon-actor.js +54 -0
- package/dist/src/core/daemon-actor.js.map +1 -0
- package/dist/src/core/dark-session.d.ts +109 -8
- package/dist/src/core/dark-session.js +266 -82
- package/dist/src/core/dark-session.js.map +1 -1
- package/dist/src/core/decision-refusal.d.ts +23 -2
- package/dist/src/core/decision-refusal.js +24 -2
- package/dist/src/core/decision-refusal.js.map +1 -1
- package/dist/src/core/env-file.d.ts +5 -0
- package/dist/src/core/env-file.js +60 -1
- package/dist/src/core/env-file.js.map +1 -1
- package/dist/src/core/execute.d.ts +15 -2
- package/dist/src/core/execute.js +15 -2
- package/dist/src/core/execute.js.map +1 -1
- package/dist/src/core/gate.d.ts +86 -1
- package/dist/src/core/gate.js +81 -1
- package/dist/src/core/gate.js.map +1 -1
- package/dist/src/core/gesture-refusal.d.ts +166 -0
- package/dist/src/core/gesture-refusal.js +188 -0
- package/dist/src/core/gesture-refusal.js.map +1 -0
- package/dist/src/core/harness-version.d.ts +1 -1
- package/dist/src/core/harness-version.js +3 -1
- package/dist/src/core/harness-version.js.map +1 -1
- package/dist/src/core/instance.d.ts +59 -2
- package/dist/src/core/instance.js +113 -0
- package/dist/src/core/instance.js.map +1 -1
- package/dist/src/core/log.d.ts +39 -1
- package/dist/src/core/log.js.map +1 -1
- package/dist/src/core/policy-explain.d.ts +10 -0
- package/dist/src/core/policy-explain.js +32 -0
- package/dist/src/core/policy-explain.js.map +1 -1
- package/dist/src/core/policy-load.d.ts +41 -1
- package/dist/src/core/policy-load.js +21 -3
- package/dist/src/core/policy-load.js.map +1 -1
- package/dist/src/core/policy-match.d.ts +43 -0
- package/dist/src/core/policy-match.js +52 -0
- package/dist/src/core/policy-match.js.map +1 -1
- package/dist/src/core/policy-proposal.d.ts +52 -0
- package/dist/src/core/policy-proposal.js +102 -2
- package/dist/src/core/policy-proposal.js.map +1 -1
- package/dist/src/core/protected-path-guard.d.ts +117 -4
- package/dist/src/core/protected-path-guard.js +362 -48
- package/dist/src/core/protected-path-guard.js.map +1 -1
- package/dist/src/core/question-preempted.d.ts +141 -0
- package/dist/src/core/question-preempted.js +152 -0
- package/dist/src/core/question-preempted.js.map +1 -0
- package/dist/src/core/read-scope.d.ts +172 -0
- package/dist/src/core/read-scope.js +252 -0
- package/dist/src/core/read-scope.js.map +1 -0
- package/dist/src/core/sandbox.d.ts +81 -0
- package/dist/src/core/sandbox.js +190 -1
- package/dist/src/core/sandbox.js.map +1 -1
- package/dist/src/core/sender-identity.d.ts +476 -0
- package/dist/src/core/sender-identity.js +572 -0
- package/dist/src/core/sender-identity.js.map +1 -0
- package/dist/src/core/shlex.d.ts +102 -0
- package/dist/src/core/shlex.js +159 -0
- package/dist/src/core/shlex.js.map +1 -0
- package/dist/src/core/values.d.ts +18 -8
- package/dist/src/core/values.js +36 -1
- package/dist/src/core/values.js.map +1 -1
- package/dist/src/daemon/advance.d.ts +10 -0
- package/dist/src/daemon/advance.js +25 -4
- package/dist/src/daemon/advance.js.map +1 -1
- package/dist/src/daemon/daemon.js +9 -0
- package/dist/src/daemon/daemon.js.map +1 -1
- package/dist/src/daemon/git-evidence.d.ts +2 -2
- package/dist/src/daemon/git-evidence.js +1 -1
- package/dist/src/mcp/server.js +8 -0
- package/dist/src/mcp/server.js.map +1 -1
- package/docs/cli-reference.md +932 -32
- package/docs/codex-enforced-session.md +75 -2
- package/docs/codex-workspace-broker.md +118 -0
- package/package.json +3 -1
- package/schema/event.schema.json +538 -9
- package/schema/fixtures/event/invalid/approval-granted-sender-hashed-false.json +20 -0
- package/schema/fixtures/event/invalid/approval-granted-sender-hashed-raw-id.json +20 -0
- package/schema/fixtures/event/invalid/audit-gesture-refused-human-actor.json +16 -0
- package/schema/fixtures/event/invalid/audit-gesture-refused-no-actor-no-sender.json +15 -0
- package/schema/fixtures/event/invalid/audit-gesture-refused-unknown-gesture.json +16 -0
- package/schema/fixtures/event/invalid/audit-question-preempted-agent-actor.json +16 -0
- package/schema/fixtures/event/invalid/audit-question-preempted-no-question-id.json +16 -0
- package/schema/fixtures/event/invalid/audit-question-preempted-unknown-source.json +15 -0
- package/schema/fixtures/event/invalid/gate-path-signed-off-absolute-path.json +14 -0
- package/schema/fixtures/event/invalid/gate-path-signed-off-agent-actor.json +14 -0
- package/schema/fixtures/event/invalid/gate-path-signed-off-missing-path.json +13 -0
- package/schema/fixtures/event/valid/approval-granted-sender-hashed.json +20 -0
- package/schema/fixtures/event/valid/audit-gesture-refused-review-note.json +21 -0
- package/schema/fixtures/event/valid/audit-gesture-refused-sender-key-unavailable.json +19 -0
- package/schema/fixtures/event/valid/audit-gesture-refused.json +19 -0
- package/schema/fixtures/event/valid/audit-question-preempted-no-verdict.json +16 -0
- package/schema/fixtures/event/valid/audit-question-preempted.json +20 -0
- package/schema/fixtures/event/valid/gate-path-signed-off.json +14 -0
- package/schema/fixtures/event/valid/harness-kind-claude-code.json +23 -0
- package/schema/fixtures/event/valid/harness-kind-codex.json +23 -0
- package/schema/fixtures/event/valid/harness-kind-cursor.json +23 -0
- package/schema/fixtures/event/valid/harness-kind-grok.json +23 -0
- package/schema/fixtures/event/valid/harness-kind-muse.json +23 -0
- package/schema/fixtures/policy/invalid/senders-half-keyed.json +20 -0
- package/schema/fixtures/policy/valid/canonical.json +1 -1
- package/schema/fixtures/policy/valid/senders-keyed.json +24 -0
- package/schema/fixtures/policy-md/valid/canonical.md +1 -1
- package/schema/fixtures/policy-md/valid/with-values.md +5 -7
- package/schema/fixtures/values/invalid/class-shaped.json +1 -1
- package/schema/fixtures/values/invalid/duplicate-entry.json +1 -1
- package/schema/fixtures/values/invalid/non-string-item.json +1 -1
- package/schema/fixtures/values/invalid/over-cap.json +1 -1
- package/schema/fixtures/values/invalid/unknown-key.json +1 -1
- package/schema/fixtures/values/invalid/version-float.json +1 -0
- package/schema/fixtures/values/invalid/version-integer.json +1 -0
- package/schema/fixtures/values/invalid/version-wrong-string.json +1 -0
- package/schema/fixtures/values/valid/empty-lists.json +2 -3
- package/schema/fixtures/values/valid/full.json +5 -7
- package/schema/fixtures/values/valid/minimal.json +1 -1
- package/schema/fixtures/values-md/invalid/schema-invalid.md +5 -3
- package/schema/fixtures/values-md/invalid/two-blocks.md +3 -3
- package/schema/fixtures/values-md/invalid/unterminated.md +2 -2
- package/schema/fixtures/values-md/invalid/version-1.md +69 -0
- package/schema/fixtures/values-md/invalid/version-unquoted.md +64 -0
- package/schema/fixtures/values-md/invalid/yaml-error.md +2 -2
- package/schema/fixtures/values-md/valid/absent.md +1 -1
- package/schema/fixtures/values-md/valid/with-values.md +5 -7
- package/schema/policy.schema.json +54 -2
- package/schema/values.schema.json +7 -11
- package/schema/fixtures/values/invalid/version-string.json +0 -1
|
@@ -0,0 +1,548 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The policy-bound Codex workspace change broker (APRV-325.2).
|
|
3
|
+
*
|
|
4
|
+
* APRV-325.1 shipped preparation, APRV-325.2.1 shipped the read-only planner,
|
|
5
|
+
* and this module is the thing both were for: the ONLY way a change reaches a
|
|
6
|
+
* canonical workspace in a constrained Codex session. It is deliberately not a
|
|
7
|
+
* mode of `src/mcp/server.ts`. That server publishes the whole agent verb
|
|
8
|
+
* catalog, including `run`, and a broker that lived inside it would be one
|
|
9
|
+
* unchecked flag away from the surface it exists to replace.
|
|
10
|
+
*
|
|
11
|
+
* ## What the caller may say, and what it may not
|
|
12
|
+
*
|
|
13
|
+
* A caller supplies exactly two things: a bounded list of typed operations, and
|
|
14
|
+
* the SHA-256 it believes the policy currently has. Everything else — the
|
|
15
|
+
* acting identity, the workspace root, the policy file, the log, the schema
|
|
16
|
+
* directory, the classes, the reversibility, the sandbox posture — comes from
|
|
17
|
+
* the installation manifest, which lives under a root-owned install root that
|
|
18
|
+
* no agent principal can write (`codex/manifest.ts`, `codex/trust.ts`).
|
|
19
|
+
* {@link parseBrokerInput} refuses an unknown key rather than ignoring it, so a
|
|
20
|
+
* caller that tries to name its own actor is told no instead of being quietly
|
|
21
|
+
* overridden, and {@link BROKER_TOOLS} is a POSITIVE allowlist of one: a name
|
|
22
|
+
* not on it is refused whether or not any surface advertised it.
|
|
23
|
+
*
|
|
24
|
+
* ## One action per class, never collapsed
|
|
25
|
+
*
|
|
26
|
+
* The planner returns one action leg per distinct path class, and this module
|
|
27
|
+
* registers, requests, starts and closes each of them separately. Collapsing
|
|
28
|
+
* four classes into one "workspace write" would lose exactly what the policy
|
|
29
|
+
* is for: the class is what the operator's roster, budget and autonomy are
|
|
30
|
+
* keyed to, and an action that reports a cheaper class than it performs is the
|
|
31
|
+
* self-reporting SPEC.md §11.1 invariant 4 forbids.
|
|
32
|
+
*
|
|
33
|
+
* ## The order, and why every step of it is load-bearing
|
|
34
|
+
*
|
|
35
|
+
* Read policy once and hash those exact bytes → check attestation against
|
|
36
|
+
* VERIFIED records → refuse if the caller's expected digest differs → plan →
|
|
37
|
+
* register the legs → authorize EVERY leg (policy, or a real grant token) →
|
|
38
|
+
* start EVERY leg → take custody → revalidate the plan UNDER custody → commit
|
|
39
|
+
* durably → read the workspace back → close every leg with what the reading
|
|
40
|
+
* said.
|
|
41
|
+
*
|
|
42
|
+
* Two of those orderings are the hard-won ones from the 2026-09-09 handover.
|
|
43
|
+
* **Every leg starts before any byte moves**, so a leg that refuses at start
|
|
44
|
+
* leaves a workspace that is untouched by construction rather than by cleanup;
|
|
45
|
+
* the already-started legs are closed `execution.failed` and the filesystem was
|
|
46
|
+
* never entered. And **revalidation happens under custody**, after the last
|
|
47
|
+
* start, because a revalidation that precedes the lock proves only what was
|
|
48
|
+
* true before another writer could act.
|
|
49
|
+
*
|
|
50
|
+
* ## Outcomes are read, not remembered
|
|
51
|
+
*
|
|
52
|
+
* `codex/workspace-commit.ts` classifies the workspace by reading it back
|
|
53
|
+
* against the journal. All-after closes every leg `execution.completed`;
|
|
54
|
+
* all-before closes every leg `execution.failed`; anything else — a partial
|
|
55
|
+
* apply, a failed rollback, an endpoint that could not be read — closes every
|
|
56
|
+
* leg `execution.indeterminate` with reason `workspace-commit-unknown`, the
|
|
57
|
+
* reason this task added to SPEC.md §8's closed set. Nothing here converts an
|
|
58
|
+
* indeterminate outcome into either of the others; that stays human-owned
|
|
59
|
+
* (`approval execution reconcile`).
|
|
60
|
+
*/
|
|
61
|
+
import { readFileSync } from "node:fs";
|
|
62
|
+
import { isAbsolute, resolve } from "node:path";
|
|
63
|
+
import { attestationRefusal, checkAttestationOfBytes, policyBytesHash, unreadablePolicyStatus, } from "../core/attest.js";
|
|
64
|
+
import { finishExecution, hasApprovalCycle, indeterminateExecution, startExecution, } from "../core/execute.js";
|
|
65
|
+
import { register, registeredAction, request } from "../core/gate.js";
|
|
66
|
+
import { loadPolicy } from "../core/policy-load.js";
|
|
67
|
+
import { readVerifiedRecords } from "../core/state.js";
|
|
68
|
+
import { acquireWorkspaceCustody, commitWorkspacePlan, touchedDirectories, WORKSPACE_LOCK_FILE, WORKSPACE_TXN_DIR, } from "./workspace-commit.js";
|
|
69
|
+
import { planWorkspaceProposal, revalidateWorkspacePlan, } from "./workspace-plan.js";
|
|
70
|
+
export const BROKER_VERSION = "approval.codex.broker.v1";
|
|
71
|
+
/**
|
|
72
|
+
* The positive server-side tool allowlist: one name, and nothing is reachable
|
|
73
|
+
* by any other.
|
|
74
|
+
*
|
|
75
|
+
* A deny list would have to name every verb the runtime grows next; this names
|
|
76
|
+
* the one a constrained Codex session may call, so anything added tomorrow is
|
|
77
|
+
* unreachable here until somebody decides otherwise. Fail closed, SPEC.md §11.
|
|
78
|
+
*/
|
|
79
|
+
export const BROKER_TOOLS = new Set(["codex_workspace_apply"]);
|
|
80
|
+
/** The indeterminate reason a mixed or unreadable commit records (SPEC.md §8). */
|
|
81
|
+
export const WORKSPACE_COMMIT_UNKNOWN = "workspace-commit-unknown";
|
|
82
|
+
/** Derive the fixed context from a validated instance manifest. */
|
|
83
|
+
export function brokerInstallation(manifest) {
|
|
84
|
+
return {
|
|
85
|
+
instanceId: manifest.instance_id,
|
|
86
|
+
actor: `agent:codex-${manifest.instance_id}`,
|
|
87
|
+
root: manifest.paths.workspace,
|
|
88
|
+
policyPath: manifest.paths.policy,
|
|
89
|
+
logPath: manifest.paths.log,
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
const HEX64 = /^[0-9a-f]{64}$/u;
|
|
93
|
+
/**
|
|
94
|
+
* Accept `{operations, expected_policy_sha256}` and refuse everything else.
|
|
95
|
+
*
|
|
96
|
+
* An unknown key is a refusal rather than a silent drop for the reason the MCP
|
|
97
|
+
* server refuses `--as`: a caller that named an actor, a root, a class or a
|
|
98
|
+
* token meant something by it, and the something they meant is not available
|
|
99
|
+
* here. Being told so is the only way they learn that.
|
|
100
|
+
*/
|
|
101
|
+
export function parseBrokerInput(value) {
|
|
102
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
103
|
+
return { ok: false, message: "the broker accepts one JSON object" };
|
|
104
|
+
}
|
|
105
|
+
const allowed = new Set(["operations", "expected_policy_sha256"]);
|
|
106
|
+
for (const key of Object.keys(value)) {
|
|
107
|
+
if (allowed.has(key))
|
|
108
|
+
continue;
|
|
109
|
+
return {
|
|
110
|
+
ok: false,
|
|
111
|
+
message: `unknown property ${JSON.stringify(key)}: the broker accepts "operations" and "expected_policy_sha256" and nothing else. Identity, workspace root, policy, log, class and reversibility are the installation's and no caller input can change them`,
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
const record = value;
|
|
115
|
+
const digest = record["expected_policy_sha256"];
|
|
116
|
+
if (typeof digest !== "string" || !HEX64.test(digest)) {
|
|
117
|
+
return { ok: false, message: "expected_policy_sha256 must be a lowercase SHA-256 hex digest" };
|
|
118
|
+
}
|
|
119
|
+
if (!("operations" in record)) {
|
|
120
|
+
return { ok: false, message: "operations is required" };
|
|
121
|
+
}
|
|
122
|
+
return { ok: true, input: { operations: record["operations"], expected_policy_sha256: digest } };
|
|
123
|
+
}
|
|
124
|
+
// ---------------------------------------------------------------------------
|
|
125
|
+
// Refusals
|
|
126
|
+
// ---------------------------------------------------------------------------
|
|
127
|
+
/**
|
|
128
|
+
* Every way the broker can say no. Frozen public API in the sense SPEC.md
|
|
129
|
+
* §11.1 invariant 6 means: each fires for exactly one condition, they are
|
|
130
|
+
* distinct from one another, and `tests/codex-broker.test.ts` pins the union.
|
|
131
|
+
*/
|
|
132
|
+
export const BROKER_REFUSAL_CODES = [
|
|
133
|
+
/** The tool name is not on {@link BROKER_TOOLS}. */
|
|
134
|
+
"tool-not-allowed",
|
|
135
|
+
/** The caller's object is not `{operations, expected_policy_sha256}`. */
|
|
136
|
+
"input-invalid",
|
|
137
|
+
/** The workspace root is not an absolute normalized path. */
|
|
138
|
+
"installation-invalid",
|
|
139
|
+
/** The log could not be read, is torn, or does not verify. */
|
|
140
|
+
"log-unavailable",
|
|
141
|
+
/** The policy file could not be read or parsed. */
|
|
142
|
+
"policy-unavailable",
|
|
143
|
+
/** The live policy bytes are not the attested ones. */
|
|
144
|
+
"policy-not-attested",
|
|
145
|
+
/** The caller's expected digest is not the live attested digest. */
|
|
146
|
+
"attestation-drift",
|
|
147
|
+
/** An endpoint names the broker's own reserved transaction paths. */
|
|
148
|
+
"reserved-path",
|
|
149
|
+
/** A replace whose after-image equals its preimage: nothing to approve. */
|
|
150
|
+
"no-op-operation",
|
|
151
|
+
/** The planner refused. `detail` carries its own code verbatim. */
|
|
152
|
+
"plan-refused",
|
|
153
|
+
/** The log already declares this task or key under different bytes. */
|
|
154
|
+
"replay",
|
|
155
|
+
/** Registration refused for any other gate reason. */
|
|
156
|
+
"register-refused",
|
|
157
|
+
/** Intake refused for any gate reason. */
|
|
158
|
+
"request-refused",
|
|
159
|
+
/** A leg needs a human's grant and no token for it was presented. */
|
|
160
|
+
"approval-required",
|
|
161
|
+
/** A leg's `execution.started` refused. Nothing was written to the workspace. */
|
|
162
|
+
"start-refused",
|
|
163
|
+
/** Another transaction holds the workspace lock. */
|
|
164
|
+
"custody-contended",
|
|
165
|
+
/** The lock or staging directory could not be created. */
|
|
166
|
+
"custody-unavailable",
|
|
167
|
+
/** The installation requires OS-exclusive custody and the host cannot prove it. */
|
|
168
|
+
"custody-insufficient",
|
|
169
|
+
/** The plan no longer validates against the workspace under custody. */
|
|
170
|
+
"workspace-drift",
|
|
171
|
+
/** Staging failed; the workspace is untouched by construction. */
|
|
172
|
+
"stage-failed",
|
|
173
|
+
/** The commit was attempted and did not take. Every leg is `execution.failed`. */
|
|
174
|
+
"commit-not-applied",
|
|
175
|
+
/** The commit was attempted and nobody knows. Every leg is indeterminate. */
|
|
176
|
+
"commit-unknown",
|
|
177
|
+
];
|
|
178
|
+
function refuse(code, message, extra = {}) {
|
|
179
|
+
return { ok: false, code, message, ...extra };
|
|
180
|
+
}
|
|
181
|
+
// ---------------------------------------------------------------------------
|
|
182
|
+
// Intake helpers
|
|
183
|
+
// ---------------------------------------------------------------------------
|
|
184
|
+
function readPolicy(policyPath) {
|
|
185
|
+
let bytes;
|
|
186
|
+
try {
|
|
187
|
+
bytes = readFileSync(policyPath);
|
|
188
|
+
}
|
|
189
|
+
catch (cause) {
|
|
190
|
+
return {
|
|
191
|
+
ok: false,
|
|
192
|
+
status: unreadablePolicyStatus(policyPath, cause instanceof Error ? cause.message : String(cause)),
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
return { ok: true, bytes, sha256: policyBytesHash(bytes), policy: loadPolicy({ file: policyPath }) };
|
|
196
|
+
}
|
|
197
|
+
/** The task id one proposal's bytes always produce. Deterministic, so a replay collides. */
|
|
198
|
+
export function brokerTaskId(instanceId, payloadHash) {
|
|
199
|
+
return `codex-workspace-${instanceId}-${payloadHash.slice(0, 16)}`;
|
|
200
|
+
}
|
|
201
|
+
/** The action key one class's leg always produces under that task. */
|
|
202
|
+
export function brokerActionKey(task, cls) {
|
|
203
|
+
return `${task}:${cls}`;
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Endpoints the broker owns and no proposal may name.
|
|
207
|
+
*
|
|
208
|
+
* The staging directory has to share a filesystem with the workspace for
|
|
209
|
+
* `rename` to be atomic, so it lives inside it. Reserving both names is what
|
|
210
|
+
* stops a proposal from writing its own journal or unlocking its own lock, and
|
|
211
|
+
* it is checked here rather than in the planner because the planner has no idea
|
|
212
|
+
* a transaction exists.
|
|
213
|
+
*/
|
|
214
|
+
function reservedEndpoint(path) {
|
|
215
|
+
const first = path.split("/")[0];
|
|
216
|
+
return first === WORKSPACE_TXN_DIR || first === WORKSPACE_LOCK_FILE;
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* The first reserved endpoint named anywhere in the RAW operations, or null.
|
|
220
|
+
*
|
|
221
|
+
* Over the unvalidated input on purpose, so the refusal precedes the planner's
|
|
222
|
+
* preimage read: the planner has no idea a transaction exists and would happily
|
|
223
|
+
* bind the bytes of the broker's own journal before anything here objected.
|
|
224
|
+
* Only the three path-valued fields of the closed operation language are read,
|
|
225
|
+
* and anything that is not a string is left to the planner to refuse.
|
|
226
|
+
*/
|
|
227
|
+
function reservedInRawOperations(operations) {
|
|
228
|
+
if (!Array.isArray(operations))
|
|
229
|
+
return null;
|
|
230
|
+
for (const entry of operations) {
|
|
231
|
+
if (typeof entry !== "object" || entry === null)
|
|
232
|
+
continue;
|
|
233
|
+
for (const field of ["path", "from", "to"]) {
|
|
234
|
+
const value = entry[field];
|
|
235
|
+
if (typeof value === "string" && reservedEndpoint(value))
|
|
236
|
+
return value;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
return null;
|
|
240
|
+
}
|
|
241
|
+
/**
|
|
242
|
+
* Does the log's latest cycle for `actionKey` end in a grant nobody has
|
|
243
|
+
* revoked?
|
|
244
|
+
*
|
|
245
|
+
* A HINT and never an authorization: it decides only whether the broker refuses
|
|
246
|
+
* early with the keys a person must decide, or lets `core/execute.ts` ask the
|
|
247
|
+
* real question (is this token the granted one, is its TTL alive, was it
|
|
248
|
+
* spent). Nothing here is compared against a secret and nothing here admits an
|
|
249
|
+
* execution.
|
|
250
|
+
*/
|
|
251
|
+
function grantOpen(records, actionKey) {
|
|
252
|
+
let granted = false;
|
|
253
|
+
for (const record of records) {
|
|
254
|
+
if (record.action_key !== actionKey)
|
|
255
|
+
continue;
|
|
256
|
+
if (record.event === "approval.granted")
|
|
257
|
+
granted = true;
|
|
258
|
+
else if (record.event === "approval.rejected" ||
|
|
259
|
+
record.event === "approval.revoked" ||
|
|
260
|
+
record.event === "approval.expired" ||
|
|
261
|
+
record.event === "approval.withdrawn" ||
|
|
262
|
+
record.event === "approval.requested")
|
|
263
|
+
granted = false;
|
|
264
|
+
}
|
|
265
|
+
return granted;
|
|
266
|
+
}
|
|
267
|
+
function legsOf(plan, task) {
|
|
268
|
+
return plan.actions.map((action) => ({
|
|
269
|
+
class: action.class,
|
|
270
|
+
actionKey: brokerActionKey(task, action.class),
|
|
271
|
+
mode: "policy",
|
|
272
|
+
}));
|
|
273
|
+
}
|
|
274
|
+
function envelopeFor(actor, legs, plan) {
|
|
275
|
+
return {
|
|
276
|
+
origin: { app: "approval-codex-broker", created_by: actor },
|
|
277
|
+
state: "proposed",
|
|
278
|
+
actions: legs.map((leg) => ({
|
|
279
|
+
class: leg.class,
|
|
280
|
+
summary: `Codex workspace change (${leg.class}): ${String(plan.payload.operations.length)} bounded operations`,
|
|
281
|
+
reversible: false,
|
|
282
|
+
est_cost_usd: "0",
|
|
283
|
+
idempotency_key: leg.actionKey,
|
|
284
|
+
payload_hash: plan.payload_hash,
|
|
285
|
+
})),
|
|
286
|
+
};
|
|
287
|
+
}
|
|
288
|
+
function executeOptionsFor(installation, options, payloadHash, token) {
|
|
289
|
+
const base = {
|
|
290
|
+
policy: { file: installation.policyPath },
|
|
291
|
+
presentedPayloadHash: payloadHash,
|
|
292
|
+
};
|
|
293
|
+
if (options.clock !== undefined)
|
|
294
|
+
base.clock = options.clock;
|
|
295
|
+
if (options.schemaDir !== undefined)
|
|
296
|
+
base.schemaDir = options.schemaDir;
|
|
297
|
+
if (options.append !== undefined)
|
|
298
|
+
base.append = options.append;
|
|
299
|
+
if (token !== undefined)
|
|
300
|
+
base.token = token;
|
|
301
|
+
return base;
|
|
302
|
+
}
|
|
303
|
+
// ---------------------------------------------------------------------------
|
|
304
|
+
// The broker
|
|
305
|
+
// ---------------------------------------------------------------------------
|
|
306
|
+
/**
|
|
307
|
+
* Apply one bounded typed proposal to the canonical workspace, or say exactly
|
|
308
|
+
* why not.
|
|
309
|
+
*
|
|
310
|
+
* `tool` is checked against {@link BROKER_TOOLS} first, before the input is
|
|
311
|
+
* even parsed: a surface that published nothing still refuses a name it does
|
|
312
|
+
* not serve, which is the defence in depth `src/mcp/server.ts` keeps for
|
|
313
|
+
* `mcp-guest-restricted`.
|
|
314
|
+
*/
|
|
315
|
+
export function applyWorkspaceChange(tool, installation, rawInput, options = {}) {
|
|
316
|
+
if (!BROKER_TOOLS.has(tool)) {
|
|
317
|
+
return refuse("tool-not-allowed", `${JSON.stringify(tool)} is not a broker tool; this surface serves exactly ${[...BROKER_TOOLS].join(", ")}`);
|
|
318
|
+
}
|
|
319
|
+
const parsed = parseBrokerInput(rawInput);
|
|
320
|
+
if (!parsed.ok)
|
|
321
|
+
return refuse("input-invalid", parsed.message);
|
|
322
|
+
if (!isAbsolute(installation.root) || resolve(installation.root) !== installation.root) {
|
|
323
|
+
return refuse("installation-invalid", "the installation's workspace root is not a normalized absolute path");
|
|
324
|
+
}
|
|
325
|
+
// --- Verified log, attested policy, and the caller's expectation of it ---
|
|
326
|
+
const read = readVerifiedRecords(installation.logPath, options.schemaDir === undefined ? {} : { schemaDir: options.schemaDir });
|
|
327
|
+
if (!read.ok)
|
|
328
|
+
return refuse("log-unavailable", read.message, { detail: read.code });
|
|
329
|
+
const records = read.records;
|
|
330
|
+
const policy = readPolicy(installation.policyPath);
|
|
331
|
+
if (!policy.ok) {
|
|
332
|
+
const attestation = attestationRefusal(policy.status);
|
|
333
|
+
return refuse("policy-unavailable", attestation?.message ?? "policy could not be read");
|
|
334
|
+
}
|
|
335
|
+
const status = checkAttestationOfBytes(records, policy.bytes);
|
|
336
|
+
const attestation = attestationRefusal(status);
|
|
337
|
+
if (attestation !== null) {
|
|
338
|
+
return refuse("policy-not-attested", attestation.message, { detail: attestation.detail });
|
|
339
|
+
}
|
|
340
|
+
if (parsed.input.expected_policy_sha256 !== policy.sha256) {
|
|
341
|
+
return refuse("attestation-drift", `the proposal expects policy ${parsed.input.expected_policy_sha256} and the attested policy is ${policy.sha256}; re-read the policy and rebuild the proposal`);
|
|
342
|
+
}
|
|
343
|
+
if (!policy.policy.ok) {
|
|
344
|
+
return refuse("policy-unavailable", `policy ${installation.policyPath} did not parse: ${policy.policy.message}`);
|
|
345
|
+
}
|
|
346
|
+
// --- Plan (the merged read-only intake does the path work) --------------
|
|
347
|
+
const context = {
|
|
348
|
+
actor: installation.actor,
|
|
349
|
+
root: installation.root,
|
|
350
|
+
policy_sha256: policy.sha256,
|
|
351
|
+
policy: policy.policy,
|
|
352
|
+
};
|
|
353
|
+
// Before the planner, because the planner would read the preimage of an
|
|
354
|
+
// endpoint it has no reason to think is special. The scan is over the raw
|
|
355
|
+
// input's own path fields and errs toward refusing.
|
|
356
|
+
const reserved = reservedInRawOperations(parsed.input.operations);
|
|
357
|
+
if (reserved !== null) {
|
|
358
|
+
return refuse("reserved-path", `${reserved} is inside the broker's own transaction custody (${WORKSPACE_TXN_DIR}, ${WORKSPACE_LOCK_FILE}) and is never a proposal endpoint`);
|
|
359
|
+
}
|
|
360
|
+
const planned = planWorkspaceProposal(parsed.input.operations, context);
|
|
361
|
+
if (!planned.ok) {
|
|
362
|
+
return refuse("plan-refused", `${planned.code}: ${planned.message}`, { detail: planned.code });
|
|
363
|
+
}
|
|
364
|
+
const plan = planned.plan;
|
|
365
|
+
for (const operation of plan.payload.operations) {
|
|
366
|
+
if (operation.kind !== "replace" || operation.before.sha256 !== operation.after.sha256)
|
|
367
|
+
continue;
|
|
368
|
+
return refuse("no-op-operation", `${operation.path} replaces its own bytes; a change with no effect has no outcome to report honestly`);
|
|
369
|
+
}
|
|
370
|
+
const task = brokerTaskId(installation.instanceId, plan.payload_hash);
|
|
371
|
+
const legs = legsOf(plan, task);
|
|
372
|
+
// --- Register: one declared action per class, all bound to one payload ---
|
|
373
|
+
const registration = register(installation.logPath, { task, envelope: envelopeFor(installation.actor, legs, plan) }, installation.actor, {
|
|
374
|
+
...(options.clock === undefined ? {} : { clock: options.clock }),
|
|
375
|
+
...(options.schemaDir === undefined ? {} : { schemaDir: options.schemaDir }),
|
|
376
|
+
...(options.append === undefined ? {} : { append: options.append }),
|
|
377
|
+
});
|
|
378
|
+
if (!registration.ok) {
|
|
379
|
+
if (registration.code !== "task-already-registered") {
|
|
380
|
+
return refuse("register-refused", registration.message, { detail: registration.code });
|
|
381
|
+
}
|
|
382
|
+
// The same bytes produce the same task id, so a second apply of an
|
|
383
|
+
// identical proposal lands here. It is legitimate only when the log's own
|
|
384
|
+
// declaration is byte-for-byte the one we just derived; anything else is a
|
|
385
|
+
// key this installation does not own and nothing may execute from it.
|
|
386
|
+
for (const leg of legs) {
|
|
387
|
+
const declared = registeredAction(records, task, leg.actionKey);
|
|
388
|
+
if (!declared.ok || declared.action.class !== leg.class || declared.action.payload_hash !== plan.payload_hash) {
|
|
389
|
+
return refuse("replay", `${task} is already registered under different bytes or classes; this proposal cannot reuse it`, { detail: registration.code });
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
// --- Authorize every leg BEFORE any start and before any mutation -------
|
|
394
|
+
const pending = [];
|
|
395
|
+
for (const leg of legs) {
|
|
396
|
+
if (hasApprovalCycle(records, leg.actionKey)) {
|
|
397
|
+
// Already asked. Re-requesting would open a second cycle for one
|
|
398
|
+
// decision, so the token (or its absence) settles this leg.
|
|
399
|
+
leg.mode = "token";
|
|
400
|
+
continue;
|
|
401
|
+
}
|
|
402
|
+
const intake = request(installation.logPath, {
|
|
403
|
+
task,
|
|
404
|
+
actionKey: leg.actionKey,
|
|
405
|
+
cls: leg.class,
|
|
406
|
+
est_cost_usd: "0",
|
|
407
|
+
reversible: false,
|
|
408
|
+
summary: `Codex workspace change (${leg.class})`,
|
|
409
|
+
payload_hash: plan.payload_hash,
|
|
410
|
+
payload: { value: plan.payload },
|
|
411
|
+
}, installation.actor, {
|
|
412
|
+
policy: { file: installation.policyPath },
|
|
413
|
+
...(options.clock === undefined ? {} : { clock: options.clock }),
|
|
414
|
+
...(options.schemaDir === undefined ? {} : { schemaDir: options.schemaDir }),
|
|
415
|
+
...(options.append === undefined ? {} : { append: options.append }),
|
|
416
|
+
});
|
|
417
|
+
if (!intake.ok) {
|
|
418
|
+
return refuse("request-refused", intake.message, { detail: intake.code });
|
|
419
|
+
}
|
|
420
|
+
leg.mode = intake.proceed ? "policy" : "token";
|
|
421
|
+
}
|
|
422
|
+
const tokens = options.tokens ?? {};
|
|
423
|
+
const afterIntake = readVerifiedRecords(installation.logPath, options.schemaDir === undefined ? {} : { schemaDir: options.schemaDir });
|
|
424
|
+
if (!afterIntake.ok)
|
|
425
|
+
return refuse("log-unavailable", afterIntake.message, { detail: afterIntake.code });
|
|
426
|
+
for (const leg of legs) {
|
|
427
|
+
if (leg.mode !== "token")
|
|
428
|
+
continue;
|
|
429
|
+
if (typeof tokens[leg.class] === "string")
|
|
430
|
+
continue;
|
|
431
|
+
// No token in hand is not the same as no authority. Sealed delivery
|
|
432
|
+
// (SPEC.md §10.4) puts the grant's token beside the log for the requester
|
|
433
|
+
// that asked, and `startExecution` opens it itself; the broker's job is
|
|
434
|
+
// only to tell a caller with NO grant what is waiting for a person. This
|
|
435
|
+
// check reduces no scrutiny: the grant is still verified where it always
|
|
436
|
+
// was, against the log's digest, and a leg that reaches `startExecution`
|
|
437
|
+
// with nothing to open is refused there.
|
|
438
|
+
if (grantOpen(afterIntake.records, leg.actionKey))
|
|
439
|
+
continue;
|
|
440
|
+
pending.push(leg.actionKey);
|
|
441
|
+
}
|
|
442
|
+
if (pending.length > 0) {
|
|
443
|
+
return refuse("approval-required", `${String(pending.length)} action(s) resolve to a human decision and no grant token was presented for them. Nothing was written`, { pending });
|
|
444
|
+
}
|
|
445
|
+
// --- Start every leg. A later refusal must mean no filesystem effect. ---
|
|
446
|
+
const started = [];
|
|
447
|
+
for (const leg of legs) {
|
|
448
|
+
const execOptions = executeOptionsFor(installation, options, plan.payload_hash, leg.mode === "token" ? tokens[leg.class] : undefined);
|
|
449
|
+
const start = startExecution(installation.logPath, leg.actionKey, execOptions, installation.actor);
|
|
450
|
+
if (start.ok) {
|
|
451
|
+
started.push(leg);
|
|
452
|
+
continue;
|
|
453
|
+
}
|
|
454
|
+
closeLegs(installation, options, plan, started, "failed", {
|
|
455
|
+
code: "leg-start-refused",
|
|
456
|
+
message: `a later action leg refused to start (${start.code}); no workspace operation was attempted`,
|
|
457
|
+
});
|
|
458
|
+
return refuse("start-refused", `${leg.actionKey} could not start: ${start.message}. No workspace operation was attempted`, { detail: start.code });
|
|
459
|
+
}
|
|
460
|
+
options.afterStart?.();
|
|
461
|
+
// --- Custody, then revalidation UNDER it, then the durable commit -------
|
|
462
|
+
const directories = touchedDirectories(plan);
|
|
463
|
+
const acquired = acquireWorkspaceCustody(installation.root, directories);
|
|
464
|
+
if (!acquired.ok) {
|
|
465
|
+
closeLegs(installation, options, plan, started, "failed", {
|
|
466
|
+
code: acquired.code,
|
|
467
|
+
message: "workspace custody was not obtained; no operation was attempted",
|
|
468
|
+
});
|
|
469
|
+
return refuse(acquired.code, acquired.message);
|
|
470
|
+
}
|
|
471
|
+
const custody = acquired.custody;
|
|
472
|
+
// A mixed commit leaves its journal inside the staging directory for a
|
|
473
|
+
// person, and `release` removes that directory. This is the one flag that
|
|
474
|
+
// decides between the two, and it is set only where the readback said mixed.
|
|
475
|
+
let keepStaging = false;
|
|
476
|
+
try {
|
|
477
|
+
if (options.requireExclusiveCustody === true && custody.report.kind !== "os-exclusive") {
|
|
478
|
+
closeLegs(installation, options, plan, started, "failed", {
|
|
479
|
+
code: "custody-insufficient",
|
|
480
|
+
message: "this installation requires OS-exclusive workspace custody",
|
|
481
|
+
});
|
|
482
|
+
return refuse("custody-insufficient", `this installation requires OS-exclusive workspace custody and the host proved only ${custody.report.kind} (${custody.report.findings.join(", ")})`);
|
|
483
|
+
}
|
|
484
|
+
const revalidated = revalidateWorkspacePlan(plan, context);
|
|
485
|
+
if (!revalidated.ok) {
|
|
486
|
+
closeLegs(installation, options, plan, started, "failed", {
|
|
487
|
+
code: revalidated.code,
|
|
488
|
+
message: "the workspace no longer matched the approved snapshot; no operation was attempted",
|
|
489
|
+
});
|
|
490
|
+
return refuse("workspace-drift", revalidated.message, { detail: revalidated.code });
|
|
491
|
+
}
|
|
492
|
+
const commit = commitWorkspacePlan(plan, custody, options.onStep === undefined ? {} : { onStep: options.onStep });
|
|
493
|
+
if (!commit.ok) {
|
|
494
|
+
closeLegs(installation, options, plan, started, "failed", {
|
|
495
|
+
code: commit.code,
|
|
496
|
+
message: "staging failed before any mutation; the workspace is unchanged",
|
|
497
|
+
});
|
|
498
|
+
return refuse("stage-failed", commit.message, { state: "before" });
|
|
499
|
+
}
|
|
500
|
+
const { state, failure } = commit.outcome;
|
|
501
|
+
if (state === "after") {
|
|
502
|
+
closeLegs(installation, options, plan, started, "completed");
|
|
503
|
+
return {
|
|
504
|
+
ok: true,
|
|
505
|
+
version: BROKER_VERSION,
|
|
506
|
+
task,
|
|
507
|
+
payload_hash: plan.payload_hash,
|
|
508
|
+
policy_sha256: policy.sha256,
|
|
509
|
+
legs: started,
|
|
510
|
+
custody: custody.report,
|
|
511
|
+
state: "after",
|
|
512
|
+
};
|
|
513
|
+
}
|
|
514
|
+
if (state === "before") {
|
|
515
|
+
closeLegs(installation, options, plan, started, "failed", {
|
|
516
|
+
code: "workspace-commit-reverted",
|
|
517
|
+
message: "the commit did not take and the workspace was read back as unchanged",
|
|
518
|
+
});
|
|
519
|
+
return refuse("commit-not-applied", `the workspace was read back as unchanged${failure === undefined ? "" : `: ${failure}`}`, { state });
|
|
520
|
+
}
|
|
521
|
+
keepStaging = commit.outcome.journalRetained;
|
|
522
|
+
closeLegs(installation, options, plan, started, "indeterminate");
|
|
523
|
+
return refuse("commit-unknown", `the workspace read back as neither the approved before-state nor the approved after-state${failure === undefined ? "" : `: ${failure}`}. The transaction journal and the workspace lock were retained, so no further brokered change can run until a person reads the journal and clears them; nothing here resolves it`, { state });
|
|
524
|
+
}
|
|
525
|
+
finally {
|
|
526
|
+
if (!keepStaging)
|
|
527
|
+
custody.release();
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
/**
|
|
531
|
+
* Close every started leg with the outcome the workspace readback established.
|
|
532
|
+
*
|
|
533
|
+
* Best effort per leg and never a throw: a leg whose close cannot be appended
|
|
534
|
+
* leaves a DANGLING execution, which is the honest state for it (SPEC.md §8),
|
|
535
|
+
* and failing to close the second leg must not stop the third from being told
|
|
536
|
+
* the truth.
|
|
537
|
+
*/
|
|
538
|
+
function closeLegs(installation, options, plan, legs, outcome, reason) {
|
|
539
|
+
for (const leg of legs) {
|
|
540
|
+
const base = executeOptionsFor(installation, options, plan.payload_hash);
|
|
541
|
+
if (outcome === "indeterminate") {
|
|
542
|
+
indeterminateExecution(installation.logPath, leg.actionKey, WORKSPACE_COMMIT_UNKNOWN, installation.actor, base);
|
|
543
|
+
continue;
|
|
544
|
+
}
|
|
545
|
+
finishExecution(installation.logPath, leg.actionKey, outcome === "completed" ? 0 : 1, installation.actor, outcome === "completed" ? base : { ...base, ...(reason === undefined ? {} : { reason }) });
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
//# sourceMappingURL=broker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"broker.js","sourceRoot":"","sources":["../../../src/codex/broker.ts"],"names":[],"mappings":"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"}
|