blue/.blue/docs/adrs/0018-dynamodb-portable-schema.accepted.md
Eric Garcia 6e8f0db6c0 chore: add dialogues, RFCs, docs and minor improvements
- Add dialogue prompt file writing for audit/debugging
- Update README install instructions
- Add new RFCs (0053, 0055-0059, 0062)
- Add recorded dialogues and expert pools
- Add ADR 0018 dynamodb-portable-schema
- Update TODO with hook configuration notes

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-26 08:51:56 -05:00

2.8 KiB

ADR 0018: DynamoDB-Portable Schema Design

Status Accepted
Date 2026-02-02

Context

Blue currently uses SQLite for local storage. Future deployment scenarios require cloud-native storage (DynamoDB) for:

  • Multi-region availability
  • Serverless scaling
  • Concurrent access from distributed services

Decision

All new schemas must be designed for DynamoDB portability.

Principles

  1. Single-table design - One table per domain, composite sort keys encode hierarchy
  2. Partition key scoping - All hot-path queries scoped to single partition key
  3. No cross-partition JOINs - Denormalize or use application-level joins for cold paths
  4. Single writer per partition - Avoid concurrent write contention within a partition
  5. Composite sort keys - Encode type and hierarchy in sort key: TYPE#subkey1#subkey2

Pattern

Table: blue_{domain}
───────────────────────────────────────────────
PK (partition key)  │ SK (sort key)           │ attributes...
───────────────────────────────────────────────
{parent_id}         │ META                    │ metadata
{parent_id}         │ CHILD#subkey            │ child record
{parent_id}         │ EVENT#timestamp         │ audit event

SQLite Implementation

For local development, the single-table pattern maps to SQLite:

CREATE TABLE blue_{domain} (
  pk TEXT NOT NULL,
  sk TEXT NOT NULL,
  data JSON NOT NULL,
  created_at TEXT NOT NULL,
  PRIMARY KEY (pk, sk)
);

Or use separate tables with foreign keys (more idiomatic SQL) as long as:

  • All queries can be scoped to a single pk value
  • No JOINs required in hot paths

Consequences

Positive:

  • Seamless migration path to DynamoDB
  • Predictable query patterns
  • Natural sharding by partition key

Negative:

  • Some denormalization required
  • Less flexible ad-hoc queries
  • Slightly more complex local schema

Examples

Dialogue Domain (RFC 0051)

PK: dialogue_id
SK: TYPE#subkey

nvidia-dec | META                  → {title, status, created_at}
nvidia-dec | EXPERT#muffin         → {role, tier, score}
nvidia-dec | PERSP#0#muffin#1      → {label, content, status}
nvidia-dec | TENSION#T01           → {description, status}
nvidia-dec | TEVENT#T01#1706900000 → {event_type, actor, reason}

Document Domain (existing)

PK: realm_id
SK: TYPE#subkey

letemcook  | META                  → {name, path}
letemcook  | DOC#rfc#0051          → {title, status, content}
letemcook  | LINK#0051#0050        → {link_type}

"Design for the cloud, develop on the laptop."