Replace artifact_type with domain on Mists
Replace artifact_type with domain on Mists
Background
Mists are quick one-off artifacts — the Muse equivalent of a GitHub Gist. They map naturally to Muse domains: a Python snippet is a code mist, a MIDI phrase is a midi mist, a future audio clip would be a stems mist.
The current artifact_type field predates this domain model and has accumulated conflicting classifications:
Current artifact_type |
What it actually is |
|---|---|
code |
code mist — correct |
midi |
midi mist — correct |
schema |
code mist, language=json |
json_schema |
code mist, language=json |
abi |
code mist, language=json |
config |
code mist, language=yaml |
dataset |
code mist, language=text |
text |
code mist |
prose |
hallucinated — never existed as a domain |
unknown |
code mist |
The language field already carries the specificity that the subtypes were trying to capture. artifact_type is a redundant and confusing layer.
Goal
Replace artifact_type with domain everywhere: DB column, API wire format, CLI flags, and UI. Valid domain values are code, midi, and stems. All text-based subtypes collapse to domain=code with language retaining the specificity (e.g. markdown, python, json, yaml).
Before:
{ "artifactType": "schema", "language": "" }
{ "artifactType": "prose", "language": "markdown" }
{ "artifactType": "code", "language": "python" }
After:
{ "domain": "code", "language": "json" }
{ "domain": "code", "language": "markdown" }
{ "domain": "code", "language": "python" }
Phases
Phase 1 — Database migration
Must be fully green before Phase 2 begins.
Add domain column to musehub_mists and backfill from artifact_type + language. Then drop artifact_type.
Backfill rules:
artifact_type |
→ domain |
language if empty |
|---|---|---|
code |
code |
(unchanged) |
prose |
code |
markdown |
text |
code |
text |
schema |
code |
json |
json_schema |
code |
json |
abi |
code |
json |
config |
code |
yaml |
dataset |
code |
text |
unknown |
code |
(unchanged) |
midi |
midi |
(unchanged) |
Deliverables:
0071_mist_domain.py— alembic migration (MD_01, MD_02, MD_03)upgrade(): adddomainNOT NULL with defaultcode, backfill from table, dropartifact_typedowngrade(): restoreartifact_typefromdomain, dropdomain
Tests (run against a real DB, no mocks — tests/test_migration_0071.py):
MD_01— all existingartifact_typevalues map to the correctdomainafter upgradeMD_02—languageis backfilled correctly forschema,abi,config,dataset,proseMD_03— downgrade restoresartifact_type; no rows lost
Phase 2 — Server models + API
Depends on Phase 1. Must be fully green before Phase 3 or Phase 4 begins.
Replace artifact_type with domain in the server-side models and all API endpoints.
Deliverables:
musehub/db/musehub_repo_models.py—MusehubMist.domain: strreplacesartifact_typemusehub/models/mists.py—MistResponse,MistListEntry,MistForkResponseusedomain;MistCreateRequestacceptsdomain, rejects unknown values with 422;MistUpdateRequestaccepts optionaldomainmusehub/services/musehub_mists.py— all references toartifact_typereplaced withdomainmusehub/services/musehub_proposals.py—_DOMAIN_WEIGHTSkeys use actual domain values; domain heat dict updatedmusehub/services/spectral_sigil.py—DOMAIN_COLORSkeyed oncode,midi,stems- Wire format:
domainin camelCase is stilldomain(no rename needed)
Tests (tests/test_mist_routes.py):
MD_04—POST /api/mistswithdomain=codereturns 201 withdomainin responseMD_05—POST /api/mistswithdomain=midireturns 201MD_06—POST /api/mistswith unknowndomainreturns 422MD_07—GET /api/mists/{id}returnsdomain, noartifactTypekeyMD_08—GET /api/{owner}/mistslist entries containdomain
Phase 3 — CLI
Depends on Phase 2. Must be fully green before Phase 5 begins.
Replace --type with --domain on muse hub mist create. Update all --json output keys.
Deliverables:
muse/cli/commands/hub/mists.py—--domainflag (values:code,midi,stems; defaultcode); remove--type- All
--jsonoutput:domainkey replacesartifactType/artifact_type
Tests (tests/test_hub_mist_cli.py):
MD_09—muse hub mist create --domain codesucceeds and--jsonoutput containsdomain: "code"MD_10—muse hub mist create --domain midisucceedsMD_11—--typeflag no longer exists (passing it raises an error)
Phase 4 — UI + templates
Depends on Phase 2. Must be fully green before Phase 5 begins.
Update all template and route logic that reads artifact_type / prism_lang mapping.
Deliverables:
musehub/api/routes/musehub/ui_mists.py—_prism_mapkeyed ondomain+language;_TYPE_COLORS→_DOMAIN_COLORS;display_artifact_type→display_domain;md_htmlbranch still driven bylanguage == "markdown"musehub/templates/musehub/pages/mist_detail.html— badge showsdomain+language(e.g.code · markdown,midi)musehub/templates/musehub/pages/mist_list.html,mist_explore.html,mist_embed.html— same badge updatemusehub/templates/musehub/fragments/mist_rows.html— same
Tests (visual — no test ID; verify manually on staging):
MD_12— markdown mist showscode · markdownbadge and renders as HTMLMD_13— Python mist showscode · pythonbadge and syntax-highlighted sourceMD_14— MIDI mist showsmidibadge and download placeholder
Phase 5 — Integration + cleanup
Depends on Phases 3 and 4.
End-to-end round-trip and removal of all remaining artifact_type references.
Deliverables:
muse content-grep "artifact_type"returns zero results across both reposmuse content-grep "artifactType"returns zero results (excluding this issue body)- Integration test: create mist via CLI → read via API → verify detail page renders correctly (MD_15)
Tests:
MD_15— full round-trip:muse hub mist create --domain code --language markdown→GET /api/mists/{id}returnsdomain=code, language=markdown→ detail page renders HTML
Acceptance Criteria
- No
artifact_typeorartifactTypeanywhere in code, tests, templates, or docs (except this issue body and migration downgrade path) - All existing mists have
domainset correctly after migration domainis one ofcode,midi,stems— no other values acceptedlanguagecontinues to drive syntax highlighting and markdown rendering- The "prose" badge is gone forever
Out of Scope
- Adding
stemsdomain rendering (MIDI is the only non-code domain with active rendering today) - API versioning / backwards compatibility for external callers
- Mist search or filtering by
domain(follow-on feature)