claw-code 源码详细分析:Parity Audit——如何用工程对比把「像不像」从口水战变成可重复报告?

涉及源码src/parity_audit.pysrc/reference_data/archive_surface_snapshot.jsoncommands_snapshot.jsontools_snapshot.jsonsrc/main.pytests/test_porting_workspace.py


1. 要解决什么问题

大型移植里,「我们已经很像原版了」最容易变成 主观口水战 :有人看目录像,有人看 CLI 像,有人坚持行为仍不对。
Parity Audit 做的是:把「像」拆成 若干可计数、可写在 CI 里的维度 ,每次跑 run_parity_audit() 得到同一形状的 ParityAuditResult ,再 to_markdown() 成人类可贴进 PR 的段落------同一代码树 + 同一快照数据 ⇒ 同一数字,从而把争论从「我觉得」推进到「报告显示」。

重要边界 (与 README 一致):这些指标衡量的是 表面与清单维度的对齐倾向不是 runtime 行为等价或法律意义上的「未侵权证明」。


2. 报告长什么样:ParityAuditResult + to_markdown

python 复制代码
# 73:110:src/parity_audit.py
@dataclass(frozen=True)
class ParityAuditResult:
    archive_present: bool
    root_file_coverage: tuple[int, int]
    directory_coverage: tuple[int, int]
    total_file_ratio: tuple[int, int]
    command_entry_ratio: tuple[int, int]
    tool_entry_ratio: tuple[int, int]
    missing_root_targets: tuple[str, ...]
    missing_directory_targets: tuple[str, ...]

    def to_markdown(self) -> str:
        lines = ['# Parity Audit']
        if not self.archive_present:
            lines.append('Local archive unavailable; parity audit cannot compare against the original snapshot.')
            return '\n'.join(lines)
        ...

五组核心度量(归档存在时才会在 Markdown 里展开):

字段 含义(分子/分母直觉)
root_file_coverage 归档根级 TS/TSX 映射表 中,当前 src/ 顶层 是否出现对应 .py 文件名
directory_coverage 归档顶层 子目录映射表 中,当前 src/ 顶层是否出现对应包名/占位
total_file_ratio 当前 src/.py 文件总数 vs 参考 JSON 中的 total_ts_like_files
command_entry_ratio commands_snapshot.json 条目数 vs 参考 command_entry_count
tool_entry_ratio tools_snapshot.json 条目数 vs 参考 tool_entry_count

另有两份 缺失清单missing_root_targetsmissing_directory_targets,直接给出 还没对齐的期望名,方便开 issue / 拆任务。


3. 「可重复」的数据从哪来

3.1 冻结的参考面:archive_surface_snapshot.json

路径:src/reference_data/archive_surface_snapshot.json。其中除列举根文件、根目录名外,还提供 分母

python 复制代码
# 60:62:src/reference_data/archive_surface_snapshot.json
  "total_ts_like_files": 1902,
  "command_entry_count": 207,
  "tool_entry_count": 184
}

学习点 :分母不依赖你本机是否真有 archive/ 目录------它来自 随仓库提交的 JSON 。这样 CI 在无归档环境下仍能比较 「当前 Python 文件数 vs 某次钉死的 TS-like 文件数」「当前快照条目数 vs 钉死的条目数」 (若 to_markdown 未因 archive_present 提前返回,见下节)。

3.2 显式映射表:ARCHIVE_ROOT_FILES / ARCHIVE_DIR_MAPPINGS

根级文件 一对一 期望(TS 名 → 当前 src/ 顶层应存在的 Python 文件名):

python 复制代码
# 13:31:src/parity_audit.py
ARCHIVE_ROOT_FILES = {
    'QueryEngine.ts': 'QueryEngine.py',
    'Task.ts': 'task.py',
    ...
    'main.tsx': 'main.py',
    ...
}

子系统目录 一对一 期望(归档目录名 → 当前 src/ 顶层应有 commands.py 或包名如 assistant):

python 复制代码
# 34:69:src/parity_audit.py
ARCHIVE_DIR_MAPPINGS = {
    'assistant': 'assistant',
    ...
    'native-ts': 'native_ts',
    ...
}

学习点 :「像不像」里最容易扯皮的一块------根入口与顶层包是否齐 ------被钉死在两个字典里;改期望 = 改表 + 改代码审查,而不是聊天里重新定义。

3.3 本地探测:CURRENT_ROOTARCHIVE_ROOT

python 复制代码
# 7:11:src/parity_audit.py
ARCHIVE_ROOT = Path(__file__).resolve().parent.parent / 'archive' / 'claw_code_ts_snapshot' / 'src'
CURRENT_ROOT = Path(__file__).resolve().parent

run_parity_auditCURRENT_ROOT.iterdir()顶层名字 与映射表比对;用 CURRENT_ROOT.rglob('*.py') 统计 全部 Python 文件数

python 复制代码
# 121:127:src/parity_audit.py
def run_parity_audit() -> ParityAuditResult:
    current_entries = {path.name for path in CURRENT_ROOT.iterdir()}
    root_hits = [target for target in ARCHIVE_ROOT_FILES.values() if target in current_entries]
    dir_hits = [target for target in ARCHIVE_DIR_MAPPINGS.values() if target in current_entries]
    missing_roots = tuple(target for target in ARCHIVE_ROOT_FILES.values() if target not in current_entries)
    missing_dirs = tuple(target for target in ARCHIVE_DIR_MAPPINGS.values() if target not in current_entries)

注意archive_present 仅检测 ARCHIVE_ROOT.exists()审计逻辑本身不读取归档内文件列表 ;对比的是 本仓库的 src/ 树 + 参考 JSON + 映射表

3.4 archive_present 与 Markdown 输出的关系

本地无归档目录 时,to_markdown() 提前返回 ,上面那些 分子分母一行都不会打印

python 复制代码
# 86:88:src/parity_audit.py
        if not self.archive_present:
            lines.append('Local archive unavailable; parity audit cannot compare against the original snapshot.')
            return '\n'.join(lines)

因此:

  • 有归档 :适合贴完整 Parity Audit 段落进 PR。
  • 无归档 :CLI 仍执行 run_parity_audit(),但对外报告 刻意缩短------提醒「无法对照本地快照」,避免误以为做过完整对比。

若要在无归档 CI 里 仍断言数字 ,应直接测 ParityAuditResult 字段(见下),不要只解析 Markdown。


4. 命令/工具条目:清单长度 vs 参考分母

python 复制代码
# 133:135:src/parity_audit.py
        total_file_ratio=(current_python_files, int(reference['total_ts_like_files'])),
        command_entry_ratio=(_snapshot_count(COMMAND_SNAPSHOT_PATH), int(reference['command_entry_count'])),
        tool_entry_ratio=(_snapshot_count(TOOL_SNAPSHOT_PATH), int(reference['tool_entry_count'])),
python 复制代码
# 117:118:src/parity_audit.py
def _snapshot_count(path: Path) -> int:
    return len(json.loads(path.read_text()))

学习点 :命令/工具「像不像」被操作化为 JSON 数组长度与钉死分母的比 。更新镜像清单时,可同时更新 archive_surface_snapshot.json 里的 command_entry_count / tool_entry_count(若归档侧枚举变了),否则会出现 「条目多了但分母旧」 的比值大于 1 的语义------维护者需在评审里约定 是否允许分子大于分母同步 bump 参考值


5. 如何变成「可重复」:CI 与测试

CLI

python 复制代码
# 104:106:src/main.py
    if args.command == 'parity-audit':
        print(run_parity_audit().to_markdown())
        return 0

测试

  • test_parity_audit_runs:子进程跑 parity-audit,断言输出含 Parity Audit(有无归档均过)。
  • test_root_file_coverage_is_complete_when_local_archive_exists仅当 audit.archive_present 时,断言根文件全覆盖、目录覆盖 ≥28、命令条目 ≥150、工具条目 ≥100。
python 复制代码
# 45:51:tests/test_porting_workspace.py
    def test_root_file_coverage_is_complete_when_local_archive_exists(self) -> None:
        audit = run_parity_audit()
        if audit.archive_present:
            self.assertEqual(audit.root_file_coverage[0], audit.root_file_coverage[1])
            self.assertGreaterEqual(audit.directory_coverage[0], 28)
            self.assertGreaterEqual(audit.command_entry_ratio[0], 150)
            self.assertGreaterEqual(audit.tool_entry_ratio[0], 100)

可重复报告 在这里体现为:开发者机器上有归档时,门槛测试必须绿 ;无归档时跳过强断言,但 test_command_and_tool_snapshots_are_nontrivial 仍对 PORTED_COMMANDS / PORTED_TOOLS 长度保底。


6. Parity Audit 没有回答什么(避免误用)

  • 行为:不跑 TS/Python 双端 E2E,不对比 API 响应体。
  • 质量:不衡量测试覆盖率、类型完整度。
  • 安全/合规:不是法律或版权结论。
  • 归档内容一致性 :不 diff 归档里每个文件与 Python 实现;只认 映射表 + 顶层存在性 + 文件计数 + 快照条目数

仓库内 PARITY.md(Rust 侧)另有一套 功能差距 叙述,与 Python parity_audit 互补而非重复。


7. 如何把报告用得「更工程」

  1. PR 模板 :要求贴 python3 -m src.main parity-audit 输出(有归档环境时)。
  2. 趋势 :把 ParityAuditResult 五元比例 随时间画线(CI artifact),看移植是否在收敛。
  3. 扩展维度 :在不动现有字段的前提下,可增加 Rust workspace 指标behavioral parity 用例通过数 等,仍通过 dataclass + to_markdown 输出,保持「一次运行、一份报告」。
  4. 无归档 CI :对 run_parity_audit() 的数值做 结构化导出 (JSON),避免依赖被 archive_present 截断的 Markdown。

8. 小结

  • Parity Audit冻结参考 JSON + 显式 TS→Py 映射 + 本地 src/ 扫描 + 快照条目计数 ,把「像不像」压成 可重复的 ParityAuditResult
  • to_markdown() 提供 人类可读、可贴 PR 的固定格式;archive_present 控制是否输出完整指标,体现 数据治理(无归档不强装完整对比)。
  • 测试 把关键门槛 编码为断言 ,使「像」在 有归档的开发环境 下成为 门禁 而非口头禅。

相关推荐
萧逸才2 小时前
【learn-claude-code】S07TaskSystem - 任务系统:大目标拆成小任务,持久化到磁盘
java·人工智能·ai
数据知道2 小时前
claw-code 源码详细分析:子系统目录地图——几十个顶层包如何用五条轴(会话 / 工具 / 扩展 / 入口 / 桥接)读懂?
服务器·python·ai·claude code
哥布林学者3 小时前
深度学习进阶(四)Transformer 整体结构
机器学习·ai
心.c3 小时前
嵌入式 AI 助手的三层意图识别架构:如何在“快、准、稳“之间取得平衡
人工智能·ai·架构
数据知道3 小时前
claw-code 源码详细分析:命令宇宙 vs 工具宇宙——`commands` / `tools` 镜像清单如何驱动路由与 shim 执行?
linux·服务器·网络·python·ai·claude code
AI自动化工坊3 小时前
HiClaw多Agent协同实战:基于Matrix协议的透明化AI团队架构
人工智能·ai·架构·agent·matrix·hiclaw
tianbaolc3 小时前
Claude Code 技能系统深度解析:核心架构
ai·架构·claude code
G皮T4 小时前
【OpenClaw】思路转变:从 “传统UI测试” 到 “AI驱动的UI测试”
自动化测试·人工智能·ai·agent·测试·ui测试·openclaw
Database_Cool_13 小时前
OpenClaw-Observability:基于 DuckDB 构建 OpenClaw 的全链路可观测体系
数据库·阿里云·ai