fix: generalize workflow-gate orthogonal relief to all phases, allow out-of-repo paths (#164)#327
Conversation
…out-of-repo paths (#164) The RESEARCH-phase relief added in #174 scoped Edit/Write blocking to the current subtask's affected_files, but only during RESEARCH, and it deliberately kept blocking any path resolving entirely outside the repo. A second report against neuro-vlad hit the identical block during INIT_STATE while editing ~/.claude/CLAUDE.md, a path outside that repo's tree entirely. is_orthogonal_to_current_subtask() now treats out-of-repo paths as unconditionally orthogonal (no subtask's affected_files can ever legitimately name a path outside the repo it was declared in), and the orthogonal-relief exception in main() now fires for any blocking phase, not just RESEARCH. scope_glob constraints still apply independently after the relief when configured. Updated ~22 tests using an absolute "/test.py" placeholder path that incidentally resolved outside the tmp_path repo root (would have silently flipped from DENY to ALLOW under the new out-of-repo relief) to a repo-relative path, added 5 new tests covering the INIT_STATE and DECOMPOSE cases, and flipped the existing out-of-repo test to its new expected behavior. The Bash-write bypass (cat >, tee, sed -i) remains a documented, deliberately deferred limitation.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (9)
📝 WalkthroughWalkthroughThe workflow gate's orthogonality check now treats any path that cannot be normalized to a repo-relative path as automatically orthogonal (allowed), and the "orthogonal hotfix" exception in ChangesWorkflow gate orthogonal relief
Estimated code review effort: 4 (Complex) | ~45 minutes Possibly related issues
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Summary
workflow-gate.py's orthogonal-file relief (added in fix(workflow-gate): scope RESEARCH block to current subtask's affected_files (#164) #174 for RESEARCH) now fires during any blocking phase — not just RESEARCH. A second report on workflow-gate blocks Edit/Write during RESEARCH for unrelated/orthogonal fixes (and is bypassable via Bash) #164 hit the identical block during INIT_STATE.~/.claude/CLAUDE.mdwhile a MAP session is active in a different repo) are now unconditionally allowed, regardless of phase — no subtask'saffected_filescan ever legitimately name a path outside the repo tree it was declared in.affected_filesremain blocked until the appropriate phase passes;scope_globconstraints still apply independently after the relief.cat >,tee,sed -i) remains an explicitly deferred, documented limitation — not part of this fix.Single-source change in
src/mapify_cli/templates_src/hooks/workflow-gate.py.jinjaand its codex siblingsrc/mapify_cli/templates_src/codex/hooks/workflow-gate.py.jinja, rendered into all 4 generated trees (.claude/hooks/,.codex/hooks/, bothtemplates/mirrors) viamake render-templates.Test plan
pytest tests/test_workflow_gate.py -v— 52/52 passed, including 5 new tests (INIT_STATE relief, INIT_STATE counter-test, INIT_STATE out-of-repo repro, DECOMPOSE out-of-repo, DECOMPOSE in-repo counter-test) and the flippedtest_research_orthogonal_out_of_repo_allowed/test.pyplaceholder path that incidentally resolved outsidetmp_path(would have silently flipped 8 DENY-asserting tests to ALLOW under the new out-of-repo relief) — changed to a repo-relative path; verified none of the ALLOW-asserting tests depended on the old out-of-repo resolutionmake check(lint + full test suite +check-render) — 3255 passed, 3 skipped, 12 deselected, all green/security-reviewon the diff — no findings (this hook is a process-discipline nudge for an already-fully-trusted local agent, not a privilege boundary;file_pathis never attacker-controlled;scope_globstill enforces independently after the relief)Closes #164
🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
Bug Fixes