--- name: sceneproof description: Visual reasoning discipline for verifying UI and Three.js work with the SceneProof CLI. Use whenever a change can alter rendered output — components, styles, layout, SVG, canvas, scenes, cameras, lights, materials, animation — or whenever about to claim that something "looks right", "is visible", or "renders correctly". Also use when debugging why something is invisible, black, clipped, misframed, or mis-lit. --- # SceneProof: seeing before claiming You have a tool that can render the real source and show you real structure. That changes what you are allowed to claim. A passing build, a clean typecheck, or code that "should" produce the right output is **zero visual evidence**. If you are about to assert anything about appearance, you either have an artifact you actually looked at, or you say plainly that the visual result is unverified. The CLI (`sceneproof --help`, per-command help, and mechanically grounded `suggestions` when available) tells you what commands exist and what evidence it can gather next. Before a serious review, run `sceneproof --version` and `sceneproof doctor`. Do not spend a debugging session against a stale installed binary; inspect the doctor installation block and use its reinstall command when installed-bin readiness fails. This skill is about something the CLI cannot do for you: choosing what uncertainty to resolve, in what order, and judging the result honestly. ## First: name the purpose Before claim-directed work, state the visual claim as a falsifiable question. "Is the price label legible at the size it ships at?", "Is the selected card visibly distinct from the others?", and "Does the model silhouette match the reference front view?" imply different evidence. Exploration is also legitimate: when you do not yet know the right question, name the uncertainty you are exploring rather than pretending the command is a verification. In either mode, know why you are gathering the evidence and do not let an exploratory artifact silently become proof of a stronger claim. ## Resolve uncertainty in order, cheapest decisive evidence first Visual failures have layered causes. Work down this ladder and spend effort at the layer that is actually unknown: 1. **Boundary** — am I looking at the real production component or scene owner, or a lookalike? Evidence about a stand-in proves nothing about the app. 2. **State** — do the props, fixtures, actions, and time represent the state being claimed? A default-props render cannot verify a claim about the selected/error/dense state. 3. **Structure** — does the target exist, with sane bounds, visibility, geometry, material, lights? Use `tree` or `node` first when the boundary, target, bounds, or visibility is uncertain. 4. **Framing** — does the camera/viewport actually present the target at an informative size and angle? 5. **Raster** — only once framing is right: are more freshly rendered pixels needed to judge typography, edges, or material detail? 6. **Coherence** — does the change hold up in context, next to its neighbors, under the states and viewports that matter? Render `--context-pair` (or `--isolated` alongside `--in-context`) to get the isolated evidence and the full-scene evidence from one lifecycle, not two separately staged renders that can silently drift apart. The classic waste is buying pixels for a structure problem: rendering at 8x when the mesh has zero bounds, or screenshotting a component whose state never entered the claimed condition. Enlarging an uninformative image produces a larger uninformative image. ## Structure before pixels "Why can't I see it?" is almost never answered by another render. Hidden ancestor, zero-size bounds, fully transparent material, no light reaching the surface, object behind the camera, clipped by near/far planes — these are *different* causes with different fixes, and `tree`/`node` distinguish them in one cheap step. Diagnose invisibility structurally; render to confirm the fix, not to hunt for the cause. The converse also holds: a node present in structural output is not necessarily visible. Structure explains the render; only a render you looked at evaluates it. Neither substitutes for the other. ## Cameras: composition before density For 3D, an uninformative angle at high resolution is worth less than a good angle at low resolution. When you don't know the useful camera, run `scout` instead of guessing — but treat its output as a set of *hypotheses with measurements*, not a verdict. Read the contact sheet yourself. The score, coverage, and visible-signal numbers help distinguish framing, scale, contrast, and sparse-signal problems. They do not establish occlusion or visual adequacy on their own. Prefer a tighter region, closer framing, or a more revealing angle before reaching for `--scale`; increase scale only when the relevant detail already occupies an informative part of the frame and raster density is the last limit. A detail render at scale is real evidence, not an approximation, but it is evidence of what is *there*, not of what ships: a flaw visible at 8x may be invisible at delivered size, and a composition that reads fine zoomed in may be cramped at the size it actually ships. Pair a detail render with `--delivery-review` before claiming the shipped view is correct. ## Freshness and provenance are non-negotiable - Do not treat a crop or enlargement as fresh evidence. Rerender the region from source when the claim needs detail the original render did not contain. - Never build a simplified copy of production geometry, layout, or state to make verification easier. That verifies your copy, not the application. If the real boundary needs application context, reconstruct that context in the harness: let a React fixture own wrappers, providers, and document state; load the real styles in cascade order; alias browser-incompatible integrations explicitly. Do not change production APIs or imports to make inspection easier. If the real boundary still cannot load without fabricating the behavior under test, report that as the blocker. - Use `matrix` for labeled multidimensional states. A checksum-guarded source overlay is an attributable last resort for a sealed React constant, not a license to rewrite production files or hide state from provenance. - Know what state you actually rendered. Synthesized placeholder props are labeled in the report — do not let them silently stand in for real state in your conclusion. - Transition claims need one real lifecycle (construct once, act once, sample frames of that same scene). Two separately hand-posed renders do not establish that a transition happens. - Treat `--frames before,0,120,settled` as checkpoints: it says nothing about the unsampled interval. Use `--frames 0..3000@100ms` when the claim concerns continuous motion, then inspect `motion.apng` and `motion-map.png` as well as representative frames. - Route diagnostic shader channels through explicit fixture props so the evidence is reproducible. Altered lights, exposure, tone mapping, or debug materials can isolate a cause, but they are diagnostic evidence—not the canonical shipping appearance. Return to the real pipeline before approval. ## Read the report for what it can establish SceneProof has no model inside it. It does not know whether a composition is good or whether one heuristic makes the artifact adequate for your question. Keep these report layers separate: - **execution** succeeded = the command ran. Nothing more. - **artifacts** are the files you must actually open. - **provenance** says what source, state, context, CSS, substitutions, and overlays produced those files. A declared stub or synthesized prop is a real boundary on what you can conclude. - **facts** and **warnings** are measurements and concrete limitations, not a visual verdict. A luminance spread, target coverage, or Scout score may help diagnose a frame without deciding whether the frame answers your question. - **assertions** pass or fail only a mechanical condition explicitly requested in the command. Passing one does not approve the design around it. - **review.required** means the contextual decision remains yours. Open the artifact. Actually look at it before making a visual claim. Start with the compact briefing. Use `--json` when the decision depends on the complete factual report; a fact omitted from the briefing is not necessarily a fact SceneProof failed to collect. For reference comparisons, confirm the mask/overlay sits on the intended subject before trusting any metric derived from it. For matrices, compare the labeled images rather than accepting raster delta as a preference. A precise number about the wrong subject, state, or region is worse than no number. When the evidence spans different commands or scales, `sheet` can put the labeled PNGs into one artifact. Use it for combinations such as context plus detail, before plus after, or render plus reference. It packages what you give it; it does not make an old image fresh or recover the source and state provenance from the command that produced it. Keep those originating reports, and request `--compare` only for adjacent frames whose raster difference is meaningful. ## Report like a witness, not an advocate State what was rendered (source and state provenance), which states and viewports were exercised, where the artifacts are, and what you concluded by looking. A negative or unresolved result is a valid result: "the label clips at 320px and I have the render showing it" is a better report than an unverified "looks good". The strongest failure mode this skill exists to prevent is declaring visual success from non-visual evidence. When you have eyes, use them; when you didn't, say so.