Skip to content

driver-memory enforces field-level unique but not object-level declared indexes[] — a composite unique is a real constraint on driver-sql and nothing at all in memory #13239

Description

@claude

Filed by the domain:engine os-dev working #13197, which added field-level uniqueness to driver-memory. Object-level declared indexes were explicitly out of that card's scope, so they are recorded here rather than carried. Unassigned; grading and routing are triage's.

Dedupe run: the global search/issues endpoint answers 403 from this container (sessions are bound to repository-scoped endpoints), so one targeted MCP search_issues was used instead. It returned 90 hits and the channel demonstrably answered — #13197 itself, #13166, #5499 and #6916 all came back — so the zero for this defect is a reading rather than a silence. Nearest neighbours: #4943 (IndexSchema.partial authorable but emitted by no driver, closed) and #4986 (normalizeDeclaredIndex not scoping a tenant-scoped table on the SQL side, closed). Neither is this.

The observation

driver-sql materializes uniqueness from two declaration surfaces, and packages/drivers/driver-sql/src/schema-drift.ts is explicit that both are indexes on the table:

  1. field-leveluniqueuniqueIndexesFromFields
  2. object-levelindexes[] entries carrying uniquenormalizeDeclaredIndex, which is also where a composite unique gets its ADR-0120 D1/D3 organization key part

driver-memory now enforces only the first. An object declaring

{ "indexes": [{ "fields": ["account_id", "code"], "unique": "organization" }] }

gets a real composite UNIQUE on the SQL family and nothing at all in memory: the colliding write lands, and a read returns both rows. That is the same declared-but-unenforced shape #13197 closed for the field surface, one surface over — the ADR-0078 / Prime-Directive-#10 class.

Why it is worth a card rather than a footnote

The two surfaces do not mean the same thing, so this is not a smaller copy of #13197:

Both points are already ruled elsewhere in-tree, so this is mechanical work with a settled shape — it just is not #13197's.

Where it would go

packages/drivers/driver-memory/src/memory-unique-constraint.ts already carries the single judgment point and the refusal envelope (code: 'UNIQUE_VIOLATION', status: 409), and its module docblock names this exclusion by name under "Deliberately out of scope", so the extension point exists and is documented. assertNoUniqueViolation takes a constraint list; a composite constraint is a wider key, not a new seam.

Not claimed here

No position on whether this is worth building. driver-memory is positioned as a dev / demo / in-process driver and is a deliberately WEAK oracle; "it should stay weak on composite indexes" is a legitimate answer, and if it is the answer the docstring's out-of-scope note is already the honest record. What is not legitimate is the current state being neither enforced nor decided.

Related

#13197 (field-level uniqueness, the card that surfaced this) · #4986 / #4943 (the declared-index scope and partial rulings on the SQL side) · #5030 / ADR-0120 D3 (the NULL-organization fold a composite would also need)


Generated by Claude Code

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions