You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
A requester cannot launch a contract — clm_requester has no read on sys_business_unit, and our_entity is required #124
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, main4460d31 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
Read only; no create / edit / delete on sys_business_unit for any CLM set.
Re-measure as each persona (requester, legal, finance, records, executive), not as the dev admin: launch with an entity picked, then read it back by name on the record page.
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/main1264e02
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.
{
"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"
]
}
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.
Activity
objectstack-fleet commentedon Oct 25, 2026
Claim: PM loop round 14
Session:
session_017nzWFRUo2U7evMkPdVniAnAccount:
zhuangjianguo(the seat's linked user asGET /useranswers it; the card's assignee)Branch:
claude/issue-124-requester-business-unit-readWorktree:
hotclm-issue-124Domain:
repo:hotclm(single-lane sister repo — nodomain:*)Seat:
repo:hotclm#1File surface:
src/profiles/*.profile.ts(a read-onlysys_business_unitgrant) · README persona notes if they describe the launch dialog — stop on breach; explain in the reportContainer & model:
S,mode:subagent,model: opus(TIER_DEFAULT; hand-derived for a sister repo),effort: mediumClause-②: 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 contractThread-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 onorigin/main1264e02Serial constraints cleared: PR #118 merged
4460d31, PR #122 merged721f01c, PR #123 merged1264e02. In flight: #119 (contract hook / validation, bundles) — disjoint except the bundles; #109 waits for this card.Generated by Claude Code
objectstack-fleet commentedon Oct 25, 2026
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" ] }Every member can read the business units, so the signing-entity picke…
objectstack-fleet commentedon Oct 25, 2026
Landed — PR #126 · 2026-10-25
MERGED(squash onmain), merged at its ACCEPT head19e8dac;Fixes #124closes this cardRelease: 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 ownneeds-user-decisioncard #127 for the maintainer's decision. State:pm:dispatchedremoved, assignee cleared.Generated by Claude Code