Skip to content

[Decision] pnpm demo 开箱即用时没有任何账号能打开「我的合同」——要不要让脚本建账号,与 #11 第一问耦合 #28

Closed

Description

@hotlong

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)

Blocked-by: objectstack-ai/objectstack#25777

维护者速读

事情:卡 26(#26 / PR #27)把 120 份种子合同按相对方分给了 §10 的三个「业务承办」,43 / 43 / 34。但开箱即用时这三个账号并不存在,名字解析不到就静默落 NULL,所以 pnpm demo 跑完,「我的合同 › 我发起的」仍然是空的,要等你在 Setup 里建好账号、再跑一次 pnpm demo(数据集是 upsert,会自动交接)才填上。

为什么这不只是「少一步」:实测下来,开箱状态更彻底——pnpm demo 只产出一个账号(dev admin),而 dev admin 不持有任何 clm_* 权限集,GET /api/v1/meta/app/clm 给它返回 navigation: []。所以开箱即用时,没有任何一个账号能打开「我的合同」这个分区,跟这张卡改没改都无关。对一个「能直接卖」的产品,这意味着 demo 的第一屏永远要靠一段说明书才能看到。

你要做的:回一个字母。A、B 或 C。


选项

A — 维持现状(卡 26 已交付的形态)。 fixture 写好名字,操作者在 Setup 建账号再跑一次;README 写明了三个名字和分配,pnpm demo 结束时也会在终端打出来。
代价:§10 一字未动,没有虚构人物,但第一屏在操作者动手之前是空的。

B — 让 scripts/demo.mjs 自己建这三个账号并各授予 clm_requester。 之后 pnpm demo 一条命令就能演示。
代价:§10 说「用户不可种子」约束的是 fixture,脚本不是 fixture——但这仍然是建账号,而且要发明邮箱与密码,那是产品内容不是工程细节。约 40 行,用的两个端点这张卡的验收里已经跑通(POST /api/v1/auth/admin/create-user 加一行 sys_user_permission_set)。

C — 把 #11 第一问判成 B(「我的合同」去掉 clm_requester.access 门控,登录即见),然后让 dev admin 分一份合同。
代价:最省事,但它是另一张卡的决定,而且会掏空 §04/§05 那套 *.access 令牌体系的一致性。

两问为什么耦合

如果 #11 判 B,dev admin 就能看见「我的合同」;而平台的 claimSeedOwnership 在单次启动下本来就会把 120 份全认领给它(实测 adminPromoted: true, ownershipClaimed: 260)。也就是说 C 一步同时解决两件事,一个新账号都不用建——代价是拿走一个门控开关。

反过来,如果 #11 判 A(我推荐的,也是卡 07 已实现的),那 B 就是让 demo 开箱可用的唯一路子,因为 A 的世界里 dev admin 永远看不到那个分区。

⇒ 先回 #11 第一问,这一张的答案就基本定了。 单独回这一张也行,但两张一起回只用想一次。

四棱分析

实际业务需求 — 偏 B。这是买家 demo 的第一屏,「跑一条命令就能看到东西」和「先读一页说明书建三个账号」对销售转化不是一个量级。A 的成本全部落在最不该承担成本的人身上——第一次接触这个产品的人。

项目长远合理性 — 偏 A 或 B,明确反对 C。C 用一个门控决定去换 demo 数据的便利,是拿架构换演示,方向反了;§04/§05 整套导航建立在五个 *.access 令牌上,抽掉一个,下一个作者照抄的就是「分区可以不门控」。A 与 B 都不动架构,区别只在这段建账号的代码放在 fixture 外面算不算越界——我认为不算,§10 那句话防的是「种子数据里出现假用户」,脚本在开发机上建演示账号是另一回事。

防 AI 写错 — 偏 B,理由不直观。A 依赖的是操作者照着 README 把名字一字不差地打对(Business Requester 1),打错一个字符就静默落 NULL、无报错无告警——这正是这个仓库一直在防的失败形状:一个静默的空结果和一个正确的空结果不可区分。B 把这个交接从人手里拿走,变成代码里的一个常量。

创业阶段不扩散 — 偏 A。B 要发明三个人的邮箱密码,等于 demo 开始携带凭据;一旦发布,这三组凭据就是产品的一部分了。这是 B 唯一的实质代价,也是它必须由你而不是由循环来定的原因。

结论:四棱里三棱偏 B,一棱(不扩散)偏 A,C 被长远合理性明确反对。我推荐 B,并建议账号名换成像真人的名字(Business Requester 1 是我起的占位,卡 26 的 agent 也把这一条列为要你定的)。但 B 要发明产品内容,所以它是你的决定,不是循环的。

影响

不阻塞任何在途卡片。M3 的卡 09–14 都不读这一条。答案影响的是 scripts/demo.mjs、README 那一节,以及(若选 C)src/apps/clm.app.ts 第 81 行。

关联

#26 / PR #27(这一条的来源,fixture 半边已交付)· #11 第一问(耦合的那一半)· #19(另一块空屏:合同版本,另有原因,仍在等裁定)· #18 / PR #21(两次启动交接,也就是无意中关掉归属认领的那次修复)。

Activity

  1. hotlong commented on Sep 7, 2026

    @hotlong
    ContributorAuthor

    补一条实测,它改变了 A 的代价

    我在开这张卡时写的是「名字解析不到就静默落 NULL」。那是错的。 卡 10(#29 / PR #30)在做启动基线对比时报了这件事,我在 main @ fb549e3 上用全新数据库自己复跑,它是对的:

    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,现在更强。但它要发明产品内容(三个人的名字、邮箱、密码,且一经发布就是产品的一部分),所以仍然是你的决定,不是循环的。


    Generated by Claude Code

  2. hotlong commented on Sep 8, 2026

    @hotlong
    ContributorAuthor

    选项 B 不是新发明——隔壁仓库已经做过一遍,而且是完整版

    我在给卡 11 找 i18n 参考时翻到 objectstack-ai/hotcrm,发现它面对的是同一个问题,答案就是 B,而且已经跑了很久:

    package.json:
      "demo:staff": "tsx scripts/demo-staff.ts"
      "demo:reset": "… echo '… then run: pnpm demo:staff'"
    

    scripts/demo-staff.ts(它的 #640)做四步,全部幂等:

    1. 用 POST /api/v1/auth/admin/create-user 建人——它的注释特意说明为什么必须走这个口而不是直接插 sys_user:后者被 ADR-0092 的写入守卫拒绝,就算插进去也是个登不进去的行;
    2. 分配岗位(sys_user_position);
    3. 重新求值每一条生效的共享规则;
    4. 以每个 demo 用户的身份验证三层真的连通了,不通就非零退出。

    而人员名单单独放在 src/sharing/demo-staffing.ts,objectstack.config.ts 从不 import 它——「真实部署不会装进这些人」是结构性的,不是靠自觉。名单本身还有一条纪律:

    「一个岗位背后没有机制,就算填上去更整齐也留空……给岗位配人是一个决定,不是一次整理」

    这对 #28 的影响

    B 的主要代价没有了。 我原来写 B 的代价是「要发明邮箱密码,一经发布就是产品的一部分」。隔壁的做法把这条消掉了:名单文件不进产物,脚本只打本机(它连 --url 不是本机都拒绝执行,理由是「客户组织里出现合成用户」是 #640 无条件排除的结果)。所以 B 不是「让 demo 携带凭据」,是「让 demo 能被本机脚本一键配好人」。

    而且它顺带解掉了我刚报的那个平台坑。 上一轮我报了 objectstack#16712——给引导后创建的用户插 sys_user_position 不解析权限。HotCRM 的脚本头解释了其中一半:

    plugin-sharing 的授权是从记录写入钩子里物化的,而该钩子在 isSystem 写入时提前返回,每一行种子数据都是 isSystem: true 写的。所以无论谁持有岗位,种子账号都不带任何授权,直到某条规则被重新求值。

    也就是说第 3 步不是可选的,而是「光配人不够」的原因。我已经把这段补进 #16712,并说明我报的那一半(导航为空 = 权限集没解析)可能和这一半(行级授权没物化)是两个不同的机制,我没有分开测过,不该让那张卡暗示一个它没验证的区分。

    建议不变,但理由更硬了

    仍然推荐 B。现在它是:照抄隔壁一个已经在跑、有验证步骤、有「不进产物」结构保证的方案,而不是从零发明产品内容。

    ⛔ 但仍然是你的决定,有两点必须你定:

    1. 三个业务承办叫什么。 Business Requester 1/2/3 是我起的占位名,卡 26 的 agent 也把这一条列为要你定的。
    2. 要不要顺带把 §04 的七个岗位也配上人。 HotCRM 的纪律是「岗位背后没有机制就留空」——按这条,HotCLM 该配的是能让机制跑起来的那几个(审批阶梯的审批人、法务受理人),而不是七个填满。这一条比名字更值得你花两分钟。

    如果你回 B,我会照 demo-staff.ts 的形状派一张卡,并要求它把「第 3 步不可省」和验证步骤原样带过来——那是这个方案里最容易被省掉、省掉后又完全看不出来的一步。


    Generated by Claude Code

  3. zhuangjianguo commented on Oct 25, 2026

    @zhuangjianguo
    Collaborator

    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 先例)。main 134707e 复测:scripts/demo.mjs 只在结尾打操作员说明(#49、#106),不建账号;README 74/109 行仍是「A seed cannot create a user」与「create the accounts and run pnpm demo again」。录裁前重读,无变化。

    为什么是平台的事:HotCRM 已在应用里写了一遍(scripts/demo-staff.ts:走 create-user 门、配岗、重求值共享规则、以每个账号身份验证三层连通),hotclm 是第二份拷贝,hotsrm 会是第三份。三份拷贝的要害都是同一条平台内部事实(plugin-sharing 在 isSystem 写入时不物化授权,所以第 3 步不可省),这种知识属于平台;平台自己已有同形机制(maybeSeedDevAdmin 在 dev 启动时铸一个能登录的管理员)。objectstack 去重:演示人员原语为 0。

    ⛔ C 已出局(#11 第一问裁 A)。B 为回退项(若维护者要 demo 第一屏现在就能看)。

    裁后执行

    1. 本席立 objectstack 卡(类 ③ 平台缺口:应用在 stack 元数据里声明演示人员,os dev / os demo 在本机幂等地建号、配岗、重求值共享规则、验证登录,非本机拒绝),回链见下一条评论;本卡 Blocked-by 它。
    2. 平台发布后 hotclm:声明五个演示人员(名字沿用 Business Requester 1/2/3、Legal Counsel 1/2,维护者未要求更名),README 删掉手建账号那一节与 demo.mjs 的操作员说明。[Decision] DESIGN.md §04 makes clm_requester every employee's default, but a set that grants clm_requester.access cannot bind to everyone #11 Q1 的收回动作(isDefault)落地后连权限集都不用声明。§10「用户不可种子」不受影响:演示人员不进 fixture、不进产物。
    3. 期间:维持 A,⛔ 不做应用侧脚本。

    ⛔ 本席不动标签;lane 席位派发时转标签并带 Ruling-ref:。


    Generated by Claude Code

  4. zhuangjianguo commented on Oct 25, 2026

    @zhuangjianguo
    Collaborator

    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.

    Blocked-by: objectstack-ai/objectstack#25777


    Generated by Claude Code

  5. objectstack-fleet commented on Oct 25, 2026

    @objectstack-fleet
    Contributor

    Out of the decision box — Ruling-ref: comment 6396320437 (batch #3 · letter D · maintainer 「同意」).

    • State: 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

  6. objectstack-fleet commented on Oct 27, 2026

    @objectstack-fleet
    Contributor

    Unblocked — 2026-10-27

    upstream state installable here
    objectstack-ai/objectstack#25777 closed 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.

    State: pm:blocked → pm:queue.


    Generated by Claude Code

  7. objectstack-fleet commented on Oct 27, 2026

    @objectstack-fleet
    Contributor

    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/main 2cbcb8b (@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.


    Generated by Claude Code

  8. objectstack-fleet commented on Oct 27, 2026

    @objectstack-fleet
    Contributor

    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."
    }
  9. added a commit that references this issue on Oct 27, 2026
    0159171
  10. objectstack-fleet commented on Oct 27, 2026

    @objectstack-fleet
    Contributor

    Ruling-ref: 6396320437

    Landed — PR #171 · 2026-10-27

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

    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.


    Generated by Claude Code

  11. objectstack-fleet commented on Oct 27, 2026

    @objectstack-fleet
    Contributor

    The one manual step left (the requesters' line manager) is filed upstream: objectstack-ai/objectstack#26616 (demoStaff cannot name a manager).


    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