Align storage & architecture specs with published npm libraries
Systematically compared @alkdev/taskgraph, @alkdev/operations, and
@alkdev/flowgraph against storage/arch specs and fixed all mismatches.
Key changes:
Tasks (storage/tasks.md + ADR-011):
- Rename TaskFrontmatter → TaskInput to match library export
- Fix dependsOn (was depends_on) in field mappings — library uses
camelCase; parseFrontmatter normalizes YAML snake_case on input
- Document DependencyEdge shape {from, to, qualityRetention?} and
DB↔library field mapping
- Document graph node vs DB column distinction (TaskGraphNodeAttrs
is a subset of TaskInput)
- Fix default risk fallback from low → medium (matches resolveDefaults)
- Fix cross-project guard column references (dependentTaskId, not taskId)
- Clarify @alkdev/taskgraph TS is source of truth; frontmatter is for
LLM output parsing and legacy imports, not Rust CLI
- Add complete library exports reference
Operations (storage/spokes.md + operations.md):
- Add version, title, _meta columns to operations table (required by
OperationSpec, were missing)
- Fix type casing: query/mutation/subscription (lowercase, matching
OperationType runtime values)
- Make outputSchema and accessControl NOT NULL (matching library)
- Document ErrorDefinition shape {code, description, schema, httpStatus?}
- Document _meta vs commonCols.metadata distinction
- Add registerAll, get, getHandler, getByName, list, subscribe methods
- Fix buildCallHandler signature ({ registry, callMap })
- Fix OperationType values (lowercase)
Call graph (storage/call-graph.md + call-graph.md):
- Change operationId to NOT NULL with RESTRICT FK (was nullable/SET NULL)
— matches flowgraph's required CallNodeAttrs.operationId
- Document sentinel __removed__ operation strategy for deletions
- Document ISO 8601 string ↔ timestamptz conversion requirement
- Rewrite CallEventMap to match actual library: flat dot-notation keys,
timestamp on all events, nested error structure, optional output on
completed event
- Remove call.running event (doesn't exist in library) — hub calls
updateStatus(running) directly on dispatch
- Fix buildCallHandler({ registry, callMap }) signature
- Fix PendingRequestMap constructor (positional EventTarget)
- Add updateCall/removeCall/graph methods to API summary
- Document abort cascade as hub logic, not flowgraph logic
- Add open questions for operation deletion and reactive vs call graph
semantics
Table reference (storage/table-reference.md):
- Update call_graph_nodes.operationId cascade to RESTRICT
- Update operations.type comment to lowercase
- Update status enum reference
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
---
|
||||
status: draft
|
||||
last_updated: 2026-05-18
|
||||
last_updated: 2026-05-25
|
||||
---
|
||||
|
||||
# Operations System
|
||||
@@ -15,25 +15,30 @@ The operations system is the universal abstraction for all work in the alk.dev p
|
||||
|
||||
### Core Types (`operations/types.ts`)
|
||||
|
||||
- `OperationType` — QUERY (read-only), MUTATION (write), SUBSCRIPTION (async generator)
|
||||
- `OperationSpec` — serializable, hashable subset (name, namespace, version, type, description, tags, inputSchema, outputSchema, errorSchemas, accessControl, \_meta)
|
||||
- `OperationType` — `QUERY = "query"`, `MUTATION = "mutation"`, `SUBSCRIPTION = "subscription"` (enum names uppercase, string values lowercase)
|
||||
- `OperationSpec` — serializable, hashable subset (name, namespace, version, type, description, title?, tags?, inputSchema, outputSchema, errorSchemas?, accessControl, _meta?)
|
||||
- `IOperationDefinition` — extends `OperationSpec` with runtime `handler`
|
||||
- `OperationContext` — metadata, requestId, parentRequestId, identity, env
|
||||
- `AccessControl` — requiredScopes (all match), requiredScopesAny (any match), resourceType, resourceAction. See below.
|
||||
- `ResponseEnvelope<T>` — universal result wrapper with source tracking (local/http/mcp). All `execute()` and `env` functions return `ResponseEnvelope<T>`.
|
||||
- `CallError` / `InfrastructureErrorCode` — structured error codes: `OPERATION_NOT_FOUND`, `ACCESS_DENIED`, `VALIDATION_ERROR`, `TIMEOUT`, `ABORTED`, `EXECUTION_ERROR`, `UNKNOWN_ERROR`.
|
||||
- `ErrorDefinition` — structured error schema declaration: `{ code: string, description: string, schema: unknown, httpStatus?: number }`
|
||||
|
||||
### Registry (`operations/registry.ts`)
|
||||
|
||||
- Register by `{namespace}.{name}` key
|
||||
- `register()` now accepts `OperationSpec & { handler? }` (handler can be registered separately)
|
||||
- `register()` accepts `OperationSpec & { handler? }` (handler can be registered separately)
|
||||
- `registerSpec()` / `registerHandler()` — separate spec and handler registration
|
||||
- `registerAll(definitions)` — bulk registration
|
||||
- `execute()` returns `Promise<ResponseEnvelope<TOutput>>` (not `Promise<TOutput>`)
|
||||
- Constructor accepts optional `SchemaAdapter` for Zod/Valibot conversion
|
||||
- Access control is enforced in the registry (via `enforceAccess`)
|
||||
- Validate input before handler execution
|
||||
- Warn on output schema mismatch (don't throw)
|
||||
- `getSpec()` / `getAllSpecs()` for serializable specs
|
||||
- `get(name)` / `getByName(namespace, name)` — retrieve definitions
|
||||
- `getHandler(name)` — retrieve handler function
|
||||
- `list()` — list all registered operation names
|
||||
|
||||
### Scanner (`operations/scanner.ts`)
|
||||
|
||||
@@ -51,6 +56,7 @@ The operations system is the universal abstraction for all work in the alk.dev p
|
||||
- Sets `trusted: true` on nested context (bypasses access control for internal calls)
|
||||
- Env functions return `Promise<ResponseEnvelope>`, callers use `unwrap(envelope)` or `envelope.data`
|
||||
- Filters SUBSCRIPTION operations out of env
|
||||
- `subscribe(registry, operationId, input, context)` — standalone function for subscription operations
|
||||
|
||||
### FromSchema (`operations/from_schema.ts`)
|
||||
|
||||
@@ -119,7 +125,7 @@ Operations use `buildEnv()` which supports direct mode (see call-graph.md):
|
||||
|
||||
- **Direct mode**: `buildEnv({ registry, context })` → env functions call `registry.execute()`
|
||||
|
||||
The call protocol (PendingRequestMap, CallHandler) is part of `@alkdev/operations`. It provides call graph tracking, abort cascading, and structured error handling across all transports. See call-graph.md for the full spec.
|
||||
The call protocol (PendingRequestMap, CallHandler) is part of `@alkdev/operations`. It provides call graph tracking, abort cascading, and structured error handling across all transports. The `buildCallHandler({ registry, callMap })` creates a `CallHandler` that subscribes to `call.requested` events on the `callMap` (a `PendingRequestMap`), enforces access control, and dispatches via `registry.execute()`. See call-graph.md for the full spec.
|
||||
|
||||
## How It Connects to Everything Else
|
||||
|
||||
|
||||
Reference in New Issue
Block a user