# Tasks: enterprise-network-registry **Change ID**: enterprise-network-registry **Package**: `@suaveplan/network-registry` **Target path**: `universal/network/network-registry` **Prerequisite packages on Verdaccio**: `@suaveplan/error`, `@suaveplan/types`, `@suaveplan/events`, `@suaveplan/logger` --- ## 1. Scaffold - [x] Create `universal/network/network-registry/` 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`: `RegistryEntry`, `HealthStatus`, `RegistrationHandle`, `RegistryQuery`, `RegistryFilter`, `RegistryChangeHandler`, `RegistryChange`, `NetworkRegistryOptions`. - [x] Write `src/types/common.md` (≥200 words, simple + advanced examples). - [x] Define error codes in `src/error-codes.ts`. - [x] Write Zod schemas in `src/types/schemas.ts` + `src/types/schemas.md`. --- ## 3. TTL manager (`src/core/ttl-manager/`) - [x] Implement `createTtlManager(clock)`: - Tracks `expiresAt` per entry. - `isExpired(entry)` — compare against `clock.now()`. - `purge(entries)` — returns list of expired entry IDs. - Runs GC on `gcIntervalMs` interval via injectable timer. - [x] Write `ttl-manager.test.ts` + `ttl-manager.md`. --- ## 4. Query engine (`src/core/query-engine/`) - [x] Implement `evaluateQuery(entry: RegistryEntry, query: RegistryQuery): boolean`: - `type`: match entry type (array = OR, string = exact). - `capabilities` (AND): entry must have ALL capabilities. - `anyCapabilities` (OR): entry must have AT LEAST ONE. - `tags`: all key/value pairs must match. - `region`: exact match. - `healthyOnly`: entry.health.healthy must be true. - [x] Implement `runQuery(entries: RegistryEntry[], query: RegistryQuery): RegistryEntry[]`: - Filter via `evaluateQuery`, sort by latency (lowest first), apply `limit`. - [x] Write `query-engine.test.ts` (≤500 lines): each filter type, AND/OR capabilities, limit. - [x] Write `query-engine.md` (≥200 words). --- ## 5. Network registry (`src/core/registry/`) - [x] Implement `createNetworkRegistry(options?)`: - Validates options with Zod. - Stores entries in `Map`. - Wires TTL manager for expiry. - Stores subscriptions as `Array<{ query: RegistryQuery; handler: RegistryChangeHandler }>`. - [x] Implement `registry.register(entry)`: - Validate with Zod; throw `REGISTRY_INVALID_ENTRY` on schema failure. - Throw `REGISTRY_DUPLICATE_ID` if already registered. - Check `maxEntries`; throw `REGISTRY_CAPACITY_EXCEEDED` if at limit. - Compute `expiresAt = clock.now() + (entry.ttlMs ?? options.ttlDefaultMs)`. - Return `RegistrationHandle` with `renew()` and `deregister()`. - Emit event-bus `registry.registered` event; notify matching subscriptions. - OTel: counter `registry.register_total`. - [x] Implement `registry.deregister(id)` — remove; emit `registry.deregistered`; notify subscriptions. - [x] Implement `registry.lookup(query)` — delegates to query engine; OTel counter `registry.lookup_total`, histogram `registry.lookup_results`. - [x] Implement `registry.get(id)` — direct lookup; throws `REGISTRY_EXPIRED` if TTL elapsed. - [x] Implement `registry.list(filter?)` — returns all non-expired entries matching optional filter. - [x] Implement `registry.updateHealth(id, status)` — updates health; emits `health-changed`. - [x] Implement `registry.subscribe(query, handler)` — returns unsubscribe. - [x] Implement `registry.purgeExpired()` — delegates to TTL manager; emits `expired` for each. - [x] Write `registry.test.ts` (≤500 lines): register, lookup, health update, TTL expiry, subscription notification, capacity exceeded. - [x] Write `registry.md` (≥200 words). --- ## 6. Property-based tests (`tests/property.test.ts`) - [x] `lookup(q)` results are always a subset of `list()`. - [x] After `purgeExpired()`, no expired entries remain in `list()`. - [x] `capabilities` AND: result set is always subset of result with only one capability filter. --- ## 7. Docs and verify - [x] All per-file `.md` files per layout in `proposal.md`. - [x] `universal/network/network-registry/README.md`. - [x] `bunx turbo lint typecheck test test:coverage --filter=@suaveplan/network-registry` — all green, 100%. - [x] `bun scripts/publish.ts --package @suaveplan/network-registry`. - [x] Update `CLAUDE.md`. Archive change folder.