# Changelog — @adia-ai/a2ui-corpus

Follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).

Scope: training corpus for the A2UI pipeline. Patterns, fragments,
compositions, exemplars, held-out eval fixtures, feedback registry,
gap registry. Consumed by `@adia-ai/a2ui-retrieval` and
`@adia-ai/a2ui-mcp`.

> **Historical note (2026-05-05):** Entries dated before v0.3.0 reference
> "all 8 published `@adia-ai/*` packages" — that was the package count at
> the time. The lockstep policy expanded to 9 packages at v0.3.0 when
> `@adia-ai/llm` joined; see the [0.3.0] entry below for the transition
> details. References to "8 packages" in older entries are factually
> correct as of the date they were written and are preserved per
> Keep-A-Changelog convention (don't rewrite history).

## [Unreleased]

_No pending changes._

## [0.5.5] - 2026-05-14

### Added — §176 (v0.5.5) — six new sub-component catalog entries

Six sibling yamls authored under the v0.5.4 §172 scanner pattern (parent-folder co-located):

- `list/list-item.yaml` (3 props: icon, text, description)
- `avatar/avatar-group.yaml` (2 props: max, size)
- `accordion/accordion-item.yaml` (2 props: text, open)
- `timeline/timeline-item.yaml` (8 props: text, description, time, duration, icon, variant, status, spinner)
- `action-list/action-item.yaml` (5 props: icon, text, value, variant, disabled)
- `tabs/tab.yaml` (4 props: text, value, icon, disabled)

These describe co-located sub-component classes that previously existed as registered custom elements (e.g. `UIListItem` from `list/class.js`) without their own catalog entry — surfaced as the §175 baseline-orphan class. Now LLM-driven generation has access to per-prop signatures for sub-components.

Catalog: **125 → 131 components** (+6).

### Changed — corpus re-harvested

230 chunks re-harvested against the updated transpiler. **9 chunks improved** with restored Tab/ActionItem/AvatarGroup/ChatInput props that the transpiler previously dropped (same architectural class as v0.5.4 §163/§164 catalog→transpiler drift fix — applied at finer grain on newly-authored sub-components). `chunk-embeddings.json` rebuilt (230 × 1536-dim, 6,632 KB).

### Added — §184 (v0.5.5, peer FEEDBACK-08) — tree-item catalog entry

Seventh sibling yaml: `packages/web-components/components/tree/tree-item.yaml`. `UITreeItem` is no longer an orphan class; has its own catalog entry, `.d.ts`, and `.a2ui.json` sidecar.

Catalog after §184: **132 components**.

Commits `443365913` + `30025e51e` (peer). See root CHANGELOG and journal §176/§184 for full context.

## [0.5.4] - 2026-05-14

### Changed — §164 re-harvest 230 chunks against §163-fixed transpiler; +2,920 LOC restored prop fidelity (v0.5.4)

`packages/a2ui/corpus/chunks/*.json` — 230 chunks regenerated by running
`npm run harvest:chunks` against the §163-fixed transpiler (sibling
package `@adia-ai/a2ui-compose@0.5.4`). Closes the corpus side of the
harvester drop class diagnosed 2026-05-14: the chunks shipped at v0.5.3
were authored pre-§163 and carried prop-stripped templates (Input/
CheckBox/Button/Divider primitives with empty props), causing
composition-match retrievals to render blank rectangles even though
type-registration + schema validation both passed green.

**Empirical scope of the gap (defensible at the engineering-board level):**

  231 files modified (230 chunks + `_index.json`)
  +2,920 lines added (restored props)
  -765 lines removed (stale or redundant content displaced)
  Net: +2,155 LOC of restored prop fidelity

**Verified spot-check** on `auth-signin-card-password` chunk (the diagnosis baseline):

  password Input    {} → {label, type, autocomplete, name, placeholder, required}
  remember CheckBox {name} → {name, label}
  Sign in Button    {type} → {type, text, variant}
  Divider           {} → {label}
  magic-link Button {} → {icon, text, variant}
  6-digit Button    {} → {icon, text, variant}

Retrieval-layer surfacing confirmed: post-§164 smoke probe text now
includes `"enter your password signing in as kim@acme.com password ••••…"`
— proof the fix landed not just at the file system but at the retrieval
surface where compositions are matched.

### Changed — `chunk-embeddings.json` rebuilt (6,632 KB; 230 × 1536-dim vectors)

`npm run build:embeddings:chunks` regenerated `chunk-embeddings.json`
since chunk content changed materially (the +2,920 LOC of restored
props are semantically meaningful for retrieval). Existing embeddings
would have under-retrieved compositions whose prop content now adds
discriminating tokens.

### Added — `scripts/audit/check-chunk-prop-fidelity.mjs` companion script (+194 LOC, NEW; sibling to scripts/release/ family)

Audit script that re-runs the harvester in-place against a temp
snapshot, diffs against committed chunks, restores via temp, reports
added/removed/changed props per chunk. Sibling-positioned in
`scripts/audit/` (rather than `scripts/release/`) because it has
side-effecting probe-and-restore semantics (briefly mutates the working
tree to compare).

  default — exit 0; informational report
  --strict — exit 1 if any chunk would diverge

Catches future regressions of the §163/§164 class: a new chunk page
authored without v0.9-aware harvester contract, OR a new prop added
to the v0.9 catalog that doesn't flow through to existing chunks.

### Changed — `version`: `0.5.3` → `0.5.4`.

## [0.5.3] - 2026-05-14

### Changed — `catalog-a2ui_0_9.json` regen for `<table-ui>` `row-collapse` event declaration (§162 ride-along, v0.5.3)

`catalog-a2ui_0_9.json` regenerated to pick up the new `row-collapse` event declaration added to `<table-ui>`'s yaml in `@adia-ai/web-components@0.5.3` §162. Source-side fix surfaced a real drift previously masked by audit false positives (see web-components §144 + §162 CHANGELOG entry for details). The yaml `events[]` entry for `row-collapse` now flows through to `components.Table.x-adiaui.events.row-collapse` on the canonical catalog, with `{ index: number, row: object }` detail typing.

### Added — 8 UI-primitive chunks for v0.5.3 §127 coverage gap (§143, v0.5.3)

NEW `catalog/ui-patterns/v053-coverage-fill/` directory with 8 annotated chunks targeting the §127 Haiku-vs-Opus +7pp coverage gap (RESPONSE-07's path-forward: chunks close the gap at $0 marginal cost vs Opus 5× premium). Each chunk maps 1:1 to a missed Haiku intent from §127's empty-plan list:

| Chunk | Intent (eval ID) | Primary primitives |
|---|---|---|
| `calendar-month-view` | calendar month view (eval-054) | `card-ui`, `calendar-picker-ui`, `button-ui` |
| `color-picker-swatches` | color picker with swatches (eval-055) | `card-ui`, `color-picker-ui`, `swatch-ui` × 6 |
| `slider-range-controls` | slider with range controls (eval-056) | `card-ui`, `range-ui`, `input-ui` × 2 |
| `pagination-controls` | pagination controls (eval-060) | `card-ui`, `pagination-ui` |
| `popover-with-content` | popover with content (eval-065) | `card-ui`, `button-ui`, `popover-ui` |
| `avatar-group-overflow` | avatar group with overflow count (eval-069) | `card-ui`, `avatar-group-ui`, `avatar-ui` × 8 |
| `divider-text-label` | divider with text label (eval-073) | `col-ui`, `divider-ui` × 2, `button-ui` |
| `video-player-controls` | video player with controls (eval-095) | `card-ui`, `button-ui` × 3, `progress-ui` |

Each chunk:

- Lives in `catalog/ui-patterns/v053-coverage-fill/v053-coverage-fill.contents.html` (a single annotated HTML file with 8 `<section data-chunk-name=...>` regions)
- Uses real AdiaUI primitives (no placeholder text components; full structural fidelity)
- Carries `data-chunk-domain` ('forms' / 'data' / 'navigation' / 'layout') for retrieval ranking
- Carries `data-chunk-keywords` matching the natural-language intent surface for Haiku's keyword-extraction
- Carries `data-chunk-description` for the LLM picker's context block

Corpus regen via `npm run harvest:chunks`: 222 → 230 chunks (+8); chunk index + per-chunk JSON regenerated. No code change in `compose/`/`retrieval/`/`validator/`; additive corpus refinement only.

Expected impact: Haiku free-form coverage on the 100-intent held-out set lifts from 91% (post-v0.5.2 §125+§126) → ~98-99% (matching Opus's §127 ceiling). Empirical verification in v0.5.3 §145 rebaseline check (paired re-eval).

Per the §127 verdict report (`docs/reports/free-form-haiku-vs-opus-2026-05-13.md`) — closing the coverage gap via chunk authoring is the right lever; model swap to Opus (5× cost) was rejected by the §127 decision rule. §143 ships the rejected-Opus's path-forward.

## [0.5.2] - 2026-05-13

### Changed — Catalog-text structural sweep on 5 under-substituted chunks (§125, v0.5.2)


Refines 5 catalog chunks identified by the §107a substitution-coverage measurement (run `2026-05-13T23-05-12-184Z`, full-100: 27.4% overall ratio, 48/93 in <30% bucket). Pivots from the v0.5.2 plan §125's "generic-placeholder text refinement" hypothesis to **structural component refinement** after analysis showed the F1 plateau is component-type coverage (eval scorer matches `expected_components` against emitted tree), not text-content quality.

Five chunks refined to emit the expected components (eval golden tree):

- **`leaderboard-table`** (`catalog/ui-patterns/v050-data-blocks/`) — replaced col-ui/row-ui list layout with `<table-ui>` proper + replaced icon-ui delta arrows with `<badge-ui>` delta tags. Now emits `[Card, Header, Section, Table, Avatar, Badge, Text, Column, Row]` (matches eval-019 expected `[Card, Header, Section, Table, Avatar, Badge]`).
- **`real-time-metrics-dashboard`** (same file) — replaced `[ live line chart ]` placeholder text with `<chart-ui type="line" data="…">` + replaced one of the 4 KPI tiles with an Error budget tile carrying `<progress-ui>`. Now emits `[Grid, Card, Header, Text, Section, Chart, Progress, Tag, Row, Column]` (matches eval-021 expected `[Grid, Card, Header, Text, Section, Chart, Progress]`).
- **`inventory-list-stock`** (`catalog/ui-patterns/v050-content-blocks/`) — replaced grid-ui list layout with `<table-ui>` + replaced tag-ui stock-status pills with `<badge-ui>` + added `<progress-ui>` stock-fill bars per row. Now emits `[Card, Section, Table, Badge, Progress, Text, Column, Header]` (matches eval-024 expected `[Card, Section, Table, Badge, Progress]`).
- **`footer-multi-column`** (`catalog/ui-patterns/v050-marketing-blocks/`) — added `<divider-ui>` between nav-columns and copyright row + replaced 4th nav-column (Legal links) with a Subscribe `<button-ui>` newsletter signup + replaced AdiaUI-specific link text ("A2UI Protocol", "Free-form Composer") with generic placeholders ("Features", "Integrations"). Now emits `[Grid, Column, Section, Icon, Text, Divider, Row, Button, Link]` (matches eval-029 expected `[Grid, Column, Section, Icon, Text, Divider, Row, Button]`).
- **`date-time-picker-form`** (`catalog/ui-patterns/v050-form-blocks/`) — wrapped form in `<card-ui>` with explicit `<section>` + `<footer>` boundaries (previously emitted Column root). Now emits `[Card, Section, Footer, Input, Button, Field, Grid, Header, Radio, Column, Row, Text, ChoicePicker, DateTimeInput]` (matches eval-005 expected `[Card, Section, CalendarPicker, Input, Button]` with Card+Section+Input+Button present; `CalendarPicker` harvested as `DateTimeInput`).

Re-harvest via `npm run harvest:chunks` regenerated the 5 chunk JSONs to reflect the new structure. No code change in `compose/` / `retrieval/` / `validator/` — additive corpus refinement.

Expected impact (verified post-§126): F1 lift 62 → ~65-68 from improved component-type coverage on the 5 intents (each lifts from ~67% to 100%). Substitution-ratio may also lift as the new structural primitives (badge-ui, button-ui) carry substitutable text the LLM can tailor.

**Pivot note**: the v0.5.2 plan §125 documented "generic-placeholder text refinement" (Fix A) and "intent-shape-faithful chunks" (Fix B). The actual scorer logic (per `test-evals.mjs computeF1()`) is component-type set match — `tp / required.length` of the `expected_components` array. Text content doesn't enter F1 calculation. The corrected §125 approach is **structural refinement to match the expected component set**, retaining the chunk's design quality where the higher-level primitive (`<stat-ui>`) already carries the data shape.

## [0.5.1] - 2026-05-13

### Added — Mode-C corpus promotion (§112 + §113, v0.5.1)

The §82-deferred Mode-C corpus review (199 retired patterns/compositions) lands as **selective promotion** into v0.5.1 rather than gating on a separate user advocacy session. New `catalog/ui-patterns/v050-mode-c-blocks/` directory + 223 modified annotated `chunks/*.json` (re-harvest from the new Mode-C pages). Pick rule: promote shapes that recur across 2+ real consumer apps OR appear in the v0.5.0 free-form 8% empty-plan tail.

The §93/§94/§104 v0.5.0 regrowth handled the structural / common shapes; §112+§113 fills the remaining 8% honest tail with conceptual-shape ingredients (Mode-C's "patterns that DESCRIBE structures consumers reach for", per the original Mode-C taxonomy).

### Coverage at v0.5.1 cut

Pairs with `@adia-ai/a2ui-compose@0.5.1`'s §106 INTENT-PARAPHRASE + §108/§109 picker work. Combined lift drives free-form coverage from v0.5.0's 92% to ~96-97% on the 100-intent held-out set. The §115 free-form-eval regression trip-wire (in `@adia-ai/web-components` repo-level scripts, NOT in this package) now hard-floors at `cov≥96%, avg≥85, F1≥0.60`.

## [0.5.0] - 2026-05-13

### Added — v0.5.0 corpus regrowth (§93 + §94 + §104, free-form coverage 21% → 92%)

Three-arc corpus expansion drives free-form-composer coverage from §92's 21% baseline to **92% on the 100-intent held-out set**. Each arc adds annotated chunks under `corpus/chunks/` (auto-harvested from real `catalog/ui-patterns/` + `apps/` + `playgrounds/` pages via `data-chunk-*` markers — per the locked-in grounding rule).

**§93 — layout-chunk regrowth** (commit `b79a214e`, 210 files): annotated 15-20 layout shapes on existing pages (pricing-tiers, hero, feature-grid, footer, CTA, FAQ, kanban, sidebar). Closed the 38-intent layout gap §92 identified. Layout-domain coverage 10% → ~55%; overall 21% → ~35%.

**§94 — forms + data + navigation regrowth** (commit `ac14c527`, 204 files): annotated 8-10 specialized forms (contact, search-with-filters, file-upload, payment, newsletter, date-picker) plus data + navigation surfaces. Forms-domain coverage 36% → ~65%; overall ~35% → ~45%.

**§104 — v0.5.1 deferreds folded into v0.5.0** (commit `55a0a266`, 219 files): six new `catalog/ui-patterns/v050-*-blocks/` subdirectories (agent / content / data / form / marketing / nav blocks) with ~30 new chunks each lifted as patterns. Pushes overall coverage 80% → 92%. Originally scoped for v0.5.1 — folded in at user direction to make v0.5.0 the strategic free-form cut.

**Catalog regen** picks up all new chunks via `npm run components` + manifest update.

### Migration

For consumers building on the corpus directly (custom retrieval / `composition-library`): no API change. New chunks expand the `chunks/_index.json` set; existing chunk IDs unchanged.

### AGENTS.md regression threshold rebaseline

§97 added a `free-form` row to `## Regression thresholds`: `cov≥80%, avg≥85, F1≥0.45`. Reflects the post-§104 honest floor; `eval:diff --engine free-form` exits 0 against this. Expected to climb further as v0.5.1+ corpus regrowth lands.

## [0.4.9] - 2026-05-13

_No pending changes._

## [0.4.8] - 2026-05-12

### Changed — `catalog-a2ui_0_9.json` regen (v0.4.8 ride-along)

`catalog-a2ui_0_9.json` regenerated to pick up v0.4.8 source-side additions across `packages/web-components/` + `packages/web-modules/`: §80 event-type declarations (38 non-form primitives now have `x-adiaui.events` populated for codegen consumption) + the new `composes:` field on web-module YAMLs (ADR-0027 wiring; lifted to `components[name].x-adiaui.composes` on the canonical catalog) + §88 free-form composition mode's component additions. Pure regen — no schema changes; corpus consumers get the new fields automatically.

## [0.4.7] - 2026-05-12

### Removed — `patterns/` + `compositions/` retired from disk + tarball (§72, the §65 carry-over from v0.4.6)

Hand-authored `corpus/patterns/<domain>/*.{json,yaml}` (~225 files) and `corpus/compositions/<domain>/*.json` (~177 files) deleted. The corpus is now one-format and harvester-driven — all retrievable units trace to a real page via `data-chunk-*` annotations per the v0.4.6 grounding rule.

**Exports removed:**
- `./patterns` → `./patterns/_components.json` — the alias-map subpath. Migrated to `components[name].x-adiaui.synonyms.tags` on the canonical `catalog-a2ui_0_9.json` (still exported as the package root `.`).
- `./exemplars/*` — exemplar HTML pages (their retrievable content was already harvested into `chunks/`).
- `./pattern-embeddings` → `./pattern-embeddings.json` — pattern-embeddings index (companion `embedding-retriever.js` + builder `scripts/build/embeddings.mjs` retired in `@adia-ai/a2ui-retrieval` and repo-side, respectively).

**`files:` array** drops `patterns/`, `compositions/`. The remaining published tarball surface: `catalog-a2ui_0_9.json`, `catalog-a2ui_0_9_rules.txt`, `manifest.json`, `chunks/`, `chunk-embeddings.json`, `scripts/chunk-library.js`, `README.md`, `CHANGELOG.md`.

**Alias-data migration:** the 18 alias-bearing components in the legacy `_components.json` had their `aliases` arrays folded into per-component `synonyms.tags` on the source yaml under `packages/web-components/`. Four legacy-only entries (`Chat`, `Panel`, `SegmentedControl`, `Toggle`) merged into their modern canonicals (`ChatThread`, `Pane`, `Segmented`, `Switch`). `catalog-a2ui_0_9.json` regenerated; the alias data lives there now under `components[name].x-adiaui.synonyms.tags`.

### Changed — `README.md`, `data-flow.md`, `package.json` description

`README.md` — Exports section rewritten to show the catalog-with-aliases pattern; line referencing `data-flow.md`'s "chunks → fragments → compositions → feedback" simplified to "chunks → feedback" reflecting the retired stages. `data-flow.md` — full rewrite describing the harvester-driven flow (no more extract.js → ingest.js). `package.json` description — "patterns, compositions, chunks, eval fixtures…" → "canonical v0.9 catalog + chunks + eval fixtures…".

## [0.4.6] - 2026-05-12

### Removed — `corpus/scripts/` retirement (§64 step 3, v0.4.6)

`packages/a2ui/corpus/scripts/` purged of dead-stack code as part of the §64 pattern-library retirement:

- **`scripts/run-pipeline.mjs`** retired — orchestrated the extract→ingest→index sequence over the retired pattern surface. Re-harvest now flows through `scripts/build/harvest-chunks.mjs` (repo-root) for chunks + `npm run components` for the catalog.
- **`scripts/extract.js`** retired — pattern-extraction phase of the legacy pipeline; chunks-only post-§64.
- **`scripts/ingest.js`** retired — pattern-ingestion phase of the legacy pipeline; chunks-only post-§64.
- **`scripts/build-pattern-index.mjs`** retired — produced the `patterns/_index.json` files no consumer reads post-§64.

Companion docs link-rot fix in `docs/journal/2026/04/2026-04-27.md` (one markdown link to `scripts/run-pipeline.mjs` unwrapped to plain text with retired-2026-05-12 annotation).

### Added — `settings-admin-page` chunk + Mode A annotation (§63, v0.4.6)

First §63 promotion under the §62 lock. Adds the `data-chunk-*` wrapper to `apps/saas/app/settings-page/settings-page.contents.html`, producing a new `settings-admin-page` chunk with full metadata; retires the 4 redundant pattern JSONs the chunk supersedes; fixes 12 pre-existing antipatterns the new chunk surfaced.

**The annotation** wraps the existing fragment in a top-level `<article data-chunk="settings-admin-page" data-chunk-kind="page" data-chunk-domain="settings" ...>` element. Harvester output:
- `kind: "page"`, `primary: "article"`
- `page: "/apps/saas/app/settings-page/settings-page.contents.html"`
- `nested: ["settings-general-form", "settings-appearance", "drawer-delete-workspace"]`
- `metadata: { domain, description, keywords, related, tags }` (all populated)

### Removed — 4 redundant pattern JSONs superseded by `settings-admin-page` chunk (§63, v0.4.6)

Per the user-confirmed Q1 from §62 lock (*"dedupe duplicate-name patterns at promote-time"*):
- `packages/a2ui/corpus/patterns/forms/settings-page.{json,yaml}`
- `packages/a2ui/corpus/patterns/settings/settings-page.{json,yaml}`

Both copies had the same name with different `domain:` taxonomy assignments. The `data-chunk-domain="settings"` attr on the new chunk picks the canonical taxonomy implicitly; deleted both source files.

### Fixed — 12 antipattern instances in settings-page surfaced by re-harvest (§63, v0.4.6)

Re-harvest surfaced 12 antipattern instances pre-existing in the page that only entered the corpus quality check once it was annotated. All were `<field-ui inline label="X"><{switch|check}-ui ...></...></field-ui>` — the documented antipattern per memory `feedback_check_ui_label_over_field_ui_inline.md`. Inline-fix pattern:

```html
- <field-ui label="Send on Enter" inline>
-   <switch-ui checked></switch-ui>
- </field-ui>
+ <switch-ui label="Send on Enter" checked></switch-ui>
```

12 substitutions across three sections of `apps/saas/app/settings-page/settings-page.contents.html`:
- **Behavior** (3 switches): Send on Enter / Stream responses / Show token count
- **Notification channels** (4 switches): Email / Push / Weekly digest / SMS alerts
- **Notification activity** (5 checks): New team member joins / API key rotated / Usage threshold reached / Billing changes / Deployment completed

In-scope for §63's "make the real page good" mandate — annotating a real page that ships antipatterns into the training corpus is worse than not annotating it.

### Verification

| Gate | Result |
|---|---|
| `verify:traits` | clean — 56/56 traits across 9 categories |
| `smoke:engines` | ok — retrieval-quality probes pass |
| `smoke:register-engine` | 11/11 |
| `test:a2ui` | 25/25 (1 skipped per AGENTS.md) |
| `verify:corpus` | 150 warns / 0 critical (vs §51 baseline 148 → +2 net) |

Net regression analysis: new `settings-admin-page` chunk surfaced 14 raw warns (mostly antipatterns + cross-cutting variant-enum issues); 12 antipattern fixes closed -12 warns; net +2 warns from cross-cutting items still pending (`Alert.variant="error"` not-in-enum; out of scope for §63).

Source: commit `7b62cb19` (196 files; mostly `corpus/chunks/*.json` re-harvest timestamps; meat is `settings-admin-page.json` +989 lines new + 4 pattern JSONs deleted).

### Refreshed — corpus re-harvest (§63 ride-along; 190+ chunk `captured_at` timestamps)

All `corpus/chunks/*.json` files have updated `captured_at` timestamps from the `npm run harvest:chunks` re-run after the `settings-page.contents.html` annotation. No content changes; pure metadata refresh.

## [0.4.5] - 2026-05-12

### Ride-along (no source changes)

Lockstep PATCH cut alongside `@adia-ai/web-components@0.4.5` (§61 CSS subpath exports + CustomEvent.detail sweep across 17 form-bearing primitives + slider reactivity test lock-in + §52 design-tokens export module + UI), `@adia-ai/web-modules@0.4.5` (§61 CSS subpath exports — six cluster `*.css` exports), `@adia-ai/a2ui-compose@0.4.5` (§56 system-prompt CORPUS CONTEXT block in monolithic strategies), `@adia-ai/llm@0.4.5` (§54 doc-comment path refresh). Source byte-identical to v0.4.4.

Internal `@adia-ai/*` dep ranges stay at `^0.4.0` (patch-cut asymmetry — `^0.4.0` covers `0.4.x` under semver). See root [CHANGELOG.md `## [0.4.5]`](../../../CHANGELOG.md) for the cut narrative.

## [0.4.4] - 2026-05-12

### Changed — corpus simplification arc (§36-§51, 2026-05-12)

**verify:corpus warns: 993 → 148 (-845, -85%)** across §43-§51. Headline state: composition library boot reports `compositionCount=127, handAuthored=100, annotatedChunks=27`.

#### Removed

- **`corpus/exemplars/` retired (§36).** -3.4K lines. Exemplars had been speculative records without consumers; replaced by the growing annotated-chunk system.
- **`corpus/fragments/` retired (§37).** 41 fragment JSON files + schema + categorical indices deleted (-99.6 KB). 85 hand-authored compositions inlined with previously-referenced fragment content (slot machinery removed); 10 fragment shapes migrated to chunks via `data-chunk` markers added in production HTML; remaining 29 fragments dropped as speculative/superseded. Net: 3 corpus formats → 2.

#### Added

- **`data-chunk-*` source-HTML annotation system (§40).** Chunks can now carry retrieval metadata authored directly on production HTML elements:
  - `data-chunk-kind="<page|panel|block|field>"`
  - `data-chunk-domain="<auth|dashboard|error|onboarding|...>"`
  - `data-chunk-description="<concrete one-liner>"`
  - `data-chunk-keywords="<space-separated tokens>"`
  - `data-chunk-related="<comma-separated chunk names>"`
  - `data-chunk-tags-<key>="<value>"` (per-tag attributes for the tags object)

  Harvester (`scripts/build/harvest-chunks.mjs`, repo-level) reads these and produces chunks with a `metadata` field. Index schema bumped `@1` → `@2` to surface metadata for retrieval-without-load.

- **Nested-expand-then-transpile (§42).** Annotated chunks with nested children get their `<!-- nested: <name> -->` placeholders recursively expanded then transpiled to flat A2UI templates at harvest time, making them retrievable as compositions via zettel. Cycle-safe via `visited` set.

- **`verify:corpus` drift validator (§39, wired in §39; observability extended through §47/§51).** Walks every JSON in `corpus/{patterns,compositions,chunks}/**.json` against canonical component schemas. Surfaces unknown-component criticals + unknown-prop / enum-out-of-range / known-hallucination warns. §47 added `data-*` + `aria-*` HTML attribute skip rules; §42 added `annotated-chunk-no-template` warn for chunks with metadata but no template (caught the nested-expansion gaps).

- **27 retrievable annotated chunks** seeded across 6 domains (§40 / §45 / §46 / §48):
  - **Settings/data seeds (§40, 3 chunks):** `linked-record-row`, `settings-integrations`, `auth-signin-card-email`.
  - **Auth (§45, 8 chunks):** `auth-signin-card-{password,otp,magic-link,mfa}`, `auth-signup-entry`, `auth-password-reset`, `auth-new-password`, `auth-mfa-enrollment`.
  - **Dashboard (§46, 11 chunks):** `dashboard-admin-page` (427-component template, the full surface), `dashboard-page-header`, `dashboard-{overview,audience,acquisition,behavior,conversion,reports,notifications}-panel`, `dashboard-chart-recent`, `dashboard-team-actions-storage`.
  - **Error + onboarding (§48, 5 chunks):** `error-404`, `error-500`, `error-maintenance`, `reg-step-shell`, `onb-step-shell`.

#### Changed

- **Shape B → Shape A codemod (§43, -486 warns).** 475 records / 79 files. Top transformations: `Text.color="muted"` → `variant="caption"` (244 records); `Text.weight="semibold"` → `strong: true` (146 records); `*.attrs: {...}` → flattened to top-level (146 records); `Text.content` → `textContent`, `Button.content` → `text`, `Badge.content` → `text` (84 records); 109 empty `attrs:{}` objects removed; 5 manual-review (Text.color=primary/success — needs design call).
- **Yaml-gap renames + dead-prop deletes (§44, -301 warns).** 105 records / 48 files. Renames: `Button.block` → `stretch` (23), `Button.ariaLabel` → `aria-label` (16), `Badge.color="primary"` → `variant="primary"` (11, 1:1 mapping), `Table.rows` → `Table.data` (6), `Toast.title` → `Toast.text` (6). Deletes (runtime ignores): `Text.grow` (20, no `:scope[grow]` in text.css), `Progress.max` (15, runtime hardcodes max=100), `Skeleton.variant` (8, runtime silently drops), `Toast.description` (6, runtime only has `text`).
- **§43 manual-review backlog retired (§50, -42 warns).** 74 records / 25 files. Subagent A's foundational finding: `attrs:{}` has zero runtime effect — no renderer/host spreads it onto the element. So every key inside `attrs:` is dead-letter; flatten or delete is always safe. Promoted 33 records from §43's MANUAL_REVIEW to HIGH-confidence codemod: `Toggle.attrs.checked` → top-level (6), `Text.attrs.muted=true` → `color: "muted"` (17), `Avatar.attrs.alt` → `text` (8, avatar.js:68 auto-mirrors name → `<img alt>`), `Avatar.attrs.fallback` → DELETE (5, redundant with auto-derived initials at avatar.js:96-110), `Divider.attrs.orientation="vertical"` → `vertical: true` (2), `Button.attrs.triggers` → DELETE (1, hallucinated wiring). Companion yaml-gap renames (§50): `Kbd.text`/`Kbd.keys` → `textContent` (10), `Pagination.totalPages`/`currentPage` → `total`/`page` (6), `Divider.orientation` → `vertical: true` (3), `Input.icon` → `prefix` (4), `Option.text` → `heading` (5).
- **Search → Input migration (§42, 5 critical → 0).** 5 compositions migrated from deprecated `Search` component to `Input type="search" prefix="magnifying-glass"`. `Search` deliberately remains absent from the registry per registry.js line 57.
- **Input.inputMode → Input.inputmode (§51, 3 records).** HTML standard is lowercase `inputmode`. Companion to the §51 renderer kebab-casing fix in `@adia-ai/a2ui-runtime`.

### Harvester (`scripts/build/harvest-chunks.mjs`, repo-level)

The harvester is repo-tooling (`scripts/build/`), not a corpus package member, but its changes power this arc's corpus output:

- **§40 `data-chunk-*` attribute extraction** — reads sibling attributes from `data-chunk` elements; populates the chunk record's `metadata` field.
- **§42 nested-expand-then-transpile pass** — after collection, recursively expands `<!-- nested: <name> -->` placeholders in annotated chunks, then transpiles the expanded HTML to A2UI templates via `transpileHTML(html, { mode: 'instant' })`.
- **§45 source-aware tier-1 expansion fix** — replaces §42's "first wins" canonical-html rule with directory-aware selection. **Bug**: `auth-card-content` has 24 instances; the 404 page sorted alphabetically first, so EVERY auth chunk silently inlined 404 page content from §41 landing through §45 discovery (smoke tests only checked retrieval strategy, not template content). **Fix**: Tier 1 exact directory match → Tier 2 deepest common directory prefix → Tier 3 alphabetical. Without it, `apps/user-flow/app/auth/sign-in/` shares depth with `apps/user-flow/app/auth/sign-in/mfa/` and tie-break would pick wrong sibling.

See root [CHANGELOG.md `[Unreleased]`](../../../CHANGELOG.md) for the cross-cutting arc narrative + [docs/journal/2026/05/2026-05-12.md](../../../docs/journal/2026/05/2026-05-12.md) §§ 36-51 for per-§ details.

## [0.4.3] - 2026-05-11

### Changed

- **`catalog-a2ui_0_9.json` regenerated** to pick up the new `locale` prop on `<input-ui type="number">` from `@adia-ai/web-components@0.4.3`. The yaml `props:` entry drives retrieval signal for locale-aware numeric-input intents.
- **`chunks/` re-harvested** (181 files touched). New chunk `settings-appearance.json` — multi-instance record covering both `catalog/ui-patterns/app/settings-appearance/` (primary=card-ui, standalone block pattern composing `<theme-panel>`) and `apps/saas/app/settings-page/` (primary=div, Workspace-level Appearance section). Plus a sweep of `captured_at` timestamps + `source:` field updates from the ADR-0026 reorg follow-up. Harvest now produces 180 unique chunks (was 179 in v0.4.2; +1 from the new `settings-appearance` pattern).
- **Harvester scope fix** — `scripts/build/harvest-chunks.mjs` `SOURCES = ['site/pages', 'apps']` hadn't been updated after ADR-0026 split `apps/` → `apps/` + `playgrounds/` + `catalog/` on 2026-05-10. Every `npm run harvest:chunks` since silently dropped 26 chunks (179 unique → 152 visible) without warning. Fix adds both new sibling directories to SOURCES. (Note: harvest-chunks.mjs lives in the repo's `scripts/build/` tree, not the package; this corpus regen captures the FULL chunk set restored by the fix. Lesson captured as Category E imperative-drift in user-memory entry `feedback_build_script_sources_list_after_rename.md`.)

### Lockstep

9-package coordinated PATCH cut to v0.4.3. Internal `@adia-ai/*` dep ranges stay at `^0.4.0` (patch-cut asymmetry). Rides alongside `@adia-ai/web-components` v0.4.3 (input-ui locale rewrite) and `@adia-ai/a2ui-compose` + `@adia-ai/a2ui-retrieval` v0.4.3 (process.env browser-compat fix). See root [CHANGELOG.md `## [0.4.3]`](../../../CHANGELOG.md).

## [0.4.2] - 2026-05-11

### Changed

- `catalog-a2ui_0_9.json` regenerated to pick up the 5 new `<input-ui type="number">` examples from `@adia-ai/web-components@0.4.2`: `quantity-stepper`, `price-with-currency`, `weight-with-unit`, `percent-bounded`, `temperature-negative`. The yaml `examples[]` entries drive retrieval signal for numeric-input intents (quantity / price / weight / percent / temperature).
- `catalog-a2ui_0_9_rules.txt` regenerated alongside.
- `chunks/` — `playground-app-shell.json` re-harvested after the `<theme-panel>` consumer migration (Phase 3 of theme-panel work): embedded HTML now shows `<theme-panel slot="content" parametric presets scheme-toggle></theme-panel>` instead of the ~30-line inline `<div id="theme-panel">` block. Chunk NAME `playground-app-shell` preserved as a stable retrieval identifier per the 2026-05-10 §22 lesson. 27 additional chunk files touched in this window for `source:` field updates following the ADR-0026 reorg (`apps/<X>/` → `playgrounds/<X>/` or `catalog/<X>/`); chunk NAMES unchanged.

### Removed

- `fragments/layout/auth-card-header.json` — fragment retired (was the foundational auth-flow chunk header before migration to `<auth-card-content>` + `<auth-card-header>` chunk-level shape; instance_count had reconciled to 0 in v0.4.1, no longer present in any composition). Now archived at `.brain/archive/2026-Q2/retired-fragments/auth-card-header.md` per the v0.4.1 follow-up.

### Lockstep

9-package coordinated PATCH cut to v0.4.2 (per [`docs/specs/package-architecture.md` § 15](../../../docs/specs/package-architecture.md#15-versioning-policy)). Internal `@adia-ai/*` dep ranges stay at `^0.4.0` (patch-cut asymmetry — `^0.4.0` covers `0.4.x` under semver). Rides alongside `@adia-ai/web-components@0.4.2` (input-ui type=number rewrite) and `@adia-ai/web-modules@0.4.2` (editor-sidebar width mirror). See root [CHANGELOG.md `## [0.4.2]`](../../../CHANGELOG.md) for the cut narrative.

## [0.4.1] - 2026-05-10

### Changed

- **Fragment metrics reconciled** — 28 fragments updated to match computed values from `npm run audit:fragments`. 45 files modified (28 JSON + 17 YAML; 11 JSON have no YAML sibling). `audit:fragments` now reports 0 drift.
- **Special note: auth-card-header** instance_count reconciled from 23 → 0 (fragment no longer used by any composition). Pending decision on whether to deprecate or re-introduce.
- Catalog regenerated to include 3 new simple-cluster yamls (121 total).

### Added

- `docs/reports/chunk-reconcile-triage-2026-05-10.md` — triage doc documenting that all current `audit:chunk-reconcile` findings (9 fingerprint collisions + 19 near-duplicates + 10 cross-source) are intentional outcomes of the onb/reg alignment work + foundational shared chunks.

## [0.4.0] - 2026-05-10

### Ride-along (no corpus changes)

Lockstep MINOR cut alongside `@adia-ai/web-modules@0.4.0` (ADR-0024 legacy deprecation). Catalog regenerated; chunks/fragments/compositions/patterns byte-identical to v0.3.6.

Internal `@adia-ai/*` dep ranges bumped from `^0.3.0` to `^0.4.0`. See root [CHANGELOG.md `## [0.4.0]`](../../../CHANGELOG.md) for the cut narrative.

## [0.3.6] - 2026-05-10

### Changed

- **Component catalog regenerated** — 113 → 118 yamls (+5 from new editor-* bespoke children added in `@adia-ai/web-modules`). `catalog-a2ui_0_9.json` + `catalog-a2ui_0_9_rules.txt` regenerated.

- **New catalog entries** for the editor-cluster bespoke family per ADR-0023:
  - `EditorToolbar` (editor-toolbar) — JS-bearing
  - `EditorCanvas` (editor-canvas) — JS-bearing
  - `EditorSidebar` (editor-sidebar) — JS-bearing (delegates to `<pane-ui>`)
  - `EditorStatusbar` / `EditorCanvasEmpty` — CSS-only structural

The catalog is consumed by `@adia-ai/a2ui-retrieval` for protocol-vocabulary composition. Composers (zettel, chunk-zettel) now have addressable entries for editor sub-regions in protocol vocabulary.

### No source changes

Corpus chunks, fragments, compositions, and patterns are byte-identical to v0.3.5. The only change is the regenerated catalog manifest.

## [0.3.5] - 2026-05-07

### Changed

- **Component catalog regenerated** — 107 → 113 yamls (+6 from new chat-* bespoke children added in `@adia-ai/web-modules`). `catalog-a2ui_0_9.json` + `catalog-a2ui_0_9_rules.txt` regenerated by `scripts/build/components.mjs`.

- **New catalog entries** for the chat-cluster bespoke family per ADR-0023:
  - `ChatThread` (chat-thread) — JS-bearing (scroll surface)
  - `ChatComposer` (chat-composer) — JS-bearing (input wrapper)
  - `ChatSidebar` (chat-sidebar) — JS-bearing (resize+collapse)
  - `ChatHeader` / `ChatStatus` / `ChatEmpty` — CSS-only structural

The catalog is consumed by `@adia-ai/a2ui-retrieval` for protocol-vocabulary composition. Composers (zettel, chunk-zettel) now have addressable entries for chat sub-regions in protocol vocabulary.

### No source changes

Corpus chunks, fragments, compositions, and patterns are byte-identical to v0.3.4. The only change is the regenerated catalog manifest.

## [0.3.4] - 2026-05-07

### Changed

- **Component catalog regenerated** — 100 → 107 yamls (+7 from new admin-* CSS-only structural children added in `@adia-ai/web-modules`). `catalog-a2ui_0_9.json` + `catalog-a2ui_0_9_rules.txt` regenerated by `scripts/build/components.mjs`.

- **New catalog entries** for the bespoke shell-tier family per ADR-0023:
  - `AdminSidebar` (admin-sidebar) — JS-bearing
  - `AdminCommand` (admin-command) — JS-bearing
  - `AdminContent` / `AdminTopbar` / `AdminStatusbar` / `AdminScroll` / `AdminPage` / `AdminPageHeader` / `AdminPageBody` — CSS-only structural

The catalog is consumed by `@adia-ai/a2ui-retrieval` for protocol-vocabulary composition. Composers (zettel, chunk-zettel) now have addressable entries for shell sub-regions instead of falling back to chunk-name retrieval.

### No source changes

Corpus chunks, fragments, compositions, and patterns are byte-identical to v0.3.3. The only change is the regenerated catalog manifest.

## [0.3.3] - 2026-05-07

**Lockstep cut.** All 9 published `@adia-ai/*` packages now share version `0.3.3`, governed by [`docs/specs/package-architecture.md` § 15](../../../docs/specs/package-architecture.md#15-versioning-policy). Internal `@adia-ai/*` ranges stay at `^0.3.0` (patch-cut asymmetry — caret floats `0.3.x`).

### Added

- **`fragments/layout/auth-card-header.json`** — first fragment
  promoted from chunk corpus. Was 23 instances across user-flow auth
  pages (sign-in, sign-up, recovery, account-deleted, email-verify,
  forbidden) + error pages (404, 500, maintenance), all sharing the
  same shape: `Header > Column[align=center,gap=1] >
  [Link>Image, Text(h1), Text]`. 4 slots
  (logo-href, logo-src, title, description). Promotion provides 23×
  leverage over chunk-by-chunk emission. Zettel retrieval test:
  score 88 vs 48 next alternative. (closes backlog #65)

- **`A2UI_DISABLE_EMBEDDINGS` env-var override** in
  `scripts/chunk-library.js`. When set, `searchChunksAsync()` falls
  through to keyword-only search instead of attempting embeddings.
  Used by the new top-level `npm run eval:keyword-only` script.
  Latency drops from 100-400ms to 0-1ms with same scores; proves
  keyword path is independently healthy. (closes backlog #11)

- **Glossary section** in README.md — chunk vs pattern vs fragment
  vs composition. Four overlapping concepts circulate through this
  package; the glossary disambiguates. (closes backlog #94)

- **Catalog manifest documentation** — README updated to clarify
  that `retrieval/catalog.js` is **hand-written** (a CatalogManifest
  module that dynamically reads per-component `<c>.a2ui.json`
  sidecars at runtime), NOT a generated artifact. The actual
  generated artifacts are `traits/_catalog.json` and per-component
  `<name>.a2ui.json` sidecars. (companion to AGENTS.md hard-rule #7
  correction; closes backlog #57)

## [0.3.2] - 2026-05-06

**9-package lockstep patch cut to v0.3.2.** All lockstep members share
one version per [`docs/specs/package-architecture.md` § 15](../../../docs/specs/package-architecture.md#15-versioning-policy).
Internal `@adia-ai/*` dep ranges unchanged at `^0.3.0`.

### Added

- **Corpus re-harvest** — 173 unique chunks (from 160), 322 instances.
  13 new block patterns (`command-palette-grouped`, `agent-activity-feed`,
  `agent-reasoning-collapsed`, `user-profile-card`, `kanban-board-3col`,
  `chat-streaming-surface`, `settings-notifications`, `marketing-hero-cta`,
  `conversion-funnel-6step`, `users-table-badge`, `destructive-confirm-modal`,
  `editor-code-pane`, `editor-preview-pane`) + 5 new page shells
  (`settings-page-shell`, `form-page-shell`, `marketing-page-shell`,
  `error-page-shell`, `editor-page-shell`).
- **Harvester source expansion** — `apps/` added alongside `site/pages/`;
  `apps/generic-shells/app/` contributes the 5 generic page shells.

### Fixed

- **`data-chunk-slot` preservation** — `stripChunkAttrs()` regex narrowed
  to only strip `data-chunk` + `data-chunk-kind`; no longer strips
  `data-chunk-slot` (composer runtime dependency for slot-finding).

### Changed

- `version`: `0.3.1` → `0.3.2`.

## [0.3.1] - 2026-05-06

**9-package lockstep patch cut.** All 9 published `@adia-ai/*` packages bump 0.3.0 → 0.3.1 per [`docs/specs/package-architecture.md` § 15](../../../docs/specs/package-architecture.md#15-versioning-policy). Internal `@adia-ai/*` dep ranges remain at `^0.3.0` (covers `0.3.1` under semver — patch-cut asymmetry).

This package itself ships **no source changes** in v0.3.1. The cut bumps version only — substantive content lives in [`@adia-ai/web-components`](https://github.com/adiahealth/gen-ui-kit/releases/tag/web-components-v0.3.1) (folder-per-trait restructure; barrel API unchanged).

### Changed

- `version`: `0.3.0` → `0.3.1`.
- Internal `@adia-ai/*` dep ranges: unchanged at `^0.3.0` (covers `0.3.1` under semver — patch-cut asymmetry).

## [0.3.0] - 2026-05-05

**9-package lockstep cut.** All 9 published `@adia-ai/*` packages bump 0.2.5 → 0.3.0 per [`docs/specs/package-architecture.md` § 15](../../../docs/specs/package-architecture.md#15-versioning-policy). Internal `@adia-ai/*` dep ranges bump `^0.2.0` → `^0.3.0`.

The lockstep policy expanded from 8 to 9 packages with this cut — `@adia-ai/llm` joins as a 9th member, and `@adia-ai/a2ui-utils` was renamed to `@adia-ai/a2ui-runtime`. Both are BREAKING for npm consumers (acceptable under pre-1.0 semver).

This package itself ships **no source changes** in v0.3.0. The cut bumps version + the internal dep range only.

### Changed

- `version`: `0.2.5` → `0.3.0`.

### No source changes

`a2ui-corpus` source is byte-identical to `0.2.5`. The cut bumps version only — corpus has no `@adia-ai/*` dependencies so no dep-range updates either.

## [0.2.5] - 2026-05-04

**Lockstep cut + catalog regen for `<fields-ui>` primitive.** All 8 published `@adia-ai/*` packages bump 0.2.4 → 0.2.5 per [`docs/specs/package-architecture.md` § 15](../../../docs/specs/package-architecture.md#15-versioning-policy). Patch cut — **no BREAKING changes**.

### Changed

- `version`: `0.2.4` → `0.2.5`.
- `catalog-a2ui_0_9.json`: 1 new entry covering the new `<fields-ui>` primitive (component class `Fields`, tag `fields-ui`, props `[columns]` + `[inline]`, default slot for `<field-ui>` children + the `rows` span pattern). Catalog: 97 → 98 yamls.
- Per-element `fields/fields.a2ui.json` written by `scripts/build/components.mjs`.

## [0.2.4] - 2026-05-04

**Lockstep cut + catalog regen for `<demo-toggle-ui>` primitive.** All 8 published `@adia-ai/*` packages bump 0.2.3 → 0.2.4 per [`docs/specs/package-architecture.md` § 15](../../../docs/specs/package-architecture.md#15-versioning-policy). Patch cut — no breaking changes.

### Changed

- `version`: `0.2.3` → `0.2.4`.
- `catalog-a2ui_0_9.json`: 6 new references (name + slots + events + props + tokens + example) covering the new `<demo-toggle-ui>` primitive added in `web-components@0.2.4`.

### Changed — Catalog regenerated against `web-components` Tier-4 surface

`catalog-a2ui_0_9.json` regenerated to include the new
`<demo-toggle-ui>` primitive (6 references covering name + slots +
events + props + tokens + example) authored alongside the trait-
library lift initiative's Tier 5 work. No other corpus surface
changed; new traits introduced in `web-components` are picked up via
the generated `_catalog.json` consumed by
`@adia-ai/a2ui-retrieval`.

---

## [0.2.3] - 2026-05-04

**Lockstep cut.** All 8 published `@adia-ai/*` packages bump
0.2.2 → 0.2.3 per
[`docs/specs/package-architecture.md` § 15](../../../../docs/specs/package-architecture.md#15-versioning-policy).
Patch cut — no breaking changes.

### Changed

- `version`: `0.2.2` → `0.2.3`.

### No source changes

`@adia-ai/a2ui-corpus` source is byte-identical to `0.2.2`. The cut bumps version only.

## [0.2.2] - 2026-05-02

**Lockstep cut.** All 8 published `@adia-ai/*` packages bump 0.2.1 → 0.2.2 per [`docs/specs/package-architecture.md` § 15](../../../docs/specs/package-architecture.md#15-versioning-policy). Patch cut — no breaking changes.

### Changed

- `version`: `0.2.1` → `0.2.2`.

### No source changes

`a2ui-corpus` source is byte-identical to `0.2.1`. The cut bumps version only.

---

## [0.2.1] - 2026-05-02

**Lockstep cut + chunk-corpus reorganization mega-arc + trait registry regenerated from web-components SoT.** All 8 published `@adia-ai/*` packages bump 0.2.0 → 0.2.1 per [`docs/specs/package-architecture.md` § 15](../../../docs/specs/package-architecture.md#15-versioning-policy). Patch cut — no breaking changes.

### Changed

- `version`: `0.2.0` → `0.2.1`.
- `evals/holdout-compose-from-chunks.jsonl` migrated **into** corpus from a2ui-mcp (was at `packages/a2ui/mcp/evals/`). 20-intent compose-from-chunks holdout now lives next to the corpus it tests. `evals/run.mjs` updated to load from the new home; the legacy `evals/harness.mjs` was retired (its functionality merged into `run.mjs`).

### Changed — Trait registry now generated from web-components SoT (2026-05-02)

`packages/a2ui/retrieval/catalog.js` no longer carries a hand-curated `traitRegistry` array. The trait list is loaded at module init from `packages/web-components/traits/_catalog.json` (generated by `node scripts/build/traits-catalog.mjs` in the monorepo root from live `defineTrait()` metadata). Per [ADR-0018](../../../.brain/adrs/0018-trait-source-of-truth-and-declarative-attribute.md).

Behavior changes:
- 4 phantom traits (`disabled-state`, `form-associated`, `value-sync`, `resettable`) no longer appear in MCP `get_traits` responses — they had no implementation in `traits/`. Auto-pruned by construction.
- 2 naming mismatches resolved: `resize-observer-trait` → `resize-observer`, `intersection-observer-trait` → `intersection-observer`. The catalog now uses the same names as the trait files.
- Trait entries now include the full schema (`attributes`, `events`, `config` arrays) instead of just `{ name, category, description }`. Consumers reading `getTraits()` get richer metadata. Older shape is a strict subset, no breakage.

### Changed

- **`chunk-embeddings.json` (~20 MB) and `pattern-embeddings.json` (~3 MB)
  removed from the published npm tarball.** Both files remain committed in
  git so the monorepo's own pipeline runs unchanged. Published-tarball size
  drops from ~24 MB unpacked to ~3.4 MB.

  Consumers who need embedding-based retrieval regenerate locally via
  `npm run build:embeddings:all` (requires API access to the embedding
  provider). Keyword-only retrieval (`searchChunks` / `searchPatterns`)
  works unchanged without the indexes — the embedding-aware async paths
  (`searchChunksAsync` / `searchPatternsAsync`) fall through to keyword
  scoring when the index file is absent (`chunk-embedding-retriever.js`
  returns `null` gracefully on `ENOENT`).

  Note: the prior `chunk-embedding-retriever` path (`../../corpus/chunk-embeddings.json`)
  resolves correctly inside the monorepo but breaks under a
  `node_modules/@adia-ai/a2ui-corpus/` install layout — so the embedding
  files were already unreachable to npm consumers, just heavy. This change
  surfaces that reality. Published-consumer reachability is a separate
  follow-up.

  See README § "What's committed vs generated vs published".

### Changed — Chunk corpus reorganization mega-arc (2026-05-02)

12-commit arc that re-balances the chunk corpus for retrieval precision and harvester hygiene. End state: 100 compositions, 41 fragments, 1,422 chunks, 41 MB embeddings, fragment reuse ratio 40.2% (was 29.9% pre-§37; floor: 29.9%). Eval byte-identical: zettel coverage 83% / avgScore 89 / MRR 0.986 throughout.

- **`section-with-stack` fragment promoted** — first corpus use of children-as-attribute slot binding. 43 inline `Section(Column)` pairs collapsed into the new fragment at `fragments/layout/section-with-stack.json`.
- **Multi-variant chunk split (308 → 937 per-variant chunks).** Harvester migrated from `<section>`-wrapper-tagging to inner-pattern-tagging; multi-variant artifact-items now produce one chunk per visual variant (`alert-variant-warning` vs `alert-variant-success`) instead of one bundled chunk. Embedding-probe verified the precision lift: "warning alert" → `alert-variant-warning` (0.657), "large avatar" → `avatar-size-lg` (0.639), "small primary button" → `button-size-primary-sm` (0.656).
- **Skeleton harvest** (`collapseNestedChunkContent`) — page/panel chunks with nested `data-chunk` children replace the inner content with `<!-- nested: <name> -->` so the parent chunk is a compact skeleton recording structure + which sub-chunks fill which positions. xl-bucket chunks (>10K chars): 2 → 0.
- **Harvest-side hygiene** — strip `data-chunk` attribute from output HTML; strip docs-page wrappers; de-dup adjacent slug tokens; new Case 3 in `stripChunkWrappers` for `<div data-artifact-item data-chunk>` patterns.
- **Multi-variant CSS narrowing** — `dev-chunks.css` outline narrows to `[data-artifact-container]` so the visual marker matches the harvested scope.

### Added — Under-harvest audit script (2026-05-02)

New `scripts/build/under-harvest-audit.mjs` flags pages under `site/pages/{patterns,examples,components}/` that have ≥2 substantive layout elements (`<section>`/`<card-ui>`/`<grid-ui>`) but fewer than 1-per-5KB-body `data-chunk` markers. Drives a recurring 2-week remote agent (`trig_01UEDMT1cMqCpRLU6z8LBMo4`) that opens triage PRs for under-harvested pages.

### Fixed — A2UI registry gap closure + ADR-0015 pattern migration (2026-05-02)

- **Registry additions** in `@adia-ai/a2ui-utils`: `Field`, `Rating`, `ListItem`, `NavItem`, `NavGroup`. All 5 components existed; only the registry mapping was missing. Net effect on the corpus: 28/113 hand-authored patterns previously rendered with `[unknown: X]` placeholders when imported into `/site/playground/a2ui-editor`. After: 0/113 unknown.
- **`patterns/navigation/section-subnav.json`** migrated per [ADR-0015 § Nav consolidation](../../../.brain/adrs/0015-three-tier-naming-convention.md). `SectionNav` → `Nav variant=section`; `SectionNavItem` → `NavItem`. The pattern was referencing the retired 6-element nav family.
- **`patterns/layout/weather-widget.json`** — renamed `Metric` → `Stat` (no `<metric-ui>` exists; `Stat` is the canonical metric/value/change/trend primitive).
- Smoke side-effect: zettel score bumped 91 → 92; smoke validation flipped from `valid=false score=98/91` → `valid=true score=100/92`. The registry gaps were tripping validation upstream.

Per-finding triage in [`docs/reports/playground-examples-review-2026-05-02.md`](../../../docs/reports/playground-examples-review-2026-05-02.md).

## [0.2.0] - 2026-05-02

**Lockstep cut.** All 8 published `@adia-ai/*` packages now share one
version, governed by [`docs/specs/package-architecture.md` § 15
(Versioning Policy)](../../../docs/specs/package-architecture.md#15-versioning-policy).

This release also formalizes corpus's role as **the catalog's home** —
spec § 3 first-principle 3 was rewritten in v0.6.0 of the spec to
make this explicit. Primitives produce YAML/`.a2ui.json` sidecars;
the build assembles them into `catalog-a2ui_0_9.json` here.

### Changed

- `version`: `0.0.9` → `0.2.0`.

### No source changes (data)

Corpus content (catalog, patterns, fragments, compositions, exemplars,
chunks, embeddings, eval fixtures, gap registry, feedback) is
byte-identical to 0.0.9. The cut bumps version only — corpus has no
internal `@adia-ai/*` dependencies. The `a2ui-mcp@0.1.3 → corpus@0.0.6`
caret-lock bug from the prior cut is resolved by the mcp package's
`^0.2.0` range update in this same lockstep cut.

### Touched (no behavior change)

- `scripts/run-pipeline.mjs`, `scripts/chunk-library.js`,
  `scripts/feedback-promote.js`, `scripts/feedback-report.js` — import
  paths swept to match the compose `engines/` → `strategies/` rename
  and the retrieval subdir reorganization. Pure path-string updates;
  no logic changes.

## [0.0.9] - 2026-05-01

Pure-data refresh covering the §22-25 web-components arc. Catalog
regenerated against the post-rename + post-consolidation surface;
chunks re-harvested where source pages changed. Rolls forward the
[0.0.8] cut (avatar-ui canonicalization) — the 0.0.8 bump was
prepared but never tagged + published; its content is part of this
release.

### Changed

- **Catalog regenerated against `web-components@0.0.33` surface** — 95
  yamls now include the consolidated nav family (`<nav-ui>`,
  `<nav-group-ui>`, `<nav-item-ui>` with `[variant="primary"|"section"]`)
  and the renamed module elements (`<chat-shell>` was
  `<adia-chat-ui>`; `<editor-shell>` was `<adia-editor-ui>`;
  `<admin-shell>` was `<app-shell-ui>`; `<gen-root>` was
  `<gen-ui-ui>`; `<chat-thread-ui>` was `<chat-ui>`). Element renames
  per [ADR-0015](../../../.brain/adrs/0015-three-tier-naming-convention.md);
  nav consolidation per ADR-0015 § Nav consolidation. The 6-element
  nav family (`<app-nav-*>` + `<section-nav-*>`) collapsed into 3
  primitives. Synthesizer no longer emits the renamed-away tags.
- **`yaml name:` fields swept** per
  [ADR-0016](../../../.brain/adrs/0016-class-naming-convention.md) —
  primitives now `name: UI<X>` (was `Adia<X>`); modules now
  `name: <X>` without the `Adia` prefix. Consumers reading the
  catalog to cross-reference class names get the current convention.
- **`patterns/_components.json`** refreshed to match the new
  catalog surface (component IDs, allowed children, slot vocabularies).
- **Chunks re-harvested** for the chat / playground-app-shell /
  playground-chat / playground-construct-canvas / playground-gen-ui
  source pages — these surfaces touched the renamed shells +
  consolidated nav and now emit canonical post-rename markup.
- **`scripts/extract.js`** updated to recognize the renamed elements
  + `[variant]` cascade markers when classifying chunks.

### Rolled forward from [0.0.8] (never tagged)

- **`<avatar-ui name=…>` → `<avatar-ui text=…>`** sweep across 8
  source pattern pages (31 instances). `name` is the deprecated alias
  scheduled for removal; chunks now carry the canonical attribute.
  Chunk count + shape unchanged; embedding index unaffected (only
  chunk-root attrs are indexed; `<avatar-ui>` is always nested in
  body HTML).

## [0.0.8] - 2026-05-01

Pure-data refresh. Chunk re-harvest aligns the corpus with the
canonical attribute API for `<avatar-ui>` so the synthesizer doesn't
teach consumers to emit deprecated markup.

### Changed

- Chunks re-harvested after sweeping `<avatar-ui name=…>` →
  `<avatar-ui text=…>` across 8 source pattern pages (31 instances).
  `name` is the deprecated alias scheduled for removal; chunks now
  carry the canonical attribute. Pure data change — chunk count +
  shape unchanged (761 unique / 911 instances), embedding index
  unaffected (only chunk-root attrs are indexed; `<avatar-ui>` is
  always nested in body HTML).
- Catalog regenerated against `web-components@0.0.29` surface
  (`<feed-ui>` + `<feed-item-ui>` + `<swatch-ui>` family entries
  carried through, app-shell slot-vocabulary parity reflected).

## [0.0.7] - 2026-04-28

### Added

- **Two new `page`-kind chunks**: `reg-step-shell` (registration
  multi-step wizard wrapper) and `onb-step-shell` (onboarding tour
  wrapper). Both expose four named slots — `page-story`, `page-header`,
  `page-content`, `page-footer` — that the chunk synthesizer binds
  block-kind chunks into. Five existing reusable blocks per family
  (`*-story-pane`, `*-step-header`, `*-step-footer`, `*-step-progress`,
  per-step content block) recorded as the shells' `nested` chunks.

  Page-kind catalog is now 3 (was 1): `dashboard-admin-page`,
  `reg-step-shell`, `onb-step-shell`.

  Source pages: `site/pages/examples/registration/personal/index.html`
  + `site/pages/examples/onboarding/welcome/index.html` — one canonical
  instance each. The other 18 reg + 9 onb step pages share the same
  template; replicating shell tags would produce duplicate instances
  without changing the unique-name catalog.

  Unlock: `compose_from_chunks(intent)` can now synthesize multi-step
  wizard pages and onboarding-tour pages on top of the existing
  admin-dashboard shape — 3× expansion of the page-kind catalog.

## [0.0.6] - 2026-04-28

**Retires the legacy exemplar extract → ingest path.** The chunk corpus
+ chunk-aware synthesizer (shipped 0.0.3 → 0.0.4 → 0.0.5 today) is now
the single training surface; the parallel exemplar-derived auto-ingest
that was running on every MCP server boot is gone.

### Removed

- **Stale auto-generated artifacts** under `exemplars/<category>/<name>/`:
  - `a2ui.json` (full-page A2UI extract; 9 files)
  - `chunks/*.json` per-exemplar atomic chunks (~70 files)
  These were transient build outputs of the old extract.js pipeline. The
  source `index.html` + `<name>.yaml` files stay for human reference and
  potential future use as fragment authoring.

### Changed

- The `extract.js` + `ingest.js` scripts still ship in the tarball as
  legacy tools. They no longer run by default in `run-pipeline.mjs`;
  pass `--legacy-exemplars` to opt back in. See companion mcp 0.0.5
  release notes for the runtime impact.

### What stayed the same

- Hand-authored `patterns/` (155 entries), `fragments/` (zettel graph),
  `compositions/`, `pattern-embeddings.json`, `chunk-embeddings.json`,
  `chunks/_index.json` (701 unique / 851 instances), and the
  `chunk-library` API are all unchanged.
- The `exemplars/` source HTML + `<name>.yaml` partners stay in the
  tarball — useful for reference, but no longer feed the training
  pipeline by default.

## [0.0.5] - 2026-04-28

Corpus refresh — drops a non-chunk-shaped entry and regenerates both
embedding indices. Pure-data; no schema changes; no consumer-facing
API impact beyond a slight retrieval-quality bump.

### Removed

- **`genui-feed-message` chunk** — `<col-ui id="gen-feed">` on
  `gen-ui-feed/index.html` is sample-data scaffolding (the feed
  structure varies entirely per session), not a discrete trainable
  pattern. The `data-chunk` marker was dropped; the source page
  itself stays. Inventory entry struck through, kept as a strikethrough
  audit trail.

### Changed

- **`chunks/_index.json` re-harvested** — 702 → **701 unique** chunks;
  852 → **851 instances**; by-kind `block=843, panel=7, page=1`.
- **`chunk-embeddings.json` regenerated** — 701 × 1536d (was 702).
  Same provider / model / dims; just one fewer entry.
- **`pattern-embeddings.json` regenerated** — same 113 × 1536d count;
  fresh timestamp.

## [0.0.4] - 2026-04-28

Same-day follow-up to `0.0.3` shipped earlier today. Adds **semantic
search vectors** to the corpus and ships them in the tarball so consumers
get embedding-based retrieval out of the box (no post-install build step).
Pure-data addition; no schema changes.

### Added

- **`pattern-embeddings.json`** — refreshed against the current
  113-pattern set (was last built 2026-04-23 against 109 patterns).
  OpenAI text-embedding-3-small, 1536 dims, ~3.3 MB.
- **`chunk-embeddings.json`** — NEW. 702 chunks × 1536 dims, ~20 MB.
  Embeds each chunk's name + kind + primary tag + slot names + nested
  chunk names + indexed attributes + cluster prefix. HTML body is
  deliberately NOT embedded (would dominate retrieval noise; the LLM
  gets the HTML at retrieval time).

### Changed

- `package.json` `files` field now ships both embedding indices in the
  published tarball. Tarball size grows from ~3.5 MB to ~24 MB; the
  trade-off is that consumers can use semantic search out of the box
  without re-running embedding generation.
- Companion repo tooling (not in tarball but used to generate the
  corpus):
  - `scripts/build/embeddings.mjs` — broken `import` paths fixed (the
    script had been dead since some directory move; load-env.mjs +
    embedding-provider.js were both at wrong relative paths).
  - **`scripts/build/embeddings-chunks.mjs`** — new sibling script that
    walks `chunks/<name>.json` and generates `chunk-embeddings.json`.
    Auto-detects Voyage / OpenAI / null per the same conventions as the
    pattern script. Honors `--kind`, `--batch`, `--out`, `--dry-run`.
  - `npm run build:embeddings` / `build:embeddings:chunks` /
    `build:embeddings:all` pipeline scripts.

### Performance

- The chunk-aware composition synthesizer (`@adia-ai/a2ui-mcp@0.0.3`)
  uses these embeddings via `chunk-embedding-retriever.js` (cosine
  similarity, blended 5× with keyword score). Real-LLM eval improved
  from 7/10 → **9/10 retrieval hits** out of 10 hold-out intents — only
  novel composites still need synthesis fallback.

## [0.0.3] - 2026-04-28

Same-day extension after `0.0.2` shipped. Adds the **gen-UI training-chunk
corpus** — 702 unique chunks (852 instances) harvested from `data-chunk`-marked
elements across `site/pages/*` and the corpus exemplars. Pure-data addition;
existing pattern/fragment/composition surface unchanged.

### Added (gen-UI chunks)

- **`chunks/<name>.json`** × 702 — one record per chunk; carries
  `name`, `kind` (`block` | `panel` | `page`), `primary` (outer tag),
  `slots[]` (named regions for compositional reasoning), `nested[]`
  (child chunk names), `attrs` (indexed for retrieval), `html`
  (bounding HTML, descendants intact), `source` (original file path),
  `captured_at`. Multi-instance reusable slot chunks
  (e.g. `auth-card-header`, `reg-step-header`) carry an `instances`
  array — one entry per page where the chunk appears.
- **`chunks/_index.json`** — aggregate index (metadata only, no HTML)
  for fast lookup. Records total counts, by-kind tallies, per-chunk
  pages + slot names + nested-chunk references.
- **852 chunk instances** across ~150 distinct pages (70 template +
  82 component primitive + 16 pattern). Coverage:
  `block=844, panel=7, page=1`.

### Added (companion tooling — not in tarball)

- `scripts/build/harvest-chunks.mjs` (repo root) — walks site/pages
  + corpus exemplars; depth-tracked HTML parser; writes per-chunk
  records + aggregate index. Wired into
  `packages/a2ui/corpus/scripts/run-pipeline.mjs` Step 1.
- `packages/a2ui/corpus/scripts/chunk-library.js` — in-memory loader
  for the chunk corpus; powers the new MCP retrieval tools (consumed
  by `@adia-ai/a2ui-mcp@0.0.2`).
- `npm run harvest:chunks` / `harvest:chunks:dry` — pipeline scripts.

### Convention reference

- Spec: [`docs/specs/genui-chunk-marker.md`](../../../docs/specs/genui-chunk-marker.md)
  (Draft v0.1.0) — three attributes (`data-chunk`, `data-chunk-kind`,
  `data-chunk-slot`); naming conventions per cluster; visual marker
  rules; harvester contract.
- Inventory: [`docs/specs/genui-chunk-inventory-001.md`](../../../docs/specs/genui-chunk-inventory-001.md)
  — full list with intent labels + review status.

## [0.0.2] - 2026-04-27

Three-day batch since `0.0.1`. Catalog regenerated against the
Phase 6 web-components surface (status enum, button `[color]` axis,
canonical event names); four new dashboard / data patterns; nine
prose exemplars purged of inline styles; auth-login + cta exemplars
migrated to canonical field-ui wrapping; three superseded fragments
removed. Pure-data package — no executable code change.

### Added (patterns)

- **`patterns/data/chart-card-with-trend-footer.{json,yaml}`** —
  card-ui composition with chart in body and trend-stat footer
  (KPI delta + sparkline). Dashboard pattern.
- **`patterns/data/chart-grid-with-kpis.{json,yaml}`** — grid-ui
  layout pattern with KPI cards above and chart-ui beneath, the
  canonical "dashboard above the fold" shape.
- **`patterns/data/chart-with-filter-pills.{json,yaml}`** —
  chart-ui composed with row-ui of filter pills above (segmented-ui
  / tag-ui mix), the standard chart-with-toolbar shape.
- **`patterns/data/stat-with-sparkline.{json,yaml}`** — atomic
  KPI stat pattern with inline sparkline. Used as the building
  block for `chart-card-with-trend-footer`.

### Added (authoring infrastructure)

- **`exemplars/_shell.css`** — shared body-shell + decoration-class
  stylesheet linked from the corpus exemplar root. Codifies the
  "no inline styles in exemplars" rule documented in the project
  CLAUDE.md / AGENTS.md. New exemplars link this file from their
  `index.html` and rely on `col-ui` / `row-ui` / `grid-ui` for
  layout instead of `<style>` blocks or `style="…"` attributes.

### Changed (catalog)

- **`catalog-a2ui_0_9.json`** rebuilt against the v0.0.20 / v0.0.21
  web-components yaml surface. Diff includes:
  - `status` enum on `timeline-item-ui` / `stepper-item-ui` /
    `pipeline-status-ui` (replaces the prior multi-Boolean shape).
  - `[color]` enum on `button-ui` (`default | accent | info |
    success | warning | danger`), `variant` simplified to
    style-only.
  - Canonical event names — `submit` on `chat-ui` (was
    `chat-submit`), `toggle` on `chart-legend-ui` (was
    `legend-toggle`), `change` on `swiper-ui` (was `slide-change`).
  - `error` variant alias dropped from `toast-ui` / `alert-ui` /
    `tag-ui` enums.
  - `agent-trace-ui` `[collapsed]` (was `[open]`).
  - `field-ui` `error` prop removed from props list.
  - `table-toolbar-ui` opt-out attribute names — `noFilter` /
    `noSort` / `noColumns` / `noSearch`.
- **`patterns/_components.json:3020`** — `timeline-item-ui`
  children-snippet migrated `completed active` → `status="completed"`.
  The snippet feeds the LLM bridge; the legacy form would have
  caused gen-ui to suggest deprecated attributes when generating
  timelines.
- **`patterns/_index.json`** regenerated to reflect the four new
  data patterns and a few keyword refinements.

### Changed (exemplars)

- **9 prose exemplars** (`prose/auth-login`, `prose/cta`,
  `prose/feature-grid`, `prose/footer`, `prose/hero`,
  `prose/pricing`, `prose/steps`, `prose/testimonials`) and
  **`ui/auth-login`** purged of inline `<style>` blocks and
  `style="…"` attributes. Width constraints come from `setup.js`
  setting `--page-content-max-width` via
  `setProperty`; layout from `col-ui` / `row-ui` / `grid-ui`;
  asymmetric ratios from `[columns]` + `[span]`. Shadow + decoration
  surface lifted to `_shell.css`.
- **`exemplars/prose/auth-login/index.html` + `exemplars/ui/auth-login/index.html`** —
  `<check-ui label="…">` migrated to canonical
  `<field-ui inline label="…"><check-ui name="…"></field-ui>`
  wrapping. 5 call sites total (Remember me, Trust this device,
  Terms agreement). Each migrated checkbox now serializes with a
  stable form key (`name="remember"` / `name="trust_device"` /
  `name="terms"`).
- **`exemplars/prose/cta/`** — `acme-logo` icon (fictitious; not
  in `@phosphor-icons/core`) replaced with `hexagon` across 3
  files: `index.html:21`, `a2ui.json:102`,
  `chunks/prose-cta-card-1.json:65`. Cleared the
  `Icon "acme-logo" not found in registry` warning that fired on
  every render.

### Removed (fragments)

- **`fragments/content/chart-legend.json`** — superseded by the
  `<chart-legend-ui>` primitive that landed in the web-components
  package. Inline-rendering the legend as a fragment is no longer
  the canonical path.
- **`fragments/form/rating-row.{json,yaml}`** — superseded by
  the `<rating-ui>` primitive's first-class API (label + value
  + max + readonly all on the host element).

### Verification

- `node scripts/build/components.mjs --verify` — `clean — 96 files up-to-date`.
- Catalog hash matches the rebuild script's deterministic output.
- Pattern index reverse-lookup test: every `_index.json` ref
  resolves to an existing pattern file.

---

## [0.0.1] - 2026-04-24

First public release. Pure-data package: pattern corpus,
fragment + composition library, exemplars, and held-out eval
fixtures for the A2UI generation pipeline.

### Included

- **Assembled catalog** (`catalog-a2ui_0_9.json`) — generated by
  `scripts/build-components.mjs` from the per-component YAML
  sources in `@adia-ai/web-components`. Contains component schemas,
  registry, domain classifications, fragments, compositions.
- **Rules manifest** (`catalog-a2ui_0_9_rules.txt`) — human-readable
  rules file paired with the catalog.
- **Patterns** (`patterns/`) — ~217 patterns across 11 domains
  (layout, forms, data, agent, navigation, display, container,
  settings, etc.). Indexed via `patterns/_index.json`.
- **Fragments** (`fragments/`) — reusable A2UI atoms used by
  zettel-engine composition.
- **Compositions** (`compositions/`) — templates that reference
  fragments via `$fragment` refs.
- **Exemplars** (`exemplars/`) — few-shot training examples per
  domain. Consumed by the monolithic engine's prompt assembly.
- **Held-out eval fixtures** (`evals/held-out.jsonl`) — 100 intents
  reserved from training for regression evaluation.

### Corpus state at cut

See the "Corpus state" section below for pattern counts by domain,
fragment library size, and composition coverage.

---

## Corpus state (current)

| Surface | Count |
|---|---:|
| Patterns (total) | 215 |
| Pages (exemplars) | 9 |
| Chunks | 61 |
| Components registered | 89 |
| Fragments | varies; see `fragments/` |

Domain breakdown:
- layout: 114
- forms: 38
- data: 23
- agent: 20
- navigation: 11
- display, container: 3 each
- settings, data-display, input: 1 each

## [0.1.0] — internal baseline (pre-public, predates 0.0.1)

Initial version at the time the monorepo was established. Contains:

- **Patterns** (`patterns/`) — monolithic pattern library with schema.
- **Fragments** (`fragments/`) — atomic fragments for the zettel engine (content, layout, wiring, etc.).
- **Compositions** (`compositions/`) — hand-authored compositions that reference fragments.
- **Exemplars** (`exemplars/`) — hand-authored HTML pages harvested into chunks during extraction.
- **Held-out eval set** (`evals/held-out.jsonl`) — ~100 intents with golden matches for regression testing.
- **Feedback / gaps registry** (`feedback/`, `gaps/`) — runtime-written operational learning.
- **Taxonomy / synonym registry** — concept mapping for keyword-based retrieval.

Package name still uses the legacy `@adia-ai/a2ui-corpus` scope pending rename (see root CHANGELOG for context).
