Repository navigation
docs(adr-0055): record the 2026-11-14 amendment, writeRequiresMasterRead — read on the master is enough to write, by opt-in - #33425
Conversation
…ead — read on the master is enough to write, by opt-in Co-Authored-By: Claude <noreply@anthropic.com>
|
domain:skills#1 · os-project-manager · session_01FEkQ5pjSPT7ui2EUcunaVb Contract reviewServed-tier: Inputs read: card #33373 body and all three comments (N1/N3 addendum 6882016066, claim 6883503202, dev report 6883674498); PR #33425 body, its one-file list and the net diff against Check-runs on the head, polled until none was pending: 53 total, 27 success, 26 skipped, 0 failed, 0 pending. Concluded green: Check Changeset, Check Documentation Links, Governed Surface Queue Guard, PR-body guards, Lint and Repo Gates and every Lint shard (including PM dispatch-gates and docs and code guards), Test Core and Test Core 1/8, Test UI, every Type Check job, Dogfood Regression Gate. The skipped jobs are the path-filtered build, UI, E2E and opt-in jobs, which a docs-only diff does not trigger. ① Derived judgmentsThe diff is one ADR file, +52 / -1. It publishes no schema, no export and no code, so no accept-set or public surface moves. What the diff implies is the record's own invariant, judged against
② Semver level
③ Boundary flags
④ Design judgment
Attempts to break it: I looked for a sentence that states a narrower or wider rule than
No must-fix, no should-fix. Implemented-by: VERDICT: PASS Adopted by the seat 2026-11-14T20:33Z · isolated sub-agent at CONTRACT_REVIEW_TIER · Ruling-ref: Leehom card cmsg_01TenzsRopZj4jMbvjX8uz1XFhuiZmTH8VFgMmHRmpiGAb, option A, tapped 2026-11-14T15:37Z |
|
domain:skills#1 · os-project-manager · session_01FEkQ5pjSPT7ui2EUcunaVb 维护者速读
席位核对Verdict: ACCEPT, held for the maintainer · head
|
|
domain:skills#1 · os-project-manager · session_01FEkQ5pjSPT7ui2EUcunaVb Correction: contract-review tierThe contract-review record(s) 6883816828 on this PR say This PR has already merged. The seat re-runs the review at |
|
domain:skills#1 · os-project-manager · session_01FEkQ5pjSPT7ui2EUcunaVb Contract reviewServed-tier: At-tier re-review of a merged PR (merge commit Check-runs on the head: none failed, none pending; every run concluded success or skipped. Green: Check Changeset, Check Documentation Links, Governed Surface Queue Guard, PR-body guards, Lint and Repo Gates with every Lint shard (docs and code guards, which carries the ADR anchor gates, and PM dispatch-gates included), every Type Check job, Test Core, Test UI, Dogfood Regression Gate. The skipped runs are path-filtered build, UI, E2E and opt-in jobs a docs-only diff does not trigger.
① Derived judgmentsOne ADR file, +52 / -1. No schema, export, refusal or code is published, so no accept-set and no public surface moves. What the diff implies:
② Semver level
③ Boundary flags
④ Design judgment
Tried to break it by looking for a sentence a consumer would derive a wrong rule from, wider or narrower than the tree. None found in the new section's rules. Findings:
No must-fix, no should-fix. Nits alone end the round. Implemented-by: VERDICT: PASS Adopted by the seat 2026-11-15T00:51Z · isolated sub-agent at CONTRACT_REVIEW_TIER (served model verified by the seat) · Ruling-ref: Leehom card cmsg_01TenzsRopZj4jMbvjX8uz1XFhuiZmTH8VFgMmHRmpiGAb, option A, tapped 2026-11-14T15:37Z |
Requested by Leehom · project thread
Fixes #33373
domain:skills#1 · os-project-manager · session_01FEkQ5mjPb2TvhBS1yQezQF
Clause-②: no
Metadata-protocol: none
维护者速读
:6(ownerMayEdit 横幅)与 §3 规则处加writeRequiresMasterRead,而 ADR 仍写着「方案 2 的门保持关闭」,与运行时相反;后来的评审会照 ADR 把行为「修回去」。docs/adr/0055-master-detail-controlled-by-parent.md文末「Amendment (2026-11-14, controlled_by_parent: per-object opt-in so read on the master is enough to insert and update the detail under the detail's own grants (ownerMayEdit covers owner update only; HotCRM Order to Cash blocked) #33250)」节,重点是「两个席位裁量点」(链上非声明子对象、生命周期动词)与「不变式」两段。git diff origin/main -- docs/adr/0055-master-detail-controlled-by-parent.md,预期只见新增横幅/:6一行在行尾追加docs/adr/**):请批准或合并。What changes
One file,⚠️ note appended).
docs/adr/0055-master-detail-controlled-by-parent.md(+52 / −1; the −1 is the:6banner line, kept verbatim with a· **Amended** (2026-11-14, #33250 / PR #33369, ruling A+ 6880588685)line after the 2026-11-07 line, and a:6ownerMayEditbanner (its "every other caller … keeps the master-edit rule" no longer holds on a detail that declares the new key).:69). A thirdwriteRequiresMasterReadis asked read on its master; the rule stands at its own hop for every detail that does not.:172,:188). A:247). AAcceptance notes
Every claim in the new text was read from the code on
origin/main(b4624440, which contains PR #33369 asdf9fe946):=== truepackages/spec/src/data/object.zod.ts(writeRequiresMasterRead,controlledByParentWriteRequiresMasterRead)object.zod.ts#refuseControlledByParentWriteRequiresMasterReadMisplacedsecurity-plugin-cbp-relation.ts#resolveCbpRelation,security-plugin.tsCbpRelation.writeRequiresMasterReadsecurity-plugin-cbp-write-gate.ts#assertControlledByParentChainEditable(if (hopRel.writeRequiresMasterRead) { … break; })object_permission/row_level_security; store fault propagatessecurity-plugin-cbp-write-gate.ts#assertMasterRowReadable,readUnlessRefusedsecurity-plugin-authz-middleware.tsstep 2.8 (['insert','update','delete','transfer','restore','purge'], delegator pass)security-plugin-authz-middleware.tsstep 2.7 (masterGateCoversThisWrite = !delegatorSets),platform-ownership-policies.ts(OWNERSHIP_FLOOR_PREDICATE,masterGateCoversOperation)controlled-by-parent-owner-may-edit.test.ts[#33250]"the opt-in" describe (by-id rows seeded by REP, predicate rows created by the caller)[#33250]"without read on the master" describe (expectHiddenRow,expectMasterReadRefusal); PR #33369 Acceptance notessecurity-plugin-cbp-write-gate.ts(stored null-master branch:nullMasterRowWritable, thenaskBodyNamedMaster)[#33250]"chains" describe; contract review 6881744779 ① item 5explain-engine.ts#chainAsksMasterRead,MASTER_DENIAL_LEG_DETAIL_WITH_READpackages/lint/src/validate-security-posture.ts(masterReadSuffices)claude/project-thread-jqd53n); the facts they state match.pnpm check:adr-indexis green with the README row unchanged.Verification
Derived gates on head 5647b9f (21 of 21 exit 0)
node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstackderived 21 commands; each ran with its exit captured before any pipe.--ran: "21 derived famil(ies) accounted for — 21 run, 0 NOT-MEASURED".check:doc-formula-expressionsran afterturbo run build --filter=@objectstack/formula --filter=@objectstack/lintunder the lock (VERDICT command-exit 0).Tier and governed-merge verdicts
dispatch-gates --tier: MANDATORY contract-review tier fordocs/adr/**(no one-line exit). This card thread ran on the claim's default tier; named as a deviation in the report, and the seat's in-seat contract review at tier is the owed record.check-governed-merges.mjs --branch claude/project-thread-mllmvl: exit 3, GOVERNED, landing tier H (人合),docs/adr/** ×1; 53 changed lines, under the 3000 threshold.skip-changeset(docs/adr/**ships in no package).Generated by Claude Code