Skip to content

controlled_by_parent admits an optional master (3/3): docs and the authoring skills teach it instead of a copied owner field #30907

Closed

Description

@objectstack-fleet

epic:#3600#1 · hotlong · session_01Q4EjjPXwX1YfHyKJUh4agu

Filing-gate category: ② maintainer-directed task. Maintainer ruling, verbatim (Claude Code session, 2026-11-06): 「A」. The ruling: controlled_by_parent admits an optional master, and a detail row with no master is visible only to its owner (Salesforce parity: a contact without an account is a private contact). Rejected: B, a membership key collecting its object's own id; C, one-hop RLS traversal; D, no platform change. Routing, verbatim: 「能交给车队开发的你不要自己开发」. The plan was re-read by an isolated contract-review-tier reviewer before filing (PASS WITH FIXES, fixes folded in). It lands in three serial cards (this one and its two siblings), each safe on its own.

Why (measured 2026-11-06, the first live scenario run, objectstack-ai/cloud#3600)

The rule "a rep sees the contacts of accounts they own; a contact need not have an account" has no declarative form in spec 18.3.0:

  • RLS account.owner == current_user.id is refused: rls-predicate-unenforceable (packages/lint/src/validate-rls-predicate-enforceability.ts:316).
  • A membership key with valueField: 'id' is refused: membership-key-value-field-invalid (validate-membership-key-declarations.ts:80).
  • controlled_by_parent with required: false on the master is refused at two doors: ObjectSchema.create() (packages/spec/src/data/object.zod.ts:4406-4417) and the parse refinement, shape master-not-required (object.zod.ts:2743-2752, controlled-by-parent-master.ts:178-185).

The only working route today is a copied owner field plus two hooks. The AI-built app took that route, and its hook failed verify.

Card 3 of 3: docs and the published authoring skills.

Blocked-by: #30906

Ask

  1. Skills (skills/**, a governed surface: land it through the governed path). Teach the optional master for "visible by the parent's owner, parent optional" instead of a copied owner field plus hooks: skills/objectstack-data/rules/relationships.md, rules/security.md, references/lint-rules.md, SKILL.md, and the evals/*.json that pin the old rule. Add one line that a membership key cannot collect its object's own id (membership-key-value-field-invalid).
  2. Docs that restate ADR-0055 §1: content/docs/permissions/authorization.mdx:539-545, rls.mdx, sharing-rules.mdx, permissions-matrix.mdx, index.mdx. ⛔ Release-owned pages are not touched (AGENTS.md documentation guardrails).
  3. Confirm the scenario scorer's row-scope check (packages/qa/scenarios/src/score/scenario-tags.ts:343) still accepts an optional-master cbp detail. It already accepts any cbp object, so no change is expected.

Known follow-up outside these repos: objectui Studio's Required toggle writes true or nothing, so an optional master cannot be authored from Studio yet. The epic seat raises it with the maintainer.

Reader: the domain:skills lane seat, from pm:queue once card 2 closes.

Activity

  1. added
    priority:p1High: required for production / M2
    pm:blockedBlocked by another issue/PR — body carries Blocked-by: #N
    domain:skillsDomain lane — seat card indexed by label:pm:seat
    area:accessPermissions that actually hold — RLS/FLS, sharing model, write-path guards
    on Nov 6, 2026
  2. objectstack-fleet commented on Nov 6, 2026

    @objectstack-fleet
    ContributorAuthor

    triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U

    Path: none

    Triage: audit · p1 kept · domain:skills · pm:blocked · 2026-11-06T10:57Z

    ⛔ Not a claim.

    • controlled_by_parent admits an optional master (3/3): the docs and the authoring skill. It needs an '@objectstack/skills': patch changeset. Blocked-by holds.

    Generated by Claude Code

  3. objectstack-fleet commented on Nov 7, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#1 · sunhaolin · session_017xRBcTJTE7kSbcMoJQ4Txf

    Carry-over from card 2 (#30906, PR #31082) for whoever claims this card. Read at 2026-11-07T04:08Z.

    PR #31082 changes the write side, ADR-0055 §3. Three prose debts it leaves outside its surface now ride this card, because it already carries the Tier H docs surface and the same ruling (「A」):

    1. ADR-0055 §3 amendment. The 2026-11-06 amendment still says §3 is unchanged and "is amended again for §3 then". §3 now holds the null-master owner rule: the owner or Modify All on the detail writes a row that names no master; an insert naming none is admitted; emptying a master asks edit on the stored master and ownerMayEdit does not cover it; a chain hop with no master of its own ends the chain under the same rule. Source: the PR feat(security, verify): a controlled_by_parent row with no master is written by its owner or by Modify All on the detail #31082 body and changeset.
    2. Spec contract jsdoc (packages/spec/src/contracts/security-service.ts). master_reference_missing ("the record's stored master reference is empty (422)") and master_chain do not mention the optional master. That path's empty reference now answers allow or deny (leg master_chain), not unresolvable. This is a packages/spec file, so it is spec-lane work. The claimant routes it (a spec-seat sub-issue, or a spec-seat claim on this card), and ⛔ does not edit it from the skills lane.
    3. The docs and the authoring skills teach the write rule above. That is this card's own ask.

    Card 2 does not wait on any of these.

  4. objectstack-fleet commented on Nov 7, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:skills#3 · huangyiirene · session_01J8VVAj7CvjkGXvgXzd6RZ7

    Unlock: Blocked-by: #30906 is met. #30906 closed completed at 2026-11-07T04:52Z, and its PR #31082 merged at 2026-11-07T04:52Z. pm:blocked → pm:queue. The carry-over in 6702057019 (ADR-0055 §3 amendment; spec jsdoc routed to the spec lane; docs and skills teach the write rule) rides this card.

  5. added
    pm:queueReady for the PM dispatch loop
    and removed
    pm:blockedBlocked by another issue/PR — body carries Blocked-by: #N
    on Nov 7, 2026
  6. objectstack-fleet commented on Nov 7, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:skills#3 · huangyiirene · session_01J8VVAj7CvjkGXvgXzd6RZ7

    Claim: PM loop round 12 · 2026-11-07T05:51Z
    Session: session_01J8VVAj7CvjkGXvgXzd6RZ7
    Account: huangyiirene
    Branch: claude/project-thread-6r15z0 (the card thread's designated branch; dev session session_01J8VVAo8GHSrxa8ZR8h3qxs)
    Worktree: objectstack-issue-30907
    Domain: domain:skills
    Seat: domain:skills#3
    File surface: skills/objectstack-data/rules/relationships.md, skills/objectstack-data/rules/security.md, skills/objectstack-data/references/lint-rules.md, skills/objectstack-data/SKILL.md, skills/objectstack-data/evals/*.json (only cases pinning the old rule), .changeset/*.md; content/docs/permissions/authorization.mdx, rls.mdx, sharing-rules.mdx, permissions-matrix.mdx, index.mdx; docs/adr/0055-master-detail-controlled-by-parent.md (a dated §3 amendment plus the in-place mark on the 2026-11-06 header line); scripts/check-skills-token-ratchet.mjs (one file's row, only by the standing ruling 6513306068 for a measured remainder after real same-file deletion). Read-only: packages/qa/scenarios/src/score/scenario-tags.ts. ⛔ Not packages/spec/src/contracts/security-service.ts (spec lane; the seat files that card) (stop on breach)
    Container & model: M, mode:thread, project-default model, effort: high. dispatch-gates --tier mandates the contract-review tier for skills/** / docs/adr/** (clause ①); waived by the maintainer's standing order in this project (2026-11-03) and said so in the PR body; this seat runs the contract review.
    Clause-②: no
    Metadata-protocol: none
    Responsibility: n/a — not a defect card
    Thread-read: 6702057019
    Premise: holds on main 719a502b: cards 1/3 (#30905) and 2/3 (#30906, PR #31082) are merged, so the platform admits an optional master and judges null-master reads and writes; the data skill and the permission docs still teach a required master or the copied-owner-field route, and ADR-0055's 2026-11-06 header still says §3 is unchanged.
    Serial constraints: none (cards 1–2 merged). The spec jsdoc debt (carry-over item 2) is routed to the spec lane by the seat.

    Changeset '@objectstack/skills': patch. Fixes #30907. Tier read by check-governed-merges at the PR (skills/**, docs/adr/**: Tier H).

  7. added
    pm:dispatchedDispatched to a dev agent by /pm-dispatch
    and removed
    pm:queueReady for the PM dispatch loop
    on Nov 7, 2026
  8. objectstack-fleet commented on Nov 7, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:skills#3 · huangyiirene · session_01J8VVAj7CvjkGXvgXzd6RZ7

    ACCEPT → PR #31092 comment 6703747961, head a60b01a6. Tier H: pm:awaiting-merge, approval requested from os-zhuang and hotlong. Follow-ups: #31094 (spec jsdoc), #31095 (other docs pages).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

area:accessPermissions that actually hold — RLS/FLS, sharing model, write-path guardsdomain:skillsDomain lane — seat card indexed by label:pm:seatpm:dispatchedDispatched to a dev agent by /pm-dispatchpriority:p1High: required for production / M2

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions