@sema-agent/core 7.42.1 → 7.44.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 +173 -0
- package/dist/agents/send-message-tool.js +1 -0
- package/dist/agents/subagent.d.ts +3 -1
- package/dist/agents/subagent.js +5 -3
- package/dist/agents/teacher.js +1 -1
- package/dist/agents/verify.js +2 -0
- package/dist/brain/errors.d.ts +23 -2
- package/dist/brain/errors.js +26 -2
- package/dist/brain/stream-engine.d.ts +2 -1
- package/dist/brain/stream-engine.js +10 -9
- package/dist/core/allow-entry.d.ts +50 -31
- package/dist/core/allow-entry.js +100 -37
- package/dist/core/ask-origin.d.ts +16 -5
- package/dist/core/ask-origin.js +11 -3
- package/dist/core/ask-unresolvable-notice.d.ts +3 -2
- package/dist/core/ask-unresolvable-notice.js +1 -1
- package/dist/core/auto-mode.d.ts +5 -4
- package/dist/core/auto-mode.js +3 -1
- package/dist/core/checkpoint-store.d.ts +44 -20
- package/dist/core/checkpoint-store.js +10 -16
- package/dist/core/child-clamp-seats.d.ts +15 -1
- package/dist/core/child-clamp-seats.js +6 -2
- package/dist/core/classifier-unavailable-arm.d.ts +42 -23
- package/dist/core/classifier-unavailable-arm.js +14 -3
- package/dist/core/decision-receipt.js +2 -0
- package/dist/core/engine-notice.d.ts +16 -14
- package/dist/core/engine-notice.js +4 -3
- package/dist/core/gate-lanes.js +37 -29
- package/dist/core/governance-codes.d.ts +4 -3
- package/dist/core/governance-codes.js +1 -0
- package/dist/core/hooks.d.ts +6 -1
- package/dist/core/hooks.js +3 -0
- package/dist/core/memory-engine/engine.d.ts +2 -2
- package/dist/core/memory-engine/engine.js +7 -14
- package/dist/core/memory-engine/file-backend.d.ts +2 -2
- package/dist/core/memory-engine/file-backend.js +5 -7
- package/dist/core/memory-engine/layout.d.ts +37 -4
- package/dist/core/memory-engine/layout.js +34 -5
- package/dist/core/mode-policy.d.ts +5 -4
- package/dist/core/mode-policy.js +4 -0
- package/dist/core/permission-rule-consent.d.ts +3 -2
- package/dist/core/permission-rule-consent.js +25 -20
- package/dist/core/permission-rule-model.d.ts +47 -7
- package/dist/core/permission-rule-model.js +80 -6
- package/dist/core/permission-rules.d.ts +8 -2
- package/dist/core/permission-rules.js +26 -9
- package/dist/core/runner/classifier-ladder.d.ts +10 -8
- package/dist/core/runner/classifier-ladder.js +3 -1
- package/dist/core/runner/contracts.d.ts +1 -16
- package/dist/core/runner/denial-limit-arms.d.ts +25 -8
- package/dist/core/runner/denial-limit-arms.js +24 -10
- package/dist/core/runner/gate-exit.js +2 -1
- package/dist/core/runner/permission-rule-lanes.d.ts +2 -2
- package/dist/core/runner/permission-rule-lanes.js +8 -2
- package/dist/core/runner/prepare-ask-lane.d.ts +3 -0
- package/dist/core/runner/prepare-ask-lane.js +2 -1
- package/dist/core/runner/prepare-caps-and-workflow.d.ts +2 -3
- package/dist/core/runner/prepare-caps-and-workflow.js +3 -2
- package/dist/core/runner/prepare-config-doors.d.ts +3 -0
- package/dist/core/runner/prepare-config-doors.js +6 -5
- package/dist/core/runner/prepare-gate-stations.js +1 -1
- package/dist/core/runner/prepare-inherited-gate.d.ts +7 -5
- package/dist/core/runner/prepare-inherited-gate.js +5 -3
- package/dist/core/runner/prepare-park-ask.d.ts +4 -4
- package/dist/core/runner/prepare-park-ask.js +2 -4
- package/dist/core/runner/prepare-policy-chain.d.ts +7 -1
- package/dist/core/runner/prepare-policy-chain.js +59 -38
- package/dist/core/runner/prepare-project-context.js +6 -2
- package/dist/core/runner/prepare-task.js +6 -6
- package/dist/core/runner/prepare-wiring-manifest.d.ts +6 -5
- package/dist/core/runner/prepare-wiring-manifest.js +8 -9
- package/dist/core/runner/resume-checkpoint-screen.js +1 -1
- package/dist/core/runner/runtask.js +1 -5
- package/dist/core/runner/steer-admission.d.ts +10 -11
- package/dist/core/runner/steer-admission.js +6 -8
- package/dist/core/runner/stream-steer-verb.d.ts +5 -4
- package/dist/core/runner/stream-steer-verb.js +6 -8
- package/dist/core/runner/synthetic-tools.d.ts +3 -2
- package/dist/core/runner/synthetic-tools.js +1 -1
- package/dist/core/session-policy-store.d.ts +3 -3
- package/dist/core/session-policy-store.js +18 -4
- package/dist/core/skill-grant-binding.d.ts +44 -0
- package/dist/core/skill-grant-binding.js +22 -0
- package/dist/core/skill-grant.d.ts +59 -28
- package/dist/core/skill-grant.js +96 -23
- package/dist/core/steer-replay.d.ts +46 -0
- package/dist/core/steer-replay.js +22 -0
- package/dist/core/task-event.d.ts +3 -2
- package/dist/core/task-spec.d.ts +14 -1
- package/dist/core/task-stream.d.ts +12 -6
- package/dist/core/tighten-task-spec.d.ts +2 -0
- package/dist/core/tighten-task-spec.js +3 -0
- package/dist/core/tool-errors.d.ts +2 -2
- package/dist/core/tool-name-aliases.d.ts +35 -5
- package/dist/core/tool-name-aliases.js +29 -4
- package/dist/core/tool-policy.d.ts +10 -0
- package/dist/core/tool-policy.js +9 -2
- package/dist/core/tool-spec.d.ts +7 -0
- package/dist/core/types.d.ts +2 -2
- package/dist/core/types.js +1 -1
- package/dist/core/wiring-manifest.d.ts +56 -14
- package/dist/core/wiring-manifest.js +29 -4
- package/dist/index.d.ts +6 -4
- package/dist/index.js +5 -4
- package/dist/orchestration/run-workflow-tool.d.ts +4 -0
- package/dist/orchestration/run-workflow-tool.js +1 -1
- package/dist/orchestration/workflow-primitives.d.ts +3 -1
- package/dist/orchestration/workflow-primitives.js +6 -6
- package/dist/orchestration/workflow-types.d.ts +5 -0
- package/dist/orchestration/workflow.d.ts +3 -2
- package/dist/orchestration/workflow.js +14 -6
- package/package.json +1 -1
- package/test/export-surface.snapshot.json +21 -5
- package/wire-changes/core@7.43.0.json +985 -0
- package/wire-changes/core@7.44.0.json +469 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { persistedRuleMandateOf, ruleClearanceOf } from "../ask-origin.js";
|
|
2
2
|
import {} from "../hooks.js";
|
|
3
|
-
import { adjudicatePersistedPathRules, adjudicatePersistedRules, callPathFaceOf, faceAskSpeaksFor, laneToolNamesOf, ruleToolGrammarOf, segmentCoverageOf, suggestRulesForCommand } from "../permission-rule-model.js";
|
|
3
|
+
import { adjudicatePersistedNameRules, adjudicatePersistedPathRules, adjudicatePersistedRules, callPathFaceOf, faceAskSpeaksFor, laneToolNamesOf, nameRuleSubjectOf, ruleToolGrammarOf, segmentCoverageOf, suggestRuleForName, suggestRulesForCommand } from "../permission-rule-model.js";
|
|
4
4
|
import { isAbsolutePathForm } from "../../tools/fs/safety.js";
|
|
5
5
|
import { effectivePathTargetOf } from "../effective-path-target.js";
|
|
6
6
|
import { declaredPathTargetOf, protectivePathTargetOf } from "../tool-registry.js";
|
|
@@ -155,6 +155,8 @@ export function createPermissionRuleLanes(cfg) {
|
|
|
155
155
|
const liveCwd = cfg.liveCwd();
|
|
156
156
|
if (grammar === "path")
|
|
157
157
|
return pathRuleLaneAnswer(table, req, { root: cfg.root, sessionId: cfg.sessionId, liveCwd, home: cfg.home });
|
|
158
|
+
if (grammar === "name")
|
|
159
|
+
return persistedRuleAnswerOf(adjudicatePersistedNameRules(table, { tool: req.toolName, name: nameRuleSubjectOf(req.toolName, req.args), cwd: cfg.root, sessionId: cfg.sessionId }));
|
|
158
160
|
const command = req.args?.command;
|
|
159
161
|
if (typeof command !== "string")
|
|
160
162
|
return undefined;
|
|
@@ -172,7 +174,7 @@ export function createPermissionRuleLanes(cfg) {
|
|
|
172
174
|
export function createRuleOffersOf(cfg) {
|
|
173
175
|
return (call, args, ask) => {
|
|
174
176
|
const toolName = wireOf("offer.laneTool", call);
|
|
175
|
-
if (!cfg.laneArmed || toolName !== PERSISTED_RULE_TOOL)
|
|
177
|
+
if (!cfg.laneArmed || (toolName !== PERSISTED_RULE_TOOL && ruleToolGrammarOf(toolName) !== "name"))
|
|
176
178
|
return {};
|
|
177
179
|
if ((cfg.principal === undefined || cfg.principal === "") && !cfg.localOwnerDeclared)
|
|
178
180
|
return {};
|
|
@@ -184,6 +186,10 @@ export function createRuleOffersOf(cfg) {
|
|
|
184
186
|
}).word;
|
|
185
187
|
if (closedDoor !== undefined)
|
|
186
188
|
return { ruleOffersAbsence: closedDoor };
|
|
189
|
+
if (ruleToolGrammarOf(toolName) === "name") {
|
|
190
|
+
const offer = suggestRuleForName(toolName, nameRuleSubjectOf(toolName, args) ?? "");
|
|
191
|
+
return offer !== undefined ? { ruleOffers: [offer] } : { ruleOffersAbsence: "lane_cannot_speak" };
|
|
192
|
+
}
|
|
187
193
|
const command = args?.command;
|
|
188
194
|
if (typeof command !== "string")
|
|
189
195
|
return { ruleOffersAbsence: "lane_cannot_speak" };
|
|
@@ -6,6 +6,7 @@ import { type OnAsk, type ToolCallRequest, type ToolPolicy } from "../tool-polic
|
|
|
6
6
|
import type { RunnerDeps, TaskSpec } from "../types.js";
|
|
7
7
|
import type { CwdRef } from "../../tools/fs/fs-shared.js";
|
|
8
8
|
import type { AskLane, Prepared } from "./contracts.js";
|
|
9
|
+
import type { GrantBindingOf } from "../skill-grant-binding.js";
|
|
9
10
|
import { consumeInheritedAskGrant } from "./inherited-ask-grants.js";
|
|
10
11
|
import { type GrantReadRoot } from "./read-root-grant.js";
|
|
11
12
|
import type { createRuleOffersOf } from "./permission-rule-lanes.js";
|
|
@@ -49,6 +50,8 @@ export interface PrepareAskLaneInput {
|
|
|
49
50
|
now: () => number;
|
|
50
51
|
/** borrowed-readonly — the policy-chain phase's rule-offer factory (the suggestion members the ask mint threads). */
|
|
51
52
|
ruleOffersOf: ReturnType<typeof createRuleOffersOf>;
|
|
53
|
+
/** borrowed-readonly — the policy-chain phase's Skill-card binding factory (`boundGrants` / `boundGrantDigest` on the ask). */
|
|
54
|
+
grantBindingOf: GrantBindingOf;
|
|
52
55
|
/** borrowed-readonly — the policy-chain phase's Runner-filled source identity (one factory, every ask mint site). */
|
|
53
56
|
askSourceIdentity: () => {
|
|
54
57
|
principal?: string;
|
|
@@ -59,7 +59,7 @@ function resolveApprovalPreview(tools, toolName, args) {
|
|
|
59
59
|
}
|
|
60
60
|
}
|
|
61
61
|
export function prepareAskLane(input) {
|
|
62
|
-
const { gateMachineryActive, abortController, effectivePolicy, budgetSnapshot, handsCwdRef, advertisedWritableDirs, tools, inheritedUnavailableAsks, inheritedAskGrants, onAsk, humanReviewRef, now, ruleOffersOf, askSourceIdentity, riskAxesOf, autoModeDenialTracking, spec, deps, sessionId, runId, hooks, hookTimeoutMs, notifyOwnHookCrash, grantReadRoot } = input;
|
|
62
|
+
const { gateMachineryActive, abortController, effectivePolicy, budgetSnapshot, handsCwdRef, advertisedWritableDirs, tools, inheritedUnavailableAsks, inheritedAskGrants, onAsk, humanReviewRef, now, ruleOffersOf, grantBindingOf, askSourceIdentity, riskAxesOf, autoModeDenialTracking, spec, deps, sessionId, runId, hooks, hookTimeoutMs, notifyOwnHookCrash, grantReadRoot } = input;
|
|
63
63
|
if (!gateMachineryActive)
|
|
64
64
|
return { askLane: undefined };
|
|
65
65
|
const composedCallSignal = (callSignal) => composeCallSignal(abortController.signal, callSignal);
|
|
@@ -98,6 +98,7 @@ export function prepareAskLane(input) {
|
|
|
98
98
|
return { ...(p.preview !== undefined ? { preview: p.preview } : {}), ...(p.withheld !== undefined ? { previewWithheld: p.withheld } : {}) };
|
|
99
99
|
})(),
|
|
100
100
|
...ruleOffersOf(req, req.args, decision.action === "ask" ? decision : undefined),
|
|
101
|
+
...grantBindingOf(req, req.args),
|
|
101
102
|
...cardDisclosureOf(decision, `approval required for "${req.toolName}"`),
|
|
102
103
|
...askSourceIdentity(),
|
|
103
104
|
...riskAxesOf(req),
|
|
@@ -30,7 +30,6 @@ import { type CheckpointSeat } from "../checkpoint-seat.js";
|
|
|
30
30
|
import { type ComplianceCapability } from "../compliance.js";
|
|
31
31
|
import type { LockedPreflight } from "../locked-config.js";
|
|
32
32
|
import type { StoredSession } from "../session.js";
|
|
33
|
-
import type { OnAsk } from "../tool-policy.js";
|
|
34
33
|
import type { RunnerDeps, RuntimeCaps, TaskEvent, TaskSpec, ToolExecuteContext } from "../types.js";
|
|
35
34
|
import type { AutoModeArmFact } from "../wiring-manifest.js";
|
|
36
35
|
import type { AssertAllKeysHandled } from "../ask-origin.js";
|
|
@@ -88,8 +87,8 @@ export interface PrepareCapsAndWorkflowInput {
|
|
|
88
87
|
harnessRef: {
|
|
89
88
|
current?: AgentHarness;
|
|
90
89
|
};
|
|
91
|
-
/** borrowed-readonly — the
|
|
92
|
-
|
|
90
|
+
/** borrowed-readonly — the run's approval seat as the config doors froze it (the Workflow mount's parentOnAsk / parentApprovalReach). */
|
|
91
|
+
askSeat: import("../wiring-manifest.js").AskSeat;
|
|
93
92
|
/** borrowed-readonly — the parent SPEC seat the children inherit (minted once by the inherited-gate phase; the Workflow mount's dep, the same value the delegation ctx carries). */ parentSpecSeat: ParentSpecSeat;
|
|
94
93
|
/** borrowed-readonly — the ONE read-face carrier expression (the Workflow mount's parentReadFace getter calls it). */
|
|
95
94
|
carrierReadFace: () => ContainmentFace | undefined;
|
|
@@ -114,7 +114,7 @@ function autoModeArmReasonOf(intent, facePresent, caps, capsFaulted) {
|
|
|
114
114
|
return { armed: true, reason: "armed" };
|
|
115
115
|
}
|
|
116
116
|
export async function prepareCapsAndWorkflow(input) {
|
|
117
|
-
const { spec, deps, parentSpecSeat, checkpointSeat, internals, session, sessionId, runId, hostTaskId, taskScope, taskRootFinal, model, thinking, lockedPreflight, toolEffects, toolFaceSnapshot, promptProfile, resolvedInteractionPosture, harnessRef,
|
|
117
|
+
const { spec, deps, parentSpecSeat, checkpointSeat, internals, session, sessionId, runId, hostTaskId, taskScope, taskRootFinal, model, thinking, lockedPreflight, toolEffects, toolFaceSnapshot, promptProfile, resolvedInteractionPosture, harnessRef, askSeat, carrierReadFace, carrierWriteFace, forwardEvent, inheritedGateForChildren, enrichSpecToolCtx, maybeOffload, requestReview, enterPlanMode, permissionMode, readDenyEntries, peerLaneActive, peerSendMessageBuiltIn, runnerSelf } = input;
|
|
118
118
|
const roster = new RosterBuilder(toolEffects);
|
|
119
119
|
for (const t of spec.tools ?? []) {
|
|
120
120
|
const mounted = mountCallerTool(t);
|
|
@@ -326,7 +326,8 @@ export async function prepareCapsAndWorkflow(input) {
|
|
|
326
326
|
return model === undefined ? undefined : { model, ...(typeof ref === "string" ? { modelRef: ref } : {}) };
|
|
327
327
|
},
|
|
328
328
|
...(spec.getApiKeyAndHeaders !== undefined ? { parentGetApiKeyAndHeaders: spec.getApiKeyAndHeaders } : {}),
|
|
329
|
-
...(
|
|
329
|
+
...(askSeat.value !== undefined ? { parentOnAsk: askSeat.value } : {}),
|
|
330
|
+
...(askSeat.reach !== undefined ? { parentApprovalReach: askSeat.reach } : {}),
|
|
330
331
|
...(spec.durableApproval !== undefined ? { parentDurableApproval: { ...spec.durableApproval } } : {}),
|
|
331
332
|
...(internals?.workflowParkedResume !== undefined
|
|
332
333
|
? { parkedResume: (resumeFromRunId) => {
|
|
@@ -29,6 +29,7 @@ import { type ResolvedSkillListingBudget } from "../skill-listing-budget.js";
|
|
|
29
29
|
import type { SessionStore } from "../session.js";
|
|
30
30
|
import type { RunnerDeps, TaskLimits, TaskSpec } from "../types.js";
|
|
31
31
|
import { type UsageWindow } from "../usage-window-store.js";
|
|
32
|
+
import { type AskSeat } from "../wiring-manifest.js";
|
|
32
33
|
import type { PrepareResume, RunInternals, ToolFaceSnapshot } from "./contracts.js";
|
|
33
34
|
export declare function limitConfigError(code: string, message: string): Error & {
|
|
34
35
|
code?: string;
|
|
@@ -147,6 +148,8 @@ export interface PrepareConfigDoorsResult {
|
|
|
147
148
|
/** owned — the resolved interaction posture (spec > spawning run > deployment); the
|
|
148
149
|
* AskUserQuestion mount and the child-ctx injection read this same value. */
|
|
149
150
|
resolvedInteractionPosture: "interactive" | "headless" | undefined;
|
|
151
|
+
/** owned, frozen — the run's approval seat ({@link resolveAskSeat}), the one read of the seats; later phases read only this. */
|
|
152
|
+
askSeat: AskSeat;
|
|
150
153
|
/** owned — the validated/resolved microCompact knob ({@link resolveMicroCompactKnob}
|
|
151
154
|
* for the door + placement reasoning). The per-run state builder consumes exactly these values —
|
|
152
155
|
* the deps bag is never re-read after this door. */
|
|
@@ -12,7 +12,7 @@ import { resolveSkillListingBudget } from "../skill-listing-budget.js";
|
|
|
12
12
|
import { describeRejectedValue } from "../tool-search-setting.js";
|
|
13
13
|
import { applyToolModelGate, assertRestoreGatedToolsValue, modelIdTail } from "../tool-model-gate.js";
|
|
14
14
|
import { resolveUsageWindows } from "../usage-window-store.js";
|
|
15
|
-
import { deriveAskEffective,
|
|
15
|
+
import { deriveAskEffective, resolveAskSeat, resolveQuestionSeam } from "../wiring-manifest.js";
|
|
16
16
|
import { assertPeerPresenceValue } from "../../agents/peer-directory.js";
|
|
17
17
|
import { TOTAL_TOKENS_REMINDER_MODES } from "./turn-attachments.js";
|
|
18
18
|
const TASK_LIMIT_KEY_DICT = {
|
|
@@ -286,6 +286,7 @@ export function prepareConfigDoors(input) {
|
|
|
286
286
|
],
|
|
287
287
|
});
|
|
288
288
|
const resolvedInteractionPosture = spec.interactionPosture ?? internals?.parentInteractionPosture ?? deps.interactionPosture;
|
|
289
|
+
const askSeat = resolveAskSeat(spec, deps);
|
|
289
290
|
{
|
|
290
291
|
const interactionPosture = resolvedInteractionPosture;
|
|
291
292
|
const discloseInteractionPostureRefusal = (err) => {
|
|
@@ -303,8 +304,7 @@ export function prepareConfigDoors(input) {
|
|
|
303
304
|
throw e;
|
|
304
305
|
}
|
|
305
306
|
if (interactionPosture === "interactive") {
|
|
306
|
-
const
|
|
307
|
-
const humanReachable = deriveAskEffective(askDoor.form, "unresolved") === "human_reachable";
|
|
307
|
+
const humanReachable = deriveAskEffective(askSeat.form, "unresolved") === "human_reachable";
|
|
308
308
|
const questionDoor = resolveQuestionSeam(spec, deps);
|
|
309
309
|
const strippedByEngine = internals?.questionFaceStripped === true;
|
|
310
310
|
if (spec.interactiveTools === false) {
|
|
@@ -318,9 +318,9 @@ export function prepareConfigDoors(input) {
|
|
|
318
318
|
if (!humanReachable || !(questionDoor.wired || strippedByEngine)) {
|
|
319
319
|
const missing = [];
|
|
320
320
|
if (!humanReachable) {
|
|
321
|
-
missing.push(
|
|
321
|
+
missing.push(askSeat.form === "declared_none" ? 'this run declares approvalReach: "none" — nobody on it can be asked to approve' : askSeat.form === "absent"
|
|
322
322
|
? "no onAsk approver is wired (spec.onAsk ?? deps.onAsk is absent — asks would auto-deny or park)"
|
|
323
|
-
: `the resolved onAsk seat is the blanket policy "${
|
|
323
|
+
: `the resolved onAsk seat is the blanket policy "${askSeat.form}" (${askSeat.provenance ?? "?"}) — a policy setting is not a reachable human`);
|
|
324
324
|
}
|
|
325
325
|
if (!questionDoor.wired && !strippedByEngine) {
|
|
326
326
|
missing.push("no content-question channel (spec.onQuestion ?? deps.onQuestion is absent, and this leg is not an engine-stripped background lane)");
|
|
@@ -433,6 +433,7 @@ export function prepareConfigDoors(input) {
|
|
|
433
433
|
promptProfile,
|
|
434
434
|
lockedPreflight,
|
|
435
435
|
resolvedInteractionPosture,
|
|
436
|
+
askSeat,
|
|
436
437
|
microCompactKnob,
|
|
437
438
|
resolvedRole,
|
|
438
439
|
model,
|
|
@@ -137,7 +137,7 @@ export function prepareGateStations(input) {
|
|
|
137
137
|
onHookError: notifyHookError,
|
|
138
138
|
shellGated: tierSeat?.shellGated(shellGatedTools, toolMarkSources) === true,
|
|
139
139
|
...(autoModeDecider.current !== undefined ? { autoMode: { decider: autoModeDecider.current, ...(autoModeDenialTracking.current !== undefined ? { denialTracking: autoModeDenialTracking.current } : {}), unavailable: classifierUnavailableSeat({ station: "leg", ...(autoModeDecider.current.timeoutMs !== undefined ? { budgetMs: autoModeDecider.current.timeoutMs } : {}), approvalSeat: askReachesPerson(askRoute), onNotice: deps.onNotice, sessionId, runId }) } } : {}),
|
|
140
|
-
permissionMode: () => permissionMode.current,
|
|
140
|
+
permissionMode: () => permissionMode.current, askSeatForm: askRoute.form,
|
|
141
141
|
...(markSources.size > 0 ? { toolMarkSources: markSources } : {}),
|
|
142
142
|
...seatInputsFor(e.toolName, wireOf("gate.skillActivationSeat", call)),
|
|
143
143
|
...(mountedToolRequiresUserInteraction(tools, e.toolName) ? { requiresUserInteraction: true } : {}),
|
|
@@ -50,19 +50,21 @@ import { type SkillGrantTable } from "../skill-grant.js";
|
|
|
50
50
|
import type { InheritedGate, Prepared, PrepareResume, RunInternals, StopForDenialLimit, ToolFaceSnapshot, WriteFaceSeat } from "./contracts.js";
|
|
51
51
|
export interface PrepareInheritedGateInput {
|
|
52
52
|
/** borrowed-readonly — the REBOUND spec. Read: `shellGate` (the own doctrine the chain fold tightens), `durableApproval`
|
|
53
|
-
* (the mandate tests + the children's copy), `
|
|
53
|
+
* (the mandate tests + the children's copy), `onQuestion` (the frozen question seat), `handsReadOnly` / `interactiveTools`
|
|
54
54
|
* / `oneShot` / `clientContext` / `principal` / `additionalDirectories` / `additionalReadDirectories` / `envFacts` /
|
|
55
55
|
* `memoryPersistenceCapable` / `getApiKeyAndHeaders` / `backgroundScope` / `enablePlanMode` (the ctx enrichment's
|
|
56
56
|
* trusted seats). Never mutated. */
|
|
57
|
-
spec: Pick<TaskSpec, "shellGate" | "durableApproval" | "
|
|
57
|
+
spec: Pick<TaskSpec, "shellGate" | "durableApproval" | "onQuestion" | "handsReadOnly" | "interactiveTools" | "oneShot" | "clientContext" | "principal" | "additionalDirectories" | "additionalReadDirectories" | "envFacts" | "memoryPersistenceCapable" | "getApiKeyAndHeaders" | "backgroundScope" | "enablePlanMode" | "excludeAllTools">;
|
|
58
58
|
/** borrowed-readonly — the seat this run hands its children (`checkpointSeatOf`, minted once by the driver after the config doors): the ctx's `checkpointStoreForChildren`, absent when the run has no seat. */
|
|
59
59
|
checkpointSeat: import("../checkpoint-seat.js").CheckpointSeat | undefined;
|
|
60
60
|
/** borrowed-readonly — the deployment seats: `autoMode.denialLimit` (the rebuilt trackers' bounds), `memoryScopeAdmission` /
|
|
61
61
|
* `deploymentMemoryScopes` / `compliancePostureResolver` (the governed-provenance bit), `onError` (the screening-face crash
|
|
62
62
|
* lane), `onNotice` (the stop seat's notice), `executionEnv` (the hook-env identity predicate), `delegationEntryCaps` (resolved
|
|
63
|
-
* and validated once here), `rosterStore` / `onBackgroundChildEvent` (ctx seats), `
|
|
64
|
-
* frozen
|
|
65
|
-
deps: Pick<RunnerDeps, "autoMode" | "memoryScopeAdmission" | "deploymentMemoryScopes" | "compliancePostureResolver" | "onError" | "onNotice" | "executionEnv" | "delegationEntryCaps" | "rosterStore" | "onBackgroundChildEvent" | "
|
|
63
|
+
* and validated once here), `rosterStore` / `onBackgroundChildEvent` (ctx seats), `onQuestion` (the deps half of the
|
|
64
|
+
* frozen question seat). */
|
|
65
|
+
deps: Pick<RunnerDeps, "autoMode" | "memoryScopeAdmission" | "deploymentMemoryScopes" | "compliancePostureResolver" | "onError" | "onNotice" | "executionEnv" | "delegationEntryCaps" | "rosterStore" | "onBackgroundChildEvent" | "onQuestion">;
|
|
66
|
+
/** borrowed-readonly — the run's approval seat as the config doors froze it: the frozen approver, and this leg's chain view. */
|
|
67
|
+
askSeat: import("../wiring-manifest.js").AskSeat;
|
|
66
68
|
/** borrowed-readonly — the trusted spawn-side channel: `inheritedGate` (the LIVE half of the chain fold), `ownOrgAdmissionRef`
|
|
67
69
|
* (the same-session continuation's freeze), `delegationProvenance` (the F-012 stamp), and the identity / peer / notification
|
|
68
70
|
* seats the ctx enrichment forwards. Never mutated. */
|
|
@@ -13,7 +13,7 @@ import { frozenSkillGrants } from "../skill-grant.js";
|
|
|
13
13
|
import { attachRebuiltDenialTrackers, createDenialLimitStop } from "./denial-limit-arms.js";
|
|
14
14
|
import { asThrownError } from "../thrown-value.js";
|
|
15
15
|
export function prepareInheritedGate(input) {
|
|
16
|
-
const { spec, deps, 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;
|
|
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
17
|
const liveInheritedGate = internals?.inheritedGate;
|
|
18
18
|
const seedInheritedGate = resume?.seed.inheritedGate;
|
|
19
19
|
const inheritedAncestorRules = (() => {
|
|
@@ -35,7 +35,8 @@ export function prepareInheritedGate(input) {
|
|
|
35
35
|
})();
|
|
36
36
|
const modeSeed = recordedModeSeed(seedInheritedGate);
|
|
37
37
|
const inheritedShellGate = liveInheritedGate?.shellGate ?? modeSeed.shellGate;
|
|
38
|
-
const
|
|
38
|
+
const chainView = askSeat.reach === "none" ? liveInheritedGate?.parentConstraints?.map((pc) => (typeof pc.onAsk === "function" ? ((({ onAsk: _person, ...rest }) => rest)(pc)) : pc)) : liveInheritedGate?.parentConstraints;
|
|
39
|
+
const inheritedParentConstraints = attachRebuiltDenialTrackers(chainView, deps.autoMode?.denialLimit);
|
|
39
40
|
const parentSeat = liveInheritedGate?.permissionModeCeiling;
|
|
40
41
|
const ceiling = parentSeat ?? liveInheritedGate?.permissionMode;
|
|
41
42
|
const announceModeFold = (receipt) => {
|
|
@@ -113,7 +114,7 @@ export function prepareInheritedGate(input) {
|
|
|
113
114
|
const f012CheckpointState = () => (inheritedParentConstraints?.length ?? 0) > 0 ||
|
|
114
115
|
seedInheritedGate?.constraintChain !== undefined ||
|
|
115
116
|
internals?.delegationProvenance !== undefined;
|
|
116
|
-
const frozenOnAsk =
|
|
117
|
+
const frozenOnAsk = askSeat.value;
|
|
117
118
|
const hookEnvSource = (ownedEnv ?? deps.executionEnv) != null ? executionEnv : undefined;
|
|
118
119
|
const notifyOwnHookCrash = (err) => {
|
|
119
120
|
try {
|
|
@@ -213,6 +214,7 @@ export function prepareInheritedGate(input) {
|
|
|
213
214
|
thinkingLevel: harnessRef.current?.getThinkingLevel(),
|
|
214
215
|
principal: spec.principal,
|
|
215
216
|
...(frozenOnAsk !== undefined ? { onAsk: frozenOnAsk } : {}),
|
|
217
|
+
...(askSeat.reach !== undefined ? { approvalReach: askSeat.reach } : {}),
|
|
216
218
|
...(frozenOnQuestion !== undefined ? { onQuestion: frozenOnQuestion } : {}),
|
|
217
219
|
...(spec.handsReadOnly === true ? { handsReadOnly: true } : {}),
|
|
218
220
|
...(carrierReadFace() === "roots" ? { readFace: "roots" } : {}),
|
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
import type { AgentHarness, AgentMessage, AgentTool, ExecutionEnv } from "../../internal/harness.js";
|
|
23
23
|
import { type OnQuestion } from "../ask-question.js";
|
|
24
24
|
import { type CheckpointStore } from "../checkpoint-store.js";
|
|
25
|
+
import type { GrantBindingOf } from "../skill-grant-binding.js";
|
|
25
26
|
import type { SessionStore } from "../session.js";
|
|
26
27
|
import { type OnAsk, type ToolCallRequest, type ToolPolicy } from "../tool-policy.js";
|
|
27
28
|
import { type ToolResultStore } from "../tool-result-store.js";
|
|
@@ -32,7 +33,6 @@ import { type ContentAskBinding } from "./content-ask-bindings.js";
|
|
|
32
33
|
import type { AskLane, IrreversibilityTier, ParkAsk, Prepared, SuspendSaga } from "./contracts.js";
|
|
33
34
|
import type { createRuleOffersOf } from "./permission-rule-lanes.js";
|
|
34
35
|
import { type ToolRosterDeltaSeat } from "../tool-roster.js";
|
|
35
|
-
import { type SkillGrantSource } from "../skill-grant.js";
|
|
36
36
|
export interface PrepareParkAskInput {
|
|
37
37
|
/** borrowed-readonly — the in-stream ask lane, or undefined when the gate machinery is inactive (then both closures are
|
|
38
38
|
* absent). Read: `composedCallSignal` (the fence and the delivery race), `approvalPreviewOf` (the row's preview). */
|
|
@@ -141,9 +141,9 @@ export interface PrepareParkAskInput {
|
|
|
141
141
|
orgAdmissionCheckpointState: () => boolean;
|
|
142
142
|
/** borrowed-readonly — the policy-chain phase's rule-offer factory (the row's suggestion members). */
|
|
143
143
|
ruleOffersOf: ReturnType<typeof createRuleOffersOf>;
|
|
144
|
-
/** borrowed-readonly — the
|
|
145
|
-
*
|
|
146
|
-
|
|
144
|
+
/** borrowed-readonly — the policy-chain phase's Skill-card binding factory: a parked `Skill` call's row carries the named skill and
|
|
145
|
+
* its lists (`boundGrants`) and their hash (`boundGrantDigest`) from it, as the live ask does. */
|
|
146
|
+
grantBindingOf: GrantBindingOf;
|
|
147
147
|
/** borrowed-readonly — the injectable wall clock (the row's `suspendedAt`). */
|
|
148
148
|
now: () => number;
|
|
149
149
|
/** borrowed-readonly — the per-task human-review accumulator; snapshotted onto the row (never written here). */
|
|
@@ -17,8 +17,6 @@ import { DEFAULT_UNATTENDED_APPROVAL_TTL_MS, publishCommittedSuspend, sanitizedT
|
|
|
17
17
|
import { remoteEnvFailureNote } from "./remote-env-retry.js";
|
|
18
18
|
import { callFaceSeat, parkedToolIdentity, parkedToolFace } from "../tool-roster.js";
|
|
19
19
|
import { seatOf, wireOf } from "../tool-name-readings.js";
|
|
20
|
-
import { skillCallGrantDigest } from "../skill-grant.js";
|
|
21
|
-
import { SKILL_TOOL_NAME } from "./synthetic-tools.js";
|
|
22
20
|
class ParkRefusal extends Error {
|
|
23
21
|
constructor(message, options) {
|
|
24
22
|
super(message, options);
|
|
@@ -29,7 +27,7 @@ const wordlessDemand = (toolName) => {
|
|
|
29
27
|
throw new Error(`a real-approval demand for "${toolName}" reached the park with no origin word — the origin stamp precedes every park`);
|
|
30
28
|
};
|
|
31
29
|
export function prepareParkAsk(input) {
|
|
32
|
-
const { askLane, saga, spec, deps, sessionId, checkpointStore, toolRosterDeltas, parkLaneArmed, contentAskRoutable, liveQuestionFace, mountedQuestionTool, contentAskBindings, lateStrandedAnswers, discloseStrandedAnswers, onAsk, runtimeCaps, inheritedUnavailableAsks, basePolicyForResumeEdit, budgetSnapshot, handsCwdRef, advertisedWritableDirs, offloadStore, ownedEnv, incompleteSuspendAdapter, session, sessions, suspendChainBase, maxSuspends, remoteEnvFailures, shellGatedTools, irreversibilityTier, toolMarkSources, effectiveShellGate, durableApproval, priorLedger, liveSpendRef, resourceTotal, faceCheckpointState, f012CheckpointState, orgAdmissionCheckpointState, ruleOffersOf,
|
|
30
|
+
const { askLane, saga, spec, deps, sessionId, checkpointStore, toolRosterDeltas, parkLaneArmed, contentAskRoutable, liveQuestionFace, mountedQuestionTool, contentAskBindings, lateStrandedAnswers, discloseStrandedAnswers, onAsk, runtimeCaps, inheritedUnavailableAsks, basePolicyForResumeEdit, budgetSnapshot, handsCwdRef, 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;
|
|
33
31
|
if (askLane === undefined || saga === undefined)
|
|
34
32
|
return { parkAsk: undefined };
|
|
35
33
|
const { composedCallSignal, approvalPreviewOf } = askLane;
|
|
@@ -318,7 +316,7 @@ export function prepareParkAsk(input) {
|
|
|
318
316
|
...askCarryRowMembers(carry),
|
|
319
317
|
...ruleOffersOf(req, parkedArgs, clearanceFacts),
|
|
320
318
|
boundInputHash: boundInputHashOf(parkedArgs),
|
|
321
|
-
...(
|
|
319
|
+
...grantBindingOf(req, parkedArgs),
|
|
322
320
|
batchToolCallIds,
|
|
323
321
|
completedCallIds,
|
|
324
322
|
}),
|
|
@@ -30,7 +30,8 @@ import { type OnAsk, type ToolPolicy } from "../tool-policy.js";
|
|
|
30
30
|
import type { RunnerDeps, RuntimeCaps, TaskSpec, ToolEffect } from "../types.js";
|
|
31
31
|
import type { CwdRef } from "../../tools/fs/fs-shared.js";
|
|
32
32
|
import type { ReadDenyMatcher } from "../../tools/fs/read-deny.js";
|
|
33
|
-
import type
|
|
33
|
+
import { type SkillGrantLane, type SkillGrantSource, type SkillGrantTable } from "../skill-grant.js";
|
|
34
|
+
import type { GrantBindingOf } from "../skill-grant-binding.js";
|
|
34
35
|
import { type AllowEntryLane, type AllowEntryTable } from "../allow-entry.js";
|
|
35
36
|
import type { InheritedGate, IrreversibilityTier, PrepareResume, RunInternals, StopForDenialLimit } from "./contracts.js";
|
|
36
37
|
import { type Arbitration } from "../ask-origin.js";
|
|
@@ -122,6 +123,8 @@ export interface PreparePolicyChainInput {
|
|
|
122
123
|
/** borrowed-readonly — the run's skill grant table; this phase binds its lane to the call facts the person's rule lane
|
|
123
124
|
* reads (root, session, live cwd, the execution environment's home). Not written here. */
|
|
124
125
|
skillGrants: SkillGrantTable;
|
|
126
|
+
/** borrowed-readonly — the loaded skills (the table the `Skill` tool activates from); {@link PreparePolicyChainResult.grantBindingOf} reads them. */
|
|
127
|
+
skillSpecs: readonly SkillGrantSource[];
|
|
125
128
|
/** borrowed-readonly — the request's and the deployment's allow-entry tables (prepare seeded them); this phase binds
|
|
126
129
|
* their lanes to the same call facts. Not written here. */
|
|
127
130
|
allowedToolTables: {
|
|
@@ -218,6 +221,9 @@ export interface PreparePolicyChainResult {
|
|
|
218
221
|
};
|
|
219
222
|
/** owned — the ONE rule-offer factory for all five ask-mint sites. */
|
|
220
223
|
ruleOffersOf: ReturnType<typeof createRuleOffersOf>;
|
|
224
|
+
/** owned — the ONE Skill-card binding factory for the same five sites: a call to the engine's `Skill` tool carries the skill and
|
|
225
|
+
* its two lists (`boundGrants`) and their hash (`boundGrantDigest`) on the live ask, an ancestor's and the parked row alike. */
|
|
226
|
+
grantBindingOf: GrantBindingOf;
|
|
221
227
|
/** owned — the personal permission-rule lane, or undefined. */
|
|
222
228
|
permissionRuleLane: PermissionRuleLanes["personal"];
|
|
223
229
|
/** owned — the org permission-rule lane (`Prepared.permissionRuleOrg`), or undefined. */
|
|
@@ -7,14 +7,16 @@ import { assertHookSeatsCallable } from "../hook-seats.js";
|
|
|
7
7
|
import { isNamespacedCoveringRuleName, namespacedRuleNameCovers } from "../permission-rules.js";
|
|
8
8
|
import { isIsolated } from "../remote-env.js";
|
|
9
9
|
import { askApproverIdentity, carryEngineAttestations, carryPrecedingSettlement, checkToolPolicyProjection, combinePolicies, createTranscriptIntegrityPolicy, createUnverifiableDeletePolicy, durableParkOptInDeclared, isLiveApproverSeat, refuseOutOfContractDecision, resolveAsk, toolPolicyNameSets, wrapToolPolicy, attestAskUnresolvableCause } from "../tool-policy.js";
|
|
10
|
-
import { judgeRuleToolName } from "../tool-name-aliases.js";
|
|
10
|
+
import { judgeRuleToolName, mountedToolNames } from "../tool-name-aliases.js";
|
|
11
11
|
import { NAMESPACED_NAME_SHAPES } from "../protocol-table.js";
|
|
12
12
|
import { emitTrace } from "../trace.js";
|
|
13
|
+
import { skillGrantBindingMembers } from "../skill-grant.js";
|
|
14
|
+
import { SKILL_TOOL_NAME } from "./synthetic-tools.js";
|
|
13
15
|
import { autoStrippedRule, cardDisclosureOf } from "../allow-entry.js";
|
|
14
16
|
import { arbitrateByMode, askClassMembersOf, askMandateMember } from "../ask-origin.js";
|
|
15
17
|
import { createModeGatePolicy, mountedToolDeclaresReadOnly } from "../mode-policy.js";
|
|
16
18
|
const ancestorFacts = (ask) => ({ ...(ask ?? {}), ancestorResolved: true });
|
|
17
|
-
import { headlessDenyAtFold, headlessDenyAtRecheck, INHERITED_STATION_FACTS, inheritedAskCarry, inheritedAskFallbackMessage, judgeInheritedClassifier, lateAskSettlementObserver, settleDenialLimitFallback } from "./denial-limit-arms.js";
|
|
19
|
+
import { headlessDenyAtFold, headlessDenyAtRecheck, INHERITED_STATION_FACTS, inheritedAskCarry, inheritedAskFallbackMessage, judgeInheritedClassifier, lateAskSettlementObserver, resolveInheritedAsk, settleDenialLimitFallback } from "./denial-limit-arms.js";
|
|
18
20
|
import { settleReadRootGrant } from "./read-root-grant.js";
|
|
19
21
|
import { askGrantShapeOf } from "./inherited-ask-grants.js";
|
|
20
22
|
import { createPermissionRuleLanes, inheritedAskRuleEvidence, createRuleOffersOf } from "./permission-rule-lanes.js";
|
|
@@ -22,7 +24,7 @@ import { createLiveSessionRules, createSessionRulePolicy } from "./session-rule-
|
|
|
22
24
|
import { thrownText } from "../thrown-value.js";
|
|
23
25
|
import { heldBy, heldValues, seatOf, wireOf } from "../tool-name-readings.js";
|
|
24
26
|
export async function preparePolicyChain(input) {
|
|
25
|
-
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, allowedToolTables, frozenOnAsk, hookEnvSource, notifyOwnHookCrash, autoModeDecider, permissionMode, scratchpadDir, toolRosterDeltas, stopForDenialLimit, delegation, abortController, now, ownSessionRulesRef } = 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, permissionMode, scratchpadDir, toolRosterDeltas, stopForDenialLimit, delegation, abortController, now, ownSessionRulesRef } = input;
|
|
26
28
|
const ancestorArbitrations = new Map();
|
|
27
29
|
const arbitrateInherited = (ask, toolCallId, judged) => {
|
|
28
30
|
const verdict = arbitrateByMode(permissionMode.current, judged.classification, { origin: judged.origin, ...askMandateMember(ancestorFacts(judged.ask.action === "ask" ? judged.ask : undefined)) });
|
|
@@ -37,7 +39,7 @@ export async function preparePolicyChain(input) {
|
|
|
37
39
|
const auditPolicyNames = (auditee) => {
|
|
38
40
|
const nameGroups = toolPolicyNameSets(auditee);
|
|
39
41
|
if (nameGroups.length > 0) {
|
|
40
|
-
const known =
|
|
42
|
+
const known = mountedToolNames(tools);
|
|
41
43
|
for (const t of harnessTools)
|
|
42
44
|
known.add(t.name);
|
|
43
45
|
const unmatched = new Set();
|
|
@@ -46,9 +48,24 @@ export async function preparePolicyChain(input) {
|
|
|
46
48
|
for (const n of list ?? []) {
|
|
47
49
|
const verdict = judgeRuleToolName(n, known);
|
|
48
50
|
if (verdict.kind !== "current") {
|
|
49
|
-
const
|
|
50
|
-
|
|
51
|
-
|
|
51
|
+
const entry = `tool policy ${kind}-list entry "${n}"`;
|
|
52
|
+
let message;
|
|
53
|
+
switch (verdict.kind) {
|
|
54
|
+
case "retired":
|
|
55
|
+
message = `${entry} is a RETIRED tool name (${verdict.guidance}) and matches nothing in this run's roster — legacy-name normalization was removed (RB-476-A), so this entry would silently guard nothing. Update the deployment's rule to the current name.`;
|
|
56
|
+
break;
|
|
57
|
+
case "unprefixed_namespace":
|
|
58
|
+
message = `${entry} carries the "__" namespace separator but no protocol prefix, and matches nothing in this run's roster — protocol tools are named ${NAMESPACED_NAME_SHAPES}, and legacy-name normalization was removed (RB-476-A), so this entry would silently guard nothing. Prefix the entry with the owning protocol's marker.`;
|
|
59
|
+
break;
|
|
60
|
+
case "unmintable_segment":
|
|
61
|
+
message = `${entry} can match no tool, ever (${verdict.guidance}), so it would silently guard nothing.${verdict.currentName !== undefined ? ` Write "${verdict.currentName}".` : ""}`;
|
|
62
|
+
break;
|
|
63
|
+
default: {
|
|
64
|
+
const exhaustive = verdict;
|
|
65
|
+
return exhaustive;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
const err = new Error(message);
|
|
52
69
|
err.code = "config.legacy_tool_name";
|
|
53
70
|
throw err;
|
|
54
71
|
}
|
|
@@ -285,6 +302,7 @@ export async function preparePolicyChain(input) {
|
|
|
285
302
|
return {};
|
|
286
303
|
return { riskAxes: { ...(irreversible !== undefined ? { irreversible } : {}), ...(egress !== undefined ? { egress } : {}) } };
|
|
287
304
|
};
|
|
305
|
+
const grantBindingOf = (call, args) => skillGrantBindingMembers(call, args, skillSpecs, SKILL_TOOL_NAME);
|
|
288
306
|
const inheritedStationFacts = (call) => {
|
|
289
307
|
const seat = seatMarksOf(call);
|
|
290
308
|
return {
|
|
@@ -374,7 +392,7 @@ export async function preparePolicyChain(input) {
|
|
|
374
392
|
}
|
|
375
393
|
if (judged.kind === "deny")
|
|
376
394
|
return vetoed(judged.result);
|
|
377
|
-
const { ask: editAsk
|
|
395
|
+
const { ask: editAsk } = judged;
|
|
378
396
|
re = editAsk;
|
|
379
397
|
const editArbitrated = arbitrateInherited(re, creq.toolCallId, judged);
|
|
380
398
|
if (editArbitrated !== undefined) {
|
|
@@ -382,21 +400,22 @@ export async function preparePolicyChain(input) {
|
|
|
382
400
|
carryPrecedingSettlement(settledBy, out);
|
|
383
401
|
return out;
|
|
384
402
|
}
|
|
385
|
-
const rr = await resolveAsk({
|
|
403
|
+
const { resolved: rr, judged: settled } = await resolveInheritedAsk(judged, (j) => resolveAsk({
|
|
386
404
|
toolName: creq.toolName,
|
|
387
405
|
toolCallId: creq.toolCallId,
|
|
388
406
|
args: editArgs,
|
|
389
|
-
...ruleOffersOf(creq, editArgs, ancestorFacts(
|
|
390
|
-
...cardDisclosureOf(
|
|
407
|
+
...ruleOffersOf(creq, editArgs, ancestorFacts(j.ask)),
|
|
408
|
+
...cardDisclosureOf(j.ask, inheritedAskFallbackMessage(creq.toolName)),
|
|
391
409
|
...askSourceIdentity(),
|
|
392
410
|
...riskAxesOf(creq),
|
|
393
|
-
...(
|
|
394
|
-
...
|
|
395
|
-
...
|
|
411
|
+
...grantBindingOf(creq, editArgs),
|
|
412
|
+
...(j.ask.requiresRealApproval === true ? { requiresRealApproval: true } : {}),
|
|
413
|
+
...askMandateMember(ancestorFacts(j.ask)),
|
|
414
|
+
...inheritedAskCarry(j, isLiveApproverSeat(onAskOf), ancestorTracker),
|
|
396
415
|
ruleEvidence: inheritedAskEvidence,
|
|
397
|
-
}, onAskOf, csignal ?? abortController.signal, lateAskSettlementObserver({ toolName: creq.toolName, toolCallId: creq.toolCallId, sessionId, runId, ...(spec.taskId !== undefined ? { taskId: spec.taskId } : {}), onNotice: deps.onNotice, onError: deps.onError }));
|
|
416
|
+
}, onAskOf, csignal ?? abortController.signal, lateAskSettlementObserver({ toolName: creq.toolName, toolCallId: creq.toolCallId, sessionId, runId, ...(spec.taskId !== undefined ? { taskId: spec.taskId } : {}), onNotice: deps.onNotice, onError: deps.onError })), ancestorTracker, creq.toolName, inheritedStationFacts(creq));
|
|
398
417
|
void settleReadRootGrant(rr.readRootGrant, undefined, { toolName: creq.toolName, toolCallId: creq.toolCallId, sessionId, runId, ...(spec.taskId !== undefined ? { taskId: spec.taskId } : {}), onNotice: deps.onNotice });
|
|
399
|
-
settleDenialLimitFallback({ fallback:
|
|
418
|
+
settleDenialLimitFallback({ fallback: settled.fallback, mintedHere: settled.mintedHere, tracker: ancestorTracker, resolved: rr, headless: headlessDenyAtRecheck, stop: stopForDenialLimit, toolName: creq.toolName, toolCallId: creq.toolCallId });
|
|
400
419
|
if (rr.action !== "allow")
|
|
401
420
|
return rr;
|
|
402
421
|
settledBy = rr;
|
|
@@ -451,7 +470,7 @@ export async function preparePolicyChain(input) {
|
|
|
451
470
|
return judged.result;
|
|
452
471
|
if (judged.kind === "deny")
|
|
453
472
|
return judged.result;
|
|
454
|
-
const { ask: inheritedAsk, fallback
|
|
473
|
+
const { ask: inheritedAsk, fallback } = judged;
|
|
455
474
|
if (fallback === undefined && sandboxAdmissionArmed && policyAskClassOf(pc.policy) === "sandbox_local" && !sandboxBoundaryCapable(creq) && judged.classification.row.sandboxAdmission) {
|
|
456
475
|
recordAncestorSandboxAdmission(creq.toolCallId, creq.toolName);
|
|
457
476
|
return { action: "allow", decisionReason: "sandbox" };
|
|
@@ -461,33 +480,34 @@ export async function preparePolicyChain(input) {
|
|
|
461
480
|
return arbitrated;
|
|
462
481
|
const presentedArgs = creq.args;
|
|
463
482
|
const askT0 = now();
|
|
464
|
-
const resolved = await resolveAsk({
|
|
483
|
+
const { resolved, judged: settled } = await resolveInheritedAsk(judged, (j) => resolveAsk({
|
|
465
484
|
toolName: creq.toolName,
|
|
466
485
|
toolCallId: creq.toolCallId,
|
|
467
486
|
args: presentedArgs,
|
|
468
|
-
...ruleOffersOf(creq, presentedArgs, ancestorFacts(
|
|
469
|
-
...cardDisclosureOf(
|
|
487
|
+
...ruleOffersOf(creq, presentedArgs, ancestorFacts(j.ask.action === "ask" ? j.ask : undefined)),
|
|
488
|
+
...cardDisclosureOf(j.ask, inheritedAskFallbackMessage(creq.toolName)),
|
|
470
489
|
...askSourceIdentity(),
|
|
471
490
|
...riskAxesOf(creq),
|
|
472
|
-
...(
|
|
473
|
-
...
|
|
474
|
-
...
|
|
491
|
+
...grantBindingOf(creq, presentedArgs),
|
|
492
|
+
...(j.ask.action === "ask" && j.ask.requiresRealApproval === true ? { requiresRealApproval: true } : {}),
|
|
493
|
+
...askMandateMember(ancestorFacts(j.ask.action === "ask" ? j.ask : undefined)),
|
|
494
|
+
...inheritedAskCarry(j, isLiveApproverSeat(pc.onAsk), pc.autoMode?.denialTracking),
|
|
475
495
|
ruleEvidence: inheritedAskEvidence,
|
|
476
|
-
}, 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 }));
|
|
496
|
+
}, 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 })), pc.autoMode?.denialTracking, creq.toolName, inheritedStationFacts(creq));
|
|
477
497
|
void settleReadRootGrant(resolved.readRootGrant, undefined, { toolName: creq.toolName, toolCallId: creq.toolCallId, sessionId, runId, ...(spec.taskId !== undefined ? { taskId: spec.taskId } : {}), onNotice: deps.onNotice });
|
|
478
498
|
const askWaitMs = Math.max(0, now() - askT0);
|
|
479
499
|
if (resolved.action === "deny" && resolved.approverUnavailable === true) {
|
|
480
500
|
if (markInheritedUnavailable(creq.toolCallId))
|
|
481
|
-
return
|
|
501
|
+
return settled.ask;
|
|
482
502
|
return markerChannelFullDeny(creq);
|
|
483
503
|
}
|
|
484
|
-
settleDenialLimitFallback({ fallback, mintedHere, tracker: pc.autoMode?.denialTracking, resolved, headless: headlessDenyAtFold, stop: stopForDenialLimit, toolName: creq.toolName, toolCallId: creq.toolCallId });
|
|
504
|
+
settleDenialLimitFallback({ fallback: settled.fallback, mintedHere: settled.mintedHere, tracker: pc.autoMode?.denialTracking, resolved, headless: headlessDenyAtFold, stop: stopForDenialLimit, toolName: creq.toolName, toolCallId: creq.toolCallId });
|
|
485
505
|
if (resolved.action !== "allow")
|
|
486
506
|
return resolved;
|
|
487
507
|
if (resolved.updatedInput !== undefined) {
|
|
488
508
|
return recheckApprovedEdit(pc.policy, pc.onAsk, creq, resolved.updatedInput, resolved, csignal, pc.autoMode);
|
|
489
509
|
}
|
|
490
|
-
recordInheritedAskGrant(creq.toolCallId, pc.onAsk, resolved.presentedInput, askWaitMs, resolved, askClassMembersOf(
|
|
510
|
+
recordInheritedAskGrant(creq.toolCallId, pc.onAsk, resolved.presentedInput, askWaitMs, resolved, askClassMembersOf(settled.classification).classes);
|
|
491
511
|
return { action: "allow", decisionReason: "mode" };
|
|
492
512
|
},
|
|
493
513
|
}
|
|
@@ -524,7 +544,7 @@ export async function preparePolicyChain(input) {
|
|
|
524
544
|
return judged.result;
|
|
525
545
|
if (judged.kind === "deny")
|
|
526
546
|
return judged.result;
|
|
527
|
-
const { ask: inheritedAsk, fallback
|
|
547
|
+
const { ask: inheritedAsk, fallback } = judged;
|
|
528
548
|
if (fallback === undefined && sandboxAdmissionArmed && policyAskClassOf(pc.policy) === "sandbox_local" && !sandboxBoundaryCapable(creq) && judged.classification.row.sandboxAdmission) {
|
|
529
549
|
recordAncestorSandboxAdmission(creq.toolCallId, creq.toolName);
|
|
530
550
|
return decision.updatedInput !== undefined ? { action: "allow", updatedInput: decision.updatedInput, decisionReason: "sandbox" } : { action: "allow", decisionReason: "sandbox" };
|
|
@@ -533,27 +553,28 @@ export async function preparePolicyChain(input) {
|
|
|
533
553
|
if (arbitrated !== undefined)
|
|
534
554
|
return arbitrated;
|
|
535
555
|
const askT0 = now();
|
|
536
|
-
const resolved = await resolveAsk({
|
|
556
|
+
const { resolved, judged: settled } = await resolveInheritedAsk(judged, (j) => resolveAsk({
|
|
537
557
|
toolName: creq.toolName,
|
|
538
558
|
toolCallId: creq.toolCallId,
|
|
539
559
|
args: presentedArgs,
|
|
540
|
-
...ruleOffersOf(creq, presentedArgs, ancestorFacts(
|
|
541
|
-
...cardDisclosureOf(
|
|
560
|
+
...ruleOffersOf(creq, presentedArgs, ancestorFacts(j.ask.action === "ask" ? j.ask : undefined)),
|
|
561
|
+
...cardDisclosureOf(j.ask, inheritedAskFallbackMessage(creq.toolName)),
|
|
542
562
|
...askSourceIdentity(),
|
|
543
563
|
...riskAxesOf(creq),
|
|
544
|
-
...(
|
|
545
|
-
...
|
|
546
|
-
...
|
|
564
|
+
...grantBindingOf(creq, presentedArgs),
|
|
565
|
+
...(j.ask.action === "ask" && j.ask.requiresRealApproval === true ? { requiresRealApproval: true } : {}),
|
|
566
|
+
...askMandateMember(ancestorFacts(j.ask.action === "ask" ? j.ask : undefined)),
|
|
567
|
+
...inheritedAskCarry(j, isLiveApproverSeat(pc.onAsk), pc.autoMode?.denialTracking),
|
|
547
568
|
ruleEvidence: inheritedAskEvidence,
|
|
548
|
-
}, 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 }));
|
|
569
|
+
}, 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 })), pc.autoMode?.denialTracking, creq.toolName, inheritedStationFacts(creq));
|
|
549
570
|
void settleReadRootGrant(resolved.readRootGrant, undefined, { toolName: creq.toolName, toolCallId: creq.toolCallId, sessionId, runId, ...(spec.taskId !== undefined ? { taskId: spec.taskId } : {}), onNotice: deps.onNotice });
|
|
550
571
|
const askWaitMs = Math.max(0, now() - askT0);
|
|
551
572
|
if (resolved.action === "deny" && resolved.approverUnavailable === true) {
|
|
552
573
|
if (markInheritedUnavailable(creq.toolCallId))
|
|
553
|
-
return
|
|
574
|
+
return settled.ask;
|
|
554
575
|
return markerChannelFullDeny(creq);
|
|
555
576
|
}
|
|
556
|
-
settleDenialLimitFallback({ fallback, mintedHere, tracker: pc.autoMode?.denialTracking, resolved, headless: headlessDenyAtFold, stop: stopForDenialLimit, toolName: creq.toolName, toolCallId: creq.toolCallId });
|
|
577
|
+
settleDenialLimitFallback({ fallback: settled.fallback, mintedHere: settled.mintedHere, tracker: pc.autoMode?.denialTracking, resolved, headless: headlessDenyAtFold, stop: stopForDenialLimit, toolName: creq.toolName, toolCallId: creq.toolCallId });
|
|
557
578
|
if (resolved.action !== "allow")
|
|
558
579
|
return resolved;
|
|
559
580
|
if (resolved.updatedInput !== undefined) {
|
|
@@ -667,7 +688,7 @@ export async function preparePolicyChain(input) {
|
|
|
667
688
|
return decision;
|
|
668
689
|
})
|
|
669
690
|
: foldedPolicy;
|
|
670
|
-
return { hooks, hookTimeoutMs, preToolUseObservational, ownGatePreToolUse, basePolicyForResumeEdit, denyNarrowingPolicy, skillGrantLane, allowEntryLanes, policyLayers, effectivePolicy, inheritedUnavailableAsks, inheritedAskGrants, askSourceIdentity, riskAxesOf, ruleOffersOf, permissionRuleLane, permissionRuleOrgLane, sandboxAdmissionArmed, sandboxBoundaryCapable, emitSandboxAdmitted, foldAskClasses, ancestorSandboxAdmissions, ancestorArbitrations };
|
|
691
|
+
return { hooks, hookTimeoutMs, preToolUseObservational, ownGatePreToolUse, basePolicyForResumeEdit, denyNarrowingPolicy, skillGrantLane, allowEntryLanes, policyLayers, effectivePolicy, inheritedUnavailableAsks, inheritedAskGrants, askSourceIdentity, riskAxesOf, ruleOffersOf, grantBindingOf, permissionRuleLane, permissionRuleOrgLane, sandboxAdmissionArmed, sandboxBoundaryCapable, emitSandboxAdmitted, foldAskClasses, ancestorSandboxAdmissions, ancestorArbitrations };
|
|
671
692
|
}
|
|
672
693
|
const advisedPolicyNames = new WeakMap();
|
|
673
694
|
const ADVISED_KEYS_CAP = 64;
|