@barry-rocks/sdk/bounds
The bound and trait types and the policy machinery behind them:
BoundSchema, tool metadata, native-tool policy, and execution scopes.
Policy resolution explains how these
combine into a session’s policy.
import { … } from "@barry-rocks/sdk/bounds";Interfaces
Section titled “Interfaces”AgentTrait
Section titled “AgentTrait”Agent Trait — a named capability granted to a task. Traits enable: they grant namespaces and/or individual tools with an access level.
Properties
Section titled “Properties”| Property | Type | Description |
|---|---|---|
access |
Access |
Access level granted to all namespaces and tools in this trait |
bound? |
Bound |
Restrictions carried by this trait. Merged (union of denials) with any barry/session bound at resolution time. Lets a trait bundle a policy with its grants — e.g. the coding trait grants git tools but denies raw git/gh in Bash so all git goes through the structured tools. |
boundNames? |
string[] |
Named bounds whose restrictions this trait carries — resolved and merged at session bound time. |
harnessTraits? |
Record<string, string> |
- |
includes? |
string[] |
Composite: includes other traits |
name |
string |
- |
namespaces |
string[] |
Tool namespaces this trait enables — all tools in a namespace are granted |
nativeTools? |
Record<string, string[]> |
- |
tools? |
string[] |
Individual tools this trait enables — takes precedence over namespace grants. Entries should be qualified namespace:tool ids; a bare tool name is legacy, matches that name in EVERY namespace, and emits a deprecation warning at resolution. Prefer "sentry:search_issues" over "search_issues". |
BashClassification
Section titled “BashClassification”Result of classifying one command line.
Properties
Section titled “Properties”BoundGuardTool
Section titled “BoundGuardTool”Properties
Section titled “Properties”| Property | Type |
|---|---|
handler |
(params, context) => Promise<unknown> |
name |
string |
schema? |
Readonly<Record<string, unknown>> |
ExecutionContext
Section titled “ExecutionContext”Properties
Section titled “Properties”| Property | Type |
|---|---|
allowedToolIds |
string[] |
bound |
Bound | null |
harness? |
string |
identity? |
string |
traits |
string[] |
FileWriteFinding
Section titled “FileWriteFinding”Properties
Section titled “Properties”| Property | Type | Description |
|---|---|---|
path? |
string |
The file the command appears to write, when the shape reveals it. |
reason |
string |
Short reason, e.g. “sed -i” or “> a source file”. Safe to show an agent. |
McpAnnotations
Section titled “McpAnnotations”MCP tool annotations — advisory hints about a tool’s behavior. Local mirror of the MCP spec’s ToolAnnotations to avoid SDK coupling.
Properties
Section titled “Properties”| Property | Type |
|---|---|
destructiveHint? |
boolean |
idempotentHint? |
boolean |
openWorldHint? |
boolean |
readOnlyHint? |
boolean |
title? |
string |
NativeHarness
Section titled “NativeHarness”Properties
Section titled “Properties”| Property | Type |
|---|---|
bag? |
object |
bag.manifest |
Pick<BagManifest, "name" | "bounds"> |
defaultMode? |
ModeId |
id |
string |
label? |
string |
modes? |
Partial<Record<ModeId, Pick<Mode, "native"> | null>> |
nativeTools |
readonly string[] |
NativePolicy
Section titled “NativePolicy”Properties
Section titled “Properties”| Property | Type |
|---|---|
allowed |
string[] |
conflicts |
Record<string, string> |
denied |
string[] |
operatorOverride? |
string |
refused |
Record<string, string> |
uncontrolled |
Record<string, string> |
ResolvedTraitGrants
Section titled “ResolvedTraitGrants”Properties
Section titled “Properties”| Property | Type | Description |
|---|---|---|
byNamespace |
ResolvedTraits |
namespace → access |
byTool |
ResolvedTraits |
qualified namespace:tool id → access (explicit per-tool grants). Keyed on the qualified id, never a bare name: two bags may both export status, and a grant for a bare status previously admitted every namespace’s status AND took precedence over the namespace grant. A caller resolves a tool’s grant with toolGrant(grants, namespace, tool). |
byToolLegacy |
ResolvedTraits |
Legacy bare-tool-name grants (tools: ["status"], no namespace). Kept for backward compatibility with manifests that have not qualified their tools: entries. A bare name matches that name in ANY namespace, which is the imprecision SDK-4 is about, so each one emits a one-time deprecation warning. Prefer qualified ns:tool ids. |
ToolMeta
Section titled “ToolMeta”Metadata for a tool — namespace, name, and whether it reads or writes. This is just metadata, not the tool itself.
Properties
Section titled “Properties”| Property | Type | Description |
|---|---|---|
access |
"read" | "write" |
- |
annotations? |
McpAnnotations |
MCP annotations from the tool’s upstream server or definition. |
contractHash? |
string |
Trusted catalog evidence for the versioned input/output contract. |
namespace |
string |
- |
toolName |
string |
- |
Type Aliases
Section titled “Type Aliases”Access
Section titled “Access”Access =
"read"|"readwrite"
Access level for agent capabilities.
- “read”: observe without side effects
- “readwrite”: observe and modify
ExecutionScope
Section titled “ExecutionScope”ExecutionScope =
z.infer<typeofexecutionScopeSchema>
ResolvedTraits
Section titled “ResolvedTraits”ResolvedTraits =
Map<string,Access>
Resolved traits — the output of resolving a task’s traits. Maps namespace or toolName → effective access level.
Variables
Section titled “Variables”ALLOW_DOMAINS_NEEDS_SANDBOX
Section titled “ALLOW_DOMAINS_NEEDS_SANDBOX”
constALLOW_DOMAINS_NEEDS_SANDBOX: “network.allowDomains is enforced only by the egress sandbox: add network.enforce: "sandbox", or deny hosts with network.domains instead” = “network.allowDomains is enforced only by the egress sandbox: add network.enforce: "sandbox", or deny hosts with network.domains instead”
Why a bound naming network.allowDomains without enforce: "sandbox" is
refused: only the egress sandbox can enforce an allowlist, so under the
guards it would read as a restriction and restrict nothing.
BoundSchema
Section titled “BoundSchema”
constBoundSchema:ZodObject<{bash:ZodOptional<ZodObject<{deny:ZodOptional<ZodArray<ZodString>>;denyPrograms:ZodOptional<ZodArray<ZodString>>; },$strict>>;deniedAccess:ZodOptional<ZodArray<ZodString>>;deniedTools:ZodOptional<ZodArray<ZodString>>;description:ZodOptional<ZodString>;files:ZodOptional<ZodObject<{allowOnly:ZodOptional<ZodArray<ZodString>>;deny:ZodOptional<ZodArray<ZodString>>; },$strict>>;name:ZodOptional<ZodString>;nativeTools:ZodOptional<ZodRecord<ZodString,ZodArray<ZodString>>>;network:ZodOptional<ZodObject<{actions:ZodOptional<ZodArray<ZodEnum<{all:"all";dns:"dns";git:fetch:"git:fetch";git:push:"git:push";http:read:"http:read";http:write:"http:write";read:"read";ssh:read:"ssh:read";ssh:write:"ssh:write";write:"write"; }>>>;allowDomains:ZodOptional<ZodArray<ZodString>>;domains:ZodOptional<ZodArray<ZodString>>;enforce:ZodOptional<ZodEnum<{guard:"guard";sandbox:"sandbox"; }>>; },$strict>>;nodes:ZodOptional<ZodObject<{allow:ZodOptional<ZodArray<ZodString>>;deny:ZodOptional<ZodArray<ZodString>>; },$strict>>; },$strict>
Strict at every level, for the same reason network.actions is an enum
rather than a string: a restriction that fails to parse is loud, while one
that parses into an empty object denies nothing and is indistinguishable
from a working bound. A misspelled denyProgram or deniedTool must not
leave the session quietly unrestricted.
CORE_NAMESPACES
Section titled “CORE_NAMESPACES”
constCORE_NAMESPACES:Set<string>
Barry’s own namespaces, as opposed to a vendor’s.
This no longer decides which namespaces get their own /mcp/ns/<namespace>
endpoint — every namespace does, which is what gives the agent
mcp__linear__* and mcp__git__* instead of one flat mcp__barry__*.
Its only remaining job is cosmetic: on the aggregate /mcp endpoint, where
everything really does share the mcp__barry__ prefix, vendor tools get a
[Linear] tag on their description to show where they came from. Tagging
Barry’s own tools there would be noise.
executionScopeSchema
Section titled “executionScopeSchema”
constexecutionScopeSchema:ZodObject<{bound:ZodNullable<ZodObject<{bash:ZodOptional<ZodObject<{deny:ZodOptional<ZodArray<ZodString>>;denyPrograms:ZodOptional<ZodArray<ZodString>>; },$strict>>;deniedAccess:ZodOptional<ZodArray<ZodString>>;deniedTools:ZodOptional<ZodArray<ZodString>>;description:ZodOptional<ZodString>;files:ZodOptional<ZodObject<{allowOnly:ZodOptional<ZodArray<ZodString>>;deny:ZodOptional<ZodArray<ZodString>>; },$strict>>;name:ZodOptional<ZodString>;nativeTools:ZodOptional<ZodRecord<ZodString,ZodArray<ZodString>>>;network:ZodOptional<ZodObject<{actions:ZodOptional<ZodArray<ZodEnum<…>>>;allowDomains:ZodOptional<ZodArray<ZodString>>;domains:ZodOptional<ZodArray<ZodString>>;enforce:ZodOptional<ZodEnum<{guard: …;sandbox: …; }>>; },$strict>>;nodes:ZodOptional<ZodObject<{allow:ZodOptional<ZodArray<ZodString>>;deny:ZodOptional<ZodArray<ZodString>>; },$strict>>; },$strict>>;contracts:ZodOptional<ZodRecord<ZodString,ZodString>>;fingerprint:ZodString;harness:ZodOptional<ZodString>;identity:ZodOptional<ZodString>;tools:ZodRecord<ZodString,ZodEnum<{read:"read";write:"write"; }>>;traits:ZodArray<ZodString>; },$strict>
NATIVE_CATEGORIES
Section titled “NATIVE_CATEGORIES”
constNATIVE_CATEGORIES: readonly ["shell","file-reads","file-writes","network"]
NETWORK_TOOL_ACTIONS
Section titled “NETWORK_TOOL_ACTIONS”
constNETWORK_TOOL_ACTIONS:Record<string,string[]>
Static map of MCP/structured tool names to their network action tags.
Keys are bare tool names as a bag defines them — push, not
mcp__git__push. Tools no longer repeat their namespace, so these match the
git bag’s own names. A key naming a tool that does not exist is silently
inert, so entries must be kept in step with the bag (git_clone sat here
for a while against a tool that was never defined).
NETWORK_TOOL_URL_PARAMS
Section titled “NETWORK_TOOL_URL_PARAMS”
constNETWORK_TOOL_URL_PARAMS:Record<string,string>
Tools whose parameters carry a URL that domain rules should apply to. Maps tool name → the parameter holding the URL.
Without this, domains only ever constrained Bash, so denying
*.internal.co still left WebFetch https://api.internal.co working.
Functions
Section titled “Functions”applyBoundGuards()
Section titled “applyBoundGuards()”applyBoundGuards<
T>(tools,scope):T[]
Type Parameters
Section titled “Type Parameters”| Type Parameter |
|---|
T extends BoundGuardTool |
Parameters
Section titled “Parameters”| Parameter | Type |
|---|---|
tools |
T[] |
scope |
Bound |
Returns
Section titled “Returns”T[]
approveExecutionScope()
Section titled “approveExecutionScope()”approveExecutionScope(
options):Promise<{bound: {bash?: {deny?:string[];denyPrograms?:string[]; };deniedAccess?:string[];deniedTools?:string[];description?:string;files?: {allowOnly?:string[];deny?:string[]; };name?:string;nativeTools?:Record<string,string[]>;network?: {actions?: ("read"|"write"|"all"|"git:push"|"git:fetch"|"http:write"|"http:read"|"ssh:write"|"ssh:read"|"dns")[];allowDomains?:string[];domains?:string[];enforce?:"guard"|"sandbox"; };nodes?: {allow?:string[];deny?:string[]; }; } |null;contracts?:Record<string,string>;fingerprint:string;harness?:string;identity?:string;tools:Record<string,"read"|"write">;traits:string[]; }>
Resolve explicit selections. No identity/default trait union occurs here.
Parameters
Section titled “Parameters”| Parameter | Type |
|---|---|
options |
{ boundByName: (name) => Promise<Bound | null | undefined>; bounds?: readonly (Bound | null | undefined)[]; harness?: string; identity?: string; tools: ToolMeta[]; traitNames: readonly string[]; traits: Record<string, AgentTrait>; } |
options.boundByName |
(name) => Promise<Bound | null | undefined> |
options.bounds? |
readonly (Bound | null | undefined)[] |
options.harness? |
string |
options.identity? |
string |
options.tools |
ToolMeta[] |
options.traitNames |
readonly string[] |
options.traits |
Record<string, AgentTrait> |
Returns
Section titled “Returns”Promise<{ bound: { bash?: { deny?: string[]; denyPrograms?: string[]; }; deniedAccess?: string[]; deniedTools?: string[]; description?: string; files?: { allowOnly?: string[]; deny?: string[]; }; name?: string; nativeTools?: Record<string, string[]>; network?: { actions?: ("read" | "write" | "all" | "git:push" | "git:fetch" | "http:write" | "http:read" | "ssh:write" | "ssh:read" | "dns")[]; allowDomains?: string[]; domains?: string[]; enforce?: "guard" | "sandbox"; }; nodes?: { allow?: string[]; deny?: string[]; }; } | null; contracts?: Record<string, string>; fingerprint: string; harness?: string; identity?: string; tools: Record<string, "read" | "write">; traits: string[]; }>
assertNodeAllowed()
Section titled “assertNodeAllowed()”assertNodeAllowed(
nodeId,bound?):void
Parameters
Section titled “Parameters”| Parameter | Type |
|---|---|
nodeId |
string |
bound? |
Bound | null |
Returns
Section titled “Returns”void
assertScopeDelegation()
Section titled “assertScopeDelegation()”assertScopeDelegation(
scope,delegator,catalog):void
Parameters
Section titled “Parameters”| Parameter | Type |
|---|---|
scope |
{ bound: { bash?: { deny?: string[]; denyPrograms?: string[]; }; deniedAccess?: string[]; deniedTools?: string[]; description?: string; files?: { allowOnly?: string[]; deny?: string[]; }; name?: string; nativeTools?: Record<string, string[]>; network?: { actions?: ("read" | "write" | "all" | "git:push" | "git:fetch" | "http:write" | "http:read" | "ssh:write" | "ssh:read" | "dns")[]; allowDomains?: string[]; domains?: string[]; enforce?: "guard" | "sandbox"; }; nodes?: { allow?: string[]; deny?: string[]; }; } | null; contracts?: Record<string, string>; fingerprint: string; harness?: string; identity?: string; tools: Record<string, "read" | "write">; traits: string[]; } |
scope.bound |
{ bash?: { deny?: string[]; denyPrograms?: string[]; }; deniedAccess?: string[]; deniedTools?: string[]; description?: string; files?: { allowOnly?: string[]; deny?: string[]; }; name?: string; nativeTools?: Record<string, string[]>; network?: { actions?: ("read" | "write" | "all" | "git:push" | "git:fetch" | "http:write" | "http:read" | "ssh:write" | "ssh:read" | "dns")[]; allowDomains?: string[]; domains?: string[]; enforce?: "guard" | "sandbox"; }; nodes?: { allow?: string[]; deny?: string[]; }; } | null |
scope.contracts? |
Record<string, string> |
scope.fingerprint |
string |
scope.harness? |
string |
scope.identity? |
string |
scope.tools |
Record<string, "read" | "write"> |
scope.traits |
string[] |
delegator |
ExecutionContext |
catalog |
readonly ToolMeta[] |
Returns
Section titled “Returns”void
assertToolAllowed()
Section titled “assertToolAllowed()”assertToolAllowed(
context,tool,nodeId):void
Parameters
Section titled “Parameters”| Parameter | Type |
|---|---|
context |
ExecutionContext |
tool |
Pick<ToolMeta, "namespace" | "toolName"> |
nodeId |
string |
Returns
Section titled “Returns”void
boundHasContent()
Section titled “boundHasContent()”boundHasContent(
bound?):boolean
True if a bound carries any actual restriction (not just {}).
network.enforce counts: a bound of {network:{enforce:"sandbox"}} is a
real instruction to escalate enforcement, and dropping it here would strip
that escalation before it ever reached the merge.
Parameters
Section titled “Parameters”| Parameter | Type |
|---|---|
bound? |
Bound |
Returns
Section titled “Returns”boolean
classifyBashCommand()
Section titled “classifyBashCommand()”classifyBashCommand(
command):BashClassification
Classify a command line: which programs it invokes, plus a fail-closed flag.
Parameters
Section titled “Parameters”| Parameter | Type |
|---|---|
command |
string |
Returns
Section titled “Returns”classifyFileWrite()
Section titled “classifyFileWrite()”classifyFileWrite(
command):FileWriteFinding|null
Does this command look like it writes a file?
Returns null when it doesn’t (the common case — most commands are builds, tests, greps and git). Never throws.
Parameters
Section titled “Parameters”| Parameter | Type |
|---|---|
command |
string |
Returns
Section titled “Returns”FileWriteFinding | null
classifyNetworkActions()
Section titled “classifyNetworkActions()”classifyNetworkActions(
classification,rawCommand):string[]
Given a BashClassification and the raw command string, return all network action tags the command would perform.
Parameters
Section titled “Parameters”| Parameter | Type |
|---|---|
classification |
BashClassification |
rawCommand |
string |
Returns
Section titled “Returns”string[]
expandActions()
Section titled “expandActions()”expandActions(
actions):Set<string>
Expand a set of action tags to include all descendants. e.g. [“write”] → {“write”, “git:push”, “http:write”, “ssh:write”}
Parameters
Section titled “Parameters”| Parameter | Type |
|---|---|
actions |
string[] |
Returns
Section titled “Returns”Set<string>
expandTraitNames()
Section titled “expandTraitNames()”expandTraitNames(
names,traits,harness?):string[]
Expand selected traits, including the compound for the actual harness.
Parameters
Section titled “Parameters”| Parameter | Type |
|---|---|
names |
readonly string[] |
traits |
Readonly<Record<string, AgentTrait>> |
harness? |
string |
Returns
Section titled “Returns”string[]
extractDomainsFromCommand()
Section titled “extractDomainsFromCommand()”extractDomainsFromCommand(
command):string[]
Parameters
Section titled “Parameters”| Parameter | Type |
|---|---|
command |
string |
Returns
Section titled “Returns”string[]
filterTools()
Section titled “filterTools()”filterTools(
tools,traitNames,allTraits,bound?,harness?):string[]
Filter tools based on traits and optional bound.
Returns BARE names, which cannot distinguish two namespaces exporting the
same tool. Use filterToolsQualified for authorization decisions.
Parameters
Section titled “Parameters”| Parameter | Type |
|---|---|
tools |
ToolMeta[] |
traitNames |
string[] |
allTraits |
Record<string, AgentTrait> |
bound? |
Bound |
harness? |
string |
Returns
Section titled “Returns”string[]
filterToolsQualified()
Section titled “filterToolsQualified()”filterToolsQualified(
tools,traitNames,allTraits,bound?,harness?):string[]
Filter tools based on traits and optional bound, returning QUALIFIED ids.
- Resolve traits → namespace grants + explicit tool grants
- Filter tools: include if namespace or toolName is enabled AND access permits
- Exclude denied tools (by namespace or toolName)
- Exclude write tools for deniedAccess entries
- Exclude tools implied by network action restrictions
- Return
namespace:toolNamefor each survivor
Prefer this over filterTools anywhere the result gates invocation. The
bare-name version cannot express “this name from that namespace” and is kept
only for callers that genuinely want names for display.
Parameters
Section titled “Parameters”| Parameter | Type |
|---|---|
tools |
ToolMeta[] |
traitNames |
string[] |
allTraits |
Record<string, AgentTrait> |
bound? |
Bound |
harness? |
string |
Returns
Section titled “Returns”string[]
getImpliedDeniedTools()
Section titled “getImpliedDeniedTools()”getImpliedDeniedTools(
actions):string[]
Return tool names that should be denied based on network action restrictions. Used by filterTools to expand the denied set.
Parameters
Section titled “Parameters”| Parameter | Type |
|---|---|
actions |
string[] |
Returns
Section titled “Returns”string[]
intersectExecutionScope()
Section titled “intersectExecutionScope()”intersectExecutionScope(
approved,current,catalog,restrictions?):ExecutionContext
Each bound must allow the operation; grants can only shrink after approval.
Parameters
Section titled “Parameters”| Parameter | Type | Default value |
|---|---|---|
approved |
{ bound: { bash?: { deny?: string[]; denyPrograms?: string[]; }; deniedAccess?: string[]; deniedTools?: string[]; description?: string; files?: { allowOnly?: string[]; deny?: string[]; }; name?: string; nativeTools?: Record<string, string[]>; network?: { actions?: ("read" | "write" | "all" | "git:push" | "git:fetch" | "http:write" | "http:read" | "ssh:write" | "ssh:read" | "dns")[]; allowDomains?: string[]; domains?: string[]; enforce?: "guard" | "sandbox"; }; nodes?: { allow?: string[]; deny?: string[]; }; } | null; contracts?: Record<string, string>; fingerprint: string; harness?: string; identity?: string; tools: Record<string, "read" | "write">; traits: string[]; } |
undefined |
approved.bound |
{ bash?: { deny?: string[]; denyPrograms?: string[]; }; deniedAccess?: string[]; deniedTools?: string[]; description?: string; files?: { allowOnly?: string[]; deny?: string[]; }; name?: string; nativeTools?: Record<string, string[]>; network?: { actions?: ("read" | "write" | "all" | "git:push" | "git:fetch" | "http:write" | "http:read" | "ssh:write" | "ssh:read" | "dns")[]; allowDomains?: string[]; domains?: string[]; enforce?: "guard" | "sandbox"; }; nodes?: { allow?: string[]; deny?: string[]; }; } | null |
... |
approved.contracts? |
Record<string, string> |
... |
approved.fingerprint |
string |
... |
approved.harness? |
string |
... |
approved.identity? |
string |
... |
approved.tools |
Record<string, "read" | "write"> |
... |
approved.traits |
string[] |
... |
current |
ExecutionContext |
undefined |
catalog |
readonly ToolMeta[] |
undefined |
restrictions |
readonly (Bound | null)[] |
[] |
Returns
Section titled “Returns”isBashDenied()
Section titled “isBashDenied()”isBashDenied(
command,deny):string|null
Check if a bash command matches any deny pattern. Patterns are substrings matched against the command string.
Parameters
Section titled “Parameters”| Parameter | Type |
|---|---|
command |
string |
deny |
string[] |
Returns
Section titled “Returns”string | null
isDomainDenied()
Section titled “isDomainDenied()”isDomainDenied(
domain,domains):string|null
Check if a domain matches any deny pattern. Patterns support wildcards: “*.foo.com” matches “api.foo.com” and “x.y.foo.com”. Exact match: “staging.example.com” matches only that domain.
Parameters
Section titled “Parameters”| Parameter | Type |
|---|---|
domain |
string |
domains |
string[] |
Returns
Section titled “Returns”string | null
isFileAllowed()
Section titled “isFileAllowed()”isFileAllowed(
filePath,allowOnly):string|null
Check if a file path matches any allowOnly pattern. Returns the matching pattern, or null when NOTHING allows it — under an allowOnly bound that null is a denial, and the caller treats it as one.
Parameters
Section titled “Parameters”| Parameter | Type |
|---|---|
filePath |
string |
allowOnly |
string[] |
Returns
Section titled “Returns”string | null
isFileDenied()
Section titled “isFileDenied()”isFileDenied(
filePath,deny):string|null
Check if a file path matches any deny pattern. Returns the matching pattern, or null when nothing denies it.
Parameters
Section titled “Parameters”| Parameter | Type |
|---|---|
filePath |
string |
deny |
string[] |
Returns
Section titled “Returns”string | null
isNetworkActionDenied()
Section titled “isNetworkActionDenied()”isNetworkActionDenied(
command,actions):string|null
Check if a bash command performs a denied network action. Returns the matched action tag, or null if allowed.
Parameters
Section titled “Parameters”| Parameter | Type |
|---|---|
command |
string |
actions |
string[] |
Returns
Section titled “Returns”string | null
isProgramDenied()
Section titled “isProgramDenied()”isProgramDenied(
command,denyPrograms):string|null
Decide whether a command is denied by denyPrograms rules.
Rules:
"git"— deny any invocation of git."git:push"— deny onlygit push …."gh:pr:create"— deny onlygh pr create …(multi-level subcommand).
Matching is on resolved program basenames + subcommand chains, so git -C /x push, FOO=1 git push, cd a && git push, (git push), git push | tee,
xargs git push, /usr/bin/git push, and bash -c "git push" all match,
while gh pr view is allowed under a gh:pr:create rule.
Fails closed: if the line couldn’t be safely tokenized AND any deny rule exists, returns a deny (so obfuscation can’t slip a denied program through).
Parameters
Section titled “Parameters”| Parameter | Type |
|---|---|
command |
string |
denyPrograms |
string[] |
Returns
Section titled “Returns”string | null
the matched rule string, or null if allowed.
mergeBounds()
Section titled “mergeBounds()”mergeBounds(
base,override):Bound|null
Parameters
Section titled “Parameters”| Parameter | Type |
|---|---|
base |
Bound | null |
override |
Bound | null |
Returns
Section titled “Returns”Bound | null
mergeNetwork()
Section titled “mergeNetwork()”mergeNetwork(
base?,override?): {actions?:string[];allowDomains?:string[];domains?:string[];enforce?:"guard"|"sandbox"; } |undefined
Parameters
Section titled “Parameters”| Parameter | Type | Description |
|---|---|---|
base? |
{ actions?: string[]; allowDomains?: string[]; domains?: string[]; enforce?: "guard" | "sandbox"; } |
- |
base.actions? |
string[] |
Network actions to deny. Entries are hierarchical action tags: “all” — all network access “write” — all outbound writes (git:push, http:write, ssh:write) “read” — all outbound reads (git:fetch, http:read, dns) “git:push” — git push specifically “git:fetch” — git fetch/pull/clone “http:write” — HTTP POST/PUT/PATCH/DELETE “http:read” — HTTP GET/HEAD “ssh:write” — scp upload, rsync push “ssh:read” — ssh connections “dns” — DNS lookups (dig, nslookup, host) Parent tags expand to include their children: “write” implies “git:push” + “http:write” + “ssh:write”. |
base.allowDomains? |
string[] |
Destination hosts the session may reach, enforced by the agent runtime’s egress proxy. Requires enforce: "sandbox": the app-level guards cannot enforce an allowlist, so a bound that sets this without it is refused. This is the inverse of domains, and the two are NOT interchangeable: a deny-list says nothing about which of the infinite remaining hosts are acceptable. Both may be set; they are independent layers and a host present in domains is denied regardless of this list. Omitting it under enforce: "sandbox" means an EMPTY allowlist — no egress except localhost. Opening a host is always an explicit act. |
base.domains? |
string[] |
Destination domains to deny. Supports wildcards: “*.internal.co” matches “api.internal.co”. Best-effort — inspects URL arguments in bash commands (curl, wget, git clone). Cannot cover bag proxy tools or dynamically constructed URLs. |
base.enforce? |
"guard" | "sandbox" |
Enforcement level: “guard” (default) — application-level tool/command interception only. Cooperative safety rail with clear error messages. “sandbox” — adds the agent runtime’s process-tree sandbox: outbound traffic is forced through an egress proxy that filters by HOSTNAME (see allowDomains), and the agent cannot lift it. Covers write-to-disk bypasses and network binaries the command classifier doesn’t know. It filters by host, not by HTTP method, so partial action denials (e.g. actions: [“write”]) still rely on the guards. |
override? |
{ actions?: string[]; allowDomains?: string[]; domains?: string[]; enforce?: "guard" | "sandbox"; } |
- |
override.actions? |
string[] |
Network actions to deny. Entries are hierarchical action tags: “all” — all network access “write” — all outbound writes (git:push, http:write, ssh:write) “read” — all outbound reads (git:fetch, http:read, dns) “git:push” — git push specifically “git:fetch” — git fetch/pull/clone “http:write” — HTTP POST/PUT/PATCH/DELETE “http:read” — HTTP GET/HEAD “ssh:write” — scp upload, rsync push “ssh:read” — ssh connections “dns” — DNS lookups (dig, nslookup, host) Parent tags expand to include their children: “write” implies “git:push” + “http:write” + “ssh:write”. |
override.allowDomains? |
string[] |
Destination hosts the session may reach, enforced by the agent runtime’s egress proxy. Requires enforce: "sandbox": the app-level guards cannot enforce an allowlist, so a bound that sets this without it is refused. This is the inverse of domains, and the two are NOT interchangeable: a deny-list says nothing about which of the infinite remaining hosts are acceptable. Both may be set; they are independent layers and a host present in domains is denied regardless of this list. Omitting it under enforce: "sandbox" means an EMPTY allowlist — no egress except localhost. Opening a host is always an explicit act. |
override.domains? |
string[] |
Destination domains to deny. Supports wildcards: “*.internal.co” matches “api.internal.co”. Best-effort — inspects URL arguments in bash commands (curl, wget, git clone). Cannot cover bag proxy tools or dynamically constructed URLs. |
override.enforce? |
"guard" | "sandbox" |
Enforcement level: “guard” (default) — application-level tool/command interception only. Cooperative safety rail with clear error messages. “sandbox” — adds the agent runtime’s process-tree sandbox: outbound traffic is forced through an egress proxy that filters by HOSTNAME (see allowDomains), and the agent cannot lift it. Covers write-to-disk bypasses and network binaries the command classifier doesn’t know. It filters by host, not by HTTP method, so partial action denials (e.g. actions: [“write”]) still rely on the guards. |
Returns
Section titled “Returns”Type Literal
Section titled “Type Literal”{ actions?: string[]; allowDomains?: string[]; domains?: string[]; enforce?: "guard" | "sandbox"; }
| Name | Type | Description |
|---|---|---|
actions? |
string[] |
Network actions to deny. Entries are hierarchical action tags: “all” — all network access “write” — all outbound writes (git:push, http:write, ssh:write) “read” — all outbound reads (git:fetch, http:read, dns) “git:push” — git push specifically “git:fetch” — git fetch/pull/clone “http:write” — HTTP POST/PUT/PATCH/DELETE “http:read” — HTTP GET/HEAD “ssh:write” — scp upload, rsync push “ssh:read” — ssh connections “dns” — DNS lookups (dig, nslookup, host) Parent tags expand to include their children: “write” implies “git:push” + “http:write” + “ssh:write”. |
allowDomains? |
string[] |
Destination hosts the session may reach, enforced by the agent runtime’s egress proxy. Requires enforce: "sandbox": the app-level guards cannot enforce an allowlist, so a bound that sets this without it is refused. This is the inverse of domains, and the two are NOT interchangeable: a deny-list says nothing about which of the infinite remaining hosts are acceptable. Both may be set; they are independent layers and a host present in domains is denied regardless of this list. Omitting it under enforce: "sandbox" means an EMPTY allowlist — no egress except localhost. Opening a host is always an explicit act. |
domains? |
string[] |
Destination domains to deny. Supports wildcards: “*.internal.co” matches “api.internal.co”. Best-effort — inspects URL arguments in bash commands (curl, wget, git clone). Cannot cover bag proxy tools or dynamically constructed URLs. |
enforce? |
"guard" | "sandbox" |
Enforcement level: “guard” (default) — application-level tool/command interception only. Cooperative safety rail with clear error messages. “sandbox” — adds the agent runtime’s process-tree sandbox: outbound traffic is forced through an egress proxy that filters by HOSTNAME (see allowDomains), and the agent cannot lift it. Covers write-to-disk bypasses and network binaries the command classifier doesn’t know. It filters by host, not by HTTP method, so partial action denials (e.g. actions: [“write”]) still rely on the guards. |
undefined
nativeToolDenials()
Section titled “nativeToolDenials()”nativeToolDenials(
bound,harness,inventory):string[]
Parameters
Section titled “Parameters”| Parameter | Type |
|---|---|
bound |
Bound | null | undefined |
harness |
string |
inventory |
readonly string[] |
Returns
Section titled “Returns”string[]
nativeToolsTakenBack()
Section titled “nativeToolsTakenBack()”nativeToolsTakenBack(
bound,harness):string[]
Native calls bypass Barry’s guards, so a guarded restriction takes back the category.
Parameters
Section titled “Parameters”| Parameter | Type |
|---|---|
bound |
Bound | null | undefined |
harness |
NativeHarness |
Returns
Section titled “Returns”string[]
nativeToolStatus()
Section titled “nativeToolStatus()”nativeToolStatus(
traits,bound,harness,mode?):object
Parameters
Section titled “Parameters”| Parameter | Type |
|---|---|
traits |
readonly AgentTrait[] |
bound |
Bound | null | undefined |
harness |
NativeHarness |
mode? |
ModeId |
Returns
Section titled “Returns”object
| Name | Type |
|---|---|
allowed |
string[] |
denied |
string[] |
refused |
Record<string, string> |
uncontrolled |
object |
qualifyToolId()
Section titled “qualifyToolId()”qualifyToolId(
namespace,toolName):string
The identity a tool is authorized under: namespace AND name, never one alone.
Two bags may both export status. Authorization is decided per (namespace,
name) — filterToolsQualified below gets that right — but returning a bare
name collapses the pair, and a consumer testing membership by name then
admits every tool sharing an allowed name. Granting system also admitted
git’s status.
Parameters
Section titled “Parameters”| Parameter | Type |
|---|---|
namespace |
string |
toolName |
string |
Returns
Section titled “Returns”string
resolveEffectiveBound()
Section titled “resolveEffectiveBound()”resolveEffectiveBound(
options):Promise<Bound|null>
One restriction chain for native enforcement and MCP guards.
Parameters
Section titled “Parameters”| Parameter | Type |
|---|---|
options |
{ boundByName: (name) => Promise<Bound | null | undefined>; bounds?: readonly (Bound | null | undefined)[]; harness?: string; traitNames: readonly string[]; traits: Readonly<Record<string, AgentTrait>>; } |
options.boundByName |
(name) => Promise<Bound | null | undefined> |
options.bounds? |
readonly (Bound | null | undefined)[] |
options.harness? |
string |
options.traitNames |
readonly string[] |
options.traits |
Readonly<Record<string, AgentTrait>> |
Returns
Section titled “Returns”Promise<Bound | null>
resolveExecutionContext()
Section titled “resolveExecutionContext()”resolveExecutionContext(
options):Promise<ExecutionContext>
No default grants: the caller supplies all selected traits.
Parameters
Section titled “Parameters”| Parameter | Type |
|---|---|
options |
{ boundByName: (name) => Promise<Bound | null | undefined>; bounds?: readonly (Bound | null | undefined)[]; harness?: string; identity?: string; tools: ToolMeta[]; traitNames: readonly string[]; traits: Record<string, AgentTrait>; } |
options.boundByName |
(name) => Promise<Bound | null | undefined> |
options.bounds? |
readonly (Bound | null | undefined)[] |
options.harness? |
string |
options.identity? |
string |
options.tools |
ToolMeta[] |
options.traitNames |
readonly string[] |
options.traits |
Record<string, AgentTrait> |
Returns
Section titled “Returns”Promise<ExecutionContext>
resolveNativePolicy()
Section titled “resolveNativePolicy()”resolveNativePolicy(
grants,harness,mode?):NativePolicy
Parameters
Section titled “Parameters”| Parameter | Type |
|---|---|
grants |
{ bound: Bound | null; tools: readonly Tool[]; } |
grants.bound |
Bound | null |
grants.tools |
readonly Tool[] |
harness? |
NativeHarness |
mode? |
ModeId |
Returns
Section titled “Returns”resolveTraits()
Section titled “resolveTraits()”resolveTraits(
traitNames,allTraits,harness?):ResolvedTraitGrants
Resolve a list of trait names into namespace and tool grant maps.
Expands composite traits (via includes), then unions all grants.
When multiple traits grant the same namespace or tool with different access
levels, the more permissive level wins (readwrite > read).
AgentTrait.tools entries may be qualified (ns:tool) or a bare legacy
name. Qualified ids key byTool; a bare name keys byToolLegacy and warns.
Parameters
Section titled “Parameters”| Parameter | Type |
|---|---|
traitNames |
string[] |
allTraits |
Record<string, AgentTrait> |
harness? |
string |
Returns
Section titled “Returns”scopeFingerprint()
Section titled “scopeFingerprint()”scopeFingerprint(
value):string
Canonical policy evidence; never contains credentials or transport tokens.
Parameters
Section titled “Parameters”| Parameter | Type |
|---|---|
value |
unknown |
Returns
Section titled “Returns”string
validateNativeTools()
Section titled “validateNativeTools()”validateNativeTools(
manifest,harness):void
An adapter bag cannot grant or deny a native name its harness does not offer.
Parameters
Section titled “Parameters”| Parameter | Type |
|---|---|
manifest |
Pick<BagManifest, "name" | "bounds" | "traits"> |
harness |
Pick<NativeHarness, "id" | "nativeTools"> |
Returns
Section titled “Returns”void
References
Section titled “References”Re-exports Bound