Repository navigation
Publish reproducible BlenderBench direct suite - #1
Merged
Merged
Conversation
There was a problem hiding this comment.
🟡 Changes recommended
Unresolved critical and moderate findings remain in scoring, provenance, checkpoint validation, orchestration, CI coverage, and runtime handling.
Get a fresh assessment by requesting another Copilot review.
Pull request overview
Publishes a reproducible, hash-bound 27-task, 270-round BlenderBench direct suite with MCP/Codex execution, independent auditing, scoring, reference artifacts, and portable CI.
Changes:
- Adds benchmark orchestration, datasets, manifests, scoring, recovery, and video tooling.
- Adds checkpoint attestation, runtime auditing, Codex controls, and focused tests.
- Publishes reproducibility documentation, reference results, provenance metadata, and CI.
File summaries
| File | Changes and review notes |
|---|---|
tools/direct_suite.py |
Compatibility runner. Moderate (2 votes): direct execution may fail to import the repository package unless the repository root is added to sys.path. |
tools/DIRECT_SUITE.md |
Direct-suite usage documentation. |
tools/direct_runtime.py |
Independent Blender audit and rendering runtime. Moderate (1 vote): missing reviewed markers should fail closed. |
tools/direct_codex.py |
Codex launcher and evidence validation. Critical (1 vote): preflight trusts model-controlled values instead of binding to MCP arguments and server-side evidence. Critical (1 vote): reject symlink or non-regular rounds.jsonl ledgers. |
tools/direct_codex.md |
Launcher documentation. Nit (3 votes): documents workspace-write although the launcher uses --sandbox read-only. |
tools/direct_codex.example.toml |
Example MCP configuration. |
tests/test_tool_listing.py |
Tool-listing tests. |
tests/test_direct_unrestricted.py |
Unrestricted execution tests. |
tests/test_direct_suite.py |
Direct-suite orchestration tests. |
tests/test_direct_saved_cleanup.py |
Saved-scene cleanup tests. |
tests/test_direct_recovery.py |
Recovery tests. |
tests/test_direct_codex.py |
Codex and checkpoint validation tests. |
tests/test_blender_cli.py |
Blender CLI behavior tests. |
readme.md |
Published benchmark result and provenance links. |
mcp/blmcp/tools/execute_blender_code.py |
Checkpoint execution and rendering. Critical (1 vote): rehash the source after arbitrary code runs and reject changes before creating checkpoint attestations. |
benchmarks/token_efficiency/creative_smoke.py |
Creative token-efficiency smoke benchmark. |
benchmarks/token_efficiency/codex_runner.py |
Codex launch specification. |
benchmarks/blenderbench_direct/VIGA-LICENSE.txt |
VIGA license text. |
benchmarks/blenderbench_direct/video.py |
Compilation video generation. Moderate (2 votes): clamp positive-duration frame counts to at least one. Moderate (1 vote): explicitly reject negative elapsed time. |
benchmarks/blenderbench_direct/TDD_EVIDENCE.md |
Verification evidence record. |
benchmarks/blenderbench_direct/suite.py |
Generation, recovery, and scoring orchestration. Moderate (2 votes): persist cancellation for the current and remaining tasks before stopping. Critical (1 vote): recheck source identity after generation and before auditing or scoring. |
benchmarks/blenderbench_direct/scoring.py |
Standalone scoring and validation. Critical (1 vote): require the exact unique round identifier set, not merely the count of successful rows. |
benchmarks/blenderbench_direct/score_pair.py |
Pinned GPU scorer. |
benchmarks/blenderbench_direct/runner.py |
Benchmark CLI commands. |
benchmarks/blenderbench_direct/requirements-scoring.in |
Scoring dependency inputs. |
benchmarks/blenderbench_direct/requirements-fixture.lock |
Fixture dependency lockfile. |
benchmarks/blenderbench_direct/requirements-fixture.in |
Fixture dependency inputs. |
benchmarks/blenderbench_direct/ref_based_eval.py |
Vendored reference evaluator. |
benchmarks/blenderbench_direct/README.md |
Reproduction documentation. |
benchmarks/blenderbench_direct/publication/results-summary.json |
Published aggregate results. |
benchmarks/blenderbench_direct/publication/reference-results.json |
Published reference results. Moderate (3 votes): replace mutable resolve/main links with the immutable dataset revision. The related artifact manifest has the same Moderate (3 votes) issue. |
benchmarks/blenderbench_direct/protocol.py |
Protocol and source-identity manifests. Moderate (1 vote): reject dirty checkouts during recovery or scoring as well as generation. |
benchmarks/blenderbench_direct/dataset.py |
Dataset staging and validation. |
benchmarks/blenderbench_direct/clip-snapshot-manifest.json |
CLIP snapshot hashes. |
benchmarks/blenderbench_direct/__init__.py |
Package initialization. |
.gitignore |
Local benchmark output exclusions. |
.github/workflows/blenderbench-portable.yml |
Portable fixture CI. Moderate (2 votes): include mcp/blmcp/** in both duplicated path filters. |
.gitattributes |
Evaluator hash protections. |
Review details
Suppressed comments (4)
benchmarks/blenderbench_direct/protocol.py:235
- The manifest check rejects a run recorded from a dirty checkout, but it does not reject a dirty checkout used for recovery or scoring:
current = collect_source_identity()includesgit_dirty, yet this condition only inspectssource. That allows the claimed clean provenance to be consumed from an unclean tree, contrary to the documented invariant; requirecurrent['git_dirty']to be false as well.
if source["git_dirty"] is not False:
raise ValueError("publication run manifest requires a clean Git source identity")
benchmarks/blenderbench_direct/video.py:15
- The validation error promises a nonnegative elapsed time, but this condition never rejects negative values. A caller can receive timeline state with a negative
elapsed_secondsand a misleading zero-token/round-0 state; explicitly checkelapsed < 0.
if not math.isfinite(elapsed) or not math.isfinite(duration) or duration <= 0:
raise ValueError("finite nonnegative elapsed and positive duration required")
tools/direct_codex.py:105
execute_blender_code_for_cliexecutes arbitrary Python viaexec, but this gate only regex-scans the serialized arguments. Dynamically constructed paths or strings (for example, concatenatinggoaland.py, decoding bytes, or reading a path from Blender data) bypass the regex while still allowing evaluator access, so the run can claim no feedback when it did receive it. Enforce the input-only filesystem boundary at the execution/OS boundary or record an execution-level access audit instead of relying on lexical matching.
tools/direct_runtime.py:377- This check accepts a missing
reviewedfield because only an explicitFalseis rejected. Sinceinitialize()is the trust boundary for parent-reviewed literal operations, an omitted marker should fail closed just like an unreviewed policy.
- Files reviewed: 39/43 changed files
- Comments generated: 12
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Comment on lines
+269
to
+270
| elif expected_rounds is not None and len(successful) != expected_rounds: | ||
| status = "failed" |
Comment on lines
+125
to
+126
| if runtime.sha(baseline_path) != initial_hash: | ||
| raise ValueError("generation modified initial.blend") |
| with synced_blend_for_cli(str(source)) as synced_path: | ||
| value = run_blender_cli(synced_path, code, arbitrary_code=True) | ||
| else: | ||
| value = run_blender_cli(str(source), code, arbitrary_code=True) |
Comment on lines
+92
to
+95
| if (isinstance(payload, dict) and payload.get('preflight') == nonce | ||
| and payload.get('python') == python | ||
| and str(payload.get('version', '')).startswith(bpy_version)): | ||
| return |
| if component.is_symlink(): | ||
| raise ValueError(f'symlink forbidden in checkpoint path: {component}') | ||
| try: | ||
| rows = [json.loads(line) for line in (root / 'rounds.jsonl').read_text().splitlines()] |
| "publication_status": "published", | ||
| "sample_aspect_ratio": "1:1", | ||
| "sha256": "04966320de680203baed6c01c3e211059350454139dc8a802c557cce24815c17", | ||
| "url": "https://huggingface.co/datasets/michaelgold/blenderbench-direct-results/resolve/main/video/blenderbench-complete-compilation.mp4", |
Comment on lines
+281
to
+282
| if (config.output_root / "STOP").exists(): | ||
| states[task] = {"status": "cancelled"}; break |
| "metric_label": "CLIP image cosine similarity", | ||
| "token_label": "task-level linear interpolation"} | ||
| try: | ||
| frame_count = round(fps * seconds_per_task) |
Comment on lines
+7
to
+11
| from pathlib import Path | ||
|
|
||
| from benchmarks.blenderbench_direct.runner import main | ||
| from benchmarks.blenderbench_direct.suite import run_suite | ||
| ROOT = Path.cwd() |
| - `search_api_docs` | ||
|
|
||
| It requires explicit scoped preapproval with `--approve-blender-tools`, retains | ||
| Codex `workspace-write` plus `approval_policy="never"`, rejects extra MCP servers |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Verification
No benchmark generation or goal/solution code was executed during release verification.