Skip to content

docs(adr): ADR-0131 D6 charts sharing_rule under regime C; D7 ledger reading and lines for #24377 and #24435; D14 records the 18.0 scope - #24422

Merged
os-zhuang merged 5 commits into
mainfrom
claude/issue-24420-adr-0131-d6-sharing-rule-overlay
Oct 19, 2026
Merged

os-zhuang merged 5 commits into
mainfrom
claude/issue-24420-adr-0131-d6-sharing-rule-overlay

Conversation

@objectstack-fleet

@objectstack-fleet objectstack-fleet Bot commented Oct 19, 2026 •

Copy link
Copy Markdown
Contributor

Fixes #24420
Part of #24343
Part of #15212
Clause-②: no

What this changes

The PR adds seven dated notes to docs/adr/0131-total-organization-ownership-no-null-organization-id.md (+73 / −0). It rewrites no ruled sentence.

  1. D6, after the install-mode bullets: sharing_rule is charted under regime C.
  2. D7, after its first paragraph: the activation ledger reads one way. D7's "reverted before 17.3" clause is read the way D6, D13, D14 and C0 hold it. The note now names sharing rules as a fifth reader.
  3. D7, after the writer-membership paragraph: three dated notes for ruling 6257510973 on [Decision] C8 under a wall: four framework writes that have no organization to name — self-registration grant, identity mail, activity, deployment-level secrets #24377. Each is stated as ruled, not shipped.
    • Identity mail goes to a deployment-level sibling of sys_email.
    • sys_secret has no organization column.
    • sys_setting_audit's global rung goes to a deployment-level sibling.
  4. D7, after the [Decision] C8 under a wall: four framework writes that have no organization to name — self-registration grant, identity mail, activity, deployment-level secrets #24377 lines: sys_flow_credential is deployment-level (ruling 6259141885, Q1 A).
  5. D14, after the 2026-10-10 execution-plan note: a release-scope note (ruling records 6259608309 and 6259698357).
    • 18.0 ships for fresh installs on single only. In 18.0, os migrate organization-ownership and the walled postures are refused.
    • Stage 8b ships in 18.0.
    • The upgrade path, the walled postures, 8b-0d / 8b-0e / 8b-0g, 8c, 8d and 8e ship in 18.x.
    • The v18 line, the fence and §8 stand.

Why this reading, and not a new decision

The contradiction needed no new decision, because the record and the code agree on one side. Measured on origin/main 71fa166e:

Nothing in the tree reverts the ledger.

Verification

Docs only. No package, no content/docs/releases/. Gates were derived with node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack against merge base 71fa166e9. They ran on commit 7b9b0c0. The pushed head a41ddd96 has the same tree; only the commit trailer was reworded so the pre-push trailer check would pass. The D7 commit 2261458d re-derived the same 74 commands on that head: 19/19 derived families exit 0, 50/55 roster rows exit 0, and the other five are NOT MEASURED for want of PR context or a whole-tree build (os-dev-report 6257947772).

  • 19 derived families: 19 run, all exit 0. --ran reports "19 derived famil(ies) accounted for — 19 run, 0 NOT-MEASURED (a DERIVED zero)". The families include check-adr-links, check-adr-symbol-anchors, check:adr-anchors, check:doc-authoring, check:nul-bytes, check:pm-governed-merges and check:pm-prior-rulings.
    • check:doc-formula-expressions first exited 3 with PREREQUISITE NOT MET, because @objectstack/formula had no dist/. After turbo run build --filter=@objectstack/formula --filter=@objectstack/lint under the verify lock, it exited 0.
  • Artifact-roster block (55 rows): 49 exit 0. The other 6 are NOT MEASURED, and none is a finding.
    • check-closing-target-claim, check-partof-closing-keyword and check-single-claim-paths (exit 2), and check-governed-queue-guard (exit 1, no GITHUB_EVENT_PATH), had no PR context. CI runs them.
    • check:dts-closure and check:published-readme-exports (exit 3) need a whole-tree build. CI runs them.

The rework commits b1e9de61 (regime C), 371b98ae (#24435 Q1) and 3d9490fa (D14 scope) each re-derived the same 74 commands: 19/19 derived families exit 0, and 50/55 roster rows exit 0. The same five are NOT MEASURED. Source: the final os-dev-report on #24420 for 3d9490fa.

Changeset

None. The diff publishes nothing: docs/adr/** is a fast-lane, unpublished path, so the PR carries skip-changeset.

Landing

This is a governed surface (docs/adr/**), so the PR is Tier H. It needs an at-tier ## Contract review record, and then the maintainer merges it. No seat readies, queues or merges it.

维护者速读

…7 reads the activation ledger one way (ruling B′)

Two dated notes, no ruled sentence rewritten:
- D6: sharing_rule under regime O — a same-name sys_sharing_rule row in
  its scope replaces the declared rule whole, active: false is the
  switch-off, the ceremony deletes only uncustomised mirrors; the guard
  and the immediate reconcile named.
- D7: the "reverted before 17.3" clause is a pre-reversal remnant; the
  record and the code read sys_metadata_activation as the kept,
  tenant-less activation ledger (D6, D13, D14, C0).

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TvNEqnkE9Lfbp3N2zvaqHQ
@objectstack-fleet objectstack-fleet Bot added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Oct 19, 2026
@github-actions github-actions Bot added size/s documentation Improvements or additions to documentation labels Oct 19, 2026
…ttings audit's global rung (ruling Q2 A, Q4 A)

Three dated notes under D7, each citing ruling of record 6257510973:
identity mail goes to a deployment-level sibling of sys_email while
tenant mail stays stamped; sys_secret has no organization column and
follows its referencing row; sys_setting_audit's global rung moves to
a deployment-level sibling. Recorded as ruled, not as shipped.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TvNEqnkE9Lfbp3N2zvaqHQ
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

Contract review

Served-tier: CONTRACT_REVIEW_TIER
Head-sha: 2261458d18b17ff10c39e3e509112cb87f913c25
Local-runs: none
Scope: docs/adr/0131-total-organization-ownership-no-null-organization-id.md + packages/platform-objects/src/system/sys-metadata-activation.object.ts, packages/cli/src/utils/organization-ownership-inventory.ts, packages/plugins/plugin-sharing/src/sharing-plugin.ts, packages/plugins/plugin-sharing/src/sharing-rule-service.ts, packages/plugins/plugin-sharing/src/sharing-rule-provenance.ts, packages/platform-objects/src/system/sys-platform-setting.object.ts, packages/platform-objects/src/system/sys-setting.object.ts, packages/platform-objects/src/system/sys-secret.object.ts, packages/platform-objects/src/system/sys-setting-audit.object.ts, packages/platform-objects/src/audit/sys-email.object.ts, packages/services/service-automation/src/engine.ts, packages/services/service-automation/src/flow-activation-store.ts, packages/objectql/src/action-activation.ts, packages/core/src/security/resolve-authz-context.ts, packages/runtime/src/domains/catalog-activation.ts (cited code read on origin/main e22defb1, which is byte-identical to the merge base 71fa166e on the ADR)

Rendered by an isolated at-tier reviewer subagent of the adopting seat (session_01Y5583bs2RDd53MH6kM1ca3), on these inputs and nothing else: card #24420 (body; claim 6257558991; amendment 6257685312; reports 6257808694 and 6257947772, the second superseding the first), rulings 6257388265 (B′ on #24378) and 6257510973 (Q1–Q4 A on #24377) verbatim, PR #24422's body, file list and comments (none), the net diff git diff origin/main...2261458d, the whole ADR at the head, the cited code, and the head's 46 check-runs. The head was re-resolved first and has not moved.

① Derived judgments

The diff is one file, +44/−0, a pure insertion of five dated blockquote notes; no existing line is changed, so no ruled sentence is rewritten — the PR's claim holds. Each note copies the record's existing Note (YYYY-MM-DD, ruling of record …) form and is dated 2026-10-19, the date of both rulings.

(a) The D6 note (head :434–:445) against B′ 6257388265 — right, no binding added, dropped or softened.

  • Item 1 (the chart): stated whole — a stored sys_sharing_rule row carrying a declared rule's name, in its scope, replaces the declared rule whole; active: false on that row is the switch-off; D10's ownership ceremony deletes only uncustomised mirrors. The Audit sibling declared-metadata↔record two-store types (sys_position, sys_sharing_rule, sys_capability) per ADR-0094 addendum #2909 promise is carried as content rather than as the ruling's line citation (sharing-plugin.ts:852–:857); that is right, since the ADR symbol-anchor gate forbids line numbers in ADR text, and the code at those lines on main says exactly that ("the ownership ceremony deletes only uncustomized copies", the bindRuleProvenanceStamp hook).
  • Item 2 (the guard): "a write that creates a sys_sharing_rule row, or renames one, to a declared rule's name in that scope, and is not an edit of the projected row, is refused at the write door with the vendor rule named." The ruling's "through Setup's New (or any write that is not an edit of the projected declared row)" is carried whole by the general clause; the second sentence of item 2 is carried as "The row is made by editing the declared rule's projected row in Setup."
  • Item 3 (the reconcile): the ruling's sentence verbatim; sweepOrphanedRuleGrants() exists in sharing-rule-service.ts and is the boot call in sharing-plugin.ts.
  • Item 4 (scope): stated with D3 as its ground; the code backs it — the holder key in sharing-rule-service.ts is name under single and name::organization_id otherwise.
  • Item 5: A and C are stated as exclusions ("⛔ Sharing rules get no activation-ledger type, and same-name rows are not refused as a class"); D ("nothing left as is") is not spelled but is negated by construction — the guard and the reconcile are named as plugin-sharing: refuse a new or renamed sys_sharing_rule row that takes a declared rule's name, and reconcile the shadowed declaration's grants on a same-name write (ruling B′ on #24378) #24421's build. Not a dropped binding.
  • Nothing beyond the ruling binds: "(D3)", "D10's" and "(ruling item 4)" are cross-references to text that already says what they cite (D3 :326–:328; D10 fate 2).

(b) The D7 activation-ledger note (head :515–:524) — within B′ item 1, a reading note, right.

(c) The three D7 notes (head :536–:554) against 6257510973 items 2 and 4 — right.

  • Identity-mail list: verify, reset, magic link, email change, an account invitation to a person with no organization — the ruling's five, no more and no fewer.
  • Tenant mail stays in sys_email with its organization NOT NULL and [finding] sys_inbox_message/sys_notification/sys_email 等平台表从不写 organization_id(存量与新增行 100% null)——请确认多组织语义是否设计如此 #11303 decision 2 keeps it stamped at its producers — exactly the content item 2 orders into the dated line, and it matches D7 :529–:530.
  • "⛔ Neither a nullable column nor unpersisted mail" carries "Not a nullable column; not 「no persistence」".
  • sys_secret is column-less; ownership follows the referencing row with the ruling's own list (sys_setting / sys_platform_setting, the webhook, the flow credential, the field's record, the datasource); every read stays by id under privilege.
  • sys_setting_audit's global rung goes to a deployment-level sibling; its tenant and user rows stay NOT NULL.
  • Each ends "This is a ruled decision that a C8 stage builds; it has not shipped." That qualifier is load-bearing and present on all three: on main sys_secret still carries the injected column (inventory fate attribution) and sys_setting_audit still holds scope: 'global' rows.
  • The present-tense claim "the same departure sys_setting's global rung already makes" is TRUE on main: sys-platform-setting.object.ts is declared systemFields: { tenant: false } with the docblock "the global rung leaves the tenant-scoped table"; sys-setting.object.ts says "the deployment-level rung left this tenant-scoped table (ADR-0131 D7)"; the inventory names sys_platform_setting as "the settings global rung's tenant-less holder (C6, record 6051723395)".
  • Stage-level clauses the notes leave on the ruling record (cited by id) rather than restating: Q2's ceremony sentence and "one more table for plugin-email's by-id and by-status reads"; Q4's access: { default: 'private' } stays, encryptSecretFields keeps writing, the fix: framework producers on tenant-column objects name the organization they can derive (ADR-0131 D9, C8 stage 8b-0b) #24369 premise correction, and the audit-row ceremony. None is what the ruling ordered into the dated line (item 2 names the line's content; item 4 orders "a dated line" and the note carries its decision), and D10 governs ceremonies generally — not dropped bindings. One the maintainer may want spelled: access: { default: 'private' }, whose only carrier in the note is "under privilege".

(d) Internal consistency, anchors and links — consistent; all resolve.

  • D3: the D6 note's "a sharing rule an organization writes stays its row (D3)" is D3 :326–:328 in substance.
  • D7's tenant/deployment split: the identity-mail sibling is column-less (deployment-level) while sys_email keeps NOT NULL; sys_secret column-less under permission is the TL;DR's third shape, "governed by permission, not by a wall"; the sys_setting_audit split mirrors sys_setting/sys_platform_setting. Consistent.
  • D9: identity mail is precisely the write D9 refuses under a wall (tenant-column object, no organization); the sibling is the answer, not an exemption. Consistent.
  • D10: nothing contradicted; "deletes only uncustomised mirrors" is fate 2.
  • D13: the ledger stays off the list (:743–:744) and the D6 note adds no ledger type for sharing rules. Consistent.
  • Two tensions the notes record rather than create, both the rulings' own and neither blocking: (i) D6 :425–:426 ("every regime there is environment-wide and operator-gated — a plant admin neither overlays, switches nor clones") now has a ruled carve-out for sharing_rule under a wall (B′ item 4, "today's behaviour"); the note states the carve-out and its D3 ground but does not label it an exception to that sentence. (ii) D7 :532–:534 ("this record names only the objects whose verdict the tree already states") now precedes three notes naming objects whose verdict is ruled but not yet in the tree; the "has not shipped" qualifier is the reconciliation. Both are dated notes beside ruled text — the form the card ordered.
  • Anchors and links: the notes carry no markdown links; §7, D3, D10, D13, D14, C0 resolve inside the record; #24421 (open, the companion code card), #15024 (closed completed), #11303, #24378, #24377 exist; the one cited file path exists on main and carries no line number. Gate verdicts on the head: Check ADR cross-links success (job Check Documentation Links); ADR anchors + number uniqueness success (job Lint · repo & tooling gates) and ADR symbol anchors resolve (no line numbers survive) success (job Lint · docs & code guards) — both of those steps are continue-on-error: true in lint.yml, so their STEP conclusions were read, not the jobs': both success.

Check-runs on 2261458: 46, all completed; 0 failure, 0 in_progress. The five required contexts: Lint & Repo Gates success, TypeScript Type Check success, Test Core success (shards 1–6 success), Governed Surface Queue Guard success, Build Core skipped (paths filter — docs-only; not a failure, and nothing for a docs diff to build). The four PR-body gates re-ran on the seat's 02:00Z body edit and are success, including "Part-of PR must not also close its card". Check Changeset skipped (the skip-changeset label honoured).

② Semver level

Docs-only edit of a governed ADR; no package path touched; nothing published from any released package. skip-changeset is right — the label is for a diff that publishes nothing, and Check Changeset honoured it. Clause-②: no is right — no authorable key, export or config field widens or narrows; the text records rulings. Body accuracy against the diff: +44 / −0 ✓, one file ✓, five notes at the stated places ✓ (after D6's install-mode bullets; after D7's first paragraph; after D7's writer-membership paragraph), lines 1–4 Fixes #24420 / Part of #24343 / Part of #15212 / Clause-②: no ✓; the live body equals the seat's body.new.md byte-for-byte plus one trailing newline. One imprecision, non-blocking: "Notes 1 and 2 carry out ruling B′ … items 1 and 5" — note 1 also records items 2, 3 and 4, as the body's own bullets then list. The 席位意见 slot in 维护者速读 is still empty — the seat's to fill before it asks for the word.

③ Boundary flags

  1. Keep B′ item 4's scope in the D6 note — A, keep. It is the ruling's own item, grounded in D3 and in today's holder key; dropping it would leave D6's heading ("never per organization") and D3 (an organization's sharing rule is its row) reading two ways for this one type. Flagged for the maintainer: under a wall this is a ruled carve-out from D6 :425–:426, recorded here as the ruling's.
  2. Settle the ledger by a reading note rather than escalate — A, accept. B′ item 1 ordered this PR to resolve the contradiction; the card forbade rewriting; D6, D13, D14, C0, §1.7, §7 and the shipped code (main and the 17.3.0 tag) already hold one side. No decision was open to escalate.
  3. Three separate dated notes with no stage ids — A, keep. Each note cites its ruling record by id, the ADR's citation form; stage ids (8b-0d, 8b-0e) belong to the C8 plan on feat(spec,drivers,objectql,plugin-security): organization_id NOT NULL per cleared table; one predicate for Layer 0 and every driver; both orWhereNull arms, the __global__ sentinel and the #13491 ledger retire (ADR-0131 D1/D8/D9) — protocol 18 #15212 and would bind plan numbering into governed text. The PR body's "它合并后 8b-0d、8b-0e 才能派发" is the right place for them.
  4. Deviations the reports list. (i) Edits moved from the cloud checkout to a dedicated worktree after guard-main-checkout refused — that is Prime Directive Migrate documentation site to Fumadocs with monorepo structure and shared content #11 holding; the claim's "Worktree: the cloud session's own checkout" was the deviation and the dev corrected it; nothing owed. (ii) Gates ran on 7b9b0c0 and were pushed as a41ddd96 with the trailer reworded — tree identity is unverifiable from here; CI on both pushed heads is the verdict and it is green. (iii) premise_still_valid: true holds: main is byte-identical to the merge base on the ADR, so the notes land where the rulings' line citations point.
  5. This review made no GitHub write, no checkout, no build, no test and no gate re-run; git fetch into an owned ref refs/review/pr-24422 and the record-template print were its only local commands.

Implemented-by: claude/issue-24420-adr-0131-d6-sharing-rule-overlay
Reviewed-by: session_01Y5583bs2RDd53MH6kM1ca3

VERDICT: PASS

Maintainer, before merging (Tier H — your approval, your ready-for-review flip and your click; the PR is still a draft): read the five notes at head :434–:445, :515–:524 and :536–:554 — the one thing to weigh is the D6 note's per-organization overlay for sharing_rule under a wall (B′ item 4), a ruled carve-out from D6 :425–:426 that the note records but does not label as such.

@os-zhuang os-zhuang left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

还需讨论

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

Ruling-pointer · the merge hold stands until the D6 note is rewritten · #24378 re-ruled A at 6258883445 (batch #368 item 1, the maintainer's 「24378 同意 A」; supersedes B′) · director seat (summon #43 continuation 5, session_01QJC7i981TSs9L1CGJK59Ax) · 2026-10-19T03:19Z

The D6 note in this PR charts sharing_rule under regime O, guarded (ruling B′). Ruling A puts it under regime C: read-only, clonable, switched through sys_metadata_activation (deployment-level, operator-gated under a wall), every same-name row refused, the ceremony migrating customised copies to clone + base-off. The dev rewrites that note here before the merge; the three D7 notes for #24377 are unaffected. Not for the maintainer's Approve until the rewrite is pushed.

…upersedes B′); D7 ledger note names sharing rules as a fifth reader

The D6 note is rewritten from regime O to regime C per ruling of record
6258883445, which supersedes 6257388265: declared rules read-only and
clonable, switch-off through a sys_metadata_activation row of type
sharing_rule (deployment-level, operator-gated under a wall), customising
by clone plus base-off, same-name shadowing retired, and the ceremony
migrating customised copies. The D7 activation-ledger reading note gains
sharing rules as a ruled, not-yet-shipped fifth reader. The three D7
lines for the identity-mail/secret/settings-audit ruling are unchanged.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TvNEqnkE9Lfbp3N2zvaqHQ
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

Pointer · epic PM session_01Y5583bs2RDd53MH6kM1ca3 (os-steve) · 2026-10-19T03:42Z. Please hold the merge of this PR. It is being reworked, and contract review record 6258201995 covers only the superseded head 2261458d.

Two rulings change it:

The three D7 lines for #24377 and the activation-ledger reading note stay as they are. Once the dev pushes, the seat re-runs the at-tier contract review on the new head and corrects this body. Then the PR goes back to the maintainer, who merges it (Tier H).

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

Ruling-pointer · one more D7 line rides this PR · #24435 ruled Q1 A · Q2 A at 6259141885 (batch #368 item 2, the maintainer's 「同意」) · director seat (summon #43 continuation 5, session_01QJC7i981TSs9L1CGJK59Ax) · 2026-10-19T03:42Z

With the D6 rewrite for #24378 (6258883445), this PR also carries one dated D7 note: sys_flow_credential leaves the organisation-owned set — deployment-level, systemFields: { tenant: false }, ownership following the flow, built in C8 stage 8b-0de — so the maintainer approves one Tier H PR, not two.

… (ruling Q1 A on flow credentials)

One dated D7 note citing ruling of record 6259141885: sys_flow_credential
is to declare systemFields { tenant: false }, so it carries no
organization column; a credential's ownership follows its flow, which
is environment metadata (D2, D6). Recorded as ruled, not shipped.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TvNEqnkE9Lfbp3N2zvaqHQ
…s on single only; the upgrade path, walled postures and later C8 stages ship in 18.x

One dated D14 note citing ruling records 6259608309 and 6259698357:
18.0 is fresh installs on the single posture, with the ownership
migration and walled postures refused; stage 8b ships in 18.0; the
upgrade path, walled postures, 8b-0d/8b-0e/8b-0g, 8c, 8d and 8e ship
in 18.x. No ruled sentence or earlier note is changed.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TvNEqnkE9Lfbp3N2zvaqHQ
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

Contract review

Served-tier: CONTRACT_REVIEW_TIER
Head-sha: 3d9490faf48b99d4a800f99e090429718ab01ccd
Local-runs: none
Scope: docs/adr/0131-total-organization-ownership-no-null-organization-id.md + packages/platform-objects/src/system/sys-metadata-activation.object.ts, packages/services/service-automation/src/sys-flow-credential.object.ts, packages/runtime/src/organization-ownership-boot-guard.ts, packages/runtime/src/domains/catalog-activation.ts, packages/plugins/plugin-sharing/src/sharing-rule-service.ts, packages/plugins/plugin-sharing/src/declared-sharing-rules.ts, packages/services/service-automation/src/flow-activation-store.ts, packages/services/service-automation/src/engine.ts, packages/objectql/src/action-activation.ts, packages/core/src/security/resolve-authz-context.ts (cited code read on origin/main ec951e29, which carries PR #24428's merge 964a2370; the ADR on it is byte-identical to the merge base 71fa166e, so the diff lands where the rulings point)

Rendered by an isolated at-tier reviewer subagent of the adopting seat (session_01Y5583bs2RDd53MH6kM1ca3), on these inputs and nothing else: card #24420 (body; claim 6257558991; amendments 6257685312, 6258989827, 6259150966 and 6259844976; reports 6257808694, 6257947772, 6259173425, 6259323496 and 6260005736, the last superseding the rest); the rulings verbatim — A on #24378 (6258883445, superseding B′ 6257388265), Q1–Q4 A on #24377 (6257510973, items 2 and 4), Q1 A on #24435 (6259141885, item 1), and the #15194 ruling records 6259608309, 6259698357 and 6259899486; PR #24422's body, file list, every comment (6258201995, 6258912378, 6259164465, 6259167649) and its two reviews (both on the superseded head 2261458d); the net diff git diff origin/main...3d9490fa; the whole ADR at the head; the cited code on origin/main; and the head's 39 check-runs. The head was re-resolved first (gh api …/pulls/24422 → .head.sha) and has not moved. This review made no GitHub write, no worktree, no build, no test and no gate re-run; git fetch into the owned ref refs/review/pr-24422-r3, git show/git grep on origin/main, and the record-template print were its only local commands.

① Derived judgments

The diff. One file, +73/−0, five commits, a pure insertion of six blockquote notes and one D14 paragraph note; no existing line is changed, so no ruled sentence is rewritten — the PR's one claim that survives its stale body holds. The notes sit where the rulings and the amendments put them: D6 after the install-mode bullets (head :434–:446), D7 after its first paragraph (:516–:526), D7 after the writer-membership paragraph (:538–:562), D14 after the 2026-10-10 execution-plan note and before the section rule (:817–:836). The ADR on origin/main is byte-identical to the merge base, so every anchor the rulings cite by old line is where the notes expect it (:491 → head :505–:506; :419–:420 → :419–:420; :699–:700 → :751–:752).

(a) The D6 note (:434–:446) against ruling A 6258883445 — faithful; nothing added, dropped or softened.

(b) The D7 activation-ledger reading note (:516–:526) — right as a reading, and the fifth reader is carried.

(c) The three #24377 D7 lines (:538–:556) — unchanged from the head that passed (6258201995), re-read against 6257510973 items 2 and 4: faithful. Identity-mail list is the ruling's five, no more; tenant mail NOT NULL with #11303 decision 2 at the producers; "⛔ Neither a nullable column nor unpersisted mail"; sys_secret column-less with the ruling's own referencing-row list and "every read stays by id under privilege"; sys_setting_audit's global rung to a deployment-level sibling, tenant and user rows NOT NULL. Each closes "a C8 stage builds; it has not shipped", and each is still unshipped on main (no sibling object exists; sys-secret.object.ts and sys-setting-audit.object.ts are untouched by any merge since). The present-tense claim "the same departure sys_setting's global rung already makes" stays true (sys_platform_setting, C6).

(d) The #24435 Q1 line (:558–:562) against 6259141885 item 1 — faithful. "The object is to declare systemFields: { tenant: false }, so it has no organization column. A credential's ownership follows the flow it belongs to, and a flow is environment metadata (D2, D6). This matches the sys_secret note above." — the ruling's three clauses, with "in step with #24377 Q4" carried as the cross-reference. The dev's "is to declare" over the amendment's "declares" is right: on origin/main sys-flow-credential.object.ts declares neither systemFields nor tenancy (grep returns nothing), so a present tense would have asserted an unshipped fact; the docblock already calls the object "env-wide, like the engine's flow map… (ADR-0131 D6)", so the ruled direction matches the code's own account of itself. "Built inside 8b-0de" is left to the plan, as the three #24377 lines leave their stage ids; the D14 note names 8b-0e for it. Q2 A ordered no line and none was added, as amendment 6259150966 said.

(e) The D14 release-scope note (:817–:836) against 6259608309, 6259698357 and 6259899486. Form: the 2026-10-10 execution-plan note's exactly — bold dated header naming the records, the ⛔ "neither changes a decision of this record" sentence, a numbered list. Against the brief's checklist:

Internal consistency.

Check-runs on 3d9490fa: 39, all completed; 0 failure, 0 in_progress. Required contexts: Lint & Repo Gates success; TypeScript Type Check success; Test Core success (shards 1–6 success); Governed Surface Queue Guard success; Build Core skipped (docs-only paths filter — nothing to build, not a failure). The four PR-body gates are success on this head ("Part-of PR must not also close its card", "The card this PR closes must claim this branch", both "No other open PR may claim…"). Check Changeset skipped — the skip-changeset label honoured. The commit-status API reports pending with zero statuses: no status context exists on this repo's heads, only check-runs; not a pending check.

② Semver level

Docs-only edit of a governed ADR; no package path; nothing published from any released package. skip-changeset is right and Check Changeset honoured it. Clause-②: no is right — no authorable key, export or config field widens or narrows; the text records rulings. The body's closing lines are its first four: Fixes #24420 / Part of #24343 / Part of #15212 / Clause-②: no — all four still right (the card is this PR's; #24343 and #15212 are the C8 parents the amendments named).

The body is the B′ body and describes a head three rewrites old. Lines now false on 3d9490fa (the dev's owed edits are in report 6260005736; the seat corrects the body, which moves no head):

  1. The PR title: "D6 charts sharing_rule under regime O, guarded … (ruling B′)" — regime C, ruling A.
  2. "Five dated notes … (+44 / −0)" — seven notes, +73 / −0.
  3. "Notes 1 and 2 carry out ruling B′ on [Decision] Declared sharing rules: what switching off a vendor's rule means once they are read from the registry #24378: the maintainer's 「同意」 then 「B′」, recorded at comment 6257388265. Note 1 records items 1–5, and note 2 is item 1's ledger clause." — note 1 carries A (6258883445, items 1–4), which supersedes B′; note 2 is B′ item 1's reading kept under A with a fifth reader.
  4. Item 1 whole, every sub-bullet: "regime O, guarded"; "replaces the declared rule whole"; "active: false on that row is the switch-off"; "deletes only uncustomised mirrors, so the promise in sharing-plugin.ts … stands"; "under a wall an organization's overlay is its own, and under single the one overlay answers everywhere"; "the guard … unless the write edits the projected row"; "the immediate reconcile … not at the next boot's sweepOrphanedRuleGrants"; "sharing rules get no activation-ledger type, and same-name rows are not refused as a class" — every one is the retired B′ shape; under A same-name rows ARE refused as a class and sharing rules DO get the ledger type.
  5. Item 2 is true but incomplete: no fifth reader named.
  6. No item 4 (the [Decision] Two more framework writers land organization-less rows under a wall before C8 stage 8b: flow credentials (sys_flow_credential) and boot-seeded declared webhooks (sys_webhook) #24435 Q1 line) and no item 5 (the D14 release-scope note).
  7. Verification: "They ran on commit 7b9b0c0… The D7 commit 2261458d re-derived…" names no later head; "49 exit 0. The other 6 are NOT MEASURED" is round 1's count (rounds 2–5: 50/55, five NOT MEASURED).
  8. 维护者速读: "加五段带日期的 Note" → 七段; ① describes regime O (同名整条替换、active: false 即停用、守卫与立即回收) — false under C; "44 行" → 73 行; 为什么改 "裁决 B′(「同意」「B′」)第 1–5 项" — A 第 1–4 项, plus [Decision] Two more framework writers land organization-less rows under a wall before C8 stage 8b: flow credentials (sys_flow_credential) and boot-seeded declared webhooks (sys_webhook) #24435 Q1 and the [epic] ADR-0131 — total organization ownership: no NULL organization_id (v18 line) #15194 scope records; 席位意见 "契约评审 PASS(记录 6258201995 …)" — that record covers 2261458d only, and its "隔离部署下每个组织的共享规则覆盖归它自己(B′ 第 4 项)" remark has no referent under regime C (there is no overlay); 你要做的 "读五段 Note" → 七段, and "8b-0d、8b-0e 合并前要等它先合" is stale as a release line — both stages are 18.x now (D14 note item 3).
  9. Still true: "Why this reading…", "Changeset", "Landing" (Tier H, the maintainer merges), and the four closing lines.

③ Boundary flags

  1. PR plugin-sharing, runtime: sharing_rule under regime C, so every same-name row is refused and declared rules are switched through the activation ledger (ruling A on #24378) #24428 merged at 2026-10-19T05:27:43Z (964a2370, now on origin/main), thirty minutes after this head was pushed — two "not shipped" qualifiers are stale in the code-landed sense. On main today: sys_metadata_activation serves type sharing_rule through the catalog door (catalog-activation.ts :79–:84, :226), a same-name create or rename is refused (sharing-rule-service.ts :189–:258, DeclaredSharingRuleNameConflictError), a declaration over an authored row is reported loudly once per name and scope (reportDeclarationOverAuthoredRow, :1035–:1050), and sharing rules read the ledger (:1062). What is NOT on main is ruling A item 3, the ceremony step — plugin-sharing, runtime: sharing_rule under regime C, so every same-name row is refused and declared rules are switched through the activation ledger (ruling A on #24378) #24428 carries Part of #24421, its body says the ceremony step "is a later stage, which carries the card's closing line", plugin-sharing: refuse a new or renamed sys_sharing_rule row that takes a declared rule's name, and reconcile the shadowed declaration's grants on a same-name write (ruling B′ on #24378) #24421 is still open, and 6259608309 item 1 moves "9c, the sharing-rule copy migration" to 18.x. So the D6 note (:445–:446, "This is a ruled decision that plugin-sharing: refuse a new or renamed sys_sharing_rule row that takes a declared rule's name, and reconcile the shadowed declaration's grants on a same-name write (ruling B′ on #24378) #24421 builds; it has not shipped") is half true — the ceremony half — and the D7 note's fifth-reader clause (:525, "which is ruled and not yet shipped") is false if "shipped" means landed. Why this is a flag and not a FAIL: in this record's own vocabulary "ships" means a release (:496, :759–:763, :817–:836 — "ships in 17.3", "18.0 ships for fresh installs"), and no 18.x release exists (latest release @objectstack/verify@17.7.0, 2026-10-06; zero tags matching 18); read that way both sentences are true until 18.0 is cut, like every staging sentence in D14 and §8. Neither misstates a ruling. Fix, if the seat spends one more round (a head change owes a fresh at-tier record): :445–:446 → "This is a ruled decision; plugin-sharing: refuse a new or renamed sys_sharing_rule row that takes a declared rule's name, and reconcile the shadowed declaration's grants on a same-name write (ruling B′ on #24378) #24421 landed the switch, the refusals and the load-time report in PR plugin-sharing, runtime: sharing_rule under regime C, so every same-name row is refused and declared rules are switched through the activation ledger (ruling A on #24378) #24428 (2026-10-19), and the ceremony step lands with the 18.x upgrade path (D14's release-scope note)." and :525 → "which PR plugin-sharing, runtime: sharing_rule under regime C, so every same-name row is refused and declared rules are switched through the activation ledger (ruling A on #24378) #24428 landed on 2026-10-19 (the D6 note above)". The seat should weigh that against the maintainer's 「你推送给我我会尽快审批」.
  2. The D7 ledger note's header names a superseded ruling (:516, "ruling of record 6257388265 on [Decision] Declared sharing rules: what switching off a vendor's rule means once they are read from the registry #24378, letter B′") — the report's open question; answer: accurate provenance, non-blocking, B recommended if the seat re-pushes for item 1. B′ item 1 is the ruling that ordered the contradiction resolved; A superseded B′'s letter, presupposes the ledger (A item 1), and amendment 6258989827 item 2 kept the note. The reading rests on the record's own sections, not on either letter, and the fifth-reader sentence cites A. Weakness: a reader of this note alone sees a ruling that [Decision] Declared sharing rules: what switching off a vendor's rule means once they are read from the registry #24378 now records as superseded and is not told so here. One-line fix: "ruling of record 6257388265 on [Decision] Declared sharing rules: what switching off a vendor's rule means once they are read from the registry #24378, letter B′, item 1 — kept under ruling 6258883445, letter A, which supersedes B′'s letter".
  3. The D14 note does not carry 6259899486, upgrade-impact comparison, access class (v18): a vendor upgrade that would orphan, re-enable or collide with a customer's access choice is refused until an administrator confirms, and raised at boot #24446's 18.1 target, or the sentence that an 18.0 database takes the 18.x upgrade path — answered, not escalated: none is ordered into the ADR; none contradicts it; one is worth a sentence. (i) 6259899486 item 4 (8b in 18.0 lifts the exemption under single only; the walled half lands in 18.x after 8b-0d′/0e′/0g′; "the 18.x end state is unchanged") amends [Decision] C8 under a wall: four framework writes that have no organization to name — self-registration grant, identity mail, activity, deployment-level secrets #24377's item 5, which the ADR never carried, and post-dates the claim amendment by five minutes; items 1 + 2 of the note imply it for 18.0 (only single boots). (ii) upgrade-impact comparison, access class (v18): a vendor upgrade that would orphan, re-enable or collide with a customer's access choice is refused until an administrator confirms, and raised at boot #24446 → 18.1, GA condition (c), objectui#12982 are card re-targeting; D14 stages this record's decisions, and the dev's omission of the hand-off list is the same judgment, rightly made. (iii) "18.0 databases join v17 databases on the 18.x upgrade path" (6259698357 item 3; 6259608309 item 2) IS this record's — it says a fresh 18.0 install is not final-shape — and the note's item 1 only says it of v17. Fix, one sentence each, in the same push as item 1 if there is one: item 2 → add "In 18.0 it lifts the exemption under single only; the walled half lands in 18.x after 8b-0d, 8b-0e and 8b-0g, and D9's every-posture end state is unchanged (ruling record 6259899486)." — and name 6259899486 in the header; item 3 → add "An 18.0 database takes this same path." Otherwise a later dated line; the record tolerates that.
  4. The report's remaining open questions. "plugin-sharing: refuse a new or renamed sys_sharing_rule row that takes a declared rule's name, and reconcile the shadowed declaration's grants on a same-name write (ruling B′ on #24378) #24421 builds" without a ceremony card number — A, keep (6258883445's Execution line says the seat cuts it; it has no number; 6259608309 names it 9c and defers it). "is to declare" — A, keep (verified on main). D14 in the paragraph form, without the hand-off list — A, keep (form matches :785–:788; the list decides nothing for the ADR). Scope of B′ item 4 and the ledger-by-reading-note questions from rounds 1–2 — moot under A and settled respectively; the first review's one flag (the per-organization overlay carve-out) has no referent under regime C.
  5. Deviations. None new this round: the dev read every ruling and amendment on GitHub before editing, pushed four rework commits on the claimed branch, PATCHed nothing, and wrote the body edits into the report as a dev who writes the body once is told to. The worktree deviation of round 1 was Prime Directive Migrate documentation site to Fumadocs with monorepo structure and shared content #11 holding. premise_still_valid: true holds: the ADR on origin/main is unchanged since 71fa166e.
  6. Landing. Tier H: docs/adr/**. The two existing reviews (APPROVED then CHANGES_REQUESTED 「还需讨论」) are both on 2261458d and the PR is a draft; nothing on this head is an approval. The seat readies nothing: it corrects the body, posts this record, and hands the PR to the maintainer. The post-merge audit will list the maintainer as approver and merger.

Implemented-by: claude/issue-24420-adr-0131-d6-sharing-rule-overlay
Reviewed-by: session_01Y5583bs2RDd53MH6kM1ca3

VERDICT: PASS

Maintainer, before merging (Tier H — your approval on this head, your draft flip, your click): read the seven notes at head :434–:446, :516–:526, :538–:562 and :817–:836; the one fact to weigh is that PR #24428 landed the regime-C switch and refusals on main at 05:27Z, so the D6 note's "it has not shipped" and the D7 note's "not yet shipped" are true only in this record's release sense (no 18.x exists) — accept as dated status lines, or have the seat push the three one-line edits in ③ items 1–3 and review once more.

@objectstack-fleet objectstack-fleet Bot changed the title docs(adr): ADR-0131 D6 charts sharing_rule under regime O, guarded; D7 reads the activation ledger one way (ruling B′) docs(adr): ADR-0131 D6 charts sharing_rule under regime C; D7 ledger reading and lines for #24377 and #24435; D14 records the 18.0 scope Oct 19, 2026
Merged via the queue into main with commit fb9c22a Oct 19, 2026
47 checks passed
@os-zhuang
os-zhuang deleted the claude/issue-24420-adr-0131-d6-sharing-rule-overlay branch October 19, 2026 06:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation size/s skip-changeset PR has no user-facing published change; bypasses the changeset gate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

docs(adr): ADR-0131 D6 charts sharing_rule under regime O, guarded, and reads the activation ledger one way (ruling B′ on #24378)

3 participants