Asset validation + repair
Triggered when asset_validate(), asset_generate_*, or asset_save_inline_svg returns warnings or errors. Do NOT loop on the same failure; follow the tree and respect the retry budget.
Failure code → repair table
| Code |
Origin |
Repair primitive |
Retry budget |
T0_CHECKERBOARD |
Imagen/Gemini rendering fake transparency |
Route change → gpt-image-1 (background:"transparent"), Ideogram v3 (style:"transparent"), Recraft V3 |
2 |
T0_ALPHA_MISSING |
RGB-only output on transparency-required asset |
Matte via asset_remove_background (BiRefNet preferred, RMBG fallback) |
1 |
T0_DIMENSIONS |
wrong width/height API params |
Fix params, regenerate |
1 |
T0_SAFE_ZONE |
subject bleeds outside platform center |
Regenerate with explicit "centered with 20% padding on all sides" |
1 |
T0_FILE_SIZE (SVG) |
path count blows budget |
asset_save_inline_svg → SVGO → K-means color reduction → vtracer |
1 |
T0_DCT_ENTROPY |
solid-color / NSFW-filter hit |
Regenerate same params once; if repeats, change prompt |
1 |
T1_PALETTE_DRIFT |
model ignored hex constraint |
Recraft with controls.colors or recolor post-process (K-means remap in LAB) |
1 |
T1_TEXT_MISSPELL |
diffusion garbled wordmark |
Drop text, composite SVG type (retry Ideogram 3 if text-only asset) |
0 in-diffusion / 1 on Ideogram |
T1_LOW_CONTRAST |
pale palette at 16×16 or over background |
Regenerate with explicit contrast instruction; else post-boost luminance |
2 |
T1_VQASCORE |
prompt-image alignment weak |
Defect area <15% → inpaint; else full regenerate |
2 |
T2_BRAND_DRIFT |
style diverges from brand refs |
Seed sweep (N=4, rank by CLIPScore + HPSv2); augment brand bundle |
1 |
T2_COMPOSITION |
off-center, cluttered, poor whitespace |
img2img at low denoise (0.35) — preserves layout, fixes style |
1 |
When a budget exhausts: stop retrying, report to user with diagnostic payload. Do not loop.
Diagnosis tree
asset_validate() returns warnings[]
└─ for each warning:
├─ read code + affected tier
├─ classify failure class:
│ local (<15% image area) → inpaint / post-process
│ global (style/palette-wide) → route change / regenerate
│ compositional (safe-zone/framing) → regenerate with centering prompt
└─ select repair primitive (table above)
├─ apply
├─ re-validate
└─ if same code fires again:
├─ retry_count < budget → try next primitive in fallback chain
└─ retry_count ≥ budget → escalate to user
Repair primitives — cost / ROI
| Primitive |
Cost relative to 1× generation |
When to choose |
| SVGO / palette remap / recolor |
0.01–0.05× |
Deterministic fix, no model call |
| Matte (BiRefNet / RMBG) |
0.05× |
alpha missing, no regeneration needed |
| Inpaint (masked edit) |
0.3× |
defect area <15%, composition is right |
| img2img low-denoise |
1× |
global style drift, preserve layout |
| ControlNet tile reinjection |
1.5× |
preserve structure, regen detail |
| Full regenerate |
4× |
architectural failure (checkerboard, wrong model) |
| Seed sweep (N=4) |
4× + selection |
brand drift, pick best |
Prefer cheaper primitives first when they apply.
Route-change rules for architectural failures
| Symptom |
Current route |
Change to |
| Checkerboard |
Imagen / Gemini |
gpt-image-1 (first), Ideogram v3, Recraft V3 |
| Wordmark garbled |
any diffusion |
Ideogram 3 Turbo (first), gpt-image-1 (second), composite SVG (always works) |
| Palette drift after 2 tries |
any |
Recraft (hard palette lock via controls.colors) |
| Subject misrendered |
SDXL |
Flux.1 [dev], gpt-image-1 |
| Path count >200 on SVG |
Recraft SVG |
inline_svg mode + strict path budget |
Proactive (pre-generation) checks
Prevent 70% of failures by validating the brief before calling asset_generate_*:
BRIEF:
☐ asset_type in closed enum (logo|app_icon|favicon|og_image|splash_screen|
illustration|icon_pack|sticker|hero|transparent_mark)
☐ subject noun concrete (not just adjectives)
☐ prompt ≥ 10 words OR brand_bundle provides style refs
TEXT-IN-IMAGE:
☐ quoted string ≤ 12 chars? else composite SVG type
☐ string > 5 words? force composite, skip diffusion-text path
PALETTE:
☐ brand.palette provided?
☐ hex codes ≤ 4 (over-constraint degrades Flux/SDXL)
TRANSPARENCY:
☐ transparency required + model in [Imagen, Gemini]? → reroute
☐ transparency required + gpt-image-1? → set API `background:"transparent"`
☐ transparency required + Flux/SDXL? → plan post-matte
ROUTING:
☐ text required + model ≠ Ideogram/gpt-image-1? → suggest reroute
☐ native SVG needed + model ≠ Recraft? → suggest Recraft or inline_svg
Where the codes come from
asset_validate (and every generator that runs a tier-0 pass before returning) emits the codes as a structured array:
{
"pass": false,
"warnings": [...],
"failures": [
{ "code": "T0_CHECKERBOARD", "tier": 0, "detail": "checkerboard pattern detected in 42.7% of analyzed pixels; reject and route to native-RGBA provider", "data": { "ratio": 0.427 } },
{ "code": "T1_PALETTE_DRIFT", "tier": 1, "detail": "...", "data": { "avg_delta_e2000": 14.2, "threshold": 10 } }
],
"tier0": { "width": 1024, "height": 1024, "has_alpha": false, ... }
}
Read validations.failures (when consuming an AssetBundle) or the top-level failures (when calling asset_validate directly). The data field on each failure carries enough context (bbox coords, ΔE value, Levenshtein distance) to pick a repair primitive without re-running the check. Source: packages/mcp-server/src/pipeline/validate.ts, ValidationFailure type in types.ts.
Integration with systematic debugging
Four-phase loop per failure:
- Gather evidence — read
validate output; log model, seed, guidance, prompt_hash.
- Pattern analysis — match to failure code; classify local/global/compositional.
- Hypothesis — pick cheapest repair primitive from the matrix.
- Verify — re-validate; if same code recurs, step down the route-change ladder, not the same primitive.
Red flags (stop, escalate):
- Same failure code 3+ times in a row
- Two different route changes failed for the same asset
- Cascading repairs (matte → vectorize → safe-zone) — brief is structurally wrong
Evidence to log per pipeline boundary
GENERATION: model, seed, guidance_scale, num_steps, prompt_hash, latency_ms, status
MATTE: tool (birefnet|rmbg|difference), alpha_px_before, alpha_px_after, checker_probe
VECTORIZE: path_count_before, path_count_after, color_count, tool (recraft|vtracer|potrace)
EXPORT: variants[].{path, format, w, h, size_bytes}
VALIDATE: tier0{...}, tier1{palette_de: x, vqa: y, ocr_lev: z}, tier2{sim: w}
Research
docs/research/14-negative-prompting-artifacts/14b-artifact-taxonomy.md — taxonomy + origin points
docs/research/14-negative-prompting-artifacts/14c-regenerate-vs-repair-strategies.md — primitives, cost/time tradeoffs
docs/research/03-evaluation-metrics/3e-asset-specific-eval.md — VQAScore, OCR, WCAG, CSD thresholds
docs/research/24-skills-for-p2a/06-validation-debug-skill.md — full design spec
1---2name: asset-validation-debug3description: Diagnose and repair asset-generation failures. Maps tier-0/1/2 validation codes (checkerboard, missing alpha, safe-zone violation, palette drift, garbled wordmark, low contrast) to concrete repair primitives (matte, inpaint, route change, seed sweep, composite). Applies a retry budget so Claude does not loop on hopeless regenerations.4---56# Asset validation + repair78Triggered when `asset_validate()`, `asset_generate_*`, or `asset_save_inline_svg` returns warnings or errors. Do NOT loop on the same failure; follow the tree and respect the retry budget.910## Failure code → repair table1112| Code | Origin | Repair primitive | Retry budget |13|---|---|---|---|14| `T0_CHECKERBOARD` | Imagen/Gemini rendering fake transparency | **Route change** → `gpt-image-1` (`background:"transparent"`), Ideogram v3 (`style:"transparent"`), Recraft V3 | 2 |15| `T0_ALPHA_MISSING` | RGB-only output on transparency-required asset | **Matte** via `asset_remove_background` (BiRefNet preferred, RMBG fallback) | 1 |16| `T0_DIMENSIONS` | wrong `width`/`height` API params | Fix params, regenerate | 1 |17| `T0_SAFE_ZONE` | subject bleeds outside platform center | Regenerate with explicit `"centered with 20% padding on all sides"` | 1 |18| `T0_FILE_SIZE` (SVG) | path count blows budget | `asset_save_inline_svg` → SVGO → K-means color reduction → vtracer | 1 |19| `T0_DCT_ENTROPY` | solid-color / NSFW-filter hit | Regenerate same params once; if repeats, change prompt | 1 |20| `T1_PALETTE_DRIFT` | model ignored hex constraint | Recraft with `controls.colors` **or** recolor post-process (K-means remap in LAB) | 1 |21| `T1_TEXT_MISSPELL` | diffusion garbled wordmark | **Drop text, composite SVG type** (retry Ideogram 3 if text-only asset) | 0 in-diffusion / 1 on Ideogram |22| `T1_LOW_CONTRAST` | pale palette at 16×16 or over background | Regenerate with explicit contrast instruction; else post-boost luminance | 2 |23| `T1_VQASCORE` | prompt-image alignment weak | Defect area <15% → **inpaint**; else full regenerate | 2 |24| `T2_BRAND_DRIFT` | style diverges from brand refs | Seed sweep (N=4, rank by CLIPScore + HPSv2); augment brand bundle | 1 |25| `T2_COMPOSITION` | off-center, cluttered, poor whitespace | **img2img** at low denoise (0.35) — preserves layout, fixes style | 1 |2627When a budget exhausts: **stop retrying, report to user with diagnostic payload**. Do not loop.2829## Diagnosis tree3031```32asset_validate() returns warnings[]33 └─ for each warning:34 ├─ read code + affected tier35 ├─ classify failure class:36 │ local (<15% image area) → inpaint / post-process37 │ global (style/palette-wide) → route change / regenerate38 │ compositional (safe-zone/framing) → regenerate with centering prompt39 └─ select repair primitive (table above)40 ├─ apply41 ├─ re-validate42 └─ if same code fires again:43 ├─ retry_count < budget → try next primitive in fallback chain44 └─ retry_count ≥ budget → escalate to user45```4647## Repair primitives — cost / ROI4849| Primitive | Cost relative to 1× generation | When to choose |50|---|---|---|51| SVGO / palette remap / recolor | 0.01–0.05× | Deterministic fix, no model call |52| Matte (BiRefNet / RMBG) | 0.05× | alpha missing, no regeneration needed |53| Inpaint (masked edit) | 0.3× | defect area <15%, composition is right |54| img2img low-denoise | 1× | global style drift, preserve layout |55| ControlNet tile reinjection | 1.5× | preserve structure, regen detail |56| Full regenerate | 4× | architectural failure (checkerboard, wrong model) |57| Seed sweep (N=4) | 4× + selection | brand drift, pick best |5859Prefer cheaper primitives first when they apply.6061## Route-change rules for architectural failures6263| Symptom | Current route | Change to |64|---|---|---|65| Checkerboard | Imagen / Gemini | `gpt-image-1` (first), Ideogram v3, Recraft V3 |66| Wordmark garbled | any diffusion | Ideogram 3 Turbo (first), `gpt-image-1` (second), composite SVG (always works) |67| Palette drift after 2 tries | any | Recraft (hard palette lock via `controls.colors`) |68| Subject misrendered | SDXL | Flux.1 [dev], `gpt-image-1` |69| Path count >200 on SVG | Recraft SVG | inline_svg mode + strict path budget |7071## Proactive (pre-generation) checks7273Prevent 70% of failures by validating the brief before calling `asset_generate_*`:7475```76BRIEF:77☐ asset_type in closed enum (logo|app_icon|favicon|og_image|splash_screen|78 illustration|icon_pack|sticker|hero|transparent_mark)79☐ subject noun concrete (not just adjectives)80☐ prompt ≥ 10 words OR brand_bundle provides style refs8182TEXT-IN-IMAGE:83☐ quoted string ≤ 12 chars? else composite SVG type84☐ string > 5 words? force composite, skip diffusion-text path8586PALETTE:87☐ brand.palette provided?88☐ hex codes ≤ 4 (over-constraint degrades Flux/SDXL)8990TRANSPARENCY:91☐ transparency required + model in [Imagen, Gemini]? → reroute92☐ transparency required + gpt-image-1? → set API `background:"transparent"`93☐ transparency required + Flux/SDXL? → plan post-matte9495ROUTING:96☐ text required + model ≠ Ideogram/gpt-image-1? → suggest reroute97☐ native SVG needed + model ≠ Recraft? → suggest Recraft or inline_svg98```99100## Where the codes come from101102`asset_validate` (and every generator that runs a tier-0 pass before returning) emits the codes as a structured array:103104```json105{106 "pass": false,107 "warnings": [...],108 "failures": [109 { "code": "T0_CHECKERBOARD", "tier": 0, "detail": "checkerboard pattern detected in 42.7% of analyzed pixels; reject and route to native-RGBA provider", "data": { "ratio": 0.427 } },110 { "code": "T1_PALETTE_DRIFT", "tier": 1, "detail": "...", "data": { "avg_delta_e2000": 14.2, "threshold": 10 } }111 ],112 "tier0": { "width": 1024, "height": 1024, "has_alpha": false, ... }113}114```115116Read `validations.failures` (when consuming an `AssetBundle`) or the top-level `failures` (when calling `asset_validate` directly). The `data` field on each failure carries enough context (bbox coords, ΔE value, Levenshtein distance) to pick a repair primitive without re-running the check. Source: `packages/mcp-server/src/pipeline/validate.ts`, `ValidationFailure` type in `types.ts`.117118## Integration with systematic debugging119120Four-phase loop per failure:1211221. **Gather evidence** — read `validate` output; log model, seed, guidance, prompt_hash.1232. **Pattern analysis** — match to failure code; classify local/global/compositional.1243. **Hypothesis** — pick cheapest repair primitive from the matrix.1254. **Verify** — re-validate; if same code recurs, step down the route-change ladder, not the same primitive.126127**Red flags (stop, escalate):**128- Same failure code 3+ times in a row129- Two different route changes failed for the same asset130- Cascading repairs (matte → vectorize → safe-zone) — brief is structurally wrong131132## Evidence to log per pipeline boundary133134```135GENERATION: model, seed, guidance_scale, num_steps, prompt_hash, latency_ms, status136MATTE: tool (birefnet|rmbg|difference), alpha_px_before, alpha_px_after, checker_probe137VECTORIZE: path_count_before, path_count_after, color_count, tool (recraft|vtracer|potrace)138EXPORT: variants[].{path, format, w, h, size_bytes}139VALIDATE: tier0{...}, tier1{palette_de: x, vqa: y, ocr_lev: z}, tier2{sim: w}140```141142## Research143144- `docs/research/14-negative-prompting-artifacts/14b-artifact-taxonomy.md` — taxonomy + origin points145- `docs/research/14-negative-prompting-artifacts/14c-regenerate-vs-repair-strategies.md` — primitives, cost/time tradeoffs146- `docs/research/03-evaluation-metrics/3e-asset-specific-eval.md` — VQAScore, OCR, WCAG, CSD thresholds147- `docs/research/24-skills-for-p2a/06-validation-debug-skill.md` — full design spec