refactor: generate Python digest bindings from the TypeScript owner - #5322
Conversation
Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com>
huangruiteng
left a comment
There was a problem hiding this comment.
Approval conclusion (author-owned PR; GitHub blocks formal self-approval)
动机
精确 head a5a0883f2c28ae1a810d81756b358fe3e7f3b777 修复 #5252/#5254 后留下的维护债:Python 与 TypeScript 各自维护同一 SHA-256 envelope 正则,主干同源模块计数为 44,超过 43 的既定上限。实际交付不是放宽预算,而是把现有 Python 模块变成 TS owner 的可验证生成物,保持调用者的导入与匹配结果。它是可独立回滚的完整维护切片;对长期维护有益,用户运行路径保持不变。
改动思路
复用已有的 generate_semantic_bindings.py 和词汇漂移 smoke,不另建生成框架或运行时桥接。生成器只接受两条具名、无 flags 的字面量正则和受限语法,从 TS 源码写出原 Python 模块;verified_generated_paths 重新计算并逐字核对整个产物,之后 census 才将这一对排除于“独立维护”。反例是改 TS owner 却不重生 Python、手改 generated 文件、附加 flags/动态表达式:前两种使新鲜度检查失败,后两种由解析器拒绝。普通导入仍直接在 Python 内编译正则。
具体改动
六个文件,+120/-19。双语 semantic-vocabulary RFC 说明来源、限制和 43 对预算;content_digest.py 从手写定义改为生成头与等价的两条正则;生成脚本新增 digest 渲染、整产物核验和 build_artifacts 登记;词汇 smoke 合并已验证生成路径,只有其中一侧确实是生成物时才从独立维护对数扣除;architecture 测试覆盖有效/无效 digest、flags、缺失/动态/不支持语法以及来源或产物篡改。
关键代码讲解
render_digest_binding(生成脚本约 82 行)解析 TS 的两个 literal export,限制跨语言正则子集并生成 Python 的同名re.Pattern;不执行 TS。verified_generated_paths(约 109 行)对全部生成物按当前源重算并字节比较;文件名或 generated 注释不能自行获得豁免。check_dual_runtime_twins(词汇 smoke 约 1057 行)先从实际 Python/TS 同名文件求 raw twins,再扣除经过重算的生成侧;未来新增的独立 pair 仍被计数。BARE_SHA256_PATTERN与ENVELOPED_SHA256_PATTERN(Python 模块 8–9 行)保持原导入名及 bare/prefixed 严格 64 位小写十六进制匹配,既有消费模块不改。
对主干的风险
最关键风险是“伪生成文件”降低计数或 TS/Python 行为分叉。33 个绑定测试、211 个 Python digest-owner 测试、17 个 TypeScript digest-owner 测试、生成器 --check、Ruff 和 diff 检查通过;基线直接计数 44/43,当前 head 45 raw、2 verified-generated、43/43,新增的验证负例会拒绝 source/artifact 漂移。完整 semantic-vocabulary-drift-smoke.py 在固定 base 和精确 head 都失败于相同四条 history.py registry-I/O manifest metadata;两份致因文件不在本 PR diff,且本 PR 所改的双运行时 invariant 有独立通过证据。这是另一路 #5321 清单修复/merge-readiness hold,不是本 PR 的 REQUEST_CHANGES 理由;不能把本 head 写成完整 smoke 绿色。
语义与 CI 对齐
这是既有 digest value owner 的收敛,不创建新公开词汇、不改变权限、持久格式、运行时默认或机器义务。43 是既定回归上限,未调大;所排除的只有完整重算且一致的生成绑定。远端 CI 按 Goal 的 wait_for_ci=false 未查询或等待;合并门禁仍须独立判定。
我的整体评价
APPROVE(以 author-owned COMMENTED review 记录)。完整 base-to-head 改动与调用链已复核;在该边界里生成来源比继续手工维护或调大预算更小且更可逆。未来相关重构检查未发现需要随本 PR 引入的新抽象;删除 Python 旧长注释使少量背景转入 RFC,但行为与错误边界保留。长期维护判断为改善,用户体验判断为保持;唯一残余是上游清单的已归因失败,需由其 owner 修复后另行确认合并就绪。
English verdict: APPROVE - exact head a5a0883f2c28ae1a810d81756b358fe3e7f3b777 reduces independently maintained twins from 44 to 43 through a whole-artifact-verified TS-owned Python binding. Focused Python/TS tests and generator checks pass; the full vocabulary smoke has the same unrelated four-location registry-manifest failure on immutable base and head. Remote CI was not polled; merge readiness is separate.
|
Owner-authorized merge decision for exact head The owner explicitly requested proceeding without waiting for the separately tracked baseline repair. Independent exact-head review is APPROVE: #5322 (review) . The managed readiness check returned Changed surfaces: the existing TS-to-Python generator, generated digest binding, vocabulary census, focused tests and bilingual RFC. Independent validation passed 33 binding tests, 211 Python digest-owner tests, 17 TS digest-owner tests, generated-artifact freshness, Ruff and diff hygiene. Digest acceptance and runtime callers are unchanged. The complete vocabulary smoke still fails on the same four history registry-I/O manifest locations on immutable base and head, tracked separately by #5321. The strict quality receipt remains non-passing for that required baseline validator; this decision records the owner's explicit exception, not a green validator or modified receipt. Remote CI completion is not claimed. The bounded refactor consolidates duplicate semantic ownership without raising the twin budget. Proceeding with admin bypass under the owner's explicit authorization; the baseline repair remains required follow-up in its existing PR. |
The digest deduplication in #5252/#5254 left two independently maintained Python/TypeScript pattern definitions. Main therefore has 44 maintained twin modules against the semantic-convergence ceiling of 43.
Reuse
generate_semantic_bindings.pyto derive the existing Python module from the TypeScript owner. The generator accepts only the two bounded flagless literal exports, rejects unsupported/dynamic syntax, and leaves all consumer imports and regex behavior unchanged. The twin census excludes a source-derived artifact only after recomputing and checking its entire content; a generated filename or header alone is insufficient. The ceiling remains 43, and there is no new runtime bridge or provider change.Validation: 244 Python binding/digest-consumer tests, 17 TS digest-consumer tests, full TS typecheck and Ruff passed. Negative cases cover owner changes, edited artifacts, unsupported syntax and flags. The direct twin check reports 43 maintained pairs. Full vocabulary smoke on the unchanged main census remains blocked by the four stale
history.pylocations already addressed in #5321; a disposable integration with exactly those four regenerated census lines passed the complete vocabulary smoke; the census was then restored. This integration result is not a claim that the unchanged head passes the full gate. No production Goal state is modified. RFC checkpoints in both languages document the owner and provenance boundary.This is separate from #5320 so the baseline repair does not expand the Agent-memory review. Frontend/CLI behavior and configuration are unchanged; the shipped Python import continues to resolve the same constants. Revert this commit to restore the independently maintained binding; no data migration is involved.