P05 · Experience · Rendered from source

innovation register

Living UI component layer

109 lines42,642 bytessha256 6a9fd683c79f
IN-001record 1
{
  "id": "IN-001",
  "hypothesis": "Adopt the shadcn Dynamic Search contract as P05's agent-facing query API verbatim",
  "rationale": "shadcn already specifies GET /r/registry.json?q&type&limit&offset with a `pagination` object as the opt-in server-side-search signal, backwards compatible with static registries. Any shadcn-MCP-capable agent can then query Actionist with zero bespoke client work.",
  "evidence_class": "observed",
  "rank": 1,
  "falsifier": "If the contract cannot express the facets P05 needs (visual similarity, theme-eligibility, archetype role) even as extensions, and agents ignore unknown params, then a bespoke API is required after all.",
  "theme": "agent_api"
}
IN-002record 2
{
  "id": "IN-002",
  "hypothesis": "Adopt canonical-component + alias-set, NOT a flat tag vocabulary",
  "rationale": "Component Gallery catalogues 60 canonical components each with an alias list, and its data empirically breaks flat naming: Banner is an alias of BOTH Alert and Hero; Stepper is both an alias of Progress indicator AND its own canonical; Label is an alias of Badge AND standalone. Our own 75-tag vocabulary averages 2.09 tags/component with 52.6% single-tagged, so it already behaves as a single-label category scheme, not a facet grid.",
  "evidence_class": "observed",
  "rank": 2,
  "falsifier": "If a sample of 200 components can be assigned to a 60-name canonical set by two independent raters with <80% agreement, the canonical model is not stable enough and faceted tags win.",
  "theme": "taxonomy"
}
IN-003record 3
{
  "id": "IN-003",
  "hypothesis": "Separate the index into two tiers by tag provenance and never let weak tags gate client-facing selection",
  "rationale": "Ground-truth `page` tags cover 4,033 components; `api` and `local` inference cover the rest. Measured per-shape, the gap is large: sidebar is 44 at page tier vs 139 at any tier. Presenting inferred tags as fact would mis-sell supply by up to 3x.",
  "evidence_class": "observed",
  "rank": 3,
  "falsifier": "If blind human review of 100 `local`-tier tag assignments finds >90% correct, the tier distinction is over-cautious and one merged index suffices.",
  "theme": "taxonomy"
}
IN-004record 4
{
  "id": "IN-004",
  "hypothesis": "Measure the visual near-duplicate rate with perceptual hash + CLIP before designing dedupe",
  "rationale": "Exact byte-identical previews are only 102 surplus of 7,678 (1.3%), while name-collision surplus is 2,058 (25.9%). The truth is between and is currently UNMEASURED; the gap is too large to design against.",
  "evidence_class": "observed",
  "rank": 4,
  "falsifier": "If pHash at a standard threshold collapses the 2,058 to under ~200 clusters, cheap hashing suffices and CLIP is unnecessary spend.",
  "theme": "dedupe"
}
IN-005record 5
{
  "id": "IN-005",
  "hypothesis": "Actionist must OWN the archetype shell and the 20 AutoSaaS app primitives; harvest only decorative/marketing surfaces",
  "rationale": "Every AutoSaaS-required primitive has ground-truth supply in the corpus (min 32 for onboarding, max 167 for spinner), but these are exactly the components that must be contract-stable, themeable, accessible and wired to the data plane. Harvested bundles carry no source, no a11y contract and no props. Supply is not the constraint; ownership of the contract is.",
  "evidence_class": "inferred",
  "rank": 5,
  "falsifier": "If a harvested table/form can be wired to P09's data plane and pass a11y checks in under a day each for 5 sampled components, owning them is wasted effort.",
  "theme": "ownership"
}
IN-006record 6
{
  "id": "IN-006",
  "hypothesis": "Treat the corpus as a dated snapshot, not a living layer, until a timestamp field exists",
  "rationale": "No meta.json in 7,949 dirs carries a harvest timestamp (fields are url/author/slug/name/description/installCommand/id/bundleUrl/previewUrl/harvested plus optional usage_count/demo_id/video_url/preview/previewVia). Directory mtimes cluster in a single 67-minute window on 2026-08-18. Staleness is currently uncomputable.",
  "evidence_class": "observed",
  "rank": 6,
  "falsifier": "If 21st.dev exposes a reliable per-component updated_at we can read at query time, a local timestamp is redundant.",
  "theme": "refresh"
}
IN-007record 7
{
  "id": "IN-007",
  "hypothesis": "Use the existing discovery frontier (urls-union) as the refresh queue; the design is mechanism-ready but legally gated",
  "rationale": "urls-union.union holds 8,225 discovered URLs against 7,949 harvested — a standing backlog of 276 already-discovered, unharvested components, and 0 harvested items missing from the union. The delta IS the refresh queue. But the mechanism that produced it is the one 21st.dev's terms prohibit.",
  "evidence_class": "observed",
  "rank": 7,
  "falsifier": "If counsel clears the harvest mechanism, this becomes a build task; if counsel refuses, the entire refresh design must move to licensed/first-party sources and this ranks last, not seventh.",
  "theme": "refresh"
}
IN-008record 8
{
  "id": "IN-008",
  "hypothesis": "Let clients select by visual attribute (colour, density, style), never by component name",
  "rationale": "Awwwards ships hex-swatch and font filtering; UIverse ships style tag facets (#neumorphism, #3d, #gradient); Mobbin ships Text-in-Screenshots so a user who cannot name a component can still search words printed on it. Our legacy store already carries visual_style across 24 values (minimalist 1739, flat 1315, gradient 768).",
  "evidence_class": "observed",
  "rank": 8,
  "falsifier": "If usability testing shows clients pick faster from a named-category list than from a visual grid, the visual-first premise is wrong.",
  "theme": "client_ux"
}
IN-009record 9
{
  "id": "IN-009",
  "hypothesis": "Run the theme-eligibility gate over all 7,949 and publish pass/fail as a first-class index field",
  "rationale": "The prior audit proved a 12-token regex swap re-themes a bundle with JS bit-identical, and measured 55/60 (91.7%) re-theming cleanly, 86.7% of colour rules already tokenised, WebGL ~16% of n=25 and Tailwind-v3 8.3% of n=60 needing exclusion. Running it corpus-wide converts sampled estimates into a per-component fact and auto-produces the exclusion list.",
  "evidence_class": "inferred",
  "rank": 9,
  "falsifier": "If the corpus-wide pass rate lands below ~60%, the re-theming premise fails and the picker must ship fixed-palette components instead.",
  "theme": "theming"
}
IN-010record 10
{
  "id": "IN-010",
  "hypothesis": "Do NOT build an industry facet from legacy best_for_industries — it does not discriminate",
  "rationale": "Mean 3.93 industries per component; 171 components claim all 10; 89.6% claim saas. Worse, only 2 of the 17 target industries (real_estate, saas) have any direct analogue, and 5 (construction, logistics_freight, insurance_agencies, mortgage_brokers, property_management) have ZERO reachable supply under a best-effort crosswalk.",
  "evidence_class": "observed",
  "rank": 10,
  "falsifier": "If re-classifying a 200-component sample directly against the 17-industry list yields a balanced distribution, the axis is recoverable by reclassification rather than abandonment.",
  "theme": "taxonomy"
}
IN-011record 11
{
  "id": "IN-011",
  "hypothesis": "Perceptual hash (pHash/dHash/wHash) as the first dedupe pass",
  "rationale": "Cheap, well-understood, and idealo/imagededup bundles an evaluation harness.",
  "evidence_class": "hypothesis",
  "rank": null,
  "falsifier": "pHash fails to cluster components that differ only in theme colour.",
  "theme": "dedupe"
}
IN-012record 12
{
  "id": "IN-012",
  "hypothesis": "CLIP embeddings as the second dedupe pass for semantic near-duplicates",
  "rationale": "Ports like shadcn-vue and shadcn-svelte guarantee semantically identical, pixel-different components.",
  "evidence_class": "hypothesis",
  "rank": null,
  "falsifier": "CLIP clusters by dominant colour rather than structure, producing useless clusters.",
  "theme": "dedupe"
}
IN-013record 13
{
  "id": "IN-013",
  "hypothesis": "Cluster on the DOM/CSS structure of bundle.html rather than the image",
  "rationale": "Structure survives re-theming; pixels do not.",
  "evidence_class": "hypothesis",
  "rank": null,
  "falsifier": "Minified compiled bundles differ enough per build that structural hashes never collide.",
  "theme": "dedupe"
}
IN-014record 14
{
  "id": "IN-014",
  "hypothesis": "One-per-author cap within a category to break house-style clustering",
  "rationale": "Top-10 authors hold 24.4% and top-50 hold 57.3% of the corpus; ruixen.ui alone has 383.",
  "evidence_class": "observed",
  "rank": null,
  "falsifier": "Capping removes the best component in a category when one author is genuinely dominant.",
  "theme": "dedupe"
}
IN-015record 15
{
  "id": "IN-015",
  "hypothesis": "Exclude junk/test fixtures by rule at index time",
  "rationale": "A corrected rule set flags 78 of 7,949 (0.98%): bare-test-name 15, localhost-author 38, fixture-string 21, numeric-name 14, char-repeat 11.",
  "evidence_class": "observed",
  "rank": null,
  "falsifier": "The rules also catch legitimate components with terse names, harming recall.",
  "theme": "curation"
}
IN-016record 16
{
  "id": "IN-016",
  "hypothesis": "Filter the client-facing picker to tagged components only",
  "rationale": "670 untagged (8.4%) are largely junk by inspection; excluding them costs nothing a client would pick.",
  "evidence_class": "inferred",
  "rank": null,
  "falsifier": "Manual review of the 670 finds a materially useful minority.",
  "theme": "curation"
}
IN-017record 17
{
  "id": "IN-017",
  "hypothesis": "Use usage_count as a popularity prior where present",
  "rationale": "usage_count is present on 1,125 of 3,000 sampled meta.json (37.5%).",
  "evidence_class": "observed",
  "rank": null,
  "falsifier": "usage_count reflects 21st.dev install traffic, not fitness for our archetypes.",
  "theme": "ranking"
}
IN-018record 18
{
  "id": "IN-018",
  "hypothesis": "Rank by tag confidence first, damped by tag spread, installs as tiebreak",
  "rationale": "find.mjs already implements exactly this ranker.",
  "evidence_class": "observed",
  "rank": null,
  "falsifier": "The ranker was tuned for a 832-entry catalog and does not generalise to 7,949.",
  "theme": "ranking"
}
IN-019record 19
{
  "id": "IN-019",
  "hypothesis": "Serve preview.webp in the grid and the bundle only on demand",
  "rationale": "Median preview 11,410 B vs median bundle 337,515 B — a ~30x scroll-performance difference.",
  "evidence_class": "observed",
  "rank": null,
  "falsifier": "Static thumbnails cannot convey interaction, which is what differentiates many components.",
  "theme": "client_ux"
}
IN-020record 20
{
  "id": "IN-020",
  "hypothesis": "Hover-to-play video preview for components with video_url",
  "rationale": "video_url is present on the same 1,125 of 3,000 sampled records as usage_count; board.html already implements hover-video.",
  "evidence_class": "observed",
  "rank": null,
  "falsifier": "Only ~37% coverage makes the affordance inconsistent and confusing.",
  "theme": "client_ux"
}
IN-021record 21
{
  "id": "IN-021",
  "hypothesis": "Virtualised grid; never pre-render cards",
  "rationale": "board.html is 885,238 B of pre-rendered HTML for only 832 cards (10.5% of corpus); that strategy cannot reach 7,949.",
  "evidence_class": "observed",
  "rank": null,
  "falsifier": "A virtualised grid harms SEO/shareability that a static export would provide.",
  "theme": "client_ux"
}
IN-022record 22
{
  "id": "IN-022",
  "hypothesis": "Progressive disclosure: pick 1 of ~10 per category, not browse 7,949",
  "rationale": "Supply per required shape is ample (ground truth 32-167), so the task is choosing 10, not finding any.",
  "evidence_class": "inferred",
  "rank": null,
  "falsifier": "Clients want to see the full range and feel constrained by a curated 10.",
  "theme": "client_ux"
}
IN-023record 23
{
  "id": "IN-023",
  "hypothesis": "Side-by-side comparison of 2-3 candidates under the client's own token pack",
  "rationale": "Choice quality improves when alternatives are seen together under real theme.",
  "evidence_class": "hypothesis",
  "rank": null,
  "falsifier": "Comparison increases decision time without improving satisfaction.",
  "theme": "client_ux"
}
IN-024record 24
{
  "id": "IN-024",
  "hypothesis": "Show each component in the client's palette BEFORE selection, not after",
  "rationale": "Closes the deterministic loop; the token swap is already proven mechanical.",
  "evidence_class": "inferred",
  "rank": null,
  "falsifier": "Re-theming introduces contrast failures that make good components look bad.",
  "theme": "theming"
}
IN-025record 25
{
  "id": "IN-025",
  "hypothesis": "Scope token replacement to :root and .dark separately, never globally",
  "rationale": "99.0% of bundles carry a .dark/prefers-color-scheme block; the prior proof rewrote every matching declaration including inside .dark, which collapses the dark variant.",
  "evidence_class": "observed",
  "rank": null,
  "falsifier": "Clients only ever need one mode, making scoping unnecessary complexity.",
  "theme": "theming"
}
IN-026record 26
{
  "id": "IN-026",
  "hypothesis": "Map white/N and black/N literals to color-mix() against theme tokens",
  "rationale": "A finite enumerable vocabulary of 39 distinct literal classes was observed across n=25; transparent/text-transparent are false positives needing no mapping.",
  "evidence_class": "observed",
  "rank": null,
  "falsifier": "color-mix() browser support or visual result is unacceptable in target browsers.",
  "theme": "theming"
}
IN-027record 27
{
  "id": "IN-027",
  "hypothesis": "Leave red/green/amber/yellow alone as semantic status colours",
  "rationale": "preetsuthar17__alert uses dark:bg-amber-950/30, dark:bg-blue-950/30, dark:bg-green-950/30 as warning/info/success variants; recolouring them to var(--primary) would make all three identical.",
  "evidence_class": "observed",
  "rank": null,
  "falsifier": "Clients expect total palette control and find unrecoloured status chips inconsistent.",
  "theme": "theming"
}
IN-028record 28
{
  "id": "IN-028",
  "hypothesis": "Exclude WebGL/shader components from theming and present them as fixed-palette effects",
  "rationale": "4/25 sampled bundles carry ~130 vec3/vec4 colour constructions in GLSL strings that no CSS variable reaches; aurora-blur re-themed is a different component.",
  "evidence_class": "observed",
  "rank": null,
  "falsifier": "A shader uniform can be driven from a CSS variable at runtime, making exclusion unnecessary.",
  "theme": "theming"
}
IN-029record 29
{
  "id": "IN-029",
  "hypothesis": "Detect and route Tailwind v3 builds to a second mapping table",
  "rationale": "5/60 bundles lack a shadcn token block; two are v3 builds using the --tw-bg-opacity idiom — equally enumerable, just different.",
  "evidence_class": "observed",
  "rank": null,
  "falsifier": "The v3 population is too small and heterogeneous to justify a second mapper.",
  "theme": "theming"
}
IN-030record 30
{
  "id": "IN-030",
  "hypothesis": "Make the eligibility gate a checkable per-component contract, not a corpus-wide assumption",
  "rationale": "Scanning post-swap CSS for any colour declaration not resolving through var()/color-mix(), ignoring transparent/currentColor, is ~20 lines and makes the guarantee per-component.",
  "evidence_class": "inferred",
  "rank": null,
  "falsifier": "The scan produces false failures on legitimate patterns, excluding good components.",
  "theme": "theming"
}
IN-031record 31
{
  "id": "IN-031",
  "hypothesis": "Screenshot re-themed bundles headlessly and diff against the original to catch contrast failures",
  "rationale": "The audit flags 'do re-themed bundles look right' as the most likely source of unpleasant surprises and explicitly UNMEASURED.",
  "evidence_class": "observed",
  "rank": null,
  "falsifier": "Automated contrast checks disagree with human aesthetic judgement often enough to be useless.",
  "theme": "theming"
}
IN-032record 32
{
  "id": "IN-032",
  "hypothesis": "Compute WCAG contrast ratios post-theme and fail components below AA",
  "rationale": "Mechanical, cheap, and catches the light-first-component-on-dark-pack case.",
  "evidence_class": "hypothesis",
  "rank": null,
  "falsifier": "Many aesthetically fine components fail AA, making the gate too aggressive.",
  "theme": "theming"
}
IN-033record 33
{
  "id": "IN-033",
  "hypothesis": "Join the two 21st stores on a NORMALISED canonical key, not raw URL string equality",
  "rationale": "The two stores use different URL shapes: meta.json.url is https://21st.dev/@author/components/slug while _provenance.fetchedFrom is https://21st.dev/r/Author/slug. Case-insensitive author+slug normalisation yields intersection 2,945, union 8,483.",
  "evidence_class": "observed",
  "rank": null,
  "falsifier": "Author renames upstream break the key, silently splitting identities.",
  "theme": "join"
}
IN-034record 34
{
  "id": "IN-034",
  "hypothesis": "Carry source_available as a first-class index field",
  "rationale": "Only the legacy store has source: 3,506 components with real .tsx. Source-bearing supply is ~2.3x smaller than the 7,949 headline.",
  "evidence_class": "observed",
  "rank": null,
  "falsifier": "Source becomes universally available via a paid key, making the field constant.",
  "theme": "join"
}
IN-035record 35
{
  "id": "IN-035",
  "hypothesis": "Prefer the legacy store's registry-item.json as the dependency record",
  "rationale": "It yields 237 distinct npm dependencies across the source-bearing store (lucide-react 1272, class-variance-authority 1031, framer-motion 874, @radix-ui/react-slot 824) — a real measurement, unlike the 18 packages visible from import-wrapper demo.tsx.",
  "evidence_class": "observed",
  "rank": null,
  "falsifier": "Declared dependencies drift from what the source actually imports.",
  "theme": "join"
}
IN-036record 36
{
  "id": "IN-036",
  "hypothesis": "Use the legacy classification.json as the semantic/use-case axis",
  "rationale": "3,507 of 3,507 carry use_cases (mean 4.63 each, 16,241 total) and 3,499 carry industries — the only local source of a job-to-be-done axis.",
  "evidence_class": "observed",
  "rank": null,
  "falsifier": "Haiku-generated use_cases are too generic to discriminate between components.",
  "theme": "taxonomy"
}
IN-037record 37
{
  "id": "IN-037",
  "hypothesis": "Do NOT delete either 21st store as a duplicate",
  "rationale": "The 2,945 intersection holds source AND bundle AND preview; 534 legacy-only are source-bearing and absent from the newer corpus. Deleting either side destroys capability.",
  "evidence_class": "observed",
  "rank": null,
  "falsifier": "Storage cost outweighs the value of the 534 legacy-only components.",
  "theme": "join"
}
IN-038record 38
{
  "id": "IN-038",
  "hypothesis": "Record every component with a provenance tier and refuse admission without one",
  "rationale": "Rights coverage is 2 license fields across 11,549 third-party records (0.017%).",
  "evidence_class": "observed",
  "rank": null,
  "falsifier": "Counsel clears the corpus wholesale, making per-record provenance unnecessary.",
  "theme": "provenance"
}
IN-039record 39
{
  "id": "IN-039",
  "hypothesis": "Default every third-party record to rights_status: gated, reuse: reference_only",
  "rationale": "SISO harvest rule 6 says summarize rather than copy when licence is unclear; the corpus's own AGENT.md independently says adapt rather than paste.",
  "evidence_class": "observed",
  "rank": null,
  "falsifier": "Counsel establishes blanket clearance.",
  "theme": "provenance"
}
IN-040record 40
{
  "id": "IN-040",
  "hypothesis": "Model the corpus as reference-for-regeneration, not a parts bin to copy",
  "rationale": "Sidesteps the rights problem: an agent that reads a bundle to learn a pattern and writes original source is doing what AGENT.md already instructs.",
  "evidence_class": "hypothesis",
  "rank": null,
  "falsifier": "Regenerated components are materially worse than the originals, negating the corpus's value.",
  "theme": "provenance"
}
IN-041record 41
{
  "id": "IN-041",
  "hypothesis": "Build the index so the corpus can be swapped for a licensed source without redesign",
  "rationale": "If counsel blocks 21st material, the index schema should survive with different rows.",
  "evidence_class": "hypothesis",
  "rank": null,
  "falsifier": "Source-specific fields leak into the schema deeply enough that swapping is a rewrite.",
  "theme": "provenance"
}
IN-042record 42
{
  "id": "IN-042",
  "hypothesis": "Treat registry.json-serving vendors as the licensed refresh path",
  "rationale": "ReactBits 672, Tailark 469, Aceternity 278, Magic UI 247, Fancy 158, HextaUI 139, Eldora 115, Kokonut 51, shadcn core 63 — all parsed live, all publishing a machine-readable registry by design rather than by scraping.",
  "evidence_class": "observed",
  "rank": null,
  "falsifier": "Their individual licences prohibit redistribution as thoroughly as 21st's terms do.",
  "theme": "refresh"
}
IN-043record 43
{
  "id": "IN-043",
  "hypothesis": "Poll registry.json endpoints and diff item lists to detect new releases",
  "rationale": "Registries publish a full item list; a diff is the cheapest possible change feed.",
  "evidence_class": "hypothesis",
  "rank": null,
  "falsifier": "Registries do not version or timestamp items, so a diff cannot distinguish new from renamed.",
  "theme": "refresh"
}
IN-044record 44
{
  "id": "IN-044",
  "hypothesis": "Copy registry.directory's freshness telemetry model",
  "rationale": "It renders per-registry new-component deltas and updated-recency spanning same-day to 10 months — exactly the staleness signal P05 lacks.",
  "evidence_class": "observed",
  "rank": null,
  "falsifier": "Its telemetry is manually curated rather than computed, and does not scale.",
  "theme": "refresh"
}
IN-045record 45
{
  "id": "IN-045",
  "hypothesis": "Show clients a per-component last-verified date",
  "rationale": "Trust in a 'living' layer depends on visible recency.",
  "evidence_class": "hypothesis",
  "rank": null,
  "falsifier": "Clients ignore dates and it only exposes staleness we would rather fix.",
  "theme": "refresh"
}
IN-046record 46
{
  "id": "IN-046",
  "hypothesis": "Re-capture previews on a change-detection trigger, not a fixed schedule",
  "rationale": "changedetection.io (Apache-2.0) implements exactly this; fixed schedules waste quota on unchanged components.",
  "evidence_class": "inferred",
  "rank": null,
  "falsifier": "Change detection over rendered pages is too noisy to be a useful trigger.",
  "theme": "refresh"
}
IN-047record 47
{
  "id": "IN-047",
  "hypothesis": "Backfill the 271 missing previews with Playwright rather than the vendor CDN",
  "rationale": "backfill-previews.mjs exists but was never run; Playwright renders from the local bundle with no vendor request.",
  "evidence_class": "observed",
  "rank": null,
  "falsifier": "Local renders differ visually from vendor previews, making the grid inconsistent.",
  "theme": "refresh"
}
IN-048record 48
{
  "id": "IN-048",
  "hypothesis": "Close the 276-component discovery backlog before any new discovery sweep",
  "rationale": "Cheapest possible corpus growth: they are already discovered and unharvested.",
  "evidence_class": "observed",
  "rank": null,
  "falsifier": "The 276 are non-components or dead URLs.",
  "theme": "refresh"
}
IN-049record 49
{
  "id": "IN-049",
  "hypothesis": "Keep serve.mjs and find.mjs; rebuild the data layer only",
  "rationale": "serve.mjs already serves harvest/ correctly and implements the POST /api/picks manifest contract end to end; find.mjs implements ranking and a --json agent surface.",
  "evidence_class": "observed",
  "rank": null,
  "falsifier": "Their assumptions are tied to the 832-entry catalog and do not survive contact with 7,949.",
  "theme": "reuse"
}
IN-050record 50
{
  "id": "IN-050",
  "hypothesis": "Steal board.html's CSS and interaction model, discard its markup and data",
  "rationale": "It has a responsive auto-fill grid, lazy loading, light/dark tokens, multi-select with a sticky tray, lightbox and hover-video — but is a static snapshot of 832 of 7,949 (10.5%) pointing at a different preview store.",
  "evidence_class": "observed",
  "rank": null,
  "falsifier": "The CSS is entangled with the pre-rendered markup and cannot be lifted cleanly.",
  "theme": "reuse"
}
IN-051record 51
{
  "id": "IN-051",
  "hypothesis": "Generate one slim picker-index.json rather than shipping three 700KB+ JSON files",
  "rationale": "classification.json is 2.17 MB, api-metadata.json 1.30 MB, catalog.json 713 KB, ranked.json 844 KB.",
  "evidence_class": "observed",
  "rank": null,
  "falsifier": "A single index becomes a bottleneck for partial updates.",
  "theme": "reuse"
}
IN-052record 52
{
  "id": "IN-052",
  "hypothesis": "Adopt the Great Library 11-stage lifecycle rather than inventing an admission ladder",
  "rationale": "It already encodes unverified -> read -> candidate -> ... -> retired with evidence[] and blockers[] requirements.",
  "evidence_class": "observed",
  "rank": null,
  "falsifier": "The lifecycle is tuned for repos, not components, and the stages do not map.",
  "theme": "provenance"
}
IN-053record 53
{
  "id": "IN-053",
  "hypothesis": "Schematize KEEPERS.md into structured records",
  "rationale": "It is the only local artifact encoding human component admission, and it is prose.",
  "evidence_class": "observed",
  "rank": null,
  "falsifier": "It is too small a precedent to be worth schematizing.",
  "theme": "provenance"
}
IN-054record 54
{
  "id": "IN-054",
  "hypothesis": "Own navigation as an archetype-level structure, not a harvested component",
  "rationale": "Navigation encodes route topology and permission state from P10, which no harvested component can know.",
  "evidence_class": "inferred",
  "rank": null,
  "falsifier": "A harvested nav shell can be parameterised by a route manifest without modification.",
  "theme": "ownership"
}
IN-055record 55
{
  "id": "IN-055",
  "hypothesis": "Own forms because validation, error state and submission are contract surfaces",
  "rationale": "Form field supply exists (120 ground truth) but a harvested field has no schema, no validation contract and no data-plane binding.",
  "evidence_class": "inferred",
  "rank": null,
  "falsifier": "A generated schema-to-form layer can wrap harvested field visuals without owning them.",
  "theme": "ownership"
}
IN-056record 56
{
  "id": "IN-056",
  "hypothesis": "Own tables because sorting, pagination, selection and empty/loading/error states are behavioural",
  "rationale": "141 ground-truth table components exist, but the behaviour matters more than the look.",
  "evidence_class": "inferred",
  "rank": null,
  "falsifier": "A headless table library plus harvested styling covers it without ownership.",
  "theme": "ownership"
}
IN-057record 57
{
  "id": "IN-057",
  "hypothesis": "Own the feedback family (toast, alert, empty, loading, error) as one coherent set",
  "rationale": "These must be consistent across an app; sourcing them from five different authors guarantees incoherence.",
  "evidence_class": "inferred",
  "rank": null,
  "falsifier": "Theme tokens alone are enough to make five authors' feedback components look coherent.",
  "theme": "ownership"
}
IN-058record 58
{
  "id": "IN-058",
  "hypothesis": "Harvest heroes, testimonials, pricing sections, galleries and marketing surfaces",
  "rationale": "These are decorative, self-contained, carry no data-plane contract, and are exactly where visual variety has client value. hero=521, testimonials=137, pricing-section=186, gallery=325.",
  "evidence_class": "observed",
  "rank": null,
  "falsifier": "Marketing surfaces still need CMS binding, making them contract-bearing after all.",
  "theme": "ownership"
}
IN-059record 59
{
  "id": "IN-059",
  "hypothesis": "Define an owned base set of roughly 20 components matching the AutoSaaS requirement list",
  "rationale": "AutoSaaS already enumerates 20 required primitives with a metadata contract (name, use case, props, states, a11y notes, responsive behavior, source path, examples, tests).",
  "evidence_class": "observed",
  "rank": null,
  "falsifier": "The 20 are wrong for Actionist's archetypes and a different set is needed.",
  "theme": "ownership"
}
IN-060record 60
{
  "id": "IN-060",
  "hypothesis": "Derive the owned set from archetype demand, not from a generic dashboard list",
  "rationale": "case_workflow is primary for 6 of 17 industries and portal secondary for 6 of 17; two archetypes carry majority demand.",
  "evidence_class": "observed",
  "rank": null,
  "falsifier": "Archetype-level reuse is an illusion and per-industry sets are required.",
  "theme": "ownership"
}
IN-061record 61
{
  "id": "IN-061",
  "hypothesis": "Version owned components independently with their own contracts",
  "rationale": "teambit/bit demonstrates component-as-independently-versioned-unit at scale.",
  "evidence_class": "inferred",
  "rank": null,
  "falsifier": "Independent versioning overhead exceeds its benefit at ~20 components.",
  "theme": "ownership"
}
IN-062record 62
{
  "id": "IN-062",
  "hypothesis": "Express owned components as a shadcn-compatible registry Actionist publishes",
  "rationale": "Makes Actionist's own base layer consumable by any shadcn-aware agent or client.",
  "evidence_class": "hypothesis",
  "rank": null,
  "falsifier": "Publishing invites support obligations Actionist does not want.",
  "theme": "ownership"
}
IN-063record 63
{
  "id": "IN-063",
  "hypothesis": "Give every component an a11y contract field with observed evidence, not a claim",
  "rationale": "Component Gallery carries 'Accessibility issues (4)' and 'Accessibility guidelines (27)' as first-class facets on design systems.",
  "evidence_class": "observed",
  "rank": null,
  "falsifier": "Automated a11y checks on isolated components produce too many false positives.",
  "theme": "ownership"
}
IN-064record 64
{
  "id": "IN-064",
  "hypothesis": "Carry 'unmaintained' and 'has known issues' as first-class facets",
  "rationale": "Component Gallery does exactly this for design systems (Unmaintained 11 of 95).",
  "evidence_class": "observed",
  "rank": null,
  "falsifier": "For a component corpus these facets are unknowable without upstream signals.",
  "theme": "provenance"
}
IN-065record 65
{
  "id": "IN-065",
  "hypothesis": "Store components in an embedded vector store colocated with metadata",
  "rationale": "pgvector or lancedb avoids a second datastore while enabling similarity + facet filtering in one query.",
  "evidence_class": "hypothesis",
  "rank": null,
  "falsifier": "Metadata filtering plus vector search in one engine is slower than two specialised ones.",
  "theme": "agent_api"
}
IN-066record 66
{
  "id": "IN-066",
  "hypothesis": "Expose an MCP server over the component index",
  "rationale": "Mobbin and 21st.dev both ship one; it is the emerging norm for agent access.",
  "evidence_class": "observed",
  "rank": null,
  "falsifier": "MCP adoption stalls and a plain HTTP API would have served better.",
  "theme": "agent_api"
}
IN-067record 67
{
  "id": "IN-067",
  "hypothesis": "Return accessibility-tree summaries rather than images to agents where possible",
  "rationale": "playwright-mcp uses accessibility-tree-over-pixels; Mobbin's own guidance caps at 3-8 images per call because each consumes context.",
  "evidence_class": "observed",
  "rank": null,
  "falsifier": "Agents select components better from images than from structural text.",
  "theme": "agent_api"
}
IN-068record 68
{
  "id": "IN-068",
  "hypothesis": "Cap agent responses at a small number of candidates with structured metadata",
  "rationale": "Mobbin enforces a default limit of 20 screens per call at 60 req/min.",
  "evidence_class": "observed",
  "rank": null,
  "falsifier": "Agents need broad candidate sets and small caps degrade selection quality.",
  "theme": "agent_api"
}
IN-069record 69
{
  "id": "IN-069",
  "hypothesis": "Publish an llms.txt describing the corpus and its query surface",
  "rationale": "Verified present on 21st.dev, Magic UI, Aceternity, Creative Tim, daisyUI and others; cheap static discoverability.",
  "evidence_class": "observed",
  "rank": null,
  "falsifier": "llms.txt is ignored by the agents that matter.",
  "theme": "agent_api"
}
IN-070record 70
{
  "id": "IN-070",
  "hypothesis": "Let agents query by archetype role rather than by component name",
  "rationale": "An agent composing a case_workflow app needs 'the table for this archetype', not 'table'.",
  "evidence_class": "hypothesis",
  "rank": null,
  "falsifier": "Archetype role is too coarse and agents still need name-level control.",
  "theme": "agent_api"
}
IN-071record 71
{
  "id": "IN-071",
  "hypothesis": "Return a re-themed preview URL in agent responses so the agent can verify visually",
  "rationale": "Closes the loop between selection and appearance.",
  "evidence_class": "hypothesis",
  "rank": null,
  "falsifier": "Agents cannot meaningfully evaluate a rendered preview and the extra payload is waste.",
  "theme": "agent_api"
}
IN-072record 72
{
  "id": "IN-072",
  "hypothesis": "Expose the theme-eligibility flag in the agent query so ineligible components are never returned",
  "rationale": "Prevents an agent selecting a component that will ignore the client's palette.",
  "evidence_class": "inferred",
  "rank": null,
  "falsifier": "Eligibility is contextual and a global flag over-excludes.",
  "theme": "agent_api"
}
IN-073record 73
{
  "id": "IN-073",
  "hypothesis": "Support text-in-preview search via OCR over the 7,678 previews",
  "rationale": "Mobbin ships Text-in-Screenshots as a distinct search dimension; it needs no taxonomy at all.",
  "evidence_class": "observed",
  "rank": null,
  "falsifier": "Component previews contain mostly lorem ipsum, so OCR adds no signal.",
  "theme": "client_ux"
}
IN-074record 74
{
  "id": "IN-074",
  "hypothesis": "Extract a dominant-colour palette per preview and allow colour-swatch filtering",
  "rationale": "Awwwards ships hex-swatch filtering as a verified non-technical browse affordance.",
  "evidence_class": "hypothesis",
  "rank": null,
  "falsifier": "Components are re-themed anyway, so their captured colour is irrelevant to choice.",
  "theme": "client_ux"
}
IN-075record 75
{
  "id": "IN-075",
  "hypothesis": "Filter by visual density/complexity using the legacy complexity axis",
  "rationale": "complexity is populated across the source store: composite 2201, atomic 1261, system 44.",
  "evidence_class": "observed",
  "rank": null,
  "falsifier": "Complexity as labelled does not correlate with what clients perceive as busy.",
  "theme": "client_ux"
}
IN-076record 76
{
  "id": "IN-076",
  "hypothesis": "Filter by visual_style using the legacy 24-value axis",
  "rationale": "minimalist 1739, flat 1315, gradient 768, dark 274, glass-morphism 260, 3d 248 — a real, populated style axis.",
  "evidence_class": "observed",
  "rank": null,
  "falsifier": "Style labels are Haiku-generated and do not match human judgement.",
  "theme": "client_ux"
}
IN-077record 77
{
  "id": "IN-077",
  "hypothesis": "Show interaction affordances as a facet",
  "rationale": "The legacy store carries an interactions axis (hover-glow, morph, scroll-animate observed).",
  "evidence_class": "observed",
  "rank": null,
  "falsifier": "Coverage of the interactions field is too sparse to filter on.",
  "theme": "client_ux"
}
IN-078record 78
{
  "id": "IN-078",
  "hypothesis": "Let clients pick by reference image: upload a screenshot, retrieve visually similar components",
  "rationale": "CLIP embeddings make image-to-image retrieval straightforward.",
  "evidence_class": "hypothesis",
  "rank": null,
  "falsifier": "Clients do not have reference images, or the matches are too loose to be useful.",
  "theme": "client_ux"
}
IN-079record 79
{
  "id": "IN-079",
  "hypothesis": "Let clients pick by describing the job in plain words, matched against use_cases",
  "rationale": "16,241 use_case strings exist across 3,507 components, averaging 4.63 each.",
  "evidence_class": "observed",
  "rank": null,
  "falsifier": "Use-case text is too generic to discriminate between similar components.",
  "theme": "client_ux"
}
IN-080record 80
{
  "id": "IN-080",
  "hypothesis": "Present a small curated shelf per archetype rather than the whole corpus",
  "rationale": "The binding constraint is curation, not supply.",
  "evidence_class": "inferred",
  "rank": null,
  "falsifier": "Clients reject curated shelves as limiting and demand full browse.",
  "theme": "client_ux"
}
IN-081record 81
{
  "id": "IN-081",
  "hypothesis": "Record every client selection as training signal for P06",
  "rationale": "Selections are the highest-quality preference data available.",
  "evidence_class": "hypothesis",
  "rank": null,
  "falsifier": "Selection is dominated by position and ordering effects rather than preference.",
  "theme": "learning"
}
IN-082record 82
{
  "id": "IN-082",
  "hypothesis": "Track which curated candidates are never chosen and retire them",
  "rationale": "Cheap corpus quality signal.",
  "evidence_class": "hypothesis",
  "rank": null,
  "falsifier": "Non-selection reflects ordering, not quality.",
  "theme": "learning"
}
IN-083record 83
{
  "id": "IN-083",
  "hypothesis": "A/B the curated top-10 per category against random draws from the eligible set",
  "rationale": "Directly tests whether curation adds value.",
  "evidence_class": "hypothesis",
  "rank": null,
  "falsifier": "Client volume is too low for statistical power.",
  "theme": "learning"
}
IN-084record 84
{
  "id": "IN-084",
  "hypothesis": "Measure time-to-first-selection as the primary UX metric",
  "rationale": "Operationalises 'a client can choose without knowing component names'.",
  "evidence_class": "hypothesis",
  "rank": null,
  "falsifier": "Fast selection correlates with disengagement rather than confidence.",
  "theme": "client_ux"
}
IN-085record 85
{
  "id": "IN-085",
  "hypothesis": "Let clients reject a whole visual style in one action to prune the space fast",
  "rationale": "Negative preference is faster to elicit than positive.",
  "evidence_class": "hypothesis",
  "rank": null,
  "falsifier": "Style rejection removes components clients would have liked individually.",
  "theme": "client_ux"
}
IN-086record 86
{
  "id": "IN-086",
  "hypothesis": "Keep a human greenlight gate for anything client-facing",
  "rationale": "KEEPERS.md is the only local precedent for admission and it is human-greenlit.",
  "evidence_class": "observed",
  "rank": null,
  "falsifier": "Human review cannot keep pace and becomes the bottleneck.",
  "theme": "curation"
}
IN-087record 87
{
  "id": "IN-087",
  "hypothesis": "Score components on completeness and flag partial ones",
  "rationale": "ranked.json already carries completeness and flags fields.",
  "evidence_class": "observed",
  "rank": null,
  "falsifier": "Those scores were computed for 832 entries and do not generalise.",
  "theme": "ranking"
}
IN-088record 88
{
  "id": "IN-088",
  "hypothesis": "Deprioritise components whose previews are under 2KB unless they are known primitives",
  "rationale": "Under-2KB is 6.1% of a 196-preview sample and correlates with small primitives rather than corruption.",
  "evidence_class": "observed",
  "rank": null,
  "falsifier": "Small previews are legitimate and deprioritising them loses good primitives.",
  "theme": "ranking"
}
IN-089record 89
{
  "id": "IN-089",
  "hypothesis": "Treat the 121 bundle-less components as index-only records",
  "rationale": "verify-harvest.mjs reconciles 7,949 = 7,828 with a bundle + 121 without, and PASSes.",
  "evidence_class": "observed",
  "rank": null,
  "falsifier": "They are recoverable and should simply be re-harvested.",
  "theme": "curation"
}
IN-090record 90
{
  "id": "IN-090",
  "hypothesis": "Never present a component whose preview is missing",
  "rationale": "271 of 7,949 lack preview.webp; a card with no image is worse than no card.",
  "evidence_class": "observed",
  "rank": null,
  "falsifier": "A generated placeholder render is adequate.",
  "theme": "client_ux"
}
IN-091record 91
{
  "id": "IN-091",
  "hypothesis": "Build the index incrementally so a partial refresh never invalidates the whole",
  "rationale": "A monolithic regenerate is what makes board.html unmaintainable.",
  "evidence_class": "hypothesis",
  "rank": null,
  "falsifier": "Incremental complexity is not worth it at this corpus size.",
  "theme": "refresh"
}
IN-092record 92
{
  "id": "IN-092",
  "hypothesis": "Store previews content-addressed to make dedupe and cache invalidation trivial",
  "rationale": "Hashing previews already revealed 65 exact-duplicate groups.",
  "evidence_class": "observed",
  "rank": null,
  "falsifier": "Content addressing complicates the simple author__slug path convention.",
  "theme": "dedupe"
}
IN-093record 93
{
  "id": "IN-093",
  "hypothesis": "Keep the 75-tag vocabulary as a retrieval index but not as the client-facing taxonomy",
  "rationale": "It is dense enough for search (mean 2.09 tags) but too flat and collision-prone to present.",
  "evidence_class": "inferred",
  "rank": null,
  "falsifier": "Clients navigate the 75 tags comfortably in testing.",
  "theme": "taxonomy"
}
IN-094record 94
{
  "id": "IN-094",
  "hypothesis": "Map the 75 tags onto a two-level hierarchy for browsing",
  "rationale": "Ant Design's General/Layout/Navigation/Data Entry/Data Display/Feedback is a proven top level.",
  "evidence_class": "hypothesis",
  "rank": null,
  "falsifier": "Any two-level mapping puts too many components under one node to be navigable.",
  "theme": "taxonomy"
}
IN-095record 95
{
  "id": "IN-095",
  "hypothesis": "Distinguish structural role from visual treatment as separate axes",
  "rationale": "headlessui's behaviour/appearance split is the canonical precedent, and conflating them is why 'hero' and 'background' both appear as tags.",
  "evidence_class": "inferred",
  "rank": null,
  "falsifier": "Clients think in conflated terms and separating the axes confuses them.",
  "theme": "taxonomy"
}
IN-096record 96
{
  "id": "IN-096",
  "hypothesis": "Add an explicit archetype-role axis absent from both stores",
  "rationale": "Neither store knows whether a table is a case list or an invoice ledger.",
  "evidence_class": "hypothesis",
  "rank": null,
  "falsifier": "Archetype role is a composition concern belonging to P12, not the component layer.",
  "theme": "taxonomy"
}
IN-097record 97
{
  "id": "IN-097",
  "hypothesis": "Reclassify a sample directly against the 17 industries to test recoverability",
  "rationale": "The existing industry axis is near-uniform and misses 5 of 17 entirely.",
  "evidence_class": "inferred",
  "rank": null,
  "falsifier": "Reclassification produces the same uniform distribution, proving components are genuinely industry-agnostic.",
  "theme": "taxonomy"
}
IN-098record 98
{
  "id": "IN-098",
  "hypothesis": "Accept that most UI components ARE industry-agnostic and drop industry from the component layer",
  "rationale": "89.6% claim saas and 171 claim all 10 industries — the data may be telling the truth.",
  "evidence_class": "inferred",
  "rank": null,
  "falsifier": "Industry-specific component demand shows up clearly once archetype-level composition is modelled.",
  "theme": "taxonomy"
}
IN-099record 99
{
  "id": "IN-099",
  "hypothesis": "Carry framework/stack as a hard filter",
  "rationale": "237 distinct npm dependencies were measured; three (lucide-react, class-variance-authority, framer-motion) dominate.",
  "evidence_class": "observed",
  "rank": null,
  "falsifier": "Stack can be normalised at generation time, making it a soft preference.",
  "theme": "join"
}
IN-100record 100
{
  "id": "IN-100",
  "hypothesis": "Flag heavyweight dependencies (three, gsap, @react-three/fiber) at index time",
  "rationale": "three appears in 85 components, gsap 57, @react-three/fiber 29.",
  "evidence_class": "observed",
  "rank": null,
  "falsifier": "Bundle-size impact is acceptable and the flag causes needless exclusion.",
  "theme": "join"
}
IN-101record 101
{
  "id": "IN-101",
  "hypothesis": "Use dependency overlap as a secondary near-duplicate signal",
  "rationale": "Components with identical dependency sets and similar names are strong duplicate candidates.",
  "evidence_class": "hypothesis",
  "rank": null,
  "falsifier": "Dependency sets are too uniform (lucide-react in 1,272) to discriminate.",
  "theme": "dedupe"
}
IN-102record 102
{
  "id": "IN-102",
  "hypothesis": "Detect cross-framework ports as a distinct duplicate class",
  "rationale": "shadcn-vue and shadcn-svelte are literal ports of shadcn/ui.",
  "evidence_class": "observed",
  "rank": null,
  "falsifier": "Our corpus is React-only, making the class empty.",
  "theme": "dedupe"
}
IN-103record 103
{
  "id": "IN-103",
  "hypothesis": "Publish the corpus join as a reproducible script, not a one-off report",
  "rationale": "Counts drift; every number should be re-derivable on demand.",
  "evidence_class": "inferred",
  "rank": null,
  "falsifier": "The corpus is static enough that re-derivation is wasted effort.",
  "theme": "join"
}
IN-104record 104
{
  "id": "IN-104",
  "hypothesis": "Fail the build if index counts diverge from a fresh count of the stores",
  "rationale": "verify-harvest.mjs already demonstrates the pattern and exits 0 on PASS.",
  "evidence_class": "observed",
  "rank": null,
  "falsifier": "Strict count gates break on legitimate incremental additions.",
  "theme": "join"
}
IN-105record 105
{
  "id": "IN-105",
  "hypothesis": "Keep a written record of which numbers are sampled vs corpus-wide",
  "rationale": "The prior audit's key theming rates are SAMPLED n=25 and n=60 and explicitly directional.",
  "evidence_class": "observed",
  "rank": null,
  "falsifier": "Everything gets measured corpus-wide, making the distinction moot.",
  "theme": "provenance"
}
IN-106record 106
{
  "id": "IN-106",
  "hypothesis": "Do not quote registry item counts as component counts",
  "rationale": "Magic UI's registry serves 247 items against a '150+ components' homepage claim; Aceternity's homepage says 200+ while its own AI page says 111 free + 23 pro.",
  "evidence_class": "observed",
  "rank": null,
  "falsifier": "Vendors align the two numbers, removing the trap.",
  "theme": "provenance"
}
IN-107record 107
{
  "id": "IN-107",
  "hypothesis": "Prefer r.jina.ai or an equivalent reader proxy for 403-walled research surfaces",
  "rationale": "component.gallery, mobbin.com and land-book.com all 403 direct fetches; the proxy retrieved Component Gallery successfully.",
  "evidence_class": "observed",
  "rank": null,
  "falsifier": "Proxy use violates the target sites' terms as surely as direct scraping.",
  "theme": "refresh"
}
IN-108record 108
{
  "id": "IN-108",
  "hypothesis": "Design the layer so a legal block on 21st material degrades it rather than killing it",
  "rationale": "Terms prohibit the harvest mechanism and rights coverage is 0.017%.",
  "evidence_class": "inferred",
  "rank": null,
  "falsifier": "Counsel clears the corpus and the contingency is unnecessary.",
  "theme": "provenance"
}