taskflow-core 0.2.0 → 0.2.1
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 +247 -862
- package/dist/agents.d.ts +12 -0
- package/dist/agents.d.ts.map +1 -1
- package/dist/agents.js +29 -1
- package/dist/agents.js.map +1 -1
- package/dist/cwd-bridge.d.ts +61 -0
- package/dist/cwd-bridge.d.ts.map +1 -0
- package/dist/cwd-bridge.js +136 -0
- package/dist/cwd-bridge.js.map +1 -0
- package/dist/detached-runner.js +31 -5
- package/dist/detached-runner.js.map +1 -1
- package/dist/exec/driver.d.ts +1 -0
- package/dist/exec/driver.d.ts.map +1 -1
- package/dist/exec/driver.js +15 -2
- package/dist/exec/driver.js.map +1 -1
- package/dist/exec/step-kinds.d.ts.map +1 -1
- package/dist/exec/step-kinds.js +28 -3
- package/dist/exec/step-kinds.js.map +1 -1
- package/dist/exec/step.d.ts +1 -0
- package/dist/exec/step.d.ts.map +1 -1
- package/dist/exec/step.js +18 -0
- package/dist/exec/step.js.map +1 -1
- package/dist/flowir/compile.d.ts.map +1 -1
- package/dist/flowir/compile.js +13 -0
- package/dist/flowir/compile.js.map +1 -1
- package/dist/host/runner-types.d.ts +16 -0
- package/dist/host/runner-types.d.ts.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -1
- package/dist/interpolate.d.ts +4 -0
- package/dist/interpolate.d.ts.map +1 -1
- package/dist/interpolate.js +14 -0
- package/dist/interpolate.js.map +1 -1
- package/dist/resources/authority.d.ts +35 -0
- package/dist/resources/authority.d.ts.map +1 -0
- package/dist/resources/authority.js +67 -0
- package/dist/resources/authority.js.map +1 -0
- package/dist/resources/backend.d.ts +302 -0
- package/dist/resources/backend.d.ts.map +1 -0
- package/dist/resources/backend.js +16 -0
- package/dist/resources/backend.js.map +1 -0
- package/dist/resources/baseline.d.ts +116 -0
- package/dist/resources/baseline.d.ts.map +1 -0
- package/dist/resources/baseline.js +447 -0
- package/dist/resources/baseline.js.map +1 -0
- package/dist/resources/canonical-json.d.ts +7 -0
- package/dist/resources/canonical-json.d.ts.map +1 -0
- package/dist/resources/canonical-json.js +75 -0
- package/dist/resources/canonical-json.js.map +1 -0
- package/dist/resources/errors.d.ts +23 -0
- package/dist/resources/errors.d.ts.map +1 -0
- package/dist/resources/errors.js +89 -0
- package/dist/resources/errors.js.map +1 -0
- package/dist/resources/execution.d.ts +90 -0
- package/dist/resources/execution.d.ts.map +1 -0
- package/dist/resources/execution.js +581 -0
- package/dist/resources/execution.js.map +1 -0
- package/dist/resources/index.d.ts +15 -0
- package/dist/resources/index.d.ts.map +1 -0
- package/dist/resources/index.js +15 -0
- package/dist/resources/index.js.map +1 -0
- package/dist/resources/journal.d.ts +138 -0
- package/dist/resources/journal.d.ts.map +1 -0
- package/dist/resources/journal.js +438 -0
- package/dist/resources/journal.js.map +1 -0
- package/dist/resources/leases.d.ts +51 -0
- package/dist/resources/leases.d.ts.map +1 -0
- package/dist/resources/leases.js +354 -0
- package/dist/resources/leases.js.map +1 -0
- package/dist/resources/permits.d.ts +52 -0
- package/dist/resources/permits.d.ts.map +1 -0
- package/dist/resources/permits.js +240 -0
- package/dist/resources/permits.js.map +1 -0
- package/dist/resources/persistence.d.ts +63 -0
- package/dist/resources/persistence.d.ts.map +1 -0
- package/dist/resources/persistence.js +522 -0
- package/dist/resources/persistence.js.map +1 -0
- package/dist/resources/registry.d.ts +56 -0
- package/dist/resources/registry.d.ts.map +1 -0
- package/dist/resources/registry.js +139 -0
- package/dist/resources/registry.js.map +1 -0
- package/dist/resources/resolve.d.ts +49 -0
- package/dist/resources/resolve.d.ts.map +1 -0
- package/dist/resources/resolve.js +309 -0
- package/dist/resources/resolve.js.map +1 -0
- package/dist/resources/sandbox.d.ts +72 -0
- package/dist/resources/sandbox.d.ts.map +1 -0
- package/dist/resources/sandbox.js +952 -0
- package/dist/resources/sandbox.js.map +1 -0
- package/dist/resources/schema.d.ts +195 -0
- package/dist/resources/schema.d.ts.map +1 -0
- package/dist/resources/schema.js +231 -0
- package/dist/resources/schema.js.map +1 -0
- package/dist/resources/types.d.ts +36 -0
- package/dist/resources/types.d.ts.map +1 -0
- package/dist/resources/types.js +75 -0
- package/dist/resources/types.js.map +1 -0
- package/dist/runner-core.d.ts +29 -0
- package/dist/runner-core.d.ts.map +1 -1
- package/dist/runner-core.js +311 -36
- package/dist/runner-core.js.map +1 -1
- package/dist/runtime/phases/script.d.ts.map +1 -1
- package/dist/runtime/phases/script.js +47 -9
- package/dist/runtime/phases/script.js.map +1 -1
- package/dist/runtime.d.ts +39 -0
- package/dist/runtime.d.ts.map +1 -1
- package/dist/runtime.js +542 -50
- package/dist/runtime.js.map +1 -1
- package/dist/schema.d.ts +68 -5
- package/dist/schema.d.ts.map +1 -1
- package/dist/schema.js +163 -22
- package/dist/schema.js.map +1 -1
- package/dist/store.d.ts +7 -0
- package/dist/store.d.ts.map +1 -1
- package/dist/store.js.map +1 -1
- package/dist/trace.d.ts +3 -0
- package/dist/trace.d.ts.map +1 -1
- package/dist/trace.js.map +1 -1
- package/package.json +3 -2
|
@@ -0,0 +1,447 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Exact host/OS evidence gating for workspace sandbox claims.
|
|
3
|
+
*
|
|
4
|
+
* A host version string or a static feature flag is not evidence. Sandboxed
|
|
5
|
+
* execution is enabled only when every field of the running target matches an
|
|
6
|
+
* approved, checked-in probe result. Missing and stale cells fail closed.
|
|
7
|
+
*/
|
|
8
|
+
import * as crypto from "node:crypto";
|
|
9
|
+
import * as fs from "node:fs";
|
|
10
|
+
import * as path from "node:path";
|
|
11
|
+
export const HOST_PROBE_HOSTS = ["pi", "codex", "claude", "opencode", "grok"];
|
|
12
|
+
export const HOST_PROBE_OSES = ["macos", "linux", "windows"];
|
|
13
|
+
export const HOST_PROBE_VERSION = "tfws-probe:v1";
|
|
14
|
+
export const PROCESS_SANDBOX_EVIDENCE_CHECKS = [
|
|
15
|
+
"exactCwd",
|
|
16
|
+
"readInsideReadOnly",
|
|
17
|
+
"writeInsideReadOnlyDenied",
|
|
18
|
+
"readInsideReadWrite",
|
|
19
|
+
"writeInsideReadWrite",
|
|
20
|
+
"siblingScopeDenied",
|
|
21
|
+
"outsideScopeDenied",
|
|
22
|
+
"symlinkEscapeDenied",
|
|
23
|
+
"ambientUserDataDenied",
|
|
24
|
+
"privateTempEnforced",
|
|
25
|
+
"descendantEnforcement",
|
|
26
|
+
"abortDescendantCleanup",
|
|
27
|
+
"networkPolicyEnforced",
|
|
28
|
+
"credentialIsolationEnforced",
|
|
29
|
+
"baselineRuntimeUsable",
|
|
30
|
+
"resolverOpenPathSwapDenied",
|
|
31
|
+
"exactMetadataNoFollow",
|
|
32
|
+
"unsupportedPolicyFailsClosed",
|
|
33
|
+
];
|
|
34
|
+
export const FILE_BROKER_EVIDENCE_CHECKS = [
|
|
35
|
+
"readInsideReadOnly",
|
|
36
|
+
"writeInsideReadOnlyDenied",
|
|
37
|
+
"readInsideReadWrite",
|
|
38
|
+
"writeInsideReadWrite",
|
|
39
|
+
"siblingScopeDenied",
|
|
40
|
+
"outsideScopeDenied",
|
|
41
|
+
"symlinkEscapeDenied",
|
|
42
|
+
"brokeredReadNoFollow",
|
|
43
|
+
"brokeredWriteNoFollow",
|
|
44
|
+
"fingerprintNoFollow",
|
|
45
|
+
"resolverOpenPathSwapDenied",
|
|
46
|
+
"abortCleanup",
|
|
47
|
+
"exactMetadataNoFollow",
|
|
48
|
+
"unsupportedPolicyFailsClosed",
|
|
49
|
+
];
|
|
50
|
+
const SHA256_RE = /^[0-9a-f]{64}$/;
|
|
51
|
+
const verifiedBaselines = new WeakSet();
|
|
52
|
+
const verifiedSandboxApprovals = new WeakSet();
|
|
53
|
+
const TARGET_KEYS = [
|
|
54
|
+
"host",
|
|
55
|
+
"hostVersion",
|
|
56
|
+
"hostBinarySha256",
|
|
57
|
+
"os",
|
|
58
|
+
"osVersion",
|
|
59
|
+
"osBuild",
|
|
60
|
+
"arch",
|
|
61
|
+
"sandboxMechanismVersion",
|
|
62
|
+
"backendId",
|
|
63
|
+
"backendCapabilityVersion",
|
|
64
|
+
"backendCapabilitiesSha256",
|
|
65
|
+
"baselinePolicyId",
|
|
66
|
+
];
|
|
67
|
+
function isNonEmptyString(value) {
|
|
68
|
+
return typeof value === "string" && value.length > 0;
|
|
69
|
+
}
|
|
70
|
+
function targetKey(target) {
|
|
71
|
+
return JSON.stringify([
|
|
72
|
+
target.host,
|
|
73
|
+
target.hostVersion,
|
|
74
|
+
target.hostBinarySha256,
|
|
75
|
+
target.os,
|
|
76
|
+
target.osVersion,
|
|
77
|
+
target.osBuild,
|
|
78
|
+
target.arch,
|
|
79
|
+
target.sandboxMechanismVersion,
|
|
80
|
+
target.backendId,
|
|
81
|
+
target.backendCapabilityVersion,
|
|
82
|
+
target.backendCapabilitiesSha256,
|
|
83
|
+
target.baselinePolicyId,
|
|
84
|
+
]);
|
|
85
|
+
}
|
|
86
|
+
export function hostProbeTargetsEqual(left, right) {
|
|
87
|
+
return targetKey(left) === targetKey(right);
|
|
88
|
+
}
|
|
89
|
+
function isWithin(root, candidate) {
|
|
90
|
+
const relative = path.relative(root, candidate);
|
|
91
|
+
return relative === "" || (relative !== ".." && !relative.startsWith(`..${path.sep}`) && !path.isAbsolute(relative));
|
|
92
|
+
}
|
|
93
|
+
function deepFreeze(value) {
|
|
94
|
+
if (typeof value !== "object" || value === null || Object.isFrozen(value))
|
|
95
|
+
return value;
|
|
96
|
+
Object.freeze(value);
|
|
97
|
+
for (const child of Object.values(value))
|
|
98
|
+
deepFreeze(child);
|
|
99
|
+
return value;
|
|
100
|
+
}
|
|
101
|
+
function resolveTrustedRegularFile(repositoryRoot, relativePath) {
|
|
102
|
+
if (!relativePath || path.isAbsolute(relativePath))
|
|
103
|
+
throw new Error("evidence path must be repository-relative");
|
|
104
|
+
const segments = relativePath.split(/[\\/]+/);
|
|
105
|
+
if (segments.some((segment) => segment === "" || segment === "." || segment === "..")) {
|
|
106
|
+
throw new Error("evidence path contains an unsafe segment");
|
|
107
|
+
}
|
|
108
|
+
let current = repositoryRoot;
|
|
109
|
+
for (const segment of segments) {
|
|
110
|
+
current = path.join(current, segment);
|
|
111
|
+
const stat = fs.lstatSync(current);
|
|
112
|
+
if (stat.isSymbolicLink())
|
|
113
|
+
throw new Error(`trusted baseline path must not contain symlinks: ${relativePath}`);
|
|
114
|
+
}
|
|
115
|
+
const canonical = fs.realpathSync(current);
|
|
116
|
+
if (!isWithin(repositoryRoot, canonical))
|
|
117
|
+
throw new Error("trusted baseline path escapes the repository root");
|
|
118
|
+
if (!fs.lstatSync(canonical).isFile())
|
|
119
|
+
throw new Error(`trusted baseline path is not a regular file: ${relativePath}`);
|
|
120
|
+
return canonical;
|
|
121
|
+
}
|
|
122
|
+
function sameFileSnapshot(left, right) {
|
|
123
|
+
return left.dev === right.dev &&
|
|
124
|
+
left.ino === right.ino &&
|
|
125
|
+
left.size === right.size &&
|
|
126
|
+
left.mtimeNs === right.mtimeNs &&
|
|
127
|
+
left.ctimeNs === right.ctimeNs;
|
|
128
|
+
}
|
|
129
|
+
/** Resolve, open without following the final component, and consume exactly one
|
|
130
|
+
* immutable byte snapshot. Hashing and JSON parsing both use these same bytes. */
|
|
131
|
+
function readTrustedJson(repositoryRoot, relativePath, maxBytes) {
|
|
132
|
+
const canonical = resolveTrustedRegularFile(repositoryRoot, relativePath);
|
|
133
|
+
const noFollow = typeof fs.constants.O_NOFOLLOW === "number" ? fs.constants.O_NOFOLLOW : 0;
|
|
134
|
+
const fd = fs.openSync(canonical, fs.constants.O_RDONLY | noFollow);
|
|
135
|
+
try {
|
|
136
|
+
const before = fs.fstatSync(fd, { bigint: true });
|
|
137
|
+
if (!before.isFile())
|
|
138
|
+
throw new Error(`trusted baseline path is not a regular file: ${relativePath}`);
|
|
139
|
+
if (before.size > BigInt(maxBytes))
|
|
140
|
+
throw new Error(`trusted baseline evidence exceeds ${maxBytes} bytes`);
|
|
141
|
+
const bytes = fs.readFileSync(fd);
|
|
142
|
+
if (bytes.byteLength > maxBytes)
|
|
143
|
+
throw new Error(`trusted baseline evidence exceeds ${maxBytes} bytes`);
|
|
144
|
+
const after = fs.fstatSync(fd, { bigint: true });
|
|
145
|
+
if (!sameFileSnapshot(before, after))
|
|
146
|
+
throw new Error(`trusted baseline file changed while reading: ${relativePath}`);
|
|
147
|
+
// Re-resolve every path component after the read. A parent-directory swap
|
|
148
|
+
// cannot authorize the opened bytes unless the live path still identifies
|
|
149
|
+
// this exact inode and immutable snapshot.
|
|
150
|
+
const liveCanonical = resolveTrustedRegularFile(repositoryRoot, relativePath);
|
|
151
|
+
const live = fs.lstatSync(liveCanonical, { bigint: true });
|
|
152
|
+
if (!sameFileSnapshot(after, live))
|
|
153
|
+
throw new Error(`trusted baseline path changed while reading: ${relativePath}`);
|
|
154
|
+
return { bytes, value: JSON.parse(bytes.toString("utf8")) };
|
|
155
|
+
}
|
|
156
|
+
finally {
|
|
157
|
+
fs.closeSync(fd);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
function sha256Bytes(bytes) {
|
|
161
|
+
return crypto.createHash("sha256").update(bytes).digest("hex");
|
|
162
|
+
}
|
|
163
|
+
function assertExactKeys(value, expected, name) {
|
|
164
|
+
const actual = Object.keys(value).sort();
|
|
165
|
+
const required = [...expected].sort();
|
|
166
|
+
if (actual.length !== required.length || actual.some((key, index) => key !== required[index])) {
|
|
167
|
+
throw new Error(`${name} must contain exactly: ${required.join(", ")}`);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
function verifyTarget(value, name) {
|
|
171
|
+
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
172
|
+
throw new Error(`${name} must be an object`);
|
|
173
|
+
const target = value;
|
|
174
|
+
assertExactKeys(target, TARGET_KEYS, name);
|
|
175
|
+
if (!HOST_PROBE_HOSTS.includes(target.host))
|
|
176
|
+
throw new Error(`${name}.host is invalid`);
|
|
177
|
+
if (!HOST_PROBE_OSES.includes(target.os))
|
|
178
|
+
throw new Error(`${name}.os is invalid`);
|
|
179
|
+
if (target.arch !== "arm64" && target.arch !== "x64")
|
|
180
|
+
throw new Error(`${name}.arch is invalid`);
|
|
181
|
+
for (const field of [
|
|
182
|
+
"hostVersion",
|
|
183
|
+
"osVersion",
|
|
184
|
+
"osBuild",
|
|
185
|
+
"sandboxMechanismVersion",
|
|
186
|
+
"backendId",
|
|
187
|
+
"backendCapabilityVersion",
|
|
188
|
+
"baselinePolicyId",
|
|
189
|
+
]) {
|
|
190
|
+
if (!isNonEmptyString(target[field]) || /[\u0000-\u001f\u007f]/.test(target[field])) {
|
|
191
|
+
throw new Error(`${name}.${field} must be non-empty and contain no control characters`);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
if (typeof target.hostBinarySha256 !== "string" || !SHA256_RE.test(target.hostBinarySha256)) {
|
|
195
|
+
throw new Error(`${name}.hostBinarySha256 must be lowercase sha256`);
|
|
196
|
+
}
|
|
197
|
+
if (typeof target.backendCapabilitiesSha256 !== "string" || !SHA256_RE.test(target.backendCapabilitiesSha256)) {
|
|
198
|
+
throw new Error(`${name}.backendCapabilitiesSha256 must be lowercase sha256`);
|
|
199
|
+
}
|
|
200
|
+
return target;
|
|
201
|
+
}
|
|
202
|
+
export function isExactHostProbeTarget(value) {
|
|
203
|
+
try {
|
|
204
|
+
verifyTarget(value, "host probe target");
|
|
205
|
+
return true;
|
|
206
|
+
}
|
|
207
|
+
catch {
|
|
208
|
+
return false;
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
function verifySuiteEvidence(value, requiredChecks, name) {
|
|
212
|
+
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
213
|
+
throw new Error(`${name} must be an object`);
|
|
214
|
+
const suite = value;
|
|
215
|
+
assertExactKeys(suite, ["pass", "checks"], name);
|
|
216
|
+
if (typeof suite.pass !== "boolean")
|
|
217
|
+
throw new Error(`${name}.pass must be boolean`);
|
|
218
|
+
if (!suite.checks || typeof suite.checks !== "object" || Array.isArray(suite.checks)) {
|
|
219
|
+
throw new Error(`${name}.checks must be an object`);
|
|
220
|
+
}
|
|
221
|
+
const checks = suite.checks;
|
|
222
|
+
assertExactKeys(checks, requiredChecks, `${name}.checks`);
|
|
223
|
+
if (Object.values(checks).some((check) => typeof check !== "boolean")) {
|
|
224
|
+
throw new Error(`${name}.checks must contain only booleans`);
|
|
225
|
+
}
|
|
226
|
+
const derivedPass = requiredChecks.every((check) => checks[check] === true);
|
|
227
|
+
if (suite.pass !== derivedPass)
|
|
228
|
+
throw new Error(`${name}.pass does not match its required checks`);
|
|
229
|
+
return { pass: suite.pass };
|
|
230
|
+
}
|
|
231
|
+
function verifyEvidenceBundle(value) {
|
|
232
|
+
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
233
|
+
throw new Error("evidence bundle must be an object");
|
|
234
|
+
const document = value;
|
|
235
|
+
assertExactKeys(document, ["schemaVersion", "probeVersion", "results"], "evidence bundle");
|
|
236
|
+
if (document.schemaVersion !== 1)
|
|
237
|
+
throw new Error("evidence bundle schemaVersion must be 1");
|
|
238
|
+
if (document.probeVersion !== HOST_PROBE_VERSION) {
|
|
239
|
+
throw new Error(`evidence bundle probeVersion must be ${HOST_PROBE_VERSION}`);
|
|
240
|
+
}
|
|
241
|
+
if (!Array.isArray(document.results) || document.results.length === 0) {
|
|
242
|
+
throw new Error("evidence bundle results must be a non-empty array");
|
|
243
|
+
}
|
|
244
|
+
const seen = new Set();
|
|
245
|
+
for (const [index, value] of document.results.entries()) {
|
|
246
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
247
|
+
throw new Error(`evidence bundle results[${index}] must be an object`);
|
|
248
|
+
}
|
|
249
|
+
const result = value;
|
|
250
|
+
assertExactKeys(result, ["target", "classification", "agent", "script", "fileBroker"], `evidence bundle results[${index}]`);
|
|
251
|
+
const target = verifyTarget(result.target, `evidence bundle results[${index}].target`);
|
|
252
|
+
const key = targetKey(target);
|
|
253
|
+
if (seen.has(key))
|
|
254
|
+
throw new Error("evidence bundle contains duplicate exact targets");
|
|
255
|
+
seen.add(key);
|
|
256
|
+
if (!["sandboxed-single-root", "sandboxed-multi-root", "resolve-only", "unsupported"].includes(result.classification)) {
|
|
257
|
+
throw new Error(`evidence bundle results[${index}].classification is invalid`);
|
|
258
|
+
}
|
|
259
|
+
verifySuiteEvidence(result.agent, PROCESS_SANDBOX_EVIDENCE_CHECKS, `evidence bundle results[${index}].agent`);
|
|
260
|
+
verifySuiteEvidence(result.script, PROCESS_SANDBOX_EVIDENCE_CHECKS, `evidence bundle results[${index}].script`);
|
|
261
|
+
verifySuiteEvidence(result.fileBroker, FILE_BROKER_EVIDENCE_CHECKS, `evidence bundle results[${index}].fileBroker`);
|
|
262
|
+
}
|
|
263
|
+
return document;
|
|
264
|
+
}
|
|
265
|
+
function verifyEvidenceDocument(value, cell, kind, requirePass) {
|
|
266
|
+
const document = verifyEvidenceBundle(value);
|
|
267
|
+
const result = document.results.find((candidate) => targetKey(candidate.target) === targetKey(cell.target));
|
|
268
|
+
if (!result) {
|
|
269
|
+
throw new Error(`${kind} evidence target does not exactly match its baseline cell`);
|
|
270
|
+
}
|
|
271
|
+
if (result.classification !== cell.classification) {
|
|
272
|
+
throw new Error(`${kind} evidence classification does not exactly match its baseline cell`);
|
|
273
|
+
}
|
|
274
|
+
if (requirePass && result[kind].pass !== true) {
|
|
275
|
+
throw new Error(`${kind} evidence did not pass`);
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
/** Validate trusted baseline data before it can authorize a sandbox claim. */
|
|
279
|
+
export function validateHostSupportBaseline(value) {
|
|
280
|
+
const errors = [];
|
|
281
|
+
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
282
|
+
return ["baseline must be an object"];
|
|
283
|
+
const rootKeys = Object.keys(value).filter((key) => !["schemaVersion", "baselineId", "cells"].includes(key));
|
|
284
|
+
if (rootKeys.length > 0)
|
|
285
|
+
errors.push(`baseline has unsupported fields: ${rootKeys.join(", ")}`);
|
|
286
|
+
const baseline = value;
|
|
287
|
+
if (baseline.schemaVersion !== 1)
|
|
288
|
+
errors.push("schemaVersion must be 1");
|
|
289
|
+
if (!isNonEmptyString(baseline.baselineId))
|
|
290
|
+
errors.push("baselineId must be a non-empty string");
|
|
291
|
+
if (!Array.isArray(baseline.cells))
|
|
292
|
+
return [...errors, "cells must be an array"];
|
|
293
|
+
const seen = new Set();
|
|
294
|
+
baseline.cells.forEach((raw, index) => {
|
|
295
|
+
const prefix = `cells[${index}]`;
|
|
296
|
+
if (!raw || typeof raw !== "object") {
|
|
297
|
+
errors.push(`${prefix} must be an object`);
|
|
298
|
+
return;
|
|
299
|
+
}
|
|
300
|
+
const cell = raw;
|
|
301
|
+
const cellKeys = Object.keys(cell).filter((key) => !["target", "classification", "agent", "script", "fileBroker", "decision"].includes(key));
|
|
302
|
+
if (cellKeys.length > 0)
|
|
303
|
+
errors.push(`${prefix} has unsupported fields: ${cellKeys.join(", ")}`);
|
|
304
|
+
const target = cell.target;
|
|
305
|
+
if (!target || typeof target !== "object") {
|
|
306
|
+
errors.push(`${prefix}.target must be an object`);
|
|
307
|
+
return;
|
|
308
|
+
}
|
|
309
|
+
const targetKeys = Object.keys(target).filter((key) => !TARGET_KEYS.includes(key));
|
|
310
|
+
if (targetKeys.length > 0)
|
|
311
|
+
errors.push(`${prefix}.target has unsupported fields: ${targetKeys.join(", ")}`);
|
|
312
|
+
if (!HOST_PROBE_HOSTS.includes(target.host))
|
|
313
|
+
errors.push(`${prefix}.target.host is invalid`);
|
|
314
|
+
if (!HOST_PROBE_OSES.includes(target.os))
|
|
315
|
+
errors.push(`${prefix}.target.os is invalid`);
|
|
316
|
+
if (target.arch !== "arm64" && target.arch !== "x64")
|
|
317
|
+
errors.push(`${prefix}.target.arch is invalid`);
|
|
318
|
+
for (const field of [
|
|
319
|
+
"hostVersion",
|
|
320
|
+
"osVersion",
|
|
321
|
+
"osBuild",
|
|
322
|
+
"sandboxMechanismVersion",
|
|
323
|
+
"backendId",
|
|
324
|
+
"backendCapabilityVersion",
|
|
325
|
+
"baselinePolicyId",
|
|
326
|
+
]) {
|
|
327
|
+
if (!isNonEmptyString(target[field]) || /[\u0000-\u001f\u007f]/.test(target[field])) {
|
|
328
|
+
errors.push(`${prefix}.target.${field} must be non-empty and contain no control characters`);
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
if (!SHA256_RE.test(target.hostBinarySha256))
|
|
332
|
+
errors.push(`${prefix}.target.hostBinarySha256 must be lowercase sha256`);
|
|
333
|
+
if (!SHA256_RE.test(target.backendCapabilitiesSha256)) {
|
|
334
|
+
errors.push(`${prefix}.target.backendCapabilitiesSha256 must be lowercase sha256`);
|
|
335
|
+
}
|
|
336
|
+
const key = targetKey(target);
|
|
337
|
+
if (seen.has(key))
|
|
338
|
+
errors.push(`${prefix} duplicates an exact target cell`);
|
|
339
|
+
seen.add(key);
|
|
340
|
+
if (!["sandboxed-single-root", "sandboxed-multi-root", "resolve-only", "unsupported"].includes(cell.classification)) {
|
|
341
|
+
errors.push(`${prefix}.classification is invalid`);
|
|
342
|
+
}
|
|
343
|
+
for (const field of ["agent", "script", "fileBroker"]) {
|
|
344
|
+
const evidence = cell[field];
|
|
345
|
+
if (!evidence || typeof evidence !== "object") {
|
|
346
|
+
errors.push(`${prefix}.${field} must be an evidence object`);
|
|
347
|
+
continue;
|
|
348
|
+
}
|
|
349
|
+
const evidenceKeys = Object.keys(evidence).filter((key) => !["path", "sha256"].includes(key));
|
|
350
|
+
if (evidenceKeys.length > 0)
|
|
351
|
+
errors.push(`${prefix}.${field} has unsupported fields: ${evidenceKeys.join(", ")}`);
|
|
352
|
+
if (!isNonEmptyString(evidence.path) || evidence.path.startsWith("/") || evidence.path.includes("..")) {
|
|
353
|
+
errors.push(`${prefix}.${field}.path must be a safe repository-relative path`);
|
|
354
|
+
}
|
|
355
|
+
if (!SHA256_RE.test(evidence.sha256))
|
|
356
|
+
errors.push(`${prefix}.${field}.sha256 must be lowercase sha256`);
|
|
357
|
+
}
|
|
358
|
+
if (!cell.decision || typeof cell.decision !== "object") {
|
|
359
|
+
errors.push(`${prefix}.decision must be an object`);
|
|
360
|
+
}
|
|
361
|
+
else {
|
|
362
|
+
const decisionKeys = Object.keys(cell.decision).filter((key) => !["owner", "status", "reason"].includes(key));
|
|
363
|
+
if (decisionKeys.length > 0)
|
|
364
|
+
errors.push(`${prefix}.decision has unsupported fields: ${decisionKeys.join(", ")}`);
|
|
365
|
+
if (!isNonEmptyString(cell.decision.owner))
|
|
366
|
+
errors.push(`${prefix}.decision.owner must be non-empty`);
|
|
367
|
+
if (!isNonEmptyString(cell.decision.reason))
|
|
368
|
+
errors.push(`${prefix}.decision.reason must be non-empty`);
|
|
369
|
+
if (cell.decision.status !== "approved" && cell.decision.status !== "rejected") {
|
|
370
|
+
errors.push(`${prefix}.decision.status is invalid`);
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
});
|
|
374
|
+
return errors;
|
|
375
|
+
}
|
|
376
|
+
/** Load and verify the checked-in finite allowlist plus every evidence body it
|
|
377
|
+
* relies on. Matcher authorization accepts only the process-local branded
|
|
378
|
+
* snapshot returned here; shape-correct caller data is never authority. */
|
|
379
|
+
export function loadVerifiedHostSupportBaseline(options) {
|
|
380
|
+
const repositoryRoot = fs.realpathSync(options.repositoryRoot);
|
|
381
|
+
if (!fs.statSync(repositoryRoot).isDirectory())
|
|
382
|
+
throw new Error("repositoryRoot must be a directory");
|
|
383
|
+
const maxBytes = options.maxEvidenceBytes ?? 5 * 1024 * 1024;
|
|
384
|
+
if (!Number.isSafeInteger(maxBytes) || maxBytes < 1)
|
|
385
|
+
throw new Error("maxEvidenceBytes must be a positive safe integer");
|
|
386
|
+
const baselinePath = options.baselinePath ?? "conformance/workspace/host-support-baseline.json";
|
|
387
|
+
const raw = readTrustedJson(repositoryRoot, baselinePath, maxBytes).value;
|
|
388
|
+
const errors = validateHostSupportBaseline(raw);
|
|
389
|
+
if (errors.length > 0)
|
|
390
|
+
throw new Error(`invalid host support baseline: ${errors.join("; ")}`);
|
|
391
|
+
const snapshot = structuredClone(raw);
|
|
392
|
+
const evidenceCache = new Map();
|
|
393
|
+
for (const cell of snapshot.cells) {
|
|
394
|
+
const requirePass = cell.decision.status === "approved" &&
|
|
395
|
+
(cell.classification === "sandboxed-single-root" || cell.classification === "sandboxed-multi-root");
|
|
396
|
+
for (const kind of ["agent", "script", "fileBroker"]) {
|
|
397
|
+
const evidence = cell[kind];
|
|
398
|
+
let trusted = evidenceCache.get(evidence.path);
|
|
399
|
+
if (!trusted) {
|
|
400
|
+
trusted = readTrustedJson(repositoryRoot, evidence.path, maxBytes);
|
|
401
|
+
evidenceCache.set(evidence.path, trusted);
|
|
402
|
+
}
|
|
403
|
+
if (sha256Bytes(trusted.bytes) !== evidence.sha256) {
|
|
404
|
+
throw new Error(`${kind} evidence sha256 mismatch for ${evidence.path}`);
|
|
405
|
+
}
|
|
406
|
+
verifyEvidenceDocument(trusted.value, cell, kind, requirePass);
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
const verified = deepFreeze(snapshot);
|
|
410
|
+
verifiedBaselines.add(verified);
|
|
411
|
+
return verified;
|
|
412
|
+
}
|
|
413
|
+
/**
|
|
414
|
+
* Match a live target against the finite approved evidence set.
|
|
415
|
+
*
|
|
416
|
+
* Only a sandboxed classification with an approved owner decision is a match.
|
|
417
|
+
* Resolve-only/unsupported cells remain useful audit evidence but never enable
|
|
418
|
+
* a sandboxed bridge.
|
|
419
|
+
*/
|
|
420
|
+
export function matchSandboxedHostTarget(baseline, target) {
|
|
421
|
+
if (!verifiedBaselines.has(baseline)) {
|
|
422
|
+
return { ok: false, reason: "host support baseline was not loaded and evidence-verified by the trusted loader" };
|
|
423
|
+
}
|
|
424
|
+
const errors = validateHostSupportBaseline(baseline);
|
|
425
|
+
if (errors.length)
|
|
426
|
+
return { ok: false, reason: `invalid host support baseline: ${errors.join("; ")}` };
|
|
427
|
+
const cell = baseline.cells.find((candidate) => targetKey(candidate.target) === targetKey(target));
|
|
428
|
+
if (!cell)
|
|
429
|
+
return { ok: false, reason: "no exact host/OS/architecture/binary evidence cell" };
|
|
430
|
+
if (cell.decision.status !== "approved")
|
|
431
|
+
return { ok: false, reason: `evidence cell is ${cell.decision.status}` };
|
|
432
|
+
if (cell.classification !== "sandboxed-single-root" && cell.classification !== "sandboxed-multi-root") {
|
|
433
|
+
return { ok: false, reason: `evidence cell is classified ${cell.classification}` };
|
|
434
|
+
}
|
|
435
|
+
const approval = deepFreeze({
|
|
436
|
+
baselineId: baseline.baselineId,
|
|
437
|
+
target: structuredClone(cell.target),
|
|
438
|
+
classification: cell.classification,
|
|
439
|
+
});
|
|
440
|
+
verifiedSandboxApprovals.add(approval);
|
|
441
|
+
return { ok: true, cell, approval };
|
|
442
|
+
}
|
|
443
|
+
/** Shape-correct, cloned, or deserialized approval objects are not authority. */
|
|
444
|
+
export function isVerifiedSandboxHostApproval(value) {
|
|
445
|
+
return typeof value === "object" && value !== null && verifiedSandboxApprovals.has(value);
|
|
446
|
+
}
|
|
447
|
+
//# sourceMappingURL=baseline.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"baseline.js","sourceRoot":"","sources":["../../src/resources/baseline.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RFC 8785 / JSON Canonicalization Scheme serializer for JSON-domain values.
|
|
3
|
+
* It intentionally rejects values which JSON would silently coerce or discard.
|
|
4
|
+
*/
|
|
5
|
+
export declare function canonicalJson(value: unknown): string;
|
|
6
|
+
export declare function sha256Canonical(value: unknown): string;
|
|
7
|
+
//# sourceMappingURL=canonical-json.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"canonical-json.d.ts","sourceRoot":"","sources":["../../src/resources/canonical-json.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAgDpD;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAEtD"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
/**
|
|
3
|
+
* RFC 8785 / JSON Canonicalization Scheme serializer for JSON-domain values.
|
|
4
|
+
* It intentionally rejects values which JSON would silently coerce or discard.
|
|
5
|
+
*/
|
|
6
|
+
export function canonicalJson(value) {
|
|
7
|
+
const ancestors = new Set();
|
|
8
|
+
function encode(current) {
|
|
9
|
+
if (current === null)
|
|
10
|
+
return "null";
|
|
11
|
+
if (typeof current === "boolean")
|
|
12
|
+
return current ? "true" : "false";
|
|
13
|
+
if (typeof current === "string") {
|
|
14
|
+
assertUnicodeScalarString(current);
|
|
15
|
+
return JSON.stringify(current);
|
|
16
|
+
}
|
|
17
|
+
if (typeof current === "number") {
|
|
18
|
+
if (!Number.isFinite(current))
|
|
19
|
+
throw new TypeError("canonical JSON requires finite numbers");
|
|
20
|
+
return JSON.stringify(current);
|
|
21
|
+
}
|
|
22
|
+
if (typeof current !== "object") {
|
|
23
|
+
throw new TypeError(`canonical JSON cannot encode ${typeof current}`);
|
|
24
|
+
}
|
|
25
|
+
if (ancestors.has(current))
|
|
26
|
+
throw new TypeError("canonical JSON cannot encode cycles");
|
|
27
|
+
ancestors.add(current);
|
|
28
|
+
try {
|
|
29
|
+
if (Array.isArray(current)) {
|
|
30
|
+
const items = [];
|
|
31
|
+
for (let index = 0; index < current.length; index++) {
|
|
32
|
+
if (!Object.hasOwn(current, index)) {
|
|
33
|
+
throw new TypeError("canonical JSON cannot encode sparse arrays");
|
|
34
|
+
}
|
|
35
|
+
items.push(encode(current[index]));
|
|
36
|
+
}
|
|
37
|
+
return `[${items.join(",")}]`;
|
|
38
|
+
}
|
|
39
|
+
const prototype = Object.getPrototypeOf(current);
|
|
40
|
+
if (prototype !== Object.prototype && prototype !== null) {
|
|
41
|
+
throw new TypeError("canonical JSON requires plain objects");
|
|
42
|
+
}
|
|
43
|
+
const record = current;
|
|
44
|
+
const keys = Object.keys(record).sort();
|
|
45
|
+
const fields = keys.map((key) => {
|
|
46
|
+
assertUnicodeScalarString(key);
|
|
47
|
+
return `${JSON.stringify(key)}:${encode(record[key])}`;
|
|
48
|
+
});
|
|
49
|
+
return `{${fields.join(",")}}`;
|
|
50
|
+
}
|
|
51
|
+
finally {
|
|
52
|
+
ancestors.delete(current);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return encode(value);
|
|
56
|
+
}
|
|
57
|
+
export function sha256Canonical(value) {
|
|
58
|
+
return createHash("sha256").update(canonicalJson(value), "utf8").digest("hex");
|
|
59
|
+
}
|
|
60
|
+
function assertUnicodeScalarString(value) {
|
|
61
|
+
for (let index = 0; index < value.length; index++) {
|
|
62
|
+
const unit = value.charCodeAt(index);
|
|
63
|
+
if (unit >= 0xd800 && unit <= 0xdbff) {
|
|
64
|
+
const next = value.charCodeAt(index + 1);
|
|
65
|
+
if (!(next >= 0xdc00 && next <= 0xdfff)) {
|
|
66
|
+
throw new TypeError("canonical JSON rejects lone UTF-16 surrogates");
|
|
67
|
+
}
|
|
68
|
+
index++;
|
|
69
|
+
}
|
|
70
|
+
else if (unit >= 0xdc00 && unit <= 0xdfff) {
|
|
71
|
+
throw new TypeError("canonical JSON rejects lone UTF-16 surrogates");
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=canonical-json.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"canonical-json.js","sourceRoot":"","sources":["../../src/resources/canonical-json.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,KAAc;IAC3C,MAAM,SAAS,GAAG,IAAI,GAAG,EAAU,CAAC;IAEpC,SAAS,MAAM,CAAC,OAAgB;QAC/B,IAAI,OAAO,KAAK,IAAI;YAAE,OAAO,MAAM,CAAC;QACpC,IAAI,OAAO,OAAO,KAAK,SAAS;YAAE,OAAO,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC;QACpE,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;YACjC,yBAAyB,CAAC,OAAO,CAAC,CAAC;YACnC,OAAO,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;QAChC,CAAC;QACD,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;YACjC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC;gBAAE,MAAM,IAAI,SAAS,CAAC,wCAAwC,CAAC,CAAC;YAC7F,OAAO,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;QAChC,CAAC;QACD,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;YACjC,MAAM,IAAI,SAAS,CAAC,gCAAgC,OAAO,OAAO,EAAE,CAAC,CAAC;QACvE,CAAC;QACD,IAAI,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC;YAAE,MAAM,IAAI,SAAS,CAAC,qCAAqC,CAAC,CAAC;QACvF,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACvB,IAAI,CAAC;YACJ,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;gBAC5B,MAAM,KAAK,GAAa,EAAE,CAAC;gBAC3B,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,OAAO,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC;oBACrD,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,KAAK,CAAC,EAAE,CAAC;wBACpC,MAAM,IAAI,SAAS,CAAC,4CAA4C,CAAC,CAAC;oBACnE,CAAC;oBACD,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;gBACpC,CAAC;gBACD,OAAO,IAAI,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;YAC/B,CAAC;YAED,MAAM,SAAS,GAAG,MAAM,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;YACjD,IAAI,SAAS,KAAK,MAAM,CAAC,SAAS,IAAI,SAAS,KAAK,IAAI,EAAE,CAAC;gBAC1D,MAAM,IAAI,SAAS,CAAC,uCAAuC,CAAC,CAAC;YAC9D,CAAC;YACD,MAAM,MAAM,GAAG,OAAkC,CAAC;YAClD,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC;YACxC,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;gBAC/B,yBAAyB,CAAC,GAAG,CAAC,CAAC;gBAC/B,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;YACxD,CAAC,CAAC,CAAC;YACH,OAAO,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;QAChC,CAAC;gBAAS,CAAC;YACV,SAAS,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAC3B,CAAC;IACF,CAAC;IAED,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;AACtB,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,KAAc;IAC7C,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAChF,CAAC;AAED,SAAS,yBAAyB,CAAC,KAAa;IAC/C,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,KAAK,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC;QACnD,MAAM,IAAI,GAAG,KAAK,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;QACrC,IAAI,IAAI,IAAI,MAAM,IAAI,IAAI,IAAI,MAAM,EAAE,CAAC;YACtC,MAAM,IAAI,GAAG,KAAK,CAAC,UAAU,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;YACzC,IAAI,CAAC,CAAC,IAAI,IAAI,MAAM,IAAI,IAAI,IAAI,MAAM,CAAC,EAAE,CAAC;gBACzC,MAAM,IAAI,SAAS,CAAC,+CAA+C,CAAC,CAAC;YACtE,CAAC;YACD,KAAK,EAAE,CAAC;QACT,CAAC;aAAM,IAAI,IAAI,IAAI,MAAM,IAAI,IAAI,IAAI,MAAM,EAAE,CAAC;YAC7C,MAAM,IAAI,SAAS,CAAC,+CAA+C,CAAC,CAAC;QACtE,CAAC;IACF,CAAC;AACF,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/** Stable, redaction-safe failures emitted by the workspace capability plane. */
|
|
2
|
+
export declare const WORKSPACE_ERROR_CODES: readonly ["TFWS_UNAUTHORIZED_GRANT", "TFWS_UNKNOWN_WORKSPACE", "TFWS_INVALID_PATH", "TFWS_PATH_ESCAPE", "TFWS_ACCESS_ESCALATION", "TFWS_CREDENTIAL_DENIED", "TFWS_PROVIDER_DENIED", "TFWS_PROVIDER_ACQUIRE_FAILED", "TFWS_PROVIDER_RELEASE_FAILED", "TFWS_UNSUPPORTED_SANDBOX_POLICY", "TFWS_LEASE_TIMEOUT", "TFWS_WRITE_INTENT_FAILED", "TFWS_RESOURCE_DIRTY", "TFWS_VERSION_COMMIT_UNAVAILABLE", "TFWS_CACHE_RESTORE_RACE", "TFWS_STATE_RESTORE_FAILED", "TFWS_IDENTITY_MISMATCH", "TFWS_HANDLE_INVALID", "TFWS_SELECTOR_INVALID"];
|
|
3
|
+
export type WorkspaceErrorCode = (typeof WORKSPACE_ERROR_CODES)[number];
|
|
4
|
+
export type WorkspaceErrorScope = "phase" | "run";
|
|
5
|
+
export type WorkspaceRetryScope = "none" | "same-attempt" | "new-attempt" | "after-reconcile" | "new-run";
|
|
6
|
+
export type WorkspaceRecovery = "none" | "cleanup" | "reconcile" | "rebind";
|
|
7
|
+
export interface WorkspacePolicyError {
|
|
8
|
+
code: WorkspaceErrorCode;
|
|
9
|
+
scope: WorkspaceErrorScope;
|
|
10
|
+
retryable: boolean;
|
|
11
|
+
terminal: boolean;
|
|
12
|
+
retryScope: WorkspaceRetryScope;
|
|
13
|
+
affectedResourceDomainIds?: string[];
|
|
14
|
+
recoveryRequired?: WorkspaceRecovery;
|
|
15
|
+
phaseId?: string;
|
|
16
|
+
logicalWorkspaceId?: string;
|
|
17
|
+
/** Must never contain a physical root. */
|
|
18
|
+
redactedMessage: string;
|
|
19
|
+
}
|
|
20
|
+
export type WorkspacePolicyErrorOverrides = Partial<Omit<WorkspacePolicyError, "code" | "redactedMessage">>;
|
|
21
|
+
export declare function workspacePolicyError(code: WorkspaceErrorCode, redactedMessage: string, overrides?: WorkspacePolicyErrorOverrides): WorkspacePolicyError;
|
|
22
|
+
export declare function isWorkspacePolicyError(value: unknown): value is WorkspacePolicyError;
|
|
23
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/resources/errors.ts"],"names":[],"mappings":"AAAA,iFAAiF;AAEjF,eAAO,MAAM,qBAAqB,YACjC,yBAAyB,EACzB,wBAAwB,EACxB,mBAAmB,EACnB,kBAAkB,EAClB,wBAAwB,EACxB,wBAAwB,EACxB,sBAAsB,EACtB,8BAA8B,EAC9B,8BAA8B,EAC9B,iCAAiC,EACjC,oBAAoB,EACpB,0BAA0B,EAC1B,qBAAqB,EACrB,iCAAiC,EACjC,yBAAyB,EACzB,2BAA2B,EAC3B,wBAAwB,EACxB,qBAAqB,EACrB,uBAAuB,CACd,CAAC;AAEX,MAAM,MAAM,kBAAkB,GAAG,CAAC,OAAO,qBAAqB,CAAC,CAAC,MAAM,CAAC,CAAC;AACxE,MAAM,MAAM,mBAAmB,GAAG,OAAO,GAAG,KAAK,CAAC;AAClD,MAAM,MAAM,mBAAmB,GAAG,MAAM,GAAG,cAAc,GAAG,aAAa,GAAG,iBAAiB,GAAG,SAAS,CAAC;AAC1G,MAAM,MAAM,iBAAiB,GAAG,MAAM,GAAG,SAAS,GAAG,WAAW,GAAG,QAAQ,CAAC;AAE5E,MAAM,WAAW,oBAAoB;IACpC,IAAI,EAAE,kBAAkB,CAAC;IACzB,KAAK,EAAE,mBAAmB,CAAC;IAC3B,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,OAAO,CAAC;IAClB,UAAU,EAAE,mBAAmB,CAAC;IAChC,yBAAyB,CAAC,EAAE,MAAM,EAAE,CAAC;IACrC,gBAAgB,CAAC,EAAE,iBAAiB,CAAC;IACrC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,0CAA0C;IAC1C,eAAe,EAAE,MAAM,CAAC;CACxB;AA8DD,MAAM,MAAM,6BAA6B,GAAG,OAAO,CAAC,IAAI,CAAC,oBAAoB,EAAE,MAAM,GAAG,iBAAiB,CAAC,CAAC,CAAC;AAE5G,wBAAgB,oBAAoB,CACnC,IAAI,EAAE,kBAAkB,EACxB,eAAe,EAAE,MAAM,EACvB,SAAS,GAAE,6BAAkC,GAC3C,oBAAoB,CAEtB;AAED,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,oBAAoB,CAYpF"}
|