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
fix(pipeline): violation-precedence 去重键在 run.at 缺失时会把不同 run 的违规合并 #461
Activity
modusensus commentedon Oct 20, 2026
现状(2026-10-21 对照
main实测)代码里一行没动,问题仍在。
dsh-mneme/src/pipeline.js:127:run.at缺失时该键塌缩成|step|need,不同 run 的同类违规会被合并——去重本意是「同一轮里同一条违规只报一次」,塌缩后变成「所有无时间戳的轮次共享一条」。现网风险低(run.at正常都有值),属于防御深度缺口。还缺什么
run.at时用run.id或进程内单调序号兜底,而不是空串;run.at均为undefined的 run 产生同step.id违规,断言产出两条。接手建议
三行以内可修,
test/pipeline-activities.test.js里已有同类断言可照抄。这条不需要设计讨论。z2Ace0107 commentedon Oct 23, 2026
想接这条,计划按你给的缺口清单来:
src/pipeline.js:127的去重键在run.at缺失时用run.id兜底(run.id也缺就退到进程内单调序号),不用空串;test/pipeline-activities.test.js补一条回归:两个run.at均为undefined的 run 产生同step.id违规,断言产出两条。at存在时行为逐字节不变,纯加固,不动写入侧契约。说明一下我的安排:我打算把 #383(/context 档位信号)和 #421(distill_records 的 HTTP 出口)也认下来,按由易到难串行做完——这条最先,#383 次之,#421 最后。三个都会在两周内开出 PR,不让认领过期。有哪个你更想自己收,随时说。
fix(pipeline): violation-precedence 去重键在 run.at 缺失时用位置索引兜底(#461)
Merge pull request #507 from z2Ace0107/codex/issue-461-violation-prec…
fix(pipeline): 匿名指纹补 step.at 等结构化字段,漏掉会合并两条不同 run 的违规
modusensus commentedon Nov 2, 2026
已在 0.9.5 交付,本 issue 关闭。
落点(两步)
第一步 PR #507
f7dacac:dsh-mneme/src/pipeline.js:147的键改成用位置索引兜底——${runKey}|${step.id}|${need},runKey在run.at缺失时取#${i}。同时把「缺失」的判定从?? ""扩到含空串:run.at = ""以前会被当成合法时间戳参与拼键。第二步 PR #513
a27c4ef:补的是 #507 合并后复盘指出的遗漏——匿名指纹原先只取 step 的id,于是两条都缺run.at、其余全同、只在steps[0].at上不同的 run 是两次不同的观测却共键。那是同一类键塌缩的反面形态(该分开的被并了),所以指纹补进step.at等结构化字段,并把null与「字段缺失」区分开写进 JSON。一处与建议不同的取舍
你建议用
run.id兜底。实际做的是位置索引——因为 run 对象根本没有id字段:normalizeRun(dsh-mneme/src/pipeline-runs.js)只产出{ at, by, triggeredBy, steps }。位置索引是这里唯一现成的判别项。回归测试两侧都补了:两个
run.at均为undefined的 run 产生同step.id违规时产出两条;at存在时行为逐字节不变。@z2Ace0107 多谢。这条的价值不在于修好了什么现网问题(
normalizeRun已经强制at必填,写入侧进不来这种形状),而在于你说清了它是防御深度问题——读侧被独立喂入非法形状时不该静默塌缩。这种「按现网风险算很低、但按契约算必须修」的判断,比一堆高危报告都难得。