fix: catch ArtifactNotFoundError in verify (#30) and validate bundle content on import (#13) - #33
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughCatch ArtifactNotFoundError in verify_source for missing stored content; add bundle content validators (VALIDATORS, validate_content) and run validation in import_check/import_apply; suppress exception chaining in KBStore put* FileExistsError handlers; add a ContextItem type-ignore. ChangesException Handling Fix
Bundle Import Validation
KBStore handler cleanup
Sequence Diagram(s)sequenceDiagram
participant import_check
participant TarFile
participant _validate_content
participant manifest_issues
import_check->>TarFile: read manifest-listed member -> bytes
TarFile->>_validate_content: provide(path, bytes)
_validate_content-->>manifest_issues: append "schema validation failed: ..." (if errors)
import_check->>import_check: classify as new/identical/conflict and include issues
🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
…ouchdev#13) import_apply wrote raw bytes to committed artifact directories without checking file content against the Pydantic models. A crafted bundle could inject malformed YAML or schema-violating artifacts that poison all subsequent list/read operations. - Add per-subdirectory validators (Claim, Page, Entity, Relation, etc.) - Validate content in import_check so issues surface before apply - Validate content in import_apply before writing to disk Fixes vouchdev#13
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (1)
src/vouch/bundle.py (1)
214-220: ⚡ Quick winPrecompute manifest path set once before iterating members.
Line 217 rebuilds the same set on every iteration. Hoisting it out of the loop reduces unnecessary work for larger bundles.
Proposed refactor
bundle_id = manifest.get("bundle_id", "") + manifest_paths = {f["path"] for f in manifest["files"]} for f in manifest["files"]: dest = kb_dir / f["path"] if not dest.exists(): new_files.append(f["path"]) @@ for member in tar.getmembers(): if member.name == MANIFEST_NAME or not member.isfile(): continue - if member.name not in {f["path"] for f in manifest["files"]}: + if member.name not in manifest_paths: continue body = tar.extractfile(member).read() # type: ignore[union-attr] _validate_content(member.name, body, issues)🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/vouch/bundle.py` around lines 214 - 220, The loop over tar.getmembers() repeatedly rebuilds the set {f["path"] for f in manifest["files"]}; hoist that computation out of the loop by computing a manifest_paths_set (or similarly named variable) once before iterating, then replace the per-iteration check member.name not in {f["path"] ...} with member.name not in manifest_paths_set; keep existing logic around MANIFEST_NAME, member.isfile(), tar.extractfile(member).read(), and the call to _validate_content(member.name, body, issues).
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/vouch/bundle.py`:
- Around line 31-33: Remove the unused Page import and reformat/sort the import
block to satisfy Ruff: combine and alphabetize imports from .models (include
Claim, Entity, Evidence, Proposal, Relation, Session, Source) and from .storage
(sha256_hex, _deserialize_page), ensuring no unused symbols (drop Page) and
follow standard import grouping/ordering so the linter errors I001/F401 are
resolved.
- Around line 43-51: The VALIDATORS mapping in bundle.py is missing a validator
for the "sources" artifacts so source records aren’t schema-checked; add a
"sources" entry to the VALIDATORS dict following the existing pattern
(decode/yaml load then validate with the Source model) so that "sources" uses
Source.model_validate(yaml.safe_load(data)) (or the equivalent decode step used
for other text artifacts) — update the VALIDATORS dict to include this key
alongside "claims", "entities", "relations", etc., using the same lambda
structure as the other validators.
---
Nitpick comments:
In `@src/vouch/bundle.py`:
- Around line 214-220: The loop over tar.getmembers() repeatedly rebuilds the
set {f["path"] for f in manifest["files"]}; hoist that computation out of the
loop by computing a manifest_paths_set (or similarly named variable) once before
iterating, then replace the per-iteration check member.name not in {f["path"]
...} with member.name not in manifest_paths_set; keep existing logic around
MANIFEST_NAME, member.isfile(), tar.extractfile(member).read(), and the call to
_validate_content(member.name, body, issues).
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ReviewNice catch on #30 — the exception swap in What's good
Needs changes
|
Resolve conflicts in context.py, sessions.py, storage.py (keep main). fix: block bad writes in import_apply per review feedback (vouchdev#13) import_apply now captures schema validation issues and skips the file instead of passing a throwaway list.
|
The description undersells what's in here. The diff actually does two unrelated things:
Could you update the description (and ideally the title) to call out both? |
Summary
Two changes in this PR:
1. fix(verify): catch ArtifactNotFoundError (#30)
verify_source()was catchingFileNotFoundErrorbutread_source_content()raisesArtifactNotFoundError(aKeyErrorsubclass).2. Bundle content validation against Pydantic models (#13)
import_applywrote raw bytes without checking against Pydantic models. Adds per-subdirectory validators (Claim, Source, Entity, Relation, Evidence, Session, Proposal, Page).