feat(ms-ai-architect): C3.3 — course_products (live-enumerert) + makeCourseClassifier (TDD) [skip-docs]
Produkt-slug->kategori-mapping for kurs-deteksjon (C3.3 av GODKJENT C3-spec).
- lib/taxonomy.mjs: makeCourseClassifier(tax) — speiler makeClassifier; forste
in-domain produkt vinner; skill AVLEDES fra category_skill (lagres ALDRI i
course_products -> kan ikke divergere); ukjent/tom/non-array -> null.
- data/domain-taxonomy.json: ny topp-niva course_products (slug->category) +
provenance. 15 in-domain live slugs.
- test-taxonomy.test.mjs (+6): atferd (in-domain->{skill,category}, first-wins,
out-of-domain/tom/non-array->null, manglende map) + REELL data-invariant
(hver slug-kategori resolver til skill, derivasjon matcher) + azure-openai-live.
ENUMERERING (gotcha #2, live mot /api/v1/modules?products=<slug> server-side):
- DOD (0 treff): azure-ai-foundry, ai-services, azure-ai-services, foundry ->
Foundry/AI-services-kurs dukker opp under 'azure-openai'.
- Slug-feller bekreftet live: 'fabric' (ikke microsoft-fabric), 'entra' (ikke
microsoft-entra-id), 'azure-cosmos-db' (ikke cosmos-db), 'azure-cognitive-search'
(ikke azure-ai-search).
- 'azure-kubernetes-service' live men EKSKLUDERT (ingen AI-kategori -> stoy).
- Inkluderte (15): azure-openai, azure-machine-learning, azure-cognitive-search,
azure-cosmos-db, fabric, azure-databricks, microsoft-copilot-studio,
power-automate, power-apps, power-platform, ai-builder, microsoft-365-copilot,
microsoft-purview, entra, defender-for-cloud.
Avvik fra spec 4.4-eksempel: course_products lagrer slug->category (ikke
slug->{skill,category}); skill avledes — anti-divergens, encapsulated av
makeCourseClassifier (downstream-kontrakt {skill,category} uendret).
Gate 7 C3.3 mott: test gronn, eval --json IDENTISK (refTall/K-counts uendret).
kb-update 263->269, validate PASSED (239/0), null regresjon.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>