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
Refined into a dispatchable work item (body rewritten; original six findings kept as the basis). Rulings: item 5 (null-organization refusal) stays strict; item 6 (re-assert fan-out) is recorded, not implemented here.
Claimed by dispatcher session session_01VR2khJ3Me96btawVsfG6jb. Branch: issue-5-sharing-hardening. Worktree ../kpi-issue-5, baseline main @ bdc87ff, dev port 3105, database .objectstack/issue-5.db. Developer subagent dispatched; no parallel item.
制造历史行的方式:先按分配表用管理员经 REST PATCH /data/kpi_check_task/{id} 送 plan: null
—— 平台返回 200 但静默忽略(plan 是 readonly 字段),读回仍是原值,REST 这条路走不通。
改用分配表许可的回退:停 dev 后用 node:sqlite 直改本实例库文件.objectstack/issue-5.db
的该行(update kpi_check_task set plan = NULL where id = '-Mo-qaYenOTtciFY',changes = 1),
不碰任何其它库、任何其它行。
回填前(sqlite 读数):
{"id":"-Mo-qaYenOTtciFY","sheet":"Kb3ZGjVNjmnbYZBp","plan":null}
rows with empty plan = 1
重启后的启动日志原样片段:
2026-09-02T19:18:44.428Z INFO [kpi] position bindings ensured {"created":0,"total":6}
2026-09-02T19:18:44.457Z INFO [kpi] 历史行方案回填完成 {"filled":1,"unresolved":0,"failed":0,"byObject":[{"object":"kpi_check_task","filled":1,"unresolved":0,"failed":0},{"object":"kpi_adjustment","filled":0,"unresolved":0,"failed":0}]}
⚠️ 一处需要知道的读数:ctx.logger.info 在 dev 的默认日志级别下不打印(align-demo-units
自己的 info 行同样不出现)。上面的回填日志是用 pnpm dev --log-level info 采到的;
默认级别下回填照常执行(第二次启动就是默认级别,该行的 plan 确实被补上了),只是那一行看不见。
这是平台日志级别问题、不是本次改动的问题,记入遗留问题。
行为全部满足(日志 filled:1、REST 读回已填、第三次启动零回填零写入)。出口:ctx.logger.info 在 dev 默认日志级别下不打印(align-demo-units 的 info 行同样不出现),该行日志需 pnpm dev --log-level info 才可见;回填本身在默认级别下照常执行。见遗留问题 R1
Dispatcher collection check for PR #16 (head b41648c, base bdc87ff): passed — 5 files (+612 / −8), none of the forbidden files, no binaries; git merge-tree clean; pnpm verify re-run: validation passed, typecheck clean, 86/86 tests; CI verify green; trailers present on both commits, no model identifiers. Next: independent review gate, then merge.
Review gate (independent reviewer, PR #16 @ b41648c): NOT MERGEABLE — 0 blocking, 1 should-fix, 5 notes. Returned to the developer on the same branch.
Should-fix: the boot-time backfill's entry-sheet lookup (planOfSheets) has no error guard while every other query in the module does; a failed read there propagates out of the kernel:bootstrapped handler as an unhandled rejection and skips the adjustment pass. Fix: guard the lookup (warn, return empty map → rows stay unresolved for the next start) and wrap run like align-demo-units does; add a unit case.
Folded in from the notes: ruleSlug comment precision (which id shapes actually change), a guard for the batch loop stalling when a whole batch is unresolved, comment wording about hooks and system context, and the backfill summary log at warn level when rows were filled (so acceptance criterion 2 is observable at the default level).
Verified by the reviewer: the rule-name bound holds (max derived name 99) and UUID-shaped ids keep their pre-fix slug byte-for-byte (differential over 3,500 ids: zero drift), so no existing rule loses reconciliation after upgrade.
选「补 warn」这一支:fresh.length === 0 && batch.length === BATCH 时记 a full batch made no progress 并带三个计数。未选 $nin —— 它会把 seen 整个塞进查询条件,批量一大就撞上与 F1 同一个参数上限。单测 整批都没写动时留下一条 warn
Merged PR #16 into main as fd268d1 (collection check passed at both rounds; review gate MERGEABLE at 888e642; CI verify green). Status → PM验收中; handed to the work-item creator for acceptance. Rulings recorded in the body: null-organization refusal stays strict; re-assert fan-out is recorded only. Reviewer note left open (not blocking): the "registration entry never throws" unit case does not pin the outer catch on its own.
Activity
baozhoutao commentedon Sep 2, 2026
Refined into a dispatchable work item (body rewritten; original six findings kept as the basis). Rulings: item 5 (null-organization refusal) stays strict; item 6 (re-assert fan-out) is recorded, not implemented here.
Claimed by dispatcher session
session_01VR2khJ3Me96btawVsfG6jb. Branch:issue-5-sharing-hardening. Worktree../kpi-issue-5, baseline main @ bdc87ff, dev port 3105, database.objectstack/issue-5.db. Developer subagent dispatched; no parallel item.Generated by Claude Code
Harden sharing service: rule-name length bound, legacy plan backfill,…
baozhoutao commentedon Sep 2, 2026
Self-test report — work item #5, branch
issue-5-sharing-hardening, PR #16 (draft).一、开测前三级核对
/home/user/kpi-issue-5b41648ce099a5e5397dcb64521b6efefe9152753/issue-5-sharing-hardening(基线 main @ bdc87ff)file:./.objectstack/issue-5.db(启动前rm -rf dist)二、单元测试与元数据校验(
pnpm verify,最终 commitb41648c)test/sharing.test.ts单文件 44 passed,其中本次新增 19 条,按校验规则逐条:方案名 200 个汉字:所有派生规则名 ≤ 100,且两次派生完全相同(幂等)✓;最坏形态:方案 / 单元 / 领导三段 id 都超长时,最长的规则名恰好 99✓;修复前真正越界的形态:三段都是 32 位合规 id(旧代码原样保留,拼出 117)✓;UUID 形态的 id(平台记录 id)仍走既有折法:头部 12 位 + 稳定哈希✓(升级兼容的钉子);合规但超长的 id 折成「截断 + 8 位稳定哈希」,长度恒为片段上界✓。三种行只写第一种;第二次运行零写入✓(断言
filled:1 / unresolved:1 / failed:0、写载荷键恰好['plan']、写上下文{isSystem:true}、第二次
writes长度 0);另有两对象都回填、被 hook 拒写计入failed不阻断其余行、无填报单的行计入
unresolved而不写空、挂点是kernel:bootstrapped且无事可做时零日志。存在旧规则 → 停用(并盖上对账标记,行保留不删)✓;不存在旧规则 → 一条都不动✓;附加别的方案的规则与被管理员改过的规则都不在对账射程内✓。管理员手工停用的规则记 skipped_inactive_admin✓;本应用上次对账停用的规则记 skipped_inactive_reconciled✓;两种情形都不改写 active✓。三、端到端(
KPI_BASE_URL=http://localhost:3105 node scripts/e2e-flow.mjs,空库)校验规则 4 满足:T39 规则数不变(29 = 29),73 项全绿、零失败。
四、验收标准 2:回填的真实运行
制造历史行的方式:先按分配表用管理员经 REST
PATCH /data/kpi_check_task/{id}送plan: null—— 平台返回 200 但静默忽略(
plan是 readonly 字段),读回仍是原值,REST 这条路走不通。改用分配表许可的回退:停 dev 后用
node:sqlite直改本实例库文件.objectstack/issue-5.db的该行(
update kpi_check_task set plan = NULL where id = '-Mo-qaYenOTtciFY',changes = 1),不碰任何其它库、任何其它行。
回填前(sqlite 读数):
重启后的启动日志原样片段:
回填后经 REST 读回该行:
第三次启动(幂等复核):
position bindings ensured照常出现(证明引导钩子确实跑了),回填相关日志 0 行,plan为空的行数 0,该行读回不变 —— 零写入。ctx.logger.info在 dev 的默认日志级别下不打印(align-demo-units自己的 info 行同样不出现)。上面的回填日志是用
pnpm dev --log-level info采到的;默认级别下回填照常执行(第二次启动就是默认级别,该行的
plan确实被补上了),只是那一行看不见。这是平台日志级别问题、不是本次改动的问题,记入遗留问题。
五、反向验证(消融)
三条,每条都先 commit 再变异,变异腿与还原腿都在磁盘上核对(注入串 / 被删串各
grep -c一次,并比对 blob 哈希与 HEAD),脚本带
trap ... EXIT INT TERM还原;本仓 vitest 直接从
src/*.ts解析,不经dist/,无产物过期风险。ruleSlug退回原来的 32 位直通、删掉截断分支3 failed | 41 passed1 failed | 42 passed1 failed | 42 passed三次还原后 blob 哈希均等于 HEAD、
git diff HEAD为空。补一条诚实记录:第一版「最坏形态」用例取的是 64 位 id,而旧代码对超过 32 位的 id 反而会折短
—— 那条用例在消融下并不会因越界而红。发现后补了「三段 32 位合规 id」这一条(旧代码拼出 117),
消融红数从 2 升到 3,这才真正盯住了修复前的越界入口。
六、自测结论
通过。 校验规则 1
5 与验收标准 13 全部满足;文案红线不涉及(无用户可见文案变化,新增的只有服务端日志与规则描述前缀,不含异常原文)。
Generated by Claude Code
baozhoutao commentedon Sep 2, 2026
Requirements conformance checklist — work item #5, PR #16, commit
b41648c.三态:✅ 已实现并验证 /⚠️ 有条件满足(出口链接) / ❌ 未实现。
输入与字段(正文六条)
RULE_NAME_MAX=100、RULE_SLUG_MAX=26,最坏形态恰好 99;5 条单测(含「修复前真正越界的 32 位形态」与幂等)kernel:bootstrapped挂点、幂等、记录条数、无可回填行零写入src/data/backfill-plan-links.ts,objectstack.config.ts的onEnable注册;真实运行filled:1,第三次启动零回填、零写入test/sharing.test.ts两个方向 + 别的方案 / 管理员改过的规则不在射程内skipped_inactive_admin/skipped_inactive_reconciled,以RECONCILED_DESCRIPTION_MARK描述前缀区分;3 条单测src/services/sharing-service.ts的KPI_SHARING_NO_ORG拒绝处provisionPlanSharing文档注释新增「已知取舍:重申的扇出」一节校验规则
filled:1 / unresolved:1 / failed:0、写载荷键恰好['plan'];第二次writes为 0pnpm verify、pnpm e2e绿(T39 规则数不变){"passed":73,"failed":0};T39rules=29 expected=29rule/object/ 计数),回填拒写那一条记error摘要用于定位,不面向终端用户验收标准
test/sharing.test.ts新增 19 条,单文件 44 passedplan为空的核对任务行启动后回填条数 1、该行plan已填;再次启动零写入filled:1、REST 读回已填、第三次启动零回填零写入)。出口:ctx.logger.info在 dev 默认日志级别下不打印(align-demo-units的 info 行同样不出现),该行日志需pnpm dev --log-level info才可见;回填本身在默认级别下照常执行。见遗留问题 R1pnpm verify与pnpm e2e原样输出绿输出 / 反馈约定
src/services/sharing-service.ts、src/data/下新增回填模块并在objectstack.config.ts挂接、test/sharing.test.ts增测docs/00~03、README、CLAUDE.md;docs/04#18 备注可补一句docs/04-需求符合度清单.md#18 备注加了第 ⑤ 点「历史行回填」;.github/未触碰遗留问题
ctx.logger.info在 dev 默认日志级别下不打印(平台日志级别行为,非本次改动引入;align-demo-units既有的对齐日志同样不可见)。影响的是可观测性,不是回填行为本身。是否要把这类启动期一次性摘要提到
warn级、或在平台侧调整 dev 默认级别,建议由验收侧定夺后另立工作项。Generated by Claude Code
baozhoutao commentedon Sep 2, 2026
Dispatcher collection check for PR #16 (head b41648c, base bdc87ff): passed — 5 files (+612 / −8), none of the forbidden files, no binaries;
git merge-treeclean;pnpm verifyre-run: validation passed, typecheck clean, 86/86 tests; CI verify green; trailers present on both commits, no model identifiers. Next: independent review gate, then merge.Generated by Claude Code
baozhoutao commentedon Sep 2, 2026
Review gate (independent reviewer, PR #16 @ b41648c): NOT MERGEABLE — 0 blocking, 1 should-fix, 5 notes. Returned to the developer on the same branch.
Should-fix: the boot-time backfill's entry-sheet lookup (
planOfSheets) has no error guard while every other query in the module does; a failed read there propagates out of thekernel:bootstrappedhandler as an unhandled rejection and skips the adjustment pass. Fix: guard the lookup (warn, return empty map → rows stay unresolved for the next start) and wraprunlikealign-demo-unitsdoes; add a unit case.Folded in from the notes:
ruleSlugcomment precision (which id shapes actually change), a guard for the batch loop stalling when a whole batch is unresolved, comment wording about hooks and system context, and the backfill summary log at warn level when rows were filled (so acceptance criterion 2 is observable at the default level).Verified by the reviewer: the rule-name bound holds (max derived name 99) and UUID-shaped ids keep their pre-fix slug byte-for-byte (differential over 3,500 ids: zero drift), so no existing rule loses reconciliation after upgrade.
Generated by Claude Code
baozhoutao commentedon Sep 2, 2026
Requirements conformance checklist (revision 2) — supersedes the checklist in comment 5515077347. Work item #5, PR #16, commit
888e642.本评论订正上一版的验收标准 2(⚠️ → ✅),并补录评审闸门 Review round 1 的五项。
工具不能编辑旧评论,故以新评论订正;上一版其余条目结论不变,原文保留可查。
三态:✅ 已实现并验证 /⚠️ 有条件满足(出口链接) / ❌ 未实现。
一、订正条目
plan为空的核对任务行启动后回填条数 1、该行plan已填;再次启动零写入warn级,dev 默认日志级别下可见,不再需要--log-level info。已用默认级别重新采证一遍(下方第三节)原⚠️ 的出口(遗留问题 R1「
ctx.logger.info在 dev 默认级别下不打印」)对本工作项已关闭 ——回填摘要不再走
info。平台该行为本身仍然存在,只是不再影响本项验收,降级为观察项(下方第五节)。二、Review round 1 五项
planOfSheets包 try/catch,失败warn并返回空 Map;run外再包一层 catch;补单测「读填报单失败不抛、不阻断另一个对象的回填」读填报单失败:不抛、不阻断另一个对象的回填,本批延到下次启动(两对象都跑到、各落unresolved、writes为 0)、注册入口即便内部整体失败也不抛。消融该 try/catch → `1 failedruleSlug注释「越界的只有它」改为两段说明888e642同步了这段更正(旧提交信息不可改写,以新提交为准)fresh.length === 0 && batch.length === BATCH时记a full batch made no progress并带三个计数。未选$nin—— 它会把seen整个塞进查询条件,批量一大就撞上与 F1 同一个参数上限。单测整批都没写动时留下一条 warnfilled > 0时摘要用warn级,零回填仍不打印;用默认级别重启采证有回填发生时摘要走 warn 级;默认级别实测见下方第三节三、验收标准 2 的重新采证(默认日志级别,
888e642)rm -rf dist+ 删库 →OS_PORT=3105 pnpm dev(不加--log-level)→pnpm e2e→停 dev → 用
node:sqlite把一条核对任务的plan清空(REST PATCH 送plan: null返回 200但静默忽略,
plan是 readonly 字段,这条通路走不通;只改本实例库.objectstack/issue-5.db这一行)→ 重启。清空后(sqlite 读数):
重启后的启动日志原样片段(默认级别):
回填后经 REST 读回:
再次启动(仍是默认级别):
回填相关日志 0 行,empty-plan check_task rows = 0,该行读回不变 —— 零写入。四、本轮全量验证
校验规则 4(
pnpm verify与pnpm e2e绿、T39 规则数不变)在本轮 commit 上重新满足。上一版清单的其余条目(输入与字段 1
6、校验规则 13 与 5、验收标准 1 与 3、输出/反馈约定)结论不变。五、遗留问题(修订)
ctx.logger.info在 dev 默认日志级别下不打印(平台行为,非本次引入;align-demo-units既有的对齐日志同样不可见)。回填摘要已改走warn,本项验收不再受影响;该平台行为是否需要处理,建议由验收侧另行判断。
---+ 署名页脚会被稳定剥除(两次尝试均如此,创建时不会)。PR Sharing-service hardening: rule-name length bound, legacy plan backfill, reconcile branch coverage #16 正文因此当前无页脚;评论通路的页脚正常存活。
这是平台正文处理行为,不影响代码与验收。
Generated by Claude Code
Merge pull request #16: sharing-service hardening (rule-name bound, l…
baozhoutao commentedon Sep 2, 2026
Merged PR #16 into main as fd268d1 (collection check passed at both rounds; review gate MERGEABLE at 888e642; CI verify green). Status → PM验收中; handed to the work-item creator for acceptance. Rulings recorded in the body: null-organization refusal stays strict; re-assert fan-out is recorded only. Reviewer note left open (not blocking): the "registration entry never throws" unit case does not pin the outer catch on its own.
Generated by Claude Code