Files
my-pi/pi-permission-system/docs/retro/0044-auto-allow-dev-null.md

42 lines
2.3 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
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).