@sema-agent/core 5.37.0 → 5.39.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 +151 -0
- package/dist/agents/send-message-tool.d.ts +8 -0
- package/dist/agents/send-message-tool.js +8 -0
- package/dist/agents/subagent.js +6 -0
- package/dist/agents/teacher.js +12 -3
- package/dist/agents/team.d.ts +7 -1
- package/dist/agents/team.js +11 -9
- package/dist/agents/verify.js +12 -3
- package/dist/core/auto-mode-prompt-assets.d.ts +5 -3
- package/dist/core/auto-mode-prompt-assets.js +1 -1
- package/dist/core/checkpoint-store.d.ts +26 -1
- package/dist/core/hooks.d.ts +152 -2
- package/dist/core/hooks.js +65 -7
- package/dist/core/mailbox-store.d.ts +39 -0
- package/dist/core/mailbox-store.js +9 -0
- package/dist/core/permission-rule-consent.d.ts +27 -4
- package/dist/core/permission-rule-consent.js +29 -4
- package/dist/core/permission-rule-model.d.ts +7 -1
- package/dist/core/runner/prepare-config-doors.d.ts +17 -0
- package/dist/core/runner/prepare-config-doors.js +33 -2
- package/dist/core/runner/prepare-task.d.ts +17 -2
- package/dist/core/runner/prepare-task.js +135 -44
- package/dist/core/runner/runtask.js +46 -11
- package/dist/core/sensitive-path-policy.js +3 -3
- package/dist/core/store-contracts/mailbox-store-contract.d.ts +29 -1
- package/dist/core/store-contracts/mailbox-store-contract.js +78 -0
- package/dist/core/tool-model-gate.d.ts +125 -0
- package/dist/core/tool-model-gate.js +303 -0
- package/dist/core/tool-policy.d.ts +1 -1
- package/dist/core/types.d.ts +210 -1
- package/dist/core/types.js +21 -0
- package/dist/core/untrusted-text.d.ts +1 -1
- package/dist/core/write-protect.d.ts +93 -0
- package/dist/core/write-protect.js +194 -0
- package/dist/index.d.ts +7 -5
- package/dist/index.js +5 -3
- package/dist/orchestration/builtin-workflows.d.ts +68 -6
- package/dist/orchestration/builtin-workflows.js +26 -9
- package/dist/orchestration/governance-baseline-validity.d.ts +44 -0
- package/dist/orchestration/governance-baseline-validity.js +55 -0
- package/dist/orchestration/run-workflow-tool.d.ts +10 -1
- package/dist/orchestration/run-workflow-tool.js +99 -31
- package/dist/orchestration/workflow-script-runner.js +9 -4
- package/dist/orchestration/workflow-script-store.d.ts +8 -3
- package/dist/prompts/coordinator.d.ts +4 -1
- package/dist/prompts/coordinator.js +8 -0
- package/dist/prompts/default.d.ts +14 -4
- package/dist/prompts/default.js +2 -1
- package/dist/scenarios/full-body.d.ts +5 -0
- package/dist/scenarios/full-body.js +8 -4
- package/dist/tools/fs/fs-shared.d.ts +3 -2
- package/dist/tools/fs/fs-shared.js +19 -9
- package/dist/tools/fs/read-deny.d.ts +15 -5
- package/dist/tools/fs/read-deny.js +33 -12
- package/dist/tools/fs/safety.d.ts +4 -1
- package/dist/tools/fs/safety.js +4 -2
- package/package.json +1 -1
- package/test/export-surface.snapshot.json +24 -1
|
@@ -4,6 +4,7 @@ import { resolveCheckpointStore } from "../checkpoint-store.js";
|
|
|
4
4
|
import { preflightLockedConfig } from "../locked-config.js";
|
|
5
5
|
import { assertRetentionCapability } from "../retention.js";
|
|
6
6
|
import { resolveModel, resolveTaskModel, roleModelIfSet } from "../roles.js";
|
|
7
|
+
import { applyToolModelGate, assertRestoreGatedToolsValue, modelIdTail } from "../tool-model-gate.js";
|
|
7
8
|
import { resolveUsageWindows } from "../usage-window-store.js";
|
|
8
9
|
import { deriveAskEffective, resolveAskSeamForm, resolveQuestionSeam } from "../wiring-manifest.js";
|
|
9
10
|
const TASK_LIMIT_KEY_DICT = {
|
|
@@ -73,7 +74,7 @@ export function resolveTaskLimits(limits) {
|
|
|
73
74
|
return limits;
|
|
74
75
|
}
|
|
75
76
|
export function isFableFamilyModelId(id) {
|
|
76
|
-
const tail = id
|
|
77
|
+
const tail = modelIdTail(id);
|
|
77
78
|
return /^claude-fable-\d/.test(tail) || /^claude-mythos-5(?!\d)/.test(tail);
|
|
78
79
|
}
|
|
79
80
|
export function resolveModelPromptTraits(model, spec, internals) {
|
|
@@ -85,10 +86,16 @@ export function resolveModelPromptTraits(model, spec, internals) {
|
|
|
85
86
|
export function prepareConfigDoors(input) {
|
|
86
87
|
const { deps, sessions, resume, internals } = input;
|
|
87
88
|
let spec = input.spec;
|
|
89
|
+
assertRestoreGatedToolsValue(spec.restoreGatedTools);
|
|
88
90
|
const toolFaceSnapshot = {
|
|
89
91
|
exclude: spec.excludeTools ? Object.freeze([...spec.excludeTools]) : undefined,
|
|
90
92
|
defer: spec.deferTools ? Object.freeze([...spec.deferTools]) : undefined,
|
|
91
93
|
alwaysLoad: spec.alwaysLoadTools ? Object.freeze([...spec.alwaysLoadTools]) : undefined,
|
|
94
|
+
restoreGated: spec.restoreGatedTools === true
|
|
95
|
+
? true
|
|
96
|
+
: spec.restoreGatedTools !== undefined
|
|
97
|
+
? Object.freeze([...spec.restoreGatedTools])
|
|
98
|
+
: undefined,
|
|
92
99
|
};
|
|
93
100
|
const promptProfile = resolveModelPromptTraits({ id: "" }, spec, internals).promptProfile;
|
|
94
101
|
if (spec.resumeAt !== undefined) {
|
|
@@ -223,11 +230,34 @@ export function prepareConfigDoors(input) {
|
|
|
223
230
|
throw e;
|
|
224
231
|
}
|
|
225
232
|
const perTask = spec.agents;
|
|
226
|
-
spec = {
|
|
233
|
+
spec = {
|
|
234
|
+
...spec,
|
|
235
|
+
tools: pool.map((t) => {
|
|
236
|
+
if (typeof t.withAgents !== "function")
|
|
237
|
+
return t;
|
|
238
|
+
const rebuilt = t.withAgents(perTask);
|
|
239
|
+
return t.modelGate !== undefined && rebuilt.modelGate === undefined ? { ...rebuilt, modelGate: t.modelGate } : rebuilt;
|
|
240
|
+
}),
|
|
241
|
+
};
|
|
227
242
|
}
|
|
228
243
|
const resolvedRole = resolveTaskModel(spec, deps);
|
|
229
244
|
const model = resolvedRole.model;
|
|
230
245
|
const fableMitigations = resolveModelPromptTraits(model, spec, internals).fableMitigations;
|
|
246
|
+
const gateDecision = applyToolModelGate({
|
|
247
|
+
tools: spec.tools,
|
|
248
|
+
modelId: model.id,
|
|
249
|
+
depsSeat: deps.toolModelGate,
|
|
250
|
+
restoreGated: toolFaceSnapshot.restoreGated,
|
|
251
|
+
envRaw: process.env.SEMA_TOOL_MODEL_GATE,
|
|
252
|
+
});
|
|
253
|
+
if (gateDecision.survivors !== undefined) {
|
|
254
|
+
spec = { ...spec, tools: gateDecision.survivors };
|
|
255
|
+
}
|
|
256
|
+
const modelGate = Object.freeze({
|
|
257
|
+
removedByClass: gateDecision.removedByClass,
|
|
258
|
+
unknownClasses: gateDecision.unknownClasses,
|
|
259
|
+
discardedEnvRaw: gateDecision.discardedEnvRaw,
|
|
260
|
+
});
|
|
231
261
|
const thinking = spec.thinking ?? resolvedRole.thinking ?? model.defaultThinking;
|
|
232
262
|
const compModel = spec.compactionModel
|
|
233
263
|
? resolveModel(spec.compactionModel, deps.models)
|
|
@@ -243,6 +273,7 @@ export function prepareConfigDoors(input) {
|
|
|
243
273
|
thinking,
|
|
244
274
|
compModel,
|
|
245
275
|
fableMitigations,
|
|
276
|
+
modelGate,
|
|
246
277
|
usageWindows,
|
|
247
278
|
brainCallGuardrailRef,
|
|
248
279
|
brainCallGuardrailMs,
|
|
@@ -11,7 +11,7 @@ import { SubagentRetainLedger } from "../../agents/retain-ledger.js";
|
|
|
11
11
|
import type { OnAsk, ToolCallRequest, ToolPolicy } from "../tool-policy.js";
|
|
12
12
|
import { type ActiveSkillFrame } from "./active-skill-scope.js";
|
|
13
13
|
import type { SessionPermissionRules } from "../session-policy-store.js";
|
|
14
|
-
import { type Hooks, type OrgGateVerdict } from "../hooks.js";
|
|
14
|
+
import { type Hooks, type HookInvocationIdentity, type OrgGateVerdict } from "../hooks.js";
|
|
15
15
|
import type { RecoveredOrphan } from "../session-reconcile.js";
|
|
16
16
|
import { CacheBreakDetector, type ToolFingerprintInput } from "../cache-break-detector.js";
|
|
17
17
|
import { type BrainCallGuardrailRef } from "../../brain/timeout.js";
|
|
@@ -29,8 +29,14 @@ import { type WiringManifest } from "../wiring-manifest.js";
|
|
|
29
29
|
import type { ActiveWorktreeSession, AgentMessage, AgentTool, ExecutionEnv } from "../../internal/harness.js";
|
|
30
30
|
import type { NestedUsageAccum, RunnerDeps, TaskEvent, TaskResult, TaskSpec, ToolActivity, ToolEffect } from "../types.js";
|
|
31
31
|
import type { RepairBundle } from "../../agents/repair-loop.js";
|
|
32
|
-
/** Test seam (mirrors `
|
|
32
|
+
/** Test seam (mirrors `__resetToolModelGateAnnouncements`): never called by production code.
|
|
33
|
+
* Re-arms BOTH arms (a WeakMap has no clear — it is re-minted). */
|
|
33
34
|
export declare function __resetMaterializeEnvAnnouncements(): void;
|
|
35
|
+
/** Test seam (mirrors `__resetMaterializeEnvAnnouncements`): never called by production code.
|
|
36
|
+
* Re-arms BOTH arms (a WeakMap has no clear — it is re-minted). Deliberately UNLIKE the read-face
|
|
37
|
+
* seam below (console latch only): tests here legitimately reuse ONE sink across prepares to pin
|
|
38
|
+
* the per-sink dedup itself, so the seam must be able to re-arm a still-referenced sink. */
|
|
39
|
+
export declare function __resetToolModelGateAnnouncements(): void;
|
|
34
40
|
/** Test seam (mirrors `__resetMalformedNoticeSeatAnnouncement`): never called by production code.
|
|
35
41
|
* Deliberately asymmetric — it resets only the console latch: the WeakSet arm needs no seam
|
|
36
42
|
* because a test resets it by minting a fresh sink function (identity IS the ledger key), while
|
|
@@ -279,6 +285,15 @@ export interface Prepared {
|
|
|
279
285
|
* model/tool interaction. Host/operator plane — never enters model context.
|
|
280
286
|
*/
|
|
281
287
|
wiringManifest: WiringManifest;
|
|
288
|
+
/**
|
|
289
|
+
* #281 件A — this leg's frozen identity envelope, minted ONCE in prepare beside the wiring
|
|
290
|
+
* manifest (same leg derivation, one mint — {@link mintHookInvocationIdentity}). Every hook
|
|
291
|
+
* station runtask drives (stop/stopFailure/userPromptSubmit/postToolBatch, the compaction
|
|
292
|
+
* wrapper) and the 件B delegation-lifecycle observer read THIS object; prepare's own stations
|
|
293
|
+
* (the tool gate, the post-tool contexts) close over the same const. Always present — a prepared
|
|
294
|
+
* leg always knows its identity.
|
|
295
|
+
*/
|
|
296
|
+
hookIdentity: HookInvocationIdentity;
|
|
282
297
|
promptManifest: {
|
|
283
298
|
constitution: "core" | "replaced" | "provider-assembled";
|
|
284
299
|
blocks: Array<{
|
|
@@ -28,8 +28,9 @@ import { CHANGED_FILES_MTIME_EPS_MS, fenceMcpServerInstructions, renderAgentList
|
|
|
28
28
|
import { inlineUntrusted } from "../untrusted-text.js";
|
|
29
29
|
import { policyAskClassOf } from "../ask-class.js";
|
|
30
30
|
import { emitTrace } from "../trace.js";
|
|
31
|
-
import { createSessionRulePolicy } from "./session-rule-policy.js";
|
|
32
|
-
import { cloneObserverInput, createHookEnvCapabilities, createPreToolUseConstraintPolicy, formatHookFeedback, persistedRuleMandateOf, runToolGate } from "../hooks.js";
|
|
31
|
+
import { createSessionRulePolicy, PATH_CONFINABLE_WRITE_TOOLS } from "./session-rule-policy.js";
|
|
32
|
+
import { cloneObserverInput, createHookEnvCapabilities, createPreToolUseConstraintPolicy, formatHookFeedback, mintHookInvocationIdentity, persistedRuleMandateOf, runToolGate } from "../hooks.js";
|
|
33
|
+
import { createWriteProtectionCheck } from "../write-protect.js";
|
|
33
34
|
import { orgRuleVerdictFor } from "../permission-rule-org.js";
|
|
34
35
|
import { CacheBreakDetector, toolsToFingerprintInputs } from "../cache-break-detector.js";
|
|
35
36
|
import { reservedCollisions, reservedFor } from "../../brain/request-params.js";
|
|
@@ -92,13 +93,104 @@ import { countElicitOptIns, deriveWiringManifest, resolveAskSeamForm, resolveDec
|
|
|
92
93
|
import { durableParkGapFor } from "../park-selfcheck.js";
|
|
93
94
|
import { GLOBAL_USAGE_KEY, usageRetryAfterMs } from "../usage-window-store.js";
|
|
94
95
|
import { deliverEngineNotice } from "../types.js";
|
|
95
|
-
|
|
96
|
+
let announcedMaterializeEnvBySink = new WeakMap();
|
|
97
|
+
const announcedMaterializeEnvConsole = new Set();
|
|
98
|
+
function materializeEnvLedger(onNotice) {
|
|
99
|
+
if (typeof onNotice !== "function")
|
|
100
|
+
return announcedMaterializeEnvConsole;
|
|
101
|
+
let lines = announcedMaterializeEnvBySink.get(onNotice);
|
|
102
|
+
if (lines === undefined) {
|
|
103
|
+
lines = new Set();
|
|
104
|
+
announcedMaterializeEnvBySink.set(onNotice, lines);
|
|
105
|
+
}
|
|
106
|
+
return lines;
|
|
107
|
+
}
|
|
96
108
|
export function __resetMaterializeEnvAnnouncements() {
|
|
97
|
-
|
|
109
|
+
announcedMaterializeEnvBySink = new WeakMap();
|
|
110
|
+
announcedMaterializeEnvConsole.clear();
|
|
98
111
|
}
|
|
99
112
|
function emitMaterializeEnvNotice(onNotice, message, detail) {
|
|
113
|
+
const ledger = materializeEnvLedger(onNotice);
|
|
114
|
+
if (ledger.has(message))
|
|
115
|
+
return;
|
|
116
|
+
ledger.add(message);
|
|
100
117
|
deliverEngineNotice(onNotice, { code: "config.materialize_env_discarded", message, detail });
|
|
101
118
|
}
|
|
119
|
+
function warnCompactionWindowHazard(tracer, spec, model, compModel, hostTaskId) {
|
|
120
|
+
if (compModel === undefined)
|
|
121
|
+
return;
|
|
122
|
+
const compWindow = compModel.contextTokens ?? compModel.contextWindow;
|
|
123
|
+
const mainWindow = model.autoCompactTokens ?? model.contextTokens ?? model.contextWindow;
|
|
124
|
+
if (compWindow > 0 && mainWindow > 0 && compWindow < mainWindow) {
|
|
125
|
+
const merged = { ...DEFAULT_COMPACTION_SETTINGS, ...spec.compaction };
|
|
126
|
+
const sanitized = sanitizeCompactionSettings(merged, mainWindow);
|
|
127
|
+
const tolerance = sanitized.clampTolerance ?? DEFAULT_CLAMP_TOLERANCE;
|
|
128
|
+
const headroom = Math.max(0, compWindow - Math.max(Math.floor(0.8 * summaryOutputBudgetTokens(compModel, sanitized)), 2048) - 512);
|
|
129
|
+
emitTrace(tracer, () => ({
|
|
130
|
+
kind: "compaction.window_config_warning",
|
|
131
|
+
version: 1,
|
|
132
|
+
taskId: hostTaskId,
|
|
133
|
+
compactionModelWindow: compWindow,
|
|
134
|
+
mainModelWindow: mainWindow,
|
|
135
|
+
...(tolerance < 1 ? { fallbackAt: Math.floor(headroom / (1 - tolerance)) } : {}),
|
|
136
|
+
ts: Date.now(),
|
|
137
|
+
}));
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
let announcedToolModelGateBySink = new WeakMap();
|
|
141
|
+
const announcedToolModelGateConsole = new Set();
|
|
142
|
+
function toolModelGateLedger(onNotice) {
|
|
143
|
+
if (typeof onNotice !== "function")
|
|
144
|
+
return announcedToolModelGateConsole;
|
|
145
|
+
let lines = announcedToolModelGateBySink.get(onNotice);
|
|
146
|
+
if (lines === undefined) {
|
|
147
|
+
lines = new Set();
|
|
148
|
+
announcedToolModelGateBySink.set(onNotice, lines);
|
|
149
|
+
}
|
|
150
|
+
return lines;
|
|
151
|
+
}
|
|
152
|
+
export function __resetToolModelGateAnnouncements() {
|
|
153
|
+
announcedToolModelGateBySink = new WeakMap();
|
|
154
|
+
announcedToolModelGateConsole.clear();
|
|
155
|
+
}
|
|
156
|
+
function announceToolModelGate(onNotice, modelId, gate) {
|
|
157
|
+
const ledger = toolModelGateLedger(onNotice);
|
|
158
|
+
for (const [gateClass, removed] of gate.removedByClass) {
|
|
159
|
+
const line = `Model gate: default-mounted tool(s) ${removed.map((n) => JSON.stringify(n)).join(", ")} (class ${JSON.stringify(gateClass)}) ` +
|
|
160
|
+
`were not mounted for model ${JSON.stringify(modelId)} — the gate table marks this model as managing multi-step work without the scaffold. ` +
|
|
161
|
+
`Explicitly composed tools are exempt; restore via TaskSpec.restoreGatedTools, SEMA_TOOL_MODEL_GATE=off, or RunnerDeps.toolModelGate: false.`;
|
|
162
|
+
if (!ledger.has(line)) {
|
|
163
|
+
ledger.add(line);
|
|
164
|
+
deliverEngineNotice(onNotice, {
|
|
165
|
+
code: "config.tool_model_gate_removed",
|
|
166
|
+
message: line,
|
|
167
|
+
detail: {
|
|
168
|
+
modelId,
|
|
169
|
+
gateClass,
|
|
170
|
+
removed: [...removed],
|
|
171
|
+
restore: { spec: "TaskSpec.restoreGatedTools", env: "SEMA_TOOL_MODEL_GATE=off", deps: "RunnerDeps.toolModelGate: false" },
|
|
172
|
+
},
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
for (const gateClass of gate.unknownClasses) {
|
|
177
|
+
const line = `ToolSpec.modelGate names gate class ${JSON.stringify(gateClass)}, which no row of the merged gate table defines — the tag is inert ` +
|
|
178
|
+
`(fail-open: the tool stays mounted). Fix the tag, or define the class via RunnerDeps.toolModelGate.classes.`;
|
|
179
|
+
if (!ledger.has(line)) {
|
|
180
|
+
ledger.add(line);
|
|
181
|
+
deliverEngineNotice(onNotice, { code: "config.tool_model_gate_unknown_class", message: line, detail: { gateClass } });
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
if (gate.discardedEnvRaw !== undefined) {
|
|
185
|
+
const line = `SEMA_TOOL_MODEL_GATE=${JSON.stringify(gate.discardedEnvRaw)} is not in the closed set (on|1|true|off|0|false, case-insensitive) — ` +
|
|
186
|
+
`not in force on this task (nothing the model gate would remove), but a task where the gate WOULD trim a default-mounted tool ` +
|
|
187
|
+
`will refuse to prepare under it (config.tool_model_gate_env_invalid). Fix or unset the flag.`;
|
|
188
|
+
if (!ledger.has(line)) {
|
|
189
|
+
ledger.add(line);
|
|
190
|
+
deliverEngineNotice(onNotice, { code: "config.tool_model_gate_env_invalid", message: line, detail: { raw: gate.discardedEnvRaw } });
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
}
|
|
102
194
|
const readFaceClampAnnouncedSinks = new WeakSet();
|
|
103
195
|
let readFaceClampConsoleAnnounced = false;
|
|
104
196
|
export function __resetReadFaceClampAnnouncement() {
|
|
@@ -153,8 +245,9 @@ export { rebaseWorkspacePath, rebaseWorkspacePathAcross } from "./prepare-worksp
|
|
|
153
245
|
function hasConversationContent(branch) {
|
|
154
246
|
return branch.some((e) => e.type === "message" || e.type === "custom_message" || e.type === "compaction");
|
|
155
247
|
}
|
|
156
|
-
function
|
|
157
|
-
|
|
248
|
+
function effectiveDelegationFacts(internals, seedIsDelegatedChild) {
|
|
249
|
+
const isDelegatedChild = internals?.isDelegatedChild !== undefined ? internals.isDelegatedChild === true : seedIsDelegatedChild === true;
|
|
250
|
+
return { isDelegatedChild, isNonForkChild: isDelegatedChild && internals?.insideFork !== true };
|
|
158
251
|
}
|
|
159
252
|
export function batchContextAt(messages, currentId) {
|
|
160
253
|
let batch = [];
|
|
@@ -238,6 +331,7 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
|
|
|
238
331
|
const doors = prepareConfigDoors({ spec, deps, sessions, resume, internals });
|
|
239
332
|
spec = doors.spec;
|
|
240
333
|
const { toolFaceSnapshot, promptProfile, lockedPreflight, resolvedInteractionPosture, resolvedRole, model, thinking, compModel, fableMitigations, usageWindows, brainCallGuardrailRef, brainCallGuardrailMs } = doors;
|
|
334
|
+
announceToolModelGate(deps.onNotice, model.id, doors.modelGate);
|
|
241
335
|
const { toolEffects, egressTools, irreversibleTools, irreversibilityTier, axisExplicitNegatives, reversibilityProbes, ownToolNames } = prepareSafetyScan({ spec, deps });
|
|
242
336
|
let shellGatedBash = false;
|
|
243
337
|
let shellGatedMonitor = false;
|
|
@@ -249,25 +343,8 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
|
|
|
249
343
|
const { acquired, session, conflictRef, wakeRecovered, resumeAtBeforeParentId } = await prepareAcquireReconcile({ sessions, spec, resume, toolEffects, ...(() => { const g = durableParkGapFor(deps, spec); return g !== undefined ? { durableParkGap: g } : {}; })() });
|
|
250
344
|
const sessionId = acquired.sessionId;
|
|
251
345
|
const hostTaskId = spec.taskId ?? sessionId;
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
const mainWindow = model.autoCompactTokens ?? model.contextTokens ?? model.contextWindow;
|
|
255
|
-
if (compWindow > 0 && mainWindow > 0 && compWindow < mainWindow) {
|
|
256
|
-
const merged = { ...DEFAULT_COMPACTION_SETTINGS, ...spec.compaction };
|
|
257
|
-
const sanitized = sanitizeCompactionSettings(merged, mainWindow);
|
|
258
|
-
const tolerance = sanitized.clampTolerance ?? DEFAULT_CLAMP_TOLERANCE;
|
|
259
|
-
const headroom = Math.max(0, compWindow - Math.max(Math.floor(0.8 * summaryOutputBudgetTokens(compModel, sanitized)), 2048) - 512);
|
|
260
|
-
emitTrace(deps.tracer, () => ({
|
|
261
|
-
kind: "compaction.window_config_warning",
|
|
262
|
-
version: 1,
|
|
263
|
-
taskId: hostTaskId,
|
|
264
|
-
compactionModelWindow: compWindow,
|
|
265
|
-
mainModelWindow: mainWindow,
|
|
266
|
-
...(tolerance < 1 ? { fallbackAt: Math.floor(headroom / (1 - tolerance)) } : {}),
|
|
267
|
-
ts: Date.now(),
|
|
268
|
-
}));
|
|
269
|
-
}
|
|
270
|
-
}
|
|
346
|
+
const delegation = effectiveDelegationFacts(internals, resume?.seed.isDelegatedChild);
|
|
347
|
+
warnCompactionWindowHazard(deps.tracer, spec, model, compModel, hostTaskId);
|
|
271
348
|
const taskScope = internals?.registryScope ?? spec.principal ?? "default";
|
|
272
349
|
internals?.peerSelfRef?.addAxis("s", sessionId);
|
|
273
350
|
internals?.peerSelfRef?.addAxis("t", hostTaskId);
|
|
@@ -705,6 +782,7 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
|
|
|
705
782
|
excludeTools: toolFaceSnapshot.exclude,
|
|
706
783
|
deferTools: toolFaceSnapshot.defer,
|
|
707
784
|
alwaysLoadTools: toolFaceSnapshot.alwaysLoad,
|
|
785
|
+
...(toolFaceSnapshot.restoreGated !== undefined ? { restoreGatedTools: toolFaceSnapshot.restoreGated } : {}),
|
|
708
786
|
promptProfile,
|
|
709
787
|
...(spec.additionalDirectories !== undefined ? { additionalDirectories: Object.freeze([...spec.additionalDirectories]) } : {}),
|
|
710
788
|
...(spec.additionalReadDirectories !== undefined ? { additionalReadDirectories: Object.freeze([...spec.additionalReadDirectories]) } : {}),
|
|
@@ -876,6 +954,7 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
|
|
|
876
954
|
parentExcludeTools: toolFaceSnapshot.exclude,
|
|
877
955
|
parentDeferTools: toolFaceSnapshot.defer,
|
|
878
956
|
parentAlwaysLoadTools: toolFaceSnapshot.alwaysLoad,
|
|
957
|
+
...(toolFaceSnapshot.restoreGated !== undefined ? { parentRestoreGatedTools: toolFaceSnapshot.restoreGated } : {}),
|
|
879
958
|
parentPromptProfile: promptProfile,
|
|
880
959
|
models: deps.models,
|
|
881
960
|
agents: deps.agents,
|
|
@@ -1335,6 +1414,8 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
|
|
|
1335
1414
|
toolEffects.set("TaskStop", "write");
|
|
1336
1415
|
tools.push(firstPartyOffload(createTaskOutputTool({ registry: defaultTaskRegistry, owner: hostTaskId, scope: taskScope, sessionId, workflowStore: deps.workflowRunStore, agentStore: deps.backgroundAgentStore, notificationWired: internals?.onTaskNotification !== undefined, oneShot: spec.oneShot, toolResultStore: offloadStore })), firstPartyOffload(createTaskStopTool({ registry: defaultTaskRegistry, owner: hostTaskId, scope: taskScope, sessionId, workflowStore: deps.workflowRunStore, agentStore: deps.backgroundAgentStore })));
|
|
1337
1416
|
if (runnerSelf && !(spec.tools ?? []).some((t) => t.name === SEND_MESSAGE_TOOL_NAME)) {
|
|
1417
|
+
toolEffects.set(SEND_MESSAGE_TOOL_NAME, "write");
|
|
1418
|
+
axisExplicitNegatives.set(SEND_MESSAGE_TOOL_NAME, { ...axisExplicitNegatives.get(SEND_MESSAGE_TOOL_NAME), egress: false });
|
|
1338
1419
|
const delegationForRevive = (spec.tools ?? []).find((t) => t.agentListing !== undefined);
|
|
1339
1420
|
const reviveSpawn = delegationForRevive !== undefined && deps.backgroundAgentStore !== undefined && deps.mailboxStore !== undefined
|
|
1340
1421
|
? async (req) => {
|
|
@@ -1581,7 +1662,7 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
|
|
|
1581
1662
|
orgMemoryDenied: complianceDenies.has("org_memory_mount"),
|
|
1582
1663
|
complianceDegraded,
|
|
1583
1664
|
parentAdmittedOrgScopes: foldAdmissionFreeze({
|
|
1584
|
-
delegated:
|
|
1665
|
+
delegated: delegation.isDelegatedChild ||
|
|
1585
1666
|
internals?.inheritedGate !== undefined ||
|
|
1586
1667
|
(resume?.seed.inheritedGate !== undefined &&
|
|
1587
1668
|
(resume.seed.inheritedGate.ancestorRules !== undefined ||
|
|
@@ -1650,7 +1731,7 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
|
|
|
1650
1731
|
loaded = await Promise.resolve(deps.loadProjectMemory({
|
|
1651
1732
|
cwd: taskRootFinal,
|
|
1652
1733
|
handsEnabled,
|
|
1653
|
-
isSubagent:
|
|
1734
|
+
isSubagent: delegation.isNonForkChild,
|
|
1654
1735
|
...(internals?.agentName ? { agentName: internals.agentName } : {}),
|
|
1655
1736
|
sessionId,
|
|
1656
1737
|
phase: projectMemoryPhase,
|
|
@@ -1775,7 +1856,7 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
|
|
|
1775
1856
|
awarenessEnabled: thinking !== undefined && ULTRA_REASONING_TIERS.has(thinking),
|
|
1776
1857
|
worktreeIsolated: internals?.isolation === "worktree" && ownedEnv !== undefined,
|
|
1777
1858
|
withinTaskCompactionEnabled: (spec.compaction?.enabled ?? true) && (spec.compaction?.withinTask ?? true),
|
|
1778
|
-
isSubagent:
|
|
1859
|
+
isSubagent: delegation.isNonForkChild,
|
|
1779
1860
|
};
|
|
1780
1861
|
const userSystemPrompt = spec.systemPrompt ?? resolvedRole.systemPrompt ?? internals?.defaultSystemPrompt;
|
|
1781
1862
|
const userAppendSystemPrompt = spec.appendSystemPrompt;
|
|
@@ -2209,10 +2290,7 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
|
|
|
2209
2290
|
const raw = process.env.SEMA_TOOL_MATERIALIZE_STRATEGY;
|
|
2210
2291
|
if (raw !== undefined && raw !== "swap" && raw !== "static" && deferred.size === 0) {
|
|
2211
2292
|
const line = `SEMA_TOOL_MATERIALIZE_STRATEGY=${JSON.stringify(raw)} is not "swap" or "static" — inert on this task (no deferred tools), but a deferring task WITHOUT an explicit spec strategy will refuse to prepare under it (an explicit legal spec outranks and discards it, loudly). Fix or unset the flag.`;
|
|
2212
|
-
|
|
2213
|
-
announcedMaterializeEnv.add(line);
|
|
2214
|
-
emitMaterializeEnvNotice(deps.onNotice, line, { raw });
|
|
2215
|
-
}
|
|
2293
|
+
emitMaterializeEnvNotice(deps.onNotice, line, { raw });
|
|
2216
2294
|
}
|
|
2217
2295
|
}
|
|
2218
2296
|
if (deferred.size > 0) {
|
|
@@ -2231,10 +2309,7 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
|
|
|
2231
2309
|
}
|
|
2232
2310
|
if (envStrategyInvalid) {
|
|
2233
2311
|
const line = `SEMA_TOOL_MATERIALIZE_STRATEGY=${JSON.stringify(rawEnvStrategy)} was ignored — not "swap" or "static", and the task spec pins toolMaterializeStrategy=${JSON.stringify(spec.toolMaterializeStrategy)} which outranks it. Fix or unset the env flag.`;
|
|
2234
|
-
|
|
2235
|
-
announcedMaterializeEnv.add(line);
|
|
2236
|
-
emitMaterializeEnvNotice(deps.onNotice, line, { raw: rawEnvStrategy, specStrategy: spec.toolMaterializeStrategy });
|
|
2237
|
-
}
|
|
2312
|
+
emitMaterializeEnvNotice(deps.onNotice, line, { raw: rawEnvStrategy, specStrategy: spec.toolMaterializeStrategy });
|
|
2238
2313
|
}
|
|
2239
2314
|
const envStrategy = envStrategyInvalid ? undefined : rawEnvStrategy;
|
|
2240
2315
|
const requestedStrategy = spec.toolMaterializeStrategy ?? envStrategy ?? "swap";
|
|
@@ -2741,7 +2816,7 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
|
|
|
2741
2816
|
list.push({ cls, layer });
|
|
2742
2817
|
foldAskClasses.set(toolCallId, list);
|
|
2743
2818
|
};
|
|
2744
|
-
const sandboxBoundaryCapable = (toolName) => egressTools.has(toolName) || toolName.includes("__") || ownToolNames.has(toolName);
|
|
2819
|
+
const sandboxBoundaryCapable = (toolName) => egressTools.has(toolName) || toolName.includes("__") || ownToolNames.has(toolName) || toolName === SEND_MESSAGE_TOOL_NAME;
|
|
2745
2820
|
const emitSandboxAdmitted = (info) => {
|
|
2746
2821
|
emitTrace(deps.tracer, () => ({
|
|
2747
2822
|
kind: "permission.sandbox_admitted",
|
|
@@ -2785,7 +2860,7 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
|
|
|
2785
2860
|
...((internals?.explicitAgentName ?? internals?.agentName) !== undefined
|
|
2786
2861
|
? { sourceAgentName: internals?.explicitAgentName ?? internals?.agentName }
|
|
2787
2862
|
: {}),
|
|
2788
|
-
...(
|
|
2863
|
+
...(delegation.isDelegatedChild ? { isDelegatedChild: true } : {}),
|
|
2789
2864
|
});
|
|
2790
2865
|
const riskAxesOf = (toolName) => {
|
|
2791
2866
|
const tier = irreversibilityTier.get(toolName);
|
|
@@ -3347,6 +3422,15 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
|
|
|
3347
3422
|
retentionPolicyWired: deps.retentionPolicy !== undefined,
|
|
3348
3423
|
});
|
|
3349
3424
|
const parkLaneArmed = wiringManifest.parkLane.effective === true;
|
|
3425
|
+
const hookIdentity = mintHookInvocationIdentity({
|
|
3426
|
+
sessionId,
|
|
3427
|
+
taskId: spec.taskId ?? sessionId,
|
|
3428
|
+
legKind: wiringManifest.leg.kind,
|
|
3429
|
+
isDelegatedChild: delegation.isDelegatedChild,
|
|
3430
|
+
...(internals?.insideFork === true ? { insideFork: true } : {}),
|
|
3431
|
+
...(internals?.agentName !== undefined ? { agentName: internals.agentName } : {}),
|
|
3432
|
+
...(internals?.parentToolCallId !== undefined ? { parentToolCallId: internals.parentToolCallId } : {}),
|
|
3433
|
+
});
|
|
3350
3434
|
const hookContextConsumerWired = hooks?.preToolUse !== undefined || hooks?.postToolUse !== undefined || hooks?.postToolUseFailure !== undefined;
|
|
3351
3435
|
const hookEnvFace = hookContextConsumerWired && (ownedEnv ?? deps.executionEnv) != null ? createHookEnvCapabilities(executionEnv) : undefined;
|
|
3352
3436
|
if (effectivePolicy || hooks?.preToolUse || egressTools.size > 0 || irreversibleTools.size > 0 || resourceSuspendEligible || platformSuspendArmed || spec.enablePlanMode === true) {
|
|
@@ -3556,6 +3640,7 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
|
|
|
3556
3640
|
: undefined,
|
|
3557
3641
|
gitAnnouncement: gitStatusRef.announced !== undefined ? { ...gitStatusRef.announced } : undefined,
|
|
3558
3642
|
delegationProvenance: internals?.delegationProvenance !== undefined ? { ...internals.delegationProvenance.ref.current } : undefined,
|
|
3643
|
+
isDelegatedChild: hookIdentity.isDelegatedChild ? true : undefined,
|
|
3559
3644
|
});
|
|
3560
3645
|
const commitSuspendSaga = async (token, cp, remoteEnv, remoteHandle) => {
|
|
3561
3646
|
if (!checkpointStore)
|
|
@@ -4138,13 +4223,16 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
|
|
|
4138
4223
|
if (eff !== undefined && !toolEffects.has(t.name))
|
|
4139
4224
|
toolEffects.set(t.name, eff);
|
|
4140
4225
|
}
|
|
4226
|
+
const writeProtectionCheck = createWriteProtectionCheck(deps.writeProtectedPaths);
|
|
4227
|
+
const writeProtectionArmed = writeProtectionCheck !== undefined && tools.some((t) => PATH_CONFINABLE_WRITE_TOOLS.has(t.name));
|
|
4141
4228
|
toolCallGateArmedRef.armed =
|
|
4142
4229
|
effectivePolicy !== undefined ||
|
|
4143
4230
|
hooks?.preToolUse !== undefined ||
|
|
4144
4231
|
egressTools.size > 0 ||
|
|
4145
4232
|
irreversibleTools.size > 0 ||
|
|
4146
4233
|
spec.enablePlanMode === true ||
|
|
4147
|
-
complianceDenies.has("web_fetch")
|
|
4234
|
+
complianceDenies.has("web_fetch") ||
|
|
4235
|
+
writeProtectionArmed;
|
|
4148
4236
|
if (toolCallGateArmedRef.armed) {
|
|
4149
4237
|
harness.on("tool_call", async (e) => {
|
|
4150
4238
|
blockedToolCalls.delete(e.toolCallId);
|
|
@@ -4155,7 +4243,7 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
|
|
|
4155
4243
|
if (blockedTracked)
|
|
4156
4244
|
blockedToolCalls.add(e.toolCallId);
|
|
4157
4245
|
if (notifyPermissionDenied) {
|
|
4158
|
-
await notifyPermissionDenied({ toolName: e.toolName, input: cloneObserverInput(e.input), toolCallId: e.toolCallId, reason: complianceDeny, source: "safety" });
|
|
4246
|
+
await notifyPermissionDenied({ toolName: e.toolName, input: cloneObserverInput(e.input), toolCallId: e.toolCallId, reason: complianceDeny, source: "safety", identity: hookIdentity });
|
|
4159
4247
|
}
|
|
4160
4248
|
return { block: true, reason: formatHookFeedback(complianceDeny), preToolContext: [] };
|
|
4161
4249
|
}
|
|
@@ -4166,7 +4254,7 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
|
|
|
4166
4254
|
const planDenyReason = `Plan mode is active — "${e.toolName}" is a write/mutating tool and is read-only-blocked. ` +
|
|
4167
4255
|
`Research with read-only tools, then call ${PRESENT_PLAN_TOOL_NAME} with your plan to get it approved before acting.`;
|
|
4168
4256
|
if (notifyPermissionDenied) {
|
|
4169
|
-
await notifyPermissionDenied({ toolName: e.toolName, input: cloneObserverInput(e.input), toolCallId: e.toolCallId, reason: planDenyReason, source: "planMode" });
|
|
4257
|
+
await notifyPermissionDenied({ toolName: e.toolName, input: cloneObserverInput(e.input), toolCallId: e.toolCallId, reason: planDenyReason, source: "planMode", identity: hookIdentity });
|
|
4170
4258
|
}
|
|
4171
4259
|
return {
|
|
4172
4260
|
block: true,
|
|
@@ -4179,6 +4267,7 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
|
|
|
4179
4267
|
result = await runToolGate({
|
|
4180
4268
|
onNotifyError: (f) => emitTrace(deps.tracer, () => ({ kind: "observer.notify_failed", version: 1, taskId: spec.taskId ?? sessionId, site: f.site, message: f.error.message, ts: Date.now() })),
|
|
4181
4269
|
event: e,
|
|
4270
|
+
identity: hookIdentity,
|
|
4182
4271
|
preToolUse: ownGatePreToolUse,
|
|
4183
4272
|
...(hookEnvFace !== undefined ? { hookEnv: hookEnvFace } : {}),
|
|
4184
4273
|
adjudicate,
|
|
@@ -4186,6 +4275,8 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
|
|
|
4186
4275
|
suspendAsk,
|
|
4187
4276
|
resolveContentAsk,
|
|
4188
4277
|
egress: egressTools.has(e.toolName),
|
|
4278
|
+
peerMessage: e.toolName === SEND_MESSAGE_TOOL_NAME,
|
|
4279
|
+
...(writeProtectionCheck !== undefined ? { writeProtectionCheck } : {}),
|
|
4189
4280
|
irreversibility: irreversibilityTier.get(e.toolName),
|
|
4190
4281
|
reversibilityProbe: reversibilityProbes.get(e.toolName),
|
|
4191
4282
|
abortSignal: abortController.signal,
|
|
@@ -4291,7 +4382,7 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
|
|
|
4291
4382
|
isInterrupt: abortController.signal.aborted || spec.signal?.aborted === true,
|
|
4292
4383
|
content: e.content.map((c) => ({ ...c })),
|
|
4293
4384
|
details: clonedDetails,
|
|
4294
|
-
}, { toolCallId: e.toolCallId, toolName: e.toolName, ...(hookEnvFace !== undefined ? { env: hookEnvFace } : {}) });
|
|
4385
|
+
}, { toolCallId: e.toolCallId, toolName: e.toolName, ...(hookEnvFace !== undefined ? { env: hookEnvFace } : {}), identity: hookIdentity });
|
|
4295
4386
|
if (patch?.additionalContext) {
|
|
4296
4387
|
content = [...content, { type: "text", text: formatHookFeedback(patch.additionalContext) }];
|
|
4297
4388
|
changed = true;
|
|
@@ -4299,7 +4390,7 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
|
|
|
4299
4390
|
}
|
|
4300
4391
|
}
|
|
4301
4392
|
else if (hooks?.postToolUse) {
|
|
4302
|
-
const patch = await hooks.postToolUse(e.toolName, e.input, { content: e.content, details: e.details, isError: e.isError }, { toolCallId: e.toolCallId, toolName: e.toolName, ...(hookEnvFace !== undefined ? { env: hookEnvFace } : {}) });
|
|
4393
|
+
const patch = await hooks.postToolUse(e.toolName, e.input, { content: e.content, details: e.details, isError: e.isError }, { toolCallId: e.toolCallId, toolName: e.toolName, ...(hookEnvFace !== undefined ? { env: hookEnvFace } : {}), identity: hookIdentity });
|
|
4303
4394
|
if (patch?.updatedOutput) {
|
|
4304
4395
|
content = patch.updatedOutput;
|
|
4305
4396
|
changed = true;
|
|
@@ -4586,7 +4677,7 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
|
|
|
4586
4677
|
const effectiveReadFaceObserved = carrierReadFace();
|
|
4587
4678
|
const effectiveReadDenyObserved = readDenyAdditionsNormalized.length > 0 ? readDenyAdditionsNormalized.map((e) => ({ ...e })) : undefined;
|
|
4588
4679
|
const preparedHolder = {};
|
|
4589
|
-
const buildPrepared = () => ({ harness, session, sessionId, taskRootPath: taskRootFinal, model, thinking, compModel, mcp: mcp, ...(a2a !== undefined && a2a.tools.length > 0 ? { a2a } : {}), blockedRef, outputRef, abortController, conflictRef, blockedToolCalls, approvalSettlement, nestedStats, ...(rewindNotes.length > 0 ? { rewindNotes } : {}), ...(effectiveReadFaceObserved !== undefined ? { effectiveReadFace: effectiveReadFaceObserved } : {}), ...(effectiveReadDenyObserved !== undefined ? { effectiveReadDenyPatterns: effectiveReadDenyObserved } : {}), effectiveMemoryScopes: memoryEffectiveScopes, cwdRef: handsCwdRef, ...(worktreeSessionRef !== undefined ? { worktreeSessionRef } : {}), ...(workspaceStateSettle !== undefined ? { workspaceStateSettle } : {}), denyNarrowingPolicy, ...(basePolicyForResumeEdit !== undefined ? { basePolicyForResumeEdit } : {}), ...(permissionRuleOrgLane !== undefined ? { permissionRuleOrg: permissionRuleOrgLane } : {}), releaseSignal, settleContentAskBindings, cacheBreakDetector, cacheFingerprint, wiringManifest, promptManifest, epochDeclaredSections, activeTools, ...(deferred.size > 0 ? { deferredToolNames: deferred } : {}), toolMaterializeStatic, deferDirectCall, ...(staticFaceForRef.current !== undefined ? { staticFaceFor: staticFaceForRef.current } : {}), ownedEnv, suspendRef, suspendProgressRef, reviewRef, remoteEnvFailures, reviewRequestRef, suspendLoopRef, suspendForResource, ...(suspendForPlatformLimit !== undefined ? { suspendForPlatformLimit } : {}), ...(envLifetimeSuspendAt !== undefined ? { envLifetimeSuspendAt } : {}), ...(usageGovernance !== undefined ? { usageGovernance } : {}), callIssuedAtRef, brainCallGuardrailRef, suspendForReview, resourceLedger: priorLedger, liveSpendRef, humanReviewRef, now, tools, toolEffects, wakeRecovered, promptOverheadTokens, lastBrainContext, readTaskFile, recentlyReadFiles, normalizeAttachmentPath, isDedupStubResult, ...(onCompactionApplied ? { onCompactionApplied } : {}), compactionReuseRef, trimPressureRef, ...(memoryEngineSession ? { memoryEngineSession } : {}), ...(subagentRetain ? { subagentRetain } : {}), ...(lspDiagnostics && nudgeLspOnEdit ? { lspDiagnostics: { registry: lspDiagnostics, nudge: nudgeLspOnEdit, runIdent: lspRunIdent } } : {}), planModeRef, ...(dateChange ? { dateChange } : {}), ...(instructionSources ? { instructionSources } : {}), ...(workflowSizeGuideline ? { workflowSizeGuideline } : {}), ...(detectExternalChanges ? { detectExternalChanges } : {}), ...(toolsDeltaRef ? { toolsDeltaRef } : {}), ...(agentListing ? { agentListing } : {}), ...(skillsListing ? { skillsListing } : {}), announcedListingsRef, gitStatusRef, listBackgroundTasks, ...(turnSnapshotRef.current !== undefined ? { turnSnapshot: turnSnapshotRef.current } : {}), ...(centerCompactionCandidate !== undefined ? { centerCompactionCandidate } : {}) });
|
|
4680
|
+
const buildPrepared = () => ({ harness, session, sessionId, taskRootPath: taskRootFinal, model, thinking, compModel, mcp: mcp, ...(a2a !== undefined && a2a.tools.length > 0 ? { a2a } : {}), blockedRef, outputRef, abortController, conflictRef, blockedToolCalls, approvalSettlement, nestedStats, ...(rewindNotes.length > 0 ? { rewindNotes } : {}), ...(effectiveReadFaceObserved !== undefined ? { effectiveReadFace: effectiveReadFaceObserved } : {}), ...(effectiveReadDenyObserved !== undefined ? { effectiveReadDenyPatterns: effectiveReadDenyObserved } : {}), effectiveMemoryScopes: memoryEffectiveScopes, cwdRef: handsCwdRef, ...(worktreeSessionRef !== undefined ? { worktreeSessionRef } : {}), ...(workspaceStateSettle !== undefined ? { workspaceStateSettle } : {}), denyNarrowingPolicy, ...(basePolicyForResumeEdit !== undefined ? { basePolicyForResumeEdit } : {}), ...(permissionRuleOrgLane !== undefined ? { permissionRuleOrg: permissionRuleOrgLane } : {}), releaseSignal, settleContentAskBindings, cacheBreakDetector, cacheFingerprint, wiringManifest, promptManifest, epochDeclaredSections, activeTools, ...(deferred.size > 0 ? { deferredToolNames: deferred } : {}), toolMaterializeStatic, deferDirectCall, ...(staticFaceForRef.current !== undefined ? { staticFaceFor: staticFaceForRef.current } : {}), ownedEnv, suspendRef, suspendProgressRef, reviewRef, remoteEnvFailures, reviewRequestRef, suspendLoopRef, suspendForResource, ...(suspendForPlatformLimit !== undefined ? { suspendForPlatformLimit } : {}), ...(envLifetimeSuspendAt !== undefined ? { envLifetimeSuspendAt } : {}), ...(usageGovernance !== undefined ? { usageGovernance } : {}), callIssuedAtRef, brainCallGuardrailRef, suspendForReview, resourceLedger: priorLedger, liveSpendRef, humanReviewRef, now, tools, toolEffects, wakeRecovered, promptOverheadTokens, lastBrainContext, readTaskFile, recentlyReadFiles, normalizeAttachmentPath, isDedupStubResult, ...(onCompactionApplied ? { onCompactionApplied } : {}), compactionReuseRef, trimPressureRef, ...(memoryEngineSession ? { memoryEngineSession } : {}), ...(subagentRetain ? { subagentRetain } : {}), ...(lspDiagnostics && nudgeLspOnEdit ? { lspDiagnostics: { registry: lspDiagnostics, nudge: nudgeLspOnEdit, runIdent: lspRunIdent } } : {}), planModeRef, ...(dateChange ? { dateChange } : {}), ...(instructionSources ? { instructionSources } : {}), ...(workflowSizeGuideline ? { workflowSizeGuideline } : {}), ...(detectExternalChanges ? { detectExternalChanges } : {}), ...(toolsDeltaRef ? { toolsDeltaRef } : {}), ...(agentListing ? { agentListing } : {}), ...(skillsListing ? { skillsListing } : {}), announcedListingsRef, gitStatusRef, listBackgroundTasks, hookIdentity, ...(turnSnapshotRef.current !== undefined ? { turnSnapshot: turnSnapshotRef.current } : {}), ...(centerCompactionCandidate !== undefined ? { centerCompactionCandidate } : {}) });
|
|
4590
4681
|
const prepared = buildPrepared();
|
|
4591
4682
|
preparedHolder.current = prepared;
|
|
4592
4683
|
return prepared;
|