Claude
Skills
Sign in
Back

visual-verify

Included with Lifetime
$97 forever

This skill should be used when the user asks to 'verify visual output', 'check how it looks', 'render and review', 'visual verify', 'check the slide', 'does this look right', or when any task produces rendered visual output (slides, charts, documents, UI).

Design

What this skill does


**Announce:** "I'm using visual-verify to set up a render-vision-fix loop."

<EXTREMELY-IMPORTANT>
## The Iron Law

**NO VISUAL TASK IS COMPLETE WITHOUT RENDERING, SCORING, AND MEETING THE THRESHOLD.**

Source code correctness does NOT imply visual correctness. You MUST render to PNG, score with vision (0-10) — Gemini CLI, or a subagent with Read if Gemini is unavailable — and iterate until score >= 9.5. Claiming "done" with a score below threshold delivers broken visuals to the user.

**Skipping the score check is NOT HELPFUL — the user gets a visual artifact with defects you didn't verify.**
</EXTREMELY-IMPORTANT>

## Gemini CLI Vision

Gemini CLI is inherently agentic — it can read files, crop, zoom, and re-examine regions autonomously. No special flags needed for complex vs. simple images; it handles both automatically.

## The Loop

```
0. PAGE MAP -> If Typst + Touying: Skill("teaching:find-slide-page")
       |      Returns heading → physical page mapping
       |      Skip if: single-page file, non-Typst, or page already known
       |
1. CHANGE  -> Modify source code (Task agent)
       |
2. RENDER  -> Produce PNG + PDF (see references/render-commands.md)
       |      Render fails? -> fix source, back to step 1
       |
2.5 TEXT   -> pdftotext pre-screen (Typst/PDF outputs with diagrams ONLY)
       |      Run: pdftotext -f <page> -l <page> -layout output.pdf -
       |      Check for defect #10 (adjacency violations)
       |      Any violations? -> fix source, back to step 1 (skip vision)
       |      Clean? -> proceed to step 3
       |      Skip if: non-PDF output, no diagrams on page
       |
3. VISION  -> Two-part check:
       |      a) INTENT — Does the render match the design intent?
       |         (Does the visual structure argue what it should?)
       |      b) DEFECTS — Scan for the 10 visual defect categories:
       |         1. Text clipped by or overflowing its container
       |         2. Text or shapes overlapping other elements
       |         3. Arrows crossing through elements instead of routing around
       |         4. Arrows landing on wrong element or pointing into empty space
       |         5. Labels floating ambiguously (not anchored to what they describe)
       |         6. Labels squeezed between adjacent elements without clearance
       |         7. Uneven spacing (cramped sections next to spacious ones)
       |         8. Text too small to read at rendered size
       |         9. Parallel sub-diagrams with inconsistent layout
       |        10. Edge labels fused with node text (pdftotext adjacency)
       |      Gemini CLI vision call with SCORING:
       |      → Score 0-10 against checklist items
       |      → Record in SCORES.md
       |
4. DECIDE  -> Score >= 9.5 AND exit criteria met? → DONE
              Score < 9.5 OR defects remain?      → extract fixes, back to step 1
```

### Step 2.5: pdftotext Pre-Screen (Diagrams Only)

**What it catches:** Edge labels colliding with node text in Fletcher/CeTZ diagrams. When two text elements overlap or touch horizontally in the rendered PDF, `pdftotext -layout` fuses them into a single string without whitespace — e.g., `Republic of1937 war bonds` instead of `Republic of   1937 war bonds`.

**When to run:** Any page that contains a `#fletcher-diagram` or `#cetz.canvas`. Skip for pages with only body text, tables, or bullet points.

**How to check:**
1. Extract the page: `pdftotext -f <page> -l <page> -layout output.pdf -`
2. Collect all node labels and edge labels from the source code
3. Scan the extracted text for any two labels appearing concatenated without whitespace
4. A fused pair (node text running directly into edge label text) is a **BLOCKING** defect — return to step 1 without spending a vision call

**Why this works:** PDF text extraction preserves spatial positions. If elements have clear space between them, whitespace appears in the output. If they overlap or touch, words concatenate. This is cheap, deterministic, and catches the most common Fletcher layout failure that vision scoring misses.

**Why this is NOT a replacement for vision:** pdftotext only catches horizontal text collisions. It cannot detect labels sitting on top of arrow lines (vertical overlap), misaligned arrows, or spacing imbalance. Vision (step 3) is still required for a full pass.

### When to Stop

The loop is done when ALL of these hold:
- Score >= 9.5
- The rendered output matches the design intent (not just defect-free but *correct*)
- No text is clipped, overlapping, or unreadable
- All arrows/lines connect to the right elements and route cleanly
- Spacing is consistent and composition is balanced
- You'd show it to someone without caveats

**Don't stop after one clean pass just because there are no critical bugs — if the composition could be better, improve it.** Conversely, don't loop forever on cosmetics — 5 iterations max before escalating to the user.

### Invocation

Set a `/goal` whose condition gates on the **enumerable defect substrate** — fused labels and BLOCKING visual defects — not the 0-10 aesthetic score (an LLM vision score is noisy and won't stably hit 9.5; chasing it is a treadmill). Run the loop body (render → vision → fix) inside each turn. The evaluator reads the defect findings from the transcript.

```
/goal Visual Task N [TASK NAME] is complete when the rendered output at
[OUTPUT PATH] has ZERO BLOCKING defects (clipping, overlap, illegible text,
wrong connections) and the pdftotext pre-screen finds no fused labels
(diagrams only), per SCORES.md. The look-at 0-10 score is advisory, not the
gate. Stop after 5 turns.
```

Hand the literal condition to the user (or run via `claude -p "/goal …"`). Each subsequent turn fires automatically until zero BLOCKING defects remain (not until an aesthetic score crosses a bar).

### Score Tracking

Initialize SCORES.md before the first iteration:

```markdown
# Visual Verify Scores

| Iteration | Score | Threshold | BLOCKING | COSMETIC | Delta |
|-----------|-------|-----------|----------|----------|-------|
```

Each vision call must score the output 0-10:
- 10.0 = all checklist items pass, zero issues
- 9.5 = 95% pass, 1-2 cosmetic issues remain (default threshold)
- < 9.0 = BLOCKING issues present

The score reflects the fraction of checklist items that pass. Gemini counts BLOCKING and COSMETIC issues against the domain-specific checklist, and the score = (items passing / total items) * 10.

### Vision Calls

**Use look-at's `look_at.sh` wrapper for all vision calls.**

```bash
# Single backend (Gemini CLI, default)
"${CLAUDE_SKILL_DIR}/../../skills/look-at/scripts/look_at.sh" \
    --file "/tmp/visual-verify.png" \
    --goal "[CONTEXT-ENRICHED GOAL]"

# Consensus mode (Gemini + GPT-5.4 in parallel)
"${CLAUDE_SKILL_DIR}/../../skills/look-at/scripts/look_at.sh" \
    --file "/tmp/visual-verify.png" \
    --goal "[CONTEXT-ENRICHED GOAL]" \
    --consensus
```

Use `--consensus` for diagram pages. Use single backend for non-diagram pages.

<EXTREMELY-IMPORTANT>
### Fallback: Subagent with Read (when Gemini is unavailable)

**If Gemini CLI fails (API key unavailable, missing, or API error), DO NOT fall back to pdftotext AS A REPLACEMENT for vision. pdftotext cannot detect vertical overlap, misalignment, or spatial defects — it only extracts text. Using it as the sole visual check produces false passes.**

Instead, spawn a subagent that uses the `Read` tool directly on the rendered PNG:

```
Agent(
    prompt="Read the image at /tmp/visual-verify.png and score it. [CONTEXT-ENRICHED GOAL]. Score 0-10 against the checklist. Report BLOCKING and COSMETIC issues separately.",
    description="Vision fallback: score rendered PNG",
    subagent_type="general-purpose"
)
```

**Why this is safe:** The Iron Law against `Read` on images exists to protect the main conversation's context window (images cost 1000-5000 tokens). Subagent context is throwaway — the tokens are discarded when the agent returns its sho
Files: 6
Size: 40.8 KB
Complexity: 53/100
Category: Design

Related in Design