@sema-agent/core 7.19.0 → 7.20.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +199 -2
- package/dist/agents/subagent.js +12 -20
- package/dist/agents/teacher.js +2 -5
- package/dist/agents/verify.js +21 -10
- package/dist/brain/anthropic.js +3 -1
- package/dist/brain/open-responses.js +4 -2
- package/dist/brain/openai.js +3 -1
- package/dist/brain/stream-engine.d.ts +4 -0
- package/dist/brain/stream-engine.js +4 -0
- package/dist/core/auto-mode.d.ts +37 -18
- package/dist/core/auto-mode.js +1 -1
- package/dist/core/child-clamp-seats.d.ts +79 -0
- package/dist/core/child-clamp-seats.js +29 -0
- package/dist/core/engine-notice.d.ts +76 -49
- package/dist/core/fs-write-gate-policy.d.ts +17 -9
- package/dist/core/fs-write-gate-policy.js +51 -4
- package/dist/core/gate-bounded-await.d.ts +38 -0
- package/dist/core/gate-bounded-await.js +53 -0
- package/dist/core/gate-fold.js +16 -48
- package/dist/core/gate-lanes.js +11 -3
- package/dist/core/gate-outcome.d.ts +9 -6
- package/dist/core/governance-codes.d.ts +16 -1
- package/dist/core/governance-codes.js +14 -0
- package/dist/core/hooks.d.ts +8 -8
- package/dist/core/memory-engine/engine.d.ts +14 -9
- package/dist/core/memory-engine/engine.js +21 -8
- package/dist/core/memory-engine/layout.d.ts +31 -0
- package/dist/core/memory-engine/layout.js +68 -3
- package/dist/core/memory-engine/tools.js +6 -0
- package/dist/core/memory-engine/types.d.ts +24 -0
- package/dist/core/memory.d.ts +19 -0
- package/dist/core/memory.js +12 -0
- package/dist/core/remote-env.d.ts +32 -0
- package/dist/core/remote-env.js +4 -1
- package/dist/core/runner/advertised-writable-dirs.d.ts +59 -1
- package/dist/core/runner/advertised-writable-dirs.js +51 -3
- package/dist/core/runner/announce-once-ledger.d.ts +15 -0
- package/dist/core/runner/announce-once-ledger.js +8 -0
- package/dist/core/runner/classifier-ladder.d.ts +5 -0
- package/dist/core/runner/classifier-ladder.js +13 -2
- package/dist/core/runner/contracts.d.ts +44 -1
- package/dist/core/runner/denial-limit-arms.d.ts +14 -1
- package/dist/core/runner/denial-limit-arms.js +5 -4
- package/dist/core/runner/env-capability-census.d.ts +30 -0
- package/dist/core/runner/env-capability-census.js +38 -0
- package/dist/core/runner/forward-sink.d.ts +32 -0
- package/dist/core/runner/forward-sink.js +41 -0
- package/dist/core/runner/gate-exit.d.ts +4 -0
- package/dist/core/runner/gate-exit.js +4 -1
- package/dist/core/runner/git-status-frame.d.ts +0 -9
- package/dist/core/runner/listing-fold.d.ts +57 -0
- package/dist/core/runner/listing-fold.js +75 -0
- package/dist/core/runner/prepare-execution-env.d.ts +1 -1
- package/dist/core/runner/prepare-execution-env.js +2 -0
- package/dist/core/runner/prepare-gate-stations.d.ts +6 -0
- package/dist/core/runner/prepare-gate-stations.js +1 -3
- package/dist/core/runner/prepare-hands-readface.d.ts +4 -0
- package/dist/core/runner/prepare-hands-readface.js +3 -5
- package/dist/core/runner/prepare-listings.d.ts +3 -0
- package/dist/core/runner/prepare-listings.js +4 -2
- package/dist/core/runner/prepare-memory.js +7 -1
- package/dist/core/runner/prepare-policy-chain.js +5 -5
- package/dist/core/runner/prepare-prompt-inputs.d.ts +2 -2
- package/dist/core/runner/prepare-run-refs.d.ts +4 -2
- package/dist/core/runner/prepare-run-refs.js +5 -4
- package/dist/core/runner/prepare-task.js +8 -6
- package/dist/core/runner/prepare-wiring-manifest.d.ts +8 -1
- package/dist/core/runner/prepare-wiring-manifest.js +5 -2
- package/dist/core/runner/run-clock-and-content.js +3 -7
- package/dist/core/runner/run-harness-handlers.js +10 -10
- package/dist/core/runner/run-leg.js +28 -19
- package/dist/core/runner/run-settle-and-teardown.js +2 -5
- package/dist/core/runner/run-turn-boundary.js +44 -33
- package/dist/core/runner/runtask.js +2 -1
- package/dist/core/runner/synthetic-tools.d.ts +13 -39
- package/dist/core/runner/synthetic-tools.js +15 -59
- package/dist/core/runner/task-root-canonical.d.ts +45 -0
- package/dist/core/runner/task-root-canonical.js +18 -0
- package/dist/core/runner/turn-attachments.d.ts +125 -49
- package/dist/core/runner/turn-attachments.js +124 -66
- package/dist/core/runner/write-protection-station.d.ts +59 -0
- package/dist/core/runner/write-protection-station.js +32 -0
- package/dist/core/safe-notify.d.ts +5 -0
- package/dist/core/safe-notify.js +24 -2
- package/dist/core/sensitive-path-policy.d.ts +53 -27
- package/dist/core/sensitive-path-policy.js +16 -26
- package/dist/core/skill-listing-budget.d.ts +34 -40
- package/dist/core/skill-listing-budget.js +25 -26
- package/dist/core/skills-directory.js +17 -10
- package/dist/core/task-registry.js +2 -1
- package/dist/core/task-spec.d.ts +8 -7
- package/dist/core/tool-policy.d.ts +12 -1
- package/dist/core/tool-policy.js +39 -25
- package/dist/core/wiring-manifest.d.ts +31 -0
- package/dist/core/wiring-manifest.js +1 -0
- package/dist/core/write-protect.d.ts +124 -18
- package/dist/core/write-protect.js +91 -34
- package/dist/index.d.ts +6 -5
- package/dist/index.js +6 -5
- package/dist/orchestration/workflow-primitives.js +10 -20
- package/dist/stores/file/memory-store.d.ts +5 -2
- package/dist/stores/file/memory-store.js +8 -4
- package/dist/tools/fs/bash-readonly-classifier.d.ts +13 -2
- package/dist/tools/fs/bash-readonly-classifier.js +318 -36
- package/dist/tools/fs/fs-bash.d.ts +1 -1
- package/dist/tools/fs/fs-bash.js +12 -25
- package/dist/tools/fs/fs-shared.d.ts +22 -0
- package/dist/tools/fs/fs-shared.js +30 -0
- package/dist/tools/fs/index.d.ts +1 -1
- package/dist/tools/fs/index.js +1 -1
- package/package.json +2 -1
- package/test/export-surface.snapshot.json +25 -3
- package/wire-changes/core@7.20.0.json +568 -0
- package/wire-changes/core@7.20.1.json +183 -0
package/dist/core/tool-policy.js
CHANGED
|
@@ -26,19 +26,18 @@ function attestEngineSettlement(d, record, call) {
|
|
|
26
26
|
ENGINE_SETTLEMENTS.set(d, { settlement, origin: record.origin, toolCallId: call.toolCallId, toolName: call.toolName });
|
|
27
27
|
return d;
|
|
28
28
|
}
|
|
29
|
-
function
|
|
30
|
-
const
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
ASK_UNRESOLVABLE_CAUSES_SEAT.set(to, u);
|
|
29
|
+
function transferEngineAttestations(from, to) {
|
|
30
|
+
for (const seat of ENGINE_ATTESTATION_SEATS) {
|
|
31
|
+
const v = seat.get(from);
|
|
32
|
+
if (v !== undefined)
|
|
33
|
+
seat.set(to, v);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
function hasEngineAttestation(o) {
|
|
37
|
+
return ENGINE_ATTESTATION_SEATS.some((seat) => seat.has(o));
|
|
39
38
|
}
|
|
40
39
|
export function carryEngineAttestations(from, to) {
|
|
41
|
-
|
|
40
|
+
transferEngineAttestations(from, to);
|
|
42
41
|
}
|
|
43
42
|
export function carryPrecedingSettlement(preceding, to) {
|
|
44
43
|
if (ENGINE_SETTLEMENTS.get(to) !== undefined)
|
|
@@ -60,6 +59,19 @@ export function classifierDenyCauseOf(d, call) {
|
|
|
60
59
|
return undefined;
|
|
61
60
|
return v.cause;
|
|
62
61
|
}
|
|
62
|
+
const CLASSIFIER_ROUNDS_SEAT = new WeakMap();
|
|
63
|
+
export function attestClassifierRound(d, round, call) {
|
|
64
|
+
CLASSIFIER_ROUNDS_SEAT.set(d, { round, toolCallId: call.toolCallId, toolName: call.toolName });
|
|
65
|
+
return d;
|
|
66
|
+
}
|
|
67
|
+
export function classifierRoundOf(d, call) {
|
|
68
|
+
if (typeof d !== "object" || d === null)
|
|
69
|
+
return undefined;
|
|
70
|
+
const v = CLASSIFIER_ROUNDS_SEAT.get(d);
|
|
71
|
+
if (v === undefined || v.toolCallId !== call.toolCallId || v.toolName !== call.toolName)
|
|
72
|
+
return undefined;
|
|
73
|
+
return v.round;
|
|
74
|
+
}
|
|
63
75
|
const ASK_UNRESOLVABLE_CAUSES_SEAT = new WeakMap();
|
|
64
76
|
export function attestAskUnresolvableCause(d, cause, call) {
|
|
65
77
|
ASK_UNRESOLVABLE_CAUSES_SEAT.set(d, { cause, toolCallId: call.toolCallId, toolName: call.toolName });
|
|
@@ -73,6 +85,7 @@ export function askUnresolvableCauseOf(d, call) {
|
|
|
73
85
|
return undefined;
|
|
74
86
|
return v.cause;
|
|
75
87
|
}
|
|
88
|
+
const ENGINE_ATTESTATION_SEATS = [ENGINE_SETTLEMENTS, CLASSIFIER_DENY_CAUSES_SEAT, ASK_UNRESOLVABLE_CAUSES_SEAT, CLASSIFIER_ROUNDS_SEAT];
|
|
76
89
|
export function engineSettlementOf(d, call) {
|
|
77
90
|
if (typeof d !== "object" || d === null)
|
|
78
91
|
return undefined;
|
|
@@ -439,7 +452,8 @@ export function combinePolicies(...policies) {
|
|
|
439
452
|
let asked;
|
|
440
453
|
let current = req;
|
|
441
454
|
let rewrite;
|
|
442
|
-
|
|
455
|
+
const records = {};
|
|
456
|
+
let anyRecord = false;
|
|
443
457
|
let ruleAskText;
|
|
444
458
|
let probeMandateSeen = false;
|
|
445
459
|
let fallbackSeen;
|
|
@@ -448,23 +462,23 @@ export function combinePolicies(...policies) {
|
|
|
448
462
|
if (d.action === "deny") {
|
|
449
463
|
const out = rewrite?.updatedInput !== undefined ? { ...d, updatedInput: rewrite.updatedInput } : d;
|
|
450
464
|
if (out !== d) {
|
|
451
|
-
|
|
452
|
-
}
|
|
453
|
-
if (settledAllow !== undefined && ENGINE_SETTLEMENTS.get(out) === undefined) {
|
|
454
|
-
const owned = out === d ? { ...d } : out;
|
|
455
|
-
if (owned !== d)
|
|
456
|
-
transferEngineSettlement(d, owned);
|
|
457
|
-
transferEngineSettlement(settledAllow, owned);
|
|
458
|
-
return owned;
|
|
465
|
+
transferEngineAttestations(d, out);
|
|
459
466
|
}
|
|
460
|
-
|
|
467
|
+
if (!anyRecord)
|
|
468
|
+
return out;
|
|
469
|
+
const owned = out === d ? { ...d } : out;
|
|
470
|
+
transferEngineAttestations(records, owned);
|
|
471
|
+
transferEngineAttestations(d, owned);
|
|
472
|
+
return owned;
|
|
461
473
|
}
|
|
462
474
|
if (d.updatedInput !== undefined) {
|
|
463
475
|
current = { ...current, args: d.updatedInput };
|
|
464
476
|
rewrite = d;
|
|
465
477
|
}
|
|
466
|
-
if (d.action === "allow" &&
|
|
467
|
-
|
|
478
|
+
if (d.action === "allow" && hasEngineAttestation(d)) {
|
|
479
|
+
transferEngineAttestations(d, records);
|
|
480
|
+
anyRecord = true;
|
|
481
|
+
}
|
|
468
482
|
if (d.action === "ask" && (asked === undefined || (d.requiresRealApproval === true && asked.requiresRealApproval !== true))) {
|
|
469
483
|
asked = d;
|
|
470
484
|
}
|
|
@@ -484,10 +498,10 @@ export function combinePolicies(...policies) {
|
|
|
484
498
|
return merged !== undefined ? { ...withFallback, updatedInput: merged } : withFallback;
|
|
485
499
|
}
|
|
486
500
|
const allowed = rewrite ?? ALLOW;
|
|
487
|
-
if (
|
|
501
|
+
if (!anyRecord)
|
|
488
502
|
return allowed;
|
|
489
503
|
const out = { ...allowed };
|
|
490
|
-
|
|
504
|
+
transferEngineAttestations(records, out);
|
|
491
505
|
return out;
|
|
492
506
|
},
|
|
493
507
|
};
|
|
@@ -24,6 +24,7 @@ import type { RunnerDeps, TaskSpec } from "./types.js";
|
|
|
24
24
|
import { type StoreDurability } from "./checkpoint-store.js";
|
|
25
25
|
import type { WiringManifestHookEntry } from "./hook-seats.js";
|
|
26
26
|
import type { McpDelivered, McpFailureKind } from "./mcp-failure.js";
|
|
27
|
+
import type { WriteProtectionTargetView } from "./write-protect.js";
|
|
27
28
|
export type { StoreDurability };
|
|
28
29
|
/** The manifest-face projection of {@link StoreDurability}: `"declared_durable"` (the name says it —
|
|
29
30
|
* a DECLARATION relayed, not a verification) vs `"process_local"` (declared so, or fail-closed
|
|
@@ -319,6 +320,33 @@ export interface WiringManifest {
|
|
|
319
320
|
mounted: boolean;
|
|
320
321
|
lane?: LspLane;
|
|
321
322
|
};
|
|
323
|
+
/**
|
|
324
|
+
* EFFECTIVE half only, PRESENT IFF this leg compiled a write-protection judge — a deployment that
|
|
325
|
+
* replaced the table with `[]` opted the layer out entirely, and reports nothing here rather than a
|
|
326
|
+
* judge-shaped word about a judge that does not exist (absence = "no judge on this leg", which is a
|
|
327
|
+
* different fact from either value below, and strictly weaker than both).
|
|
328
|
+
*
|
|
329
|
+
* `targetView` is the JUDGE'S OWN word (`WriteProtectionMatcher.targetView`, relayed verbatim), and it
|
|
330
|
+
* is how an operator tells a hands-less deployment's write floor from a hands-ful one without inspecting
|
|
331
|
+
* the engine's seats — the same fact `config.write_protection_target_view_absent` announces once per run
|
|
332
|
+
* when a covered write tool is mounted beside a `"spelling-only"` judge.
|
|
333
|
+
*
|
|
334
|
+
* IN the fingerprint below (unlike `tools`/`lsp`/`hooks`): which view the judge got is an ASSEMBLY fact
|
|
335
|
+
* — it follows the table seat and whether the deployment wired hands at all — so legs of one assembly
|
|
336
|
+
* agree on it, which is exactly the equality the fingerprint advertises.
|
|
337
|
+
*
|
|
338
|
+
* @contract write_protection.target_view_disclosed — WHICH reading of a write's target the leg's
|
|
339
|
+
* write-protection judge holds is DISCLOSED, never inferred: the judge self-reports one of two words at
|
|
340
|
+
* its compile (`"target"` — it holds an execution environment and re-judges a table-missing spelling on
|
|
341
|
+
* its resolved real target; `"spelling-only"` — it holds none, so the spelling is the whole judgment and
|
|
342
|
+
* an alias onto a protected path is cleared), the leg's wiring manifest relays that word verbatim, and a
|
|
343
|
+
* `"spelling-only"` judge with a covered write tool mounted also announces
|
|
344
|
+
* `config.write_protection_target_view_absent` exactly once per run; the disclosure changes no verdict —
|
|
345
|
+
* the absence law it makes readable is the judge's own and stands unaltered.
|
|
346
|
+
*/
|
|
347
|
+
writeProtection?: {
|
|
348
|
+
targetView: WriteProtectionTargetView;
|
|
349
|
+
};
|
|
322
350
|
/** EFFECTIVE half only — a short, non-sensitive fingerprint (sha256 prefix over the canonical
|
|
323
351
|
* JSON of this manifest's own resolved facts; every field here is an enum/boolean/count, no
|
|
324
352
|
* secrets) so an operator can correlate legs that ran under the same resolved assembly. */
|
|
@@ -397,6 +425,9 @@ export interface WiringFacts {
|
|
|
397
425
|
mounted: boolean;
|
|
398
426
|
lane?: LspLane;
|
|
399
427
|
};
|
|
428
|
+
/** Effective half only — the compiled write-protection judge's OWN target-view word
|
|
429
|
+
* ({@link WiringManifest.writeProtection}); absent ⇒ this leg compiled no judge (an emptied table). */
|
|
430
|
+
writeProtectionTargetView?: WriteProtectionTargetView;
|
|
400
431
|
}
|
|
401
432
|
/** Named view of the deps seats the static half reads (a `Pick` of the real {@link RunnerDeps} —
|
|
402
433
|
* single-source shapes, no parallel hand-copied interface). */
|
|
@@ -141,6 +141,7 @@ export function deriveWiringManifest(facts) {
|
|
|
141
141
|
...(facts.half === "effective" && facts.tools !== undefined ? { tools: facts.tools } : {}),
|
|
142
142
|
...(facts.half === "effective" && facts.hooks !== undefined && facts.hooks.length > 0 ? { hooks: facts.hooks.map((h) => ({ ...h })) } : {}),
|
|
143
143
|
...(facts.half === "effective" && facts.lsp !== undefined ? { lsp: { ...facts.lsp } } : {}),
|
|
144
|
+
...(facts.half === "effective" && facts.writeProtectionTargetView !== undefined ? { writeProtection: { targetView: facts.writeProtectionTargetView } } : {}),
|
|
144
145
|
};
|
|
145
146
|
if (facts.half === "effective") {
|
|
146
147
|
const { leg: _leg, mcp: _mcp, tools: _tools, lsp: _lsp, hooks: _hooks, ...assembly } = manifest;
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import type { ExecutionEnv } from "../internal/harness-types.js";
|
|
2
|
+
import type { PermissionResult } from "./tool-policy.js";
|
|
1
3
|
import { type ToolCallLike } from "./tool-registry.js";
|
|
2
4
|
/**
|
|
3
5
|
* How one table row matches the judged path:
|
|
@@ -45,12 +47,58 @@ export declare function foldWriteProtectCase(s: string): string;
|
|
|
45
47
|
* candidate configuration with the engine's own rules.
|
|
46
48
|
*/
|
|
47
49
|
export declare function resolveWriteProtectedTable(entries?: readonly WriteProtectedEntry[]): readonly WriteProtectedRow[];
|
|
48
|
-
/**
|
|
49
|
-
*
|
|
50
|
+
/**
|
|
51
|
+
* The judge's answer for ONE covered write ({@link WriteProtectionMatcher.judge}):
|
|
52
|
+
* · `clear` — no row on either view: the write is not this layer's business;
|
|
53
|
+
* · `hit` — a row matched; `via` says which view named it: `"spelling"` (the anchored spelling, no
|
|
54
|
+
* filesystem consulted) or `"target"` (the resolved real target, the spelling being innocent);
|
|
55
|
+
* · `unresolvable` — the real target could not be resolved (an unfollowable symlink, an errored probe, a
|
|
56
|
+
* namespace spelling the tree refuses); `cause` is the canonicalizer's own sentence and the consumer
|
|
57
|
+
* REFUSES, an unjudged target never being vouched.
|
|
58
|
+
*/
|
|
59
|
+
export type WriteProtectionVerdict = {
|
|
60
|
+
readonly kind: "clear";
|
|
61
|
+
} | {
|
|
62
|
+
readonly kind: "hit";
|
|
63
|
+
readonly hit: WriteProtectedHit;
|
|
64
|
+
readonly via: "spelling" | "target";
|
|
65
|
+
} | {
|
|
66
|
+
readonly kind: "unresolvable";
|
|
67
|
+
readonly cause: string;
|
|
68
|
+
readonly unresolvedSymlink: boolean;
|
|
69
|
+
};
|
|
70
|
+
/** What one judgment knows about the call, all optional — every member has an absence reading. */
|
|
71
|
+
export interface WriteProtectionJudgeContext {
|
|
72
|
+
/** The call's LIVE tracked working directory (see {@link WriteProtectionMatcher.matchPath}). */
|
|
73
|
+
readonly cwd?: string;
|
|
74
|
+
/** The base a RELATIVE spelling resolves against on the TARGET view — the tool's own declared base
|
|
75
|
+
* ({@link pathTargetBaseOf}). Absent ⇒ `cwd`, then the compile-time `rootPath`, then the environment's
|
|
76
|
+
* own working directory: the same fallback chain the write tool itself walks. */
|
|
77
|
+
readonly base?: string;
|
|
78
|
+
/** Bounds the filesystem probes of the target view. */
|
|
79
|
+
readonly signal?: AbortSignal;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* WHICH reading of a write's TARGET a compiled judge has — its own word, and the vocabulary the wiring
|
|
83
|
+
* manifest discloses it with. `"target"`: the judge holds an execution environment, so a spelling that
|
|
84
|
+
* misses the table is judged a SECOND time on its resolved real target (an alias, a symlink, a `..` walk
|
|
85
|
+
* that lands on a protected row is seen). `"spelling-only"`: no environment, so the spelling IS the whole
|
|
86
|
+
* judgment and a path reaching a row only through an alias is cleared — the module header's absence law,
|
|
87
|
+
* unchanged by this word, which only makes it READABLE. Never derived by a reader from the judge's seats.
|
|
88
|
+
*/
|
|
89
|
+
export declare const WRITE_PROTECTION_TARGET_VIEWS: readonly ["spelling-only", "target"];
|
|
90
|
+
/** One of {@link WRITE_PROTECTION_TARGET_VIEWS}. */
|
|
91
|
+
export type WriteProtectionTargetView = (typeof WRITE_PROTECTION_TARGET_VIEWS)[number];
|
|
92
|
+
/** The compiled judge over one resolved table. `matchPath` is the SPELLING view alone (literal folded
|
|
93
|
+
* comparisons, no filesystem access — the admin preview face); `judge` is the whole judgment (see the
|
|
94
|
+
* module header for the two views). */
|
|
50
95
|
export interface WriteProtectionMatcher {
|
|
96
|
+
/** WHICH reading of a target this judge HAS — minted at compile and read verbatim by everyone who needs
|
|
97
|
+
* the fact; a reader re-deriving it from the seats is a second opinion, free to drift. */
|
|
98
|
+
readonly targetView: WriteProtectionTargetView;
|
|
51
99
|
/** The resolved rows this judge was compiled from (canonical names — the disclosure face). */
|
|
52
100
|
readonly rows: readonly WriteProtectedRow[];
|
|
53
|
-
/** Judge ONE path
|
|
101
|
+
/** Judge ONE path SPELLING. Returns the first matching row (basename rows first, then segment,
|
|
54
102
|
* then segment-run — deterministic), or null.
|
|
55
103
|
*
|
|
56
104
|
* `cwd` = the call's LIVE tracked working directory, read at judgment time off the ONE ref the fs
|
|
@@ -58,33 +106,91 @@ export interface WriteProtectionMatcher {
|
|
|
58
106
|
* Absent ⇒ judged exactly as given — the historical reading, and the honest answer for a host
|
|
59
107
|
* that tracks no cwd. */
|
|
60
108
|
matchPath(path: string, cwd?: string): WriteProtectedHit | null;
|
|
109
|
+
/**
|
|
110
|
+
* Judge ONE covered write by the file the tool will write: the spelling view first (`matchPath`; a hit
|
|
111
|
+
* there is the answer and costs no I/O), then — on a miss, and only when the judge was compiled with an
|
|
112
|
+
* execution environment — the resolved real target through the shared `canonicalizeTarget`.
|
|
113
|
+
*
|
|
114
|
+
* @contract write_protection.judges_the_real_target — the always-on write-protection table and the
|
|
115
|
+
* opt-in sensitive-path deny set differ in VOCABULARY (literal rows / segment globs) and SEVERITY
|
|
116
|
+
* (ask / deny), never in REACH: both judge the file the tool will write — the spelling anchored at the
|
|
117
|
+
* live cwd AND its resolved real target, through one canonicalizer — and a target neither can resolve is
|
|
118
|
+
* refused, never vouched. An environment-less judge has no target view and answers by the spelling alone —
|
|
119
|
+
* the same absence law the cwd follows (absent ⇒ the spelling is judged exactly as given). REACH is what
|
|
120
|
+
* this sentence promises, not a LOCK: the identity is resolved at judgment time and re-resolved by the
|
|
121
|
+
* tool at execute time (the module header states that window and the seat that would close it).
|
|
122
|
+
*/
|
|
123
|
+
judge(path: string, ctx?: WriteProtectionJudgeContext): Promise<WriteProtectionVerdict>;
|
|
124
|
+
}
|
|
125
|
+
/** Compile-time seats of {@link compileWriteProtection}. Every member is optional and has an absence reading. */
|
|
126
|
+
export interface WriteProtectionCompileOptions {
|
|
127
|
+
/** The engine data root for the passthrough in the module header (same seat and same meaning as
|
|
128
|
+
* `createSensitivePathPolicy`'s): omitted ⇒ the knob its consumers read (`$AGENT_DATA_DIR ?? ~/.ai-agent`). */
|
|
129
|
+
readonly dataRoot?: string;
|
|
130
|
+
/** The execution environment the hands write against — the TARGET view resolves in ITS filesystem
|
|
131
|
+
* (a remote/sandboxed task resolves in its container). Omitted ⇒ no target view: the spelling is the
|
|
132
|
+
* judgment (a host with no hands has no filesystem to resolve against). */
|
|
133
|
+
readonly env?: ExecutionEnv;
|
|
134
|
+
/** The task root — the base a `base: "root"` write tool's relative spelling resolves against, and the
|
|
135
|
+
* path-family source when the call carries no cwd. Omitted ⇒ relative spellings resolve against the
|
|
136
|
+
* cwd, then the environment's own working directory. */
|
|
137
|
+
readonly rootPath?: string;
|
|
61
138
|
}
|
|
62
139
|
/**
|
|
63
140
|
* Compile the write-protection judge for a deployment configuration. Returns `undefined` when the
|
|
64
141
|
* resolved table is EMPTY (`[]` replacement) — the caller then mounts no tighten at all, keeping an
|
|
65
142
|
* opted-out deployment's decision path byte-identical to a build without this layer.
|
|
66
143
|
*
|
|
67
|
-
*
|
|
68
|
-
*
|
|
69
|
-
*
|
|
70
|
-
*
|
|
144
|
+
* The data-root spellings are read ONCE here at compile (a judge that re-read `process.env` per call
|
|
145
|
+
* would answer two calls of one run differently); their CANONICAL keys are resolved per judgment, on the
|
|
146
|
+
* target view only, and only once a row has matched there (see {@link canonicalDataRootKeys} for why they
|
|
147
|
+
* are never cached). The passthrough is a property of the JUDGE, not of the default table — a deployment
|
|
71
148
|
* that replaces the table wholesale gets the same law over its own rows.
|
|
72
149
|
*/
|
|
73
|
-
export declare function compileWriteProtection(entries?: readonly WriteProtectedEntry[], opts?:
|
|
74
|
-
|
|
75
|
-
|
|
150
|
+
export declare function compileWriteProtection(entries?: readonly WriteProtectedEntry[], opts?: WriteProtectionCompileOptions): WriteProtectionMatcher | undefined;
|
|
151
|
+
/**
|
|
152
|
+
* The gate tighten's DECISION for one judgment — the words the fold writes on the pass, minted beside the
|
|
153
|
+
* verdict they read so the two cannot drift:
|
|
154
|
+
* · `hit` ⇒ `ask` (`safety`; no `requiresRealApproval` — one explicit look, clearable by an approver, a
|
|
155
|
+
* blanket `onAsk:"allow"`, the classifier or a matching persisted rule). The matched row NAME goes on the
|
|
156
|
+
* message (table names are deployment-validated vocabulary); the model-authored target path deliberately
|
|
157
|
+
* does not — `message` is the classifier's `askMessage`, and the approval card already shows the args. The
|
|
158
|
+
* spelling form's sentence is the historical one byte for byte; the target form says the target RESOLVED.
|
|
159
|
+
* · `unresolvable` ⇒ `deny` naming the cause: an unjudged target is never vouched, and an ask would be a
|
|
160
|
+
* question about a file nobody can name — the rule the canonicalizing deny set follows for the same reason.
|
|
161
|
+
* · `clear` ⇒ `undefined`: the surviving decision stands.
|
|
162
|
+
*/
|
|
163
|
+
export declare function writeProtectionTightenDecision(toolName: string, verdict: WriteProtectionVerdict): PermissionResult | undefined;
|
|
164
|
+
/**
|
|
165
|
+
* The ENGINE-FILLED gate input (`ToolGateInput.writeProtectionCheck`). Returns `null` SYNCHRONOUSLY when the
|
|
166
|
+
* call is not this layer's business — not a covered write, or no resolvable target string — and otherwise
|
|
167
|
+
* the judgment of {@link WriteProtectionMatcher.judge}, a promise. The split is load-bearing for the gate:
|
|
168
|
+
* a call the judge does not cover must not cost the fold a suspension point.
|
|
169
|
+
*/
|
|
170
|
+
export type WriteProtectionCheck = (toolName: string, args: unknown, face?: ToolCallLike["face"], cwd?: string, signal?: AbortSignal) => Promise<WriteProtectionVerdict> | null;
|
|
171
|
+
/**
|
|
172
|
+
* ONE leg's write-protection mount: the gate input and the judge's own {@link WriteProtectionTargetView},
|
|
173
|
+
* handed back together so the two readers of this compile — the gate station that mounts the check and the
|
|
174
|
+
* disclosure face that reports which reading it got — read ONE compile. `undefined` in place of the whole
|
|
175
|
+
* record is "no judge" (an emptied table), a different fact from a judge whose target view is absent.
|
|
176
|
+
*/
|
|
177
|
+
export interface WriteProtectionMount {
|
|
178
|
+
/** The gate input (`ToolGateInput.writeProtectionCheck`). */
|
|
179
|
+
readonly check: WriteProtectionCheck;
|
|
180
|
+
/** The compiled judge's own word for the reading it has of a write's target. */
|
|
181
|
+
readonly targetView: WriteProtectionTargetView;
|
|
182
|
+
}
|
|
76
183
|
/**
|
|
77
184
|
* Build the ENGINE-FILLED gate input (`ToolGateInput.writeProtectionCheck`): covered tools are the
|
|
78
185
|
* path-confinable write set (Write/Edit/NotebookEdit — the shared spelling), the judged target is
|
|
79
186
|
* the SAME string the tool itself will resolve (`writeTargetPath`, the shared single source with
|
|
80
187
|
* the sensitive-path guard and the fs-write gate), and the verdict is the table judge's. A covered
|
|
81
|
-
* write with NO resolvable target returns null here — this layer is ADDITIVE friction on a named
|
|
82
|
-
* set of targets, not a containment boundary (a target-less call cannot land on a named row, and
|
|
83
|
-
*
|
|
84
|
-
*
|
|
188
|
+
* write with NO resolvable target string returns null here — this layer is ADDITIVE friction on a named
|
|
189
|
+
* set of targets, not a containment boundary (a target-less call cannot land on a named row, and the
|
|
190
|
+
* tool's own schema validation refuses it before any write); the fail-closed treatment of that case
|
|
191
|
+
* belongs to the containment gates (fs-write-gate-policy documents that split). A target string the
|
|
192
|
+
* environment cannot RESOLVE is the judge's own `unresolvable` verdict, not this null.
|
|
85
193
|
* Returns `undefined` when the resolved table is empty — nothing to judge, mount nothing.
|
|
86
|
-
* `opts
|
|
194
|
+
* `opts` are the judge's own seats, passed straight through ({@link compileWriteProtection}).
|
|
87
195
|
*/
|
|
88
|
-
export declare function createWriteProtectionCheck(entries?: readonly WriteProtectedEntry[], opts?:
|
|
89
|
-
dataRoot?: string;
|
|
90
|
-
}): ((toolName: string, args: unknown, face?: ToolCallLike["face"], cwd?: string) => WriteProtectedHit | null) | undefined;
|
|
196
|
+
export declare function createWriteProtectionCheck(entries?: readonly WriteProtectedEntry[], opts?: WriteProtectionCompileOptions): WriteProtectionMount | undefined;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { isWinFormPath, writeTargetPath, isUncPath, isAbsoluteForFamily, joinForFamily, pathFamilyOf } from "../tools/fs/safety.js";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { canonicalizeTarget, isWinFormPath, writeTargetPath, isUncPath, isAbsoluteForFamily, joinForFamily, pathFamilyOf } from "../tools/fs/safety.js";
|
|
2
|
+
import { protectivePathTargetOf } from "./tool-registry.js";
|
|
3
|
+
import { pathTargetBaseOf } from "./effective-path-target.js";
|
|
4
|
+
import { canonicalDataRootKeys, dataRootSpellings, relativeUnderRoot } from "./sensitive-path-policy.js";
|
|
4
5
|
const freezeTable = (rows) => Object.freeze(rows.map((r) => Object.freeze(r)));
|
|
5
6
|
export const WRITE_PROTECTED_DEFAULT_TABLE = freezeTable([
|
|
6
7
|
{ name: ".gitconfig", kind: "basename" },
|
|
@@ -155,11 +156,13 @@ function relativeUnderDataRoot(path, roots) {
|
|
|
155
156
|
}
|
|
156
157
|
return null;
|
|
157
158
|
}
|
|
159
|
+
export const WRITE_PROTECTION_TARGET_VIEWS = ["spelling-only", "target"];
|
|
158
160
|
export function compileWriteProtection(entries, opts) {
|
|
159
161
|
const rows = resolveWriteProtectedTable(entries);
|
|
160
162
|
if (rows.length === 0)
|
|
161
163
|
return undefined;
|
|
162
|
-
const
|
|
164
|
+
const dataRootPaths = dataRootSpellings(opts?.dataRoot);
|
|
165
|
+
const rootViews = dataRootPaths.map((r) => {
|
|
163
166
|
const win = isWinFormPath(r);
|
|
164
167
|
return { win, segments: pathViewSegments(r, false, win ? BOTH_SEPARATOR_FAMILIES : POSIX_SEPARATOR_FAMILY, uncAnchorSegments(r)) };
|
|
165
168
|
});
|
|
@@ -180,49 +183,103 @@ export function compileWriteProtection(entries, opts) {
|
|
|
180
183
|
runs.push({ name: row.name, parts: folded.split("/").filter((s) => s.length > 0) });
|
|
181
184
|
}
|
|
182
185
|
}
|
|
186
|
+
const judgeSegments = (raw) => {
|
|
187
|
+
if (raw.length === 0)
|
|
188
|
+
return null;
|
|
189
|
+
const segs = raw.map(foldWriteProtectCase);
|
|
190
|
+
const base = basenames.get(segs[segs.length - 1] ?? "");
|
|
191
|
+
if (base !== undefined)
|
|
192
|
+
return { name: base, kind: "basename" };
|
|
193
|
+
for (const s of segs) {
|
|
194
|
+
const hit = segments.get(s);
|
|
195
|
+
if (hit !== undefined)
|
|
196
|
+
return { name: hit, kind: "segment" };
|
|
197
|
+
}
|
|
198
|
+
for (const run of runs) {
|
|
199
|
+
const n = run.parts.length;
|
|
200
|
+
for (let i = 0; i + n <= segs.length; i++) {
|
|
201
|
+
if (run.parts.every((p, j) => segs[i + j] === p))
|
|
202
|
+
return { name: run.name, kind: "segment-run" };
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
return null;
|
|
206
|
+
};
|
|
207
|
+
const judgeViews = (spelling) => judgeSegments(pathViewSegments(spelling, false, POSIX_SEPARATOR_FAMILY, uncAnchorSegments(spelling))) ??
|
|
208
|
+
judgeSegments(pathViewSegments(spelling, false)) ??
|
|
209
|
+
judgeSegments(pathViewSegments(spelling, true));
|
|
210
|
+
const judgeSpelling = (path, cwd) => {
|
|
211
|
+
const base = typeof cwd === "string" && cwd.length > 0 ? cwd : undefined;
|
|
212
|
+
const family = pathFamilyOf({ cwd: base });
|
|
213
|
+
const spelled = base !== undefined && family !== undefined && !isAbsoluteForFamily(family, path) ? joinForFamily(family, base, path) : path;
|
|
214
|
+
return judgeViews(relativeUnderDataRoot(spelled, rootViews) ?? spelled);
|
|
215
|
+
};
|
|
216
|
+
const env = opts?.env;
|
|
217
|
+
const rootPath = opts?.rootPath;
|
|
183
218
|
return {
|
|
184
219
|
rows,
|
|
220
|
+
targetView: env === undefined ? "spelling-only" : "target",
|
|
185
221
|
matchPath(path, cwd) {
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
const
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
};
|
|
211
|
-
return judge(pathViewSegments(judged, false)) ?? judge(pathViewSegments(judged, true));
|
|
222
|
+
return judgeSpelling(path, cwd);
|
|
223
|
+
},
|
|
224
|
+
async judge(path, ctx = {}) {
|
|
225
|
+
const bySpelling = judgeSpelling(path, ctx.cwd);
|
|
226
|
+
if (bySpelling !== null)
|
|
227
|
+
return { kind: "hit", hit: bySpelling, via: "spelling" };
|
|
228
|
+
if (env === undefined)
|
|
229
|
+
return { kind: "clear" };
|
|
230
|
+
const canon = await canonicalizeTarget(env, path, ctx.signal, pathFamilyOf({ root: rootPath, cwd: ctx.cwd ?? env.cwd }), ctx.base ?? ctx.cwd ?? rootPath);
|
|
231
|
+
if (!canon.ok)
|
|
232
|
+
return { kind: "unresolvable", cause: canon.message, unresolvedSymlink: canon.unresolvedSymlink === true };
|
|
233
|
+
const byTarget = judgeViews(canon.key);
|
|
234
|
+
if (byTarget === null)
|
|
235
|
+
return { kind: "clear" };
|
|
236
|
+
for (const rootKey of await canonicalDataRootKeys(env, dataRootPaths, ctx.signal)) {
|
|
237
|
+
const relative = relativeUnderRoot(canon.key, rootKey);
|
|
238
|
+
if (relative === null)
|
|
239
|
+
continue;
|
|
240
|
+
if (relative === "")
|
|
241
|
+
return { kind: "clear" };
|
|
242
|
+
const remainder = judgeViews(relative);
|
|
243
|
+
return remainder === null ? { kind: "clear" } : { kind: "hit", hit: remainder, via: "target" };
|
|
244
|
+
}
|
|
245
|
+
return { kind: "hit", hit: byTarget, via: "target" };
|
|
212
246
|
},
|
|
213
247
|
};
|
|
214
248
|
}
|
|
249
|
+
export function writeProtectionTightenDecision(toolName, verdict) {
|
|
250
|
+
if (verdict.kind === "hit") {
|
|
251
|
+
return {
|
|
252
|
+
action: "ask",
|
|
253
|
+
message: verdict.via === "target"
|
|
254
|
+
? `tool "${toolName}" writes to a write-protected path — its real target resolves onto table entry "${verdict.hit.name}" — explicit approval required`
|
|
255
|
+
: `tool "${toolName}" writes to a write-protected path (table entry "${verdict.hit.name}") — explicit approval required`,
|
|
256
|
+
decisionReason: "safety",
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
if (verdict.kind === "unresolvable") {
|
|
260
|
+
return {
|
|
261
|
+
action: "deny",
|
|
262
|
+
message: verdict.unresolvedSymlink
|
|
263
|
+
? `tool "${toolName}" is blocked: its target is a symlink whose real target could not be resolved, so the write-protection judge cannot tell whether it lands on a protected path (${verdict.cause})`
|
|
264
|
+
: `tool "${toolName}" is blocked: its target could not be resolved on this tree, so the write-protection judge cannot tell whether it lands on a protected path (${verdict.cause})`,
|
|
265
|
+
decisionReason: "safety",
|
|
266
|
+
};
|
|
267
|
+
}
|
|
268
|
+
return undefined;
|
|
269
|
+
}
|
|
215
270
|
export function createWriteProtectionCheck(entries, opts) {
|
|
216
271
|
const matcher = compileWriteProtection(entries, opts);
|
|
217
272
|
if (matcher === undefined)
|
|
218
273
|
return undefined;
|
|
219
|
-
|
|
274
|
+
const check = (toolName, args, face, cwd, signal) => {
|
|
220
275
|
const call = { toolName, args, ...(face !== undefined ? { face } : {}) };
|
|
221
|
-
|
|
276
|
+
const protective = protectivePathTargetOf(call);
|
|
277
|
+
if (protective === undefined || protective.access === "read")
|
|
222
278
|
return null;
|
|
223
|
-
const path = writeTargetPath(call);
|
|
279
|
+
const path = writeTargetPath(call, protective);
|
|
224
280
|
if (typeof path !== "string" || path.length === 0)
|
|
225
281
|
return null;
|
|
226
|
-
return matcher.
|
|
282
|
+
return matcher.judge(path, { ...(cwd !== undefined ? { cwd } : {}), ...(signal !== undefined ? { signal } : {}), ...(() => { const b = pathTargetBaseOf(protective, { root: opts?.rootPath, cwd }); return b !== undefined ? { base: b } : {}; })() });
|
|
227
283
|
};
|
|
284
|
+
return { check, targetView: matcher.targetView };
|
|
228
285
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -89,7 +89,7 @@ export { MAX_EXEC_OUTPUT_BYTES, RollingTailBuffer, markTruncated } from "./core/
|
|
|
89
89
|
export { physicalPathOf, physicalPathOfExisting } from "./core/physical-path.js";
|
|
90
90
|
export type { ExecutionEnv, FileInfo, Result, FileErrorCode, ExecutionErrorCode, WriteExpectation, WriteReceipt } from "./internal/harness.js";
|
|
91
91
|
export type { ExecResult } from "./internal/harness.js";
|
|
92
|
-
export { RemoteExecutionError, hasDestroy, isRemoteExecutionEnv, isSuspendable, isIsolated, missingRestoreSurface, isRetryableRemoteErrorCode, RETRYABLE_REMOTE_ERROR_CODES, } from "./core/remote-env.js";
|
|
92
|
+
export { RemoteExecutionError, hasDestroy, isRemoteExecutionEnv, isSuspendable, isIsolated, canonicalPathIsAuthoritative, missingRestoreSurface, isRetryableRemoteErrorCode, RETRYABLE_REMOTE_ERROR_CODES, } from "./core/remote-env.js";
|
|
93
93
|
export { withRetry } from "./core/with-retry.js";
|
|
94
94
|
export type { RetryPolicy, RetryResult } from "./core/with-retry.js";
|
|
95
95
|
export type { RemoteExecutionEnv, WorkspaceHandle, SnapshotId, SessionToken, SandboxTier, OutputChunk, ExecStreamOptions, RemoteConnectConfig, VmLifecycleOptions, SecretRef, RemoteExecutionErrorCode, ExecutionEnvFactory, ExecutionEnvFactoryContext, } from "./core/remote-env.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, } 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 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";
|
|
@@ -128,8 +128,8 @@ export { FileStorageBackend, FileSessionRepo, FileCheckpointStore, FileMemorySto
|
|
|
128
128
|
export { CacheBreakDetector, type CacheBreakFinding, type ToolFingerprintInput } from "./core/cache-break-detector.js";
|
|
129
129
|
export { maybeCompact, type MaybeCompactOptions, type CompactionWindowSafetyInfo } from "./core/auto-compaction.js";
|
|
130
130
|
export { brainToRuntime } from "./core/runtime.js";
|
|
131
|
-
export { createSensitivePathPolicy, RECOMMENDED_SENSITIVE_PATTERNS
|
|
132
|
-
export { createFsWriteGatePolicy, type FsWriteGatePolicyOptions } from "./core/fs-write-gate-policy.js";
|
|
131
|
+
export { createSensitivePathPolicy, RECOMMENDED_SENSITIVE_PATTERNS } from "./core/sensitive-path-policy.js";
|
|
132
|
+
export { createFsWriteGatePolicy, WRITE_EXEMPT_DIR_COVERS_ROOT_CODE, type FsWriteGatePolicyOptions } from "./core/fs-write-gate-policy.js";
|
|
133
133
|
export { RETIRED_TOOL_NAMES } from "./core/tool-name-aliases.js";
|
|
134
134
|
export { DEFAULT_SUBAGENT_TOOL_NAME } from "./agents/subagent.js";
|
|
135
135
|
export { renderTaskNotificationXml, taskNotificationDedupKey, isDelegatedAgentTerminal, isTerminalTaskNotification, SystemInjectionQueue, type TaskNotificationPayload, type TaskNotificationStatus, type ExternalNotificationInput, type SystemInjection, type SystemInjectionPriority, SYSTEM_INJECTION_PRIORITIES, isSystemInjectionPriority, AGENT_MESSAGE_TAG, renderAgentMessageFrame, type SemaProvenance, } from "./core/task-notification.js";
|
|
@@ -179,6 +179,7 @@ export { type AskCarry } from "./core/hooks.js";
|
|
|
179
179
|
export { SWAPPABLE_DEP_SEATS, SWAP_SEAT_NOTICE, isSwappableDepSeat, screenSwappableDeps, type SwappableDepSeat, type SwappableDeps } from "./core/swappable-deps.js";
|
|
180
180
|
export { parseAutoModeResponse, createAutoModeDecider, AUTO_MODE_UNAVAILABLE_CAUSES, isAutoModeUnavailableCause, classifierUnavailableDenyMessage, classifierParseFailureDenyMessage, AUTO_MODE_PARSE_FAILURES, isAutoModeParseFailure, type AutoModeParseFailure, type AutoModeUnavailableCause, AUTO_MODE_CLASSIFIER_FALLBACKS, isAutoModeClassifierFallback, AUTO_MODE_FALLBACK_CAUSES, isAutoModeFallbackCause, type AutoModeClassifierFallback, type AutoModeFallbackCause, type AutoModeClassifierRound, type AutoModeLadderRung, type AutoModeVerdict, type AutoModeDecider, type AutoModeDeciderOptions, type AutoModeClassified, type AutoModeClassifyFn, type AutoModeClassifyInput, createAutoModeDenialTracker, denialLimitFallbackMessage, denialLimitSentence, unarmedWindow, type AutoModeDenialTracker, type AutoModeDenialLimitOptions, type DenialLimitCounts, type DenialLimitFallbackFace, type UnarmedDenialLimitFallback, type DenialLimitFallback, type DenialLimitVerdict, } from "./core/auto-mode.js";
|
|
181
181
|
export { AUTO_MODE_DENIAL_LIMIT_DEFAULTS, AUTO_MODE_DENIAL_AUTO_DENY_DEFAULT_MS, AUTO_MODE_CLASSIFIER_MAX_TOKENS } from "./core/auto-mode-defaults.js";
|
|
182
|
+
export { classifierSeatModel, type ClassifierSeat } from "./core/runner/classifier-ladder.js";
|
|
182
183
|
export { buildAutoModePrompt, renderAutoModeWindow, renderAutoModeAction, AUTO_MODE_DEFAULTS_SENTINEL, type AutoModeRules, type BuildAutoModePromptOptions, type AutoModeWindowOptions, } from "./core/auto-mode-prompt.js";
|
|
183
184
|
export { AUTO_MODE_BASE_PROMPT, AUTO_MODE_PERMISSIONS_EXTERNAL } from "./core/auto-mode-prompt-assets.js";
|
|
184
185
|
export { AUTO_MODE_ARMING_RECIPE_VERSION, autoModeArmingRecipeOf, sanitizeAutoModeArmingRecipe, foldAutoModeArming, type AutoModeArmingRecipe, type AutoModeArmingFace, type AutoModeArmingFold, type AutoModeRebuildRefusal, } from "./core/auto-mode-arming.js";
|
|
@@ -216,7 +217,7 @@ export { AdoptionError, assertAdoptionBootGate, readRootAdoptionFile, writeRootA
|
|
|
216
217
|
export { adoptLocalDataRoot, ackAdoptionConfig, witnessAdoptionConfig, listAdoptionQuarantine, readAdoptionStatus, type AdoptionStatus, type AdoptLocalDataRootOptions, type AdoptLocalDataRootResult, type AdoptionCarriageLeg, type AdoptionCarriageLegContext, type AdoptionConfigWitnessReceipt, } from "./stores/file/adoption/adopt.js";
|
|
217
218
|
export { formatHookFeedback, runToolGate, createHookEnvCapabilities, createPreToolUseConstraintPolicy, type PersistedRuleHit, type PersistedRuleHitRule, type PersistedRuleUnreadable, type PersistedRuleCoverage, type PersistedRuleAnswer, normalizePersistedRuleHit, type Hooks, type HookToolContext, type HookInvocationIdentity, type UserPromptSubmitContext, type PostToolBatchContext, type HookEnvCapabilities, type HookToolOutput, type PreToolUseResult, type PostToolUseResult, type UserPromptSubmitResult, type HookToolFailure, type PostToolUseFailureResult, type PostToolBatchCall, type PostToolBatchResult, type PreCompactContext, type PreCompactResult, type PostCompactContext, type StopFailureContext, type PermissionDeniedPayload, } from "./core/hooks.js";
|
|
218
219
|
export { HOOK_FAMILIES, HOOKS_INVALID_CODE, type HookFamily, type WiringManifestHookEntry } from "./core/hook-seats.js";
|
|
219
|
-
export { InMemoryMemoryStore, composeMemoryBlock, composeLayeredMemoryBlock, normalizeMemorySpec, type NormalizedMemorySpec, type MemorySpecInput, supportsConsolidation, supportsPeriodicConsolidation, firstSentence, expandLexicalTerms, lexicalSearchMatch, type Embedder, classifyPromotable, enforcePromotableWriteGate, guardedMemoryStore, MemoryGateError, detectSecret, enforceSecretWriteGate, enforceStructuredNoteSecretGate, type UtilityGate, type MemoryStore, type MemoryVectorMode, type ScoredMemory, type MemoryNoteHeader, type MemoryNoteRecord, type MemoryNoteType, type StructuredNoteInput, } from "./core/memory.js";
|
|
220
|
+
export { InMemoryMemoryStore, composeMemoryBlock, composeLayeredMemoryBlock, normalizeMemorySpec, type NormalizedMemorySpec, type MemorySpecInput, supportsConsolidation, supportsPeriodicConsolidation, firstSentence, expandLexicalTerms, lexicalSearchMatch, type Embedder, classifyPromotable, enforcePromotableWriteGate, guardedMemoryStore, MemoryGateError, MemoryProjectionError, detectSecret, enforceSecretWriteGate, enforceStructuredNoteSecretGate, type UtilityGate, type MemoryStore, type MemoryVectorMode, type ScoredMemory, type MemoryNoteHeader, type MemoryNoteRecord, type MemoryNoteType, type StructuredNoteInput, } from "./core/memory.js";
|
|
220
221
|
export { MemoryEngine, FileMemoryEngineBackend, memoryBackendContract, assertMemoryBackendSearchEquivalence, type MemoryBackendContractHooks, buildMemoryInstruction, writableRootOf, truncateIndex, scanEntryFiles, deriveRepoKey, deriveRepoMemoryDir, deriveControlPlaneDir, deriveRepoControlPlaneDir, resolveMemoryEngineRoot, scopeDirName, ControlPlaneCorruptError, parseEntryFile, serializeEntryFile, computeEntryRev, entryFromFile, MEMORY_ORIGIN_CAUSES, committedOriginOf, originEquals, consolidationExposedFrontmatter, ambiguousOriginRepresentation, type OriginClearanceRow, type OriginClearanceEvent, type OriginClearanceShadow, committedDistilledOf, distilledEquals, type MemoryEntryDistilled, type MemoryEntryDistilledInput, CONSOLIDATION_DEFAULTS, ConsolidationRefusedError, MEMORY_SEARCH_SUPERSEDED_TAG, consolidationTypeEligible, deriveSupersededSet, memorySupersededNote, readIntentCredentials, supersessionFuseCeiling, memoryConsolidationRecommendedNotice, memoryConsolidationCommittedNotice, memoryConsolidationConflictNotice, memoryConsolidationIncompleteNotice, memoryConsolidationRefusedNotice, memoryConsolidationWithheldNotice, type ConsolidationGateRead, type ConsolidationGateRow, type ConsolidationIntent, type ConsolidationIntentCredentialRow, type ConsolidationLeaseSeat, type ConsolidationProductProposal, type ConsolidationProposal, type MemoryConsolidationOptions, type ConsolidationCommitReceipt, type ConsolidationReconcileReport, type ConsolidationResolveReceipt, type ConsolidationPlanSummary, type ConsolidationPlanFoldEvidence, type SessionMemoryStatus, DISTILLER_DEFAULT_MAX_INPUTS_PER_PRODUCT, LLM_DISTILLER_CONTRACT, LLM_DISTILLER_CONTRACT_DL2, LLM_DISTILLER_CONTRACT_DL3, LLM_DISTILLER_CONTRACTS, MEMORY_DISTILLER_CONTRACT_V1, contractGroupingDiff, driveConsolidationToFixpoint, isAliasModelId, llmPlanDistiller, mintExposurePartitionedPlan, mintLlmConsolidationPlan, MEMORY_DISTILLER_PURITY_CONTRACT_V1, detectCleanArmVerbatimLeak, type CleanArmLeakFinding, type CleanArmLeakVerdict, type MemoryDistillerPurityContract, openAiCompatChatSeat, parseJsonAnswer, planParseRepairs, sanitizeLlmGroups, scheduleUnderFuse, type ConsolidationDistillFn, type ConsolidationDriveCycleRow, type ConsolidationDriveEngine, type ConsolidationDriveResult, type ConsolidationFoldState, type DistillerCandidate, type DistillerChatAnswer, type DistillerChatFn, type DistillerChatRequest, type FuseSchedule, type LlmConsolidationPlan, type LlmConsolidationPlanArm, type LlmConsolidationPlanProduct, type LlmDistillerContract, type MintLlmConsolidationPlanResult, type PlanParseRepairs, type SanitizedLlmGroups, CONSOLIDATION_DRIVER_PLANS_DIR, CONSOLIDATION_DRIVER_RUNS_FILE, CONSOLIDATION_RUN_STOP_REASONS, archiveDistillerPlan, readConsolidationDriverRun, runMemoryConsolidationDriver, type ConsolidationDriverEngine, type ConsolidationDriverRunRow, type ConsolidationRunReceipt, type ConsolidationRunStopReason, type RunMemoryConsolidationOptions, isInstructionEntry, type MemoryEntryOrigin, type MemoryOriginCause, MEMORY_INSTRUCTION_TEMPLATE, MEMORY_RECALL_DISCIPLINE, MEMORY_PREFERENCE_DISCIPLINE, MEMORY_READONLY_NOTICE, MEMORY_CAPTURE_OPTOUT_NOTICE, memoryCaptureOptedOutNotice, memoryCaptureOptOutUnpersistedNotice, SESSION_CAPTURE_OPTOUT_DIR, markSessionCaptureOptOut, readSessionCaptureOptOut, listSessionCaptureOptOut, fileSessionCaptureRecordStore, type SessionCaptureOptOutRecord, type SessionCaptureOptOutMarkOutcome, type SessionCaptureRecordStore, readV2HeaderHints, type V2HeaderHints, LINEAGE_FILE, CHALLENGES_FILE, CHALLENGED_HISTORY_FILE, CHALLENGE_LEDGER_MAX_EVENTS, rebuildStrictControlPlaneLedger, type ControlPlaneRebuildReceipt, type StrictControlPlaneLedger, type ChallengeAssignment, type ChallengeEvent, type ChallengedHistoryRow, type LineagePendingTxn, type LineagePromotion, MEMORY_INDEX_FILENAME, MEMORY_INDEX_MAX_LINES, MEMORY_INDEX_MAX_BYTES, MEMORY_SEARCH_TOOL_NAME, MEMORY_GET_TOOL_NAME, MEMORY_INDEX_TOOL_NAME, MEMORY_ENGINE_TOOL_NAMES, type MemorySearchDetails, type MemorySearchHit, type CleanMemorySearchHit, type ExposedMemorySearchHit, MEMORY_EXPOSURE_BANNER, MEMORY_EXPOSURE_HANDLE_TAG, memoryExposureIndexRow, type MemoryGetDetails, type MemoryIndexDetails, type MemoryIndexRow, type CleanMemoryIndexRow, type ExposedMemoryIndexRow, STUB_ARCHIVED_LINE, DEFAULT_MAX_MEMORY_FILES, DEFAULT_MAX_ENTRY_DEPTH, DEFAULT_HARVEST_DEADLINE_MS, DEFAULT_HARVEST_FILE_BUDGET, MASS_DELETION_FUSE_RATIO, scanMemoryWrite, scanMemoryFileName, scanRemediation, MEMORY_FILENAME_SEGMENT_RE, renderAnnouncements, enqueueMemoryAnnouncement, drainMemoryAnnouncements, peekMemoryAnnouncements, bumpScanFuse, scanFuseCount, clearScanFuse, ANNOUNCEMENTS_FILE, MEMORY_ANNOUNCEMENTS_MAX, SCAN_FUSE_FILE, SCAN_FUSE_THRESHOLD, type MemoryAnnouncement, type ScanFinding, type MemoryEngineOptions, type MemoryInjection, type EntryProvenanceAccount, type TransferEvidence, type CommittedBinding, type CommittedEntrySnapshot, type CommittedScopeSnapshots, type EntryCustodyReport, erasureSelectHash, type EraseMemoryEntriesInput, type ErasureSelect, type ErasedBinding, type MemoryErasureAttestation, computeMemoryBundleHash, type MemoryExportBundle, type MemoryImportReport, type MemoryExportSnapshot, type MemoryBundleImportPlan, type BundleChallengeRow, type BundleLineageRow, type BundlePollutedSession, type MemoryBackend, type MemoryEntry, type MemoryEntryFrontmatter, type MemoryEntryHeader, type MemoryScopeEnumeration, type ScoredMemoryEntry, type NotePatch, type PatchReport, type MaterializedFile, type MemorySessionHandle, type HarvestReport, type HarvestRejection, type HarvestRejectionCode, type ParsedEntryFile, type ScannedEntryFile, SCOPE_SEGMENT_MAX_ENCODED, PROJECT_MARKER_PATH, encodeScopeSegment, decodeScopeSegment, parseScopeKey, formatUserScope, formatOrgScope, formatProjScope, formatUserProjScope, isPersonalScope, assertScopeContractPlacement, formatProjectMarker, parseProjectMarker, resolveProjectId, PROJECT_ID_REGEX, type ParsedScopeKey, migrateScope, type MigrateScopeReport, materializeEntriesToFiles, harvestFilesToPatches, projectionsToWriteBack, screenInboundEntries, REMOTE_HARVEST_PER_FILE_BYTES, REMOTE_MASS_DELETION_FUSE_RATIO, type RemoteMemoryFile, type RemoteMemoryBaseline, type RemoteMaterialization, type RemoteHarvestResult, type InboundEntryFinding, deriveProjectMemoryDir, deriveProjectControlDir, recordProjectIdHint, lookupProjectIdHint, PROJECT_ID_HINTS_FILE, reconcileMemoryEntries, nextSyncBaseline, mergeRecallHits, type MemorySyncCursor, type MemorySyncConflict, type MemorySyncPlan, type RecallSource, syncMemoryScope, type MemorySyncTransport, type MemorySyncRequestBody, type MemorySyncResponseBody, type MemorySyncClientConflict, type SyncMemoryScopeOptions, type MemorySyncClientResult, } from "./core/memory-engine/index.js";
|
|
221
222
|
export { SHARED_MEMORY_READ_CAP_BYTES, SHARED_MEMORY_LIST_PAGE_SIZE, SharedMemoryStoreError, type SharedMemoryStoreProvider, type SharedMemoryStoreReader, type SharedMemoryPagedList, type SharedMemoryStoreInfo, type SharedMemoryDocumentEntry, type SharedMemorySnapshot, type SharedMemoryRequestContext, type MemoryListDetails, type MemoryReadDetails, } from "./core/shared-memory/types.js";
|
|
222
223
|
export { sharedMemoryStoreContract, type SharedMemoryFixture, type SharedMemoryStoreContractHooks, } from "./core/shared-memory/contract.js";
|