|
1 | 1 | --- |
2 | | -'@objectstack/cli': patch |
| 2 | +'@objectstack/cli': minor |
3 | 3 | --- |
4 | 4 |
|
5 | | -feat(cli): `os migrate organization-ownership --apply` executes only the plan the operator reviewed (ADR-0131 D10) |
| 5 | +feat(cli)!: `os migrate organization-ownership --apply` executes only the plan the operator reviewed (ADR-0131 D10) |
6 | 6 |
|
7 | | -Clause-②: no |
| 7 | +Clause-②: yes (widening) |
8 | 8 |
|
9 | | -`--apply` now requires `--plan-file FILE`, the plan file a plan run wrote. Before it writes anything it compares that file with the plan it computes, and refuses when either differs: |
| 9 | +<!-- adr-0087: not-required (no-migration-prescription) No metadata moves: no spec key, authorable spelling, object definition or stored shape is added, removed, renamed or re-shaped, and no exported declaration is removed or narrowed, so there is nothing for `objectstack migrate meta` to rewrite. What narrows is the accept set of one CLI command's writing mode: `--apply` without the reviewed plan file is refused, and the remedy is in the invocation an operator types (add `--plan-file`), never a rewrite of a package source or a stored row. The other categories are closed on facts: the package publishes (not unpublished); no ADR-0087 id is named or touched (not registered or already-registered); and nothing exported is removed or narrowed (not runtime-interface-only, type-surface-only or runtime-export-retired). --> |
10 | 10 |
|
11 | | -- **Another inventory digest** (`plan-digest-mismatch`): the fates it would run are not the ones the reviewed plan showed. That happens with a different `--fate-supplement`, or with another release's inventory. Without this check, planning with supplement A and applying with supplement B ran B's fates unreviewed, including a mirror deletion A never listed. |
12 | | -- **Another tenancy posture** (`plan-posture-mismatch`): the plan file records the posture it was computed under (`OS_TENANCY_POSTURE` / `OS_MULTI_ORG_ENABLED`), and the posture decides which rows attribution gives an owner and which it reports. A plan reviewed under a wall, which lists rows as reported, would otherwise give them owners when applied under `single`. |
13 | | -- **Another database** (`plan-database-mismatch`). |
| 11 | +**BREAKING** (a narrowing of `--apply`'s accept set, released in 18.0.0-next.1), shipped as `minor` under the launch-window convention for breaking changes. It also widens the command: a new flag, `--plan-file`, new refusal reasons, and two new keys on the apply report. |
| 12 | + |
| 13 | +`--apply` now requires `--plan-file FILE`, the plan file a plan run wrote. Before it writes anything, it compares that file with the plan it computes, and refuses when any of these differs: |
| 14 | + |
| 15 | +- **The inventory digest** (`plan-digest-mismatch`). The fates it would run are not the ones the reviewed plan showed: a different `--fate-supplement`, or another release's inventory. Without this check, planning with supplement A and applying with supplement B ran B's fates unreviewed, including a mirror deletion A never listed. |
| 16 | +- **The tenancy posture** (`plan-posture-mismatch`). The plan file records the posture it was computed under (`OS_TENANCY_POSTURE` / `OS_MULTI_ORG_ENABLED`), and the posture decides which rows attribution gives an owner and which it reports. A plan reviewed under a wall, which lists rows as reported, would otherwise give them owners when applied under `single`. |
| 17 | +- **The database** (`plan-database-mismatch`). |
14 | 18 |
|
15 | 19 | The refusal names both values and the remedy: run the plan again with the same flags (or run the apply under the plan's posture), review it, and pass the new file. No flag skips the comparison. |
16 | 20 |
|
17 | | -A file that is not an organization-ownership plan (missing its digest, posture or database), or cannot be read, is refused as `plan-file-unusable`. `--apply` without the flag is refused as `plan-file-required`. Both refusals come before the backup question and before the database is opened. |
| 21 | +A file that is not an organization-ownership plan, or that lacks its digest, posture or database, or cannot be read, is refused as `plan-file-unusable`. `--apply` without the flag is refused as `plan-file-required`. Both refusals come before the backup question and before the database is opened. |
18 | 22 |
|
19 | 23 | A checkpoint recorded under another digest is no longer discarded silently. The reviewed plan supersedes it: every step runs again (each is idempotent), and the apply report names the discarded checkpoint in `restartedFrom`, beside `reviewedPlan`. |
20 | 24 |
|
21 | | -`--apply` has not shipped in a release yet (its changeset is still pending), so no released invocation changes. The one-line form is: |
| 25 | +## FROM → TO |
| 26 | + |
| 27 | +| invocation | FROM (18.0.0-next.1) | TO | |
| 28 | +|:--|:--|:--| |
| 29 | +| `os migrate organization-ownership --apply --backup-taken` | performed the plan it computed at apply time | refused, `plan-file-required`: run `os migrate organization-ownership --out plan.json`, review it, then `--apply --backup-taken --plan-file plan.json` | |
| 30 | +| `os migrate organization-ownership --fate-supplement host-fates.json --apply --backup-taken` | performed the plan it computed with that supplement | refused, `plan-file-required`: plan with the same `--fate-supplement`, then add `--plan-file plan.json` | |
| 31 | +| `--apply … --plan-file plan.json`, where the file was planned with another supplement, release, posture or database | (no such flag) | refused with `plan-digest-mismatch`, `plan-posture-mismatch` or `plan-database-mismatch`, naming both values | |
22 | 32 |
|
23 | 33 | ```bash |
24 | 34 | os migrate organization-ownership --out plan.json # plan, then review plan.json |
|
0 commit comments