Skip to content

Skill catalog taxonomy

The controlled taxonomy classifies professional knowledge for catalog discovery, diversity planning, and Admin filtering. It does not grant runtime, network, connector, secret, filesystem, or desktop permissions.

The separate arinova-skill-catalog content repository owns the canonical skill-catalog/taxonomy.yaml and its v2 JSON schema. A server checkout intentionally contains neither file. A signed release bundle carries the full taxonomy alongside the catalog and candidate-inventory projections; server startup verifies and validates that bundle before any catalog API becomes available.

Server code owns the typed runtime contract, semantic validation, APIs, and a committed TypeScript fallback for builds and first paint. It must not recover a missing or rejected bundle from a compiled taxonomy or embedded catalog.

Taxonomy v2 has two levels: categories are public Skill Hub navigation, while groups are the Admin filtering and diversity-policy axis. Each category names exactly one group, and every group enumerates its categories. Bundle validation requires those two projections to be self-consistent.

Each approved entry has exactly one primary category and up to two secondary categories. Its effective category list contains one to three sorted values, and its tag list contains two to twelve sorted values. Distribution reports count an entry once through its primary category’s group. Secondary categories improve discovery only and never increase the approved-entry total.

Package classification is the majority of its entries’ primary categories; ties choose the alphabetically first category. A reviewed package-level override is allowed when the reviewer records a deliberate exception. Group is then derived from the resulting package category using the active bundle taxonomy.

Immutable v1 database snapshots remain unchanged. Taxonomy is not part of the catalog import identity or toolchain scheme hash, so adding an unused category does not rewrite imports or require a database migration.

The web client starts with apps/web/src/app/admin/skill-packages/catalog-taxonomy.generated.ts as an SSR and first-paint fallback, then merges taxonomy returned by the runtime API. A category introduced by a content-only release therefore becomes selectable without a server or web rebuild. Missing locale keys use the existing humanized-slug display until translations arrive.

The committed fallback is allowed to lag canonical content. The required gate checks that it remains structurally valid, semantically self-consistent, and in canonical generated form; it does not compare it byte-for-byte with the content taxonomy. Refresh it explicitly with the TS-only code generator when a server maintenance change needs a newer initial fallback.

Run the same command in either checkout shape:

Terminal window
pnpm run check:skill-catalog

In a plain server checkout, the command runs fallback validation and all server-owned Node contract tests without the canonical taxonomy. In a content overlay, the presence of both canonical files additionally enables taxonomy, catalog, projection, and content-only validation. A partial overlay containing only one of the two canonical files fails closed.

Content releases that depend on a new server contract must wait for the exact server main commit before updating the content repository’s server-repo.lock.json. Content-only taxonomy additions that use an existing contract do not require a server commit or fallback refresh.

The public package catalog uses categories as its persistent navigation. Tags are contextual refinements: selecting a category reveals represented tags, and multiple selected tags use OR semantics. Category label keys are localized when present; unknown keys and tags are defensively humanized.

Favorites remains a dedicated, unfiltered package list. Its taxonomy badges are informational because there is no Favorites filter state or URL contract. The legacy /api/skills marketplace remains outside this taxonomy contract.

Build a7f47a5ca54ddcf7806cd48b81ce1b9827042766