feat: vendor permission system source

This commit is contained in:
云服务部-叶林立
2026-08-19 14:35:19 +08:00
parent 198584daf8
commit 410c50a3e5
809 changed files with 157793 additions and 139 deletions
@@ -0,0 +1,41 @@
---
issue: 44
issue_title: "Auto-allow /dev/null in external directory checks"
---
# Retro: #44 — Auto-allow /dev/null in external directory checks
## Final Retrospective (2026-05-03T14:30:00Z)
### Session summary
Planned, implemented, shipped, and released (v3.2.0) a hardcoded allowlist of safe OS device paths (`/dev/null`, `/dev/stdin`, `/dev/stdout`, `/dev/stderr`) that are excluded from the `external_directory` permission gate.
The change touched one source file (`src/external-directory.ts`) and two test files, with a docs update to `README.md`.
The user challenged the security model mid-planning ("could agents use `/dev/null` to destroy files?"), which strengthened the plan's Risks section.
### Observations
#### What went well
- The user's security challenge during planning ("should this be a setting?") prompted a thorough analysis of `cat /dev/null > file` scenarios.
This analysis showed that the external-directory gate never protected against in-CWD truncation (the tokenizer splits on `>`, so the redirect target and `/dev/null` are separate tokens).
The resulting two new Risks rows made the plan more defensible and the commit history shows the reasoning for future readers.
- TDD steps 56 collapsed into one commit because `extractExternalPathsFromBashCommand` delegates to `isPathOutsideWorkingDirectory`.
Recognizing the transitive coverage during execution avoided an unnecessary implementation commit without losing test coverage.
#### What caused friction (agent side)
- `instruction-violation` — Used a literal `|` inside a backtick span in a markdown table cell in the plan.
Markdownlint's MD056 does not exempt inline code from column-count validation, so the pre-commit hook rejected the commit.
Required a follow-up edit to escape as `\|`.
Impact: one failed commit attempt + one fixup edit.
Self-identified after the lint failure (not user-caught).
#### What caused friction (user side)
- No friction observed.
The user's mid-planning challenge was well-timed — it arrived after the initial plan was committed but before implementation, which is the ideal moment for security review.
### Changes made
1. No `AGENTS.md` or prompt changes — the pipe-in-table escape rule was proposed but the user declined it (the lint catches it anyway).