Skip to content

Commit ce353b0

Browse files
committed
feat(spec): register the ADR-0030 notification cut-over in sys_migration's well-known ids
`sys_migration` records, per deployment, that a data migration ran against that deployment's own database — the evidence consumers gate on instead of the platform version. Its well-known ids were the two ADR-0104 scans and nothing else. `migrateSysNotificationToEvent` had no id: it is destructive and one-way, operators are handed the call verbatim in the ADR-0030 handoff, and a run of it recorded nothing, so a deployment that performed the cut-over and one that never did read identically from the ledger. An id is what a row can be keyed by; without one the question had nowhere to be answered even in principle. Adds `NOTIFICATION_EVENT_MIGRATION_ID = 'adr-0030-notification-event'` to `@objectstack/spec/system`. Purely additive: no existing export, schema or predicate moves, and no consumer reads the new id. What a row under the id MEANS is deliberately left open, and the docblock says so rather than letting its silence be read as an answer. The two ADR-0104 ids take their `last_run_at` / `applied_at` / `verified_at` / `blocking` semantics from an `os migrate` command that scans, self-checks and only then records; this migration has neither command nor self-check and reports `migrated`/`already_done`/`not_applicable`/`error` to its caller. Which columns one of its runs may claim, whether anything may gate on the row, and whether a datastore created after the cut-over belongs in `CREATION_ATTESTED_MIGRATION_IDS`, are contract questions on this surface. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01ARYe3yQTQCUFm5qPYNgKaJ
1 parent 9af0da9 commit ce353b0

2 files changed

Lines changed: 41 additions & 0 deletions

File tree

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
---
2+
"@objectstack/spec": minor
3+
---
4+
5+
`@objectstack/spec/system` now names the ADR-0030 notification cut-over, so "has this deployment run it?" has a place to be answered.
6+
7+
`sys_migration` is the ledger a deployment writes to record that a data migration ran against its own database, and consumers read it instead of the platform version. Its well-known ids were `adr-0104-file-references` and `adr-0104-value-shapes` — the two ADR-0104 scans, both driven by an `os migrate` command that records the row. `migrateSysNotificationToEvent` (`@objectstack/metadata/migrations`) had none. It is destructive and one-way, operators are handed the call verbatim in `docs/handoff/adr-0030-notification-convergence.md`, and it recorded nothing when it ran: a deployment that performed the cut-over and one that never did are indistinguishable from the ledger. A row can only be keyed by an id, so without one the question had nowhere to be answered even in principle.
8+
9+
Added: `NOTIFICATION_EVENT_MIGRATION_ID = 'adr-0030-notification-event'`, exported from `@objectstack/spec/system`. Purely additive — no existing export, schema or predicate changes, and nothing reads the new id yet.
10+
11+
Deliberately NOT decided here, and the constant's docblock says so rather than leaving its silence to be read as an answer: what a `sys_migration` row under this id means. The two ADR-0104 ids get their `last_run_at` / `applied_at` / `verified_at` / `blocking` semantics from a command that scans, self-checks and only then records; this migration has no command and no self-check, and reports `migrated` / `already_done` / `not_applicable` / `error` to its caller instead. Which of those columns one of its runs may claim, whether anything may gate on the row, and whether a datastore created after the cut-over belongs in `CREATION_ATTESTED_MIGRATION_IDS`, are contract questions on this surface and are left open.

packages/spec/src/system/migration.zod.ts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,36 @@ export const FILE_REFERENCES_MIGRATION_ID = 'adr-0104-file-references';
169169
*/
170170
export const VALUE_SHAPES_MIGRATION_ID = 'adr-0104-value-shapes';
171171

172+
/**
173+
* Well-known migration id: ADR-0030 notification convergence — this
174+
* deployment's legacy per-user `sys_notification` inbox rows split into
175+
* `sys_inbox_message` + `sys_notification_receipt`, and the `sys_notification`
176+
* row itself rewritten to the L2 event shape, by `migrateSysNotificationToEvent`
177+
* (`@objectstack/metadata/migrations`).
178+
*
179+
* Registered so that "has this cut-over run here?" is ANSWERABLE at all. The
180+
* cut-over is destructive and one-way, it is handed to operators as a call they
181+
* make themselves (`docs/handoff/adr-0030-notification-convergence.md`, under
182+
* "Data migration (not auto-run)"), and it shipped with no id — so a deployment
183+
* that ran it recorded nothing, and one that did not is indistinguishable from
184+
* one that did. A ledger row can only be keyed by an id; without one the
185+
* question has no place to be answered even in principle. That absence, not the
186+
* migration, is what this constant repairs.
187+
*
188+
* WARNING — what a row under this id MEANS is deliberately NOT settled here,
189+
* and its silence is not an answer. The two ids above are written by an
190+
* `os migrate` command that scans, self-checks, and only then records, which is
191+
* what gives `last_run_at` / `applied_at` / `verified_at` / `blocking` their
192+
* meaning for them. This migration has no such command and no self-check: it
193+
* reports `migrated` / `already_done` / `not_applicable` / `error` to its
194+
* caller and nothing else. Which of those columns a run of it may legitimately
195+
* claim, whether anything may gate on the row, and whether a datastore created
196+
* after the cut-over belongs in {@link CREATION_ATTESTED_MIGRATION_IDS}, are
197+
* open contract questions on this surface (#14025) — not facts this constant
198+
* asserts, and not ones to settle by copying the neighbours above.
199+
*/
200+
export const NOTIFICATION_EVENT_MIGRATION_ID = 'adr-0030-notification-event';
201+
172202
/**
173203
* The migrations a datastore attests at CREATION rather than by scanning.
174204
*

0 commit comments

Comments
 (0)