Identity tables were derived from hub's PostgreSQL schema but simplified
without documenting what was removed or why. This restructures them for the
current auth landscape (API key + wraith SSH/cert-authority):
- ADR-049: Separate api_keys and peer_credentials tables (different lookup
patterns, columns, lifecycles), remove Gitea columns, map hub data→metadata
- ADR-050: Extract SHA-256 vs KDF decision from inline spec text
- Add peer_credentials table for SSH key and cert-authority auth
- Specify all FK cascade behaviors within system DB (RESTRICT, CASCADE, SET NULL)
- Complete index specifications for all identity tables
- Add scope boundary section (storage owns schemas, not auth/authorization)
- Update audit_logs with credentialId+credentialType polymorphic reference
- Add 3 new open questions (OQ-33/34/35) for credential type expansion
Reorient @alkdev/storage around a single SQLite database host with Honker
for pub/sub, event streams, and task queues. PostgreSQL is removed as a
target (ADR-038), eliminating dual schema maintenance and infrastructure
complexity. Honker provides DB + pubsub + queues in one .db file (ADR-039).
Add system/tenant DB model (ADR-040): identity tables in system.db, all
graph data in tenant-{orgId}.db files. Identity tables move from the hub
into storage (ADR-041). Scoping columns (ownerId, projectId) added to
graphs table (ADR-042). Graph types get scope (system/tenant/user) to
protect infrastructure schemas (ADR-043).
Define Drizzle-Honker session adapter (ADR-044): ~100-line adapter enabling
Drizzle typed queries and Honker pubsub/queue on a single connection with
transactional consistency.
Resolve OQ-03, OQ-04, OQ-19, OQ-21, OQ-22, OQ-23, OQ-24. Add new
open questions OQ-26 through OQ-29 for Honker integration specifics.
New docs: honker-integration.md (adapter, event patterns, migration).
Scrub all PG/jsonb/libsql references from existing spec docs.
- New acl.md: AclGraph Module definition (PrincipalNode, ResourceNode,
DelegatesEdge, ScopesEdge, MemberEdge), principal-agent hierarchy
with no-escalation invariant, setup-time vs runtime separation,
multi-parent aggregation rules, cycle detection, scope semantics
- ADR-034: ACL as metagraph (not domain-specific tables)
- ADR-035: Actors become PrincipalNode entries, standalone table removed
- ADR-036: Principal-agent as DelegatesEdge with scope narrowing
- ADR-037: Setup-time definitions seed graph types, runtime instances
are separate graphs
- Resolve OQ-03 (actors table design) — actors become ACL nodes
- Add OQ-20 through OQ-25 (delegation expiration, evaluator location,
graph instance lifecycle, BelongsToEdge derivation, identityId
references, scope string semantics)
- Update README.md and overview.md to reflect new doc and ADRs
- Note: multi-tenancy / graph scoping problem (no ownerId/scopeId on
graphs table, no identity tables at this level) still needs
resolution — identity and org tables will likely need to be added
at this level for referential integrity
Add three open questions (OQ-17, OQ-18, OQ-19) covering attribute query
strategy, CRUD generation approach, and storage-operations bridge placement.
Create ADR-033 recording the v1 decision: JSON path queries for attributes
with hand-written CRUD for static tables.
Expand forward-look.md with Repository Layer Strategy section analyzing
three approaches (JSON path, native columns via dbtype, hybrid) and their
implications for the metagraph pattern. Add drizzle-graphql and dbtype
from-dbtype comparison showing neither handles dynamic schema-as-data.
Update overview.md with dbtype/ujsx in the dependency diagram, expanded
ecosystem context in the bridging pattern section, and new open questions.
Align open-questions.md: resolve OQ-17 and OQ-18 for v1 (ADR-033), add
OQ-19 as open, update summary counts and ADR impact table.
- Update architect.md to codify the ADR/OQ/README pattern:
- decisions/ directory with numbered ADRs (not inline)
- open-questions.md with OQ-IDs (not scattered per-doc)
- README.md as index with doc table and ADR table
- Spec docs reference ADRs and OQs by number
- Document lifecycle states (draft/reviewed/stable/deprecated)
- Anti-patterns updated for the new pattern
- Update sdd_process.md:
- Phase 1 (Architecture) now specifies the full doc structure
- Document Structure section updated with ADR/OQ format templates
- Architect role deliverables updated
- Architecture Reviewer checks updated for structural issues
- Spec document Design Decisions section format specified
- Create decisions/ directory with 32 numbered ADRs (ADR-001 through ADR-032)
extracted from inline DD/SD/ED/SE decision sections
- Create open-questions.md with 16 OQs organized by theme, cross-referenced
to ADRs, with status tracking (resolved/open)
- Create README.md as architecture index with doc table, ADR table, and
lifecycle status definitions (draft/reviewed/stable/deprecated)
- Replace inline decision sections in all spec docs with ADR reference tables
- Replace inline open questions with OQ references to centralized tracker
- Update frontmatter: metagraph-module.md, overview.md, sqlite-host.md → reviewed;
schema-evolution.md and encrypted-data.md remain draft
- DD1-DD10 → ADR-009 through ADR-018
- D1-D8 → ADR-001 through ADR-008
- SD1-SD5 → ADR-019 through ADR-023 (SD5 folded into ADR-006/008)
- ED1-ED5 → ADR-023 through ADR-027
- SE1-SE5 → ADR-028 through ADR-032
Graph type definitions as TypeBox Modules — the core architecture evolution
for @alkdev/storage. The SchemaBuilder is removed (no existing consumers),
replaced by direct TypeModule construction with Metagraph.Import() for
base attribute composition and Type.Composite() for node/edge type
specialization.
Key additions:
- metagraph-module.md: Module pattern, edge constraints as named entries,
SchemaBuilder equivalence, DB bridge contracts (moduleToDbSchema return
type, validateNode/validateEdge signatures), 10 design decisions (DD1-DD10)
- forward-look.md: pointer abstraction (ujsx ValuePointer analogy, JPATH
Module), dbtype table rendering relationship, ujsx as universal IR pipeline
Critical corrections from architecture review:
- Type.Composite uses IntersectEvaluated (intersection, not Object.assign
override) — overlapping keys with subtype relationships resolve correctly
- Type.Ref inside Type.Composite within a Module is verified working
- BaseNode/BaseEdge use Metagraph.Import() for same-package Modules (Option B),
not local re-declaration (no circular dep within same package)
- Edge constraints use Type.String() for node type name arrays (not Type.Ref) —
constraints contain names, not schemas
Architecture docs previously referenced the hub as the authoritative source
for call/identity specs. In reality, call protocol, identity, and access control
come from @alkdev/operations; call graph schemas from @alkdev/flowgraph; task
graph schemas from @alkdev/taskgraph; event transport from @alkdev/pubsub. The
hub is a consumer of @alkdev/storage, not the other way around.
Key changes:
- overview.md: add Ecosystem Integration section with dependency direction
diagram, What Comes From Where table, repo layer bridging pattern, and
circular dependency avoidance guidance
- overview.md: promote repo-layer vs operations-bridging from open question
to explicit decision (CRUD in storage, bridging in consumer)
- overview.md: add zero-ecosystem-dependency statement; fix taskgraph type
names (TaskGraphNodeAttributes, DependencyEdge)
- overview.md: fix terminology (hub is consumer, not authority)
- metagraph.md: add Ecosystem Context section; replace hub references with
correct ecosystem sources; fix GraphStatus/GraphBaseType enum
mischaracterization (C1); unify empty-array semantics with sqlite-host (C2);
clarify repo layer does NOT import operations (C3); add flowgraph canonical
schema note; add versioning cross-reference to graph_types table
- encrypted-data.md: reframe hub as provenance not authority; update What
Lives Where table; fix standalone table advice; update references
- sqlite-host.md: fix actors table description; unify empty-array semantics;
contextualize hub as reference consumer; add operations identity reference
The verbatim-module-syntax lint rule was correctly flagging that
GraphConfig is only used in a type position (typeof GraphConfig). Since
typeof resolves purely at the type level, import type works fine here
and is the correct form. No lint exclusion needed.
Also: deno fmt across all files (markdown line wrapping).