Skip to content

Commit d64bcb6

Browse files
claude[bot]claude
andauthored
refactor(metadata,spec)!: retire the adr-0030-notification-event migration — no operator door, no platform invoker (#17194)
* wip: retire adr-0030-notification-event migration * wip: regenerate engine-double ledger * wip: plugin.test.ts expectations follow the two-member set * wip: changeset without a FROM/TO framing * refactor(metadata,spec)!: retire the adr-0030-notification-event migration `migrateSysNotificationToEvent` had no way to be run: zero production callers anywhere in `packages` / `apps` / `examples`, and no `os migrate` sub-command, while the two sibling members of `CREATION_ATTESTED_MIGRATION_IDS` had both. Removed together: the runner and its three result/option/receipt types, its barrel export, its tests, the ruled `sys_migration` receipt-claim matrix and that matrix's pin, the spec docblock stating it, and the id's membership in `CREATION_ATTESTED_MIGRATION_IDS`. `NOTIFICATION_EVENT_MIGRATION_ID` is kept as the name of rows already written under it; nothing writes or reads one now. Both alternatives stay refused: an `os migrate notification-event` sub-command is a permanent operator surface for a migration with no measured demand, and a boot-time invoker is an unattended data rewrite. Pre-ADR-0030 `sys_notification` rows are not carried by the platform on this line. Two new retirement pins replace the withdrawn ledger pin, each asserting the two ADR-0104 survivors by name beside the negative, so a correct removal is distinguishable from a set that lost everything. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015QE8qk46e5CHJxyQEUjbf8 * docs(handoff): finish the ADR-0030 retirement — the runbook's own description too The first pass tombstoned only the cut-over sequence's step 2. Three claims above it still described the migration as live: the `### Data migration (not auto-run)` section that names the deleted file and its export, the breaking-change callout telling a reader to "do the objectui cut-over and the data migration together", and the Tests line counting the migration's own suites among the green ones. Found by the docs-drift round on the PR. The runbook tombstone is now a pointer to the one full account, so the file states it once. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015QE8qk46e5CHJxyQEUjbf8 --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent 9c52b1b commit d64bcb6

17 files changed

Lines changed: 525 additions & 2159 deletions
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
---
2+
'@objectstack/metadata': minor
3+
'@objectstack/spec': minor
4+
---
5+
6+
**BREAKING** — retire the `adr-0030-notification-event` data migration.
7+
8+
`migrateSysNotificationToEvent` had no way to be run: zero production callers
9+
anywhere in the repo, and no `os migrate` sub-command, while the two sibling
10+
members of `CREATION_ATTESTED_MIGRATION_IDS` had both. The runner, its barrel
11+
export, its tests, the ruled `sys_migration` receipt-claim matrix, that matrix's
12+
pin, and the id's membership in `CREATION_ATTESTED_MIGRATION_IDS` are removed
13+
together. Pre-ADR-0030 `sys_notification` rows are not carried by the platform
14+
on this line.
15+
16+
## What is gone, and what an upgrader does about it
17+
18+
**Nothing is renamed and nothing replaces it**, so there is no new spelling to
19+
adopt — every item below is a deletion, and the fix is to stop using it.
20+
21+
- `migrateSysNotificationToEvent` (`@objectstack/metadata/migrations`) — deleted.
22+
No replacement exists, and none is coming: an `os migrate notification-event`
23+
sub-command was considered and refused. Delete the call. The compiler delivers
24+
this one: the import fails to resolve.
25+
- `SysNotificationMigrationResult`, `SysNotificationMigrationOptions` and
26+
`SysNotificationMigrationReceipt` (same entry point) — deleted with it. They
27+
described that runner's own result, options and receipt and nothing else.
28+
- `CREATION_ATTESTED_MIGRATION_IDS` (`@objectstack/spec/system`) — was a
29+
three-member tuple and is now a two-member one holding
30+
`'adr-0104-file-references'` and `'adr-0104-value-shapes'`. Both ADR-0104 ids
31+
keep their sub-commands, their receipt rows and their birth attestation; only
32+
the notification id left. Code typed against
33+
`(typeof CREATION_ATTESTED_MIGRATION_IDS)[number]` that names the notification
34+
id no longer compiles — delete that arm.
35+
36+
`NOTIFICATION_EVENT_MIGRATION_ID` (`@objectstack/spec/system`) is **kept**. A
37+
deployment attested at birth, or one that made the operator call while the runner
38+
shipped, still holds a `sys_migration` row keyed `'adr-0030-notification-event'`,
39+
and the constant is that row's name. Nothing writes or reads a row under it any
40+
more — `attestFreshDatastore` no longer includes it — and it is not a
41+
registration: it gates nothing and never did.
42+
43+
## Reversal path
44+
45+
Two answers were considered and both refused: an `os migrate notification-event`
46+
sub-command is a permanent operator surface for a migration with no measured
47+
demand, and a boot-time invoker is an unattended data rewrite nobody asked for.
48+
⚠️ Nobody has measured whether any live deployment carries pre-ADR-0030
49+
`sys_notification` rows. If a **named** deployment turns out to hold rows it
50+
needs, the migration returns as an operator-runnable sub-command shaped exactly
51+
like `files-to-references` / `value-shapes` — dry-run default, `--apply` gate,
52+
documented consequence — under its own card.
53+
54+
<!-- adr-0087: not-required (no-migration-prescription) Nothing authorable moves and nothing is renamed: no spec key, no config field, no stored-metadata shape, and no replacement spelling for anyone to adopt. The removed surfaces are one runtime function on `@objectstack/metadata/migrations`, its three own result/option/receipt types, and one member of a constant tuple — none of which appears in any authorable document, so `objectstack migrate meta` has nothing it could rewrite and a ledger entry would prescribe a rewrite that does not exist. The consumer-side action is a deletion, delivered by the compiler on the import and by the barrel tombstone beside it. -->

docs/handoff/adr-0030-notification-convergence.md

Lines changed: 36 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -62,24 +62,43 @@ a per-user inbox row directly.
6262
a `dedupKey`. No more direct `sys_notification` writes. The plugin resolves the
6363
`messaging` service lazily at hook time (`audit-plugin.ts`).
6464

65-
### Data migration (not auto-run)
65+
### ⚰️ Data migration — RETIRED, there is none
66+
67+
This section used to describe
6668
`packages/metadata/src/migrations/migrate-sys-notification-to-event.ts`
67-
(exported from `@objectstack/metadata/migrations`). Splits each legacy
68-
`sys_notification` inbox row into `sys_inbox_message` + a receipt, rewrites the
69-
row to the event shape, and clears the legacy columns. **Idempotent**; reports
70-
`not_applicable` on fresh installs.
69+
(exported from `@objectstack/metadata/migrations`), which split each legacy
70+
`sys_notification` inbox row into `sys_inbox_message` + a receipt, rewrote the
71+
row to the event shape and cleared the legacy columns.
72+
73+
**That runner is gone (#16194).** It had zero production callers and no
74+
`os migrate` sub-command, and both ways of giving it one were refused: an
75+
operator door is a permanent surface for a migration with no measured demand,
76+
and a boot-time invoker is an unattended data rewrite. ⇒ **Pre-ADR-0030
77+
`sys_notification` rows are not carried by the platform on this line.** After
78+
the cut-over the bell shows rows emitted from the new pipeline onward; older
79+
per-user inbox rows stay where they are, unread by the new UI.
80+
81+
⚠️ Nobody has measured whether any live deployment still holds pre-ADR-0030
82+
`sys_notification` rows. If **your named deployment** does and needs them, ⛔ do
83+
not re-add the call — the migration returns as an operator-runnable `os migrate`
84+
sub-command shaped exactly like `files-to-references` / `value-shapes` (dry-run
85+
default, `--apply` gate, documented consequence), under its own card. Say so on
86+
#16194.
7187

7288
### Tests
73-
`messaging-service`, `inbox-channel`, `messaging-service-plugin`, `notify-node`,
74-
and the migration all have updated/added coverage. All green.
89+
`messaging-service`, `inbox-channel`, `messaging-service-plugin` and
90+
`notify-node` all have updated/added coverage. All green. (The migration's own
91+
suites went with the runner.)
7592

7693
---
7794

7895
## ⚠️ Breaking change — Console bell (objectui, separate repo)
7996

8097
The bell read `sys_notification.{recipient_id, is_read, title, body, …}`. Those
8198
fields **no longer exist**. Until objectui is updated, the bell will be empty /
82-
error. **Do the objectui cut-over and the data migration together.**
99+
error. ⚰️ There is **no data migration to pair it with** any more (see above):
100+
do the objectui cut-over on its own, and expect the bell to start from the
101+
rows the new pipeline emits.
83102

84103
### objectui changes required (`app-shell`)
85104
1. **`AppHeader.tsx` / `InboxPopover.tsx`**: poll **`sys_inbox_message`** filtered
@@ -98,13 +117,19 @@ error. **Do the objectui cut-over and the data migration together.**
98117
### Cut-over sequence (avoid a blank bell)
99118
1. Deploy this framework change (objects + emit + producers). New notifications
100119
now land in `sys_inbox_message` + receipts.
101-
2. Run `migrateSysNotificationToEvent({ driver, data })` to carry existing
102-
notifications into `sys_inbox_message` + receipts.
103-
3. Deploy the objectui bell repoint.
120+
2. Deploy the objectui bell repoint.
104121

105122
(Step order tolerates a brief window where new rows exist but the UI hasn't
106123
flipped — the inbox is being populated the whole time.)
107124

125+
> ⚰️ **This sequence used to have three steps.** The middle one was
126+
> `migrateSysNotificationToEvent({ driver, data })`, carrying pre-cut-over
127+
> `sys_notification` rows into `sys_inbox_message` + receipts. That runner is
128+
> retired (#16194) and **pre-ADR-0030 rows are not carried by the platform on
129+
> this line** — the reasoning, the unmeasured-deployment caveat and the reversal
130+
> path are in [Data migration — RETIRED](#-data-migration--retired-there-is-none)
131+
> above. ⛔ Do not re-add the call here.
132+
108133
---
109134

110135
## Behavior notes / watch-outs

packages/metadata/src/migrations/driver-exec.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,12 @@
1010
* `(path, init)`. `SqlDriver` keeps its knex handle `protected`, so
1111
* `driver.raw` is `undefined` there too, and `SqliteWasmDriver` inherits that.
1212
* The result was a published, operator-documented migration path that refused
13-
* every driver the platform ships — quietly, because
14-
* `migrateSysNotificationToEvent` *returns* `{ status: 'error' }` rather than
15-
* throwing, and the message blamed the operator's driver instead of saying the
16-
* migration did not run.
13+
* every driver the platform ships — quietly, because the helper that found the
14+
* defect *returned* `{ status: 'error' }` rather than throwing, and the message
15+
* blamed the operator's driver instead of saying the migration did not run.
16+
* (That helper — the ADR-0030 notification cut-over — has since been retired
17+
* whole; the surface argument below is what outlived it, and every remaining
18+
* migration in this directory depends on it.)
1719
*
1820
* ## Why `execute` is tried FIRST
1921
*

packages/metadata/src/migrations/index.ts

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,32 @@ export { dropProjectionTables, type DropProjectionResult } from './drop-projecti
4646
*/
4747

4848

49-
export {
50-
migrateSysNotificationToEvent,
51-
type SysNotificationMigrationResult,
52-
type SysNotificationMigrationOptions,
53-
type SysNotificationMigrationReceipt,
54-
} from './migrate-sys-notification-to-event.js';
49+
/**
50+
* ⚰️ TOMBSTONE — `migrateSysNotificationToEvent` /
51+
* `migrate-sys-notification-to-event.ts` (with `SysNotificationMigrationResult`
52+
* / `SysNotificationMigrationOptions` / `SysNotificationMigrationReceipt`) was
53+
* REMOVED. ⛔ Do not reintroduce a runner for the ADR-0030 notification
54+
* cut-over in this package.
55+
*
56+
* It had no way to be run. Re-measured on the tree this tombstone landed on:
57+
* ZERO production callers anywhere in `packages` / `apps` / `examples` — the
58+
* definition, its own usage docblock, this barrel line, one comment in
59+
* `./driver-exec.ts`, the id's docblock in `@objectstack/spec` and three test
60+
* files were every non-CHANGELOG occurrence there was. The instrument was live
61+
* in the same run: the symbol was in 17 files.
62+
*
63+
* Two ways to give it one were considered and both refused. An
64+
* `os migrate notification-event` sub-command shaped like its two
65+
* `CREATION_ATTESTED_MIGRATION_IDS` siblings is a permanent operator surface
66+
* for a migration with no measured demand; a boot-time invoker is an
67+
* unattended data rewrite nobody asked for. Pre-ADR-0030 `sys_notification`
68+
* rows are not carried by the platform on this line.
69+
*
70+
* ⚠️ Stated rather than papered over: nobody has measured whether any live
71+
* deployment carries pre-ADR-0030 `sys_notification` rows. If a NAMED
72+
* deployment turns out to hold rows it needs, the migration returns as an
73+
* operator-runnable sub-command shaped exactly like `files-to-references` /
74+
* `value-shapes`, under its own card — with the dry-run posture, the `--apply`
75+
* gate and the documented consequence those two carry, none of which this one
76+
* ever had.
77+
*/

0 commit comments

Comments
 (0)