@sema-agent/core 7.14.0 → 7.16.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 +59 -0
- package/dist/core/ask-origin.d.ts +2 -2
- package/dist/core/checkpoint-store.d.ts +14 -15
- package/dist/core/governance-codes.js +2 -0
- package/dist/core/hooks.d.ts +4 -3
- package/dist/core/memory-engine/delegation-settlement.d.ts +37 -12
- package/dist/core/memory-engine/delegation-settlement.js +128 -39
- package/dist/core/memory-engine/engine.d.ts +9 -8
- package/dist/core/memory-engine/engine.js +115 -120
- package/dist/core/memory-engine/file-backend.d.ts +17 -5
- package/dist/core/memory-engine/file-backend.js +78 -34
- package/dist/core/memory-engine/index.d.ts +2 -2
- package/dist/core/memory-engine/index.js +2 -2
- package/dist/core/memory-engine/layout.d.ts +152 -54
- package/dist/core/memory-engine/layout.js +441 -104
- package/dist/core/memory-engine/types.d.ts +8 -3
- package/dist/core/memory-engine/types.js +5 -0
- package/dist/core/runner/abort-race.d.ts +3 -3
- package/dist/core/runner/active-skill-scope.d.ts +2 -2
- package/dist/core/runner/assemble-result.d.ts +29 -29
- package/dist/core/runner/checkpoint-scope.d.ts +4 -4
- package/dist/core/runner/clock-and-limits.d.ts +3 -3
- package/dist/core/runner/compaction-call-options.d.ts +11 -11
- package/dist/core/runner/compaction-knobs.d.ts +4 -4
- package/dist/core/runner/compaction-seams.d.ts +5 -5
- package/dist/core/runner/contracts.d.ts +224 -226
- package/dist/core/runner/decide-continuation.d.ts +6 -6
- package/dist/core/runner/denial-limit-arms.d.ts +8 -8
- package/dist/core/runner/derived-route-fallback.d.ts +2 -2
- package/dist/core/runner/gate-exit.d.ts +6 -6
- package/dist/core/runner/git-status-frame.d.ts +7 -7
- package/dist/core/runner/inherited-ask-grants.d.ts +6 -6
- package/dist/core/runner/memory-capture-optout.d.ts +1 -1
- package/dist/core/runner/memory-consolidation-driver.d.ts +4 -4
- package/dist/core/runner/memory-consolidation.d.ts +6 -6
- package/dist/core/runner/park-commit.d.ts +6 -6
- package/dist/core/runner/permission-rule-lanes.d.ts +22 -20
- package/dist/core/runner/permission-rule-lanes.js +1 -1
- package/dist/core/runner/prepare-acquire-reconcile.d.ts +4 -4
- package/dist/core/runner/prepare-ask-lane.d.ts +3 -3
- package/dist/core/runner/prepare-boundary-parks.d.ts +3 -3
- package/dist/core/runner/prepare-caps-and-workflow.d.ts +5 -5
- package/dist/core/runner/prepare-config-doors.d.ts +21 -21
- package/dist/core/runner/prepare-context-lane.d.ts +6 -6
- package/dist/core/runner/prepare-defer-classify.d.ts +3 -3
- package/dist/core/runner/prepare-defer-classify.js +12 -10
- package/dist/core/runner/prepare-delegation-surface.d.ts +1 -1
- package/dist/core/runner/prepare-file-history.d.ts +2 -2
- package/dist/core/runner/prepare-gate-stations.d.ts +8 -9
- package/dist/core/runner/prepare-gate-stations.js +2 -2
- package/dist/core/runner/prepare-hands-readface.d.ts +41 -41
- package/dist/core/runner/prepare-hands-readface.js +27 -29
- package/dist/core/runner/prepare-inherited-gate.d.ts +6 -6
- package/dist/core/runner/prepare-listings.d.ts +3 -3
- package/dist/core/runner/prepare-lsp.d.ts +3 -3
- package/dist/core/runner/prepare-memory-engine-session.d.ts +5 -5
- package/dist/core/runner/prepare-memory.js +6 -7
- package/dist/core/runner/prepare-offload-wrappers.d.ts +2 -2
- package/dist/core/runner/prepare-park-ask.d.ts +11 -12
- package/dist/core/runner/prepare-park-ask.js +3 -3
- package/dist/core/runner/prepare-policy-chain.d.ts +6 -6
- package/dist/core/runner/prepare-policy-chain.js +2 -2
- package/dist/core/runner/prepare-prompt-inputs.d.ts +5 -5
- package/dist/core/runner/prepare-protocol-tools.d.ts +1 -1
- package/dist/core/runner/prepare-question-face.d.ts +4 -4
- package/dist/core/runner/prepare-run-refs.d.ts +11 -11
- package/dist/core/runner/prepare-safety-scan.d.ts +1 -1
- package/dist/core/runner/prepare-suspend-saga.d.ts +4 -4
- package/dist/core/runner/prepare-task.d.ts +12 -12
- package/dist/core/runner/prepare-task.js +5 -7
- package/dist/core/runner/prepare-tool-disclosure-mount.d.ts +2 -3
- package/dist/core/runner/prepare-wiring-manifest.d.ts +4 -4
- package/dist/core/runner/prepare-workspace-restore.d.ts +1 -1
- package/dist/core/runner/remote-env-retry.d.ts +3 -3
- package/dist/core/runner/resume-admission.d.ts +1 -1
- package/dist/core/runner/resume-claim.d.ts +1 -1
- package/dist/core/runner/resume-internals-and-config.d.ts +1 -1
- package/dist/core/runner/resume-policy-outcome.d.ts +1 -1
- package/dist/core/runner/resume-preflight.d.ts +1 -1
- package/dist/core/runner/resume-review-outcome.d.ts +1 -1
- package/dist/core/runner/run-brain-sinks.d.ts +1 -1
- package/dist/core/runner/run-clock-and-content.d.ts +4 -4
- package/dist/core/runner/run-compaction-machinery.d.ts +3 -3
- package/dist/core/runner/run-git-lane.d.ts +1 -1
- package/dist/core/runner/run-harness-handlers.d.ts +2 -2
- package/dist/core/runner/run-identity-wiring.d.ts +4 -4
- package/dist/core/runner/run-leg.d.ts +3 -3
- package/dist/core/runner/run-notification-lane.d.ts +2 -2
- package/dist/core/runner/run-reasoning-seat.d.ts +2 -2
- package/dist/core/runner/run-settle-and-teardown.d.ts +4 -4
- package/dist/core/runner/run-telemetry-and-budget-seats.d.ts +2 -2
- package/dist/core/runner/run-terminal-adoption.d.ts +5 -5
- package/dist/core/runner/runtask.d.ts +14 -14
- package/dist/core/runner/session-file-state-replay.d.ts +3 -3
- package/dist/core/runner/session-rule-policy.d.ts +2 -2
- package/dist/core/runner/steer-admission.d.ts +2 -2
- package/dist/core/runner/stream-halt-verbs.d.ts +1 -1
- package/dist/core/runner/stream-reap.d.ts +1 -1
- package/dist/core/runner/synthetic-tools.d.ts +8 -8
- package/dist/core/runner/teardown-bounded.d.ts +2 -2
- package/dist/core/runner/tool-defer-gate.d.ts +86 -0
- package/dist/core/runner/tool-defer-gate.js +57 -0
- package/dist/core/runner/tool-disclosure.d.ts +33 -69
- package/dist/core/runner/tool-disclosure.js +0 -43
- package/dist/core/runner/tool-end-body.d.ts +3 -3
- package/dist/core/runner/tool-face-overlay.d.ts +2 -2
- package/dist/core/runner/tool-output-projection.d.ts +2 -2
- package/dist/core/runner/turn-attachments.d.ts +53 -53
- package/dist/core/runner/usage-accounting.d.ts +4 -4
- package/dist/core/runner/workspace-path.d.ts +1 -1
- package/dist/core/runner-deps.d.ts +16 -9
- package/dist/core/task-spec.d.ts +8 -2
- package/dist/core/tool-spec.d.ts +7 -4
- package/dist/core/types.d.ts +1 -1
- package/dist/engine/llm/types.d.ts +1 -1
- package/dist/index.d.ts +4 -4
- package/dist/index.js +3 -3
- package/dist/tools/fs/bash-readonly-classifier.d.ts +40 -40
- package/dist/tools/fs/encoding.d.ts +31 -40
- package/dist/tools/fs/fs-bash.d.ts +76 -35
- package/dist/tools/fs/fs-bash.js +86 -29
- package/dist/tools/fs/fs-pdf.d.ts +8 -8
- package/dist/tools/fs/fs-search-tools.d.ts +4 -4
- package/dist/tools/fs/fs-shared.d.ts +144 -158
- package/dist/tools/fs/fs-write.d.ts +8 -8
- package/dist/tools/fs/gh-rate-limit.d.ts +13 -14
- package/dist/tools/fs/index.d.ts +74 -78
- package/dist/tools/fs/notebook.d.ts +24 -25
- package/dist/tools/fs/pdf.d.ts +3 -3
- package/dist/tools/fs/read-deny.d.ts +22 -22
- package/dist/tools/fs/read-face.d.ts +21 -24
- package/dist/tools/fs/repo-map.d.ts +8 -8
- package/dist/tools/fs/safety.d.ts +116 -129
- package/dist/tools/fs/search.d.ts +63 -71
- package/package.json +5 -2
- package/test/export-surface.snapshot.json +9 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type BeforeWriteHook, type CwdRef, type ReadDenyMatcher, type ReadFace } from "../../tools/fs/index.js";
|
|
2
2
|
import { type ReadFileState } from "../../tools/fs/safety.js";
|
|
3
|
-
import type { RunnerDeps, TaskSpec } from "../types.js";
|
|
3
|
+
import type { RunnerDeps, ShellGateDoctrine, TaskSpec } from "../types.js";
|
|
4
4
|
import type { Model } from "../../internal/llm.js";
|
|
5
5
|
import type { AgentTool, ExecutionEnv, WorkspaceState } from "../../internal/harness.js";
|
|
6
6
|
import type { AdvertisedWritableDirs } from "./advertised-writable-dirs.js";
|
|
@@ -11,10 +11,10 @@ import { RosterBuilder } from "../tool-roster.js";
|
|
|
11
11
|
* Deliberately asymmetric — it resets only the console latch: the WeakSet arm needs no seam
|
|
12
12
|
* because a test resets it by minting a fresh sink function (identity IS the ledger key), while
|
|
13
13
|
* the console arm's key is the process itself, which only this seam can refresh. Moved WITH the
|
|
14
|
-
* phase
|
|
14
|
+
* phase; prepare-task.ts keeps a re-export so the existing import sites stand. */
|
|
15
15
|
export declare function __resetReadFaceClampAnnouncement(): void;
|
|
16
16
|
/**
|
|
17
|
-
*
|
|
17
|
+
* The Runner's per-session read-file-state seats (CC parity: readFileState is minted
|
|
18
18
|
* once per REPL session and mutated across turns; it has NO turn-boundary and NO abort clear site —
|
|
19
19
|
* its only clears are compaction/fork/subagent-cleanup/dispose). sema's map stays per-task (the §11
|
|
20
20
|
* ruling-A closure wiring), so the SESSION scope lives here instead: prepare adopts each task's live
|
|
@@ -30,17 +30,17 @@ export declare function __resetReadFaceClampAnnouncement(): void;
|
|
|
30
30
|
* Bounded: an LRU over sessionIds (insertion-order refresh on read), because the SessionStore's own
|
|
31
31
|
* eviction is not observable from here — a dropped seat costs one transcript replay, nothing else.
|
|
32
32
|
* The stored value is the task's LIVE map (object identity), so in-turn mutations — tool write-backs,
|
|
33
|
-
* and above all the
|
|
33
|
+
* and above all the compaction clear — are the seat's truth by construction; a snapshot copy
|
|
34
34
|
* here would resurrect summarized-away reads on the next turn.
|
|
35
35
|
*
|
|
36
|
-
* BRANCH BINDING
|
|
36
|
+
* BRANCH BINDING: a sessionId alone does not name a transcript — the same id
|
|
37
37
|
* can be rebranched (`resumeAt`), rewound out-of-band, or DELETED and re-created (`release()` + the
|
|
38
38
|
* default create-on-miss acquire), and the seat's map would then vouch for reads the CURRENT branch
|
|
39
39
|
* never saw. Each seat therefore records `anchorLeafId` — a leaf on the lineage its task produced —
|
|
40
40
|
* and inheritance must first prove the CURRENT branch still descends from that anchor
|
|
41
41
|
* (see {@link sessionSeatAnchorHolds}). The anchor is written twice: at ADOPT (the leaf at prepare;
|
|
42
42
|
* `null` when the branch was still empty) and SEALED at the task's settle to the task's own tail
|
|
43
|
-
* (`reanchor`). A `null` anchor is NEVER inheritable (
|
|
43
|
+
* (`reanchor`). A `null` anchor is NEVER inheritable ("the branch is non-empty now" proves
|
|
44
44
|
* nothing about WHOSE messages those are — another Runner repopulating a released id, or a session
|
|
45
45
|
* import, makes a non-empty branch that never contained this seat's reads). An unprovable anchor
|
|
46
46
|
* falls back to the transcript replay, which reads the current branch by construction — cost, never
|
|
@@ -59,14 +59,14 @@ export declare class SessionReadFileStates {
|
|
|
59
59
|
* `anchorLeafId` = the session's leaf as read at THIS prepare (null = the branch was empty; a
|
|
60
60
|
* null-anchored seat is not inheritable until the settle-time {@link reanchor} names a real leaf). */
|
|
61
61
|
adopt(sessionId: string, state: ReadFileState, anchorLeafId: string | null): void;
|
|
62
|
-
/**
|
|
62
|
+
/** The settle-time SEAL: re-anchor the seat to the finished task's own tail, so a
|
|
63
63
|
* first-task (null-anchor) seat becomes inheritable only through a leaf its task provably wrote.
|
|
64
64
|
* Identity-guarded: touches the row only while it still holds THIS task's map (a later prepare on
|
|
65
65
|
* the same session has already replaced the seat and owns its own anchor). */
|
|
66
66
|
reanchor(sessionId: string, state: ReadFileState, anchorLeafId: string): void;
|
|
67
67
|
}
|
|
68
68
|
/**
|
|
69
|
-
*
|
|
69
|
+
* Does the session's CURRENT branch still descend from the seat's anchor?
|
|
70
70
|
* TRUE is the licence to inherit; anything unprovable answers FALSE (the caller then replays the
|
|
71
71
|
* transcript — the fail-closed direction costs a rebuild, never admits a wrong entry).
|
|
72
72
|
*
|
|
@@ -82,17 +82,17 @@ export declare class SessionReadFileStates {
|
|
|
82
82
|
* - a COMPACTION on the walked segment (A-082 idx2): refuses, even though the branch is perfectly
|
|
83
83
|
* intact. The walked segment is exactly what landed AFTER this seat was anchored, and a
|
|
84
84
|
* compaction there summarized older Read results OUT of the context the model will be shown —
|
|
85
|
-
* the very state
|
|
85
|
+
* the very state the compaction clear removes from the live map at the landing site. That clear reaches the seat
|
|
86
86
|
* only when the SAME Runner did both (the seat IS that map, by object identity); a second Runner
|
|
87
87
|
* on the shared durable session clears its own map and commits the compaction as an ORDINARY
|
|
88
88
|
* LINEAR APPEND, which every other test here passes. Inheriting across it would let requireRead
|
|
89
89
|
* and checkStale both pass on a read whose card the model no longer has — a blind edit from a
|
|
90
|
-
* summarized-away recollection, the exact failure the
|
|
90
|
+
* summarized-away recollection, the exact failure the compaction clear exists to prevent. Refusing
|
|
91
91
|
* costs one transcript replay, and the replay reads the POST-compaction branch by construction,
|
|
92
92
|
* so the fail-closed direction is also the CORRECT state. A compaction at or ABOVE the anchor is
|
|
93
93
|
* not on the walked segment and does not refuse: the seat that observed it already carries its
|
|
94
94
|
* clear (P-483-4), and an ordinary foreign turn with no compaction still inherits (G-483-5) —
|
|
95
|
-
* dropping every seat a foreign Runner touched would restore the cross-turn amnesia
|
|
95
|
+
* dropping every seat a foreign Runner touched would restore the cross-turn read-state amnesia this seat-anchor check already ended.
|
|
96
96
|
*/
|
|
97
97
|
export declare function sessionSeatAnchorHolds(getEntry: (id: string) => Promise<{
|
|
98
98
|
parentId: string | null;
|
|
@@ -118,8 +118,8 @@ export interface PrepareHandsReadFaceInput {
|
|
|
118
118
|
* resume; the workspace_state rung is skipped; the face fold goes stricter-wins). */
|
|
119
119
|
resume: Pick<PrepareResume, "seed"> | undefined;
|
|
120
120
|
/** borrowed-readonly — the acquired session (B-3 output), as a Pick (相 API 规则件 R-4: receiver
|
|
121
|
-
* preserved): `getWorkspaceState` feeds the
|
|
122
|
-
* the transcript replay; `getStorage`/`getEntry` feed the
|
|
121
|
+
* preserved): `getWorkspaceState` feeds the continuation rung; `buildContext` feeds
|
|
122
|
+
* the transcript replay; `getStorage`/`getEntry` feed the seat-anchor verification (one
|
|
123
123
|
* leaf read per prepare + a bounded parent walk on the inherit leg only). */
|
|
124
124
|
session: Pick<StoredSession, "getWorkspaceState" | "buildContext" | "getStorage" | "getEntry">;
|
|
125
125
|
/** borrowed-readonly — the acquired session's id, for error/notice tags and the band's session
|
|
@@ -136,9 +136,9 @@ export interface PrepareHandsReadFaceInput {
|
|
|
136
136
|
fullShellReachable: boolean;
|
|
137
137
|
/** borrowed-readonly — the MAX-RANK fold of spec.shellGate with the inherited chain's doctrine
|
|
138
138
|
* (computed in the driver's inherited-gate block); the shellGate fold's doctrine value. */
|
|
139
|
-
effectiveShellGate:
|
|
139
|
+
effectiveShellGate: ShellGateDoctrine;
|
|
140
140
|
/** borrowed-readonly — B-1's frozen task-start face snapshot; only `.exclude` is read here (the
|
|
141
|
-
* Monitor-mount honesty bit for the gh rate-limit hint
|
|
141
|
+
* Monitor-mount honesty bit for the gh rate-limit hint). */
|
|
142
142
|
toolFaceSnapshot: ToolFaceSnapshot;
|
|
143
143
|
/** borrowed-readonly — B-1's resolved main model; read ONLY for its pdf capability profile
|
|
144
144
|
* (the Read tool's document-degradation fork). */
|
|
@@ -149,39 +149,39 @@ export interface PrepareHandsReadFaceInput {
|
|
|
149
149
|
/** borrowed-readonly — the deployment seats this phase reads, as a Pick over the SAME deps
|
|
150
150
|
* object (R-4: `deps.onError?.()` keeps its receiver; a new deps read must widen this Pick).
|
|
151
151
|
* `readDenyBuiltinTiers`/`readDenyBuiltinExclude` are SNAPSHOTTED before the first await that
|
|
152
|
-
* precedes the toolkit compile (
|
|
152
|
+
* precedes the toolkit compile (the caller retains these arrays by reference). */
|
|
153
153
|
deps: Pick<RunnerDeps, "onError" | "onNotice" | "tracer" | "readDenyPatterns" | "readDenyBuiltinTiers" | "readDenyBuiltinExclude" | "readFace" | "permissionRuleStore" | "hands">;
|
|
154
154
|
/** borrowed-readonly — the trusted spawn-side seats the band forwards: the finished-command
|
|
155
|
-
* notification lane, the mid-flight detach hub, and
|
|
155
|
+
* notification lane, the mid-flight detach hub, and the Runner's per-session
|
|
156
156
|
* read-state seats (absent on a standalone prepare ⇒ the transcript-replay rung covers alone). */
|
|
157
157
|
internals: Pick<RunInternals, "onTaskNotification" | "detachHub" | "sessionReadStates"> | undefined;
|
|
158
|
-
/** borrowed-readonly
|
|
158
|
+
/** borrowed-readonly — ABSOLUTE paths this prepare's restore wrote, deleted,
|
|
159
159
|
* or failed to write. Every read-state seed above describes the PRE-restore tree, so these keys are
|
|
160
160
|
* dropped from the map: the engine replaced those bytes itself, and a surviving entry makes the
|
|
161
161
|
* next refusal blame "the user or a linter" for the engine's own write. Absent (the common case)
|
|
162
162
|
* when no file restore ran. Fail-closed by construction — dropping a read record only ever
|
|
163
163
|
* produces refusals. */
|
|
164
164
|
restoredFilePaths?: readonly string[];
|
|
165
|
-
/** borrowed-readonly — (ref cell; the REF itself is never replaced)
|
|
165
|
+
/** borrowed-readonly — (ref cell; the REF itself is never replaced) memory write gate:
|
|
166
166
|
* the band's beforeWrite closure reads `.current` call-time; prepareMemory (driver, BEFORE this phase
|
|
167
|
-
* since
|
|
167
|
+
* since the memory root must be known before the toolkit compiles) installs the gate — the one
|
|
168
168
|
* writer; this phase only reads. Declared in the driver because the SAME ref feeds prepareMemory. */
|
|
169
169
|
memoryWriteGateRef: {
|
|
170
170
|
current?: BeforeWriteHook;
|
|
171
171
|
};
|
|
172
|
-
/** borrowed-mutable —
|
|
172
|
+
/** borrowed-mutable — the advertised-writable-directory seat (see its module header for the one
|
|
173
173
|
* rule). Present on the hands leg only (a fence exists). The memory phase, which runs BEFORE this one,
|
|
174
174
|
* has already admitted its write root through it; this phase admits the deployment's scratchpad and
|
|
175
175
|
* folds `roots` into the write-capable containment allowlist before the toolkit compiles. */
|
|
176
176
|
advertisedWritableDirs?: AdvertisedWritableDirs;
|
|
177
|
-
/** borrowed-readonly — the driver's per-tool offload wrapper (
|
|
177
|
+
/** borrowed-readonly — the driver's per-tool offload wrapper (posture + policy); the
|
|
178
178
|
* band rides through it exactly as caller/MCP tools do. */
|
|
179
179
|
firstPartyOffload: (tool: AgentTool) => AgentTool;
|
|
180
180
|
/** borrowed-mutable — the SHARED mount array (§4.4: later refs alias it; identity is the
|
|
181
181
|
* contract, never map/copy). This phase pushes the hands band IN PLACE (after caller tools /
|
|
182
182
|
* built-ins / MCP / A2A, before the background-task mounts — T22 order). Mutation owners after
|
|
183
183
|
* this phase: P11 background/Monitor/worktree pushes, the driver's excludeTools splice, the
|
|
184
|
-
* refresh seam's runtime splice/push.
|
|
184
|
+
* refresh seam's runtime splice/push. The array is builder-private: this phase `mountAll`s the band. */
|
|
185
185
|
roster: RosterBuilder;
|
|
186
186
|
/** borrowed-readonly HERE (census divergence #5 vs the design row): this phase only reads
|
|
187
187
|
* `.has("Bash")`/`.has("Monitor")` for the provenance bits — its mutation owners are B-2/P8/P9
|
|
@@ -197,16 +197,16 @@ export interface PrepareHandsReadFaceInput {
|
|
|
197
197
|
/** borrowed-mutable — the classify doctrine's probe installs (`.set`, only where the doctrine
|
|
198
198
|
* owns the seat). Same-object contract as above. */
|
|
199
199
|
reversibilityProbes: ReversibilityProbes;
|
|
200
|
-
/** borrowed-readonly —
|
|
200
|
+
/** borrowed-readonly — the run's reminder provenance mark (minted/adopted
|
|
201
201
|
* by the driver's adoption ladder); threaded into the hands band so the fs-side engine mints
|
|
202
202
|
* (the Read cyber/dedup/offset/empty reminders, the gh rate-limit hint) stamp the same mark the
|
|
203
203
|
* system-prompt declaration names. */
|
|
204
204
|
reminderMark: string;
|
|
205
|
-
/** borrowed-mutable —
|
|
205
|
+
/** borrowed-mutable — the leg's disclosure trigger counters; the hands
|
|
206
206
|
* band's Read/notebook/PDF trailer outlets bump keys on it at tool-execute time (the driver owns
|
|
207
207
|
* the object and folds it into result stats). */
|
|
208
208
|
reminderDisclosureCounts: import("../reminder-disclosure.js").ReminderDisclosureCounts;
|
|
209
|
-
/** borrowed-readonly —
|
|
209
|
+
/** borrowed-readonly — the first-touch history hook prepare built (present iff a fileHistoryStore is
|
|
210
210
|
* wired and the run mounts a real fs env); threaded to the write band's trackFileEdit seat. */
|
|
211
211
|
trackFileEdit?: import("../types.js").TrackFileEditHook;
|
|
212
212
|
/** borrowed-readonly — the mutation lane's LANDED observation seat (the accumulator behind
|
|
@@ -233,11 +233,11 @@ export interface PrepareHandsReadFaceResult {
|
|
|
233
233
|
path: string;
|
|
234
234
|
content: string;
|
|
235
235
|
}>) => Promise<void>) | undefined;
|
|
236
|
-
/** owned —
|
|
236
|
+
/** owned — the per-task logical cwd ref (observable `cd`), minted when a real
|
|
237
237
|
* writable shell mounts. The driver stamps it into checkpoints, threads it into worktree tools
|
|
238
238
|
* and gate cwd reads; tools mutate `.current` at run time. Undefined when no shell / readOnly. */
|
|
239
239
|
handsCwdRef: CwdRef | undefined;
|
|
240
|
-
/** owned —
|
|
240
|
+
/** owned — the settle-side snapshot base (what the cwd/worktree refs were RESTORED
|
|
241
241
|
* to), so runtask's settle write diffs against it. The driver's G4 worktree mount writes
|
|
242
242
|
* `.restoredWorktreeDir` after this phase — object identity carried. */
|
|
243
243
|
workspaceStateSettle: {
|
|
@@ -246,7 +246,7 @@ export interface PrepareHandsReadFaceResult {
|
|
|
246
246
|
restoredWorktreeDir?: string;
|
|
247
247
|
baselineUnknown?: boolean;
|
|
248
248
|
} | undefined;
|
|
249
|
-
/** owned —
|
|
249
|
+
/** owned — the branch-nearest `workspace_state` entry, fetched ONCE here and shared
|
|
250
250
|
* with the driver's worktree seed (the G4 mount reads `.activeWorktree` through it). */
|
|
251
251
|
wsSnapshot: WorkspaceState | undefined;
|
|
252
252
|
/** owned — the wsSnapshot path rebaser (identity when no snapshot / same root); the G4 worktree
|
|
@@ -266,7 +266,7 @@ export interface PrepareHandsReadFaceResult {
|
|
|
266
266
|
pattern: string;
|
|
267
267
|
caseSensitive: boolean;
|
|
268
268
|
}>;
|
|
269
|
-
/** write-back (D-3 hold) — the hands-LESS legs' resolved face (
|
|
269
|
+
/** write-back (D-3 hold) — the hands-LESS legs' resolved face (the read posture is a
|
|
270
270
|
* property of the RUN, not the mount). Driver assigns onto its outer `let`. */
|
|
271
271
|
handsLessResolvedFace: ReadFace | undefined;
|
|
272
272
|
/** owned — the canonicalized write-capable extra roots (additionalDirectories + the advertised
|
|
@@ -276,19 +276,19 @@ export interface PrepareHandsReadFaceResult {
|
|
|
276
276
|
/** owned — the read-only arm of the fence widening (2026-08-05 both-arms ruling); same identity
|
|
277
277
|
* contract as above. */
|
|
278
278
|
additionalReadRootsCanonical: string[];
|
|
279
|
-
/** owned —
|
|
279
|
+
/** owned — the canonical containment root, published so the working-file ATTACHMENT
|
|
280
280
|
* reader applies the same containment the hands tools do. Undefined ⇔ hands-less. */
|
|
281
281
|
attachmentRootCanonical: string | undefined;
|
|
282
|
-
/** owned —
|
|
282
|
+
/** owned — the ONE compiled deny judge per prepare (built-ins ∪ deployment ∪
|
|
283
283
|
* task additions). Undefined ⇔ hands-less (its consumers only exist with hands). */
|
|
284
284
|
readDenyMatcher: ReadDenyMatcher | undefined;
|
|
285
|
-
/**
|
|
286
|
-
*
|
|
287
|
-
*
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
/** owned
|
|
285
|
+
/** owned — the shell-seat PROVENANCE set: the shell-running tools whose tier the engine's shell seat (read
|
|
286
|
+
* boundary + shellGate doctrine) is the SOLE POSITIVE source of — no explicit deployment mark on that name.
|
|
287
|
+
* The one seat every consumer reads (risk grading, the gate's tighten attribution, the persisted-rule mandate
|
|
288
|
+
* boundary): `shellGatedTools.has(toolName)`. Minted here, never grown afterwards; empty when the seat fold
|
|
289
|
+
* did not run (no real writable shell). */
|
|
290
|
+
shellGatedTools: ReadonlySet<string>;
|
|
291
|
+
/** owned — the ENV-HAND tool names, minted AT THE MOUNT: every tool this
|
|
292
292
|
* phase mounted over the ExecutionEnv (the fs/bash band), later grown by the driver's own env
|
|
293
293
|
* mounts (Monitor, the worktree pair — the SAME Set identity, mutated at those mount sites).
|
|
294
294
|
* Consumed by the O9a external-content-target fold: these are the tools whose RESULTS are the
|
|
@@ -297,12 +297,12 @@ export interface PrepareHandsReadFaceResult {
|
|
|
297
297
|
* misses Monitor/worktree, which are hands — both directions wrong for this consumer). Empty on
|
|
298
298
|
* a hands-less leg (nothing mounts on the env; the driver's env mounts are hands-gated too). */
|
|
299
299
|
envHandToolNames: Set<string>;
|
|
300
|
-
/** owned
|
|
300
|
+
/** owned — the settle-time SEAT SEAL: re-anchors the session seat to the
|
|
301
301
|
* task's OWN last-committed entry (see {@link SessionReadFileStates.reanchor}). The driver calls
|
|
302
302
|
* it once at the run's settle (every terminal, suspend included), under the session lock, passing
|
|
303
303
|
* the last entryId ITS OWN run committed (the message_committed lane) — never a re-read of the
|
|
304
304
|
* shared session leaf, which a concurrent writer on another Runner could have moved onto a branch
|
|
305
|
-
* this task's reads were never on
|
|
305
|
+
* this task's reads were never on. No commits observed ⇒ no-op (the adopt-time anchor
|
|
306
306
|
* stands). Synchronous, never throws. Undefined ⇔ hands-less / no seat channel. */
|
|
307
307
|
sealReadStateSeat: ((ownCommittedTailEntryId: string | undefined) => void) | undefined;
|
|
308
308
|
}
|
|
@@ -2,7 +2,7 @@ import { emitTrace } from "../trace.js";
|
|
|
2
2
|
import { StubExecutionEnv } from "../stub-env.js";
|
|
3
3
|
import { hasBackgroundShell } from "../background-shell.js";
|
|
4
4
|
import { defaultTaskRegistry } from "../task-registry.js";
|
|
5
|
-
import { bashReversibilityProbe, compileReadDeny, createHandsToolkit, deploymentReadFaceClampNotice, pdfModelCapabilitiesOf, resolveReadDenyBuiltins, inheritSessionReadFileState, resolveReadFace, seedReadFileStateFromContext, seedReadFileStateFromTranscript, } from "../../tools/fs/index.js";
|
|
5
|
+
import { bashReadBoundaryProbe, bashReversibilityProbe, compileReadDeny, createHandsToolkit, deploymentReadFaceClampNotice, pdfModelCapabilitiesOf, resolveReadDenyBuiltins, inheritSessionReadFileState, resolveReadFace, seedReadFileStateFromContext, seedReadFileStateFromTranscript, } from "../../tools/fs/index.js";
|
|
6
6
|
import { resolveKey, sha256 } from "../../tools/fs/safety.js";
|
|
7
7
|
import { normalizeFileText } from "../../tools/fs/encoding.js";
|
|
8
8
|
import { wholeFileRecordsFromTranscript } from "./session-file-state-replay.js";
|
|
@@ -117,8 +117,7 @@ export function resolveHandsLessReadFace(input) {
|
|
|
117
117
|
attachmentRootCanonical: undefined,
|
|
118
118
|
readDenyMatcher: undefined,
|
|
119
119
|
envHandToolNames: new Set(),
|
|
120
|
-
|
|
121
|
-
shellGatedMonitor: false,
|
|
120
|
+
shellGatedTools: new Set(),
|
|
122
121
|
sealReadStateSeat: undefined,
|
|
123
122
|
};
|
|
124
123
|
}
|
|
@@ -140,8 +139,7 @@ export async function prepareHandsMount(input) {
|
|
|
140
139
|
let resolvedReadFace;
|
|
141
140
|
let readDenyAdditionsNormalized = [];
|
|
142
141
|
let handsLessResolvedFace;
|
|
143
|
-
|
|
144
|
-
let shellGatedMonitor = false;
|
|
142
|
+
const shellGatedTools = new Set();
|
|
145
143
|
const additionalRootsCanonical = [];
|
|
146
144
|
const additionalReadRootsCanonical = [];
|
|
147
145
|
let attachmentRootCanonical;
|
|
@@ -345,34 +343,35 @@ export async function prepareHandsMount(input) {
|
|
|
345
343
|
}
|
|
346
344
|
roster.mountAll(band.map((t) => (envHandToolNames.add(t.name), firstPartyOffload(t))), { source: "builtin", mountedBy: "hands" });
|
|
347
345
|
const shellGate = effectiveShellGate;
|
|
348
|
-
if (
|
|
349
|
-
|
|
350
|
-
`
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
const bashEffectiveTier = shellGate === "always" || bashTierBefore === "always" ? "always" : "maybe";
|
|
357
|
-
irreversibilityTier.set("Bash", bashEffectiveTier);
|
|
358
|
-
irreversibleTools.add("Bash");
|
|
346
|
+
if (!(executionEnv instanceof StubExecutionEnv) && spec.handsReadOnly !== true) {
|
|
347
|
+
if (shellGate === "off") {
|
|
348
|
+
deps.onError?.(new Error(`shell gate doctrine is "off" while a real writable shell (Bash) is mounted — the read boundary is ` +
|
|
349
|
+
`still judged on every command (a deny-listed or out-of-root read asks; the ask is mandated), but no ` +
|
|
350
|
+
`residual shell-risk classifier is installed: writes, egress and unknown commands are adjudicated by ` +
|
|
351
|
+
`the ordinary policy/hook chain only. Set spec.shellGate to "classify" or "always" if this deployment ` +
|
|
352
|
+
`expects doctrine-gated shell behavior.`), { phase: "config", sessionId, classification: "shell-gate-off" });
|
|
353
|
+
}
|
|
359
354
|
const shellReadBoundary = () => ({
|
|
360
355
|
roots: [rootCanonical, ...additionalRootsCanonical, ...additionalReadRootsCanonical],
|
|
361
356
|
...(handsCwdRef?.current !== undefined ? { cwd: handsCwdRef.current } : {}),
|
|
362
357
|
denyMatch: (p) => readDenyMatcher?.matchPath(p)?.pattern ?? null,
|
|
363
358
|
...(resolvedReadFace !== undefined ? { face: resolvedReadFace } : {}),
|
|
364
359
|
});
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
const
|
|
371
|
-
irreversibilityTier.set(
|
|
372
|
-
irreversibleTools.add(
|
|
373
|
-
if (
|
|
374
|
-
reversibilityProbes.set("
|
|
375
|
-
|
|
360
|
+
const installShellSeat = (name) => {
|
|
361
|
+
const tierBefore = irreversibilityTier.get(name);
|
|
362
|
+
const seatOwned = !egressTools.has(name) && tierBefore !== "always" && tierBefore !== "maybe";
|
|
363
|
+
if (seatOwned)
|
|
364
|
+
shellGatedTools.add(name);
|
|
365
|
+
const tier = shellGate === "always" || tierBefore === "always" ? "always" : "maybe";
|
|
366
|
+
irreversibilityTier.set(name, tier);
|
|
367
|
+
irreversibleTools.add(name);
|
|
368
|
+
if (seatOwned && tier === "maybe") {
|
|
369
|
+
reversibilityProbes.set(name, shellGate === "classify" ? bashReversibilityProbe(undefined, shellReadBoundary) : bashReadBoundaryProbe(shellReadBoundary));
|
|
370
|
+
}
|
|
371
|
+
};
|
|
372
|
+
installShellSeat("Bash");
|
|
373
|
+
if (backgroundTaskToolsActive)
|
|
374
|
+
installShellSeat("Monitor");
|
|
376
375
|
}
|
|
377
376
|
}
|
|
378
377
|
return {
|
|
@@ -391,8 +390,7 @@ export async function prepareHandsMount(input) {
|
|
|
391
390
|
attachmentRootCanonical,
|
|
392
391
|
readDenyMatcher,
|
|
393
392
|
envHandToolNames,
|
|
394
|
-
|
|
395
|
-
shellGatedMonitor,
|
|
393
|
+
shellGatedTools,
|
|
396
394
|
sealReadStateSeat,
|
|
397
395
|
};
|
|
398
396
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* PrepareTask's INHERITED-GATE phase, verbatim from the driver: the live/seed fold of the
|
|
3
3
|
* chain this run inherits (ancestor rules rev-monotonic per (session, principal), shellGate by max rank, the
|
|
4
4
|
* re-supplied parent constraints with their rebuilt denial trackers, the auto-mode intent, the org-admission
|
|
5
5
|
* freeze with its tighten-only intersection and the monotonic governed bit), the effective shellGate against the
|
|
@@ -8,11 +8,11 @@
|
|
|
8
8
|
* FROZEN ask and question seats (spec over deps), the two delegation refs the memory phase binds late, the ONE
|
|
9
9
|
* child-chain assembly `inheritedGateForChildren`, the caller-tool ctx enrichment `enrichSpecToolCtx` shared by
|
|
10
10
|
* the roster wrap and the revival spawner, the denial-limit stop seat, and the full-shell reachability predicate.
|
|
11
|
-
* The interface is the dependency list the segment had implicitly
|
|
11
|
+
* The interface is the dependency list the segment had implicitly.
|
|
12
12
|
*
|
|
13
13
|
* SYNCHRONOUS FUNCTION, SYNCHRONOUS CALL: the stretch has no await (the one `await` in it sits inside the
|
|
14
14
|
* `hostSessionFork` closure a tool calls later), so the phase adds no yield between the run-refs phase before it
|
|
15
|
-
* and the caps phase after it (
|
|
15
|
+
* and the caps phase after it (a stretch with no await is extracted as a sync function).
|
|
16
16
|
*
|
|
17
17
|
* LATE-BOUND SEATS. The closures minted here run long after this phase returns — at spawn time, at tool-call
|
|
18
18
|
* time, at suspend time — and several of the facts they read are resolved by LATER stations of the same prepare:
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
* sat behind a short-circuit). Read-stability of the host handles for the call: {@link RunInternals}
|
|
26
26
|
* (`@contract prepare.deps-read-stable`).
|
|
27
27
|
*
|
|
28
|
-
* Every cell that leaves here as `borrowed-mutable` carries its writer table on the Result member
|
|
28
|
+
* Every cell that leaves here as `borrowed-mutable` carries its writer table on the Result member.
|
|
29
29
|
*/
|
|
30
30
|
import type { AgentHarness, ExecutionEnv } from "../../internal/harness.js";
|
|
31
31
|
import type { SubagentWorktreeIsolation } from "../../agents/subagent.js";
|
|
@@ -43,7 +43,7 @@ import type { DelegationContentSafety } from "../memory-engine/delegation-proven
|
|
|
43
43
|
import type { SessionPermissionRules } from "../session-policy-store.js";
|
|
44
44
|
import type { SessionStore } from "../session.js";
|
|
45
45
|
import { type OnAsk } from "../tool-policy.js";
|
|
46
|
-
import type { RunnerDeps, RuntimeCaps, TaskEvent, TaskSpec, ToolExecuteContext } from "../types.js";
|
|
46
|
+
import type { RunnerDeps, RuntimeCaps, ShellGateDoctrine, TaskEvent, TaskSpec, ToolExecuteContext } from "../types.js";
|
|
47
47
|
import type { ActiveSkillScope } from "./active-skill-scope.js";
|
|
48
48
|
import type { InheritedGate, Prepared, PrepareResume, RunInternals, ToolFaceSnapshot } from "./contracts.js";
|
|
49
49
|
import { type StopForDenialLimit } from "./denial-limit-arms.js";
|
|
@@ -194,7 +194,7 @@ export interface PrepareInheritedGateResult {
|
|
|
194
194
|
/** owned — the monotonic governed-provenance bit for this leg. */
|
|
195
195
|
orgGovernedProvenance: boolean;
|
|
196
196
|
/** owned — the spec's own shellGate tightened by the inherited doctrine. */
|
|
197
|
-
effectiveShellGate:
|
|
197
|
+
effectiveShellGate: ShellGateDoctrine;
|
|
198
198
|
/** borrowed-mutable — THIS task's own session-rule snapshot for its children's chain. Writers (R-3): the policy-chain
|
|
199
199
|
* station's session-policy read, once per leg, when a store is wired and the task carries its own sessionId. Read by
|
|
200
200
|
* `inheritedGateForChildren` at spawn time. */
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* PrepareTask's LISTINGS phase: the per-task agent definitions' tool-name audit
|
|
3
3
|
* (deny entries fail loud, allow entries advise), the agent-listing announce face read off the
|
|
4
4
|
* delegation tool's roster (with its deferred / excluded / removal-to-zero arms), the two listing
|
|
5
5
|
* opt-out advisories, the announced-listings mirror seeded from the once-per-session ledger, the
|
|
6
6
|
* deferred roster's ToolSearch ride, and the date_change seam. The body is the driver's stretch moved
|
|
7
|
-
* verbatim; the interface is the dependency list it had implicitly
|
|
7
|
+
* verbatim; the interface is the dependency list it had implicitly.
|
|
8
8
|
*
|
|
9
9
|
* SYNCHRONOUS FUNCTION, SYNCHRONOUS CALL: the stretch has no await, so the phase adds no yield between
|
|
10
|
-
* the disclosure mount before it and the context-lane seats after it (
|
|
10
|
+
* the disclosure mount before it and the context-lane seats after it (a stretch
|
|
11
11
|
* with no await is extracted as a sync function — an `async` wrapper would open a microtask window).
|
|
12
12
|
*
|
|
13
13
|
* Throws pass through unchanged: `config.agent.unknown_tool` (a deny entry naming a tool this
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* PrepareTask's LSP phase, verbatim from the driver: the manager fold (spec > deps), the
|
|
3
3
|
* LSP tool mount over the per-task env with its git-ignore filter, the diagnostics lane behind its four
|
|
4
4
|
* preconditions (a manager whose sessions feed a registry, write-capable hands, not opted out), the run-scoped
|
|
5
5
|
* registry key, and the edit nudge (raw path → the SAME resolution the tool leg uses → registry reset +
|
|
6
6
|
* session didChange). No manager ⇒ nothing mounts and both lane seats are undefined. The interface is the
|
|
7
|
-
* dependency list the segment had implicitly
|
|
7
|
+
* dependency list the segment had implicitly.
|
|
8
8
|
*
|
|
9
9
|
* SYNCHRONOUS FUNCTION, SYNCHRONOUS CALL: the stretch has no await, so the phase adds no yield between the
|
|
10
|
-
* fork-governance note before it and the memory trio's occupancy read after it (
|
|
10
|
+
* fork-governance note before it and the memory trio's occupancy read after it (a stretch
|
|
11
11
|
* with no await is extracted as a sync function — an `async` wrapper would open a microtask window).
|
|
12
12
|
* Read-stability of the host handles for the call: {@link RunInternals} (`@contract prepare.deps-read-stable`).
|
|
13
13
|
*/
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
* classification + one-way session pollution wrap section (
|
|
4
|
-
*
|
|
2
|
+
* PrepareTask's MEMORY-ENGINE-SESSION phase, verbatim from the driver: the content-origin
|
|
3
|
+
* classification + one-way session pollution wrap section (consolidating several design threads).
|
|
4
|
+
* Its arming predicate (a mounted memory session OR an
|
|
5
5
|
* upstream recorder channel), the chain-narrowed classification config, the children's provenance seat, the
|
|
6
6
|
* declared-MCP-class announcement, the settlement seat, the per-tool wrap with its three record verbs (mark /
|
|
7
7
|
* recordExternal / recordIncomplete), the Read tool's recall-taint arm and the delegation arm's three-valued
|
|
8
8
|
* attestation judgment all live here; the announcement helper only this section called moved with it. The
|
|
9
|
-
* interface is the dependency list the segment had implicitly
|
|
9
|
+
* interface is the dependency list the segment had implicitly.
|
|
10
10
|
*
|
|
11
11
|
* SYNCHRONOUS FUNCTION, SYNCHRONOUS CALL: the stretch has no await of its own (the awaits sit inside the wrappers it
|
|
12
12
|
* installs, which run at tool-call time), so the phase adds no yield between the deferred classification before it
|
|
13
|
-
* and the prompt assembly after it (
|
|
13
|
+
* and the prompt assembly after it (a stretch with no await is extracted as a sync function).
|
|
14
14
|
* Read-stability of the host handles for the call: {@link RunInternals} (`@contract prepare.deps-read-stable`).
|
|
15
15
|
*
|
|
16
16
|
* One read changed spelling and nothing else: the declared-class announcement read `mcp?.statuses` while `mcp` had
|
|
@@ -10,6 +10,7 @@ import { readSessionCaptureOptOut } from "../memory-engine/layout.js";
|
|
|
10
10
|
import { createMemoryEngineTools } from "../memory-engine/tools.js";
|
|
11
11
|
import { assertScopeContractPlacement, parseScopeKey, resolveProjectId } from "../memory-engine/scope-contract.js";
|
|
12
12
|
import { FileMemoryEngineBackend } from "../memory-engine/file-backend.js";
|
|
13
|
+
import { writableRootOf } from "../memory-engine/types.js";
|
|
13
14
|
let undeclaredCapturePostureAnnounced = false;
|
|
14
15
|
export async function prepareMemory(input) {
|
|
15
16
|
const { spec, deps, sessionId, taskRootPath, memoryWriteGateRef, admissionCtx } = input;
|
|
@@ -460,20 +461,18 @@ export async function prepareMemory(input) {
|
|
|
460
461
|
}
|
|
461
462
|
const foreignUnderRoot = [];
|
|
462
463
|
if (input.writeToolsMounted && writeHandle.writeScope !== null && input.advertisedWritableDirs !== undefined) {
|
|
463
|
-
for (const d of [...writeEngine.readonlyDirNamesUnderRoot(writeHandle)].sort())
|
|
464
|
-
foreignUnderRoot.push(`another scope's directory ${d}`);
|
|
465
464
|
const controlPlane = canonicalize(writeEngine.controlPlaneDir);
|
|
466
|
-
if (isContainedIn(writeHandle
|
|
465
|
+
if (isContainedIn(writableRootOf(writeHandle), controlPlane))
|
|
467
466
|
foreignUnderRoot.push(`the engine's control plane ${controlPlane}`);
|
|
468
467
|
}
|
|
469
468
|
if (foreignUnderRoot.length > 0) {
|
|
470
|
-
deps.onError?.(new Error(`memory advertised writable directory refused: the write scope's root ${writeHandle
|
|
469
|
+
deps.onError?.(new Error(`memory advertised writable directory refused: the write scope's root ${writableRootOf(writeHandle)} contains what is not the model's to touch (${foreignUnderRoot.join("; ")}) — the file tools' root fence is directory-granular, so admitting it would expose those files; memory writes through the file tools stay closed this session and the write instruction is not taught.`), { phase: "config", sessionId });
|
|
471
470
|
}
|
|
472
471
|
writeChannelOpen =
|
|
473
472
|
input.writeToolsMounted &&
|
|
474
473
|
writeHandle.writeScope !== null &&
|
|
475
474
|
foreignUnderRoot.length === 0 &&
|
|
476
|
-
(input.advertisedWritableDirs === undefined || (await input.advertisedWritableDirs.admit({ path: writeHandle
|
|
475
|
+
(input.advertisedWritableDirs === undefined || (await input.advertisedWritableDirs.admit({ path: writableRootOf(writeHandle), advertiser: "memory", expectCanonical: writableRootOf(writeHandle) })));
|
|
477
476
|
memoryWriteGateRef.current = async (w) => {
|
|
478
477
|
if (readOnlyEngine !== undefined && readOnlyHandle !== undefined) {
|
|
479
478
|
const ro = readOnlyEngine.gateWrite(readOnlyHandle, w.key, w.content);
|
|
@@ -482,7 +481,7 @@ export async function prepareMemory(input) {
|
|
|
482
481
|
}
|
|
483
482
|
if (input.memoryPersistenceDeclared === false) {
|
|
484
483
|
const root = writeHandle.writableRoot;
|
|
485
|
-
if (w.key === root || w.key.startsWith(`${root}${sep}`)) {
|
|
484
|
+
if (root !== null && (w.key === root || w.key.startsWith(`${root}${sep}`))) {
|
|
486
485
|
return {
|
|
487
486
|
ok: false,
|
|
488
487
|
code: "read_only_layering",
|
|
@@ -493,7 +492,7 @@ export async function prepareMemory(input) {
|
|
|
493
492
|
}
|
|
494
493
|
{
|
|
495
494
|
const root = writeHandle.writableRoot;
|
|
496
|
-
if (w.key === root || w.key.startsWith(`${root}${sep}`)) {
|
|
495
|
+
if (root !== null && (w.key === root || w.key.startsWith(`${root}${sep}`))) {
|
|
497
496
|
const state = captureOptedOut ? { record: { at: 0, reason: "in-run state" }, fault: false } : await writeEngine.sessionCaptureOptOutOrFault(sessionId);
|
|
498
497
|
if (state.record !== undefined || state.fault) {
|
|
499
498
|
return {
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* (The offload half of the prelude) — prepareTask's nested-usage accumulator, the
|
|
3
3
|
* large-tool-result offload store resolution and the THREE offload wrappers every later mount site
|
|
4
4
|
* applies (caller tools, first-party hand tools, remote MCP/A2A peers), verbatim from the driver.
|
|
5
5
|
*
|
|
6
6
|
* SYNCHRONOUS by construction: the segment held no await in the driver, and a phase that yields where
|
|
7
7
|
* the driver did not would open a microtask window between two steps that used to be adjacent (the
|
|
8
|
-
*
|
|
8
|
+
* posture). Nothing here touches the store — the wrappers close over it and only the
|
|
9
9
|
* wrapped tools' `execute` reach it, at run time.
|
|
10
10
|
*
|
|
11
11
|
* What stays in the driver: the trust-axis choice of `offloadScope` (`spec.principal ?? "default"`)
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* PrepareTask's PARK CLOSURE and CONTENT-ASK ROUTING closure, verbatim from the driver's
|
|
3
3
|
* gate-machinery block: `resolveContentAsk` (the question face's delivery race, the binding table's cap and redemption
|
|
4
4
|
* identity, the stranded-answer disclosure) and `suspendAsk` (the sync-first decline and the park-priority mandates, the
|
|
5
5
|
* args capture / fidelity projection / re-adjudication steps, the pause-then-cut fence, the gate-kind choice, the row
|
|
6
6
|
* mint, the commit through the saga and the post-commit publication). The one module-scope helper only this segment
|
|
7
|
-
* threw (`ParkRefusal`) moved with it. The interface is the dependency list the segment had implicitly
|
|
8
|
-
*
|
|
7
|
+
* threw (`ParkRefusal`) moved with it. The interface is the dependency list the segment had implicitly
|
|
8
|
+
* — the two closures used to capture every seat here off the driver's scope, which is the capture surface this
|
|
9
9
|
* decomposition exists to make explicit.
|
|
10
10
|
*
|
|
11
11
|
* The thirteen-argument park closure is unchanged: twelve positional seats then the structural {@link AskCarry}, the
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
* carry onto the row exactly as before — this phase mints no origin, changes no word, adds no arm to the closed set.
|
|
14
14
|
*
|
|
15
15
|
* SYNCHRONOUS FUNCTION, SYNCHRONOUS CALL: the stretch has no await of its own (both closures run per tool call), so the
|
|
16
|
-
* phase adds no yield between the boundary parks before it and the gate station after it
|
|
16
|
+
* phase adds no yield between the boundary parks before it and the gate station after it.
|
|
17
17
|
* Read-stability of the host handles for the call: {@link RunInternals} (`@contract prepare.deps-read-stable`).
|
|
18
18
|
*
|
|
19
19
|
* Both closures exist exactly when the ask lane and the saga do (the same predicate) — an absent lane answers two absent
|
|
@@ -25,7 +25,7 @@ import { type CheckpointStore } from "../checkpoint-store.js";
|
|
|
25
25
|
import type { SessionStore } from "../session.js";
|
|
26
26
|
import { type OnAsk, type ToolCallRequest, type ToolPolicy } from "../tool-policy.js";
|
|
27
27
|
import { type ToolResultStore } from "../tool-result-store.js";
|
|
28
|
-
import type { RunnerDeps, RuntimeCaps, TaskSpec } from "../types.js";
|
|
28
|
+
import type { RunnerDeps, RuntimeCaps, ShellGateDoctrine, TaskSpec } from "../types.js";
|
|
29
29
|
import type { CwdRef } from "../../tools/fs/fs-shared.js";
|
|
30
30
|
import { type ContentAskBinding } from "./content-ask-bindings.js";
|
|
31
31
|
import type { AskLane, ParkAsk, Prepared, SuspendSaga } from "./contracts.js";
|
|
@@ -50,7 +50,7 @@ export interface PrepareParkAskInput {
|
|
|
50
50
|
/** borrowed-readonly — the leg's checkpoint store, or undefined (then `suspendAsk` is absent — the park predicate's store
|
|
51
51
|
* term). Read: the declared fidelity; the saga writes to it. */
|
|
52
52
|
checkpointStore: CheckpointStore | undefined;
|
|
53
|
-
/** borrowed-readonly — the leg's delta seat (
|
|
53
|
+
/** borrowed-readonly — the leg's delta seat (B18): the park reads the gated tool's identity off its
|
|
54
54
|
* CURRENT roster snapshot so the row carries who the action was minted against. */
|
|
55
55
|
toolRosterDeltas: ToolRosterDeltaSeat;
|
|
56
56
|
/** borrowed-readonly — the wiring-manifest phase's park predicate (`parkLane.effective`): arms `suspendAsk`. */
|
|
@@ -108,12 +108,11 @@ export interface PrepareParkAskInput {
|
|
|
108
108
|
maxSuspends: number;
|
|
109
109
|
/** borrowed-mutable — the run-scoped remote-lifecycle failure log. Writer here: a refused `suspendVM` (`push`). */
|
|
110
110
|
remoteEnvFailures: Prepared["remoteEnvFailures"];
|
|
111
|
-
/** borrowed-readonly —
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
shellGatedMonitor: boolean;
|
|
111
|
+
/** borrowed-readonly — the shell-seat provenance set: the shell-running tools whose tier is the engine's shell seat's, not a
|
|
112
|
+
* deployment mark (the risk descriptor's `shellGated` is the gated tool's membership). */
|
|
113
|
+
shellGatedTools: ReadonlySet<string>;
|
|
115
114
|
/** borrowed-readonly — the effective shell-gate doctrine persisted on the descriptor. */
|
|
116
|
-
effectiveShellGate:
|
|
115
|
+
effectiveShellGate: ShellGateDoctrine;
|
|
117
116
|
/** borrowed-readonly — the EFFECTIVE durable-approval opt-in (the caller's, or the synthesized mandate scope): picks the
|
|
118
117
|
* gate kind, the scope and the ttl. */
|
|
119
118
|
durableApproval: TaskSpec["durableApproval"];
|
|
@@ -156,7 +155,7 @@ export interface PrepareParkAskResult {
|
|
|
156
155
|
/** The M19 park-ask phase body — prepareTask's park closure and content-ask routing stretch, verbatim (see the module header). */
|
|
157
156
|
export declare function prepareParkAsk(input: PrepareParkAskInput): PrepareParkAskResult;
|
|
158
157
|
/**
|
|
159
|
-
* From the resumed/active transcript, the batch position of `currentId
|
|
158
|
+
* From the resumed/active transcript, the batch position of `currentId`: the tool-call
|
|
160
159
|
* ids of the assistant message that issued it (the batch), and the subset already resolved (executed
|
|
161
160
|
* before the suspend — #1..k-1). ID-based, not positional (council Question #1): immune to reordering.
|
|
162
161
|
*/
|