5.6 KiB
OpenSpec Change: network-bootstrap
- Change ID: network-bootstrap
- Package:
@suaveplan/network-bootstrap - Category: universal
- Target path:
packages/network/network-bootstrap - Status: PROPOSED
- Date: 2026-05-11
- Parent:
network-transport-family(2026-05-11) — Wave 1 - Migration source:
../suaveplan/packages/universal/network-bootstrap+../suaveplan/enterprise/network-bootstrap.md
Summary
Migrate @suaveplan/network-bootstrap into genesis as a universal-tier plugin providing initial-peer discovery and bootstrap orchestration for the @suaveplan/network mesh. Upstream ships at 99.15% coverage with a working BootstrapPlugin, discovery-chain, peer cache, and bootstrap middleware. This migration ports the full surface, hardens it against genesis primitives (@suaveplan/retry, @suaveplan/events, @suaveplan/types, OTel), and converts upstream export * barrels to explicit named exports per AGENTS.md §6a.
network-bootstrap is Wave 1 of the network migration sequence because every concrete transport in Waves 3–4 (hyperswarm, libp2p, gundb, …) consumes a bootstrap chain to find initial peers. Landing it first unblocks every downstream transport.
Why this is needed
@suaveplan/network ✅ defines NetworkPlugin lifecycle and NetworkBus but does NOT define how a freshly-started node finds its first peers. Today every transport would have to roll its own initial-peer logic — duplicated code and inconsistent retry/cache semantics. network-bootstrap is the canonical place: pluggable discovery chain, exponential-backoff retries, persistent peer cache, deterministic peer selection.
Current-state audit
Upstream surface (../suaveplan/packages/universal/network-bootstrap/src/):
core/discovery-chain/— ordered chain ofDiscoveryStrategyimplementations, first-match-wins with fallthroughcore/peer-cache/— persistent cache of known-good peer endpoints (TTL + eviction)plugin/bootstrap-plugin/—NetworkPluginwrapper that wires the discovery chain into node startupplugin/bootstrap-middleware/— middleware hook for runtime augmentation of the chaintypes/bootstrap.types.ts—DiscoveryStrategy,BootstrapResult,PeerCacheEntry, options
Upstream coverage: 99.15% statement, no E2E. Upstream depends on its own ad-hoc retry/event utilities that genesis already replaces.
Parity Checklist
| Capability | Upstream | Migrated | Notes |
|---|---|---|---|
DiscoveryStrategy interface |
✅ | ✅ | Re-exported from @suaveplan/types if shared, else local. |
DiscoveryChain ordered execution |
✅ | ✅ | First-success-wins, configurable fallthrough on error vs. empty result. |
PeerCache with TTL + eviction |
✅ | ✅ | Backed by @suaveplan/storage AbstractStorage (universal); upstream's bespoke cache replaced. |
BootstrapPlugin (NetworkPlugin lifecycle) |
✅ | ✅ | install/start/stop/dispose per @suaveplan/network's contract. |
| Bootstrap middleware hook | ✅ | ✅ | Runtime augmentation of chain order/contents. |
| Retry with backoff | ✅ (ad-hoc) | ⬆️ | Replaced with @suaveplan/retry RetryPolicy + jitter. |
| Bus events on join/fail | ✅ (ad-hoc) | ⬆️ | Replaced with @suaveplan/events NetworkBus topics (bootstrap:started, :peer-found, :exhausted). |
| Structured errors | 🚫 (plain Error) | ⬆️ | defineCodes("NET_BOOTSTRAP", [...]) per AGENTS.md. Codes: CHAIN_EXHAUSTED, CACHE_CORRUPTED, STRATEGY_TIMEOUT, INVALID_OPTIONS. |
| Zod boundary validation | 🚫 | ⬆️ | Every public option struct gets a Zod schema. |
| OTel instrumentation | 🚫 | ⬆️ | Spans (bootstrap.chain.execute), counters (bootstrap.peers_found_total{strategy}, bootstrap.failures_total{strategy,code}), histograms (bootstrap.chain_duration_ms). |
| AbortSignal support | 🚫 | ⬆️ | Threaded through every async path. |
export * barrels |
✅ (some) | ⬆️ | Converted to explicit named exports per AGENTS.md §6a. |
| Test-runner imports | direct vitest | ⬆️ | Rewritten to @suaveplan/testing/runner per AGENTS.md §7. |
| 100% test coverage | 🚫 (99.15%) | ⬆️ | Bring to 100/100/100/100 per CLAUDE.md gate. |
| Property tests | 🚫 | ⬆️ | fast-check property suite on chain ordering + cache eviction. |
| Storybook stories | 🚫 (no UI) | 🚫 | Not applicable — universal-tier, no UI surface. |
No upstream capability is dropped without uplift.
Available workspace deps on genesis
@suaveplan/network✅ —NetworkPlugin,NetworkBus,MessageEnvelope@suaveplan/types✅ — shared interfaces (Clock,Rng, etc.)@suaveplan/error✅ —defineCodes,SuaveplanError@suaveplan/events✅ — typed event bus@suaveplan/retry✅ — backoff strategies + circuit breaker@suaveplan/storage✅ —AbstractStoragefor the peer cache backing@suaveplan/testing✅ — runner-agnostic test utilities + runner wrapper
All deps present; no blocking gaps.
Acceptance gate
bunx turbo lint typecheck test --filter=@suaveplan/network-bootstrapgreen.bunx turbo test:coverage --filter=@suaveplan/network-bootstrapat 100/100/100/100.bun run docs:check --filter=@suaveplan/network-bootstrapgreen (every.tshas a sibling.md).MANIFEST.mdregen confirms dep graph has no cycles.STATUS.mdrow flipped from–to✅.
Out of scope
- Concrete discovery strategies for individual transports — those ship with their owning
network-discovery-*packages (Wave 2). - Server-tier daemons — separate
network-*-serverpackages (Wave 5).