Skip to content

feat: context-aware path checking for destructive commands#54

Open
dgerlanc wants to merge 19 commits into
mainfrom
worktree-context-aware-mmi
Open

feat: context-aware path checking for destructive commands#54
dgerlanc wants to merge 19 commits into
mainfrom
worktree-context-aware-mmi

Conversation

@dgerlanc

Copy link
Copy Markdown
Owner

Summary

  • Adds directory-aware approval decisions so destructive commands (rm, mv, chmod, chown) can be scoped to specific directories via a per-pattern paths field in config
  • New internal/cmdpath package with command descriptor registry, target extraction, path resolution, and prefix checking
  • Config parsing validates paths usage (only on simple patterns, requires registered descriptor, detects conflicting constraints)
  • Hook approval flow gains a new step after safe-pattern matching that checks extracted paths against allowed prefixes
  • $PROJECT (cwd) and $PROJECT_ROOT (git repo root, worktree-aware) variables for path expressions
  • Fail-closed semantics: unresolvable variables, unknown commands, and ~user paths are rejected
  • New PATH_VIOLATION rejection code and PathCheck audit struct for observability

Example config

[[commands.simple]]
name = "destructive-project-only"
commands = ["rm", "mv", "chmod", "chown"]
paths = ["$PROJECT", "/tmp"]

Test plan

  • Unit tests for each command descriptor (rm, mv, chmod, chown) with flags, --, variables, mode/owner parsing
  • Unit tests for path resolution (tilde expansion, relative paths, prefix checking, directory boundaries)
  • Config validation tests (paths on regex/subcommand rejected, unknown command rejected, conflicting constraints rejected)
  • Integration tests through ProcessWithResult (approved, violated, unresolved, no-paths)
  • End-to-end tests in main_test.go covering 8 scenarios
  • Full test suite passes

dgerlanc added 19 commits March 24, 2026 17:40
Adds a spec for making mmi approval decisions directory-aware,
so destructive commands like rm can be scoped to the project tree.
- Add data flow section showing paths from TOML through Pattern to SafeResult
- Disallow paths on regex patterns (no descriptor lookup possible)
- Specify conflict resolution for overlapping patterns
- Add tilde expansion handling (~/ → $HOME)
- Add -- (end-of-options) handling in all descriptors
- Specify chmod mode and chown owner parsing heuristics
- Specify PATH_VIOLATION uses ask decision (not deny)
- Name new package: internal/cmdpath
- Document cwd absolute path assumption
- List SPEC.md sections requiring updates
Git -C doesn't fit the same descriptor model as rm/mv — it shifts
working context rather than targeting files. Deferred to future work.
Initial scope is now: rm, mv, chmod, chown (destructive only).
A command appearing in both path-constrained and unconstrained
patterns is now a hard error at config load, not a warning.
Adds worked examples for rm showing the full flow from core command
through arg extraction, path resolution, and prefix checking.
Covers flags, relative paths, --, and unresolvable variables.
Worktrees at arbitrary locations (e.g., /tmp/my-worktree) are not
under $PROJECT_ROOT, so users need paths = ["$PROJECT_ROOT", "$PROJECT"]
to cover both the main repo and the worktree.
11 tasks covering: Pattern.Paths field, audit structs, command descriptor
registry, target extraction (rm/mv/chmod/chown), path resolution,
config parsing/validation, hook integration, e2e tests, and SPEC.md updates.
Add extractChmodTargets and extractChownTargets with regex-based heuristics
to distinguish mode/owner arguments from filesystem targets, sharing a
common extractWithFirstArgSkip helper. Remove stub implementations from
extract.go.
Parse the optional `paths` field from TOML simple patterns, thread it through
to patterns.Pattern, and reject paths on regex/subcommand patterns. Validate
that commands with paths have registered descriptors and detect conflicting
patterns where the same command appears with and without path constraints.
- Fail closed if cwd is not absolute (spec requirement)
- Document chmod compound mode regex gap (fail-closed)
- Document chown owner pattern filename matching edge case
- Add Path Constraints section with config examples and variables
- Add path violation audit log example
- Update How It Works and Security Model sections
- Add paths to segment field reference
- Add Key Packages section to CLAUDE.md
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant