@sema-agent/core 7.45.0 → 7.47.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 +298 -1
- package/dist/agents/extra-tool-names.d.ts +65 -0
- package/dist/agents/extra-tool-names.js +124 -0
- package/dist/agents/subagent.d.ts +17 -5
- package/dist/agents/subagent.js +33 -25
- package/dist/agents/tool-filter.d.ts +17 -1
- package/dist/agents/tool-filter.js +7 -0
- package/dist/core/agent-config-dir.d.ts +20 -0
- package/dist/core/agent-config-dir.js +49 -0
- package/dist/core/allow-entry.d.ts +6 -4
- package/dist/core/allow-entry.js +6 -5
- package/dist/core/ask-origin.d.ts +35 -12
- package/dist/core/ask-origin.js +24 -7
- package/dist/core/checkpoint-store.d.ts +39 -2
- package/dist/core/effective-path-target.d.ts +136 -4
- package/dist/core/effective-path-target.js +110 -2
- package/dist/core/engine-notice.d.ts +12 -4
- package/dist/core/gate-fold.js +5 -2
- package/dist/core/gate-lanes.js +11 -4
- package/dist/core/gate-outcome.d.ts +4 -2
- package/dist/core/gate-outcome.js +2 -2
- package/dist/core/governance-codes.d.ts +3 -1
- package/dist/core/governance-codes.js +3 -0
- package/dist/core/hooks.d.ts +3 -0
- package/dist/core/path-rule-binding.d.ts +65 -0
- package/dist/core/path-rule-binding.js +99 -0
- package/dist/core/permission-rule-model.d.ts +59 -24
- package/dist/core/permission-rule-model.js +48 -44
- package/dist/core/permission-rule-provider.d.ts +7 -0
- package/dist/core/permission-rule-provider.js +10 -3
- package/dist/core/permission-rule-store.d.ts +8 -0
- package/dist/core/permission-rule-store.js +6 -2
- package/dist/core/permission-rule-sync.js +2 -2
- package/dist/core/permission-rules.d.ts +26 -45
- package/dist/core/permission-rules.js +77 -57
- package/dist/core/runner/child-tree.d.ts +97 -0
- package/dist/core/runner/child-tree.js +104 -0
- package/dist/core/runner/construction-doors.d.ts +5 -0
- package/dist/core/runner/construction-doors.js +6 -0
- package/dist/core/runner/contracts.d.ts +46 -0
- package/dist/core/runner/gate-exit.d.ts +4 -1
- package/dist/core/runner/gate-exit.js +5 -1
- package/dist/core/runner/permission-rule-lanes.d.ts +34 -25
- package/dist/core/runner/permission-rule-lanes.js +18 -12
- package/dist/core/runner/persisted-path-rows.d.ts +31 -7
- package/dist/core/runner/persisted-path-rows.js +31 -12
- package/dist/core/runner/prepare-ask-lane.d.ts +4 -0
- package/dist/core/runner/prepare-ask-lane.js +4 -2
- package/dist/core/runner/prepare-execution-env.d.ts +5 -2
- package/dist/core/runner/prepare-execution-env.js +10 -3
- package/dist/core/runner/prepare-gate-stations.d.ts +3 -0
- package/dist/core/runner/prepare-gate-stations.js +2 -1
- package/dist/core/runner/prepare-hands-readface.d.ts +8 -4
- package/dist/core/runner/prepare-hands-readface.js +11 -11
- package/dist/core/runner/prepare-inherited-gate.d.ts +8 -1
- package/dist/core/runner/prepare-inherited-gate.js +8 -2
- package/dist/core/runner/prepare-park-ask.d.ts +3 -0
- package/dist/core/runner/prepare-park-ask.js +5 -3
- package/dist/core/runner/prepare-policy-chain.d.ts +14 -2
- package/dist/core/runner/prepare-policy-chain.js +13 -5
- package/dist/core/runner/prepare-suspend-saga.d.ts +10 -0
- package/dist/core/runner/prepare-suspend-saga.js +7 -1
- package/dist/core/runner/prepare-task.js +37 -18
- package/dist/core/runner/prepare-turn-wiring.d.ts +2 -0
- package/dist/core/runner/prepare-turn-wiring.js +2 -1
- package/dist/core/runner/prepare-workspace-restore.d.ts +3 -0
- package/dist/core/runner/prepare-workspace-restore.js +1 -0
- package/dist/core/runner/resume-apply.js +17 -3
- package/dist/core/runner/resume-checkpoint-screen.js +13 -0
- package/dist/core/runner/run-leg.js +5 -1
- package/dist/core/runner/runtask.js +2 -2
- package/dist/core/runner/sub-agent-deny-lists.d.ts +1 -1
- package/dist/core/runner/write-protection-station.d.ts +3 -2
- package/dist/core/runner/write-protection-station.js +1 -0
- package/dist/core/runner-deps.d.ts +14 -0
- package/dist/core/sensitive-path-policy.d.ts +8 -0
- package/dist/core/sensitive-path-policy.js +18 -2
- package/dist/core/shell-wrapper-projection.d.ts +11 -0
- package/dist/core/shell-wrapper-projection.js +56 -0
- package/dist/core/shell-wrapper-table.d.ts +144 -34
- package/dist/core/shell-wrapper-table.js +40 -20
- package/dist/core/synthetic-read-verdict.d.ts +3 -0
- package/dist/core/synthetic-read-verdict.js +3 -1
- package/dist/core/tool-catalog-entries.d.ts +21 -0
- package/dist/core/tool-catalog-entries.js +12 -2
- package/dist/core/tool-face.d.ts +10 -1
- package/dist/core/tool-name-readings.d.ts +8 -0
- package/dist/core/tool-name-readings.js +2 -0
- package/dist/core/tool-policy.d.ts +40 -17
- package/dist/core/tool-policy.js +11 -9
- package/dist/core/tool-registry.d.ts +9 -0
- package/dist/core/tool-registry.js +10 -0
- package/dist/core/tool-spec.d.ts +3 -2
- package/dist/core/write-protect.d.ts +14 -3
- package/dist/core/write-protect.js +41 -10
- package/dist/index.d.ts +6 -4
- package/dist/index.js +5 -3
- package/dist/orchestration/run-spec.js +8 -7
- package/dist/orchestration/workflow.js +1 -1
- package/dist/shell/lex.d.ts +22 -0
- package/dist/shell/lex.js +75 -13
- package/dist/tools/fs/bash-program-position.d.ts +14 -90
- package/dist/tools/fs/bash-program-position.js +41 -74
- package/dist/tools/fs/bash-readonly-classifier.d.ts +17 -444
- package/dist/tools/fs/bash-readonly-classifier.js +169 -1225
- package/dist/tools/fs/index.d.ts +3 -2
- package/dist/tools/fs/program-read-model.d.ts +711 -0
- package/dist/tools/fs/program-read-model.js +1259 -0
- package/dist/tools/fs/program-read-model.rows.d.ts +18 -0
- package/dist/tools/fs/program-read-model.rows.js +624 -0
- package/dist/tools/fs/read-deny-home.d.ts +19 -1
- package/dist/tools/fs/read-deny-home.js +62 -24
- package/dist/tools/fs/read-deny.d.ts +54 -14
- package/dist/tools/fs/read-deny.js +104 -50
- package/dist/tools/fs/removal-targets.d.ts +7 -6
- package/dist/tools/fs/removal-targets.js +34 -24
- package/dist/tools/fs/safety.d.ts +3 -0
- package/dist/tools/fs/safety.js +10 -3
- package/dist/tools/fs/shell-read-argv.d.ts +86 -0
- package/dist/tools/fs/shell-read-argv.js +388 -0
- package/dist/tools/fs/shell-read-bindings.d.ts +300 -0
- package/dist/tools/fs/shell-read-bindings.js +755 -0
- package/dist/tools/fs/shell-read-check.js +23 -15
- package/dist/tools/fs/shell-read-establish.js +82 -8
- package/dist/tools/fs/shell-read-judge.d.ts +11 -1
- package/dist/tools/fs/shell-read-judge.js +9 -1
- package/dist/tools/fs/shell-read-plan.d.ts +33 -8
- package/dist/tools/fs/shell-read-plan.js +309 -407
- package/dist/tools/fs/shell-read-word.d.ts +60 -26
- package/dist/tools/fs/shell-read-word.js +47 -37
- package/dist/tools/fs/shell-read-write-targets.d.ts +15 -64
- package/dist/tools/fs/shell-read-write-targets.js +85 -137
- package/dist/tools/fs/shell-reentry-text.d.ts +136 -6
- package/dist/tools/fs/shell-reentry-text.js +203 -53
- package/dist/tools/monitor.d.ts +3 -3
- package/package.json +1 -1
- package/test/export-surface.snapshot.json +25 -5
- package/wire-changes/core@7.46.0.json +1522 -0
- package/wire-changes/core@7.47.0.json +412 -0
|
@@ -43,7 +43,8 @@ import type { OwnOrgAdmissionVerdict } from "../memory-admission.js";
|
|
|
43
43
|
import type { DelegationContentSafety } from "../memory-engine/delegation-provenance.js";
|
|
44
44
|
import { type SessionPermissionRules } from "../session-policy-store.js";
|
|
45
45
|
import type { SessionStore } from "../session.js";
|
|
46
|
-
import { type OnAsk } from "../tool-policy.js";
|
|
46
|
+
import { type OnAsk, type ToolPolicy } from "../tool-policy.js";
|
|
47
|
+
import type { PathRuleBases } from "../permission-rule-model.js";
|
|
47
48
|
import type { PermissionMode, RunnerDeps, RuntimeCaps, ShellGateDoctrine, TaskEvent, TaskSpec, ToolExecuteContext, ToolSpec } from "../types.js";
|
|
48
49
|
import { PermissionModeController } from "../mode-policy.js";
|
|
49
50
|
import { type SkillGrantTable } from "../skill-grant.js";
|
|
@@ -89,6 +90,12 @@ export interface PrepareInheritedGateInput {
|
|
|
89
90
|
ownedEnv: ExecutionEnv | undefined;
|
|
90
91
|
/** borrowed-readonly — the frozen preflight; only `toolPolicy` (the RESOLVED caller policy the children's chain carries). */
|
|
91
92
|
lockedPreflight: Pick<LockedPreflight, "toolPolicy">;
|
|
93
|
+
/** borrowed-readonly — the chain's top leg's anchors as this leg reads them (handed on to children), and how this leg
|
|
94
|
+
* installs the policies its chain hands it (`chainPolicyOnLeg`). */
|
|
95
|
+
pathRuleAnchors: {
|
|
96
|
+
readonly chainTop: PathRuleBases;
|
|
97
|
+
readonly onLeg: (policy: ToolPolicy, position: number) => ToolPolicy;
|
|
98
|
+
};
|
|
92
99
|
/** borrowed-readonly — the frozen tool-face snapshot (the ctx forwards exclude / defer / alwaysLoad / restoreGated; the
|
|
93
100
|
* full-shell predicate reads the exclusion of Bash). */
|
|
94
101
|
toolFaceSnapshot: ToolFaceSnapshot;
|
|
@@ -5,6 +5,7 @@ import { createPreToolUseConstraintPolicy } from "../hooks.js";
|
|
|
5
5
|
import { continuesLineage } from "../session-policy-store.js";
|
|
6
6
|
import { StubExecutionEnv } from "../stub-env.js";
|
|
7
7
|
import { askApproverIdentity, durableMandateSourceOf } from "../tool-policy.js";
|
|
8
|
+
import { chainAnchorRecords } from "./child-tree.js";
|
|
8
9
|
import { deliverEngineNotice } from "../types.js";
|
|
9
10
|
import { PermissionModeController, modeRequestAfterResume } from "../mode-policy.js";
|
|
10
11
|
import { SessionModeSeats } from "./session-mode-seats.js";
|
|
@@ -13,7 +14,7 @@ import { frozenSkillGrants } from "../skill-grant.js";
|
|
|
13
14
|
import { attachRebuiltDenialTrackers, createDenialLimitStop } from "./denial-limit-arms.js";
|
|
14
15
|
import { asThrownError } from "../thrown-value.js";
|
|
15
16
|
export function prepareInheritedGate(input) {
|
|
16
|
-
const { spec, deps, askSeat, internals, resume, sessions, sessionId, runId, hostTaskId, taskRootFinal, executionEnv, ownedEnv, lockedPreflight, toolFaceSnapshot, mountsCallerTool, promptProfile, resolvedInteractionPosture, permissionModeSeat, handsEnabled, reportUsage, harnessRef, skillGrants, forwardEvent, subagentRetain, worktreeIsolation, requestReview, requestStopAfterTurn, enterPlanMode, reminderMark, reminderDisclosureCounts, fileHistoryEnabled, historyScope, historyRoot, historyFs, abortRun } = input;
|
|
17
|
+
const { spec, deps, askSeat, internals, resume, sessions, sessionId, runId, hostTaskId, taskRootFinal, executionEnv, ownedEnv, lockedPreflight, pathRuleAnchors, toolFaceSnapshot, mountsCallerTool, promptProfile, resolvedInteractionPosture, permissionModeSeat, handsEnabled, reportUsage, harnessRef, skillGrants, forwardEvent, subagentRetain, worktreeIsolation, requestReview, requestStopAfterTurn, enterPlanMode, reminderMark, reminderDisclosureCounts, fileHistoryEnabled, historyScope, historyRoot, historyFs, abortRun } = input;
|
|
17
18
|
const liveInheritedGate = internals?.inheritedGate;
|
|
18
19
|
const seedInheritedGate = resume?.seed.inheritedGate;
|
|
19
20
|
const inheritedAncestorRules = (() => {
|
|
@@ -35,7 +36,11 @@ export function prepareInheritedGate(input) {
|
|
|
35
36
|
})();
|
|
36
37
|
const modeSeed = recordedModeSeed(seedInheritedGate);
|
|
37
38
|
const inheritedShellGate = liveInheritedGate?.shellGate ?? modeSeed.shellGate;
|
|
38
|
-
const
|
|
39
|
+
const askView = askSeat.reach === "none" ? liveInheritedGate?.parentConstraints?.map((pc) => (typeof pc.onAsk === "function" ? ((({ onAsk: _person, ...rest }) => rest)(pc)) : pc)) : liveInheritedGate?.parentConstraints;
|
|
40
|
+
const chainView = askView?.map((pc, position) => {
|
|
41
|
+
const policy = pathRuleAnchors.onLeg(pc.policy, position);
|
|
42
|
+
return policy === pc.policy ? pc : { ...pc, policy };
|
|
43
|
+
});
|
|
39
44
|
const inheritedParentConstraints = attachRebuiltDenialTrackers(chainView, deps.autoMode?.denialLimit);
|
|
40
45
|
const parentSeat = liveInheritedGate?.permissionModeCeiling;
|
|
41
46
|
const ceiling = parentSeat ?? liveInheritedGate?.permissionMode;
|
|
@@ -186,6 +191,7 @@ export function prepareInheritedGate(input) {
|
|
|
186
191
|
permissionMode: permissionMode.current,
|
|
187
192
|
permissionModeCeiling: legModeCeiling,
|
|
188
193
|
...(parentConstraints.length > 0 ? { parentConstraints } : {}),
|
|
194
|
+
...chainAnchorRecords(pathRuleAnchors.chainTop, parentConstraints),
|
|
189
195
|
admittedOrgScopes: memoryAdmittedOrgScopesRef.current,
|
|
190
196
|
...(orgGovernedProvenance ? { orgAdmissionGoverned: true } : {}),
|
|
191
197
|
};
|
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
* closures, so the orchestrator grows no branch.
|
|
21
21
|
*/
|
|
22
22
|
import type { AgentHarness, AgentMessage, AgentTool, ExecutionEnv } from "../../internal/harness.js";
|
|
23
|
+
import type { CallTargetStamp } from "../effective-path-target.js";
|
|
23
24
|
import { type OnQuestion } from "../ask-question.js";
|
|
24
25
|
import { type CheckpointStore } from "../checkpoint-store.js";
|
|
25
26
|
import type { GrantBindingOf } from "../skill-grant-binding.js";
|
|
@@ -96,6 +97,8 @@ export interface PrepareParkAskInput {
|
|
|
96
97
|
handsCwdRef: CwdRef | undefined;
|
|
97
98
|
/** borrowed-readonly — the root the live gate stamps beside the cwd ({@link import("./prepare-ask-lane.js").PrepareAskLaneInput.handsRoot}). */
|
|
98
99
|
handsRoot: string | undefined;
|
|
100
|
+
/** borrowed-readonly — the live gate's target-reading stamp ({@link import("./prepare-ask-lane.js").PrepareAskLaneInput.stampCallTarget}). */
|
|
101
|
+
stampCallTarget: CallTargetStamp | undefined;
|
|
99
102
|
/** borrowed-readonly — the SAME seat the live gate stamps from ({@link import("./prepare-ask-lane.js").PrepareAskLaneInput.advertisedWritableDirs}): a parked call's projection re-adjudication asks one question about one call, so it must ask it against the same admitted list. Read at park time, not written here. */
|
|
100
103
|
advertisedWritableDirs: Pick<AdvertisedWritableDirs, "roots"> | undefined;
|
|
101
104
|
/** borrowed-readonly — the run's offload store, or undefined (a volatile store holding results refuses the park). */
|
|
@@ -27,7 +27,7 @@ const wordlessDemand = (toolName) => {
|
|
|
27
27
|
throw new Error(`a real-approval demand for "${toolName}" reached the park with no origin word — the origin stamp precedes every park`);
|
|
28
28
|
};
|
|
29
29
|
export function prepareParkAsk(input) {
|
|
30
|
-
const { askLane, saga, spec, deps, sessionId, checkpointStore, toolRosterDeltas, parkLaneArmed, contentAskRoutable, liveQuestionFace, mountedQuestionTool, contentAskBindings, lateStrandedAnswers, discloseStrandedAnswers, onAsk, runtimeCaps, inheritedUnavailableAsks, basePolicyForResumeEdit, budgetSnapshot, handsCwdRef, handsRoot, advertisedWritableDirs, offloadStore, ownedEnv, incompleteSuspendAdapter, session, sessions, suspendChainBase, maxSuspends, remoteEnvFailures, shellGatedTools, irreversibilityTier, toolMarkSources, effectiveShellGate, durableApproval, priorLedger, liveSpendRef, resourceTotal, faceCheckpointState, f012CheckpointState, orgAdmissionCheckpointState, ruleOffersOf, grantBindingOf, now, humanReviewRef, abortController, harness, pausedRef } = input;
|
|
30
|
+
const { askLane, saga, spec, deps, sessionId, checkpointStore, toolRosterDeltas, parkLaneArmed, contentAskRoutable, liveQuestionFace, mountedQuestionTool, contentAskBindings, lateStrandedAnswers, discloseStrandedAnswers, onAsk, runtimeCaps, inheritedUnavailableAsks, basePolicyForResumeEdit, budgetSnapshot, handsCwdRef, handsRoot, stampCallTarget, advertisedWritableDirs, offloadStore, ownedEnv, incompleteSuspendAdapter, session, sessions, suspendChainBase, maxSuspends, remoteEnvFailures, shellGatedTools, irreversibilityTier, toolMarkSources, effectiveShellGate, durableApproval, priorLedger, liveSpendRef, resourceTotal, faceCheckpointState, f012CheckpointState, orgAdmissionCheckpointState, ruleOffersOf, grantBindingOf, now, humanReviewRef, abortController, harness, pausedRef } = input;
|
|
31
31
|
if (askLane === undefined || saga === undefined)
|
|
32
32
|
return { parkAsk: undefined };
|
|
33
33
|
const { composedCallSignal, approvalPreviewOf } = askLane;
|
|
@@ -159,7 +159,7 @@ export function prepareParkAsk(input) {
|
|
|
159
159
|
if (!presented.ok) {
|
|
160
160
|
throw new ParkRefusal(`the stored form of "${req.toolName}"'s arguments could not be presented for re-adjudication (${describeThrown(presented.cause)})`, { cause: presented.cause });
|
|
161
161
|
}
|
|
162
|
-
const
|
|
162
|
+
const reprojectedReq = () => ({
|
|
163
163
|
toolName: req.toolName,
|
|
164
164
|
args: presented.value,
|
|
165
165
|
toolCallId: req.toolCallId,
|
|
@@ -167,7 +167,9 @@ export function prepareParkAsk(input) {
|
|
|
167
167
|
...callFaceSeat(req.face),
|
|
168
168
|
...(handsCwdRef !== undefined ? { cwd: handsCwdRef.current } : {}), ...(handsRoot !== undefined ? { root: handsRoot } : {}),
|
|
169
169
|
...advertisedWritableRootsSeat(advertisedWritableDirs),
|
|
170
|
-
}
|
|
170
|
+
});
|
|
171
|
+
const withReading = stampCallTarget?.(reprojectedReq(), cutSignal);
|
|
172
|
+
const reprojectedRaced = await raceSettlementAgainstSignal(withReading === undefined ? Promise.resolve(basePolicyForResumeEdit.check(reprojectedReq(), cutSignal)) : withReading.then((r) => basePolicyForResumeEdit.check(r, cutSignal)), cutSignal);
|
|
171
173
|
if (reprojectedRaced.tag === "aborted")
|
|
172
174
|
return undefined;
|
|
173
175
|
if (reprojectedRaced.tag === "threw")
|
|
@@ -27,6 +27,8 @@ import { type Hooks } from "../hooks.js";
|
|
|
27
27
|
import type { LockedPreflight } from "../locked-config.js";
|
|
28
28
|
import type { SessionPermissionRules } from "../session-policy-store.js";
|
|
29
29
|
import { type OnAsk, type ToolPolicy } from "../tool-policy.js";
|
|
30
|
+
import type { PathRuleBases } from "../permission-rule-model.js";
|
|
31
|
+
import type { HeadLeads } from "../path-rule-binding.js";
|
|
30
32
|
import type { RunnerDeps, RuntimeCaps, TaskSpec, ToolEffect } from "../types.js";
|
|
31
33
|
import type { CwdRef } from "../../tools/fs/fs-shared.js";
|
|
32
34
|
import type { ReadDenyMatcher } from "../../tools/fs/read-deny.js";
|
|
@@ -65,9 +67,17 @@ export interface PreparePolicyChainInput {
|
|
|
65
67
|
additionalRootsCanonical: readonly string[];
|
|
66
68
|
/** borrowed-readonly — the run's resolved env (path rules resolve in it; the sandbox declaration is read off it). */
|
|
67
69
|
executionEnv: ExecutionEnv;
|
|
68
|
-
/** borrowed-readonly — the frozen preflight: `toolPolicy` (the caller slot) and
|
|
69
|
-
* resume-edit override). */
|
|
70
|
+
/** borrowed-readonly — the frozen preflight as installed on this leg: `toolPolicy` (the caller slot) and
|
|
71
|
+
* `basePolicyForResumeEdit` (the lock-aware resume-edit override), their path rules anchored where this leg installed them. */
|
|
70
72
|
lockedPreflight: Pick<LockedPreflight, "toolPolicy" | "basePolicyForResumeEdit">;
|
|
73
|
+
/** borrowed-readonly — the path rules' anchors on this leg: `leg` (this leg's root and environment home — where this
|
|
74
|
+
* leg's own lists are installed) and `chainTop` (the top leg's: the person's global / session rows and every `~/`). */
|
|
75
|
+
pathRuleAnchors: {
|
|
76
|
+
readonly leg: PathRuleBases;
|
|
77
|
+
readonly chainTop: PathRuleBases;
|
|
78
|
+
};
|
|
79
|
+
/** borrowed-readonly — the leg's one resolution of where rule heads lead (the rows' twins). */
|
|
80
|
+
headLeads: HeadLeads;
|
|
71
81
|
/** borrowed-readonly — the run's ONE tool roster, read only here (the name audit's universe: names + aliases). */
|
|
72
82
|
tools: ReadonlyArray<AgentTool>;
|
|
73
83
|
/** borrowed-readonly — the harness list (placeholders keep their deferred names), the audit universe's second half. */
|
|
@@ -96,6 +106,8 @@ export interface PreparePolicyChainInput {
|
|
|
96
106
|
readDenyMatcher: ReadDenyMatcher | undefined;
|
|
97
107
|
/** borrowed-readonly — the run's one notice for a person's rule store that could not be read (`ruleStoreUnreadableNotice`). */
|
|
98
108
|
announceRuleStoreSkipped: (at: "prepare" | "call") => void;
|
|
109
|
+
/** borrowed-readonly — the run's one notice for rows the person's store served that were left out (`ruleRowsDroppedNotice`). */
|
|
110
|
+
announceRuleRowsDropped: (rows: import("../permission-rule-provider.js").EffectivePermissionRules["droppedRows"]) => void;
|
|
99
111
|
/** borrowed-readonly — whether the question tool mounted (the lanes' question-tool exclusion). */
|
|
100
112
|
questionToolMounted: boolean;
|
|
101
113
|
/** borrowed-readonly — the resolved per-principal entitlements; only `forceDurableGate` (the mandate-park facility and
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { withArgsReading } from "../effective-path-target.js";
|
|
1
2
|
import { policyAskClassOf } from "../ask-class.js";
|
|
2
3
|
import { ASK_USER_QUESTION_TOOL_NAME } from "../ask-question.js";
|
|
3
4
|
import { classifierUnavailableSeat } from "./classifier-ladder.js";
|
|
@@ -13,7 +14,7 @@ import { emitTrace } from "../trace.js";
|
|
|
13
14
|
import { skillGrantBindingMembers } from "../skill-grant.js";
|
|
14
15
|
import { SKILL_TOOL_NAME } from "./synthetic-tools.js";
|
|
15
16
|
import { autoStrippedRule, cardDisclosureOf } from "../allow-entry.js";
|
|
16
|
-
import { arbitrateByMode, askClassMembersOf, askMandateMember } from "../ask-origin.js";
|
|
17
|
+
import { arbitrateByMode, askClassMembersOf, askFaceOf, askMandateMember } from "../ask-origin.js";
|
|
17
18
|
import { createModeGatePolicy, mountedToolDeclaresReadOnly } from "../mode-policy.js";
|
|
18
19
|
const ancestorFacts = (ask) => ({ ...(ask ?? {}), ancestorResolved: true });
|
|
19
20
|
import { headlessDenyAtFold, headlessDenyAtRecheck, INHERITED_STATION_FACTS, inheritedAskCarry, inheritedAskFallbackMessage, judgeInheritedClassifier, lateAskSettlementObserver, resolveInheritedAsk, settleDenialLimitFallback } from "./denial-limit-arms.js";
|
|
@@ -24,7 +25,7 @@ import { createLiveSessionRules, createSessionRulePolicy } from "./session-rule-
|
|
|
24
25
|
import { thrownText } from "../thrown-value.js";
|
|
25
26
|
import { heldBy, heldValues, seatOf, wireOf } from "../tool-name-readings.js";
|
|
26
27
|
export async function preparePolicyChain(input) {
|
|
27
|
-
const { spec, deps, internals, sessionId, runId, hostTaskId, taskRootFinal, additionalRootsCanonical, executionEnv, lockedPreflight, tools, harnessTools, toolEffects, egressTools, irreversibilityTier, axisExplicitNegatives, shellGatedTools, toolMarkSources, envHandToolNames, handsCwdRef, readDenyMatcher, announceRuleStoreSkipped, questionToolMounted, runtimeCaps, inheritedAncestorRules, ancestorSessionRulesRef, inheritedParentConstraints, seedInheritedGate, skillGrants, skillSpecs, allowedToolTables, frozenOnAsk, hookEnvSource, notifyOwnHookCrash, autoModeDecider, readFace, permissionMode, scratchpadDir, toolRosterDeltas, stopForDenialLimit, delegation, abortController, now, ownSessionRulesRef } = input;
|
|
28
|
+
const { spec, deps, internals, sessionId, runId, hostTaskId, taskRootFinal, additionalRootsCanonical, executionEnv, lockedPreflight, pathRuleAnchors, headLeads, tools, harnessTools, toolEffects, egressTools, irreversibilityTier, axisExplicitNegatives, shellGatedTools, toolMarkSources, envHandToolNames, handsCwdRef, readDenyMatcher, announceRuleStoreSkipped, announceRuleRowsDropped, questionToolMounted, runtimeCaps, inheritedAncestorRules, ancestorSessionRulesRef, inheritedParentConstraints, seedInheritedGate, skillGrants, skillSpecs, allowedToolTables, frozenOnAsk, hookEnvSource, notifyOwnHookCrash, autoModeDecider, readFace, permissionMode, scratchpadDir, toolRosterDeltas, stopForDenialLimit, delegation, abortController, now, ownSessionRulesRef } = input;
|
|
28
29
|
const ancestorArbitrations = new Map();
|
|
29
30
|
const arbitrateInherited = (ask, toolCallId, judged) => {
|
|
30
31
|
const verdict = arbitrateByMode(permissionMode.current, judged.classification, { origin: judged.origin, ...askMandateMember(ancestorFacts(judged.ask.action === "ask" ? judged.ask : undefined)) });
|
|
@@ -312,10 +313,11 @@ export async function preparePolicyChain(input) {
|
|
|
312
313
|
...(seat.sources.size > 0 ? { toolMarkSources: seat.sources } : {}),
|
|
313
314
|
...(deps.a2a?.isolatePeers === true ? { a2aIsolatePeers: true } : {}),
|
|
314
315
|
...(face !== undefined ? { readFace: face } : {}),
|
|
316
|
+
askFace: askFaceOf(wireOf("inherited.askFace", call)),
|
|
315
317
|
};
|
|
316
318
|
};
|
|
317
319
|
const inheritedAskEvidence = inheritedAskRuleEvidence(deps.permissionRuleStore);
|
|
318
|
-
const listFacts = { root: taskRootFinal, sessionId, liveCwd: () => handsCwdRef?.current,
|
|
320
|
+
const listFacts = { root: taskRootFinal, sessionId, liveCwd: () => handsCwdRef?.current, anchors: pathRuleAnchors.leg };
|
|
319
321
|
const skillGrantLane = skillGrants.lane(listFacts);
|
|
320
322
|
const allowEntryLanes = { request: allowedToolTables.request.lane(listFacts), deployment: allowedToolTables.deployment.lane(listFacts) };
|
|
321
323
|
const { personal: permissionRuleLane, org: permissionRuleOrgLane } = createPermissionRuleLanes({
|
|
@@ -324,6 +326,9 @@ export async function preparePolicyChain(input) {
|
|
|
324
326
|
principal: spec.principal,
|
|
325
327
|
sessionId,
|
|
326
328
|
root: taskRootFinal,
|
|
329
|
+
rootCanonical: pathRuleAnchors.leg.root,
|
|
330
|
+
chainTop: pathRuleAnchors.chainTop,
|
|
331
|
+
leads: headLeads,
|
|
327
332
|
liveCwd: () => handsCwdRef?.current,
|
|
328
333
|
home: executionEnv.homeDir,
|
|
329
334
|
questionToolMounted,
|
|
@@ -331,6 +336,7 @@ export async function preparePolicyChain(input) {
|
|
|
331
336
|
onRevisionDefect: (message) => deps.onError?.(new Error(message), { phase: "config", sessionId }),
|
|
332
337
|
onDisclosure: (message) => emitTrace(deps.tracer, () => ({ kind: "permission.rule_store_unreadable", version: 1, taskId: hostTaskId, message, ts: Date.now() })),
|
|
333
338
|
onStoreUnreadable: announceRuleStoreSkipped,
|
|
339
|
+
onRowsDropped: announceRuleRowsDropped,
|
|
334
340
|
signal: abortController.signal,
|
|
335
341
|
stripsAllow: (rule, req) => permissionMode.current === "auto" && autoStrippedRule(rule, req),
|
|
336
342
|
});
|
|
@@ -366,7 +372,8 @@ export async function preparePolicyChain(input) {
|
|
|
366
372
|
}
|
|
367
373
|
let re;
|
|
368
374
|
try {
|
|
369
|
-
|
|
375
|
+
const editReq = withArgsReading(creq, editArgs, csignal ?? abortController.signal);
|
|
376
|
+
re = refuseOutOfContractDecision(await pol.check(editReq !== undefined ? await editReq : { ...creq, args: editArgs }, csignal ?? abortController.signal));
|
|
370
377
|
}
|
|
371
378
|
catch (err) {
|
|
372
379
|
return vetoed({
|
|
@@ -646,7 +653,8 @@ export async function preparePolicyChain(input) {
|
|
|
646
653
|
}
|
|
647
654
|
}
|
|
648
655
|
const recheckLayers = [...recheckPrefix, ...postEmitterSameInstanceAdapters];
|
|
649
|
-
const
|
|
656
|
+
const finalRead = withArgsReading(req, decision.updatedInput, signal);
|
|
657
|
+
const finalReq = finalRead !== undefined ? await finalRead : { ...req, args: decision.updatedInput };
|
|
650
658
|
let asked;
|
|
651
659
|
const revalidated = {};
|
|
652
660
|
let restated;
|
|
@@ -118,6 +118,10 @@ export interface PrepareSuspendSagaInput {
|
|
|
118
118
|
reminderMark: string;
|
|
119
119
|
/** borrowed-readonly — the hand's live tracked cwd, or undefined; `current` is read at mint time. Not written here. */
|
|
120
120
|
handsCwdRef: CwdRef | undefined;
|
|
121
|
+
/** borrowed-readonly — the hands' root (the `root` every adjudicated request of the leg carries), or undefined (hands-less). */
|
|
122
|
+
handsRoot: string | undefined;
|
|
123
|
+
/** borrowed-readonly — the home the leg's caller policies installed `~/` at (absolute), or undefined. */
|
|
124
|
+
handsHome: string | undefined;
|
|
121
125
|
/** borrowed-readonly — the active EnterWorktree session seat, or undefined; `current` is read at mint time. */
|
|
122
126
|
worktreeSessionRef: Prepared["worktreeSessionRef"];
|
|
123
127
|
/** borrowed-readonly — the resumed leg's not-yet-delivered continuation content; its orphan obituaries fold into this
|
|
@@ -140,6 +144,12 @@ export interface PrepareSuspendSagaInput {
|
|
|
140
144
|
permissionMode: PermissionModeController;
|
|
141
145
|
/** borrowed-readonly — the inherited admitted org scopes, or undefined (copied onto the row). */
|
|
142
146
|
inheritedAdmittedOrgScopes: readonly string[] | undefined;
|
|
147
|
+
/** borrowed-readonly — the chain's top leg's anchors this leg carries (absent on a leg that is its own top): recorded on
|
|
148
|
+
* the data half so a resumed child judges the person's global / session rows and `~/` rows where its chain did. */
|
|
149
|
+
inheritedPathRuleAnchors: InheritedGate["pathRuleAnchors"];
|
|
150
|
+
/** borrowed-readonly — where each parent constraint this leg runs under was installed (position for position), recorded on
|
|
151
|
+
* the data half so a resume that re-supplies the chain uninstalled installs each entry there. */
|
|
152
|
+
inheritedPathRuleInstallations: InheritedGate["pathRuleInstallations"];
|
|
143
153
|
/** borrowed-readonly — this leg's OWN org verdict seat; `current` is read at mint time. Not written here. */
|
|
144
154
|
ownOrgVerdictRef: {
|
|
145
155
|
current: OwnOrgAdmissionVerdict | undefined;
|
|
@@ -79,7 +79,7 @@ function stampPlacementRootSessionId(placementRootResolved) {
|
|
|
79
79
|
return placementValueOrAbsent(placementRootResolved);
|
|
80
80
|
}
|
|
81
81
|
export function prepareSuspendSaga(input) {
|
|
82
|
-
const { gateMachineryActive, abortController, harness, checkpointStore, deps, sessionId, hostTaskId, taskScope, liveSpendRef, resume, nestedStats, internals, activeTools, outputRef, readFileStateForCheckpoint, faceCheckpointSection, writeFaceCheckpointSection, skillGrantCheckpointSection, reminderMark, handsCwdRef, worktreeSessionRef, undeliveredContinuationRef, inheritedParentConstraints, seedInheritedGate, ancestorRulesNow, inheritedShellGate, permissionMode, inheritedAdmittedOrgScopes, ownOrgVerdictRef, orgGovernedProvenance, announcedListingsRef, gitStatusRef, hookIdentity, placementRootResolved, externalContentTargetActive, remoteEnvFailures, memoryEngineSession, suspendLoopRef, ownedEnv, incompleteSuspendAdapter } = input;
|
|
82
|
+
const { gateMachineryActive, abortController, harness, checkpointStore, deps, sessionId, hostTaskId, taskScope, liveSpendRef, resume, nestedStats, internals, activeTools, outputRef, readFileStateForCheckpoint, faceCheckpointSection, writeFaceCheckpointSection, skillGrantCheckpointSection, reminderMark, handsCwdRef, handsRoot, handsHome, worktreeSessionRef, undeliveredContinuationRef, inheritedParentConstraints, seedInheritedGate, ancestorRulesNow, inheritedShellGate, permissionMode, inheritedAdmittedOrgScopes, inheritedPathRuleAnchors, inheritedPathRuleInstallations, ownOrgVerdictRef, orgGovernedProvenance, announcedListingsRef, gitStatusRef, hookIdentity, placementRootResolved, externalContentTargetActive, remoteEnvFailures, memoryEngineSession, suspendLoopRef, ownedEnv, incompleteSuspendAdapter } = input;
|
|
83
83
|
if (!gateMachineryActive)
|
|
84
84
|
return { saga: undefined };
|
|
85
85
|
const inFlightSpendMicroUsd = () => {
|
|
@@ -115,6 +115,8 @@ export function prepareSuspendSaga(input) {
|
|
|
115
115
|
repairBundle: repairBundleForCheckpoint(parkedSpendMicroUsd),
|
|
116
116
|
workspaceHandle,
|
|
117
117
|
handsCwd: handsCwdRef?.current,
|
|
118
|
+
handsRoot,
|
|
119
|
+
handsHome,
|
|
118
120
|
activeWorktree: worktreeSessionRef?.current ? { ...worktreeSessionRef.current } : undefined,
|
|
119
121
|
runningBackgroundTasks: (() => {
|
|
120
122
|
const live = defaultTaskRegistry
|
|
@@ -142,6 +144,8 @@ export function prepareSuspendSaga(input) {
|
|
|
142
144
|
inheritedShellGate !== undefined ||
|
|
143
145
|
modeRecorded ||
|
|
144
146
|
inheritedAdmittedOrgScopes !== undefined ||
|
|
147
|
+
inheritedPathRuleAnchors !== undefined ||
|
|
148
|
+
inheritedPathRuleInstallations !== undefined ||
|
|
145
149
|
ownOrgVerdictRef.current !== undefined ||
|
|
146
150
|
orgGovernedProvenance ||
|
|
147
151
|
requiresParentConstraint
|
|
@@ -151,6 +155,8 @@ export function prepareSuspendSaga(input) {
|
|
|
151
155
|
...(modeRecorded ? { permissionMode: declaredMode } : {}),
|
|
152
156
|
...(permissionMode.prePlanMode !== undefined ? { prePlanMode: permissionMode.prePlanMode } : {}),
|
|
153
157
|
...(inheritedAdmittedOrgScopes !== undefined ? { admittedOrgScopes: [...inheritedAdmittedOrgScopes] } : {}),
|
|
158
|
+
...(inheritedPathRuleAnchors !== undefined ? { pathRuleAnchors: { ...inheritedPathRuleAnchors } } : {}),
|
|
159
|
+
...(inheritedPathRuleInstallations !== undefined ? { pathRuleInstallations: inheritedPathRuleInstallations.map((r) => (r === null ? null : { ...r })) } : {}),
|
|
154
160
|
...(ownOrgVerdictRef.current !== undefined
|
|
155
161
|
? { ownAdmittedOrgScopes: [...ownOrgVerdictRef.current.scopes], ownAdmittedOrgWriteScope: ownOrgVerdictRef.current.writeScope }
|
|
156
162
|
: {}),
|
|
@@ -8,7 +8,9 @@ import { brainToRuntime } from "../runtime.js";
|
|
|
8
8
|
import { hasSessionFork } from "../session.js";
|
|
9
9
|
import { SEND_MESSAGE_TOOL_NAME } from "../../agents/send-message-tool.js";
|
|
10
10
|
import { callerToolMembership } from "../../agents/inherited-tool-pool.js";
|
|
11
|
-
import {
|
|
11
|
+
import { toolPolicyPathRules, toolPolicyWriteTargetGuard } from "../tool-policy.js";
|
|
12
|
+
import { bindPathRules, createHeadLeads } from "../path-rule-binding.js";
|
|
13
|
+
import { whereItsAnsweredPrefixLeads } from "../../tools/fs/read-deny-home.js";
|
|
12
14
|
import { loadAnnounceOnceLedger } from "./announce-once-ledger.js";
|
|
13
15
|
import { isValidReminderMark, mintReminderMark } from "../reminder-mint.js";
|
|
14
16
|
import { clampPermissionMode } from "../ask-origin.js";
|
|
@@ -16,17 +18,18 @@ import { modePolicyOf, modeRequestAfterResume, refusePermissionModeDoors } from
|
|
|
16
18
|
import { resolveOutputStyleFrame } from "../output-style.js";
|
|
17
19
|
import { recordedModeSeed } from "../checkpoint-store.js";
|
|
18
20
|
import { emitTrace } from "../trace.js";
|
|
19
|
-
import { persistedPathRowsOfTask, ruleStoreUnreadableNotice } from "./persisted-path-rows.js";
|
|
21
|
+
import { persistedPathRowsOfTask, ruleRowsDroppedNotice, ruleStoreUnreadableNotice } from "./persisted-path-rows.js";
|
|
20
22
|
import { reservedCollisions, reservedFor } from "../../brain/request-params.js";
|
|
21
23
|
import { STALL_FIRST_BYTE_MS, STALL_FIRST_TOKEN_MS, STALL_IDLE_MS, withBrainCallGuardrail } from "../../brain/timeout.js";
|
|
22
24
|
import { OFFLOAD_TOOL_NAME } from "../tool-result-store.js";
|
|
23
25
|
import { OUTPUT_TOOL_NAME, SKILL_TOOL_NAME, createOutputTool } from "./synthetic-tools.js";
|
|
24
|
-
import { skillGateWiring } from "../skill-grant.js";
|
|
26
|
+
import { compileSkillGrant, skillGateWiring } from "../skill-grant.js";
|
|
27
|
+
import { legCallTargetStamp } from "../effective-path-target.js";
|
|
25
28
|
import { AllowEntryTable, screenAllowedToolsValue } from "../allow-entry.js";
|
|
26
29
|
import { compileOutputSchema } from "./strict-output-schema.js";
|
|
27
30
|
import { MEMORY_ENGINE_TOOL_NAMES } from "../memory-engine/tools.js";
|
|
28
31
|
import { foldAdmissionFreeze } from "../memory-admission.js";
|
|
29
|
-
import { deploymentCanRerootChild } from "./child-tree.js";
|
|
32
|
+
import { chainAnchorRecords, chainPolicyOnLeg, chainTopAnchors, deploymentCanRerootChild } from "./child-tree.js";
|
|
30
33
|
import { prepareMemory } from "./prepare-memory.js";
|
|
31
34
|
import { prepareMemoryEngineSession } from "./prepare-memory-engine-session.js";
|
|
32
35
|
import { prepareDeferClassify } from "./prepare-defer-classify.js";
|
|
@@ -40,6 +43,7 @@ export { runGuardChain } from "./prepare-context-lane.js";
|
|
|
40
43
|
import { preparePromptAssembly } from "./prepare-prompt-assembly.js";
|
|
41
44
|
import { limitConfigError, prepareConfigDoors } from "./prepare-config-doors.js";
|
|
42
45
|
import { prepareSafetyScan } from "./prepare-safety-scan.js";
|
|
46
|
+
import { isAbsolutePathForm } from "../../tools/fs/safety.js";
|
|
43
47
|
import { prepareAcquireReconcile } from "./prepare-acquire-reconcile.js";
|
|
44
48
|
import { settleBranchWriteBack } from "./branch-writeback.js";
|
|
45
49
|
import { prepareHandsMount, resolveHandsLessReadFace } from "./prepare-hands-readface.js";
|
|
@@ -347,7 +351,7 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
|
|
|
347
351
|
throw e;
|
|
348
352
|
}
|
|
349
353
|
const rollback = createRollbackStack((e) => deps.onError?.(e, { phase: "config", sessionId }));
|
|
350
|
-
const { executionEnv, ownedEnvSeat, ownedEnvObservedAt, handsEnabled, taskRootInitial } = await prepareExecutionEnv({ deps, spec, internals, resume, placementRootResolved, sessionId, forgetOnThrow, rollback });
|
|
354
|
+
const { executionEnv, ownedEnvSeat, ownedEnvObservedAt, handsEnabled, taskRootInitial, placement } = await prepareExecutionEnv({ deps, spec, internals, resume, placementRootResolved, sessionId, forgetOnThrow, rollback });
|
|
351
355
|
const externalContentTargetActive = executionEnv.externalContentTarget === true || resume?.seed.externalContentTarget === true;
|
|
352
356
|
const abortController = new AbortController();
|
|
353
357
|
if (spec.signal?.aborted)
|
|
@@ -400,8 +404,15 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
|
|
|
400
404
|
}
|
|
401
405
|
}
|
|
402
406
|
const ownedEnv = ownedEnvSeat.current;
|
|
403
|
-
const { taskRootFinal, rebaseRestoredPath } = await prepareWorkspaceRestore({ ownedEnv, deps, spec, internals, resume, taskRootInitial, abortController, sessionId });
|
|
407
|
+
const { taskRootFinal, rebaseRestoredPath } = await prepareWorkspaceRestore({ ownedEnv, deps, spec, internals, resume, taskRootInitial, placement, abortController, sessionId });
|
|
404
408
|
const { canonical: taskRootCanonical } = await resolveTaskRootCanonical({ env: executionEnv, given: taskRootFinal, onNotice: deps.onNotice, sessionId, runId });
|
|
409
|
+
const legHome = executionEnv.homeDir;
|
|
410
|
+
const legAnchors = { root: taskRootCanonical, ...(legHome !== undefined && isAbsolutePathForm(legHome) ? { home: legHome } : {}) };
|
|
411
|
+
const chainTop = chainTopAnchors({ leg: legAnchors, live: internals?.inheritedGate?.pathRuleAnchors, seed: resume?.seed.inheritedGate?.pathRuleAnchors, placement, rebase: rebaseRestoredPath });
|
|
412
|
+
const onLeg = chainPolicyOnLeg({ leg: legAnchors, chainTop, placement, chain: (internals?.inheritedGate?.parentConstraints ?? []).map((c) => c.policy), installations: { live: internals?.inheritedGate?.pathRuleInstallations, seed: resume?.seed.inheritedGate?.pathRuleInstallations }, rebase: rebaseRestoredPath });
|
|
413
|
+
const [installedToolPolicy, installedBaseEdit] = [lockedPreflight.toolPolicy, lockedPreflight.basePolicyForResumeEdit].map(onLeg.own);
|
|
414
|
+
const installedPreflight = { ...lockedPreflight, toolPolicy: installedToolPolicy, basePolicyForResumeEdit: installedBaseEdit };
|
|
415
|
+
const headLeads = createHeadLeads((part) => whereItsAnsweredPrefixLeads(executionEnv, part));
|
|
405
416
|
const { trackFileEdit, fileHistoryBoundary, restoredFilePaths, rewindNotes, fileHistoryEnabled, fileHistoryFact, historyScope, historyRoot, historyFs } = await prepareFileHistory({ deps, spec, request: fileHistoryRequest, internals, executionEnv, taskRootFinal, handsEnabled, sessionId, session, abortController });
|
|
406
417
|
const { noteFileEdited, editedFilesSnapshot, harnessRef, toolProgressRef, skillGrants, forwardEvent, reviewRequestRef, requestReview, stopRequestedRef, requestStopAfterTurn, bindPermissionModeSeat, enterPlanMode, subagentRetain, worktreeIsolation } = prepareRunRefs({ spec, internals, executionEnv, taskRootFinal });
|
|
407
418
|
const allowedToolTables = { request: new AllowEntryTable(), deployment: new AllowEntryTable() };
|
|
@@ -411,14 +422,19 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
|
|
|
411
422
|
let readDenyAdditionsNormalized = [];
|
|
412
423
|
let handsLessResolvedFace;
|
|
413
424
|
let handsLessResolvedWriteFace;
|
|
414
|
-
const { liveInheritedGate, seedInheritedGate, inheritedAncestorRules, inheritedShellGate, inheritedParentConstraints, permissionMode, commitModeSeats, endModeCeiling, inheritedAdmittedOrgScopes, priorOwnOrgVerdict, orgGovernedProvenance, effectiveShellGate, ownSessionRulesRef, ancestorSessionRulesRef, ancestorRulesNow, memoryAdmittedOrgScopesRef, ownOrgVerdictRef, orgAdmissionCheckpointState, faceCheckpointSection, faceCheckpointState, writeFaceCheckpointSection, skillGrantCheckpointSection, f012CheckpointState, frozenOnAsk, hookEnvSource, notifyOwnHookCrash, frozenOnQuestion, parentSpecSeat, provenanceForChildrenRef, delegationSettlementRef, inheritedGateForChildren, carrierReadFace, carrierWriteFace, fullShellReachable, gateStopRef, stopForDenialLimit, enrichSpecToolCtx } = prepareInheritedGate({ spec, deps, askSeat: doors.askSeat, internals, resume, sessions, sessionId, runId, hostTaskId, taskRootFinal, executionEnv, ownedEnv, lockedPreflight, checkpointSeat, toolFaceSnapshot, mountsCallerTool, promptProfile, resolvedInteractionPosture, permissionModeSeat, handsEnabled, reportUsage, harnessRef, skillGrants, requestAllowedTools: allowedToolTables.request, 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 });
|
|
425
|
+
const { liveInheritedGate, seedInheritedGate, inheritedAncestorRules, inheritedShellGate, inheritedParentConstraints, permissionMode, commitModeSeats, endModeCeiling, inheritedAdmittedOrgScopes, priorOwnOrgVerdict, orgGovernedProvenance, effectiveShellGate, ownSessionRulesRef, ancestorSessionRulesRef, ancestorRulesNow, memoryAdmittedOrgScopesRef, ownOrgVerdictRef, orgAdmissionCheckpointState, faceCheckpointSection, faceCheckpointState, writeFaceCheckpointSection, skillGrantCheckpointSection, f012CheckpointState, frozenOnAsk, hookEnvSource, notifyOwnHookCrash, frozenOnQuestion, parentSpecSeat, provenanceForChildrenRef, delegationSettlementRef, inheritedGateForChildren, carrierReadFace, carrierWriteFace, fullShellReachable, gateStopRef, stopForDenialLimit, enrichSpecToolCtx } = prepareInheritedGate({ spec, deps, askSeat: doors.askSeat, internals, resume, sessions, sessionId, runId, hostTaskId, taskRootFinal, executionEnv, ownedEnv, lockedPreflight: installedPreflight, pathRuleAnchors: { chainTop, onLeg: onLeg.chained }, checkpointSeat, toolFaceSnapshot, mountsCallerTool, promptProfile, resolvedInteractionPosture, permissionModeSeat, handsEnabled, reportUsage, harnessRef, skillGrants, requestAllowedTools: allowedToolTables.request, 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
426
|
bindPermissionModeSeat(permissionMode);
|
|
416
427
|
const announceRuleStoreSkipped = ruleStoreUnreadableNotice(deps.onNotice, { sessionId, runId });
|
|
417
|
-
const
|
|
428
|
+
const announceRuleRowsDropped = ruleRowsDroppedNotice(deps.onNotice, { sessionId, runId });
|
|
429
|
+
const persistedPathRowsRead = persistedPathRowsOfTask({ deps, principal: spec.principal, sessionId, root: taskRootFinal, rootCanonical: taskRootCanonical, leads: headLeads, chainTop, taskId: hostTaskId, handsEnabled, onRowsDropped: announceRuleRowsDropped, signals: [abortController.signal, ...(spec.signal !== undefined ? [spec.signal] : [])], onUnread: announceRuleStoreSkipped });
|
|
418
430
|
const persistedPathRows = persistedPathRowsRead === undefined ? { readDirectories: [], denyRows: [] } : await persistedPathRowsRead;
|
|
419
|
-
const
|
|
431
|
+
const policyDenyRows = toolPolicyPathRules([installedToolPolicy, ...(inheritedParentConstraints ?? []).map((c) => c.policy)], legAnchors).filter((r) => r.faces.length > 0 && r.behavior === "deny");
|
|
432
|
+
for (const r of policyDenyRows)
|
|
433
|
+
if (r.unanchored !== undefined)
|
|
434
|
+
emitTrace(deps.tracer, () => ({ kind: "permission.rule_store_unreadable", version: 1, taskId: hostTaskId, message: `the deny rule ${r.rule} needs a ${r.unanchored.join(" / ")} base this task does not declare — the shell's file commands and the search tools do not judge it on this leg (the gate asks)`, ts: Date.now() }));
|
|
435
|
+
const effectivePathDenyRules = [...policyDenyRows.filter((r) => r.unanchored === undefined), ...persistedPathRows.denyRows];
|
|
420
436
|
const writeProtectionJudgeRef = {};
|
|
421
|
-
const writeGuards = { protection: () => writeProtectionJudgeRef.current, target: toolPolicyWriteTargetGuard([
|
|
437
|
+
const writeGuards = { protection: () => writeProtectionJudgeRef.current, target: toolPolicyWriteTargetGuard([installedToolPolicy, ...(inheritedParentConstraints ?? []).map((c) => c.policy)]) };
|
|
422
438
|
const { roster, blockedRef, runtimeCaps, runtimeCapsFaulted, complianceDenies, complianceDegraded, agentForkDenial, observersActive, autoModeArmReason, autoModeDeciderRef, autoModeDenialTrackingRef, autoModeArmingRef, armAutoMode, selfOrchestrationActive, workflowToolsActive, workflowSizeGuideline } = await prepareCapsAndWorkflow({ spec, deps, askSeat: doors.askSeat, internals, session, sessionId, runId, hostTaskId, taskScope, taskRootFinal, model, thinking, lockedPreflight, checkpointSeat, toolEffects, toolFaceSnapshot, promptProfile, resolvedInteractionPosture, harnessRef, parentSpecSeat, carrierReadFace, carrierWriteFace, forwardEvent, inheritedGateForChildren, enrichSpecToolCtx, maybeOffload, requestReview, enterPlanMode, permissionMode, readDenyEntries: () => ({ entries: readDenyMatcher?.entries ?? [], ruleRows: effectivePathDenyRules }), peerLaneActive, peerSendMessageBuiltIn, runnerSelf, memoryEngineSession: () => memoryEngineSession, centerAdoption: () => centerAdoptionRef.current, readDenyAdditionsNormalized: () => readDenyAdditionsNormalized });
|
|
423
439
|
const tools = roster.tools;
|
|
424
440
|
const pausedRef = {};
|
|
@@ -556,7 +572,7 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
|
|
|
556
572
|
if (internals?.ownOrgAdmissionRef !== undefined && ownOrgVerdictRef.current !== undefined) {
|
|
557
573
|
internals.ownOrgAdmissionRef.current = ownOrgVerdictRef.current;
|
|
558
574
|
}
|
|
559
|
-
const handsReadFaceInput = { permissionMode,
|
|
575
|
+
const handsReadFaceInput = { permissionMode, denyRuleRows: effectivePathDenyRules, headLeads, writeGuards, persistedReadDirectories: persistedPathRows.readDirectories, handsEnabled, executionEnv, taskRootFinal, taskRootCanonical, rebaseRestoredPath, resume, session, sessionId, hostTaskId, taskScope, fullShellReachable, effectiveShellGate, toolFaceSnapshot, model, spec, deps, internals, memoryWriteGate, ...(advertisedWritableDirs !== undefined ? { advertisedWritableDirs } : {}), firstPartyOffload, roster, egressTools, irreversibilityTier, irreversibleTools, reversibilityProbes, reminderMark, reminderDisclosureCounts, ...(trackFileEdit !== undefined ? { trackFileEdit } : {}), onFileEdited: noteFileEdited, harnessRef, toolProgressRef, ...(restoredFilePaths.length > 0 ? { restoredFilePaths } : {}) };
|
|
560
576
|
const handsReadFace = handsEnabled ? await prepareHandsMount(handsReadFaceInput) : resolveHandsLessReadFace(handsReadFaceInput);
|
|
561
577
|
const { readFileStateForCheckpoint, seedContextFiles, handsCwdRef, workspaceStateSettle, wsSnapshot, rebaseWsPath, backgroundTaskToolsActive, shellReadCheck, shellReadAdmission, additionalRootsCanonical, additionalReadRootsCanonical, attachmentRootCanonical, readDenyMatcher, envHandToolNames, sealReadStateSeat } = handsReadFace;
|
|
562
578
|
resolvedReadFace = handsReadFace.resolvedReadFace;
|
|
@@ -737,7 +753,7 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
|
|
|
737
753
|
releaseSignal = () => sig.removeEventListener("abort", onExternalAbort);
|
|
738
754
|
}
|
|
739
755
|
}
|
|
740
|
-
const { hooks, hookTimeoutMs, preToolUseObservational, ownGatePreToolUse, basePolicyForResumeEdit, denyNarrowingPolicy, skillGrantLane, allowEntryLanes, policyLayers, effectivePolicy, inheritedUnavailableAsks, inheritedAskGrants, askSourceIdentity, riskAxesOf, ruleOffersOf, grantBindingOf, permissionRuleLane, permissionRuleOrgLane, sandboxAdmissionArmed, sandboxBoundaryCapable, emitSandboxAdmitted, foldAskClasses, ancestorSandboxAdmissions, ancestorArbitrations } = await preparePolicyChain({ spec, deps, internals, sessionId, runId, hostTaskId, taskRootFinal, additionalRootsCanonical, executionEnv, lockedPreflight, tools, harnessTools, toolEffects, egressTools, irreversibilityTier, axisExplicitNegatives, shellGatedTools, toolMarkSources, envHandToolNames, handsCwdRef, readDenyMatcher, announceRuleStoreSkipped, questionToolMounted, runtimeCaps, inheritedAncestorRules, ancestorSessionRulesRef, inheritedParentConstraints, seedInheritedGate, skillGrants, skillSpecs, allowedToolTables, frozenOnAsk, hookEnvSource, notifyOwnHookCrash, autoModeDecider: () => autoModeDeciderRef.current, readFace: () => resolvedReadFace, permissionMode, scratchpadDir: spec.envFacts?.scratchpadDir, toolRosterDeltas: rosterSeat, stopForDenialLimit, delegation, abortController, now, ownSessionRulesRef });
|
|
756
|
+
const { hooks, hookTimeoutMs, preToolUseObservational, ownGatePreToolUse, basePolicyForResumeEdit, denyNarrowingPolicy, skillGrantLane, allowEntryLanes, policyLayers, effectivePolicy, inheritedUnavailableAsks, inheritedAskGrants, askSourceIdentity, riskAxesOf, ruleOffersOf, grantBindingOf, permissionRuleLane, permissionRuleOrgLane, sandboxAdmissionArmed, sandboxBoundaryCapable, emitSandboxAdmitted, foldAskClasses, ancestorSandboxAdmissions, ancestorArbitrations } = await preparePolicyChain({ spec, deps, internals, sessionId, runId, hostTaskId, taskRootFinal, additionalRootsCanonical, executionEnv, lockedPreflight: installedPreflight, pathRuleAnchors: { leg: legAnchors, chainTop }, headLeads, tools, harnessTools, toolEffects, egressTools, irreversibilityTier, axisExplicitNegatives, shellGatedTools, toolMarkSources, envHandToolNames, handsCwdRef, readDenyMatcher, announceRuleStoreSkipped, announceRuleRowsDropped, questionToolMounted, runtimeCaps, inheritedAncestorRules, ancestorSessionRulesRef, inheritedParentConstraints, seedInheritedGate, skillGrants, skillSpecs, allowedToolTables, frozenOnAsk, hookEnvSource, notifyOwnHookCrash, autoModeDecider: () => autoModeDeciderRef.current, readFace: () => resolvedReadFace, permissionMode, scratchpadDir: spec.envFacts?.scratchpadDir, toolRosterDeltas: rosterSeat, stopForDenialLimit, delegation, abortController, now, ownSessionRulesRef });
|
|
741
757
|
const { onAsk, preToolContexts, blockedToolCalls, gateOutcomes, batchHaltRef, blockedTracked, incompleteSuspendAdapter, durableSuspendInfraReady, resourceSuspendEligible, usageGovernance, durableApproval, wiringManifest, writeProtection, parkLaneArmed, gateMachineryActive, hookIdentity, hookEnvFace, sessionBoxBound } = prepareWiringManifest({ spec, deps, askSeat: doors.askSeat, internals, resume, sessionId, runId, hostTaskId, taskScope, hooks, preToolUseObservational, policyLayers, effectivePolicy, handsEnabled, taskRootFinal, mcp, irreversibleTools, egressTools, shellReadStationArmed: handsReadFace.shellReadStationArmed, toolEffects, ownedEnv, executionEnv, offloadStore, onceLedger, usageWindows, envLifetimeSuspendAt, runtimeCaps, resolvedInteractionPosture, durableQuestionFace, liveQuestionFace, checkpointStore, sessions, modelGateManifest, autoModeArmReason, permissionMode, lockedPreflight, peerLaneRefs, frameSettlement, harness, pausedRef, liveInheritedGate, delegation, toolRoster, readDenyBuiltinTiersActive: handsReadFace.readDenyBuiltinTiersActive, lspManagerWired, lspDiagnosticsLive: lspDiagnostics !== undefined, fileHistoryFact, sessionBox });
|
|
742
758
|
const writeProtectionCheck = writeProtection?.check;
|
|
743
759
|
writeProtectionJudgeRef.current = writeProtection?.judgeTarget;
|
|
@@ -747,18 +763,21 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
|
|
|
747
763
|
return undefined;
|
|
748
764
|
});
|
|
749
765
|
}
|
|
750
|
-
const
|
|
751
|
-
const
|
|
766
|
+
const listPathRows = () => skillSpecs.flatMap((s) => compileSkillGrant(s, "model").rows).flatMap((r) => (r.behavior === "deny" && r.compiled.kind === "path" ? [r.compiled.rule] : []));
|
|
767
|
+
const stampCallTarget = attachmentRootCanonical === undefined ? undefined : legCallTargetStamp({ env: executionEnv, root: attachmentRootCanonical, cwd: () => handsCwdRef?.current, judgesPaths: () => effectivePolicy?.pathRules !== undefined || basePolicyForResumeEdit?.pathRules !== undefined || permissionRuleLane !== undefined || listPathRows().length > 0, leads: () => headLeads.resolve([...toolPolicyPathRules([effectivePolicy, basePolicyForResumeEdit, ...(inheritedParentConstraints ?? []).map((c) => c.policy)], legAnchors), ...bindPathRules(listPathRows().map((rule) => ({ parsed: rule, ruleText: rule.rule })), legAnchors)]) });
|
|
768
|
+
const { askLane } = prepareAskLane({ gateMachineryActive, abortController, effectivePolicy, budgetSnapshot, handsCwdRef, handsRoot: attachmentRootCanonical, stampCallTarget, advertisedWritableDirs, tools, inheritedUnavailableAsks, inheritedAskGrants, onAsk, humanReviewRef, now, ruleOffersOf, grantBindingOf, askSourceIdentity, riskAxesOf, autoModeDenialTracking: autoModeDenialTrackingRef, spec, deps, sessionId, runId, hooks, hookTimeoutMs, notifyOwnHookCrash, grantReadRoot: handsReadFace.grantReadRoot });
|
|
769
|
+
const inheritedAnchorRecords = chainAnchorRecords(chainTop, inheritedParentConstraints ?? []);
|
|
770
|
+
const { saga } = prepareSuspendSaga({ gateMachineryActive, abortController, harness, checkpointStore, deps, sessionId, hostTaskId, taskScope, liveSpendRef, resume, nestedStats, internals, activeTools, outputRef, readFileStateForCheckpoint, faceCheckpointSection, writeFaceCheckpointSection, skillGrantCheckpointSection, reminderMark, handsCwdRef, handsRoot: attachmentRootCanonical, handsHome: attachmentRootCanonical !== undefined ? legAnchors.home : undefined, worktreeSessionRef, undeliveredContinuationRef, inheritedParentConstraints, seedInheritedGate, ancestorRulesNow, inheritedShellGate, permissionMode, inheritedAdmittedOrgScopes, inheritedPathRuleAnchors: chainTop !== legAnchors ? inheritedAnchorRecords.pathRuleAnchors : undefined, inheritedPathRuleInstallations: inheritedAnchorRecords.pathRuleInstallations, ownOrgVerdictRef, orgGovernedProvenance, announcedListingsRef, gitStatusRef, hookIdentity, placementRootResolved, externalContentTargetActive, remoteEnvFailures, memoryEngineSession, suspendLoopRef, ownedEnv, incompleteSuspendAdapter });
|
|
752
771
|
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, handsRoot: attachmentRootCanonical, advertisedWritableDirs, offloadStore, ownedEnv, incompleteSuspendAdapter, session, sessions, suspendChainBase, maxSuspends, remoteEnvFailures, shellGatedTools, irreversibilityTier, toolMarkSources, effectiveShellGate, durableApproval, priorLedger, liveSpendRef, resourceTotal, faceCheckpointState, f012CheckpointState, orgAdmissionCheckpointState, ruleOffersOf, grantBindingOf, now, humanReviewRef, abortController, harness, pausedRef });
|
|
772
|
+
const { parkAsk } = prepareParkAsk({ askLane, saga, spec, deps, sessionId, checkpointStore, toolRosterDeltas: rosterSeat, parkLaneArmed, contentAskRoutable, liveQuestionFace, mountedQuestionTool, contentAskBindings, lateStrandedAnswers, discloseStrandedAnswers, onAsk, runtimeCaps, inheritedUnavailableAsks, basePolicyForResumeEdit, budgetSnapshot, handsCwdRef, handsRoot: attachmentRootCanonical, stampCallTarget, advertisedWritableDirs, offloadStore, ownedEnv, incompleteSuspendAdapter, session, sessions, suspendChainBase, maxSuspends, remoteEnvFailures, shellGatedTools, irreversibilityTier, toolMarkSources, effectiveShellGate, durableApproval, priorLedger, liveSpendRef, resourceTotal, faceCheckpointState, f012CheckpointState, orgAdmissionCheckpointState, ruleOffersOf, grantBindingOf, now, humanReviewRef, abortController, harness, pausedRef });
|
|
754
773
|
const seatInputsFor = skillGateWiring({ tools, skillToolName: SKILL_TOOL_NAME, seatOf: skillSeatOf, mode: () => permissionMode.current, lane: skillGrantLane, onAllowed: (info) => emitTrace(deps.tracer, () => ({ kind: "permission.skill_allowed", version: 1, taskId: hostTaskId, ...info, entries: [...info.entries], ts: Date.now() })), allowEntries: { deploymentAllows: { ...allowEntryLanes.deployment, onAllowed: (info) => emitTrace(deps.tracer, () => ({ kind: "permission.allowed_tools_allowed", version: 1, taskId: hostTaskId, source: "deployment", ...info, entries: [...info.entries], ts: Date.now() })) }, requestAllows: { ...allowEntryLanes.request, onAllowed: (info) => emitTrace(deps.tracer, () => ({ kind: "permission.allowed_tools_allowed", version: 1, taskId: hostTaskId, source: "request", ...info, entries: [...info.entries], ts: Date.now() })) } } });
|
|
755
|
-
const { approvedCallScreen } = 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.
|
|
774
|
+
const { approvedCallScreen } = 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, stampCallTarget, readDenyInForce: () => ({ tiers: handsReadFace.readDenyBuiltinTiersActive, rows: [...readDenyAdditionsNormalized.map((e) => e.pattern), ...handsReadFaceInput.denyRuleRows.filter((r) => r.faces.includes("read")).map((r) => r.rule)] }), hookEnvFace, writeProtectionCheck, shellReadCheck, readFace: () => resolvedReadFace, irreversibilityTier, reversibilityProbes, abortController, shellGatedTools, autoModeDecider: autoModeDeciderRef, autoModeDenialTracking: autoModeDenialTrackingRef, askRoute: { ...wiringManifest.ask, effective: askSeatEffective(wiringManifest) }, permissionMode, toolMarkSources, ...(deps.a2a?.isolatePeers === true ? { a2aIsolatePeers: true } : {}), ancestorArbitrations, runId, stopForDenialLimit, permissionRuleLane, seatInputsFor, permissionRuleOrgLane, questionToolMounted, sandboxAdmissionArmed, sandboxBoundaryCapable, emitSandboxAdmitted, delegation, notifyOwnHookCrash, frameSettlement });
|
|
756
775
|
const postureFrameRef = { report: (err) => deps.onError?.(err, { phase: "degraded", sessionId }) };
|
|
757
776
|
const { microCompact, charsPerToken } = prepareContextLane({ model, deps, sessionId, runId, hostTaskId, offloadStore, toolRosterDeltas: rosterSeat, microCompactKnob, harness, batchHaltRef, gitStatusRef, postureFrameRef, requestLossyRef, trimPressureRef, contextOverlay: legContextOverlay, ...(readFileStateForCheckpoint !== undefined ? { readFileState: readFileStateForCheckpoint } : {}) });
|
|
758
777
|
const preparedHolder = {};
|
|
759
|
-
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, skillGrants: skillGrantLane, callerPolicy:
|
|
778
|
+
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, skillGrants: skillGrantLane, callerPolicy: installedToolPolicy, inheritedPolicies: (inheritedParentConstraints ?? []).map((c) => c.policy), persistedRuleLane: permissionRuleLane, orgRuleLane: permissionRuleOrgLane, stampCallTarget, abortController, hostTaskId, taskScope, buildAssembleInputs, centerAdoptionRef, harnessRef, epochDeclaredSections, carrierReadFace, carrierWriteFace, readDenyAdditionsNormalized, preparedHolder });
|
|
760
779
|
await onceLedger.settle(session, announcedListingsRef);
|
|
761
|
-
const buildPrepared = () => ({ harness, session, sessionId, runId, registryAccess: { owner: hostTaskId, scope: taskScope }, reminderMark, reminderDisclosureCounts, fullShellReachable, approvalPosture: { get mode() { return permissionMode.current; }, askEffective: askSeatEffective(wiringManifest) }, ...(outputStyleFrame !== undefined ? { outputStyleFrame } : {}), 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, ...(attachmentRootCanonical !== undefined ? { handsRoot: attachmentRootCanonical } : {}), toolProgressRef, ...(advertisedWritableDirs !== undefined ? { advertisedWritableDirs } : {}), ...(worktreeSessionRef !== undefined ? { worktreeSessionRef } : {}), ...(workspaceStateSettle !== undefined ? { workspaceStateSettle } : {}), ...(sealReadStateSeat !== undefined ? { sealReadStateSeat } : {}), denyNarrowingPolicy, skillGrants: skillGrantLane, skillSpecs, ...(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 } : {}), ...(approvedCallScreen !== undefined ? { approvedCallScreen } : {}) });
|
|
780
|
+
const buildPrepared = () => ({ harness, session, sessionId, runId, registryAccess: { owner: hostTaskId, scope: taskScope }, reminderMark, reminderDisclosureCounts, fullShellReachable, approvalPosture: { get mode() { return permissionMode.current; }, askEffective: askSeatEffective(wiringManifest) }, ...(outputStyleFrame !== undefined ? { outputStyleFrame } : {}), 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, ...(attachmentRootCanonical !== undefined ? { handsRoot: attachmentRootCanonical } : {}), ...(stampCallTarget !== undefined ? { stampCallTarget } : {}), toolProgressRef, ...(advertisedWritableDirs !== undefined ? { advertisedWritableDirs } : {}), ...(worktreeSessionRef !== undefined ? { worktreeSessionRef } : {}), ...(workspaceStateSettle !== undefined ? { workspaceStateSettle } : {}), ...(sealReadStateSeat !== undefined ? { sealReadStateSeat } : {}), denyNarrowingPolicy, skillGrants: skillGrantLane, skillSpecs, ...(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 } : {}), ...(approvedCallScreen !== undefined ? { approvedCallScreen } : {}) });
|
|
762
781
|
rollback.commit();
|
|
763
782
|
commitModeSeats(abortController.signal);
|
|
764
783
|
const prepared = buildPrepared();
|
|
@@ -92,6 +92,8 @@ export interface PrepareTurnWiringInput {
|
|
|
92
92
|
persistedRuleLane: Prepared["persistedRuleLane"];
|
|
93
93
|
/** borrowed-readonly — the org rule lane, or undefined (a layer of the judge). */
|
|
94
94
|
orgRuleLane: Prepared["permissionRuleOrg"];
|
|
95
|
+
/** borrowed-readonly — the leg's target-reading stamp, or undefined (hands-less): the visibility judge stamps its request. */
|
|
96
|
+
stampCallTarget: Prepared["stampCallTarget"];
|
|
95
97
|
/** borrowed-readonly — the run's abort controller; only `signal` (the deny door's and the stat's signal). */
|
|
96
98
|
abortController: Pick<AbortController, "signal">;
|
|
97
99
|
/** borrowed-readonly — the per-task identity (the background listing's owner). */
|
|
@@ -13,7 +13,7 @@ import { PROMPT_HASH_SALT } from "./prompt-hash-salt.js";
|
|
|
13
13
|
import { CHANGED_FILES_MTIME_EPS_MS } from "./turn-attachments.js";
|
|
14
14
|
import { thrownText } from "../thrown-value.js";
|
|
15
15
|
export function prepareTurnWiring(input) {
|
|
16
|
-
const { 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, skillGrants, callerPolicy, inheritedPolicies, persistedRuleLane, orgRuleLane, abortController, hostTaskId, taskScope, buildAssembleInputs, centerAdoptionRef, harnessRef, epochDeclaredSections, carrierReadFace, carrierWriteFace, readDenyAdditionsNormalized, preparedHolder } = input;
|
|
16
|
+
const { 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, skillGrants, callerPolicy, inheritedPolicies, persistedRuleLane, orgRuleLane, stampCallTarget, abortController, hostTaskId, taskScope, buildAssembleInputs, centerAdoptionRef, harnessRef, epochDeclaredSections, carrierReadFace, carrierWriteFace, readDenyAdditionsNormalized, preparedHolder } = input;
|
|
17
17
|
const cacheBreakDetector = deps.cacheBreakDetection === false ? undefined : new CacheBreakDetector();
|
|
18
18
|
const cacheFingerprint = cacheBreakDetector
|
|
19
19
|
? { systemPrompt: systemPromptSeat.current, tools: toolsToFingerprintInputs(harnessTools) }
|
|
@@ -109,6 +109,7 @@ export function prepareTurnWiring(input) {
|
|
|
109
109
|
inheritedPolicies,
|
|
110
110
|
...(persistedRuleLane !== undefined ? { persistedRuleLane } : {}),
|
|
111
111
|
...(orgRuleLane !== undefined ? { orgRuleLane } : {}),
|
|
112
|
+
...(stampCallTarget !== undefined ? { stampCallTarget } : {}),
|
|
112
113
|
signal: abortController.signal,
|
|
113
114
|
});
|
|
114
115
|
const changedFilesReadDenied = async (paths) => {
|
|
@@ -29,6 +29,9 @@ export interface PrepareWorkspaceRestoreInput {
|
|
|
29
29
|
* driver). Dead after this call by design (R-5): later phases read the returned
|
|
30
30
|
* `taskRootFinal`, never this spelling. */
|
|
31
31
|
taskRootInitial: string;
|
|
32
|
+
/** borrowed-readonly — where a delegated child landed against where it was asked (the execution-env phase's one
|
|
33
|
+
* judgment), reported beside the root it resolved; absent on a leg no delegation caller placed. */
|
|
34
|
+
placement?: import("./contracts.js").ChildPlacement | undefined;
|
|
32
35
|
/** borrowed-readonly — prepare's abort seat; only `.signal` is read (kept as the object so the
|
|
33
36
|
* moved body's `abortController.signal` spelling stays verbatim). */
|
|
34
37
|
abortController: {
|
|
@@ -115,6 +115,7 @@ export async function prepareWorkspaceRestore(input) {
|
|
|
115
115
|
isolated: internals.isolation === "worktree",
|
|
116
116
|
remote: workspaceEnv !== undefined &&
|
|
117
117
|
(isRemoteExecutionEnv(workspaceEnv) || workspaceEnv.hostLocalPaths === false),
|
|
118
|
+
...(input.placement !== undefined ? { placement: input.placement } : {}),
|
|
118
119
|
});
|
|
119
120
|
}
|
|
120
121
|
catch {
|
|
@@ -4,8 +4,10 @@ import { ASK_USER_QUESTION_TOOL_NAME } from "../ask-question.js";
|
|
|
4
4
|
import { CheckpointError, remainingBudgetMicroUsd } from "../checkpoint-store.js";
|
|
5
5
|
import { settledByDecider } from "../gate-outcome.js";
|
|
6
6
|
import { mintHookInvocationIdentity, resolveHookTimeoutMs, runHookSeat } from "../hooks.js";
|
|
7
|
+
import { chainPolicyOnLeg, chainTopAnchors } from "./child-tree.js";
|
|
7
8
|
import { checkToolPolicyProjection, policyCannotAnswer, refuseOutOfContractDecision } from "../tool-policy.js";
|
|
8
9
|
import { callFaceSeat, parkedCallFaceOf } from "../tool-roster.js";
|
|
10
|
+
import { readCallTarget } from "../effective-path-target.js";
|
|
9
11
|
import { inlineUntrusted } from "../untrusted-text.js";
|
|
10
12
|
import { deepJsonEqual, describeSuppliedValue } from "./decide-continuation.js";
|
|
11
13
|
import { orgVerdictBeforeClaim } from "./permission-rule-lanes.js";
|
|
@@ -110,14 +112,16 @@ export async function resumeApply(input) {
|
|
|
110
112
|
resourceSpentMicroUsd: cp.resourceLedger?.spentMicroUsd ?? 0,
|
|
111
113
|
suspendCount: cp.suspendCount ?? 0,
|
|
112
114
|
};
|
|
113
|
-
const
|
|
115
|
+
const editedCall = {
|
|
114
116
|
toolName: cp.pendingAction.toolName,
|
|
115
117
|
args: editedArgs,
|
|
116
118
|
toolCallId: cp.pendingAction.toolCallId,
|
|
117
119
|
budget: editBudget,
|
|
118
120
|
...callFaceSeat(parkedCallFaceOf(cp.pendingAction)),
|
|
119
121
|
...(cp.state.handsCwd !== undefined ? { cwd: cp.state.handsCwd } : {}),
|
|
122
|
+
...(cp.state.handsRoot !== undefined ? { root: cp.state.handsRoot } : {}),
|
|
120
123
|
};
|
|
124
|
+
const editedReq = { ...editedCall, targetReading: await readCallTarget(undefined, editedCall) };
|
|
121
125
|
const ig = cp.state.inheritedGate;
|
|
122
126
|
if (ig?.requiresParentConstraint === true) {
|
|
123
127
|
const chain = ig.constraintChain;
|
|
@@ -139,10 +143,20 @@ export async function resumeApply(input) {
|
|
|
139
143
|
const editBasePolicy = toolPolicyLocked
|
|
140
144
|
? (runner.deps.basePolicyForResumeEdit ?? runner.deps.toolPolicy)
|
|
141
145
|
: (config.basePolicyForResumeEdit ?? runner.deps.basePolicyForResumeEdit ?? config.toolPolicy ?? runner.deps.toolPolicy);
|
|
142
|
-
|
|
146
|
+
const rowLeg = { ...(typeof cp.state.handsRoot === "string" ? { root: cp.state.handsRoot } : {}), ...(typeof cp.state.handsHome === "string" ? { home: cp.state.handsHome } : {}) };
|
|
147
|
+
const asRecorded = (p) => p;
|
|
148
|
+
const installedEditBase = chainPolicyOnLeg({
|
|
149
|
+
leg: rowLeg,
|
|
150
|
+
chainTop: chainTopAnchors({ leg: rowLeg, live: internals?.inheritedGate?.pathRuleAnchors, seed: cp.state.inheritedGate?.pathRuleAnchors, placement: undefined, rebase: asRecorded }),
|
|
151
|
+
placement: undefined,
|
|
152
|
+
chain: (internals?.inheritedGate?.parentConstraints ?? []).map((c) => c.policy),
|
|
153
|
+
installations: { live: internals?.inheritedGate?.pathRuleInstallations, seed: cp.state.inheritedGate?.pathRuleInstallations },
|
|
154
|
+
rebase: asRecorded,
|
|
155
|
+
}).own(editBasePolicy);
|
|
156
|
+
if (installedEditBase !== undefined) {
|
|
143
157
|
let rechecked;
|
|
144
158
|
try {
|
|
145
|
-
rechecked = refuseOutOfContractDecision(await raceEditAbort(Promise.resolve(
|
|
159
|
+
rechecked = refuseOutOfContractDecision(await raceEditAbort(Promise.resolve(installedEditBase.check(editedReq, editSignal))));
|
|
146
160
|
}
|
|
147
161
|
catch (err) {
|
|
148
162
|
if (err instanceof CheckpointError)
|