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
Ruled: 6396320437 · letter D · 2026-10-25T10:07Z (D = platform demo-staffing primitive, added by the director seat beyond A/B/C below; C out since #11 Q1 = A)
ERROR [SeedLoader] Deferred reference UNRESOLVED after pass 2 —
clm_contract.owner_id stays NULL on record 'Master Services Agreement — Aurora Systems'.
The row itself was seeded, so every row counter looks healthy while the relationship is
MISSING: nothing links it to sys_user.name = 'Business Requester 1', because no such
sys_user row exists … Nothing retries this: pass 2 is the last one.
×120,外加一条 WARN [Seeder] ✗ … and 100 more error(s) 汇总。行数不受影响(820 行,120 份合同 owner_id 全 NULL)。
我第一次复测时也拿到了「0 错误」——因为 820 行内联种子超了 8 秒预算,转入后台继续,而我在 Server is ready 之后就去 grep 了。就绪横幅出现在 23:51:07,错误出现在 23:52:22,我早看了 75 秒。这是同一个失败形状的又一次变装:过早读取的日志和干净的日志不可区分。
对选项的影响
A 的代价要重写。 原来写的是「第一屏在操作者动手之前是空的」。实际是:
第一屏是空的,而且每一次开箱 pnpm demo 都会打 120 条 ERROR,永远如此。
对一个把「启动打了告警就不算通过」写进 AGENTS.md 的仓库,把 120 条 ERROR 当作稳态是自相矛盾的。这一条把四棱里的「防 AI 写错」和「长远合理性」都进一步推向 B——原来只有「实际业务需求」和「防错」偏 B,现在是四棱里三棱明确偏 B,只剩「不扩散」(B 要发明三组凭据)还站在 A 那边。
还有一点值得注意:平台那条错误信息自己开出的药方,正是 §10 禁止的那一味——"Add the missing sys_user record to the seed"。也就是说平台认为「种子里该有这个用户」,而设计文档说「用户不可种子」。这个分歧本身就是这张卡要你裁的那一刀,只是现在它被平台用 120 条错误每次都喊出来。
C 仍然不推荐,理由不变:拿架构换演示数据的便利,方向反了。但要说清楚——C 同样能消掉这 120 条错误(dev admin 持有合同,名字解析得到),所以它现在是「一步解决三件事」而不是两件。这不改变我的建议,只是让你知道它的全部诱惑。
B 的主要代价没有了。 我原来写 B 的代价是「要发明邮箱密码,一经发布就是产品的一部分」。隔壁的做法把这条消掉了:名单文件不进产物,脚本只打本机(它连 --url 不是本机都拒绝执行,理由是「客户组织里出现合成用户」是 #640 无条件排除的结果)。所以 B 不是「让 demo 携带凭据」,是「让 demo 能被本机脚本一键配好人」。
Platform card filed per the D ruling above: objectstack-ai/objectstack#25777 — a declarative demo-staffing primitive (app declares demo accounts; os dev creates them, assigns positions, re-evaluates sharing rules and verifies sign-in, localhost only). Class ③, unlabelled, awaiting triage there.
fix commit f00e8d5 is an ancestor of tag @objectstack/spec@18.2.0
main now pins @objectstack/* 18.2.0 (PR #155, merge 21f2319, push CI Validate success), so the fix is installable in this repo. The ruling recorded in the body stands; this card returns to the queue for dispatch. The dev re-measures the premise on main before writing code.
Claim: PM loop round 17
Ruling-ref: 6396320437
Session: session_017nzWFRUo2U7evMkPdVniAn
Account: zhuangjianguo (the seat's linked user as GET /user answers it; the card's assignee)
Branch: claude/issue-28-demo-staff
Worktree: hotclm-issue-28
Domain: repo:hotclm (single-lane sister repo — no domain:*)
Seat: repo:hotclm#1
File surface: objectstack.config.ts (the demoStaff declaration) · scripts/demo.mjs (drop the operator note) · README.md (drop the hand-made-accounts section, describe the declared staff) · package.json scripts only if the demo commands need it — 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 (an out-of-the-box account that can open 我的合同) | objectstack-ai/objectstack#25777 shipped in 18.2.0 | everyone who runs pnpm demo
Thread-read: 6437403870
Premise: re-measured by the dev on origin/main2cbcb8b (@objectstack 18.2.0) first
Serial constraints cleared: in flight #31 (datasets), #157 (hook display_name), #156 (flows) — disjoint files; #41 and #19 (seeds) follow this card.
{
"issue": 28,
"status": "done",
"branch": "claude/issue-28-demo-staff",
"pr": "https://github.com/objectstack-ai/hotclm/pull/171",
"session": "session_017nzWFRUo2U7evMkPdVniAn",
"premise_still_valid": true,
"summary": "objectstack.config.ts declares demoStaff (18.2.0, objectstack#25777 / f00e8d5), gated on CLM_DEMO_SEED like data. It lists 11 accounts. Business Requester 1-3 take no position and are named from CONTRACT_OWNERS. Legal Counsel 1-2 take clm_legal_counsel and are named from LEGAL_OWNERS. Head of Legal, Finance Controller, Executive, General Manager, Records Manager and CLM Administrator take one position each. All use @example.com addresses and no password, because the platform signs them in with the dev seed password admin123. scripts/demo.mjs drops the closing operator note and the roster read behind it, and its dev-admin priming boot is unchanged. README replaces the hand-made-accounts section with the declared staff, their addresses and the shared password, and says where they exist. The premise has partly moved: on main the dev admin already opens 我的合同 (isDefault from #11 Q1) and holds all 120 contracts through the seed claim. The core of the card still held: no persona account existed and 404 seed references stayed unresolved. demoStaff cannot express a manager, because its schema is strictly name, email, position? and permissionSets?. Measured: manager_id is NULL on all 11 accounts after pnpm demo. README therefore keeps the Set Manager step for that part only, with no app-side workaround.",
"tests": "Browser: Chromium /opt/pw-browsers/chromium, zh-CN, port 3149, every reading signed in as the persona. BEFORE (origin/main 2cbcb8b, fresh DB, pnpm demo): 1 account (Dev Admin), which lands on 我的合同 › 我发起的 holding all 120 claimed contracts. legal_owner NULL ×120. Log: 404 ERROR [SeedLoader] Deferred reference UNRESOLVED (owner_id 120, legal_owner 68, obligation.owner 199, decided_by 17), 20 WARN [Seeder] ✗ lines, and the summary WARN '404 dropped record(s) and 404 error(s)'. AFTER (head b14b3cc, pnpm demo and pnpm demo:zh, each on a fresh DB, no manual step): sys_user 12, sys_user_position 8 (all with organization_id). owner_id 43/43/34; legal_owner 34/34 + 52 NULL; obligation.owner 50/53/40/29/27 + 1 NULL; decided_by 10/7 + 8 NULL. Every account signed in with admin123 and saw no change-password prompt. Requesters 1/2/3 landed on 我的合同 › 我发起的 with 43/43/34 rows; 我负责的履约 showed 23/26/18 open. Counsel 1/2 landed on 法务工作台 with 我的审查 34/34. Head of Legal: 法务工作台, 全部合同 120. Finance: 财务, 收付款计划 300, 生效合同 60. Records: 执行与档案, 待执行 6, 待归档 7, 合同台账 82. CLM Administrator: 管理 › 审批矩阵. Executive and GM: 我的合同 + 分析. zh repeated requester1 43/23, counsel1 34, finance 60, records 6. IDEMPOTENCY: a second pnpm demo and a second pnpm demo:zh on the same DB both kept 12 accounts and 8 positions. Managers set before the re-run through POST /api/v1/auth/admin/set-user-manager (200 ×3) were kept, and each re-run logged only the Plugin superseded WARN. BOOT LINES: branch first runs printed 0 ERROR and 2 WARN (Plugin superseded, Inline seed exceeded 8000ms budget), both also present on main. Both builds print the same 6 author-time compile warnings and the same hierarchy-security line, and no PROVISIONAL line appeared. pnpm dev on a fresh DB: 1 account, demoStaff off. CONSOLE: the platform's '[auth] demoStaff: … created … (admin123)' line is info level and does not show in default os dev output, so README names the accounts and the password. Reverse check: position 'clm_nope' made CLM_DEMO_SEED=1 pnpm validate exit 1 ('Demo account 'Head of Legal' (stack.demoStaff[5]) is assigned position 'clm_nope', which this stack does not declare') while plain pnpm validate exited 0. The change was restored from HEAD and git diff HEAD came back empty. No ablation: no tested behaviour changed.",
"gates": "On head b14b3cc's tree: pnpm install exit 0. pnpm validate exit 0 ('✓ Validation passed'). pnpm lint exit 0 ('6 suggestion(s)', 0 warnings; main's config gives the same 6 suggestions and 0 warnings on this tree, so #64's warning is already gone on main). pnpm typecheck exit 0. pnpm lint:i18n-gate exit 0 ('COVERAGE : 0 missing keys across 2 locale(s)'). CLM_DEMO_SEED=1 pnpm validate exit 0. CI on PR #171 had not been read at report time (in_progress).",
"dogfood_battery": "n/a — sister repo (hotclm), no `!` in the PR title, no (narrowing) arm",
"mcp_calls": "0",
"api_writes": "2 — fleet-write relay: pr_create (POST /repos/objectstack-ai/hotclm/pulls + POST /issues/171/assignees, one dispatch); post-stamped os-dev-report comment POST /repos/objectstack-ai/hotclm/issues/28/comments. git push is not counted.",
"open_questions": [
{
"question": "demoStaff cannot carry a line manager, so rung 1 of the approval ladder stalls on a fresh pnpm demo until someone runs Set Manager by hand. Should we ask the platform for this?",
"options": [
"A: file a platform card asking for an optional `manager` field on a demoStaff entry (naming another entry), and keep README's manual Set Manager step until it ships",
"B: accept the manual step permanently"
],
"recommendation": "A. The ruling's intent is that `pnpm demo` needs no operator step, and the manager is the one step left. It is the same class of fact as the position, and only the platform can write manager_id (an admin operation)."
}
],
"out_of_scope_findings": [
"carrier: #41 / #19 (the seed cards that follow #28 per the claim) · clm_review.reviewer still names the Dev Admin, although the demo staff now exist while the seed runs, so the 60 reviews could be dealt to Legal Counsel 1/2. src/data/keys.ts comments (lines ~124, ~199) still say 'the operator creates the accounts and runs pnpm demo again', which is now stale. Both are outside this card's file surface. Noted, not filed.",
"carrier: none · With demoStaff armed, the platform defers the inline seed to kernel:bootstrapped, after the dev admin exists. scripts/demo.mjs's two-boot priming may therefore be redundant. Not measured. Noted in the PR's Acceptance notes.",
"carrier: none · README 'Rung 1' paragraph 'Skip it and the request opens on a slot nobody holds — pending_approvers reads manager:undefined (#22558)': objectstack#22558 is closed, and the 18.2 author-time warning says an unset manager opens the request on the organization's administrators. Possibly stale, not measured (no approval was driven). Noted in Acceptance notes."
],
"persona_dispatch_rule_for_the_seat": "How devs should create personas from now on. (1) Use the demo staff and do not hand-create accounts. Run `pnpm demo` or `pnpm demo:zh` on a fresh DB and sign in as one of the 11 declared accounts with password admin123 (no create-user call, no change-password step; these accounts have no mustChangePassword): requester1/2/3@example.com (Business Requester 1-3, no position); counsel1/2@example.com (Legal Counsel 1-2, clm_legal_counsel); legal.head@example.com (clm_legal_head); finance@example.com (clm_finance_controller); executive@example.com (clm_executive); gm@example.com (clm_general_manager); records@example.com (clm_records_manager); clm.admin@example.com (clm_admin). (2) The manager is the one manual step. As the dev admin, POST /api/v1/auth/admin/set-user-manager {userId, managerId} for each requester, typically pointing them at Executive (README Rung 1). A re-run keeps the manager. (3) To add a persona permanently, add an entry to `demoStaff` in objectstack.config.ts ({name, email, position?, permissionSets?}). It may name only positions and sets the stack declares (validate refuses others), and it takes no password key. The next `pnpm demo` creates it, idempotently. (4) Only for a throwaway persona outside the declared set does the old route apply: create-user, sys_user_position by position name, and change-password because of mustChangePassword.",
"governed_text_proposal": "DESIGN.md §10, last paragraph: replace 「用户不可种子;各岗位账号在 Setup 建用户后分配 position(…);业务承办 ×3 不是 position,`clm_requester` 是全员默认集,在 Setup 直接授予。」 with 「用户不可种子:fixture 里没有 sys_user 行。演示账号由应用在 `objectstack.config.ts` 的 `demoStaff` 里声明,由平台在本地开发启动时创建(只随 `pnpm demo` 的 `CLM_DEMO_SEED` 开关、幂等、`os build` 不写进产物)。名单为:业务承办 ×3(Business Requester 1–3);法务经办 ×2(Legal Counsel 1–2);法务负责人、财务负责人、分管领导、总经理、档案与记录管理员、CLM 管理员各一。业务承办不是 position,`clm_requester` 是全员默认集(isDefault),不需授予。直属经理(`manager_id`)`demoStaff` 无法声明,仍在 Setup → Users → Set Manager 手动设置。」 The seat carries this on PR #120."
}
Release: pnpm demo now creates 11 demo accounts (requesters, counsel, head of legal, finance, executive, GM, records, CLM admin), signed in with the development password, each opening its own workbench with no manual step. The one step left is setting the requesters' manager; the platform card for it is linked in the next comment. State: pm:dispatched removed, assignee cleared.
Activity
hotlong commentedon Sep 7, 2026
补一条实测,它改变了 A 的代价
我在开这张卡时写的是「名字解析不到就静默落 NULL」。那是错的。 卡 10(#29 / PR #30)在做启动基线对比时报了这件事,我在
main@fb549e3上用全新数据库自己复跑,它是对的:×120,外加一条
WARN [Seeder] ✗ … and 100 more error(s)汇总。行数不受影响(820 行,120 份合同 owner_id 全 NULL)。我第一次复测时也拿到了「0 错误」——因为 820 行内联种子超了 8 秒预算,转入后台继续,而我在
Server is ready之后就去 grep 了。就绪横幅出现在 23:51:07,错误出现在 23:52:22,我早看了 75 秒。这是同一个失败形状的又一次变装:过早读取的日志和干净的日志不可区分。对选项的影响
A 的代价要重写。 原来写的是「第一屏在操作者动手之前是空的」。实际是:
对一个把「启动打了告警就不算通过」写进
AGENTS.md的仓库,把 120 条 ERROR 当作稳态是自相矛盾的。这一条把四棱里的「防 AI 写错」和「长远合理性」都进一步推向 B——原来只有「实际业务需求」和「防错」偏 B,现在是四棱里三棱明确偏 B,只剩「不扩散」(B 要发明三组凭据)还站在 A 那边。还有一点值得注意:平台那条错误信息自己开出的药方,正是 §10 禁止的那一味——"Add the missing
sys_userrecord to the seed"。也就是说平台认为「种子里该有这个用户」,而设计文档说「用户不可种子」。这个分歧本身就是这张卡要你裁的那一刀,只是现在它被平台用 120 条错误每次都喊出来。C 仍然不推荐,理由不变:拿架构换演示数据的便利,方向反了。但要说清楚——C 同样能消掉这 120 条错误(dev admin 持有合同,名字解析得到),所以它现在是「一步解决三件事」而不是两件。这不改变我的建议,只是让你知道它的全部诱惑。
我的建议仍是 B,现在更强。但它要发明产品内容(三个人的名字、邮箱、密码,且一经发布就是产品的一部分),所以仍然是你的决定,不是循环的。
Generated by Claude Code
hotlong commentedon Sep 8, 2026
选项 B 不是新发明——隔壁仓库已经做过一遍,而且是完整版
我在给卡 11 找 i18n 参考时翻到
objectstack-ai/hotcrm,发现它面对的是同一个问题,答案就是 B,而且已经跑了很久:scripts/demo-staff.ts(它的 #640)做四步,全部幂等:POST /api/v1/auth/admin/create-user建人——它的注释特意说明为什么必须走这个口而不是直接插sys_user:后者被 ADR-0092 的写入守卫拒绝,就算插进去也是个登不进去的行;sys_user_position);而人员名单单独放在
src/sharing/demo-staffing.ts,objectstack.config.ts从不 import 它——「真实部署不会装进这些人」是结构性的,不是靠自觉。名单本身还有一条纪律:这对 #28 的影响
B 的主要代价没有了。 我原来写 B 的代价是「要发明邮箱密码,一经发布就是产品的一部分」。隔壁的做法把这条消掉了:名单文件不进产物,脚本只打本机(它连
--url不是本机都拒绝执行,理由是「客户组织里出现合成用户」是 #640 无条件排除的结果)。所以 B 不是「让 demo 携带凭据」,是「让 demo 能被本机脚本一键配好人」。而且它顺带解掉了我刚报的那个平台坑。 上一轮我报了 objectstack#16712——给引导后创建的用户插
sys_user_position不解析权限。HotCRM 的脚本头解释了其中一半:也就是说第 3 步不是可选的,而是「光配人不够」的原因。我已经把这段补进 #16712,并说明我报的那一半(导航为空 = 权限集没解析)可能和这一半(行级授权没物化)是两个不同的机制,我没有分开测过,不该让那张卡暗示一个它没验证的区分。
建议不变,但理由更硬了
仍然推荐 B。现在它是:照抄隔壁一个已经在跑、有验证步骤、有「不进产物」结构保证的方案,而不是从零发明产品内容。
⛔ 但仍然是你的决定,有两点必须你定:
Business Requester 1/2/3是我起的占位名,卡 26 的 agent 也把这一条列为要你定的。如果你回 B,我会照
demo-staff.ts的形状派一张卡,并要求它把「第 3 步不可省」和验证步骤原样带过来——那是这个方案里最容易被省掉、省掉后又完全看不出来的一步。Generated by Claude Code
zhuangjianguo commentedon Oct 25, 2026
Ruling: batch #3 item 1 · letter D · maintainer 「同意」 2026-10-25T10:07:34Z
裁定:D(新增项)—— 演示账号由平台建;hotclm 等平台,期间维持 A
维护者在第 3 批决策箱回了「同意」(= 推荐项 D,回退 B)。裁决文档:https://claude.ai/artifact/N1GCqHkEVMy3kneFmVEM8w 。D 是本席按维护者 2026-10-25 的规则(「本项目是元数据应用,平台相关的功能应该在平台开发」)在正文 A/B/C 之外新增的选项。
鲜度门:正文 2026-09-07T23:03Z;评论两条,最后一条 2026-09-08T00:36Z(HotCRM
demo-staff.ts先例)。main134707e 复测:scripts/demo.mjs只在结尾打操作员说明(#49、#106),不建账号;README 74/109 行仍是「A seed cannot create a user」与「create the accounts and runpnpm demoagain」。录裁前重读,无变化。为什么是平台的事:HotCRM 已在应用里写了一遍(
scripts/demo-staff.ts:走create-user门、配岗、重求值共享规则、以每个账号身份验证三层连通),hotclm 是第二份拷贝,hotsrm 会是第三份。三份拷贝的要害都是同一条平台内部事实(plugin-sharing在isSystem写入时不物化授权,所以第 3 步不可省),这种知识属于平台;平台自己已有同形机制(maybeSeedDevAdmin在 dev 启动时铸一个能登录的管理员)。objectstack 去重:演示人员原语为 0。⛔ C 已出局(#11 第一问裁 A)。B 为回退项(若维护者要 demo 第一屏现在就能看)。
裁后执行
os dev/os demo在本机幂等地建号、配岗、重求值共享规则、验证登录,非本机拒绝),回链见下一条评论;本卡Blocked-by它。Business Requester 1/2/3、Legal Counsel 1/2,维护者未要求更名),README 删掉手建账号那一节与demo.mjs的操作员说明。[Decision]DESIGN.md§04 makesclm_requesterevery employee's default, but a set that grantsclm_requester.accesscannot bind toeveryone#11 Q1 的收回动作(isDefault)落地后连权限集都不用声明。§10「用户不可种子」不受影响:演示人员不进 fixture、不进产物。⛔ 本席不动标签;lane 席位派发时转标签并带
Ruling-ref:。Generated by Claude Code
zhuangjianguo commentedon Oct 25, 2026
Platform card filed per the D ruling above: objectstack-ai/objectstack#25777 — a declarative demo-staffing primitive (app declares demo accounts;
os devcreates them, assigns positions, re-evaluates sharing rules and verifies sign-in, localhost only). Class ③, unlabelled, awaiting triage there.Blocked-by: objectstack-ai/objectstack#25777
Generated by Claude Code
objectstack-fleet commentedon Oct 25, 2026
Out of the decision box — Ruling-ref: comment 6396320437 (batch #3 · letter D · maintainer 「同意」).
needs-user-decision→pm:blocked,Blocked-by: objectstack-ai/objectstack#25777(platform demo-staffing primitive). Interim: status quo, no app-side account script.Generated by Claude Code
objectstack-fleet commentedon Oct 27, 2026
Unblocked — 2026-10-27
closedf00e8d5is an ancestor of tag@objectstack/spec@18.2.0mainnow pins@objectstack/*18.2.0 (PR #155, merge21f2319, push CIValidatesuccess), so the fix is installable in this repo. The ruling recorded in the body stands; this card returns to the queue for dispatch. The dev re-measures the premise onmainbefore writing code.State:
pm:blocked→pm:queue.Generated by Claude Code
objectstack-fleet commentedon Oct 27, 2026
Claim: PM loop round 17
Ruling-ref: 6396320437
Session:
session_017nzWFRUo2U7evMkPdVniAnAccount:
zhuangjianguo(the seat's linked user asGET /useranswers it; the card's assignee)Branch:
claude/issue-28-demo-staffWorktree:
hotclm-issue-28Domain:
repo:hotclm(single-lane sister repo — nodomain:*)Seat:
repo:hotclm#1File surface:
objectstack.config.ts(thedemoStaffdeclaration) ·scripts/demo.mjs(drop the operator note) ·README.md(drop the hand-made-accounts section, describe the declared staff) ·package.jsonscripts only if the demo commands need it — 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 (an out-of-the-box account that can open 我的合同) | objectstack-ai/objectstack#25777 shipped in 18.2.0 | everyone who runs pnpm demoThread-read: 6437403870
Premise: re-measured by the dev on
origin/main2cbcb8b(@objectstack 18.2.0) firstSerial constraints cleared: in flight #31 (datasets), #157 (hook display_name), #156 (flows) — disjoint files; #41 and #19 (seeds) follow this card.
Generated by Claude Code
objectstack-fleet commentedon Oct 27, 2026
os-dev-report
{ "issue": 28, "status": "done", "branch": "claude/issue-28-demo-staff", "pr": "https://github.com/objectstack-ai/hotclm/pull/171", "session": "session_017nzWFRUo2U7evMkPdVniAn", "premise_still_valid": true, "summary": "objectstack.config.ts declares demoStaff (18.2.0, objectstack#25777 / f00e8d5), gated on CLM_DEMO_SEED like data. It lists 11 accounts. Business Requester 1-3 take no position and are named from CONTRACT_OWNERS. Legal Counsel 1-2 take clm_legal_counsel and are named from LEGAL_OWNERS. Head of Legal, Finance Controller, Executive, General Manager, Records Manager and CLM Administrator take one position each. All use @example.com addresses and no password, because the platform signs them in with the dev seed password admin123. scripts/demo.mjs drops the closing operator note and the roster read behind it, and its dev-admin priming boot is unchanged. README replaces the hand-made-accounts section with the declared staff, their addresses and the shared password, and says where they exist. The premise has partly moved: on main the dev admin already opens 我的合同 (isDefault from #11 Q1) and holds all 120 contracts through the seed claim. The core of the card still held: no persona account existed and 404 seed references stayed unresolved. demoStaff cannot express a manager, because its schema is strictly name, email, position? and permissionSets?. Measured: manager_id is NULL on all 11 accounts after pnpm demo. README therefore keeps the Set Manager step for that part only, with no app-side workaround.", "tests": "Browser: Chromium /opt/pw-browsers/chromium, zh-CN, port 3149, every reading signed in as the persona. BEFORE (origin/main 2cbcb8b, fresh DB, pnpm demo): 1 account (Dev Admin), which lands on 我的合同 › 我发起的 holding all 120 claimed contracts. legal_owner NULL ×120. Log: 404 ERROR [SeedLoader] Deferred reference UNRESOLVED (owner_id 120, legal_owner 68, obligation.owner 199, decided_by 17), 20 WARN [Seeder] ✗ lines, and the summary WARN '404 dropped record(s) and 404 error(s)'. AFTER (head b14b3cc, pnpm demo and pnpm demo:zh, each on a fresh DB, no manual step): sys_user 12, sys_user_position 8 (all with organization_id). owner_id 43/43/34; legal_owner 34/34 + 52 NULL; obligation.owner 50/53/40/29/27 + 1 NULL; decided_by 10/7 + 8 NULL. Every account signed in with admin123 and saw no change-password prompt. Requesters 1/2/3 landed on 我的合同 › 我发起的 with 43/43/34 rows; 我负责的履约 showed 23/26/18 open. Counsel 1/2 landed on 法务工作台 with 我的审查 34/34. Head of Legal: 法务工作台, 全部合同 120. Finance: 财务, 收付款计划 300, 生效合同 60. Records: 执行与档案, 待执行 6, 待归档 7, 合同台账 82. CLM Administrator: 管理 › 审批矩阵. Executive and GM: 我的合同 + 分析. zh repeated requester1 43/23, counsel1 34, finance 60, records 6. IDEMPOTENCY: a second pnpm demo and a second pnpm demo:zh on the same DB both kept 12 accounts and 8 positions. Managers set before the re-run through POST /api/v1/auth/admin/set-user-manager (200 ×3) were kept, and each re-run logged only the Plugin superseded WARN. BOOT LINES: branch first runs printed 0 ERROR and 2 WARN (Plugin superseded, Inline seed exceeded 8000ms budget), both also present on main. Both builds print the same 6 author-time compile warnings and the same hierarchy-security line, and no PROVISIONAL line appeared. pnpm dev on a fresh DB: 1 account, demoStaff off. CONSOLE: the platform's '[auth] demoStaff: … created … (admin123)' line is info level and does not show in default os dev output, so README names the accounts and the password. Reverse check: position 'clm_nope' made CLM_DEMO_SEED=1 pnpm validate exit 1 ('Demo account 'Head of Legal' (stack.demoStaff[5]) is assigned position 'clm_nope', which this stack does not declare') while plain pnpm validate exited 0. The change was restored from HEAD and git diff HEAD came back empty. No ablation: no tested behaviour changed.", "gates": "On head b14b3cc's tree: pnpm install exit 0. pnpm validate exit 0 ('✓ Validation passed'). pnpm lint exit 0 ('6 suggestion(s)', 0 warnings; main's config gives the same 6 suggestions and 0 warnings on this tree, so #64's warning is already gone on main). pnpm typecheck exit 0. pnpm lint:i18n-gate exit 0 ('COVERAGE : 0 missing keys across 2 locale(s)'). CLM_DEMO_SEED=1 pnpm validate exit 0. CI on PR #171 had not been read at report time (in_progress).", "dogfood_battery": "n/a — sister repo (hotclm), no `!` in the PR title, no (narrowing) arm", "mcp_calls": "0", "api_writes": "2 — fleet-write relay: pr_create (POST /repos/objectstack-ai/hotclm/pulls + POST /issues/171/assignees, one dispatch); post-stamped os-dev-report comment POST /repos/objectstack-ai/hotclm/issues/28/comments. git push is not counted.", "open_questions": [ { "question": "demoStaff cannot carry a line manager, so rung 1 of the approval ladder stalls on a fresh pnpm demo until someone runs Set Manager by hand. Should we ask the platform for this?", "options": [ "A: file a platform card asking for an optional `manager` field on a demoStaff entry (naming another entry), and keep README's manual Set Manager step until it ships", "B: accept the manual step permanently" ], "recommendation": "A. The ruling's intent is that `pnpm demo` needs no operator step, and the manager is the one step left. It is the same class of fact as the position, and only the platform can write manager_id (an admin operation)." } ], "out_of_scope_findings": [ "carrier: #41 / #19 (the seed cards that follow #28 per the claim) · clm_review.reviewer still names the Dev Admin, although the demo staff now exist while the seed runs, so the 60 reviews could be dealt to Legal Counsel 1/2. src/data/keys.ts comments (lines ~124, ~199) still say 'the operator creates the accounts and runs pnpm demo again', which is now stale. Both are outside this card's file surface. Noted, not filed.", "carrier: none · With demoStaff armed, the platform defers the inline seed to kernel:bootstrapped, after the dev admin exists. scripts/demo.mjs's two-boot priming may therefore be redundant. Not measured. Noted in the PR's Acceptance notes.", "carrier: none · README 'Rung 1' paragraph 'Skip it and the request opens on a slot nobody holds — pending_approvers reads manager:undefined (#22558)': objectstack#22558 is closed, and the 18.2 author-time warning says an unset manager opens the request on the organization's administrators. Possibly stale, not measured (no approval was driven). Noted in Acceptance notes." ], "persona_dispatch_rule_for_the_seat": "How devs should create personas from now on. (1) Use the demo staff and do not hand-create accounts. Run `pnpm demo` or `pnpm demo:zh` on a fresh DB and sign in as one of the 11 declared accounts with password admin123 (no create-user call, no change-password step; these accounts have no mustChangePassword): requester1/2/3@example.com (Business Requester 1-3, no position); counsel1/2@example.com (Legal Counsel 1-2, clm_legal_counsel); legal.head@example.com (clm_legal_head); finance@example.com (clm_finance_controller); executive@example.com (clm_executive); gm@example.com (clm_general_manager); records@example.com (clm_records_manager); clm.admin@example.com (clm_admin). (2) The manager is the one manual step. As the dev admin, POST /api/v1/auth/admin/set-user-manager {userId, managerId} for each requester, typically pointing them at Executive (README Rung 1). A re-run keeps the manager. (3) To add a persona permanently, add an entry to `demoStaff` in objectstack.config.ts ({name, email, position?, permissionSets?}). It may name only positions and sets the stack declares (validate refuses others), and it takes no password key. The next `pnpm demo` creates it, idempotently. (4) Only for a throwaway persona outside the declared set does the old route apply: create-user, sys_user_position by position name, and change-password because of mustChangePassword.", "governed_text_proposal": "DESIGN.md §10, last paragraph: replace 「用户不可种子;各岗位账号在 Setup 建用户后分配 position(…);业务承办 ×3 不是 position,`clm_requester` 是全员默认集,在 Setup 直接授予。」 with 「用户不可种子:fixture 里没有 sys_user 行。演示账号由应用在 `objectstack.config.ts` 的 `demoStaff` 里声明,由平台在本地开发启动时创建(只随 `pnpm demo` 的 `CLM_DEMO_SEED` 开关、幂等、`os build` 不写进产物)。名单为:业务承办 ×3(Business Requester 1–3);法务经办 ×2(Legal Counsel 1–2);法务负责人、财务负责人、分管领导、总经理、档案与记录管理员、CLM 管理员各一。业务承办不是 position,`clm_requester` 是全员默认集(isDefault),不需授予。直属经理(`manager_id`)`demoStaff` 无法声明,仍在 Setup → Users → Set Manager 手动设置。」 The seat carries this on PR #120." }pnpm demo creates the demo staff itself (#171)
objectstack-fleet commentedon Oct 27, 2026
Ruling-ref: 6396320437
Landed — PR #171 · 2026-10-27
MERGED(squash onmain), merged at its ACCEPT headb14b3cc;Fixes #28closes this cardRelease:
pnpm demonow creates 11 demo accounts (requesters, counsel, head of legal, finance, executive, GM, records, CLM admin), signed in with the development password, each opening its own workbench with no manual step. The one step left is setting the requesters' manager; the platform card for it is linked in the next comment. State:pm:dispatchedremoved, assignee cleared.Generated by Claude Code
DESIGN §10: demo accounts are declared in demoStaff and created by th…
objectstack-fleet commentedon Oct 27, 2026
The one manual step left (the requesters' line manager) is filed upstream: objectstack-ai/objectstack#26616 (
demoStaffcannot name a manager).Generated by Claude Code
fix(console): an app that serves the caller no navigation opens on an…