Initial Commit
This commit is contained in:
124
openspec/archive/2026-05-04-network-plugin-topology/proposal.md
Normal file
124
openspec/archive/2026-05-04-network-plugin-topology/proposal.md
Normal file
@@ -0,0 +1,124 @@
|
||||
# OpenSpec Change: network-plugin-topology
|
||||
|
||||
- **Change ID**: network-plugin-topology
|
||||
- **Package**: `@suaveplan/network-plugin-topology` (new)
|
||||
- **Status**: PROPOSED
|
||||
- **Type**: new-package
|
||||
- **Date**: 2026-04-29
|
||||
|
||||
## Why
|
||||
|
||||
The tiered network needs explicit topology management: promoting/demoting nodes across tiers, tracking group membership, and assigning nodes to latency groups. The genesis `fsm` and `events` packages provide primitives. This plugin implements the `HierarchicalTopologyImpl` (Tier 0 Host, Tier 1 SubHost, Tier 2 Leaf) and `LatencyAssigner` consumed by the `network-webrtc` mesh.
|
||||
|
||||
## What changes
|
||||
|
||||
- **ADDED**: `TopologyPlugin` class implementing `NetworkPlugin`.
|
||||
- **ADDED**: `HierarchicalTopologyImpl` — manages `Tier 0 → Tier 1 → Tier 2` hierarchy, promotion/demotion.
|
||||
- **ADDED**: `LatencyAssigner` — assigns peers to latency groups based on RTT, rebalances periodically.
|
||||
- **ADDED**: `GroupManager` — tracks group membership, handles join/leave.
|
||||
- **ADDED**: `NETWORK_TOPO_CODES` — frozen error registry.
|
||||
|
||||
## Out of scope
|
||||
|
||||
- Global topology view across many groups → deferred to federation layer.
|
||||
- Persistent topology state → future `network-plugin-topology-persistence`.
|
||||
|
||||
## Source mapping
|
||||
|
||||
This change derives from `../suaveplan/enterprise/network-topology.md` and `../suaveplan/packages/universal/network-topology/`.
|
||||
|
||||
| Requirement | Source lines | Notes |
|
||||
|---|---|---|
|
||||
| Tier 0 Host, Tier 1 SubHost, Tier 2 Leaf | `network-topology/README.md` §HierarchicalTopologyImpl | verbatim |
|
||||
| Promotion/demotion | `network-topology/README.md` §HierarchicalTopologyImpl | verbatim |
|
||||
| Latency-based group assignment | `network-topology/README.md` §LatencyAssigner | verbatim |
|
||||
| Rebalancing | `network-topology/README.md` §LatencyAssigner | verbatim |
|
||||
|
||||
### Requirements with no source line
|
||||
|
||||
| Requirement | Justification |
|
||||
|---|---|
|
||||
| `TopologyPlugin` implements `NetworkPlugin` | Required to plug into `NetworkNode` |
|
||||
| Consumes `election:result` from bus | Loose coupling to governance plugin |
|
||||
| Consumes `peer:latency` from bus | Loose coupling to webrtc plugin |
|
||||
|
||||
## Verification approach
|
||||
|
||||
- `src/topology/topology.spec-conformance.test.ts` — pins tier assignment, promotion, demotion.
|
||||
- `src/latency/latency.spec-conformance.test.ts` — pins group assignment, rebalancing, thresholds.
|
||||
- `src/group/group.spec-conformance.test.ts` — pins join/leave, membership tracking.
|
||||
- `tests/dep-graph.test.ts` — pins no direct import of webrtc or governance packages.
|
||||
|
||||
## Enhancement: Resource-Constrained Adaptation
|
||||
|
||||
**Source**: `docs/old-network-planning/ADAPT_3.md` §Resource Management, `PHASE_5.md` §Performance Metrics, `PLAN_ENHANCED_PHASE_5.md`
|
||||
|
||||
The topology must adapt to device capabilities:
|
||||
|
||||
- `DeviceProfiler` — classifies peers into profiles: `CONSTRAINED`, `STANDARD`, `POWERFUL`, `SERVER`.
|
||||
- `ResourceBalancer` — monitors CPU, memory, bandwidth utilization. Detects imbalances and recommends promotions/demotions.
|
||||
- `AdaptiveTierDepth` — adjusts maximum tier depth based on network size (logarithmic scaling) and available high-resource nodes.
|
||||
- `MessagePool` — reduces allocations for constrained devices via object pooling.
|
||||
- `ZeroCopyPassing` — where possible, passes message references instead of copying bytes between transport and protocol layers.
|
||||
- `BatteryAwareMode` — when `DeviceProfile` is `CONSTRAINED` and battery level is low, reduces heartbeat frequency, defers non-urgent reorganizations, and lowers transport retry aggression.
|
||||
- `BandwidthConservation` — `moderate` and `aggressive` modes that reduce gossip frequency, compress registry deltas more aggressively, and batch lower-priority messages.
|
||||
|
||||
## Enhancement: Tier Partition Handler
|
||||
|
||||
**Source**: `docs/old-network-planning/MODULAR_IMPLEMENTATION_PHASE_5.md` §TierPartitionHandler, `TIER_PARTITION_HANDLER_TEST_FIX_PLAN.md`
|
||||
|
||||
- `PartitionDetector` — builds connectivity map, detects isolated subgraphs via multi-factor analysis (heartbeat, path verification, consensus).
|
||||
- `PartitionManager` — allows partitions to function autonomously with local hierarchies. Tracks partition size, composition, resource distribution.
|
||||
- `PartitionRecovery` — controlled reconnection with prioritized sequence. Merges hierarchies using primary partition selection (size-based, performance-based, or hybrid).
|
||||
- `StateReconciliationOnMerge` — reconciles diverged states after partition healing.
|
||||
|
||||
## Enhancement: Geographic-Aware Routing
|
||||
|
||||
**Source**: `docs/old-network-planning/PLAN_ENHANCED_PHASE_5.md` §Geographic Optimization
|
||||
|
||||
- `GeoLocator` — tracks peer geographic region (inferred from latency or explicit metadata).
|
||||
- `RegionalClustering` — preferentially groups peers from same region.
|
||||
- `GeoLatencyOptimizer` — minimizes cross-region latency in parent-child assignments.
|
||||
|
||||
## Enhancement: Circuit Breaker & Hysteresis
|
||||
|
||||
**Source**: `docs/old-network-planning/PHASE_5.md` §Cascading Failure Prevention
|
||||
|
||||
- `ReorganizationCircuitBreaker` — pauses reorganizations during cascading failures:
|
||||
- Time-based: suspend for configurable period.
|
||||
- Count-based: limit reorganizations per time window.
|
||||
- Impact-based: evaluate disruption before proceeding.
|
||||
- `PromotionHysteresis` — cooldown periods after level changes to prevent oscillation.
|
||||
- `StabilityThreshold` — minimum stability period before promotion eligibility.
|
||||
|
||||
## Enhancement: Empty Tier Handling
|
||||
|
||||
**Source**: `docs/old-network-planning/PHASE_5.md` §Empty Tier Handling
|
||||
|
||||
- `EmptyTierDetector` — monitors node counts per tier.
|
||||
- `EmptyTierRemover` — removes empty tiers, reconnects adjacent levels, renumbers affected tiers.
|
||||
- `TierRenumberer` — updates level numbers and configurations consistently.
|
||||
|
||||
## Enhancement: Tiered Routing Rules
|
||||
|
||||
**Gap**: The topology plugin manages tiers but there is no specification for how messages flow between tiers. This enhancement adds explicit routing rules.
|
||||
|
||||
**Routing rules**:
|
||||
|
||||
1. **Leaf → Leaf (same mesh)**: Route through nearest common ancestor (Tier 1 or Tier 0). Direct leaf-to-leaf sends are disallowed unless the topology is flat (no Tier 1 sub-hosts).
|
||||
2. **Leaf → Host**: Direct if connected, else via Tier 1 sub-host.
|
||||
3. **Host → Leaf**: Forward through Tier 1 sub-hosts. Tier 0 does not flood all peers directly; it delegates to sub-hosts.
|
||||
4. **Broadcast**: Fan out from Tier 0 → Tier 1 → Tier 2 (tree broadcast, not mesh flood).
|
||||
5. **Cross-tier credential delegation**: Cross-tier operations require explicit credential delegation from a higher tier (enforced by `network-plugin-crypto-messages`).
|
||||
|
||||
**Components**:
|
||||
|
||||
- `TieredRouter` — implements the routing rules above. Consumes topology state and produces `nextHop` decisions.
|
||||
- `BroadcastTree` — builds a spanning tree from Tier 0 for mesh-wide broadcasts. Rebuilt on every `topology:changed` event.
|
||||
- `RouteCache` — caches frequently used `(sourceTier, targetTier, targetId) → nextHop` mappings. Invalidated on topology changes.
|
||||
|
||||
**Integration with partition plugin**: When `network-plugin-partition` detects a split, `TieredRouter` falls back to partition-local routing. When partitions heal, the broadcast tree is rebuilt.
|
||||
|
||||
## Migration impact
|
||||
|
||||
None — additive only.
|
||||
115
openspec/archive/2026-05-04-network-plugin-topology/tasks.md
Normal file
115
openspec/archive/2026-05-04-network-plugin-topology/tasks.md
Normal file
@@ -0,0 +1,115 @@
|
||||
# Tasks — network-plugin-topology
|
||||
|
||||
> Blocked on: `network-core`.
|
||||
|
||||
## 1. Scaffold
|
||||
|
||||
- [x] 1.1 `packages/network/network-plugin-topology/` with `package.json` (`@suaveplan/network-plugin-topology@0.0.0`), `tsconfig.json`, `vitest.config.ts`, `README.md`.
|
||||
- [x] 1.2 Workspace deps: `@suaveplan/network`, `@suaveplan/error`, `@suaveplan/types`, `@suaveplan/events`, `@suaveplan/fsm`, `@suaveplan/timing`, `@opentelemetry/api`, `zod`.
|
||||
- [x] 1.3 `sideEffects: false`.
|
||||
|
||||
## 2. Types
|
||||
|
||||
- [x] 2.1 `src/topology/hierarchical-topology.ts` exports `Tier`, `TopologyNode`, `HierarchicalTopologyConfig`, `TopologyBus`.
|
||||
- [x] 2.2 `src/latency/latency-assigner.ts` exports `LatencyBucket`, `LatencyAssignerConfig`, `LatencyBus`.
|
||||
- [x] 2.3 `src/group/group-manager.ts` exports `Group`, `GroupBus`, `GroupManagerConfig`.
|
||||
- [x] 2.4 `src/error-codes.ts` — `defineCodes("NET_TOPO", [...])`.
|
||||
|
||||
## 3. Hierarchical topology
|
||||
|
||||
- [x] 3.1 `src/topology/hierarchical-topology.ts` — `HierarchicalTopology`.
|
||||
- [x] 3.2 N-tier (operator-supplied `maxDepth`; not hard-coded to 3).
|
||||
- [x] 3.3 `promote(peerId, toTier)`, `demote(peerId, toTier)` with direction enforcement.
|
||||
- [x] 3.4 Emits `topology:change` on `NetworkBus`.
|
||||
|
||||
## 4. Latency assigner
|
||||
|
||||
- [x] 4.1 `src/latency/latency-assigner.ts` — `LatencyAssigner`.
|
||||
- [x] 4.2 Operator-supplied `LatencyBucket[]` (no built-in RTT thresholds).
|
||||
- [x] 4.3 Push-driven `record(peerId, latencyMs)` (consumer drives cadence; no internal timer).
|
||||
- [x] 4.4 Emits `latency:rebalance` on bus only when bucket changes.
|
||||
|
||||
## 5. Group manager
|
||||
|
||||
- [x] 5.1 `src/group/group-manager.ts` — `GroupManager`.
|
||||
- [x] 5.2 `defineGroup(groupId, capacity)`, `join(peerId)`, `leave(peerId)`, `removeGroup`.
|
||||
- [x] 5.3 Emits `group:membership` on bus.
|
||||
|
||||
## 6. Plugin wrapper
|
||||
|
||||
- [x] 6.1 `src/plugin/topology-plugin.ts` — `TopologyPlugin` implements `NetworkPlugin`.
|
||||
- [x] 6.2 Subscribes to `election:result`, `peer:latency` on bus.
|
||||
- [x] 6.3 Installs topology, latency, group managers on `install()`.
|
||||
|
||||
## 7. Spec
|
||||
|
||||
- [ ] 7.1 Update `openspec/specs/network/spec.md` with `NET-14`, `NET-15`. *(deferred — spec edits require a coordinated update to the network spec capability file)*
|
||||
|
||||
## 8. Conformance tests
|
||||
|
||||
- [x] 8.1 `src/topology/topology.spec-conformance.test.ts` — tier assignment, promotion, demotion.
|
||||
- [x] 8.2 `src/latency/latency.spec-conformance.test.ts` — bucket assignment, transitions, validation.
|
||||
- [x] 8.3 `src/group/group.spec-conformance.test.ts` — join/leave, membership tracking, capacity.
|
||||
- [x] 8.4 `src/error-codes.spec-conformance.test.ts` — frozen registry.
|
||||
|
||||
## 10. Resource-constrained adaptation
|
||||
|
||||
- [ ] 10.1 `src/resource/device-profiler.ts` — `DeviceProfiler`. *(deferred to follow-up `network-plugin-topology-resource`)*
|
||||
- [ ] 10.2 `src/resource/resource-balancer.ts` — `ResourceBalancer`. *(deferred)*
|
||||
- [ ] 10.3 `src/resource/adaptive-tier-depth.ts` — `AdaptiveTierDepth`. *(deferred — `HierarchicalTopology.observedMaxTier()` exposes the data this would consume)*
|
||||
- [ ] 10.4 `src/resource/message-pool.ts` — `MessagePool`. *(deferred)*
|
||||
|
||||
## 11. Tier partition handler
|
||||
|
||||
- [ ] 11.1 `src/partition/partition-detector.ts`. *(deferred — overlaps with shipped `@suaveplan/network-plugin-partition`; the boundary will be settled in a follow-up)*
|
||||
- [ ] 11.2 `src/partition/partition-manager.ts`. *(deferred)*
|
||||
- [ ] 11.3 `src/partition/partition-recovery.ts`. *(deferred)*
|
||||
- [ ] 11.4 `src/partition/state-reconciliation.ts`. *(deferred)*
|
||||
|
||||
## 12. Geographic-aware routing
|
||||
|
||||
- [ ] 12.1 `src/geo/geo-locator.ts`. *(deferred to `network-plugin-topology-geo`)*
|
||||
- [ ] 12.2 `src/geo/regional-clustering.ts`. *(deferred)*
|
||||
- [ ] 12.3 `src/geo/geo-latency-optimizer.ts`. *(deferred)*
|
||||
|
||||
## 13. Circuit breaker & hysteresis
|
||||
|
||||
- [ ] 13.1 `src/stability/reorganization-circuit-breaker.ts`. *(deferred to `network-plugin-topology-stability`; the existing `@suaveplan/network-plugin-circuit-breaker` covers per-path circuit-breaking already)*
|
||||
- [ ] 13.2 `src/stability/promotion-hysteresis.ts`. *(deferred)*
|
||||
- [ ] 13.3 `src/stability/stability-threshold.ts`. *(deferred)*
|
||||
|
||||
## 14. Empty tier handling
|
||||
|
||||
- [ ] 14.1 `src/tier/empty-tier-detector.ts`. *(deferred)*
|
||||
- [ ] 14.2 `src/tier/empty-tier-remover.ts`. *(deferred)*
|
||||
- [ ] 14.3 `src/tier/tier-renumberer.ts`. *(deferred)*
|
||||
|
||||
## 15. Spec
|
||||
|
||||
- [ ] 15.1 Update `openspec/specs/network/spec.md` with `NET-49`, `NET-50`, `NET-51`, `NET-52`. *(deferred — covers stretch features)*
|
||||
|
||||
## 16. Conformance tests
|
||||
|
||||
- [ ] 16.1 `src/resource/resource.spec-conformance.test.ts`. *(deferred with section 10)*
|
||||
- [ ] 16.2 `src/partition/partition.spec-conformance.test.ts`. *(deferred with section 11)*
|
||||
- [ ] 16.3 `src/geo/geo.spec-conformance.test.ts`. *(deferred with section 12)*
|
||||
- [ ] 16.4 `src/stability/stability.spec-conformance.test.ts`. *(deferred with section 13)*
|
||||
- [ ] 16.5 `src/tier/empty-tier.spec-conformance.test.ts`. *(deferred with section 14)*
|
||||
|
||||
## 17. Verify
|
||||
|
||||
- [x] 17.1 `bunx turbo lint typecheck test --filter=@suaveplan/network-plugin-topology` green.
|
||||
- [x] 17.2 `bunx turbo test:coverage --filter=@suaveplan/network-plugin-topology` 100/100/100/100.
|
||||
- [x] 17.3 `bun scripts/openspec-conformance.ts @suaveplan/network-plugin-topology` PASS.
|
||||
|
||||
---
|
||||
|
||||
## Audit Note (2026-05-04)
|
||||
|
||||
**Status**: PARTIAL — core sections (1–8, 17) shipped at full quality (100/100/100/100 coverage, 100% docs, openspec-conformance PASS). Stretch sections (10 resource adaptation, 11 partition handler, 12 geographic routing, 13 stability, 14 empty-tier handling) are deferred to follow-up changes because:
|
||||
|
||||
- Section 11 partition handling overlaps with `@suaveplan/network-plugin-partition` (shipped) and needs a coordinated boundary contract before duplicate work lands.
|
||||
- Section 13 stability overlaps with `@suaveplan/network-plugin-circuit-breaker` (shipped); the topology-specific reorganization breaker should be layered on top of the generic primitive rather than reinventing it.
|
||||
- Sections 10, 12, 14 are independent stretch features that benefit from being scoped as their own changes (`network-plugin-topology-resource`, `network-plugin-topology-geo`, `network-plugin-topology-stability`) so each can ship at the same quality bar without bloating the core topology surface.
|
||||
|
||||
The shipped core (`HierarchicalTopology`, `LatencyAssigner`, `GroupManager`, `TopologyPlugin`) is fully N-tier and fully operator-configurable — there are no built-in tier counts, tier names, or threshold defaults anywhere in the public API. The deferred stretch features can be added without breaking changes to the shipped surface.
|
||||
Reference in New Issue
Block a user