Skip to content

Commit 91e9eda

Browse files
committed
docs(spec,plugin-sharing): the master_chain refusals can name the record's own master; canEdit no longer lists the attachment and comment parent gates
The ControlledByParentWriteDenialLeg docblock said the master_chain arm's three resolution refusals name a master above the record's own master. The walk resolves the record's own master first, so when that master is itself controlled_by_parent the refusals can name it too. The two canEdit docblocks (ISharingService and SharingService) listed the sys_attachment and sys_comment parent gates among canEdit's callers; those gates read checkEdit and the master-detail write check now. Docblock sentences only: no type change, no code change. Claude-Session: https://claude.ai/code/session_01KNKBCRDJCu5tGy3TEbvtrF Co-authored-by: Claude <noreply@anthropic.com>
1 parent ee8751d commit 91e9eda

3 files changed

Lines changed: 14 additions & 13 deletions

File tree

‎packages/plugins/plugin-sharing/src/sharing-service.ts‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -816,10 +816,10 @@ export class SharingService implements ISharingService {
816816
* verdict that is not `deny`. The truth table is byte-for-byte the historical
817817
* one — `abstain` is where the old `true` for public / owner-less / bypassed
818818
* objects went — so every existing caller (the sharing middleware, the
819-
* `sys_attachment` parent gate, the ADR-0055 master check) keeps its exact
820-
* semantics. A caller that would let this answer OVERRIDE another authority
821-
* must read {@link checkEdit} instead, because only there is "I permit this"
822-
* distinguishable from "I do not enforce here".
819+
* ADR-0055 master check) keeps its exact semantics. A caller that would let
820+
* this answer OVERRIDE another authority must read {@link checkEdit} instead,
821+
* because only there is "I permit this" distinguishable from "I do not
822+
* enforce here".
823823
*/
824824
async canEdit(
825825
object: string,

‎packages/spec/src/contracts/security-service.ts‎

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -312,9 +312,10 @@ export interface OwnershipFloorAlternate {
312312
* ({@link ISecurityService.checkAuthoredRowWrite}).
313313
* - `master_chain`: the chain itself cannot be walked to a master that governs
314314
* its own rows. It re-enters an object it has already visited, it exceeds
315-
* the depth bound, or a master ABOVE the record's own master has no relation
316-
* to derive from, is not present, or has an empty master reference. Above the
317-
* first hop the check answers these as refusals, not as defects of the
315+
* the depth bound, or a master that is itself `controlled_by_parent` (the
316+
* record's own master, or any master above it) has no relation to derive its
317+
* own master from, is not present, or has an empty master reference. Past the
318+
* record itself the check answers these as refusals, not as defects of the
318319
* request, so they are a leg here and never `unresolvable`.
319320
*
320321
* The first three legs run on every hop, so `object_permission` can name the

‎packages/spec/src/contracts/sharing-service.ts‎

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -291,18 +291,18 @@ export interface ISharingService {
291291
* [#7144] The write DEPTH in that first sentence is an INPUT this service is
292292
* handed, never one it resolves — so a caller outside the CRUD middleware
293293
* (the `sys_comment` and `sys_attachment` PARENT-record gates, which both
294-
* reach this service through this method) matches ownership at `own`. That is
295-
* the ruled shape, and the fail-open that blocks widening it is written up
296-
* once in "Write DEPTH is an input the CALLER supplies" on this interface.
294+
* reach this service through {@link checkEdit}) matches ownership at `own`.
295+
* That is the ruled shape, and the fail-open that blocks widening it is
296+
* written up once in "Write DEPTH is an input the CALLER supplies" on this
297+
* interface.
297298
*
298299
* [#6428] The two-state PROJECTION of {@link checkEdit}: `true` for every
299300
* verdict that is not `deny`, i.e. `allow` and `abstain` alike. That
300301
* collapse is the historical semantics, kept byte-for-byte so existing
301302
* callers do not drift — it is correct for a caller that only ADDS this gate
302303
* to whatever else already guards the row (the sharing middleware, the
303-
* `sys_attachment` parent gate, the ADR-0055 master check), and WRONG for a
304-
* caller that would let this answer override another authority's floor. The
305-
* latter must read {@link checkEdit}.
304+
* ADR-0055 master check), and WRONG for a caller that would let this answer
305+
* override another authority's floor. The latter must read {@link checkEdit}.
306306
*/
307307
canEdit(
308308
object: string,

0 commit comments

Comments
 (0)