Skip to content

34 backfilled contracts carry a legal_owner, and is_backfilled says on the same row that no review ever happened - #115

Merged
zhuangjianguo merged 1 commit into
mainfrom
claude/issue-53-legal-owner-custodian
Oct 25, 2026
Merged

zhuangjianguo merged 1 commit into
mainfrom
claude/issue-53-legal-owner-custodian

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Fixes #53 — ruling B: legal_owner's help text names the custodian lawyer, which a backfilled contract also has
Clause-②: no
Metadata-protocol: none

Ruling-ref: issue comment 6396326020 (batch #3 item 4, letter B, maintainer 「同意」). Session session_017nzWFRUo2U7evMkPdVniAn, branch claude/issue-53-legal-owner-custodian.

What changed

clm_contract.legal_owner was described as "The lawyer who accepted the review. Required before a submitted contract enters review." That is false on every backfilled contract, which skips review by design yet still has a lawyer in legal responsible for its file. The ruling says the column means the contract's custodian in legal, so its help text now says so, in the object and in both translation bundles:

before after
contract.object.ts description and en help The lawyer who accepted the review. Required before a submitted contract enters review. The lawyer in legal who owns this contract's file. Usually assigned when the contract enters legal review; a backfilled contract skips review, so legal names its lawyer here directly.
zh-CN help 受理这次审查的法务。合同进入审查前必须先有经办人。 在法务归口负责这份合同档案的律师。通常在合同进入法务审查时分配;补录的合同不经审查,由法务直接在这里指定。

A code comment beside the field carries the mechanics (F2 assigns on submission, the state machine still requires the column before in_review, F16 assigns nothing, clm_records cannot write it), so the help text stays written for the person reading the screen.

Why "legal names", not the ruling's example "records assigns"

The ruling's wording was an example (「例如」), and its last clause was checked against the code before it was written. No part of the product has records assigning legal_owner on a backfilled contract:

  • F16 (executed_upload, src/actions/contract-backfill.actions.ts) has no legal_owner param and the flow writes none.
  • clm_records cannot write the column: src/profiles/records.profile.ts spreads editableOnly(Contract, ['status', 'archive_no']), which locks every other contract field, legal_owner included.
  • clm_legal can: its FLS opens every non-stamped contract field (legal_owner is in the parties group, not a stamped group) and its row policy covers every status. clm_admin can too.

So on a backfilled contract the column is set by legal (or an admin) editing the record, and the help text says that. Writing "records assigns" would describe a process the product does not have.

What did not change, on purpose

This PR delivers the whole of ruling step 1 in code, and step 2 needs no change. That is why it closes #53 while step 3 stays with #43.

Gates

Run on the tree committed unchanged as 3e470f6. pnpm install exited 0. Each exit code was captured before any pipe.

pnpm validate         exit 0   ✓ Validation passed (1340ms)
pnpm lint             exit 0   6 suggestion(s) (1117ms)   (the contract_approval approver-slate suggestions, unchanged from main)
pnpm typecheck        exit 0   tsc --noEmit
pnpm lint:i18n-gate   exit 0   ✓ i18n gate · LOCALES "en", "zh-CN" checked · COVERAGE: 0 missing keys across 2 locale(s)

Browser

pnpm demo --port 3153 on a clean .objectstack/data (rm -rf .objectstack/data first), then Chromium at /opt/pw-browsers/chromium driven by Playwright, signed in as admin@objectos.ai.

  • Record: NDA-2026-0006 "Mutual Non-Disclosure Agreement — Basalt Energy" (4V-BF26k2ggfqaR7). GET /api/v1/data/clm_contract with {"is_backfilled":true,"status":"active"} answered 200, total: 41, and this row has is_backfilled: true, review_started_at: null.
  • The read-only record page shows no field help (the platform's detail renderer draws none). The help text renders on the record's Edit form (?form=…) as the field's description paragraph under the Legal Owner lookup:
    • en-US context: label Legal Owner, help The lawyer in legal who owns this contract's file. Usually assigned when the contract enters legal review; a backfilled contract skips review, so legal names its lawyer here directly.
    • zh-CN context: label 法务经办人, help 在法务归口负责这份合同档案的律师。通常在合同进入法务审查时分配;补录的合同不经审查,由法务直接在这里指定。
  • Browser console on that page: one 401 and one 404 resource load, plus the two [object-ui] predicate fallbacks for the submit_contract / start_renewal header actions. None of these comes from this change (only text changed). Screenshots are in the session scratch directory: branch-legal-owner-en-US.png and branch-legal-owner-zh-CN.png.
  • On this first demo boot the field is empty on the record: all 68 legal_owner references resolve against counsel accounts that do not exist yet (ERROR [SeedLoader] … clm_contract.legal_owner is NULL … 'Legal Counsel 1'). That is the documented first-boot state pnpm demo prints. The help text renders either way.

Boot warnings vs main: a second pnpm demo --port 3154 from a detached origin/main (f5ad133) worktree, also on a clean database. Both boots logged 430 raw WARN/ERROR lines. After normalising record ids and timestamps, the warning classes and their counts are identical (diff exit 0): the superseded-metadata-plugin and inline-seed-budget notices, the 6 approver-slate warnings, the hierarchy-security capability notice, and the first-boot deferred-reference set (68 legal_owner, 120 owner_id, 17 decided_by, 199 obligation.owner). This change adds no new boot warning.

Acceptance notes

  • zh-CN label. The label 法务经办人 (field label and the contract_cycle_time dataset dimension in src/translations/zh-CN/app.ts) still reads as "the lawyer handling it", which sits a little narrower than the 归口 semantics the help now gives. Relabelling was outside this card's file surface (description only) and is left as is. Owner: none.
  • Finance can reassign the custodian (read from the code, not measured). clm_finance locks CONTRACT_LEGAL_FIELDS (the legal group plus risk_level and liability_cap) and status. legal_owner is in parties, so the finance controller, who edits contracts from approved onward through contract_finance_post_approval, appears able to write it. Whether the custodian column should join finance's locked set is a §04 question. Owner: none.
  • §03 sync: none needed (see above). If a later design-doc PR gives the §03 field table per-field descriptions, the legal_owner entry would read: legal_owner lookup user(法务归口人:通常在进入审查时分配;补录合同由法务直接指定).

🤖 Generated with Claude Code

https://claude.ai/code/session_017nzWFRUo2U7evMkPdVniAn

The column was described as "the lawyer who accepted the review", which is
false on every backfilled contract: those skip review, yet legal still owns
their file, and F12/F13 copy legal_owner on their renewal and expiry notices.
The maintainer ruled the column means the contract's custodian in legal
(ruling B), so the description and both translation bundles now say that,
with review acceptance demoted to how the column is usually first set.

The text says "legal names its lawyer here" rather than "records assigns":
F16 assigns no legal_owner and clm_records cannot write the column, so legal
(or an admin) editing the record is the only path a backfilled contract has.

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

Copy link
Copy Markdown
Contributor Author

席位核对 — ACCEPT · head 3e470f6 · 2026-10-25T12:58Z

check reading
shape draft → main, line 1 Fixes #53 — ruling B …; assignee zhuangjianguo
CI on the head both Validate check-runs success on 3e470f6 = PR head.sha
scope 3 files (+11/−3): legal_owner.description, its en and zh-CN help, one code comment; no seed, no F16, nothing governed (§03 lists legal_owner with no description — no sync needed)
the ruling 6396326020 letter B step 1: custodian semantics delivered. The ruling's example wording "records assigns" was checked and not used — F16 writes no legal_owner and clm_records cannot edit the column — so the text says legal names the lawyer; a truthful reading of the same decision
measured (dev) backfilled NDA-2026-0006 edit form shows the new help in en and zh-CN; boot warning set identical to main
step 3 the optional custodian field on the F16 backfill form moves to #43 (F16 cannot run on 18.1 until objectstack-ai/objectstack#25643 ships)

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.

34 backfilled contracts carry a legal_owner, and is_backfilled says on the same row that no review ever happened

2 participants