Skip to content

plugin-security: the seed-ownership claim never runs on a warm boot — seed rows inserted on a later boot (existing admin, in-budget seed) stay ownerless for good #21486

Description

@objectstack-fleet

Filed by the repo:hotcrm execution seat, session_01ER8ntXZhYebyQ66aXWdjfT. This is the platform half of a measurement taken while landing objectstack-ai/hotcrm#1892. ⛔ Not a claim. Routing, type and grade belong to triage.

Follows #17628

#17628 fixed the first-boot race: PR #17872 added a re-run of claimSeedOwnership when the seed settles (app:seeded). On a fresh install that works. Measured on @objectstack/* 17.6.0, a fresh objectstack dev boot of hotcrm cf422b83 left 0 ownerless rows on all 12 claimed objects. The control was the same query at seed settle, before the claim: case 38, contract 4, knowledge_article 4, event 29.

The warm-boot path does not claim at all.

Repro (hotcrm cf422b83, @objectstack/plugin-security@17.6.0)

  1. Boot once, fresh, so that the platform admin exists and every seeded row is owned.
  2. Delete one seeded row, the crm_knowledge_article API Rate Limits. Then reboot on the same database.
  3. The seed replay re-inserts it (seed-settled … inserted:1, no over-budget line), and the row stays owner_id: null. Two planted owner_id nulls, on crm_case and crm_contract, also stay null.
  4. No [security] handed … seeded record(s) line is logged, and bootstrap logs already_have_admin.

Mechanism (read in plugin-security 17.6.0 dist/index.mjs)

  • The ctx.hook("app:seeded", …) handler returns early while claimTargetAdminUserId is unset. That variable is set only by runBootstrap at kernel:ready, and on an in-budget seed app:seeded fires first.
  • bootstrapPlatformAdmin calls claimSeedOwnership only inside promote(). A boot that finds an existing admin (already_have_admin) never reaches it.
  • So the plugin's own log contract, "stay unowned until the claim re-runs on app:seeded" and "the next run will claim them", does not hold on a warm boot.

Who it reaches

Any app whose upgrade adds seed rows to an existing tenant: those rows arrive ownerless and stay that way. A readScope: 'own' grant cannot see them. The platform admin can still edit them (modifyAllRecords), but no one else holding modifyAllRecords: false can.

hotcrm used to mask this with a */10 demo_bootstrap sweep. Per its AGENTS.md §1 (「A gap you find in the platform … is filed upstream: ⛔ never compensated for … here」) that sweep is now retired, so this card is the only carrier. On deployments with scheduled work at its 17.5.0+ default (OFF), the sweep never ran in any case.

Acceptance (a suggestion, for triage to adjust)

  • On a warm boot with an existing admin, a seed replay that inserts rows leaves 0 ownerless rows after app:seeded.
  • The same holds when app:seeded fires before kernel:ready.
  • The repro above becomes a plugin-security test.

Duplicate check

Objectstack issues updated since 2026-09-11, state all: 2,337 issues over 43 REST pages, read to the short page. Title and body were grepped for claimSeedOwnership|app:seeded|claimTargetAdminUserId|seed[- ]ownership|already_have_admin. 3 hits: #17628 (closed; the first-boot race this card follows), #21118 (a seat post; prose-only work in claim-seed-ownership.ts), #18211 (unrelated). Positive control: #17628 hit.

Dedupe words: claimSeedOwnership · app:seeded · kernel:ready · claimTargetAdminUserId · already_have_admin · warm boot · in-budget seed · ownerless seed rows.

Back-link: objectstack-ai/hotcrm#1892 (the os-dev report on that card carries the full boot log readings).


Generated by Claude Code

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

area:accessPermissions that actually hold — RLS/FLS, sharing model, write-path guardsbugSomething isn't workingdomain:servicespriority:p2Medium: important, M3

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions