# Tasks: enterprise-network-governance **Change ID**: enterprise-network-governance **Package**: `@suaveplan/network-governance` **Target path**: `universal/network/network-governance` **Prerequisite packages on Verdaccio**: `@suaveplan/error`, `@suaveplan/types`, `@suaveplan/events`, `@suaveplan/logger`, `@suaveplan/rules` --- ## 1. Scaffold - [x] Create `universal/network/network-governance/` with `src/`, `tests/`, and all feature subdirectories. - [x] Write `package.json` at version `0.1.0`: `"sideEffects": false`, exports map, deps per `proposal.md`. - [x] Write `tsconfig.json`, `vitest.config.ts`, scripts. --- ## 2. Types and error codes - [x] Define all public types in `src/types/common.ts`: `NetworkPolicy`, `RateLimitPolicy`, `AccessControlPolicy`, `QuotaPolicy`, `CapabilityPolicy`, `GovernanceRequest`, `GovernanceDecision`, `AuditEntry`, `GovernanceEvent`, `GovernanceEngineOptions`. - [x] Write `src/types/common.md` (≥200 words, simple + advanced examples). - [x] Define error codes in `src/error-codes.ts`. - [x] Write Zod schemas for all policy types in `src/types/schemas.ts` + `src/types/schemas.md`. --- ## 3. Policy implementations (`src/policies/`) ### 3a. Rate limit policy - [x] Implement `evaluateRateLimitPolicy(policy, request, store, clock)`: - Sliding-window counter keyed by `policy.keyBy` field from request. - Increment counter; if count > `maxRequests`, return deny with `throttleMs` until window resets. - Use injectable `Clock` for window bounds. - [x] Write `rate-limit.test.ts` + `rate-limit.md`. ### 3b. Access control policy - [x] Implement `evaluateAccessControlPolicy(policy, request)`: - Check `denylist` first (explicit deny overrides). - Check `allowlist` next (explicit allow). - If `requireAuth` and no `peerId`/`userId`, deny. - [x] Write `access-control.test.ts` + `access-control.md`. ### 3c. Quota policy - [x] Implement `evaluateQuotaPolicy(policy, request, store, clock)`: - Track active connection count per key; deny if `maxConnections` exceeded. - Reset on `resetIntervalMs` using injectable `Clock`. - [x] Write `quota.test.ts` + `quota.md`. ### 3d. Capability policy - [x] Implement `evaluateCapabilityPolicy(policy, request)`: - Check if request `capabilities` includes ALL `policy.requiredCapabilities`. - If `policy.target` is set, only apply when `request.target` matches the pattern (exact or glob). - [x] Write `capability.test.ts` + `capability.md`. --- ## 4. Governance engine (`src/core/engine/`) - [x] Implement `createGovernanceEngine(options?)`: - Stores policies in a sorted array (descending by `priority`). - Maintains audit log as bounded ring buffer (`auditLogSize`, default 1000). - [x] Implement `engine.addPolicy(policy)` — validates with Zod; inserts in priority order. - [x] Implement `engine.removePolicy(id)`. - [x] Implement `engine.evaluate(request, signal?)`: - Check `signal.aborted`. - Iterate policies in priority order; evaluate via the appropriate evaluator. - First `deny` → short-circuit (deny wins over allow at same priority). - Collect `appliedPolicies`. - Write to audit log. - Emit event-bus event per decision type. - OTel: span `governance.evaluate`, counter `governance.decisions_total` (attribute: `allowed`). - [x] Implement `engine.getAuditLog(limit?)`. - [x] Write `engine.test.ts` (≤500 lines): allow, deny, throttle, multi-policy, priority ordering, audit log. - [x] Write `engine.md` (≥200 words). --- ## 5. Property-based tests (`tests/property.test.ts`) - [x] Deny always wins when a deny policy matches, regardless of allow policies. - [x] Rate-limit counter is monotonically non-decreasing per key within a window. --- ## 6. Docs and verify - [x] All per-file `.md` files per layout in `proposal.md`. - [x] `universal/network/network-governance/README.md`. - [x] `bunx turbo lint typecheck test test:coverage --filter=@suaveplan/network-governance` — all green, 100%. - [x] `bun scripts/publish.ts --package @suaveplan/network-governance`. - [x] Update `CLAUDE.md`. Archive change folder.