skill: cross-task artifact pass with sha256 dual-channel verification

Core artifacts travel as an explicit manifest; coordinator triple-checks
(core report vs manifest vs recomputed hash) before cleanup, regression
rewrites files verbatim, recomputes sha256, stops on ARTIFACT-HASH-MISMATCH
and only then runs the same core code plus import-only regression tests.
This commit is contained in:
host committed 2026-11-03 02:48:55 +00:00
1 parent d973e63b11
commit 0072e1ae6a
2 files changed
+156

No files matched your search

+119
View File
@@ -640,6 +640,100 @@ tests/ # QA 线程专属,含跨端一致性用例
- 路线选择(web + PWA / WebView 壳,iOS / Android 原生后置)必须在 G0
由用户定,不能由某个客户端线程中途自己改路线、自己把原生端加回 MVP。
## 跨任务产物传递(artifact pass)
问题:任务 worktree 互相隔离,回归任务默认拿不到核心任务的代码。
此前回归只能按契约自己写一套独立 fixture 测试来“猜”契约,
这种回归绝不能声称“重跑了核心代码”。本节是唯一的补救机制:
核心产物作为显式产物,经协调员复核后传给回归,回归跑同一份代码。
### 产物清单(manifest)
核心任务交付时必须同时写出产物清单文件,例如
`artifacts/ARTIFACT_MANIFEST.json`,格式只含下列字段,
不含任何密钥、口令、token:
```
{
"artifact_version": "1",
"source_task_id": "<核心任务 id 全文,协调员记录>",
"source_project_id": "<核心任务项目 id 全文>",
"contract_version": "<契约版本,例如 v1.1>",
"files": [
{"path": "shared/todo_v11.py", "sha256": "<64 位小写 hex>", "bytes": 4811},
{"path": "tests/test_todo_v11.py", "sha256": "<64 位小写 hex>", "bytes": 2417}
]
}
```
清单里的 hash 必须由核心任务用 `sha256sum` 实测算出,
不许手写、不许照抄上一轮、不许用文件名代替 hash。
`tests/TEST_RUN.txt` 必须是真实跑测试的输出,不许手写。
### 协调员传递前三方核对(缺一不可)
协调员在清理核心任务租户之前,必须先把核心产物取出来,
否则清理后产物不可恢复,回归无物可跑。取出来后独立重算:
1. 核心任务结尾报告里报的 hash;
2. 产物清单文件里的 hash;
3. 协调员自己对取出的文件重算的 hash。
三处全对上才算“已核验产物”,协调员才能往下传。
任一处对不上就停:不传、不派生回归、不接受核心交付,
先查是取错文件、写错清单还是核心任务本身算错,修好后
重新走一遍三方核对。协调员绝不把未经核验的 hash 塞进回归提示词。
### 回归任务双通道核对(先核对,再跑测试)
协调员派生回归时,必须双通道给齐,缺一通道不派生:
- 通道一(提示词清单):回归提示词里贴出已核验的产物清单全文
(每个文件路径、sha256、字节数)。
- 通道二(文件产物):回归提示词里贴出核心文件的完整原文,
回归任务按原文原样写盘到相同路径(含产物清单文件本身),
写盘后自己跑 `sha256sum` 重算,再与通道一的清单逐项比对。
回归任务的第 0 步永远是核对,不是跑测试:
- 全对上:才能跑测试,并在结尾写 `ARTIFACT-VERIFY` 一节,
列出每个文件的期望 hash、实测 hash、是否一致,最后写
`ARTIFACT-VERIFY-OK`。
- 任一文件对不上:立刻停下来,结尾只报
`ARTIFACT-HASH-MISMATCH`,不跑测试、不写自己的 fixture、
不猜契约、不把失败写成通过。协调员收到不匹配报告后,
不接受该回归的任何测试结论,重新传递或重新跑核心任务。
### 回归跑同一份代码的硬规则
- 回归直接跑核心代码与核心测试原样,例如
`python3 -m unittest discover -s tests -v`,输出如实记入
`tests/TEST_RUN.txt`,不许手写。
- 回归如需补测,只能新增“import 核心模块”的测试,
绝不复制核心实现、绝不写一套功能等价的 fixture 来冒充核心代码。
补测失败是缺陷,不是让回归顺手改核心代码的理由。
- 回归任务只读核心产物文件:不改核心代码、不改核心测试、
不改契约版本、不加新功能。核心代码有缺陷时,缺陷回核心线程修,
修完产生新的产物清单版本(artifact_version 加一、hash 全变),
旧核验立即作废,协调员与回归必须按新清单重新走三方核对
与双通道核对,不得沿用旧 hash 冒充新代码已回归。
- 产物传递不改变验收规则:回归通过不等于用户验收通过,
验收仍由用户逐项确认;产物传递也不改变清理规则,
清理仍按精确 id 逐项核对,绝不按名字前缀删。
### 协调员回归提示词模板(必填字段)
回归提示词除“协调员派生子任务的必填字段”外,必须再含:
1. 已核验产物清单全文(通道一)。
2. 核心文件完整原文(通道二),并写明“先原样写盘、算 hash、
对不上就停,不要硬跑”。
3. 核心任务 id 与项目 id 前缀(供复核,不供猜测)。
4. 回归范围:只跑清单里的核心代码与测试,不加新功能、
不重写 fixture、不改核心文件。
5. 结尾必填 `ARTIFACT-VERIFY` 一节与 `ARTIFACT-VERIFY-OK`
或 `ARTIFACT-HASH-MISMATCH` 其中之一,缺这节视为交付不完整。
## 校验(协调员每过一个门禁自查一次)
- 每个子任务提示词里有没有角色模板全文、拥有目录、分支名、完成定义、TODO-UPDATE 要求?
@@ -673,6 +767,10 @@ tests/ # QA 线程专属,含跨端一致性用例
PostgreSQL、Drizzle 或 Prisma 二选一、Vitest),G2 冻结后有没有
未经用户特别要求就换语言?iOS / Android 是不是仍写成后置占位,
未编译 / 未验证有没有标注为未发布?
- 跨任务产物传递走了吗?核心产物清理前取出了吗?三方核对全对上了吗?
回归提示词里产物清单与文件原文双通道齐了吗?回归结尾有
ARTIFACT-VERIFY 一节与 ARTIFACT-VERIFY-OK 吗?回归是跑同一份
核心代码,还是自己写 fixture 猜契约?
有一项为否,就停在当前门禁,不进入下一阶段。
## 附录:角色模板(播种随附版)
@@ -806,6 +904,20 @@ full-auto-executor + installation id。质量门禁全部自动且阻塞合并
一条决策写清日期、议题、决定、理由、影响端;推翻旧决策追加新条
写明“取代 D-n”,绝不改旧条原文、不删旧条。
## 跨任务产物传递(协调员)
- 回归任务拿不到核心代码时,绝不让回归自己写 fixture 猜契约:
走技能正文“跨任务产物传递”一节。
- 清理核心租户前先取出核心产物(代码、测试、产物清单
`artifacts/ARTIFACT_MANIFEST.json`),
独立重算 sha256,与核心报告、清单文件三方核对,全对上才传。
- 派生回归时双通道给齐:提示词里贴已核验产物清单全文,
再贴核心文件完整原文,令回归先原样写盘、算 hash、对不上就停。
- 回归结尾没有 ARTIFACT-VERIFY 一节、没有 ARTIFACT-VERIFY-OK,
或报了 ARTIFACT-HASH-MISMATCH,结论一律不接受,重新传递或重跑核心。
- 核心修完缺陷出新产物时,旧核验作废,按新清单重新走三方核对
与双通道核对,不得沿用旧 hash。
## 失败处理
- 有进度的中断任务:断点续跑。
@@ -1148,6 +1260,12 @@ agent 类产品还要参与 G3.5 可行性 spike:任务能创建、能跑出
5. 缺陷清单:每个缺陷写清复现步骤、影响客户端、严重程度、归属线程。
6. 回归清单:契约从 v1 升到 v2 时,哪些用例必须重跑;G5 缺陷修完回 G5 回归,
回归范围按契约变更影响面定,不是每次都全量重测。
7. 跨任务产物传递:回归第 0 步永远是核对,不是跑测试。
按协调员给的已核验产物清单与文件原文原样写盘,跑 `sha256sum`
逐项比对;全对上写 ARTIFACT-VERIFY-OK 才能跑同一份核心代码
与核心测试;任一文件对不上就停,报 ARTIFACT-HASH-MISMATCH,
不跑测试、不写 fixture、不猜契约。补测只能 import 核心模块,
不能复制核心实现,不能写功能等价的 fixture 冒充核心代码。
## 未编译端的口径
@@ -1166,6 +1284,7 @@ iOS / Android 原生后置占位不进 QA 通过表,标注“未编译 / 未
- 不替开发线程改代码“顺手修掉”,修了就测不出原缺陷。
- 不把“没测”写成“通过”。没测的端和用例要单独列出。
- 不在 hash 未核对通过时跑测试,不用自己写的 fixture 冒充核心代码。
---
@@ -0,0 +1,37 @@
"""software-engineering 技能的跨任务产物传递:轻量关键词断言。
只断言正文与附录都含有产物传递的关键概念,不逐字背诵全文:
产物清单文件名、sha256sum 实测、hash 不一致就停、核对通过标记、
回归跑同一份代码而非自己写 fixture 猜契约。正文改了附录没同步时,
本测试在附录部分就会失败(与 GitHub 保证测试同款口径)。
"""
import unittest
from pathlib import Path
SKILL = Path(__file__).resolve().parents[1] / "skills" / "software-engineering" / "SKILL.md"
KEYWORDS = ("跨任务产物传递", "ARTIFACT_MANIFEST",
"sha256sum", "ARTIFACT-VERIFY-OK",
"ARTIFACT-HASH-MISMATCH", "三方核对",
"双通道", "fixture")
class SoftwareEngineeringArtifactPassTestCase(unittest.TestCase):
def test_artifact_pass_in_body_and_appendix(self):
text = SKILL.read_text(encoding="utf-8")
main, sep, appendix = text.partition("## 附录:角色模板")
self.assertTrue(sep, "appendix marker missing")
for kw in KEYWORDS:
self.assertIn(kw, main, kw)
self.assertIn(kw, appendix, "appendix: " + kw)
def test_artifact_pass_forbids_fixture_substitution(self):
text = SKILL.read_text(encoding="utf-8")
main = text.partition("## 附录:角色模板")[0]
self.assertIn("绝不复制核心实现", main)
self.assertIn("跑同一份", main)
if __name__ == "__main__":
unittest.main()