02. Mycelium - Domain Manifest

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 capsules[].endpoints.mycelium in cmn.json (e.g., https://cmn.dev/cmn/mycelium/{hash}.json) Schema: https://cmn.dev/schemas/v1/mycelium.json Size: ~1-10 KB

{
  "$schema": "https://cmn.dev/schemas/v1/mycelium.json",
  "capsule": {
    "uri": "cmn://cmn.dev/mycelium/b3.3yMR7vZQ9hL2xKJdFtN8wPcB6sY1mXgU4eH5pTa2",
    "core": {
      "name": "cmn.dev",
      "domain": "cmn.dev",
      "key": "ed25519.5XmkQ9vZP8nL3xJdFtR7wNcA6sY2bKgU1eH9pXb4",
      "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 tools for CMN protocol (hypha, synapse, substrate)"
        }
      ]
    },
    "core_signature": "ed25519.3yMR7vZQ9hL2xKJdFtN8wPcB6sY1mXgU4eH5pTa23yMR7vZQ9hL2xKJdFtN8wPcB6sY1mXgU4eH5pTa2"
  },
  "capsule_signature": "ed25519.3yMR7vZQ9hL2xKJdFtN8wPcB6sY1mXgU4eH5pTa23yMR7vZQ9hL2xKJdFtN8wPcB6sY1mXgU4eH5pTa2"
}

Note: Content endpoints (spore, archive[], optional taste) are defined in cmn.json capsule entries, not in the mycelium manifest. See 01-substrate §1.2.1.

2. Field Definitions

2.1 Mycelium Fields

FieldTypeDescription
$schemaStringSchema URL: https://cmn.dev/schemas/v1/mycelium.json
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 via Synapse 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). See §2.3.
capsule.core.updated_at_epoch_msNumberUnix timestamp in milliseconds. Used for version ordering.
capsule.core.sporesArrayList of published spores.
capsule.core.tastesArray?Optional list of published taste reports ({hash, target_uri}) for mirror discovery and re-submission.
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 URL: https://cmn.dev/schemas/v1/mycelium.json

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 capsules[0].mycelium_hash 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 mycelium_hash and endpoints
  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

The mycelium hash is stored in cmn.json as capsules[0].mycelium_hash. Use this value from the domain entry point for change detection and content verification.

7.2 Mycelium Resolution

When fetching the full mycelium content:

Use capsules[0].endpoints.mycelium template from cmn.json:

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:

Use capsules[0].endpoints.spore template from cmn.json:

Resolution flow: cmn.json → use capsules[0].endpoints.spore → fetch spore.

If endpoints are missing, return an error. Synapse is only used as a backup when the domain is unreachable, not as 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 registered Synapse instances (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)
    • new < cachedReject (older version)

Protection Against:

9. Example

Entry Point (cmn.json):

{
  "$schema": "https://cmn.dev/schemas/v1/cmn.json",
  "capsules": [
    {
      "uri": "cmn://cmn.dev",
      "key": "ed25519.5XmkQ9vZP8nL3xJdFtR7wNcA6sY2bKgU1eH9pXb4",
      "mycelium_hash": "b3.3yMR7vZQ9hL2xKJdFtN8wPcB6sY1mXgU4eH5pTa2",
      "endpoints": {
        "mycelium": "https://cmn.dev/cmn/mycelium/{hash}.json",
        "spore": "https://cmn.dev/cmn/spore/{hash}.json",
        "archive": [
          {
            "format": "tar+zstd",
            "url": "https://cmn.dev/cmn/archive/{filename}",
            "delta_url": "https://cmn.dev/cmn/archive/delta/{hash}/{old_hash}.zdict"
          }
        ]
      }
    }
  ],
  "capsule_signature": "ed25519.3yMR7vZQ9hL2xKJdFtN8wPcB6sY1mXgU4eH5pTa23yMR7vZQ9hL2xKJdFtN8wPcB6sY1mXgU4eH5pTa2"
}

Client resolution: Take capsules[0].mycelium_hash, replace {hash} in capsules[0].endpoints.mycelium template → fetch full mycelium.

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

{
  "$schema": "https://cmn.dev/schemas/v1/mycelium.json",
  "capsule": {
    "uri": "cmn://cmn.dev/mycelium/b3.3yMR7vZQ9hL2xKJdFtN8wPcB6sY1mXgU4eH5pTa2",
    "core": {
      "name": "cmn.dev",
      "domain": "cmn.dev",
      "key": "ed25519.5XmkQ9vZP8nL3xJdFtR7wNcA6sY2bKgU1eH9pXb4",
      "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 tools for CMN protocol (hypha, synapse, substrate)"
        }
      ]
    },
    "core_signature": "ed25519.3yMR7vZQ9hL2xKJdFtN8wPcB6sY1mXgU4eH5pTa23yMR7vZQ9hL2xKJdFtN8wPcB6sY1mXgU4eH5pTa2"
  },
  "capsule_signature": "ed25519.3yMR7vZQ9hL2xKJdFtN8wPcB6sY1mXgU4eH5pTa23yMR7vZQ9hL2xKJdFtN8wPcB6sY1mXgU4eH5pTa2"
}