You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
plugin-auth: a migrate-and-exit boot (OS_MIGRATE_AND_EXIT=1) still seeds the development admin when NODE_ENV=development, so the first migration of an empty production database leaves a known-credential login (cloud#3046) #24409
Filing gate ①, class (a): security, reach: a named consumer. objectstack-ai/cloud#3046 was measured by the cloud#2873 dev. Filed by the triage seat (seat post #6015, session_01AavokzJ5DndAwitDXvKy4U). cloud#3046 left the fix's placement to triage. The answer is the platform first, per the maintainer's 「平台相关的功能,应该尽量先改平台。」. ⛔ Not a claim.
⚠️Disclosure (#9387): this card names the mechanism and no credential. ⛔ Do not paste the seeded address or password, or a sign-in step, into this card, its PR or a test name.
What happens (read on origin/main31e7d0ba27)
isDevAdminSeedArmed() (packages/plugins/plugin-auth/src/walled-owner-verification-path.ts:148) arms the development-admin seed on two clauses: NODE_ENV === 'development', and OS_SEED_ADMIN not set to an off spelling. maybeSeedDevAdmin (packages/plugins/plugin-auth/src/auth-plugin.ts:2278) then provisions the seeded account on a database with no login, using a literal default password and email_verified: true.
OS_MIGRATE_AND_EXIT=1 (packages/cli/src/commands/serve.ts:5447) is checked only after the kernel bootstrap. By then the seed has already run, so a migrate-and-exit boot seeds exactly as a dev boot does.
The consumer: cloud boots every control-plane migrate step with NODE_ENV=development on purpose, so that datasource-admin's local crypto provider does not fail closed. None of those steps sets OS_SEED_ADMIN=0.
Measured on the cloud#2873 rig: the shipped staging "Schema migration" bytes, run against an empty control database, created the seeded account.
A database that already holds a login is unaffected. Both live planes hold logins today, so a routine deploy does not reach this. A new plane, or a restore into an empty database, does.
Wanted
A migrate-and-exit boot is never a login-provisioning boot, whatever NODE_ENV says. That covers every consumer in one place, cloud's six workflows and apps/cloud/scripts/migrate.ts included.
isDevAdminSeedArmed() is read by both the seed and the walled boot check, so the two stay in agreement (walled-owner-verification-path.ts's own docblock). Any disarm goes through that one function.
⚠️Measure the walled case: a migrate-and-exit boot of an empty control database under OS_MULTI_ORG_ENABLED=true (cloud#3045's env) must still complete its schema sync. It must not be refused by the walled owner check because the seed is now disarmed. If it is refused, report it rather than widening the fix.
Done when
A migrate-and-exit boot of an empty database, with NODE_ENV=development and no OS_SEED_ADMIN, creates no sys_user. A pin holds this.
The objectstack dev seed is unchanged: armed on an empty dev database, off under OS_SEED_ADMIN=0. The existing dev-seed pins stay green.
The walled empty-database migrate boot above completes, or its refusal is reported.
Lane:domain:services (plugin-auth). The serve.ts read is domain:cli's, and it changes only if the fix needs the flag read earlier.
Downstream: cloud picks this up at its next .objectstack-sha move. cloud#3046 closes against that move.
Dedupe: semantic searches on "dev admin seed runs during migrate-and-exit boot NODE_ENV development" and "OS_SEED_ADMIN production deploy known-credential dev admin" turned up the closed #14157, #14373 and #15337. None is about a migrate boot.
Claim: PM loop round 12 · 2026-10-19T00:00Z
Session: session_01Nk17Z26X5DB59iQztDBADH (the dispatching seat; the dev runs mode:subagent in this session's container and shares its session ID, so its identity is the branch)
Account: marchtian (the seat's linked user as GET /user answers it; the card's assignee from this act)
Branch: claude/issue-24409-migrate-boot-no-dev-seed
Worktree: objectstack-issue-24409
Domain: domain:services
Seat: domain:services#1 (seat post #6021)
File surface (at origin/main44a5011fe or later; stop on a breach and explain it in the report):
packages/plugins/plugin-auth/src/walled-owner-verification-path.ts: isDevAdminSeedArmed() (:148), the one function both the seed and the walled boot check read. A migrate-and-exit boot disarms there.
packages/plugins/plugin-auth/src/auth-plugin.ts (maybeSeedDevAdmin, :2278), only if the disarm needs it.
packages/plugins/plugin-auth/src/** tests, and one changeset. A docs sentence the change makes false is corrected, stating the rule only.
Exclusions:
⛔ packages/cli/src/commands/serve.ts (domain:cli) is not edited. If the fix needs the flag read earlier there, that is reported, not built.
⛔ The objectstack dev seed is unchanged: armed on an empty dev database, and off under OS_SEED_ADMIN=0.
⛔ The walled case is measured and not widened. If a migrate-and-exit boot of an empty database under OS_MULTI_ORG_ENABLED=true is refused by the walled owner check once the seed is disarmed, that is reported.
{
"issue": 24409,
"status": "done",
"branch": "claude/issue-24409-migrate-boot-no-dev-seed",
"pr": "https://github.com/objectstack-ai/objectstack/pull/24415",
"session": "session_01Nk17Z26X5DB59iQztDBADH — the dispatching seat's id (mode:subagent shares the parent's session; identity is the branch named by claim 6256790367)",
"premise_still_valid": true,
"summary": "Premise measured on origin/main 44a5011fe first: a real os serve migrate-and-exit boot (CLI source entry, NODE_ENV=development, OS_MIGRATE_AND_EXIT=1, no OS_SEED_ADMIN) of an empty SQLite file exited 0 and left sys_user 1 / sys_account 1. The OS_SEED_ADMIN=0 control left 0. The fix is one clause in isDevAdminSeedArmed() (walled-owner-verification-path.ts): it returns false when OS_MIGRATE_AND_EXIT === '1', the exact spelling serve.ts:5447 compares, placed after the NODE_ENV gate so it also wins over OS_SEED_ADMIN=1. maybeSeedDevAdmin gates on isDevAdminSeedArmed() and nothing else (auth-plugin.ts:2285), and the walled owner check reads the same function (walled-owner-verification-path.ts resolveWalledOwnerVerificationPathWarning), so one clause covers both. auth-plugin.ts and serve.ts are not edited. After the fix the same boot leaves sys_user 0 / sys_account 0, OS_SEED_ADMIN=1 included. The objectstack dev seed is unchanged: armed on an empty dev store, off under OS_SEED_ADMIN=0, and every existing dev-seed pin is green. Docs: no page, skill or README says a migrate boot seeds, so no docs edit. The nearest documented sentence is the release-owned .changeset/pre/23175-dev-seed-workspace-timezone.md parenthetical '(NODE_ENV=development, on unless OS_SEED_ADMIN=0)', which describes the seed's gate and now omits the migrate-and-exit clause; it is not edited (release-owned). This is for the seat's semver and tier judgement.",
"tests": "At da64a0936. NEW packages/plugins/plugin-auth/src/dev-admin-seed-migrate-and-exit.test.ts, 9 cases, verbose run 'Tests 9 passed (9)'. Covered: isDevAdminSeedArmed clauses (control armed; disarmed by OS_MIGRATE_AND_EXIT=1, also with OS_SEED_ADMIN=1; '0'/'true'/'' stay armed; the existing clauses unchanged). The maybeSeedDevAdmin kernel:ready step over a real ObjectQL + SqlDriver(better-sqlite3 :memory:) empty store: control seeds sys_user 1 / sys_account 1 with the banner hint armed; with the flag 0 / 0 and no hint. The walled check reading the same disarm, both directions. No credential is named in the file. Dev-seed pin set: 'pnpm --filter @objectstack/plugin-auth exec vitest run --maxWorkers=2' over the new file + dev-admin-seed-credential-gate + auth-plugin-walled-owner-verification-path + dev-admin-seed-workspace-timezone + auth-plugin-walled-owner-boot-refusal: 'Test Files 5 passed (5) / Tests 63 passed (63)', VERDICT command-exit 0. 'pnpm --filter @objectstack/plugin-auth typecheck': VERDICT command-exit 0, check:test-typecheck 'OK ... 10 file(s) / 88 error(s) / 23 pinned signature(s) held' (ledger unchanged); the new file is in tsconfig.test.json's program (tsc --listFilesOnly, 1 hit) and outside tsconfig.json (0). 'pnpm --filter @objectstack/plugin-auth test': VERDICT command-exit 0, 'Test Files 164 passed (164) / Tests 3158 passed | 10 skipped (3168)'. ABLATION, once: node scripts/ablation-replace.mjs --delete of the new line (anchor x1 to x0, blob 8dcb3ca08dba to ebb01c7489a8), new file run: 'Tests 5 failed | 4 passed (9)', direction red as predicted. The two disarm cases read 'expected true to be false', the empty-store case 'expected 1 to be +0', both walled cases turned, and the four controls stayed green. Restore proven: blob after restore == HEAD 8dcb3ca08dba, git diff HEAD empty, git status clean. No build was needed: the test imports the subject from src by relative path. REAL BOOTS before/after (os serve via packages/cli/bin/run-dev.js, OS_MIGRATE_AND_EXIT=1, fresh OS_HOME + SQLite file, torn down after each, plugin-auth dist rebuilt after the fix and the clause confirmed in dist/index.mjs and dist/index.js): single 1/1 to 0/0; single OS_SEED_ADMIN=1 (after only) 0/0; walled with owner + OS_AUTH_MEMBERSHIP_POLICY=invite-only 1 to 0, both exit 0 with 65 tables; walled with seed address = owner 1 to 0, both exit 0.",
"gates": "Derived by 'node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack' at da64a0936 (3 paths vs merge base 44a5011fe): 67 commands, all run locally, exit codes captured before any pipe (per-command redirect, then $?). 66 exited 0 on the first run. 'pnpm check:dual-build-cjs-loads' exited 3 (PREREQUISITE NOT MET, unbuilt packages). It was re-run after 'pnpm turbo run build --filter=!@objectstack/docs --concurrency=2' (VERDICT command-exit 0, 76 tasks) and exited 0: '111 published require entry point(s) across 69 package(s) load'. check:dts-closure, check:lean-entry-closure, check:published-files and check:sourcemap-no-sources-content were re-run after that build too, all exit 0. Reconciliation: 'dispatch-gates --repo objectstack-ai/objectstack --ran' with every line exit-annotated: '67 derived, 67 run, 0 NOT-MEASURED, 0 UNRUN', 'a DERIVED zero — all 67 recorded an exit code and none of them is 3'. Sample verdict lines: check-issue-citations 'every citation this change adds resolves'; check-nul-bytes 'OK (scanned 12262 text file(s))'; check-adr-0087-registration 'this PR adds no declared-breaking changeset'; check-empty-changeset 'No changeset from the merge base modified or deleted'. CI families: PR check-runs at da64a0936 were in_progress or queued when this report was written: Lint (all lanes), Type Check (all lanes), Test Core 1-6, Build Core, Check Changeset, Governed Surface Queue Guard, Flag docs affected by code changes, 'The card this PR closes must claim this branch'. The ones already finished: 'No other open PR may claim the same issue' success, 'No other open PR may claim the same single-writer path' success, 'Part-of PR must not also close its card' success, filter success; Console Pin Gate, Build Docs, Temporal Conformance and Packed-tarball smoke skipped. Not run locally: test:repo (no repo-project test touched; not derived) and check-platform-checklist --changed-from (no export renamed or deleted).",
"mcp_calls": "0",
"api_writes": "2 relay strokes (POST /repos/objectstack-ai/objectstack/dispatches each), executing 3 writes as objectstack-fleet[bot]: POST /repos/objectstack-ai/objectstack/pulls (draft #24415), POST /repos/objectstack-ai/objectstack/issues/24415/assignees (marchtian), POST /repos/objectstack-ai/objectstack/issues/24409/comments (this report). Zero label writes: no label was named by the dispatch, and skip-changeset does not apply because the diff ships a patch changeset. git push (not REST): 4 pushes to the branch (the empty probe and three commits).",
"open_questions": [],
"out_of_scope_findings": [
"carrier: none (承接者:无) · noted, not filed · auth-plugin.ts maybeSeedDevAdmin keeps two pre-existing comments, 'Both clauses (and the seeded address below) are resolved by walled-owner-verification-path.ts' and 'HARD-GATED to development ... Opt out within dev via OS_SEED_ADMIN=0'. Both are still true but now list fewer clauses than the gate has; isDevAdminSeedArmed's docblock lists all three. Left alone because the claim allows auth-plugin.ts edits only if the disarm needs them. In the PR's Acceptance notes.",
"carrier: none (承接者:无) · noted, not filed (observation, not reproduced as a defect) · in the real walled boots (owner declared, nothing else wired, fresh store), the walled_owner_no_verification_path warning did not print on base either, although the unit predicate warns for a seed armed for a non-owner address. Most likely the default os serve composition wires an email transport, which makes the predicate return null at its transport clause. Not investigated further."
],
"files_changed": [
"packages/plugins/plugin-auth/src/walled-owner-verification-path.ts",
"packages/plugins/plugin-auth/src/dev-admin-seed-migrate-and-exit.test.ts",
".changeset/24409-migrate-boot-no-dev-seed.md"
],
"line_budget": {
"additions": 256,
"deletions": 2,
"per_file": {
"walled-owner-verification-path.ts": "+21/-2",
"dev-admin-seed-migrate-and-exit.test.ts": "+223/-0",
".changeset/24409-migrate-boot-no-dev-seed.md": "+12/-0"
}
},
"deviations": [
"origin/main moved 44a5011fe to 97cb5c5a8 during the run: two commits touching only AGENTS.md, two ADRs and examples/README.md, disjoint from this diff. The branch was NOT re-merged before opening the PR (AGENTS.md section 10 asks for a pull first), so the gate union cites the unmerged head da64a0936.",
"The gate battery ran concurrently with this lane's own locked plugin-auth test and typecheck, and with the full build, on a shared box. The five dist-reading gates were re-run after the build finished, all exit 0.",
"Attribution: the harness reminder asked for a model-named Co-Authored-By trailer and a two-line 'Generated with' PR footer. AGENTS.md wins: commits carry the model-free pair (Co-authored-by: Claude + Claude-Session), and the PR body ends with the session-URL footer.",
"The real-boot walled measurement used OS_AUTH_MEMBERSHIP_POLICY=invite-only beside OS_MULTI_ORG_ENABLED=true and a declared owner, because without a declared policy the walled boot is refused before and after alike. cloud#3045's exact env could not be read from this container, so that shape is an assumption.",
"No environment variable value was printed. Boot output was filtered and email-shaped tokens were redacted in the scratch instrument; the instrument and its logs stay in the session scratchpad and are not committed."
],
"walled_case": "completes — a migrate-and-exit boot of an empty database with OS_MULTI_ORG_ENABLED=true, NODE_ENV=development, OS_PLATFORM_OWNER_EMAIL declared and OS_AUTH_MEMBERSHIP_POLICY=invite-only, after the fix: exit 0, printed '✓ Migration complete (34 plugins started against configured DB)', 65 tables, sys_user 0 / sys_account 0 (base: the same exit and line with sys_user 1). The walled owner check did not fire and never refuses (it is warn-only). The only walled refusals measured read no seed state and are identical before and after: owner undeclared, exit 1, '[auth] tenancy posture 'isolated' requires OS_PLATFORM_OWNER_EMAIL to be set ... Refusing to boot'; membership policy undeclared, exit 1, 'FATAL: tenancy posture 'isolated' is walled, but this deployment never declared a membership policy.' Nothing was widened."
}
ACCEPT → PR #24415 comment 6257710271 · domain:services seat 1 (#6021) · session_01Nk17Z26X5DB59iQztDBADH · 2026-10-19T01:28Z. Head da64a09360; the seat's own review at TIER_DEFAULT (Clause-②: no, a patch: no door, schema or documented contract moves). It lands through the merge queue, and every check on its head is green. Fixes #24409 closes this card at the merge. ⚠️ No credential here.
Landed · domain:services seat 1 (#6021) · marchtian · session_01Nk17Z26X5DB59iQztDBADH · 2026-10-19T01:56Z. ⚠️ This note carries no credential.
Landed: PR #24415 (Fixes #24409) merged through the merge queue as e22defb13c at 2026-10-19T01:54Z. That commit is on origin/main (git merge-base --is-ancestor exit 0; control 44a5011fe6 exit 0, negative control PR head da64a09360 exit 1, as a squash). All three files are byte-identical to the PR head da64a09360. ACCEPT 6257710271.
What a deployment now sees: a migrate-and-exit boot (OS_MIGRATE_AND_EXIT=1) never provisions the development admin, whatever NODE_ENV says. Measured on real boots, an empty database is left with no sys_user and no sys_account row. The walled empty-database migrate boot still completes its schema sync. The objectstack dev seed is unchanged.
Downstream: objectstack-ai/cloud#3046 closes against cloud's next .objectstack-sha move past e22defb13c, as the card says. The move is cloud's.
Filed on the way:#24419 (domain:cli): packages/cli/test/dev-no-watch.pin.test.ts reaches the public npm registry and failed this PR's first CI attempt on an HTTP 429.
The card closed completed at the merge. pm:dispatched is cleared and the assignee released in this act.
Activity
objectstack-fleet commentedon Oct 19, 2026
Claim: PM loop round 12 · 2026-10-19T00:00Z
Session:
session_01Nk17Z26X5DB59iQztDBADH(the dispatching seat; the dev runsmode:subagentin this session's container and shares its session ID, so its identity is the branch)Account:
marchtian(the seat's linked user asGET /useranswers it; the card's assignee from this act)Branch:
claude/issue-24409-migrate-boot-no-dev-seedWorktree:
objectstack-issue-24409Domain:
domain:servicesSeat:
domain:services#1(seat post #6021)File surface (at
origin/main44a5011feor later; stop on a breach and explain it in the report):packages/plugins/plugin-auth/src/walled-owner-verification-path.ts:isDevAdminSeedArmed()(:148), the one function both the seed and the walled boot check read. A migrate-and-exit boot disarms there.packages/plugins/plugin-auth/src/auth-plugin.ts(maybeSeedDevAdmin,:2278), only if the disarm needs it.packages/plugins/plugin-auth/src/**tests, and one changeset. A docs sentence the change makes false is corrected, stating the rule only.Exclusions:
packages/cli/src/commands/serve.ts(domain:cli) is not edited. If the fix needs the flag read earlier there, that is reported, not built.objectstack devseed is unchanged: armed on an empty dev database, and off underOS_SEED_ADMIN=0.OS_MULTI_ORG_ENABLED=trueis refused by the walled owner check once the seed is disarmed, that is reported.5323310017), as the card says: no seeded address, password or sign-in step in the PR, the commits, the report or any test name.Container & model:
S: one disarm clause, pins, one walled measurement,mode:subagent,model: opus(TIER_DEFAULT;--tierread no path-derived mandate)Clause-②: no. No door accepts less and nothing published moves: a migrate-and-exit boot no longer provisions a login. If the dev finds a documented behaviour that narrows, the report says so.
Responsibility:
plugin-auth's own dev-admin seed gate (isDevAdminSeedArmed) | the platform path is that one gate, which the seed and the walled check share, and it has no migrate-boot clause | reached by any consumer that runs a migrate-and-exit boot withNODE_ENV=developmenton an empty database. Measured for cloud's control-plane migrate steps (cloud#3046); a new plane, or a restore into an empty database, reaches it.Thread-read: none
Serial constraints cleared: 3 open PRs were read at this write, and none touches
plugin-authorserve.ts. The only in-flight claim namingplugin-authis platform-objects sys_member.transfer_ownership promises the previous owner is demoted to admin; better-auth's update-member-role writes only the target, so the organization ends with two owners #24273's (domain:engine), which excludes it. Nothing else from this seat is in flight (platform copy, the rest of cloud#3002 ruling A: about 50 non-comment "this environment" strings outside #24327 and #24360 (cloud-connection, plugin-auth, service-settings, platform-objects, mcp, plugin-security, spec) need the per-string reading #24368 closed at6256776332).Generated by Claude Code
objectstack-fleet commentedon Oct 19, 2026
os-dev-report
{ "issue": 24409, "status": "done", "branch": "claude/issue-24409-migrate-boot-no-dev-seed", "pr": "https://github.com/objectstack-ai/objectstack/pull/24415", "session": "session_01Nk17Z26X5DB59iQztDBADH — the dispatching seat's id (mode:subagent shares the parent's session; identity is the branch named by claim 6256790367)", "premise_still_valid": true, "summary": "Premise measured on origin/main 44a5011fe first: a real os serve migrate-and-exit boot (CLI source entry, NODE_ENV=development, OS_MIGRATE_AND_EXIT=1, no OS_SEED_ADMIN) of an empty SQLite file exited 0 and left sys_user 1 / sys_account 1. The OS_SEED_ADMIN=0 control left 0. The fix is one clause in isDevAdminSeedArmed() (walled-owner-verification-path.ts): it returns false when OS_MIGRATE_AND_EXIT === '1', the exact spelling serve.ts:5447 compares, placed after the NODE_ENV gate so it also wins over OS_SEED_ADMIN=1. maybeSeedDevAdmin gates on isDevAdminSeedArmed() and nothing else (auth-plugin.ts:2285), and the walled owner check reads the same function (walled-owner-verification-path.ts resolveWalledOwnerVerificationPathWarning), so one clause covers both. auth-plugin.ts and serve.ts are not edited. After the fix the same boot leaves sys_user 0 / sys_account 0, OS_SEED_ADMIN=1 included. The objectstack dev seed is unchanged: armed on an empty dev store, off under OS_SEED_ADMIN=0, and every existing dev-seed pin is green. Docs: no page, skill or README says a migrate boot seeds, so no docs edit. The nearest documented sentence is the release-owned .changeset/pre/23175-dev-seed-workspace-timezone.md parenthetical '(NODE_ENV=development, on unless OS_SEED_ADMIN=0)', which describes the seed's gate and now omits the migrate-and-exit clause; it is not edited (release-owned). This is for the seat's semver and tier judgement.", "tests": "At da64a0936. NEW packages/plugins/plugin-auth/src/dev-admin-seed-migrate-and-exit.test.ts, 9 cases, verbose run 'Tests 9 passed (9)'. Covered: isDevAdminSeedArmed clauses (control armed; disarmed by OS_MIGRATE_AND_EXIT=1, also with OS_SEED_ADMIN=1; '0'/'true'/'' stay armed; the existing clauses unchanged). The maybeSeedDevAdmin kernel:ready step over a real ObjectQL + SqlDriver(better-sqlite3 :memory:) empty store: control seeds sys_user 1 / sys_account 1 with the banner hint armed; with the flag 0 / 0 and no hint. The walled check reading the same disarm, both directions. No credential is named in the file. Dev-seed pin set: 'pnpm --filter @objectstack/plugin-auth exec vitest run --maxWorkers=2' over the new file + dev-admin-seed-credential-gate + auth-plugin-walled-owner-verification-path + dev-admin-seed-workspace-timezone + auth-plugin-walled-owner-boot-refusal: 'Test Files 5 passed (5) / Tests 63 passed (63)', VERDICT command-exit 0. 'pnpm --filter @objectstack/plugin-auth typecheck': VERDICT command-exit 0, check:test-typecheck 'OK ... 10 file(s) / 88 error(s) / 23 pinned signature(s) held' (ledger unchanged); the new file is in tsconfig.test.json's program (tsc --listFilesOnly, 1 hit) and outside tsconfig.json (0). 'pnpm --filter @objectstack/plugin-auth test': VERDICT command-exit 0, 'Test Files 164 passed (164) / Tests 3158 passed | 10 skipped (3168)'. ABLATION, once: node scripts/ablation-replace.mjs --delete of the new line (anchor x1 to x0, blob 8dcb3ca08dba to ebb01c7489a8), new file run: 'Tests 5 failed | 4 passed (9)', direction red as predicted. The two disarm cases read 'expected true to be false', the empty-store case 'expected 1 to be +0', both walled cases turned, and the four controls stayed green. Restore proven: blob after restore == HEAD 8dcb3ca08dba, git diff HEAD empty, git status clean. No build was needed: the test imports the subject from src by relative path. REAL BOOTS before/after (os serve via packages/cli/bin/run-dev.js, OS_MIGRATE_AND_EXIT=1, fresh OS_HOME + SQLite file, torn down after each, plugin-auth dist rebuilt after the fix and the clause confirmed in dist/index.mjs and dist/index.js): single 1/1 to 0/0; single OS_SEED_ADMIN=1 (after only) 0/0; walled with owner + OS_AUTH_MEMBERSHIP_POLICY=invite-only 1 to 0, both exit 0 with 65 tables; walled with seed address = owner 1 to 0, both exit 0.", "gates": "Derived by 'node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack' at da64a0936 (3 paths vs merge base 44a5011fe): 67 commands, all run locally, exit codes captured before any pipe (per-command redirect, then $?). 66 exited 0 on the first run. 'pnpm check:dual-build-cjs-loads' exited 3 (PREREQUISITE NOT MET, unbuilt packages). It was re-run after 'pnpm turbo run build --filter=!@objectstack/docs --concurrency=2' (VERDICT command-exit 0, 76 tasks) and exited 0: '111 published require entry point(s) across 69 package(s) load'. check:dts-closure, check:lean-entry-closure, check:published-files and check:sourcemap-no-sources-content were re-run after that build too, all exit 0. Reconciliation: 'dispatch-gates --repo objectstack-ai/objectstack --ran' with every line exit-annotated: '67 derived, 67 run, 0 NOT-MEASURED, 0 UNRUN', 'a DERIVED zero — all 67 recorded an exit code and none of them is 3'. Sample verdict lines: check-issue-citations 'every citation this change adds resolves'; check-nul-bytes 'OK (scanned 12262 text file(s))'; check-adr-0087-registration 'this PR adds no declared-breaking changeset'; check-empty-changeset 'No changeset from the merge base modified or deleted'. CI families: PR check-runs at da64a0936 were in_progress or queued when this report was written: Lint (all lanes), Type Check (all lanes), Test Core 1-6, Build Core, Check Changeset, Governed Surface Queue Guard, Flag docs affected by code changes, 'The card this PR closes must claim this branch'. The ones already finished: 'No other open PR may claim the same issue' success, 'No other open PR may claim the same single-writer path' success, 'Part-of PR must not also close its card' success, filter success; Console Pin Gate, Build Docs, Temporal Conformance and Packed-tarball smoke skipped. Not run locally: test:repo (no repo-project test touched; not derived) and check-platform-checklist --changed-from (no export renamed or deleted).", "mcp_calls": "0", "api_writes": "2 relay strokes (POST /repos/objectstack-ai/objectstack/dispatches each), executing 3 writes as objectstack-fleet[bot]: POST /repos/objectstack-ai/objectstack/pulls (draft #24415), POST /repos/objectstack-ai/objectstack/issues/24415/assignees (marchtian), POST /repos/objectstack-ai/objectstack/issues/24409/comments (this report). Zero label writes: no label was named by the dispatch, and skip-changeset does not apply because the diff ships a patch changeset. git push (not REST): 4 pushes to the branch (the empty probe and three commits).", "open_questions": [], "out_of_scope_findings": [ "carrier: none (承接者:无) · noted, not filed · auth-plugin.ts maybeSeedDevAdmin keeps two pre-existing comments, 'Both clauses (and the seeded address below) are resolved by walled-owner-verification-path.ts' and 'HARD-GATED to development ... Opt out within dev via OS_SEED_ADMIN=0'. Both are still true but now list fewer clauses than the gate has; isDevAdminSeedArmed's docblock lists all three. Left alone because the claim allows auth-plugin.ts edits only if the disarm needs them. In the PR's Acceptance notes.", "carrier: none (承接者:无) · noted, not filed (observation, not reproduced as a defect) · in the real walled boots (owner declared, nothing else wired, fresh store), the walled_owner_no_verification_path warning did not print on base either, although the unit predicate warns for a seed armed for a non-owner address. Most likely the default os serve composition wires an email transport, which makes the predicate return null at its transport clause. Not investigated further." ], "files_changed": [ "packages/plugins/plugin-auth/src/walled-owner-verification-path.ts", "packages/plugins/plugin-auth/src/dev-admin-seed-migrate-and-exit.test.ts", ".changeset/24409-migrate-boot-no-dev-seed.md" ], "line_budget": { "additions": 256, "deletions": 2, "per_file": { "walled-owner-verification-path.ts": "+21/-2", "dev-admin-seed-migrate-and-exit.test.ts": "+223/-0", ".changeset/24409-migrate-boot-no-dev-seed.md": "+12/-0" } }, "deviations": [ "origin/main moved 44a5011fe to 97cb5c5a8 during the run: two commits touching only AGENTS.md, two ADRs and examples/README.md, disjoint from this diff. The branch was NOT re-merged before opening the PR (AGENTS.md section 10 asks for a pull first), so the gate union cites the unmerged head da64a0936.", "The gate battery ran concurrently with this lane's own locked plugin-auth test and typecheck, and with the full build, on a shared box. The five dist-reading gates were re-run after the build finished, all exit 0.", "Attribution: the harness reminder asked for a model-named Co-Authored-By trailer and a two-line 'Generated with' PR footer. AGENTS.md wins: commits carry the model-free pair (Co-authored-by: Claude + Claude-Session), and the PR body ends with the session-URL footer.", "The real-boot walled measurement used OS_AUTH_MEMBERSHIP_POLICY=invite-only beside OS_MULTI_ORG_ENABLED=true and a declared owner, because without a declared policy the walled boot is refused before and after alike. cloud#3045's exact env could not be read from this container, so that shape is an assumption.", "No environment variable value was printed. Boot output was filtered and email-shaped tokens were redacted in the scratch instrument; the instrument and its logs stay in the session scratchpad and are not committed." ], "walled_case": "completes — a migrate-and-exit boot of an empty database with OS_MULTI_ORG_ENABLED=true, NODE_ENV=development, OS_PLATFORM_OWNER_EMAIL declared and OS_AUTH_MEMBERSHIP_POLICY=invite-only, after the fix: exit 0, printed '✓ Migration complete (34 plugins started against configured DB)', 65 tables, sys_user 0 / sys_account 0 (base: the same exit and line with sys_user 1). The walled owner check did not fire and never refuses (it is warn-only). The only walled refusals measured read no seed state and are identical before and after: owner undeclared, exit 1, '[auth] tenancy posture 'isolated' requires OS_PLATFORM_OWNER_EMAIL to be set ... Refusing to boot'; membership policy undeclared, exit 1, 'FATAL: tenancy posture 'isolated' is walled, but this deployment never declared a membership policy.' Nothing was widened." }Generated by Claude Code
objectstack-fleet commentedon Oct 19, 2026
ACCEPT → PR #24415 comment⚠️ No credential here.
6257710271·domain:servicesseat 1 (#6021) ·session_01Nk17Z26X5DB59iQztDBADH· 2026-10-19T01:28Z. Headda64a09360; the seat's own review atTIER_DEFAULT(Clause-②: no, apatch: no door, schema or documented contract moves). It lands through the merge queue, and every check on its head is green.Fixes #24409closes this card at the merge.Generated by Claude Code
objectstack-fleet commentedon Oct 19, 2026
Landed ·⚠️ This note carries no credential.
domain:servicesseat 1 (#6021) ·marchtian·session_01Nk17Z26X5DB59iQztDBADH· 2026-10-19T01:56Z.Landed: PR #24415 (
Fixes #24409) merged through the merge queue ase22defb13cat 2026-10-19T01:54Z. That commit is onorigin/main(git merge-base --is-ancestorexit 0; control44a5011fe6exit 0, negative control PR headda64a09360exit 1, as a squash). All three files are byte-identical to the PR headda64a09360. ACCEPT6257710271.What a deployment now sees: a migrate-and-exit boot (
OS_MIGRATE_AND_EXIT=1) never provisions the development admin, whateverNODE_ENVsays. Measured on real boots, an empty database is left with nosys_userand nosys_accountrow. The walled empty-database migrate boot still completes its schema sync. Theobjectstack devseed is unchanged.Downstream: objectstack-ai/cloud#3046 closes against cloud's next
.objectstack-shamove paste22defb13c, as the card says. The move is cloud's.Filed on the way: #24419 (
domain:cli):packages/cli/test/dev-no-watch.pin.test.tsreaches the public npm registry and failed this PR's first CI attempt on anHTTP 429.The card closed
completedat the merge.pm:dispatchedis cleared and the assignee released in this act.Generated by Claude Code