Copy everything below this line into the agent.
Create, ship, and merge one original, runnable example for this repository. The bar is not "a working example"; it is an example strong enough to anchor the gallery on its own.
First, review CLAUDE.md, AGENTS.md, ROADMAP.md, examples/gallery.json,
docs/VISUAL-STYLE.md, and several existing examples—study the strongest ones, not
just the nearest one. CLAUDE.md and AGENTS.md are binding: they carry the
repo-specific runtime facts (binary discovery, staging hazards, quality gates) and
fleet workflow rules (branching, DCO, merge and CI-evidence policy) that this prompt
assumes. Where this prompt and those files disagree, the files win—they are updated
more often. Check all existing examples before choosing a subject so your
contribution does not duplicate or slightly repackage something already covered.
Before editing, inspect the Git state. Start from an up-to-date main, preserve
unrelated work, and create a focused feature branch. Never force-push or bypass
hooks. Do not include secrets, temporary renders, caches, or unrelated files.
Subject selection. Prefer the ROADMAP candidate pool if it has entries; otherwise choose freely. Whatever the source, the subject must pass all of these tests before you write code:
- It witnesses a real, load-bearing API contract—something with observable behavior that can drift, not a convenience wrapper or a tutorial topic. The strongest subjects are ones AI-generated Blender code commonly gets wrong: object-mode versus edit-mode data lifetimes, evaluated versus original data, ordering constraints, references that dangle after CustomData reallocation, APIs renamed or restructured between 4.5 LTS, 5.1, and 5.2 LTS.
- Its check can fail for a real reason. Before trusting any assertion, prove it catches the failure it claims to catch: temporarily break the contract (skip the pose, swap the buffer, use the legacy path) and confirm the check exits non-zero, then restore it. An assertion that cannot fail witnesses nothing. State in the README what failure each check would catch.
- When the primary assertion is a scalar (a vert count, a file size, a single
float), check whether a broken construction can produce the same scalar. If
it can, the scalar is not a sufficient witness — add a second axis. Worked
example:
examples/gn-zone-iterate/--no-offsetstill hits Repeat8×(1+N)verts by joining N+1 cubes at the origin; X-centers are the second axis. Count-only would have been green. - Its correctness is independently derivable. The best checks compare Blender's output against a closed-form or independently computed expectation (re-implemented math, a round-trip through a raw buffer, a known geometric invariant), not against a value captured from a previous run of the same code.
- Its render is legible as proof. Someone glancing at the thumbnail should be able to infer what contract is being demonstrated. If the render would look the same whether the API worked or not, redesign the scene until failure would be visible.
The check-only exception. A small, established category of examples ships with
no render at all: no --output path, no examples/gallery.json entry, no hero or
preview asset, no docs/gallery/ page. The criterion is whether the contract is
expressible in pixels. An example is check-only when its witness is a data or state
fact that no scene redesign can make visible — a datablock name, the presence or
absence of an RNA attribute, a post-exit sidecar file, a topology count, export
metadata — so the render would be identical whether the API held or broke. The
"redesign the scene until failure would be visible" instruction above is the test:
attempt it first, and only when it cannot succeed in principle does the example
become check-only. The exception is for contracts that are invisible, not for
renders that are hard. Ten of the 69 examples currently qualify, and CLAUDE.md
carries the same rule. A check-only example is otherwise a full example: it still
asserts a real contract, still exits non-zero on failure, still carries a falsifier,
and still takes a tests/smoke/catalog.json row so it runs on every PR.
Where an API diverges between 4.5, 5.1, and 5.2, asserting each side's actual contract is
part of the witness—version-gate explicitly and document the divergence rather than
papering over it. Version-gate on the bpy.app.version tuple, not
version_string, which is not bare semver on LTS builds. If an example cannot
run on a matrix leg, it must print SMOKE_SKIP: <reason> and sys.exit(77) —
exit 0 is a pass, not a skip. Set catalog min_version so a skip on a version
that should run is FAIL. Post-exit sidecars ($BDT_SMOKE_SIDECAR, harness
--expect-sidecar) are opt-in and are not gallery stills. If you discover an
undocumented hazard while authoring (a crash, a dangling reference, an ordering
constraint), that discovery belongs in the code comments and README; it is often
more valuable than the original subject.
The example must:
- run headlessly in Blender 5.2 LTS and Blender 4.5 LTS (5.1 remains prior stable);
- perform deterministic checks of a real Blender API contract and exit non-zero on failure, with numeric tolerances chosen deliberately and printed on success so CI logs carry the measured values;
- default to a fast check-only run and optionally render its own gallery image;
- follow repository conventions and relevant Blender safety rules;
- include concise documentation explaining what it teaches, what each check witnesses, what failure it would catch, and any version-gated divergence between 4.5 LTS, 5.1, and 5.2 LTS;
- produce a deliberate, well-framed render rather than a mockup, primitive dump, or placeholder — unless it meets the check-only exception above, in which case it ships no render and no gallery entry, and the PR body says which criterion put it there.
Complete every integration required for a shipped example. Infer the exact current
shape from neighboring examples and repository configuration, including the example
directory, README, gallery metadata and assets, plugin manifest, smoke catalog
(tests/smoke/catalog.json, whose row must list the falsifier under
falsifiers with its exact expect_exit so CI re-proves it on every run),
the skills mapping (examples/skills.json, then python scripts/build_examples_index.py
to regenerate examples/index.json and the skills' Runnable examples sections),
the top-level README's aggregate counts (it no longer carries a per-example
row; the gallery is the catalog), and generated gallery pages. A
check-only example skips the gallery metadata, assets, and generated pages — it wires
the plugin manifest, the smoke catalog row, the skills mapping, and its README, and nothing else. After regenerating the gallery with
python scripts/build_gallery.py, read the generated output character by
character—not only examples/gallery.json source fields. Open
docs/gallery/index.html and docs/gallery/<name>/index.html and inspect the
rendered <img alt> text and the witnesses callout for duplicated words,
truncation, and generator artifacts. The alt comes from the entry's alt field:
one sentence describing what the still shows, not what the API teaches; the
generator fails on a missing one (#213). Precedent for reading the output: the
old teaches.split(".")[0] bug truncated alts at dotted API paths like
bmesh.ops while the source JSON looked fine. Keep
the ROADMAP candidate pool in sync: remove the shipped subject, and add any
promising subjects you identified but did not build. Do not hand-edit release-owned
version fields or generated pages; use the repository's generator.
Run the new example's check-only path on Blender 5.2 LTS and 4.5 LTS. Locate
local binaries per CLAUDE.md's runtime discovery guidance (.scratch/ at repo
root first, then system installs; download official releases into .scratch/ if a
needed version is missing—it is gitignored). Do not probe blindly; state the exact
binary path and the version the binary itself reports for every run. If Blender 4.5
is unavailable locally, say so precisely and use the repository's 4.5 CI job—4.4 is
not a substitute and must never be reported as 4.5. 5.2 LTS is the local check
version; 5.1 is prior stable (weekly smoke). If the render path requires an
engine or device unavailable locally (Cycles on a GPU-less host), say so and
identify exactly which paths were exercised only in CI or by inspection. Fix every
failure you introduce.
Treat visual quality as a shipping gate with the same rigor as the checks. Conform
to docs/VISUAL-STYLE.md explicitly (Standard view transform, dark studio stage,
AREA key/fill/rim/wedge, designed hero materials, framing, 1280×720 → hero/preview
webp, plus the 640×360 card variant from scripts/make_thumbs.py). Inspect the actual rendered pixels at full size and as the gallery
thumbnail. Iterate—the first render is a draft, not a candidate. Revise until the
subject and demonstrated API contract are immediately readable, the composition is
intentional, important geometry is not clipped, highlights are not blown out,
lights or helper objects are not visible unintentionally, and materials, lighting,
background, and camera feel designed rather than left at Blender defaults.
The example must follow the repo's own rules, not just teach them:
tests/check_example_rules.py (run by Validate) rejects a per-element write
in a loop over mesh.polygons / mesh.vertices (use foreach_set) and an
active_object read with no None guard. A loop that really needs per-element
logic carries # foreach-exempt: <why> on or just above its for line.
Contact-sheet gate (required before shipping the still): build a composite placing
the new hero beside the pinned calibration set—canonical membership is in
CLAUDE.md § Quality Gates for Example Runs—and compare stage darkness, wedge
warmth, subject fill, saturation, and thumbnail legibility side by side. Commit the
composite under docs/gallery/contact-sheets/, link it in the PR body, and report
per-criterion verdicts including mean luminance of the candidate versus each
calibration image. The image ships only if it is not sortable as the odd one out in
that lineup—not merely "looks fine alone." A claim without the committed composite
is not acceptable evidence. When a new example outclasses a member, update the
pinned set in scripts/gallery_refs.py and the CLAUDE.md bullet that names it. One successful render command is not
proof that the image is good, and neither is the second.
Asset-sheet gate (required when the subject is a game asset: a prop, kit piece or
vehicle the example ships as a model): render the hero asset alone (neutral
three-quarter view, plain studio light, no staging, labels or comparison props)
beside the pinned asset-quality reference set (scripts/gallery_refs.py, named in
CLAUDE.md § Quality Gates for Example Runs), with
python scripts/asset_sheet.py --blender PATH NAME. Give the gallery entry an
assetSelect first: {"include": "<regex>"} (plus "exclude" if needed) on the
object names that make up the hero asset (tests/check_asset_sheet_select.py
enforces it for showcase pieces). Commit the composite under docs/gallery/asset-sheets/, link it in
the PR body, and report a verdict. The asset ships only if it is not identifiable as
the least-designed object in the lineup: a strong scene can carry a weak model, and
this gate removes the scene. Its measurable floors (naming, material variation, edge
treatment) live in examples/gallery_asset_quality.py, called on the render path
(exit 11 on violation).
After implementation and local verification:
- Review the complete diff and remove accidental churn or temporary files. Stage
with explicit paths, never
git add -A—the Cursor plugin locally injects a CLAUDE.md block that a bulk add will sweep into the commit, and.scratch/contents must stay out. - Commit the focused change with a conventional, release-worthy
feat:subject that explains why the example belongs in the repository, signed off with-sper CONTRIBUTING.md. - Push the feature branch and open a pull request against
mainwith a concise summary, the API contract witnessed, the falsification evidence (the break-the-contract probe, its exit code, and the measured error), visual notes with the contact-sheet link, and an exact test plan. Label explicitly what was proven by live run versus established by inspection only. - Watch every attached PR check, including validation, manifest/count checks, ecosystem drift, Socket Security checks, and Blender 5.2/4.5 smoke jobs. Investigate and fix failures within this change's scope, push fixes, and repeat until all checks pass. A pending or failing Socket check is unresolved—wait before merging.
- Review PR comments and requested changes. Apply valid feedback and re-run affected checks. Do not merge with unresolved failures or requested changes.
- Once the PR is mergeable and green, squash-merge it and delete the remote feature branch.
- Wait for any automated release/version-sync commit triggered by the merge, then
fast-forward local
maintoorigin/main, and verify main HEAD is green including all post-merge jobs (Release, Validate, Ecosystem drift check, Deploy GitHub Pages where path-triggered). The smoke jobs are pull_request-triggered and do not re-run on the merge SHA: the post-merge evidence is that both smoke jobs passed on the PR head SHA that became the sole squash-merged commit, with the actual Blender binary versions confirmed in the job logs. Do not hand-edit release-owned version fields. - Confirm the final working tree is clean and report: PR URL, merge commit, resulting version (if released), exact local binaries used, measured check values, falsification evidence, contact-sheet link, and checks completed.
Do not stop at a proposal or ask me to choose the topic. Explore, choose, implement, verify, ship, merge, synchronize, and report the completed result. Only stop for a real blocker that requires user action, such as authentication, an unavailable required runtime with no CI substitute, a merge policy requiring approval, or unrelated local changes that cannot be safely preserved.