docs: restructure architecture docs to flowgraph pattern

- 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
This commit is contained in:
2026-05-29 07:19:03 +00:00
parent 6c3ed598db
commit 67ccfbf928
39 changed files with 1117 additions and 435 deletions

View File

@@ -0,0 +1,92 @@
---
status: reviewed
last_updated: 2026-05-29
---
# @alkdev/storage Architecture
Typed graph storage with dual database hosts. Deno-first, published via JSR.
## Current State
Storage is in Phase 1/2 (SQLite tables and type system implemented; repository layer, tests, PostgreSQL host, and encrypted data not yet implemented).
## Architecture Documents
| Document | Content | Status |
|----------|---------|--------|
| [overview.md](overview.md) | Package purpose, exports, dependencies, ecosystem integration | reviewed |
| [metagraph-module.md](metagraph-module.md) | TypeBox Module type system, bridge functions, implementation path | reviewed |
| [sqlite-host.md](sqlite-host.md) | SQLite tables, relations, client factory, PG porting notes | reviewed |
| [schema-evolution.md](schema-evolution.md) | Value.Diff/Cast/Patch for schema migration, version strategy | draft |
| [encrypted-data.md](encrypted-data.md) | Crypto utility, encrypted node type, key management | draft |
| [forward-look.md](forward-look.md) | Pointers, dbtype, ujsx IR (conceptual, post-v1) | draft |
### Design Decisions
| ADR | Decision | Status |
|-----|----------|--------|
| [001](decisions/001-deno-first-jsr-publishes.md) | Deno-first, JSR publishes, npm comes free | Accepted |
| [002](decisions/002-metagraph-over-domain-tables.md) | Metagraph pattern over domain-specific tables | Accepted |
| [003](decisions/003-typebox-module-as-api-surface.md) | TypeBox Module as the graph type definition API surface | Accepted |
| [004](decisions/004-injectable-clients-no-side-effects.md) | Injectable clients, no module-level side effects | Accepted |
| [005](decisions/005-drizzle-plus-typebox-via-drizzlebox.md) | Drizzle + TypeBox via drizzlebox | Accepted |
| [006](decisions/006-enum-pattern-as-const-objects.md) | `as const` objects, not TypeScript enums | Accepted |
| [007](decisions/007-no-comments-in-code.md) | No comments in code | Accepted |
| [008](decisions/008-common-columns-pattern.md) | Common columns pattern | Accepted |
| [009](decisions/009-typebox-module-replaces-schemabuilder.md) | TypeBox Module replaces the SchemaBuilder | Accepted |
| [010](decisions/010-metagraph-import-for-same-package.md) | Metagraph.Import() for same-package Modules | Accepted |
| [011](decisions/011-config-as-module-entry-with-literal-values.md) | Config as Module entry with Literal values | Accepted |
| [012](decisions/012-node-edge-attributes-as-module-entries.md) | Node/edge attribute schemas are Module entries | Accepted |
| [013](decisions/013-storage-produces-graphology-format.md) | Storage produces graphology format, flowgraph consumes it | Accepted |
| [014](decisions/014-dereferenced-entry-schemas.md) | Repository stores dereferenced entry schemas | Accepted |
| [015](decisions/015-edge-constraints-as-named-entries.md) | Edge type constraints as named Module entries | Accepted |
| [016](decisions/016-naming-convention-for-module-entries.md) | Naming convention for Module entries | Accepted |
| [017](decisions/017-pointer-abstraction-is-forward-looking.md) | Pointer abstraction is forward-looking, not v1 | Accepted |
| [018](decisions/018-dbtype-integration-is-post-v1.md) | dbtype integration is post-v1 | Accepted |
| [019](decisions/019-json-text-for-schema-columns.md) | JSON text for schema columns in SQLite | Accepted |
| [020](decisions/020-no-nodetypeid-on-nodes.md) | No nodeTypeId on nodes | Accepted |
| [021](decisions/021-edge-identity-uses-consumer-keys.md) | Edge identity uses consumer-defined keys | Accepted |
| [022](decisions/022-composite-fks-for-node-references.md) | Composite foreign keys for node references | Accepted |
| [023](decisions/023-per-attribute-encryption.md) | Per-attribute encryption, not per-node | Accepted |
| [024](decisions/024-encrypted-data-as-node-type.md) | Encrypted data as node type, not standalone table | Accepted |
| [025](decisions/025-password-based-encryption-pbkdf2.md) | Password-based encryption via PBKDF2 | Accepted |
| [026](decisions/026-application-managed-key-ring.md) | Application-managed key ring | Accepted |
| [027](decisions/027-no-key-rotation-utility.md) | No key rotation utility in this package | Accepted |
| [028](decisions/028-additive-only-with-cast-migration.md) | Additive-only for v1, Cast migration when needed | Accepted |
| [029](decisions/029-version-as-breaking-change-signal.md) | Version as a coarse-grained breaking-change signal | Accepted |
| [030](decisions/030-schema-change-detection-via-diff.md) | Schema change detection via Value.Diff | Accepted |
| [031](decisions/031-moduletodbschema-for-updates.md) | moduleToDbSchema() for schema updates | Accepted |
| [032](decisions/032-single-author-not-crdt.md) | Single-author model, not CRDT | Accepted |
### Open Questions
All unresolved design questions are tracked in [open-questions.md](open-questions.md), organized by theme with cross-references between related questions.
## Document Lifecycle
Architecture documents use YAML frontmatter with `status` and `last_updated` fields:
```yaml
---
status: draft | reviewed | stable | deprecated
last_updated: YYYY-MM-DD
---
```
| Status | Meaning | Transitions |
|--------|---------|-------------|
| `draft` | Under active development. Content may change significantly. Implementation should not start until the document reaches `reviewed`. | → `reviewed` when all open questions are resolved and cross-cutting issues are addressed. |
| `reviewed` | Architecture is final and reviewed. Implementation may begin. API contracts are specified but not yet verified by tests. Changes require a review cycle. | → `stable` when implementation is complete and API contracts are verified by tests. → `draft` if a fundamental redesign is needed. |
| `stable` | API contracts are locked and verified by tests. Changes require a review cycle and may warrant an ADR. | → `deprecated` when superseded. |
| `deprecated` | Superseded by another document. Kept for reference. | Removed when no longer referenced. |
ADR documents use a separate `Status` field in their body: `Proposed`, `Accepted`, `Deprecated`, or `Superseded`. ADRs never revert from `Accepted`.
## References
- Source: `src/`
- AGENTS.md: `/workspace/@alkdev/storage/AGENTS.md`
- Flowgraph architecture (pattern reference): `/workspace/@alkdev/flowgraph/docs/architecture/`
- ujsx architecture: `/workspace/@alkdev/ujsx/docs/architecture/`
- Operations architecture: `/workspace/@alkdev/operations/docs/architecture/`