@sema-agent/core
Version:
Stateless, task-oriented AI agent core
788 lines • 52.6 kB
JavaScript
import { argsAsTheToolReads, withArgsReading } from "./effective-path-target.js";
import { attest, attestationOf, decisionText, foldHookAsk, ownArgs, refusalOf, refuseOutOfContractDecision } from "./tool-policy.js";
import { arbitrateByMode, classifyAsk, decisionAskClassesOf, fileCommandOptionsSentence, persistedRuleMandateOf, ruleClearanceOf, safetyAxisOf, stampAskOrigin } from "./ask-origin.js";
import { classifierParseFailureDenyMessage, denialLimitFallbackMessage, rungDidNotRule, unarmedWindow } from "./auto-mode.js";
import { classifierNoRulingArm, settleNoRulingAsk } from "./classifier-unavailable-arm.js";
import { SETTLEMENT_NOBODY_JUDGED } from "./gate-outcome.js";
import { inlineUntrusted } from "./untrusted-text.js";
import { ASK_USER_QUESTION_TOOL_NAME } from "./ask-question.js";
import { applyPersistedTightening, disclosedRuleSet } from "./persisted-rule-arms.js";
import { skillAllowDecision, skillRowRefusal } from "./skill-grant.js";
import { allowRuleShadowOf } from "./allow-entry.js";
import { CD_GIT_COMPOUND_SENTENCE, changesDirectoryBeforeGit, readOnlyShellVerdict } from "./read-only-shell.js";
import { readShellCommand } from "./shell-lexer.js";
import { COMMAND_RULE_TOOL } from "./permission-rule-model.js";
import { catalogRuleFaceOf } from "./tool-registry.js";
import { callFaceSeat } from "./tool-roster.js";
import { heldBy, wireOf } from "./tool-name-readings.js";
import { asksUnstated, modeAcceptsFileCommand, permissionSeatAt, unstatedAskMessage } from "./mode-policy.js";
import { ORG_RULE_DECISION_REASON, ORG_UNAVAILABLE_DECISION_REASON, orgUnreadableClause } from "./permission-rule-org.js";
import { exitGate, passAskFace, unownedArgsMessage } from "./runner/gate-exit.js";
import { readOrgRuleLane, readPersistedRuleLane } from "./rule-lane-reads.js";
import { traceHookCrash } from "./gate-crash-trace.js";
import { createGateDeadline, awaitWriteProtectionJudgment, withGateTimeout } from "./gate-bounded-await.js";
import { readStationAnswer } from "./shell-read-silence.js";
import { agentIdOf, judgedInputOf, raiseToolCheck } from "./mods/stations.js";
import { readToolChecks } from "./tool-check-reading.js";
import { policyThrowLine, reportPolicyThrow } from "./runner/policy-throw.js";
const QUESTION_TOOL_NAMES = new Set([ASK_USER_QUESTION_TOOL_NAME]);
function parkWith(suspendAsk, parkArgs, carry) {
return suspendAsk(...parkArgs, carry);
}
const ruleCallUnreadableOf = (lane) => lane?.unreadable === true && lane.reason !== undefined;
const ruleStoreUnreadableOf = (lane) => lane?.unreadable === true && lane.reason === undefined;
export async function runGateLanes(pass) {
const { input, toolName, toolCallId, callSignal, ledger, notifier, screening, adjudicate, resolveAsk, suspendAsk } = pass;
const boundedAwaitDeadlineMs = createGateDeadline(input, notifier);
let orgRealApprovalRequired = false;
let markedThisRound;
let approvedWithArgs = false;
let carriedOwnAsk;
const takeApprovedEdit = (read) => {
carriedOwnAsk = read.outstanding ?? (pass.decision.action === "ask" ? pass.decision : undefined);
pass.decision = read.allow;
approvedWithArgs = true;
};
const safetyOf = (d) => safetyAxisOf({ egress: input.egress, shellGated: input.shellGated, irreversibility: input.irreversibility, probeMandated: d.action === "ask" && d.probeMandated === true, probeUnanswered: pass.probeUnanswered === true, tightened: pass.tightenedBy });
const realApprovalOf = (d, org) => {
if (d.action !== "ask" || d.requiresRealApproval !== true)
return undefined;
if (d.origin === undefined)
throw new Error(`a real-approval ask for "${toolName}" reached a park site with no origin word — the origin stamp precedes every park`);
return { origin: d.origin, ...(org !== undefined ? { org } : {}) };
};
const carryOf = (d) => ({
...(callSignal !== undefined ? { signal: callSignal } : {}),
...(d.action === "ask" && d.denialLimitFallback !== undefined ? { denialLimitFallback: unarmedWindow(d.denialLimitFallback) } : {}),
...(d.action === "ask" && d.classifierNoRuling !== undefined ? { classifierNoRuling: d.classifierNoRuling } : {}),
...(d.action === "ask" && d.origin !== undefined ? { origin: d.origin } : {}),
...(d.action === "ask" && d.askClass !== undefined && d.classes !== undefined ? { askClass: d.askClass, classes: d.classes } : {}),
...(d.action === "ask" && d.mandated === true ? { mandated: true, ...(d.mandate !== undefined ? { mandate: d.mandate } : {}) } : {}),
...(d.action === "ask" && d.authoredBy === "deployment" ? { authoredBy: "deployment" } : {}),
});
const parkAsk = async (d, req, args, safety, liveFaceUnavailable, org) => {
if (suspendAsk === undefined || d.action !== "ask")
return undefined;
const suspended = await parkWith(suspendAsk, [req, args, safety, liveFaceUnavailable, realApprovalOf(d, org), d.allowRuleShadowed, d.decisionReason, d.probeReason, d.probeCause, d.segmentCoverage, d.matchedAskRule, d.probeMandated], carryOf(d));
if (suspended && "parkFailed" in suspended)
pass.parkFailed = suspended.parkFailed;
return suspended && !("parkFailed" in suspended) ? { suspend: suspended, preToolContext: pass.preToolContext } : undefined;
};
const markedUnresolvable = () => (markedThisRound ??= input.isMarkedUnresolvable?.(input.event.toolCallId) === true);
const mandateMarksNow = () => ({
egress: input.egress,
shellGated: input.shellGated,
irreversibility: input.irreversibility,
requiresUserInteraction: input.requiresUserInteraction,
probeUnanswered: pass.probeUnanswered === true,
writeProtected: pass.writeProtected === true,
targetUnresolved: pass.targetUnresolved === true,
});
const readFaceNow = input.readFace?.();
const askOriginFacts = (org, lane) => ({
contentQuestion: heldBy("lanes.contentQuestionClass", QUESTION_TOOL_NAMES, pass.req),
markedUnresolvable: markedUnresolvable(),
org,
...(ruleCallUnreadableOf(lane) ? { ruleCallUnreadable: true } : {}),
...(ruleStoreUnreadableOf(lane) ? { ruleStoreUnreadable: true } : {}),
tightened: pass.tightenedBy,
mandateMarks: mandateMarksNow(),
...(input.toolMarkSources !== undefined ? { toolMarkSources: input.toolMarkSources } : {}),
...(input.a2aIsolatePeers === true ? { a2aIsolatePeers: true } : {}),
...(readFaceNow !== undefined ? { readFace: readFaceNow } : {}),
askFace: passAskFace(pass),
});
const classifyStanding = (unstamped, facts) => (pass.askClassification = classifyAsk(unstamped, facts));
let orgTightenCount = 0;
let orgEvidence = (() => {
const w = input.orgRules === undefined ? "not_wired" : "not_adjudicated";
return { revisionAbsent: w, ruleAbsent: w };
})();
const mintRuleEvidence = (personal) => ({
...(orgEvidence.revision !== undefined ? { orgRevision: orgEvidence.revision } : { orgRevisionAbsent: orgEvidence.revisionAbsent ?? "not_reported" }),
...(orgEvidence.rule !== undefined ? { orgRule: orgEvidence.rule } : { orgRuleAbsent: orgEvidence.ruleAbsent ?? "not_reported" }),
...(personal.dots !== undefined ? { personalRuleDots: personal.dots } : { personalRuleDotsAbsent: personal.dotsAbsent ?? "not_reported" }),
});
const applyOrgLayer = async (current, args) => {
if (input.orgRules === undefined)
return { decision: current, org: undefined };
if (wireOf("lanes.orgContentAskExemption", pass.req) === ASK_USER_QUESTION_TOOL_NAME && input.orgRules.contentAskToolMounted === true)
return { decision: current, org: undefined };
let decided = current;
const answer = await readOrgRuleLane(input.orgRules, Object.freeze({ toolName, args, toolCallId, ...callFaceSeat(pass.req.face) }), input.abortSignal);
if (answer.status === "unavailable") {
orgEvidence = { revisionAbsent: "unavailable", ruleAbsent: "unavailable" };
orgRealApprovalRequired = true;
await notifier.notifyAsync(() => input.orgRules?.onUnavailable?.({ toolName, toolCallId, message: answer.disclosures.join("; ") }), "toolGate.orgSnapshotUnavailable");
const orgUnavailableMessage = `tool "${toolName}" needs approval: this deployment is org-governed and cannot currently adjudicate ` +
`against an organization policy snapshot — every allow tightens to a real approval until it can`;
if (decided.action === "allow") {
decided = { action: "ask", message: orgUnavailableMessage, decisionReason: ORG_UNAVAILABLE_DECISION_REASON, requiresRealApproval: true };
orgTightenCount += 1;
}
else if (decided.action === "ask" && decided.requiresRealApproval !== true) {
decided = { ...decided, requiresRealApproval: true, ...(pass.tightenedBy !== undefined ? { message: orgUnavailableMessage } : {}) };
orgTightenCount += 1;
}
return { decision: decided, org: "unavailable" };
}
const revisionCell = answer.revision !== undefined ? { revision: answer.revision } : { revisionAbsent: "not_reported" };
if (answer.verdict === undefined) {
orgEvidence = { ...revisionCell, ruleAbsent: "no_match" };
return { decision: decided, org: undefined };
}
const { behavior, rule, unreadable } = answer.verdict;
orgEvidence = { ...revisionCell, rule };
if (behavior === "deny") {
orgTightenCount += 1;
pass.deniedBy = "org";
pass.denyCause = undefined;
return { decision: refusalOf({ action: "deny", message: `an organization policy rule (${rule}) denies this call${unreadable !== undefined ? `, ${orgUnreadableClause(unreadable)}` : ""}`, decisionReason: ORG_RULE_DECISION_REASON }, args), org: undefined };
}
if (decided.action === "deny")
return { decision: decided, org: undefined };
orgTightenCount += 1;
orgRealApprovalRequired = true;
const orgRuleMessage = unreadable !== undefined
? `an organization policy rule (${rule}) may reach this call, ${orgUnreadableClause(unreadable)} — a person must decide`
: `an organization policy rule (${rule}) requires approval for this call`;
return {
decision: decided.action === "ask"
?
{ ...decided, requiresRealApproval: true, ...(decided.requiresRealApproval !== true && pass.tightenedBy !== undefined ? { message: orgRuleMessage } : {}) }
: { action: "ask", message: orgRuleMessage, decisionReason: ORG_RULE_DECISION_REASON, requiresRealApproval: true },
org: "rule",
};
};
const finalArgs = pass.policyRewrite !== undefined ? pass.policyRewrite : pass.currentInput;
if (pass.decision.action === "deny")
pass.decision = refusalOf(pass.decision, finalArgs);
const orgAnswer = await applyOrgLayer(pass.decision, finalArgs);
pass.decision = orgAnswer.decision;
const readPersistedRules = (req) => readPersistedRuleLane(input.persistedRules, req, input.abortSignal);
const laneReq = Object.freeze(pass.policyRewrite !== undefined ? await withArgsReading(pass.req, pass.policyRewrite, pass.callSignal ?? input.abortSignal) : { ...pass.req });
const laneAnswer = input.persistedRules !== undefined && wireOf("lanes.persistedLaneSkip", pass.req) !== ASK_USER_QUESTION_TOOL_NAME ? await readPersistedRules(laneReq) : undefined;
{
const tightened = applyPersistedTightening(pass.decision, laneAnswer, laneReq);
pass.decision = tightened.tightened === "deny" ? refusalOf(tightened.decision, laneReq.args) : tightened.decision;
if (tightened.tightened === "deny")
pass.deniedBy = "persisted_rule";
if (tightened.tightened === "deny")
pass.denyCause = undefined;
const skillRefusal = pass.decision.action === "deny" ? undefined : skillRowRefusal(input.skillGrants, laneReq);
if (skillRefusal !== undefined) {
pass.decision = refusalOf(skillRefusal, laneReq.args);
pass.deniedBy = "policy";
pass.denyCause = undefined;
}
}
let settledRefusal;
const checkTool = async (standing, args, org, rewrite, mayClear) => {
const agentId = agentIdOf(input.identity);
const ceiling = org !== undefined ? { ceiling: "ask" } : {};
const e = { tool: toolName, input: judgedInputOf(args), tool_use_id: toolCallId, ...(agentId !== undefined ? { agentId } : {}), ...ceiling };
const signal = callSignal ?? input.abortSignal;
const own = input.modBus;
settledRefusal = undefined;
const settleThroughLedger = (settle) => async (ask, call, sig) => {
const read = ledger.fromDecision(await settle(ask, call, sig));
if (read.decision.action === "deny")
settledRefusal = { deniedBy: read.deniedBy ?? "policy", cause: ledger.causeOf(read.decision) };
return read.decision;
};
const chains = [
...(own !== undefined ? [{ raise: (p) => raiseToolCheck(own, { ...e }, p, signal), ...(mayClear !== undefined ? { mayClear } : {}) }] : []),
...(input.inheritedToolChecks ?? []).map((c) => ({ raise: (p) => raiseToolCheck(c.bus, { ...e }, p, signal, c.judges), settle: settleThroughLedger(c.settle) })),
];
const project = (current, clears) => {
const reason = decisionText(current);
const said = reason !== undefined ? { reason } : {};
return current.action === "ask" ? { decision: "ask", ...said, classes: [...(current.classes ?? [])], mandated: clears?.() !== true, ...ceiling } : { decision: "allow", ...said, ...ceiling };
};
return await readToolChecks(chains, standing, { toolName, judged: args, rewrite, request: Object.freeze({ ...pass.req, args }), signal }, project);
};
const refuseByExtension = (deny) => {
pass.decision = deny;
pass.deniedBy = settledRefusal?.deniedBy ?? "hook";
pass.denyCause = settledRefusal?.cause;
};
if (pass.decision.action === "allow") {
const read = await checkTool(pass.decision, finalArgs, orgAnswer.org, pass.policyRewrite);
if (read !== undefined)
pass.toolCheckRaised = true;
if (read?.kind === "denied")
refuseByExtension(read.deny);
else if (read?.kind === "asked")
pass.decision = read.ask;
else if (read?.kind === "approved")
takeApprovedEdit(read);
}
if (pass.decision.action === "ask") {
pass.decision = { ...pass.decision };
if (pass.policyRewrite !== undefined) {
pass.currentInput = pass.policyRewrite;
pass.req = Object.freeze({ ...pass.req, args: pass.policyRewrite, ...(laneReq.targetReading !== undefined ? { targetReading: laneReq.targetReading } : {}) });
}
const ruleMayClear = () => ruleClearanceOf(pass.decision.action === "ask" ? pass.decision : undefined, mandateMarksNow()).ruleMayClear;
const classMayClear = () => pass.decision.action === "ask" && classifyAsk(pass.decision, askOriginFacts(orgAnswer.org, laneAnswer)).row.ruleMayClear;
let personalEvidence = { dotsAbsent: input.persistedRules === undefined ? "not_wired" : "not_adjudicated" };
if (laneAnswer?.unreadable === true)
personalEvidence = { dotsAbsent: "unavailable" };
let laneCoverage;
const questionTool = wireOf("lanes.allowLayerQuestionSkip", pass.req) === ASK_USER_QUESTION_TOOL_NAME;
const allowLayerMayClear = () => !orgRealApprovalRequired &&
pass.decision.action === "ask" &&
pass.decision.requiresRealApproval !== true &&
pass.decision.decisionReason !== "hook" &&
!questionTool &&
!markedUnresolvable();
const unionDotsOf = (rules) => {
const seen = new Set();
const union = [];
for (const r of rules) {
if (r.dots === undefined || r.dots.length === 0)
return { dotsAbsent: "not_reported" };
for (const d of r.dots) {
const key = JSON.stringify([d.actor, d.counter]);
if (!seen.has(key))
(seen.add(key), union.push(d));
}
}
return { dots: union };
};
if (input.persistedRules && allowLayerMayClear()) {
const answer = laneAnswer ?? {};
laneCoverage = answer.coverage;
personalEvidence = answer.hit?.behavior === "ask" ? unionDotsOf(answer.hit.rules) : { dotsAbsent: answer.unreadable === true ? "unavailable" : "no_match" };
}
const afterRuleClear = () => {
if (input.permissionMode === undefined || input.permissionMode() === "auto")
input.autoMode?.denialTracking?.recordAllow();
};
const mode = input.permissionMode?.();
const rewrite = pass.policyRewrite !== undefined ? { updatedInput: pass.policyRewrite } : {};
const listAllow = (decisionReason, whose, entries) => ({
action: "allow",
message: `${whose} allowedTools (${entries.map((e) => inlineUntrusted(e, 200)).join(", ")}) ${entries.length === 1 ? "covers" : "cover"} this call`,
decisionReason,
...rewrite,
});
const storedAllows = laneAnswer?.hit?.behavior === "allow" ? laneAnswer.hit.rules : undefined;
const members = [
["hook", () => (pass.hookAllowedBy !== undefined && pass.policyRewrite === undefined ? { entries: pass.hookAllowedBy, clear: () => ({ action: "allow", message: "a PreToolUse hook allowed this call", decisionReason: "hook" }), afterClear: async () => undefined } : undefined)],
["deployment", () => {
const hit = input.deploymentAllows?.allowing(pass.req, mode);
return hit && { entries: hit.entries, clear: () => listAllow("deployment_rule", "the deployment's", hit.entries), afterClear: () => notifier.notifyAsync(() => input.deploymentAllows?.onAllowed?.({ toolName: pass.req.toolName, toolCallId, entries: hit.entries }), "toolGate.allowedToolsResolved") };
}],
["persisted", () => storedAllows && {
entries: storedAllows.map((r) => r.rule),
clear: () => ({ action: "allow", message: storedAllows.length === 1 ? `a persisted allow rule (${disclosedRuleSet(storedAllows)}) covers this call` : `persisted allow rules (${disclosedRuleSet(storedAllows)}) cover every segment of this call`, decisionReason: "persisted_rule", ...rewrite }),
afterClear: () => notifier.notifyAsync(() => input.persistedRules?.onResolved?.({ toolName: pass.req.toolName, toolCallId, rules: storedAllows.map((r) => r.rule) }), "toolGate.persistedRuleResolved"),
shadowed: () => (personalEvidence = unionDotsOf(storedAllows)),
}],
["skill", () => {
const hit = input.skillGrants?.allowing(pass.req, mode);
return hit && { entries: hit.entries, clear: () => skillAllowDecision(hit, pass.policyRewrite), afterClear: () => notifier.notifyAsync(() => input.skillGrants?.onAllowed?.({ toolName: pass.req.toolName, toolCallId, ...hit }), "toolGate.skillGrantResolved") };
}],
["request", () => {
const hit = input.requestAllows?.allowing(pass.req, mode);
return hit && { entries: hit.entries, clear: () => listAllow("request_rule", "this run's", hit.entries), afterClear: () => notifier.notifyAsync(() => input.requestAllows?.onAllowed?.({ toolName: pass.req.toolName, toolCallId, entries: hit.entries }), "toolGate.allowedToolsResolved") };
}],
];
const shadows = [];
if (!questionTool) {
for (const [member, match] of members) {
if (pass.decision.action !== "ask")
break;
const hit = match();
if (hit === undefined)
continue;
if (allowLayerMayClear() && ruleMayClear() && classMayClear()) {
pass.decision = hit.clear();
await hit.afterClear();
if (member !== "hook")
afterRuleClear();
break;
}
shadows.push(allowRuleShadowOf(member, hit.entries));
hit.shadowed?.();
}
}
if (pass.decision.action === "ask") {
const { allowRuleShadowed: _claimed, ...standing } = pass.decision;
pass.decision = shadows.length > 0 ? { ...standing, allowRuleShadowed: shadows } : standing;
}
const originFacts = askOriginFacts(orgAnswer.org, laneAnswer);
let noRulingMinted = false;
const fallbackAskOf = (standingAsk, fallback, latestBlockedAction) => {
const { classifierNoRuling: _why, ...standing } = standingAsk;
const fallbackAsk = { ...standing, message: denialLimitFallbackMessage(fallback, latestBlockedAction), decisionReason: "classifier", requiresRealApproval: true, denialLimitFallback: fallback };
return stampAskOrigin(fallbackAsk, originFacts, classifyStanding(fallbackAsk, originFacts));
};
if (pass.decision.action === "ask") {
const stamped = { ...pass.decision, ruleEvidence: mintRuleEvidence(personalEvidence), ...(laneCoverage !== undefined ? { segmentCoverage: laneCoverage } : {}) };
pass.decision = stampAskOrigin(stamped, originFacts, classifyStanding(stamped, originFacts));
}
if (allowLayerMayClear() && pass.decision.action === "ask" && ruleMayClear() && classMayClear() && pass.probeBoundaryDeclined !== true && wireOf("lanes.readOnlyShellAllow", pass.req) === COMMAND_RULE_TOOL) {
const commandParam = catalogRuleFaceOf(COMMAND_RULE_TOOL)?.primaryParams[0] ?? "command";
const args = pass.req.args;
const command = typeof args === "object" && args !== null && !Array.isArray(args) ? args[commandParam] : undefined;
const backgrounded = typeof args === "object" && args !== null && args.run_in_background === true;
const shape = typeof command === "string" ? readShellCommand(command) : undefined;
if (typeof command === "string" && shape !== undefined && !backgrounded && readOnlyShellVerdict(command, shape, input.trackedCwd?.()).readOnly) {
pass.decision = {
action: "allow",
message: "the command is read-only (upstream's read-only command tables) — allowed without asking",
decisionReason: "read_only",
...(pass.policyRewrite !== undefined ? { updatedInput: pass.policyRewrite } : {}),
};
await notifier.notifyAsync(() => input.onReadOnlyAllowed?.({ toolName: pass.req.toolName, toolCallId, command }), "toolGate.readOnlyAllowed");
afterRuleClear();
}
else if (shape !== undefined && pass.tightenedBy === "shell_gate" && changesDirectoryBeforeGit(shape, input.trackedCwd?.())) {
pass.decision = { ...pass.decision, message: CD_GIT_COMPOUND_SENTENCE };
}
}
if (pass.toolCheckRaised !== true && pass.decision.action !== "deny") {
const read = await checkTool(pass.decision, pass.currentInput, orgAnswer.org, pass.policyRewrite, () => allowLayerMayClear() && ruleMayClear() && classMayClear());
if (read?.kind === "denied")
refuseByExtension(read.deny);
else if (read?.kind === "cleared")
pass.decision = read.allow;
else if (read?.kind === "asked") {
const asked = read.minted ? { ...read.ask, ruleEvidence: mintRuleEvidence(personalEvidence) } : read.ask;
if (read.marked === true)
markedThisRound = undefined;
const facts = read.marked === true ? askOriginFacts(orgAnswer.org, laneAnswer) : originFacts;
pass.decision = stampAskOrigin(asked, facts, classifyStanding(asked, facts));
}
else if (read?.kind === "shadowed" && pass.decision.action === "ask")
pass.decision = { ...pass.decision, allowRuleShadowed: [...(pass.decision.allowRuleShadowed ?? []), ...read.shadows] };
else if (read?.kind === "approved")
takeApprovedEdit(read);
}
if (pass.decision.action === "ask")
ledger.supersede();
if (input.autoMode && pass.decision.action === "ask" && pass.decision.origin !== undefined && pass.askClassification?.row.classifierEligible === true && (input.permissionMode === undefined || input.permissionMode() === "auto")) {
const classifySignal = callSignal ?? input.abortSignal;
const heard = await input.autoMode.decider
.decide({ req: pass.req, askMessage: decisionText(pass.decision) }, classifySignal)
.catch(() => ({ kind: "unavailable", cause: "error" }));
const verdict = heard.kind === "allow" && input.permissionMode !== undefined && input.permissionMode() !== "auto" ? undefined : heard;
if (verdict !== undefined)
pass.classifierRound = verdict.classifier;
if (verdict?.kind === "allow") {
input.autoMode.denialTracking?.recordAllow();
pass.decision = {
action: "allow",
message: "auto-mode classifier allowed this call",
decisionReason: "classifier",
...(pass.policyRewrite !== undefined ? { updatedInput: pass.policyRewrite } : {}),
};
}
else if (verdict !== undefined) {
const noRuling = rungDidNotRule(verdict);
const arm = noRuling !== undefined ? classifierNoRulingArm({ ask: pass.decision, req: pass.req, cause: noRuling, attribution: verdict.classifier, seat: input.autoMode.unavailable, aborted: classifySignal?.aborted === true }) : undefined;
if (arm?.kind === "asked") {
noRulingMinted = true;
pass.decision = stampAskOrigin(arm.ask, originFacts, classifyStanding(arm.ask, originFacts));
pass.classifierRound = undefined;
}
else if (arm?.kind === "denied")
pass.decision = refusalOf(arm.deny, finalArgs);
else {
const reason = verdict.kind === "block" ? (verdict.reason ? inlineUntrusted(verdict.reason) : "") : classifierParseFailureDenyMessage(verdict.classifier);
const category = verdict.kind === "block" && verdict.category ? inlineUntrusted(verdict.category) : "";
const tracked = input.autoMode.denialTracking?.recordBlock();
if (tracked?.limitReached === true) {
pass.decision = fallbackAskOf(pass.decision, tracked.fallback, reason || category || toolName);
}
else {
const denied = {
action: "deny",
message: verdict.kind === "block" ? `auto-mode classifier blocked this call${reason ? `: ${reason}` : category ? `: [${category}]` : ""}` : reason,
decisionReason: "classifier",
};
pass.decision = refusalOf(verdict.kind === "parse_error" ? attest(denied, pass.req, { classifierCause: "parse_error" }) : denied, finalArgs);
}
}
}
if (pass.decision.action === "deny") {
pass.deniedBy = "classifier";
pass.denyCause = attestationOf(pass.decision, pass.req)?.classifierCause;
}
}
if (input.sandboxAdmission !== undefined &&
pass.decision.action === "ask" &&
wireOf("lanes.sandboxQuestionSkip", pass.req) !== ASK_USER_QUESTION_TOOL_NAME &&
input.isMarkedUnresolvable?.(input.event.toolCallId) !== true &&
pass.decision.requiresRealApproval !== true &&
pass.decision.decisionReason !== "hook" &&
pass.decision.origin !== "ask_rule" &&
pass.hookAsk === undefined &&
input.egress !== true &&
input.peerMessage !== true &&
pass.askClassification?.row.sandboxAdmission === true &&
pass.probeBoundaryDeclined !== true &&
input.sandboxAdmission.boundaryCapable !== true) {
const recorded = input.sandboxAdmission.askClassesOf(toolCallId);
const admissible = recorded !== undefined && recorded.length > 0 && recorded.every((r) => r.cls === "sandbox_local");
if (admissible) {
const askClasses = recorded;
input.sandboxAdmission.onAdmitted({ toolCallId, toolName, askClasses, boundary: "sandbox_internal" });
pass.preToolContext.push(`permission.sandbox_admitted: this call's pending approval was auto-admitted because the deployment declares an isolated sandbox execution env and the request stays inside it. Recorded for audit.`);
pass.decision = {
action: "allow",
message: "admitted inside the deployment-declared sandbox (permission.sandbox_admitted)",
decisionReason: "sandbox",
...(pass.policyRewrite !== undefined ? { updatedInput: pass.policyRewrite } : {}),
};
}
}
if (pass.decision.action === "ask" && input.permissionMode !== undefined && pass.askClassification !== undefined) {
const standing = pass.decision;
const mode = input.permissionMode();
const fileCommandByWord = modeAcceptsFileCommand(mode, wireOf("lanes.modeFileCommand", pass.req), pass.policyRewrite ?? pass.currentInput);
const verdict = arbitrateByMode(mode, pass.askClassification, { ...(standing.origin !== undefined ? { origin: standing.origin } : {}), ...(standing.mandate !== undefined ? { mandate: standing.mandate } : {}) }, { fileCommand: pass.shellWritesPlaced === true && fileCommandByWord });
if (verdict.kind === "ask" && fileCommandByWord && pass.shellWritesPlaced !== true && pass.shellUnplacedOptions !== undefined && pass.askClassification.classes.size === 1 && pass.askClassification.classes.has("ordinary")) {
pass.decision = { ...standing, message: fileCommandOptionsSentence(pass.shellUnplacedOptions.program) };
}
if (verdict.kind === "accepted") {
ledger.supersede();
pass.decision = { action: "allow", message: `accepted by the ${verdict.mode} permission mode (one of its file commands)`, decisionReason: "mode", ...(pass.policyRewrite !== undefined ? { updatedInput: pass.policyRewrite } : {}) };
}
else if (verdict.kind === "released") {
pass.arbitration = verdict;
ledger.supersede();
await notifier.notifyAsync(() => input.onModeReleased?.({ toolName, toolCallId, release: { mode: verdict.mode, askClass: verdict.askClass, classes: verdict.classes, ...(verdict.origin !== undefined ? { origin: verdict.origin } : {}), ...(verdict.mandate !== undefined ? { mandate: verdict.mandate } : {}), ...(verdict.reason !== undefined ? { reason: verdict.reason } : {}) }, ...(pass.shellReadUnestablished === true ? { readUnestablished: true } : {}) }), "toolGate.onModeReleased");
pass.decision = {
action: "allow",
message: `released by the ${verdict.mode} permission mode (the ${verdict.askClass} ask was not put to anyone)`,
decisionReason: "mode",
...(pass.policyRewrite !== undefined ? { updatedInput: pass.policyRewrite } : {}),
};
}
else if (verdict.kind === "denied_by_mode") {
pass.arbitration = verdict;
pass.deniedBy = "mode";
pass.denyCause = undefined;
pass.decision = refusalOf({
action: "deny",
message: verdict.mode === "dontAsk"
? `refused by the dontAsk permission mode: this call needed approval (${verdict.askClass}) and the mode answers no ask; run under a mode with an approver, or change the call`
: `refused by the bypassPermissions permission mode: the write-protection judge could not resolve this write's target, and with nobody to ask the mode refuses rather than releases it`,
decisionReason: "mode",
}, finalArgs);
}
}
const safety = safetyOf(pass.decision);
if (suspendAsk && pass.decision.action === "ask") {
const parked = await parkAsk(pass.decision, pass.req, pass.currentInput, safety, undefined, originFacts.org);
if (parked)
return parked;
}
if (pass.decision.action === "ask" && wireOf("lanes.contentAskRoute", pass.req) === ASK_USER_QUESTION_TOOL_NAME) {
const outcome = input.resolveContentAsk !== undefined ? await (callSignal !== undefined ? input.resolveContentAsk(pass.req, callSignal) : input.resolveContentAsk(pass.req)) : { kind: "unavailable", parkDeclined: false };
if (outcome.kind === "answered") {
pass.decision = { action: "allow" };
}
else if (outcome.kind === "unavailable") {
if (suspendAsk && outcome.parkDeclined && pass.parkFailed === undefined) {
const parked = await parkAsk(pass.decision, pass.req, pass.currentInput, safety, true, originFacts.org);
if (parked)
return parked;
}
if (pass.decision.origin === undefined)
throw new Error(`the content ask for "${toolName}" reached its refusal without an origin word`);
ledger.set({ settlement: { kind: input.resolveContentAsk !== undefined ? "approver_unavailable" : "no_approver", who: { party: "none" }, when: Date.now() }, origin: pass.decision.origin });
pass.deniedBy = "ask_resolution";
pass.decision = refusalOf({
action: "deny",
message: "AskUserQuestion could not be parked for a durable human answer on this path (no checkpoint " +
"facility, or the suspend failed) and a synchronous permission approver cannot carry an answer — " +
"the question was NOT shown to anyone. Proceed with your best judgment and state the assumption " +
"you made.",
}, finalArgs);
}
else {
pass.decision = { action: "allow" };
}
}
if (pass.decision.action === "ask") {
let askBeforeResolve = pass.decision;
const resolveOnce = (d) => (callSignal !== undefined ? resolveAsk(d, pass.req, callSignal) : resolveAsk(d, pass.req));
let resolved = await resolveOnce(askBeforeResolve);
const refallback = settleNoRulingAsk({ ask: askBeforeResolve, mintedHere: noRulingMinted, resolved: { action: resolved.action, settlement: attestationOf(resolved, pass.req)?.settlement }, tracker: input.autoMode?.denialTracking });
if (refallback !== undefined && askBeforeResolve.action === "ask") {
askBeforeResolve = fallbackAskOf(askBeforeResolve, refallback, toolName);
resolved = await resolveOnce(askBeforeResolve);
}
resolved = ledger.fromResolved(resolved, askBeforeResolve, pass.req);
if (resolved.action === "deny")
pass.deniedBy = "ask_resolution";
pass.decision = resolved.action === "deny" ? refusalOf(resolved, finalArgs) : resolved;
if (resolved.action === "deny" && resolved.approverUnavailable === true && suspendAsk && pass.parkFailed === undefined) {
const parked = await parkAsk(askBeforeResolve, pass.req, pass.currentInput, safety, true, originFacts.org);
if (parked)
return parked;
}
if (askBeforeResolve.action === "ask" && askBeforeResolve.denialLimitFallback !== undefined) {
if (pass.decision.action === "allow") {
input.autoMode?.denialTracking?.recordAllow();
}
else if ((resolved.action === "deny" &&
ledger.settled !== undefined &&
(SETTLEMENT_NOBODY_JUDGED[ledger.settled.settlement.kind] || ledger.settled.settlement.kind === "approver_unavailable")) ||
resolved.approverUnavailable === true) {
try {
input.onHeadlessDenialLimit?.({ toolName, toolCallId, fallback: unarmedWindow(askBeforeResolve.denialLimitFallback) });
}
catch {
}
}
}
approvedWithArgs = pass.decision.action === "allow" && pass.decision.updatedInput !== undefined;
}
}
if (approvedWithArgs && pass.decision.action === "allow" && pass.decision.updatedInput !== undefined) {
let editArgs = pass.decision.updatedInput;
let editDenied;
let editRewrittenSinceHuman = false;
let unanswered;
const refusedAtResolution = (d) => { editDenied = d; pass.deniedBy = "ask_resolution"; };
for (let round = 0;; round++) {
const taken = ownArgs(editArgs);
if (!taken.ok) {
editDenied = { action: "deny", message: unownedArgsMessage(`the approved edit for "${toolName}"`, taken.reason) };
pass.deniedBy = "policy";
break;
}
editArgs = argsAsTheToolReads(pass.req, taken.value);
if (round >= 3) {
editDenied = {
action: "deny",
message: `the approval-edit chain for "${toolName}" exceeded the re-approval cap — denied fail-closed; re-submit the edited action directly`,
};
pass.deniedBy = "policy";
break;
}
let editHookAsk;
if (screening !== undefined) {
const screened = await screening.screen(editArgs, `the approved edit for "${toolName}"`);
if (screened.kind === "refused") {
editDenied = { action: "deny", message: screened.reason };
pass.deniedBy = "hook";
break;
}
const hr = screened.answer;
if (hr) {
if (hr.additionalContext)
pass.preToolContext.push(hr.additionalContext);
if (hr.action === "deny") {
editDenied = { action: "deny", message: decisionText(hr) ?? `the approved edit for "${toolName}" was blocked by a PreToolUse hook` };
pass.deniedBy = "hook";
break;
}
if (hr.action === "ask") {
const { updatedInput: _adopted, ...ask } = hr;
editHookAsk = ask;
}
if (hr.updatedInput !== undefined) {
editArgs = argsAsTheToolReads(pass.req, hr.updatedInput);
editRewrittenSinceHuman = true;
}
}
}
let recheck = { action: "allow" };
if (adjudicate) {
try {
const editReq = Object.freeze({ toolName, args: editArgs, toolCallId, ...(pass.req.face !== undefined ? { face: pass.req.face } : {}) });
recheck = refuseOutOfContractDecision(await (callSignal !== undefined ? adjudicate(editReq, callSignal) : adjudicate(editReq)));
}
catch (err) {
reportPolicyThrow((e) => traceHookCrash(input, e, notifier), "the tool policy's re-check of the approved edit", { toolName, toolCallId }, err, callSignal ?? input.abortSignal);
recheck = {
action: "deny",
message: `policy re-check of the approved edit for "${toolName}" errored: ${policyThrowLine(err)}`,
};
}
}
{
const attributed = ledger.classifierRoundOf(recheck);
if (attributed !== undefined)
pass.classifierRound = attributed;
const read = ledger.fromDecision(recheck);
recheck = read.decision;
if (recheck.action === "deny" && read.deniedBy !== undefined) {
editDenied = recheck;
pass.deniedBy = read.deniedBy;
pass.denyCause = ledger.causeOf(recheck);
break;
}
}
if (recheck.updatedInput !== undefined) {
editArgs = argsAsTheToolReads(pass.req, recheck.updatedInput);
editRewrittenSinceHuman = true;
}
const editOrg = await applyOrgLayer(recheck, editArgs);
recheck = editOrg.decision;
if (recheck.action === "deny") {
editDenied = recheck;
break;
}
let editLane;
const editLaneReq = Object.freeze(await withArgsReading(pass.req, editArgs, callSignal ?? input.abortSignal));
if (input.persistedRules !== undefined && wireOf("lanes.persistedEditSkip", pass.req) !== ASK_USER_QUESTION_TOOL_NAME) {
editLane = await readPersistedRules(editLaneReq);
const editTightened = applyPersistedTightening(recheck, editLane, editLaneReq);
recheck = editTightened.decision;
if (editTightened.tightened === "deny")
pass.deniedBy = "persisted_rule";
if (recheck.action === "deny") {
editDenied = recheck;
break;
}
}
const editSkillRefusal = skillRowRefusal(input.skillGrants, editLaneReq);
if (editSkillRefusal !== undefined) {
editDenied = editSkillRefusal;
pass.deniedBy = "policy";
break;
}
if (recheck.action === "allow") {
if (recheck.updatedInput !== undefined) {
editArgs = argsAsTheToolReads(pass.req, recheck.updatedInput);
editRewrittenSinceHuman = true;
}
if (editRewrittenSinceHuman && asksUnstated(recheck, permissionSeatAt(input, editArgs)?.seat, input.permissionMode?.())) {
recheck = { action: "ask", message: permissionSeatAt(input, editArgs)?.question ?? unstatedAskMessage(toolName) };
pass.tightenedBy = "unstated";
}
}
if (recheck.updatedInput !== undefined) {
editArgs = argsAsTheToolReads(pass.req, recheck.updatedInput);
editRewrittenSinceHuman = true;
}
let editFacts;
const stampEditAsk = (ask) => {
const editAskSnapshot = { ...ask, ruleEvidence: mintRuleEvidence({ dotsAbsent: "not_adjudicated" }) };
if (editFacts === undefined) {
markedThisRound = undefined;
editFacts = askOriginFacts(editOrg.org, editLane);
}
return stampAskOrigin(editAskSnapshot, editFacts, classifyStanding(editAskSnapshot, editFacts));
};
if (editHookAsk !== undefined)
recheck = foldHookAsk(recheck, editHookAsk);
let editDecision = recheck.action === "ask" ? stampEditAsk(recheck) : recheck;
if (carriedOwnAsk !== undefined) {
const { updatedInput: _theOriginalBytes, ...carried } = carriedOwnAsk;
const rra = carried.requiresRealApproval === true ? { requiresRealApproval: true } : {};
editDecision = stampEditAsk(editDecision.action === "ask" ? { ...editDecision, foldedAskClasses: [...(editDecision.foldedAskClasses ?? []), ...decisionAskClassesOf(carried), ...(carried.classes ?? [])], ...rra } : carried);
carriedOwnAsk = undefined;
}
const editRead = await checkTool(editDecision, editArgs, editOrg.org, undefined);
if (editRead?.kind === "denied") {
refuseByExtension(editRead.deny);
editDenied = editRead.deny;
break;
}
if (editRead?.kind === "approved") {
carriedOwnAsk = editRead.outstanding ?? (editDecision.action === "ask" ? editDecision : undefined);
editArgs = editRead.allow.updatedInput;
editRewrittenSinceHuman = false;
continue;
}
if (editRead?.kind === "asked" && editRead.marked === true)
editFacts = undefined;
if (editRead?.kind === "asked")
editDecision = stampEditAsk(editRead.ask);
else if (editRead?.kind === "shadowed" && editDecision.action === "ask")
editDecision = { ...editDecision, allowRuleShadowed: [...(editDecision.allowRuleShadowed ?? []), ...editRead.shadows] };
if (editDecision.action !== "ask")
break;
const editAskDecision = editDecision;
if (input.permissionMode !== undefined && pass.askClassification !== undefined) {
const editVerdict = arbitrateByMode(input.permissionMode(), pass.askClassification, { ...(editAskDecision.origin !== undefined ? { origin: editAskDecision.origin } : {}), ...(editAskDecision.mandate !== undefined ? { mandate: editAskDecision.mandate } : {}) });
if (editVerdict.kind === "released") {
ledger.supersede();
pass.arbitration = editVerdict;
await notifier.notifyAsync(() => input.onModeReleased?.({ toolName, toolCallId, release: { mode: editVerdict.mode, askClass: editVerdict.askClass, classes: editVerdict.classes, ...(editVerdict.origin !== undefined ? { origin: editVerdict.origin } : {}), ...(editVerdict.mandate !== undefined ? { mandate: editVerdict.mandate } : {}), ...(editVerdict.reason !== undefined ? { reason: editVerdict.reason } : {}) }, ...(pass.shellReadUnestablished === true ? { readUnestablished: true } : {}) }), "toolGate.onModeReleased");
break;
}
if (editVerdict.kind === "denied_by_mode") {
ledger.supersede();
pass.arbitration = editVerdict;
editDenied = { action: "deny", message: `the approved edit for "${toolName}" raised a new approval requirement that the ${editVerdict.mode} permission mode refuses`, decisionReason: "mode" };
pass.deniedBy = "mode";
break;
}
}
const editAskReq = Object.freeze({ toolName, args: editArgs, toolCallId, ...(pass.req.face !== undefined ? { face: pass.req.face } : {}) });
if (suspendAsk !== undefined && markedUnresolvable()) {
unanswered = { ask: editAskDecision, req: editAskReq, org: editOrg.org };
break;
}
const rr = ledger.fromResolved(await (callSignal !== undefined ? resolveAsk(editAskDecision, editAskReq, callSignal) : resolveAsk(editAskDecision, editAskReq)), editAskDecision, editAskReq);
if (rr.action !== "allow") {
refusedAtResolution(rr);
if (rr.approverUnavailable === true)
unanswered = { ask: editAskDecision, req: editAskReq, org: editOrg.org, deny: rr };
break;
}
if (rr.updatedInput === undefined) {
editRewrittenSinceHuman = false;
break;
}
editArgs = rr.updatedInput;
editRewrittenSinceHuman = false;
}
const rejudged = () => editDenied === undefined || editDenied === unanswered?.deny;
if (rejudged() && editRewrittenSinceHuman && input.writeProtectionCheck !== undefined) {
const check = input.writeProtectionCheck;
const verdict = await awaitWriteProtectionJudgment((deadline) => check(toolName, editArgs, pass.req.face, input.trackedCwd?.(), deadline), boundedAwaitDeadlineMs, callSignal ?? input.abortSignal);
if (verdict !== undefined && verdict.kind !== "clear") {
editDenied = {
action: "deny",
message: verdict.kind === "hit"
? `the approved edit for "${toolName}" was rewritten by the restriction chain onto a write-protected path (table entry "${verdict.hit.name}") that no approval covers — denied fail-closed; re-submit the edited action directly`
: `the approved edit for "${toolName}" was rewritten by the restriction chain onto a target whose destination could not be determined (target_unresolved: ${verdict.cause}) — denied fail-closed; re-submit the edited action directly`,
};
pass.deniedBy = "write_protection";
}
}
if (rejudged() && input.shellReadCheck !== undefined) {
const station = input.shellReadCheck;
const judged = station.judge(pass.req, editArgs, input.trackedCwd?.(), callSignal ?? input.abortSignal, { seat: "rejudge", toolCallId });
if (judged !== null) {
let verdict;
try {
verdict = await withGateTimeout(judged, boundedAwaitDeadlineMs(), callSignal ?? input.abortSignal, "shellReadStation");
}
catch {
verdict = station.unanswered(pass.req, "the read station could not answer");
}
const reading = readStationAnswer(verdict, { toolName, toolCallId, report: (e) => traceHookCrash(input, e, notifier) });
if (reading.kind !== "vouch") {
editDenied = {
action: "deny",
message: reading.verdict.sentence ?? `the approved edit for "${toolName}" reads where the read boundary does not vouch — denied fail-closed; re-submit the command as a fresh call and answer its card`,
};
pass.deniedBy = "read_boundary";
if (reading.verdict.details !== undefined)
pass.denyDetails = reading.verdict.details;
}
}
}
if (unanswered !== undefined && editDenied === unanswered.deny && pass.parkFailed === undefined) {
const parked = await parkAsk(unanswered.ask, unanswered.req, editArgs, safetyOf(unanswered.ask), unanswered.deny !== undefined || undefined, unanswered.org);
if (parked)
return parked;
}
if (unanswered !== undefined && unanswered.deny === undefined && editDenied === undefined)
refusedAtResolution(ledger.fromResolved(await (callSignal !== undefined ? resolveAsk(unanswered.ask, unanswered.req, callSignal) : resolveAsk(unanswered.ask, unanswered.req)), unanswered.ask, unanswered.req));
pass.decision = editDenied !== undefined ? refusalOf(editDenied, editArgs) : { ...pass.decision, updatedInput: editArgs };
}
return await exitGate(pass);
}