docs(skill): add software-engineering README and same-dir reference test
SKILL.md header pointed at same-dir README.md but the pack had no such file (CHANGELOG was supplied by #217, README was not). This track adds the README only: purpose, chapter map, appendix provenance entry point, seeding behaviour, and known boundaries. It states no rule, changes no SKILL.md semantics, and does not duplicate the CHANGELOG/script explanations -- overlapping parts are pointers, with an explicit division-of-labour section. Deletion retention is written only as the tombstone-design placeholder, deferring to the skill_seed implementation, because no tombstone implementation has landed. Test pins that every file SKILL.md cites as same-directory exists (CHANGELOG, README).
This commit is contained in:
1 parent
4e554b5c07
commit
452fc8ea7e
2 files changed
+222
No files matched your search
@@ -0,0 +1,134 @@
|
||||
# software-engineering 技能包说明
|
||||
|
||||
本文件是源码包的导航与装机说明,不是技能规则本身。
|
||||
规则只在 `SKILL.md` 里,改规则只改 `SKILL.md`;本文件不复述
|
||||
门禁、角色细则与校验规则,复述就会漂移。
|
||||
|
||||
版本与状态以 `SKILL.md` 文首为准:v0.2,2026-10-30,草稿;
|
||||
其文首自述未提 PR、未部署生产、未改任何生产代码。
|
||||
本文件只补说明,不改规则、不合并、不部署。
|
||||
|
||||
## 用途
|
||||
|
||||
面向“从零做一款软件、尤其是要同时做 web、macOS、Windows、
|
||||
iOS、Android 多个客户端”的任务:按产品规划、产品设计、架构契约、
|
||||
多客户端并行开发、联调测试、验收的顺序,用协调员任务派生角色线程
|
||||
推进,契约冻结后各客户端只在自己目录内开发,最后走评审合并与用户验收。
|
||||
|
||||
用与不用的判定只在 `SKILL.md` 的“何时用 / 何时不用”两节,
|
||||
本文件不另立标准。只做单文件小改动、只问概念时不用本技能,
|
||||
这是 `SKILL.md` 的原话指向,不是本文件的补充规则。
|
||||
|
||||
## 包内文件一览
|
||||
|
||||
源码位置是 `cloud/skills/software-engineering/`,包内文件如下:
|
||||
|
||||
- `SKILL.md`:唯一规则权威,含正文与文末附录随附版。
|
||||
- `README.md`:本文件,导航与装机说明,不进入租户。
|
||||
- `CHANGELOG.md`:变更时间线,见下文“与 CHANGELOG 的分工”。
|
||||
- `templates/roles/`:附录的 9 个编辑源,见下文“附录溯源”。
|
||||
- `tools/check_appendix.py`:附录校验脚本,只校验,不改 `SKILL.md`。
|
||||
|
||||
## SKILL.md 章节结构(只列名,不复述规则)
|
||||
|
||||
正文节:
|
||||
|
||||
- 何时用 / 何时不用
|
||||
- 核心原则(协调员和所有角色线程都必须遵守)
|
||||
- 阶段 DAG(不是所有线程同时开,是按门禁、分阶段开)
|
||||
- 门禁表
|
||||
- 接单选型:协调员第一件事是问,不是写代码
|
||||
- 角色线程矩阵
|
||||
- 协调员派生子任务的必填字段
|
||||
- 待办机制(不依赖提示词注入)
|
||||
- 契约冻结与变更协议
|
||||
- 目录与分支规则
|
||||
- GitHub 保证(每线程一分支、一 PR、一合并门),下含分支、
|
||||
PR 交付、合并门、合并方式与合并记录、发布与回滚、
|
||||
安全六个小节
|
||||
- 测试与验收
|
||||
- 失败、续跑与成本
|
||||
- 诚实边界:原生客户端
|
||||
- 校验(协调员每过一个门禁自查一次)
|
||||
|
||||
附录节:
|
||||
|
||||
- 附录:角色模板(播种随附版),下含 9 章附录角色,
|
||||
每章标题注明其来源文件,见下文“附录溯源”。
|
||||
|
||||
## 附录溯源
|
||||
|
||||
附录 9 章的编辑源在 `templates/roles/` 下,文件与章一一对应:
|
||||
|
||||
`00-coordinator.md`、`01-product-manager.md`、`02-architect.md`、
|
||||
`03-designer.md`、`04-client-developer.md`、`05-backend.md`、
|
||||
`06-qa.md`、`07-acceptance.md`、`08-shared-core.md`。
|
||||
|
||||
校验入口(仓库根目录执行):
|
||||
|
||||
```sh
|
||||
python3 cloud/skills/software-engineering/tools/check_appendix.py
|
||||
```
|
||||
|
||||
该脚本默认校验模式逐章比对源与附录;`--emit` 模式只把拼接后
|
||||
的附录规范形式打印到标准输出,供编辑者起草参考,绝不是可直接
|
||||
覆盖 `SKILL.md` 的字节补丁。校验的规范形式、允许差异与失败条件
|
||||
以脚本注释为准,本文件不另抄一份;补齐的时间线见 `CHANGELOG.md`。
|
||||
任一侧改动都应先被校验拦住,而不是悄悄漂移:改附录先改源,
|
||||
再按技能轨重发附录,脚本本身不替编辑者改 `SKILL.md`。
|
||||
|
||||
## 播种行为
|
||||
|
||||
装机路径(`SKILL.md` 文首原话指向):
|
||||
|
||||
- 源码位置:`cloud/skills/software-engineering/SKILL.md`
|
||||
- 播种后租户内位置:`<codex-home>/skills/software-engineering/SKILL.md`
|
||||
|
||||
播种实现是 `cloud/skill_seed.py`,本段只是其摘要,冲突以实现
|
||||
与测试为准:
|
||||
|
||||
- 只复制各技能的 `SKILL.md` 一个文件;`README.md`、`CHANGELOG.md`、
|
||||
`templates/`、`tools/` 均不进入租户目录。
|
||||
- 目标缺失则复制;目标与源码相同则不动;目标已被租户改动
|
||||
(内容不同)则绝不覆盖,记入 `skills_skipped_differ` 并原样保留。
|
||||
- 包内某技能目录缺 `SKILL.md` 时跳过,不凭空捏造。
|
||||
- 因此租户任务内只能看到 `SKILL.md` 随附的附录全文,附录仍是
|
||||
租户侧的权威版本;本文件与附录源只在源码包一侧可见。
|
||||
|
||||
删除行为按现行实现写,不按设想写:租户已删 `SKILL.md` 会在
|
||||
下次播种时重建(missing 即复制)。删除保留机制见 tombstone 设计,
|
||||
行为以 skill_seed 实现为准。
|
||||
|
||||
## 与 CHANGELOG 的分工
|
||||
|
||||
同一说明只落一处,本文件与 `CHANGELOG.md` 不复制粘贴同一份说明:
|
||||
|
||||
- `README.md`(本文件):包是干什么的、文件都在哪、从哪验证、
|
||||
播种后租户能看到什么。回答“怎么找到、怎么核对”。
|
||||
- `CHANGELOG.md`:何时补了什么、此前缺什么、缺的那段历史是否
|
||||
可追溯。回答“这包经历了什么变化”。此前 v0.1 → v0.2 的 5 个
|
||||
P0 缺口明细因当时无此文件而无法从本文件追溯,`CHANGELOG.md`
|
||||
开篇已明说不编造那段历史;2026-10-31 起的附录溯源补齐条目
|
||||
记在那里,不重复抄到本文件。
|
||||
- `SKILL.md`:规则本身,唯一权威。
|
||||
- `tools/check_appendix.py` 的注释:校验的规范形式权威。
|
||||
- `cloud/skill_seed.py` 及其测试:播种行为权威。
|
||||
|
||||
改规则改 `SKILL.md`,改溯源记录改 `CHANGELOG.md`,改校验规则
|
||||
改脚本注释与对应测试;本文件只在导航、路径或分工本身变化时才改。
|
||||
|
||||
## 已知边界
|
||||
|
||||
- 本轨只补说明:不改 `SKILL.md` 正文语义,不改任何规则,
|
||||
不改播种行为,不合并,不部署。
|
||||
- 租户已删 `SKILL.md` 会重播种,见上文“播种行为”;删除保留
|
||||
未落地为实现,不以本文件声称已实现。
|
||||
- 附录分隔符不统一的现状与校验处理见 `CHANGELOG.md` 与脚本注释,
|
||||
本文件不另行规定、不强行统一 `SKILL.md`。
|
||||
- `SKILL.md` 正文还提到 `templates/artifacts/` 下的模板名
|
||||
(PRD 大纲、接单问卷、验收清单);本包 `templates/` 目前只有
|
||||
`roles/`,artifacts 模板不在本轨补齐范围,本文件不声称它们已存在,
|
||||
引用状态以 `SKILL.md` 原文为准。
|
||||
- 播种落盘与 `skills/list` 发现已验证;任务内模型实际调用技能
|
||||
尚未验证,本文件不声称已验证(见 `cloud/skill_seed.py` 的
|
||||
honest boundary 注记)。
|
||||
@@ -0,0 +1,88 @@
|
||||
"""Same-directory references of the software-engineering skill.
|
||||
|
||||
Background: SKILL.md's header points at two same-directory files --
|
||||
``CHANGELOG.md`` ("see CHANGELOG") and ``README.md`` (install path).
|
||||
CHANGELOG was supplied by the appendix-provenance track; README was
|
||||
still missing, so the header's install-path pointer dangled. This file
|
||||
pins the repair, and nothing else:
|
||||
|
||||
- every file SKILL.md cites with the qualifier "same directory"
|
||||
(``同目录 `X.md` ``) exists in the skill directory -- today exactly
|
||||
CHANGELOG.md and README.md, so a future dangling same-directory
|
||||
reference fails here instead of shipping silently;
|
||||
- README covers the topics it is supposed to cover (package layout,
|
||||
appendix provenance entry point, seeding behaviour, and the
|
||||
tombstone-design placeholder for deletion retention) without
|
||||
becoming a second copy of the appendix or of CHANGELOG: it must
|
||||
not contain appendix chapter headings, and it must not invent a
|
||||
tombstone marker filename.
|
||||
|
||||
Scope guard: this test never edits SKILL.md. In particular it does
|
||||
NOT assert on the templates/artifacts/ names mentioned in the SKILL
|
||||
body (PRD outline, intake questions, acceptance checklist): those are
|
||||
not same-directory references, they are not in this pack, and their
|
||||
status is README's stated known boundary, not a dangling header
|
||||
reference to pin here.
|
||||
"""
|
||||
|
||||
import re
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
|
||||
REPO_ROOT = Path(__file__).resolve().parents[2]
|
||||
SKILL_DIR = REPO_ROOT / "cloud" / "skills" / "software-engineering"
|
||||
SKILL_FILE = SKILL_DIR / "SKILL.md"
|
||||
README_FILE = SKILL_DIR / "README.md"
|
||||
|
||||
# ``同目录 `X.md` `` -- the header's same-directory citations only.
|
||||
SAME_DIR_REF_RE = re.compile(r"同目录\s*`([^`]+\.md)`")
|
||||
|
||||
|
||||
class SkillReadmeRefsTestCase(unittest.TestCase):
|
||||
def test_same_dir_refs_all_exist(self):
|
||||
skill_text = SKILL_FILE.read_text(encoding="utf-8")
|
||||
refs = set(SAME_DIR_REF_RE.findall(skill_text))
|
||||
self.assertEqual(
|
||||
refs, {"CHANGELOG.md", "README.md"},
|
||||
"SKILL.md 的同目录引用应恰为 CHANGELOG 与 README,实际:%s"
|
||||
% sorted(refs))
|
||||
for name in sorted(refs):
|
||||
self.assertTrue(
|
||||
(SKILL_DIR / name).is_file(),
|
||||
"SKILL.md 引用的同目录文件缺失:%s" % name)
|
||||
|
||||
def test_readme_covers_required_topics(self):
|
||||
self.assertTrue(README_FILE.is_file(), "README.md 缺失")
|
||||
text = README_FILE.read_text(encoding="utf-8")
|
||||
for fragment in (
|
||||
"templates/roles/",
|
||||
"check_appendix.py",
|
||||
"CHANGELOG.md",
|
||||
"skill_seed",
|
||||
"只复制各技能的 `SKILL.md` 一个文件",
|
||||
# Deletion retention is NOT implemented: README must
|
||||
# say so via the tombstone-design placeholder, and
|
||||
# defer to the skill_seed implementation, verbatim.
|
||||
"删除保留机制见 tombstone 设计",
|
||||
"行为以 skill_seed 实现为准",
|
||||
"分工",
|
||||
):
|
||||
self.assertIn(fragment, text, "README.md 应提及:%s" % fragment)
|
||||
|
||||
def test_readme_does_not_duplicate_appendix(self):
|
||||
text = README_FILE.read_text(encoding="utf-8")
|
||||
self.assertIsNone(
|
||||
re.search(r"^## 附录角色:", text, flags=re.M),
|
||||
"README 不应复制附录章节标题,否则会成为第二份会漂移的附录")
|
||||
|
||||
def test_readme_invents_no_tombstone_marker(self):
|
||||
text = README_FILE.read_text(encoding="utf-8")
|
||||
self.assertIn("tombstone", text, "README 应提及 tombstone 设计占位")
|
||||
self.assertIsNone(
|
||||
re.search(r"tombstone\.[a-z]+", text),
|
||||
"tombstone 未落地为实现,README 不得编造标记文件名")
|
||||
self.assertNotIn(".tombstone", text)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in new issue
Block a user