@sema-agent/core 7.34.0 → 7.35.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +156 -3
- package/dist/brain/errors.d.ts +23 -1
- package/dist/brain/errors.js +19 -2
- package/dist/brain/status-sink.d.ts +7 -1
- package/dist/brain/stream-shared.d.ts +3 -1
- package/dist/brain/stream-shared.js +16 -4
- package/dist/core/ask-origin.d.ts +34 -6
- package/dist/core/ask-origin.js +24 -23
- package/dist/core/ask-question.js +2 -1
- package/dist/core/checkpoint-store.d.ts +4 -0
- package/dist/core/gate-fold.js +2 -2
- package/dist/core/gate-lanes.js +5 -4
- package/dist/core/governance-codes.d.ts +17 -1
- package/dist/core/governance-codes.js +11 -1
- package/dist/core/hooks.d.ts +3 -0
- package/dist/core/message-utils.d.ts +2 -1
- package/dist/core/message-utils.js +2 -1
- package/dist/core/mode-policy.d.ts +3 -0
- package/dist/core/mode-policy.js +5 -0
- package/dist/core/permission-rule-model.d.ts +4 -0
- package/dist/core/permission-rule-model.js +4 -0
- package/dist/core/permission-rules.js +21 -1
- package/dist/core/persisted-rule-arms.d.ts +4 -1
- package/dist/core/persisted-rule-arms.js +4 -0
- package/dist/core/retired-keys.js +1 -1
- package/dist/core/runner/active-skill-scope.js +5 -4
- package/dist/core/runner/assemble-result.js +2 -2
- package/dist/core/runner/contracts.d.ts +26 -4
- package/dist/core/runner/denial-limit-arms.d.ts +6 -1
- package/dist/core/runner/denial-limit-arms.js +4 -4
- package/dist/core/runner/file-history-request.d.ts +26 -0
- package/dist/core/runner/file-history-request.js +90 -0
- package/dist/core/runner/permission-rule-lanes.d.ts +2 -1
- package/dist/core/runner/permission-rule-lanes.js +14 -11
- package/dist/core/runner/prepare-ask-lane.d.ts +1 -1
- package/dist/core/runner/prepare-ask-lane.js +2 -2
- package/dist/core/runner/prepare-file-history.d.ts +9 -3
- package/dist/core/runner/prepare-file-history.js +4 -90
- package/dist/core/runner/prepare-gate-stations.d.ts +4 -3
- package/dist/core/runner/prepare-gate-stations.js +15 -11
- package/dist/core/runner/prepare-inherited-gate.d.ts +8 -1
- package/dist/core/runner/prepare-inherited-gate.js +10 -4
- package/dist/core/runner/prepare-park-ask.d.ts +4 -2
- package/dist/core/runner/prepare-park-ask.js +5 -4
- package/dist/core/runner/prepare-policy-chain.d.ts +3 -2
- package/dist/core/runner/prepare-policy-chain.js +171 -175
- package/dist/core/runner/prepare-task.d.ts +3 -1
- package/dist/core/runner/prepare-task.js +9 -5
- package/dist/core/runner/run-brain-sinks.js +3 -1
- package/dist/core/runner/run-leg.js +5 -3
- package/dist/core/runner/run-notification-lane.d.ts +5 -0
- package/dist/core/runner/run-notification-lane.js +3 -2
- package/dist/core/runner/runtask.d.ts +3 -1
- package/dist/core/runner/runtask.js +20 -16
- package/dist/core/runner/session-mode-seats.d.ts +48 -0
- package/dist/core/runner/session-mode-seats.js +73 -0
- package/dist/core/runner/session-rule-policy.js +3 -2
- package/dist/core/secret-env.d.ts +30 -58
- package/dist/core/secret-env.js +149 -586
- package/dist/core/sensitive-path-policy.js +2 -1
- package/dist/core/store-contracts/checkpoint-store-contract.js +2 -1
- package/dist/core/tool-policy.d.ts +31 -6
- package/dist/core/tool-policy.js +35 -16
- package/dist/core/tool-registry.d.ts +36 -0
- package/dist/core/tool-registry.js +22 -1
- package/dist/core/tool-roster.d.ts +17 -2
- package/dist/core/tool-roster.js +11 -1
- package/dist/core/trace.d.ts +11 -0
- package/dist/engine/execution-env/node-execution-env.d.ts +3 -1
- package/dist/engine/execution-env/node-execution-env.js +5 -2
- package/dist/engine/harness/agent-harness.js +2 -1
- package/dist/engine/lsp/node-lsp-manager.js +1 -1
- package/dist/index.d.ts +4 -4
- package/dist/index.js +4 -4
- package/dist/stores/file/index.d.ts +5 -3
- package/dist/stores/file/session-store.d.ts +8 -2
- package/dist/stores/file/session-store.js +5 -5
- package/dist/tools/fs/file-read-check.d.ts +2 -1
- package/dist/tools/fs/file-read-check.js +15 -7
- package/dist/tools/fs/shell-read-check.d.ts +10 -2
- package/dist/tools/fs/shell-read-check.js +12 -8
- package/package.json +1 -1
- package/test/export-surface.snapshot.json +15 -1
- package/wire-changes/core@7.35.0.json +584 -0
- package/wire-changes/core@7.35.1.json +59 -0
|
@@ -6,7 +6,7 @@ import { cloneObserverInput, resolveHookTimeoutMs } from "../hooks.js";
|
|
|
6
6
|
import { assertHookSeatsCallable } from "../hook-seats.js";
|
|
7
7
|
import { isNamespacedCoveringRuleName, namespacedRuleNameCovers } from "../permission-rules.js";
|
|
8
8
|
import { isIsolated } from "../remote-env.js";
|
|
9
|
-
import { askApproverIdentity, carryEngineAttestations, carryPrecedingSettlement, checkToolPolicyProjection, combinePolicies, createTranscriptIntegrityPolicy, createUnverifiableDeletePolicy, durableParkOptInDeclared, isLiveApproverSeat, resolveAsk, toolPolicyNameSets, attestAskUnresolvableCause } from "../tool-policy.js";
|
|
9
|
+
import { askApproverIdentity, carryEngineAttestations, carryPrecedingSettlement, checkToolPolicyProjection, combinePolicies, createTranscriptIntegrityPolicy, createUnverifiableDeletePolicy, durableParkOptInDeclared, isLiveApproverSeat, resolveAsk, toolPolicyNameSets, wrapToolPolicy, attestAskUnresolvableCause } from "../tool-policy.js";
|
|
10
10
|
import { RETIRED_TOOL_NAMES } from "../tool-name-aliases.js";
|
|
11
11
|
import { NAMESPACED_NAME_SHAPES, protocolOf } from "../protocol-table.js";
|
|
12
12
|
import { emitTrace } from "../trace.js";
|
|
@@ -20,6 +20,7 @@ import { askGrantShapeOf } from "./inherited-ask-grants.js";
|
|
|
20
20
|
import { createPermissionRuleLanes, inheritedAskRuleEvidence, createRuleOffersOf } from "./permission-rule-lanes.js";
|
|
21
21
|
import { createLiveSessionRules, createSessionRulePolicy } from "./session-rule-policy.js";
|
|
22
22
|
import { thrownText } from "../thrown-value.js";
|
|
23
|
+
import { anyNamed, firstNamed, ruleNamesOf } from "../tool-roster.js";
|
|
23
24
|
export async function preparePolicyChain(input) {
|
|
24
25
|
const { spec, deps, internals, sessionId, runId, hostTaskId, taskRootFinal, additionalRootsCanonical, executionEnv, lockedPreflight, tools, harnessTools, toolEffects, egressTools, irreversibilityTier, axisExplicitNegatives, shellGatedTools, envHandToolNames, handsCwdRef, readDenyMatcher, announceRuleStoreSkipped, questionToolMounted, runtimeCaps, inheritedAncestorRules, ancestorSessionRulesRef, inheritedParentConstraints, seedInheritedGate, hasSkillManifest, skillScope, frozenOnAsk, hookEnvSource, notifyOwnHookCrash, autoModeDecider, permissionMode, scratchpadDir, toolRosterDeltas, stopForDenialLimit, delegation, abortController, now, ownSessionRulesRef } = input;
|
|
25
26
|
const ancestorArbitrations = new Map();
|
|
@@ -232,7 +233,7 @@ export async function preparePolicyChain(input) {
|
|
|
232
233
|
list.push({ cls, layer });
|
|
233
234
|
foldAskClasses.set(toolCallId, list);
|
|
234
235
|
};
|
|
235
|
-
const sandboxBoundaryCapable = (
|
|
236
|
+
const sandboxBoundaryCapable = (call) => anyNamed(egressTools, ruleNamesOf(call)) || !envHandToolNames.has(call.toolName);
|
|
236
237
|
const emitSandboxAdmitted = (info) => {
|
|
237
238
|
emitTrace(deps.tracer, () => ({
|
|
238
239
|
kind: "permission.sandbox_admitted",
|
|
@@ -256,18 +257,16 @@ export async function preparePolicyChain(input) {
|
|
|
256
257
|
void toolName;
|
|
257
258
|
};
|
|
258
259
|
const callerPolicyLayer = policy !== undefined && sameInstanceAncestorCount > 0
|
|
259
|
-
? {
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
},
|
|
270
|
-
}
|
|
260
|
+
? wrapToolPolicy(policy, async (creq, csignal) => {
|
|
261
|
+
const decision = await policy.check(creq, csignal ?? abortController.signal);
|
|
262
|
+
sharedFirstDecision.set(creq.toolCallId, decision);
|
|
263
|
+
if (sharedFirstDecision.size > SHARED_FIRST_DECISION_CAP) {
|
|
264
|
+
const oldest = sharedFirstDecision.keys().next().value;
|
|
265
|
+
if (oldest !== undefined)
|
|
266
|
+
sharedFirstDecision.delete(oldest);
|
|
267
|
+
}
|
|
268
|
+
return decision;
|
|
269
|
+
})
|
|
271
270
|
: policy;
|
|
272
271
|
const askSourceIdentity = () => ({
|
|
273
272
|
principal: spec.principal,
|
|
@@ -278,11 +277,12 @@ export async function preparePolicyChain(input) {
|
|
|
278
277
|
: {}),
|
|
279
278
|
...(delegation.isDelegatedChild ? { isDelegatedChild: true } : {}),
|
|
280
279
|
});
|
|
281
|
-
const riskAxesOf = (
|
|
282
|
-
const
|
|
283
|
-
const
|
|
280
|
+
const riskAxesOf = (call) => {
|
|
281
|
+
const names = ruleNamesOf(call);
|
|
282
|
+
const tier = firstNamed(irreversibilityTier, names)?.value;
|
|
283
|
+
const negatives = firstNamed(axisExplicitNegatives, names)?.value;
|
|
284
284
|
const irreversible = tier === "always" || tier === "maybe" ? true : tier === "never" ? false : negatives?.irreversible;
|
|
285
|
-
const egress = egressTools
|
|
285
|
+
const egress = anyNamed(egressTools, names) ? true : negatives?.egress;
|
|
286
286
|
if (irreversible === undefined && egress === undefined)
|
|
287
287
|
return {};
|
|
288
288
|
return { riskAxes: { ...(irreversible !== undefined ? { irreversible } : {}), ...(egress !== undefined ? { egress } : {}) } };
|
|
@@ -314,7 +314,9 @@ export async function preparePolicyChain(input) {
|
|
|
314
314
|
cwdRef: handsCwdRef,
|
|
315
315
|
deniesDirectoryRead: readDenyMatcher !== undefined ? (d) => readDenyMatcher.matchPath(d) !== null : undefined,
|
|
316
316
|
});
|
|
317
|
-
const recheckApprovedEdit = async (pol, onAskOf, creq, edit, approved, csignal,
|
|
317
|
+
const recheckApprovedEdit = async (pol, onAskOf, creq, edit, approved, csignal, ancestorAutoMode) => {
|
|
318
|
+
const ancestorDecider = ancestorAutoMode?.decider;
|
|
319
|
+
const ancestorTracker = ancestorAutoMode?.denialTracking;
|
|
318
320
|
let editArgs = edit;
|
|
319
321
|
let settledBy = approved;
|
|
320
322
|
const vetoed = (d) => {
|
|
@@ -350,7 +352,7 @@ export async function preparePolicyChain(input) {
|
|
|
350
352
|
}
|
|
351
353
|
if (re.updatedInput !== undefined)
|
|
352
354
|
editArgs = re.updatedInput;
|
|
353
|
-
const judged = await judgeInheritedClassifier({ liveMode: () => permissionMode.current, autoMode:
|
|
355
|
+
const judged = await judgeInheritedClassifier({ liveMode: () => permissionMode.current, autoMode: ancestorAutoMode, ask: re, req: { ...creq, args: editArgs }, signal: csignal ?? abortController.signal, subject: "the approved edit", allowRewrite: editArgs, unavailableSeat: classifierUnavailableSeat({ station: "ancestor", ...(ancestorDecider?.timeoutMs !== undefined ? { budgetMs: ancestorDecider.timeoutMs } : {}), approvalSeat: isLiveApproverSeat(onAskOf), onNotice: deps.onNotice, sessionId, runId }) });
|
|
354
356
|
if (judged.kind === "allow") {
|
|
355
357
|
const cleared = { ...judged.result };
|
|
356
358
|
carryEngineAttestations(judged.result, cleared);
|
|
@@ -371,10 +373,10 @@ export async function preparePolicyChain(input) {
|
|
|
371
373
|
toolName: creq.toolName,
|
|
372
374
|
toolCallId: creq.toolCallId,
|
|
373
375
|
args: editArgs,
|
|
374
|
-
...ruleOffersOf(creq
|
|
376
|
+
...ruleOffersOf(creq, editArgs, ancestorFacts(re)),
|
|
375
377
|
message: re.message ?? `approval required for "${creq.toolName}" (inherited parent policy)`,
|
|
376
378
|
...askSourceIdentity(),
|
|
377
|
-
...riskAxesOf(creq
|
|
379
|
+
...riskAxesOf(creq),
|
|
378
380
|
...(re.requiresRealApproval === true ? { requiresRealApproval: true } : {}),
|
|
379
381
|
...askMandateMember(ancestorFacts(re)),
|
|
380
382
|
...(re.persistedRuleShadowed !== undefined ? { persistedRuleShadowed: re.persistedRuleShadowed } : {}),
|
|
@@ -438,7 +440,7 @@ export async function preparePolicyChain(input) {
|
|
|
438
440
|
if (judged.kind === "deny")
|
|
439
441
|
return judged.result;
|
|
440
442
|
const { ask: inheritedAsk, fallback, mintedHere } = judged;
|
|
441
|
-
if (fallback === undefined && sandboxAdmissionArmed && policyAskClassOf(pc.policy) === "sandbox_local" && !sandboxBoundaryCapable(creq
|
|
443
|
+
if (fallback === undefined && sandboxAdmissionArmed && policyAskClassOf(pc.policy) === "sandbox_local" && !sandboxBoundaryCapable(creq) && classifyAsk(inheritedAsk, INHERITED_STATION_FACTS).row.sandboxAdmission) {
|
|
442
444
|
recordAncestorSandboxAdmission(creq.toolCallId, creq.toolName);
|
|
443
445
|
return { action: "allow" };
|
|
444
446
|
}
|
|
@@ -451,10 +453,10 @@ export async function preparePolicyChain(input) {
|
|
|
451
453
|
toolName: creq.toolName,
|
|
452
454
|
toolCallId: creq.toolCallId,
|
|
453
455
|
args: presentedArgs,
|
|
454
|
-
...ruleOffersOf(creq
|
|
456
|
+
...ruleOffersOf(creq, presentedArgs, ancestorFacts(inheritedAsk.action === "ask" ? inheritedAsk : undefined)),
|
|
455
457
|
message: inheritedAsk.message ?? `approval required for "${creq.toolName}" (inherited parent policy)`,
|
|
456
458
|
...askSourceIdentity(),
|
|
457
|
-
...riskAxesOf(creq
|
|
459
|
+
...riskAxesOf(creq),
|
|
458
460
|
...(inheritedAsk.action === "ask" && inheritedAsk.requiresRealApproval === true ? { requiresRealApproval: true } : {}),
|
|
459
461
|
...askMandateMember(ancestorFacts(inheritedAsk.action === "ask" ? inheritedAsk : undefined)),
|
|
460
462
|
...(inheritedAsk.action === "ask" && inheritedAsk.persistedRuleShadowed !== undefined ? { persistedRuleShadowed: inheritedAsk.persistedRuleShadowed } : {}),
|
|
@@ -472,92 +474,90 @@ export async function preparePolicyChain(input) {
|
|
|
472
474
|
if (resolved.action !== "allow")
|
|
473
475
|
return resolved;
|
|
474
476
|
if (resolved.updatedInput !== undefined) {
|
|
475
|
-
return recheckApprovedEdit(pc.policy, pc.onAsk, creq, resolved.updatedInput, resolved, csignal, pc.autoMode
|
|
477
|
+
return recheckApprovedEdit(pc.policy, pc.onAsk, creq, resolved.updatedInput, resolved, csignal, pc.autoMode);
|
|
476
478
|
}
|
|
477
479
|
recordInheritedAskGrant(creq.toolCallId, pc.onAsk, resolved.presentedInput, askWaitMs, resolved);
|
|
478
480
|
return { action: "allow" };
|
|
479
481
|
},
|
|
480
482
|
}
|
|
481
|
-
: {
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
483
|
+
: wrapToolPolicy(pc.policy, async (creq, csignal) => {
|
|
484
|
+
let decision;
|
|
485
|
+
try {
|
|
486
|
+
decision = await pc.policy.check(creq, csignal ?? abortController.signal);
|
|
487
|
+
}
|
|
488
|
+
catch (err) {
|
|
489
|
+
return {
|
|
490
|
+
action: "deny",
|
|
491
|
+
message: `inherited parent policy errored for "${creq.toolName}": ${thrownText(err)}`,
|
|
492
|
+
};
|
|
493
|
+
}
|
|
494
|
+
if (decision.action !== "ask")
|
|
495
|
+
return decision;
|
|
496
|
+
if (creq.toolName === ASK_USER_QUESTION_TOOL_NAME) {
|
|
497
|
+
if (pc.contentMandate !== true || markInheritedUnavailable(creq.toolCallId))
|
|
494
498
|
return decision;
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
carryEngineAttestations(resolved, approvedWithRewrite);
|
|
558
|
-
return approvedWithRewrite;
|
|
559
|
-
},
|
|
560
|
-
});
|
|
499
|
+
return {
|
|
500
|
+
action: "deny",
|
|
501
|
+
message: `inherited parent policy requires durable handling of the question raised for "${creq.toolName}" and the marker channel is at capacity — ` +
|
|
502
|
+
`denied fail-closed (tighten-only)`,
|
|
503
|
+
};
|
|
504
|
+
}
|
|
505
|
+
if (pc.durableMandate === true) {
|
|
506
|
+
if (mandatedCallFloats(creq.toolCallId))
|
|
507
|
+
return decision;
|
|
508
|
+
return mandateUnreconstructibleDeny(creq);
|
|
509
|
+
}
|
|
510
|
+
const presentedArgs = decision.updatedInput !== undefined ? decision.updatedInput : creq.args;
|
|
511
|
+
const judged = await judgeInheritedClassifier({ liveMode: () => permissionMode.current, autoMode: pc.autoMode, ask: decision, req: { ...creq, args: presentedArgs }, signal: csignal ?? abortController.signal, subject: "this call", allowRewrite: decision.updatedInput, unavailableSeat: classifierUnavailableSeat({ station: "ancestor", ...(pc.autoMode?.decider.timeoutMs !== undefined ? { budgetMs: pc.autoMode.decider.timeoutMs } : {}), approvalSeat: isLiveApproverSeat(pc.onAsk), onNotice: deps.onNotice, sessionId, runId }) });
|
|
512
|
+
if (judged.kind === "allow")
|
|
513
|
+
return judged.result;
|
|
514
|
+
if (judged.kind === "deny")
|
|
515
|
+
return judged.result;
|
|
516
|
+
const { ask: inheritedAsk, fallback, mintedHere } = judged;
|
|
517
|
+
if (fallback === undefined && sandboxAdmissionArmed && policyAskClassOf(pc.policy) === "sandbox_local" && !sandboxBoundaryCapable(creq) && classifyAsk(inheritedAsk, INHERITED_STATION_FACTS).row.sandboxAdmission) {
|
|
518
|
+
recordAncestorSandboxAdmission(creq.toolCallId, creq.toolName);
|
|
519
|
+
return decision.updatedInput !== undefined ? { action: "allow", updatedInput: decision.updatedInput } : { action: "allow" };
|
|
520
|
+
}
|
|
521
|
+
const arbitrated = arbitrateInherited(inheritedAsk.action === "ask" ? { ...inheritedAsk, ...(decision.updatedInput !== undefined ? { updatedInput: decision.updatedInput } : {}) } : inheritedAsk, creq.toolCallId);
|
|
522
|
+
if (arbitrated !== undefined)
|
|
523
|
+
return arbitrated;
|
|
524
|
+
const askT0 = now();
|
|
525
|
+
const resolved = await resolveAsk({
|
|
526
|
+
toolName: creq.toolName,
|
|
527
|
+
toolCallId: creq.toolCallId,
|
|
528
|
+
args: presentedArgs,
|
|
529
|
+
...ruleOffersOf(creq, presentedArgs, ancestorFacts(inheritedAsk.action === "ask" ? inheritedAsk : undefined)),
|
|
530
|
+
message: inheritedAsk.message ?? `approval required for "${creq.toolName}" (inherited parent policy)`,
|
|
531
|
+
...askSourceIdentity(),
|
|
532
|
+
...riskAxesOf(creq),
|
|
533
|
+
...(inheritedAsk.action === "ask" && inheritedAsk.requiresRealApproval === true ? { requiresRealApproval: true } : {}),
|
|
534
|
+
...askMandateMember(ancestorFacts(inheritedAsk.action === "ask" ? inheritedAsk : undefined)),
|
|
535
|
+
...(inheritedAsk.action === "ask" && inheritedAsk.persistedRuleShadowed !== undefined ? { persistedRuleShadowed: inheritedAsk.persistedRuleShadowed } : {}),
|
|
536
|
+
...inheritedAskCarry(judged, isLiveApproverSeat(pc.onAsk), pc.autoMode?.denialTracking),
|
|
537
|
+
ruleEvidence: inheritedAskEvidence,
|
|
538
|
+
}, pc.onAsk, csignal ?? abortController.signal, lateAskSettlementObserver({ toolName: creq.toolName, toolCallId: creq.toolCallId, sessionId, runId, ...(spec.taskId !== undefined ? { taskId: spec.taskId } : {}), onNotice: deps.onNotice, onError: deps.onError }));
|
|
539
|
+
void settleReadRootGrant(resolved.readRootGrant, undefined, { toolName: creq.toolName, toolCallId: creq.toolCallId, sessionId, runId, ...(spec.taskId !== undefined ? { taskId: spec.taskId } : {}), onNotice: deps.onNotice });
|
|
540
|
+
const askWaitMs = Math.max(0, now() - askT0);
|
|
541
|
+
if (resolved.action === "deny" && resolved.approverUnavailable === true) {
|
|
542
|
+
if (markInheritedUnavailable(creq.toolCallId))
|
|
543
|
+
return inheritedAsk;
|
|
544
|
+
return markerChannelFullDeny(creq);
|
|
545
|
+
}
|
|
546
|
+
settleDenialLimitFallback({ fallback, mintedHere, tracker: pc.autoMode?.denialTracking, resolved, headless: headlessDenyAtFold, stop: stopForDenialLimit, toolName: creq.toolName, toolCallId: creq.toolCallId });
|
|
547
|
+
if (resolved.action !== "allow")
|
|
548
|
+
return resolved;
|
|
549
|
+
if (resolved.updatedInput !== undefined) {
|
|
550
|
+
return recheckApprovedEdit(pc.policy, pc.onAsk, creq, resolved.updatedInput, resolved, csignal, pc.autoMode);
|
|
551
|
+
}
|
|
552
|
+
if (pc.preToolUse === undefined) {
|
|
553
|
+
recordInheritedAskGrant(creq.toolCallId, pc.onAsk, resolved.presentedInput, askWaitMs, resolved);
|
|
554
|
+
}
|
|
555
|
+
if (decision.updatedInput === undefined)
|
|
556
|
+
return resolved;
|
|
557
|
+
const approvedWithRewrite = { ...resolved, updatedInput: decision.updatedInput };
|
|
558
|
+
carryEngineAttestations(resolved, approvedWithRewrite);
|
|
559
|
+
return approvedWithRewrite;
|
|
560
|
+
}));
|
|
561
561
|
const rewriteCapableLayers = policy !== undefined || parentConstraintWrappers.length > 0;
|
|
562
562
|
const rewriteEmitterIndex = new Map();
|
|
563
563
|
const rewriteCapableChain = [
|
|
@@ -570,16 +570,14 @@ export async function preparePolicyChain(input) {
|
|
|
570
570
|
if (policy !== undefined && pc.policy === policy)
|
|
571
571
|
sameInstanceAdapterIndices.add(j + callerSlotOffset);
|
|
572
572
|
});
|
|
573
|
-
const instrumentedChain = rewriteCapableChain.map((layer, idx) => ({
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
return d;
|
|
582
|
-
},
|
|
573
|
+
const instrumentedChain = rewriteCapableChain.map((layer, idx) => wrapToolPolicy(layer, async (creq, csignal) => {
|
|
574
|
+
const d = await layer.check(creq, csignal);
|
|
575
|
+
if (d.updatedInput !== undefined)
|
|
576
|
+
rewriteEmitterIndex.set(creq.toolCallId, idx);
|
|
577
|
+
if (d.action === "ask") {
|
|
578
|
+
recordFoldAskClass(creq.toolCallId, idx < callerSlotOffset ? policyAskClassOf(policy) : "mandate", idx < callerSlotOffset ? "caller_policy" : "ancestor_constraint");
|
|
579
|
+
}
|
|
580
|
+
return d;
|
|
583
581
|
}));
|
|
584
582
|
const modeGateLayer = createModeGatePolicy(permissionMode, { env: executionEnv, rootPath: taskRootFinal, acceptDirs: [taskRootFinal, ...additionalRootsCanonical], roster: toolRosterDeltas, readOnlyDeclared: (name) => mountedToolDeclaresReadOnly(tools, name), ...(scratchpadDir !== undefined ? { exemptDirs: [scratchpadDir] } : {}) });
|
|
585
583
|
const policyLayers = [
|
|
@@ -593,70 +591,68 @@ export async function preparePolicyChain(input) {
|
|
|
593
591
|
: [...integrityGuardLayers, ...policyLayers, modeGateLayer];
|
|
594
592
|
const foldedPolicy = guardedPolicyLayers.length === 1 ? guardedPolicyLayers[0] : combinePolicies(...guardedPolicyLayers);
|
|
595
593
|
const effectivePolicy = foldedPolicy !== undefined && rewriteCapableLayers
|
|
596
|
-
? {
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
catch (err) {
|
|
603
|
-
rewriteEmitterIndex.delete(req.toolCallId);
|
|
604
|
-
throw err;
|
|
605
|
-
}
|
|
606
|
-
const emitterIdx = rewriteEmitterIndex.get(req.toolCallId);
|
|
594
|
+
? wrapToolPolicy(foldedPolicy, async (req, signal) => {
|
|
595
|
+
let decision;
|
|
596
|
+
try {
|
|
597
|
+
decision = await foldedPolicy.check(req, signal);
|
|
598
|
+
}
|
|
599
|
+
catch (err) {
|
|
607
600
|
rewriteEmitterIndex.delete(req.toolCallId);
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
601
|
+
throw err;
|
|
602
|
+
}
|
|
603
|
+
const emitterIdx = rewriteEmitterIndex.get(req.toolCallId);
|
|
604
|
+
rewriteEmitterIndex.delete(req.toolCallId);
|
|
605
|
+
if (decision.action === "deny" || decision.updatedInput === undefined)
|
|
606
|
+
return decision;
|
|
607
|
+
const recheckPrefix = rewriteCapableChain.slice(0, emitterIdx ?? rewriteCapableChain.length);
|
|
608
|
+
const postEmitterSameInstanceAdapters = [];
|
|
609
|
+
if (emitterIdx !== undefined && emitterIdx > 0) {
|
|
610
|
+
for (let i = emitterIdx + 1; i < rewriteCapableChain.length; i++) {
|
|
611
|
+
if (sameInstanceAdapterIndices.has(i))
|
|
612
|
+
postEmitterSameInstanceAdapters.push(rewriteCapableChain[i]);
|
|
617
613
|
}
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
if (d.updatedInput !== undefined) {
|
|
632
|
-
return {
|
|
633
|
-
action: "deny",
|
|
634
|
-
message: "policy required a rewrite during final-form re-check — the arguments that would execute were not accepted as-is (fail-closed; rewrite chains are not iterated to a fixpoint)",
|
|
635
|
-
updatedInput: decision.updatedInput,
|
|
636
|
-
};
|
|
637
|
-
}
|
|
638
|
-
if (d.action === "ask" && asked === undefined)
|
|
639
|
-
asked = d;
|
|
640
|
-
carryEngineAttestations(d, revalidated);
|
|
614
|
+
}
|
|
615
|
+
const recheckLayers = [...recheckPrefix, ...postEmitterSameInstanceAdapters];
|
|
616
|
+
const finalReq = { ...req, args: decision.updatedInput };
|
|
617
|
+
let asked;
|
|
618
|
+
const revalidated = {};
|
|
619
|
+
try {
|
|
620
|
+
for (const layer of recheckLayers) {
|
|
621
|
+
const d = await layer.check(finalReq, signal);
|
|
622
|
+
if (d.action === "deny") {
|
|
623
|
+
const carried = { ...d, updatedInput: decision.updatedInput };
|
|
624
|
+
carryEngineAttestations(d, carried);
|
|
625
|
+
carryPrecedingSettlement(decision, carried);
|
|
626
|
+
return carried;
|
|
641
627
|
}
|
|
628
|
+
if (d.updatedInput !== undefined) {
|
|
629
|
+
return {
|
|
630
|
+
action: "deny",
|
|
631
|
+
message: "policy required a rewrite during final-form re-check — the arguments that would execute were not accepted as-is (fail-closed; rewrite chains are not iterated to a fixpoint)",
|
|
632
|
+
updatedInput: decision.updatedInput,
|
|
633
|
+
};
|
|
634
|
+
}
|
|
635
|
+
if (d.action === "ask" && asked === undefined)
|
|
636
|
+
asked = d;
|
|
637
|
+
carryEngineAttestations(d, revalidated);
|
|
642
638
|
}
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
}
|
|
639
|
+
}
|
|
640
|
+
finally {
|
|
641
|
+
rewriteEmitterIndex.delete(req.toolCallId);
|
|
642
|
+
}
|
|
643
|
+
if (asked !== undefined && decision.action === "allow") {
|
|
644
|
+
const surfaced = { ...asked, updatedInput: decision.updatedInput };
|
|
645
|
+
carryEngineAttestations(asked, surfaced);
|
|
646
|
+
return surfaced;
|
|
647
|
+
}
|
|
648
|
+
if (decision.action === "allow") {
|
|
649
|
+
const owned = { ...decision };
|
|
650
|
+
carryEngineAttestations(decision, owned);
|
|
651
|
+
carryEngineAttestations(revalidated, owned);
|
|
652
|
+
return owned;
|
|
653
|
+
}
|
|
654
|
+
return decision;
|
|
655
|
+
})
|
|
660
656
|
: foldedPolicy;
|
|
661
657
|
return { hooks, hookTimeoutMs, preToolUseObservational, ownGatePreToolUse, basePolicyForResumeEdit, denyNarrowingPolicy, policyLayers, effectivePolicy, inheritedUnavailableAsks, inheritedAskGrants, askSourceIdentity, riskAxesOf, ruleOffersOf, permissionRuleLane, permissionRuleOrgLane, sandboxAdmissionArmed, sandboxBoundaryCapable, emitSandboxAdmitted, foldAskClasses, ancestorSandboxAdmissions, ancestorArbitrations };
|
|
662
658
|
}
|
|
@@ -113,7 +113,9 @@ runnerSelf?: RunnerSelfSeat,
|
|
|
113
113
|
* shape the Runner uses for the generated taskId/sessionId. */
|
|
114
114
|
runIdSink?: {
|
|
115
115
|
runId?: string;
|
|
116
|
-
}
|
|
116
|
+
},
|
|
117
|
+
/** The Runner's lock on this leg's session, handed only when the spec named none: taken the moment the store mints the id. */
|
|
118
|
+
holdSessionLock?: (sessionId: string) => Promise<void>): Promise<Prepared>;
|
|
117
119
|
/** The entry IS the contract the notification lane's seat names ({@link PrepareTaskFn}, contracts.ts):
|
|
118
120
|
* a signature change reds HERE, at the declaration, as `false` failing the `true` bound. IDENTITY, not assignability:
|
|
119
121
|
* the parameter tuple (arity, optionality, each type) and the return type must be the SAME type in both directions —
|
|
@@ -44,6 +44,7 @@ import { parkContaminationMarker } from "./park-commit.js";
|
|
|
44
44
|
export { gatedCallIdOf, USAGE_WINDOW_REAP_MARGIN_MS } from "./park-commit.js";
|
|
45
45
|
import { prepareOffloadWrappers } from "./prepare-offload-wrappers.js";
|
|
46
46
|
import { prepareFileHistory } from "./prepare-file-history.js";
|
|
47
|
+
import { resolveFileHistoryRequest } from "./file-history-request.js";
|
|
47
48
|
import { prepareExecutionEnv } from "./prepare-execution-env.js";
|
|
48
49
|
import { prepareRunRefs } from "./prepare-run-refs.js";
|
|
49
50
|
import { prepareInheritedGate } from "./prepare-inherited-gate.js";
|
|
@@ -281,7 +282,7 @@ function refusePermissionModeDoors(spec) {
|
|
|
281
282
|
}
|
|
282
283
|
return mode;
|
|
283
284
|
}
|
|
284
|
-
export async function prepareTask(spec, deps, sessions, resume, internals, runnerSelf, runIdSink) {
|
|
285
|
+
export async function prepareTask(spec, deps, sessions, resume, internals, runnerSelf, runIdSink, holdSessionLock) {
|
|
285
286
|
const runId = uuidv7();
|
|
286
287
|
if (runIdSink !== undefined)
|
|
287
288
|
runIdSink.runId = runId;
|
|
@@ -304,8 +305,10 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
|
|
|
304
305
|
let shellGatedTools = new Set();
|
|
305
306
|
refuseRequireExistingWithoutSession(spec);
|
|
306
307
|
refuseRegistryScopeMismatch(spec, internals);
|
|
308
|
+
const fileHistoryRequest = resolveFileHistoryRequest(spec, deps);
|
|
307
309
|
const { acquired, session, conflictRef, wakeRecovered } = await prepareAcquireReconcile({ sessions, spec, resume, toolEffects, ...(internals?.sessionPlacement !== undefined ? { placement: internals.sessionPlacement } : {}), ...(() => { const g = durableParkGapFor(deps, spec); return g !== undefined ? { durableParkGap: g } : {}; })() });
|
|
308
310
|
const sessionId = acquired.sessionId;
|
|
311
|
+
await holdSessionLock?.(sessionId);
|
|
309
312
|
const onceLedger = await loadAnnounceOnceLedger(session, resume?.seed.announcedListings, deps.onError);
|
|
310
313
|
const hostTaskId = spec.taskId ?? sessionId;
|
|
311
314
|
const delegation = effectiveDelegationFacts(internals, resume?.seed.isDelegatedChild);
|
|
@@ -403,7 +406,7 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
|
|
|
403
406
|
const ownedEnv = ownedEnvSeat.current;
|
|
404
407
|
const { taskRootFinal, rebaseRestoredPath } = await prepareWorkspaceRestore({ ownedEnv, deps, spec, internals, resume, taskRootInitial, abortController, sessionId });
|
|
405
408
|
const { canonical: taskRootCanonical } = await resolveTaskRootCanonical({ env: executionEnv, given: taskRootFinal, onNotice: deps.onNotice, sessionId, runId });
|
|
406
|
-
const { trackFileEdit, fileHistoryBoundary, restoredFilePaths, rewindNotes, fileHistoryEnabled, fileHistoryFact, historyScope, historyRoot, historyFs } = await prepareFileHistory({ deps, spec, internals, executionEnv, taskRootFinal, handsEnabled, sessionId, session, abortController });
|
|
409
|
+
const { trackFileEdit, fileHistoryBoundary, restoredFilePaths, rewindNotes, fileHistoryEnabled, fileHistoryFact, historyScope, historyRoot, historyFs } = await prepareFileHistory({ deps, spec, request: fileHistoryRequest, internals, executionEnv, taskRootFinal, handsEnabled, sessionId, session, abortController });
|
|
407
410
|
const { noteFileEdited, editedFilesSnapshot, harnessRef, toolProgressRef, skillScope, forwardEvent, reviewRequestRef, requestReview, stopRequestedRef, requestStopAfterTurn, bindPermissionModeSeat, enterPlanMode, subagentRetain, worktreeIsolation } = prepareRunRefs({ spec, internals, executionEnv, taskRootFinal });
|
|
408
411
|
const legContextOverlay = () => runnerSelf?.contextOverlayOf?.(harnessRef.current?.getModelRef() ?? resolvedRole.modelRef);
|
|
409
412
|
let resolvedReadFace;
|
|
@@ -411,7 +414,7 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
|
|
|
411
414
|
let readDenyAdditionsNormalized = [];
|
|
412
415
|
let handsLessResolvedFace;
|
|
413
416
|
let handsLessResolvedWriteFace;
|
|
414
|
-
const { liveInheritedGate, seedInheritedGate, inheritedAncestorRules, inheritedShellGate, inheritedParentConstraints, permissionMode, inheritedAdmittedOrgScopes, priorOwnOrgVerdict, orgGovernedProvenance, effectiveShellGate, ownSessionRulesRef, ancestorSessionRulesRef, ancestorRulesNow, memoryAdmittedOrgScopesRef, ownOrgVerdictRef, orgAdmissionCheckpointState, faceCheckpointSection, faceCheckpointState, writeFaceCheckpointSection, f012CheckpointState, frozenOnAsk, hookEnvSource, notifyOwnHookCrash, frozenOnQuestion, parentSpecSeat, provenanceForChildrenRef, delegationSettlementRef, inheritedGateForChildren, carrierReadFace, carrierWriteFace, fullShellReachable, gateStopRef, stopForDenialLimit, enrichSpecToolCtx } = prepareInheritedGate({ spec, deps, internals, resume, sessions, sessionId, runId, hostTaskId, taskRootFinal, executionEnv, ownedEnv, lockedPreflight, checkpointSeat, toolFaceSnapshot, mountsCallerTool, promptProfile, resolvedInteractionPosture, permissionModeSeat, handsEnabled, reportUsage, harnessRef, skillScope, forwardEvent, subagentRetain, worktreeIsolation, requestReview, requestStopAfterTurn, enterPlanMode, reminderMark, reminderDisclosureCounts, fileHistoryEnabled, historyScope, historyRoot, historyFs, abortRun: () => { abortController.abort(); void harness.abort(); }, runtimeCaps: () => runtimeCaps, hooks: () => hooks, preToolUseObservational: () => preToolUseObservational, hookTimeoutMs: () => hookTimeoutMs, hookEnvFace: () => hookEnvFace, autoModeDecider: () => autoModeDeciderRef.current, autoModeDenialTracking: () => autoModeDenialTrackingRef.current, autoModeArming: () => autoModeArmingRef.current, agentForkDenial: () => agentForkDenial, observersActive: () => observersActive, resolvedReadFace: () => resolvedReadFace, resolvedWriteFace: () => resolvedWriteFace, readDenyAdditionsNormalized: () => readDenyAdditionsNormalized, handsLessResolvedFace: () => handsLessResolvedFace, handsLessResolvedWriteFace: () => handsLessResolvedWriteFace, centerAdoption: () => centerAdoptionRef.current, memoryEngineSession: () => memoryEngineSession });
|
|
417
|
+
const { liveInheritedGate, seedInheritedGate, inheritedAncestorRules, inheritedShellGate, inheritedParentConstraints, permissionMode, commitModeSeats, endModeCeiling, inheritedAdmittedOrgScopes, priorOwnOrgVerdict, orgGovernedProvenance, effectiveShellGate, ownSessionRulesRef, ancestorSessionRulesRef, ancestorRulesNow, memoryAdmittedOrgScopesRef, ownOrgVerdictRef, orgAdmissionCheckpointState, faceCheckpointSection, faceCheckpointState, writeFaceCheckpointSection, f012CheckpointState, frozenOnAsk, hookEnvSource, notifyOwnHookCrash, frozenOnQuestion, parentSpecSeat, provenanceForChildrenRef, delegationSettlementRef, inheritedGateForChildren, carrierReadFace, carrierWriteFace, fullShellReachable, gateStopRef, stopForDenialLimit, enrichSpecToolCtx } = prepareInheritedGate({ spec, deps, internals, resume, sessions, sessionId, runId, hostTaskId, taskRootFinal, executionEnv, ownedEnv, lockedPreflight, checkpointSeat, toolFaceSnapshot, mountsCallerTool, promptProfile, resolvedInteractionPosture, permissionModeSeat, handsEnabled, reportUsage, harnessRef, skillScope, forwardEvent, subagentRetain, worktreeIsolation, requestReview, requestStopAfterTurn, enterPlanMode, reminderMark, reminderDisclosureCounts, fileHistoryEnabled, historyScope, historyRoot, historyFs, abortRun: () => { abortController.abort(); void harness.abort(); }, runtimeCaps: () => runtimeCaps, hooks: () => hooks, preToolUseObservational: () => preToolUseObservational, hookTimeoutMs: () => hookTimeoutMs, hookEnvFace: () => hookEnvFace, autoModeDecider: () => autoModeDeciderRef.current, autoModeDenialTracking: () => autoModeDenialTrackingRef.current, autoModeArming: () => autoModeArmingRef.current, agentForkDenial: () => agentForkDenial, observersActive: () => observersActive, resolvedReadFace: () => resolvedReadFace, resolvedWriteFace: () => resolvedWriteFace, readDenyAdditionsNormalized: () => readDenyAdditionsNormalized, handsLessResolvedFace: () => handsLessResolvedFace, handsLessResolvedWriteFace: () => handsLessResolvedWriteFace, centerAdoption: () => centerAdoptionRef.current, memoryEngineSession: () => memoryEngineSession });
|
|
415
418
|
bindPermissionModeSeat(permissionMode);
|
|
416
419
|
const announceRuleStoreSkipped = ruleStoreUnreadableNotice(deps.onNotice, { sessionId, runId });
|
|
417
420
|
const persistedPathRowsRead = persistedPathRowsOfTask({ deps, principal: spec.principal, sessionId, root: taskRootFinal, home: executionEnv.homeDir, taskId: hostTaskId, handsEnabled, signals: [abortController.signal, ...(spec.signal !== undefined ? [spec.signal] : [])], onUnread: announceRuleStoreSkipped });
|
|
@@ -750,15 +753,16 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
|
|
|
750
753
|
const { askLane } = prepareAskLane({ gateMachineryActive, abortController, effectivePolicy, budgetSnapshot, handsCwdRef, advertisedWritableDirs, tools, inheritedUnavailableAsks, inheritedAskGrants, onAsk, humanReviewRef, now, ruleOffersOf, askSourceIdentity, riskAxesOf, autoModeDenialTracking: autoModeDenialTrackingRef, spec, deps, sessionId, runId, hooks, hookTimeoutMs, notifyOwnHookCrash, grantReadRoot: handsReadFace.grantReadRoot });
|
|
751
754
|
const { saga } = prepareSuspendSaga({ gateMachineryActive, abortController, harness, checkpointStore, deps, sessionId, hostTaskId, taskScope, liveSpendRef, resume, nestedStats, internals, activeTools, outputRef, readFileStateForCheckpoint, faceCheckpointSection, writeFaceCheckpointSection, reminderMark, handsCwdRef, worktreeSessionRef, undeliveredContinuationRef, inheritedParentConstraints, seedInheritedGate, ancestorRulesNow, inheritedShellGate, permissionMode, inheritedAdmittedOrgScopes, ownOrgVerdictRef, orgGovernedProvenance, announcedListingsRef, gitStatusRef, hookIdentity, placementRootResolved, externalContentTargetActive, remoteEnvFailures, memoryEngineSession, suspendLoopRef, ownedEnv, incompleteSuspendAdapter });
|
|
752
755
|
const { suspendForResource, suspendForPlatformLimit, suspendForReview } = prepareBoundaryParks({ saga, spec, checkpointStore, abortController, harness, session, sessions, sessionId, deps, priorLedger, maxSlices, maxSuspends, resourceTotal, priorSuspendCount, suspendChainBase, humanReviewRef, liveSpendRef, now, faceCheckpointState, f012CheckpointState, orgAdmissionCheckpointState, pausedRef, remoteEnvFailures, resourceSuspendEligible, durableSuspendInfraReady, incompleteSuspendAdapter });
|
|
753
|
-
const { parkAsk } = prepareParkAsk({ askLane, saga, spec, deps, sessionId, checkpointStore, toolRosterDeltas: rosterSeat, parkLaneArmed, contentAskRoutable, liveQuestionFace, mountedQuestionTool, contentAskBindings, lateStrandedAnswers, discloseStrandedAnswers, onAsk, runtimeCaps, inheritedUnavailableAsks, basePolicyForResumeEdit, budgetSnapshot, handsCwdRef, advertisedWritableDirs, offloadStore, ownedEnv, incompleteSuspendAdapter, session, sessions, suspendChainBase, maxSuspends, remoteEnvFailures, shellGatedTools, effectiveShellGate, durableApproval, priorLedger, liveSpendRef, resourceTotal, faceCheckpointState, f012CheckpointState, orgAdmissionCheckpointState, ruleOffersOf, now, humanReviewRef, abortController, harness, pausedRef });
|
|
756
|
+
const { parkAsk } = prepareParkAsk({ askLane, saga, spec, deps, sessionId, checkpointStore, toolRosterDeltas: rosterSeat, parkLaneArmed, contentAskRoutable, liveQuestionFace, mountedQuestionTool, contentAskBindings, lateStrandedAnswers, discloseStrandedAnswers, onAsk, runtimeCaps, inheritedUnavailableAsks, basePolicyForResumeEdit, budgetSnapshot, handsCwdRef, advertisedWritableDirs, offloadStore, ownedEnv, incompleteSuspendAdapter, session, sessions, suspendChainBase, maxSuspends, remoteEnvFailures, shellGatedTools, irreversibilityTier, effectiveShellGate, durableApproval, priorLedger, liveSpendRef, resourceTotal, faceCheckpointState, f012CheckpointState, orgAdmissionCheckpointState, ruleOffersOf, now, humanReviewRef, abortController, harness, pausedRef });
|
|
754
757
|
prepareGateStations({ askLane, parkAsk, tools, toolRosterDeltas: rosterSeat, toolEffects, deps, toolCallGateArmedRef, effectivePolicy, hooks, egressTools, irreversibleTools, spec, complianceDenies, harness, blockedToolCalls, inheritedAskGrants, inheritedUnavailableAsks, foldAskClasses, ancestorSandboxAdmissions, preToolContexts, gateOutcomes, batchHaltRef, blockedTracked, hookIdentity, reminderMark, hostTaskId, sessionId, ownGatePreToolUse, hookTimeoutMs, handsCwdRef, readDenyInForce: () => ({ tiers: handsReadFace.readDenyBuiltinTiersActive, rows: [...readDenyAdditionsNormalized.map((e) => e.pattern), ...handsReadFaceInput.pathDenyRules.filter((r) => r.faces.includes("read")).map((r) => r.rule)] }), hookEnvFace, writeProtectionCheck, shellReadCheck, irreversibilityTier, reversibilityProbes, abortController, shellGatedTools, autoModeDecider: autoModeDeciderRef, autoModeDenialTracking: autoModeDenialTrackingRef, askRoute: wiringManifest.ask, permissionMode, toolMarkSources, ...(deps.a2a?.isolatePeers === true ? { a2aIsolatePeers: true } : {}), ancestorArbitrations, runId, stopForDenialLimit, permissionRuleLane, permissionRuleOrgLane, questionToolMounted, sandboxAdmissionArmed, sandboxBoundaryCapable, emitSandboxAdmitted, delegation, notifyOwnHookCrash, frameSettlement });
|
|
755
758
|
const postureFrameRef = {};
|
|
756
759
|
const { microCompact, charsPerToken } = prepareContextLane({ model, deps, sessionId, runId, hostTaskId, offloadStore, microCompactKnob, harness, batchHaltRef, gitStatusRef, postureFrameRef, requestLossyRef, trimPressureRef, contextOverlay: legContextOverlay, ...(readFileStateForCheckpoint !== undefined ? { readFileState: readFileStateForCheckpoint } : {}) });
|
|
757
760
|
const preparedHolder = {};
|
|
758
761
|
const { cacheBreakDetector, cacheFingerprint, promptOverheadTokens, readTaskFile, normalizeAttachmentPath, isDedupStubResult, recentlyReadFiles, onCompactionApplied, detectExternalChanges, listBackgroundTasks, centerCompactionCandidate, effectiveReadFaceObserved, effectiveWriteFaceObserved, effectiveReadDenyObserved } = prepareTurnWiring({ deps, systemPromptSeat, harnessTools, fpRef, model, epochArtifactDigestForSnapshot, promptProfile, fableMitigations, systemBlocks, thinking, spec, sessionId, turnSnapshotRef, promptManifest, charsPerToken, handsEnabled, executionEnv, attachmentRootCanonical, additionalRootsCanonical, additionalReadRootsCanonical, readDenyMatcher, resolvedReadFace, handsCwdRef, readFileStateForCheckpoint, denyNarrowingPolicy, abortController, hostTaskId, taskScope, buildAssembleInputs, centerAdoptionRef, harnessRef, epochDeclaredSections, carrierReadFace, carrierWriteFace, readDenyAdditionsNormalized, preparedHolder });
|
|
759
762
|
await onceLedger.settle(session, announcedListingsRef);
|
|
760
|
-
const buildPrepared = () => ({ harness, session, sessionId, runId, registryAccess: { owner: hostTaskId, scope: taskScope }, reminderMark, reminderDisclosureCounts, fullShellReachable, approvalPosture: { get mode() { return permissionMode.current; }, askEffective: wiringManifest.ask.effective ?? "unresolved" }, permissionMode, editedFilesSnapshot, taskRootPath: taskRootFinal, model, thinking, compModel: effectiveCompModel, mcp, ...(mcpRedial !== undefined ? { mcpRedial } : {}), ...(a2a.tools.length > 0 ? { a2a } : {}), blockedRef, outputRef, abortController, conflictRef, blockedToolCalls, gateOutcomes, batchHaltRef, nestedStats, ...(rewindNotes.length > 0 ? { rewindNotes } : {}), ...(fileHistoryBoundary !== undefined ? { fileHistoryBoundary } : {}), ...(effectiveReadFaceObserved !== undefined ? { effectiveReadFace: effectiveReadFaceObserved, effectiveWriteFace: effectiveWriteFaceObserved } : {}), ...(effectiveReadDenyObserved !== undefined ? { effectiveReadDenyPatterns: effectiveReadDenyObserved } : {}), effectiveMemoryScopes: memoryEffectiveScopes, cwdRef: handsCwdRef, toolProgressRef, ...(advertisedWritableDirs !== undefined ? { advertisedWritableDirs } : {}), ...(worktreeSessionRef !== undefined ? { worktreeSessionRef } : {}), ...(workspaceStateSettle !== undefined ? { workspaceStateSettle } : {}), ...(sealReadStateSeat !== undefined ? { sealReadStateSeat } : {}), denyNarrowingPolicy, ...(permissionRuleLane !== undefined ? { persistedRuleLane: permissionRuleLane } : {}), ...(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, pausedRef, undeliveredContinuationRef, suspendProgressRef, remoteEnvFailures, reviewRequestRef, suspendLoopRef, suspendForResource, ...(suspendForPlatformLimit !== undefined ? { suspendForPlatformLimit } : {}), ...(envLifetimeSuspendAt !== undefined ? { envLifetimeSuspendAt } : {}), ...(usageGovernance !== undefined ? { usageGovernance } : {}), callIssuedAtRef, workCutRef, brainCallGuardrailRef, gateStopRef, stopForDenialLimit, suspendForReview, ...(readFileStateForCheckpoint !== undefined ? { readFileState: readFileStateForCheckpoint } : {}), resourceLedger: priorLedger, liveSpendRef, humanReviewRef, now, tools, toolRoster, toolRosterDeltas: rosterSeat, structuredProjector, toolEffects, wakeRecovered, promptOverheadTokens, lastBrainContext, readTaskFile, recentlyReadFiles, normalizeAttachmentPath, isDedupStubResult, ...(onCompactionApplied ? { onCompactionApplied } : {}), compactionReuseRef, trimPressureRef, microCompact, ...(memoryEngineSession ? { memoryEngineSession } : {}), ...(subagentRetain ? { subagentRetain } : {}), ...(lspDiagnostics && nudgeLspOnEdit ? { lspDiagnostics: { registry: lspDiagnostics, nudge: nudgeLspOnEdit, runIdent: lspRunIdent } } : {}), stopRequestedRef, announcedSnapshotRecovered: onceLedger.recovered, ...(dateChange ? { dateChange } : {}), ...(instructionSources ? { instructionSources } : {}), ...(projectInstructionContent !== undefined ? { projectInstructionContent } : {}), ...(workflowSizeGuideline ? { workflowSizeGuideline } : {}), ...(detectExternalChanges ? { detectExternalChanges } : {}), ...(toolsDeltaRef ? { toolsDeltaRef } : {}), ...(agentListing ? { agentListing } : {}), ...(skillsListing ? { skillsListing } : {}), announcedListingsRef, frameReceipts: { pending: [], listingSnapshotOwed: false }, frameSettlement, ...(peerLaneRefs.boundaryRound !== undefined ? { peerBoundaryRound: peerLaneRefs.boundaryRound } : {}), gitStatusRef, postureFrameRef, listBackgroundTasks, hookIdentity, ...(sessionBoxBound !== undefined ? { sessionBox: sessionBoxBound } : {}), hookTimeoutMs, ...(turnSnapshotRef.current !== undefined ? { turnSnapshot: turnSnapshotRef.current } : {}), ...(centerCompactionCandidate !== undefined ? { centerCompactionCandidate } : {}), ...(shellReadCheck !== undefined ? { shellReadCheck } : {}), ...(toolDisclosureSeat !== undefined ? { toolDisclosure: toolDisclosureSeat } : {}) });
|
|
763
|
+
const buildPrepared = () => ({ harness, session, sessionId, runId, registryAccess: { owner: hostTaskId, scope: taskScope }, reminderMark, reminderDisclosureCounts, fullShellReachable, approvalPosture: { get mode() { return permissionMode.current; }, askEffective: wiringManifest.ask.effective ?? "unresolved" }, permissionMode, editedFilesSnapshot, taskRootPath: taskRootFinal, model, thinking, compModel: effectiveCompModel, mcp, ...(mcpRedial !== undefined ? { mcpRedial } : {}), ...(a2a.tools.length > 0 ? { a2a } : {}), blockedRef, outputRef, abortController, conflictRef, blockedToolCalls, gateOutcomes, batchHaltRef, nestedStats, ...(rewindNotes.length > 0 ? { rewindNotes } : {}), ...(fileHistoryBoundary !== undefined ? { fileHistoryBoundary } : {}), ...(effectiveReadFaceObserved !== undefined ? { effectiveReadFace: effectiveReadFaceObserved, effectiveWriteFace: effectiveWriteFaceObserved } : {}), ...(effectiveReadDenyObserved !== undefined ? { effectiveReadDenyPatterns: effectiveReadDenyObserved } : {}), effectiveMemoryScopes: memoryEffectiveScopes, cwdRef: handsCwdRef, toolProgressRef, ...(advertisedWritableDirs !== undefined ? { advertisedWritableDirs } : {}), ...(worktreeSessionRef !== undefined ? { worktreeSessionRef } : {}), ...(workspaceStateSettle !== undefined ? { workspaceStateSettle } : {}), ...(sealReadStateSeat !== undefined ? { sealReadStateSeat } : {}), denyNarrowingPolicy, ...(permissionRuleLane !== undefined ? { persistedRuleLane: permissionRuleLane } : {}), ...(basePolicyForResumeEdit !== undefined ? { basePolicyForResumeEdit } : {}), ...(permissionRuleOrgLane !== undefined ? { permissionRuleOrg: permissionRuleOrgLane } : {}), releaseSignal, endModeCeiling, settleContentAskBindings, cacheBreakDetector, cacheFingerprint, wiringManifest, promptManifest, epochDeclaredSections, activeTools, ...(deferred.size > 0 ? { deferredToolNames: deferred } : {}), toolMaterializeStatic, deferDirectCall, ...(staticFaceForRef.current !== undefined ? { staticFaceFor: staticFaceForRef.current } : {}), ownedEnv, pausedRef, undeliveredContinuationRef, suspendProgressRef, remoteEnvFailures, reviewRequestRef, suspendLoopRef, suspendForResource, ...(suspendForPlatformLimit !== undefined ? { suspendForPlatformLimit } : {}), ...(envLifetimeSuspendAt !== undefined ? { envLifetimeSuspendAt } : {}), ...(usageGovernance !== undefined ? { usageGovernance } : {}), callIssuedAtRef, workCutRef, brainCallGuardrailRef, gateStopRef, stopForDenialLimit, suspendForReview, ...(readFileStateForCheckpoint !== undefined ? { readFileState: readFileStateForCheckpoint } : {}), resourceLedger: priorLedger, liveSpendRef, humanReviewRef, now, tools, toolRoster, toolRosterDeltas: rosterSeat, structuredProjector, toolEffects, wakeRecovered, promptOverheadTokens, lastBrainContext, readTaskFile, recentlyReadFiles, normalizeAttachmentPath, isDedupStubResult, ...(onCompactionApplied ? { onCompactionApplied } : {}), compactionReuseRef, trimPressureRef, microCompact, ...(memoryEngineSession ? { memoryEngineSession } : {}), ...(subagentRetain ? { subagentRetain } : {}), ...(lspDiagnostics && nudgeLspOnEdit ? { lspDiagnostics: { registry: lspDiagnostics, nudge: nudgeLspOnEdit, runIdent: lspRunIdent } } : {}), stopRequestedRef, announcedSnapshotRecovered: onceLedger.recovered, ...(dateChange ? { dateChange } : {}), ...(instructionSources ? { instructionSources } : {}), ...(projectInstructionContent !== undefined ? { projectInstructionContent } : {}), ...(workflowSizeGuideline ? { workflowSizeGuideline } : {}), ...(detectExternalChanges ? { detectExternalChanges } : {}), ...(toolsDeltaRef ? { toolsDeltaRef } : {}), ...(agentListing ? { agentListing } : {}), ...(skillsListing ? { skillsListing } : {}), announcedListingsRef, frameReceipts: { pending: [], listingSnapshotOwed: false }, frameSettlement, ...(peerLaneRefs.boundaryRound !== undefined ? { peerBoundaryRound: peerLaneRefs.boundaryRound } : {}), gitStatusRef, postureFrameRef, listBackgroundTasks, hookIdentity, ...(sessionBoxBound !== undefined ? { sessionBox: sessionBoxBound } : {}), hookTimeoutMs, ...(turnSnapshotRef.current !== undefined ? { turnSnapshot: turnSnapshotRef.current } : {}), ...(centerCompactionCandidate !== undefined ? { centerCompactionCandidate } : {}), ...(shellReadCheck !== undefined ? { shellReadCheck } : {}), ...(toolDisclosureSeat !== undefined ? { toolDisclosure: toolDisclosureSeat } : {}) });
|
|
761
764
|
rollback.commit();
|
|
765
|
+
commitModeSeats(abortController.signal);
|
|
762
766
|
const prepared = buildPrepared();
|
|
763
767
|
preparedHolder.current = prepared;
|
|
764
768
|
return prepared;
|
|
@@ -54,7 +54,9 @@ export function runBrainSinks(input) {
|
|
|
54
54
|
...(t.nextDelayMs !== undefined ? { nextDelayMs: t.nextDelayMs } : {}),
|
|
55
55
|
ts: Date.now(),
|
|
56
56
|
}
|
|
57
|
-
:
|
|
57
|
+
: t.kind === "echo_dropped"
|
|
58
|
+
? { kind: "brain.echo_dropped", version: 1, taskId: rs.telemetry.taskId, field: t.field, ts: Date.now() }
|
|
59
|
+
: { kind: "vision.placeholder", version: 1, taskId: rs.telemetry.taskId, count: t.count, ts: Date.now() });
|
|
58
60
|
};
|
|
59
61
|
const withBrainSinks = (fn) => runWithStatusSink(statusEmit, () => runWithBrainTelemetry(telemetryEmit, () => runWithReasoningWireFacts(observeReasoningWireFacts, fn)));
|
|
60
62
|
return { subagentName, withBrainSinks };
|