# Auto-fix allowlist, BUILDER-ONLY, the ONLY unattended fixes

**Routing:** every row below is a mutation (`perl -i`, in-place CSS/JS edits).
A read-only seat holds Bash, and Bash alone can run `perl -i` / `sed -i` /
`node -e` with a file write even without a Write or Edit tool: the tool
allowlist is not the enforcement boundary, the routing rule is: these fixes
are executed by `primitive-authoring-agent` (or a human), never dispatched to or run
by `demo-audit-agent` or any other read-only dogfood seat. A read-only run
reports "matches this allowlist row" as part of its finding and stops.

| Finding | Mechanical fix | Source of truth |
|---|---|---|
| `transparent-fill` on `[data-swatch]` with inline `var(--chart-N)` fallback | swap fallback to `var(--a-data-N)` in component CSS + JS | zero-raw-color rule: `--a-chrome-*` / `--a-data-0..9` / semantic tokens only |
| `drift` `<avatar-ui name=…>` | `perl -i -pe 's/(<avatar-ui[^>]*?\s)name=/\1text=/g'` | `.claude/docs/MIGRATION GUIDE.md`, the `name=`→`text=` item |
| `drift` `<grid-ui cols=…>` | `cols=` → `columns=` (same perl shape) | attribute-api-migration convention |
| `drift` `<stepper-ui current=…>` | `current=` → `step=` | same |
| `drift` `<stepper-item-ui state=…>` | drop the attribute (parent `[step]` drives it) | same |
| `drift` `card-ui [slot="meta"]` | nest the tag inside `slot="heading"` (heading is flex) | same |
| `alert-flex-row` | wrap multi-element body in `<col-ui slot="content" gap="0-5">` | same |

Never auto-fixed: `zero-area` (always human-eyeballed), `empty-control` on an
unrecognized component, native-primitive replacement (attribute-shape
decisions), card-header wrapper hoists (slot intent), any warning without an
allowlist row.
**NEVER exceed 5 mechanical fixes per PR or apply a fix outside this
allowlist**, blast radius stays human-reviewable.
