Example

Decide whether to trust a project

See what triggers a project-trust decision, how a saved decision outranks the default, and why AGENTS.md is not a trigger.

Pi asks a project-trust question only when the working directory holds something that would load, and the answer decides which protected resources load. The order is command-line flag, then a project_trust extension, then a saved decision, then defaultProjectTrust. Context files such as AGENTS.md are not a trigger and load either way. This is a decision-table walkthrough of the Chapter 8 tests.

What triggers a decision

Present from the working directory Decision required
.pi/settings.json yes
.pi/mcp.json yes
.pi/extensions, .pi/skills, .pi/prompts, .pi/themes yes
.pi/SYSTEM.md, .pi/APPEND_SYSTEM.md yes
.agents/skills in this or an ancestor directory yes
a bare .pi directory no
AGENTS.md or CLAUDE.md no — a context file

Trust is requested because something would load, not merely because .pi exists. A context file carries instructions and arrives regardless of the answer, which is why declining trust does not stop it.

Saved decisions

Decisions are stored by canonical directory path in <agent-dir>/trust.json. The closest path applies, so a parent decision covers its children:

{
  "<canonical-directory>": true,
  "<canonical-directory>/subdir": false
}

Persisting a decision is what /trust does. Setting a path to null clears it.

The decision order

Order Source Notes
1 --approve / --no-approve outranks everything, including an extension
2 project_trust handler first handler returning a decision owns it
3 saved decision in trust.json closest ancestor path wins
4 defaultProjectTrust agent-directory setting, default "ask"

Print, JSON and RPC modes cannot show the prompt, so with nothing above them "always" loads protected resources while "ask" and "never" skip them. Use --approve or --no-approve for an explicit one-time answer in a script.

Mechanism and limitations

Documented: the pinned security.md trigger list, the trust.json location, and defaultProjectTrust. Observed: trust.test.ts checks each trigger, including that context files ask nothing, and decision.test.ts runs the shipped pi in print mode with a project extension that writes a flag file, pinning the order above and that a saved decision beats the default.

The order is a loading gate, not a sandbox: once Pi runs, enabled tools use the process’s operating-system permissions. One contract detail the shipped binary showed: a project_trust handler returns an object, { trusted: "yes" | "no" | "undecided", remember?: boolean }, not a bare string; a bare string is silently ignored. The fragments here are illustrative.

Full source and tests .

Understand this example

Copy this prompt into your AI tool. No code runs here.

Apply this example

Copy this prompt into your AI tool. No code runs here.