Repository navigation
feat(service-settings)!: the settings audit trail's global rung moves to a deployment-level sibling, sys_platform_setting_audit (18.x step 2, expand-first) - #24590
Conversation
…bal-rung settings audit to a sibling (WIP) Claude-Session: https://claude.ai/code/session_01HZT9daB4YX41N1SVVxYcek Co-authored-by: Claude <noreply@anthropic.com>
…ped rows still read (WIP) Claude-Session: https://claude.ai/code/session_01HZT9daB4YX41N1SVVxYcek Co-authored-by: Claude <noreply@anthropic.com>
…rung to its sibling; checklist re-pointed (WIP) Claude-Session: https://claude.ai/code/session_01HZT9daB4YX41N1SVVxYcek Co-authored-by: Claude <noreply@anthropic.com>
…ing too (WIP) Claude-Session: https://claude.ai/code/session_01HZT9daB4YX41N1SVVxYcek Co-authored-by: Claude <noreply@anthropic.com>
…rally; tenant-audit census regenerated Claude-Session: https://claude.ai/code/session_01HZT9daB4YX41N1SVVxYcek Co-authored-by: Claude <noreply@anthropic.com>
…bel; query options typed in the expand pin Claude-Session: https://claude.ai/code/session_01HZT9daB4YX41N1SVVxYcek Co-authored-by: Claude <noreply@anthropic.com>
…0e-deployment-level Claude-Session: https://claude.ai/code/session_01HZT9daB4YX41N1SVVxYcek Co-authored-by: Claude <noreply@anthropic.com>
… ceremony drops their declared column The kept ceremony class blocks its column-drops step on a column the runtime still declares, so the fate moves with the declaration, in step 5. Claude-Session: https://claude.ai/code/session_01HZT9daB4YX41N1SVVxYcek Co-authored-by: Claude <noreply@anthropic.com>
…pped them; this step builds the settings-audit sibling only Per the epic seat's binding scope correction (step 0's measured plan, os-dev-report 6268559156): the column-less flip of sys_secret and sys_flow_credential moves to step 6, with the opened ceremony. Claude-Session: https://claude.ai/code/session_01HZT9daB4YX41N1SVVxYcek Co-authored-by: Claude <noreply@anthropic.com>
…_flow_credential stayed tenant-scoped Claude-Session: https://claude.ai/code/session_01HZT9daB4YX41N1SVVxYcek Co-authored-by: Claude <noreply@anthropic.com>
📓 Docs Drift CheckThis PR changes 4 package(s): 60 hand-written doc(s) name something this change touched — list omitted above 15 rows. Re-derive on the tree named below: ⛔ 13 release-owned page(s) also affected — read-only, see AGENTS.md Documentation Guardrails. What this run could not see
Coarse fallback — 151 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): Which tree this was computed onThis run read A worktree cut from an older # while this PR is open — GitHub drops the merge commit once it closes
git fetch origin aa347d082214b0ff47d6ca657299c728f29d29b9 && git checkout aa347d082214b0ff47d6ca657299c728f29d29b9
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 8fbbd5082f3fcde0d972c76cfcd4d286c4eb4fa1 2b295cabd4d838576682f001485858831f0be334 && git checkout -B drift-repro 8fbbd5082f3fcde0d972c76cfcd4d286c4eb4fa1 && git merge --no-ff 2b295cabd4d838576682f001485858831f0be334
node scripts/docs-audit/affected-docs.mjs --json 8fbbd5082f3fcde0d972c76cfcd4d286c4eb4fa1
|
Contract reviewServed-tier: Reviewer: an isolated at-tier reviewer subagent of the adopting seat ( ① Derived judgments(a) Fresh install — PASS. (b) 18.0 database — PASS, the report's claim verified. The writer routes by rung only ( (c) Nothing moves, deletes or re-stamps 18.0 rows; no column drops — PASS. The diff touches no ceremony, apply, migration or schema-sync code; (d) R1–R4 and the boot guard (F2) — PASS. F2: (e) Complete feature (6270035914) — PASS. New installs write the new shape through a live predicate; the sibling is registered in the service manifest ( (f) The open questions — all five "A" readings are sound. (1) Reverting the Minor, non-blocking: ② Semver level
③ Boundary flags
Implemented-by: VERDICT: PASS |
…0e-deployment-level Claude-Session: https://claude.ai/code/session_01HZT9daB4YX41N1SVVxYcek Co-authored-by: Claude <noreply@anthropic.com>
…d tree; the read-door docblock and dual-write title name the sibling Claude-Session: https://claude.ai/code/session_01HZT9daB4YX41N1SVVxYcek Co-authored-by: Claude <noreply@anthropic.com>
…0e-deployment-level Claude-Session: https://claude.ai/code/session_01HZT9daB4YX41N1SVVxYcek Co-authored-by: Claude <noreply@anthropic.com>
…he merged tree (both siblings: sys_identity_email, sys_platform_setting_audit) Claude-Session: https://claude.ai/code/session_01HZT9daB4YX41N1SVVxYcek Co-authored-by: Claude <noreply@anthropic.com>
Closes #24530
Clause-②: yes (narrowing)
18.x line, step 2 (8b-0e′), expand-first. This is PR 2a only.
The
sys_secret/sys_flow_credentialflip (ruling record 6259141885, #24435 Q1 A, for the latter) is not in this PR. It moves to step 6, with the opened ceremony; see "Measured" below.⛔ Merge gate. This PR stays a draft until #24522's upgrade harness (#24552) has merged. Then it merges
main, runs the harness, and lands only when R1–R4 hold with the harness green.What changes
New
sys_platform_setting_audit, the settings audit trail's global rung, created fresh:systemFields: { tenant: false }: no organization column;requiredPermissions: ['manage_platform_settings'], assys_platform_settinghas;managedBy: 'engine-owned', with reads only on the data API;sys_setting_audit, withscopealwaysglobal.It registers with service-settings (the manifest), joins
SETTINGS_READ_DOOR_OBJECTS(so each namespace'sreadPermissionapplies there too), and joinsPLATFORM_OBJECTS_BY_PACKAGE.The writer routes by rung (
buildSettingAuditWriter, through one predicate,settingAuditObjectFor):scope === 'global'goes to the sibling, with no organization;sys_setting_audit, stamped as before;Regenerated with the repo's tooling:
scripts/platform-object-tenancy-census.json: the sibling is added, out of reach becausesystemFields.tenantisfalse;Inventory: the sibling's row, placed next to
sys_setting_audit's (column-drop, no column).Platform checklist: two items that read the global rung's audit rows from
sys_setting_auditare re-pointed, each with a revision bump and a history entry.Measured: why
sys_secretandsys_flow_credentialare untouchedMeasured: the 18.0 DDL for the two tables, populated with 18.0-shaped rows, then the engine's schema sync and the v18 boot guard's own predicate.
findV17ShapeTables)detectManagedDrift)systemFields: { tenant: false },organization_idnot declared["sys_flow_credential","sys_secret"]drop_column,destructive, on both tablestenancy: { enabled: false },organization_idkept declared[][]The first row refuses every 18.0 database at boot, which breaks R2. The second escapes the guard, and the epic seat rules that escape a gap, not a route. The kept ceremony class would also block its
column-dropsstep on a column the runtime still declares: measured onorganization-ownership-boot-refusal-order.dogfood.test.tswhen the two objects' inventory fates were moved, and reverted. So both objects ship as 18.0 shipped them, and their flip lands with step 6.18.0 rows
sys_setting_audit, stamped with the Default Organization. They stay there, readable through the data API as before.sys_setting_auditrows selected byscope = 'global', never by a NULL organization.The step-5/6 ceremony owes
sys_setting_auditscope = 'global'rows tosys_platform_setting_audit: an inventorydeparturesentry, plus aMOVESentry inorganization-ownership-apply.tslikesys_setting'sglobal-rung-move. Thenscope'sglobaloption can retire, and 8e's NOT NULL applies to the rest.sys_secretsystemFields: { tenant: false }, the inventory fate goes 3 →column-drop, and thecolumn-dropsstep dropsorganization_id. The settings writer stops stamping it.sys_flow_credentialcolumn-drops.sys_platform_setting_auditStep 7 removes the dual read: once the move has run, the global rung's history is the sibling alone.
Proof
pnpm dev -- --freshshowcase boot.GET /api/v1/discoveryanswered 200.PUT /api/settings/ai(encrypted, global) andPUT /api/settings/branding(tenant) answered 200./data/sys_platform_setting_auditlists the global rows with no organization, and/data/sys_setting_auditthe tenant rows, stamped.f6128e3, run locally on this branch: 5/5 green (its files are not committed here).OS_TENANCY_POSTURE=isolated pnpm dev -- --freshexits 1 withtenancy posture 'isolated' is not supported in 18.0 (NOT_IMPLEMENTED).New pins:
service-settings/src/settings-deployment-level-expand.test.ts: a real engine undersinglewith a live D9-stamp control. The new write shape, and the dual read on an 18.0-shaped row.service-settings/src/settings-secret-organization.test.ts: per-rung routing through the one predicate.qa/dogfood/test/settings-audit-global-rung-sibling.dogfood.test.ts: two showcase boots over one file, the second with an 18.0-shaped stamped global audit row.Ablation X6: the routing predicate was pinned to
sys_setting_audit, viascripts/ablation-replace.mjs, rebuilt, and checked byablation-dist-preflightin both directions.HEADblob.Acceptance notes
manage_platform_settingsto be read through the data API. That is the narrowing the changeset states, with its remedy.docs/qachecklist items 7 and 29 were re-pointed because their clauses stopped being true. Not in the claim's named surface; noted for the seat.Generated by Claude Code