network/carrier/SealedPacket

Summary: network/carrier/SealedPacket.js — multi-hop onion-sealed packets (network plan §24/§26 public carrier layer).  Phase 0 audit finding: `engine/collab/CollabAnonymousRelay.js` implements SINGLE-hop anonymization (host relay + garlic-encrypted payload) for one game-collab session. The OS network layer needs TRUE multi-hop onion routing across semi-trusted carrier meshes that are not part of any group. This module builds that generically, reusing the same ECDH P-256 + AES-256-GCM primitives (`CollabCrypto`) rather than inventing new crypto.  Each layer is wrapped from the innermost (final recipient) outward, so only the addressed hop can decrypt its own layer. A peeled layer reveals only the NEXT hop's peerId (or, at the final layer, the actual payload) — never the full path, the true sender, or the payload, matching §26.


buildSealedPacket

async buildSealedPacket({ hops, payload } = {})

Summary: Build a multi-hop sealed packet.


peelSealedPacket

Summary: Peel one layer with this hop's ECDH private key.


network/carrier/index


network/chunks/ChunkCache

Summary: Bounded in-memory LRU used only while the browser endpoint is alive.


createChunkCache

createChunkCache({ maxEntries = 128, maxBytes = 64 * 1024 * 1024 } = {})


cacheVerifiedChunk

cacheVerifiedChunk(cache, { chunkId, fragmentRoot, bytes } = {})

Summary: Store bytes that the caller has already content/Merkle verified.


network/chunks/ChunkFragmenter

Summary: network/chunks/ChunkFragmenter.js — split large objects into chunks, and chunks into transport-sized fragments (network plan §27/§31/§32).


splitIntoChunks

splitIntoChunks(bytes, chunkSize = DEFAULT_CHUNK_BYTES)

Summary: Split an object's bytes into chunks no larger than `chunkSize` (which must not exceed the network-wide 4MB ceiling).


splitChunkIntoFragments

splitChunkIntoFragments(chunkBytes, fragmentSize = DEFAULT_FRAGMENT_BYTES)

Summary: Split one chunk's bytes into transport-sized fragments.


reassembleFragments

Summary: Concatenate fragments back into one chunk's bytes.


reassembleChunks

Summary: Concatenate chunks back into the full object's bytes.


network/chunks/ChunkLimits

Summary: network/chunks/ChunkLimits.js — size ceilings/defaults (network plan §27).


Summary: Network-wide hard ceiling for one logical chunk. Not the default — a ceiling.


Summary: Sensible default chunk size (§27: "512 KB-1 MB").


Summary: Default transport fragment size (§27/§28; matches WebRTC DataChannel's assumed default `max-message-size`).


Summary: Experimental larger fragment size for trusted high-bandwidth links.


Summary: Soft caps for non-bulk message classes (§27).


network/chunks/ChunkTransport

Summary: network/chunks/ChunkTransport.js — binds the transport-agnostic chunk pipeline (ChunkFragmenter/MerkleFragments/ChunkVerifier/FlowControl/ DedupeCache) to a real peer connection (network plan §27/§28/§31/§32, previously deferred: "Real WebRTC DataChannel transport wiring").  Deliberately transport-agnostic at the call boundary — takes a `sendToPeer` function matching engine/collab/CollabCore.js's `sendToPeer(core, peerId, data)` signature (which already auto-chunks anything over ~60KB to dodge SCTP frame limits and reassembles transparently on the receive side, and round-trips `Uint8Array` natively via CollabCodec.js's msgpack `bin` format) rather than importing CollabCore itself. Callers feed every relevant `onOp(peerId, op)` message through `handleChunkTransportMessage` before their own app-level op handling — same pattern SyncTransport.js uses for MasterServerClient signal events.  Real credit-based backpressure (FlowControl.js's whole point): a CollabCore-style reliable-ordered data channel does NOT drop or backpressure large "critical" application messages on its own (see CollabCore.js's `_sendBinary` — only a handful of non-critical types like `__ping__` get dropped under buffer pressure); blasting every fragment of a multi-MB object immediately would build unbounded `bufferedAmount`. This module gates sends on an ACK-based credit window instead: a fragment's credit is only released once the receiver confirms it actually arrived (`CHUNK_FRAGMENT_ACK`), not merely once handed to the transport.


createChunkTransport

createChunkTransport({ sendToPeer, maxInFlightBytes, getChunk = async ()


requestChunkFromPeer

requestChunkFromPeer(transport, { peerId, chunkId, fragmentRoot, timeoutMs = REQUEST_TIMEOUT_MS, lane = PRIORITY_LANE.NORMAL, } = {})

Summary: Ask one peer for a manifest-declared chunk and await its verified bytes.


enqueueChunkSend

enqueueChunkSend(transport, { peerId, chunkId, chunkBytes, fragmentRoot, lane = PRIORITY_LANE.NORMAL, fragmentSize = DEFAULT_FRAGMENT_BYTES })

Summary: Enqueue one chunk's fragments for sending to a peer. Actual sends are paced by the credit window (see module doc) — this returns immediately; fragments drain asynchronously as ACKs free up credit.


handleChunkTransportMessage

Summary: Feed every `onOp(peerId, op)` message through this (e.g. from `createCollabCore({ onOp })`). Handles fragment sends and their acks; returns false for anything that isn't a chunk-transport message so callers can safely chain their own app-level op handling after it.


network/chunks/ChunkVerifier

Summary: network/chunks/ChunkVerifier.js — verify received fragments/chunks against a manifest's declared hashes (network plan §31/§32).


verifyChunkFragments

Summary: Verify a fully-received set of fragments for one chunk against the manifest's declared fragment merkle root — before spending time/memory reassembling+hashing the whole chunk.


reassembleAndVerifyChunk

Summary: Reassemble fragments and verify the resulting chunk's content hash matches the manifest's declared chunkId. Returns the reassembled bytes on success, or null (fails closed) on mismatch.


network/chunks/DedupeCache

Summary: network/chunks/DedupeCache.js — generic seen-packet dedupe table (network plan §29), keyed by whatever content/event/packet hash a caller chooses. Type-specific retention: callers pick the ttlMs per dedupe key type (control packets 1-5min, route announcements 5-30min, chunks/ledger events effectively forever via their own content hash, etc.) — this module just enforces "seen within its TTL -> drop" generically.


createDedupeCache

Summary: Create an empty dedupe cache.


hasSeen

Summary: True if `key` was marked seen and its TTL hasn't expired yet. Expired entries are lazily evicted.


markSeen

markSeen(cache, key, ttlMs, now = Date.now()

Summary: Mark `key` as seen for `ttlMs` milliseconds.


checkAndMark

checkAndMark(cache, key, ttlMs, now = Date.now()

Summary: Convenience: check-and-mark in one call — the usual receive-path pattern ("if already seen, drop; otherwise mark seen and process").


pruneDedupeCache

pruneDedupeCache(cache, now = Date.now()

Summary: Remove all expired entries. Returns the number removed.


network/chunks/FlowControl

Summary: network/chunks/FlowControl.js — credit-based flow control + priority lanes (network plan §28). QUIC-style: a receiver advertises how much in-flight data it can absorb; senders must reserve credit before sending and the receiver restores it once a fragment is verified/written.


createFlowControl

createFlowControl({ maxInFlightBytes = 16 * 1024 * 1024 } = {})

Summary: Create a flow-control window.


tryReserveCredit

Summary: Try to reserve `bytes` of send credit. Returns false (caller must pause) if it would exceed the window.


releaseCredit

Summary: Restore credit after a fragment is verified/written (or dropped/timed out).


availableCredit

Summary: Bytes of credit still available right now.


createPriorityQueue

Summary: Create an empty multi-lane priority queue.


enqueue

Summary: Enqueue an item on a priority lane (lower lane number = served first).


dequeue

Summary: Dequeue the next item, always draining the lowest non-empty lane first.


isQueueEmpty

Summary: True if every lane is empty.


network/chunks/Manifest

Summary: network/chunks/Manifest.js — signed object manifests (network plan §31). A manifest describes an object as an ordered list of chunks (each with a content hash + fragment merkle root); the object itself is fetched chunk-by-chunk, possibly from many peers at once (SwarmScheduler.js).


buildManifest

async buildManifest({ objectId, scope = 'private', version = 1, chunks = [], permissions = [], encryptionEpoch = null, signer, } = {})

Summary: Build + sign a manifest.


verifyManifest

Summary: Verify a manifest's protocol/type and signature.


manifestTotalSize

Summary: Total object size implied by a manifest's chunk list.


manifestChunkIds

Summary: List of chunk ids a manifest references, in order.


network/chunks/MerkleFragments

Summary: network/chunks/MerkleFragments.js — per-fragment hashing + a chunk's merkle root (network plan §32), so receivers can reject a corrupted fragment early instead of only detecting failure after the whole chunk is reassembled. Reuses the engine's existing SHA-256 content hash helper (already used for identity fingerprints elsewhere).


hashFragment

Summary: SHA-256 hex hash of one fragment's raw bytes.


computeChunkHash

Summary: SHA-256 hex hash of a full chunk's raw bytes (used as the chunk's content id).


computeFragmentHashes

Summary: Hash every fragment of a chunk, in order.


computeMerkleRoot

Summary: Compute a chunk's merkle root from its (ordered) fragment hashes: pair up adjacent hashes, hash their concatenation, repeat until one root remains (odd node carries up unchanged, standard merkle tree construction).


network/chunks/SwarmFetchCoordinator

Summary: Resolve a signed manifest from many DHT providers, retrying failed peers, verifying every content hash, and preserving manifest chunk order.


fetchManifestFromSwarm

async fetchManifestFromSwarm({ signedManifest, transport, findProviders, fallbackPeers = ()


network/chunks/SwarmScheduler

Summary: network/chunks/SwarmScheduler.js — spread chunk fetches across multiple providing peers (network plan §31 swarm fetching). Pure scheduling logic; the actual byte transfer happens over routes/sessions from earlier phases.


planSwarmFetch

planSwarmFetch({ chunkIds, providers, maxLanes = 4 } = {})

Summary: Assign each requested chunk to one candidate provider peer, load-balancing so no single peer is asked for every chunk, then group the assignments into fetch "lanes" of up to `maxLanes` concurrent requests.


network/chunks/index


network/crypto/Hpke

Summary: RFC 9180 base mode: DHKEM(P-256, HKDF-SHA256), HKDF-SHA256, AES-128-GCM. Signaling uses a fresh encapsulation for every message, so the AEAD sequence number is always zero and the base nonce is used directly.


hpkeSeal

async hpkeSeal(recipientPublicKeyHex, plaintext, options = {})


hpkeOpen

async hpkeOpen(recipientPrivateKey, encHex, ciphertextHex, options = {})


network/crypto/OpaqueRoute


deriveOpaqueRoute

async deriveOpaqueRoute({ routeSecret = null, projectId = 'default' } = {})


network/crypto/Trust


verifyRawSignature

async verifyRawSignature(publicKeyHex, bytes, signatureHex)


verifySignedManifest

async verifySignedManifest(signed, expectedPins, nowSeconds = Math.floor(Date.now()


async verifySignedV3Manifest(signed, expectedPins, nowSeconds = Math.floor(Date.now()


network/crypto/index


network/daemon/ParticleNetworkDaemon

Summary: Validate and normalize a V2 ICE response. Explicit direct mode is strict so a malformed or compromised response cannot smuggle relay credentials into a no-TURN client. Legacy relay responses remain accepted when they contain a real authenticated TURN URL.


readParticleTrustFloor

readParticleTrustFloor(networkRootId, nodeId, storage = globalThis.localStorage)


writeParticleTrustFloor

writeParticleTrustFloor(networkRootId, nodeId, floor, storage = globalThis.localStorage)


network/daemon/ParticleNetworkDaemonRegistry


acquireParticleNetworkDaemon

acquireParticleNetworkDaemon({ server, deviceSigner, onEvent = null, preferV3 = false } = {})


network/daemon/ParticleNetworkPreferredDaemon

Summary: Selects V3 only from a valid, pinned V2 advertisement. A valid advertisement with no V3 marker selects V2. Any V3 marker commits the connection attempt to V3; V3 integrity failures are forwarded and never retried as V2.


network/daemon/index


network/dht/BootstrapSource

Summary: network/dht/BootstrapSource.js — pluggable bootstrap sources for the no-bootstrap-is-impossible reality check (network plan §37/§47/§48): "no pure zero-bootstrap global discovery exists" — cached peers, LAN, invite code, DHT, radio beacon, or a seed/master server are the only starting paths. This module defines a tiny, transport-agnostic interface (`{ id, scan(), advertise(record) }`) and a registry to combine several sources into one bootstrap attempt order; it ships NO concrete transport.  Concrete adapter (wired at the OS integration layer, per this module's engine/network-stays-webgpu-os-free rule): webgpu-os/drivers/ ResidentBootstrapSource.js wraps the OS browser extension's "resident" node (webgpu-os/browser-extension/services/ResidentService.js, exposed via BrowserBridgeClient.resident) — a standing MV3 offscreen document that persists a device's PUBLIC identity cert and stays warm via a chrome.alarms keepalive. Kept honest in that adapter: the resident node does NOT answer presence with no OS tab open (it is a lightweight cert vault + heartbeat only, off by default) — its `scan()` returns a "last remembered identity" hint, not a confirmed-reachable peer.


createBootstrapSource

createBootstrapSource({ id, scan, advertise = null } = {})

Summary: Wrap a bootstrap source implementation.


createBootstrapRegistry

Summary: Create a registry of bootstrap sources, tried in registration order.


runBootstrap

Summary: Try each registered source in order, collecting whatever records each one returns (a source throwing/timing out just contributes nothing — this never fails the whole bootstrap attempt).


flattenBootstrapResults

Summary: Flatten runBootstrap()'s per-source results into one record list, tagged with their source.


network/dht/DhtMessages

Summary: network/dht/DhtMessages.js — future Particle DHT message primitives (network plan §47): FIND_PEER / FIND_ROUTE / FIND_PROVIDERS / PEER_EXCHANGE ANNOUNCE_PROVIDER / ANNOUNCE_ROUTE. Low priority per the plan — these are just versioned envelope builders (protocol.js `particle-dht/1`) for a future real DHT transport; no network code lives here yet. Bootstrap is still required even with a DHT (network plan §47: cached peers/LAN/master server/invite) — see BootstrapSource.js.


makeFindPeerMessage

makeFindPeerMessage({ targetPeerId, requesterPeerId } = {})


makeFindRouteMessage

makeFindRouteMessage({ routeId, requesterPeerId } = {})


makeFindProvidersMessage

makeFindProvidersMessage({ key, requesterPeerId } = {})


makeAnnounceProviderMessage

makeAnnounceProviderMessage({ key, peerId, ttlMs } = {})


makeAnnounceRouteMessage

makeAnnounceRouteMessage({ routeId, peerId, services = [], ttlMs } = {})


makePeerExchangeMessage

makePeerExchangeMessage({ knownPeers = [] } = {})


network/dht/DhtNode

Summary: network/dht/DhtNode.js — a local Particle DHT node view (network plan §47, low priority/future). Combines a ProviderStore with a lightweight known- peers registry and answers FIND_PEER/FIND_ROUTE/FIND_PROVIDERS queries from LOCAL knowledge only — this phase delivers the data structures and message-handling logic; real gossip/replication across a live DHT transport is deferred (network plan §47: "still needs bootstrap" even once a real DHT exists — see BootstrapSource.js).


createDhtNode

Summary: Create a local DHT node view.


rememberPeer

rememberPeer(node, peerId, { routeHints = [], reportedBy = null, direct = false } = {}, now = Date.now()

Summary: Record/refresh knowledge of a peer (from PEER_EXCHANGE or any direct contact).


handleFindPeer

Summary: Answer a local FIND_PEER query: do we know this peer, and if so, its route hints?


handleFindRoute

handleFindRoute(node, routeId, now = Date.now()

Summary: Answer a local FIND_ROUTE query: any peers providing this route?


handleFindProviders

handleFindProviders(node, key, now = Date.now()

Summary: Answer a local FIND_PROVIDERS query for an arbitrary key (chunk hash, service name, ...).


handleAnnounceProvider

handleAnnounceProvider(node, { key, peerId, ttlMs } = {}, now = Date.now()

Summary: Ingest an ANNOUNCE_PROVIDER (route or generic key -> peer).


handlePeerExchange

handlePeerExchange(node, knownPeers = [], now = Date.now()

Summary: Ingest a PEER_EXCHANGE payload (array of `{peerId, routeHints}`).


listKnownPeers

listKnownPeers(node, { limit = 64 } = {})

Summary: Bounded peer summaries for authenticated PEER_EXCHANGE messages.


providersMapForKeys

providersMapForKeys(node, keys, now = Date.now()

Summary: Build the providers map SwarmScheduler.planSwarmFetch expects for a list of keys.


pruneDhtNode

pruneDhtNode(node, { peerStaleMs = 30 * 60 * 1000 } = {}, now = Date.now()

Summary: Prune expired provider records and stale peer knowledge.


network/dht/DhtTransport

Summary: network/dht/DhtTransport.js — a scoped-down real transport for DhtNode.js's FIND_PEER/FIND_ROUTE/FIND_PROVIDERS queries (network plan §47, low priority). Deliberately NOT a full Kademlia DHT (no k-buckets, no XOR distance routing, no iterative closest-node lookup) — this is a minimal query/forward/respond loop over the existing mesh:  1. A query with no local answer is gossip-flooded across the mesh via CollabMeshTopology.js's existing TTL+dedupe fanout (same mechanism CarrierRelay.js uses) — reuses its per-query fingerprint (`_gossip.fp`) as this transport's queryId, so no new id scheme or message-shape changes were needed in DhtMessages.js. 2. Every node that relays a (non-duplicate) query remembers which neighbor it heard the query from (`reversePaths`) — classic flood/reverse-path relay (the same idea AODV uses), not a gossip broadcast itself. 3. Any node with a local answer (from its own DhtNode.js knowledge) sends a direct (non-gossiped) DHT_RESPONSE back along that reverse path, one hop at a time, until it reaches the original requester.  Known MVP limitation (intentional, per the plan's "low priority" scope): `reversePaths` entries are not proactively pruned by this module; a real deployment would want a TTL sweep alongside `pruneDhtNode()`.


createDhtTransport

createDhtTransport({ sendToPeer, topology, node, verifyControlIdentity = async ()


findPeerOverNetwork

findPeerOverNetwork(transport, targetPeerId, { timeoutMs = DEFAULT_QUERY_TIMEOUT_MS } = {})

Summary: Query the mesh for a peer's route hints. Checks local knowledge first; only floods the network if we don't already know it.


findRouteOverNetwork

findRouteOverNetwork(transport, routeId, { timeoutMs = DEFAULT_QUERY_TIMEOUT_MS } = {})

Summary: Query the mesh for a route's live providers. Checks local knowledge first.


findProvidersOverNetwork

findProvidersOverNetwork(transport, key, { timeoutMs = DEFAULT_QUERY_TIMEOUT_MS } = {})

Summary: Query the mesh for an arbitrary key's providers (chunk hash, service name, ...). Checks local knowledge first.


announceProviderOverNetwork

async announceProviderOverNetwork(transport, { key, ttlMs, signer } = {})

Summary: Authenticated, bounded provider announcement to current mesh neighbors.


announceRouteOverNetwork

async announceRouteOverNetwork(transport, { routeId, services = [], ttlMs, signer } = {})

Summary: Authenticated route announcement; services are descriptive and bounded, never ambient authority.


sendPeerExchangeOverNetwork

async sendPeerExchangeOverNetwork(transport, { peerId, signer, limit = MAX_PEER_EXCHANGE } = {})

Summary: Send a signed, bounded sample of local peer knowledge to one connected peer.


handleDhtMessage

Summary: Feed every relevant `onOp(peerId, op)` message through this, alongside `ChunkTransport.js`'s and `CarrierRelay.js`'s own handlers (same "return false if not ours" chaining pattern).


network/dht/ProviderStore

Summary: network/dht/ProviderStore.js — local view of "who provides what" (network plan §47 DHT objects: network_id -> route providers, manifest_hash -> chunk providers, group_alias -> route hints, service_name -> providers). This is a LOCAL cache only — no network gossip/replication yet (that's the deferred real-DHT transport); it's what a future DHT node would populate from FIND_PROVIDERS/ANNOUNCE_PROVIDER traffic, and what SwarmScheduler.js (Phase 7) already consumes as its `providers` map.


createProviderStore

Summary: Create an empty provider store.


announceProvider

announceProvider(store, key, peerId, ttlMs = DEFAULT_PROVIDER_TTL_MS, now = Date.now()

Summary: Announce that `peerId` provides `key` (e.g. a manifest chunk hash, route id, service name).


revokeProvider

Summary: Remove one provider's record for a key.


findProviders

findProviders(store, key, now = Date.now()

Summary: Live (non-expired) provider peerIds for a key, or [].


providersMapFor

providersMapFor(store, keys, now = Date.now()

Summary: Build the `Map<key, peerId[]>` shape SwarmScheduler.planSwarmFetch expects, for a set of keys.


pruneProviderStore

pruneProviderStore(store, now = Date.now()

Summary: Remove all expired provider records. Returns the number of (key, peerId) pairs removed.


network/dht/index


network/endpoint/ParticleEndpointRuntime


network/endpoint/index


network/groupCrypto/DeviceEncryptionKey

Summary: network/groupCrypto/DeviceEncryptionKey.js — per-device ECDH encryption keypair used to receive group welcome packets (network plan §14).  This is intentionally SEPARATE from the ECDSA signing identities in engine/network/identity/NetworkIdentity.js: signing proves "who you are"; this key only exists so other members can encrypt an epoch key TO this specific device. Reuses engine/collab/CollabCrypto.js's ECDH P-256 primitives (the same ones used for peer-to-peer session encryption).


createDeviceEncryptionKeyPair

Summary: Generate a fresh ECDH P-256 keypair for this device to receive welcome packets. Ephemeral by design (network plan §14 "per-device public encryption keys") — callers that need persistence should store `publicKeyRaw`/export the private key themselves via their own storage.


network/groupCrypto/GroupEpoch

Summary: network/groupCrypto/GroupEpoch.js — MLS-inspired group encryption epochs (network plan §14 group security / §39 route+key rotation on removal).  Each group has a sequence of "epochs"; each epoch has its own AES-256-GCM key. Content sealed under an epoch can only be opened by holders of that epoch's key. Removing a member rotates to a fresh epoch and CRYPTO-ERASES the old one (drops the key reference) so previously-sealed content stays unreadable to anyone who only has the new epoch's key — the removed member's copy of the old epoch key becomes useless going forward, and any FUTURE content is sealed under a key they never received.  This deliberately builds directly on `engine/state/integrity/SecureCrypto.js` (raw AES-256-GCM primitives) rather than the higher-level `SecureRetentionManager` class: welcome packets need to export/re-wrap the raw epoch key material for a specific recipient's ECDH public key, and `SecureRetentionManager` does not expose its internal CryptoKey for export. The crypto-erase SEMANTICS (drop the key reference; GCM tamper detection) are identical to `SecureRetentionManager.cryptoErase()`.


createGroupCrypto

Summary: Create an empty group crypto state (no epochs started yet).


startEpoch

Summary: Start the next epoch with a fresh AES-256-GCM key. Returns the new epoch number.


isEpochErased

Summary: True if `epoch` has no live key (never started here, or crypto-erased).


sealForEpoch

async sealForEpoch(gc, epoch, plaintext)

Summary: Seal a plaintext string under a specific epoch's key.


openEnvelope

Summary: Open an envelope from `sealForEpoch`. Returns null (fails closed) if the epoch's key is missing/erased, the group id doesn't match, or the GCM authentication tag fails (tampering/wrong key).


rotateEpoch

Summary: Rotate to a new epoch and crypto-erase the current one (network plan §14/§39). Removed members keep whatever they already downloaded, but cannot read anything sealed after the rotation, and (once their key reference is dropped) cannot re-derive the old epoch's key either.


makeWelcomePacket

async makeWelcomePacket({ gc, epoch, recipientEcdhPublicKeyRaw } = {})

Summary: Build a welcome packet: an epoch's raw key, ECDH-wrapped to one recipient's device encryption public key. Only that recipient's matching private key can unwrap it.


openWelcomePacket

async openWelcomePacket({ gc, welcomePacket, recipientPrivateKey } = {})

Summary: Recipient side: unwrap a welcome packet with the matching device private key and import the epoch's raw key into the recipient's own GroupCrypto instance (so they can now `openEnvelope()` content sealed under it).


network/groupCrypto/index


network/groupLedger/GovernancePolicy

Summary: network/groupLedger/GovernancePolicy.js — group governance modes on top of the CSE PolicyEngine (network plan §16 "adminless and moderatorless groups"): unanimous / majority / threshold / founder-protected / open-capability. This module decides WHETHER a given vote/approval set is enough for a governance action to commit; GroupLedger.js decides WHAT happens once it does.


createGovernancePolicy

createGovernancePolicy({ mode = GOVERNANCE_MODES.MAJORITY, founders = ()

Summary: Build a governance policy for a group.


Summary: Governance actions that always require approval (network plan §17 eviction/bans).


network/groupLedger/GroupLedger

Summary: network/groupLedger/GroupLedger.js — private append-only group governance ledger (network plan §15/§16/§17).  Reuses the Causal State Engine's `EventLog` (hash-chained append-only log, spec §13) and `CapabilityRegistry` as-is; governance approval decisions go through `GovernancePolicy.js` (PolicyEngine). Every event is a signed protocol envelope (protocol.js `particle-group-ledger/1`), so the ledger itself is a plain array of verifiable receipts — a group's current state is always the result of replaying it, never a separate source of truth.  `EventLog` is in-memory only; callers are responsible for persisting `ledger.eventLog.entries()` (e.g. via webgpu-os/storage/AppSandbox on the OS side) and rehydrating with `replayGroupLedger()` — this module does not import any OS/storage code, keeping the engine layer storage-agnostic.


createGroupLedger

createGroupLedger({ groupId, founders = [], mode = GOVERNANCE_MODES.MAJORITY, threshold = null } = {})

Summary: Create a new (empty, ungenesised) group ledger.


genesisGroup

async genesisGroup(ledger, { founderSigner, constitution = {} } = {})

Summary: Append the GROUP_GENESIS event and register the signing founder as the first member.


castVote

Summary: Cast a vote toward approving a pending proposal (network plan §17 eviction flow).


getVotes

Summary: Current vote set for a pending proposal (read-only copy).


proposeGroupEvent

async proposeGroupEvent(ledger, { type, payload = {}, signer, proposalId = null } = {})

Summary: Propose (and, if the governance policy allows, immediately commit) a governance event. Safe/low-risk actions commit right away; irreversible actions (MEMBER_REVOKED/MEMBER_BANNED/KEY_ROTATED/ROLE_CHANGED) require enough prior `castVote()` calls under the same `proposalId` first.


verifyGroupLedger

Summary: True if the ledger's hash chain is intact end-to-end (tamper check).


replayGroupLedger

replayGroupLedger({ groupId, founders = [], mode = GOVERNANCE_MODES.MAJORITY, threshold = null, entries = [] } = {})

Summary: Rebuild a live ledger from previously-persisted `ledger.eventLog.entries()` (network plan §15 persistence gap — see this file's header comment; OS-side storage, e.g. webgpu-os/storage/AppSandbox, is the caller's job, not this module's). Replays each entry through `EventLog.append()` (recomputing the exact same hash chain deterministically) and re-derives `members`/ `founders` via the same side-effect rules `genesisGroup`/`proposeGroupEvent` apply live, so a rehydrated ledger behaves identically to one built by replaying the same operations in real time — with one honest limitation: `EventLog` entries carry no wall-clock timestamp, and a `GROUP_GENESIS` envelope only embeds the ONE signer's public key, so a `members` entry reconstructed from genesis (unlike a later `MEMBER_ADDED`, whose payload carries full details) will have `joinedAt: null` and, for any co-founder who isn't the genesis envelope's own signer, `publicKeyHex: null`. This does NOT weaken governance security — founder-protected mode checks `ledger.founders` (a Set of principals, fully and exactly restored from the genesis payload), not the `members` map.


network/groupLedger/index


network/identity/NetworkIdentity

Summary: network/identity/NetworkIdentity.js — profile/device/membership identity layer for the Particle Global OS Network Layer (network plan §11).  The network plan keeps several identity levels distinct: profile_id      stable user identity, portable across devices/groups device_id       per-device identity used for route/session proofs membership_id   per-group pseudonymous identity (unlinkable across groups)  engine/state/authority/Identity.js already wraps CollabIdentity (ECDSA P-256) as a generic `createSigner(principal)`, and now mints a SEPARATE persisted keypair per distinct principal string (Phase 0 audit finding — no new crypto, just named keys). This module is a thin, semantically-named layer on top of that: each helper below is just `createSigner()` with a principal string that encodes the identity level.


bindProfileIdentityProvider

Summary: Bind the OS ProfileDriver as the canonical profile/Passport identity owner. The engine retains its named-key fallback for standalone demos and tests, but an initialized OS always resolves the active profile through this provider.


createDeviceIdentity

Summary: This device's per-device signer — used for low-level route/session proofs with a Masterserver (HELLO/PROVE). Never used as group identity.


createProfileIdentity

async createProfileIdentity(profileId = 'default')

Summary: This user's stable profile signer. One profile per logical user on this device (multiple profiles are supported by passing distinct `profileId`s, e.g. for multi-account testing) — each gets its own persisted keypair.


createMembershipIdentity

Summary: A per-group pseudonymous membership signer for a profile. Distinct keypair per (profileId, groupId) pair, so a member's participation in one group cannot be linked to their participation in another, or to their underlying profile, by key alone.


peerIdFromSigner

Summary: Derive a stable "peer id" string for use in route tables / mesh topology from any signer's fingerprint (device, profile, or membership signer).


computeFingerprint

Summary: Full SHA-256 public-key fingerprint used by Realm Network identities.


network/index

Summary: network/index.js — public barrel for the Particle Global OS Network Layer.  See C:\Users\btspa\.windsurf\plans\particle-network-layer-2bf6f0.md for the full plan. Phase 1 (protocol foundation): versioned envelopes, canonical signing, and profile/device/membership identity + route capabilities on top of the existing engine/collab (P2P) and engine/state (CSE) modules.  Build status: [x] Phase 0 audit  [x] Phase 1 protocol foundation [x] Phase 2 dynamic routes + master server list [x] Phase 2b live Masterserver signaling client (transport/MasterServerClient.js) [x] Phase 3 invites & trust groups   [x] Phase 4 group crypto [x] Phase 5 peer tickets  [x] Phase 6 sync manager/workstations, now WIRED to live transport (syncManager/SyncTransport.js broadcasts/merges workstation CRDT ops over an attached route's MasterServerClient.signal(), gated by SyncManager.shouldSync()) — demoed live in factory/apps/network-manager's Routes tab [x] Phase 7 chunks  [x] Phase 8 carrier layer  [x] Phase 9 DHT-lite (future/low-priority scope), with a concrete BootstrapSource adapter for the browser extension's resident cert vault at webgpu-os/drivers/ResidentBootstrapSource.js (OS-layer glue, per this module's no-webgpu-os-dependency rule — read-only, honestly scoped to "remembered identity", not live background reachability)


network/invites/InvitePacket

Summary: network/invites/InvitePacket.js — signed, one-time, expiring invites (network plan §13).  An invite is a doorway into a group's approval process, NOT automatic membership: it just names a temporary meeting route and a role offer, and is signed by the inviter so anyone can verify who issued it. It does not itself grant route/group access — that capability is minted only after the join-request identity exchange (see JoinFlow.js), once the joiner's real principal is known. "Base64 is not security" (network plan §13) — the encode/decode here is just a convenient transport, the actual guarantee is the ECDSA signature over the canonical envelope (protocol.js).


makeInvite

async makeInvite({ groupId, routeId, roleOffer = 'member', oneTime = true, expiresAt = null, inviterSigner, } = {})

Summary: Build + sign an invite packet.


encodeInvite

Summary: URL-safe base64 encoding of a signed invite envelope, for sharing as a code/link.


decodeInvite

Summary: Decode an invite code back into its (still-UNVERIFIED) signed envelope.


verifyInvite

async verifyInvite(signedInvite, { now = Date.now()

Summary: Verify a decoded invite: known protocol/type, not expired, and the signature actually matches the embedded inviter public key.


createInviteRegistry

Summary: Create a registry to track which one-time invites have already been used.


network/invites/JoinFlow

Summary: network/invites/JoinFlow.js — invite -> temp route -> mutual identity proof exchange -> group policy check (network plan §13 invite pipeline).  This module only establishes "this join request is a genuine, signed response to a live, unconsumed invite" — it does NOT decide group policy (vote thresholds, founder approval, etc). That decision belongs to GroupLedger.proposeGroupEvent('MEMBER_ADDED', ...); once that commits, call grantJoinCapability() to actually let the new member attach to the group's real route.


requestJoin

async requestJoin({ signedInvite, joinerSigner } = {})

Summary: Joiner side: build a signed join request referencing a (decoded) invite.


verifyJoinRequest

async verifyJoinRequest({ signedInvite, joinRequest, inviteRegistry = null, now = Date.now()

Summary: Inviter/group side: validate an invite together with a join request responding to it.


grantJoinCapability

grantJoinCapability({ signedInvite, joinerPrincipal, groupRouteId, inviteRegistry = null, allow = [ROUTE_ACTIONS.ATTACH, ROUTE_ACTIONS.SUBSCRIBE, ROUTE_ACTIONS.PUBLISH], } = {})

Summary: After the group has approved the join (GroupLedger MEMBER_ADDED commit), mint the new member's first route capability for the group's real route and consume the invite if it was one-time.


network/invites/index


network/peerTickets/PeerTicket

Summary: network/peerTickets/PeerTicket.js — encrypted, remembered reconnect records (network plan §38).  A peer ticket is a signed statement "peerId X is reachable, offers these services, at these route hints, valid until Y" — it lets a device reconnect to known peers/groups without the discovery server, once trust has already been established once. Sealing (encrypting the ticket itself) reuses the same ECDH-wrap pattern as group welcome packets (engine/network/groupCrypto/GroupEpoch.js), OR a group's current encryption epoch directly, per network plan §38 "encrypt to recipient device key OR group epoch key".


makePeerTicket

async makePeerTicket({ peerId, deviceId = null, profileId = null, groupId = null, services = [], routeHints = [], expiresAt = null, routeEpoch = null, encryptionEpoch = null, issuerSigner, } = {})

Summary: Build + sign a peer ticket.


verifyPeerTicket

async verifyPeerTicket(signedTicket, { now = Date.now()

Summary: Verify a peer ticket: known protocol/type, not expired, signature valid.


sealPeerTicketToDevice

Summary: ECDH-wrap a signed ticket so only the holder of `recipientEcdhPublicKeyRaw`'s private key can read it.


openSealedPeerTicket

Summary: Recipient side: unwrap a device-sealed ticket. Returns null (fails closed) on any error.


sealPeerTicketToEpoch

async sealPeerTicketToEpoch(groupCrypto, epoch, signedTicket)

Summary: Seal a ticket under a group encryption epoch (readable by any member with that epoch's key).


openSealedPeerTicketFromEpoch

Summary: Open an epoch-sealed ticket. Returns null if the epoch key is missing/erased or tampered.


network/peerTickets/PeerTicketStore

Summary: network/peerTickets/PeerTicketStore.js — local reconnect memory (network plan §38). In-memory only; callers persist via their own storage (e.g. webgpu-os/storage/AppSandbox) and rehydrate with addPeerTicket() on boot — engine/network stays storage-agnostic (see GroupLedger.js for the same pattern).


createPeerTicketStore

Summary: Create an empty peer ticket store.


addPeerTicket

Summary: Remember a (already verified) peer ticket, keyed by its peerId. Overwrites any older ticket for the same peer.


getPeerTicket

Summary: Look up the remembered ticket for a peer, or null.


removePeerTicket

Summary: Forget a peer's ticket. Returns true if one existed.


pruneExpiredPeerTickets

pruneExpiredPeerTickets(store, now = Date.now()

Summary: Remove tickets whose payload.expiresAt has passed. Returns the removed peerIds.


listPeerTicketsByFreshness

Summary: All remembered tickets, most-recently-received first (network plan §38: try freshest known peers first).


snapshotPeerTicketStore

Summary: Full, JSON-serializable snapshot of a peer ticket store for OS-side persistence (network plan §38 persistence gap — see this file's header comment; storage itself, e.g. webgpu-os/storage/AppSandbox, is the caller's job). Same shape `listPeerTicketsByFreshness` already returns — exposed under its own name so the persistence contract (snapshot/hydrate pair) stays explicit even if the internal shape changes later.


hydratePeerTicketStore

Summary: Rebuild a peer ticket store from a previously-persisted snapshotPeerTicketStore() array.


network/peerTickets/ReconnectOrder

Summary: network/peerTickets/ReconnectOrder.js — full device-boot reconnect order (network plan §38): cached peer tickets (freshest first) -> LAN -> group gossip -> master servers -> carrier -> DHT. Ties Phase 5 (peer tickets) onto Phase 2's `buildConnectionOrder` (routes/MasterServerList.js) without modifying it.


network/peerTickets/index


network/protocol

Summary: network/protocol.js — namespaced/versioned message envelopes for the Particle Global OS Network Layer (network plan §34).  Every message on the network carries an explicit, versioned protocol namespace (e.g. `particle-route/1`). Unversioned or unrecognized protocol strings are rejected outright — this is what lets the wire format evolve (particle-route/2, ...) without silently misparsing old/foreign traffic.  Canonical signing reuses the Causal State Engine's deterministic canonicalization (engine/state/util/canonical.js, RFC-8785-style) so that signed envelopes hash/verify identically regardless of key order or JS engine, and reuses CSE's cross-actor verification (verifyWithKey) so a receiver can verify a sender's signature from just their public key hex.


isKnownProtocol

Summary: True when `protocol` is one of this build's known, versioned namespaces.


makeEnvelope

makeEnvelope({ protocol, type, payload = null, extra = {} } = {})

Summary: Build an unsigned protocol envelope. Throws if `protocol` isn't a known, versioned namespace (spec §34 rule: reject unversioned packets).


assertKnownProtocol

Summary: Assert an inbound (possibly untrusted) message is a well-formed envelope with a known protocol namespace. Does NOT verify signatures — see `verifyEnvelope`. Throws on failure so callers fail closed.


signEnvelope

Summary: Sign an envelope with a CSE authority signer (engine/state/authority/Identity.js `createSigner`, itself bound to a CollabIdentity ECDSA P-256 keypair). The signature covers the canonical bytes of the envelope BEFORE the signature/signerFingerprint fields exist, so verification reconstructs the same canonical body by stripping those two fields back off.


verifyEnvelope

async verifyEnvelope(signedEnvelope, signer = null)

Summary: Verify a signed envelope. Pass either a `signer` (verifies against its own key — same-principal round-trip) or nothing to verify against the envelope's own embedded `signerPublicKeyHex` (cross-actor verification, the normal case when receiving from a remote peer).


Summary: All known/versioned protocol namespaces (network plan §34).


Summary: Signed, short-lived Accord capability discovery records.


verifyAccordCapabilityAdvertisement

async verifyAccordCapabilityAdvertisement(record, { now = Date.now()


negotiateAccordCapability

async negotiateAccordCapability(advertisements, request, options = {})

Summary: Select a verified capability that can satisfy an exact bounded request.


network/realm/accord/AccordCrypto

Summary: Shared validation and domain-separated signing for the Navi Accord wire protocol.


safeInteger

safeInteger(value, name, minimum = 0, maximum = Number.MAX_SAFE_INTEGER)


boundedToken

boundedToken(value, name, maximum = 128)


assertSecureRecordId

assertSecureRecordId(value, name = 'record ID')


normalizeTokenList

normalizeTokenList(values, name, { maximum = 128, allowEmpty = false } = {})


normalizeIdList

normalizeIdList(values, name, { maximum = 128, allowEmpty = true } = {})


assertIdentityId

assertIdentityId(value, name = 'identity ID')


normalizeWindow

normalizeWindow(input, { issuedAt = Date.now()


validateActiveWindow

validateActiveWindow(record, now = Date.now()


normalizeBudget

normalizeBudget(value, name = 'budget', { allowZero = false } = {})


assertSafePublicData

assertSafePublicData(value, name = 'public data', { maximumBytes = ACCORD_MAX_PUBLIC_BYTES } = {})

Summary: Validate bounded JSON-compatible public data and reject common exfiltration containers. This is deliberately structural: unrestricted session exports, credentials, and private-memory payloads cannot be smuggled under aliases.


canonicalPublicCopy

canonicalPublicCopy(value, name = 'public data', options = {})


finishSignedAccordRecord

async finishSignedAccordRecord(record, idField, signer)


verifySignedAccordRecord

async verifySignedAccordRecord(record, { format, idField })


authorizeWith

async authorizeWith(adapter, record, role)


Summary: Task-bound capability delegation, revocation, and approval proofs.


createAccordDelegation

async createAccordDelegation(task, input, signer)


verifyAccordDelegation

async verifyAccordDelegation(record, { task, acceptance = null, capabilityGrant, verifyCapabilityGrant, now = Date.now()


createAccordDelegationRevocation

async createAccordDelegationRevocation(delegation, input, signer)


verifyAccordDelegationRevocation

async verifyAccordDelegationRevocation(record, { delegation, now = Date.now()


createAccordApprovalProof

async createAccordApprovalProof(task, input, signer)


verifyAccordApprovalProof

async verifyAccordApprovalProof(record, { task, now = Date.now()


network/realm/accord/AccordReplayGuard

Summary: Bounded replay and monotonic-sequence protection for verified Accord records.


consumeReplay

consumeReplay(replayGuard, record, { idField, streamKey = null, sequence = null } = {})


Summary: Signed Accord progress, cancellation, results, and purpose-isolated reputation evidence.


createAccordProgress

async createAccordProgress(task, acceptance, input, signer)


verifyAccordProgress

async verifyAccordProgress(record, { task, acceptance, now = Date.now()


createAccordCancellation

async createAccordCancellation(task, input, signer)


verifyAccordCancellation

async verifyAccordCancellation(record, { task, now = Date.now()


async createAccordResultV1(task, acceptance, delegation, input, signer)


async verifyAccordResultV1(record, { task, acceptance, delegation, capabilityGrant, verifyCapabilityGrant, contextCapsules = [], approvalProofs = [], cancellation = null, now = Date.now()


createAccordReputationEvidence

async createAccordReputationEvidence(task, result, input, signer)


verifyAccordReputationEvidence

async verifyAccordReputationEvidence(record, { now = Date.now()


Summary: Requester-signed Accord tasks and executor-signed negotiated acceptance.


verifyAccordTask

async verifyAccordTask(record, { now = Date.now()


createAccordTaskAcceptance

async createAccordTaskAcceptance(task, input, signer)


verifyAccordTaskAcceptance

async verifyAccordTaskAcceptance(record, { task, now = Date.now()


Summary: Recipient-bound, allowlisted, signed context for a single Accord task.


async createContextCapsuleV1(task, input, signer)


async verifyContextCapsuleV1(record, { task, acceptance = null, now = Date.now()


network/realm/accord/index


network/realm/addressing/RealmAddress

Summary: RealmAddress.js — human aliases that resolve to location-independent IDs.


RealmAddressResolver

Summary: In-memory verified resolver. Persistence/discovery providers can replay records into it.


parseRealmAddress

Summary: Parse and canonicalize a realm:// alias or direct-ID address.


createRealmAliasRecord

Summary: Create an attributable alias update. Aliases can move; Realm IDs cannot.


verifyRealmAliasRecord

async verifyRealmAliasRecord(record, options = {})


network/realm/addressing/RealmIds

Summary: RealmIds.js — stable, typed identifiers for Realm Network resources. IDs are deliberately independent of names, hosts, routes, and storage locations.  The digest is SHA-256 over domain-separated canonical data, so the same control material always produces the same identifier while two resource types can never collide with one another.


realmKeyFingerprint

Summary: Return the full SHA-256 fingerprint of a raw uncompressed P-256 key.


createRealmId

Summary: Derive a typed stable ID from canonical control material. Callers must provide persistent material, never a location or session ID.


createKeyControlledRealmId

Summary: Derive an identity controlled by a specific P-256 public key.


createContentRealmId

Summary: Derive an immutable content identity from exact bytes.


assertRealmId

assertRealmId(id, expectedType = null, label = 'Realm ID')


network/realm/addressing/index


network/realm/atlas/AtlasProviders

Summary: Feature-gated Atlas provider contracts with bounded verified in-memory stores.


AtlasRecordProvider

Summary: A complete bounded provider suitable for local, direct-contact, organization, and peer-gossip adapters. Network code passes verified records into this contract; no provider becomes active until explicitly enabled.


Summary: Signed, bounded Realm Atlas publication records and visibility policy.


AtlasReplayGuard

Summary: Monotonic per-publisher replay guard for verified Atlas histories.


Summary: Create a signed immutable AtlasRecordV1.


async verifyAtlasRecordV1(record, { now = Date.now()

Summary: Verify canonical structure, SHA-256 identity, signature, freshness, and optional publisher authority.


canAccessAtlasRecordV1(record, context = {})

Summary: Evaluate a viewer against the signed audience without granting entry permissions.


network/realm/atlas/BoundedServerAtlasProvider

Summary: Optional opaque V3 Atlas provider matching the bounded ephemeral server contract.


createServerAtlasAdvertisement

async createServerAtlasAdvertisement(record, { scopeKey, signer, issuedAt = Math.floor(Date.now()

Summary: Build the exact opaque advertisement accepted by the additive V3 server.


verifyServerAtlasAdvertisement

async verifyServerAtlasAdvertisement(record, { now = Math.floor(Date.now()


openServerAtlasAdvertisement

async openServerAtlasAdvertisement(advertisement, { scopeKey, now = Date.now()

Summary: Verify and decrypt one V3 envelope without trusting the server that stored it.


network/realm/atlas/index


network/realm/authority/AuthorityHandoff

Summary: Checkpoint-backed, signed authority handoff state machine.


verifyAuthorityHandoffMessage

async verifyAuthorityHandoffMessage(message, options = {})


network/realm/authority/AuthorityLease

Summary: Signed, fenced authority leases for semantic Realm state. Leases are explicit records. They never confer authority merely because a peer has a connection, hosts a transport, or possesses a Capsule. Every mutation must present the active lease ID and its monotonically increasing fencing token.


renewAuthorityLease

async renewAuthorityLease(previous, input, signer)


verifyAuthorityLease

async verifyAuthorityLease(lease, options = {})


verifyAuthorityRevocation

async verifyAuthorityRevocation(record, options = {})


network/realm/authority/AuthorityLeaseManager

Summary: In-memory authority decision engine; persistence is supplied by the caller.


network/realm/authority/HostMigrationQuorum


verifyHostMigrationVote

async verifyHostMigrationVote(vote, authorizeVoter = null)


network/realm/authority/SemanticReplication

Summary: Semantic replication records, idempotent inboxes, resumable outboxes, and divergence evidence.


verifySemanticEnvelope

async verifySemanticEnvelope(value, options = {})


network/realm/authority/index


network/realm/branches/BranchStorage

Summary: Bounded persistent storage adapter for branch metadata and offline queues. Capsule/blob bytes remain in the shared RealmContentStore; this adapter never duplicates content-addressed storage.


RealmBranchStorage

Summary: LocalStorage-compatible persistent key/value adapter.


prepareRealmBranchStorageRecord

prepareRealmBranchStorageRecord(record, label = 'branch storage record')


network/realm/branches/MergeProposal

Summary: MergeProposalV1 contracts, dependency-safe decisions, and merge commits.


createMergeProposal

Summary: Create a signed MergeProposalV1 from a semantic comparison.


verifyMergeProposal

async verifyMergeProposal(proposal, options = {})

Summary: Verify proposal signature, IDs, dependency DAG, authorization, and expiry.


buildDefaultMergeDecisions

Summary: Default policy: accept clean changes and retain conflicts on the source branch.


applyMergeProposal

async applyMergeProposal({ proposal, decisions, base, mine, theirs }, options = {})

Summary: Apply accepted changes to mine; rejected/conflicting source work is untouched.


createMergeCommit

async createMergeCommit(input, signer, options = {})

Summary: Apply a proposal and publish the decision as a signed Chronicle event. Any rejected work receives a stable signed branch rooted at the source head.


verifyMergeCommit

async verifyMergeCommit(event, options = {})


Summary: Public MergeProposalV1 contract.


network/realm/branches/OfflineOperationQueue

Summary: Persistent, causal, resumable queue for signed offline Chronicle events.


network/realm/branches/RealmBranch

Summary: RealmBranchV1 identity, ownership, signed-head chains, and branch DAGs.


RealmBranchDAG

Summary: Verified in-memory projection of branch descriptors and RealmBranchRefV1 head chains. Persistence is delegated to BranchStorage.js.


createRealmBranch

Summary: Create a stable RealmBranchV1. The label is intentionally excluded from the identity derivation, so renaming or alias changes cannot change branch IDs.


verifyRealmBranch

async verifyRealmBranch(branch, options = {})

Summary: Verify branch identity, controller signature, and optional owner authority.


Summary: Public RealmBranchV1 contract.


network/realm/branches/RealmBranchCrypto

Summary: Shared signed-record plumbing for Realm branch contracts.


signBranchRecord

async signBranchRecord(body, { idField, format }, signer)


verifyBranchRecord

async verifyBranchRecord(record, { idField, format })


network/realm/branches/SemanticAdapters

Summary: Explicit semantic and confluence-proven CRDT adapters for three-way merge.


compareSemanticSnapshots

async compareSemanticSnapshots({ base, mine, theirs }, registry = createDefaultSemanticAdapterRegistry()

Summary: Produce a deterministic base/mine/theirs semantic comparison.


applySemanticChange

applySemanticChange(snapshot, change, selected, registry)


network/realm/branches/index


network/realm/capsule/CapsuleAssembler


network/realm/capsule/CapsuleMigration


network/realm/capsule/RealmBranchRef


createRealmBranchRef

async createRealmBranchRef(input, signer, previous = null)


verifyRealmBranchRef

async verifyRealmBranchRef(ref, options = {})


network/realm/capsule/RealmCapsule

Summary: Convert the output of PackageVerifier.parseAny()/verify() into the package input accepted by buildRealmCapsule. Package verification stays owned by the existing package stack; this adapter only binds its verified artifact bytes and roots into the Capsule.


adaptVerifiedPackageArtifact

async adaptVerifiedPackageArtifact({ artifactBytes, parsedPackage, verification } = {})


prepareRealmBlob

async prepareRealmBlob(input, options = {})


buildRealmCapsule

async buildRealmCapsule(input, signer, options = {})


verifyRealmCapsule

async verifyRealmCapsule(capsule, options = {})


createOfflineCapsuleExport

async createOfflineCapsuleExport(capsule, resolveBlob, options = {})


verifyOfflineCapsuleExport

async verifyOfflineCapsuleExport(bundle, options = {})


network/realm/capsule/RealmCapsuleSchema


RealmCapsuleValidationError

class RealmCapsuleValidationError extends TypeError


validateRealmCapsuleShape

validateRealmCapsuleShape(value, { requireSignature = true } = {})


validateDependencyGraph

validateDependencyGraph(records, options = {})


network/realm/capsule/index


network/realm/chronicle/RealmChronicle

Summary: RealmChronicle.js — signed SHA-256 causal history for a Realm branch. Chronicle events contain semantic records and state-root transitions, not simulation ticks.  The implementation is storage-agnostic so the same verification code is used for local persistence, Capsule import, and peers.


createChronicleEvent

Summary: Create a complete signed Chronicle event.


verifyChronicleEvent

async verifyChronicleEvent(event, options = {})

Summary: Verify content hash, event hash, signer fingerprint, signature, and optional actor binding.


verifyChronicle

async verifyChronicle(value, options = {})

Summary: Verify and rebuild a complete Chronicle snapshot or event list.


network/realm/chronicle/index


network/realm/contracts

Summary: Stable Realm Network V1 contract descriptors. Descriptors contain references to the concrete implementations. Importing this module does not create stores, links, providers, timers, or network connections.


Summary: Fail-closed Realm entry planning over verified identity, content, and policy evidence.


RealmGate

Summary: Runtime Gate evaluator. It owns no persistence and performs no entry itself; it only emits a short-lived signed plan that Shield can enforce.


verifyGatePlan

async verifyGatePlan(record, options = {})


network/realm/gate/index


Summary: Scoped, attenuable, delegable, revocable CapabilityGrantV1 contracts.


RealmCapabilityRegistry

Summary: Runtime registry with online revocation and dynamic membership/role checks.


verifyCapabilityGrant

async verifyCapabilityGrant(record, options = {})


attenuateCapabilityGrant

async attenuateCapabilityGrant(parentRecord, input, signer)


recoverCapabilityGrant

async recoverCapabilityGrant(previousRecord, input, signer)


verifyCapabilityRevocation

async verifyCapabilityRevocation(record, options = {})


verifyCapabilityAuditReceipt

async verifyCapabilityAuditReceipt(record, options = {})


Summary: Public contract descriptor for callers that discover schemas dynamically.


network/realm/governance/GovernanceCrypto

Summary: Shared signing primitives for Realm organization and capability records.


finishSignedRecord

async finishSignedRecord(record, idField, signer)


verifySignedRecord

async verifySignedRecord(record, { format, idField })


boundedInteger

boundedInteger(value, name, minimum = 0)


boundedToken

boundedToken(value, name, maximum = 128, { wildcard = false } = {})


uniqueSorted

uniqueSorted(values, name, normalize, maximum = 128)


network/realm/governance/OrganizationLedger

Summary: Cryptographically verified organization history. The ledger uses the same contextual verifier for live persistence and replay. A proposal freezes its eligible membership set and quorum at its epoch; later joins cannot vote, while revoked members and superseded keys fail immediately.


replayOrganizationLedger

async replayOrganizationLedger(organizationRecord, envelopes, options = {})


network/realm/governance/OrganizationV1

Summary: Signed OrganizationV1 root contract and its fixed governance vocabulary.


network/realm/governance/index


network/realm/health/HealthSnapshot

Summary: Record a RealmLink snapshot without exposing identities, keys, or payloads.


createHealthMonitor

createHealthMonitor({ realmId = null, branchId = null, now = ()


recordHealthComponent

recordHealthComponent(monitor, componentId, { status, reason = null, metrics = {}, ttlMs = 60_000, } = {})


observeRealmLinkHealth

observeRealmLinkHealth(monitor, linkSnapshot, { ttlMs = 30_000 } = {})


observeDiscoveryHealth

observeDiscoveryHealth(monitor, providerStatuses, { ttlMs = 60_000 } = {})


observePresenceHealth

observePresenceHealth(monitor, { activeActors = 0, rejected = 0, sequenceGaps = 0 } = {}, { ttlMs = 60_000 } = {})


network/realm/health/ReachabilityProjection

Summary: Build a secret-free reachability projection from locally observed evidence.


projectEndpointReachability

projectEndpointReachability({ residentActive = false, routeCount = 0, masterservers = [], peers = [], observedAt = Date.now()


network/realm/health/index


network/realm/identity/RealmPassport

Summary: RealmPassport.js — portable, signed public identity records. This module owns no keys and performs no persistence.  It consumes the existing signer interface and produces canonical records that can be stored, copied, and independently verified by any Realm Network peer.


createPassportLineage

async createPassportLineage({ passportId, createdAt = Date.now()

Summary: Create a self-signed genesis lineage. The Passport ID is bound to its root key.


appendPassportRotation

appendPassportRotation(lineage, newSigner, previousSigner, options = {})


appendPassportRecovery

appendPassportRecovery(lineage, newSigner, previousSigner, options = {})


appendPassportRevocation

async appendPassportRevocation(lineage, currentSigner, options = {})

Summary: Append a terminal, signed key-revocation record.


verifyPassportLineage

Summary: Verify every digest, key fingerprint, link, and signature in a lineage.


verifyDeviceGrant

async verifyDeviceGrant(grant, options = {})


verifyDeviceRevocation

async verifyDeviceRevocation(record, options = {})


verifyRecoveryRecord

async verifyRecoveryRecord(record, options = {})


createRealmPassport

Summary: Build a signed, allowlisted public Passport projection.


network/realm/identity/index


network/realm/index

Summary: Explicit exports win over same-named subsystem descriptors and keep the public V1 contract surface stable while subsystem APIs remain available.


network/realm/link/ContinuityStore

Summary: Storage-agnostic continuity records for reconnect and verified transfer resume. Raw reconnect tokens are deliberately rejected: callers persist an opaque credential only after sealing it with the OS/profile storage layer.


createContinuityRecord

createContinuityRecord({ linkId, realmId, branchId, localPeerId, remotePeerId = null, sessionEpoch = 0, lastSentSequence = 0, remoteMaxSequence = 0, remoteSeenSequences = [], sealedReconnectCredential = null, peerTicket = null, routeHints = [], transfers = [], updatedAt = Date.now()


continuityStorageKey

continuityStorageKey({ realmId, branchId, linkId })


createMemoryContinuityAdapter

Summary: In-memory adapter for tests and ephemeral sessions; durable OS storage is injected with the same interface.


createContinuityStore

createContinuityStore({ adapter = createMemoryContinuityAdapter()


updateTransferProgress

updateTransferProgress(record, update, now = Date.now()

Summary: Update one transfer monotonically; completed/cancelled records cannot be reopened.


network/realm/link/DiscoveryProvider

Summary: Realm discovery is an orchestration contract, not a new discovery network. Providers adapt the existing bootstrap, DHT, invite, contact, peer-ticket, and Masterserver mechanisms into one bounded result shape.


normalizeDiscoveryCandidate

normalizeDiscoveryCandidate(candidate, { sourceId, now = Date.now()

Summary: Normalize an untrusted provider result into the Realm discovery shape.


createDiscoveryProvider

createDiscoveryProvider({ id, kind = DISCOVERY_KIND.CUSTOM, priority = 0, discover, advertise = null, revoke = null, health = null, } = {})

Summary: Define one discovery provider. Network algorithms remain in the adapted subsystem.


discoverRealmPeers

async discoverRealmPeers(registry, query = {}, { timeoutMs = 5000, correlationId = null } = {})

Summary: Query all enabled providers concurrently; one provider failure never erases valid peer results.


createBootstrapRegistryProvider

createBootstrapRegistryProvider({ id = 'bootstrap', registry, priority = 10 } = {})

Summary: Adapt the existing ordered bootstrap registry without reproducing its scan logic.


createPeerTicketDiscoveryProvider

createPeerTicketDiscoveryProvider({ id = 'peer-tickets', store, priority = 100 } = {})

Summary: Adapt the existing signed peer-ticket store into discovery hints.


createDhtDiscoveryProvider

createDhtDiscoveryProvider({ id = 'dht', transport, priority = 20 } = {})

Summary: Adapt the existing mesh DHT query transport; callers choose exactly one query key.


network/realm/link/RealmLink

Summary: Create one transport-independent logical link. `verifyIdentity` is required so cryptographic key ownership is also checked against Passport/device authorization rather than trusted from an embedded public key.


createRealmLink

createRealmLink({ linkId, realmId, branchId, localIdentity, signer, verifyIdentity, supportedCapabilities = [], authorizeCapabilities = async ({ requested, supported })


attachRealmLinkTransport

async attachRealmLinkTransport(link, session, { initiate = true } = {})

Summary: Attach an existing transport session and optionally initiate the authenticated handshake.


handleRealmLinkFrame

async handleRealmLinkFrame(link, frame, { binding = null } = {})

Summary: Verify, deduplicate, authorize, and dispatch one inbound Realm Link frame.


sendRealmLinkData

async sendRealmLinkData(link, kind, payload, { capability = null } = {})


upgradeRealmLinkTransport

Summary: Attempt a higher-priority channel while the current one remains live.


realmLinkContinuityRecord

realmLinkContinuityRecord(link, overrides = {})


persistRealmLinkContinuity

async persistRealmLinkContinuity(link, overrides = {})


markRealmLinkDisconnected

async markRealmLinkDisconnected(link, reason = 'transport-disconnected')


closeRealmLink

async closeRealmLink(link, reason = 'local-close')


realmLinkEvidence

Summary: Canonical digest input for diagnostics/evidence without exposing keys or payloads.


network/realm/link/RealmLinkProtocol

Summary: Build and sign one control/data frame using the existing authority signer.


signRealmLinkFrame

async signRealmLinkFrame({ linkId, realmId, branchId, senderPeerId, sessionEpoch, sequence, messageId, issuedAt, type, payload = null, signer, } = {})


verifyRealmLinkFrame

async verifyRealmLinkFrame(frame, { linkId, realmId, branchId, now = Date.now()

Summary: Cryptographically validate a frame. Passport/device authorization is a separate required hook.


createRealmLinkReplayWindow

createRealmLinkReplayWindow({ width = 256, maxSequence = 0, seen = [] } = {})

Summary: Sliding sequence window supports limited cross-transport reordering while rejecting replay.


acceptRealmLinkReplay

acceptRealmLinkReplay(window, frame, { now = Date.now()


network/realm/link/TransportProvider

Summary: Realm transport providers adapt existing channels. They do not implement WebRTC, relays, WebSockets, LAN sockets, or encryption themselves.


assertRealmTransportSession

Summary: Validate the minimal bidirectional channel RealmLink consumes.


createTransportProvider

createTransportProvider({ id, kind = TRANSPORT_KIND.CUSTOM, priority = null, canConnect = ()


connectRealmTransport

async connectRealmTransport(registry, target, opts = {})

Summary: Try compatible providers in priority order. A failed direct path naturally falls through to an existing relay/WebSocket provider.


isPreferredTransport

Summary: True when a candidate session is a meaningful relay-to-direct upgrade.


network/realm/link/index


network/realm/presence/PresenceV1

Summary: Verify signature, expiry, and Passport/device key authorization.


createPresenceV1({ realmId, branchId, actorId, deviceId, sessionId, sequence, status = PRESENCE_STATUS.ONLINE, activity = null, location = null, issuedAt = Date.now()


async verifyPresenceV1(record, { authorizeKey, now = Date.now()


createPresenceTracker

createPresenceTracker({ authorizeKey, now = ()


ingestPresence

Summary: Accept each signed session sequence once; a gap is surfaced but does not invent missing state.


pruneExpiredPresence

pruneExpiredPresence(tracker, now = tracker.now()


presenceSnapshot

presenceSnapshot(tracker, { realmId = null, branchId = null } = {})


network/realm/presence/index


network/realm/publishing/RealmJourneyJournal

Summary: Signed publish/inspect/enter/leave history with exact branch-aware returns.


RealmJourneyJournal

Summary: An append-only signed journal. Entry transitions are replayed locally; no network or storage side effects occur until a caller persists its snapshot.


normalizeRealmLocation

normalizeRealmLocation(value, name = 'Realm location')


verifyJourneyEvent

async verifyJourneyEvent(record, options = {})


verifyJourneyJournal

async verifyJourneyJournal(events, options = {})


network/realm/publishing/index


network/realm/shield/RealmShield

Summary: Runtime isolation, quotas, moderation, and tamper-evident audit for Realm entry.


RealmShield

Summary: Realm Shield is deliberately local. It applies signed Gate plans but stores no Realm authority and performs no server-side enforcement.


network/realm/shield/index


network/routes/MasterServerList

Summary: network/routes/MasterServerList.js — client-shipped master server list + connection fallback ordering (network plan §4).  A master server is a meeting place, not an authority: it introduces peers and forwards signaling, nothing more (network plan §4/§6). This module only normalizes/validates the list shape and computes connection attempt order; it does not open any sockets (that is the signaling tier, Phase 2b/Phase A).


defaultParticleMasterServers

Summary: A fresh, mutable copy of the client-shipped production bootstrap list.


readParticleMasterServerRecord

Summary: Strict read used by writers to quarantine unsupported/corrupt records.


saveParticleMasterServers

saveParticleMasterServers(list, storage = globalThis.localStorage)


normalizeMasterServerList

Summary: Validate + normalize a client master-server-list config (network plan §4). Unknown/malformed servers are dropped rather than throwing, so a bad entry in a self-hosted community list can't break the whole client.


pickNextMasterServer

pickNextMasterServer(masterServers, { excluded = [] } = {})

Summary: Pick the next enabled master server to try, in priority order, skipping any whose url is in `excluded` (e.g. servers that just failed this round).


buildConnectionOrder

Summary: Build the full connection attempt order (network plan §4): cached peers -> LAN -> group gossip -> master servers (by priority) -> carrier -> DHT -> relay. Stages disabled via `fallbacks` (or with no master servers configured) are omitted.


Summary: Fallback stages other than master servers themselves, in priority order (§4).


network/routes/NodeRoleProtocol

Summary: Build a signed, expiring role announcement for one route.


signNodeRoleAnnouncement

async signNodeRoleAnnouncement({ routeId, nodeId, sequence, availability = 'foreground', roles = ['resident'], capabilities = [], ttlMs = NODE_ROLE_MAX_TTL_MS, signer, now = Date.now()


verifyNodeRoleAnnouncement

async verifyNodeRoleAnnouncement(message, { routeId, peerId, lastSequence = 0, now = Date.now()

Summary: Verify signature, device-key binding, route scope, freshness, and ordering.


network/routes/OsNetworkSession

Summary: network/routes/OsNetworkSession.js — the concrete `createSession(routeId, opts)` factory `RouteSessionManager.js` was designed to take (network plan Phase 2 note: "typically a thin wrapper around `createCollabCore({ projectId: routeId, ... })`"). This was the one piece of the plan's own architecture that was designed but never actually instantiated — Phase 2b shipped the simpler Masterserver-relay-as-direct- transport shortcut (`syncManager/SyncTransport.js`) for V1 sync, which left `ChunkTransport.js`/`CarrierRelay.js`/`DhtTransport.js` (all three built against a real peer-addressed `sendToPeer` + `CollabMeshTopology`) with no live mesh to run on. This module closes that gap.  `CollabCore.js`'s Tier 4 signaling (see `CollabSignal.js`'s header comment) already reads `os.network.masterServers` from localStorage and lazily acquires the shared pinned V2 ParticleNetworkDaemon itself. Explicit compatibility endpoints may still use the shared V1 registry. Therefore `createCollabCore({ projectId: routeId })` gets real cross-internet WebRTC signaling over the same Masterserver config the Control Panel manages.  Deliberately skips CollabCore's own peer-identity/ECDH handshake (`publicKeyRaw`/`identityProof`/`ecdhPublicKeyRaw`/`ecdhPrivateKey`, `encrypt: true`): that machinery expects raw `CollabIdentity.js` keys (ECDH keypair + identity proof), which is a different, lower-level API than the CSE-wrapped `createSigner()` this layer's identity/ signers use (see `engine/network/identity/NetworkIdentity.js`'s own header comment). This is not a security gap — every OS-level payload carried over this session already brings its own crypto/verification: `ChunkVerifier.js` content hashes, `SealedPacket.js` onion ECDH, `GroupEpoch.js` AES-GCM, signed `GroupLedger.js`/`PeerTicket.js` envelopes. CollabCore here is used purely as a WebRTC *transport* (data channels + DTLS), the same way `ChunkTransport.js` et al. were written to treat any `sendToPeer`.


createOsNetworkSession

createOsNetworkSession(routeId, opts = {})


addSessionOpHandler

Summary: Register an op handler (e.g. `ChunkTransport.js`'s `handleChunkTransportMessage`, `CarrierRelay.js`'s `handleCarrierRelayMessage`, `DhtTransport.js`'s `handleDhtMessage` — all follow the same `(peerId, op) => boolean` "handled?" chaining pattern). Handlers are tried in registration order; the first one that returns `true` consumes the message.


registerSessionProtocol

Summary: Register a bounded, version-aware route protocol handler.


sessionSendToPeer

Summary: This session's `sendToPeer(peerId, data)` — the exact shape ChunkTransport/CarrierRelay/DhtTransport expect.


sessionSendProtocol

sessionSendProtocol(session, peerId, data, { requireAdvertised = false } = {})

Summary: Send a versioned protocol envelope, optionally requiring peer advertisement.


sessionBroadcast

Summary: Broadcast one application op to every connected direct mesh neighbor.


sessionBroadcastProtocol

sessionBroadcastProtocol(session, data, { requireAdvertised = false } = {})

Summary: Broadcast a versioned envelope only to compatible or pre-catalog peers.


sessionPeerIds

Summary: Connected peer IDs for routing and role coordination.


sessionTopologyStats

Summary: Mesh topology stats for UI display (mode, neighbor count, supernode status, gossip counters).


sessionPeerMetrics

Summary: Locally measured, secret-free peer transport observations.


sessionProtocolStatus

Summary: Protocol catalog, peer negotiation, and bounded dispatch counters.


destroyOsNetworkSession

Summary: Tear down a session's WebRTC connections, signaling, and topology timers.


network/routes/ReconnectBackoff

Summary: network/routes/ReconnectBackoff.js — exponential reconnect backoff with jitter (network plan §8: "0.5s -> 1s -> 2s -> 4s -> 8s -> max 30s, with random jitter"). Mirrors the constants already used by engine/collab/CollabCore.js (RECONNECT_BASE_MS=1000, RECONNECT_MAX_MS=30000, MAX_RECONNECT_ATTEMPTS=8) so route-level and WebRTC-level reconnects behave consistently.


createReconnectBackoff

Summary: Create a reconnect backoff sequence.


nextBackoffDelay

Summary: Compute the next delay (ms) and advance the attempt counter.


isBackoffExhausted

Summary: True once `maxAttempts` has been exceeded (0 = never exhausted). Matches nextBackoffDelay's `exhausted` flag.


resetBackoff

Summary: Reset the attempt counter after a successful (re)connect.


network/routes/RouteProtocolRegistry

Summary: Dispatch one route operation. Protocol-bearing traffic always fails closed.


registerRouteProtocol

registerRouteProtocol(registry, { id, protocols = [], matches = null, handle, authorize = null, validate = null, priority = 0, maxBytes = null, } = {})


dispatchRouteProtocol

async dispatchRouteProtocol(registry, peerId, op, context = {})


network/routes/RouteSessionManager

Summary: network/routes/RouteSessionManager.js — orchestrates one P2P session per attached route/group.  Phase 0 audit finding: engine/collab/CollabCore.js is built around a single projectId/roomPassword session. The network layer needs many concurrent routes/groups at once, so rather than rewriting CollabCore.js (which would risk existing game-collab call sites), this manager holds N session instances behind a pluggable factory — callers pass in `createSession(routeId, opts) => session` (typically a thin wrapper around `createCollabCore({ projectId: routeId, ... })`) and this module just tracks lifecycle (one session per routeId, created on demand, torn down explicitly or when the route's last local lease is dropped).


createRouteSessionManager

createRouteSessionManager({ createSession, destroySession = null } = {})


ensureRouteSession

ensureRouteSession(manager, routeId, opts = {})

Summary: Get the session for `routeId`, creating it via the factory if it doesn't exist yet.


acquireRouteSession

acquireRouteSession(manager, routeId, opts = {})

Summary: Acquire one local consumer lease for a route. The first lease creates the session. The final release tears it down after a bounded idle grace period.


releaseRouteSession

releaseRouteSession(manager, routeId, options = {})

Summary: Release one local route lease without affecting other consumers.


routeSessionLeaseStatus

Summary: Inspect lease ownership without exposing route secrets or session internals.


getRouteSession

Summary: Get an existing session, or null. Does NOT create one.


teardownRouteSession

teardownRouteSession(manager, routeId, options = {})

Summary: Tear down and forget a route's session (calls `destroySession` if provided).


listRouteSessions

Summary: List routeIds with a live session.


network/routes/RouteTable

Summary: network/routes/RouteTable.js — dynamic, capability-gated routes for the Particle Global OS Network Layer (network plan §9 "dynamic routes instead of rooms" + §10 capability checks).  A route is NOT server-owned: it exists in this local table only while a capability-holding principal has attached to it and kept its lease alive via heartbeats. There is no createRoute() — attachRoute() both creates the local entry (if absent) and joins it. Leases expire on their own; nothing here talks to a network — this is pure local bookkeeping that the Masterserver signaling tier (Phase 2b) and per-route session manager below will drive.


createRouteTable

Summary: Create an empty route table.


attachRoute

attachRoute(table, { routeId, principal, capability, ttlMs = DEFAULT_ROUTE_TTL_MS, meta = {} } = {})

Summary: Attach to a route. Validates the capability authorizes `route/attach` for (principal, routeId) right now; if the route doesn't exist locally yet it is created (this is what "routes appear when clients attach" means — there is no separate creation step). Re-attaching refreshes the lease.


heartbeatRoute

heartbeatRoute(table, { routeId, principal, ttlMs = DEFAULT_ROUTE_TTL_MS } = {})

Summary: Refresh a principal's lease on a route (heartbeat). Re-checks the capability so a revoked capability cannot keep renewing its lease.


detachRoute

detachRoute(table, { routeId, principal } = {})

Summary: Detach a principal from a route. Removes the route entirely once empty.


pruneExpiredRoutes

Summary: Remove all expired subscriber leases (and any routes left with zero subscribers). Call this periodically (e.g. alongside heartbeat ticks).


isRouteAttached

Summary: True if `routeId` currently has at least one live subscriber.


getRoute

Summary: Snapshot of a route's subscribers, or null.


listRoutes

Summary: List all currently-live routes (opaque summaries only — no capability objects).


Summary: Default route lease TTL (network plan §9/§35: ~90s).


Summary: Default heartbeat interval to keep a lease alive (network plan §8: 25-30s).


network/routes/index


network/stateChannels/BroadcastStateChannelTransport


network/stateChannels/InProcessStateChannelTransport


network/stateChannels/MeshStateChannelTransport

Summary: State Channel transport over browser-to-browser WebRTC mesh messages.


network/stateChannels/ParticleSignalStateChannelTransport


network/stateChannels/SseStateChannelTransport

Summary: Default standard transport: SSE projections/receipts down, HTTP intents up.


network/stateChannels/StateChannelAuthority


network/stateChannels/StateChannelAuthorityCoordinator

Summary: Browser authority lifecycle with signed heartbeats, replicated checkpoints, deterministic takeover, and fencing. It never makes the discovery server an authority and can be attached to any MeshStateChannelTransport.


network/stateChannels/StateChannelClient


network/stateChannels/StateChannelContract


createStateIntent

createStateIntent(channelId, action, payload, options = {})


createStateProjection

createStateProjection(channelId, projection, options = {})


createStateReceipt

createStateReceipt(intent, options = {})


validateStateChannelMessage

validateStateChannelMessage(message, channelId = null)


readStateChannelMessage

readStateChannelMessage(message, channelId = null)


negotiateStateChannelVersion

negotiateStateChannelVersion(peerVersions, localVersions = STATE_CHANNEL_SUPPORTED_VERSIONS)


network/stateChannels/StateChannelTransportResolver

Summary: Resolve transport from authority location. Server-backed channels remain SSE by default; peer authority explicitly selects the WebRTC mesh.


network/stateChannels/index


network/syncManager/SyncCategory

Summary: network/syncManager/SyncCategory.js — sync categories + target scopes (network plan §20 Sync Manager).


Summary: What a synced value may fan out to.


Summary: The category groupings a profile's Sync Manager governs (network plan §20).


network/syncManager/SyncManager

Summary: network/syncManager/SyncManager.js — per-profile sync rules (network plan §20). This module only decides WHAT should sync WHERE (rules + gating); it does not move any bytes — actual transport goes through the routes/ group crypto layers built in earlier phases. Rules are local, in-memory config; callers persist them via their own storage.


createSyncManager

Summary: Create a sync manager with sensible defaults (network plan §20 examples: "sync AI memory only to my devices", "never sync private keys" — private keys simply have no category here at all, by design).


setSyncRule

setSyncRule(manager, category, { scope, enabled, targetDeviceIds } = {})

Summary: Set/update a category's sync rule.


getSyncRule

Summary: Get a category's current rule, or null if unset.


listSyncRules

Summary: All rules as a flat array of `{ category, scope, enabled, ... }`.


shouldSync

Summary: Should `category` currently sync to `targetScope` right now? Used as a gate before a caller pushes an update over a route/group.


network/syncManager/SyncTransport

Summary: network/syncManager/SyncTransport.js — moves the group-workstation CRDT bytes that SyncManager.js only ever decided WHETHER to send (network plan §20, plus §18/§19's workstation CRDT). Reuses a caller-owned, already connected + already route-attached Particle daemon or explicitly enabled legacy client as the wire: local ops use `client.signal(routeId, ...)` to every other session attached to the route, and incoming SIGNAL events for that routeId are folded in via CRDT join (`mergeWorkstationState`). CRDTs are commutative/idempotent by construction, so no ordering, ack, or conflict-resolution logic is needed here — this is intentionally the entire transport.  This module owns no socket/timer of its own; it is pure glue between SyncManager's gate (`shouldSync`), Workstation's CRDT state, and whatever Particle signaling session + opaque route tag the caller has brought up (e.g. factory/apps/network-manager's Routes tab, or a future group app).


serializeWorkstationState

Summary: Serialize a WorkstationState.js state object into a JSON-safe wire payload.


deserializeWorkstationState

Summary: Inverse of serializeWorkstationState — reconstructs real CRDT instances (not plain values).


createSyncTransport

createSyncTransport({ client, routeId, syncManager, category, targetScope, getWorkstation, setWorkstation })

Summary: Wire a live group workstation to a connected + route-attached MasterServerClient. Both push (outgoing) and handleEvent (incoming) are gated by the same `shouldSync` check, so disabling a category locally stops us from both broadcasting AND accepting that category's updates.


network/syncManager/index


network/transport/MasterServerClient

Summary: network/transport/MasterServerClient.js — live WebSocket signaling client for a single Masterserver (network plan §7/§8/§12, Phase 2b). Speaks the tiny HELLO -> PROVE -> PING/PONG -> DISCOVER wire protocol implemented by Masterserver/app/routes.py. All outgoing envelopes use the `particle-discovery/1` namespace — the server validates `protocol` and `type` independently (Masterserver/app/protocol.py validate_envelope), so a single namespace for every message type from this client is sufficient and matches the confirmed-live wire format.  PROVE requires signing the exact raw challenge bytes the server issued (Masterserver/app/session_crypto.py verifies a raw P1363 ECDSA signature over those bytes) — NOT a stringified/hex-encoded form of them. This is why deviceSigner.signRaw() (engine/state/authority/Identity.js) is used here instead of the string-based signer.sign().


createMasterServerClient

createMasterServerClient({ url, deviceSigner = null, onEvent = null } = {})

Summary: Create a live client for one Masterserver. Does not auto-connect — call `connect()` explicitly.


Summary: Connection lifecycle states surfaced via onEvent().


network/transport/MasterServerRegistry

Summary: network/transport/MasterServerRegistry.js — shared, ref-counted transport/MasterServerClient.js registry (network plan §4/§7/§8/§12).  Multiple independent OS consumers can each want a live session to the same Masterserver URL at the same time — e.g. SecureMesh's signaling tier (engine/collab/CollabSignal.js Tier 4) and the Particle Network control panel's live inspector (factory/apps/network-manager/NetworkManagerApp.js). Without this, each would open its own redundant WebSocket + HELLO/PROVE handshake to the same server. This module multiplexes N listeners onto ONE underlying MasterServerClient connection per URL, connecting on first acquire and disconnecting only once every consumer has released it.  A Masterserver route/session concept is per-connection, not per-consumer — sharing one session is exactly what "a master server introduces peers and forwards signaling" (README.md's can/cannot boundary) assumes: any number of local app-level features can ride the same proven session and attach their own routes on it independently (ATTACH_ROUTE is additive; a session can be attached to many routes at once).


acquireSharedMasterServerClient

acquireSharedMasterServerClient({ url, deviceSigner = null, onEvent = null } = {})

Summary: Acquire a shared, ref-counted MasterServerClient for `url`, connecting it if this is the first consumer. Every event the underlying client emits is fanned out to every registered listener — consumers are expected to filter for events relevant to them (by routeId/message shape), same as they would with their own private client.


hasSharedMasterServerClient

Summary: True if a shared client for this url already exists (connecting or connected).


sharedMasterServerClientStats

Summary: Current listener/ref count for a url's shared client, or null if none exists. Diagnostics only.


network/transport/index


network/workstation/Workstation

Summary: network/workstation/Workstation.js — a group's shared OS surface (network plan §18), distinct from any member's personal desktop. Wraps WorkstationState.js (the CRDT layer) with a groupId and a checkpoint-payload builder for GroupLedger's WORKSTATION_CHECKPOINTED event (network plan §19: "the governance ledger periodically checkpoints collaborative state" — the ledger stores authority decisions plus a hash of live state, not every live edit).


createWorkstation

Summary: Create a new (empty) group workstation.


mergeWorkstation

Summary: Merge in another replica's CRDT state (order-independent).


computeWorkstationStateRoot

Summary: Stable content hash of the current workstation state ("desktopStateRoot").


buildWorkstationCheckpointPayload

buildWorkstationCheckpointPayload(workstation, { governanceHead, appRegistryHash = null, manifestRoot = null } = {})

Summary: Build the payload for a WORKSTATION_CHECKPOINTED governance event (network plan §19). Pass the result straight into GroupLedger's `proposeGroupEvent(ledger, { type: 'WORKSTATION_CHECKPOINTED', payload, signer })`.


network/workstation/WorkstationState

Summary: network/workstation/WorkstationState.js — CRDT-backed group workstation surface (network plan §18/§19: shared desktop layout, app registry, folders, agents — distinct from any member's personal desktop).  Reuses the Causal State Engine's approved CRDT types (ORSet for pinned-apps/folders/agents membership, LWWRegister for per-window layout and wallpaper) unmodified: every mutation returns a NEW state object (non-mutating join algebra), so replicas that exchange state in any order converge without coordination.


createWorkstationState

Summary: Create an empty workstation CRDT state.


setWindowLayout

setWindowLayout(state, windowId, layout, ts, node = '')

Summary: Set a window's layout (LWW: highest (ts, node) wins on merge).


setWallpaper

setWallpaper(state, wallpaper, ts, node = '')


mergeWorkstationState

Summary: Join two workstation states (CRDT merge — order-independent, convergent).


snapshotWorkstationState

Summary: Plain, JSON-serializable snapshot (for hashing/checkpointing/transport).


network/workstation/index


render/CameraMath

Summary: Compute perspective projection matrix.


computePerspectiveProjection

computePerspectiveProjection(camera, aspectFallback, options = {})

Summary: Compute perspective projection matrix.


computeViewProjMatrix

computeViewProjMatrix(camera, transform, viewportWidth, viewportHeight)


render/DrawHelpers

Summary: Draw a mesh with the given bind group and uniforms.


drawMeshes

Summary: Draw multiple meshes efficiently.


beginStandardRenderPass

Summary: Create a render pass with standard settings.


ensureDepthTexture

ensureDepthTexture(device, current, width, height)

Summary: Ensure depth texture matches canvas size, recreating if needed.


ensureSceneColorTexture

ensureSceneColorTexture(device, current, width, height, format = "bgra8unorm")

Summary: Ensure scene color texture matches canvas size, recreating if needed. Used for screen-space water refraction which needs to sample the rendered scene.


buildViewProjData

buildViewProjData(projection, view, multiply, out = null)

Summary: Build viewProj matrix data for a frame buffer.


renderParticleBillboards

Summary: Render particle billboards or points in an existing render pass. Automatically detects point-list vs triangle-list topology.


renderVolumetricSmoke

renderVolumetricSmoke(encoder, swapView, smoke, options)

Summary: Render volumetric smoke in a separate pass after the main render pass.


render/DualModeRenderer

Summary: Map velocity to color


velocityToColor

velocityToColor(vx, vy, vz, scale = 0.1)

Summary: Map velocity to color


generateInstanceData

generateInstanceData(positions, velocities, particleSize = 1.0, colorScale = 0.1)

Summary: Generate particle instance data from positions and velocities


ViewMode

Summary: View modes


Summary: LOD distance thresholds


ParticleStyle

Summary: Particle rendering styles


render/IndexedClusterCuller


render/LightManager

Summary: LightManager.js - Collects ECS Light entities and uploads to GPU Queries all entities with Light + Transform components each frame, builds a GPU uniform buffer, and exposes a bind group for renderers. GPU Layout (std140-aligned): vec3 ambientColor + f32 ambientIntensity        (16 bytes) vec3 sunDirection + f32 sunIntensity             (16 bytes) vec3 sunColor     + u32 lightCount               (16 bytes) f32  globalBrightness + f32 enableDiffuse + f32 enableSun + f32 _pad (16 bytes) Light[16] array                                   (16 * 48 = 768 bytes) Total: 64 + 768 = 832 bytes Each Light (48 bytes, 12 floats): vec3 position  + u32 lightType     (16 bytes) vec3 color     + f32 intensity     (16 bytes) vec3 direction + f32 range         (16 bytes)


render/Mesh


computeBoundsFromInterleavedPositions

computeBoundsFromInterleavedPositions(vertexData, strideFloats, positionOffsetFloats = 0)


createScreenQuadMesh

createScreenQuadMesh(device, options = {})


getVertexBufferLayoutForMesh

getVertexBufferLayoutForMesh(mesh, slot = 0)


createUnitCubeMesh

createUnitCubeMesh(device, options = {})


render/MinimapRenderer

Summary: MinimapRenderer.js - Top-Down Minimap System Renders a 2D top-down view of the terrain showing: - Terrain colors based on block types - Player position and direction indicator - Chunk boundaries (optional) - Points of interest markers


render/PlanetPreviewRenderer


render/RenderBundleManager

Summary: Render Bundle Manager - Pre-record draw commands for massive CPU overhead reduction Based on WebGPU best practices from Toji.dev Reduces draw call overhead by 10x for repeated rendering


ParticleRenderBundleCache

Summary: Particle-specific render bundle optimization Pre-records particle billboard rendering for massive performance gains


render/RenderingInit

Summary: Initialize particle simulation and renderer.


initSmokeRenderer

Summary: Initialize volumetric smoke renderer (fluid sim is lazy).


initSimulationRendering

Summary: Initialize particle system and optionally smoke renderer.


render/SceneRenderer

Summary: Render all spawned ECS entities.


renderEntities

Summary: Render all spawned ECS entities.


renderRoom

Summary: Render room geometry (floor, walls, ceiling).


renderLightCube

Summary: Render a light cube at a position.


render/VolumetricRaymarch

Summary: Default raymarch parameters


Summary: Default raymarch parameters


RenderMode

Summary: Render modes


render/WorldParticleRenderer


render/atmosphere/AerialPerspective

Summary: AerialPerspective - Distance-based color shifting


render/atmosphere/AtmosphereUtils

Summary: Calculate recommended Mie asymmetry based on visibility


getAdaptiveStepMultiplier

Summary: Get step size recommendation based on optical depth


render/atmosphere/AtmosphericScattering

Summary: AtmosphericScattering - Physical atmosphere simulation


render/atmosphere/AuroraPass

Summary: AuroraPass - Volumetric aurora rendering pass


render/atmosphere/BlueNoise

Summary: BlueNoiseTexture - GPU blue noise texture manager


render/atmosphere/CelestialMoon

Summary: Moon class for orbital mechanics and state management


MoonSystem

Summary: MoonSystem - Manages multiple moons


MoonDefaults

Summary: Default configurations for different moon types


MoonPresets

Summary: Preset moon configurations for the world


MoonWGSL

Summary: WGSL shader code for moon rendering


render/atmosphere/CelestialStars

Summary: StarField class for managing star rendering


StarSystem

Summary: StarSystem - Complete star management system


StarLayer

Summary: Star layer types - for different visual effects


StarDefaults

Summary: Star field configuration defaults


StarLayerPresets

Summary: Star layer presets


Constellations

Summary: Constellation definitions (named star patterns)


StarsWGSL

Summary: WGSL shader code for star rendering


render/atmosphere/CelestialSun

Summary: Sun class for orbital mechanics and state management


SunWGSL

Summary: WGSL shader code for sun rendering


render/atmosphere/DistanceFog

Summary: DistanceFog - Distance-based fog system


DistanceFog

Summary: DistanceFog - Distance-based fog system


render/atmosphere/HillaireLUT

Summary: HillaireLUT - Main class for Hillaire-style atmospheric LUT system


render/atmosphere/PlanetCurvature

Summary: PlanetCurvature - Planetary curvature simulation


render/atmosphere/ProceduralSky

Summary: ProceduralSky - Complete sky system


ProceduralSky

Summary: ProceduralSky - Complete sky system


render/atmosphere/Space


render/atmosphere/SpectralWeather

Summary: SpectralWeather - T21 spectral weather simulation


render/atmosphere/TemporalAccumulation

Summary: TemporalAccumulation - TAA pass for atmosphere


render/atmosphere/index


render/atmosphere/sky/index


render/debug/GridRenderer

Summary: GridRenderer - Infinite grid for 3D viewport Now powered by vGPU driver


render/debug/PhysicsLineRenderer

Summary: PhysicsLineRenderer.js - GPU Line Rendering for Physics Objects Renders ropes, wires, hair strands, and chain links using GPU instancing. Supports both line primitives and tube geometry for thicker cables.


render/debug/WireframeBoxRenderer

Summary: WireframeBoxRenderer - Renders wireframe boxes for debug visualization Used to visualize voxel colliders in the editor Now powered by vGPU driver


render/debug/index

Summary: Debug Renderers - GPU debug visualization tools These renderers are useful for both editor and runtime debug visualization.


render/geometry/CapsuleGeometry


createCapsuleGeometry

createCapsuleGeometry(radius = 0.3, height = 1.0, radialSegments = 16, hemisphereSegments = 8)


render/geometry/ConeGeometry


createConeGeometry

createConeGeometry(radius = 0.5, height = 1.0, segments = 16)


render/geometry/CubeGeometry


render/geometry/CylinderGeometry


createHollowCylinderGeometry

createHollowCylinderGeometry(outerRadius = 0.5, innerRadius = 0.4, height = 1.0, radialSegments = 24,)


createCylinderGeometry

createCylinderGeometry(radius = 0.5, height = 1.0, radialSegments = 16, heightSegments = 1,)


render/geometry/GroundGeometry


render/geometry/PlaneGeometry


render/geometry/PrimitiveGeometry

Summary: Barrel export file for primitive geometry generators Re-exports all geometry modules for convenient importing


render/geometry/SkyboxGeometry


render/geometry/SphereGeometry


createSphereGeometry

createSphereGeometry(radius = 0.5, widthSegments = 16, heightSegments = 12)


render/geometry/StaticMeshBuilder


buildStaticMeshFromGeometry

buildStaticMeshFromGeometry(device, geometry, label, options = {})


render/geometry/TorusGeometry


createTorusGeometry

createTorusGeometry(majorRadius = 0.4, minorRadius = 0.15, majorSegments = 24, minorSegments = 12)


render/gpu/IndirectDrawSystem


render/index

Summary: Engine Render Modules Exports all render-related utilities from subfolders


render/lighting/RealtimeGI


render/materials/AnimatedMaterialSystem

Summary: AnimatedMaterialSystem.js Per-frame evaluation of animated material node graphs. Materials with Time nodes in their graph get evaluated every frame, producing live PBR values (baseColor, metallic, roughness, emissive) that the viewport renderer uses instead of static material definitions.


initAnimatedMaterials

Summary: Initialize the animated material system. Scans all materials for animated node graphs and caches them.


tickAnimatedMaterials

Summary: Evaluate all animated material graphs for this frame. Call once per frame before rendering entities.


getAnimatedPBR

Summary: Get the current-frame animated PBR values for a material. Returns null if the material is not animated.


isAnimatedMaterial

Summary: Check if a material is registered as animated.


render/materials/BindGroupManager

Summary: BindGroupLayoutBuilder - Fluent API for building bind group layouts


FrameBindGroup

Summary: FrameBindGroup - Manages Group 0 (per-frame global data)


MaterialBindGroup

Summary: MaterialBindGroup - Manages Group 1 (per-material data)


ObjectBindGroup

Summary: ObjectBindGroup - Manages Group 2 (per-object data like transforms)


BindGroupCache

Summary: BindGroupCache - Caches bind groups to avoid recreation


createVoxelBindGroupLayouts

Summary: Create the standard voxel renderer bind group layouts


Summary: Bind group frequency tiers


render/materials/MaterialLibrary

Summary: MaterialLibrary.js - Material CRUD & Persistence Manages a collection of PBR material definitions. Each material has: - PBR scalar properties (metallic, roughness, emissive intensity) - Color values (baseColor, emissiveColor) - Texture slot paths (albedo, normal, metallicRoughness, emissive, ao) - Metadata (id, label, tags) Persists to localStorage and can export/import JSON.


writeMaterialLibraryRecord

writeMaterialLibraryRecord(materials, storage = globalThis.localStorage)


normalizeMaterial

Summary: Normalize a material descriptor, filling missing fields with defaults.


createMaterialLibrary

Summary: Create a MaterialLibrary instance.


render/materials/MaterialSystem


createMaterialSystem

createMaterialSystem(device, options = {})


render/materials/PipelineCache

Summary: PipelineCache.js - WebGPU Pipeline Caching and Specialization Implements: 1. Pipeline caching with composite keys (shader + overrides + render state) 2. Async pipeline compilation to prevent frame hitches 3. Pipeline specialization via override constants 4. Automatic pipeline invalidation on shader changes


RenderStateDescriptor

Summary: RenderStateDescriptor - Describes render pipeline state


PipelineDescriptor

Summary: PipelineDescriptor - Complete pipeline configuration


PipelineCache

Summary: PipelineCache - Caches compiled pipelines


ShaderModuleCache

Summary: ShaderModuleCache - Caches compiled shader modules


MaterialPipelineManager

Summary: MaterialPipelineManager - High-level material-to-pipeline management


render/materials/ShaderComposer

Summary: ShaderChunkRegistry - Central registry for shader code chunks