Skip to content

A requester cannot launch a contract — clm_requester has no read on sys_business_unit, and our_entity is required #124

Closed

Description

@objectstack-fleet

Filing class: ① product defect (blocks the core flow) — reach: public door, measured on 18.1.0 by the #99 dev (os-dev-report on #99, main 4460d31 and PR #123 head 78319e8). Reader: the repo:hotclm seat, dispatch from pm:queue.

Symptom

Since #118, clm_contract.our_entity is a required lookup to the platform's sys_business_unit, and clm_requester grants no read on that object. Signed in as a plain requester (Business Requester 1):

  • GET /api/v1/data/sys_business_unit → 403 PERMISSION_DENIED;
  • the launch dialog's "Our signing entity" picker reads "You do not have permission to perform this action", so the dialog cannot be submitted;
  • server log: Access denied: operation find on object sys_business_unit is not permitted for positions [org_member, everyone];
  • on a contract's record page the field shows the raw id, and the server logs Failed to expand relationship field … our_entity … sys_business_unit.

PR #118 was measured as the dev admin, which is why it was not seen. Every member now holds clm_requester by default (PR #122), so this blocks every employee who is not an administrator from launching a contract.

Expected

A requester can pick a signing entity among the active company-kind units and sees its name on the contract. Likely site: an object grant on sys_business_unit (read only) in the set that needs it — clm_requester at least; the dev checks whether 18.1 lets an app permission set grant read on a platform object, and whether the other four sets also need it for the record page. ⛔ If the platform refuses an app grant on sys_business_unit, stop and report: that is a platform card, not an app workaround.

Constraints

Dedupe: hotclm issues listed and grepped for business unit, our_entity, signing entity, launch — only #20, #109, #118, #119, none of them this.


Filed by the repo:hotclm PM seat from the #99 dev report.

Activity

  1. objectstack-fleet commented on Oct 25, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: PM loop round 14
    Session: session_017nzWFRUo2U7evMkPdVniAn
    Account: zhuangjianguo (the seat's linked user as GET /user answers it; the card's assignee)
    Branch: claude/issue-124-requester-business-unit-read
    Worktree: hotclm-issue-124
    Domain: repo:hotclm (single-lane sister repo — no domain:*)
    Seat: repo:hotclm#1
    File surface: src/profiles/*.profile.ts (a read-only sys_business_unit grant) · README persona notes if they describe the launch dialog — stop on breach; explain in the report
    Container & model: S, mode:subagent, model: opus (TIER_DEFAULT; hand-derived for a sister repo), effort: medium
    Clause-②: no
    Metadata-protocol: none
    Responsibility: this app's permission sets (which platform objects a CLM member may read) | none known | every non-admin member who launches or reads a contract
    Thread-read: none
    Premise: measured by the #99 dev on 18.1.0 (requester GET sys_business_unit → 403; launch dialog picker refused); re-measured by the dev on origin/main 1264e02
    Serial constraints cleared: PR #118 merged 4460d31, PR #122 merged 721f01c, PR #123 merged 1264e02. In flight: #119 (contract hook / validation, bundles) — disjoint except the bundles; #109 waits for this card.


    Generated by Claude Code

  2. objectstack-fleet commented on Oct 25, 2026

    @objectstack-fleet
    ContributorAuthor

    os-dev-report

    {
      "issue": 124,
      "status": "done",
      "branch": "claude/issue-124-requester-business-unit-read",
      "pr": "https://github.com/objectstack-ai/hotclm/pull/126",
      "session": "session_017nzWFRUo2U7evMkPdVniAn",
      "premise_still_valid": true,
      "summary": "Premise re-measured on origin/main 1264e02 as real personas: GET sys_business_unit 403 for Business Requester 1, Legal Counsel 1 and Finance Controller 1; launch-dialog picker 403 for all three; record page showed the raw id. Fix is one line in src/profiles/requester.profile.ts: clm_requester grants read-only object access on sys_business_unit (create/edit/delete false). Every member gets it through the everyone anchor, so the other four sets are unchanged. 18.1.0 accepts the app grant on a platform object (this set already grants sys_comment, sys_activity, sys_attachment and sys_approval_request). A read grant is not a high-privilege bit (describeHighPrivilegeBits, spec 18.1.0). After the change: all three personas 200 with the 3 company units; the picker offers the 3; requester and counsel launched NDA-2026-0021 (ARC-EU) and NDA-2026-0022 (ARC-APAC), and both record pages show the entity by name; AMD-2026-0001 shows Arcadia Holdings Inc. for all three. Requester POST/PATCH on sys_business_unit 403; explain allows read and denies create/update/delete. Finance's launch is refused by clm_finance's own legal-field FLS at create_contract, not by this grant: recorded NOT MEASURED and reported below. Commit trailers follow the dispatch's model-named pair, which matches the repo's history; os-dev.md asks for a model-free pair (noted under open_questions).",
      "tests": "No test suite in this metadata-only repo; evidence is the live measurement on 18.1.0, pnpm demo --port 3424, one throwaway DB, before = 1264e02, after = 19e8dac, personas created the README way (admin create-user x3, sys_user_position x2, change-password x3, demo re-run to hand over rows). GET /api/v1/data/sys_business_unit: before 403 PERMISSION_DENIED x3 personas; after 200 total 3 (ARC-US, ARC-EU, ARC-APAC, kind company, active) x3. Launch-dialog picker (Playwright, Chromium /opt/pw-browsers/chromium): before, its filtered request returned 403 and the popover read 'You do not have permission...' x3; after, 200 and 3 options x3. Launch with entity picked: requester launch_contract 200, then intake resume 200 twice, created NDA-2026-0021 with our_entity ARC-EU; record page 'OUR SIGNING ENTITY | Arcadia Europe GmbH'. Counsel created NDA-2026-0022 with our_entity ARC-APAC; record page 'OUR SIGNING ENTITY | Arcadia Asia Pacific Pte. Ltd.'. Finance: picker 200, launch NOT MEASURED, because resume returned 400 'Field write denied: not permitted to edit [confidentiality_term_months, governing_law, status, summary]'. Record page AMD-2026-0001: before, the raw id G8yvrH008o2ERCyS and GET sys_business_unit/ID 403 x3; after, 'Arcadia Holdings Inc.' x3 with no 403. Read-only probes as requester: POST 403, PATCH 403; explain read allowed (granted by [clm_requester]), create/update/delete denied. Explain principal: clm_requester 'via additive baseline (ADR-0090 D5)' before and after. Boot WARN/ERROR signatures before and after identical except seeder counters and the inline-seed budget timing line; high-privilege, security-anchor, refused and degraded match 0 lines in all three boot logs. No ablation: config-only diff. Records and executive personas not measured (outside the dispatch's persona list).",
      "gates": "head 19e8dac, exit codes captured to files before any pipe: pnpm install exit 0; pnpm validate exit 0 'Validation passed (867ms)', 7 pre-existing warnings; pnpm lint exit 0, 6 suggestion(s), no security-anchor-high-privilege; pnpm typecheck exit 0; pnpm lint:i18n-gate exit 0 'COVERAGE : 0 missing keys across 2 locale(s)'. CI check-runs on 19e8dac when the report was written: Validate completed success (a second Validate run in_progress). dispatch-gates.mjs not applicable (sister repo; gates per hotclm AGENTS.md).",
      "dogfood_battery": "n/a — no ! in the PR title and no (narrowing) arm",
      "mcp_calls": "0",
      "api_writes": "2 — POST repository_dispatch via fleet-write relay (pr_create objectstack-ai/hotclm#126 with assignee zhuangjianguo); POST issues/124/comments (this os-dev-report via post-stamped). git push is not a REST write.",
      "open_questions": [
        { "question": "Commit trailers: the dispatch prescribes 'Co-Authored-By: Claude Opus 5.5 (1M context)' plus Claude-Session, and os-dev.md says the commit trailer pair is model-free. Which governs?", "options": ["A keep the dispatch's model-named pair (it matches every recent hotclm main commit)", "B amend os-dev.md or the dispatch template so the two agree"], "recommendation": "B, so the next dev does not have to choose; this commit used A because the dispatch named it explicitly and the history agrees." }
      ],
      "out_of_scope_findings": [
        "class: a · reach: public door, the launch dialog as a clm_finance_controller member on 18.1.0 after this PR: intake resume 400 \"Node 'create_contract' failed: create_record(clm_contract) failed: [Security] Field write denied: not permitted to edit [confidentiality_term_months, governing_law, status, summary] on 'clm_contract'\" · evidence: finance.profile.ts readOnly(Contract, [...CONTRACT_LEGAL_FIELDS, 'status', ...]); clm_requester declares none of those fields, and only declaring sets vote (_grants.ts), so finance's lock applies to a brand-new draft too. On main this was masked by the sys_business_unit 403 one step earlier. Likely the same for clm_records holders (editableOnly locks), not measured · dedupe words: finance launch contract, Field write denied create_contract, clm_finance FLS legal fields, intake create refused"
      ]
    }
  3. added a commit that references this issue on Oct 25, 2026
    ae13f57
  4. objectstack-fleet commented on Oct 25, 2026

    @objectstack-fleet
    ContributorAuthor

    Landed — PR #126 · 2026-10-25

    reading value
    PR #126 MERGED (squash on main), merged at its ACCEPT head 19e8dac; Fixes #124 closes this card
    authority maintainer, project thread, verbatim: 「你可以自己审核的就自己合并」

    Release: every member can read the organization's business units, so the launch dialog's signing-entity picker works and the record page names the entity. What this fix unmasked — a finance controller's own launch is refused by clm_finance's field locks — is filed as its own needs-user-decision card #127 for the maintainer's decision. State: pm:dispatched removed, assignee cleared.


    Generated by Claude Code

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions