Skip to content

@intutic/gate / core

@intutic/gate ​

Classes ​

Interfaces ​

Decision ​

Properties ​

PropertyTypeDescription
reasonstringThe rule's reason and [id]; for a hold, the reason alone, which the gate words as a hold.
ruleIdstring-
severitySeverity | nullnull means allow.

ExecutableTool ​

Indexable ​

ts
[key: string]: unknown

Properties ​

PropertyType
executeAnyFn
name?string

GateClientOptions ​

Options for a GateClient. Every field is optional.

Properties ​

PropertyTypeDefault valueDescription
apiKey?string''The API key. Without one the client is local-only.
baseUrl?stringINTUTIC_CONTROL_PLANE_URL, then Intutic's hosted control planeThe control plane's address.
failClosed?booleantrueBlock a call when the hook gate gives no verdict: the control plane cannot be reached, answers without one, or answers GOVERNANCE_UNAVAILABLE. false lets such a call go ahead.
harness?string'generic'Attributes incidents to the right adapter. Sent as harnessType on every gate call and event.
sessionId?string''-
timeoutMs?number2000How long one control-plane request may take.
workspaceId?string''-

GateConfig ​

How a Gate evaluates calls. Every field is optional.

Extended by ​

Properties ​

PropertyTypeDefault valueDescription
allowlistPath?string'.intutic/image-allowlist.json'The image allowlist, relative to repoRoot unless absolute.
enforce?booleantruefalse turns Gate.guard into a no-op.
repoRoot?string'.'Where relative manifest and allowlist paths resolve from.
useHookGate?booleantrueCall the control plane's hook gate (needs a client).
useSopRules?booleantrueFetch and apply the workspace's SOP rules (needs a client).
workspaceId?string''Compared with the workspace the policy snapshot was compiled for, and scopes the SOP-rule fetch.

GateResponse ​

Properties ​

PropertyTypeDescription
allowedboolean-
code?stringThe code the hook gate names, when it names one: the MCP registry's on its refusals, GOVERNANCE_UNAVAILABLE when its checks could not run, and INVALID_REQUEST when it could not read the request.
decisionId?stringThe hook gate's id for this decision, when this answer is its own verdict: every verdict it gives names one, and a GOVERNANCE_UNAVAILABLE refusal keeps it only while failClosed refuses too. The gate reports the call with it (gateDecisionId), so the control plane exports the decision to SIEM once and files its incident once.
incidentId?string-
reachedbooleanFalse when the hook gate gave no verdict and failClosed decided it.
reasonstring-

ImagePolicy ​

Properties ​

PropertyType
images?Record<string, { approved_digests?: string[]; }>
registries_allowed?string[]
require_digest?boolean

ImageRef ​

A parsed container image reference.

Properties ​

PropertyTypeDescription
digeststring | nullsha256:... or null
rawstring-
repositorystringregistry/namespace/name, no tag, no digest
sourcestringwhich manifest file it came from
tagstring | null-

IntuticHeadersOptions ​

Port of intutic_headers() from packages/intutic-clawde/intutic_clawde/gate/framework.py.

Properties ​

PropertyTypeDescription
harness?stringAttributes traces to this adapter. Defaults to "generic".
sessionId?string-
workspaceId?string-

McpAllowlistRecord ​

The workspace's mcpAllowedServers list as the gates apply it: only the listed servers may be called, and under shadow (an observe-only workspace) a call to another is recorded instead of refused. A workspace with no list has no record.

Properties ​

PropertyType
serversstring[]
severity"block" | "shadow"

McpRegistryRecord ​

What the registry decides, per workspace. The MCP proxy's McpRegistryPolicy has the same shape.

Properties ​

PropertyTypeDescription
approvedServersstring[]-
blockedServersstring[]-
defaultPolicy"deny" | "allow"-
disabledToolsRecord<string, string[]>Server name → tool names disabled within it.
heldServersstring[]Servers a high-risk tool change returned to the approval queue; refused under either default.

Rule ​

Properties ​

PropertyTypeDescription
idstring-
patternRegExp-
reasonstring-
severitystring-
steps?RegExp[][] | nullA sequence rule's compiled steps (flags s, sequence.ts), or null. The rule is matched by searching for its steps in order, in linear time, rather than by pattern, which a backtracking engine runs in time growing with the square of the text. Absent on a rule built by hand, which is matched by pattern.
subjectRuleSubject-

SopRegister ​

The register as GET /api/v1/sop/rules answers it: the rules, and whether the workspace's intervention mode is OPAQUE (interventionMode, absent from a control plane that predates it, which reads as not OPAQUE). The gate uses the mode when there is no policy snapshot to read it from.

Properties ​

PropertyType
opaqueboolean
rulesSopRule[]

SopRule ​

Properties ​

PropertyType
actionstring
argPatternstring | null
idstring
reasonstring
toolPatternstring

SsoGroupPolicy ​

Properties ​

PropertyType
highRiskToolsstring[]
requiredGroupsstring[]
requireOboForstring[]

SsoGroupRecord ​

Properties ​

PropertyType
issuedAtstring
member| { memberId: string; ssoGroups: string[]; } | null
policySsoGroupPolicy

WrapToolOptions ​

Options for wrapTool.

Properties ​

PropertyTypeDescription
gate?GateOverrides the process-wide installed gate for this tool only.
name?stringTool name reported to the gate. Defaults to the function's own .name (or the tool object's .name), then falls back to "tool".

Type Aliases ​

AnyFn ​

ts
type AnyFn = (...args) => any;

Parameters ​

ParameterType
...argsany[]

Returns ​

any


GateRefusalCode ​

ts
type GateRefusalCode = typeof GATE_REFUSAL_CODES[number];

ImageRefusalCode ​

ts
type ImageRefusalCode = 
  | typeof E_UNPINNED_LATEST
  | typeof E_UNPINNED_TAG
  | typeof E_UNKNOWN_REGISTRY
  | typeof E_UNKNOWN_IMAGE
  | typeof E_DIGEST_MISMATCH
  | typeof E_MANIFEST_UNPARSEABLE;

ImageVerdict ​

ts
type ImageVerdict = 
  | {
  code: "";
  detail: string;
  images: ImageRef[];
  ok: true;
}
  | {
  code: ImageRefusalCode;
  detail: string;
  images: ImageRef[];
  ok: false;
};

code is '' on a pass and names the failure otherwise.


RuleSubject ​

ts
type RuleSubject = "tool" | "command" | "target" | "phrase" | "action" | "any";

phrase: the source is |-separated phrases matched as words (phrases.ts), not a regex. action: the source is matched against the action tokens the command classifies to (" action:deploy ", actions.ts) — what a local review_before: action:<name> compiles to.


Severity ​

ts
type Severity = 
  | typeof SEV_SHADOW
  | typeof SEV_WARN
  | typeof SEV_BLOCK
  | typeof SEV_HOLD;

SnapshotState ​

ts
type SnapshotState = "ok" | "absent" | "invalid" | "empty" | "stale";

SsoGroupClearance ​

ts
type SsoGroupClearance = "GRANTED" | "DENIED" | "REQUIRES_OBO";

SSO-group tool clearance, read from the policy snapshot.

Port of evaluateSsoGroupClearance and the @sso_groups record in packages/shared-types/src/ssoGroupClearance.ts — the evaluator the control plane's hook gate, the MCP proxy and the sync daemon's snapshot compiler share. This package has no workspace dependencies, so it carries a copy, and src/__tests__/ssoGroups.test.ts runs the shared vectors (packages/shared-types/fixtures/sso-group-clearance-vectors.json) through it so the copy cannot drift. intutic_clawde/gate/sso_groups.py is the Python port of the same thing.

The snapshot's record carries the workspace's policy and the member the snapshot was issued to, with their groups as the control plane resolved them. It sits inside the snapshot's digest; when the digest fails, the gate still applies the policy but treats the member's groups as unknown, so an edited group list clears nothing.


ToolInput ​

ts
type ToolInput = Record<string, unknown>;

Variables ​

ACTION_APPROVAL ​

ts
const ACTION_APPROVAL: "require_approval" = 'require_approval';

ACTION_BLOCK ​

ts
const ACTION_BLOCK: "block" = 'block';

ACTION_WARN ​

ts
const ACTION_WARN: "warn" = 'warn';

ARGUMENTS_SIZE_LIMIT ​

ts
const ARGUMENTS_SIZE_LIMIT: number;

The largest tool arguments, in UTF-8 bytes of compact JSON, the gate evaluates.


COMMAND_SIZE_LIMIT ​

ts
const COMMAND_SIZE_LIMIT: number;

The largest shell command, in UTF-8 bytes, the gate evaluates.


GATE_DEADLINE_MS ​

ts
const GATE_DEADLINE_MS: number;

How long the hook script the sandbox bootstrap writes may run, from process start, before it refuses.


GATE_REFUSAL_CODES ​

ts
const GATE_REFUSAL_CODES: readonly ["SSO_GROUP", "SNAPSHOT", "HELD", "SERVER_BLOCKED", "SERVER_HELD", "SERVER_NOT_APPROVED", "TOOL_DISABLED", "SERVER_NOT_ALLOWED", "POLICY_SNAPSHOT_UNVERIFIED", "SOP_RULE", "HOOK_GATE", "COMMAND_TOO_LARGE", "CHAOS_FAULT", "E_UNPINNED_LATEST", "E_UNPINNED_TAG", "E_UNKNOWN_REGISTRY", "E_UNKNOWN_IMAGE", "E_DIGEST_MISMATCH", "E_MANIFEST_UNPARSEABLE", "WORKFLOW_SANDBOX", "NO_GATE"];

Every code an IntuticGateRefusal can carry: the tier that refused, or for the image-integrity tier the specific failure. Held to packages/shared-types/fixtures/refusal-codes.json (gate) by a test, as the Python gate's list and the gate SDK reference are.


READ_ONLY_TOOLS ​

ts
const READ_ONLY_TOOLS: ReadonlySet<string>;

Tools that cannot change anything. They still get the local snapshot check (Tier A1), but skip the remote gate call (Tier B).


SEV_BLOCK ​

ts
const SEV_BLOCK: "block";

SEV_HOLD ​

ts
const SEV_HOLD: "hold";

A hold rule (a REQUIRE_APPROVAL: SOP, or a local review_before: token): refuses like a block, but asks a person rather than denying — see hold.ts.


SEV_SHADOW ​

ts
const SEV_SHADOW: "shadow";

Severity tiers, in the order the shipped gate handles them.


SEV_WARN ​

ts
const SEV_WARN: "warn";

Functions ​

active() ​

ts
function active(): Gate | null;

The process-wide gate install set, or null.

Returns ​

Gate | null


canonicalJson() ​

ts
function canonicalJson(value): string;

JSON with object keys sorted at every level, so key order never changes a hash.

Parameters ​

ParameterType
valueunknown

Returns ​

string


checkCommand() ​

ts
function checkCommand(
   command, 
   repoRoot, 
   policy
): ImageVerdict;

Full check for a deploy command. The entry point the gate calls.

Parameters ​

ParameterType
commandstring
repoRootstring
policyImagePolicy

Returns ​

ImageVerdict


checkImages() ​

ts
function checkImages(images, policy): ImageVerdict;

Evaluate parsed references against the allowlist. First failure wins.

Parameters ​

ParameterType
imagesreadonly ImageRef[]
policyImagePolicy

Returns ​

ImageVerdict


checkWrittenManifest() ​

ts
function checkWrittenManifest(
   path, 
   content, 
   policy
): ImageVerdict;

Check a manifest at authoring time, before it is ever applied.

Lets the dashboard show the bad image being written a full turn before it is applied — the write is flagged, the apply is blocked.

Parameters ​

ParameterType
pathstring
contentstring
policyImagePolicy

Returns ​

ImageVerdict


classify() ​

ts
function classify(toolName, toolInput): string[];

Classify one tool call into the abstract actions it performs.

Returns prefixed tokens (action:deploy, ...) in the order the Rust/Python emit them. Order matters: the ordering detectors read position in the sequence.

Parameters ​

ParameterType
toolNamestring
toolInputunknown

Returns ​

string[]


evaluate() ​

ts
function evaluate(
   toolName, 
   target, 
   command, 
   snap, 
   guardDisabled?
): Decision;

Evaluate one tool call against the snapshot. First match wins.

Parameters ​

ParameterTypeDefault value
toolNamestringundefined
targetstringundefined
commandstringundefined
snapSnapshotundefined
guardDisabledbooleanfalse

Returns ​

Decision


fetchRegister() ​

ts
function fetchRegister(
   baseUrl, 
   apiKey, 
   workspaceId, 
   timeoutMs?
): Promise<SopRegister | null>;

fetchRules with the workspace's mode: null if the register did not answer.

Parameters ​

ParameterTypeDefault value
baseUrlstringundefined
apiKeystringundefined
workspaceIdstringundefined
timeoutMsnumberFETCH_TIMEOUT_MS

Returns ​

Promise<SopRegister | null>


fetchRules() ​

ts
function fetchRules(
   baseUrl, 
   apiKey, 
   workspaceId, 
   timeoutMs?
): Promise<SopRule[] | null>;

Fetch active VALIDATED rules, or null if they could not be fetched.

null and [] mean different things and the caller must not conflate them: null is "the register did not answer", [] is "the register answered and this workspace has no rules". Only the second is a statement about policy.

Parameters ​

ParameterTypeDefault value
baseUrlstringundefined
apiKeystringundefined
workspaceIdstringundefined
timeoutMsnumberFETCH_TIMEOUT_MS

Returns ​

Promise<SopRule[] | null>


firstMatch() ​

ts
function firstMatch(
   rules, 
   toolName, 
   toolInput
): SopRule | null;

The rule that decides this call: the most severe one matching it (block, then require_approval, then warn), the first of that severity in control-plane order. null when none matches.

Parameters ​

ParameterType
rulesreadonly SopRule[]
toolNamestring
toolInputRecord<string, unknown> | null | undefined

Returns ​

SopRule | null


guardDisabledFromEnv() ​

ts
function guardDisabledFromEnv(): boolean;

Returns ​

boolean


holdKey() ​

ts
function holdKey(toolName, toolInput): object;

The bypass key's call half: the tool and a hash of its arguments.

Parameters ​

ParameterType
toolNamestring
toolInputunknown

Returns ​

object

NameType
targetHashstring
toolNameNormalizedstring

holdMessage() ​

ts
function holdMessage(
   ruleReason, 
   ruleId, 
   outcome
): string;

What the agent is told, held or not recorded — the one place this package words a hold. Says who can approve, and that a retry passes only with the bypass setting on, because "retry after approval" alone is false under the default settings.

Parameters ​

ParameterType
ruleReasonstring
ruleIdstring
outcome{ holdId: string; recorded: boolean; }
outcome.holdIdstring
outcome.recordedboolean

Returns ​

string


install() ​

ts
function install(gate): void;

Set the process-wide gate that wrapped tools use; null clears it.

Parameters ​

ParameterType
gateGate | null

Returns ​

void


intuticHeaders() ​

ts
function intuticHeaders(opts?): Record<string, string>;

Default headers for a client pointed at the Intutic proxy (an OpenAI- compatible chat client, a raw fetch call, etc.).

x-session-id matters: the proxy defaults an unset one to the literal "unknown", which merges every run into a single dashboard session. x-intutic-harness attributes traces to this adapter — the proxy honours it for trace attribution (unknown headers are ignored by older proxies, so it is always safe to send).

Usage:

const client = new OpenAI(\{ baseURL: proxyUrl, defaultHeaders: intuticHeaders(\{ sessionId: runId \}) \})

Parameters ​

ParameterType
optsIntuticHeadersOptions

Returns ​

Record<string, string>


isDeploy() ​

ts
function isDeploy(toolName, toolInput): boolean;

True when this call would deploy — the trigger for the image check.

Parameters ​

ParameterType
toolNamestring
toolInputunknown

Returns ​

boolean


isDeployCommand() ​

ts
function isDeployCommand(toolName, toolInput): boolean;

True when this call should be image-checked.

Parameters ​

ParameterType
toolNamestring
toolInputunknown

Returns ​

boolean


isPinned() ​

ts
function isPinned(img): boolean;

Parameters ​

ParameterType
imgImageRef

Returns ​

boolean


isTest() ​

ts
function isTest(toolName, toolInput): boolean;

True when this call runs a test suite.

Parameters ​

ParameterType
toolNamestring
toolInputunknown

Returns ​

boolean


loadSnapshot() ​

ts
function loadSnapshot(workspaceId?, path?): Snapshot;

Read the policy snapshot the sync daemon compiled: from path, else snapshotPath. A missing file gives an empty snapshot whose state is 'absent'. A snapshot whose digest does not match its rules, or that was compiled for a workspace other than a non-empty workspaceId, is 'invalid': its rules and MCP records are dropped.

Parameters ​

ParameterTypeDefault value
workspaceIdstring''
path?stringundefined

Returns ​

Snapshot


manifestPathsFromCommand() ​

ts
function manifestPathsFromCommand(command): object;

Extract the -f/-k targets from a kubectl/helm command.

Returns {paths, readable}. readable is false when the command applies something we cannot inspect — stdin (-f -), a URL, or a command we could not tokenise. That drives the fail-closed path.

Parameters ​

ParameterType
commandstring

Returns ​

object

NameType
pathsstring[]
readableboolean

parseImageRef() ​

ts
function parseImageRef(raw, source?): ImageRef;

Parse registry/repo:tag@sha256:... into its parts.

Docker's own rule for splitting registry from repository: the first path component is a registry host only if it contains a dot or a colon, or is exactly localhost. This function does not need to make that classification itself — it only needs to find the tag/digest boundary, which is a colon (or @) in the LAST path component; a colon earlier (a registry port, localhost:5000/foo) is left alone.

Parameters ​

ParameterTypeDefault value
rawstringundefined
sourcestring''

Returns ​

ImageRef


parseRegister() ​

ts
function parseRegister(payload): SopRegister;

parseRules, and the interventionMode beside them.

Parameters ​

ParameterType
payloadunknown

Returns ​

SopRegister


parseRules() ​

ts
function parseRules(payload): SopRule[];

Accept the rule list in whichever envelope the control plane used.

/api/v1/sop/rules returns {rules:[...]}, while sibling list endpoints variously return {items:[...]} and {data:[...]}. Reading the wrong key yields zero rules and a tier that enforces nothing while looking healthy — the worst failure a gate can have — so all three are accepted rather than assumed.

Parameters ​

ParameterType
payloadunknown

Returns ​

SopRule[]


ruleMatches() ​

ts
function ruleMatches(
   rule, 
   toolName, 
   toolInputJson
): boolean;

Mirror of matchSopRule, including its silent-skip on bad regex.

Parameters ​

ParameterType
ruleSopRule
toolNamestring
toolInputJsonstring

Returns ​

boolean


serialiseToolInput() ​

ts
function serialiseToolInput(toolInput): string;

The JSON.stringify(tool_input ?? {}) shape every mirror matches against.

JSON.stringify already produces compact separators and preserves insertion order and non-ASCII by default — this function exists mainly so every call site names the contract explicitly rather than calling JSON.stringify inline and drifting on a future edit.

Parameters ​

ParameterType
toolInputRecord<string, unknown> | null | undefined

Returns ​

string


snapshotPath() ​

ts
function snapshotPath(): string;

Where the policy snapshot is read from: INTUTIC_SNAPSHOT_RULES, else ~/.intutic/hooks/policy-snapshot.rules.

Returns ​

string


supportsArgPatterns() ​

ts
function supportsArgPatterns(rules): boolean;

True when the control plane emitted at least one usable argPattern.

A control plane predating intutic-enterprise#14 cannot produce one, so this doubles as a deployment probe — surface it rather than letting the tier be silently inert.

Parameters ​

ParameterType
rulesreadonly SopRule[]

Returns ​

boolean


touchesInfra() ​

ts
function touchesInfra(path): boolean;

True when a written path is infrastructure-as-code.

Parameters ​

ParameterType
pathstring | null | undefined

Returns ​

boolean


verdictReason() ​

ts
function verdictReason(v): string;

The single line an operator sees on the dashboard.

Parameters ​

ParameterType
vImageVerdict

Returns ​

string


wrapTool() ​

Call Signature ​

ts
function wrapTool<T>(fn, opts?): T;

Wrap a single tool — a plain async function, or a { execute, ... } object — so Gate.guard() runs before the real implementation.

The object form returns a NEW object (a shallow copy with execute replaced); it does not mutate the one passed in, since the frameworks this targets tend to hand out tool definitions that are re-used or frozen. Already-wrapped functions/objects pass through unchanged, so wrapping the same tool twice does not double-gate it.

Type Parameters ​
Type Parameter
T extends AnyFn
Parameters ​
ParameterType
fnT
opts?WrapToolOptions
Returns ​

T

Call Signature ​

ts
function wrapTool<T>(tool, opts?): T;

Wrap a single tool — a plain async function, or a { execute, ... } object — so Gate.guard() runs before the real implementation.

The object form returns a NEW object (a shallow copy with execute replaced); it does not mutate the one passed in, since the frameworks this targets tend to hand out tool definitions that are re-used or frozen. Already-wrapped functions/objects pass through unchanged, so wrapping the same tool twice does not double-gate it.

Type Parameters ​
Type Parameter
T extends ExecutableTool
Parameters ​
ParameterType
toolT
opts?WrapToolOptions
Returns ​

T


wrapTools() ​

Call Signature ​

ts
function wrapTools<T>(tools, gate?): T[];

Wrap a collection of tools in one call.

Accepts either an array (tool name comes from each tool's own .name/ function name) or a record keyed by tool name (the Vercel AI SDK / Mastra tools: { myTool: {...} } shape) — in the record form the KEY is always the name reported to the gate, since that is the identity the framework itself uses to invoke the tool.

Type Parameters ​
Type Parameter
T extends ExecutableTool | AnyFn
Parameters ​
ParameterType
toolsreadonly T[]
gate?Gate
Returns ​

T[]

Call Signature ​

ts
function wrapTools<T>(tools, gate?): Record<string, T>;

Wrap a collection of tools in one call.

Accepts either an array (tool name comes from each tool's own .name/ function name) or a record keyed by tool name (the Vercel AI SDK / Mastra tools: { myTool: {...} } shape) — in the record form the KEY is always the name reported to the gate, since that is the identity the framework itself uses to invoke the tool.

Type Parameters ​
Type Parameter
T extends ExecutableTool | AnyFn
Parameters ​
ParameterType
toolsRecord<string, T>
gate?Gate
Returns ​

Record<string, T>

The circuit breaker for AI agents