The Mycelium is a Site Descriptor. It represents a developer or organization and their published spores.

1. Overview

The domain entry point (cmn.json) is documented in 01-substrate.md. This document covers the full mycelium manifest that contains the complete site metadata.

Location: Defined by the type: "mycelium" endpoint in cmn.json (e.g., https://cmn.dev/cmn/mycelium/{hash}.json) Schema: https://cmn.dev/schemas/v1/mycelium.json (hostname non-authoritative — see 01-substrate §6) Size: ~1-10 KB

{
  "$schema": "https://cmn.dev/schemas/v1/mycelium.json",
  "capsule": {
    "uri": "cmn://cmn.dev/mycelium/b3.3yMR7vZQ9hL2xKJdFtN8wPcB6sY1mXgU4eH5pTa2",
    "core": {
      "domain": "cmn.dev",
      "key": "ed25519.5XmkQ9vZP8nL3xJdFtR7wNcA6sY2bKgU1eH9pXb4",
      "name": "cmn.dev",
      "synopsis": "",
      "updated_at_epoch_ms": 1769777183174,
      "spores": [
        {
          "id": "cmn-spec",
          "hash": "b3.3yMR7vZQ9hL2xKJdFtN8wPcB6sY1mXgU4eH5pTa2",
          "name": "CMN Protocol Specification",
          "synopsis": "Code Mycelial Network - A sovereign-first protocol for code distribution"
        },
        {
          "id": "cmn-tools",
          "hash": "b3.8cQnH4xPmZ2vLkJdRt7wNbA9sF3eYgU1hK6pXq5",
          "name": "CMN Tools",
          "synopsis": "Command-line and service tooling for the CMN protocol"
        }
      ]
    },
    "core_signature": "ed25519.3yMR7vZQ9hL2xKJdFtN8wPcB6sY1mXgU4eH5pTa23yMR7vZQ9hL2xKJdFtN8wPcB6sY1mXgU4eH5pTa2"
  },
  "capsule_signature": "ed25519.3yMR7vZQ9hL2xKJdFtN8wPcB6sY1mXgU4eH5pTa23yMR7vZQ9hL2xKJdFtN8wPcB6sY1mXgU4eH5pTa2"
}

Note: Content endpoints (spore, archive, taste) are defined in the cmn.json endpoint array, not in the mycelium manifest. See 01-substrate §1.2.1.

2. Field Definitions

2.1 Mycelium Fields

FieldTypeDescription
$schemaStringhttps://cmn.dev/schemas/v1/mycelium.json (hostname non-authoritative — see 01-substrate §6).
capsuleObjectThe capsule container.
capsule.uriStringMycelium URI: cmn://{domain}/mycelium/{hash}
capsule.coreObjectThe mycelium content.
capsule.core.nameStringDeveloper or organization name.
capsule.core.domainStringThe domain (e.g., cmn.dev).
capsule.core.keyStringEd25519 public key of the content author. Enables offline signature verification once the key-domain binding is already trusted, without fetching cmn.json.
capsule.core.synopsisStringBrief description of the developer/org.
capsule.core.bioString?Multiline markdown with full details about this domain.
capsule.core.nutrientsArray?Nutrient methods, ordered by preference (first = preferred). Omit if none. See §2.3.
capsule.core.updated_at_epoch_msNumberUnix timestamp in milliseconds. Used for version ordering.
capsule.core.sporesArray?List of published spores. Omit if the domain has not published any spores yet.
capsule.core.tastesArray?Published taste reports ({hash, target_uri}) for mirror discovery and re-submission. Omit if none.
capsule.core_signatureStringEd25519 signature of the core object (ed25519.<base58>, JCS canonical).
capsule_signatureStringEd25519 signature of the capsule object (ed25519.<base58>, JCS canonical).

2.2 Spore Entry

FieldTypeDescription
idStringStable identifier for the spore (e.g., cmn-tools). Used for deduplication across releases. Required.
hashStringBLAKE3 hash with prefix (e.g., b3.3yMR7vZQ9hL2x...). Required.
nameStringHuman-readable name of the spore. Required.
synopsisString?Optional short description.

Note: Spore entries use hash instead of full uri to keep the file size small. Clients can construct the full URI as cmn://{domain}/{hash}. The id field matches the id in spore.core.json and ensures that re-releasing a spore replaces the previous entry rather than appending a duplicate.

2.3 Nutrients

Optional array of nutrient methods, ordered by preference (first entry = preferred). Each entry is a typed method object with type as the only required field. All entries MAY include label for UI display.

{
  "nutrients": [
    {"type": "lightning", "address": "user@example.com"},
    {"type": "lightning", "offer": "lno1qgsq..."},
    {"type": "onchain_btc", "address": "bc1q..."},
    {"type": "evm", "chain_id": 8453, "token": "native", "recipient": "0x1a2b..."},
    {"type": "webpage", "url": "https://github.com/sponsors/alice", "label": "GitHub Sponsors"}
  ]
}

Nutrient types align with strain-payment-method-* conventions. Each type below corresponds to a strain (e.g., lightningstrain-payment-method-lightning), and field names match the strain’s payment request fields where applicable.

The base mycelium.json schema only requires type for nutrient entries. Type-specific required fields below are convention-level requirements enforced by corresponding strain-payment-method-* conventions and tooling.

Direct payment types — static addresses for voluntary donations:

TypeRequired FieldsOptional FieldsDescription
lightningaddress or offerLightning address (user@domain, compatible with Nostr zaps) or BOLT12 offer (lno1...). One entry per form.
onchain_btcaddressBitcoin L1 address.
liquidaddressasset_idLiquid sidechain address.
evmchain_id, recipienttokenEthereum or L2 (Arbitrum, Base, Optimism, etc.). token: ERC-20 contract address or "native" (default).
solanarecipienttokenSolana address. token: SPL mint address or "native" (default).
moneroaddressMonero address.

Webpage type — any nutrient page, platform profile, or checkout:

TypeRequired FieldsDescription
webpageurlHuman-facing payment page (GitHub Sponsors, Open Collective, Polar.sh, etc.).

The type field is an open string — any value is valid. New payment networks require no protocol update.

Design notes:

3. Schema Validation

Schema: https://cmn.dev/schemas/v1/mycelium.json (see 01-substrate §6)

Validators SHOULD embed schemas for offline validation. No network fetch should be required.

4. Signing and Hashing

4.1 Core Signature

The core_signature signs the core object:

  1. Serialize core using JCS (RFC 8785)
  2. Sign the canonical bytes with Ed25519 private key
  3. Format as ed25519.<base58>

Purpose:

4.2 Content Hash Calculation

The hash in capsule.uri is calculated from core + core_signature:

  1. Construct hash input: {"core": <core>, "core_signature": "<signature>"}
  2. Serialize hash input using JCS
  3. Hash with BLAKE3 → b3.<base58>
  4. The mycelium URI is cmn://{domain}/mycelium/{hash} (the hash is also stored in cmn.json as an element of the hashes array on the type: "mycelium" endpoint for change detection)

Key Properties:

4.3 Capsule Signature

The capsule_signature signs the entire capsule object (including uri):

  1. Build capsule: {"uri": <uri>, "core": <core>, "core_signature": "<signature>"}
  2. Serialize using JCS
  3. Sign with Ed25519 private key → ed25519.<base58>

Purpose:

4.4 Canonical JSON (JCS)

All signatures and hashes use JCS (see 01-substrate §1.3).

5. Publishing Workflow

Publishing implementations MUST:

  1. Build the core object
  2. Sign core → core_signature
  3. Compute hash from core + core_signature
  4. Construct uri with hash: cmn://{domain}/mycelium/{hash}
  5. Build capsule with uri, core, core_signature
  6. Sign capsule → capsule_signature
  7. Save full mycelium to /cmn/mycelium/{hash}.json
  8. Generate cmn.json capsule entry with endpoints (including type: "mycelium" with hashes array)
  9. Sign cmn.json capsules array → capsule_signature
  10. Save to cmn.json

6. File Organization

site_root/
├── .well-known/
│   └── cmn.json                                          # Domain entry point (~150 bytes)
└── cmn/
    └── mycelium/
        └── b3.3yMR7vZQ9hL2x...pTa2.json                  # Current version

Benefits:

7. Content Resolution

7.1 Hash Lookup and Sharding

The mycelium endpoint in cmn.json carries a hashes array. Each hash points to a mycelium shard. Most domains use a single shard.

Shard rules:

7.2 Mycelium Resolution

When fetching the full mycelium content:

Find the type: "mycelium" endpoint in capsules[0].endpoints:

If endpoints are missing, return an error - there are no default fallback URLs.

7.3 Spore Resolution

When a client needs to fetch a specific spore:

Find the type: "spore" endpoint in capsules[0].endpoints:

Resolution flow: cmn.json → find type: "spore" endpoint → fetch spore.

If endpoints are missing, return an error. Synapse is only a fallback when the domain is unreachable, not a default endpoint.

Static Deployment: This design allows static file hosting without any server-side logic.

8. Pulse (Publishing Updates)

When mycelium is updated, publishing tools MUST regenerate both the capsule and full mycelium files.

Optional notification:

Publishing implementations MAY send a Pulse notification to one or more Synapse nodes (see 05-strain §5.2).

Synapse Validation:

  1. Schema Validation: Validate against embedded schema
  2. Signature Verification: Verify core_signature and capsule_signature against the domain’s public key
  3. Version Check: Compare updated_at_epoch_ms with cached version
    • new > cached → Accept (newer version)
    • new == cached, same hash → Ignore (duplicate)
    • new == cached, different hash → Reject (conflict — publisher MUST increment timestamp to correct)
    • new < cachedReject (older version)

Content Correction: If a publisher needs to fix a mistake (e.g., typo in synopsis, wrong spore entry), they MUST increment updated_at_epoch_ms before re-signing and re-publishing. This produces a new hash and a newer timestamp, which a Synapse node can accept as an ordinary update. The monotonic timestamp requirement ensures that corrections are unambiguous and prevents conflicting edits.

Replay and rollback analysis for these timestamp rules is covered in 08-security §4.

9. Example

Entry Point (cmn.json):

{
  "$schema": "https://cmn.dev/schemas/v1/cmn.json",
  "capsules": [
    {
      "uri": "cmn://cmn.dev",
      "key": "ed25519.5XmkQ9vZP8nL3xJdFtR7wNcA6sY2bKgU1eH9pXb4",
      "endpoints": [
        {"type": "mycelium", "url": "https://cmn.dev/cmn/mycelium/{hash}.json", "hashes": ["b3.3yMR7vZQ9hL2xKJdFtN8wPcB6sY1mXgU4eH5pTa2"]},
        {"type": "spore",    "url": "https://cmn.dev/cmn/spore/{hash}.json"},
        {"type": "archive",  "url": "https://cmn.dev/cmn/archive/{hash}.tar.zst", "format": "tar+zstd"},
        {"type": "taste",    "url": "https://cmn.dev/cmn/taste/{hash}.json"}
      ]
    }
  ],
  "capsule_signature": "ed25519.3yMR7vZQ9hL2xKJdFtN8wPcB6sY1mXgU4eH5pTa23yMR7vZQ9hL2xKJdFtN8wPcB6sY1mXgU4eH5pTa2"
}

Client resolution: Find the type: "mycelium" endpoint, iterate its hashes array, replace {hash} in the url template for each → fetch each mycelium shard.

Full (/cmn/mycelium/b3.3yMR7vZQ9hL2x...pTa2.json):

{
  "$schema": "https://cmn.dev/schemas/v1/mycelium.json",
  "capsule": {
    "uri": "cmn://cmn.dev/mycelium/b3.3yMR7vZQ9hL2xKJdFtN8wPcB6sY1mXgU4eH5pTa2",
    "core": {
      "domain": "cmn.dev",
      "key": "ed25519.5XmkQ9vZP8nL3xJdFtR7wNcA6sY2bKgU1eH9pXb4",
      "name": "cmn.dev",
      "synopsis": "",
      "updated_at_epoch_ms": 1769777183174,
      "spores": [
        {
          "id": "cmn-spec",
          "hash": "b3.3yMR7vZQ9hL2xKJdFtN8wPcB6sY1mXgU4eH5pTa2",
          "name": "CMN Protocol Specification",
          "synopsis": "Code Mycelial Network - A sovereign-first protocol for code distribution"
        },
        {
          "id": "cmn-tools",
          "hash": "b3.8cQnH4xPmZ2vLkJdRt7wNbA9sF3eYgU1hK6pXq5",
          "name": "CMN Tools",
          "synopsis": "Command-line and service tooling for the CMN protocol"
        }
      ]
    },
    "core_signature": "ed25519.3yMR7vZQ9hL2xKJdFtN8wPcB6sY1mXgU4eH5pTa23yMR7vZQ9hL2xKJdFtN8wPcB6sY1mXgU4eH5pTa2"
  },
  "capsule_signature": "ed25519.3yMR7vZQ9hL2xKJdFtN8wPcB6sY1mXgU4eH5pTa23yMR7vZQ9hL2xKJdFtN8wPcB6sY1mXgU4eH5pTa2"
}