移除 pi-extension-codex-fast-mode:
- 删除整个扩展目录;同步清理根 package.json 的 files / pi.extensions /
dependencies 条目、package-lock.json、tests/extension-load.test.ts 断言
与文档章节。
- pi-minimal-footer 的 Fast on 渲染是该扩展的唯一消费者。扩展移除后 accent
分支不再有生产者,collectFooterStatusItems 简化为直接返回非空状态字符串,
去掉 FooterStatusItem 与 accent 标志,避免留下死代码。
移除 500 次裁决后的后台分析体系:
- 删除 analysis-agent.ts(192 行)与 ledger.ts(296 行),以及对应的
auto-review-runtime / auto-review-ledger 测试。
- runtime.ts 由 177 行收敛到 85 行:安装选项缩为 { service, config };删除
handleAgentSettled 与 agent_settled 注册;保留 session_start / turn_start
(denial circuit breaker 属安全语义)/ session_shutdown。
- 删除 analysis 配置键:config、extension-config、config-schema、生成的
permissions.schema.json 与种子配置。
- 删除 reviewer 的 onDecision 回调(唯一消费者是 ledger)。
- 删除迁移机制 scripts/migrate-permission-policy.mjs、其测试与 update.sh 中
46 行 migrate_permission_policy 接线。种子部署保持“目标缺失才写入”,已存在
的 policy.jsonc 永不被覆盖。
AutoReview 模型改为纯配置驱动:
- 删除 DEFAULT_PROVIDER / DEFAULT_MODEL 常量与 findCodexTemplate 合成逻辑;
model.ts 由 65 行收敛到 48 行。
- provider / model 任一缺失时返回新增失败类别 model-unconfigured 并 defer 到
人工审批;provider 未注册或模型未发布同样 defer。
- reasoning 不再有默认常量,完全由配置决定。
- session_start 在 auto-review 已列入 authorizerChain 且 provider/model 未配齐
时 ui.notify 提示一次,避免不使用 AutoReview 的用户被打扰。
- 种子 autoReview 只保留 enabled,provider/model/reasoning 由用户按本机实际
可用的模型填写。
破坏性变更:analysis 键已从 strictObject schema 删除,任何仍带该键的
policy.jsonc 会使整份配置被拒(fail-closed 到全 ask)。这是刻意的变更,已由
config-loader 测试固定,防止将来无声放宽。
测试:
- 新增 auto-review-model.test.ts(7 例),覆盖此前完全缺失的模型解析:真实
命中、未配置、provider 未知、模型未发布,以及不再合成替代模型。
- 重写 auto-review-runtime.test.ts(6 例):authorizer 注册、未配置时提示
一次、已配置 / disabled / 无 UI / 不在 chain 时静默。
- config-loader.test.ts 新增 2 例:带 analysis 的旧配置被拒且 fail-closed、
autoReview 逐字段合并。
- composition-root.test.ts 的 EXPECTED_HANDLERS 移除 agent_settled。
文档:AGENTS.md、README.md、pi-permission-system 的 README / CHANGELOG /
configuration.md / architecture.md / auto-review UPSTREAM.md。
验证:pi-permission-system 的 typecheck、2577 个测试与 build 全部通过;根 50
个测试通过;schema 重新生成无漂移;新种子通过 schema 校验;5 个脚本 sh -n
通过;git diff --check 无空白问题。未安装 shellcheck;未执行真实 pi install /
update(属外部写操作)。
@gotgenes/pi-permission-system
Permission enforcement extension for the Pi coding agent that provides centralized, deterministic permission gates over tool, bash, MCP, skill, and special operations.
Fork notice: This package is a full fork of MasuRii/pi-permission-system, published to npm as
@gotgenes/pi-permission-system. It has diverged substantially from upstream in config format, internal architecture, and permission model.my-pi maintenance note: This directory was imported from upstream tag
pi-permission-system-v26.2.1at commitec4fdb11343dc94f7185b113e559a4cf9f8dc035. It is loaded from source and maintained directly by my-pi; npmdistoutput is not used. my-pi uses one global ordinary policy and a separate non-overridable hard-guard file; explicitly configured authorizers may approve any ordinary-policyask, includingpath.
What It Does
- Enforces
allow/ask/denyat tool-call time with UI confirmation dialogs - Uses one global ordinary policy file; project
policy.jsoncfiles are not loaded - Chooses the most specific matching pattern, so a specific deny wins over a broad
"*": "allow"regardless of declaration order - Applies a separate hard-guard policy first so session grants, per-agent rules, and model review cannot override high-risk denies
- Controls Bash, paths, MCP, skills, and tool surfaces while leaving active-tool ownership entirely to Tool Search
- Reviews ordinary
askrequests automatically with integrated AutoReview once you name a review model in config; itsallow/denyverdict is final for ordinary tools andpath, whiledeferreaches the next authorizer or human terminal - Forwards subagent
askdecisions to the parent authority and keeps structured audit logs
Install
pi install npm:@gotgenes/pi-permission-system
Quick Start
-
Create ordinary policy at
~/.pi/agent/extensions/pi-permission-system/policy.jsonc:{ "authorizerChain": ["auto-review"], "permission": { "*": "ask", "read": "allow", "bash": { "*": "ask", "git status*": "allow" } } } -
Create independent hard guards at
~/.pi/agent/extensions/pi-permission-system/hard-guards.jsonc:{ "version": 1, "permission": { "*": "allow", "*.env": "deny", "*.env.*": "deny", "*.env.example": "allow", "~/.ssh/**": "deny" } } -
Restart Pi or run
/reload. Ordinaryaskrequests now reach AutoReview first; onlydeferopens the human dialog.
The path surface is a cross-cutting gate that applies to all file access — Pi tools, bash commands, MCP calls, and extension tools alike.
Extension and MCP tools that operate on paths (via input.path, MCP's input.arguments.path, or a registered access extractor) are gated by default, so a path deny cannot be overridden by a per-tool allow — making it the right place to protect sensitive files like .env or ~/.ssh/* from every tool at once.
A path pattern matches both the path as the agent references it and its canonical (symlink-resolved) form, so a deny still fires when a symlink aliases a sensitive target.
For per-tool path patterns (read, write, edit, find, grep, ls), patterns are matched against the file path from input.path.
This lets you express rules like "allow reads but deny .env files" at the individual tool level.
Like the cross-cutting path surface, per-tool patterns match both the referenced path and its canonical (symlink-resolved) form, so a per-tool deny resists symlink-alias evasion.
When Pi's current working directory is known, relative path inputs also match their cwd-normalized absolute form, so src/App.jsx can match both src/* and /workspace/project/*.
Paths outside the working tree have no separate boundary gate. Configure them with the same path, per-tool, and Bash patterns used for in-project paths. These layers still compose with most-restrictive-wins.
See docs/configuration.md for the full recipe.
Configuration
The integrated extension uses two independent global JSONC files:
| Purpose | Scope | Path |
|---|---|---|
| Ordinary policy, runtime knobs, AutoReview | Global only | ~/.pi/agent/extensions/pi-permission-system/policy.jsonc |
| Non-overridable hard guards | Global only | ~/.pi/agent/extensions/pi-permission-system/hard-guards.jsonc |
Project-level policy.jsonc files are ignored. Project agent Markdown remains a separate per-agent restriction mechanism.
The bundle seeds missing files with mode 0600. During update.sh, only the exact known legacy default policy is backed up and replaced by the current bundled seed. Any customized or invalid policy is preserved and reported instead of being guessed or overwritten.
Within a pattern map, the most specific match wins: exact patterns, then more literal characters, fewer wildcards, and longer patterns. Declaration order is only a tie-breaker.
There is no external_directory gate. Outside-CWD paths use the same configured tool, path, and Bash rules as other paths.
Tool Search alone owns Pi's active tool list. Permission System only decides whether an invoked tool call is allowed, denied, or requires confirmation.
See docs/configuration.md for the complete reference and docs/hard-guards.md for the independent hard-guard format.
Documentation
| Document | Contents |
|---|---|
| docs/configuration.md | Full policy reference, runtime knobs, per-agent overrides, recipes |
| docs/session-approvals.md | Session-scoped rules, pattern suggestions, bash arity table |
| docs/cross-extension-api.md | Cross-extension service accessor, event bus integration, prompt and decision broadcasts |
| docs/subagent-integration.md | Permission forwarding, coexistence with subagent extensions |
| docs/guides/permission-frontmatter-for-subagent-extensions.md | Convention guide for subagent extension authors |
| docs/opencode-compatibility.md | OpenCode compatibility — shared concepts, divergences, porting guide |
| docs/troubleshooting.md | Common issues, diagnostic logging, threat model |
| docs/migration/legacy-to-flat.md | Migration from pre-v2 config layout |
| docs/migration/strict-config-validation.md | Strict config validation (breaking) — rejected configs, and the cross-scope fail-closed clamp |
| docs/migration/0644-project-trust-gating.md | Project-trust gating (breaking) — project config loads only after project trust |
| docs/migration/0745-prompt-payload-contracts.md | Prompt payload contracts (breaking) — the forwarded wire, the ui_prompt broadcast, and the deprecated preview caps |
| docs/migration/0746-review-log-fields.md | Review-log fields (breaking) — message replaced by request facts, and the reviewLogFieldMaxWidth bound |
Development
pnpm run check # Type-check TypeScript (no emit)
pnpm run lint # Biome + ESLint + lint:md
pnpm run lint:md # rumdl on README and docs
pnpm run test # Run tests from ./test
pnpm run test:watch # Run tests in watch mode
Pre-commit hooks
This project uses prek to run Biome, ESLint, and rumdl on staged files before each commit.
Run pnpm install to set up hooks automatically.
Acknowledgments
This project began as a fork of MasuRii/pi-permission-system. Thank you to MasuRii for the original work that made this possible.
Thank you to the OpenCode team for the permission model design that inspired the flat config format and evaluation semantics used in this extension.
