Defines bounded, failure-safe application lifecycle behavior for resolving, initializing, joining, creating, serving, recreating, and stopping isolated swarm-managed subnets.
An application SHALL request a subnet using a valid descriptor, not a raw ID. The swarm SHALL derive the normative ID and request only addresses for it. Overlay results SHALL enter only an ephemeral typed unverified-target set for that subnet, preserving original URL and validated socket until compatibility. They MUST NOT enter URL-only persistent host/refinery state before success. Overlay and subnet connections MUST remain separate. Every subnet peer MUST independently pass magic-byte, application-name, and major/minor checks. An overlay channel MUST NOT be reused, transferred, re-handshaken, or multiplexed for subnet traffic. Default transient policy retains the overlay for the application session; immediate post-lookup/join stop requires explicit reduced-privacy policy and occurs after every caller-visible terminal outcome, not an internal lookup phase within join. Any overlay stop MUST NOT stop the independent subnet.
Resolution and connection phases SHALL have finite deadlines. A complete join deadline MUST be configurable and no greater than 900 seconds. Every untrusted candidate SHALL pass the overlay's resolution-time egress policy before connection and consume the configured resolution/dial concurrency, rate, per-destination, and total-candidate budgets. Rejected destinations SHALL remain fallible candidate failures and MUST NOT trigger a second resolution in the connector. Direct candidates SHALL retain the exact validated destination socket. Tor/I2P candidates SHALL retain the exact trusted locally configured proxy socket plus canonical hidden-service destination, with no local DNS or advertisement-selected proxy. Every accepted transport path SHALL reject malformed/unsupported input without unwind before or during compatibility.
Candidate ordering SHALL use two independently OsRng-shuffled bounded tiers:
at most 256 URLs from the bounded previously-compatible retry index and a
bounded reservoir sampled across the fresh terminal traversal through completion
or its fixed 16-page cap.
Persisted peers MUST be re-resolved and revalidated. After both tiers exist, the
candidate-preparation subdeadline SHALL use at most half the then-remaining
overall time and split resolution/validation time equally between tiers; unused
persisted time MAY pass to fresh, not conversely. A two-phase pre-start target
plan SHALL then split remaining dial time at a monotonic midpoint: persisted
targets stop/cancel by it and consume no more than their configured limit or half
the attempt budget; fresh targets activate for the second half. URL, wire, store,
hash, DNS-answer, and lexical order MUST NOT choose either attempted prefix.
Fresh candidates MUST NOT be persisted before compatibility succeeds.
Before each subnet attempt starts, the swarm SHALL invoke a fallible app
initializer with that attempt's P2p handle. It SHALL construct subnet-scoped
app state, register protocols, and return both caller-visible state and a
bounded shutdown hook. No listener, connection, or protocol job SHALL start
before success.
The registry SHALL retain ownership of the returned app state and shutdown hook for the active attempt's entire lifetime; dropping the caller handle MUST NOT drop required state. If initialization fails or is cancelled, partial state is released, nothing starts, and the original error is returned.
P2p::start() alone SHALL NOT complete join. Join succeeds only after an
ordinary inbound, outbound, or manual subnet channel passes the compatibility
handshake and remains registered as an ordinary peer. Temporary direct, seed,
and refinement channels MUST NOT complete join, even when their handshake
succeeds.
Until then the registry SHALL expose a distinct joining state. Timeout, cancellation, or candidate exhaustion SHALL stop tasks and connections, run the shutdown hook, remove the attempt, and return a typed error without panicking on untrusted input.
Applications SHALL select overlay-only, static-only, combined, or overlay-then-static behavior. Sources MUST NOT activate implicitly outside the selected policy.
P2p attempt. It SHALL rerun the
initializer for the fresh attempt and remain inside one overall deadline.No policy SHALL rely on runtime manual- or seed-session reload. Every source uses the same compatibility and ordinary-channel completion rule.
Each subnet SHALL have independent hostlists, refinement, app state, tasks, datastore, and hostlist files. Persistent paths SHALL be namespaced by full ID under a configured root. No state, address outcome, dispatch, or shutdown signal may cross subnets. Deleting one subnet MUST NOT alter another.
Overlay role persistence rules apply only to overlay-owned state. Applications MAY separately configure subnet persistence for a transient overlay participant; such paths reveal local subnet history and MUST be documented. Private secrets MUST NOT be logged.
A subnet SHALL be created either join-only or serving. Serving creation SHALL require a persistent overlay role, at least one local listener bind address, and at least one externally advertised endpoint assigned to that subnet. Bind addresses and advertised endpoints SHALL be separate fields and MUST NOT be assumed identical. All addresses SHALL be validated before network start.
Serving initialization SHALL configure listeners before P2p::start(). It
completes when app initialization succeeds and required listeners bind; it does
not require an existing peer. This permits the first member of a new subnet to
serve. It may attempt peer discovery afterward under an explicit source policy.
A transient SHALL reject serving before any network activity.
Before initializer, listener, or author activation, serving SHALL atomically allocate or reuse one 256-slot local-author reserve partition for the subnet. If all configured partitions are occupied by subnets with protected local IDs, serving SHALL fail with a typed capacity error. A newly allocated empty partition SHALL be released on pre-authoring initialization/bind failure. Stopping serving SHALL retain a nonempty partition until all protected local IDs expire, then release it only if the subnet has not resumed serving.
An already started join-only subnet MUST NOT be promoted by mutating inbound settings and calling session reload. Promotion SHALL require a controlled stop/recreate operation: stop the joined instance completely, then create a new serving-configured instance and rerun initialization. The operation SHALL be serialized with other lifecycle actions and return a typed result if recreation fails. Retained state MAY be reused only from that subnet's namespace.
Listener binds and externally advertised endpoints MUST remain distinct. Swarm SHALL NOT claim automatic Tor or I2P identity provisioning. Reusing one advertised endpoint across local subnets SHALL produce an explicit linkability warning.
Join-only subnets SHALL author no ads. A successfully serving subnet SHALL author bounded ads only on the overlay jittered cadence and only with its advertised endpoints. Initialization, listener readiness, peer connection, recreation, and new overlay channels MUST NOT emit immediately. Stopping serving SHALL cease future authoring without a withdrawal.
Leave SHALL disable authoring, stop network producers/channels/protocol jobs, run app shutdown, and remove registry ownership. It MUST emit no withdrawal. Repeated leave SHALL be idempotent. Same-subnet join, serve, recreate, leave, and delete operations SHALL have one serialized owner.
The caller SHALL choose to retain or delete namespaced state after shutdown. Deletion MUST occur only after stop and affect only that ID.
Different subnets MAY transition concurrently; one ID SHALL have one owner. Duplicate joins MUST NOT create duplicate instances. Swarm shutdown SHALL stop authoring, cancel attempts, stop every subnet despite individual failures, and stop the overlay last within a finite deadline.
Applications SHALL pin public descriptors with golden IDs and accept valid private descriptors. Private secrets MUST NOT be logged, advertised, sent in lookup, or exposed by public status; overlay messages use only the derived ID. Possession of the descriptor SHALL NOT bypass compatibility or app-level authorization.