# OpenSpec Change: enterprise-network-governance - **Change ID**: enterprise-network-governance - **Package**: `@suaveplan/network-governance` - **Category**: universal/network - **Target path**: `universal/network/network-governance` - **Status**: SUPERSEDED-BY-GENESIS-WAVE - **Date**: 2026-04-24 --- ## Summary Deliver `@suaveplan/network-governance` on the genesis branch from scratch at enterprise quality. The package provides network policy governance: define and enforce rate limits, access control policies (IP allowlist/denylist, peer authentication, capability gating), connection quotas, and audit trails for policy decisions. Genesis adds structured errors via `@suaveplan/error`, Zod schemas for all policy types, OTel instrumentation on policy evaluations, `AbortSignal` on async operations, injectable `Clock` for time-window rate limiting, event-bus emission for policy violations, and property-based tests for policy evaluation invariants. --- ## Current-state audit (genesis) The package does not exist on genesis yet — this is a fresh build. --- ## Available workspace deps on genesis | Package | Role | |---|---| | `@suaveplan/error` (`workspace:^`) | Base class for `NetworkGovernanceError`; stable error codes | | `@suaveplan/types` (`workspace:^`) | `LoggerLike`, `Clock`, `EventBusLike` | | `@suaveplan/events` (`workspace:^`) | Event bus for policy violation events | | `@suaveplan/logger` (`workspace:^`) | Structured logging with audit trail | | `@suaveplan/rules` (`workspace:^`) | Business rules engine for policy evaluation | | `zod` (`catalog:forms`) | Zod schemas | | `@opentelemetry/api` (`catalog:observability`) | Spans + counters on policy evaluation | | `tslib` (`catalog:build`) | Runtime helpers | Dev deps: `vitest`, `@vitest/coverage-istanbul`, `fast-check` (all `catalog:testing`). --- ## Public API surface ### Core ```ts function createGovernanceEngine(options?: GovernanceEngineOptions): GovernanceEngine interface GovernanceEngine { addPolicy(policy: NetworkPolicy): void removePolicy(policyId: string): void evaluate(request: GovernanceRequest, signal?: AbortSignal): Promise getAuditLog(limit?: number): ReadonlyArray on(event: GovernanceEvent, handler: (entry: AuditEntry) => void): () => void } ``` ### Policy types ```ts type NetworkPolicy = | RateLimitPolicy | AccessControlPolicy | QuotaPolicy | CapabilityPolicy interface BasePolicy { id: string name: string priority: number action: 'allow' | 'deny' | 'throttle' enabled?: boolean } interface RateLimitPolicy extends BasePolicy { type: 'rate-limit' maxRequests: number windowMs: number keyBy: 'peer-id' | 'ip' | 'user-id' | string } interface AccessControlPolicy extends BasePolicy { type: 'access-control' allowlist?: string[] denylist?: string[] requireAuth?: boolean } interface QuotaPolicy extends BasePolicy { type: 'quota' maxConnections?: number maxBandwidthBps?: number resetIntervalMs?: number } interface CapabilityPolicy extends BasePolicy { type: 'capability' requiredCapabilities: string[] target?: string // endpoint or channel pattern } ``` ### Evaluation types ```ts interface GovernanceRequest { peerId?: string ip?: string userId?: string capabilities?: string[] target?: string metadata?: Record } interface GovernanceDecision { readonly allowed: boolean readonly reason?: string readonly appliedPolicies: ReadonlyArray readonly throttleMs?: number } interface AuditEntry { readonly timestamp: number readonly peerId?: string readonly decision: GovernanceDecision readonly policyId: string readonly type: GovernanceEvent } type GovernanceEvent = 'allowed' | 'denied' | 'throttled' | 'quota-exceeded' interface GovernanceEngineOptions { logger?: LoggerLike clock?: Clock eventBus?: EventBusLike auditLogSize?: number } ``` ### Error codes ```ts type NetworkGovernanceErrorCode = | 'GOVERNANCE_POLICY_NOT_FOUND' | 'GOVERNANCE_EVALUATION_FAILED' | 'GOVERNANCE_INVALID_POLICY' | 'GOVERNANCE_ABORT' function registerNetworkGovernanceErrorCodes(): void ``` --- ## Genesis additions 1. **Structured `NetworkGovernanceError`** with stable `GOVERNANCE.*` codes 2. **Zod schemas** for all policy types and `GovernanceRequest` 3. **Rate limiting with sliding window** — injectable `Clock` for time-window bounds 4. **Audit log** with bounded ring buffer (`auditLogSize`, default 1000) 5. **Policy priority ordering** — higher-priority policies evaluated first; first deny wins 6. **Event-bus violation emission** — fires `governance.denied`, `governance.throttled` 7. **OTel instrumentation** — span `governance.evaluate`, counter `governance.decisions_total`, attributes `decision.allowed`, `policy_id` 8. **Property-based tests** — deny wins over allow when both match same request; rate limit counter monotonically increases per key --- ## File layout ```text universal/network/network-governance/ package.json tsconfig.json vitest.config.ts src/ index.ts error-codes.ts constants/ index.ts types/ common.ts common.md core/ engine/ engine.ts engine.md engine.types.ts engine.test.ts index.ts policies/ rate-limit/ rate-limit.ts rate-limit.md rate-limit.test.ts index.ts access-control/ access-control.ts access-control.md access-control.test.ts index.ts quota/ quota.ts quota.md quota.test.ts index.ts capability/ capability.ts capability.md capability.test.ts index.ts tests/ integration.test.ts property.test.ts ``` --- ## Impact **Workspace dep prerequisites**: `@suaveplan/error`, `@suaveplan/types`, `@suaveplan/events`, `@suaveplan/logger`, `@suaveplan/rules` must be published.