Skip to content

Legal and finance can edit a counterparty they do not own - #193

Merged
zhuangjianguo merged 2 commits into
mainfrom
claude/issue-152-party-public-rw
Nov 3, 2026
Merged

zhuangjianguo merged 2 commits into
mainfrom
claude/issue-152-party-public-rw

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Fixes #152

Ruling D (comment 6607872904, maintainer 2026-11-03): clm_party becomes public_read_write; the permission sets stay as they are. The rider, clm_clause, measured the same shape on main, so it gets the same one-line change under the same ruling.

What changed

  • src/objects/party.object.ts: sharingModel: 'public_read' to 'public_read_write', with a short comment on why.
  • src/objects/clause.object.ts: the same change (rider, ruling item 4).
  • Nothing in src/profiles changes. Platform 18.2.0 (plugin-security platform-ownership-policies.ts, owdOpenWritesCoversOperation) opens the row scope for update only. Deletes stay owner-only, and object permissions plus field locks still decide who may write which field.

Measured: zh-CN demo staff, 18.2.0, port 3162, a fresh .objectstack DB per side

Before = origin/main 7e7c2dc. After = this branch cf33339. Each persona signed in with its own session (requester1, counsel1, finance, records @example.com). Every write was read back with a GET as the same persona. Seeded rows were owned by the dev admin at reading time.

API

Persona and write main branch
counsel1 PATCH risk_flag on the party requester1 created 403 您无权访问这条记录… (server log: row-level security) 200, read-back watch
counsel1 PATCH risk_flag on seeded 峰顶翻译 403 row-level 200, read-back watch
finance PATCH bank_name (same two parties) 403 row-level 200, read-back holds the new value
finance PATCH name 403 row-level 403 [Security] Field write denied: not permitted to edit [name] on 'clm_party' (field lock)
requester1 PATCH contact_name on the party it created 403 您没有执行此操作的权限… (object permission) 403, same object-permission refusal
records PATCH contact_name 403 object permission 403 object permission
counsel1 / finance / requester1 DELETE that party; counsel1 DELETE seeded party 403 403, the row is still there (admin GET 200)
counsel1 PATCH position_note on a seeded clause (rider) 403 row-level 200, read-back holds the new value
finance / requester1 / records PATCH that clause 403 object permission 403 object permission
counsel1 DELETE that clause 403 403

Browser (Chromium, zh-CN console, signed in as each persona)

  • main: on the party record page, counsel1, finance, requester1 and records each see no 编辑 button and no 双击编辑 cell. The more-actions menu offers only 添加到收藏 / 分享. counsel1 and finance see the same on a clause.
  • branch: counsel1 opens seeded 北风物流, clicks 编辑, sets 风险标记 to 关注 and fills 风险说明, then clicks 更新. Result: PATCH /api/v1/data/clm_party/… → 200, toast 相对方“北风物流”已更新. After a reload the header reads 风险标记 关注.
  • branch: finance opens the same party and clicks 编辑. The form leaves only bank_name and bank_account open; the other 13 controls (name included) are locked. Finance edits 开户行 and saves: PATCH → 200, toast 相对方“北风物流”已更新, and the read-back holds it.
  • branch: counsel1 opens a seeded clause (服务质量保证), clicks 编辑, changes position_note and saves: PATCH /api/v1/data/clm_clause/… → 200, toast 条款“服务质量保证”已更新.
  • branch: requester1 and records still see no 编辑 on the party, and finance sees none on the clause.
  • Console errors on both sides, unchanged by this diff: one 401 on the sign-in page (the pre-session probe), plus one 404 on counsel1's first page load.

Gates (tree of cf33339, no edit after the run; each exit captured before any pipe)

validate=0        ✓ Validation passed (929ms)
lint=0            6 suggestion(s), 0 warnings (same as main)
typecheck=0       tsc --noEmit
lint:i18n-gate=0  COVERAGE : 0 missing keys across 2 locale(s)
CLM_DEMO_SEED=1 pnpm validate=0   ✓ Validation passed (865ms)

Acceptance notes

🤖 Generated with Claude Code

https://claude.ai/code/session_017nzWFRUo2U7evMkPdVniAn

Legal could not edit a counterparty or a playbook clause it did not
create: both objects were public_read, so every write was owner-scoped
and no sharing rule covered legal (or finance on the banking pair).
Under ruling D both become public_read_write. The platform opens the
row scope for update only; deletes stay owner-only, and the object
permissions and field locks in src/profiles (unchanged) still decide
who writes which field.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017nzWFRUo2U7evMkPdVniAn
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

席位核对 — ACCEPT · head 8ab6300 · 2026-11-03T16:04Z

check reading
shape draft → main, Fixes #152; mergeable clean
CI on the head both Validate check-runs success on 8ab6300 = PR head.sha
scope ruling D (6607872904): clm_party sharingModel public_read → public_read_write, and the rider clm_clause gets the same change (same shape measured on main: counsel1's edit of a seeded clause was refused at row level). Nothing in src/profiles changes grants. The seat added one comment-only commit (8ab6300) correcting two comments the change made false (contract-intake.flow.ts, requester.profile.ts). Nothing governed; lint 0 warnings
measured (zh-CN demo staff, API and browser) counsel1 sets risk_flag on a party it did not create: 403 → 200. finance writes bank_name: 403 → 200. finance writes name: 403 (now the field lock, not row level). requester1 PATCHes its own party: 403 (object permission). records: 403. Non-owner DELETE: 403, row kept. Clause: counsel1 edits a seeded clause 403 → 200; finance, requester1 and records still 403; DELETE 403. In the browser, finance's party form opens only bank_name / bank_account
governed text §03 object map and row labels, and the §04 OWD sentence, go to the seat's design PR #120

Landing: under the maintainer's merge authorization (project thread: 「你可以自己审核的就自己合并」).


Generated by Claude Code

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Decision] Legal and finance cannot edit a counterparty they do not own — §04 gives them update on clm_party, but its writes are owner-scoped

2 participants