feat(ledger): the consumer map reads transition names and concatenated prefixes (#2970)
CI & Build / Python lint (push) Successful in 4s
CI & Build / Plugin hooks (push) Failing after 10s
CI & Build / integration (push) Successful in 26s
CI & Build / TypeScript typecheck (push) Successful in 33s
CI & Build / Python tests (push) Successful in 1m6s
CI & Build / Build & push image (push) Successful in 23s
CI & Build / Python lint (push) Successful in 4s
CI & Build / Plugin hooks (push) Failing after 10s
CI & Build / integration (push) Successful in 26s
CI & Build / TypeScript typecheck (push) Successful in 33s
CI & Build / Python tests (push) Successful in 1m6s
CI & Build / Build & push image (push) Successful in 23s
Paying down #2962 measured `flag="unused-css"` against a hand audit and found it had a permanent false-positive floor: roughly sixty classes it called unused are alive and always would be, because two ordinary authoring forms produce names no reader of `class=` attributes can see. A flag whose list you cannot act on line by line is worse than no flag — act on it and you delete live UI. - A transition `name=` IS a class reference. `<Transition name="toast">` makes Vue apply `.toast-enter-active` and its siblings at runtime, and React's `<CSSTransition classNames="fade">` does the same with a different suffix set. Every spelling of the tag is read (`Transition`, `TransitionGroup`, `transition-group`), and the emitted suffix set is the union of Vue 3, Vue 2 and React: naming a class no rule defines costs nothing, since it resolves to no row. A bound `:name` stays unknowable. - A concatenated name contributes its static head as a PREFIX reference. `` `status-${s}` ``, `'pri-' + p` and `class="card-{{ v }}"` all leave a head behind once the hole is blanked — and `_CLASS_TOKEN_RE` accepts a trailing hyphen, so until now the extractor emitted a junk token `"status-"` that matched nothing. It is now `status-*`, and resolve_consumers credits every row whose symbol starts with that head, each under the same own-file-else-fan-out rule as an exact token. `*` cannot occur in a class token, so the marker rides the existing dict[str, int] with no schema change. A head shorter than two characters says nothing and is dropped. Crediting every candidate row is the honest reading: the template genuinely does not say which one it built, and the alternative is reporting live rules as dead. What the map still cannot see is a name assembled in a script — `classList.add` — which stays deliberately out of scope; the skill, the `flag=` docstring and the refresh payload docs all say so now. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -118,8 +118,9 @@ async def list_shapes(
|
||||
whose body changed since judged (the judgment stands; confirm
|
||||
it again with classify_shapes, or re-judge); "unused-css"
|
||||
(milestone 302): live css rules no file's markup names — a
|
||||
deletion candidate to look at, never auto-deleted (the map reads
|
||||
templates only; a class built at runtime is invisible to it).
|
||||
deletion candidate to look at, never auto-deleted. Transition
|
||||
classes and concatenated names are read (#2970), so the list is
|
||||
worth acting on; a name assembled in a script still is not.
|
||||
|
||||
Returns {"shapes": [...], "total": N} — total counts every match, not
|
||||
just this page. Every css row carries `used_by` {count, paths} — the
|
||||
@@ -305,8 +306,9 @@ async def refresh_pattern_coverage(project_id: int) -> dict:
|
||||
unclassified, repos, largest_gaps, `proposed` (canon proposals awaiting
|
||||
confirmation), `derive_groups` (the biggest repeats-with-no-canon
|
||||
families, each css one with `consumers` — the files whose markup
|
||||
render it, milestone 302), `unused_css` (css rules no template names;
|
||||
None where the map has no evidence of templates), `derive_new` (copies
|
||||
render it, milestone 302), `unused_css` (css rules no template names —
|
||||
counting a `<Transition name=>`'s generated classes and concatenated
|
||||
names as named, #2970; None where the map has no evidence of templates), `derive_new` (copies
|
||||
that joined a family since the previous
|
||||
refresh — the drift to act on now: derive the canon, don't queue an
|
||||
audit), `proposer` (what this refresh examined) — plus
|
||||
|
||||
Reference in New Issue
Block a user