## 背景(来源:交接记录 #22 第三节与 #23 UI 实测复核,维护者以 /os-project-pm-dispatch 放行本批) 一批用户可见的文案与盖章问题,单条都很小,合成一单串行修: | # | 现象 | 位置(初判) | |---|---|---| | 1 | 审核记录列表「原状态 / 新状态」显示 `draft / branch_checking / hr_reviewing …` 内部值 | `kpi_review_record` 的 from_status/to_status 为文本字段,列表直出;改为按 `src/lib/workflow.ts` 的 `STATUS_LABEL` 写入中文(hook 写入时转换)或改字段为带选项的 select 复用状态标签 | | 2 | 核对任务「确认无误 / 提出争议」后「处理人 / 处理时间」仍为空 | `src/hooks/check-task.hook.ts` 未盖章 `decided_by` / `decided_at` | | 3 | 已归档填报单再改明细,提示仍写「填报单已提交,数据已冻结」 | `src/hooks/entry-line.hook.ts` 锁定提示按填报单状态区分「已提交」「已归档」 | | 4 | 结果看板「人员得分」轴与「到人得分」报表显示用户 id 而非姓名;「各组织单元平均得分」出现「(未指定)」柱(分管领导维度无组织单元) | `src/dashboards/index.ts`、`src/reports/index.ts`、`src/datasets/index.ts`:人员维度用显示名(lookup 显示字段或结果记录的 name);组织单元图排除分管领导维度 | | 5 | 归档被拒提示的节点名取流程最后节点(「领导审批」),实际要求人力审核 | `src/hooks/sheet.hook.ts` 拒绝文案取节点的分支(仅改文案取值,不改规则) | | 6 | 必填提示叠字:「争议内容(必填) 为必填项」 | 字段 label 去掉「(必填)」,交给必填标记 | | 7 | 管理员可手工新建填报单(残缺单致页头崩溃,平台 #14888) | `src/hooks/sheet.hook.ts` 新建保护取消 `kpi_admin` 例外,一律拒绝手工新建(文案已就绪);列表「新建」按钮对填报单收掉(权限集 allowCreate=false,发布路径为系统写入不受影响) | `KpiError:` 前缀是平台 toast 拼接,不在本单处理。 ## 范围与不做 只做上表 7 条;不改计分、不改流程规则(第 5、7 条只动文案与新建保护);不动 `src/data/`、`scripts/`(脚本若依赖管理员手工建填报单则如实报告)。改 label 走 `pnpm i18n:extract`。 ## 方案分级与放行(调度员) 低风险小改合批;第 1 条若改字段类型属改已有对象,先在本单评论给出 A(hook 写中文)/ B(改 select)两案与影响面,调度员放行方向 A(不改字段类型);第 7 条取消管理员例外为维护者 2026-09-03 已知悉的建议方向,放行。逐条独立提交、一个 PR 关联本单。 ## 验收标准 1. 审核记录列表状态列显示中文;历史记录处理方式如实说明(不迁移或一次性回填,二选一并记录)。 2. 核对确认/争议后处理人、处理时间盖章为当前用户与时间。 3. 已归档单改数提示含「已归档」。 4. 看板与报表人员维度显示姓名;组织单元平均分不再出现「(未指定)」。 5. 归档被拒提示指向「人力审核」。 6. 必填提示不再叠字。 7. 管理员手工新建填报单被拒且列表无「新建」;发布方案生成填报单正常;`scripts/e2e-flow.mjs`、`scripts/software-flow.mjs` 全 PASS(若脚本靠手工建单,报告说明)。 8. `pnpm verify` 绿;测试报告(逐条截图)与符合度清单挂本单评论,截图走 `acceptance-evidence`。
Activity
baozhoutao commentedon Sep 6, 2026
追加第 8 条(来源:#39 实测遗留,调度员 2026-09-06 并入本单)
91.75999999999999),同行「最终得分」显示91.76kpi_entry_sheet.indicator_score等汇总字段的写入未按字段scale取整,或列表渲染未按 scale 格式化;修法二选一:hook 写入时按字段 scale 四舍五入(推荐,口径唯一在src/lib/scoring.ts/汇总处),或视图列格式化。验收:三处得分合计字段显示两位小数,software-flow/e2e-flow得分断言不变baozhoutao commentedon Sep 6, 2026
追加第 9 条(来源:#36 复查轮记录级,调度员 2026-09-06 并入本单)
src/pages/index.ts顶部注释写「部门填报人员在『待人力审核』里本来就一行都读不到」,与实测相反(本部门单进入人力审核中时能看到 1 行,动作被 hook 422 拒绝)baozhoutao commentedon Sep 6, 2026
issue-38 copy-and-stamps-,worktree/Users/baozhoutao/GitHub/kpi-issue-38 copy-and-stamps-,基线 main @ c197bf4。派发开发子 agent(Opus)。baozhoutao commentedon Sep 6, 2026
issue-38-copy-and-stamps//Users/baozhoutao/GitHub/kpi-issue-38-copy-and-stamps(上一条认领评论的名称为脚本拼接笔误)。baozhoutao commentedon Sep 6, 2026
开工方案(开发子 agent,2026-09-06)
基线 main @ c197bf4,分支
issue-38-copy-and-stamps,实例 3114 /issue-38.db/software档案。逐条实现方式如下,含两处需要调度员确认的边界。第 1 条 审核记录状态中文 —— 两案与影响面(按放行方向 A 开工)
hooks/util.ts的writeReview(),在那里按lib/workflow.ts的STATUS_LABEL转换sheet.hook×2、check-task.hook、plan.hook、adjustment.hook)一次覆盖;字段类型、视图、导出、快照 payload 均不动from_status/to_status全库只被读来展示(视图列、snapshot-service的 payload),没有任何代码按内部值比较(已全仓 grep 核实)entry.object.ts、翻译包重出;导出与快照里存的仍是内部值历史记录处理:不迁移,不回填。 理由:试运行前无正式数据,开发库每轮实测都是空库重建;回填要对已锁定的留痕记录做批量写入,收益为零、风险在留痕对象上。已归档快照 payload 里的历史值同样保持原样。
注意:
writeReview()在hooks/util.ts,派发单的允许改动清单里没有列它(清单列的是sheet.hook.ts/check-task.hook.ts)。但另两个调用点在adjustment.hook.ts(禁触碰)与plan.hook.ts(未列),逐调用点改会碰禁区;改writeReview()一处是覆盖全部且不碰禁区的唯一走法,故按此实现并在此留痕报备。第 2 条 核对盖章 —— 基线复测:已修复,不需要改代码
在本 worktree 基线代码上用 UI 实测(陈东 / 华东分公司核对人员,点「确认无误」):核对人 = 陈东、核对时间 = 2026/9/6 下午12:25,REST 复核
decided_by/decided_at均已落库。check-task.hook.ts的beforeUpdate本就盖章,原来失效是因为免检口径是isSystem(按钮动作体带系统标记 → 直接 return),而 #28 把免检收窄成「无发起人的纯系统写入」后,按钮路径不再免检,盖章随之生效(commit 07d176c 已在基线里)。本条按「已由基线修复」结案,报告附改前/现状截图,不做无谓改动。第 3 条 归档提示
entry-line.hook.ts的修改 / 删除两处冻结提示按填报单状态分岔:archived→ 「填报单已归档,数据已锁定不可再改」;其余非draft状态维持「已提交,数据已冻结……请发起数据调整申请」。三段式不变。第 4 条 看板人员姓名 / 「(未指定)」柱 —— 一半是平台能力问题
抓包核实(
POST /api/v1/analytics/dataset/query):unit维度服务端已把 lookup 解析成名称(返回「财务部」「华东分公司」);person维度返回的是原始 id({"person":"7zLYIwpX82If…","avg_score":124.25})。差别在字段类型:Field.lookup→type: 'lookup',Field.user→type: 'user'(同样带reference: 'sys_user'),数据集维度解析只认前者。这是平台侧的能力缺口,按纪律只上报、不修平台(上报链接随测试报告补)。kpi_result.name(汇总时已写成「方案名 · 姓名」)作为展示维度,看板「人员得分」与「到人得分」报表都换到它。残留偏差:轴标签带方案名前缀(如「2026 年第 3 季度考核 · 王强」),不是纯姓名,会在符合度清单里按unit为空的到人 / 分管领导结果行。给「各组织单元平均得分」加dimension ∈ {部门, 分公司}的固定过滤(与既有「人员得分」挂固定过滤 +filterBindings的写法一致),标题相应写明范围。第 5 条 归档拒绝节点名
基线复现(冯薇 / 分管领导对已通过单点「归档」):
KpiError: 操作失败:当前节点「领导审批」需要由对应岗位处理…。归档动作不落在任何流程节点上(requiredPositionFor对 archive 固定要kpi_hr_reviewer),而文案取的是transition()给的atStepDef(流程最后一个节点)。只改文案取值:archive 时取hr_review节点的名称(方案没配则回落到STEP_LABEL.hr_review「人力审核」),规则一行不动。第 6 条 必填叠字 —— 边界冲突,请调度员确认
现场证据:对话框里是「争议内容(必填) *」,
*是平台的必填标记,叠字属实。但落点不是字段 label,而是动作参数 label,全部在src/actions/index.ts(驳回原因 / 争议内容 / 否决原因 / 处理结论 ×2,共 5 处),而该文件在派发单里被列为禁触碰。工作项正文又明确把第 6 条列入必做范围。处置:按「同因同域」把 5 处一并去掉「(必填)」后缀,单独一个 commit、只含这 5 个字符串,便于评审侧整段取舍;同时在此留痕报备。若调度员判定禁触碰优先,回复即可,我按回复处理(该 commit 可单独 revert,不牵动其他 8 条)。
第 7 条 禁止手工新建填报单
SheetInsertGuardHook取消kpi_admin例外:非系统上下文一律拒绝(文案已就绪);权限集里管理员与人力审核的kpi_entry_sheet关掉allowCreate(其余岗位本就没有),列表「新建」随之消失。发布路径是 hook 内 sudo 写入,不受影响。第 8 条 得分合计浮点尾数
基线复现:华南分公司「指标得分合计」=
91.75999999999999,同行「最终得分」=91.76。原因:indicator_score是平台 summary 字段(sum ofkpi_entry_line.final_score)且未声明scale,而total_score是声明了scale: 2的 formula 字段,所以只有后者是干净的两位小数。计分口径不动(lib/scoring.ts禁改),按派发单指定的落点在sheet.hook.ts的写入闸上按两位小数取整汇总字段(indicator_score/bonus_total/weight_total)。另一条路是给对象上的 summary 字段补scale(顺带补齐数字四件套),但那要动entry.object.ts的字段定义,超出本单允许范围,记录备查。第 9 条 注释更正
src/pages/index.ts顶部把「部门填报人员在『待人力审核』里本来就一行都读不到」改成事实表述:区块按数据范围显示、不按岗位;本部门单进入人力审核中时该岗位能看到该行,动作由 hook 拒绝(422),入口噪音的根治依赖 objectstack-ai/objectstack#15135。交付方式
逐条独立提交,一个 PR 关联本单;门禁
pnpm verify;software-flow.mjs(基线已实测 55 PASS)与e2e-flow.mjs(需 default 种子档案的独立空库,改后单独跑)在改后复跑;测试报告与符合度清单随后挂本单,截图走acceptance-evidence。baozhoutao commentedon Sep 6, 2026
测试报告 —— #38 文案与盖章小批(开发自测)
结论
9 条全部达成,其中第 2 条经复测确认「基线已修复、无需改代码」,第 4 条的人员姓名带方案名前缀(平台能力受限,已上报)。 两个流程脚本全绿:
software-flow.mjs55 PASS / 0 FAIL、e2e-flow.mjs74 PASS / 0 FAIL;pnpm verify(validate + typecheck + 139 单测 + i18n 新鲜度)绿。测试环境
issue-38-copy-and-stamps,基线 main @ c197bf4;实例OS_PORT=3114/OS_DATABASE_URL=file:./.objectstack/issue-38.db;software(第 1~8 条)与默认档案(e2e-flow.mjs专用,独立空库issue-38-default.db),换档案前rm -rf dist重建;scripts/software-people.mjs建(口令 Passw0rd!23);逐条实测
第 1 条 审核记录状态中文 ✅
approved/archived/hr_reviewing/draft。改前 / 改后:
第 2 条 核对盖章 ✅(基线已修复,本单未改代码)
decided_by/decided_at均已落库。check-task.hook.ts的beforeUpdate一直有盖章语句,原来失效是因为免检口径是isSystem(按钮动作体带系统标记 → 直接 return);流程按钮绕过岗位校验:动作体以受信任身份写入被 hook 当系统写入免检,任何岗位可越节点审批/归档 #28 把免检收窄成「无发起人的纯系统写入」后按钮路径不再免检,盖章随之生效(commit 07d176c 已在本单基线里)。基线 / 改后各一张:
第 3 条 归档提示 ✅
保存失败: 修改填报明细失败:填报单已提交,数据已冻结。如需更正,请发起数据调整申请。保存失败: 修改填报明细失败:填报单已归档,数据已锁定不可再改。归档数据不能更正,如有疑问请联系人力审核。第 4 条 看板人员姓名 / 「(未指定)」柱⚠️
3zVvYskdT9F8DPwTQmE…一类的原始用户 id;改后是「2026 年第 3 季度考核 · 冯薇 / 吴刚 / 周雪 / 孙磊 / 张伟 / 徐涛 / 李娜 / 王强 / 赵敏 / 郑洁」,到人得分报表同样。person即可(代码注释已写明这条回退路径)。第 5 条 归档拒绝节点名 ✅
KpiError: 操作失败:当前节点「领导审批」需要由对应岗位处理,你没有该岗位。如需处理,请联系管理员分配岗位。KpiError: 操作失败:当前节点「人力审核」需要由对应岗位处理,你没有该岗位。如需处理,请联系管理员分配岗位。software-flowT16a)。第 6 条 必填叠字 ✅
提出争议 | 请填写以下信息以继续操作。 | 争议内容(必填)* | 取消 | 确认提出争议 | 请填写以下信息以继续操作。 | 争议内容* | 取消 | 确认software-flowT8b「提出争议但未写核对意见被拒绝」仍 PASS。第 7 条 禁止手工新建填报单⚠️
三个观察点,两个达成、一个有偏差:
422 新建填报单失败:填报单由考核方案发布时自动生成,不能手工新建。请在考核方案中发布方案。(KPI_SHEET_MANUAL_INSERT)403 PERMISSION_DENIED。admin@objectos.ai是平台内置开发管理员(组织 owner),按平台设计绕过权限集,列表按钮与新建表单都还在;点进去保存会被上面第 1 条的 422 拦下,建不出残缺单。换句话说:「建不出来」是硬的,「按钮看不见」对领了 KPI 权限集的账号成立,对平台 owner 不成立。 这一条不是本单代码能收的口子(权限集对 owner 不生效是平台判定),据实记录,未做任何绕行。software-flowT3 / T4a「发布成功、生成 11 张填报单」仍 PASS;两个流程脚本都不依赖手工建单。第 8 条 得分合计两位小数 ✅
software-flow),华南分公司是尾数样本:91.75999999999999,同行「最终得分」=91.76;91.76,与最终得分一致。software-flow的全部得分断言(T5bT5e、T11、T12、T13b、T14a/b、T15bT15e)仍 PASS。第 9 条 注释更正 ✅
visible(CEL) is served to the client but never evaluated — a silently inert gate (17.2.0) objectstack#15135。回归与门禁
scripts/software-flow.mjs(software 档案空库)scripts/e2e-flow.mjs(默认档案独立空库)pnpm validatepnpm typecheckpnpm testto_status === '已归档')pnpm i18n:extract:check未覆盖 / 说明
证据 commit:
f5cbbe8fd216296e78c70eb6c25021a98554c5ae(孤儿分支acceptance-evidence,目录issue-38/)。baozhoutao commentedon Sep 6, 2026
需求符合度清单 —— #38(提 PR 前门禁)
逐条对照工作项正文的 9 条现象 + 10 条验收标准,三态标注。非 ✅ 条目各带出口链接。
一、正文 9 条
hooks/util.ts的writeReview()按lib/workflow.ts的STATUS_LABEL转换,4 个调用点一次覆盖;字段类型未改Field.user维度返回原始用户 id;应用侧换用结果记录名称列顶着。出口 = 平台能力受限上报 objectstack-ai/objectstack#16390;平台补上后把维度换回person(代码注释已写明回退路径)dimension ∈ {部门, 分公司},(未指定)柱消失required: true与报错文案未动。边界说明:落点在派发单列为禁触碰的src/actions/index.ts(工作项正文又把本条列为必做),已单独成 commit790af52便于取舍,并在开工评论报备kpi_admin例外,REST 实测 422KPI_SHEET_MANUAL_INSERTadmin@objectos.ai(组织 owner)不成立 —— 平台按设计让 owner 绕过权限集,按钮仍在,但点下去仍被数据层 422 拦下,建不出残缺单。差异原因是平台的 owner 判定,应用侧的权限集与 hook 两层都已按要求收紧;未做任何绕行。出口 = 记录并交验收侧判断是否需要另立平台上报pages/index.ts注释按事实更正二、验收标准 10 条
software-flow55 PASS ✅ /e2e-flow74 PASS ✅;「列表无新建」对平台 owner 不成立(见上)fe25b21pnpm verify绿 + 报告与清单挂本单 + 截图走 acceptance-evidencef5cbbe8fd216296e78c70eb6c25021a98554c5ae三、范围与三禁自查
src/lib/scoring.ts(只 importround2,未改)、adjustment.hook.ts、bonus.hook.ts、views/index.ts的 CheckTaskViews / AdjustmentViews / BonusViews、services/、apps/、src/data/、scripts/、docs/、README、CLAUDE.md —— 全部零改动。src/hooks/util.ts(第 1 条的writeReview())—— 另两个调用点在禁触碰的adjustment.hook.ts与未列的plan.hook.ts,改这一处是覆盖全部又不碰禁区的唯一走法;src/actions/index.ts(第 6 条的 5 个 label)—— 工作项正文把第 6 条列为必做,而该文件在派发单里被列为禁触碰;单独成 commit,可整段取舍。test/position-guard.test.ts一行断言随第 1 条改为中文(to_status === '已归档'),属实现改动的必要同步。lib/scoring.ts的round2,未另立舍入口径(更彻底的「给 summary 字段补 scale」要动字段定义,超范围,已在代码注释与开工评论里记录)。baozhoutao commentedon Sep 6, 2026
交接验收侧(开发子 agent 收工)
issue-38-copy-and-stamps→main,9 条逐条独立提交,正文不带自动关闭关键字)acceptance-evidence,commitf5cbbe8fd216296e78c70eb6c25021a98554c5ae,目录issue-38/(21 张改前 / 改后截图)status:自测报告中→status:PR审查中,处理人交 @baozhoutaopnpm verify全绿;software-flow.mjs55 PASS /e2e-flow.mjs74 PASS要请验收侧拍板的三件事(细节见符合度清单与 PR 正文):
hooks/util.ts(第 1 条留痕唯一写入口)与actions/index.ts(第 6 条 5 个 label,单独 commit790af52,可整段取舍)。第 2 条经复测为基线已修复(#28 的免检收窄),本单未改代码,证据在测试报告里。
Merge pull request #43: copy and stamp fixes — Chinese status labels,…
baozhoutao commentedon Sep 6, 2026
合并记录(调度员,2026-09-06)
src/hooks/util.ts留痕写入口、src/actions/index.ts5 个「(必填)」label)已报备,调度员裁定接受(均在工作项条目范围内,是派发时禁区划得过窄);禁触碰的计分、调整/加减分 hook、视图另三段、服务、种子、脚本零改动;CI 绿;测试报告、需求符合度清单(第 4 条status:PM验收中,处理人不变(验收侧)。