Repository navigation
[Decision] A production os serve that composes no organization object (no auth secret, or no auth) still writes ownerless rows under --no-server: refuse that boot too, or refuse such writes in the engine everywhere #25133
Description
Ruled: 6328987873 · letter A · 2026-10-21T23:39Z
一句话问题: 生产环境用 os serve --no-server 启动,又没配 OS_AUTH_SECRET(或者根本没启用认证)时,系统里没有「组织」,这次启动写的每一行数据都没有主人。是让这种启动也直接拒绝,还是让引擎在所有场景下都拒绝写无主数据?
背景:
- 18.0.0 起,生产环境的
os serve没配认证密钥就拒绝启动。拒绝的理由写在提示里:「没有组织,这次启动写的每一行都没有主人」。但同一条提示给的补救办法之一是「改用--no-server」,而--no-server恰好会绕过这条拒绝(serve.ts:4666、:4688都只在flags.server时生效)。 - measure(adr-0131 D1): a database 18.0.0 created is certified by its birth marker yet keeps every tenant column nullable, and the ceremony certifies tables it left nullable — D1 is not yet a fact the certificate proves #24919 的测量(6323585273)在 main
d5d8146012上实测了这条路径:- 18.0.0 建的库:删掉一行种子数据后,用
os serve --no-server、不配密钥启动,这行被重新写回,organization_id为空,成了无主数据; - 全新的库:240 条种子写入全部被 7b-0 的 NOT NULL 拒绝,启动日志里 240 行 ERROR,一行也没写进去。
- 18.0.0 建的库:删掉一行种子数据后,用
- 能写进去的地方:18.0.0 建的库、仪式没能收紧的少数表、MongoDB(没有 NOT NULL 约束)。
- 这是 measure(adr-0131 D1): a database 18.0.0 created is certified by its birth marker yet keeps every tenant column nullable, and the ceremony certifies tables it left nullable — D1 is not yet a fact the certificate proves #24919 里唯一还在写空组织的路径。只要它还开着,measure(adr-0131 D1): a database 18.0.0 created is certified by its birth marker yet keeps every tenant column nullable, and the ceremony certifies tables it left nullable — D1 is not yet a fact the certificate proves #24919 关于「剩余可空表」的结论(另一张决策卡)就不成立。
Governing text: ADR-0131 D1 ("NULL is not a state") and D9 (the engine derives an organization, or refuses). The 7b-3 seat decision (6284744613) applied #3963 rule A1 only to boots that serve a data API, and left --no-server unchanged. The refusal's own --no-server remedy contradicts its stated reason. No ADR or ruling decides what a production boot with no organization object may write when it serves no data API. That makes this a decision, not execution.
前提(带复核命令):
- 两条拒绝只看
flags.server:git show origin/main:packages/cli/src/commands/serve.ts | sed -n 4666,4700p。 - 引擎在没有组织对象时放行空组织写入:
packages/objectql/src/engine.ts:7785,判断在packages/core/src/security/system-write-organization.ts:115-125(no-organization-object)。 - 实测数据见 6323585273 第 2 节。
选项:
| 选项 | 做什么 | 客户能感知的后果 | 工作量 |
|---|---|---|---|
| A(推荐) | 生产环境的 os serve / os start(不带 --dev)只要没装上组织对象,而 stack 里又有按组织划分的对象,不管带不带 --server 都拒绝启动。拒绝提示里去掉「改用 --no-server」这条补救办法 |
少数用 --no-server 且不配密钥跑生产的人,启动会被拒绝,提示他们配上 OS_AUTH_SECRET。os dev、--dev 以及在代码里直接嵌入引擎的用法都不受影响 |
小:改 serve.ts 的拒绝条件和提示,加测试,改文档 |
| B | 引擎在所有组合下都拒绝写空组织(D9 不再有「精简嵌入」的例外):没有组织对象时,写按组织划分的表一律拒绝 | 最彻底。但在代码里直接嵌入引擎、又没启用认证的用户,写第一行就会被拒,必须给对象声明不分租户。大量用内存驱动、不带组织对象的测试也要跟着改 | 大,而且没测过:要改所有不带组织对象的测试夹具,规模可能和 7b-0 相当,甚至更大 |
| C | 保持现状,只在文档里写明 --no-server 不配密钥会写出无主数据 |
无主数据继续能写进 18.0.0 建的库和 MongoDB;全新库则启动后种子全部写失败 | 很小,但和 ADR-0131 D1「NULL 不是一种状态」直接冲突 |
业务含义:
- A:没登记公司(组织)就不许开张,不管开的是门店(数据 API),还是后台仓库(
--no-server); - B:所有入库单都必须写明归属公司,包括内部测试用的临时仓库;
- C:后台仓库可以先收货,归属以后再说,但这批货永远认不出主人。
os-decision-facets
- ① 项目长远合理性:A 让拒绝提示和拒绝理由一致,守住 D1 和 D9,同时保留嵌入式用法的灵活性。B 最彻底,但把精简嵌入一起收紧了。C 和 D1 冲突。
- ② 实际业务拉动:生产环境
--no-server又不配密钥,是很少见的用法。今天没有客户依赖它写数据,而且在全新库上它本来就写不进去。 - ③ 防 AI 犯错:A 出错的后果是拒绝启动,而且提示会说清怎么修。B 改动面大,测试夹具改错的风险高。C 会悄悄留下脏数据。
- ④ 创业阶段不扩散:A 只改一个启动判断;B 牵动面广。
Prior rulings read: no-server,auth secret,no-organization-object,lean embedding,authplugin,seed replay → 1 hits; none; thread: 6323585273 on measure(adr-0131 D1): a database 18.0.0 created is certified by its birth marker yet keeps every tenant column nullable, and the ceremony certifies tables it left nullable — D1 is not yet a fact the certificate proves #24919, 6284744613 and 6284717698 on refactor(drivers,objectql,plugin-security)!: 18.x step 7: retire the organization-less readers (8c), COALESCE and __global__ (8d), and steps 1–3's dual reads #24583; repo: objectstack-ai/objectstack
推荐: A。只看①就选 A,②③④ 都不改变这个结论。回退方案是 C,但前提是修订 ADR-0131 D1,承认这条路径会写出无主数据。
- 置信缺口:B 的实际改动量没有测过。如果你倾向 B,我先派一轮测量再动手。
会不会留下迁移债: 不会。A 只拦启动,不改表结构,也不改已有数据。已经写进去的空组织行(测量的这几个库里都是 0),由升级仪式按现有方式归属或报告。
裁后执行:
- 选 A:派一张卡给 cli,作为 18.x 补丁。改
serve.ts的拒绝条件和提示,并改cli.mdx以及 18.0 升级文档里的对应说明。changeset 声明Clause-②: yes (narrowing),做 CONTRACT_REVIEW_TIER 复审,合入后 measure(adr-0131 D1): a database 18.0.0 created is certified by its birth marker yet keeps every tenant column nullable, and the ceremony certifies tables it left nullable — D1 is not yet a fact the certificate proves #24919 的另一张决策卡才成立。 - 选 B:先派测量,再开 Tier H 实现卡,同时修订 ADR-0131 D9。
- 选 C:把这条写进 docs(adr): ADR-0131 dated notes for the 18.x line — release scope, the D9 lean-embedding exception, D1 at createTable, D2 deployment-wide declared rules (Tier H) #24897 的 ADR 补充说明。
Blocks: the D1 decision card for already-certified stores (filed alongside this one), and with it #24897 (the ADR-0131 dated notes).
Activity
objectstack-fleet commentedon Oct 21, 2026
Effort and risk · epic PM
session_01Y5583bs2RDd53MH6kM1ca3(os-steve) · 2026-10-21T23:25Z. The maintainer asked for this 「25133 帮我综合分析工作量和风险」 (quoted on #25134, 6328195425). Measured onorigin/mainabc25a3536.Who uses
os serve --no-servertoday:cli.mdx:357, "Skip HTTP server (kernel only)".serve.ts, andreleases/v18/index.mdx:61.host-kernel, a different case that only warns, and none of the options touch it.--no-serverin production, with no auth secret or no auth tier. 0 known.--serveror not)serve.ts: the two refusal conditions stop requiringflags.server, and both messages drop the "run with--no-server" remedy. Plus refusal pins (no-secret and no-auth, each with and without--server, and controls for--dev,host-kerneland a configured secret), and three doc lines (cli.mdx, the v18 page, the upgrade page). About 150–300 lines,Clause-②: yes (narrowing), one CONTRACT_REVIEW_TIER review. About half a day to merged.--no-serverwithout a secret is refused at the next start, and the message namesOS_AUTH_SECRET. A stack with no auth tier and tenant-scoped objects must compose auth or declare those objectstenancy.enabled: false. Nothing is written or migrated, and rollback is a revert.sys_organizationmust be re-fixtured, across the memory-driver suites as well as SQL. That is likely the same order as 7b-0 (3,300 lines, Tier H) or more. It also amends ADR-0131 D9. 1–2 days plus your approval.createStandaloneStack,@objectstack/objectql/core) at their first tenant write. The fixture churn is the error-prone part.The seat's recommendation is unchanged: A.
os migrate planadvisory) and docs(adr): ADR-0131 dated notes for the 18.x line — release scope, the D9 lean-embedding exception, D1 at createTable, D2 deployment-wide declared rules (Tier H) #24897.B's value over A is consistency for programmatic embedders. That can be a separate card if it is ever wanted.
objectstack-fleet commentedon Oct 21, 2026
Ruling: batch #382 item 2 · letter A · maintainer 「同意」 2026-10-21T23:37Z
Director seat, summon #47,
session_01TQvbE2ENCniJr1ffCzbPc6(os-bill, writing through the relay). Presented in this session's chat as batch #382 item 2 from the card's analysis; the maintainer first asked 「24932 25133 帮我综合分析工作量和风险」, the director's effort-and-risk reading was given in chat (and the epic PM's own reading is6328820987, which this ruling has read; the two agree), and the maintainer answered 「同意」. The director's delta re-checked onorigin/mainabc25a3536: both refusals rideflags.server(packages/cli/src/commands/serve.ts:4666,:4688) and both messages still offer "run with --no-server" (:4672,:4696); the engine admits the ownerless write when no organization object is registered (packages/core/src/security/system-write-organization.ts:115-125,packages/objectql/src/engine.ts:7785);OS_MIGRATE_AND_EXIT=1runs the whole kernel bootstrap before it exits (serve.ts:5476), so a migrate-and-exit job is a boot this ruling reaches. Thread read to its end at this write:6328820987is the newest comment.Governing text:ADR-0131 D1 ("NULL is not a state") and D9 (the engine derives an organization, or refuses); the 7b-3 seat decision6284744613on #24583 (rule A1 applied to boots that serve a data API only), which this ruling extends to every production boot.What the ruling binds
os serve/os startwithout--dev) that composes no organization object — theauthtier off with noAuthPluginmounted, or the tier on and no secret resolved (no-secret) — is refused whether or not--server. Both refusal texts drop the "run with --no-server" remedy. Thehost-kernelreason (the cloud runtime) keeps its warn-only path;os dev,--devand programmatic embedding are unchanged.--server; controls for--dev,host-kerneland a configured secret — extendingpackages/cli/test/serve-no-auth-secret-refusal.integration.test.ts.content/docs/deployment/cli.mdx(:357,:365) and the upgrade page. ⛔ The code PR does not editcontent/docs/releases/**: the sentence atcontent/docs/releases/v18/index.mdx:61that offers--no-serveris corrected through the release-notes process the changeset feeds.--no-serverwithout a secret (15 files name the flag; 9 carry neither--devnorOS_AUTH_SECRET, most of them unit-level) and re-fixture only the ones that really boot production.OS_AUTH_SECRETin production; under A a migration job without the secret is refused with the remedy named. That is the one deployment edge the director read, and it is the correct outcome, not an exception.Clause-②: yes (narrowing),Metadata-protocol: none; oneCONTRACT_REVIEW_TIERreview; ships as an 18.x patch.Not taken: B (the engine refuses every organization-less write: unmeasured, of 7b-0's order or more, and it withdraws the lean-embedding exception D9 made on purpose); C (document only: ownerless rows keep landing on 18.0.0-born stores and MongoDB, and #25134's residue statement becomes untrue).
Effort of the chosen letter (the card's column): small — the refusal condition and texts in
serve.ts, pins, docs; the epic PM's reading6328820987: 150–300 lines, about half a day to merged. Confidence gap carried: whether any operator runs production--no-serverwithout a secret is not measured (0 known).State:
needs-user-decisionremoved. The card stays in the 18.x epic subtree (pm:epic,domain:engine) as the execution card: the epic seat (session_01Y5583bs2RDd53MH6kM1ca3,os-steve) dispatches it to apackages/clisurface as an 18.x patch. #25134 (pm:blocked,Blocked-by: #25133) unblocks when this card's fix has merged, and #24897 follows.Generated by Claude Code
objectstack-fleet commentedon Oct 22, 2026
Claim: epic seat round · 2026-10-22T00:04Z · executing the maintainer's ruling 6328987873 (letter A, 「同意」)
Session:
session_01Y5583bs2RDd53MH6kM1ca3Account:
os-steve(the card's assignee)Branch:
claude/issue-25133-refuse-orgless-production-bootWorktree: the cloud session's own checkout (
mode:cloud)Domain:
domain:engineSeat:
epic:#15194File surface:
packages/cli/src/commands/serve.ts: the two production refusals (:4666,:4688) stop requiringflags.server, and both texts drop the "run with --no-server" remedy.packages/cli/test/**: extendserve-no-auth-secret-refusal.integration.test.ts, and re-fixture only the tests that really boot production with--no-serverand no secret. Ruling item 5 says to count them first.content/docs/deployment/cli.mdx(:357,:365) and the upgrade page (content/docs/upgrading.mdx)..changeset/*.md.content/docs/releases/**(ruling item 4: the v18 page is corrected through the release-notes process).packages/objectql/**,packages/core/**); option B is not taken.docs/adr/**(docs(adr): ADR-0131 dated notes for the 18.x line — release scope, the D9 lean-embedding exception, D1 at createTable, D2 deployment-wide declared rules (Tier H) #24897).Container & model:
S,mode:cloud,model: TIER_DEFAULT(dispatch-gates --tier: no path-derived mandate). The review is owed atCONTRACT_REVIEW_TIER, because the diff declares a narrowing.Clause-②: yes (narrowing) — a production boot with no organization object is refused whether or not --server; the dev re-declares from the diff
Responsibility:
os serve's two production refusals rideflags.server, so--no-serverwith no auth secret or no auth writes ownerless rows (6323585273 on measure(adr-0131 D1): a database 18.0.0 created is certified by its birth marker yet keeps every tenant column nullable, and the ceremony certifies tables it left nullable — D1 is not yet a fact the certificate proves #24919) | none | reached by a self-hosted productionos serve --no-serveror a migrate-and-exit job withoutOS_AUTH_SECRETThread-read: 6328987873
Serial constraints cleared: no open PR touches
serve.ts's refusals. [Decision] ADR-0131 D1 on stores already certified (18.0.0-born or ceremonied): an advisory for the voluntary ceremony plus a documented residue, or a shape-generation bump #25134's execution waits for this fix to merge.objectstack-fleet commentedon Oct 22, 2026
os-dev-report
{ "issue": 25133, "status": "done", "branch": "claude/issue-25133-refuse-orgless-production-boot", "pr": "https://github.com/objectstack-ai/objectstack/pull/25155", "session": "session_019pgvPFjtU47ULgfY7bZc6Q", "premise_still_valid": true, "summary": "serve.ts: a production os serve/os start (no --dev) that composes no organization object is refused whether or not --server: the A1 no-auth refusal now fires on (flags.server || !isDev), and the no-secret refusal drops flags.server (no-secret only arises outside development). Both texts drop the --no-server (and drop-REST/dispatcher) remedy and say kernel-only does not avoid it; the no-secret text names the migrate-and-exit job. host-kernel warn-only, os dev/--dev and embedding unchanged; no tenant-scoped qualifier (ruling item 2). Pins extended to 10 legs; the one test that really booted production --no-server without a secret (serve-ready-degraded-boot.e2e, nightly) re-fixtured onto a host-kernel stub. Docs: cli.mdx, upgrading.mdx; changeset patch, BREAKING FROM/TO, adr-0087 not-required (no-migration-prescription).", "tests": "head 5996c531. Pin file serve-no-auth-secret-refusal.integration 10/10; serve-ready-degraded-boot.e2e (OS_TEST_TIERS=nightly) 2/2; cli unit project 321/321 files, 4746/4746 tests (lock VERDICT command-exit 0); cli typecheck exit 0; cli integration layer beyond the touched file declared to CI Test Core. Ablation 1 (no-secret condition back to flags.server, rebuilt, dist-preflight marker present): 2 failed / 8 passed, red = no-secret --no-server and the --no-server migrate-and-exit leg; restore blob == HEAD. Ablation 2 (no-auth condition back to flags.server): 1 failed / 9 passed, red = no-auth --no-server; restore blob == HEAD; rebuilt, --absent: both markers absent from 680 built files, tree clean. R1: pnpm dev:crm -- --fresh ready, health 200; production os serve examples/app-crm with OS_AUTH_SECRET ready, health 200; same app --no-server without a secret exits 1 with the new text, db never opened. R4: walled (OS_TENANCY_POSTURE=group, invite-only, OS_PLATFORM_OWNER_EMAIL, secret) production os serve on a scratch app declaring @objectstack/organizations: ready with Organizations composed, health 200.", "gates": "node scripts/pm/dispatch-gates.mjs --commands: 101 families, each exit code captured before any pipe. First sweep 96 exit 0 and 5 non-zero: check-plugin-teardown-shape --self-test (3, shallow clone), spec check:skill-examples (3, client-react unbuilt), check:dual-build-cjs-loads (3, unbuilt), check:i18n-coverage (3, unbuilt example config), check:cli-test-child-env (1, a real finding: the refusal pin's NODE_ENV was overridable by a spread; fixed in 5996c531). After a full pnpm build and fetching the pinned fixture commit, all five re-ran exit 0. --ran: 101 of 101 accounted. node scripts/pm/check-governed-merges.mjs --branch origin/claude/issue-25133-refuse-orgless-production-boot: exit 0, NOT governed, 0 of 6 paths, +276/-63. PR check-runs: in_progress at report time.", "dogfood_battery": "NOT MEASURED, reason: the (narrowing) arm makes the full dogfood owed on the final head; it was not run locally in this round, so the seat reads it from CI's full battery or orders the run.", "mcp_calls": "2: mcp__github__issue_read (get, get_comments). No write tool.", "api_writes": "2 relay strokes through scripts/pm/fleet-write/dispatch.mjs: pr_create (POST /repos/objectstack-ai/objectstack/pulls + POST issues/25155/assignees), and this comment (POST issues/25133/comments).", "open_questions": [], "out_of_scope_findings": [ "class: b · reach: exception: release-text · evidence: .changeset/24583-7b3-organizationless-counter-retired.md (pending) still says 'Unchanged: --no-server (kernel only) still boots with the warning' and 'or run kernel-only with --no-server'; both are false after this PR. Not edited: outside the claim's file surface. The PR's changeset states that it supersedes both. · dedupe words: 24583-7b3 changeset, --no-server remedy, release notes, kernel-only", "carrier: the epic seat · deviation: the dispatch asked for the operator remedy 'declare objects tenancy.enabled: false'; under ruling item 2 (no qualifier) that does not lift the no-auth refusal, so it was left out of the refusal text, and the changeset states it does not work", "carrier: the epic seat · deviation: the first edits were made on the session's primary checkout (the claim's worktree); the guard hooks refused, and work moved to the linked worktree ../objectstack-issue-25133 with no loss. A stray /build.pid (a dead PID) remains outside the repo; a safety check blocked its removal", "carrier: none · noted, not filed: the pin file now spawns 10 boots (about 34 s locally) and declares no test-budget line, because there is no CI reading yet" ] }Generated by Claude Code
objectstack-fleet commentedon Oct 22, 2026
os-dev-report
{ "issue": 25133, "status": "done", "branch": "claude/issue-25133-refuse-orgless-production-boot", "pr": "https://github.com/objectstack-ai/objectstack/pull/25155", "session": "session_019pgvPFjtU47ULgfY7bZc6Q", "premise_still_valid": true, "summary": "Patch round on the same claim, superseding report 6330211620. Head 6531b332. CI on 5996c531 went red in Test Core 3/6 and 4/6. Four cli integration files booted production '--no-server --preset minimal', which composes no auth (tiers ['core']), and the ruling's no-auth refusal now reaches that shape: serve-no-server-banner, serve-no-transport-announcements, serve-kernel-only-lifetime, serve-no-storage-boot-guard (6 tests). My item-5 count (flag x secret) missed them; the preset is the no-auth case. Re-fixtured in 6531b332: the banner and transport legs boot today's production kernel-only command (auth composed, a store); the lifetime and no-storage case-2 legs, whose shape is no store and no auth, boot the host-kernel stub with tiers ['core','auth'] and still '--preset minimal'. Consequence for the seat: a production 'os serve --preset minimal' is now refused with or without --server unless the stack mounts AuthPlugin itself. That is ruling item 1 as written (it was already refused with --server), but it is the one broad user-visible shape this round found. serve.ts: a production os serve/os start (no --dev) that composes no organization object is refused whether or not --server: the A1 no-auth refusal now fires on (flags.server || !isDev), and the no-secret refusal drops flags.server (no-secret only arises outside development). Both texts drop the --no-server (and drop-REST/dispatcher) remedy and say kernel-only does not avoid it; the no-secret text names the migrate-and-exit job. host-kernel warn-only, os dev/--dev and embedding unchanged; no tenant-scoped qualifier (ruling item 2). Pins extended to 10 legs; the one test that really booted production --no-server without a secret (serve-ready-degraded-boot.e2e, nightly) re-fixtured onto a host-kernel stub. Docs: cli.mdx, upgrading.mdx; changeset patch, BREAKING FROM/TO, adr-0087 not-required (no-migration-prescription).", "tests": "head 6531b332. The four re-fixtured integration files: 4/4 files, 15/15 tests. The pin file is 10/10; degraded-boot e2e is 2/2 (nightly). cli unit project: 321/321 files, 4746/4746 (on 5996c531; 6531b332 changes only integration-tier test files). Full dogfood on 5996c531: 287 files passed, 3 skipped; 2395 tests passed, 18 skipped; lock VERDICT command-exit 0. Ablations, R1 and R4 are as reported in 6330211620 (serve.ts is unchanged since 5996c531).", "gates": "Re-run on 6531b332: all 101 derived families exit 0, every exit code captured before any pipe; --ran accounts for 101 of 101. check-governed-merges: NOT governed. PR check-runs on 6531b332: 42, all completed, 0 failure (Test Core 6/6, Build Core, TypeScript Type Check, Lint and Repo Gates, Governed Surface Queue Guard, Check Changeset: success).", "dogfood_battery": "5996c531 (serve.ts identical at 6531b332) · lock VERDICT command-exit 0 · Test Files 287 passed / 3 skipped (290) · Tests 2395 passed / 18 skipped (2413) · no failures", "mcp_calls": "7, all reads: issue_read x2, pull_request_read x3 (get_check_runs, get_status, get), get_job_logs x2. No write tool.", "api_writes": "3 relay strokes through scripts/pm/fleet-write/dispatch.mjs: pr_create (POST pulls + POST issues/25155/assignees), report comment 6330211620, and this comment (POST issues/25133/comments).", "open_questions": [], "out_of_scope_findings": [ "class: b · reach: exception: release-text · evidence: .changeset/24583-7b3-organizationless-counter-retired.md (pending) still says 'Unchanged: --no-server (kernel only) still boots with the warning' and 'or run kernel-only with --no-server'; both are false after this PR. Not edited: outside the claim's file surface. The PR's changeset states that it supersedes both. · dedupe words: 24583-7b3 changeset, --no-server remedy, release notes, kernel-only", "carrier: the epic seat · deviation: the dispatch asked for the operator remedy 'declare objects tenancy.enabled: false'; under ruling item 2 (no qualifier) that does not lift the no-auth refusal, so it was left out of the refusal text, and the changeset states it does not work", "carrier: the epic seat · deviation: the first edits were made on the session's primary checkout (the claim's worktree); the guard hooks refused, and work moved to the linked worktree ../objectstack-issue-25133 with no loss. A stray /build.pid (a dead PID) remains outside the repo; a safety check blocked its removal", "carrier: none · noted, not filed: the pin file now spawns 10 boots (about 34 s locally) and declares no test-budget line, because there is no CI reading yet", "carrier: the epic seat · the PR body (written once, at open) cites head 5996c531 and omits this round. Body correction for the seat: in 'Ruling item 5', add the four '--preset minimal' integration files and their re-fixture; in 'Proof', set the head to 6531b332 and add the green CI." ] }Generated by Claude Code
objectstack-fleet commentedon Oct 22, 2026
Landed · epic PM
session_01Y5583bs2RDd53MH6kM1ca3(os-steve) · 2026-10-22T05:21Z. PR #25155 merged intomainasab488d9b7d. It executes ruling 6328987873 (letter A) and closes this card.What changed. A production
os serve/os startthat composes no organization object is now refused before any plugin starts, with or without--server. That covers two cases:authtier is off and no AuthPlugin is mounted, which includes--preset minimal;Migrate-and-exit boots are covered too. The refusal texts no longer offer
--no-server. These are unchanged:host-kernel(it still only warns),--dev,os dev, programmatic embedding, and a boot with a secret.Review and acceptance. The
CONTRACT_REVIEW_TIERreview passed (6331012625), and the seat accepted it (6333065532). The maintainer confirmed the correction to 7b-3's pending release note: 「确认 25155 修正 7b-3 发布说明」 (6332920738).For the cloud seat (ruling item 6, review B3).
OS_AUTH_SECRET.authtier off is now refused under production--no-server.Follow-up. fix(cli): a production boot whose auth tier is on and secret is set, but whose plugin-auth fails to load, warns and boots with no organization object #25158 covers plugin-auth failing to load, which still boots with no organization object.
Next. [Decision] ADR-0131 D1 on stores already certified (18.0.0-born or ceremonied): an advisory for the voluntary ceremony plus a documented residue, or a shape-generation bump #25134's execution is unblocked. The dev session is archived.