@adia-ai/adia-ui-forge 0.1.3 → 0.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/plugin.json +4 -7
- package/CHANGELOG.md +35 -34
- package/README.md +35 -40
- package/agents/a2ui-engineer.md +22 -53
- package/agents/component-author.md +29 -0
- package/agents/framework-verifier.md +26 -0
- package/agents/release-engineer.md +21 -81
- package/agents/routing-corpus.json +293 -64
- package/bin/demo-postwrite-pattern-gate +94 -0
- package/bin/forge-lint +17 -2
- package/bin/sidecar-prewrite-guard +104 -0
- package/commands/deploy.md +9 -0
- package/commands/dogfood.md +10 -0
- package/commands/gen-review.md +9 -0
- package/commands/release.md +10 -0
- package/hooks/hooks.json +15 -0
- package/package.json +3 -6
- package/references/contracts/a2ui-mcp-surface.md +35 -0
- package/references/contracts/migration-guide-format.md +34 -0
- package/references/shared/content-trust.md +19 -74
- package/skills/adia-a2ui/SKILL.md +99 -0
- package/skills/{adia-ui-a2ui → adia-a2ui}/evals/routing-corpus.json +10 -10
- package/skills/adia-a2ui/references/anti-patterns.md +27 -0
- package/skills/adia-a2ui/references/chunk-authoring.md +71 -0
- package/skills/adia-a2ui/references/corpus-discipline.md +68 -0
- package/skills/adia-a2ui/references/eval-diagnostics.md +86 -0
- package/skills/adia-a2ui/references/format-extension-decisions.md +66 -0
- package/skills/adia-a2ui/references/leverage-rules.md +52 -0
- package/skills/adia-a2ui/references/mcp-pipeline-ops.md +83 -0
- package/skills/adia-a2ui/references/mcp-tool-reference.md +59 -0
- package/skills/adia-a2ui/references/pipeline-overview.md +115 -0
- package/skills/adia-a2ui/references/semantic-fail-lifting.md +74 -0
- package/skills/adia-a2ui/references/strategy-engines.md +109 -0
- package/skills/adia-a2ui/references/zettel-calibration.md +104 -0
- package/skills/adia-author/SKILL.md +112 -0
- package/skills/adia-author/evals/routing-corpus.json +222 -0
- package/skills/{adia-ui-authoring → adia-author}/references/anti-patterns.md +33 -4
- package/skills/{adia-ui-authoring → adia-author}/references/authoring-cycle.md +9 -11
- package/skills/adia-author/references/canonical-pattern-index.md +243 -0
- package/skills/{adia-ui-authoring → adia-author}/references/code-style.md +19 -21
- package/skills/adia-author/references/common-gotchas.md +129 -0
- package/skills/adia-author/references/composite-demo-protocol.md +271 -0
- package/skills/{adia-ui-authoring → adia-author}/references/css-patterns.md +19 -6
- package/skills/{adia-ui-authoring → adia-author}/references/lifecycle-patterns.md +1 -0
- package/skills/{adia-ui-authoring → adia-author}/references/llm-bridge.md +3 -5
- package/skills/{adia-ui-authoring → adia-author}/references/module-promotion.md +20 -38
- package/skills/{adia-ui-authoring → adia-author}/references/primitive-audit.md +2 -4
- package/skills/{adia-ui-authoring → adia-author}/references/shell-patterns.md +12 -18
- package/skills/{adia-ui-authoring → adia-author}/references/token-contract.md +5 -7
- package/skills/{adia-ui-authoring → adia-author}/references/worked-example.md +3 -3
- package/skills/{adia-ui-authoring → adia-author}/references/yaml-contract.md +3 -3
- package/skills/{adia-ui-authoring → adia-author}/scripts/build-canonical-pattern-index.mjs +3 -3
- package/skills/adia-deploy/SKILL.md +128 -0
- package/skills/{adia-ui-ops → adia-deploy}/references/deploy-playbooks.md +47 -30
- package/skills/adia-dogfood/SKILL.md +124 -0
- package/skills/adia-dogfood/references/admin-shell-anatomy.md +77 -0
- package/skills/adia-dogfood/references/app-shell-pitfalls.md +66 -0
- package/skills/adia-dogfood/references/card-anatomy-sweep.md +66 -0
- package/skills/adia-dogfood/references/html-attr-sweep.md +63 -0
- package/skills/adia-dogfood/references/native-leak-annotations.md +73 -0
- package/skills/adia-dogfood/references/visual-probe-triage.md +80 -0
- package/skills/{adia-ui-dogfood → adia-dogfood}/scripts/analyze.mjs +30 -14
- package/skills/adia-gen-review/SKILL.md +127 -0
- package/skills/adia-gen-review/references/corpus-html-patterns.md +279 -0
- package/skills/adia-gen-review/references/loop-protocol.md +216 -0
- package/skills/adia-gen-review/references/rubric-cosmetic.md +100 -0
- package/skills/adia-gen-review/references/rubric-decompose.md +101 -0
- package/skills/adia-gen-review/references/rubric-score.md +214 -0
- package/skills/{adia-ui-gen-review → adia-gen-review}/references/scores.schema.json +2 -2
- package/skills/{adia-ui-gen-review → adia-gen-review}/scripts/gen-review-coverage-audit.mjs +4 -4
- package/skills/{adia-ui-gen-review → adia-gen-review}/scripts/gen-review-decompose.mjs +10 -6
- package/skills/{adia-ui-gen-review → adia-gen-review}/scripts/gen-review-status.mjs +5 -5
- package/skills/{adia-ui-gen-review → adia-gen-review}/scripts/validate-cycle-scores.mjs +5 -5
- package/skills/adia-llm-internals/SKILL.md +77 -0
- package/skills/{adia-ui-llm → adia-llm-internals}/references/adapter-contract.md +4 -2
- package/skills/{adia-ui-llm → adia-llm-internals}/references/add-a-provider.md +4 -5
- package/skills/{adia-ui-llm → adia-llm-internals}/references/bridge-facade.md +10 -3
- package/skills/{adia-ui-llm → adia-llm-internals}/references/browser-proxy-boundary.md +1 -1
- package/skills/{adia-ui-llm → adia-llm-internals}/references/model-registry.md +5 -3
- package/skills/{adia-ui-llm → adia-llm-internals}/references/streaming-sse.md +2 -2
- package/skills/adia-release/SKILL.md +72 -0
- package/skills/adia-release/references/changelog-discipline.md +119 -0
- package/skills/adia-release/references/cut-procedure.md +247 -0
- package/skills/adia-release/references/gates-catalog.md +222 -0
- package/skills/adia-release/references/independent-package-release.md +52 -0
- package/skills/adia-release/references/migration-guide-authoring.md +86 -0
- package/skills/adia-release/references/notes-authoring.md +90 -0
- package/skills/adia-release/references/recovery-paths.md +106 -0
- package/skills/{adia-ui-release → adia-release}/scripts/bump.mjs +28 -3
- package/skills/{adia-ui-release → adia-release}/scripts/dispatch-publish.mjs +10 -7
- package/skills/{adia-ui-release → adia-release}/scripts/insert-stub.mjs +1 -1
- package/skills/{adia-ui-release → adia-release}/scripts/package-paths.mjs +6 -0
- package/skills/{adia-ui-release → adia-release}/scripts/promote-unreleased.mjs +1 -1
- package/skills/{adia-ui-release → adia-release}/scripts/release-pack.mjs +38 -31
- package/skills/{adia-ui-release → adia-release}/scripts/tag-lockstep.mjs +7 -3
- package/skills/adia-site-docs/SKILL.md +68 -0
- package/skills/adia-site-docs/evals/audit-report.md +30 -0
- package/skills/adia-site-docs/evals/routing-corpus.json +176 -0
- package/skills/adia-site-docs/intent.md +72 -0
- package/agents/README.md +0 -209
- package/agents/author.md +0 -56
- package/agents/repo-steward.md +0 -56
- package/agents/spec-architect.md +0 -53
- package/agents/tech-lead.md +0 -57
- package/agents/verifier.md +0 -55
- package/bin/lib/audit-axes.mjs +0 -555
- package/bin/lib/dry-run-irreversible.mjs +0 -236
- package/bin/lib/run-skill-evals.mjs +0 -487
- package/bin/lib/teach-router.mjs +0 -250
- package/commands/adia-forge-a2ui.md +0 -10
- package/commands/adia-forge-author.md +0 -10
- package/commands/adia-forge-dogfood.md +0 -8
- package/commands/adia-forge-llm.md +0 -8
- package/commands/adia-forge-orient.md +0 -10
- package/commands/adia-forge-release.md +0 -8
- package/commands/adia-forge-review.md +0 -10
- package/references/shared/pev-rationale.md +0 -64
- package/references/shared/skill-conventions.md +0 -133
- package/skills/adia-ui-a2ui/CHANGELOG.md +0 -32
- package/skills/adia-ui-a2ui/SKILL.md +0 -243
- package/skills/adia-ui-a2ui/evals/adversarial-corpus.json +0 -75
- package/skills/adia-ui-a2ui/evals/teach-routing-cases.json +0 -100
- package/skills/adia-ui-a2ui/references/anti-patterns.md +0 -24
- package/skills/adia-ui-a2ui/references/chunk-authoring.md +0 -88
- package/skills/adia-ui-a2ui/references/corpus-discipline.md +0 -56
- package/skills/adia-ui-a2ui/references/eval-diagnostics.md +0 -127
- package/skills/adia-ui-a2ui/references/fragment-graph.md +0 -91
- package/skills/adia-ui-a2ui/references/mcp-pipeline-ops.md +0 -106
- package/skills/adia-ui-a2ui/references/mcp-tool-reference.md +0 -398
- package/skills/adia-ui-a2ui/references/pipeline-overview.md +0 -175
- package/skills/adia-ui-a2ui/references/semantic-fail-lifting.md +0 -120
- package/skills/adia-ui-a2ui/references/strategy-engines.md +0 -111
- package/skills/adia-ui-a2ui/references/teach-protocol.md +0 -220
- package/skills/adia-ui-a2ui/references/zettel-calibration.md +0 -93
- package/skills/adia-ui-a2ui/scripts/audit-a2ui-roster.mjs +0 -96
- package/skills/adia-ui-a2ui/scripts/teach-route.mjs +0 -157
- package/skills/adia-ui-a2ui/skill.json +0 -38
- package/skills/adia-ui-authoring/CHANGELOG.md +0 -32
- package/skills/adia-ui-authoring/SKILL.md +0 -256
- package/skills/adia-ui-authoring/assets/case-studies/admin-shell-decomposition.md +0 -101
- package/skills/adia-ui-authoring/assets/case-studies/maxtokens-32768-discovery.md +0 -109
- package/skills/adia-ui-authoring/assets/case-studies/theme-panel-promotion.md +0 -113
- package/skills/adia-ui-authoring/evals/adversarial-design-plan-gates.json +0 -138
- package/skills/adia-ui-authoring/evals/routing-corpus.json +0 -245
- package/skills/adia-ui-authoring/references/canonical-pattern-index.md +0 -179
- package/skills/adia-ui-authoring/references/common-gotchas.md +0 -93
- package/skills/adia-ui-authoring/references/composite-demo-protocol.md +0 -1084
- package/skills/adia-ui-authoring/references/teach-protocol.md +0 -428
- package/skills/adia-ui-authoring/scripts/audit-authoring-roster.mjs +0 -148
- package/skills/adia-ui-authoring/skill.json +0 -45
- package/skills/adia-ui-dogfood/CHANGELOG.md +0 -17
- package/skills/adia-ui-dogfood/README.md +0 -62
- package/skills/adia-ui-dogfood/SKILL.md +0 -866
- package/skills/adia-ui-dogfood/skill.json +0 -40
- package/skills/adia-ui-forge/SKILL.md +0 -88
- package/skills/adia-ui-forge/evals/routing-corpus.json +0 -30
- package/skills/adia-ui-gen-review/CHANGELOG.md +0 -108
- package/skills/adia-ui-gen-review/SKILL.md +0 -266
- package/skills/adia-ui-gen-review/references/loop-protocol.md +0 -712
- package/skills/adia-ui-gen-review/references/rubric-cosmetic.md +0 -144
- package/skills/adia-ui-gen-review/references/rubric-decompose.md +0 -117
- package/skills/adia-ui-gen-review/references/rubric-score.md +0 -249
- package/skills/adia-ui-gen-review/references/teach-protocol.md +0 -214
- package/skills/adia-ui-gen-review/skill.json +0 -23
- package/skills/adia-ui-llm/CHANGELOG.md +0 -25
- package/skills/adia-ui-llm/SKILL.md +0 -165
- package/skills/adia-ui-llm/evals/adversarial-corpus.json +0 -75
- package/skills/adia-ui-llm/evals/routing-corpus.json +0 -30
- package/skills/adia-ui-llm/evals/teach-routing-cases.json +0 -73
- package/skills/adia-ui-llm/references/teach-protocol.md +0 -78
- package/skills/adia-ui-llm/scripts/audit-llm-roster.mjs +0 -93
- package/skills/adia-ui-llm/scripts/teach-route.mjs +0 -119
- package/skills/adia-ui-llm/skill.json +0 -33
- package/skills/adia-ui-ops/CHANGELOG.md +0 -291
- package/skills/adia-ui-ops/SKILL.md +0 -401
- package/skills/adia-ui-ops/references/INDEX.md +0 -158
- package/skills/adia-ui-ops/references/audit-cadence.md +0 -263
- package/skills/adia-ui-ops/references/audit-patterns/archive-link-sweep.md +0 -96
- package/skills/adia-ui-ops/references/audit-patterns/audit-history-ledger.md +0 -162
- package/skills/adia-ui-ops/references/audit-patterns/browser-bundle-node-imports.md +0 -154
- package/skills/adia-ui-ops/references/audit-patterns/changelog-unreleased-bloat.md +0 -75
- package/skills/adia-ui-ops/references/audit-patterns/coverage-gaps.md +0 -187
- package/skills/adia-ui-ops/references/audit-patterns/entry-file-coverage.md +0 -122
- package/skills/adia-ui-ops/references/audit-patterns/format-hygiene.md +0 -217
- package/skills/adia-ui-ops/references/audit-patterns/lockstep-versioning.md +0 -113
- package/skills/adia-ui-ops/references/audit-patterns/memory-fragmentation.md +0 -180
- package/skills/adia-ui-ops/references/audit-patterns/orphan-detection.md +0 -202
- package/skills/adia-ui-ops/references/audit-patterns/pointer-validation.md +0 -180
- package/skills/adia-ui-ops/references/audit-patterns/redundancy-detection.md +0 -210
- package/skills/adia-ui-ops/references/audit-patterns/spec-dating-sweep.md +0 -91
- package/skills/adia-ui-ops/references/audit-patterns/stale-content.md +0 -182
- package/skills/adia-ui-ops/references/audit-patterns/staleness-tooling.md +0 -156
- package/skills/adia-ui-ops/references/audit-patterns/token-waste-detection.md +0 -196
- package/skills/adia-ui-ops/references/doc-types/adr-pattern.md +0 -210
- package/skills/adia-ui-ops/references/doc-types/architecture-md.md +0 -190
- package/skills/adia-ui-ops/references/doc-types/changelog.md +0 -183
- package/skills/adia-ui-ops/references/doc-types/decisions-log.md +0 -146
- package/skills/adia-ui-ops/references/doc-types/plan-roadmap.md +0 -182
- package/skills/adia-ui-ops/references/doc-types/postmortem-pattern.md +0 -206
- package/skills/adia-ui-ops/references/genres/prose-and-writing.md +0 -149
- package/skills/adia-ui-ops/references/guidance/context-budget.md +0 -137
- package/skills/adia-ui-ops/references/guidance/llm-doc-writing.md +0 -116
- package/skills/adia-ui-ops/references/guidance/reliability-dial.md +0 -186
- package/skills/adia-ui-ops/references/recipes/adr-introduction.md +0 -211
- package/skills/adia-ui-ops/references/recipes/audit-existing-repo.md +0 -234
- package/skills/adia-ui-ops/references/recipes/cold-start-harvest.md +0 -263
- package/skills/adia-ui-ops/references/recipes/concurrent-learnings-merge.md +0 -158
- package/skills/adia-ui-ops/references/recipes/continuous-learning-loop.md +0 -169
- package/skills/adia-ui-ops/references/recipes/external-reference-verification.md +0 -158
- package/skills/adia-ui-ops/references/recipes/findings-index-readout.md +0 -126
- package/skills/adia-ui-ops/references/recipes/greenfield-setup.md +0 -252
- package/skills/adia-ui-ops/references/recipes/harvest-repo-brain.md +0 -169
- package/skills/adia-ui-ops/references/recipes/import-repo-brain-harvest.md +0 -153
- package/skills/adia-ui-ops/references/recipes/memory-organization.md +0 -182
- package/skills/adia-ui-ops/references/recipes/recommend-then-validate.md +0 -199
- package/skills/adia-ui-ops/references/recipes/self-healing-hooks.md +0 -366
- package/skills/adia-ui-ops/references/recipes/skill-stewardship-loop.md +0 -113
- package/skills/adia-ui-ops/references/standards/agents-md-spec.md +0 -138
- package/skills/adia-ui-ops/references/standards/claude-md-convention.md +0 -123
- package/skills/adia-ui-ops/references/standards/cross-tool-matrix.md +0 -85
- package/skills/adia-ui-ops/references/standards/readme-conventions.md +0 -232
- package/skills/adia-ui-ops/references/teach-protocol.md +0 -215
- package/skills/adia-ui-ops/scripts/audit-ops-roster.mjs +0 -104
- package/skills/adia-ui-ops/skill.json +0 -65
- package/skills/adia-ui-release/CHANGELOG.md +0 -66
- package/skills/adia-ui-release/SKILL.md +0 -323
- package/skills/adia-ui-release/assets/case-studies/2026-05-20-batch-push-v0.6.14-v0.6.15.md +0 -144
- package/skills/adia-ui-release/assets/case-studies/2026-05-20-corpus-drift-remediation-v0.6.15.md +0 -155
- package/skills/adia-ui-release/assets/case-studies/2026-05-20-version-skip-correction-v0.6.12.md +0 -114
- package/skills/adia-ui-release/assets/case-studies/2026-05-21-author-from-scratch-v0.6.18.md +0 -139
- package/skills/adia-ui-release/assets/case-studies/2026-05-21-feedback37-retraction-v0.6.21.md +0 -124
- package/skills/adia-ui-release/assets/case-studies/2026-05-21-fn1-enrichment-pass-v0.6.19.md +0 -125
- package/skills/adia-ui-release/assets/case-studies/2026-05-21-stale-test-detection-v0.6.20.md +0 -142
- package/skills/adia-ui-release/assets/case-studies/2026-05-23-freshness-gate-recovery-v0.6.32.md +0 -97
- package/skills/adia-ui-release/assets/case-studies/2026-05-26-catalog-drift-recurring-v0.6.40.md +0 -147
- package/skills/adia-ui-release/assets/templates/stub-changelog.template.md +0 -22
- package/skills/adia-ui-release/evals/evals.json +0 -164
- package/skills/adia-ui-release/references/changelog-discipline.md +0 -250
- package/skills/adia-ui-release/references/cycle-happy-path.md +0 -520
- package/skills/adia-ui-release/references/exe-deploy.md +0 -149
- package/skills/adia-ui-release/references/gates-catalog.md +0 -778
- package/skills/adia-ui-release/references/independent-package-release.md +0 -129
- package/skills/adia-ui-release/references/ledger-discipline.md +0 -232
- package/skills/adia-ui-release/references/migration-guide-authoring.md +0 -174
- package/skills/adia-ui-release/references/multi-agent-baseline.md +0 -207
- package/skills/adia-ui-release/references/notes-authoring.md +0 -212
- package/skills/adia-ui-release/references/recovery-paths.md +0 -262
- package/skills/adia-ui-release/references/rollup-notes.md +0 -208
- package/skills/adia-ui-release/references/teach-protocol.md +0 -468
- package/skills/adia-ui-release/scripts/audit-gate-roster.mjs +0 -196
- package/skills/adia-ui-release/scripts/make-ledger.mjs +0 -200
- package/skills/adia-ui-release/skill.json +0 -77
- package/skills/dogfood-sweep/CHANGELOG.md +0 -37
- package/skills/dogfood-sweep/README.md +0 -105
- package/skills/dogfood-sweep/SKILL.md +0 -1000
- package/skills/dogfood-sweep/analyze.mjs +0 -600
- package/skills/dogfood-sweep/skill.json +0 -31
- /package/skills/{adia-ui-authoring → adia-author}/references/api-contract.md +0 -0
- /package/skills/{adia-ui-release → adia-release}/scripts/assert-monorepo-root.mjs +0 -0
|
@@ -1,1000 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: dogfood-sweep
|
|
3
|
-
description: Six-mode static + visual sweep across `/site/components/*`, `apps/`, `playgrounds/`, `catalog/`. Modes — (1) component visual probe (headless Chromium), (2) app-shell static QA, (3) HTML typo sweep, (4) native-primitive leak (`<button>` vs `<button-ui>`, `<input>` vs `<input-ui>`, etc.), (5) admin-shell composition (flags FEEDBACK-41 cluster — `<admin-statusbar>` / `[data-spacer]` / `[data-actions]` missing — the 2026-05-23 claims-ui regression class), (6) component anatomy + card header sweep (card-ui `<header><div>` wrapper anti-pattern + missing anatomy sections per FB-52). Triggers on "run dogfood sweep", "scan component pages", "find broken demos", "visual-QA all components", "audit native primitive leaks", "find raw `<button>` usage", "any `<button>` instead of `<button-ui>`?", "audit admin-shell composition", "shell composition audit", "find shells missing statusbar", "is the admin-shell complete?", "audit card header anatomy", "scan card-ui div wrappers", or scheduled `dogfood-*` routines.
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# dogfood-sweep
|
|
7
|
-
|
|
8
|
-
Walks every `/site/components/*` demo page in headless Chromium and runs
|
|
9
|
-
the visual-correctness probes that type-checks and tests don't catch.
|
|
10
|
-
Emits a severity-ranked report, applies the unambiguous fixes, opens a
|
|
11
|
-
PR with the report and any landed diffs.
|
|
12
|
-
|
|
13
|
-
The script (`.agents/skills/dogfood-sweep/analyze.mjs`) is the data gatherer. This
|
|
14
|
-
skill is the orchestrator: env setup, triage, fixes, PR.
|
|
15
|
-
|
|
16
|
-
## When to use
|
|
17
|
-
|
|
18
|
-
- A scheduled routine triggers the skill (CRON every 4h is the default
|
|
19
|
-
cadence — short enough to catch regressions before they ship, long
|
|
20
|
-
enough that the cache stays meaningful).
|
|
21
|
-
- A human asks to "dogfood the components", "scan the demos for visual
|
|
22
|
-
bugs", "run the headless visual sweep".
|
|
23
|
-
- After a wide refactor of token semantics, slot vocabulary, or
|
|
24
|
-
component-stamping patterns — exactly the changes that silently break
|
|
25
|
-
demos but pass the verify gate.
|
|
26
|
-
|
|
27
|
-
## What the script catches
|
|
28
|
-
|
|
29
|
-
| # | Probe | Bug class |
|
|
30
|
-
|---|-------|----------|
|
|
31
|
-
| 1 | Zero-area | Element collapsed: parent `display:none`, toolbar overflow spilled it, layout glitch |
|
|
32
|
-
| 2 | Transparent fill | `[data-swatch]` / variant pill / button / chart indicator with `rgba(0,0,0,0)` background — fallback token doesn't resolve (the chart-legend `--chart-N` class) |
|
|
33
|
-
| 3 | Empty control | `input-ui` / `search-ui` whose `connected()` should have stamped internals but didn't |
|
|
34
|
-
| 4 | Synonym-attr / synonym-slot drift | Markers from `docs/conventions/attribute-api-migration.md` (`avatar-ui[name]`, `grid-ui[cols]`, `card-ui [slot=meta]`, `stepper-ui[current]`, `stepper-item-ui[state]`) |
|
|
35
|
-
| 5 | Alert flex-row | `alert-ui` with multiple bare `<text-ui>` children (need `<col-ui slot="content">` wrap) |
|
|
36
|
-
| 6 | **Missing component CSS** | `*-ui` tag rendered on page but no stylesheet matching `/components/{prefix}/{prefix}.css` loaded. Catches the swap-to-primitive-but-forget-the-link class — markup looks right, JS registers the element, listbox renders **unstyled**. Added 2026-05-04 after a real miss. |
|
|
37
|
-
| 7 | **Unstyled popover** | `[popover]:popover-open` with transparent background + zero padding. Visual-symptom probe for the same class as #6, from the runtime side. |
|
|
38
|
-
| 8 | Console | Every `console.error` + `console.warn` during page load + 800ms settling |
|
|
39
|
-
|
|
40
|
-
Severity:
|
|
41
|
-
- **critical** — page is visibly broken; element collapsed, swatch
|
|
42
|
-
transparent, control un-stamped.
|
|
43
|
-
- **warning** — likely-broken composition the layout will silently
|
|
44
|
-
mis-render (e.g. alert flex-row).
|
|
45
|
-
- **info** — synonym-attribute or deprecation drift; not breaking,
|
|
46
|
-
sweep when convenient.
|
|
47
|
-
|
|
48
|
-
## Workflow
|
|
49
|
-
|
|
50
|
-
```bash
|
|
51
|
-
# 1. Fresh checkout / clean tree.
|
|
52
|
-
git checkout main && git pull
|
|
53
|
-
npm install --frozen-lockfile
|
|
54
|
-
|
|
55
|
-
# 2. Start dev server in the background. Wait for "ready".
|
|
56
|
-
npm run dev > /tmp/vite.log 2>&1 &
|
|
57
|
-
DEV_PID=$!
|
|
58
|
-
for i in {1..30}; do
|
|
59
|
-
grep -q "ready in" /tmp/vite.log && break
|
|
60
|
-
sleep 1
|
|
61
|
-
done
|
|
62
|
-
|
|
63
|
-
# 3. Run the analyzer. Exits 1 iff any critical findings.
|
|
64
|
-
node .agents/skills/dogfood-sweep/analyze.mjs
|
|
65
|
-
ANALYZER_EXIT=$?
|
|
66
|
-
|
|
67
|
-
# 4. Stop the dev server.
|
|
68
|
-
kill $DEV_PID 2>/dev/null
|
|
69
|
-
```
|
|
70
|
-
|
|
71
|
-
The report lands at `docs/reports/dogfooding-YYYY-MM-DD.md`.
|
|
72
|
-
|
|
73
|
-
## Triage rules
|
|
74
|
-
|
|
75
|
-
For each **critical** finding, evaluate independently:
|
|
76
|
-
|
|
77
|
-
1. **Diagnosis right?** Cross-check with component source. Probes are
|
|
78
|
-
probabilistic — `tab-ui`/`list-ui` 0×0 height, for example, is often
|
|
79
|
-
a logical-marker case, not a bug.
|
|
80
|
-
2. **Fix mechanical and unambiguous?** Decision rule below; if you'd
|
|
81
|
-
need to negotiate with a human about *what* the right fix is, leave
|
|
82
|
-
it for the human.
|
|
83
|
-
3. **Pattern documented?** Cross-check
|
|
84
|
-
`docs/conventions/attribute-api-migration.md` and the project memory
|
|
85
|
-
under `~/.claude/projects/-Users-kimba-Projects-chat-ui/memory/`.
|
|
86
|
-
|
|
87
|
-
Apply the fix iff all three are true.
|
|
88
|
-
|
|
89
|
-
## Fix decision rules (apply unattended)
|
|
90
|
-
|
|
91
|
-
| Finding kind | Mechanical fix | Source-of-truth |
|
|
92
|
-
|--------------|----------------|------------------|
|
|
93
|
-
| `transparent-fill` on `[data-swatch]` with inline `var(--chart-N)` fallback | Swap fallback to `var(--a-data-N)` in component CSS + JS | Memory: hard rule 6 ("All colors must reference --a-chrome-*, --a-data-0..9, or semantic tokens") |
|
|
94
|
-
| `drift` on `<avatar-ui name=…>` | `perl -i -pe 's/(<avatar-ui[^>]*?\s)name=/\1text=/g'` | `MIGRATION GUIDE.md` v0.0.20 section item 9 |
|
|
95
|
-
| `drift` on `<grid-ui cols=…>` | `cols=` → `columns=` via the same perl pattern | `attribute-api-migration.md` |
|
|
96
|
-
| `drift` on `<stepper-ui current=…>` | `current=` → `step=` | same |
|
|
97
|
-
| `drift` on `<stepper-item-ui state=…>` | drop the attribute (parent drives via `[step]`) | same |
|
|
98
|
-
| `drift` on `<card-ui [slot="meta"]>` | nest the tag inside `slot="heading"` (heading is `display: flex`) | `attribute-api-migration.md` |
|
|
99
|
-
| `alert-flex-row` | wrap multi-element body in `<col-ui slot="content" gap="0-5">` | `attribute-api-migration.md` |
|
|
100
|
-
|
|
101
|
-
Do **NOT** auto-fix:
|
|
102
|
-
|
|
103
|
-
- `zero-area` findings — diagnosis varies (intentional empty-state
|
|
104
|
-
demo, logical-marker pattern, real bug). Always human-eyeballed.
|
|
105
|
-
- `empty-control` on a component the skill doesn't recognize.
|
|
106
|
-
- Any finding with severity `warning` that lacks a documented fix
|
|
107
|
-
recipe in the table above.
|
|
108
|
-
- More than 5 mechanical fixes per PR — bound the blast radius so
|
|
109
|
-
humans can review fix shape before scaling to a sweep.
|
|
110
|
-
|
|
111
|
-
## Verification gate after any fix
|
|
112
|
-
|
|
113
|
-
Per `AGENTS.md`:
|
|
114
|
-
|
|
115
|
-
```bash
|
|
116
|
-
node scripts/build/components.mjs --verify # must print "clean"
|
|
117
|
-
npm run test:a2ui # must be 25/0/1 or better
|
|
118
|
-
node .agents/skills/dogfood-sweep/analyze.mjs # the original critical
|
|
119
|
-
# finding must be gone
|
|
120
|
-
```
|
|
121
|
-
|
|
122
|
-
If any gate fails after applying a fix, **revert the fix and file the
|
|
123
|
-
finding for human review** instead of opening a broken PR.
|
|
124
|
-
|
|
125
|
-
## After harvest
|
|
126
|
-
|
|
127
|
-
Always commit the report file under `docs/reports/`, even when zero
|
|
128
|
-
critical/warning findings — it's a paper trail of "things were fine on
|
|
129
|
-
this date", which is the data the agent uses to detect when something
|
|
130
|
-
*used* to be fine and is now broken.
|
|
131
|
-
|
|
132
|
-
If chunks regenerated as a side effect of any fix, run
|
|
133
|
-
`npm run harvest:chunks`.
|
|
134
|
-
|
|
135
|
-
## PR shape
|
|
136
|
-
|
|
137
|
-
```
|
|
138
|
-
title: dogfood: <YYYY-MM-DD> — <N> critical, <M> warning
|
|
139
|
-
body:
|
|
140
|
-
## Findings
|
|
141
|
-
|
|
142
|
-
${first 100 lines of the report}
|
|
143
|
-
|
|
144
|
-
Full report: [docs/reports/dogfooding-${date}.md](...)
|
|
145
|
-
|
|
146
|
-
## Auto-applied fixes (${K})
|
|
147
|
-
|
|
148
|
-
- [x] avatar-ui name= → text= in packages/web-components/components/table/index.html (5 instances)
|
|
149
|
-
- [x] (etc.)
|
|
150
|
-
|
|
151
|
-
## Left for human review (${L})
|
|
152
|
-
|
|
153
|
-
- zero-area on tab-ui (logical marker; needs human eyeball)
|
|
154
|
-
- (etc.)
|
|
155
|
-
```
|
|
156
|
-
|
|
157
|
-
Title is bounded so it sorts naturally in the PR list. Body always
|
|
158
|
-
includes the report excerpt + link.
|
|
159
|
-
|
|
160
|
-
## Repo touchpoints
|
|
161
|
-
|
|
162
|
-
- Script: [`analyze.mjs`](analyze.mjs) (sibling file).
|
|
163
|
-
- Script docs: [`README.md`](README.md) (sibling file).
|
|
164
|
-
- Reports archive: `docs/reports/dogfooding-*.md`
|
|
165
|
-
- Probe contract source: probes are inline in `analyze.mjs`. New probe →
|
|
166
|
-
add to that file's `runProbes()` or `runStampContractProbe()`, then
|
|
167
|
-
document the bug class it catches in the table above.
|
|
168
|
-
|
|
169
|
-
## When to expand the probe set
|
|
170
|
-
|
|
171
|
-
- New component ships with internal stamping logic → add to
|
|
172
|
-
`STAMP_CONTRACTS` in `analyze.mjs`.
|
|
173
|
-
- New synonym-attribute drift class documented in
|
|
174
|
-
`attribute-api-migration.md` → add to `DRIFT_MARKERS`.
|
|
175
|
-
- A class of bugs slips past the analyzer in a real PR → add a probe
|
|
176
|
-
for that bug class first, **then** fix the bug. Test for the test.
|
|
177
|
-
|
|
178
|
-
## Cadence rationale
|
|
179
|
-
|
|
180
|
-
4-hour CRON cadence chosen because:
|
|
181
|
-
|
|
182
|
-
- Pages drift on the order of hours, not days, when a wide-refactor
|
|
183
|
-
PR lands. A daily sweep would let a regression sit half a day.
|
|
184
|
-
- The full sweep is ~3 minutes (82 pages × ~2s each), bounded by
|
|
185
|
-
Playwright's networkidle. Cheap to run.
|
|
186
|
-
- The Anthropic prompt cache is 5-minute TTL, so 4h sweeps don't
|
|
187
|
-
share cache but each fully amortizes their own miss.
|
|
188
|
-
- Pre-merge checks should still catch most regressions; this is the
|
|
189
|
-
belt-and-braces layer for the things that slip through.
|
|
190
|
-
|
|
191
|
-
---
|
|
192
|
-
|
|
193
|
-
## § App Shell QA
|
|
194
|
-
|
|
195
|
-
Mechanical QA sweep across every `apps/<name>/.../<page>.html` shell.
|
|
196
|
-
Pairs with dogfood-sweep (both run headless check scripts over HTML files)
|
|
197
|
-
but targets the Shell + Fragment + Controller trio pitfalls (ADR-0021)
|
|
198
|
-
rather than component visual correctness.
|
|
199
|
-
|
|
200
|
-
### When to use
|
|
201
|
-
|
|
202
|
-
- After any `apps/` structural sweep — new app, page-trio migration,
|
|
203
|
-
cluster rollup, contents.js refactor.
|
|
204
|
-
- Before tagging a release — the trio convention is consumer-facing;
|
|
205
|
-
broken shells deploy as 404s on EXE.
|
|
206
|
-
- When a single playground regresses visually and you suspect a class
|
|
207
|
-
issue rather than a one-off.
|
|
208
|
-
- On request: "audit app shells", "QA the playgrounds", "find broken
|
|
209
|
-
app pages", "shell sweep".
|
|
210
|
-
|
|
211
|
-
### What the script catches
|
|
212
|
-
|
|
213
|
-
The six pitfalls from `docs/conventions/composition-and-examples.md § Pitfalls when shell-ifying`:
|
|
214
|
-
|
|
215
|
-
| # | Pitfall | Audit finding |
|
|
216
|
-
|---|---------|---------------|
|
|
217
|
-
| 1 | Co-located custom-elements not imported | `[unregistered-tag] <tab-ui>` (lives in `tabs/tab.js`, not `tab/`) |
|
|
218
|
-
| 2 | Demo-root flex chain broken | `[demo-root-flex] body is full-height flex but #demo-root has display:block flex:0` |
|
|
219
|
-
| 3 | Composite renders internal *-ui tags HTML doesn't show | `[unregistered-tag] <textarea-ui>` when only `<chat-input-ui>` is in the markup |
|
|
220
|
-
| 4 | Top-level await without async setup wrap | `[setup-failed] contents.js setup failed:` console error |
|
|
221
|
-
| 5 | Vite import-analysis 500 on dynamic import | `[network-4xx] 500 import-analysis` for `./<name>.contents.js` |
|
|
222
|
-
| 6 | icon-ui not imported despite `<icon-ui>` / `[icon=…]` / composites that render icons | `[icon-ui-missing]` |
|
|
223
|
-
|
|
224
|
-
Plus three secondary signals:
|
|
225
|
-
- `[collapsed-element] <foo-ui> is 0px tall` — element registered but layout collapsed.
|
|
226
|
-
- `[unregistered-tag] <bar-ui>` for any non-CSS-only primitive.
|
|
227
|
-
- `[network-4xx]` — typoed `<link rel="stylesheet">` href, missing contents.html,
|
|
228
|
-
or a stale `import.meta.url` reference.
|
|
229
|
-
|
|
230
|
-
False positives already filtered: CSS-only components (`aside-ui`, `header-ui`,
|
|
231
|
-
`section-ui`, `footer-ui`), inherently-thin elements (`divider-ui`,
|
|
232
|
-
`separator-ui`), empty containers with no children.
|
|
233
|
-
|
|
234
|
-
### How to run
|
|
235
|
-
|
|
236
|
-
```bash
|
|
237
|
-
# Full sweep (~2 min wall-clock, 73 shells × ~1.5s each)
|
|
238
|
-
node scripts/dev/audit-app-shells.mjs
|
|
239
|
-
|
|
240
|
-
# One page (debug a specific finding)
|
|
241
|
-
node scripts/dev/audit-app-shells.mjs --only=chat
|
|
242
|
-
|
|
243
|
-
# Stop on first issue
|
|
244
|
-
node scripts/dev/audit-app-shells.mjs --fail-fast
|
|
245
|
-
|
|
246
|
-
# Diff against prod to see what's locally regressed
|
|
247
|
-
node scripts/dev/audit-app-shells.mjs --compare-prod
|
|
248
|
-
```
|
|
249
|
-
|
|
250
|
-
Prerequisites:
|
|
251
|
-
1. `npm run dev` must be running (vite on `:5173`)
|
|
252
|
-
2. `npm run proxy` (or `node packages/llm/server.js`) for the LLM proxy (only if probing chat / gen-ui)
|
|
253
|
-
|
|
254
|
-
If vite is mid dep-reoptimization, the first sweep may stall. Wait 30s, then re-run.
|
|
255
|
-
|
|
256
|
-
### Expected output
|
|
257
|
-
|
|
258
|
-
Clean run: each shell line prints a green checkmark with finding count = 0.
|
|
259
|
-
Any findings print the pitfall tag + a one-line description. Exit code 0 when
|
|
260
|
-
no critical findings; exit code 1 on any critical.
|
|
261
|
-
|
|
262
|
-
### When to escalate
|
|
263
|
-
|
|
264
|
-
Apply the fix recipes from `docs/conventions/composition-and-examples.md`
|
|
265
|
-
for pitfalls 1–6 unattended. Escalate to human review when:
|
|
266
|
-
- A finding cannot be matched to a known pitfall (unexpected tag name, novel
|
|
267
|
-
import pattern, framework-level error in console).
|
|
268
|
-
- More than 10 shells are affected — bound blast radius.
|
|
269
|
-
- The fix would alter shared catalog/ or packages/ files (not just the shell).
|
|
270
|
-
|
|
271
|
-
### Fix recipes (summary)
|
|
272
|
-
|
|
273
|
-
Full recipes in `docs/conventions/composition-and-examples.md § Pitfalls when shell-ifying`.
|
|
274
|
-
Quick index:
|
|
275
|
-
|
|
276
|
-
- **Pitfall 1** — add `import "/packages/web-components/components/tabs/tab.js"` (co-located sibling).
|
|
277
|
-
- **Pitfall 2** — add `#demo-root { flex: 1; display: flex; flex-direction: column; min-height: 0; }`.
|
|
278
|
-
- **Pitfall 3** — import every primitive the composite renders internally (see composite table below).
|
|
279
|
-
- **Pitfall 4** — wrap top-level `await` in `export default async function setup(host) { ... }`.
|
|
280
|
-
- **Pitfall 5** — add `/* @vite-ignore */` to the dynamic import.
|
|
281
|
-
- **Pitfall 6** — add `import "/packages/web-components/components/icon/icon.js"` to shell head or contents.js.
|
|
282
|
-
|
|
283
|
-
Known composites and their internal primitives:
|
|
284
|
-
|
|
285
|
-
| Composite | Internally renders |
|
|
286
|
-
|-----------|-------------------|
|
|
287
|
-
| `chat-input-ui` | `textarea-ui`, `select-ui` |
|
|
288
|
-
| `search-ui` | `input-ui` |
|
|
289
|
-
| `empty-state-ui` | `icon-ui`, `text-ui` |
|
|
290
|
-
| `button-ui` (with `icon=`) | `icon-ui` |
|
|
291
|
-
| `badge-ui` (with `icon=`) | `icon-ui` |
|
|
292
|
-
| `menu-item-ui` | `icon-ui`, `text-ui` |
|
|
293
|
-
|
|
294
|
-
### Verification
|
|
295
|
-
|
|
296
|
-
1. Apply diffs.
|
|
297
|
-
2. Re-run `node scripts/dev/audit-app-shells.mjs`. Target: 0 findings on real issues.
|
|
298
|
-
3. Spot-check the worst-affected page in a real browser.
|
|
299
|
-
4. Commit: `fix(repo-org): icon-ui imports in N contents.js — empty-state, theme toggle, send button missing`
|
|
300
|
-
|
|
301
|
-
### Related artifacts
|
|
302
|
-
|
|
303
|
-
- Audit script: `scripts/dev/audit-app-shells.mjs`
|
|
304
|
-
- Pitfalls + recipes: `docs/conventions/composition-and-examples.md § Pitfalls when shell-ifying`
|
|
305
|
-
- Page-trio convention: ADR-0021 (`.brain/adrs/0021-page-shell-contents-controller-trio.md`)
|
|
306
|
-
- Apps directory layout: ADR-0020 (`.brain/adrs/0020-apps-and-component-demo-co-location.md`)
|
|
307
|
-
|
|
308
|
-
---
|
|
309
|
-
|
|
310
|
-
## § HTML Typo Sweep
|
|
311
|
-
|
|
312
|
-
Find and fix a specific, high-frequency HTML authoring bug: attribute values
|
|
313
|
-
that open with `"`, embed additional `"` characters unescaped, and close with
|
|
314
|
-
another `"` — breaking the attribute boundary and confusing the HTML parser.
|
|
315
|
-
Both this sweep and the dogfood analyzer operate on static HTML files,
|
|
316
|
-
making them natural companions.
|
|
317
|
-
|
|
318
|
-
### The bug class
|
|
319
|
-
|
|
320
|
-
Canonical broken pattern:
|
|
321
|
-
|
|
322
|
-
```html
|
|
323
|
-
<div data-artifact-label="name="attachment"">
|
|
324
|
-
```
|
|
325
|
-
|
|
326
|
-
The parser sees:
|
|
327
|
-
- `data-artifact-label=""` — value empty (closes at the second `"`)
|
|
328
|
-
- `attachment` — a new, unquoted attribute
|
|
329
|
-
- `""` — a stray empty-valued attribute
|
|
330
|
-
|
|
331
|
-
Common offenders: `data-artifact-label`, `data-note`, `aria-label`, `title`, `alt`.
|
|
332
|
-
|
|
333
|
-
### When to use
|
|
334
|
-
|
|
335
|
-
- User says "fix html typos", "sweep for broken attributes", "check for nested
|
|
336
|
-
double quotes", "audit html for this pattern".
|
|
337
|
-
- You just fixed one instance in one file and the user asks whether the same
|
|
338
|
-
bug exists elsewhere.
|
|
339
|
-
- A commit touches docs/demo HTML at scale; use as a pre-flight check.
|
|
340
|
-
|
|
341
|
-
### When NOT to use
|
|
342
|
-
|
|
343
|
-
- Fixing a single isolated typo in one file (use targeted edit directly).
|
|
344
|
-
- Fixing broader HTML issues: missing closing tags, malformed nesting, bad entity
|
|
345
|
-
references. This skill does one thing only.
|
|
346
|
-
- JavaScript string literals or template-literal HTML inside `<script>` blocks.
|
|
347
|
-
- Non-HTML files (Markdown with inline HTML blocks, JSX, Vue templates).
|
|
348
|
-
|
|
349
|
-
### Detection regex
|
|
350
|
-
|
|
351
|
-
Use the **narrow** audit regex — a broad regex produces thousands of false
|
|
352
|
-
positives on legitimate multi-attribute tags:
|
|
353
|
-
|
|
354
|
-
```js
|
|
355
|
-
// Narrow: an attribute closes with " and the next char is not whitespace or >
|
|
356
|
-
const AUDIT = /ATTR_NAME="[^"]*"(?=[^\s>])/g;
|
|
357
|
-
```
|
|
358
|
-
|
|
359
|
-
Audit loop — Node one-shot:
|
|
360
|
-
|
|
361
|
-
```js
|
|
362
|
-
import fs from 'node:fs';
|
|
363
|
-
import path from 'node:path';
|
|
364
|
-
|
|
365
|
-
function walk(dir) {
|
|
366
|
-
const out = [];
|
|
367
|
-
for (const e of fs.readdirSync(dir, { withFileTypes: true })) {
|
|
368
|
-
const p = path.join(dir, e.name);
|
|
369
|
-
if (e.isDirectory()) out.push(...walk(p));
|
|
370
|
-
else if (e.name.endsWith('.html')) out.push(p);
|
|
371
|
-
}
|
|
372
|
-
return out;
|
|
373
|
-
}
|
|
374
|
-
|
|
375
|
-
const ATTR = 'data-artifact-label'; // the attr to sweep
|
|
376
|
-
const ROOT = 'site'; // the tree to scan
|
|
377
|
-
const RE = new RegExp(`${ATTR}="[^"]*"(?=[^\\s>])`, 'g');
|
|
378
|
-
|
|
379
|
-
let total = 0;
|
|
380
|
-
const perFile = [];
|
|
381
|
-
for (const f of walk(ROOT)) {
|
|
382
|
-
const html = fs.readFileSync(f, 'utf8');
|
|
383
|
-
let m, count = 0;
|
|
384
|
-
while ((m = RE.exec(html)) !== null) count++;
|
|
385
|
-
if (count) { total += count; perFile.push({ f, count }); }
|
|
386
|
-
}
|
|
387
|
-
console.log(`${total} broken across ${perFile.length} files`);
|
|
388
|
-
for (const { f, count } of perFile) console.log(` ${count}\t${f}`);
|
|
389
|
-
```
|
|
390
|
-
|
|
391
|
-
Report per-file counts to the user before fixing. If count is zero, stop.
|
|
392
|
-
|
|
393
|
-
### Fix procedure
|
|
394
|
-
|
|
395
|
-
Fix regex — captures intended value, stops at `>` so it never crosses a
|
|
396
|
-
tag boundary:
|
|
397
|
-
|
|
398
|
-
```js
|
|
399
|
-
const FIX = new RegExp(
|
|
400
|
-
`${ATTR}="([^>]*[a-z0-9][a-z0-9_-]*="[^"]*")"(?=[\\s>])`,
|
|
401
|
-
'g',
|
|
402
|
-
);
|
|
403
|
-
```
|
|
404
|
-
|
|
405
|
-
Wrap the captured value in single quotes on the outside (HTML allows
|
|
406
|
-
single-quoted attribute values; preferred over `"` for readability):
|
|
407
|
-
|
|
408
|
-
```js
|
|
409
|
-
const fixed = html.replace(FIX, (_m, value) => {
|
|
410
|
-
if (value.includes("'")) {
|
|
411
|
-
const escaped = value.replace(/"/g, '"');
|
|
412
|
-
return `${ATTR}="${escaped}"`;
|
|
413
|
-
}
|
|
414
|
-
return `${ATTR}='${value}'`;
|
|
415
|
-
});
|
|
416
|
-
```
|
|
417
|
-
|
|
418
|
-
After the automated pass, re-run the Phase 1 audit. Any remaining hits are
|
|
419
|
-
edge cases (trailing prose, no outer `ident=` prefix) — fix each individually
|
|
420
|
-
with a targeted edit. Don't extend the automated regex for these.
|
|
421
|
-
|
|
422
|
-
### Which attributes to sweep
|
|
423
|
-
|
|
424
|
-
Start with the attribute the user flagged, then iterate in order:
|
|
425
|
-
|
|
426
|
-
1. `data-artifact-label` — design-system demo pages label each example.
|
|
427
|
-
2. `data-note` — often holds prose with example attribute syntax inline.
|
|
428
|
-
3. `aria-label` — often authored as `aria-label="Save "foo""`.
|
|
429
|
-
4. `title` — tooltip text with inline attribute citations.
|
|
430
|
-
5. `alt` — image alt text occasionally references attributes.
|
|
431
|
-
6. `placeholder` — rare, but seen.
|
|
432
|
-
|
|
433
|
-
Run each attribute independently. Do NOT glob `ANY_ATTR="..."` in one regex.
|
|
434
|
-
|
|
435
|
-
### Verification
|
|
436
|
-
|
|
437
|
-
All three must pass before declaring the sweep done:
|
|
438
|
-
|
|
439
|
-
1. **Zero remaining** — re-run the Phase 1 audit. Expected: `0` broken values across 0 files.
|
|
440
|
-
2. **Tag balance** — for each touched file, count opening vs closing tags:
|
|
441
|
-
```js
|
|
442
|
-
const openDiv = (html.match(/<div\b/g) || []).length;
|
|
443
|
-
const closeDiv = (html.match(/<\/div>/g) || []).length;
|
|
444
|
-
// Expect openDiv === closeDiv. Same for section, grid-ui, article, etc.
|
|
445
|
-
```
|
|
446
|
-
3. **HTTP spot check** — if a dev server is running, sample-curl a handful of fixed pages:
|
|
447
|
-
```bash
|
|
448
|
-
for p in breadcrumb stat input upload; do
|
|
449
|
-
code=$(curl -s -o /dev/null -w "%{http_code}" \
|
|
450
|
-
"http://localhost:5174/site/pages/components/$p/index.html")
|
|
451
|
-
echo "$code $p"
|
|
452
|
-
done
|
|
453
|
-
```
|
|
454
|
-
|
|
455
|
-
### Anti-patterns
|
|
456
|
-
|
|
457
|
-
- **Never sweep with a broad regex** like `="[^"]*"[^"]*"` across all attributes.
|
|
458
|
-
- **Never auto-fix with the non-greedy version of the capture** — it stops at
|
|
459
|
-
the first `"` and captures only `name=` instead of `name="attachment"`.
|
|
460
|
-
- **Never edit `<script>` block content with these regexes** — embedded JS
|
|
461
|
-
strings have different quoting rules.
|
|
462
|
-
- **Never silently skip edge cases** after the automated pass. Phase 1
|
|
463
|
-
re-audit is non-optional.
|
|
464
|
-
- **Never commit the one-shot fix script to the repo.** Use `/tmp` or `node -e`.
|
|
465
|
-
|
|
466
|
-
### Output format to user
|
|
467
|
-
|
|
468
|
-
```
|
|
469
|
-
Swept `data-artifact-label` across site/**/*.html:
|
|
470
|
-
- 86 fixes across 21 files (automated regex).
|
|
471
|
-
- 4 edge cases fixed manually (trailing prose / no outer ident= prefix):
|
|
472
|
-
calendar-picker (1), menu (1), segmented (2).
|
|
473
|
-
|
|
474
|
-
Verification:
|
|
475
|
-
- Final audit — 0 remaining broken values.
|
|
476
|
-
- Tag balance — div/section/grid-ui match on all 22 touched files.
|
|
477
|
-
- HTTP spot check — 200 on 13 sampled pages.
|
|
478
|
-
```
|
|
479
|
-
|
|
480
|
-
---
|
|
481
|
-
|
|
482
|
-
## § Native Primitive Leak Audit
|
|
483
|
-
|
|
484
|
-
Static-HTML probe that **flags questionable implementations** where an
|
|
485
|
-
agent (or human) reached for a native HTML primitive (`<button>`,
|
|
486
|
-
`<input>`, `<select>`, `<textarea>`, `<a href>`, `<img>`, `<table>`)
|
|
487
|
-
inside a composition surface (`apps/`, `playgrounds/`, `catalog/`)
|
|
488
|
-
when an AdiaUI `*-ui` primitive exists.
|
|
489
|
-
|
|
490
|
-
**Distinct from the component-CSS-loaded probe (#6 above)**: that probe
|
|
491
|
-
catches "you used `<button-ui>` but forgot the CSS link"; this probe
|
|
492
|
-
catches "you used `<button>` instead of `<button-ui>` at all". Same
|
|
493
|
-
bug-class family (design-system bypass) from the opposite direction.
|
|
494
|
-
|
|
495
|
-
**Why this exists**: AdiaUI is light-DOM substrate (ADR-0033). Native
|
|
496
|
-
primitives bypass theme tokens, focus-ring discipline, accessibility
|
|
497
|
-
patterns, and the trait registry. Even when type-checks + visual
|
|
498
|
-
sweeps pass, raw `<button>` is a smell — usually an agent
|
|
499
|
-
short-circuit, occasionally a legitimate escape hatch (file pickers,
|
|
500
|
-
hidden inputs, content-loaded images).
|
|
501
|
-
|
|
502
|
-
### When to use
|
|
503
|
-
|
|
504
|
-
- After any wide authoring sweep where an agent generated screens
|
|
505
|
-
(genui rendering session, page-shell template authoring,
|
|
506
|
-
catalog/ui-patterns rollouts).
|
|
507
|
-
- Before tagging a release — questionable native primitives are
|
|
508
|
-
consumer-facing smells.
|
|
509
|
-
- On request: "audit native primitive leaks", "find raw button usage",
|
|
510
|
-
"flag questionable HTML implementations", "scan for non-adia
|
|
511
|
-
primitives", "any `<button>` instead of `<button-ui>`?", "any
|
|
512
|
-
`<input>` instead of `<input-ui>`?".
|
|
513
|
-
- As part of the dogfood CRON sweep — pairs with the visual probes
|
|
514
|
-
to catch both "wrong CSS" (#6/7) and "wrong tag" (this).
|
|
515
|
-
|
|
516
|
-
### How to run
|
|
517
|
-
|
|
518
|
-
```bash
|
|
519
|
-
# Default — criticals + warnings only, info hidden
|
|
520
|
-
node scripts/dev/audit-native-primitive-leak.mjs
|
|
521
|
-
|
|
522
|
-
# Show all findings including info-level (<a href>, <img>)
|
|
523
|
-
node scripts/dev/audit-native-primitive-leak.mjs --all
|
|
524
|
-
|
|
525
|
-
# Promote <a href> probe to warning severity (off by default — too noisy
|
|
526
|
-
# given how often raw <a> is legitimate for navigation/anchors)
|
|
527
|
-
node scripts/dev/audit-native-primitive-leak.mjs --strict-links
|
|
528
|
-
|
|
529
|
-
# Restrict to a specific tag
|
|
530
|
-
node scripts/dev/audit-native-primitive-leak.mjs --tag=button
|
|
531
|
-
|
|
532
|
-
# Restrict to a specific directory
|
|
533
|
-
node scripts/dev/audit-native-primitive-leak.mjs --include=apps/genui
|
|
534
|
-
|
|
535
|
-
# JSON output for downstream processing
|
|
536
|
-
node scripts/dev/audit-native-primitive-leak.mjs --json
|
|
537
|
-
|
|
538
|
-
# Strict mode — any finding (incl. info) fails the build
|
|
539
|
-
node scripts/dev/audit-native-primitive-leak.mjs --strict
|
|
540
|
-
```
|
|
541
|
-
|
|
542
|
-
Exit codes: `0` = no critical findings; `1` = ≥1 critical (or any finding in `--strict`).
|
|
543
|
-
|
|
544
|
-
### What the probe catches
|
|
545
|
-
|
|
546
|
-
| Tag | Severity | AdiaUI equivalent | Escape hatches (NOT flagged) |
|
|
547
|
-
|-----|----------|-------------------|------------------------------|
|
|
548
|
-
| `<button>` | **critical** | `button-ui` | None — always a smell |
|
|
549
|
-
| `<input>` | **critical** | `input-ui` | `type="hidden"`, `type="file"`, `type="radio"`, `type="checkbox"` |
|
|
550
|
-
| `<select>` | **critical** | `select-ui` | None |
|
|
551
|
-
| `<textarea>` | **critical** | `textarea-ui` | None |
|
|
552
|
-
| `<table>` | **critical** | `table-ui` | None |
|
|
553
|
-
| `<a href>` | info (warning with `--strict-links`) | `link-ui` | Bare `<a name=…>` anchors (no `href`) |
|
|
554
|
-
| `<img>` | info | `image-ui` | None automatic — `<img>` is often legit for content-loaded assets |
|
|
555
|
-
|
|
556
|
-
**Skipped automatically**:
|
|
557
|
-
- Showcase demos at `packages/web-components/components/<name>/<name>.html`
|
|
558
|
-
— these legitimately demonstrate native usage in code-block examples
|
|
559
|
-
- Native primitives inside `<code>`, `<pre>`, `<script>`, `<style>` blocks
|
|
560
|
-
— code examples, not rendered DOM
|
|
561
|
-
- Native primitives inside the matching primitive's own component
|
|
562
|
-
directory (e.g. `<input>` inside `packages/web-components/components/input/`
|
|
563
|
-
is stamp-internal)
|
|
564
|
-
- `node_modules`, `.git`, `dist`, `build`, `.brain`
|
|
565
|
-
|
|
566
|
-
### Intentional escape hatch — annotation
|
|
567
|
-
|
|
568
|
-
When a native primitive IS the right answer (file picker, hidden
|
|
569
|
-
field, content-loaded image, anchor with custom semantics, code-editor
|
|
570
|
-
input that's not a form field, docs-index table that's not a data
|
|
571
|
-
widget), annotate adjacent to the tag so the audit demotes the finding
|
|
572
|
-
to `info`. Two equivalent forms:
|
|
573
|
-
|
|
574
|
-
**Attribute form (most reliable — preferred)**:
|
|
575
|
-
|
|
576
|
-
```html
|
|
577
|
-
<input type="file" data-native-ok="file picker, no upload-ui equiv" accept=".json" />
|
|
578
|
-
```
|
|
579
|
-
|
|
580
|
-
**Preceding-comment form**:
|
|
581
|
-
|
|
582
|
-
```html
|
|
583
|
-
<!-- native-ok: file picker, no upload-ui equivalent -->
|
|
584
|
-
<input type="file" accept=".json" />
|
|
585
|
-
```
|
|
586
|
-
|
|
587
|
-
The audit checks a **200-char window before** the opening tag for
|
|
588
|
-
intent markers (`<!-- native-ok:` or `data-native-ok=`). The window
|
|
589
|
-
was widened from 80 chars in commit `<post-§3-commit>` after a peer
|
|
590
|
-
agent found that realistic preceding-line comments (indent + comment
|
|
591
|
-
prefix + reason text + closing `-->` + newline) sat at exactly the
|
|
592
|
-
80-char boundary and were not detected. The attribute form is still
|
|
593
|
-
more reliable because it lives INSIDE the opening tag — no window
|
|
594
|
-
math needed.
|
|
595
|
-
|
|
596
|
-
Intent markers within the window demote the finding to `info`-level
|
|
597
|
-
(still visible in `--all` mode for the paper trail, but doesn't fail
|
|
598
|
-
the audit).
|
|
599
|
-
|
|
600
|
-
### Triage rules
|
|
601
|
-
|
|
602
|
-
For each **critical** finding:
|
|
603
|
-
|
|
604
|
-
1. **Is there a genuine escape hatch?** (file picker, hidden input,
|
|
605
|
-
stamp-internal usage that wasn't auto-detected) — add the
|
|
606
|
-
`<!-- native-ok -->` annotation; re-run audit.
|
|
607
|
-
2. **Is it a real bug?** Replace `<button>` with `<button-ui>`,
|
|
608
|
-
`<input>` with `<input-ui>` (preserving slot/attribute semantics
|
|
609
|
-
via `attribute-api-migration.md`).
|
|
610
|
-
3. **Is the AdiaUI primitive registered in the consuming shell?**
|
|
611
|
-
Cross-check that `button.js` / `input.js` etc. are imported via
|
|
612
|
-
the page-trio's `.contents.js` or via a `<link rel="stylesheet">`.
|
|
613
|
-
|
|
614
|
-
**Do NOT auto-fix** — native-primitive replacement requires
|
|
615
|
-
attribute-shape decisions (`button` → `button-ui label="…"` vs
|
|
616
|
-
`<button-ui><text-ui>…</text-ui></button-ui>` depending on slot
|
|
617
|
-
discipline). Human eyeball every replacement; this audit surfaces, it
|
|
618
|
-
doesn't repair.
|
|
619
|
-
|
|
620
|
-
### Pair with peer probes
|
|
621
|
-
|
|
622
|
-
- The **component-CSS-loaded probe (#6)** catches "wrong CSS"; this
|
|
623
|
-
catches "wrong tag". Run both as a regular sweep.
|
|
624
|
-
- The **app-shell QA sweep** (`scripts/dev/audit-app-shells.mjs`)
|
|
625
|
-
catches "missing import"; this catches "didn't use the primitive at
|
|
626
|
-
all". Pre-merge gate composition: shell-QA + native-primitive-leak
|
|
627
|
-
for a 2-script "are we using the design system honestly?" check.
|
|
628
|
-
|
|
629
|
-
### Output shape (human-readable)
|
|
630
|
-
|
|
631
|
-
```
|
|
632
|
-
[audit-native-primitive-leak] scanning apps, playgrounds, catalog
|
|
633
|
-
|
|
634
|
-
apps/genui/app/render-preview/render-preview.contents.html
|
|
635
|
-
✗ L36 <textarea> → consider <textarea-ui>
|
|
636
|
-
<textarea
|
|
637
|
-
apps/overview.examples.html
|
|
638
|
-
✗ L10 <table> → consider <table-ui>
|
|
639
|
-
<table>
|
|
640
|
-
|
|
641
|
-
Summary: 2 critical, 0 warning, 168 info
|
|
642
|
-
(scanned: apps + playgrounds + catalog; 7 probe(s) active)
|
|
643
|
-
(168 info-level finding(s) hidden; pass --all to see)
|
|
644
|
-
```
|
|
645
|
-
|
|
646
|
-
### When to expand the probe set
|
|
647
|
-
|
|
648
|
-
- A new AdiaUI primitive ships that has a clear native equivalent →
|
|
649
|
-
add to the `PROBES` array in `audit-native-primitive-leak.mjs`.
|
|
650
|
-
- A class of native-primitive smell slips past the audit in a real PR
|
|
651
|
-
→ add the probe first, **then** fix the bug. Test for the test.
|
|
652
|
-
- A native primitive is consistently legitimate in a specific surface
|
|
653
|
-
→ add it to the showcase-demo / stamp-internal skip-list, document
|
|
654
|
-
the rationale in this section.
|
|
655
|
-
|
|
656
|
-
### Repo touchpoints
|
|
657
|
-
|
|
658
|
-
- Script: `scripts/dev/audit-native-primitive-leak.mjs`
|
|
659
|
-
- Probe contract: `PROBES` array at top of the script — each entry has
|
|
660
|
-
`tag` + `adiaEquivalent` + `severity` + `rationale` + escape-hatch
|
|
661
|
-
rules
|
|
662
|
-
- Intent-marker contract: `INTENT_MARKERS` array — adjacent
|
|
663
|
-
`<!-- native-ok -->` or `data-native-ok=` annotations
|
|
664
|
-
- Related skill content: `adia-ui-authoring/references/primitive-audit.md`
|
|
665
|
-
(the consumer-side authoring discipline that this audit enforces)
|
|
666
|
-
|
|
667
|
-
### Anti-patterns
|
|
668
|
-
|
|
669
|
-
- **Don't bulk-replace `<a href>` with `<link-ui>`** without
|
|
670
|
-
understanding link semantics — many `<a href>` cases are legitimately
|
|
671
|
-
navigation anchors and the `--strict-links` flag exists exactly so
|
|
672
|
-
you can opt-in when you want that scrutiny.
|
|
673
|
-
- **Don't suppress findings by stripping the script's PROBES entries**
|
|
674
|
-
to make the audit pass. The right move is either (a) replace the
|
|
675
|
-
native tag, (b) annotate the escape hatch, or (c) document why the
|
|
676
|
-
probe should be retired (and update the PROBES array deliberately).
|
|
677
|
-
- **Don't run this on `docs/` or showcase demos** — they're skipped
|
|
678
|
-
by default because they contain literal code-block examples that
|
|
679
|
-
use native primitives. Adding them to the scan roots produces
|
|
680
|
-
noise.
|
|
681
|
-
- **Don't escalate `--strict-links` to default** — `<a href>` is the
|
|
682
|
-
fundamental web hyperlink primitive. Most usage is legitimate.
|
|
683
|
-
The flag exists for the rare "I want to audit every link" sweep.
|
|
684
|
-
- **Don't trust the preceding-comment annotation form for very long
|
|
685
|
-
reason text** — if the `<!-- native-ok: <reason> -->` block exceeds
|
|
686
|
-
~180 chars total (indent + prefix + reason + `-->`), the comment-
|
|
687
|
-
begin can fall outside the 200-char detection window. The
|
|
688
|
-
attribute form (`data-native-ok="<reason>"`) lives inside the
|
|
689
|
-
opening tag and never has this problem. Prefer the attribute form
|
|
690
|
-
when reason text is verbose.
|
|
691
|
-
|
|
692
|
-
---
|
|
693
|
-
|
|
694
|
-
## § Admin-Shell Composition Audit
|
|
695
|
-
|
|
696
|
-
Static-HTML probe that **flags incomplete admin-shell compositions** —
|
|
697
|
-
the FEEDBACK-41 cluster where a consumer (agent or human) drops in
|
|
698
|
-
`<admin-shell>` + `<admin-sidebar>` + `<admin-content>` but skips the
|
|
699
|
-
4 "easy-to-forget" canonical parts that make the result look like the
|
|
700
|
-
reference at `ui-kit.exe.xyz/site/examples/admin-dashboard`. The
|
|
701
|
-
2026-05-23 claims-ui regression class.
|
|
702
|
-
|
|
703
|
-
The script (`scripts/dev/audit-shell-composition.mjs`) walks
|
|
704
|
-
`apps/<name>/.../*.html`, `playgrounds/<name>/*.html`, and
|
|
705
|
-
`catalog/page-shells/*.html`, parses each `<admin-shell>` it finds, and
|
|
706
|
-
checks the **13 canonical parts** any complete admin-shell should
|
|
707
|
-
have. The authoritative reference is `chat-ui:site/index.html` lines
|
|
708
|
-
42-120 — the actual source that renders
|
|
709
|
-
`ui-kit.exe.xyz/site/examples/admin-dashboard`:
|
|
710
|
-
|
|
711
|
-
1. `<admin-shell mode="rounded borderless">` outer (with a canonical mode attr)
|
|
712
|
-
2. `<admin-sidebar slot="leading" resizable collapsible>` (left rail)
|
|
713
|
-
3. Sidebar's inner `<admin-topbar slot="header">` with `<select-ui avatar="…" value="…" variant="ghost">` (workspace/context switcher — NOT `<menu-ui>`; that's the legacy v0.5.x pattern) — ★ commonly mis-implemented
|
|
714
|
-
4. Sidebar's `<section-ui>` (the AdiaUI primitive, NOT native `<section>`) wrapping `<nav-ui>`
|
|
715
|
-
5. Sidebar's `<admin-statusbar slot="footer">` with `<select-ui avatar="…">` (user menu) — ★ commonly missing
|
|
716
|
-
6. Sidebar's `<div data-resize></div>` (REQUIRED when `resizable` is on)
|
|
717
|
-
7. `<admin-content>` with inner `<admin-topbar>` containing `<button-ui data-sidebar-toggle="leading" icon="sidebar">` + `<breadcrumb-ui>` + `<span data-spacer>` + `<div data-actions>` — ★ spacer + actions commonly missing
|
|
718
|
-
8. `[data-actions]` contains `<popover-ui>` + `<theme-panel slot="content">` for theme picker (NOT a custom `<theme-picker-ui>` — that doesn't exist)
|
|
719
|
-
9. `<admin-scroll>` wrapping optional `<aside data-subnav hidden>` + `<router-ui>` (or `<admin-page>` directly for non-routed)
|
|
720
|
-
10. `<admin-page>` with `<admin-page-header>` + `<admin-page-body>`
|
|
721
|
-
11. `<admin-statusbar>` at content footer (version-strip band) — ★ commonly missing
|
|
722
|
-
12. Second `<admin-sidebar slot="trailing">` (changelog/inspector rail, hidden by default) — strongly recommended
|
|
723
|
-
13. `<admin-command>` with `<command-ui>` (cmd-K palette, top-level child of admin-shell) — strongly recommended
|
|
724
|
-
|
|
725
|
-
Severity:
|
|
726
|
-
- **critical** — outer `<admin-shell>` exists but the page would render
|
|
727
|
-
as broken structure (no admin-content, no admin-sidebar, etc.).
|
|
728
|
-
- **warning** — structure is present but one of the commonly-missing
|
|
729
|
-
parts (3, 5, 6, 7 spacer/actions, 8 theme picker, 11) is absent OR
|
|
730
|
-
uses the wrong primitive (e.g. `<menu-ui>` instead of `<select-ui>`
|
|
731
|
-
for the context-switcher; native `<section>` instead of
|
|
732
|
-
`<section-ui>` for the nav wrap). Cite the canonical reference.
|
|
733
|
-
- **info** — parts 12-13 absent (strongly recommended but not strictly
|
|
734
|
-
required for minimal surfaces); alternate section wrapper choice;
|
|
735
|
-
opted-out mode declared via `data-shell-opt-out=`.
|
|
736
|
-
|
|
737
|
-
### When to use
|
|
738
|
-
|
|
739
|
-
- After any wide screen-authoring sweep where an agent composed admin
|
|
740
|
-
surfaces (genui rendering, page-shell template authoring, consumer
|
|
741
|
-
feedback triage where the diagnosis is "doesn't look like the
|
|
742
|
-
reference").
|
|
743
|
-
- After a fresh consumer onboarding (claims-ui-vN, new third-party
|
|
744
|
-
product) — the FEEDBACK-41 cluster surfaces here repeatedly.
|
|
745
|
-
- Before publishing a new `apps/<name>` admin surface — last gate
|
|
746
|
-
before users see structural drift.
|
|
747
|
-
- As a follow-up gate when the `adia-ui-kit` skill's pre-author bundle
|
|
748
|
-
gate (`§LoadingProtocol` 8-canonical-parts enumeration) is skipped or
|
|
749
|
-
half-followed.
|
|
750
|
-
|
|
751
|
-
### When NOT to use
|
|
752
|
-
|
|
753
|
-
- Component demos under `/site/components/*` — those are intentional
|
|
754
|
-
single-component spotlights, not shells. Use `§ Component Dogfood`
|
|
755
|
-
(the §Workflow at the top of this skill) for those.
|
|
756
|
-
- Surfaces with `data-shell-opt-out="<reason>"` on the outer
|
|
757
|
-
`<admin-shell>` — the escape hatch is honored, audit skips them.
|
|
758
|
-
- Marketing pages that use `<admin-shell>` for narrow visual chrome
|
|
759
|
-
but aren't full admin dashboards. Annotate with `data-shell-opt-out=`.
|
|
760
|
-
|
|
761
|
-
### How to run
|
|
762
|
-
|
|
763
|
-
```bash
|
|
764
|
-
# Default — scan apps/, playgrounds/, catalog/page-shells/; warn-only
|
|
765
|
-
npm run audit:shell-composition
|
|
766
|
-
|
|
767
|
-
# Strict — exit non-zero on any warning (CI gate)
|
|
768
|
-
npm run audit:shell-composition:strict
|
|
769
|
-
|
|
770
|
-
# All surfaces — include docs/ examples (noisier; usually skip)
|
|
771
|
-
npm run audit:shell-composition:all
|
|
772
|
-
```
|
|
773
|
-
|
|
774
|
-
The probe is structurally static — no headless browser, just AST walks
|
|
775
|
-
on the HTML files. Fast enough to run in pre-commit.
|
|
776
|
-
|
|
777
|
-
### What the probe catches
|
|
778
|
-
|
|
779
|
-
| # | Symptom | Diagnosis |
|
|
780
|
-
|---|---------|-----------|
|
|
781
|
-
| 1 | `<admin-shell>` with no inner `<admin-content>` | Critical — wrong outer composition |
|
|
782
|
-
| 2 | `<admin-sidebar>` missing `<admin-statusbar slot="footer">` | Warning — part 5 missing (user-menu band) |
|
|
783
|
-
| 3 | `<admin-content>` `<admin-topbar>` missing `[data-spacer]` | Warning — part 6 spacer missing |
|
|
784
|
-
| 4 | `<admin-content>` `<admin-topbar>` missing `[data-actions]` | Warning — part 6 actions missing |
|
|
785
|
-
| 5 | `<admin-content>` missing trailing `<admin-statusbar>` | Warning — part 8 missing (version-strip band) |
|
|
786
|
-
| 6 | `<admin-sidebar>` `<admin-topbar>` only contains plain text | Warning — part 3 missing context-switcher menu |
|
|
787
|
-
| 7 | `<admin-scroll>` missing as wrapper around `<admin-page>` | Warning — part 7 wrap missing |
|
|
788
|
-
|
|
789
|
-
### Intentional escape hatch — annotation
|
|
790
|
-
|
|
791
|
-
If a page deliberately uses an incomplete admin-shell (a marketing
|
|
792
|
-
hero, a narrow modal preview, etc.), annotate the outer tag:
|
|
793
|
-
|
|
794
|
-
```html
|
|
795
|
-
<admin-shell mode="rounded" data-shell-opt-out="marketing hero, no sidebar needed">
|
|
796
|
-
<admin-content>
|
|
797
|
-
<admin-page>
|
|
798
|
-
<admin-page-header><h1>Welcome</h1></admin-page-header>
|
|
799
|
-
</admin-page>
|
|
800
|
-
</admin-content>
|
|
801
|
-
</admin-shell>
|
|
802
|
-
```
|
|
803
|
-
|
|
804
|
-
The audit skips the structural checks but emits an **info** finding
|
|
805
|
-
naming the opt-out reason. Reviewers can sanity-check the annotation
|
|
806
|
-
during code review.
|
|
807
|
-
|
|
808
|
-
### Triage rules
|
|
809
|
-
|
|
810
|
-
For each **warning** finding:
|
|
811
|
-
|
|
812
|
-
1. **Is the page a canonical product surface?** (apps/saas, apps/genui
|
|
813
|
-
admin examples, catalog/page-shells/admin-*) — fix mandatory; this
|
|
814
|
-
is the reference. Add the missing parts.
|
|
815
|
-
2. **Is the page a playground for ONE narrow feature?** — fix optional;
|
|
816
|
-
acceptable to annotate `data-shell-opt-out="playground for X"`.
|
|
817
|
-
3. **Is the page a consumer-feedback regression class** (per kit skill
|
|
818
|
-
`§FailureModeReceipts`)? — fix mandatory; document the missing parts
|
|
819
|
-
in the receipt.
|
|
820
|
-
|
|
821
|
-
For each **critical** finding: halt, re-author the outer composition
|
|
822
|
-
from the canonical 8-part template at `adia-ui-kit` `§Patterns` →
|
|
823
|
-
"Admin shell anatomy" before continuing.
|
|
824
|
-
|
|
825
|
-
### Pair with peer probes
|
|
826
|
-
|
|
827
|
-
The audit is **complementary** to the pre-author bundle gate in
|
|
828
|
-
`adia-ui-kit` SKILL.md `§LoadingProtocol`: the gate is a **forward-time**
|
|
829
|
-
check (before generation), the audit is a **backward-time** check
|
|
830
|
-
(after generation). Use both.
|
|
831
|
-
|
|
832
|
-
Also complementary to **§ Native Primitive Leak Audit**: that probe
|
|
833
|
-
catches "agent reached for `<button>` instead of `<button-ui>`"; this
|
|
834
|
-
probe catches "agent assembled the right primitives but skipped the
|
|
835
|
-
canonical composition recipe". Same root cause family (incomplete
|
|
836
|
-
substrate adherence), different surface.
|
|
837
|
-
|
|
838
|
-
### Output shape (human-readable)
|
|
839
|
-
|
|
840
|
-
```
|
|
841
|
-
audit-shell-composition v1.0.0
|
|
842
|
-
|
|
843
|
-
Scanned 18 files across apps/ + playgrounds/ + catalog/page-shells/
|
|
844
|
-
|
|
845
|
-
CRITICAL findings: 0
|
|
846
|
-
WARNING findings: 3
|
|
847
|
-
INFO findings: 2
|
|
848
|
-
|
|
849
|
-
WARNING — apps/genui/app/admin-dashboard.html:14
|
|
850
|
-
<admin-sidebar> missing <admin-statusbar slot="footer"> (part 5)
|
|
851
|
-
→ Add user-menu band with avatar + menu-ui trigger
|
|
852
|
-
→ Reference: catalog/page-shells/admin-default.html line 22
|
|
853
|
-
|
|
854
|
-
WARNING — playgrounds/admin-shell/admin-shell.html:31
|
|
855
|
-
<admin-content> <admin-topbar> missing [data-spacer] (part 6)
|
|
856
|
-
→ Add <div data-spacer></div> between breadcrumb and [data-actions]
|
|
857
|
-
|
|
858
|
-
INFO — apps/saas/app/marketing-hero.html:8
|
|
859
|
-
<admin-shell> has data-shell-opt-out="marketing hero, no sidebar"
|
|
860
|
-
→ Audit skipped per opt-out
|
|
861
|
-
|
|
862
|
-
Exit: 0 (warn-only mode); use --strict to fail on warnings.
|
|
863
|
-
```
|
|
864
|
-
|
|
865
|
-
### Repo touchpoints
|
|
866
|
-
|
|
867
|
-
- `scripts/dev/audit-shell-composition.mjs` — the probe itself.
|
|
868
|
-
- `package.json` — `audit:shell-composition{,:strict,:all}` npm scripts.
|
|
869
|
-
- `.agents/skills/adia-ui-kit/SKILL.md` `§LoadingProtocol` — the
|
|
870
|
-
forward-time companion (pre-author bundle gate 8-canonical-parts
|
|
871
|
-
enumeration).
|
|
872
|
-
- `.agents/skills/adia-ui-kit/SKILL.md` `§Patterns` → "Admin shell
|
|
873
|
-
anatomy" — the canonical 8-part template the probe checks against.
|
|
874
|
-
- `.agents/skills/adia-ui-release/references/gates-catalog.md` —
|
|
875
|
-
Category 6 entries for the 3 npm scripts.
|
|
876
|
-
|
|
877
|
-
### Anti-patterns
|
|
878
|
-
|
|
879
|
-
- **Don't run on raw component demo pages** — `/site/components/*` is
|
|
880
|
-
not in the default scan root because most demos are single-primitive
|
|
881
|
-
spotlights, not shells. If you point the audit at them, you'll get
|
|
882
|
-
noise findings for "missing admin-shell" on demos that legitimately
|
|
883
|
-
don't have one.
|
|
884
|
-
- **Don't silence warnings by stripping the CANONICAL_PARTS array** to
|
|
885
|
-
make the audit pass. The fix is to add the missing parts to the
|
|
886
|
-
consumer surface or annotate `data-shell-opt-out=` with a reason.
|
|
887
|
-
- **Don't escalate `:strict` to default on personal branches** — the
|
|
888
|
-
warn-only default lets authors iterate; CI bumps to `:strict` at
|
|
889
|
-
publish time.
|
|
890
|
-
- **Don't run the audit on consumer repos directly** — the audit is
|
|
891
|
-
substrate-side tooling. For consumer repos (claims-ui, third-party
|
|
892
|
-
products), point them at the `adia-ui-kit` skill's `§Patterns` →
|
|
893
|
-
"Admin shell anatomy" or the live reference at
|
|
894
|
-
`ui-kit.exe.xyz/site/examples/admin-dashboard`.
|
|
895
|
-
|
|
896
|
-
---
|
|
897
|
-
|
|
898
|
-
## § Component Anatomy + Card Header Sweep (v2.27.4+, FB-52 §11)
|
|
899
|
-
|
|
900
|
-
Two static-grep probes added after the 2026-05-23 docs-overhaul session
|
|
901
|
-
surfaced patterns that the existing 5 modes don't catch:
|
|
902
|
-
|
|
903
|
-
1. **Card-ui header `<div>` wrapper anti-pattern** — header content
|
|
904
|
-
wrapped in a bare `<div>` (no `slot=`) bypasses card-ui's
|
|
905
|
-
`:has(> [slot])` grid activator. Title + badge collapse into one
|
|
906
|
-
row instead of the canonical 1fr-heading + auto-action grid.
|
|
907
|
-
2. **Component anatomy section coverage** — component example pages
|
|
908
|
-
missing the canonical anatomy sections (`props`, `events`, `slots`,
|
|
909
|
-
`data-attrs`, `keyboard`, `css-vars`, `a2ui`, `related`) after
|
|
910
|
-
`anatomy-sweep.mjs` should have populated them.
|
|
911
|
-
|
|
912
|
-
Both probes are static greps (no headless browser), fast enough to run
|
|
913
|
-
in pre-commit.
|
|
914
|
-
|
|
915
|
-
### Probe A — Card-ui header `<div>` wrapper
|
|
916
|
-
|
|
917
|
-
Detection: any `<header>` directly inside `<card-ui>` whose immediate
|
|
918
|
-
child is a `<div>` with no `slot=` attribute.
|
|
919
|
-
|
|
920
|
-
```bash
|
|
921
|
-
# Find candidate card-ui files
|
|
922
|
-
grep -rln '<card-ui' \
|
|
923
|
-
packages/web-components/patterns/ \
|
|
924
|
-
packages/web-modules/ \
|
|
925
|
-
site/ \
|
|
926
|
-
apps/ \
|
|
927
|
-
playgrounds/ \
|
|
928
|
-
catalog/ \
|
|
929
|
-
2>/dev/null | \
|
|
930
|
-
while read -r file; do
|
|
931
|
-
# Look for card-ui > header > div without slot=
|
|
932
|
-
awk '
|
|
933
|
-
/<card-ui/ { in_card = 1 }
|
|
934
|
-
in_card && /<header>/ { in_header = 1; next }
|
|
935
|
-
in_header && /<div>[^<]*$|<div [^>]*>$/ {
|
|
936
|
-
if ($0 !~ /slot=/) {
|
|
937
|
-
print FILENAME ":" NR ": " $0
|
|
938
|
-
}
|
|
939
|
-
in_header = 0
|
|
940
|
-
}
|
|
941
|
-
/<\/card-ui>/ { in_card = 0; in_header = 0 }
|
|
942
|
-
' "$file"
|
|
943
|
-
done
|
|
944
|
-
```
|
|
945
|
-
|
|
946
|
-
**Severity**: warning. The card renders, but heading + action collapse
|
|
947
|
-
into a full-width row. No console error; pure visual regression.
|
|
948
|
-
|
|
949
|
-
**Fix**: hoist the header children out of the wrapper `<div>`. Apply
|
|
950
|
-
`slot="action"` to badges/buttons that should land in the trailing
|
|
951
|
-
column. Reference: `adia-ui-kit/references/patterns-recipes.md`
|
|
952
|
-
`§Card-ui header — slotted children, NOT <div> wrapper`.
|
|
953
|
-
|
|
954
|
-
### Probe B — Component anatomy section coverage
|
|
955
|
-
|
|
956
|
-
Detection: a component's `*.examples.html` page is missing the
|
|
957
|
-
schema-derivable anatomy sections that `scripts/docs/anatomy-sweep.mjs`
|
|
958
|
-
should have populated.
|
|
959
|
-
|
|
960
|
-
```bash
|
|
961
|
-
# A component page is under-documented if it has no reference sections at all
|
|
962
|
-
for f in packages/web-components/components/*/*.examples.html; do
|
|
963
|
-
name=$(basename "$(dirname "$f")")
|
|
964
|
-
if ! grep -q 'data-property="props"\|data-property="events"\|data-property="slots"' "$f"; then
|
|
965
|
-
echo "MISSING anatomy: $name → $f"
|
|
966
|
-
fi
|
|
967
|
-
done
|
|
968
|
-
```
|
|
969
|
-
|
|
970
|
-
**Severity**: info — a page can ship without anatomy sections if the
|
|
971
|
-
component is intentionally minimal (e.g. a one-prop primitive), but
|
|
972
|
-
the sweep should have offered at minimum `props` or `events`. If
|
|
973
|
-
neither is present, it's worth a manual review.
|
|
974
|
-
|
|
975
|
-
**Fix**: run `node scripts/docs/anatomy-sweep.mjs` to auto-populate
|
|
976
|
-
schema-derivable sections. If the sweep still skips the component,
|
|
977
|
-
investigate whether the yaml has missing `props:`/`events:`/`slots:`
|
|
978
|
-
declarations.
|
|
979
|
-
|
|
980
|
-
### When to use both probes
|
|
981
|
-
|
|
982
|
-
- After any wide screen-authoring sweep that generated `<card-ui>` blocks
|
|
983
|
-
- After a new-component yaml + examples.html author-pass (probe B
|
|
984
|
-
catches the case where the author skipped the sweep step)
|
|
985
|
-
- Before publishing a docs-site refresh — both probes should be 0
|
|
986
|
-
findings or have explicit opt-outs
|
|
987
|
-
|
|
988
|
-
### Anti-patterns
|
|
989
|
-
|
|
990
|
-
- **Don't probe non-component `<header>` tags** — admin-shell's own
|
|
991
|
-
`<header>` (inside admin-topbar, drawer-ui, etc.) is structurally
|
|
992
|
-
different and the `<div>`-wrapper pattern is acceptable there. The
|
|
993
|
-
awk script above restricts to `<card-ui>` ancestor scope.
|
|
994
|
-
- **Don't auto-fix probe A findings** — the right fix depends on
|
|
995
|
-
intent (which child should be `slot="action"` vs auto-placed). Flag
|
|
996
|
-
+ manual review only.
|
|
997
|
-
- **Don't escalate probe B to error severity** — some components
|
|
998
|
-
legitimately have only a `usage` section (e.g. CSS-only primitives
|
|
999
|
-
with no JS API). Info-level only.
|
|
1000
|
-
|