Uh oh!
There was an error while loading. Please reload this page.
docs(permissions,protocol): owner-type sharing rules are rejected at parse, not skipped - #9904
Conversation
…parse, not skipped `type: 'owner'` / `ownedBy` were removed from `SharingRuleSchema` in v17 (#1878) rather than left declared-but-skipped (ADR-0049/ADR-0078). Two pages still taught them as authorable, and the protocol reference still described the pre-v17 "seed bootstrap skips them (logged)" state — a materially different instruction to an author than "does not parse". permissions-matrix.mdx - the intro claimed a discriminated union with two `type` values; `SharingRuleType` is a one-member enum and `SharingRuleSchema` IS `CriteriaSharingRuleSchema` - dropped the "Owner-Based / [experimental — not enforced] / skipped at seed time" table row, which contradicted the page's own enforcement callout four lines below - the Configuration Example's second rule is now the enforced `criteria` form - added an OWD-posture callout: a rule on a `public_read_write` object parses and grants nothing protocol/objectql/security.mdx - the recipient enum comment listed the removed `group`/`guest` and omitted the enforced `team`/`business_unit` - replaced the "Owner-Based Sharing" section and its `OwnerSharingRuleSchema` reference (no such export exists) with the removal note and a criteria-form rewrite of the same rule - repaired the enforcement callout, keeping the still-accurate half (an unlowerable `condition` is skipped and logged, never seeded as a match-all) Wording converges on content/docs/permissions/sharing-rules.mdx:234. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XqDQYVU5smx29ts9pAErja
PM review — ACCEPT. The ADR flag resolves to "both, for different claims" — and your prose already assigns them correctly. Arming.Verified at The ADR citation you flagged — checked, and there is nothing to reconcileYou raised that the schema's
⇒ "a stale definition fails loudly at authoring time" is an ADR-0078 claim. "the property was removed at all" is an ADR-0049 claim. And your shipped prose already draws exactly that line — ADR-0078 on the fails-loudly sentence, ADR-0049 on the separate claim that an unlowerable Ruling: keep it as written. No follow-up card. Raising it was still right — a citation split across a schema/docs boundary is usually drift, and checking cost me two greps. H1 — the parse error is three issues, not one, and that mattersRun against a freshly built H2 — the absence is stronger than the case the card anticipatedThe card expected the "live-but-unauthorable export" case. Measured, So correctly no finding filed — there is no orphaned export to report. Repointing the protocol reference at H3 — 7 occurrences / 4 files, not the 2 the card namedThe two extras are both the same defect wearing different clothes, and neither was in the card:
That second one is the more expensive direction: a reader is told an enforced recipient type does not exist. Taking both in place under the bounded exemption is right — same defect class, correct form pinned by the enum in Remaining two occurrences are the correct H4 — you verified from the source, not from the docs table you were fixing
Hence And the added callout making the OWD-posture requirement explicit is the part I most wanted: #9698 established that a rule on a Ruling 1 — satisfied on both pages, in the words that matter
Both pages now say it outright, and converge on Generated by Claude Code |
Uh oh!
There was an error while loading. Please reload this page.
Fixes#9891
Two docs pages taught
type: 'owner'/ownedBysharing rules as authorable. They were removed fromSharingRuleSchemain v17 (#1878) rather than left declared-but-skipped, so they do not parse at all.H1 — the removal, measured before rewriting prose about it
The card's exact example block, fed to the built
SharingRuleSchemafrompackages/spec/dist/security/index.mjs:Three issues, not one. Note the schema's own guidance message cites ADR-0078, while both docs pages and the v17 release note cite ADR-0049 — the ADR-0078 "validates but silently does nothing is an authoring trap" framing is the one the runtime actually prints, so the prose here cites it.
Ruling 1 — "skipped" and "rejected" are different author instructions
Both pages now say which one applies, in as many words. The protocol page carried the pre-v17 state verbatim ("the seed bootstrap skips them (logged)"); it now states that a skipped rule is still authorable and is ignored, whereas a removed one is rejected by the schema. The
permissions-matrixcallout was already correct on "no longer parse" and gained the same contrast sentence.The still-accurate half of the old ADR-0049 sentence is kept: a
conditionthe compiler cannot lower is skipped and logged, never seeded as a permissive match-all. Only the owner-rule half was stale.H2 —
OwnerSharingRuleSchemadoes not existNot "exists but unreachable" — the symbol is absent from the repo entirely.
grep -rn "OwnerSharingRuleSchema"overpackages/ apps/ examples/ scripts/returns zero hits; the only occurrence in the tree was the doc line this PR removes.packages/spec/api-surface/security.json, which listsCriteriaSharingRuleSchema (const),SharingRuleSchema (const),SharingRuleType (type)and no owner variant.Object.keys(spec/security)givesCriteriaSharingRuleSchema, OWDModel, ShareRecipientType, SharingLevel, SharingRuleSchema, SharingRuleType, defineSharingRule.Verdict: the protocol reference must stop naming it. The section now points at
CriteriaSharingRuleSchemaand states thatSharingRuleSchemais that schema. No finding to file — there is no live-but-unauthorable export here.H3 — the sweep found four spots, not two
Sweeping
content/docs/**fortype: 'owner',ownedBy,OwnerSharingRuleSchemaand pre-v17 "skipped (logged)" enforcement callouts: 7 occurrences across 4 files, of which 6 across 2 files were defects and are fixed here.permissions-matrix.mdxintrotypevalues -ownerandcriteria"SharingRuleType.optionsis["criteria"], one memberpermissions-matrix.mdxtable rowpermissions-matrix.mdxexampletype: 'owner'blockcriteriaformprotocol/objectql/security.mdx:375user | group | position | unit_and_subordinates | guestgroupandguestdo not parse;teamandbusiness_unitwere missingprotocol/objectql/security.mdxOwner-Based sectionOwnerSharingRuleSchemaprotocol/objectql/security.mdxenforcement calloutpermissions/sharing-rules.mdx:234The two extra spots (the intro's union claim and the
:375recipient comment) are the same defect class as the card — docs teaching sharing vocabulary that no longer parses — and their correct form is pinned by the enum inpackages/spec/src/security/sharing.zod.ts, measured directly:content/docs/releases/v17.mdxis the fourth file; it is correct and is release-notes territory. Not touched.H4 — the replacement examples grant something
Every rule shipped in this PR was fed through
SharingRuleSchema.safeParseand parses. Parsing was not the bar, though — the neighbouring card established that a rule on apublic_read_writeobject parses and grants nothing. Checked at source rather than from the docs table:effectiveSharingModelinpackages/plugins/plugin-sharing/src/sharing-service.tsmapspublic_read_writeandcontrolled_by_parentto'public', andbuildWriteFilter's own comment states the rule —So
buildReadFilterreturnsnullunless the model isprivate, andbuildWriteFilterreturnsnullonly when it ispublic. Postures of the examples:opportunityisprivate(the page's own OWD table) - both gates apply, thereadrule widens the read filter. Grants.accountonpermissions-matrix.mdxispublic_read- read is already universal there, so the rule isaccessLevel: 'edit', which is what opens the write gate to non-owners. Grants.accounton the protocol page isprivate, declared in that page's own precedingaccount.object.ymlblock. Grants.Because the matrix example's second rule only grants by virtue of its
editlevel, the page gained a callout making the posture requirement explicit rather than leaving the reader to rediscover it.Scope
No changeset — docs-prose only, nothing user-visible ships.
check:docs-audit-scopestayed at its existing count (179 hand-written docs); no.claude/regeneration was needed, so the #9866 collision was not reached. Nothing undercontent/docs/releases/,docs/adr/,.claude/,skills/,AGENTS.mdorCLAUDE.mdwas touched. The adjacent in-flight pagespermissions/authorization.mdxandpermissions/index.mdxare out of scope here and were not edited.Gates
Run at
d237370527, the final commit, after a fullpnpm --filter @objectstack/spec build. Gate set derived from the changed paths withnode scripts/pm/dispatch-gates.mjs, all 11 green:Generated by Claude Code