01. Substrate - Discovery & Identity

The Code Mycelial Network (CMN) is a domain-sovereign, distributed network for code sharing and evolution. Each domain is a sovereign node with full control over its content, identity, and distribution.

1. Core Principles

1.1 Domain Sovereignty

Every domain is an independent, self-governing node:

FQDN Sovereignty:

1.2 Trust Anchor: Domain Identity

Domain ownership is verified through the domain entry point:

1.2.1 Domain Entry Point (cmn.json)

Every CMN domain publishes a cmn.json file at the domain root. This lightweight entry point (~200 bytes) serves two purposes:

  1. Identity Verification: Provides key — the domain’s Ed25519 public key, authenticated by the transport layer (e.g., HTTPS with TLS certificate)
  2. Efficient Change Detection: Contains a hash reference to the full mycelium manifest

Location: https://{domain}/.well-known/cmn.json

CMN follows the .well-known URI standard (RFC 8615), which defines a path prefix for “well-known locations” in URI space. This is the same standard used by:

Using .well-known makes CMN discoverable via standard Web infrastructure, compatible with existing HTTP servers, CDNs, and caching layers without special configuration.

Schema: https://cmn.dev/schemas/v1/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"
}

Field Definitions:

FieldTypeDescription
$schemaStringSchema URL: https://cmn.dev/schemas/v1/cmn.json
capsulesArrayArray of capsule entries. First entry (capsules[0]) is the domain’s own mycelium; additional entries are replicated mycelia from other domains.
capsules[].uriStringDomain URI of the capsule origin: cmn://{origin_domain}. The first entry (capsules[0]) is always this host domain.
capsules[].keyStringEd25519 public key of the entry’s origin domain in {algorithm}.{base58} format.
capsules[].previous_keysArray?Optional. Retired public keys for verifying historical content (see §1.2.3).
capsules[].mycelium_hashStringContent hash of the mycelium manifest for this entry.
capsules[].endpointsObjectEndpoint definitions: mycelium, spore, archive[], and optional taste.
capsule_signatureStringEd25519 signature of the capsules array, verified with capsules[0].key (format: ed25519.<base58>, JCS canonical).

The key is inside each capsule entry, so the capsule_signature covers the key binding — all entries, their public keys, endpoints, and mycelium hashes are signed together as a single authorized unit.

Note: Each capsule entry in cmn.json contains endpoint definitions (mycelium, spore, archive[], optional taste). Replicators can add additional capsule entries with different endpoints while preserving the original entry.

Resolution Flow:

1. Download cmn.json
2. Compare capsules[0].mycelium_hash with cached hash
3. If same → Skip download (efficient)
4. If different → Download full mycelium using capsules[0].endpoints.mycelium template
5. Resolve spore/archive/taste endpoints from the same `cmn.json` capsule entry

HTTPS Security Model:

1.2.2 Identity Verification Flow

Spores embed the author’s public key in capsule.core.key, enabling offline verification. Trust in the key is established through a tiered model (see §1.2.4).

Any spore, any source:
1. Read core.key → verify core_signature → signature matches ✓
2. Local cache has key + TTL valid → trusted ✓
3. Cache expired/missing → fetch domain cmn.json
   → key found → trusted ✓, cache key
   → key NOT found / domain down:
     → source is Synapse → trusted ✓, don't cache
     → source not Synapse → ask Synapse (key, domain) → trusted ✓, don't cache
   → nothing works → untrusted ✗

1.2.3 Key Rotation

Domains MAY rotate their Ed25519 key at any time by updating cmn.json with a new key and moving the old key to previous_keys:

{
  "$schema": "https://cmn.dev/schemas/v1/cmn.json",
  "capsules": [
    {
      "uri": "cmn://example.com",
      "key": "ed25519.NEW_KEY_BASE58",
      "previous_keys": [
        { "key": "ed25519.OLD_KEY_BASE58", "retired_at_epoch_ms": 1772000000000 }
      ],
      "mycelium_hash": "b3.3yMR7vZQ9hL2xKJdFtN8wPcB6sY1mXgU4eH5pTa2",
      "endpoints": {
        "mycelium": "https://example.com/cmn/mycelium/{hash}.json",
        "spore": "https://example.com/cmn/spore/{hash}.json",
        "archive": [
          {
            "format": "tar+zstd",
            "url": "https://example.com/cmn/archive/{filename}",
            "delta_url": "https://example.com/cmn/archive/delta/{hash}/{old_hash}.zdict"
          }
        ]
      }
    }
  ],
  "capsule_signature": "ed25519.SIGNED_WITH_NEW_KEY"
}

Verification of historical content:

  1. Try capsule.key first
  2. If signature fails, try each key in previous_keys (ordered newest-first)
  3. retired_at_epoch_ms indicates when each key was retired

Rotation hardening (implementation guidance):

  1. Keep retired keys in previous_keys for at least the key-trust TTL window (default 7 days) plus allowed clock skew, so cached/historical content remains verifiable during rollout.
  2. During rotation windows, clients SHOULD prefer live domain confirmation over Synapse witness when available.
  3. If key rotation coincides with other high-risk changes (for example: endpoint template changes + sudden mycelium replacement), clients SHOULD surface a high-risk warning (key_rotation_review) before treating new trust as first-class.

Why this works: The key is the cryptographic identity; the domain is the name resolution layer. HTTPS authenticates the domain, the domain declares its keys (current and previous) in cmn.json, and all content is verified against these keys. CMN domains can rotate keys freely because the domain remains the stable discovery anchor while the key provides cryptographic proof of authorship.

Synapse behavior: Synapse MUST cache key alongside every verified mycelium. When verifying historical content (e.g., a replicate whose original domain is offline), Synapse uses the cached key rather than requiring a live fetch.

1.2.4 Key Trust Model

Spores embed the author’s public key in capsule.core.key. This makes spores self-describing: any holder can verify core_signature without network access. However, signature validity alone does not establish trust — someone could generate a keypair and claim any domain. Trust requires confirming that the key belongs to the claimed domain.

Trust tiers:

TierSourceTrust LevelCachedTTL
Domain confirmationcmn.json from HTTPS domainFirst-classYes7 days (configurable)
Synapse witnessSynapse key endpointSecond-classNoRe-verified each cycle

Refresh policies (implementation guidance):

PolicyBehavior
expired (default)Use cached trust while TTL is valid. Re-confirm from network only when expired/missing.
alwaysRe-confirm key trust from network every verification cycle.
offlineNever refresh from network. Only cached trust entries are accepted.

In offline, a missing/expired key trust cache MUST fail verification (for example: key_untrusted) instead of silently downgrading to untrusted network sources.

Synapse witness fallback policy (implementation guidance):

PolicyBehavior when domain confirmation is unavailable
allow (default)Permit Synapse witness as second-class trust (not cached).
require_domainDo not use Synapse witness for key trust. Verification fails if domain confirmation is unavailable and cache is insufficient.

Domain confirmation (first-class trust):

Synapse witness (second-class trust):

Offline verification workflow (no network required at verification time):

  1. Online preflight: verify one spore from each trusted domain, so core.key ↔ domain is cached from live cmn.json.
  2. Enter offline mode in the client implementation.
  3. Verify spores using embedded core.key + cached key trust only.
  4. If cache is expired/missing, fail and require an online refresh cycle.

Legacy spores: Spores without core.key fall back to the original verification flow: fetch cmn.json first, extract the public key, then verify signatures.

1.3 Value Formats

Hashes, public keys, and signatures use a unified algorithm.value format with dot separator and base58 encoding:

Base58 uses the alphabet 123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz (no 0, O, I, l). Hash values encode to ~44 base58 characters; signatures encode to ~88 characters.

This format is used consistently across URIs, JSON fields, filenames, and API paths.

Canonical JSON (JCS): All signatures and hashes use JSON Canonicalization Scheme (JCS, RFC 8785):

This ensures identical input produces identical bytes for signing and hashing, regardless of implementation.

Important: Unicode NFC normalization is applied to filenames in Merkle tree hashing (see 03-spore §4.6.3), not to JSON string values in JCS.

1.4 Distributed Architecture

The Network:

  1. Sovereign Nodes (Publishers)

    • Primary source of truth
    • Publish Mycelium (site descriptor) and Spores (code units)
    • Control distribution endpoints
    • Evolve code through spawn and absorb across domains
  2. Synapse (Indexers)

    • Crawl and cache Mycelium metadata from publisher domains
    • Build searchable index for discovery
    • Provide fallback when domains are offline
    • No write authority — read-only caches of verified content

Visitors (read-only):

2. Identity System

2.1 CMN URI Format

The URI is the primary key for all entities:

Properties:

For detailed URI specification, see 06-uri.md.

2.2 Synapse (Backup & Discovery)

Role:

Limitations:

API Examples (defined by the strain-synapse convention):

3. Content Distribution

3.1 Multi-Source Distribution

Each capsule entry in cmn.json contains endpoint definitions (mycelium, spore, archive[], optional taste). Replicators can add additional capsule entries with different hosting endpoints.

// cmn.json — all endpoints per capsule entry
{
  "capsules": [
    {
      "uri": "cmn://example.com",
      "key": "ed25519...",
      "mycelium_hash": "b3...",
      "endpoints": {
        "mycelium": "https://cdn.example.com/cmn/mycelium/{hash}.json",
        "spore": "https://cdn.example.com/cmn/spore/{hash}.json",
        "archive": [
          {
            "format": "tar+zstd",
            "url": "https://cdn.example.com/cmn/archive/{filename}",
            "delta_url": "https://cdn.example.com/cmn/archive/delta/{hash}/{old_hash}.zdict"
          }
        ],
        "taste": "https://cdn.example.com/cmn/taste/{hash}.json"
      }
    }
  ]
}

Benefits:

3.2 Distribution Sources (capsule.dist)

Spores can reference multiple source locations:

{
  "capsule": {
    "dist": [
      { "type": "archive", "filename": "cmn-spec.tar.zst" },
      { "type": "git", "url": "https://github.com/user/repo", "ref": "v1.0.0" }
    ]
  }
}

Supported Protocols:

Incremental behavior: git and optional endpoints.archive[].delta_url provide incremental transfer paths. delta_url is endpoint-level discovery (not a separate dist entry). It MUST include {hash} (target hash) and {old_hash} (cached base hash); direction is always old_hash -> hash. Implementations SHOULD fall back to full archive when delta prerequisites are unavailable.

The protocol does not require filename-suffix parsing for format detection. Clients MUST use archive[].format to choose decoders. In current Hypha releases, only tar+zstd is generated.

3.3 Pulse (Push Notification)

Domains can notify Synapse immediately after publishing by sending a Pulse notification (see 05-strain §5.2).

What happens:

Optional: Crawlers will eventually discover changes anyway.

4. Open Source Principles

4.1 Open Source Mandate

CMN is inherently public and open source:

4.2 Replicating

Anyone can replicate any spore:

A replicate hosts the same spore (identical hash) under a different domain. The core and core_signature remain unchanged from the original publisher:

See 03-spore §6.1 for the full replicate format.

4.3 Forking

Modify and republish with attribution:

A fork (spawn) creates a new spore with different hash, new domain, and a spawned_from bond:

Evolution Graph:

See 03-spore §6.2 for the full spawn format.

5. Conflict Resolution

5.1 The Sovereign Winner

In a decentralized network, multiple forks can exist:

Spore A
  ├─> Spore B1 (by domain-x.com)
  └─> Spore B2 (by domain-y.com)

No Central Authority:

Visitor Decides:

5.2 Spore Retention

Domain Responsibility:

Synapse Pruning:

6. Summary

CMN is a domain-sovereign network:

Next Steps: