Skip to content

feat(blueprints): tag-driven category with regex fallback + cleanup sweep#3238

Merged
drewstone merged 1 commit into
developfrom
chore/cloud-cleanup-sweep
May 25, 2026
Merged

feat(blueprints): tag-driven category with regex fallback + cleanup sweep#3238
drewstone merged 1 commit into
developfrom
chore/cloud-cleanup-sweep

Conversation

@drewstone
Copy link
Copy Markdown
Contributor

Why

The catalog's category chip was derived from a 5-bucket regex on the blueprint's name + description — hallucinated taxonomy, drifted easily, and gave deployers no path to declare what category their blueprint belonged to.

This change adds blueprintUi.tags?: readonly string[] to the on-chain BlueprintUiContract, makes the catalog read it as the authoritative source, and demotes the regex to a last-resort fallback.

Resolution priority

  1. blueprintUi.tags[0] — publisher-declared, on-chain, authoritative. Multi-tag blueprints surface the first as the primary chip; search + filter consider every declared tag.
  2. blueprint.category — chain-derived legacy field, present on older metadata. Title-cased before display.
  3. Keyword inference — 5-bucket regex on name + description. Narrow on purpose: misclassifying into the wrong bucket is worse than dropping into "Other" and asking the publisher to declare tags.

Tag normalization

normalizeTag title-cases so chips render uniformly across publisher casing variants (inference / Inference / INFERENCE all render as Inference), but preserves all-caps acronyms (TEE, LLM, ZK, MEV) which are conventional in the space.

Schema

parseTags in shared-ui authoring accepts a string array verbatim, drops non-strings / empty / duplicates, caps at MAX_TAG_COUNT (8) and MAX_TAG_LENGTH (40). Tested in authoring.spec.ts — 6 new tests covering absent → undefined, simple array, dedup + drop-invalid, count cap, length cap, all-invalid → undefined.

Search includes every declared tag

A search for "TEE" now matches a blueprint tagged ["Inference", "TEE"] even though its primary chip says Inference. The haystack expanded from [name, description, author, category, primaryCategory, id] to [name, description, author, category, ...allTags, id].

Cleanup also dropped a dead import in BlueprintAppLandingPage

BlueprintAppFrameHost was unused after the iframe-first layout PR moved iframe rendering into IframeBlueprintLayout. Removed in this sweep.

Test plan

  • yarn nx build/typecheck tangle-cloud — clean
  • yarn nx test tangle-shared-ui --testPathPattern=authoring.spec — 31/31 passing (was 25, added 6)
  • yarn nx test tangle-cloud — 162/162 passing
  • yarn nx lint tangle-cloud — 0 errors (2 pre-existing warnings)
  • After merge: publishers can declare blueprintUi: { tags: ["Inference", "TEE"] } in their on-chain metadata; the catalog renders the first as the chip; search/filter matches all of them.

Migration

Existing blueprints continue to work via the legacy fallbacks. No publisher action required; tags are opt-in.

The catalog's category chip was derived from a 5-bucket regex on the
blueprint's name + description — hallucinated taxonomy, drifted easily,
and gave deployers no path to declare what category their blueprint
belonged to.

This change adds `blueprintUi.tags?: readonly string[]` to the
on-chain BlueprintUiContract, makes the catalog read it as the
authoritative source, and demotes the regex to a last-resort fallback.

## Resolution priority

1. `blueprintUi.tags[0]` — publisher-declared, on-chain, authoritative.
   Multi-tag blueprints surface the first as the primary chip; search +
   filter consider every declared tag.
2. `blueprint.category` — chain-derived legacy field, present on older
   metadata. Title-cased before display.
3. Keyword inference — 5-bucket regex on name + description. Narrow on
   purpose: misclassifying into the wrong bucket is worse than dropping
   into "Other" and letting publishers fix it via tags.

## Tag normalization

`normalizeTag` title-cases so chips render uniformly across publisher
casing variants ("inference" / "Inference" / "INFERENCE" all render as
"Inference"), but preserves all-caps acronyms (TEE, LLM, ZK, MEV) that
are conventional in the space.

## Schema

`parseTags` (in shared-ui authoring) accepts a string array verbatim,
drops non-strings / empty / duplicates, caps at MAX_TAG_COUNT (8) and
MAX_TAG_LENGTH (40). Tested in `authoring.spec.ts` — 6 new tests:
absent → undefined, simple array, dedup + drop-invalid, count cap,
length cap, all-invalid → undefined.

## Search includes every declared tag

A search for "TEE" now matches a blueprint tagged ["Inference", "TEE"]
even though its primary chip says Inference. The haystack expanded
from `[name, description, author, category, primaryCategory, id]` to
`[name, description, author, category, ...allTags, id]`.

## Verification

- `yarn nx build/typecheck tangle-cloud` — clean
- `yarn nx test tangle-shared-ui --testPathPattern=authoring.spec` —
  31/31 passing (was 25, added 6)
- `yarn nx test tangle-cloud` — 162/162 passing
@drewstone drewstone requested a review from AtelyPham as a code owner May 25, 2026 13:10
@drewstone drewstone merged commit f862ff0 into develop May 25, 2026
8 checks passed
@drewstone drewstone deleted the chore/cloud-cleanup-sweep branch May 25, 2026 13:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant