@descryy/runtime-controller 0.0.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/dist/capability-registry.d.ts +24 -0
- package/dist/capability-registry.d.ts.map +1 -0
- package/dist/capability-registry.js +42 -0
- package/dist/capability-registry.js.map +1 -0
- package/dist/collector-version.d.ts +10 -0
- package/dist/collector-version.d.ts.map +1 -0
- package/dist/collector-version.js +12 -0
- package/dist/collector-version.js.map +1 -0
- package/dist/container-sandbox.d.ts +188 -0
- package/dist/container-sandbox.d.ts.map +1 -0
- package/dist/container-sandbox.js +233 -0
- package/dist/container-sandbox.js.map +1 -0
- package/dist/controller.d.ts +162 -0
- package/dist/controller.d.ts.map +1 -0
- package/dist/controller.js +433 -0
- package/dist/controller.js.map +1 -0
- package/dist/dependency-version-check.d.ts +90 -0
- package/dist/dependency-version-check.d.ts.map +1 -0
- package/dist/dependency-version-check.js +121 -0
- package/dist/dependency-version-check.js.map +1 -0
- package/dist/env.d.ts +16 -0
- package/dist/env.d.ts.map +1 -0
- package/dist/env.js +18 -0
- package/dist/env.js.map +1 -0
- package/dist/environment-metadata.d.ts +23 -0
- package/dist/environment-metadata.d.ts.map +1 -0
- package/dist/environment-metadata.js +80 -0
- package/dist/environment-metadata.js.map +1 -0
- package/dist/environment-version-check.d.ts +83 -0
- package/dist/environment-version-check.d.ts.map +1 -0
- package/dist/environment-version-check.js +218 -0
- package/dist/environment-version-check.js.map +1 -0
- package/dist/execution-safety.d.ts +154 -0
- package/dist/execution-safety.d.ts.map +1 -0
- package/dist/execution-safety.js +194 -0
- package/dist/execution-safety.js.map +1 -0
- package/dist/index.d.ts +35 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +14 -0
- package/dist/index.js.map +1 -0
- package/dist/orchestration.d.ts +70 -0
- package/dist/orchestration.d.ts.map +1 -0
- package/dist/orchestration.js +255 -0
- package/dist/orchestration.js.map +1 -0
- package/dist/process-collector.d.ts +34 -0
- package/dist/process-collector.d.ts.map +1 -0
- package/dist/process-collector.js +148 -0
- package/dist/process-collector.js.map +1 -0
- package/dist/process-manager.d.ts +133 -0
- package/dist/process-manager.d.ts.map +1 -0
- package/dist/process-manager.js +333 -0
- package/dist/process-manager.js.map +1 -0
- package/dist/readiness.d.ts +120 -0
- package/dist/readiness.d.ts.map +1 -0
- package/dist/readiness.js +179 -0
- package/dist/readiness.js.map +1 -0
- package/dist/sandbox.d.ts +139 -0
- package/dist/sandbox.d.ts.map +1 -0
- package/dist/sandbox.js +271 -0
- package/dist/sandbox.js.map +1 -0
- package/package.json +29 -0
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `DEC-NEXT-fault-layer-empirical-confirmation.md`'s `environment`
|
|
3
|
+
* mechanism: "declared/expected runner version (CI config) vs. observed
|
|
4
|
+
* runner version at execution." Same shape as `dependency-version-check.ts`'s
|
|
5
|
+
* comparison -- cheap, always available, no rerun needed.
|
|
6
|
+
*
|
|
7
|
+
* ## "Declared" is the project's own `.nvmrc`/`engines.node`, not a
|
|
8
|
+
* CI-workflow parser
|
|
9
|
+
*
|
|
10
|
+
* The ruling names "a CI config's pinned Node/language version" as one
|
|
11
|
+
* example of what "declared" can mean, not the only one -- its actual
|
|
12
|
+
* requirement is "whatever 'declared environment' already means elsewhere
|
|
13
|
+
* in this repo," checked directly rather than assumed (`environment-profile`
|
|
14
|
+
* turned out to mean something else entirely: DEC-270's safety level and
|
|
15
|
+
* credentials, not a version declaration). Nothing in this repo already
|
|
16
|
+
* parses a CI workflow file, and doing so first here would mean writing a
|
|
17
|
+
* YAML parser (or a regex sketch of one) for a signal that is, in every
|
|
18
|
+
* real Node project, already restated in `package.json` -- `.nvmrc` and
|
|
19
|
+
* `engines.node` are the actual, load-bearing declarations `nvm`/`npm`
|
|
20
|
+
* themselves read, checked directly against this repo's own root
|
|
21
|
+
* `package.json` (`engines: { node: ">=22.5" }`) and every fixture app
|
|
22
|
+
* under `fixture-apps/`, which all carry the same field. A future CI-file
|
|
23
|
+
* reader is a real, disclosed extension point, not a silent omission --
|
|
24
|
+
* this function's `declaredSource` is a closed union specifically so a
|
|
25
|
+
* third source can be added later without changing the shape callers
|
|
26
|
+
* already read.
|
|
27
|
+
*
|
|
28
|
+
* ## `satisfiesDeclaredNodeVersion`'s grammar is a real, narrower subset
|
|
29
|
+
*
|
|
30
|
+
* Supports `^x.y.z`, `~x.y.z`, `>=`/`<=`/`>`/`<` clauses, a bare version at
|
|
31
|
+
* any precision (`"20"`, `"20.11"`, `"20.11.5"`, each an x-range at that
|
|
32
|
+
* precision -- `"20"` means "any 20.x.y", matching what `actions/setup-node`
|
|
33
|
+
* itself does for a bare major), and space-separated AND clauses
|
|
34
|
+
* (`">=20.0.0 <21.0.0"`), npm's own shape for a bounded range. Does **not**
|
|
35
|
+
* support `||` (OR), hyphen ranges (`"1.2.3 - 2.3.4"`), prerelease/build
|
|
36
|
+
* tags, or the `x`/`*` wildcard tokens (`"20.x"`) -- an input using any of
|
|
37
|
+
* those parses to `null` ("cannot say") rather than a silently wrong
|
|
38
|
+
* true/false, the same "disclosed narrower scope, not a guess" pattern this
|
|
39
|
+
* repo already applies to `EnvironmentMetadata.toolchainVersions`' `null`
|
|
40
|
+
* entries.
|
|
41
|
+
*/
|
|
42
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
43
|
+
import { join } from "node:path";
|
|
44
|
+
export const DECLARED_VERSION_SOURCES = ["nvmrc", "package.json engines.node"];
|
|
45
|
+
/**
|
|
46
|
+
* Reads the declared Node version for the project rooted at `cwd` and
|
|
47
|
+
* compares it against `observedVersion` (the real, already-known runtime
|
|
48
|
+
* value -- `process.version`, or `EnvironmentMetadata.nodeVersion`, the same
|
|
49
|
+
* "always known, never probed" value this repo already captures elsewhere;
|
|
50
|
+
* this function never probes for it itself).
|
|
51
|
+
*
|
|
52
|
+
* `.nvmrc` takes precedence over `package.json engines.node` when both are
|
|
53
|
+
* present -- `.nvmrc` names one exact intended version a developer actually
|
|
54
|
+
* runs locally; `engines.node` is more often a permissive range meant to
|
|
55
|
+
* describe compatibility rather than pin a single runtime. The narrower,
|
|
56
|
+
* more specific declaration wins, the same precedence
|
|
57
|
+
* `classifyFaultLayer` (`descry-core`) already applies between `dependency`
|
|
58
|
+
* and `environment` themselves ("the narrower, more specific structural
|
|
59
|
+
* fact... is checked first").
|
|
60
|
+
*/
|
|
61
|
+
export function checkEnvironmentVersion(cwd, observedVersion) {
|
|
62
|
+
const notApplicable = {
|
|
63
|
+
applicable: false,
|
|
64
|
+
mismatch: false,
|
|
65
|
+
declaredVersion: null,
|
|
66
|
+
declaredSource: null,
|
|
67
|
+
observedVersion,
|
|
68
|
+
};
|
|
69
|
+
const nvmrcPath = join(cwd, ".nvmrc");
|
|
70
|
+
let declaredVersion = null;
|
|
71
|
+
let declaredSource = null;
|
|
72
|
+
if (existsSync(nvmrcPath)) {
|
|
73
|
+
const raw = readFileSync(nvmrcPath, "utf8").trim();
|
|
74
|
+
if (raw.length > 0) {
|
|
75
|
+
declaredVersion = raw;
|
|
76
|
+
declaredSource = "nvmrc";
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
const packageJsonPath = join(cwd, "package.json");
|
|
81
|
+
if (existsSync(packageJsonPath)) {
|
|
82
|
+
let parsed;
|
|
83
|
+
try {
|
|
84
|
+
parsed = JSON.parse(readFileSync(packageJsonPath, "utf8"));
|
|
85
|
+
}
|
|
86
|
+
catch {
|
|
87
|
+
parsed = null;
|
|
88
|
+
}
|
|
89
|
+
const node = parsed?.engines?.node;
|
|
90
|
+
if (typeof node === "string" && node.trim().length > 0) {
|
|
91
|
+
declaredVersion = node;
|
|
92
|
+
declaredSource = "package.json engines.node";
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
if (declaredVersion === null || declaredSource === null) {
|
|
97
|
+
return notApplicable;
|
|
98
|
+
}
|
|
99
|
+
const satisfies = satisfiesDeclaredNodeVersion(declaredVersion, observedVersion);
|
|
100
|
+
if (satisfies === null) {
|
|
101
|
+
// Declared with a grammar this reader does not cover (or the observed
|
|
102
|
+
// string was not parseable), so honestly "not applicable" rather than
|
|
103
|
+
// implying a comparison was actually made -- see this module's header.
|
|
104
|
+
return { applicable: false, mismatch: false, declaredVersion, declaredSource, observedVersion };
|
|
105
|
+
}
|
|
106
|
+
return { applicable: true, mismatch: !satisfies, declaredVersion, declaredSource, observedVersion };
|
|
107
|
+
}
|
|
108
|
+
const VERSION_PATTERN = /^v?(\d+)(?:\.(\d+))?(?:\.(\d+))?/;
|
|
109
|
+
function parseVersion(raw) {
|
|
110
|
+
const match = VERSION_PATTERN.exec(raw.trim());
|
|
111
|
+
if (match === null)
|
|
112
|
+
return null;
|
|
113
|
+
const major = Number(match[1]);
|
|
114
|
+
if (!Number.isFinite(major))
|
|
115
|
+
return null;
|
|
116
|
+
return {
|
|
117
|
+
major,
|
|
118
|
+
minor: match[2] !== undefined ? Number(match[2]) : 0,
|
|
119
|
+
minorSpecified: match[2] !== undefined,
|
|
120
|
+
patch: match[3] !== undefined ? Number(match[3]) : 0,
|
|
121
|
+
patchSpecified: match[3] !== undefined,
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
/** Positive when `a` > `b`, negative when `a` < `b`, zero when equal -- major.minor.patch only. */
|
|
125
|
+
function compareVersions(a, b) {
|
|
126
|
+
if (a.major !== b.major)
|
|
127
|
+
return a.major - b.major;
|
|
128
|
+
if (a.minor !== b.minor)
|
|
129
|
+
return a.minor - b.minor;
|
|
130
|
+
return a.patch - b.patch;
|
|
131
|
+
}
|
|
132
|
+
const CARET_PATTERN = /^\^(\d+)(?:\.(\d+))?(?:\.(\d+))?$/;
|
|
133
|
+
const TILDE_PATTERN = /^~(\d+)(?:\.(\d+))?(?:\.(\d+))?$/;
|
|
134
|
+
const COMPARATOR_PATTERN = /^(>=|<=|>|<|=)?(\d+)(?:\.(\d+))?(?:\.(\d+))?$/;
|
|
135
|
+
/**
|
|
136
|
+
* `null` means "this clause's grammar is not one of the ones documented in
|
|
137
|
+
* this module's header" -- propagated up as `null`, never coerced to a
|
|
138
|
+
* guessed `true`/`false`.
|
|
139
|
+
*/
|
|
140
|
+
function satisfiesClause(clause, observed) {
|
|
141
|
+
const trimmed = clause.trim();
|
|
142
|
+
if (trimmed.length === 0)
|
|
143
|
+
return null;
|
|
144
|
+
const caret = CARET_PATTERN.exec(trimmed);
|
|
145
|
+
if (caret !== null) {
|
|
146
|
+
const base = {
|
|
147
|
+
major: Number(caret[1]),
|
|
148
|
+
minor: caret[2] !== undefined ? Number(caret[2]) : 0,
|
|
149
|
+
minorSpecified: true,
|
|
150
|
+
patch: caret[3] !== undefined ? Number(caret[3]) : 0,
|
|
151
|
+
patchSpecified: true,
|
|
152
|
+
};
|
|
153
|
+
return compareVersions(observed, base) >= 0 && observed.major === base.major;
|
|
154
|
+
}
|
|
155
|
+
const tilde = TILDE_PATTERN.exec(trimmed);
|
|
156
|
+
if (tilde !== null) {
|
|
157
|
+
const base = {
|
|
158
|
+
major: Number(tilde[1]),
|
|
159
|
+
minor: tilde[2] !== undefined ? Number(tilde[2]) : 0,
|
|
160
|
+
minorSpecified: true,
|
|
161
|
+
patch: tilde[3] !== undefined ? Number(tilde[3]) : 0,
|
|
162
|
+
patchSpecified: true,
|
|
163
|
+
};
|
|
164
|
+
return compareVersions(observed, base) >= 0 && observed.major === base.major && observed.minor === base.minor;
|
|
165
|
+
}
|
|
166
|
+
const comparator = COMPARATOR_PATTERN.exec(trimmed);
|
|
167
|
+
if (comparator === null)
|
|
168
|
+
return null;
|
|
169
|
+
const op = comparator[1];
|
|
170
|
+
const base = {
|
|
171
|
+
major: Number(comparator[2]),
|
|
172
|
+
minor: comparator[3] !== undefined ? Number(comparator[3]) : 0,
|
|
173
|
+
minorSpecified: comparator[3] !== undefined,
|
|
174
|
+
patch: comparator[4] !== undefined ? Number(comparator[4]) : 0,
|
|
175
|
+
patchSpecified: comparator[4] !== undefined,
|
|
176
|
+
};
|
|
177
|
+
const cmp = compareVersions(observed, base);
|
|
178
|
+
switch (op) {
|
|
179
|
+
case ">=":
|
|
180
|
+
return cmp >= 0;
|
|
181
|
+
case "<=":
|
|
182
|
+
return cmp <= 0;
|
|
183
|
+
case ">":
|
|
184
|
+
return cmp > 0;
|
|
185
|
+
case "<":
|
|
186
|
+
return cmp < 0;
|
|
187
|
+
case "=":
|
|
188
|
+
case undefined:
|
|
189
|
+
// Bare version: an x-range at whatever precision was actually given.
|
|
190
|
+
if (!base.minorSpecified)
|
|
191
|
+
return observed.major === base.major;
|
|
192
|
+
if (!base.patchSpecified)
|
|
193
|
+
return observed.major === base.major && observed.minor === base.minor;
|
|
194
|
+
return cmp === 0;
|
|
195
|
+
default:
|
|
196
|
+
return null;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Whether `observedVersion` satisfies `declaredRange` under the grammar
|
|
201
|
+
* documented in this module's header. `null` means the comparison could not
|
|
202
|
+
* be made at all (either string used a construct this reader does not
|
|
203
|
+
* cover) -- distinct from `false`, which is a real, positive "does not
|
|
204
|
+
* satisfy" answer.
|
|
205
|
+
*/
|
|
206
|
+
export function satisfiesDeclaredNodeVersion(declaredRange, observedVersion) {
|
|
207
|
+
const observed = parseVersion(observedVersion);
|
|
208
|
+
if (observed === null)
|
|
209
|
+
return null;
|
|
210
|
+
const clauses = declaredRange.split(/\s+/).filter((clause) => clause.length > 0);
|
|
211
|
+
if (clauses.length === 0)
|
|
212
|
+
return null;
|
|
213
|
+
const results = clauses.map((clause) => satisfiesClause(clause, observed));
|
|
214
|
+
if (results.some((result) => result === null))
|
|
215
|
+
return null;
|
|
216
|
+
return results.every((result) => result === true);
|
|
217
|
+
}
|
|
218
|
+
//# sourceMappingURL=environment-version-check.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"environment-version-check.js","sourceRoot":"","sources":["../src/environment-version-check.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AAEH,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,OAAO,EAAE,2BAA2B,CAAU,CAAC;AAsBxF;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,uBAAuB,CAAC,GAAW,EAAE,eAAuB;IAC1E,MAAM,aAAa,GAAkC;QACnD,UAAU,EAAE,KAAK;QACjB,QAAQ,EAAE,KAAK;QACf,eAAe,EAAE,IAAI;QACrB,cAAc,EAAE,IAAI;QACpB,eAAe;KAChB,CAAC;IAEF,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;IACtC,IAAI,eAAe,GAAkB,IAAI,CAAC;IAC1C,IAAI,cAAc,GAAiC,IAAI,CAAC;IAExD,IAAI,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAC1B,MAAM,GAAG,GAAG,YAAY,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC;QACnD,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACnB,eAAe,GAAG,GAAG,CAAC;YACtB,cAAc,GAAG,OAAO,CAAC;QAC3B,CAAC;IACH,CAAC;SAAM,CAAC;QACN,MAAM,eAAe,GAAG,IAAI,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC;QAClD,IAAI,UAAU,CAAC,eAAe,CAAC,EAAE,CAAC;YAChC,IAAI,MAA2B,CAAC;YAChC,IAAI,CAAC;gBACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,eAAe,EAAE,MAAM,CAAC,CAAiB,CAAC;YAC7E,CAAC;YAAC,MAAM,CAAC;gBACP,MAAM,GAAG,IAAI,CAAC;YAChB,CAAC;YACD,MAAM,IAAI,GAAG,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC;YACnC,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACvD,eAAe,GAAG,IAAI,CAAC;gBACvB,cAAc,GAAG,2BAA2B,CAAC;YAC/C,CAAC;QACH,CAAC;IACH,CAAC;IAED,IAAI,eAAe,KAAK,IAAI,IAAI,cAAc,KAAK,IAAI,EAAE,CAAC;QACxD,OAAO,aAAa,CAAC;IACvB,CAAC;IAED,MAAM,SAAS,GAAG,4BAA4B,CAAC,eAAe,EAAE,eAAe,CAAC,CAAC;IACjF,IAAI,SAAS,KAAK,IAAI,EAAE,CAAC;QACvB,sEAAsE;QACtE,sEAAsE;QACtE,uEAAuE;QACvE,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,eAAe,EAAE,CAAC;IAClG,CAAC;IAED,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,SAAS,EAAE,eAAe,EAAE,cAAc,EAAE,eAAe,EAAE,CAAC;AACtG,CAAC;AAUD,MAAM,eAAe,GAAG,kCAAkC,CAAC;AAE3D,SAAS,YAAY,CAAC,GAAW;IAC/B,MAAM,KAAK,GAAG,eAAe,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC;IAC/C,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IAChC,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/B,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IACzC,OAAO;QACL,KAAK;QACL,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACpD,cAAc,EAAE,KAAK,CAAC,CAAC,CAAC,KAAK,SAAS;QACtC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACpD,cAAc,EAAE,KAAK,CAAC,CAAC,CAAC,KAAK,SAAS;KACvC,CAAC;AACJ,CAAC;AAED,mGAAmG;AACnG,SAAS,eAAe,CAAC,CAAgB,EAAE,CAAgB;IACzD,IAAI,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,KAAK;QAAE,OAAO,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC;IAClD,IAAI,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,KAAK;QAAE,OAAO,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC;IAClD,OAAO,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC;AAC3B,CAAC;AAED,MAAM,aAAa,GAAG,mCAAmC,CAAC;AAC1D,MAAM,aAAa,GAAG,kCAAkC,CAAC;AACzD,MAAM,kBAAkB,GAAG,+CAA+C,CAAC;AAE3E;;;;GAIG;AACH,SAAS,eAAe,CAAC,MAAc,EAAE,QAAuB;IAC9D,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC;IAC9B,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAEtC,MAAM,KAAK,GAAG,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC1C,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;QACnB,MAAM,IAAI,GAAkB;YAC1B,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YACvB,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YACpD,cAAc,EAAE,IAAI;YACpB,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YACpD,cAAc,EAAE,IAAI;SACrB,CAAC;QACF,OAAO,eAAe,CAAC,QAAQ,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,QAAQ,CAAC,KAAK,KAAK,IAAI,CAAC,KAAK,CAAC;IAC/E,CAAC;IAED,MAAM,KAAK,GAAG,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC1C,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;QACnB,MAAM,IAAI,GAAkB;YAC1B,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YACvB,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YACpD,cAAc,EAAE,IAAI;YACpB,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YACpD,cAAc,EAAE,IAAI;SACrB,CAAC;QACF,OAAO,eAAe,CAAC,QAAQ,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,QAAQ,CAAC,KAAK,KAAK,IAAI,CAAC,KAAK,IAAI,QAAQ,CAAC,KAAK,KAAK,IAAI,CAAC,KAAK,CAAC;IAChH,CAAC;IAED,MAAM,UAAU,GAAG,kBAAkB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACpD,IAAI,UAAU,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IAErC,MAAM,EAAE,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC;IACzB,MAAM,IAAI,GAAkB;QAC1B,KAAK,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;QAC5B,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC9D,cAAc,EAAE,UAAU,CAAC,CAAC,CAAC,KAAK,SAAS;QAC3C,KAAK,EAAE,UAAU,CAAC,CAAC,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC9D,cAAc,EAAE,UAAU,CAAC,CAAC,CAAC,KAAK,SAAS;KAC5C,CAAC;IACF,MAAM,GAAG,GAAG,eAAe,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IAE5C,QAAQ,EAAE,EAAE,CAAC;QACX,KAAK,IAAI;YACP,OAAO,GAAG,IAAI,CAAC,CAAC;QAClB,KAAK,IAAI;YACP,OAAO,GAAG,IAAI,CAAC,CAAC;QAClB,KAAK,GAAG;YACN,OAAO,GAAG,GAAG,CAAC,CAAC;QACjB,KAAK,GAAG;YACN,OAAO,GAAG,GAAG,CAAC,CAAC;QACjB,KAAK,GAAG,CAAC;QACT,KAAK,SAAS;YACZ,qEAAqE;YACrE,IAAI,CAAC,IAAI,CAAC,cAAc;gBAAE,OAAO,QAAQ,CAAC,KAAK,KAAK,IAAI,CAAC,KAAK,CAAC;YAC/D,IAAI,CAAC,IAAI,CAAC,cAAc;gBAAE,OAAO,QAAQ,CAAC,KAAK,KAAK,IAAI,CAAC,KAAK,IAAI,QAAQ,CAAC,KAAK,KAAK,IAAI,CAAC,KAAK,CAAC;YAChG,OAAO,GAAG,KAAK,CAAC,CAAC;QACnB;YACE,OAAO,IAAI,CAAC;IAChB,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,4BAA4B,CAAC,aAAqB,EAAE,eAAuB;IACzF,MAAM,QAAQ,GAAG,YAAY,CAAC,eAAe,CAAC,CAAC;IAC/C,IAAI,QAAQ,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IAEnC,MAAM,OAAO,GAAG,aAAa,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IACjF,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAEtC,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,eAAe,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC;IAC3E,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,KAAK,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IAC3D,OAAO,OAAO,CAAC,KAAK,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,KAAK,IAAI,CAAC,CAAC;AACpD,CAAC"}
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* §21's execution boundary (RT-070): resource limits and privilege
|
|
3
|
+
* reporting for a runtime whose declared mode is trusted-local (see
|
|
4
|
+
* DECISIONS.md RT-070) -- every spawned process runs with the invoking
|
|
5
|
+
* user's own OS privileges, no filesystem or network restriction. That
|
|
6
|
+
* declaration does not make unrestricted execution safe; it names the
|
|
7
|
+
* boundary instead of leaving it absent, which is what §38's "arbitrary
|
|
8
|
+
* application code runs without a defined safety boundary" actually bans.
|
|
9
|
+
* Real isolation (containers/namespaces) is a separate architectural
|
|
10
|
+
* decision this module does not invent (plan §29's own instruction).
|
|
11
|
+
*
|
|
12
|
+
* What this module DOES enforce, for real, via the OS: CPU time, virtual
|
|
13
|
+
* memory, and process count, through `prlimit` -- an exec wrapper, never a
|
|
14
|
+
* shell. Reintroducing `sh -c 'ulimit ...; exec ...'` to get these would
|
|
15
|
+
* undo RT-036's `tokenizeCommand` refusal of shell metacharacters. `prlimit`
|
|
16
|
+
* is util-linux and absent on macOS, so it is reported as a capability,
|
|
17
|
+
* never assumed.
|
|
18
|
+
*/
|
|
19
|
+
import type { CapabilityStatus, ResourceLimits } from "@descryy/runtime-contracts";
|
|
20
|
+
/**
|
|
21
|
+
* Whether `prlimit` is reachable on this platform's `PATH`. Takes `env` as
|
|
22
|
+
* a parameter (defaulting to `process.env`) rather than reading it
|
|
23
|
+
* internally so the "unavailable" branch is directly testable without
|
|
24
|
+
* mutating this process's own real environment or depending on running on
|
|
25
|
+
* a platform that genuinely lacks it.
|
|
26
|
+
*/
|
|
27
|
+
export declare function resourceLimitCapability(env?: NodeJS.ProcessEnv): CapabilityStatus;
|
|
28
|
+
/**
|
|
29
|
+
* RT-193 originally made this always `unavailable` -- no platform had any
|
|
30
|
+
* enforcement mechanism wired up. The sandbox-isolation lane changes that
|
|
31
|
+
* on Linux: `networkIsolationCapability()` (`./sandbox.ts`) is real, backed
|
|
32
|
+
* by a bwrap network namespace. This function is kept as the stable name
|
|
33
|
+
* every existing caller (`ExecutionController.run()`, this package's own
|
|
34
|
+
* tests) already imports, delegating rather than duplicating the check --
|
|
35
|
+
* exactly the seam RT-193's own comment anticipated ("if a real mechanism
|
|
36
|
+
* is ever built, this one function changes and every caller keeps working
|
|
37
|
+
* unmodified"). Still unconditionally `unavailable` on macOS/Windows, where
|
|
38
|
+
* nothing enforces it yet.
|
|
39
|
+
*/
|
|
40
|
+
export declare function networkPolicyCapability(env?: NodeJS.ProcessEnv): CapabilityStatus;
|
|
41
|
+
/**
|
|
42
|
+
* Wraps `command`/`args` so the OS enforces `limits`, via `prlimit`.
|
|
43
|
+
* `undefined` or an empty `limits` returns `command`/`args` unchanged --
|
|
44
|
+
* every execution before RT-070 keeps behaving exactly as before unless it
|
|
45
|
+
* opts in.
|
|
46
|
+
*
|
|
47
|
+
* **Throws rather than silently spawning unconstrained** when a limit was
|
|
48
|
+
* requested and `prlimit` is unavailable. `tokenizeCommand`'s own precedent
|
|
49
|
+
* (RT-036) is refuse rather than guess; the equivalent failure here would
|
|
50
|
+
* be a caller asking for a memory cap and getting a process that can
|
|
51
|
+
* allocate without bound, silently -- exactly the "sandbox that doesn't
|
|
52
|
+
* sandbox" shape §38 bans, one row up from this one.
|
|
53
|
+
*/
|
|
54
|
+
export declare function applyResourceLimits(command: string, args: readonly string[], limits: ResourceLimits | undefined, env?: NodeJS.ProcessEnv): {
|
|
55
|
+
readonly command: string;
|
|
56
|
+
readonly args: readonly string[];
|
|
57
|
+
};
|
|
58
|
+
/**
|
|
59
|
+
* DEC-272's disclosure requirement: the sandbox boundary (RT-070) must be
|
|
60
|
+
* stated to the user directly in-product, not left as a silent gap in a
|
|
61
|
+
* doc. Fixed, not derived from `runningAsRoot` -- the boundary is the same
|
|
62
|
+
* regardless of which privilege level was found; only the observed fact
|
|
63
|
+
* changes.
|
|
64
|
+
*
|
|
65
|
+
* **Scope, corrected by the attach-mode-mitigations lane: this is the
|
|
66
|
+
* unconditional-unisolated text, not a universal one.** Written when
|
|
67
|
+
* RT-193/RT-070 landed, before `sandbox.ts` existed -- at that point it was
|
|
68
|
+
* accurate for every execution, because nothing anywhere in this runtime
|
|
69
|
+
* could isolate anything. That stopped being true the moment the
|
|
70
|
+
* sandbox-isolation lane gave spawn-mode real, bwrap-backed filesystem/
|
|
71
|
+
* network isolation (`applySandbox`, this same package): a spawned process
|
|
72
|
+
* that actually got a `FilesystemPolicy`/`NetworkPolicy` applied to it is
|
|
73
|
+
* genuinely more contained than "the same as if you started it yourself"
|
|
74
|
+
* says. Using this constant unconditionally for that process would be a
|
|
75
|
+
* real disclosure-accuracy bug -- understating a boundary is not the safe
|
|
76
|
+
* direction to be wrong in, it just happens to be a less alarming one.
|
|
77
|
+
* `sandboxBoundaryDisclosureFor()` below is the mode-aware replacement: it
|
|
78
|
+
* returns this exact string when no policy was applied (attach-mode always,
|
|
79
|
+
* and any spawn that declared none -- unchanged from before this lane), and
|
|
80
|
+
* a real, specific description of what is and is not contained when a
|
|
81
|
+
* policy genuinely was. This constant is kept, unchanged, as that function's
|
|
82
|
+
* own no-policy-applied return value and as attach-mode's own disclosure,
|
|
83
|
+
* not deprecated -- attach-mode never has anything more accurate to say.
|
|
84
|
+
*/
|
|
85
|
+
export declare const SANDBOX_BOUNDARY_DISCLOSURE: string;
|
|
86
|
+
/**
|
|
87
|
+
* Whether a real `FilesystemPolicy`/`NetworkPolicy` was actually enforced on
|
|
88
|
+
* the process this disclosure describes -- not merely requested.
|
|
89
|
+
* `applySandbox` already refuses to spawn (throws) rather than proceed
|
|
90
|
+
* unconstrained when a declared policy cannot be enforced (see its own
|
|
91
|
+
* comment), so by the time a caller can observe a successfully spawned
|
|
92
|
+
* process, "declared" and "applied" are the same fact; this type exists so
|
|
93
|
+
* a caller states that fact explicitly rather than this function silently
|
|
94
|
+
* assuming it.
|
|
95
|
+
*/
|
|
96
|
+
export interface AppliedIsolationPolicies {
|
|
97
|
+
readonly filesystemPolicyApplied: boolean;
|
|
98
|
+
readonly networkPolicyApplied: boolean;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* The mode-aware replacement for reading `SANDBOX_BOUNDARY_DISCLOSURE`
|
|
102
|
+
* unconditionally. Defaults to reporting no policy applied -- so calling
|
|
103
|
+
* this with no argument at all is identical to the pre-existing constant,
|
|
104
|
+
* the same non-regression contract every other opt-in in this file
|
|
105
|
+
* (`applyResourceLimits`, `applySandbox`) already keeps.
|
|
106
|
+
*
|
|
107
|
+
* **Still only ever true for spawn-mode.** Attach-mode has no code path
|
|
108
|
+
* that can produce `filesystemPolicyApplied: true` or
|
|
109
|
+
* `networkPolicyApplied: true` for any process it did not itself spawn --
|
|
110
|
+
* see `sandbox.ts`'s own module doc for why that is structural, not a gap
|
|
111
|
+
* in this function. A caller in attach-mode should simply never pass
|
|
112
|
+
* anything but the default here, and the default's return value is this
|
|
113
|
+
* disclosure's original, unconditional "not isolated" text, unchanged.
|
|
114
|
+
*/
|
|
115
|
+
export declare function sandboxBoundaryDisclosureFor(policies?: AppliedIsolationPolicies): string;
|
|
116
|
+
/**
|
|
117
|
+
* Attach mode's own contractual scope guarantee -- distinct from the
|
|
118
|
+
* sandbox-*boundary* disclosure above (what is or isn't contained) because
|
|
119
|
+
* this is a claim about what an attach-mode `Collector` is even permitted
|
|
120
|
+
* to *do*, not about what OS boundary wraps it. See `Collector` in
|
|
121
|
+
* `@descryy/runtime-contracts` for the interface-level statement this
|
|
122
|
+
* mirrors, and `sandbox.ts`'s own module doc for why attach-mode can never
|
|
123
|
+
* acquire the isolation `sandboxBoundaryDisclosureFor` describes for
|
|
124
|
+
* spawn-mode. Stated once, here, so every attach-mode caller surfaces the
|
|
125
|
+
* identical sentence rather than each writing its own paraphrase.
|
|
126
|
+
*/
|
|
127
|
+
export declare const ATTACH_MODE_SCOPE_DISCLOSURE: string;
|
|
128
|
+
export interface PrivilegeReport {
|
|
129
|
+
/** Null when this platform has no uid concept at all (`process.getuid` is undefined on Windows) -- distinct from `false`, which is a real answer, not an absent one. */
|
|
130
|
+
readonly runningAsRoot: boolean | null;
|
|
131
|
+
/** DEC-272: plain-language statement of the sandbox boundary, carried on the same result the privilege level already travels on rather than a new return path. Always populated -- the disclosure is unconditional, not dependent on `runningAsRoot`. */
|
|
132
|
+
readonly disclosure: string;
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Reports, never enforces. §21's privilege policy for a runtime declared
|
|
136
|
+
* trusted-local (RT-070) is not "refuse to run as root" -- CI containers
|
|
137
|
+
* commonly run as root by default, and a hard refusal there would turn a
|
|
138
|
+
* documented boundary into an undocumented outage. The policy is: the real
|
|
139
|
+
* privilege level becomes an observable fact instead of an invisible one,
|
|
140
|
+
* which is what nothing before RT-070 made it.
|
|
141
|
+
*
|
|
142
|
+
* A required parameter, not a defaulted one: `undefined` is the real,
|
|
143
|
+
* meaningful value a platform with no uid concept produces
|
|
144
|
+
* (`process.getuid` is itself `undefined` on Windows), and a *default*
|
|
145
|
+
* parameter cannot tell "caller explicitly passed undefined" apart from
|
|
146
|
+
* "caller omitted the argument" -- both look identical to the function.
|
|
147
|
+
* `currentPrivilegeReport()` below is the zero-argument convenience wrapper
|
|
148
|
+
* real callers use; this is what makes both branches -- root, and no uid
|
|
149
|
+
* concept at all -- directly testable without this process actually
|
|
150
|
+
* needing to run as root or on Windows.
|
|
151
|
+
*/
|
|
152
|
+
export declare function privilegeReportFor(getuid: (() => number) | undefined): PrivilegeReport;
|
|
153
|
+
export declare function currentPrivilegeReport(): PrivilegeReport;
|
|
154
|
+
//# sourceMappingURL=execution-safety.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"execution-safety.d.ts","sourceRoot":"","sources":["../src/execution-safety.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAGH,OAAO,KAAK,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAGnF;;;;;;GAMG;AACH,wBAAgB,uBAAuB,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,gBAAgB,CAU9F;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,uBAAuB,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,gBAAgB,CAE9F;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,MAAM,EAAE,cAAc,GAAG,SAAS,EAClC,GAAG,GAAE,MAAM,CAAC,UAAwB,GACnC;IAAE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,CAchE;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,eAAO,MAAM,2BAA2B,QAGT,CAAC;AAEhC;;;;;;;;;GASG;AACH,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,uBAAuB,EAAE,OAAO,CAAC;IAC1C,QAAQ,CAAC,oBAAoB,EAAE,OAAO,CAAC;CACxC;AAID;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,4BAA4B,CAAC,QAAQ,GAAE,wBAA8C,GAAG,MAAM,CAwB7G;AAED;;;;;;;;;;GAUG;AACH,eAAO,MAAM,4BAA4B,QAKoC,CAAC;AAE9E,MAAM,WAAW,eAAe;IAC9B,wKAAwK;IACxK,QAAQ,CAAC,aAAa,EAAE,OAAO,GAAG,IAAI,CAAC;IACvC,yPAAyP;IACzP,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,CAAC,MAAM,MAAM,CAAC,GAAG,SAAS,GAAG,eAAe,CAGtF;AAED,wBAAgB,sBAAsB,IAAI,eAAe,CAExD"}
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* §21's execution boundary (RT-070): resource limits and privilege
|
|
3
|
+
* reporting for a runtime whose declared mode is trusted-local (see
|
|
4
|
+
* DECISIONS.md RT-070) -- every spawned process runs with the invoking
|
|
5
|
+
* user's own OS privileges, no filesystem or network restriction. That
|
|
6
|
+
* declaration does not make unrestricted execution safe; it names the
|
|
7
|
+
* boundary instead of leaving it absent, which is what §38's "arbitrary
|
|
8
|
+
* application code runs without a defined safety boundary" actually bans.
|
|
9
|
+
* Real isolation (containers/namespaces) is a separate architectural
|
|
10
|
+
* decision this module does not invent (plan §29's own instruction).
|
|
11
|
+
*
|
|
12
|
+
* What this module DOES enforce, for real, via the OS: CPU time, virtual
|
|
13
|
+
* memory, and process count, through `prlimit` -- an exec wrapper, never a
|
|
14
|
+
* shell. Reintroducing `sh -c 'ulimit ...; exec ...'` to get these would
|
|
15
|
+
* undo RT-036's `tokenizeCommand` refusal of shell metacharacters. `prlimit`
|
|
16
|
+
* is util-linux and absent on macOS, so it is reported as a capability,
|
|
17
|
+
* never assumed.
|
|
18
|
+
*/
|
|
19
|
+
import { execFileSync } from "node:child_process";
|
|
20
|
+
import { networkIsolationCapability } from "./sandbox.js";
|
|
21
|
+
/**
|
|
22
|
+
* Whether `prlimit` is reachable on this platform's `PATH`. Takes `env` as
|
|
23
|
+
* a parameter (defaulting to `process.env`) rather than reading it
|
|
24
|
+
* internally so the "unavailable" branch is directly testable without
|
|
25
|
+
* mutating this process's own real environment or depending on running on
|
|
26
|
+
* a platform that genuinely lacks it.
|
|
27
|
+
*/
|
|
28
|
+
export function resourceLimitCapability(env = process.env) {
|
|
29
|
+
try {
|
|
30
|
+
execFileSync("prlimit", ["--version"], { env, stdio: "ignore" });
|
|
31
|
+
return { availability: "available", reason: null };
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
return {
|
|
35
|
+
availability: "unavailable",
|
|
36
|
+
reason: "prlimit (util-linux) is not on PATH -- CPU/memory/process limits cannot be enforced on this platform without reintroducing a shell, which this runtime refuses to do (RT-036)",
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* RT-193 originally made this always `unavailable` -- no platform had any
|
|
42
|
+
* enforcement mechanism wired up. The sandbox-isolation lane changes that
|
|
43
|
+
* on Linux: `networkIsolationCapability()` (`./sandbox.ts`) is real, backed
|
|
44
|
+
* by a bwrap network namespace. This function is kept as the stable name
|
|
45
|
+
* every existing caller (`ExecutionController.run()`, this package's own
|
|
46
|
+
* tests) already imports, delegating rather than duplicating the check --
|
|
47
|
+
* exactly the seam RT-193's own comment anticipated ("if a real mechanism
|
|
48
|
+
* is ever built, this one function changes and every caller keeps working
|
|
49
|
+
* unmodified"). Still unconditionally `unavailable` on macOS/Windows, where
|
|
50
|
+
* nothing enforces it yet.
|
|
51
|
+
*/
|
|
52
|
+
export function networkPolicyCapability(env = process.env) {
|
|
53
|
+
return networkIsolationCapability(env);
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Wraps `command`/`args` so the OS enforces `limits`, via `prlimit`.
|
|
57
|
+
* `undefined` or an empty `limits` returns `command`/`args` unchanged --
|
|
58
|
+
* every execution before RT-070 keeps behaving exactly as before unless it
|
|
59
|
+
* opts in.
|
|
60
|
+
*
|
|
61
|
+
* **Throws rather than silently spawning unconstrained** when a limit was
|
|
62
|
+
* requested and `prlimit` is unavailable. `tokenizeCommand`'s own precedent
|
|
63
|
+
* (RT-036) is refuse rather than guess; the equivalent failure here would
|
|
64
|
+
* be a caller asking for a memory cap and getting a process that can
|
|
65
|
+
* allocate without bound, silently -- exactly the "sandbox that doesn't
|
|
66
|
+
* sandbox" shape §38 bans, one row up from this one.
|
|
67
|
+
*/
|
|
68
|
+
export function applyResourceLimits(command, args, limits, env = process.env) {
|
|
69
|
+
if (limits === undefined)
|
|
70
|
+
return { command, args };
|
|
71
|
+
const flags = [];
|
|
72
|
+
if (limits.maxMemoryBytes !== undefined)
|
|
73
|
+
flags.push(`--as=${limits.maxMemoryBytes}`);
|
|
74
|
+
if (limits.maxCpuSeconds !== undefined)
|
|
75
|
+
flags.push(`--cpu=${limits.maxCpuSeconds}`);
|
|
76
|
+
if (limits.maxProcesses !== undefined)
|
|
77
|
+
flags.push(`--nproc=${limits.maxProcesses}`);
|
|
78
|
+
if (flags.length === 0)
|
|
79
|
+
return { command, args };
|
|
80
|
+
const capability = resourceLimitCapability(env);
|
|
81
|
+
if (capability.availability !== "available") {
|
|
82
|
+
throw new Error(`resource limits were requested but cannot be enforced on this platform: ${capability.reason}`);
|
|
83
|
+
}
|
|
84
|
+
return { command: "prlimit", args: [...flags, "--", command, ...args] };
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* DEC-272's disclosure requirement: the sandbox boundary (RT-070) must be
|
|
88
|
+
* stated to the user directly in-product, not left as a silent gap in a
|
|
89
|
+
* doc. Fixed, not derived from `runningAsRoot` -- the boundary is the same
|
|
90
|
+
* regardless of which privilege level was found; only the observed fact
|
|
91
|
+
* changes.
|
|
92
|
+
*
|
|
93
|
+
* **Scope, corrected by the attach-mode-mitigations lane: this is the
|
|
94
|
+
* unconditional-unisolated text, not a universal one.** Written when
|
|
95
|
+
* RT-193/RT-070 landed, before `sandbox.ts` existed -- at that point it was
|
|
96
|
+
* accurate for every execution, because nothing anywhere in this runtime
|
|
97
|
+
* could isolate anything. That stopped being true the moment the
|
|
98
|
+
* sandbox-isolation lane gave spawn-mode real, bwrap-backed filesystem/
|
|
99
|
+
* network isolation (`applySandbox`, this same package): a spawned process
|
|
100
|
+
* that actually got a `FilesystemPolicy`/`NetworkPolicy` applied to it is
|
|
101
|
+
* genuinely more contained than "the same as if you started it yourself"
|
|
102
|
+
* says. Using this constant unconditionally for that process would be a
|
|
103
|
+
* real disclosure-accuracy bug -- understating a boundary is not the safe
|
|
104
|
+
* direction to be wrong in, it just happens to be a less alarming one.
|
|
105
|
+
* `sandboxBoundaryDisclosureFor()` below is the mode-aware replacement: it
|
|
106
|
+
* returns this exact string when no policy was applied (attach-mode always,
|
|
107
|
+
* and any spawn that declared none -- unchanged from before this lane), and
|
|
108
|
+
* a real, specific description of what is and is not contained when a
|
|
109
|
+
* policy genuinely was. This constant is kept, unchanged, as that function's
|
|
110
|
+
* own no-policy-applied return value and as attach-mode's own disclosure,
|
|
111
|
+
* not deprecated -- attach-mode never has anything more accurate to say.
|
|
112
|
+
*/
|
|
113
|
+
export const SANDBOX_BOUNDARY_DISCLOSURE = "This app runs with your own user permissions, the same as if you started it yourself. " +
|
|
114
|
+
"The filesystem and network are not isolated -- anything your own account could read, write, " +
|
|
115
|
+
"or reach, this run can too.";
|
|
116
|
+
const NO_POLICIES_APPLIED = { filesystemPolicyApplied: false, networkPolicyApplied: false };
|
|
117
|
+
/**
|
|
118
|
+
* The mode-aware replacement for reading `SANDBOX_BOUNDARY_DISCLOSURE`
|
|
119
|
+
* unconditionally. Defaults to reporting no policy applied -- so calling
|
|
120
|
+
* this with no argument at all is identical to the pre-existing constant,
|
|
121
|
+
* the same non-regression contract every other opt-in in this file
|
|
122
|
+
* (`applyResourceLimits`, `applySandbox`) already keeps.
|
|
123
|
+
*
|
|
124
|
+
* **Still only ever true for spawn-mode.** Attach-mode has no code path
|
|
125
|
+
* that can produce `filesystemPolicyApplied: true` or
|
|
126
|
+
* `networkPolicyApplied: true` for any process it did not itself spawn --
|
|
127
|
+
* see `sandbox.ts`'s own module doc for why that is structural, not a gap
|
|
128
|
+
* in this function. A caller in attach-mode should simply never pass
|
|
129
|
+
* anything but the default here, and the default's return value is this
|
|
130
|
+
* disclosure's original, unconditional "not isolated" text, unchanged.
|
|
131
|
+
*/
|
|
132
|
+
export function sandboxBoundaryDisclosureFor(policies = NO_POLICIES_APPLIED) {
|
|
133
|
+
const { filesystemPolicyApplied, networkPolicyApplied } = policies;
|
|
134
|
+
if (!filesystemPolicyApplied && !networkPolicyApplied)
|
|
135
|
+
return SANDBOX_BOUNDARY_DISCLOSURE;
|
|
136
|
+
if (filesystemPolicyApplied && networkPolicyApplied) {
|
|
137
|
+
return ("This process was spawned inside a real OS-level sandbox (bubblewrap): filesystem access is restricted " +
|
|
138
|
+
"to its declared allowedRoots (plus its own working directory) -- nothing else on this machine is visible " +
|
|
139
|
+
"to it, not merely unwritable -- and network access is fully denied, including this machine's own loopback. " +
|
|
140
|
+
"This is real isolation, not a name-only boundary.");
|
|
141
|
+
}
|
|
142
|
+
if (filesystemPolicyApplied) {
|
|
143
|
+
return ("This process was spawned inside a real OS-level sandbox (bubblewrap): filesystem access is restricted " +
|
|
144
|
+
"to its declared allowedRoots (plus its own working directory) -- nothing else on this machine is visible " +
|
|
145
|
+
"to it, not merely unwritable. Network access was NOT restricted for this run -- it can reach anything " +
|
|
146
|
+
"your own account's network could reach.");
|
|
147
|
+
}
|
|
148
|
+
return ("This process was spawned inside a real OS-level sandbox (bubblewrap): network access is fully denied " +
|
|
149
|
+
"for this run, including this machine's own loopback. Filesystem access was NOT restricted for this run -- " +
|
|
150
|
+
"it can read, write, or reach anything your own account's filesystem could.");
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Attach mode's own contractual scope guarantee -- distinct from the
|
|
154
|
+
* sandbox-*boundary* disclosure above (what is or isn't contained) because
|
|
155
|
+
* this is a claim about what an attach-mode `Collector` is even permitted
|
|
156
|
+
* to *do*, not about what OS boundary wraps it. See `Collector` in
|
|
157
|
+
* `@descryy/runtime-contracts` for the interface-level statement this
|
|
158
|
+
* mirrors, and `sandbox.ts`'s own module doc for why attach-mode can never
|
|
159
|
+
* acquire the isolation `sandboxBoundaryDisclosureFor` describes for
|
|
160
|
+
* spawn-mode. Stated once, here, so every attach-mode caller surfaces the
|
|
161
|
+
* identical sentence rather than each writing its own paraphrase.
|
|
162
|
+
*/
|
|
163
|
+
export const ATTACH_MODE_SCOPE_DISCLOSURE = "Attach mode observes an already-running process; it never executes code in it or applies changes to it. " +
|
|
164
|
+
"This is a permanent, documented architectural limitation, not a temporary gap -- there is no honest way to " +
|
|
165
|
+
"retroactively sandbox a process that was already running, unconfined, before this tool touched it. " +
|
|
166
|
+
"Respawn-and-supervise and the cgroup resource-limit move are real alternatives next to attach mode, not " +
|
|
167
|
+
"fixes to it; see their own documentation for what each actually gets you.";
|
|
168
|
+
/**
|
|
169
|
+
* Reports, never enforces. §21's privilege policy for a runtime declared
|
|
170
|
+
* trusted-local (RT-070) is not "refuse to run as root" -- CI containers
|
|
171
|
+
* commonly run as root by default, and a hard refusal there would turn a
|
|
172
|
+
* documented boundary into an undocumented outage. The policy is: the real
|
|
173
|
+
* privilege level becomes an observable fact instead of an invisible one,
|
|
174
|
+
* which is what nothing before RT-070 made it.
|
|
175
|
+
*
|
|
176
|
+
* A required parameter, not a defaulted one: `undefined` is the real,
|
|
177
|
+
* meaningful value a platform with no uid concept produces
|
|
178
|
+
* (`process.getuid` is itself `undefined` on Windows), and a *default*
|
|
179
|
+
* parameter cannot tell "caller explicitly passed undefined" apart from
|
|
180
|
+
* "caller omitted the argument" -- both look identical to the function.
|
|
181
|
+
* `currentPrivilegeReport()` below is the zero-argument convenience wrapper
|
|
182
|
+
* real callers use; this is what makes both branches -- root, and no uid
|
|
183
|
+
* concept at all -- directly testable without this process actually
|
|
184
|
+
* needing to run as root or on Windows.
|
|
185
|
+
*/
|
|
186
|
+
export function privilegeReportFor(getuid) {
|
|
187
|
+
if (getuid === undefined)
|
|
188
|
+
return { runningAsRoot: null, disclosure: SANDBOX_BOUNDARY_DISCLOSURE };
|
|
189
|
+
return { runningAsRoot: getuid() === 0, disclosure: SANDBOX_BOUNDARY_DISCLOSURE };
|
|
190
|
+
}
|
|
191
|
+
export function currentPrivilegeReport() {
|
|
192
|
+
return privilegeReportFor(process.getuid?.bind(process));
|
|
193
|
+
}
|
|
194
|
+
//# sourceMappingURL=execution-safety.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"execution-safety.js","sourceRoot":"","sources":["../src/execution-safety.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
export { withDefaultProcessEnv } from "./env.ts";
|
|
2
|
+
export type { SpawnProcessOptions, ProcessExitInfo, ManagedProcess, AttachProcessOptions } from "./process-manager.ts";
|
|
3
|
+
export { spawnProcess, attachManagedProcess, isProcessAlive } from "./process-manager.ts";
|
|
4
|
+
export type { ReadinessMechanism, HttpReadinessCheck, TcpPortReadinessCheck, LogPatternReadinessCheck, CommandReadinessCheck, CustomHookReadinessCheck, ReadinessCheck, ReadinessResult, AwaitReadinessOptions, } from "./readiness.ts";
|
|
5
|
+
export { READINESS_MECHANISMS, awaitReadiness } from "./readiness.ts";
|
|
6
|
+
export type { CreateExecutionInput, RunOptions, ProcessLifecycleEvent } from "./controller.ts";
|
|
7
|
+
export { ExecutionController } from "./controller.ts";
|
|
8
|
+
export type { ProcessCollector } from "./process-collector.ts";
|
|
9
|
+
export { createProcessCollector } from "./process-collector.ts";
|
|
10
|
+
export type { RegisteredCollectorCapabilities, CollectorCapabilityKey } from "./capability-registry.ts";
|
|
11
|
+
export { buildExecutionCapabilities, bestCapabilityStatus } from "./capability-registry.ts";
|
|
12
|
+
export type { PrivilegeReport, AppliedIsolationPolicies } from "./execution-safety.ts";
|
|
13
|
+
export { resourceLimitCapability, applyResourceLimits, networkPolicyCapability, privilegeReportFor, currentPrivilegeReport, SANDBOX_BOUNDARY_DISCLOSURE, sandboxBoundaryDisclosureFor, ATTACH_MODE_SCOPE_DISCLOSURE, } from "./execution-safety.ts";
|
|
14
|
+
export type { SandboxOptions } from "./sandbox.ts";
|
|
15
|
+
export { filesystemIsolationCapability, networkIsolationCapability, unsupportedNetworkPolicyReason, resolveExecutableDirectory, applySandbox, } from "./sandbox.ts";
|
|
16
|
+
export type { ContainerSandboxOptions } from "./container-sandbox.ts";
|
|
17
|
+
export { containerRuntimeCapability, containerFilesystemIsolationCapability, containerNetworkIsolationCapability, unsupportedContainerNetworkPolicyReason, resolveContainerImage, applyContainerSandbox, } from "./container-sandbox.ts";
|
|
18
|
+
export { captureEnvironmentMetadata } from "./environment-metadata.ts";
|
|
19
|
+
export type { DependencyVersionMismatch, DependencyVersionCheckResult } from "./dependency-version-check.ts";
|
|
20
|
+
export { checkDependencyVersions } from "./dependency-version-check.ts";
|
|
21
|
+
export type { DeclaredVersionSource, EnvironmentVersionCheckResult } from "./environment-version-check.ts";
|
|
22
|
+
export { DECLARED_VERSION_SOURCES, checkEnvironmentVersion, satisfiesDeclaredNodeVersion } from "./environment-version-check.ts";
|
|
23
|
+
/**
|
|
24
|
+
* RT-073: promoted from internal-only. `tokenizeCommand`'s POSIX-style
|
|
25
|
+
* "refuse rather than guess" tokenizer is exactly what `packages/test-runner`
|
|
26
|
+
* needs to validate a declared runner command before spawning it -- the
|
|
27
|
+
* same job it already does for `ServiceConfiguration.command` here.
|
|
28
|
+
* Re-implementing a second copy for one more caller would be the "two
|
|
29
|
+
* shapes that could drift" mistake this codebase has already named and
|
|
30
|
+
* avoided elsewhere (RT-068's `BrowserConfiguration`, RT-070's
|
|
31
|
+
* `ResourceLimits`).
|
|
32
|
+
*/
|
|
33
|
+
export type { CommandTokenization, ServicesValidation } from "./orchestration.ts";
|
|
34
|
+
export { tokenizeCommand, validateServicesConfiguration, substitutePortPlaceholders } from "./orchestration.ts";
|
|
35
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAC;AAEjD,YAAY,EAAE,mBAAmB,EAAE,eAAe,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AACvH,OAAO,EAAE,YAAY,EAAE,oBAAoB,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAE1F,YAAY,EACV,kBAAkB,EAClB,kBAAkB,EAClB,qBAAqB,EACrB,wBAAwB,EACxB,qBAAqB,EACrB,wBAAwB,EACxB,cAAc,EACd,eAAe,EACf,qBAAqB,GACtB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,oBAAoB,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAEtE,YAAY,EAAE,oBAAoB,EAAE,UAAU,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAC/F,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAEtD,YAAY,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AAEhE,YAAY,EAAE,+BAA+B,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AACxG,OAAO,EAAE,0BAA0B,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAE5F,YAAY,EAAE,eAAe,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAC;AACvF,OAAO,EACL,uBAAuB,EACvB,mBAAmB,EACnB,uBAAuB,EACvB,kBAAkB,EAClB,sBAAsB,EACtB,2BAA2B,EAC3B,4BAA4B,EAC5B,4BAA4B,GAC7B,MAAM,uBAAuB,CAAC;AAE/B,YAAY,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EACL,6BAA6B,EAC7B,0BAA0B,EAC1B,8BAA8B,EAC9B,0BAA0B,EAC1B,YAAY,GACb,MAAM,cAAc,CAAC;AAEtB,YAAY,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AACtE,OAAO,EACL,0BAA0B,EAC1B,sCAAsC,EACtC,mCAAmC,EACnC,uCAAuC,EACvC,qBAAqB,EACrB,qBAAqB,GACtB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EAAE,0BAA0B,EAAE,MAAM,2BAA2B,CAAC;AAEvE,YAAY,EAAE,yBAAyB,EAAE,4BAA4B,EAAE,MAAM,+BAA+B,CAAC;AAC7G,OAAO,EAAE,uBAAuB,EAAE,MAAM,+BAA+B,CAAC;AAExE,YAAY,EAAE,qBAAqB,EAAE,6BAA6B,EAAE,MAAM,gCAAgC,CAAC;AAC3G,OAAO,EAAE,wBAAwB,EAAE,uBAAuB,EAAE,4BAA4B,EAAE,MAAM,gCAAgC,CAAC;AAEjI;;;;;;;;;GASG;AACH,YAAY,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAClF,OAAO,EAAE,eAAe,EAAE,6BAA6B,EAAE,0BAA0B,EAAE,MAAM,oBAAoB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export { withDefaultProcessEnv } from "./env.js";
|
|
2
|
+
export { spawnProcess, attachManagedProcess, isProcessAlive } from "./process-manager.js";
|
|
3
|
+
export { READINESS_MECHANISMS, awaitReadiness } from "./readiness.js";
|
|
4
|
+
export { ExecutionController } from "./controller.js";
|
|
5
|
+
export { createProcessCollector } from "./process-collector.js";
|
|
6
|
+
export { buildExecutionCapabilities, bestCapabilityStatus } from "./capability-registry.js";
|
|
7
|
+
export { resourceLimitCapability, applyResourceLimits, networkPolicyCapability, privilegeReportFor, currentPrivilegeReport, SANDBOX_BOUNDARY_DISCLOSURE, sandboxBoundaryDisclosureFor, ATTACH_MODE_SCOPE_DISCLOSURE, } from "./execution-safety.js";
|
|
8
|
+
export { filesystemIsolationCapability, networkIsolationCapability, unsupportedNetworkPolicyReason, resolveExecutableDirectory, applySandbox, } from "./sandbox.js";
|
|
9
|
+
export { containerRuntimeCapability, containerFilesystemIsolationCapability, containerNetworkIsolationCapability, unsupportedContainerNetworkPolicyReason, resolveContainerImage, applyContainerSandbox, } from "./container-sandbox.js";
|
|
10
|
+
export { captureEnvironmentMetadata } from "./environment-metadata.js";
|
|
11
|
+
export { checkDependencyVersions } from "./dependency-version-check.js";
|
|
12
|
+
export { DECLARED_VERSION_SOURCES, checkEnvironmentVersion, satisfiesDeclaredNodeVersion } from "./environment-version-check.js";
|
|
13
|
+
export { tokenizeCommand, validateServicesConfiguration, substitutePortPlaceholders } from "./orchestration.js";
|
|
14
|
+
//# sourceMappingURL=index.js.map
|