Developer Docs Mist Domain
PHASE 12

Mist Domain

A Mist is a content-addressed, cryptographically signable, forkable, embeddable artifact share — what a gist becomes when you reimagine it through the full Muse philosophy. Every Mist is a Muse repo with domain="mist", giving it full branching, time-travel, signed commits, and MCP tooling for free.

Concepts

PropertyValue
IdentityContent-addressed — SHA-256 over content bytes, base-58 encoded, truncated to 12 chars
StorageEvery Mist is a Muse repo with domain="mist"
VersioningFull muse log, muse diff, muse checkout on the backing repo
AuthorshipOptional Ed25519 (--sign) or GPG signature proving human/agent identity
Visibilitypublic (default) or secret
ForkabilityAny public Mist is forkable; fork depth capped at 5
EmbeddabilityStandalone iframe card served at /{owner}/mists/{id}/embed

URL schema

# Web UI
/{owner}/mists/{mist_id}           # detail page
/{owner}/mists/{mist_id}/embed     # iframe-safe embed card
/{owner}/mists/{mist_id}/raw       # raw artifact download
/{owner}/mists                     # owner's public mist list
/mists/explore                     # global discovery feed

# REST API
POST   /api/mists                  # create
GET    /api/mists/{mist_id}        # read
PATCH  /api/mists/{mist_id}        # update (owner only)
DELETE /api/mists/{mist_id}        # delete (owner only)
POST   /api/mists/{mist_id}/fork   # fork
GET    /api/mists/{mist_id}/forks  # list direct forks
GET    /api/mists/explore          # global public feed
GET    /api/{owner}/mists          # owner's public list

# MCP Resource
musehub://mists/{owner}/{mist_id}  # single mist resource
musehub://mists/{owner}            # owner's mist list resource

Artifact types

The server auto-detects the artifact type from the filename and content bytes. Callers may omit artifact_type in POST /api/mists — the server fills it in. Symbol anchors are extracted automatically for Python, JavaScript, and TypeScript code artifacts.

TypeDetection heuristicLanguage detection
codeCommon code extensions (.py, .js, .ts, .rs, .go, …)Yes — from extension
midi.mid / .midi extension or MIDI magic bytes (4D 54 68 64)No
schema.json + JSON content with $schema or type/properties keysNo
abi.abi, .abi.json, or JSON array of ABI objectsNo
dataset.csv, .tsv, .ndjson, .jsonlNo
config.yaml, .yml, .toml, .env, .ini, .confNo
text.md, .txt, .rst, .adoc or unrecognised textNo
unknownBinary content with no recognised signatureNo

CLI reference

The muse mist subcommand is the primary interface for humans and agents.

Create

muse mist create <file> [options]

  --title TEXT          Human-readable title
  --description TEXT    Longer description (shown on the detail page)
  --visibility          public (default) | secret
  --tags TAG,...        Comma-separated tags (max 10, 64 chars each)
  --agent-id TEXT       Agent identifier for provenance
  --model-id TEXT       Model ID for agent provenance
  --sign                Sign with the local Ed25519 identity key
  --push                Push to the configured hub after creation
  --json                Machine-readable output
muse mist create validate_handle.py \
  --title "Handle validation primitive" \
  --tags "security,auth" \
  --sign --push --json
# → {"mist_id": "aB3xKq9dPwNm", "url": "http://staging.musehub.ai/gabriel/mists/aB3xKq9dPwNm", ...}

Other commands

CommandDescription
muse mist list [--owner HANDLE] [--artifact-type TYPE] [--json]List mists
muse mist read <mist_id> [--json]Fetch a single mist
muse mist fork <mist_id> [--push] [--json]Fork a public mist
muse mist update <mist_id> [--title ...] [--content FILE] [--json]Partial update (owner only)
muse mist delete <mist_id> [--json]Hard delete (owner only)

REST API

All write endpoints require Authorization: MSign ... (see Cryptographic Identity).

POST /api/mists

Create a new mist. The mist_id is computed by the server.

{
  "filename":    "validate_handle.py",
  "content":     "def _validate_handle(h): ...",
  "visibility":  "public",
  "title":       "Handle validation primitive",
  "description": "Security gate used by auth middleware.",
  "tags":        ["security", "auth"],
  "agentId":     "cccode-v3",
  "modelId":     "claude-sonnet-4-6"
}

Returns 201 with the full mist object. Returns 409 if the same content already exists under your handle (idempotent — the existing mist_id is stable).

GET /api/mists/explore

Global public discovery feed. Supports artifact_type and cursor pagination.

GET /api/mists/explore?artifact_type=code&limit=20&cursor=<ISO-8601>

{
  "mists":      [...],
  "total":      1234,
  "nextCursor": "2026-04-14T09:30:00+00:00"
}

PATCH /api/mists/{mist_id}

Partial update. Only provided fields change. Updating content increments version and records a new commit on the backing repo. Returns 404 if not found or caller is not the owner.

DELETE /api/mists/{mist_id}

Hard delete. Returns 204 on success, 404 if not found or not the owner.

POST /api/mists/{mist_id}/fork

Create a fork. Returns 422 if the parent is already at fork depth 5.

MCP tools & resources

ToolAuthDescription
muse_mist_createwriteCreate a new Mist
muse_mist_updatewritePatch title/description/visibility/tags/content
muse_mist_forkwriteFork a public Mist
muse_mist_deletewriteHard-delete a Mist (owner only)
muse_mist_readreadFetch full Mist including content
muse_mist_rawreadFetch raw artifact content as a plain string
muse_mist_listreadList mists (owner or global explore)
muse_mist_list_forksreadList direct forks of a Mist
muse_mist_embedreadGet iframe, script, and badge embed codes

Resources:

musehub://mists/{owner}/{mist_id}   — full mist response (content included)
musehub://mists/{owner}             — owner's public mist list (no content)

Secret mists are returned for the authenticated owner; unauthenticated or non-owner reads return a forbidden error.

Agent publishing workflow

An agent session produces an artifact it wants to share permanently:

# Via MCP tool (no shell required):
result = muse_mist_create(
    filename="validate_handle.py",
    content=content,
    title="Handle validation security primitive",
    agent_id="cccode-v3",
    model_id="claude-sonnet-4-6",
    visibility="public",
    tags=["security", "auth"],
)
# → {"mistId": "aB3xKq9dPwNm", "url": "http://staging.musehub.ai/gabriel/mists/aB3xKq9dPwNm", ...}
# Or via CLI (signed with MUSE_AGENT_KEY env var injected by Agentception):
muse mist create /tmp/validate_handle.py \
  --title "Handle validation security primitive" \
  --agent-id cccode-v3 \
  --model-id claude-sonnet-4-6 \
  --sign --push --json

The resulting URL is a permanent, verifiable artifact. The agent_id and model_id fields prove provenance. In the ERC-8004 on-chain identity world: agent contract address → MSign key → Mist signature → content hash.

Forking & sub-domain delegation

Every Mist is a Muse repo (domain="mist"). Forking creates a new repo whose first commit copies the parent's content. The fork graph is visible on the detail page sidebar (Forked From + Forks panels).

Depth limit: Fork chains are capped at depth 5. The server returns 422 when a depth-5 Mist is forked.

Sub-domain delegation (future): Because each Mist backs a full Muse repo, any future domain plugin (genomics, spatial, MIDI v2) can be applied to the backing repo, gaining symbol-level diffs, blast radius, and AST versioning for free.

Embedding

iframe

<iframe
  src="http://staging.musehub.ai/{owner}/mists/{mist_id}/embed"
  width="600"
  height="400"
  frameborder="0"
  title="my_file.py">
</iframe>

Script tag

<script
  src="http://staging.musehub.ai/embed.js"
  data-mist="{owner}/{mist_id}">
</script>

The embed card shows the artifact type chip, filename, syntax-highlighted content, size/version metadata, and a "View on MuseHub" link. The embed endpoint increments embed_count on each render. Cross-origin framing is allowed (frame-ancestors *).

Content addressing

The mist_id is computed deterministically from the artifact bytes:

import hashlib, base58

def compute_mist_id(content: bytes) -> str:
    digest = hashlib.sha256(content).digest()
    return base58.b58encode(digest).decode()[:12]
PropertyDetail
DeterministicThe same file always produces the same mist_id
Collision-resistantSHA-256 with 12-char base-58 → ~7×10¹⁶ distinct IDs
Offline verifiableAny caller can recompute the ID and confirm integrity without contacting the server
Idempotent createsPOST /api/mists with the same content returns 409 — the existing Mist is not overwritten

Security model

ThreatMitigation
Path traversal via filename_validate_mist_filename() rejects .., /, \, null bytes, control chars, ANSI escapes
Content injection (XSS)Content stored verbatim; Jinja2 auto-escapes at render time
Oversized contentContentSizeLimitMiddleware returns 413 for bodies > 10 MiB
Unauthorised mutationPATCH/DELETE check mist.owner == caller.handle; return 404 on mismatch
Secret mist leakageSecret mists excluded from /explore and owner list; direct GET returns 403
Fork bombDepth cap enforced at service layer (_FORK_DEPTH_LIMIT = 5) and REST route (422)
Rate limitingMIST_CREATE_LIMIT = 20/min, MIST_FORK_LIMIT = 30/min per MSign handle
Tag injectionvalidate_tags() enforces count ≤ 10, length ≤ 64, no null bytes

Limits

ParameterLimit
Content size10 MiB (enforced by middleware)
Filename length255 characters
Title length500 characters
Description length10,000 characters
Tag count10
Tag length64 characters
Fork depth5
Create rate20 / minute per handle
Fork rate30 / minute per handle
Explore page size1–100 (default 20)