Repository navigation
[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
Description
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_notewas created with its injectedorganization_id, then declaredsystemFields: { tenant: false }.os migrate applyreports "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 --yesis refused by the organization-ownership drop gate: exit 1, column kept. - No way on in 18.0:
os migrate organization-ownershiprefuses on every database (NOT_IMPLEMENTED). - By source (not measured):
findV17ShapeTablesinpackages/runtime/src/organization-ownership-boot-guard.tsreads onlysystemFields.tenant === falseplus the physical column. Soos servewould 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:
ceremonyOrganizationColumnDropsinpackages/cli/src/utils/organization-ownership-drop-gate.tsholds back everyorganization_iddrop. - The 18.x side: the cli CHANGELOG entry
6074eafsays the ceremony plans this population.
Governing text:
- Ruling
6259608309on [epic] ADR-0131 — total organization ownership: no NULL organization_id (v18 line) #15194 item 1: "18.0 is fresh installs only … An incomplete ceremony must never certify an old database." It speaks of v17 databases, not this one. - ADR-0131 D10: no automatic drop, delete or attribution; the ceremony owns the drops.
packages/spec/src/data/object.zod.tssystemFields.tenant: "Default true (the column is always provisioned …)".
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 保持只有 18.x 迁移流程负责删列;C 在 18.0 开例外删除路径;B 新增作者期读库校验面。
- ② 实际业务拉动:零——无用户报告,仅 dev 实测;零拉动不扩面。
- ③ 防 AI 犯错:A 拒绝信息如实、给唯一出路;C 让破坏性删除在 18.0 可达。
- ④ 创业阶段不扩散:A 不新增;B 新增校验面(默认否);C 新增行为并推翻已裁"无逃生门"。
Prior rulings read: "fresh installs only" "no escape hatch" "tenant: false" "organization_id" →6259608309([epic] ADR-0131 — total organization ownership: no NULL organization_id (v18 line) #15194 item 1); ADR-0131 D10; thread: PR fix(cli): the organization-ownership drop refusal says what 18.0 supports for a v17 database #24635 report
自检:只看①选 A;②③④ 是否翻转:否。
推荐:A。 回退:B(若您希望在作者阶段就挡住)。置信缺口: os serve 一侧的拒绝只读了源码,没有实测;18.x 迁移流程对这类表的处理,只读了 CHANGELOG 的说明。
裁后执行
- A: one
domain:clicard (the drop-gate refusal inpackages/cliplus the boot guard's v17-shape refusal inpackages/runtime, both this lane's), measured through both doors,os serveincluded. Same-file serial with 18.0 release text still sends operators toos migrate organization-ownership --out / --apply --plan-file, which 18.0 refuses on every database (family close-out: spec upgrade-guide entries, runtime boot refusals, plugin-security report, docs) #24637's runtime row; the two may ride one PR. - B: a
domain:clicard for the validation, with the maintainer's naming of the new surface quoted. - C: a ruling amendment on [epic] ADR-0131 — total organization ownership: no NULL organization_id (v18 line) #15194 first (it reopens item 1), then the gate and boot guard change under a contract review.
Generated by Claude Code
Activity
objectstack-fleet commentedon Oct 19, 2026
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(GitHubos-justin; written asobjectstack-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.tsheader: 「⛔ No flag stands it down」), the cli CHANGELOG entry for6074eaf(an application object declaringsystemFields: { 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--jsonshape, 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 declaressystemFields: { tenant: false }over its injectedorganization_idhas 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 everyorganization_iddrop, the boot guard still refuses,--jsonis 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/maineadea5720829)git grep -n "ceremonyOrganizationColumnDrops" origin/main -- packages/cli/src→apply.ts:45,:566;organization-ownership-drop-gate.ts:47— everydrop_column organization_idthe drift offers is held back; the header: 「⛔ No flag stands it down」.findV17ShapeTables(organization-ownership-boot-guard.ts:196–218) readssystemFields.tenant === falseplus 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.0df297be0); theacme_notereproduction was measured there by the dev on theapplydoor; theservedoor 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)
Execution parameters (ruled here, no further decision card)
needs-user-decision→pm:queuein this act, withdomain:cliandpriority:p3(zero pull; refusal text only). Notarget:v18: a wrong sentence in a refusal is not a release blocker.domain:cli· 1 PR · S. Both doors measured on an 18.0-created database with theacme_notereproduction of PR fix(cli): the organization-ownership drop refusal says what 18.0 supports for a v17 database #24635:os migrate apply --allow-destructiveandos serve.os migrate organization-ownership --out / --apply --plan-file, which 18.0 refuses on every database (family close-out: spec upgrade-guide entries, runtime boot refusals, plugin-security report, docs) #24637's runtime row (the boot guard; 18.0 release text still sends operators toos migrate organization-ownership --out / --apply --plan-file, which 18.0 refuses on every database (family close-out: spec upgrade-guide entries, runtime boot refusals, plugin-security report, docs) #24637 is in flight on the spec seat, p1target:v18); the claiming seat orders this card after that row or lets its dev ride that PR'sdomain:clihalf, as the card already says.domain:cli· 1 PR · S (precedent PR fix(cli): the organization-ownership drop refusal says what 18.0 supports for a v17 database #24635, +279/−13).Generated by Claude Code
objectstack-fleet commentedon Oct 20, 2026
Blocked-by: #24581
domain:cliseat 1 (seat post #6024) ·zhuangjianguo· sessionsession_01SYEJqDL3NXxrJRBVqaMu9T· 2026-10-20T00:35Z · statepm: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) andpackages/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, claim6276776808, 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 declarestenant: false). On the mergedmain:acme_note, an 18.0-created database, thentenant: false) at both doors,os migrate apply --allow-destructiveandos serve.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