--- status: draft last_updated: 2026-05-25 --- # Package Boundaries ## Overview This repository is `@alkdev/hub` — the hub API server. Spokes are separate packages/repos that connect to the hub via WebSocket. Published `@alkdev/*` packages are platform-agnostic npm dependencies. ``` @alkdev/hub → @alkdev/operations, @alkdev/pubsub, @alkdev/taskgraph, @alkdev/flowgraph (spoke) → @alkdev/operations, @alkdev/pubsub hub ←/→ (spoke) (communicate via call protocol over WebSocket) ``` ## This Package: `@alkdev/hub` The API server. Uses `@alkdev/operations`, `@alkdev/pubsub`, `@alkdev/taskgraph`, and `@alkdev/flowgraph` for operations, pubsub, call protocol, and task/workflow graph management. Adds HTTP serving, persistence, and coordination. **Modules** (to be implemented): - HTTP server (Hono) — serves API endpoints, MCP endpoint, WebSocket upgrade - Storage (Drizzle+Postgres) — all persistent tables, migrations, relations - Auth (keypal) — API key management, bearer token validation - OpenAI proxy — LLM provider proxy, key management, rate limiting - Coordination — coord.spawn/status/message/notify/abort/detect operations - Agent sessions (AI SDK) — session management, message persistence, tool routing - Call graph — runtime call graph tracking, observability - Spoke management — RunnerPool, registration, dispatch, heartbeat - Config — encrypted config loading, key ring management - Crypto — AES-256-GCM encryption, PBKDF2 key derivation **Dependencies**: `@alkdev/operations`, `@alkdev/pubsub`, `@alkdev/taskgraph`, `@alkdev/flowgraph`, `@alkdev/typebox`, `@alkdev/drizzlebox`, Hono, Drizzle+pg, ioredis, AI SDK, keypal, @hono/mcp **Does NOT depend on**: Any spoke package — spokes are standalone repos that connect to the hub. ## External @alkdev Packages ### `@alkdev/operations` (npm, v0.1.0) Shared operations and call protocol. Platform-agnostic. Used by both hub and spokes. **Exports**: - `.` — Core: types (OperationType, Identity, OperationContext, AccessControl, ErrorDefinition, IOperationDefinition, OperationSpec), registry, call protocol (PendingRequestMap, buildCallHandler, CallEventSchema, subscribe), access control (checkAccess, enforceAccess), error (CallError, InfrastructureErrorCode, mapError), env (buildEnv), scanner (scanOperations), validation (assertIsSchema, validateOrThrow, collectErrors), from_schema (FromSchema), response-envelope (ResponseEnvelope, localEnvelope, httpEnvelope, mcpEnvelope, unwrap, isResponseEnvelope) - `./from-mcp` — MCP tool adapter (optional peer: @modelcontextprotocol/sdk) - `./from-typemap` — Zod/Valibot schema adapters (optional peer: @alkdev/typemap) - `./from-openapi` — OpenAPI/SSE/HTTP service adapter **Dependencies**: `@alkdev/typebox`, `@alkdev/pubsub`, `@logtape/logtape` ### `@alkdev/pubsub` (npm, v0.1.0) PubSub, event targets, and operators. Platform-agnostic. **Exports**: - `.` — Core: createPubSub, types, operators, Repeater (inlined) - `./event-target-redis` — Redis adapter (optional peer: ioredis) - `./event-target-websocket-client` — Spoke-side WebSocket adapter - `./event-target-websocket-server` — Hub-side WebSocket adapter - `./event-target-worker` — Web Worker adapter (host + thread sides) **Dependencies**: None (runtime). `ioredis` is optional peer for Redis event target. ### `@alkdev/taskgraph` (npm, v0.0.2) Task graph construction, analysis, and frontmatter parsing. **Exports**: - `.` — TaskGraph class (fromTasks, fromRecords, fromJSON), analysis functions, schema enums, frontmatter parsing **Dependencies**: `@alkdev/typebox`, `graphology`, `yaml` ### `@alkdev/flowgraph` (npm, v0.1.0) Workflow graph: DAG construction, ujsx templates, reactive execution, call/operation graphs. **Exports**: - `./graph` — FlowGraph class, node/edge attribute types - `./analysis` — typeCompat, buildTypeEdges, topologicalOrder, validateGraph - `./schema` — CallNodeAttrs, CallEdgeAttrs, OperationNodeAttrs, CallStatus, CallEventMapValue - `./reactive` — WorkflowReactiveRoot - `./component` — ujsx template components (Operation, Sequential, Parallel, Conditional, Map) **Dependencies**: `@alkdev/typebox`, `graphology`, `preact` ## Rules 1. **Published packages are platform-agnostic** — they don't know about HTTP, WebSocket, or Redis connections (only Redis *types* for the EventTarget). Connection management lives in this repo. 2. **Published packages are persistence-agnostic** — they don't import Drizzle or pg. Storage lives here. 3. **This repo does not depend on any spoke package** — spokes connect via the call protocol over WebSocket. 4. **Spokes don't need Redis** — Redis connections are hub-internal. Spokes communicate via WebSocket. 5. **Spokes don't need Postgres** — all persistent state lives in the hub. 6. **No circular deps** — dependency direction is always toward published packages. 7. **Published @alkdev/* packages must not import from @alkdev/hub.** 8. **Pin dependency versions** — use exact versions in deno.json, update manually when needed. ## Storage Location Decision Storage (Drizzle tables, migrations, client setup) lives in **this repo** (`src/storage/`). Rationale: - Storage requires runtime Postgres connections → hub concern - Storage schemas are hub-specific (sessions, mappings, spokes, call graphs) - Spokes are ephemeral and stateless — they don't persist anything - The `@alkdev/drizzlebox` pattern and all table schemas are documented in `docs/architecture/storage/`, the actual implementation is in `src/storage/`