Skip to content

Local Tools and Policy

Some workflows need to run an external program, such as a directory listing or a project-specific utility. Devlish represents that action as a tool request containing a tool name and an argument list. A permission declares which tool the workflow may request; a policy can then decide whether a particular request is allowed.

This page explains the request format, local execution, and policy decisions before showing their syntax. Start with Permissions for the distinction between declared capabilities and the access supplied by a host. Ordinary local execution and signed production admission have different guarantees.

Run catalog tool tool_request as tool_result

Declare the capability separately in the manifest:

Permissions:
Run catalog tool "ls"

Run catalog tools declares the unscoped capability. A scoped permission allows only the named tool.

A complete local workflow can construct the request inline:

Permissions:
Run catalog tool "ls"
Run catalog tool record with "ls" as tool_id and list of "-1" as arguments as tool_result
Respond with "Local tool completed."

In ordinary file mode, tool IDs resolve through the startup working directory and operator PATH. IDs are simple program names, never paths. The startup directories are captured outside model input. This local profile is a location guardrail: allowed programs run with the current user’s access, rather than inside a filesystem or network sandbox. Signed catalog execution and verified admission are separate profiles.

A policy is another Devlish program. It receives the effect and request, then returns a decision and a nonempty reason:

Respond with record with "deny" as decision and "This effect is forbidden." as reason

Decisions are allow, deny, or abstain; legacy boolean allow decisions remain supported. Explicit denials always block. Invalid, conflicting, missing, or failed decisions block as well.

--default-authorization allow-unless-forbidden permits an explicit abstention; deny-unless-allowed blocks it. This flag requires both --policy and a fresh --policy-log path. It never removes program capability checks. In interactive mode, DEVLISH_DEFAULT_AUTHORIZATION selects the posture; the default is allow-unless-forbidden. File mode defaults to denying abstentions.

Local execution bounds each stream to 64 KiB and execution/capture to five seconds. Capture failure, abnormal termination, invalid UTF-8, or exceeded limits withhold output. A normal nonzero exit code is preserved for the program to interpret.

Authorization to execute a tool does not authorize disclosure of its output. Policies can govern subsequent model calls and responses independently; the local example returns a fixed acknowledgement instead of captured filenames.

Default policy logs record commitments and decisions. --policy-evidence opts into sensitive request/result capture for protected replay evidence. Terminal capture evidence and independent verification, signed launch reservations, and one-attempt broker continuation are separate audit mechanisms; ordinary local execution does not establish verified containment.

For runnable examples and exact profile limits, see the local tool guide and application guide.