Repository navigation
Commit d0514e6
fix(plugin-security): the platform-admin promotion WITHHELD warning says what 18.0 supports for a v17 database (#24718)
Fixes #24709
Clause-②: no
## What this changes
The boot warning "[security] platform-admin promotion WITHHELD: an
unscoped grant exists whose permission-set name
(sys_user_permission_set.permission_set) was never written" ended by
sending the operator to the organization-ownership migration: "The
organization-ownership migration's id-to-name rewrite (ADR-0131 D10)
names it; the next pass after that reads it by name." 18.0 refuses that
migration on every database, so an operator booting a v17-shaped
database with an unnamed grant was pointed at a refusal.
The warning now ends with the sentence the boot refusal and the two
sibling release-text rows already carry (PR #24635 and PR #24679 landed
it): "18.0 supports fresh installs only and does not upgrade a v17
database: keep a v17 database on a 17.x release until the 18.x release
that carries the upgrade path."
Text only. The withholding does not move:
`findPlatformAdminGrantHolder`, the `unnamedHolder` guard, the returned
`adminPromoted: false` / `admin_grant_unnamed` result, the `logger.warn`
/ `logger.info` fallback and every other clause of the warning (what is
withheld, why, "this pass will not mint a second one") are unchanged.
Files:
`packages/plugins/plugin-security/src/bootstrap-platform-admin.ts` (the
string only, 2 lines),
`packages/plugins/plugin-security/src/grant-readers-unnamed-grant.test.ts`
(one new case), `.changeset/24709-platform-admin-withheld-18-text.md`
(`@objectstack/plugin-security` patch).
## Pin
One case in `grant-readers-unnamed-grant.test.ts`, beside the existing
unnamed-holder cases, which already build the state (an unscoped
`admin_full_access` grant written with a NULL name, an older account the
age rule would otherwise promote). It runs `bootstrapPlatformAdmin` with
a capturing logger and asserts:
- the pass took the unnamed-holder branch (`adminPromoted: false`,
`reason: 'admin_grant_unnamed'`) and logged the WITHHELD warning exactly
once (anti-vacuity);
- the whole warning text equals the kept clauses followed by the 18.0
sentence, and ends with it;
- the text names none of `organization-ownership`, `os migrate`,
`--out`, `--apply`, `--plan-file`, `ceremony`, `id-to-name`.
## Evidence (head `7357dcca56`)
- Closure build: `pnpm --workspace-concurrency=2 --filter
'@objectstack/plugin-security^...' build`, under the verify lock,
VERDICT command-exit 0.
- Pin file alone: `pnpm --filter @objectstack/plugin-security exec
vitest run --maxWorkers=2 src/grant-readers-unnamed-grant.test.ts` is 8
passed (7 existing plus the new case), VERDICT command-exit 0, run again
after the ablation was restored: 8 passed.
- Typecheck: `pnpm --filter @objectstack/plugin-security typecheck` exit
0, including `check:test-typecheck` (the test layer compiles, 0 errors).
- Ablation (the diff changes a test-pinned string): the old clause put
back through `scripts/ablation-replace.mjs` (anchor hit once, blob
`eac7d8f87baa` to `f9123b5ffce1` on disk). The test imports
`./bootstrap-platform-admin.js` from `src`, so no rebuild leg applies.
Result: 1 failed, 7 passed, the new case red with the old clause as the
received text, the expected direction (red). Restore proven on disk:
blob equals the HEAD blob and `git diff HEAD` is empty.
- Gates: `node scripts/pm/dispatch-gates.mjs --commands --repo
objectstack-ai/objectstack` derived 68 commands; each was run with its
exit captured before any pipe, then `--ran` reconciled: 68 derived, 67
run (all exit 0), 1 NOT-MEASURED, 0 UNRUN. `pnpm check:i18n` first
exited 3 (prerequisite not met), was re-run after building its stated
closure, and exited 0.
- NOT MEASURED: `pnpm check:dual-build-cjs-loads`, reason: it reads the
built output of every package and exits 3 (prerequisite not met) without
a whole-workspace build, which CI's `Build Core` owns; this diff changes
no export, `package.json` or build config.
- Left to CI: the full plugin-security suite, `test:repo`, the
type-check lanes, and the lint workflow's repo-wide gates.
## Acceptance notes
- Not changed, by the ruling that only the warning string moves: the doc
comment in `bootstrap-platform-admin.ts` (the "By name, and the grant
that names nothing" section), the comment above the `unnamedHolder`
guard, the header of `grant-readers-unnamed-grant.test.ts` and a comment
in `cleanup-package-permissions.ts` all still describe the v18
ceremony's rewrite in the future tense. They are developer-facing
comments, not operator text; noted, not filed.
- The second `promotion WITHHELD for ...` warning in the same file (the
Default Organization one) is a different condition and names no
migration; unchanged.
- Order note from the card: #24681 (the 18.x steps that reopen the
ceremony) re-states the surfaces #24635 taught, and this line joins them
when it lands. #24681 remains open and this PR does not touch its files.
- #24637 remains open: this is its `domain:services` row 2, and other
rows of that family are outside this PR.
- `origin/main` moved by five commits while this was open (none touches
plugin-security or this changeset), so main was not merged in.
---
_Generated by [Claude
Code](https://claude.ai/code/session_011TdZ8GjixNZFLz1xJD9zzK)_
Co-authored-by: Claude <noreply@anthropic.com>1 parent ec2694d commit d0514e6
3 files changed
Lines changed: 50 additions & 2 deletions
File tree
- .changeset
- packages/plugins/plugin-security/src
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
880 | 880 | | |
881 | 881 | | |
882 | 882 | | |
883 | | - | |
884 | | - | |
| 883 | + | |
| 884 | + | |
885 | 885 | | |
886 | 886 | | |
887 | 887 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
221 | 221 | | |
222 | 222 | | |
223 | 223 | | |
| 224 | + | |
| 225 | + | |
| 226 | + | |
| 227 | + | |
| 228 | + | |
| 229 | + | |
| 230 | + | |
| 231 | + | |
| 232 | + | |
| 233 | + | |
| 234 | + | |
| 235 | + | |
| 236 | + | |
| 237 | + | |
| 238 | + | |
| 239 | + | |
| 240 | + | |
| 241 | + | |
| 242 | + | |
| 243 | + | |
| 244 | + | |
| 245 | + | |
| 246 | + | |
| 247 | + | |
| 248 | + | |
| 249 | + | |
| 250 | + | |
| 251 | + | |
| 252 | + | |
| 253 | + | |
| 254 | + | |
| 255 | + | |
| 256 | + | |
| 257 | + | |
| 258 | + | |
| 259 | + | |
| 260 | + | |
224 | 261 | | |
225 | 262 | | |
226 | 263 | | |
| |||
0 commit comments