tasks: add drift sync tasks to align source with architecture specs

This commit is contained in:
2026-05-29 10:41:15 +00:00
parent 62f8da8ec4
commit 2b0badd501
9 changed files with 418 additions and 0 deletions

View File

@@ -0,0 +1,38 @@
---
id: drift/any-to-unknown
name: Replace Type.Any() with Type.Unknown() across all source files
status: pending
depends_on: []
scope: narrow
risk: trivial
impact: component
level: implementation
---
## Description
The architecture spec (metagraph-module.md, ADR-012) mandates `Type.Unknown()` as the canonical choice for "no validation applied" fields, not `Type.Any()`. Both produce `{}` in JSON Schema, but `Type.Unknown()` explicitly communicates intent. There are 6 locations in the source that use `Type.Any()` where the spec says `Type.Unknown()`.
This is a mechanical find-and-replace with no behavioral change — `Type.Any()` and `Type.Unknown()` produce identical JSON Schema output (`{}`).
## Acceptance Criteria
- [ ] `src/graphs/types.ts`: `metadata` fields in `BaseNodeAttributes` and `BaseEdgeAttributes` use `Type.Unknown()` instead of `Type.Any()`
- [ ] `src/graphs/types.ts`: `schema` fields in `NodeType` and `EdgeType` use `Type.Unknown()` instead of `Type.Any()`
- [ ] `src/sqlite/tables/nodes.ts`: `AttributesSchema` uses `Type.Record(Type.String(), Type.Unknown())` instead of `Type.Any()`
- [ ] `src/sqlite/tables/edges.ts`: `AttributesSchema` uses `Type.Record(Type.String(), Type.Unknown())` instead of `Type.Any()`
- [ ] `deno check mod.ts src/graphs/mod.ts src/sqlite/mod.ts` passes with no errors
- [ ] No remaining `Type.Any()` calls in `src/` (verified via grep)
## References
- docs/architecture/metagraph-module.md — "Type.Unknown() is canonical"
- docs/architecture/decisions/012-node-edge-attributes-as-module-entries.md
## Notes
> To be filled by implementation agent
## Summary
> To be filled on completion

View File

@@ -0,0 +1,53 @@
---
id: drift/bridge-functions
name: Create bridge.ts with moduleToDbSchema, validateNode, validateEdge
status: pending
depends_on:
- drift/metagraph-module
scope: moderate
risk: medium
impact: component
level: implementation
---
## Description
Create the bridge between TypeBox Modules and database row values. The `moduleToDbSchema()` function projects a graph type Module to DB row values for the metagraph tables. The `validateNode()` and `validateEdge()` functions validate data against Module entries.
This is Phase 2 of the metagraph-module.md implementation path.
Per the spec, `moduleToDbSchema()` takes a `TModule` and returns a `DbSchema` with:
- `graphType: DbGraphTypeRow` — name from Module name, config from Config entry
- `nodeTypes: DbNodeTypeRow[]` — one per `*Node` entry, name = entry name minus suffix
- `edgeTypes: DbEdgeTypeRow[]` — one per `*Edge` entry, with constraint data from `*EdgeConstraints` entries
The function must enforce the entry naming convention (`*Node`, `*Edge`, `Config`, `*EdgeConstraints`, `*Enum`, `BaseNode`, `BaseEdge`) and throw on:
- Entries with unrecognized suffixes (bare names are treated as shared types, not DB rows)
- `*EdgeConstraints` entries referencing edge types not in the Module
- `*EdgeConstraints` with empty `allowedSourceTypes` AND `allowedTargetTypes`
- Module without a `Config` entry
## Acceptance Criteria
- [ ] `src/graphs/bridge.ts` exists with `moduleToDbSchema()`, `validateNode()`, `validateEdge()` exports
- [ ] `moduleToDbSchema()` accepts a `TModule` and returns `DbSchema` with `graphType`, `nodeTypes`, `edgeTypes`
- [ ] `moduleToDbSchema()` enforces naming convention: entries ending in `Node` become node type rows, entries ending in `Edge` become edge type rows, `Config` becomes the graph type config
- [ ] `moduleToDbSchema()` throws on missing Config, unrecognized bare entry suffixes, empty EdgeConstraints, EdgeConstraints referencing nonexistent edge types
- [ ] `validateNode(module, entryName, data)` returns `boolean``true` if data passes `Value.Check` against the resolved Module entry, `false` if invalid, throws if `entryName` doesn't match an `*Node` entry
- [ ] `validateEdge(module, entryName, data)` same pattern for `*Edge` entries
- [ ] `src/graphs/mod.ts` re-exports from `bridge.ts`
- [ ] `deno check mod.ts` passes
## References
- docs/architecture/metagraph-module.md — "Bridge Functions" and "DB Persistence Bridge" sections
- docs/architecture/decisions/014-dereferenced-entry-schemas.md
- docs/architecture/decisions/016-naming-convention-for-module-entries.md
## Notes
> To be filled by implementation agent
## Summary
> To be filled on completion

View File

@@ -0,0 +1,55 @@
---
id: drift/crypto-module
name: Port and adapt crypto utility from hub reference implementation
status: pending
depends_on:
- drift/metagraph-module
scope: narrow
risk: low
impact: component
level: implementation
---
## Description
Port the encryption utility from the hub's proven reference implementation at `/workspace/@alkdev/hub/src/crypto/mod.ts` to `src/graphs/crypto.ts` in `@alkdev/storage`. This is a copy-and-adapt task — the crypto logic is already working and tested in the hub. The port requires these adaptations:
1. **Replace `interface EncryptedData` with `EncryptedDataSchema`** — the hub uses a plain TypeScript interface; storage uses a TypeBox schema (`Type.Object`) so it can be used for runtime validation and composed into `SecretNode` attributes. Add `type EncryptedData = Static<typeof EncryptedDataSchema>` as the type alias.
2. **Remove code comments** — per ADR-007, `@alkdev/storage` has no comments in code. The hub has JSDoc comments which should be stripped.
3. **Keep `@std/encoding` imports**`encodeBase64` and `decodeBase64` are the same Deno standard library module the project already uses.
4. **No other changes to crypto logic** — AES-256-GCM, PBKDF2 with SHA-256, key versioning (v1 = 100k iterations), salt/IV generation, error message — all identical to the hub version.
The module exports to `src/graphs/crypto.ts` (zero db deps, per the spec's export plan).
## Acceptance Criteria
- [ ] `src/graphs/crypto.ts` exists, adapted from `/workspace/@alkdev/hub/src/crypto/mod.ts`
- [ ] Exports: `encrypt`, `decrypt`, `generateEncryptionKey`, `EncryptedDataSchema`, `type EncryptedData = Static<typeof EncryptedDataSchema>`
- [ ] `EncryptedDataSchema` is `Type.Object` (not a plain interface) with fields: `keyVersion` (`Type.Integer({ minimum: 1 })`), `salt` (`Type.String()`), `iv` (`Type.String()`), `data` (`Type.String()`)
- [ ] `encrypt()`, `decrypt()`, `generateEncryptionKey()` are functionally identical to the hub version
- [ ] No code comments (per ADR-007)
- [ ] Key versioning: v1 uses 100,000 PBKDF2 iterations (same as hub)
- [ ] Error message on decrypt failure: `"Decryption failed: Invalid data or key"` (same as hub, no information leakage)
- [ ] No external crypto dependencies — only `crypto.subtle` (Web Crypto API) and `@std/encoding`
- [ ] `src/graphs/mod.ts` re-exports from `crypto.ts`
- [ ] `deno check mod.ts` passes
## References
- **Reference implementation**: `/workspace/@alkdev/hub/src/crypto/mod.ts` — copy and adapt from this
- docs/architecture/encrypted-data.md — spec for EncryptedDataSchema, key versioning, export plan
- docs/architecture/decisions/025-password-based-encryption-pbkdf2.md
- docs/architecture/decisions/026-application-managed-key-ring.md
- docs/architecture/decisions/027-no-key-rotation-utility.md
- docs/architecture/decisions/007-no-comments-in-code.md
## Notes
> To be filled by implementation agent
## Summary
> To be filled on completion

View File

@@ -0,0 +1,42 @@
---
id: drift/metagraph-module
name: Create Metagraph Type.Module in modules/metagraph.ts
status: pending
depends_on: []
scope: narrow
risk: low
impact: component
level: implementation
---
## Description
Create the `Metagraph` TypeBox Module as specified in metagraph-module.md. This is the central schema definition that replaces the standalone schemas in `types.ts`. The Module provides `Config`, `BaseNode`, and `BaseEdge` entries that concrete graph type Modules compose from via `Metagraph.Import()` and `Type.Composite()`.
Also export the `GRAPH_STATUS` and `GRAPH_BASE_TYPE` const objects (these are runtime values, not Module entries — they stay as `as const` objects per ADR-006). The `GraphStatus` TypeBox schema (union of `GRAPH_STATUS` literals) also stays as a standalone export since it's used by the sqlite host for the `graphs.status` column enum.
## Acceptance Criteria
- [ ] `src/graphs/modules/metagraph.ts` exists and exports `Metagraph` as `Type.Module({...})` with entries: `Config`, `BaseNode`, `BaseEdge`
- [ ] `Metagraph.Config` uses `Type.Union` with defaults for `type` field, `Type.Boolean` with defaults for `multi` and `allowSelfLoops`
- [ ] `Metagraph.BaseNode` has `created` (optional date-time string), `modified` (optional date-time string), `metadata` (optional Record<String, Unknown>)
- [ ] `Metagraph.BaseEdge` has `type` (string), `metadata` (optional Record<String, Unknown>)
- [ ] `metadata` fields use `Type.Unknown()` per spec (not `Type.Any()`)
- [ ] `src/graphs/modules/metagraph.ts` also exports `GRAPH_STATUS` const and `GraphStatus` TypeBox schema (for sqlite host usage)
- [ ] `src/graphs/mod.ts` re-exports from `modules/metagraph.ts`
- [ ] `deno check mod.ts` passes
## References
- docs/architecture/metagraph-module.md — "Base Module: Metagraph" section
- docs/architecture/decisions/009-typebox-module-replaces-schemabuilder.md
- docs/architecture/decisions/010-metagraph-import-for-same-package.md
- docs/architecture/decisions/006-enum-pattern-as-const-objects.md
## Notes
> To be filled by implementation agent
## Summary
> To be filled on completion

View File

@@ -0,0 +1,50 @@
---
id: drift/reference-modules
name: Create reference graph type Modules (call-graph, secret-graph)
status: pending
depends_on:
- drift/metagraph-module
- drift/bridge-functions
scope: moderate
risk: medium
impact: component
level: implementation
---
## Description
Create concrete graph type Modules that compose from `Metagraph` via `Import()` and `Type.Composite()`. These serve as reference implementations and validation that the Module pattern works end-to-end with the bridge functions.
Per metagraph-module.md Phase 3, start with:
- `call-graph.ts` — mirrors `@alkdev/flowgraph`'s `CallNodeAttrs`/`CallEdgeAttrs` schemas
- `secret-graph.ts` — the encrypted data graph type from encrypted-data.md
Each Module uses `Metagraph.Import("BaseNode")` and `Metagraph.Import("BaseEdge")` for base composition (ADR-010: same-package Modules use `Import()` directly).
## Acceptance Criteria
- [ ] `src/graphs/modules/call-graph.ts` exports `CallGraph` as `Type.Module({...})` with entries: `Config`, `CallNode`, `SubcallNode`, `TriggeredEdge`, `DependsOnEdge`, `TriggeredEdgeConstraints`, `DependsOnEdgeConstraints`, `CallStatus`, `Identity`
- [ ] `CallGraph.Config` uses `Type.Literal` values (frozen config: directed, not multi, no self-loops)
- [ ] `CallGraph.CallNode` composes `Metagraph.Import("BaseNode")` with call-specific attributes via `Type.Composite`
- [ ] `CallGraph.TriggeredEdge` composes `Metagraph.Import("BaseEdge")` with `type: Type.Literal("triggered")`
- [ ] Edge constraint entries follow `*EdgeConstraints` naming convention with `edgeType`, `allowedSourceTypes`, `allowedTargetTypes`
- [ ] `src/graphs/modules/secret-graph.ts` exports `SecretGraph` with: `Config`, `SecretNode`, `ClientNode`, `HasSecretEdge`, `HasSecretEdgeConstraints`
- [ ] `moduleToDbSchema(CallGraph)` produces valid `DbSchema` rows compatible with the sqlite metagraph tables
- [ ] `moduleToDbSchema(SecretGraph)` produces valid `DbSchema` rows
- [ ] `validateNode(CallGraph, "CallNode", validData)` returns `true`
- [ ] `src/graphs/modules/index.ts` barrel re-exports all Module definitions
- [ ] `deno check mod.ts` passes
## References
- docs/architecture/metagraph-module.md — "Concrete Graph Type Modules" and "Edge Type Constraints" sections
- docs/architecture/encrypted-data.md — SecretGraph Module definition
- docs/architecture/decisions/010-metagraph-import-for-same-package.md
## Notes
> To be filled by implementation agent
## Summary
> To be filled on completion

View File

@@ -0,0 +1,36 @@
---
id: drift/remove-schema-builder
name: Remove schemaBuilder.ts — replaced by Type.Module() per ADR-009
status: pending
depends_on: []
scope: single
risk: trivial
impact: component
level: implementation
---
## Description
The `SchemaBuilder` class in `src/graphs/schemaBuilder.ts` is the old fluent builder pattern for constructing graph type definitions. ADR-009 and the metagraph-module.md spec explicitly replace it with `Type.Module()` construction. The `SchemaBuilder` is unreleased API — it has no consumers outside this package.
Remove the file and its re-export from `src/graphs/mod.ts`.
## Acceptance Criteria
- [ ] `src/graphs/schemaBuilder.ts` is deleted
- [ ] `src/graphs/mod.ts` no longer exports from `schemaBuilder.ts`
- [ ] No remaining imports of `SchemaBuilder` anywhere in `src/` or `test/`
- [ ] `deno check mod.ts` passes
## References
- docs/architecture/metagraph-module.md — "SchemaBuilder removed; replaced by Type.Module() construction"
- docs/architecture/decisions/009-typebox-module-replaces-schemabuilder.md
## Notes
> To be filled by implementation agent
## Summary
> To be filled on completion

View File

@@ -0,0 +1,54 @@
---
id: drift/replace-types-exports
name: Replace types.ts standalone schemas with Metagraph Module re-exports
status: pending
depends_on:
- drift/metagraph-module
- drift/any-to-unknown
- drift/remove-schema-builder
scope: moderate
risk: medium
impact: component
level: implementation
---
## Description
After the Metagraph Module exists and SchemaBuilder is removed, `types.ts` needs to be updated to align with the Module approach. The current standalone schemas (`BaseNodeAttributes`, `BaseEdgeAttributes`, `GraphConfig`, `NodeType`, `EdgeType`, `GraphSchema`, `GRAPH_BASE_TYPE`, `GraphBaseType`) represent the old flat model that the Module replaces.
The transition strategy per the spec:
- `BaseNodeAttributes``Metagraph.BaseNode` (referenced by name, or via `Metagraph.Import("BaseNode")`)
- `BaseEdgeAttributes``Metagraph.BaseEdge`
- `GraphConfig``Metagraph.Config`
- `NodeType`, `EdgeType`, `GraphSchema` → removed (replaced by Module entries + `moduleToDbSchema()`)
- `GRAPH_BASE_TYPE` / `GraphBaseType` → removed (duplicates `Metagraph.Config` type union)
- `GRAPH_STATUS` / `GraphStatus` → move to `modules/metagraph.ts` since they're still needed by sqlite host
**Important**: Since `NodeType`, `EdgeType`, and `GraphSchema` are used in the `schemaBuilder.ts` (which is being deleted), and their replacement (`moduleToDbSchema()`) doesn't exist yet (that's `bridge.ts`), this task should either:
- Remove them entirely if nothing else imports them, OR
- Mark them as deprecated with a JSDoc `@deprecated` comment pointing to the Module approach, to be removed when `bridge.ts` lands
Check what actually imports these before deciding. The sqlite host tables don't use `NodeType`, `EdgeType`, or `GraphSchema` — they use their own drizzlebox-generated schemas.
## Acceptance Criteria
- [ ] `src/graphs/types.ts` is either deleted or reduced to only re-exporting from `modules/metagraph.ts`
- [ ] `src/graphs/mod.ts` still exports everything consumers need (Metagraph, GRAPH_STATUS, GraphStatus)
- [ ] No standalone `BaseNodeAttributes`, `BaseEdgeAttributes`, `GraphConfig`, `NodeType`, `EdgeType`, `GraphSchema`, `GRAPH_BASE_TYPE`, `GraphBaseType` remain as top-level exports (they're either removed or re-exports from Module)
- [ ] `src/sqlite/tables/graphs.ts` import of `GRAPH_STATUS` still resolves (from `modules/metagraph.ts` now, not `types.ts`)
- [ ] `deno check mod.ts` passes
- [ ] `deno check src/sqlite/mod.ts` passes
## References
- docs/architecture/metagraph-module.md — "Transition from SchemaBuilder" section
- docs/architecture/decisions/009-typebox-module-replaces-schemabuilder.md
- docs/architecture/decisions/003-typebox-module-as-api-surface.md
## Notes
> To be filled by implementation agent
## Summary
> To be filled on completion

View File

@@ -0,0 +1,54 @@
---
id: review/drift-sync
name: Review drift sync — verify all specs align with source after implementation
status: pending
depends_on:
- drift/any-to-unknown
- drift/remove-schema-builder
- drift/metagraph-module
- drift/replace-types-exports
- drift/update-sqlite-imports
- drift/bridge-functions
- drift/reference-modules
- drift/crypto-module
scope: broad
risk: low
impact: phase
level: review
---
## Description
Review the entire codebase after all drift tasks are complete. Verify that the source code now matches the architecture specs in all the areas that were previously drifted. Confirm no regressions, no orphaned exports, and no remaining inconsistencies.
## Acceptance Criteria
- [ ] No `Type.Any()` calls remain in `src/` (should all be `Type.Unknown()`)
- [ ] `schemaBuilder.ts` is gone, not re-exported anywhere
- [ ] `types.ts` is either deleted or reduced to re-exports from `modules/metagraph.ts`
- [ ] No standalone `BaseNodeAttributes`, `BaseEdgeAttributes`, `GraphConfig`, `NodeType`, `EdgeType`, `GraphSchema`, `GRAPH_BASE_TYPE`, `GraphBaseType` exports remain (replaced by Module)
- [ ] `Metagraph` Module is exported from the main `@alkdev/storage` package
- [ ] `bridge.ts` exists with `moduleToDbSchema`, `validateNode`, `validateEdge`
- [ ] `crypto.ts` exists with `encrypt`, `decrypt`, `generateEncryptionKey`, `EncryptedDataSchema`
- [ ] Reference Modules (`CallGraph`, `SecretGraph`) compose from `Metagraph` via `Import()` and `Composite()`
- [ ] `deno check mod.ts` passes — no type errors
- [ ] `deno check src/sqlite/mod.ts` passes — sqlite host still compiles
- [ ] `deno lint` passes (excluding known slow-types exclusions)
- [ ] `deno test --allow-all test/` passes (even if tests are empty — no breakage)
- [ ] Import graph is clean: no circular imports, sqlite host doesn't reach into `graphs/types.ts` anymore
- [ ] Architecture docs are still accurate — no new drifts introduced by changes
## References
- docs/architecture/metagraph-module.md
- docs/architecture/sqlite-host.md
- docs/architecture/encrypted-data.md
- docs/architecture/overview.md
## Notes
> To be filled by implementation agent
## Summary
> To be filled on completion

View File

@@ -0,0 +1,36 @@
---
id: drift/update-sqlite-imports
name: Update sqlite host imports from graphs/types.ts to new module paths
status: pending
depends_on:
- drift/replace-types-exports
scope: single
risk: trivial
impact: isolated
level: implementation
---
## Description
After `types.ts` is replaced, the sqlite host's one import from the graphs module (`GRAPH_STATUS` in `src/sqlite/tables/graphs.ts`) needs to point to the new location. This is a small, mechanical import path update.
Additionally, check if `GraphConfigType` (the `Static<>` type alias) is used anywhere in the sqlite host — if so, it needs to resolve from the Metagraph Module instead.
## Acceptance Criteria
- [ ] `src/sqlite/tables/graphs.ts` imports `GRAPH_STATUS` from the new module path (likely `../../graphs/modules/metagraph.ts` or via re-export from `../../graphs/mod.ts`)
- [ ] No other sqlite files import from `../../graphs/types.ts`
- [ ] `deno check src/sqlite/mod.ts` passes
## References
- docs/architecture/sqlite-host.md — table definitions, enum pattern
- docs/architecture/decisions/006-enum-pattern-as-const-objects.md
## Notes
> To be filled by implementation agent
## Summary
> To be filled on completion