You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix(spec): register the missing migration surface for the enable.trash/mru removal + repoint tombstones at #3146 (#3207) (#4734)
The 16.x removal of the dead object capability flags (PR #3414) tombstoned
enable.trash / enable.mru in the .strict() capabilities block but registered
no ADR-0087 D2 conversion, and its prescriptions pointed at #1893 — closed
2026-07-24. Per the #3207 ruling (2026-08-02): soft delete is parked at
#3146, and the retirement follows the full spec-property-retirement kit.
- New conversion `object-enable-trash-mru-removed` (protocol 17,
retiredFromLoadPath): stored 16.x rows replay clean through
applyConversionsToStoredItem instead of flagging metadata_spec_invalid on
every rehydration (#3903 invariant — chain-owned history is not a
current-contract violation), and `os migrate meta --from 16` rewrites
authored sources. Wired into MIGRATIONS_BY_MAJOR[17] with rationale;
fixture proves the strip is surgical (surviving `searchable` untouched).
- Tombstones now name #3146 (trash) and the `os migrate meta --from 16`
rewrite (both); the restore legacy-apiMethod guidance and the
api-derivation note drop the dead #1893 pointer.
- remove-enable-trash-mru changeset flipped minor -> major: v17 is the
breaking window and the guard stands aside in pre-mode; a breaking
removal listed under "Minor Changes" in the compiled CHANGELOG would
mislead upgrading agents.
- Pin tests: prescription must name #3146 + the migrate command and must
not resurrect #1893; stored-row replay strips exactly the two keys.
Gates: spec build green; check:generated all 8 green after
gen:spec-changes/gen:upgrade-guide; liveness/empty-state/strictness-ledger/
skill gates green; spec 7400, cli 581, metadata-protocol 231 tests pass;
check:i18n 9/9 in sync (zero drift).
Claude-Session: https://claude.ai/code/session_0176qgxgCXTJCUv4YFLtusP9
Co-authored-by: Claude <noreply@anthropic.com>
fix(spec): register the missing ADR-0087 migration surface for the `enable.trash` / `enable.mru` removal, and repoint its tombstones at the parked soft-delete issue (#3207)
6
+
7
+
The 16.x removal of the dead object capability flags (PR #3414,
8
+
`remove-enable-trash-mru`) tombstoned both keys in the `.strict()`
9
+
capabilities block but registered no D2 conversion. Two consequences this
10
+
closes:
11
+
12
+
-**Stored 16.x rows flagged forever.** A `sys_metadata` object row written
13
+
before the removal still carries `enable.trash`/`enable.mru`; with no
14
+
conversion to own that history, every rehydration re-flagged it
15
+
`metadata_spec_invalid` — mislabelling chain-owned history as a
16
+
current-contract violation (#3903's invariant). The new
Copy file name to clipboardExpand all lines: docs/protocol-upgrade-guide.md
+3Lines changed: 3 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -176,6 +176,8 @@ The subtle half is the defaults, and it is worth stating because no gate can see
176
176
177
177
The same enforce-or-remove pass reaches the event vocabulary: `DataEventType` drops `data.field.changed` (#4673). It had no producer anywhere — the engine emits `data.record.{created,updated,deleted}` and, since #4639, `data.records.{updated,deleted}` — so a subscriber switching on it held a branch that could never run, and the `switch` still compiled, which is why an empty member could sit in a public enum this long. It could not have been implemented against this contract as written: `DataEventSchema` is record-shaped and has no `field` / `oldValue` / `newValue` slot, so the member advertised a granularity the payload has no room for. Nothing is lost — per-field detail already rides on `data.record.updated` as `changes` (with `before` / `after`), one event per write instead of N on a wide table. Like the driver contract above it is a runtime surface, never stored in stack metadata, so it is one semantic TODO for event consumers rather than a source rewrite, and it carries no tombstone: a removed enum VALUE cannot hold a fix-it error, exactly as the sharing-rule `full` retirement noted. Should a real per-field stream ever be wanted, it earns its own contract on the #4639 precedent rather than reclaiming this slot.
178
178
179
+
The object capability block closes out the same ADR-0049 pass: `enable.trash` and `enable.mru` left the schema in the 16.x line (#3207, the #2377 close-out — every delete has always been a hard delete and MRU tracking was never implemented, so both default-true flags gated nothing), and the `.strict()` capabilities block rejects them with the prescription. This step registers the migration surface that removal was missing: stored 16.x rows replay clean instead of flagging `metadata_spec_invalid`, and `os migrate meta --from 16` rewrites authored sources. Soft delete stays parked at #3146; if built it returns as a live enforced flag rather than by reviving these keys.
180
+
179
181
### Mechanical (applied for you)
180
182
181
183
| Conversion | Surface | Change | Load window |
@@ -215,6 +217,7 @@ The same enforce-or-remove pass reaches the event vocabulary: `DataEventType` dr
215
217
|`flow-node-script-branch-keys-removed`|`flow.node.script.config.actionType / flow.node.script.config.template / flow.node.script.config.recipients / flow.node.script.config.variables / flow.node.script.config.script`| script flow-node config keys 'actionType' (→ 'function' when it was shorthand for one; otherwise removed — 'email'/'slack' were logger-backed stubs that delivered nothing), plus 'template' / 'recipients' / 'variables' (fed those stubs) and 'script' (inline JS the runtime never executed) (#4343) | retired — `migrate meta` only |
216
218
|`retry-policy-converged`|`flow.node.config.retry.retryDelayMs / job.retryPolicy.maxRetries / job.retryPolicy.backoffMultiplier`| retry policy unified across job.retryPolicy and try_catch retry: base delay 'retryDelayMs' → 'backoffMs', and the pre-17 job defaults (maxRetries 3, backoffMultiplier 2) written out explicitly now that the merged default is 0 / 1 (#4661) | live — protocol 17 loader accepts the old shape |
217
219
|`object-managed-by-system-to-system-data`|`object.managedBy`| object managedBy 'system' → 'system-data' (#3355 — ADR-0103's residual bucket named the engine-owned half v16 had already moved out to `engine-owned`; the rename leaves the name describing what the bucket actually holds: admin/user-writable platform data) | retired — `migrate meta` only |
220
+
|`object-enable-trash-mru-removed`|`object.enable.trash / object.enable.mru`| object capability flags 'enable.trash'/'enable.mru' removed (#3207, #2377 close-out — no recycle bin and no MRU tracking ever ran; both default-true flags gated nothing) | retired — `migrate meta` only |
218
221
219
222
### Semantic (delegated to you, with acceptance criteria)
Copy file name to clipboardExpand all lines: packages/spec/spec-changes.json
+12Lines changed: 12 additions & 0 deletions
Original file line number
Diff line number
Diff line change
@@ -277,6 +277,12 @@
277
277
"to": "object managedBy 'system' → 'system-data' (#3355 — ADR-0103's residual bucket named the engine-owned half v16 had already moved out to `engine-owned`; the rename leaves the name describing what the bucket actually holds: admin/user-writable platform data)",
"to": "object capability flags 'enable.trash'/'enable.mru' removed (#3207, #2377 close-out — no recycle bin and no MRU tracking ever ran; both default-true flags gated nothing)",
"to": "object managedBy 'system' → 'system-data' (#3355 — ADR-0103's residual bucket named the engine-owned half v16 had already moved out to `engine-owned`; the rename leaves the name describing what the bucket actually holds: admin/user-writable platform data)",
"to": "object capability flags 'enable.trash'/'enable.mru' removed (#3207, #2377 close-out — no recycle bin and no MRU tracking ever ran; both default-true flags gated nothing)",
0 commit comments