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
Seeded reviews name the Dev Admin as reviewer instead of the legal staff #186
Filing gate: ② demo fidelity, found by #19's dev (PR #185), measured on 18.2.0.
Today. All 60 seeded clm_review rows name the Dev Admin as reviewer (src/data/negotiation.seed.ts). The column was set that way when the dev admin was the only account at seed time. Since PR #171 the demo staff (demoStaff) exist before the seed runs. counsel1 sees the pending reviews it can read listed as 「Legal · Dev Admin」, and the README tells the evaluator to reassign a review by hand.
Why it is not a one-column change (the dev's reading):
reviewer is required, and legalOwnerOf returns null on SOW/ORD contracts and on the contract handed back to the queue, so those rows would be refused.
Finance, compliance and business review stages need their own reviewer: finance@, the legal head or the requester? negotiation.seed.ts records this as open.
scripts/demo.mjs keeps a DEMO_USER priming check that exists only for this column. It can retire.
keys.ts would export a counselFor helper.
Proposed. Legal stage → the contract's legal_owner (counsel1/2), falling back to legal.head@ where there is none. Finance stage → finance@. Business stage → the contract's requester. Compliance stage → legal.head@. The dev measures each persona sees and can act on its reviews. If the mapping is contested, it goes to the decision box.
Claim: PM loop round 17
Ruling-ref: none (seat-filed follow-up of #19, PR #185; the stage mapping in the card body is the seat's call)
Session: session_017nzWFRUo2U7evMkPdVniAn
Account: zhuangjianguo (the seat's linked user as GET /user answers it; the card's assignee)
Branch: claude/issue-186-seed-reviewers
Worktree: hotclm-issue-186
Domain: repo:hotclm (single-lane sister repo — no domain:*)
Seat: repo:hotclm#1
File surface: src/data/** (review reviewer column, keys helper) · scripts/demo.mjs (retire the DEMO_USER priming check only if nothing else needs it) · README.md — 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 demo (seeded reviews sit with the staff who would review them) | none | every evaluator of the demo
Thread-read: none
Premise: re-measured by the dev on origin/main37ce10c (@objectstack 18.2.0, after PR #185)
Serial constraints cleared: #19 landed (PR #185, src/data/**). In flight: #183 (src/email-templates/**), disjoint.
{
"issue": 186,
"status": "done",
"branch": "claude/issue-186-seed-reviewers",
"pr": "https://github.com/objectstack-ai/hotclm/pull/189",
"session": "session_017nzWFRUo2U7evMkPdVniAn",
"premise_still_valid": true,
"summary": "Premise confirmed on origin/main 37ce10c (18.2.0, zh-CN, clean DB): all 60 seeded clm_review rows named Dev Admin (Legal x35, Finance x23, Business x2). New keys.ts reviewerOf() deals each review by the seat's stage mapping: legal goes to the contract's legal_owner, or Head of Legal on the one handed-back contract; finance to Finance Controller; compliance to Head of Legal (the plan deals none); business to the launching requester. One measured deviation: the 7 finance reviews on contracts before 'approved' go to Head of Legal. clm_review is controlled_by_parent and finance edits contracts only from approved onward, so finance@'s PATCH on such a review answers 403 ('requires edit access to its master record'). Business stays the requester's although §04 gives the requester R only (PATCH 403): both business reviews are already decided, and the card asks only that the requester sees it. scripts/demo.mjs drops the DEMO_USER name check (the priming boot and its sign-in check stay). The README states the rule, per-account counts, and that a re-run resets a review's reviewer and decision. Result: counsel1 16 / counsel2 18 / legal.head 8 / finance 16 / requester2 1 / requester3 1. The card's claim comment was not yet on #186 when I started (0 comments, pm:queue); it was there by PR time. I wrote no claim.",
"tests": "Live, pnpm demo:zh, port 3160, @objectstack 18.2.0, throwaway DB, Chromium /opt/pw-browsers/chromium in zh-CN, signed in via /_console/login as each persona. BEFORE 37ce10c: admin@ GET clm_review total 60, every display_name '... · Dev Admin'. finance@ PATCH finance review on an in_review contract -> 403, on an in_approval contract -> 403, on an active contract -> 200; requester2@ PATCH own business review -> 403. AFTER run 1 (0410379, clean DB): contracts 120 / versions 300 / reviews 60 / deviations 25 / signatures 30 / obligations 200 / instalments 300, no seed error, 0 reviews name Dev Admin. counsel1@ sees 60 reviews, 'Legal · Legal Counsel 1' 14 approved + 2 pending. In the browser, contract MSA-2026-0003 审查与偏离 grid shows 'Legal · Legal Counsel 1 | 法务 | Legal Counsel 1 | 待定'; review page 编辑 > 结论=通过 > 更新 -> PATCH 200, toast 「审查“Legal · Legal Counsel 1”已更新」, after reload 结论 通过 with 结论时间 stamped. finance@ sees 50 reviews (all 23 finance). Browser, SOW-2026-0005 (生效中) grid shows 'Finance · Finance Controller | 财务 | Finance Controller | 通过'; 编辑 > 结论=要求修改 > 更新 -> PATCH 200. legal.head@ decided a pre-approval 'Finance · Head of Legal' review in the browser -> PATCH 200; finance@ API PATCH on the same review -> 403. requester2@ browser, ORD-2026-0005 grid shows 'Business · Business Requester 2 | 业务 | Business Requester 2 | 通过'. Browser console: one 404 and one 401 on the login page before sign-in, no >=400 response after it. RUN 2 (same DB): 'Seeds: app.objectstack.hotclm 1130 rows', no error, identical deal, the 3 decided reviews back to fixture decisions (decision was never applyOn:create). RUN 3 (same DB, 3 reviews first reassigned to Dev Admin): after the re-run they read Legal Counsel 1 / Finance Controller / Business Requester 2 again, 0 of 60 name Dev Admin, no row refused. demo.mjs printed '1/2 done — admin account ready.' on all three runs. No unit tests exist in this repo for src/data; no ablation, because no tested behaviour changed.",
"gates": "On the final tree (head 5d7606e), each exit code captured before any pipe: pnpm install 0; pnpm validate 0 ('✓ Validation passed'); pnpm lint 0 (0 warnings, '6 suggestion(s)', same as main); pnpm typecheck 0; pnpm lint:i18n-gate 0 ('COVERAGE : 0 missing keys across 2 locale(s)'); CLM_DEMO_SEED=1 pnpm validate 0 ('✓ Validation passed'). CI check-runs on PR #189: in_progress / not read (I did not wait, per contract). dispatch-gates.mjs is objectstack-only and was not used for this sister repo.",
"dogfood_battery": "n/a — no `!` in the PR title and no (narrowing) arm",
"mcp_calls": "0",
"api_writes": "2 — fleet-write relay: pr_create (create + assignee leg, read-back identical, PR #189, assignee zhuangjianguo); os-dev-report comment on #186 via post-stamped. Plus 2 git pushes (not REST). Writes to the demo's own local API on localhost:3160 were throwaway-DB readings, not GitHub writes.",
"open_questions": [
{
"question": "Finance cannot record or decide a finance-stage review before its contract is approved (403, master not editable). §04 grants clm_finance RCU(stage=finance) on clm_review, but finance's contract edit window opens at approved, after the review stage. Which way should the product go?",
"options": [
"A: Keep it. Write into §04 that legal records the finance review on finance's behalf before approval. The fixture already does this for 7 rows.",
"B: Give finance edit on contracts routed to it (contract_finance_routed edit instead of read), with FLS locking every contract field. This widens a sharing rule.",
"C: Ask the platform for child-object write that does not require master edit (a controlled_by_parent exception). That would be an upstream gap issue."
],
"recommendation": "Seat decides through a needs-user-decision card. My lean is A for now: it needs no new grant, and the demo already reads that way. B reopens a §04 window that was ruled on."
},
{
"question": "A business review names the requester, but the requester holds R only on clm_review (§04). Keep that, or deal business reviews to someone who can decide them?",
"options": [
"A: Keep the requester (this PR). It reads as the launching desk's sign-off, both seeded rows are already decided, and the requester sees it.",
"B: Head of Legal, the only non-admin who can write a business review. This misattributes the sign-off."
],
"recommendation": "A, because the card's measurement asks only that the requester sees it."
},
{
"question": "objectstack.config.ts spells the 'Head of Legal' and 'Finance Controller' demoStaff names as literals; keys.ts now mirrors them as LEGAL_HEAD / FINANCE_CONTROLLER. A rename in one place would silently drop reviews (reviewer is required). The fix is outside this card's surface.",
"options": [
"A: A small follow-up: config spells those two entries from keys.ts, as it already does for CONTRACT_OWNERS and LEGAL_OWNERS.",
"B: Leave the mirror and its warning comment."
],
"recommendation": "A, one-line change in objectstack.config.ts."
}
],
"out_of_scope_findings": [
"class: b · reach: PATCH /api/v1/data/clm_review/ID signed in as finance@example.com, finance-stage review on an in_review or in_approval contract -> 403 PERMISSION_DENIED 'requires edit access to its master record' (18.2.0, before and after this PR) · evidence: DESIGN.md §04 matrix 'clm_review … clm_finance RCU(stage=finance)'; src/profiles/finance.profile.ts review_finance_stage_insert/update; contract_finance_post_approval edit window starts at approved · Seam: spec:clm_finance.objects.clm_review allowEdit + rowLevelSecurity review_finance_stage_update → runtime:security controlled_by_parent master-edit check · dedupe words: finance review stage write, controlled_by_parent master edit, finance stage review 403, route_finance co-sign review",
"carrier: #157 — review titles are English in zh-CN ('Legal · Legal Counsel 1'), because mirror.hook.ts hard-codes the stage labels; already so before this PR ('Legal · Dev Admin')",
"carrier: none — noted, not filed: seeded reviews' owner_id (所有者) reads Dev Admin through the platform's seed-settle claim; controlled_by_parent makes it grant nothing",
"carrier: none — noted, not filed: a re-run of pnpm demo puts a decided review back to its fixture decision (decision/decided_at are not applyOn:create), the same not-yet-covered limit as deviations and signature rounds. The README now states it.",
"carrier: none — noted, not filed: scripts/demo.mjs's remaining reason for the priming boot (organization_id null on rows written before the org exists) was not re-measured on 18.2.0"
],
"governed_text_proposal": "DESIGN.md §10, clm_review · clm_deviation row, append to 要点: 「审查人按环节分派:法务 → 合同法务负责人(无则法务负责人);财务 → 财务负责人(合同未到 approved 时为法务负责人,因财务在此之前不能写审查);合规 → 法务负责人;业务 → 发起人」. Whether §04 should change for the pre-approval finance review is open question 1 above."
}
Release: the 60 seeded reviews now sit with the staff who would hold them (legal counsel, the legal head, finance, the requester) instead of the Dev Admin, so a lawyer signing into the demo sees and decides their own reviews. State: pm:dispatched removed, assignee cleared.
Activity
objectstack-fleet commentedon Oct 27, 2026
Claim: PM loop round 17
Ruling-ref: none (seat-filed follow-up of #19, PR #185; the stage mapping in the card body is the seat's call)
Session:
session_017nzWFRUo2U7evMkPdVniAnAccount:
zhuangjianguo(the seat's linked user asGET /useranswers it; the card's assignee)Branch:
claude/issue-186-seed-reviewersWorktree:
hotclm-issue-186Domain:
repo:hotclm(single-lane sister repo — nodomain:*)Seat:
repo:hotclm#1File surface:
src/data/**(review reviewer column, keys helper) ·scripts/demo.mjs(retire the DEMO_USER priming check only if nothing else needs it) ·README.md— 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 demo (seeded reviews sit with the staff who would review them) | none | every evaluator of the demoThread-read: none
Premise: re-measured by the dev on
origin/main37ce10c(@objectstack 18.2.0, after PR #185)Serial constraints cleared: #19 landed (PR #185,
src/data/**). In flight: #183 (src/email-templates/**), disjoint.Generated by Claude Code
objectstack-fleet commentedon Oct 27, 2026
os-dev-report
{ "issue": 186, "status": "done", "branch": "claude/issue-186-seed-reviewers", "pr": "https://github.com/objectstack-ai/hotclm/pull/189", "session": "session_017nzWFRUo2U7evMkPdVniAn", "premise_still_valid": true, "summary": "Premise confirmed on origin/main 37ce10c (18.2.0, zh-CN, clean DB): all 60 seeded clm_review rows named Dev Admin (Legal x35, Finance x23, Business x2). New keys.ts reviewerOf() deals each review by the seat's stage mapping: legal goes to the contract's legal_owner, or Head of Legal on the one handed-back contract; finance to Finance Controller; compliance to Head of Legal (the plan deals none); business to the launching requester. One measured deviation: the 7 finance reviews on contracts before 'approved' go to Head of Legal. clm_review is controlled_by_parent and finance edits contracts only from approved onward, so finance@'s PATCH on such a review answers 403 ('requires edit access to its master record'). Business stays the requester's although §04 gives the requester R only (PATCH 403): both business reviews are already decided, and the card asks only that the requester sees it. scripts/demo.mjs drops the DEMO_USER name check (the priming boot and its sign-in check stay). The README states the rule, per-account counts, and that a re-run resets a review's reviewer and decision. Result: counsel1 16 / counsel2 18 / legal.head 8 / finance 16 / requester2 1 / requester3 1. The card's claim comment was not yet on #186 when I started (0 comments, pm:queue); it was there by PR time. I wrote no claim.", "tests": "Live, pnpm demo:zh, port 3160, @objectstack 18.2.0, throwaway DB, Chromium /opt/pw-browsers/chromium in zh-CN, signed in via /_console/login as each persona. BEFORE 37ce10c: admin@ GET clm_review total 60, every display_name '... · Dev Admin'. finance@ PATCH finance review on an in_review contract -> 403, on an in_approval contract -> 403, on an active contract -> 200; requester2@ PATCH own business review -> 403. AFTER run 1 (0410379, clean DB): contracts 120 / versions 300 / reviews 60 / deviations 25 / signatures 30 / obligations 200 / instalments 300, no seed error, 0 reviews name Dev Admin. counsel1@ sees 60 reviews, 'Legal · Legal Counsel 1' 14 approved + 2 pending. In the browser, contract MSA-2026-0003 审查与偏离 grid shows 'Legal · Legal Counsel 1 | 法务 | Legal Counsel 1 | 待定'; review page 编辑 > 结论=通过 > 更新 -> PATCH 200, toast 「审查“Legal · Legal Counsel 1”已更新」, after reload 结论 通过 with 结论时间 stamped. finance@ sees 50 reviews (all 23 finance). Browser, SOW-2026-0005 (生效中) grid shows 'Finance · Finance Controller | 财务 | Finance Controller | 通过'; 编辑 > 结论=要求修改 > 更新 -> PATCH 200. legal.head@ decided a pre-approval 'Finance · Head of Legal' review in the browser -> PATCH 200; finance@ API PATCH on the same review -> 403. requester2@ browser, ORD-2026-0005 grid shows 'Business · Business Requester 2 | 业务 | Business Requester 2 | 通过'. Browser console: one 404 and one 401 on the login page before sign-in, no >=400 response after it. RUN 2 (same DB): 'Seeds: app.objectstack.hotclm 1130 rows', no error, identical deal, the 3 decided reviews back to fixture decisions (decision was never applyOn:create). RUN 3 (same DB, 3 reviews first reassigned to Dev Admin): after the re-run they read Legal Counsel 1 / Finance Controller / Business Requester 2 again, 0 of 60 name Dev Admin, no row refused. demo.mjs printed '1/2 done — admin account ready.' on all three runs. No unit tests exist in this repo for src/data; no ablation, because no tested behaviour changed.", "gates": "On the final tree (head 5d7606e), each exit code captured before any pipe: pnpm install 0; pnpm validate 0 ('✓ Validation passed'); pnpm lint 0 (0 warnings, '6 suggestion(s)', same as main); pnpm typecheck 0; pnpm lint:i18n-gate 0 ('COVERAGE : 0 missing keys across 2 locale(s)'); CLM_DEMO_SEED=1 pnpm validate 0 ('✓ Validation passed'). CI check-runs on PR #189: in_progress / not read (I did not wait, per contract). dispatch-gates.mjs is objectstack-only and was not used for this sister repo.", "dogfood_battery": "n/a — no `!` in the PR title and no (narrowing) arm", "mcp_calls": "0", "api_writes": "2 — fleet-write relay: pr_create (create + assignee leg, read-back identical, PR #189, assignee zhuangjianguo); os-dev-report comment on #186 via post-stamped. Plus 2 git pushes (not REST). Writes to the demo's own local API on localhost:3160 were throwaway-DB readings, not GitHub writes.", "open_questions": [ { "question": "Finance cannot record or decide a finance-stage review before its contract is approved (403, master not editable). §04 grants clm_finance RCU(stage=finance) on clm_review, but finance's contract edit window opens at approved, after the review stage. Which way should the product go?", "options": [ "A: Keep it. Write into §04 that legal records the finance review on finance's behalf before approval. The fixture already does this for 7 rows.", "B: Give finance edit on contracts routed to it (contract_finance_routed edit instead of read), with FLS locking every contract field. This widens a sharing rule.", "C: Ask the platform for child-object write that does not require master edit (a controlled_by_parent exception). That would be an upstream gap issue." ], "recommendation": "Seat decides through a needs-user-decision card. My lean is A for now: it needs no new grant, and the demo already reads that way. B reopens a §04 window that was ruled on." }, { "question": "A business review names the requester, but the requester holds R only on clm_review (§04). Keep that, or deal business reviews to someone who can decide them?", "options": [ "A: Keep the requester (this PR). It reads as the launching desk's sign-off, both seeded rows are already decided, and the requester sees it.", "B: Head of Legal, the only non-admin who can write a business review. This misattributes the sign-off." ], "recommendation": "A, because the card's measurement asks only that the requester sees it." }, { "question": "objectstack.config.ts spells the 'Head of Legal' and 'Finance Controller' demoStaff names as literals; keys.ts now mirrors them as LEGAL_HEAD / FINANCE_CONTROLLER. A rename in one place would silently drop reviews (reviewer is required). The fix is outside this card's surface.", "options": [ "A: A small follow-up: config spells those two entries from keys.ts, as it already does for CONTRACT_OWNERS and LEGAL_OWNERS.", "B: Leave the mirror and its warning comment." ], "recommendation": "A, one-line change in objectstack.config.ts." } ], "out_of_scope_findings": [ "class: b · reach: PATCH /api/v1/data/clm_review/ID signed in as finance@example.com, finance-stage review on an in_review or in_approval contract -> 403 PERMISSION_DENIED 'requires edit access to its master record' (18.2.0, before and after this PR) · evidence: DESIGN.md §04 matrix 'clm_review … clm_finance RCU(stage=finance)'; src/profiles/finance.profile.ts review_finance_stage_insert/update; contract_finance_post_approval edit window starts at approved · Seam: spec:clm_finance.objects.clm_review allowEdit + rowLevelSecurity review_finance_stage_update → runtime:security controlled_by_parent master-edit check · dedupe words: finance review stage write, controlled_by_parent master edit, finance stage review 403, route_finance co-sign review", "carrier: #157 — review titles are English in zh-CN ('Legal · Legal Counsel 1'), because mirror.hook.ts hard-codes the stage labels; already so before this PR ('Legal · Dev Admin')", "carrier: none — noted, not filed: seeded reviews' owner_id (所有者) reads Dev Admin through the platform's seed-settle claim; controlled_by_parent makes it grant nothing", "carrier: none — noted, not filed: a re-run of pnpm demo puts a decided review back to its fixture decision (decision/decided_at are not applyOn:create), the same not-yet-covered limit as deviations and signature rounds. The README now states it.", "carrier: none — noted, not filed: scripts/demo.mjs's remaining reason for the priming boot (organization_id null on rows written before the org exists) was not re-measured on 18.2.0" ], "governed_text_proposal": "DESIGN.md §10, clm_review · clm_deviation row, append to 要点: 「审查人按环节分派:法务 → 合同法务负责人(无则法务负责人);财务 → 财务负责人(合同未到 approved 时为法务负责人,因财务在此之前不能写审查);合规 → 法务负责人;业务 → 发起人」. Whether §04 should change for the pre-approval finance review is open question 1 above." }Generated by Claude Code
DESIGN.md §10: seeded version files and review dealing (#19, #186)
Seeded reviews sit with the staff who would hold them (#189)
objectstack-fleet commentedon Oct 27, 2026
Ruling-ref: none (seat-filed follow-up of #19; stage mapping is the seat's call)
Landed — PR #189 · 2026-10-27
MERGED(squash onmain), merged at its ACCEPT head5d7606e;Fixes #186closes this cardRelease: the 60 seeded reviews now sit with the staff who would hold them (legal counsel, the legal head, finance, the requester) instead of the Dev Admin, so a lawyer signing into the demo sees and decides their own reviews. State:
pm:dispatchedremoved, assignee cleared.Generated by Claude Code