Skip to content

docs(sharing): record the external-recipient arm on ADR-0111 D7 and the grant contract - #25603

Merged
os-zhuang merged 2 commits into
mainfrom
claude/project-thread-eflr1z
Oct 24, 2026
Merged

os-zhuang merged 2 commits into
mainfrom
claude/project-thread-eflr1z

Conversation

@objectstack-fleet

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

Copy link
Copy Markdown
Contributor

Requested by Tesla · project thread

Part of #25549

Clause-②: no
Metadata-protocol: none

The Tier H follow-up to #25591, which landed letter A of the ruling on #25549 (record 6377844010): on a public object, a share or sharing rule is admitted for a recipient who is an external member of the record's organization. This PR records that decision where the governing texts live, and carries the two wording nits from the seat's contract review of #25591.

维护者速读(草稿)

改了什么: 只改文字,不改行为。ADR-0111 D7 第 2 条加一行带日期的修订,写明「全员可读写」对象上的分享可以给该组织的外部成员(供应商门户用户),其他人照旧拒绝;ISharingService.grant 的接口说明同步改正;共享规则跳过收件人时的那句提示,补上「记录所属组织解析不出来」这种情况;一处测试注释里写错的文件名改正。

为什么改: #25591 已按裁决 A 落地,但 ADR 和接口说明仍写着「公开对象上的分享永远无效」,以后读文档的人(包括 AI)会被误导。ADR 属于受管文件,需要单独的 PR 由你批准。

风险与代价(含回滚): 无运行时风险,提示文字改了一句(没有程序解析这句话)。回滚即还原这一个提交。

席位意见:

你要做的: 看一眼 ADR 修订那一段的措辞,同意即批准合并。

What changes

  • ADR-0111 D7 item 2 (docs/adr/0111-record-share-management-authority-and-verb-boundary.md): one dated amendment paragraph under the item, the text drafted in the os-dev-report of feat(sharing): a share or sharing rule on a public object reaches an external member of the record's organization #25591 (comment 6378915159 on sharing: a share or sharing rule to an external member is refused as inert on a public_read_write or model-less system object, though the external OWD floor would consult it #25549).
  • ISharingService.grant docblock (packages/spec/src/contracts/sharing-service.ts): "a share on a public / bypass / owner-less / controlled_by_parent object enforces nothing" becomes "a bypass / owner-less / controlled_by_parent object enforces nothing; on a public object it is admitted only for a recipient who is an external member of the record's organization". Comment only.
  • Review nit 1, the pass note (plugin-sharing sharing-rule-service.ts internalHalfNote): the per-recipient refusal a pass skips is also raised when a record's organization cannot be resolved, which admits no recipient. The note now says so: "rows were written only for external members of each record's organization; none for the other recipients this rule expands to (internal members already reach its records, and a record whose organization could not be resolved admits no recipient)". The note field's docblock says the same. Two test assertions follow the text.
  • Review nit 2 (system-caller-inert-grant.test.ts, the RULE_ABORTING_OBJECTS comment): it named external-recipient-public-object.test.ts, which does not exist; it now points at block 3 of the same file.
  • Changeset .changeset/25549-external-share-followup-wording.md: @objectstack/plugin-sharing and @objectstack/spec patch.

Verification (head 3aae2160; re-reconciled at 297cfe51 after the sharing-service.mdx drift fix: 123 derived, 123 run, 0 NOT-MEASURED)

  • pnpm --filter @objectstack/plugin-sharing typecheck exit 0; the suite under os-verify-lock: 55/55 files, 1233 tests passed.
  • node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack at 3aae2160 derived 100 families, each run with its exit code captured before any pipe. First sweep: 98 exit 0, 2 exit 3 (PREREQUISITE NOT MET: workspace dists for check:dual-build-cjs-loads and check:i18n); after check:type-check-debt's locked workspace build, both re-ran exit 0. --ran reconciliation: 100 derived, 100 run, 0 NOT-MEASURED, 0 UNRUN.

🤖 Generated with Claude Code

https://claude.ai/code/session_01AjwMndyviznGagEUcX7QVx

…he grant contract

ADR-0111 D7 item 2 gains the dated amendment for the external-recipient
arm. ISharingService.grant's docblock stops saying a share on a public
object enforces nothing. The rule pass note also covers a record whose
organization could not be resolved, and a test comment no longer names
a file that does not exist.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AjwMndyviznGagEUcX7QVx
@github-actions github-actions Bot added size/s documentation Improvements or additions to documentation tests tooling labels Oct 24, 2026
@github-actions

github-actions Bot commented Oct 24, 2026 •

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 2 package(s): @objectstack/plugin-sharing, @objectstack/spec, touching 3 documentable anchor(s).

3 hand-written doc(s) NAME something this change touched and may need an implementation-accuracy re-verification:

  • content/docs/kernel/contracts/index.mdx (via ISharingService (symbol, a top-level interface))
  • content/docs/kernel/runtime-services/sharing-service.mdx (via ISharingService (symbol, a top-level interface))
  • content/docs/permissions/attachments-access.mdx (via ISharingService (symbol, a top-level interface))
What this run could not see
  • the SDK route bridge reached 54 of 206 client-bound route-ledger rows — the other 152 have no registrar path: tail to select them, so pages documenting THEIR client methods cannot appear above, on this or any run. Of those 152: 0 are remediable by widening that discovery convention (an in-repo file declares the path; the convention did not scan it); 55 are structural — on a ledger where NOT ONE row is declared in-repo, so no discovery change reaches them at any price; 97 are undecided (no in-repo declaration, on a ledger that has other in-repo registrars — absence and an unreadable spelling are not distinguishable here). The rows themselves: node scripts/docs-audit/affected-docs.mjs --bridge-coverage
  • a page that states a rule by its inputs shares no identifier with the emitter that implements the rule, so an emitter-only diff cannot list it — not on this run and not on any run. Measured on fix(driver-sql): emit varchar(maxLength) for a text field a declared index keys on #11430: content/docs/protocol/objectql/types.mdx documents the text-family column mapping by the ObjectQL type names it maps FROM (text / textarea / html) while the diff changed createColumn; it went unlisted, and it was the page that diff falsified, in four places. No shared token exists to detect this on, so a rule your change carries has to be re-read by hand in the pages that restate it.
  • a key NAME is not a key, so the hand re-read the line above prescribes can land on the wrong schema. The same spelling is authorable on one governed type and a [REMOVED] tombstone on another for each of active, aria, joins, objects, template, tools and version (censused on [finding] tools is a key on BOTH AgentSchema (tombstoned, dead) and SkillSchema (live, cloud-attested), so a name-based search attributes skill examples to the agent key — it produced a false stop-the-line alarm on PR #19059 #19093 over the liveness ledger's governed types, top-level keys); nothing in a search result distinguishes the two, so a grep hit on a LIVE example reads as evidence about the DEAD key. Measured on fix(spec): the agent.tools liveness row says dead — it claimed live on a key the schema tombstoned #19059: content/docs/ai/agents.mdx was reported as contradicting the agent.tools tombstone over its tools: example at :161, which is inside the defineSkill({ block opened at :155 — the page was already correct. Settle ownership by PARSING the value against both schemas, never by the name: that literal PASSES SkillSchema, and as an AgentSchema it FAILS at tools with the tombstone prescription. ⛔ These names are not the whole class — a key retired through a .strict() guidance map leaves no tombstone in the walked shape and none of them here (tool.category, live as AIToolDefinition.category).

Coarse fallback — 144 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): node scripts/docs-audit/affected-docs.mjs --json 9f390945ebbf34696f71806d0247df47cfeaef1c → packageMentionDocs.

Which tree this was computed on

This run read content/docs from 5aae37838e4f4665b599e02c00d620f8ea20804c — the merge of head 297cfe51f80f51d7b0eaeb972c324326a08cbe38 into base 9f390945ebbf34696f71806d0247df47cfeaef1c, which is what actions/checkout gives a pull_request run. Not the PR head.

A worktree cut from an older main holds a different content/docs, so re-deriving there can legitimately return a different list — that is a different tree, not a wrong row. To answer on the same tree:

# while this PR is open — GitHub drops the merge commit once it closes
git fetch origin 5aae37838e4f4665b599e02c00d620f8ea20804c && git checkout 5aae37838e4f4665b599e02c00d620f8ea20804c
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 9f390945ebbf34696f71806d0247df47cfeaef1c 297cfe51f80f51d7b0eaeb972c324326a08cbe38 && git checkout -B drift-repro 9f390945ebbf34696f71806d0247df47cfeaef1c && git merge --no-ff 297cfe51f80f51d7b0eaeb972c324326a08cbe38

node scripts/docs-audit/affected-docs.mjs --json 9f390945ebbf34696f71806d0247df47cfeaef1c

⚠️ That checkout carried uncommitted changes, so the commit above does not fully identify what was read.

Advisory only, and a precision-first one (#9192): a page is listed because it names a
symbol, wire route or SDK method this diff touched — not because it mentions a changed
package. Each row says which anchor put it there, so a wrong row is reportable rather than
merely annoying. To re-verify, run the docs-accuracy-audit workflow scoped to these files:
node scripts/docs-audit/affected-docs.mjs 9f390945ebbf34696f71806d0247df47cfeaef1c → pass the list as
args.docs, on the commit named under Which tree this was computed on.

…arm of SHARING_NOT_ENABLED

The docs-drift check named this page: its SHARING_NOT_ENABLED entry still
listed a public sharing model as refused for every recipient.

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

Copy link
Copy Markdown
Contributor Author

维护者速读

  • 改了什么: feat(sharing): a share or sharing rule on a public object reaches an external member of the record's organization #25591 已合并(外部成员可在"全员可读写"对象上被单独分享记录),这个 PR 把文字补齐:ADR-0111 D7 第 2 条加一段带日期的修订;ISharingService.grant 的接口注释不再说"公开对象上的分享不起作用";sharing-service.mdx 里 SHARING_NOT_ENABLED 一条写明外部成员例外;另外修了两处措辞(规则说明文字、一处测试注释里的旧文件名)。6 个文件,+29 / −12。
  • 为什么改: ADR 和接口注释还写着旧规则,和已上线的代码相反。照着写代码的人会以为公开对象一律不能分享。
  • 风险与代价(含回滚): 不改行为:一行运行时说明文字,其余是文档和注释。两个包各一个 patch changeset,Clause-②: no。回滚就是 revert 这一个提交。
  • 席位意见: 建议合并。修订段已对照 feat(sharing): a share or sharing rule on a public object reaches an external member of the record's organization #25591 核过:只对有真实负责人的公开对象生效,接收人须恰好是该组织的外部成员,判定不看授权人,controlled_by_parent 仍一律拒绝。CI 全绿(42 项:36 成功,6 跳过)。
  • 你要做的: ADR 是治理路径,需要人合并。os-zhuang 批准的是推送前的旧头 3aae2160,新头 297cfe51 只多了 mdx 那一行,请在新头上重新 Approve。现在处于发版暂停,PR 保持草稿,Tesla 解除暂停后席位入队。

席位核对 · ACCEPT(待人批) · domain:spec seat 1 (seat post #6017) · os-tesla · session session_013odhA26dvzy7pQmevdTTvy · 2026-10-24T05:24Z

Head 297cfe51f8 · Part of card #25549 (closed by #25591) · ruling 6377844010 / re-ruling 6378238137 (letter A) · contract review on #25591 6378972131, whose routed follow-ups this PR carries.

  • Shape: draft, base main, 6 files, +29 / −12. check-governed-merges: 1 governed path (the ADR), so landing tier H.
  • Content checked against the merged code: the ADR-0111 D7 amendment matches feat(sharing): a share or sharing rule on a public object reaches an external member of the record's organization #25591's inertGrantReason arm and the materialiser note. The spec docblock is comment-only (no schema or accept-set change). The two review nits are fixed. The PR-body Verification heading was patched by the seat to the re-reconciled head (123 derived, 123 run, 0 NOT-MEASURED).
  • Gates pinned to the head: 42 check-runs on 297cfe51f8, 36 success + 6 skipped, 0 red. Mergeable state clean.
  • Landing: held as draft under Tesla's release-prep merge pause (from 03:57Z). needs-user-decision on the PR. Once the pause is lifted and an authorized APPROVED is on this head, the seat runs pr_ready + automerge_enable.

Generated by Claude Code

@os-zhuang
os-zhuang marked this pull request as ready for review October 24, 2026 16:16
@os-zhuang
os-zhuang enabled auto-merge October 24, 2026 16:16
@os-zhuang
os-zhuang added this pull request to the merge queue Oct 24, 2026
Merged via the queue into main with commit 8654435 Oct 24, 2026
55 checks passed
@os-zhuang
os-zhuang deleted the claude/project-thread-eflr1z branch October 24, 2026 16:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants