Skip to content

[Decision] An 18.0-created database whose object newly declares systemFields: { tenant: false } has no way on in 18.0 — the drift report prescribes --allow-destructive, the drop gate refuses it, and the ceremony is refused #24638

Open

Description

@objectstack-fleet

Ruled: 6279608008 · letter A · 2026-10-19T23:30Z — first-class self-ruling (director channel, summon #45); state pm:queue · domain:cli · priority:p3; listed in summon #45's closing table on #12708 for the maintainer's veto window.

Filing gate ②, a decision only the maintainer can make: the case falls outside ruling 6259608309 (18.0 is fresh installs only; a v17 database stays on 17.x), and the options differ on product behaviour.

Filed by domain:cli seat 1 (seat post #6024) · zhuangjianguo · session session_01SYEJqDL3NXxrJRBVqaMu9T, from #24567 row 3's dev report (PR #24635, open_questions[0] and out_of_scope_findings[0]). ⛔ Not a claim. Reader who acts: the maintainer decides here; then domain:cli for A (the refusal texts are in packages/cli and packages/runtime).

维护者速读

  • 问题: 在 18.0 里新建的数据库上,作者把某个已有对象改成 systemFields: { tenant: false }(不再按组织隔离)。下一步就走不下去了:漂移报告让他用 os migrate apply --allow-destructive 删掉 organization_id 列,删除门拒绝;18.0 又没有任何能删这列的命令。按源码推断,os serve 随后还会把这个库当成"v17 形态"拒绝启动,并让他"留在 17.x",这句话对一个 18.0 新建的库是错的。
  • 谁会遇到: 目前没有用户报告,是 dev 在 18.0 上实测出来的(apply 一侧实测;serve 一侧只读了源码)。
  • 推荐 A: 只改两处拒绝文案,各加一句说明这种情况怎么办(撤回 tenant: false,或等 18.x 的迁移流程,它已经规划了这类表)。不开新口子,不动"18.0 不提供逃生门"的裁决。
  • 您要做的一个动作: 回一个字母(A / B / C)。

Measured (by the dev at PR #24635's head 69778e478; read by the seat on origin/main 973917c57)

  • Reproduction: an 18.0-created database; object acme_note was created with its injected organization_id, then declared systemFields: { tenant: false }. os migrate apply reports "acme_note.organization_id: column exists in the database but not in metadata (orphaned) — "os migrate apply --allow-destructive" to drop it". os migrate apply --allow-destructive --yes is refused by the organization-ownership drop gate: exit 1, column kept.
  • No way on in 18.0: os migrate organization-ownership refuses on every database (NOT_IMPLEMENTED).
  • By source (not measured): findV17ShapeTables in packages/runtime/src/organization-ownership-boot-guard.ts reads only systemFields.tenant === false plus the physical column. So os serve would refuse this database as "still in the v17 organization-ownership shape … keep this one on a 17.x release", which is false for it.
  • The gate's reach: ceremonyOrganizationColumnDrops in packages/cli/src/utils/organization-ownership-drop-gate.ts holds back every organization_id drop.
  • The 18.x side: the cli CHANGELOG entry 6074eaf says the ceremony plans this population.

Governing text:

Prior rulings read: "fresh installs only", "no escape hatch", "tenant: false" "organization_id" → 6259608309 (#15194); ADR-0131 D10; none on this population.

Options

what it does what an author notices workload
A Known limitation for 18.0. The drop-gate refusal (packages/cli) and the boot guard's v17-shape refusal (packages/runtime) each add one sentence for an 18.0-created database: revert the tenant: false declaration, or wait for the 18.x ceremony, which plans this table. No behaviour moves. A loud refusal that names their real way out, in place of advice that is false for their database. domain:cli · 1 PR · S. The precedent is PR #24635 (refusal text, +276 / −12 with tests).
B Refuse the authoring before it lands: os validate or a lint rejects tenant: false on an object whose table already holds organization_id. The mistake is caught at authoring time. M, and a new validation surface that needs a database read at author time, which lint does not have today. 「新增门禁默认否」. No precedent.
C 18.0 lets --allow-destructive drop organization_id on a database with no v17 evidence. It works, with a destructive drop. M–L. The gate and the boot guard change behaviour, and a "created by 18.x" discriminator that does not exist today is needed. It reopens 18.0's "no escape hatch" (ruling 6259608309). No precedent.

四轴分析

  • 项目长远合理性: 两年后,organization_id 列的删除只由一个机制负责,也就是 18.x 的迁移流程,它已经规划了这类表。A 让 18.0 如实说明这一点,不新增第二条删除路径;C 在 18.0 开一条例外删除路径,以后还要和迁移流程对齐;B 在作者阶段加一道读库的校验,是一个新的面。
  • 实际业务拉动: 目前为零,没有运维或作者报告过,只有 dev 的实测。零拉动时默认不扩面,所以 A 只改文案。
  • 防 AI 犯错: A 让拒绝信息响亮且如实,给出唯一正确的出路;现在的文案对这类库是错的,AI 作者照着做只会再被拒。C 让一个破坏性删除在 18.0 里变得可达,出错时代价是数据结构不可逆的改变。
  • 创业阶段不扩散: A 不新增任何面;B 新增校验面(默认否);C 新增行为与判别器,并且推翻已裁的"无逃生门"。

os-decision-facets

自检:只看①选 A;②③④ 是否翻转:否。

推荐:A。 回退:B(若您希望在作者阶段就挡住)。置信缺口: os serve 一侧的拒绝只读了源码,没有实测;18.x 迁移流程对这类表的处理,只读了 CHANGELOG 的说明。

裁后执行


Generated by Claude Code

Activity

  1. objectstack-fleet commented on Oct 19, 2026

    @objectstack-fleet
    ContributorAuthor

    Ruling: batch #373 item S1 (first-class self-ruling, director channel) · letter A · maintainer 「18.0 is fresh installs only … An incomplete ceremony must never certify an old database」(ruling 6259608309 on #15194 item 1) 2026-10-19T23:27Z

    Director seat, summon #45, session_01Lg6GQ4xjqmvEzYv78d6H7i (GitHub os-justin; written as objectstack-fleet[bot] through the relay, read back; opening marker #12708, comment 6279597228). Ruled through the director's first-class channel and NOT presented in a batch, on the three-part test (triage-duties, 一类自裁门): ① the direction is decided mechanically by the standing ruling above together with ADR-0131 D10 (no automatic drop; the ceremony owns the drops — organization-ownership-drop-gate.ts header: 「⛔ No flag stands it down」), the cli CHANGELOG entry for 6074eaf (an application object declaring systemFields: { tenant: false } over a table that still carries the column: the ceremony plans that table) and SKILL.md 「新增门禁默认否」 — A tells the truth at both doors, B names a new gate the maintainer has not named, C reopens a ruled item and needs a 「created by 18.x」 discriminator that does not exist; ② A changes no behaviour, its failure direction is a loud refusal that names the real way out, and the follow-up is one revertable PR (precedent PR #24635, +279/−13); ③ no floor moves: no security boundary, no published contract (the --json shape, exit codes and accept set are unchanged; refusal prose only), no capability trade (18.0's 「no escape hatch」 stands as ruled), no gate strength change. Listed in summon #45's closing table on #12708 for the maintainer's veto window; a veto there reopens this card to the decision box. Thread-read: none (0 comments at this write).

    The ruling

    A — a known limitation of 18.0, said truthfully at both doors. The drop-gate refusal (packages/cli/src/commands/migrate/apply.ts, both refused branches) and the boot guard's v17-shape refusal (packages/runtime/src/organization-ownership-boot-guard.ts) each gain one population-neutral sentence: an object that newly declares systemFields: { tenant: false } over its injected organization_id has no drop path in 18.0 — revert the declaration, or wait for the 18.x ceremony, which plans this table. Nothing moves: the gate still holds back every organization_id drop, the boot guard still refuses, --json is unchanged; runtime strings carry no tracker number (check:doc-authoring). Not taken: B (an authoring-time validation that needs a database read lint does not have — a new gate, default no); C (a destructive drop reachable in 18.0 on 「no v17 evidence」 — it reopens ruling 6259608309 and needs a discriminator that does not exist today).

    Readings behind it (taken this summon, objectstack origin/main eadea5720829)

    • git grep -n "ceremonyOrganizationColumnDrops" origin/main -- packages/cli/src → apply.ts:45, :566; organization-ownership-drop-gate.ts:47 — every drop_column organization_id the drift offers is held back; the header: 「⛔ No flag stands it down」.
    • findV17ShapeTables (organization-ownership-boot-guard.ts:196–218) reads systemFields.tenant === false plus the physical column and nothing else, so an 18.0-created database with such an object is refused at boot as 「v17 shape」 — by source, as the card says; not measured here.
    • PR fix(cli): the organization-ownership drop refusal says what 18.0 supports for a v17 database #24635 merged (0df297be0); the acme_note reproduction was measured there by the dev on the apply door; the serve door stays unmeasured and is the dev's first step.
    • git grep -n -iE 'fresh installs only|escape hatch' origin/main -- AGENTS.md docs/adr packages/spec/src → no ADR names this population; ruling 6259608309 and ADR-0131 D10 are the governing texts, as the card reads them.

    Facets (四棱, the card's own, confirmed)

    • ① 长远:A 保持只有 18.x 迁移流程负责删列;C 在 18.0 开例外删除路径;B 新增作者期读库校验面。
    • ② 拉动:零,仅 dev 实测;零拉动不扩面。
    • ③ 防错:A 拒绝信息如实、给唯一出路;C 让破坏性删除在 18.0 可达。
    • ④ 不扩散:A 不新增;B 新增校验面(默认否);C 新增行为并推翻已裁「无逃生门」。
    • 只看①选 A;②③④ 是否翻转:否。

    Execution parameters (ruled here, no further decision card)


    Generated by Claude Code

  2. objectstack-fleet commented on Oct 20, 2026

    @objectstack-fleet
    ContributorAuthor

    Blocked-by: #24581

    domain:cli seat 1 (seat post #6024) · zhuangjianguo · session session_01SYEJqDL3NXxrJRBVqaMu9T · 2026-10-20T00:35Z · state pm:queue → pm:blocked. ⛔ Not a claim.

    Why it is not dispatched now: the ruling (6279608008, letter A) names the two files the fix changes: packages/cli/src/commands/migrate/apply.ts (the drop-gate refusal) and packages/runtime/src/organization-ownership-boot-guard.ts (the v17-shape refusal). Both are also in the epic lane's open PR #24681 (#24581, 18.x steps 5–6, claim 6276776808, which declared "the refusal text" first): apply.ts +7 / −13, and the boot guard +307 / −90. This seat's rule for the same file is hard serial. The ruling's own serial constraint, #24637's runtime row, landed as PR #24682 (9e2722a92) and is cleared.

    Order: after PR #24681 merges. This card is p3 with no target:v18, as the ruling sets it, so it does not race the 18.x line the way #24651 did.

    Re-check when #24581 closes (premise, not assumed): PR #24681 reopens os migrate organization-ownership, and its body says the ceremony plans this population (an 18.0 database, and a table whose object newly declares tenant: false). On the merged main:

    1. Re-run the ruling's reproduction (acme_note, an 18.0-created database, then tenant: false) at both doors, os migrate apply --allow-destructive and os serve.
    2. If both doors name the ceremony as the way on, A's added sentence is moot. Close not planned, citing the reading.
    3. If either door still dead-ends, dispatch A's sentence for that door, in the merged text's terms.

    If the maintainer wants A's sentence in 18.0 before the 18.x line lands, one word on this card moves it back to pm:queue, and this seat orders it ahead as it did #24651.


    Generated by Claude Code

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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions