@sema-agent/core 7.21.1 → 7.23.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/CHANGELOG.md +290 -1
- package/dist/agents/send-message-tool.js +1 -0
- package/dist/agents/subagent.d.ts +1 -0
- package/dist/agents/subagent.js +2 -1
- package/dist/core/ask-origin.d.ts +1 -0
- package/dist/core/ask-origin.js +3 -2
- package/dist/core/auto-compaction.d.ts +2 -2
- package/dist/core/auto-mode-rebuild.js +6 -2
- package/dist/core/auto-mode.d.ts +40 -18
- package/dist/core/auto-mode.js +63 -45
- package/dist/core/checkpoint-store.d.ts +9 -13
- package/dist/core/context-edit.js +1 -1
- package/dist/core/engine-notice.d.ts +62 -1
- package/dist/core/engine-notice.js +14 -1
- package/dist/core/gate-bounded-await.d.ts +13 -3
- package/dist/core/gate-fold.js +3 -3
- package/dist/core/governance-codes.d.ts +1 -1
- package/dist/core/governance-codes.js +6 -0
- package/dist/core/mcp.d.ts +65 -0
- package/dist/core/mcp.js +190 -41
- package/dist/core/memory-engine/consolidation.d.ts +5 -0
- package/dist/core/memory-engine/consolidation.js +7 -3
- package/dist/core/memory-engine/engine.d.ts +8 -0
- package/dist/core/memory-engine/engine.js +25 -19
- package/dist/core/memory-engine/layout.d.ts +47 -9
- package/dist/core/memory-engine/layout.js +157 -57
- package/dist/core/memory-engine/session-incarnation.d.ts +27 -0
- package/dist/core/memory-engine/session-incarnation.js +63 -0
- package/dist/core/parent-spec-seat.d.ts +15 -3
- package/dist/core/parent-spec-seat.js +5 -0
- package/dist/core/park-selfcheck.js +1 -1
- package/dist/core/path-identity.d.ts +11 -4
- package/dist/core/path-identity.js +5 -2
- package/dist/core/permission-rule-model.d.ts +1 -2
- package/dist/core/read-root-candidate.js +11 -1
- package/dist/core/retention.d.ts +8 -1
- package/dist/core/retention.js +2 -0
- package/dist/core/runner/assemble-result.d.ts +2 -7
- package/dist/core/runner/assemble-result.js +25 -8
- package/dist/core/runner/classifier-ladder.js +1 -0
- package/dist/core/runner/contracts.d.ts +26 -15
- package/dist/core/runner/inherited-ask-grants.d.ts +2 -7
- package/dist/core/runner/inherited-ask-grants.js +1 -0
- package/dist/core/runner/mcp-redial.d.ts +109 -0
- package/dist/core/runner/mcp-redial.js +60 -0
- package/dist/core/runner/memory-consolidation-driver.d.ts +2 -0
- package/dist/core/runner/prepare-ask-lane.js +1 -0
- package/dist/core/runner/prepare-caps-and-workflow.js +9 -12
- package/dist/core/runner/prepare-context-lane.d.ts +43 -1
- package/dist/core/runner/prepare-context-lane.js +25 -4
- package/dist/core/runner/prepare-hands-readface.d.ts +3 -0
- package/dist/core/runner/prepare-hands-readface.js +13 -3
- package/dist/core/runner/prepare-memory.js +3 -3
- package/dist/core/runner/prepare-protocol-tools.d.ts +6 -1
- package/dist/core/runner/prepare-protocol-tools.js +20 -38
- package/dist/core/runner/prepare-task.js +4 -4
- package/dist/core/runner/prepare-turn-wiring.js +2 -2
- package/dist/core/runner/prepare-wiring-manifest.d.ts +4 -0
- package/dist/core/runner/prepare-wiring-manifest.js +2 -1
- package/dist/core/runner/run-harness-handlers.js +4 -2
- package/dist/core/runner/run-identity-wiring.d.ts +3 -1
- package/dist/core/runner/run-identity-wiring.js +4 -1
- package/dist/core/runner/run-recovery-lanes.js +6 -3
- package/dist/core/runner/run-settle-and-teardown.d.ts +3 -1
- package/dist/core/runner/run-settle-and-teardown.js +6 -2
- package/dist/core/runner/run-telemetry-and-budget-seats.js +11 -1
- package/dist/core/runner/run-terminal-adoption.d.ts +4 -1
- package/dist/core/runner/run-terminal-adoption.js +2 -6
- package/dist/core/runner/runtask.js +8 -5
- package/dist/core/runner/stream-lifecycle-verbs.d.ts +5 -1
- package/dist/core/runner/stream-lifecycle-verbs.js +23 -2
- package/dist/core/runner/write-protection-station.d.ts +7 -25
- package/dist/core/runner/write-protection-station.js +18 -0
- package/dist/core/runner-deps.d.ts +16 -7
- package/dist/core/skill-listing-budget.d.ts +5 -4
- package/dist/core/task-registry.d.ts +0 -6
- package/dist/core/task-result.d.ts +31 -12
- package/dist/core/task-spec.d.ts +2 -1
- package/dist/core/task-stream.d.ts +26 -0
- package/dist/core/tool-spec.d.ts +5 -1
- package/dist/core/trace.d.ts +5 -0
- package/dist/core/types.d.ts +3 -3
- package/dist/core/types.js +1 -1
- package/dist/core/wiring-manifest.d.ts +23 -0
- package/dist/core/wiring-manifest.js +3 -0
- package/dist/core/write-protect.d.ts +64 -12
- package/dist/core/write-protect.js +88 -34
- package/dist/engine/execution-env/node-execution-env.d.ts +19 -2
- package/dist/engine/execution-env/node-execution-env.js +5 -1
- package/dist/index.d.ts +5 -4
- package/dist/index.js +2 -2
- package/dist/orchestration/workflow-governance.js +1 -1
- package/dist/orchestration/workflow-primitives.d.ts +2 -2
- package/dist/tools/fs/bash-program-position.d.ts +26 -5
- package/dist/tools/fs/bash-program-position.js +63 -16
- package/dist/tools/fs/bash-readonly-classifier.d.ts +27 -17
- package/dist/tools/fs/bash-readonly-classifier.js +134 -55
- package/dist/tools/fs/fs-bash.js +43 -18
- package/dist/tools/fs/fs-read.js +2 -1
- package/dist/tools/fs/fs-shared.d.ts +33 -7
- package/dist/tools/fs/fs-shared.js +12 -1
- package/dist/tools/fs/index.d.ts +4 -2
- package/dist/tools/fs/read-deny.d.ts +25 -11
- package/dist/tools/fs/read-deny.js +5 -1
- package/dist/tools/fs/safety.d.ts +38 -4
- package/dist/tools/fs/safety.js +31 -3
- package/package.json +2 -2
- package/test/export-surface.snapshot.json +11 -1
- package/wire-changes/core@7.22.0.json +637 -0
- package/wire-changes/core@7.23.0.json +316 -0
|
@@ -30,13 +30,26 @@ export interface WriteProtectedHit {
|
|
|
30
30
|
}
|
|
31
31
|
export declare const WRITE_PROTECTED_DEFAULT_TABLE: readonly WriteProtectedRow[];
|
|
32
32
|
/**
|
|
33
|
-
* The ONE
|
|
34
|
-
* compile, path segments at match)
|
|
35
|
-
* (U+0131 dotless ı → i, U+017F long ſ → s)
|
|
36
|
-
*
|
|
37
|
-
*
|
|
33
|
+
* The ONE SEGMENT fold of this module, applied to BOTH sides of every comparison (table names at
|
|
34
|
+
* compile, path segments at match), in the reference implementation's own order:
|
|
35
|
+
* · `toLowerCase` plus the two confusable letters its fold maps (U+0131 dotless ı → i, U+017F long ſ → s);
|
|
36
|
+
* · the INVISIBLE FORMAT characters it strips — the zero-width joiners/non-joiners, the bidirectional
|
|
37
|
+
* overrides and the byte-order mark (U+200C–U+200F, U+202A–U+202E, U+206A–U+206F, U+FEFF), verbatim.
|
|
38
|
+
* A segment carrying one of these LOOKS like the row it is not, on both sides of every comparison, so
|
|
39
|
+
* the strip is a deception axis rather than a platform one: it applies to every reading below, not to
|
|
40
|
+
* the win32 one alone. It can only ADD matches, which on a TIGHTEN costs one extra question — and the
|
|
41
|
+
* data-root passthrough, where an added match would be a guard BYPASSED, deliberately does not use this
|
|
42
|
+
* fold at all (its comparison is byte-exact; see {@link relativeUnderDataRoot}).
|
|
43
|
+
* · …and a strip that would EMPTY the segment keeps the segment instead (the reference fold's own `|| n`):
|
|
44
|
+
* an all-invisible component names a real file, and folding it to "" would make it collide with nothing
|
|
45
|
+
* or with everything depending on the caller.
|
|
46
|
+
* Deliberately NOT full Unicode confusable folding: that would be a different, wider claim than the one made
|
|
47
|
+
* (the read deny set's ASCII-contract doc states the same boundary for its own fold). The NTFS data-stream
|
|
48
|
+
* suffix the reference fold also strips is a win32 NAMESPACE fact, not a comparison one, and lives with the
|
|
49
|
+
* other component normalization of those views ({@link ComponentNormalization}) so a POSIX file legally
|
|
50
|
+
* named `a:b` keeps its own identity on the POSIX reading.
|
|
38
51
|
*/
|
|
39
|
-
export declare function
|
|
52
|
+
export declare function foldWriteProtectSegment(s: string): string;
|
|
40
53
|
/**
|
|
41
54
|
* Resolve the ACTIVE table under the deployment seat (validated, loud — #123's bad-value states all
|
|
42
55
|
* throw and name the knob). `undefined` = the default table; `[]` = NO table (an explicit, legal
|
|
@@ -47,15 +60,32 @@ export declare function foldWriteProtectCase(s: string): string;
|
|
|
47
60
|
* candidate configuration with the engine's own rules.
|
|
48
61
|
*/
|
|
49
62
|
export declare function resolveWriteProtectedTable(entries?: readonly WriteProtectedEntry[]): readonly WriteProtectedRow[];
|
|
63
|
+
/**
|
|
64
|
+
* WHY the ENVIRONMENT half of one judgment could not contribute — the canonicalizer refused the spelling,
|
|
65
|
+
* a link the tree could not follow, a namespace spelling it declines, an environment call that threw.
|
|
66
|
+
* Reported through {@link WriteProtectionCompileOptions.onViewAbsent}; it is a DISCLOSURE, never a verdict
|
|
67
|
+
* (see the absence law on {@link WriteProtectionMatcher.judge}).
|
|
68
|
+
*/
|
|
69
|
+
export interface WriteProtectionViewAbsence {
|
|
70
|
+
/** The environment's own sentence, verbatim — what it said when asked to resolve this target. */
|
|
71
|
+
readonly cause: string;
|
|
72
|
+
/** The failure was specifically a symlink whose real target is unknowable, as opposed to a spelling the
|
|
73
|
+
* tree refuses or a probe that errored. */
|
|
74
|
+
readonly unresolvedSymlink: boolean;
|
|
75
|
+
}
|
|
50
76
|
/**
|
|
51
77
|
* The judge's answer for ONE covered write ({@link WriteProtectionMatcher.judge}):
|
|
52
|
-
* · `clear` — no row on
|
|
78
|
+
* · `clear` — no row on any view that could answer: the write is not this layer's business;
|
|
53
79
|
* · `hit` — a row matched; `via` says which view named it: `"spelling"` (the anchored spelling, no
|
|
54
80
|
* filesystem consulted), `"chain"` (a spelling the leaf symlink chain passes through, judged as a
|
|
55
81
|
* spelling) or `"target"` (the resolved real target, the spelling being innocent);
|
|
56
|
-
* · `unresolvable` — the
|
|
57
|
-
*
|
|
58
|
-
*
|
|
82
|
+
* · `unresolvable` — NO half of the judgment answered at all. The judge itself no longer mints this: an
|
|
83
|
+
* environment that cannot resolve the target has ANSWERED, and an answer of "I cannot resolve this"
|
|
84
|
+
* leaves the lexical half's judgment standing (the absence law below). What is left for this verdict is
|
|
85
|
+
* the judgment that never happened — the gate's bounded wait elapsing or the task ending before
|
|
86
|
+
* anything came back (`awaitWriteProtectionJudgment`, gate-bounded-await.ts) — where there is no
|
|
87
|
+
* lexical answer to stand on either, and the consumer REFUSES. `unresolvedSymlink` is that minter's
|
|
88
|
+
* `false`: a wait that produced nothing knows nothing about what it was waiting for.
|
|
59
89
|
*/
|
|
60
90
|
export type WriteProtectionVerdict = {
|
|
61
91
|
readonly kind: "clear";
|
|
@@ -115,8 +145,8 @@ export interface WriteProtectionMatcher {
|
|
|
115
145
|
* @contract write_protection.judges_the_real_target — the always-on write-protection table and the
|
|
116
146
|
* opt-in sensitive-path deny set differ in VOCABULARY (literal rows / segment globs) and SEVERITY
|
|
117
147
|
* (ask / deny), never in REACH: both judge the file the tool will write — the spelling anchored at the
|
|
118
|
-
* live cwd AND its resolved real target, through one canonicalizer
|
|
119
|
-
*
|
|
148
|
+
* live cwd AND its resolved real target, through one canonicalizer. Where they DO part: a target the write-protection
|
|
149
|
+
* judge cannot resolve leaves its resolved view ABSENT (the spelling still judges); the deny set still REFUSES whole. An environment-less judge has no target view and answers by the spelling alone —
|
|
120
150
|
* the same absence law the cwd follows (absent ⇒ the spelling is judged exactly as given). REACH is what
|
|
121
151
|
* this sentence promises, not a LOCK: the identity is resolved at judgment time and re-resolved by the
|
|
122
152
|
* tool at execute time (the module header states that window and the seat that would close it).
|
|
@@ -136,6 +166,17 @@ export interface WriteProtectionCompileOptions {
|
|
|
136
166
|
* path-family source when the call carries no cwd. Omitted ⇒ relative spellings resolve against the
|
|
137
167
|
* cwd, then the environment's own working directory. */
|
|
138
168
|
readonly rootPath?: string;
|
|
169
|
+
/**
|
|
170
|
+
* Called at most ONCE per judgment, at the moment the ENVIRONMENT half is found unable to contribute
|
|
171
|
+
* ({@link WriteProtectionViewAbsence}) — before the judgment returns, and on the hit arm as well as the
|
|
172
|
+
* clear one, because the fact is about the ENVIRONMENT rather than about the answer it did not change.
|
|
173
|
+
* Omitted ⇒ the absence is silent, which is the honest default for a judge compiled outside a leg.
|
|
174
|
+
* A throwing sink is the caller's bug and is not caught here; the leg that wires one wraps it.
|
|
175
|
+
*
|
|
176
|
+
* Deliberately carries no call identity: what it reports is a deployment-level fact (this environment
|
|
177
|
+
* cannot answer path questions), and its consumer announces once per leg rather than once per write.
|
|
178
|
+
*/
|
|
179
|
+
readonly onViewAbsent?: (absence: WriteProtectionViewAbsence) => void;
|
|
139
180
|
}
|
|
140
181
|
/**
|
|
141
182
|
* Compile the write-protection judge for a deployment configuration. Returns `undefined` when the
|
|
@@ -204,5 +245,16 @@ export interface WriteProtectionMount {
|
|
|
204
245
|
* environment cannot RESOLVE is the judge's own `unresolvable` verdict, not this null.
|
|
205
246
|
* Returns `undefined` when the resolved table is empty — nothing to judge, mount nothing.
|
|
206
247
|
* `opts` are the judge's own seats, passed straight through ({@link compileWriteProtection}).
|
|
248
|
+
*
|
|
249
|
+
* @contract write_protection.membership_is_the_call — WHICH calls the always-on table judges is a
|
|
250
|
+
* PREDICATE OVER THE CALL and nothing else: the call's own face declares a path target whose access is not
|
|
251
|
+
* a read, so a custom writer joins this judge by DECLARING what it writes and a tool that declares nothing
|
|
252
|
+
* is not this layer's business under any name. There is deliberately NO name-list seat beside it, and the
|
|
253
|
+
* asymmetry with the opt-in deny policy — which does take one (`createSensitivePathPolicy({ tools })`, its
|
|
254
|
+
* own pre-declaration hatch) — is the intended shape rather than a gap: a name list on a default-ON floor
|
|
255
|
+
* is a way to narrow that floor silently, one tool name at a time, while the seat this layer gives a
|
|
256
|
+
* deployment for narrowing is the whole-table replacement, which says what it removes. A deployment that
|
|
257
|
+
* wants name-list membership composes the deny policy alongside; the two then answer under the shared
|
|
258
|
+
* `deny > ask > allow` fold, which is what makes the missing seat cost nothing.
|
|
207
259
|
*/
|
|
208
260
|
export declare function createWriteProtectionCheck(entries?: readonly WriteProtectedEntry[], opts?: WriteProtectionCompileOptions): WriteProtectionMount | undefined;
|
|
@@ -57,8 +57,20 @@ export const WRITE_PROTECTED_DEFAULT_TABLE = freezeTable([
|
|
|
57
57
|
{ name: ".sema.json", kind: "basename" },
|
|
58
58
|
{ name: ".sema", kind: "segment" },
|
|
59
59
|
]);
|
|
60
|
-
export function
|
|
61
|
-
|
|
60
|
+
export function foldWriteProtectSegment(s) {
|
|
61
|
+
const cased = s.toLowerCase().replace(/ı/g, "i").replace(/ſ/g, "s");
|
|
62
|
+
return stripInvisibleFormat(cased) || cased;
|
|
63
|
+
}
|
|
64
|
+
function stripInvisibleFormat(s) {
|
|
65
|
+
return s.replace(/[\u200c-\u200f\u202a-\u202e\u206a-\u206f\ufeff]/g, "");
|
|
66
|
+
}
|
|
67
|
+
function stripWin32Component(raw, normalization) {
|
|
68
|
+
const base = normalization.invisibleFirst ? stripInvisibleFormat(raw) : raw;
|
|
69
|
+
const colon = normalization.stream ? base.indexOf(":") : -1;
|
|
70
|
+
return (colon < 0 ? base : base.slice(0, colon)).replace(/[. ]+$/, "");
|
|
71
|
+
}
|
|
72
|
+
function foldWriteProtectName(name) {
|
|
73
|
+
return name.split("/").map(foldWriteProtectSegment).join("/");
|
|
62
74
|
}
|
|
63
75
|
const KINDS = ["basename", "segment", "segment-run"];
|
|
64
76
|
function describeEntryValue(v) {
|
|
@@ -107,7 +119,7 @@ export function resolveWriteProtectedTable(entries) {
|
|
|
107
119
|
const seen = new Set();
|
|
108
120
|
for (const entry of entries) {
|
|
109
121
|
const row = normalizeWriteProtectedEntry(entry);
|
|
110
|
-
const key = `${row.kind}:${
|
|
122
|
+
const key = `${row.kind}:${foldWriteProtectName(row.name)}`;
|
|
111
123
|
if (seen.has(key))
|
|
112
124
|
continue;
|
|
113
125
|
seen.add(key);
|
|
@@ -115,8 +127,9 @@ export function resolveWriteProtectedTable(entries) {
|
|
|
115
127
|
}
|
|
116
128
|
return freezeTable(out);
|
|
117
129
|
}
|
|
118
|
-
function pathViewSegments(path,
|
|
130
|
+
function pathViewSegments(path, normalization, seps = BOTH_SEPARATOR_FAMILIES, anchorFloor = 0) {
|
|
119
131
|
const segs = [];
|
|
132
|
+
const win32 = normalization !== "literal";
|
|
120
133
|
for (const raw of path.split(seps)) {
|
|
121
134
|
if (raw.length === 0)
|
|
122
135
|
continue;
|
|
@@ -131,11 +144,17 @@ function pathViewSegments(path, win32, seps = BOTH_SEPARATOR_FAMILIES, anchorFlo
|
|
|
131
144
|
segs.push("..");
|
|
132
145
|
continue;
|
|
133
146
|
}
|
|
134
|
-
const stripped =
|
|
147
|
+
const stripped = normalization === "literal" ? raw : stripWin32Component(raw, normalization);
|
|
135
148
|
segs.push(stripped.length > 0 ? stripped : raw);
|
|
136
149
|
}
|
|
137
150
|
return segs;
|
|
138
151
|
}
|
|
152
|
+
const WIN32_NORMALIZATIONS = [
|
|
153
|
+
{ invisibleFirst: false, stream: false },
|
|
154
|
+
{ invisibleFirst: false, stream: true },
|
|
155
|
+
{ invisibleFirst: true, stream: false },
|
|
156
|
+
{ invisibleFirst: true, stream: true },
|
|
157
|
+
];
|
|
139
158
|
const BOTH_SEPARATOR_FAMILIES = /[\\/]/;
|
|
140
159
|
const POSIX_SEPARATOR_FAMILY = /\//;
|
|
141
160
|
function uncAnchorSegments(path) {
|
|
@@ -149,7 +168,7 @@ function relativeUnderDataRoot(path, roots) {
|
|
|
149
168
|
if (root.win ? !isWinFormPath(path) : isWinFormPath(path) || !path.startsWith("/"))
|
|
150
169
|
continue;
|
|
151
170
|
const seps = root.win ? BOTH_SEPARATOR_FAMILIES : POSIX_SEPARATOR_FAMILY;
|
|
152
|
-
const segs = pathViewSegments(path,
|
|
171
|
+
const segs = pathViewSegments(path, "literal", seps, uncAnchorSegments(path));
|
|
153
172
|
if (segs.length < root.segments.length)
|
|
154
173
|
continue;
|
|
155
174
|
if (root.segments.every((s, i) => segs[i] === s))
|
|
@@ -165,13 +184,13 @@ export function compileWriteProtection(entries, opts) {
|
|
|
165
184
|
const dataRootPaths = dataRootSpellings(opts?.dataRoot);
|
|
166
185
|
const rootViews = dataRootPaths.map((r) => {
|
|
167
186
|
const win = isWinFormPath(r);
|
|
168
|
-
return { win, segments: pathViewSegments(r,
|
|
187
|
+
return { win, segments: pathViewSegments(r, "literal", win ? BOTH_SEPARATOR_FAMILIES : POSIX_SEPARATOR_FAMILY, uncAnchorSegments(r)) };
|
|
169
188
|
});
|
|
170
189
|
const basenames = new Map();
|
|
171
190
|
const segments = new Map();
|
|
172
191
|
const runs = [];
|
|
173
192
|
for (const row of rows) {
|
|
174
|
-
const folded =
|
|
193
|
+
const folded = foldWriteProtectName(row.name);
|
|
175
194
|
if (row.kind === "basename") {
|
|
176
195
|
if (!basenames.has(folded))
|
|
177
196
|
basenames.set(folded, row.name);
|
|
@@ -187,7 +206,7 @@ export function compileWriteProtection(entries, opts) {
|
|
|
187
206
|
const judgeSegments = (raw) => {
|
|
188
207
|
if (raw.length === 0)
|
|
189
208
|
return null;
|
|
190
|
-
const segs = raw.map(
|
|
209
|
+
const segs = raw.map(foldWriteProtectSegment);
|
|
191
210
|
const base = basenames.get(segs[segs.length - 1] ?? "");
|
|
192
211
|
if (base !== undefined)
|
|
193
212
|
return { name: base, kind: "basename" };
|
|
@@ -205,9 +224,20 @@ export function compileWriteProtection(entries, opts) {
|
|
|
205
224
|
}
|
|
206
225
|
return null;
|
|
207
226
|
};
|
|
208
|
-
const judgeViews = (spelling) =>
|
|
209
|
-
judgeSegments(pathViewSegments(spelling,
|
|
210
|
-
|
|
227
|
+
const judgeViews = (spelling) => {
|
|
228
|
+
const posix = judgeSegments(pathViewSegments(spelling, "literal", POSIX_SEPARATOR_FAMILY, uncAnchorSegments(spelling)));
|
|
229
|
+
if (posix !== null)
|
|
230
|
+
return posix;
|
|
231
|
+
const bothSeparators = judgeSegments(pathViewSegments(spelling, "literal"));
|
|
232
|
+
if (bothSeparators !== null)
|
|
233
|
+
return bothSeparators;
|
|
234
|
+
for (const normalization of WIN32_NORMALIZATIONS) {
|
|
235
|
+
const hit = judgeSegments(pathViewSegments(spelling, normalization));
|
|
236
|
+
if (hit !== null)
|
|
237
|
+
return hit;
|
|
238
|
+
}
|
|
239
|
+
return null;
|
|
240
|
+
};
|
|
211
241
|
const judgeSpelled = (spelled) => judgeViews(relativeUnderDataRoot(spelled, rootViews) ?? spelled);
|
|
212
242
|
const judgeSpelling = (path, cwd) => {
|
|
213
243
|
const base = typeof cwd === "string" && cwd.length > 0 ? cwd : undefined;
|
|
@@ -231,31 +261,55 @@ export function compileWriteProtection(entries, opts) {
|
|
|
231
261
|
return { kind: "clear" };
|
|
232
262
|
const family = pathFamilyOf({ root: rootPath, cwd: ctx.cwd ?? env.cwd });
|
|
233
263
|
const base = ctx.base ?? ctx.cwd ?? rootPath;
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
264
|
+
let noted = false;
|
|
265
|
+
const noteAbsence = (cause, unresolvedSymlink) => {
|
|
266
|
+
if (noted)
|
|
267
|
+
return;
|
|
268
|
+
noted = true;
|
|
269
|
+
opts?.onViewAbsent?.({ cause, unresolvedSymlink });
|
|
270
|
+
};
|
|
271
|
+
let canonKey;
|
|
272
|
+
try {
|
|
273
|
+
const canon = await canonicalizeTarget(env, path, ctx.signal, family, base);
|
|
274
|
+
if (canon.ok)
|
|
275
|
+
canonKey = canon.key;
|
|
276
|
+
else
|
|
277
|
+
noteAbsence(canon.message, canon.unresolvedSymlink === true);
|
|
278
|
+
}
|
|
279
|
+
catch (err) {
|
|
280
|
+
noteAbsence(err instanceof Error ? err.message : String(err), false);
|
|
281
|
+
}
|
|
282
|
+
try {
|
|
283
|
+
if (canonKey !== undefined) {
|
|
284
|
+
const byTarget = judgeViews(canonKey);
|
|
285
|
+
if (byTarget !== null) {
|
|
286
|
+
for (const rootKey of await canonicalDataRootKeys(env, dataRootPaths, ctx.signal)) {
|
|
287
|
+
const relative = relativeUnderRoot(canonKey, rootKey);
|
|
288
|
+
if (relative === null)
|
|
289
|
+
continue;
|
|
290
|
+
if (relative === "")
|
|
291
|
+
return { kind: "clear" };
|
|
292
|
+
const remainder = judgeViews(relative);
|
|
293
|
+
return remainder === null ? { kind: "clear" } : { kind: "hit", hit: remainder, via: "target" };
|
|
294
|
+
}
|
|
295
|
+
return { kind: "hit", hit: byTarget, via: "target" };
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
for (const hop of await symlinkChainHops(env, path, ctx.signal, family, base, (cause) => noteAbsence(cause, false))) {
|
|
299
|
+
const byHop = judgeSpelled(hop);
|
|
300
|
+
if (byHop === null)
|
|
242
301
|
continue;
|
|
243
|
-
if (
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
302
|
+
if (canonKey !== undefined) {
|
|
303
|
+
for (const rootKey of await canonicalDataRootKeys(env, dataRootPaths, ctx.signal)) {
|
|
304
|
+
if (relativeUnderRoot(canonKey, rootKey) !== null)
|
|
305
|
+
return { kind: "clear" };
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
return { kind: "hit", hit: byHop, via: "chain" };
|
|
247
309
|
}
|
|
248
|
-
return { kind: "hit", hit: byTarget, via: "target" };
|
|
249
310
|
}
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
if (byHop === null)
|
|
253
|
-
continue;
|
|
254
|
-
for (const rootKey of await canonicalDataRootKeys(env, dataRootPaths, ctx.signal)) {
|
|
255
|
-
if (relativeUnderRoot(canon.key, rootKey) !== null)
|
|
256
|
-
return { kind: "clear" };
|
|
257
|
-
}
|
|
258
|
-
return { kind: "hit", hit: byHop, via: "chain" };
|
|
311
|
+
catch (err) {
|
|
312
|
+
noteAbsence(err instanceof Error ? err.message : String(err), false);
|
|
259
313
|
}
|
|
260
314
|
return { kind: "clear" };
|
|
261
315
|
},
|
|
@@ -7,6 +7,21 @@ import type { SchedulerCapability, ScheduledIntent, SchedulerContext, ScheduledT
|
|
|
7
7
|
import { SchedulerError } from "../../core/scheduler.js";
|
|
8
8
|
/** Convert user-facing timeout seconds into a positive, timer-safe millisecond delay. */
|
|
9
9
|
export declare function resolveExecTimeoutMs(timeoutSeconds: unknown): number | undefined;
|
|
10
|
+
/**
|
|
11
|
+
* Anchor a RELATIVE symlink target at its link's own directory, UNFOLDED and with exactly one separator
|
|
12
|
+
* between the two. A directory that IS a root already ends in its own separator (`/`, `C:\`, `C:/`,
|
|
13
|
+
* `\\host\share\`, all of which `dirname` answers that way), and concatenating a second one mints a
|
|
14
|
+
* DOUBLE-separator spelling for a path that has one spelling — `/tmp -> private/tmp` came back as
|
|
15
|
+
* `//private/tmp`, which the judges that walk this chain then match against nothing, because a guarded row
|
|
16
|
+
* and a containment root are both written with single separators. Joining through `path.resolve`/`path.join`
|
|
17
|
+
* would fix the separator and fold `..` with it, which is the one thing this walk may not do.
|
|
18
|
+
*
|
|
19
|
+
* `separator` is the one the caller's `dirname` writes, passed rather than read from the module so the rule
|
|
20
|
+
* is a pure function of its inputs. A backslash counts as a terminator only where it IS a separator: on a
|
|
21
|
+
* POSIX tree a directory whose name ends in one (`/a/b\`) is an ordinary name, and reading it as terminated
|
|
22
|
+
* would rename `/a/b\/t` to `/a/b\t` — the same class of rewrite as folding `..` lexically.
|
|
23
|
+
*/
|
|
24
|
+
export declare function anchorAtLinkDir(linkDir: string, target: string, separator: string): string;
|
|
10
25
|
/** review finding (win32): `where bash.exe` can resolve to `System32\bash.exe` — the
|
|
11
26
|
* WSL LAUNCHER, not a native shell. Running it drops into a Linux subsystem where Windows cwd/paths
|
|
12
27
|
* do not exist; silently adopting it is exactly the "wrong shell, false green" failure D1 forbids.
|
|
@@ -171,8 +186,10 @@ export declare class NodeExecutionEnv implements ExecutionEnv, BackgroundShellCa
|
|
|
171
186
|
* target, until a hop is not a link (`EINVAL`), is absent (`ENOENT` / `ENOTDIR`), repeats, or the bound is
|
|
172
187
|
* reached. A relative target is ANCHORED at its link's directory and never folded — `..` is the filesystem's
|
|
173
188
|
* to resolve during the next `readlink`'s own lookup (a lexical fold reads `bridge/../next` as `next` and misses
|
|
174
|
-
* every link behind `bridge`).
|
|
175
|
-
*
|
|
189
|
+
* every link behind `bridge`). Anchoring puts EXACTLY ONE separator between the directory and the target
|
|
190
|
+
* ({@link anchorAtLinkDir}); a root directory already ends in its own. One syscall per hop, no `lstat`. On a
|
|
191
|
+
* win32 host a share-shaped hop is kept and ends the walk unprobed. Any other errno is an answer nobody can
|
|
192
|
+
* use (`err`), never a shortened chain.
|
|
176
193
|
*/
|
|
177
194
|
canonicalChain(path: string): Promise<Result<SymlinkChain, FileError>>;
|
|
178
195
|
exists(path: string): Promise<Result<boolean, FileError>>;
|
|
@@ -42,6 +42,10 @@ function fileKindFromStats(stats) {
|
|
|
42
42
|
return undefined;
|
|
43
43
|
}
|
|
44
44
|
const HAS_POSIX_MODE_FACE = process.platform !== "win32";
|
|
45
|
+
export function anchorAtLinkDir(linkDir, target, separator) {
|
|
46
|
+
const endsInSeparator = linkDir.endsWith(separator) || (separator === "\\" && linkDir.endsWith("/"));
|
|
47
|
+
return endsInSeparator ? `${linkDir}${target}` : `${linkDir}${separator}${target}`;
|
|
48
|
+
}
|
|
45
49
|
const SYMLINK_CHAIN_HOP_BOUND = 64;
|
|
46
50
|
function fileInfoFromStats(path, stats) {
|
|
47
51
|
const kind = fileKindFromStats(stats);
|
|
@@ -1043,7 +1047,7 @@ export class NodeExecutionEnv {
|
|
|
1043
1047
|
return ok({ hops });
|
|
1044
1048
|
return err(toFileError(error, cur));
|
|
1045
1049
|
}
|
|
1046
|
-
const next = isAbsolute(target) ? target :
|
|
1050
|
+
const next = isAbsolute(target) ? target : anchorAtLinkDir(dirname(cur), target, sep);
|
|
1047
1051
|
if (seen.has(next))
|
|
1048
1052
|
break;
|
|
1049
1053
|
hops.push(next);
|
package/dist/index.d.ts
CHANGED
|
@@ -57,7 +57,7 @@ export { assertOracleIsolation, type GraderEnv, type OracleIsolationVerdict, typ
|
|
|
57
57
|
export { decideAutoPromote, deriveTripwire, FROZEN_DENYLIST_FLOOR, type AutoPromoteTerminal, type AutoPromoteInputs, type PromotedRecord, type TripwireResult, } from "./core/auto-promote.js";
|
|
58
58
|
export { runCascade, type CascadeRung, type CascadeConfig, type CascadeAttempt, type CascadeRunResult, type GateVerdict, } from "./agents/cascade.js";
|
|
59
59
|
export { pgQuery, mysqlQuery, sqliteQuery } from "./tools/sql-adapters.js";
|
|
60
|
-
export { materializeMcpTools, MCP_PREFIX, type MaterializedMcp, type McpServerStatus, type McpRefreshResult } from "./core/mcp.js";
|
|
60
|
+
export { materializeMcpTools, MCP_PREFIX, type MaterializedMcp, type McpServerStatus, type McpRefreshResult, type McpReconnectResult } from "./core/mcp.js";
|
|
61
61
|
export { MCP_FAILURE_KINDS, MCP_DELIVERY_VERDICTS, classifyMcpFailure, type McpFailure, type McpFailureKind, type McpDelivered } from "./core/mcp-failure.js";
|
|
62
62
|
export { MCP_INJECTION_DROP_REASONS, MCP_INJECTION_DROP_TEXT, mcpInjectionDroppedNotice, type McpInjectionDropReason, type McpInjectionDropFacts } from "./core/mcp-injection-drop.js";
|
|
63
63
|
export { askUnresolvableNotice, type AskUnresolvableFacts } from "./core/ask-unresolvable-notice.js";
|
|
@@ -70,7 +70,7 @@ export { createSessionRulePolicy } from "./core/runner/session-rule-policy.js";
|
|
|
70
70
|
export { LOCKED_KEY_REGISTRY, resolveLockedKeys, type LockedKey, type LockedConfig } from "./core/locked-config.js";
|
|
71
71
|
export { BUILTIN_COMPLIANCE_DENIES, COMPLIANCE_CAPABILITIES, WEB_FETCH_TOOL_NAME, complianceCallDenial, resolveComplianceDenies, type ComplianceCapability, type CompliancePosture, type ComplianceProfile, } from "./core/compliance.js";
|
|
72
72
|
export { admitMemoryScopes, foldAdmissionFreeze, type OwnOrgAdmissionVerdict, type MemoryAdmissionInput, type MemoryAdmissionOutcome, type MemoryAdmissionVerdict, type MemoryScopeAdmission, type MemoryScopeOrigin, type MemoryScopeRequest, } from "./core/memory-admission.js";
|
|
73
|
-
export { assertRetentionCapability, type ManagedRetentionCapability, type RetentionDeclaration, type RetentionDeclaring, type RetentionPolicy, type RetentionReceipt, } from "./core/retention.js";
|
|
73
|
+
export { assertRetentionCapability, RETENTION_CASCADE_DOMAINS, RETENTION_CASCADE_EXEMPT, type ManagedRetentionCapability, type RetentionDeclaration, type RetentionDeclaring, type RetentionPolicy, type RetentionReceipt, } from "./core/retention.js";
|
|
74
74
|
export { GOVERNANCE_CODES, governanceRetryClass, type GovernanceCode, type GovernanceRetryClass } from "./core/governance-codes.js";
|
|
75
75
|
export { NOTICE_AUDIENCE, noticeAudienceOf, ENGINE_NOTICE_CODES, type EngineNoticeCode, type NoticeAudience } from "./core/governance-codes.js";
|
|
76
76
|
export { TtlSessionStore, type TtlSessionStoreOptions, type EvictPolicy } from "./core/session-store.js";
|
|
@@ -105,7 +105,7 @@ export { classifyCompoundReadonlyDetailed, formatOutOfRootReadApprovalOption, ty
|
|
|
105
105
|
export { resolveBashTimeoutCaps } from "./tools/fs/index.js";
|
|
106
106
|
export { READ_FACE_DEFAULT_DENY_ENTRIES, READ_FACE_BUILTIN_DENY_TABLE, READ_DENY_BUILTIN_TIERS, READ_DENY_DEFAULT_TIERS, resolveReadDenyBuiltins, compileReadDeny, type ReadDenyEntry, type ReadDenyMatcher, type NormalizedReadDenyEntry, type ReadDenyBuiltinTier, type ReadDenyBuiltinRow, type ReadDenyBuiltinConfig, } from "./tools/fs/index.js";
|
|
107
107
|
export { deploymentFaceClampNotice, resolveContainmentFace, type ContainmentFace, type ContainmentFaceInputs, type ContainmentFaceKind, type ContainmentFaceLayer, } from "./tools/fs/index.js";
|
|
108
|
-
export { WRITE_PROTECTED_DEFAULT_TABLE, resolveWriteProtectedTable, compileWriteProtection, type WriteProtectedEntry, type WriteProtectedRow, type WriteProtectedKind, type WriteProtectedHit, type WriteProtectionMatcher, type WriteProtectionVerdict, type WriteProtectionJudgeContext, type WriteProtectionCompileOptions, type WriteProtectionCheck, WRITE_PROTECTION_TARGET_VIEWS, type WriteProtectionTargetView, type WriteProtectionMount, } from "./core/write-protect.js";
|
|
108
|
+
export { WRITE_PROTECTED_DEFAULT_TABLE, resolveWriteProtectedTable, compileWriteProtection, type WriteProtectedEntry, type WriteProtectedRow, type WriteProtectedKind, type WriteProtectedHit, type WriteProtectionMatcher, type WriteProtectionVerdict, type WriteProtectionViewAbsence, type WriteProtectionJudgeContext, type WriteProtectionCompileOptions, type WriteProtectionCheck, WRITE_PROTECTION_TARGET_VIEWS, type WriteProtectionTargetView, type WriteProtectionMount, } from "./core/write-protect.js";
|
|
109
109
|
export { InMemoryToolResultStore, OFFLOAD_TOOL_NAME, DEFAULT_TOOL_RESULT_THRESHOLD_CHARS, assertSafeToolResultRef, buildToolResultRef, toolResultContentSegment, MAX_MINTED_TOOL_RESULT_REF_CHARS, type ToolResultProvenance, assertToolResultProvenanceMatch, normalizeToolResultProvenance, toolResultProvenanceOf, ToolResultRefConflictError, TOOL_RESULT_REF_CONFLICT_CODE, type ToolResultStore, type ToolResultSlice, type ToolResultDeletionReport, } from "./core/tool-result-store.js";
|
|
110
110
|
export { InMemoryCheckpointStore, CheckpointError, mintCheckpointId, mintCheckpointToken, checkpointVersionOf, CURRENT_CHECKPOINT_VERSION, MAX_SUPPORTED_CHECKPOINT_VERSION, ORG_ADMISSION_CHECKPOINT_VERSION, F012_CHECKPOINT_VERSION, REAL_APPROVAL_CHECKPOINT_VERSION, RESOURCE_CHECKPOINT_VERSION, TOKEN_CHECKPOINT_VERSION, debitLedger, remainingBudgetMicroUsd, remainingTokens, winnerFromOutcome, validatePendingSteer, readPendingSteerQueue, appendPendingSteer, MAX_PENDING_STEER_CHARS, MAX_PENDING_STEER_ENTRIES, PENDING_STEER_QUEUE_BYTE_BUDGET_BYTES, PENDING_STEER_FROZEN_FIELDS, ACTOR_ASSERTION_FROZEN_FIELDS, MAX_ACTOR_FIELD_CHARS, MAX_STEER_INPUT_ID_CHARS, type ActorAssertion, type PendingSteerEntry, type PendingSteerInput, riskSeverity, buildRiskDescriptor, summarizeCheckpoint, type RiskDescriptor, type ProbeCause, type ProbeCauseOperands, type CheckpointStore, type CheckpointSummary, type Checkpoint, type CheckpointToken, type CheckpointGate, type CheckpointState, type SerializedCheckpointState, type CheckpointFaultMode, type PendingAction, type ResumeOutcome, type ResolvedOutcome, type ReopenReason, type ResolveExpectation, type TerminalClaimIntent, type TerminalClaimOutcome, type SafetyAxis, type RealApprovalGateBit, type ResourceLedger, type ResourceLimitReason, type PlatformLimitReason, type CheckpointRow, realApprovalOrgFact, resolveCheckpointStore, checkpointStoreExecutionUndeclared, } from "./core/checkpoint-store.js";
|
|
111
111
|
export { EXECUTION_OUTCOME_RECORD_WORDS, EXECUTION_RECORD_LEAVES_ROW_UNRECORDED, type ExecutionOutcomeRecordWord, type ExecutionRecordRowFacts, type ExecutionVerdict, ExecutionOutcomeConflictError, checkpointExecutionRecorded, executionRecordDisposition, sameExecutionRecord, executionVerdict, } from "./core/checkpoint-execution-record.js";
|
|
@@ -225,7 +225,8 @@ export { termSet, jaccardDistance, cosineDistance } from "./core/memory-vector.j
|
|
|
225
225
|
export { encodeSurfacedKey, buildManifestText, validateSelectedIds, composeSelectiveBody, formatMemoryAge, resolveLinkedIds, RECALL_CAVEAT, DEFAULT_MAX_SELECTED, DEFAULT_MAX_LINKED, type MemorySelector, type MemorySelectRequest, type SelectiveRecallOptions, type SelectiveRecallResult, type LayeredRecallOptions, type LayeredRecallResult, } from "./core/memory-recall.js";
|
|
226
226
|
export { runMemoryConsolidation, CONSOLIDATION_SYSTEM_PROMPT, DEFAULT_CONSOLIDATION_BAND, DEFAULT_CONSOLIDATION_SEARCH_LIMIT, DEFAULT_CONSOLIDATION_MAX_NOTES, normalizeForExactMatch, type ConsolidationParams, type ConsolidationStats, type ConsolidationNote, type ConsolidationLLM, } from "./core/runner/memory-consolidation.js";
|
|
227
227
|
export { consolidateScope, advanceCursorAfterInline, type ConsolidateScopeDeps, type ConsolidateScopeOptions, } from "./core/consolidate-scope.js";
|
|
228
|
-
export { resolveMemoryConsolidationDriver,
|
|
228
|
+
export { resolveMemoryConsolidationDriver, autoRunOnRecommendationEffective, // the ONE arming reading (`memory.auto_consolidation.arming_has_one_resolver`) — the seat's absence is not "off"
|
|
229
|
+
type MemoryConsolidationDriverDeps, } from "./core/runner/memory-consolidation-driver.js";
|
|
229
230
|
export { DEFAULT_COMPACTION_INSTRUCTIONS } from "./core/auto-compaction.js";
|
|
230
231
|
export { DEFAULT_SYSTEM_PROMPT, CODE_AGENT_PROMPT, SUBAGENT_PROMPT, CODE_SYSTEM_PROMPT, MEMORY_GUIDANCE, MEMORY_SAFETY, MEMORY_HYGIENE, NO_PERSISTENT_MEMORY_NOTICE, OUTPUT_EFFICIENCY, CYBER_RISK, HARNESS_SECTION_ANCHOR, URL_SAFETY, SUMMARIZE_TOOL_RESULTS, EXECUTION_ENVIRONMENT, EXECUTION_ENVIRONMENT_OPEN_READS, executionEnvironmentBlockFor, harnessContext, buildEnvironmentContext, buildGitSnapshot, buildScratchpadSection, GIT_STATUS_MAX_CHARS, formatLocalDate, type EnvironmentFacts, defaultPromptProvider, composeSystemPrompt, composeConstitution, constitutionBlocks, type PromptBlock, analyzePromptCacheFriendliness, assertPromptCacheFriendly, type PromptProvider, type StablePromptContext, type PromptCacheReport, type PromptTextDeclaration, } from "./prompts/default.js";
|
|
231
232
|
export { SUPERVISOR_PROMPT, ORCHESTRATION_GUIDANCE, ORCHESTRATION_AWARENESS, GOAL_COMPLETION_GUIDANCE } from "./prompts/supervisor.js";
|
package/dist/index.js
CHANGED
|
@@ -56,7 +56,7 @@ export { createSessionRulePolicy } from "./core/runner/session-rule-policy.js";
|
|
|
56
56
|
export { LOCKED_KEY_REGISTRY, resolveLockedKeys } from "./core/locked-config.js";
|
|
57
57
|
export { BUILTIN_COMPLIANCE_DENIES, COMPLIANCE_CAPABILITIES, WEB_FETCH_TOOL_NAME, complianceCallDenial, resolveComplianceDenies, } from "./core/compliance.js";
|
|
58
58
|
export { admitMemoryScopes, foldAdmissionFreeze, } from "./core/memory-admission.js";
|
|
59
|
-
export { assertRetentionCapability, } from "./core/retention.js";
|
|
59
|
+
export { assertRetentionCapability, RETENTION_CASCADE_DOMAINS, RETENTION_CASCADE_EXEMPT, } from "./core/retention.js";
|
|
60
60
|
export { GOVERNANCE_CODES, governanceRetryClass } from "./core/governance-codes.js";
|
|
61
61
|
export { NOTICE_AUDIENCE, noticeAudienceOf, ENGINE_NOTICE_CODES } from "./core/governance-codes.js";
|
|
62
62
|
export { TtlSessionStore } from "./core/session-store.js";
|
|
@@ -183,7 +183,7 @@ export { termSet, jaccardDistance, cosineDistance } from "./core/memory-vector.j
|
|
|
183
183
|
export { encodeSurfacedKey, buildManifestText, validateSelectedIds, composeSelectiveBody, formatMemoryAge, resolveLinkedIds, RECALL_CAVEAT, DEFAULT_MAX_SELECTED, DEFAULT_MAX_LINKED, } from "./core/memory-recall.js";
|
|
184
184
|
export { runMemoryConsolidation, CONSOLIDATION_SYSTEM_PROMPT, DEFAULT_CONSOLIDATION_BAND, DEFAULT_CONSOLIDATION_SEARCH_LIMIT, DEFAULT_CONSOLIDATION_MAX_NOTES, normalizeForExactMatch, } from "./core/runner/memory-consolidation.js";
|
|
185
185
|
export { consolidateScope, advanceCursorAfterInline, } from "./core/consolidate-scope.js";
|
|
186
|
-
export { resolveMemoryConsolidationDriver, } from "./core/runner/memory-consolidation-driver.js";
|
|
186
|
+
export { resolveMemoryConsolidationDriver, autoRunOnRecommendationEffective, } from "./core/runner/memory-consolidation-driver.js";
|
|
187
187
|
export { DEFAULT_COMPACTION_INSTRUCTIONS } from "./core/auto-compaction.js";
|
|
188
188
|
export { DEFAULT_SYSTEM_PROMPT, CODE_AGENT_PROMPT, SUBAGENT_PROMPT, CODE_SYSTEM_PROMPT, MEMORY_GUIDANCE, MEMORY_SAFETY, MEMORY_HYGIENE, NO_PERSISTENT_MEMORY_NOTICE, OUTPUT_EFFICIENCY, CYBER_RISK, HARNESS_SECTION_ANCHOR, URL_SAFETY, SUMMARIZE_TOOL_RESULTS, EXECUTION_ENVIRONMENT, EXECUTION_ENVIRONMENT_OPEN_READS, executionEnvironmentBlockFor, harnessContext, buildEnvironmentContext, buildGitSnapshot, buildScratchpadSection, GIT_STATUS_MAX_CHARS, formatLocalDate, defaultPromptProvider, composeSystemPrompt, composeConstitution, constitutionBlocks, analyzePromptCacheFriendliness, assertPromptCacheFriendly, } from "./prompts/default.js";
|
|
189
189
|
export { SUPERVISOR_PROMPT, ORCHESTRATION_GUIDANCE, ORCHESTRATION_AWARENESS, GOAL_COMPLETION_GUIDANCE } from "./prompts/supervisor.js";
|
|
@@ -297,7 +297,7 @@ function pickWhitelist(scriptSpec) {
|
|
|
297
297
|
if (!Array.isArray(readDenyPatternsRaw)) {
|
|
298
298
|
throw new WorkflowScriptError('agent(spec): `readDenyPatterns` must be an array of deny entries (a "/"-separated segment run such as ".ssh", or { pattern, caseSensitive? })');
|
|
299
299
|
}
|
|
300
|
-
const entries = mapUntrustedArray(readDenyPatternsRaw, "agent(spec): `readDenyPatterns`", MAX_SCRIPT_DENY_ENTRIES, "Every entry is judged against every path the child reads, for the child's whole run; the built-in
|
|
300
|
+
const entries = mapUntrustedArray(readDenyPatternsRaw, "agent(spec): `readDenyPatterns`", MAX_SCRIPT_DENY_ENTRIES, "Every entry is judged against every path the child reads, for the child's whole run; the deployment's own entries, and whichever built-in tiers the deployment switched on (none by default), are in force on top of these.", pickReadDenyEntry);
|
|
301
301
|
try {
|
|
302
302
|
compileReadDeny(entries, "agent(spec).readDenyPatterns");
|
|
303
303
|
}
|
|
@@ -51,8 +51,8 @@ parentReadFace?: () => TaskSpec["readFace"],
|
|
|
51
51
|
/** The WRITE seat's twin of the above — the host run's RESOLVED write-face containment, folded
|
|
52
52
|
* stricter-wins into every spawned child on its own seat (the two seats never read each other). */
|
|
53
53
|
parentWriteFace?: () => TaskSpec["writeFace"],
|
|
54
|
-
/** Twin of the above for the deny-set additions (
|
|
55
|
-
*
|
|
54
|
+
/** Twin of the above for the deny-set additions (the extra entries the host's own deployment/task
|
|
55
|
+
* layers stacked on; the built-in rows the DEPLOYMENT switched on — none by default — apply beside them). */
|
|
56
56
|
parentReadDenyPatterns?: () => TaskSpec["readDenyPatterns"],
|
|
57
57
|
/** #345 ③ — the HOST task's write-hands clamp is ON (`spec.handsReadOnly === true`). Injected
|
|
58
58
|
* tighten-only into every spawned child, like the read-face clamp above; see the injection
|
|
@@ -47,9 +47,16 @@ export declare const ARGV_REENTRY_PROGRAM_RE: RegExp;
|
|
|
47
47
|
export declare const ARGV_REENTRY_DEFAULT_PROGRAM = "echo";
|
|
48
48
|
/**
|
|
49
49
|
* What a launcher declares about its OWN options: each exact spelling with its ARITY — `0` for a switch, `1` for an
|
|
50
|
-
* option whose value is the next token.
|
|
51
|
-
*
|
|
52
|
-
*
|
|
50
|
+
* option whose value is the next token. Every spelling not in the map falls to the refusal (the conservative side,
|
|
51
|
+
* and the verdict those spellings always had); a `1` with no token left to take is not readable either.
|
|
52
|
+
*
|
|
53
|
+
* THREE SPELLINGS OF ONE DECLARATION, because getopt has three: an arity-1 entry is honoured separated (`-k 5`),
|
|
54
|
+
* fused to its long name (`--signal=TERM`) and fused to its short letter (`-k5`), and an arity-0 short entry inside
|
|
55
|
+
* a cluster of arity-0 letters (`-pv`). Reading only the exact spelling made one program two.
|
|
56
|
+
*
|
|
57
|
+
* WHAT A ROW MAY NOT GET WRONG: declaring an arity-1 option as arity 0 steps onto its VALUE and reads the value as
|
|
58
|
+
* the program — the one direction that turns a refusal into a wrong answer rather than a lost one. A row carries
|
|
59
|
+
* only options whose arity every supported implementation agrees on; a flag no row declares still refuses.
|
|
53
60
|
*/
|
|
54
61
|
export interface LauncherRow {
|
|
55
62
|
/** Consulted ONLY for the launcher the command line itself names — a bare keyword in front of the command
|
|
@@ -58,6 +65,19 @@ export interface LauncherRow {
|
|
|
58
65
|
* them would turn a whole refusal into an ordinary walked segment — a widening, where every other read of this
|
|
59
66
|
* table only ever finds MORE program to judge. */
|
|
60
67
|
readonly optionArity: ReadonlyMap<string, 0 | 1>;
|
|
68
|
+
/** A bare NEGATIVE integer in this launcher's option section is its OWN argument (`nice -5 <cmd>`), not a flag
|
|
69
|
+
* the table cannot read. Per row: elsewhere a dash-leading token is an option, and reading one as a number
|
|
70
|
+
* would step over a flag whose meaning this table does not know. */
|
|
71
|
+
readonly negativeIntegerIsOwnArgument?: true;
|
|
72
|
+
/** Positional operands the launcher takes BEFORE the program, consumed whatever they spell (`timeout DURATION
|
|
73
|
+
* COMMAND`); a spelling-based reading under-accepted, and every spelling it missed became the program word. */
|
|
74
|
+
readonly requiredOperands?: number;
|
|
75
|
+
/** The launcher reads NAME=VALUE operands with ITS OWN name grammar (`env 1=x …`), wider than the shell's. */
|
|
76
|
+
readonly assignmentOperands?: true;
|
|
77
|
+
/** The launcher hands its operands to a SHELL as text (`watch "cat /x"` runs `sh -c`): no program word to read. */
|
|
78
|
+
readonly shellText?: true;
|
|
79
|
+
/** With no program word the launcher runs a SHELL: piped text would reach it, so an empty program position refuses. */
|
|
80
|
+
readonly whenNoProgram?: "shell";
|
|
61
81
|
}
|
|
62
82
|
/**
|
|
63
83
|
* The ONE launcher truth: programs that RUN ANOTHER PROGRAM named in ordinary argv tokens, so a declared reader can
|
|
@@ -136,7 +156,8 @@ export interface ProgramPosition {
|
|
|
136
156
|
*/
|
|
137
157
|
export declare function readProgramPosition(toks: SegmentTokens): ProgramPosition;
|
|
138
158
|
/** Does this program position hand a program operands the walk cannot see? True when the chain re-enters through
|
|
139
|
-
* stdin AND the program it runs is not
|
|
140
|
-
|
|
159
|
+
* stdin AND the program it runs is not one the caller accepts as a stream target. ONE reading, shared by every
|
|
160
|
+
* consumer; WHICH targets are accepted is the caller's declaration, not this reader's. */
|
|
161
|
+
export declare function argvReentryUnjudged(pos: ProgramPosition, acceptedTargets: ReadonlySet<string>): boolean;
|
|
141
162
|
/** ONE sentence per refusal kind, minted here and nowhere else. */
|
|
142
163
|
export declare function programPositionRefusalSentence(refusal: ProgramPositionRefusal): string;
|