fix: address PR #14 review feedback (exposure layer)#15
Conversation
…n get_filter, clean stale metadata/ - Rename `exposure/redaction.py` → `exposure/metadata.py` (name now matches behavior) - `apply_exposure()` removes pre-existing `metadata/` dir in `student_public` mode to prevent hidden-truth leakage on path reuse - `get_filter()` now accepts `str | ExposureMode` with automatic coercion - Add regression test for path-reuse leakage and string-mode acceptance test Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
pr-agent-context report: No unresolved review comments, failing checks, or actionable patch coverage gaps were found on PR
#15. Treat this PR as all clear unless new signals appear.Run metadata: |
There was a problem hiding this comment.
Pull request overview
This PR refines the exposure layer to better match naming/behavior, prevent hidden-truth leakage when reusing output directories, and broaden get_filter() to accept string exposure modes with appropriate errors.
Changes:
- Renames the exposure metadata writer module to
metadata.pyand updates imports. - Ensances
apply_exposure()to delete any pre-existingmetadata/directory when writingstudent_publicbundles. - Updates
get_filter()to acceptstr | ExposureModeand adds regression/behavior tests for string modes and path reuse.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| tests/exposure/test_exposure.py | Adds tests for string-mode support and for removing stale metadata/ on output path reuse. |
| leadforge/exposure/modes.py | Updates metadata writer import and removes existing metadata/ for student_public mode. |
| leadforge/exposure/metadata.py | Houses metadata writing logic (module renamed from redaction.py); minor comment cleanup. |
| leadforge/exposure/filters.py | Widens get_filter() to accept string modes via ExposureMode(mode) coercion and updates docs/errors. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| elif meta_dir.exists(): | ||
| shutil.rmtree(meta_dir) |
There was a problem hiding this comment.
shutil.rmtree(meta_dir) will raise if bundle_root/metadata exists but is not a directory (e.g., a file). Since this cleanup runs in student_public mode to prevent leakage on path reuse, consider handling both cases (remove dir tree when it’s a dir; unlink when it’s a file/symlink) so save() can’t fail due to an unexpected existing path.
| elif meta_dir.exists(): | |
| shutil.rmtree(meta_dir) | |
| elif meta_dir.exists() or meta_dir.is_symlink(): | |
| if meta_dir.is_symlink() or not meta_dir.is_dir(): | |
| meta_dir.unlink() | |
| else: | |
| shutil.rmtree(meta_dir) |
Summary
redaction.py→metadata.py— module writes metadata, not redactions; name now matches behaviormetadata/on path reuse —apply_exposure()removes any pre-existingmetadata/dir when mode isstudent_public, preventing accidental hidden-truth leakageget_filter()signature — now acceptsstr | ExposureModewith automatic coercion viaExposureMode(mode)Addresses all 4 Copilot review comments from #14.
Test plan
🤖 Generated with Claude Code