Skip to content

spec: security-service contract jsdoc still describes a controlled_by_parent master as always required (optional master, cards #30905/#30906) #31094

Closed

Description

@objectstack-fleet

domain:skills#3 · huangyiirene · session_01J8VVAj7CvjkGXvgXzd6RZ7

Filing gate: carry-over item 2 on #30907 (comment 6702057019, from card 2's seat): the packages/spec jsdoc is spec-lane work and is not edited from the skills lane. Wording measured by the #30907 card thread (PR #31092 body) and confirmed by that PR's contract review (6703355433). ⛔ Not a claim. Triage sets the grade and the lane.
class: c · reach: every reader of the SecurityService contract's refusal reasons and write check.

What is owed

packages/spec/src/contracts/security-service.ts on main 719a502b. Since #30905 / #30906 (maintainer ruling 「A」, PR #31082) a controlled_by_parent object may have one OPTIONAL master; a row naming none is read by its owner or View All, and written by its owner or Modify All on the detail.

  1. L342–348, master_chain. Says the leg refuses when a master above is itself controlled_by_parent and has an empty master reference. Owed: the leg also refuses the record itself when its optional master reference is empty and the principal neither owns it (owner_id) nor holds Modify All on its object; a master above whose optional master is empty ends the chain under that row's owner rule. Only a required master's empty reference above the record is the chain-walk refusal the current text describes.
  2. L377–378, master_reference_missing. Says "the record's stored master reference is empty (422 MISSING_REQUIRED_FIELD)". Owed: "the record's stored required master reference is empty"; an empty optional master reference is not this reason (the check answers allow, or deny on leg master_chain).
  3. L1064–1065, checkControlledByParentWrite. Says "A by-id write to a controlled_by_parent record requires EDIT access to its master." Owed: "…, or, where its optional master reference is empty, ownership of the record or Modify All on its object (ADR-0055 §3 as amended 2026-11-07)".

Re-read the write gate (packages/plugins/plugin-security/src/security-plugin-cbp-write-gate.ts) before rewording; jsdoc only, no behaviour change.

Level: packages/spec jsdoc: an '@objectstack/spec': patch changeset (docs-only), Clause-②: no, Metadata-protocol: none (triage to confirm).

Related: #30907, PR #31092, #30906, PR #31082, #30905.

Activity

  1. added
    findingRecorded observation — held, not dispatchable until the findings triage round grades it
    area:accessPermissions that actually hold — RLS/FLS, sharing model, write-path guards
    documentationImprovements or additions to documentation
    domain:specDomain lane — seat card indexed by label:pm:seat
    pm:queueReady for the PM dispatch loop
    and removed
    findingRecorded observation — held, not dispatchable until the findings triage round grades it
    on Nov 7, 2026
  2. objectstack-fleet commented on Nov 7, 2026

    @objectstack-fleet
    ContributorAuthor

    triage#1 · os-zhuang · session_01AavokzJ5DndAwitDXvKy4U

    Path: none

    Triage: audit · p2 · domain:spec · 2026-11-07T06:54Z

    ⛔ Not a claim.


    Generated by Claude Code

  3. objectstack-fleet commented on Nov 7, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:spec#4 · marchtian · session_017ihL2eHDXrsKgGAUHq956U

    Claim: PM loop round 1 · 2026-11-07T13:07Z
    Session: session_017ihL2etQ7BmrJuMddPx75W (card thread; dispatched by seat session session_017ihL2eHDXrsKgGAUHq956U)
    Account: marchtian
    Branch: claude/project-thread-67i8vs
    Worktree: the card thread's own container checkout
    Domain: domain:spec
    Seat: domain:spec#4
    File surface: packages/spec/src/contracts/security-service.ts (jsdoc only) + one .changeset/*.md
    Container & model: XS docs card, mode:thread, model: default tier (dispatch-gates --tier: no path-derived mandate; floor sonnet · default opus · ceiling fable), reason: jsdoc-only, no behaviour change; full Fable review of the diff before ACCEPT per the maintainer's standing spec rule, effort: medium
    Clause-②: no
    Metadata-protocol: none
    Responsibility: n/a — not a defect card (contract prose lagging PR #31082)
    Thread-read: 6703612303
    Premise: holds
    Serial constraints cleared: none (sibling #31099 is file-disjoint)

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

    @objectstack-fleet
    ContributorAuthor

    domain:spec#4 · marchtian · session_017ihL2etQ7BmrJuMddPx75W

    os-dev-report

    {
     "issue": 31094,
     "status": "done",
     "branch": "claude/project-thread-67i8vs",
     "pr": "https://github.com/objectstack-ai/objectstack/pull/31126",
     "head": "6e4fd170a",
     "session": "session_017ihL2etQ7BmrJuMddPx75W",
     "premise_still_valid": true,
     "summary": "JSDoc-only change in packages/spec/src/contracts/security-service.ts plus a spec patch changeset. Card items 1-3 applied as owed, each checked against security-plugin-cbp-write-gate.ts and controlled-by-parent-optional-master.test.ts: the code agrees with the card's owed text. Same-file sentences the ruling also made false were corrected in place (see deviations). The ⛔ lines at the end of the member docblock are untouched.",
     "tests": "No behaviour change, no test added. Behaviour described is pinned by plugin-security controlled-by-parent-optional-master.test.ts (checkControlledByParentWrite describe blocks, required-master master_reference_missing control).",
     "gates": "Local, on head 6e4fd170a after a packages/** build (verify lock VERDICT command-exit 0): all 74 commands from dispatch-gates --commands :: exit 0. --ran reconciliation: 74 derived, 74 run, 0 NOT-MEASURED, 0 UNRUN (exit 0). check:docs: 242 generated files in sync. eslint --no-inline-config on the touched file :: exit 0 (spec has no lint script). First pass (before the build) had 4 exit-3 prerequisite misses, cleared by fetching the teardown-shape fixture commit and building. CI on 6e4fd170a: 64 check-runs, 0 not success/skipped, including Lint & Repo Gates, TypeScript Type Check, Test Core, Build Core, Governed Surface Queue Guard, Lint UI (skipped), Type Check UI, Test UI, Build & E2E UI, Live E2E UI, Check Changeset.",
     "line_budget": "+52 / -16 in security-service.ts, changeset +15; under the 3000-line threshold",
     "dogfood_battery": "n/a — no ! in the PR title and no (narrowing) arm",
     "deviations": [
      "Bounded in-place fix (same defect class, same file, no other claim, same gate family): beyond items 1-3, also corrected ControlledByParentWriteDenialLeg's intro sentence, ControlledByParentWriteOutcome's allow bullet, the member's 'answers the master check alone' sentence and its empty-permission-set bullet (a principal with no sets answers on master_chain, not object_permission, for a record whose optional master is empty). Named in the PR body.",
      "First commit was made with core.hooksPath overridden by mistake; the repo's pre-commit (regen-pending) and pre-push (commit-card-trailers) were then run by hand on it, both exit 0; later commits ran the hooks normally."
     ],
     "files_changed": [
      "packages/spec/src/contracts/security-service.ts",
      ".changeset/31094-security-service-optional-master-jsdoc.md"
     ],
     "open_questions": [],
     "out_of_scope_findings": [
      "class: b · reach: contract text read by every consumer of ISecurityService.checkControlledByParentWrite · evidence: ControlledByParentWriteOutcome's allow bullet says every leg passes on every master, but the write gate's ownerMayEdit opt-in leg (ADR-0055 §3 amendment 2026-10-26; security-plugin-cbp-write-gate.ts, the by-id update owner branch) resolves allow for the row's owner with only READ on the master; the spec file never mentions the opt-in. Pre-existing, found by the Fable review. Seam: spec:ControlledByParentWriteOutcome.allow → runtime:assertControlledByParentWrite ownerMayEdit branch · dedupe words: ownerMayEdit, checkControlledByParentWrite, allow, jsdoc, security-service"
     ],
     "mcp_calls": "0",
     "api_writes": "3 — pr_create (relay fw-20261107T132650Z-007ccf, PR #31126, assignee marchtian); comment on PR #31126 (Fable verdict 6707550458, post-stamped); this report comment (post-stamped)",
     "security_findings": "none",
     "fable_review": "PR comment 6707550458: R1 on 45406927 PASS (1 should-fix + 2 nits applied, 1 nit out of scope); delta on e6e69d53 PASS (1 nit, rewrap, applied in 6e4fd170a). Verdict on 6e4fd170a: PASS."
    }
  6. objectstack-fleet commented on Nov 7, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:spec#4 · marchtian · session_017ihL2eHDXrsKgGAUHq956U

    Landed · domain:spec#4 · 2026-11-07T16:36Z

    reading value
    PR #31126 merged 2026-11-07T16:36:05Z through the queue, merge commit a5cb4f1bf03293ebbe8033ba4d813bf940575d53, reviewed head 6e4fd170a (contract review PASS + ACCEPT on that head)
    card closed completed by Fixes

    State: pm:dispatched removed. Should-fix follow-up filed: #31180 (ownerMayEdit opt-in missing from the contract).

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 guardsdocumentationImprovements or additions to documentationdomain:specDomain lane — seat card indexed by label:pm:seatpriority:p2Medium: important, M3

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions