Repository navigation
Foundation: image provenance manifest enforced by the fixture validator (#308) - #330
CompleteDotTech wants to merge 3 commits into
Conversation
… by the fixture validator (#308) Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
|
Opus reviewer (independent review 2 of 2). Model: Claude Opus 5.5 ( How I tested it as a recipe builderI scaffolded a throwaway recipe 61 in a scratch folder (
BlockingB1. CI is red: B2. The Suggestions (not blocking)
Decisions in the PR body
Checks run (fresh venv,
|
|
Opus reviewer (independent review 1 of 2): Claude Opus 5.5 ( Reviewed head The design is sound and the validator held up well when I tried to break it. It fails closed on every non-compliant recipe I built that follows the documented Blocking
Suggestions (not blocking; the first two matter for the 40 recipes that copy this)
The "Decisions for the reviewers" list
Attempts to get a non-compliant recipe past the validator (all built in a temp dir)
Mutation check on
Checks run (fresh venv,
|
Closes #308
What this adds
A per-recipe image provenance manifest and its enforcement in the fixture validator. Foundation work (no recipe touched); this defines a file format every multimodal recipe copies, so it needs two independent reviews.
recipes/<slug>/assets-manifest.json, one per recipe, required exactly when the recipe has files underassets/. Simple JSON:{"schema": 1, "assets": [entry, ...]}. Each entry:path,sha256,format,width,height,origin(generatedonly),generator(build_fixtures.py:draw_sceneorjev_cookbook.<module>:<function>),parameters(object, seed included),licence(MITorCC0-1.0),description,attestations(synthetictrue;real_photo,real_brand,real_person,third_party_contentfalse), optionalshared_across_splits.src/jev_cookbook/fixtures/assets-manifest.schema.json(packaged;_schema.pygainsconstandminimum).src/jev_cookbook/fixtures/_assets.py, called fromvalidate_recipe, sopython -m jev_cookbook.fixtures validate <recipe>,--allandtools/notebook_ci.py fixturesall enforce it. Errors arepath: [rule] message; the rules are listed indocs/fixtures.md("Image provenance manifest", with a worked example and a generator helper for Foundation: no shared way to generate synthetic test images, so each of forty recipes will hand-roll one, or reach for real photos, brands and screenshots #314).docs/fixtures.md,docs/recipe-template.md, one bullet inCONTRIBUTING.mdsection 5.Decisions for the reviewers
assets/manifest.json.tools/check_recipe_assets.py(merged in Foundation: image-file contract, checker, scope rule and notebook image policy (#307) #322) saysassets/holds image files only (non-image-in-assets), and that file is outside this issue's paths, so the manifest sits beside the folder asrecipes/<slug>/assets-manifest.json. A recipe PR can edit it (it is inside the recipe folder).synthetic: trueattestation added to the issue's four false ones, so the manifest says "synthetic" explicitly as well as "no real photo/brand/person/third party".MIT,CC0-1.0) because third-party material is banned; widen it if a real need appears.fields(any depth, any key) with no whitespace that starts withassets/or ends.png/.jpg/.jpeg. Each must equal a manifestpathexactly and passresolve_asset_path(root=recipe).train/validation/testexamples (demo exempt), under one path or two. It does not decode pixels, so two encodings of one picture are two hashes (stated in the docs). The allow-list isshared_across_splits: trueon every entry carrying those bytes.pyproject.toml(package-data for the new schema file) andtests/test_multimodal_backends.py/tests/test_fixtures.pyare outside the issue's list but needed: the schema file must ship; the multimodal test built an image recipe with no manifest (now correctly rejected) so it gained one; the unsupported-keyword test usedminimumas its example of an unsupported keyword and now usesmaximum.docs/multimodal-track.mdnow points to the manifest section (allowed by the orchestrator after the PR opened).tmp_pathby the tests (Pillow-drawn images) rather than committed binaries undertests/.How it was verified
Fresh venv,
pip install -e ".[dev]", Windows:ruff check .: All checks passed.ruff format --check .: 399 files already formatted (this also formats the docs code blocks).origin/main(e998eb5, Foundation: enforce the Images API's 280 px minimum, hash image bytes in replay keys, bound tiles (#306) #321, which changedvision.py) with a signed merge commit, then re-ran everything on the merged head.pytestfull run: 5457 passed, 60 skipped, 31 xfailed; 2 failures, the known Windows-onlytests/test_notebook_ci_sandbox.pyones (signal.SIGKILL, Foundation: two notebook-CI sandbox tests use signal.SIGKILL and fail on Windows #302); no Tests: kernel tests in tests/test_new_recipe.py flake on Windows under load (ZMQError: Address in use, exit-time noise) #328 kernel flakes appeared. Before the merge,test_image_metadata_fixtures_validate_box_answerswas broken by the new rule and fixed by giving it a manifest. The 2 skips intests/test_fixtures_assets.pyare symlink tests (this Windows account cannot create symlinks); the containment branch is covered by a monkeypatched test.python tools/render_catalog.py --check: exit 0.python tools/check_hygiene.py: passed.python tools/check_recipe_assets.py: passed.python tools/notebook_ci.py fixtures: 51 recipe folders, 0 failed.python -m jev_cookbook.fixtures validate --all: all valid (no recipe hasassets/, so unchanged).tests/test_fixtures_assets.py(147): each rule positive and negative: missing manifest, unlisted file, orphan entry, hash/format/size mismatch, missing/invalid licence, every attestation true/false/missing/non-boolean, required and unknown fields, path traversal in a listed path (13 shapes) and in afieldsvalue, symlink, generator, duplicate entry, split leak and allow-list, unreadable manifest, plus checks that the docs example and helper pass the schema/validator and that the schema patterns equal the code's.🤖 Generated with Claude Code