Skip to content

Commit 0e0678c

Browse files
docs(adr-0131): D6's second install mode is spelled unmanaged — a dated spelling note executing ruling B on #15213 (#22845)
Fixes #22831 Clause-②: no (an ADR text note; no schema, export or accept set moves) This PR carries out step 1 of the maintainer's ruling **B** on #15213 (director record `6108509158`, batch #317 item 3, 「同意」 2026-10-11T11:24Z). In ADR-0131, the second install mode is now spelled `unmanaged`. The change is dated and points at the ruling, and the rest of the original prose is untouched. **No decision changes, and no code changes.** **Patch round 1** carries out the maintainer's decision **B** on this PR's open question (record `6109891008` on #22831, verbatim 「B,:412 一起改」). D6's bullet label now reads **Unmanaged.** as well. That label was `:412` at the previous head and is `:414` now, because the note grew by two lines. **Tier H (Prime Directive #14).** `docs/adr/**` is a governed surface, so this PR lands only after the maintainer's APPROVED review on the patched head. The seat handles the review request. `check-governed-merges.mjs --test` on this file list answers landing tier H. ## What the diff does One file changes: `docs/adr/0131-total-organization-ownership-no-null-organization-id.md`, +20 / -5 (25 changed lines). Line numbers are at this PR's head, `3d9b4f245e`. | Position | Line | Before | After | |---|---|---|---| | "D6": D2's install-mode sentence, which states D6's two modes | `:269` | **template** | **unmanaged** | | "§6 Q5": D6's "Two install modes" paragraph | `:378` | `template` | `unmanaged` | | D6's bullet label (decision B, record `6109891008`) | `:414` | - **Template.** | - **Unmanaged.** (the body is kept) | | "§6 Q5": the same answer restated in §6 | `:855` | `template` | `unmanaged` | | "the C12 row" in §8 | `:942` | Template install mode: ... | Unmanaged install mode: ... | The PR also adds **one dated paragraph at D6**, `:380`-`:393`. It sits directly under the "Two install modes" paragraph and above that paragraph's two bullets, and its lead is **Spelling note (2026-10-11, #22831).** The note says five things: - The second mode is spelled `unmanaged`. It cites ruling B on #15213 (record `6108509158`, 「同意」, 2026-10-11) and, for the bullet label, the maintainer's decision B on #22831 (record `6109891008`, 2026-10-11). - The record was accepted spelling it `template`. The note names the five places that now read `unmanaged`: the paragraph, the **Unmanaged** bullet label, D2's sentence, §6's restatement and the C12 row. - Why: - `unmanaged` is the industry's name for this mode: Salesforce's unmanaged packages and Power Platform's unmanaged solutions. ADR-0086's comparison table already names both. - `managed` and `unmanaged` are the two states of one property. - `template` already names other things in the code: `TemplateManifestSchema`, the `email_template` type and the `os init` templates. - ⛔ Only the spelling moves. The copy-once import, full editability, no upgrade channel and the refusal on `group` / `isolated` all stand. - The rest of the prose that says "template" ("template package", "template import", "template install mode") is kept, and it names the same mode. **Form.** The note follows this record's own convention for a dated note: a bold lead that names the date and the card, with ruling records cited as "record" plus the comment id. Examples are **Execution-plan note (2026-10-10, #22619).** at D14 (landed by #22650) and *Read against the code on 2026-10-10* at D2. ADR-0026's "Note (2026-09-07, #16140)" is a cross-ADR precedent for a spelling note in particular. The status line is not touched. The 2026-10-10 notes did not touch it either; only the 2026-09-17 amendment, which changed a decision, did. ## How I read the positions - **"D6".** The card maps it to `:268`-`:270`. That sentence sits at the end of **D2**, but it states D6's two install modes and cites "(D6)". The ruling's own premise list names `:376`, `:839` and the C12 row (base numbering). The two readings together cover the same four sites, and this PR changes all four. The bullet label is the fifth site, added by decision B on #22831. - **"§6 Q5" and its restatement: yes, I read the restatement as part of §6 Q5's spelling.** I measured this on PR #14976's history (`refs/pull/14976/head`, fetched into a scratch ref and deleted afterwards): - The install-mode question ("Who chooses the install mode", D6) was §6 **Q5** in the drafts from `47db4e9f71` through `de84c708bd`. - It became Q4 after `5d55c80100` dropped the Staging question. - At acceptance (`0be9039d4a`) it was folded into §6's "accepted as proposed" paragraph, now `:852`-`:858`. - D6's paragraph carries the same answer, marked "(ruled 2026-09-04)". So both lines are Q5's answer: one is in D6, the other in §6. - **The C12 row** is `:942` at the head; it was `:927` at the base. - **Every changed site spells the install-mode value.** None of them is the e-mail or notification "template" noun that D10, §6 Q1 and C4 use. ## Mentions of "template" kept as written Each install-mode mention below is kept as written. The reason is the same for all of them unless a line says otherwise: they are history, the ruling keeps the original prose untouched, and the D6 note names the mode they mean. Line numbers are at the head. - `:14`-`:16`: the maintainer's verbatim ruling (「…有一种是模版形式直接进库…但是单库多租户禁止安装这种模版软件包…」). This is a quotation, so it is never edited. - `:86`, `:88`-`:89` (TL;DR): "by installing a **template** package"; "Template packages are refused on shared-DB multi-tenant deployments". - `:221` (§1.7): "or install as a template" (C11's documentation promise). - `:284` (D3): "(Studio, template package; ...)". - `:418` (D6, inside the now-**Unmanaged** bullet's body): "a template import would hand every tenant an editable shared schema". Decision B moves the label only; the body is kept. - `:449` and `:455`-`:456` (D6): "template install wrote into `sys_metadata`"; "template content environment-owned". - `:634`-`:635` (D12 item 10): "Template packages are refused; managed only ... a template import". This is a list label about packages, and decision B leaves it as it is. - `:697` (D14): "D6's template mode". - `:735` (D14's execution-plan note, item 3, itself dated 2026-10-10): "D6's template install mode". - `:807` (§4): "template-installed templates". - `:816` (§4): "The template install mode is new work". - `:846` (§5): "a template install that forfeits upgrades". The e-mail and notification "template" noun is untouched because it is not an install mode. It appears at `:9`, `:11`, §1.4, `:242`, `:251`, `:274`, D6's `email_template` overlay rows and "Templates." paragraph, D10, D12 item 11, §6 Q1, C4 and the §9 file paths. ## Gates (run at `3d9b4f245e`, the patched head) `origin/main` moved 4 commits past the merge base `31b5a5f7f5` (to `12b9daf749`), and none of them touches `docs/adr/`. Per the patch order, I did not merge. I re-derived `node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack` with no paths at the head and got the **same 19 commands** as at `7f0c390035` and `115ec7061e`. All 19 exited **0**. Reconciliation: `dispatch-gates --ran: 19 derived famil(ies) accounted for — 19 run, 0 NOT-MEASURED (a DERIVED zero — all 19 recorded an exit code and none of them is 3)`. The derivation printed a STALE TREE warning: 3 gate files changed on `origin/main` since the base (`scripts/check-route-envelope.mjs`, `scripts/engine-double-contract.pinned.json`, `scripts/pm/os-regen-merge.sh`). None of the three is among the 19, and none of their changes names `docs/adr/`. CI runs the current copies on the merge ref. | Command | Exit | The gate's own verdict line (excerpt) | |---|---|---| | `node scripts/check-adr-links.mjs` (+ `--self-test`) | 0 / 0 | `726 relative link destination(s) under docs/adr/ resolve` | | `node scripts/check-adr-symbol-anchors.mjs` (+ `--self-test`) | 0 / 0 | `2309 anchors across 142 records resolve ... 0 line anchors survive` | | `pnpm check:adr-anchors` | 0 | `OK (66 anchored file(s), every governing ADR still referenced; 136 decision number(s) ...)` | | `pnpm check:doc-authoring` | 0 | `18140 customer-facing string(s) across 1349 spec sources clean` | | `pnpm check:nul-bytes` | 0 | `OK (scanned 10879 text file(s) ... no raw ASCII control bytes)` | | `pnpm --filter @objectstack/lint run check:doc-formula-expressions` | 0 | `22 record-scoped formula example(s) across 472 files / 1388 TS blocks judged clean` | | `node scripts/check-closing-keyword-parity.mjs` (+ `--self-test`) | 0 / 0 | `OK (3 parsers agree on all 9 keywords ...)` | | `node scripts/check-comment-mask-corpus.mjs` | 0 | `8779 files, 0 disagree, 0 unparseable` | | `node scripts/check-ci-filter-parity.mjs`, `pnpm check:cross-package-test-inputs`, `check:driver-memory-census`, `check:gitlink-declared`, `check:pm-governed-merges`, `check:pm-prior-rulings`, `check:refd-timer-probe`, `check:watch-hint-literal` | 0 each | each printed OK / ✓ | `@objectstack/formula` and `@objectstack/lint` were rebuilt under the verify lock before the run (`VERDICT command-exit 0`, a full turbo cache hit), so `check:doc-formula-expressions` measured rather than refusing. In the first round, that gate's first run exited 3 (`PREREQUISITE NOT MET`) before the build; that run measured nothing and is not counted. Two more readings, unchanged by the patch: - **`check-issue-citations` does not judge this file.** `docs/adr/**` is a `DEFERRED_SURFACES` row, so the gate reads 0 files. The numbers the note cites, #22831 and #15213, both answer as open issues, not pull requests. - **`pnpm lint` is not owed.** ESLint's own `--format json` on the changed file answers `"File ignored because no matching configuration was supplied."` (1 file, 0 errors). Every `files:` block in `eslint.config.mjs` matches only JS and TS extensions. ## Changeset This PR publishes nothing: `docs/adr/**` ships in no package's `files[]`. The repo's route for that is the `skip-changeset` label, and the seat has applied it. ## Acceptance notes - **Open question answered.** "Should D6's bullet label 'Template.' move too?" The maintainer chose **B**, recorded in `6109891008` on #22831: 「B,:412 一起改」. It is carried out at `:414`. The note now names the bullet label among the sites that read `unmanaged`, cites `6109891008` beside ruling B, and no longer lists the bullet as kept prose. - **Mechanism checks** (base `1eff3224d7`, then head `3d9b4f245e`): - Code-font `template` drops from 2 install-mode sites to 0. The 2 code-font hits at the head are both inside the note, which quotes the old spelling. - Bold **template**: 2, then 1. The one left is the TL;DR at `:86`, which is kept. - The bullet label - **Template.**: 1, then 0. The label - **Unmanaged.**: 0, then 1. - "Template install mode": 1, then 0. - Whole-word `unmanaged`: 1, then 9. - Record `6108509158`: 0, then 1. Record `6109891008`: 0, then 1. - No anchor JSON under `scripts/adr-anchors/` quotes any of these lines. - **Mentions outside this file, not changed because they are outside the file surface:** - ADR-0126's status line (`docs/adr/0126-packaged-metadata-customization-model.md`, line 3) says "template = copied once, fully editable ..." in plain prose. - The ADR-0087 entry `packages/spec/src/migrations/entries/semantic/18.meta-doors-organization-scope-retired.ts` (line 30) says "by a template install" in its description string. Neither spells the manifest value. carrier: #15213's S2, which writes `unmanaged` into the spec and its docs. Noted, not filed. ## 维护者速读(草稿) **改了什么**: - ADR-0131 里第二种安装方式的拼写从 `template` 改成了 `unmanaged`。改了这五处: - D2 里讲两种安装方式的那句; - D6「两种安装方式」那段; - D6 下面那个要点的标题,「**Template.**」改成「**Unmanaged.**」,按您的「B,:412 一起改」,要点正文不变; - §6 里同一结论的复述; - §8 的 C12 行。 - D6 加了一段带日期的「拼写说明」,指向 #15213 上的裁决 B 和本卡上的决定 B。这段说明写了为什么叫 `unmanaged`: - 这是行业通用叫法(Salesforce 和 Power Platform 都这么叫),ADR-0086 里已经提到过; - `managed` 和 `unmanaged` 是同一个属性的两种状态; - `template` 在代码里已经指别的东西(脚手架清单、邮件模板、`os init` 模板)。 - 其余写着「template」的原文一字未动,包括 D12 第 10 条「Template packages are refused」。决定本身也没有变:拷贝一次、完全可编辑、不跟随升级、单库多租户拒装,都照旧。 **为什么改**: - 您在 #15213 对裁决 B 回了「同意」,裁决要求 ADR 记录随之同步。 - 要点标题这一处,是您在本卡上选的 B。 - 不改的话,照 ADR 写代码或写清单的人(包括 AI)仍会写 `installModes: ['managed', 'template']`,和 S1、S2 按裁决写的 `unmanaged` 对不上。 **风险与代价(含回滚)**:纯文档改动,不影响运行时,也不影响发版。回滚只需 revert 这一个 PR。 **席位意见**: **你要做的**:在新的提交 `3d9b4f245e` 上审阅本 PR,同意就点 Approve。这是 Tier H 治理面,需要您批准才能落地。 --- _Generated by [Claude Code](https://claude.ai/code/session_016njDy8ozy9B9Ns5Y8kAWEK)_ --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent 3f0b6f2 commit 0e0678c

1 file changed

Lines changed: 20 additions & 5 deletions

File tree

‎docs/adr/0131-total-organization-ownership-no-null-organization-id.md‎

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,7 @@ environment ledger exactly as ADR-0094 D3 already redirects it today.
266266
Setup authoring under `single` requires `manage_metadata` — D14's execution-plan note, item 4.
267267

268268
A package reaches a deployment in one of **two install modes** (D6): **managed** — registered as code,
269-
sealed, upgradeable; or **template** — copied once into the environment ledger as environment
269+
sealed, upgradeable; or **unmanaged** — copied once into the environment ledger as environment
270270
metadata, fully editable, no upgrade channel, refused on shared-DB multi-tenant postures.
271271

272272
This retires: `bootstrapBuiltinRoles`, `bootstrapDeclaredPositions`, `bootstrapDeclaredPermissions`,
@@ -375,7 +375,22 @@ The `single` anchor's own disposition is #11979's (Choice 4B), which this record
375375

376376
**Two install modes.** The package **declares** the modes it permits (`installModes`, default
377377
`['managed']`); the installer picks one at install time; a shared-DB multi-tenant deployment refuses
378-
`template` whatever the package permits (ruled 2026-09-04).
378+
`unmanaged` whatever the package permits (ruled 2026-09-04).
379+
380+
**Spelling note (2026-10-11, #22831).** The second install mode is spelled `unmanaged`: the maintainer's
381+
ruling **B** on [#15213](https://github.com/objectstack-ai/objectstack/issues/15213) (record `6108509158`,
382+
「同意」, 2026-10-11) and, for the bullet label below, the maintainer's decision **B** on #22831 (record
383+
`6109891008`, 2026-10-11). This record was accepted spelling it `template`; the value now reads `unmanaged`
384+
in this paragraph, in the **Unmanaged** bullet label below, in D2's install-mode sentence, in §6's record of
385+
the accepted install-mode question and in §8's C12 row. Why: it is the industry's name for this mode —
386+
Salesforce's unmanaged packages and Power Platform's unmanaged solutions, both already in
387+
[ADR-0086](./0086-authz-metadata-config-boundary-and-cross-package-composition.md)'s comparison;
388+
`managed` and `unmanaged` are the two states of one property, whether the package stays the authority; and
389+
`template` already names other things in the code — the scaffold manifest
390+
(`TemplateManifestSchema`), the `email_template` metadata type and the `os init` templates. ⛔ Only the
391+
spelling moves: the copy-once import, full editability, no upgrade channel and the refusal on `group` /
392+
`isolated` stand as decided. The rest of this record's prose — "template package", "template import",
393+
"template install mode" — is kept as written and names this same mode.
379394

380395
- **Managed** (default). The package is registered into the registry as code. **No door edits a managed
381396
definition** — not Setup, not Studio, not the data or metadata API; to change one, the vendor publishes a
@@ -396,7 +411,7 @@ The `single` anchor's own disposition is #11979's (Choice 4B), which this record
396411
- **E — extend** (`object`, `app`): fields, validations, navigation arrive as a package.
397412
Managed is the **only** mode a shared-DB multi-tenant deployment (`group` / `isolated`) accepts, and every
398413
regime there is environment-wide and operator-gated — a plant admin neither overlays, switches nor clones.
399-
- **Template.** The package's metadata is copied **once** into the environment definition ledger as
414+
- **Unmanaged.** The package's metadata is copied **once** into the environment definition ledger as
400415
environment-provenance items — from then on it is the environment's own metadata, editable in Studio like
401416
anything authored there, with no upgrade channel (a later version is a new import, refused where names
402417
collide; provenance recorded for information only). ⛔ **Refused on `group` / `isolated`** with a message
@@ -837,7 +852,7 @@ sits beside them.
837852
Four of the five questions this draft carried were **accepted as proposed** on 2026-09-04 (「接受你的建议」)
838853
and are now part of the decisions: the `single`-posture first-user grant row is owned by the Default
839854
Organization (D5); the package **declares** the install modes it permits (`installModes`, default
840-
`['managed']`), the installer picks one, and a shared-DB multi-tenant deployment refuses `template`
855+
`['managed']`), the installer picks one, and a shared-DB multi-tenant deployment refuses `unmanaged`
841856
whatever the package permits (D6); deployment-level settings go to configuration, with a tenant-less
842857
object only for values an operator must change without a restart (D7); ADR-0005's per-organization
843858
overlay axis is retired (D6). One remains:
@@ -924,7 +939,7 @@ One epic tracks the family. C0 and #15030 land before 17.3; every other card is
924939
| C3 | Retire the seeders, the per-organization catalog machinery and the four catalog objects; `PositionSchema.permissionSets` added and `sys_position_permission_set` rows migrated into definitions; built-ins and audience anchors as declared metadata; Setup catalog creation = environment metadata write under `single`, refused under a wall; platform-admin grant row owned by the Default Organization | D2, D3, D5, D13 | C1, C2 |
925940
| C4 | Templates: `sendTemplate` resolves the registry; seed and provenance stamp retired; door closed; customized-rows ruling applied | D6, D10 | ADR merge (+ §6 Q1) |
926941
| C5 | `sys_metadata` family tenant-less (environment definitions, UI-editable by metadata authors); per-organization overlay axis retired (org-scoped writes of the five tier-A types refused); `sys_view_definition` and its two runtime index migrations retired as inert (ADR-0087 entry; ADR-0017 amended); ADR-0005 amended | D6, D7, D13 | C1 |
927-
| C12 | Template install mode: manifest `installModes`, one-time import into the environment ledger with provenance, refusal on `group` / `isolated`, CLI + marketplace surfaces | D6 | C5 |
942+
| C12 | Unmanaged install mode: manifest `installModes`, one-time import into the environment ledger with provenance, refusal on `group` / `isolated`, CLI + marketplace surfaces | D6 | C5 |
928943
| C6 | Deployment-level state has no column: settings global rung leaves `sys_setting`; plumbing objects drop the column; #12699 declaration made total | D7 | ADR merge (+ §6 Q3) |
929944
| C7 | Inventory + the manual migration ceremony (`os migrate` family: plan / apply / post-check, idempotent + resumable, per-table constraint gate) and the v18 boot refusal against an un-migrated database. First named fate-3 members (the #14096 census, ruled 2026-09-04): `sys_file`, `sys_upload_session`, `sys_approval_request`, `sys_approval_action`, `sys_approval_approver`, `sys_automation_run`, `sys_notification_delivery`, `sys_record_share` | D10 | C2, C3, C4, C5, C6 |
930945
| C8 | One predicate; NOT NULL per cleared table; every-posture refusal; both arms and the ledger retired — protocol 18 | D1, D8, D9, D13, D14 | C7 |

0 commit comments

Comments
 (0)