Skip to content

fix(dev): unify dev admin seed in-process; remove port-drift HTTP seed - #1503

Merged
xuyushun441-sys merged 3 commits into
mainfrom
fix/dev-seed-admin-in-process
Jun 2, 2026
Merged

fix(dev): unify dev admin seed in-process; remove port-drift HTTP seed#1503
xuyushun441-sys merged 3 commits into
mainfrom
fix/dev-seed-admin-in-process

Conversation

@xuyushun441-sys

Copy link
Copy Markdown
Contributor

Problem

pnpm dev:showcase often failed to auto-seed a usable admin:

  • Port drift (the real bug):os dev seeded over HTTP against a hard-coded localhost:3000. In dev, serve auto-shifts off a busy port (3000 → 3001), but the parent never learned the new port and POSTed to 3000 — hitting the wrong server (or nothing). The showcase instance never got an admin.
  • Ghost admin: a second, divergent seed in plugin-dev inserted a raw sys_user row with no credential (admin@dev.local), producing an un-loginable account. It also wasn't even loaded by the showcase.

So we had two seeds: one in the right place (in-process) but broken (no credential, no promotion), and one correct (real auth path, promoted) but in the wrong place (HTTP, racing readiness, hard-coded port).

Fix — consolidate to one in-process seed

  • plugin-auth: maybeSeedDevAdmin() runs on kernel:ready. Creates admin@objectos.ai / admin123 through better-auth's real server-side signUpEmail pipeline (hashed credential + hooks) → fully loginable; plugin-security's first-user middleware promotes it to platform admin. Empty-DB only (excludes the SystemUserId.SYSTEM service account), idempotent, never overwrites an existing account. Hard-gated to NODE_ENV=development; opt out with OS_SEED_ADMIN=0. No port, no readiness race.
  • cli/dev: deleted the HTTP seedAdminAccount; --seed-admin now only passes OS_SEED_ADMIN[_EMAIL|_PASSWORD] to the serve child. Removed a dead port param from the watch loop.
  • cli/serve: publishes the actually-bound port — process.send({type:'objectstack:listening', port, url}) over IPC + a runtime.<env>.json state file under OS_HOME for external supervisors.
  • plugin-dev: removed the credential-less raw insert; seedAdminUser now maps to the unified OS_SEED_ADMIN toggle.

Verification (real showcase runs)

BehaviorResult
Seed creates loginable adminsign-in admin@objectos.ai/admin123200
Platform-admin promotionsys_user_permission_setadmin_full_access, organization_id: null
Port auto-shift3999 busy → bound 4000; parent logged the shift; seed landed on 4000 (old code seeded stale 3999)
runtime.json written{pid, port, url, environmentId, startedAt}
Opt-out (--no-seed-admin)child OS_SEED_ADMIN=0 → no seed → 401
Idempotent on persistent DBRUN2 same DB: sign-in 200, perm-set total 1 (no dup), sys_user count 2

Tests: plugin-auth 88, plugin-dev 7, cli 144 — all green. Typecheck/build clean.

🤖 Generated with Claude Code

os-zhuangand others added 2 commits June 2, 2026 08:52
feat(studio): AI-draft review/diff mode in the object designer (v1) (#1456)
objectui@fdd083657e2da9832059492d4c88e818a5990a8d
`pnpm dev:showcase` often failed to provision a usable admin. The CLI
seeded over HTTP against a hard-coded localhost:3000, but dev auto-shifts
off a busy port — so the POST hit the wrong server (or nothing) and the
showcase instance never got an admin. A second, divergent seed in
plugin-dev inserted a raw sys_user row with no credential, producing an
un-loginable ghost admin (admin@dev.local).
Consolidate to a single in-process seed in the runtime:
- plugin-auth: maybeSeedDevAdmin() runs on kernel:ready, creates the admin
(admin@objectos.ai / admin123) through better-auth's real signUpEmail
pipeline (hashed credential + hooks), so it is fully loginable;
plugin-security's first-user middleware promotes it to platform admin.
Empty-DB only (excludes the SystemUserId.SYSTEM account), idempotent,
never overwrites an existing account. Hard-gated to NODE_ENV=development;
opt out with OS_SEED_ADMIN=0. No port, no readiness race.
- cli/dev: delete the HTTP seedAdminAccount entirely; --seed-admin now just
passes OS_SEED_ADMIN[_EMAIL|_PASSWORD] to the serve child. Drop the dead
`port` param from the watch loop.
- cli/serve: publish the actually-bound port — process.send({type:
'objectstack:listening', port, url}) over IPC + a runtime.<env>.json
state file under OS_HOME for external supervisors.
- plugin-dev: remove the credential-less raw sys_user insert; seedAdminUser
now maps to the unified OS_SEED_ADMIN toggle.
Verified on the showcase: loginable admin + platform-admin promotion,
correct seed under port auto-shift (3999 busy -> 4000), runtime.json
written, --no-seed-admin opt-out, and idempotency on a persistent DB (no
duplicate user / permission set). Tests: plugin-auth 88, plugin-dev 7,
cli 144 — all green.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@vercel

vercelBot commented Jun 2, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

ProjectDeploymentActionsUpdated (UTC)
specReadyReadyPreview, CommentJun 2, 2026 2:13am

Request Review

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@github-actionsgithub-actionsBot added documentation Improvements or additions to documentation tooling labels Jun 2, 2026
@xuyushun441-sys
xuyushun441-sys merged commit 8c01eea into mainJun 2, 2026
12 checks passed
@xuyushun441-sys
xuyushun441-sys deleted the fix/dev-seed-admin-in-process branch June 2, 2026 02:20
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentationImprovements or additions to documentationsize/mtooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@xuyushun441-sys@os-zhuang