oh-my-openagent 的 Prompt 契约测试移除工程:AST 扫描器、fail-first 验证与 seam 保留策略

发布时间:2026/9/19 15:30:58
oh-my-openagent 的 Prompt 契约测试移除工程:AST 扫描器、fail-first 验证与 seam 保留策略
oh-my-openagent 的 Prompt 契约测试移除工程AST 扫描器、fail-first 验证与 seam 保留策略【免费下载链接】oh-my-openagentOmO: Just type mass ulw keyword with your prompt. Now you are the master of graph engineering.项目地址: https://gitcode.com/gh_mirrors/oh/oh-my-openagent本篇技术指南围绕 oh-my-openagent 仓库中一次完整的分支级工程实践展开系统性移除对作者创作的 prompt、指令、SKILL.md、规则、AGENTS.md与 Markdown 指令文本的自动化断言即 prompt 契约测试同时用自研 AST 扫描器 SHA-256 指纹分类索引建立fail-first先在基线失败、再在最终树上变绿的可复现证据链并明确保留 6 类机器消费的测试 seam。读完本文你将掌握这套扫描器管线的原理与命令、证据文件的组织方式以及如何在大体量 Agent 项目中安全地裁剪纯文本契约类测试而不损失运行时、安全与用户可见行为覆盖率。背景为什么 prompt 契约测试必须被移除在 oh-my-openagent 这类深度依赖 prompt 编排的 Agent 工程中测试代码很容易出现一种过度契约化倾向直接对 agent 系统提示词、SKILL.md正文、规则文件、AGENTS.md的措辞、标题、章节顺序、文本片段、快照乃至作者创作文本的长度做断言。这类断言的共同问题是纯 prose 没有稳定的自动化测试 seam——它描述的是写给人或模型读的指导文字而不是机器消费的结构化值。任何措辞润色都会让测试无意义地红掉而真正的行为回归却无法被这类测试捕获。该分支的最终结论见 FINAL-REPORT.md非常明确移除对 authored prompt、directive、SKILL.md、rule、AGENTS.md与 markdown-instruction 文本的自动化契约同时完整保留机器消费的值machine-consumed values真实工件之间的字节级/副本级相等性real artifact equality解析、路由、分发、状态、安全、运行时投递行为用户可见的 UI 与错误行为。这一边界随后被固化进仓库策略写入了 AGENTS.md 与 tests/AGENTS.md完整 diff 见 agents-policy-diff.txtPrompt/prose contract tests are forbidden. Never assert authored agent prompt,SKILL.md, rule,AGENTS.md, or markdown-instruction wording, headings, section order, fragments, snapshots, negative past wording, or authored text length. Test only machine-consumed fields/sentinels/tool names, byte or shipped-copy equality between real artifacts, or observable runtime behavior such as parsing, routing, dispatch, state, security, and dynamic input propagation. Pure prose has no automated-test seam; review and QA-by-read are the correct verification.扫描器管线从 git 跟踪文件到分类索引移除了哪些、保留了哪些不能靠人工判断必须由确定性的 AST 扫描器给出全量清单。整套工具位于 .omo/evidence/20260817-remove-prompt-contract-tests/ 目录入口说明见 README.md。1. 枚举直接来自git ls-files无 allowlistaudit_prompt_contracts.py用正则(?:^|/).\.(?:test|spec)\.(?:[cm]?[jt]sx?)$过滤git ls-files -z的输出audit_prompt_contracts.py枚举仓库内所有被跟踪的JavaScript/TypeScript 测试与 spec 文件。这里有两个关键设计没有任何路径 manifest 或 allowlist 控制发现范围凡是git跟踪的测试文件都在扫描范围内若某个被跟踪的路径在工作树中被删除它不会被静默忽略而是单独汇报为tracked-missing确保删文件本身也成为证据的一部分。2. 解析TypeScript 编译器 API扫描器把文件清单写入临时 JSON再调用node prompt_contract_ast.mjsprompt_contract_ast.mjs。该脚本使用仓库内安装的 TypeScript 6.0.3 编译器 API 解析每个测试文件输出{ parser: typescript-6.0.3, candidates }结构。扫描覆盖的断言模式非常广详见 prompt_contract_scan.mjs、prompt_contract_values.mjs、prompt_contract_derived.mjs、prompt_contract_node_assert.mjs断言字面量穿过变量引用、数组、for...of绑定、布尔.includes()表达式、matcher 链被持续追踪顺序助手调用order-helper、派生标题/token 数组、indexOf顺序断言startsWith别名、正则派生的展示类检查presentation checksNode 原生assert的各种变体、可调用断言callable assertions以及快照断言snapshot assertions。也就是说即便测试作者把断言的期望值藏在变量、数组或派生函数里扫描器也能还原出实际断言了哪段文本。3. 指纹不含行号的 SHA-256每个 candidate 按path candidate kind matcher actual expression expected value计算 SHA-256 指纹并与 prompt-contract-classification-index.json或补充分类 prompt-contract-classification-supplemental.json中的 disposition 做联接。指纹刻意不含行号因此代码行移动不会破坏指纹稳定性同时该索引记录了全部 scanner 脚本的哈希audit_prompt_contracts.py、classification_bundle.py、prompt_contract_ast.mjs 等 15 个文件的 SHA-256保证用的就是这份扫描器这一事实本身可被校验。4. 判定allowed / unclassified / forbidden / stale分类提案classification-proposals/core.json 及其余 codex/infra/opencode/senpi-shared/scripts-tests 提案中每条 allowed 或 forbidden 记录必须同时满足两个条件属于扫描器定义的显式 seam 类别machine-sentinel、parser-fixture、runtime-behavior、security-boundary、shipped-copy-equality、user-ui-error带有非空的 rationale例如AGENTS.md 是机器发现的指令文件名常量、用 fixture body 证明 root 上下文排除逻辑。audit_prompt_contracts.py的退出码逻辑audit_prompt_contracts.py为return int( bool( payload.unclassified_count or payload.forbidden_count or payload.stale_classification_count ) )即只要存在未分类、被禁止或**过期stale**的分类条目命令就以非零退出——这是整个 fail-first 门禁的落点。Fail-first 证明先红后绿的可复现证据移除测试最大的风险是偷偷放水用缩小范围或一刀切放行来把红变绿。该分支的做法相反用同一份最终扫描器分类索引分别在两个时间点跑出相反的退出码把过程性证据全部落盘维度原始基线RED最终 rebase 树GREEN基线/状态commit3dd88267f87bd47795d3eea7782e676bb40e2f9brebase 到当前 dev 的最终工作树退出码10跟踪测试数2,2912,297候选断言数2,4211,910已分类 allowed1,6741,910未分类7470forbidden00过期分类940缺失跟踪文件00证据文件逐一对应原始基线完整违规清单red-prompt-contract-scan-post-quality.txt含 747 条 unclassified 明细编辑后、rebased 前摘要green-prompt-contract-scan-post-quality.txt最终 rebase 后摘要green-prompt-contract-scan-rebased.txt。三者使用完全相同的命令python3 .omo/evidence/20260817-remove-prompt-contract-tests/audit_prompt_contracts.py \ --classification .omo/evidence/20260817-remove-prompt-contract-tests/prompt-contract-classification-index.json \ --compact--compact模式下摘要以 JSON 输出随后逐行打印每个候选的位置、分类与指纹tracked-missing与stale也各自独立成行杜绝删路径来消灭违规的作弊路径。保留的 seam六类仍可断言的测试边界移除的不是所有文本断言而是对作者 prose 的契约。保留边界被汇总在 preserved-prompt-test-seams.json 中该文件本身由 7 份分类提案汇总而来绑定 1,476 个活跃指纹seam 类别含义出现次数唯一指纹machine-sentinel机器消费的哨兵值/字段名/工具名如AGENTS.md常量、task_create、$SESSION_ID718594parser-fixture解析器 fixture 往返JSON/JSONC/Markdown 配置加载后值不变213187runtime-behavior可观察的运行时行为注入、路由、去重、重试、状态机473416security-boundary安全边界URL 校验、密钥脱敏、指令注入拦截6751shipped-copy-equality真实工件之间的字节/副本相等源码 vs 打包产物121109user-ui-error用户可见的 UI 与错误消息135119一个典型的分界示例packages/memory-core/src/compile/cache.test.ts中toBe(second)、toContain(- AGENT_ID: other-agent)等属于机器行为断言被保留而packages/memory-core/src/reflection/assets/assets.test.ts中断言Phase 1: Investigate等作者创作文本顺序的候选则被移除或重构为运行时行为断言。分类提案中的每条 rationale 都解释了为什么这条断言不落在 prose 上。自动化验证矩阵五条独立红线测试裁剪之外整个仓库必须仍处于绿色状态。FINAL-REPORT 记录的自动化验证结果如下bun run typecheck根目录、scripts 与每个 package 全部 exit 0bun test15,613 passed、0 failed7 个既有平台/TUI skip131,764 个断言2,048 个文件bun run buildexit 0bun run test:codexexit 0最终 Node 段492/492 passed扫描器回归套件在声明的 uv 环境下15 项全部通过独立评审阻塞项解决记录review-fixes.txtrebase 后命令与结果台账post-rebase-validation.txt聚焦域汇总focused-domain-verification.txtLSP 调用与干净的 changed source/helper 结果lsp-diagnostics.txt扫描器自身的严格检查pytest、Ruff、basedpyright strict、no-excuse 检查、Node 语法检查、单文件 ≤250 行纯逻辑LOC上限全部通过。扫描器回归套件与审计入口的复现命令来自 README.mduv run --script .omo/evidence/20260817-remove-prompt-contract-tests/test_audit_prompt_contracts.py -v uv run --script .omo/evidence/20260817-remove-prompt-contract-tests/test_node_assert_scanner.py -q uv run --script .omo/evidence/20260817-remove-prompt-contract-tests/test_snapshot_scanner.py -q真实表面 QA四个宿主环境的现场验证自动化测试不能证明真实插件还能跑。该分支对四个真实宿主环境做了现场 QA汇总见 manual-qa-summary.txt1. OpenCode 真实本地插件opencode-serve-wake-rebased/ 目录RESULTFIXED一次终端停止one terminal stop、一个子任务会话one child task sessionlive-route 分发live-route dispatch正常真实数据库计数不变精确计数按卫生规则脱敏。2. Codex 真实 app-server隔离的本地插件安装mock-model turn 完整走完hook/completed事件序列sessionStart、userPromptSubmit、stop均被观测到真实 Codex 配置哈希保持不变。3. Codex 隔离安装器插件缓存为5.0.0-beta.8omosisyphuslabs已启用10 个组件 bin 与 agent TOML 完成链接真实 Codex 配置哈希同样不变。4. Senpi 本地扩展经 xterm.js与 CLISenpi 终端证据位于 senpi-web-terminal/ 目录截图、文本、ANSI 与 metadata 齐备tipsJSON 合法help命令 exit 0、非法选项 exit 1——用户可见 CLI 行为未受裁剪影响。下图为该次 xterm.js 终端现场运行结果Senpi post-rebase CLI 断言resultPASS、ultraworkInjectedtrue、commentCheckerPASS、realSenpiUntouchedtrue。清理与范围控制不留残余裁剪不是删了就跑还包括对称的收尾移除了有引用佐证的孤儿导出orphaned exports、测试助手、一个死模块dead module与过期的 scoped 文档死代码引用证据见 dead-code-reference-audit.txt生成的 CodeGraph/Senpi 产物最终 diff 为零临时 detached 扫描器 worktree、XDG/CODEX/Senpi 隔离 home、fake server、PTY 以及 LSP bridge 全部被清理脏的共享主 checkout 中不留任何任务编辑残留。证据卫生可复核但不可泄露所有证据制品遵循同一契约见 README.md记录精确命令、观测输出、二进制 PASS/FAIL 条件与清理回执。原始密钥、环境 dump、凭据、cookie、授权头与私有日志一律省略分类来源通过 prompt-contract-classification-index.json 中的sources数组做哈希绑定每份提案文件都带有 SHA-256保证被允许的就是这些、且只有这些。策略侧同样留痕根规则 AGENTS.md 与仓库测试规则 tests/AGENTS.md 的 RED/GREEN 审计输出分别为 red-agents-policy-audit.txt 与 green-agents-policy-audit.txt评审者可读的差异在 agents-policy-diff.txt 中展示git diff --check零空白错误。可复用的方法论要点把裁剪做成门禁而非人工决策任何测试断言候选都必须落到 6 类 machine seam 之一并给出非空理由否则 CI 拒绝——这防止未来重新长出 prompt 契约测试fail-first 证据三件套同一命令在基线RED与最终树GREEN各跑一次中间态存档让确实删了该删的可审计指纹不含行号用pathkindmatcheractualexpected的 SHA-256 做稳定标识代码挪动不会制造假 diff真实宿主 QA 与单测解耦裁剪文本契约测试后用 OpenCode/Codex/Senpi 的真实插件安装、hook 事件序列与终端 exit code 补足行为未变的置信度。这套从AST 全量扫描 → 哈希分类 → RED/GREEN 门禁 → 多宿主 QA的完整证据链位于 .omo/evidence/20260817-remove-prompt-contract-tests/可作为大型 Agent 仓库做测试治理时的直接参考范本。【免费下载链接】oh-my-openagentOmO: Just type mass ulw keyword with your prompt. Now you are the master of graph engineering.项目地址: https://gitcode.com/gh_mirrors/oh/oh-my-openagent创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考