Files
2026-05-27 23:29:53 +01:00

96 lines
4.0 KiB
Markdown

# 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.