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,219 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The durable half of the Codex workspace broker (APRV-325.2).
|
|
3
|
+
*
|
|
4
|
+
* `workspace-plan.ts` decides what a change IS; this module is the only place
|
|
5
|
+
* that makes one happen. It exists because POSIX gives no atomic multi-file
|
|
6
|
+
* rename: four `rename(2)` calls are four separate instants, and a crash
|
|
7
|
+
* between the second and the third leaves a workspace that is neither the state
|
|
8
|
+
* the human approved nor the state they started from.
|
|
9
|
+
*
|
|
10
|
+
* ## The three states, and the one this module refuses to invent
|
|
11
|
+
*
|
|
12
|
+
* A committed transaction is `after`. An untouched one is `before`. Anything
|
|
13
|
+
* else is `mixed`, and mixed is reported as mixed. The classification is made
|
|
14
|
+
* by READING the filesystem back against the journal's recorded digests, never
|
|
15
|
+
* from what the applying code believes it did: a `rename` that returned zero
|
|
16
|
+
* and a `rename` whose effect a crash lost look identical from inside the
|
|
17
|
+
* process that called it, and only the bytes on disk can tell them apart. That
|
|
18
|
+
* is why {@link inspectWorkspaceState} runs after a successful apply as well as
|
|
19
|
+
* after a failed one, and why a mixed result reaches the log as
|
|
20
|
+
* `execution.indeterminate` with reason `workspace-commit-unknown` rather than
|
|
21
|
+
* as a failure (SPEC.md §8's closed reason set, extended by this task).
|
|
22
|
+
*
|
|
23
|
+
* ## Ordering, and why the journal is written before anything moves
|
|
24
|
+
*
|
|
25
|
+
* 1. Stage every new byte and every preimage into a directory on the SAME
|
|
26
|
+
* filesystem as the workspace, and `fsync` each file and then the directory.
|
|
27
|
+
* Nothing in the workspace has changed yet, so a crash here is `before`.
|
|
28
|
+
* 2. Write the journal — the plan's payload hash, every endpoint, and the
|
|
29
|
+
* before/after digest of each — and `fsync` it and its directory. This is
|
|
30
|
+
* the instant after which a crash is RECOVERABLE rather than merely
|
|
31
|
+
* undecidable: a journal on disk names what the workspace was and what it
|
|
32
|
+
* was becoming, so a later reader can prove which of the two it is in.
|
|
33
|
+
* 3. Apply, in a fixed order, then `fsync` every touched parent directory.
|
|
34
|
+
* 4. Read the endpoints back. Only an all-`after` reading removes the journal
|
|
35
|
+
* as a success; an all-`before` reading removes it as an untaken
|
|
36
|
+
* transaction; a mixed reading LEAVES IT for a person.
|
|
37
|
+
*
|
|
38
|
+
* ## Custody is claimed only as far as the platform proves it
|
|
39
|
+
*
|
|
40
|
+
* {@link acquireWorkspaceCustody} takes an `O_CREAT | O_EXCL` lock, which
|
|
41
|
+
* excludes other cooperating brokers and nothing else, and then asks POSIX
|
|
42
|
+
* ownership and mode whether any other principal can write the endpoints it is
|
|
43
|
+
* about to touch. It reports `os-exclusive` only when both hold, `advisory`
|
|
44
|
+
* otherwise, and it always reports `acl-unproven`, because ownership and mode
|
|
45
|
+
* do not speak about ACLs (the same honesty `codex/trust.ts` already keeps). A
|
|
46
|
+
* caller that needs the strong answer asks for it and is refused when the host
|
|
47
|
+
* cannot give it; nothing here silently downgrades.
|
|
48
|
+
*/
|
|
49
|
+
import type { PlannedWorkspaceOperation, WorkspacePlan } from "./workspace-plan.js";
|
|
50
|
+
export declare const WORKSPACE_COMMIT_VERSION: "approval.codex.workspace-commit.v1";
|
|
51
|
+
/**
|
|
52
|
+
* The one directory name inside a workspace root that a proposal may never
|
|
53
|
+
* name (the broker refuses an endpoint under it before the planner ever reads
|
|
54
|
+
* a preimage). Staging has to share a filesystem with the workspace for
|
|
55
|
+
* `rename` to be atomic, so it lives inside it; reserving the name is what
|
|
56
|
+
* stops a proposal from staging over its own transaction.
|
|
57
|
+
*/
|
|
58
|
+
export declare const WORKSPACE_TXN_DIR = ".approval-codex-txn";
|
|
59
|
+
/** The lockfile, beside the staging directory and under the same reservation. */
|
|
60
|
+
export declare const WORKSPACE_LOCK_FILE = ".approval-codex-lock";
|
|
61
|
+
/**
|
|
62
|
+
* How much exclusion the host actually granted.
|
|
63
|
+
*
|
|
64
|
+
* `os-exclusive`: the lock is held AND POSIX says no principal other than this
|
|
65
|
+
* process's effective user can write the workspace root or any parent
|
|
66
|
+
* directory this transaction touches. `advisory`: the lock is held and that
|
|
67
|
+
* second claim failed or could not be made. Nothing returns `os-exclusive`
|
|
68
|
+
* from a claim; it is returned from an inspection.
|
|
69
|
+
*/
|
|
70
|
+
export type CustodyKind = "os-exclusive" | "advisory";
|
|
71
|
+
export interface CustodyReport {
|
|
72
|
+
kind: CustodyKind;
|
|
73
|
+
/** Machine-readable, always includes `acl-unproven`. Never a judgment. */
|
|
74
|
+
findings: readonly string[];
|
|
75
|
+
}
|
|
76
|
+
export interface WorkspaceCustody {
|
|
77
|
+
report: CustodyReport;
|
|
78
|
+
root: string;
|
|
79
|
+
txnDir: string;
|
|
80
|
+
release: () => void;
|
|
81
|
+
}
|
|
82
|
+
export type CustodyResult = {
|
|
83
|
+
ok: true;
|
|
84
|
+
custody: WorkspaceCustody;
|
|
85
|
+
} | {
|
|
86
|
+
ok: false;
|
|
87
|
+
code: "custody-contended" | "custody-unavailable";
|
|
88
|
+
message: string;
|
|
89
|
+
};
|
|
90
|
+
/**
|
|
91
|
+
* Take the workspace lock and report how much exclusion it bought.
|
|
92
|
+
*
|
|
93
|
+
* The lock is `O_CREAT | O_EXCL` on a reserved name, which is the strongest
|
|
94
|
+
* primitive available to a process with no privilege: it excludes every other
|
|
95
|
+
* broker that respects it and no one else. Whether anything else CAN write is a
|
|
96
|
+
* separate question, asked of POSIX afterwards, and answered conservatively.
|
|
97
|
+
*/
|
|
98
|
+
export declare function acquireWorkspaceCustody(root: string, touchedDirectories: readonly string[]): CustodyResult;
|
|
99
|
+
/** One endpoint of one operation, with the two digests that classify it. */
|
|
100
|
+
export interface JournalEndpoint {
|
|
101
|
+
/** Workspace-relative POSIX path. */
|
|
102
|
+
path: string;
|
|
103
|
+
/** SHA-256 of the bytes this path held before the transaction, or null when absent. */
|
|
104
|
+
before_sha256: string | null;
|
|
105
|
+
/** SHA-256 of the bytes it must hold after it, or null when absent. */
|
|
106
|
+
after_sha256: string | null;
|
|
107
|
+
}
|
|
108
|
+
export interface JournalOperation {
|
|
109
|
+
index: number;
|
|
110
|
+
kind: PlannedWorkspaceOperation["kind"];
|
|
111
|
+
endpoints: readonly JournalEndpoint[];
|
|
112
|
+
/** Staged file holding the new bytes, relative to the staging directory. */
|
|
113
|
+
staged: string | null;
|
|
114
|
+
/** Staged file holding the preimage bytes, relative to the staging directory. */
|
|
115
|
+
preimage: string | null;
|
|
116
|
+
}
|
|
117
|
+
export interface WorkspaceCommitJournal {
|
|
118
|
+
version: typeof WORKSPACE_COMMIT_VERSION;
|
|
119
|
+
root: string;
|
|
120
|
+
payload_hash: string;
|
|
121
|
+
custody: CustodyKind;
|
|
122
|
+
operations: readonly JournalOperation[];
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* The endpoints one planned operation owns, in the shape recovery reads.
|
|
126
|
+
*
|
|
127
|
+
* A move owns two, and the second one's `before` is deliberately `null`: the
|
|
128
|
+
* planner refuses a move whose destination exists, so "absent" is the state the
|
|
129
|
+
* transaction started from and the state a rollback must restore.
|
|
130
|
+
*/
|
|
131
|
+
export declare function journalEndpointsOf(operation: PlannedWorkspaceOperation): JournalEndpoint[];
|
|
132
|
+
/** Every parent directory a transaction will write into, absolute and deduplicated. */
|
|
133
|
+
export declare function touchedDirectories(plan: WorkspacePlan): string[];
|
|
134
|
+
/** What one endpoint currently is, relative to the two states the journal names. */
|
|
135
|
+
export type EndpointState = "before" | "after" | "other" | "unreadable";
|
|
136
|
+
/** The whole transaction's state, proven by reading. Never inferred. */
|
|
137
|
+
export type WorkspaceState = "before" | "after" | "mixed";
|
|
138
|
+
export interface WorkspaceInspection {
|
|
139
|
+
state: WorkspaceState;
|
|
140
|
+
/** Per-endpoint readings, in journal order. Present for every state. */
|
|
141
|
+
endpoints: readonly {
|
|
142
|
+
path: string;
|
|
143
|
+
state: EndpointState;
|
|
144
|
+
}[];
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Classify the workspace against a journal by reading it.
|
|
148
|
+
*
|
|
149
|
+
* `mixed` is the honest answer for anything that is not uniformly one state,
|
|
150
|
+
* INCLUDING a single unreadable endpoint: "I could not look" and "it is half
|
|
151
|
+
* done" are both "nobody knows", and collapsing the first into `before` would
|
|
152
|
+
* be the runtime deciding an effect did not happen.
|
|
153
|
+
*/
|
|
154
|
+
export declare function inspectWorkspaceState(journal: WorkspaceCommitJournal): WorkspaceInspection;
|
|
155
|
+
export interface CommitOptions {
|
|
156
|
+
/**
|
|
157
|
+
* Called once, after the journal is durable and before the first visible
|
|
158
|
+
* mutation, and once after each applied operation with that operation's
|
|
159
|
+
* index. A TEST SEAM and nothing else: it takes a number and returns
|
|
160
|
+
* nothing, so it can supply no value and relax no check. Throwing from it
|
|
161
|
+
* simulates the crash a timing test cannot produce, and every path below
|
|
162
|
+
* treats the throw exactly as it treats a filesystem error.
|
|
163
|
+
*/
|
|
164
|
+
onStep?: (step: number) => void;
|
|
165
|
+
}
|
|
166
|
+
export interface CommitOutcome {
|
|
167
|
+
/** What reading the workspace back established. Never what the code believed. */
|
|
168
|
+
state: WorkspaceState;
|
|
169
|
+
inspection: WorkspaceInspection;
|
|
170
|
+
journal: WorkspaceCommitJournal;
|
|
171
|
+
/** The error that stopped the apply, when one did. */
|
|
172
|
+
failure?: string;
|
|
173
|
+
/** True when the journal was deliberately left on disk for a person. */
|
|
174
|
+
journalRetained: boolean;
|
|
175
|
+
}
|
|
176
|
+
export type CommitResult = {
|
|
177
|
+
ok: true;
|
|
178
|
+
outcome: CommitOutcome;
|
|
179
|
+
} | {
|
|
180
|
+
ok: false;
|
|
181
|
+
code: "stage-failed";
|
|
182
|
+
message: string;
|
|
183
|
+
};
|
|
184
|
+
/**
|
|
185
|
+
* Stage, journal, apply, read back.
|
|
186
|
+
*
|
|
187
|
+
* The caller holds custody (and therefore the staging directory) and keeps it
|
|
188
|
+
* until this returns. A `stage-failed` result is the one result that guarantees
|
|
189
|
+
* the workspace is untouched by construction rather than by inspection: nothing
|
|
190
|
+
* visible has been attempted when it fires.
|
|
191
|
+
*/
|
|
192
|
+
export declare function commitWorkspacePlan(plan: WorkspacePlan, custody: WorkspaceCustody, options?: CommitOptions): CommitResult;
|
|
193
|
+
export type RecoverResult = {
|
|
194
|
+
ok: true;
|
|
195
|
+
state: "none";
|
|
196
|
+
message: string;
|
|
197
|
+
} | {
|
|
198
|
+
ok: true;
|
|
199
|
+
state: WorkspaceState;
|
|
200
|
+
inspection: WorkspaceInspection;
|
|
201
|
+
journal: WorkspaceCommitJournal;
|
|
202
|
+
} | {
|
|
203
|
+
ok: false;
|
|
204
|
+
code: "journal-unreadable";
|
|
205
|
+
message: string;
|
|
206
|
+
};
|
|
207
|
+
/**
|
|
208
|
+
* Read a workspace's retained journal and say which of the three states it is
|
|
209
|
+
* in. It CHANGES NOTHING in the workspace.
|
|
210
|
+
*
|
|
211
|
+
* That is the whole contract, and the restraint is the point: a recovery that
|
|
212
|
+
* rolled a mixed workspace forward would be guessing which half of it the
|
|
213
|
+
* human approved, and a recovery that rolled one back would be deleting the
|
|
214
|
+
* half that already committed. Both are the runtime inventing a fact. A proven
|
|
215
|
+
* `before` or `after` needs no repair by definition, so there is nothing left
|
|
216
|
+
* for this function to do but say so and let the operator clear the staging
|
|
217
|
+
* directory.
|
|
218
|
+
*/
|
|
219
|
+
export declare function recoverWorkspaceCommit(root: string): RecoverResult;
|