移植语义纪律(Pi/Hermes → DSH)
适用:把 Pi/Hermes 时代的插件业务语义平移到 DSH Host 侧(纯领域层 + 服务面 + 测试)。实证出处:dsh-plugins PR #42/#45/#46/#49/#51(2026-09-30 五连发,全部按本纪律一次通过验收)。
1. 源码定位规律(省一半找源时间)
- 全量实现在
reference/flopi-candidate/plugins/flopi.<名>/;reference/flopi-main-delta/plugins/flopi.<名>/是删减版(常只剩 README/TASKS)。先去 flopi-candidate,别在 main-delta 里空转(SuitAgent/星标/超能三片 worker 连续踩出并互传的规律)。 reference/不可编辑,只读;语义出处逐条注释锚定到「文件 + 行号」(如plugin_api.py L106-110)——验收时 PM 抽查锚点,将来对照有据。
2. 平移四原则
- 语义等价优先于形状等价:如原「文件字节 sha256 做 revision」→ canonical JSON 内容哈希(键序无关);语义(外部内容变化即失效在途写)不变,形态适配新宿主——差异必须注释说明。
- 偏离只许「更严」方向:发现原实现的类型洞/松校验(如 Python
float(True)=1.0落进合法域、str()折叠后 isinstance 恒真、[] or {}折叠 quirk)不平移,新实现收紧并逐条列出(PR #45 的四收紧是范本)。放宽方向的原语义偏离必须先问用户。 - 不虚构未验证分支:原实现里属于未定路线(如 Python 子进程宿主的 503/504 分支)在新宿主无对应物时,如实标注「归 X 路线落地」,不猜一个实现(PR #46 范本)。
- 原语义读不透 → 保守实现 + PR 标注开放问题,不猜。
3. 外部 IO 注入缝纪律(Host 插件通用)
引擎 HTTP、GitHub API、llm 等外部 IO 一律注入式(可 mock 的 transport/service 对象经参数或 ctx 缝传入),插件本体零网络副作用:
- 三级装配(PR #48 范本):外部覆盖注入 > 注入缝真实实现(内建 fetch,可再注入 mock)> 缝缺失时离线桩兜底(明确报「未接入」,fail-closed)。
- 缺省不自行发起网络:宿主未给注入缝 ≠ 隐式启用全局 fetch——settings 接线落缝后才成生产默认。
- 离线不伪造:外部不可达时返回明确错误对象,绝不编数据(沿原实现原则平移)。
- 凭据零接触:授权门只查配置面(如
llm.listProviders()探测路由注册),凭据本体走宿主 seam;token/key 一律调用方注入。
4. Python→JS 跨语言平移(2026-09-30/10-01 波实证,PR #61/#62/#68/#69)
- 正则后顾断言不许降级为消耗式前缀:Python
(?<!!)是零宽断言,JS 用(^|[^!])捕获式替代会消耗字符——[a](1.md)[b](2.md)[c](3.md)紧邻形态交替漏配(PR #69 审查模糊实测约 20% 用例分歧)。V8 已支持后顾断言,直接同型移植。更险的是漏配结果是稳定不动点,幂等断言测不出来——跨语言正则必须带紧邻/交替形态的定向回归。 - URL/路径编码不做隐式等价假设:JS
encodeURI不编码非 ASCII,Pythonurllib.parse.quote按 UTF-8 百分号编码——含中文/emoji 的路径两语言产出不同 URL。自建编码器对齐 safe 集(quote(safe=...)的字符逐一列出),并做跨语言差分对照(PR #69 quotePath 106 输入零分歧的实证方法)。 - 内容哈希当不了修订号:canonical JSON sha256 这类哈希无先后序——判「陈旧/变没变」要么用单调计数、要么用内容身份(相同即跳过重拉),别拿哈希比大小(PR #68 实现期自查纠正:初版把内容哈希当递增 revision 设计进事件契约)。
- 数值/日期/排序三件套:Python
round()是银行家舍入(half-to-even,12.5→12),JSMath.round不是——按原语义手写;Pythondate.fromisoformat拒绝越界日(2026-02-30),V8Date.parse会滚动成合法日期——需显式日历校验;Pythonsorted元组序是码点序,JSlocaleCompare对 CJK/数字不一致——显式三分比较(PR #61 三件套,审查逐值核过)。 - 替换串的捕获组就是语义:原实现的 re.sub 替换串不含某捕获组(如 md 链接的
"title"参数)= 该数据被丢弃——照原样平移(「不擅自增强」),测试按原行为断言(PR #69)。 - 跨语言差异必须申报或消除:要么修到等价(零宽断言),要么在 README/TASKS「与原差异(如实)」逐条申报(quotePath/标题丢弃);沉默的行为分歧 = 违反锚定纪律。
5. 测试与验收配套
- mock 贴宿主真契约:假 storageDomain 要带域名正则校验(
^[a-z][a-z0-9_]*$);假 transport 断言最终请求形状(URL/method/body);假 llm 覆盖错误码流。 - 并发分支测试计数:同基线并行开发的多个分支,各自全套测试只含自己的新增——合并后 main 是并集(83+11 / 83+15 / 83+18 三分支合并后 127 的实证)。验收数字以合并后 main 实测为准,不以单分支自报数为准。
- 真实付费调用/真实网络/真实宿主装载在 mock 级切片一律 NOT_VERIFIED,README/TASKS 如实标注并指向验证窗口。