mirror of
https://github.com/codestable/CodeStable.git
synced 2026-09-19 09:03:09 +08:00
feat: add project learning lifecycle
This commit is contained in:
@@ -0,0 +1,228 @@
|
||||
---
|
||||
status: active
|
||||
created: 2026-08-01
|
||||
work: ../work/epic-cs-continuous-learning-lifecycle.md
|
||||
---
|
||||
|
||||
# CodeStable 持续学习生命周期
|
||||
|
||||
## 起点与目标
|
||||
|
||||
四个 task skill 已会检索项目 lesson,`cs-keep` 也有证据、查重与合并门槛,但闭环停在“读过”和
|
||||
“写下”:任务中不会稳定识别真正的晶化时刻,lesson 再次命中后不验证真伪,也没有项目内迁移
|
||||
效果的因果证据。现有 eval 每个 cell 只有一次 agent invocation,不能证明任务 A 的经验改善了
|
||||
fresh 任务 B。
|
||||
|
||||
本 Epic 先落地项目内三步闭环:
|
||||
|
||||
```text
|
||||
任务内静默观察 -> 强信号候选 -> 显式授权后写 observed lesson
|
||||
-> fresh 任务 read-repair -> validated / retired
|
||||
-> 测试、checker、项目文档、ADR 等 canonical owner
|
||||
```
|
||||
|
||||
最终用 paired cross-session 实验证明:A 形成的 lesson 在不传递聊天上下文、不向 B 泄题时,能
|
||||
提高 fresh agent 完成 B 的正确率。跨项目、团队级与 CodeStable 全局方法论只预留边界。
|
||||
|
||||
## 范围与非目标
|
||||
|
||||
范围:
|
||||
|
||||
- `cs-feat`、`cs-issue`、`cs-refactor`、`cs-epic` 的静默信号识别、read-repair 与收尾 UX。
|
||||
- `cs-keep` 的 lesson 创建、验证、反证、晋升、退役与清理。
|
||||
- 项目内 session candidate -> lesson -> canonical owner 的迁移。
|
||||
- 维护者侧 paired/sequential eval runner 与 `cs-learning-transfer-001`。
|
||||
- ADR、双语公开文档、契约/eval 测试与 package 回归验证。
|
||||
|
||||
非目标:
|
||||
|
||||
- 不新增第九个 skill,不扩大 `cs` 最小决策核,不让 task skill 读取 sibling skill 文件。
|
||||
- 不恢复 `cs-feedback`、production feedback importer、transcript 扫描、状态机或自动上传。
|
||||
- 不创建 `.codestable/learning/`、全局 lessons、常驻索引、后台 telemetry 或集中 runtime。
|
||||
- 不持久化未收敛讨论、原始问答、完整思考过程或候选分支。
|
||||
- 不自动跨项目共享;脱敏反馈包、团队知识库与 shipped skill 上游更新留给后续 Epic。
|
||||
- 不用更醒目的文字代替能落成测试、lint、checker、类型或 deterministic helper 的约束。
|
||||
|
||||
## 核心模型
|
||||
|
||||
| 对象 | 生命周期与 owner |
|
||||
|---|---|
|
||||
| Learning signal | 当前任务内的可核实事件;未过门槛即丢弃 |
|
||||
| Crystallization candidate | 会话内有界候选;不是项目事实,不自动获得写入授权 |
|
||||
| Lesson | 项目级 staging,一条一文件;只保留尚未被更强 owner 完整承接的经验 |
|
||||
| Canonical guard | 测试、checker、lint、类型或 helper,机械阻止同类错误 |
|
||||
| Canonical knowledge | 项目既有文档、glossary、ADR 或 `attention.md` 中的唯一事实 owner |
|
||||
| Transfer evidence | fresh B 在有/无 lesson 的同源仓库上产生的 paired 结果 |
|
||||
|
||||
检索次数、模型自评置信度和“本次讨论过”不算学习证据。lesson 是可删、可纠偏的 staging,
|
||||
canonical guard/knowledge 才是稳定归宿。
|
||||
|
||||
## 行为契约
|
||||
|
||||
### 开工:有效命中必须说明影响
|
||||
|
||||
只有 scope 符合、未退役、经当前代码/测试/canonical 文档核实,并真实改变计划或验证的条目才算
|
||||
有效命中。四个 task skill 必须报告:`经验命中:{path}({status});核验:{fact};影响:
|
||||
{plan_or_check}`。纯关键词碰撞不报告为有效命中,也不能把“读过”冒充“采用”。
|
||||
|
||||
应用前 read-repair:`retired` 不应用;`observed` / `validated` 先核实再用;只是相关但没有改变
|
||||
行为时不制造复用证据;当前事实明确反证时立即停止应用并走窄退役,证据不足时不猜。
|
||||
|
||||
### 任务中:静默识别晶化时刻
|
||||
|
||||
任务内只在内存保留最多 3 条候选,按新证据替换低价值项,不暂停或询问。已有普通 work 时可
|
||||
复用证据节;不得为候选新建 work、transcript 或状态文件。
|
||||
|
||||
强信号限于:owner 纠正实际改变方案/代码/术语/验证;可复现证据推翻根因;同一路径失败两次后
|
||||
更换假设;blocking/important finding 暴露未编码不变量;新 red -> green 捕获可复发失败;lesson
|
||||
真实改变本次行为或被反证;重复 workaround;方法显著降低重试、成本或风险。
|
||||
|
||||
候选还必须同时有可追溯证据、能写成未来动作、适用于本次精确 diff 之外、且没有现成 canonical
|
||||
owner。网络波动、拼写、泛化口号、活动记录和已被机械 owner 完整覆盖的事实直接丢弃。选择时先看
|
||||
失败后果,再看证据与复发可能,最后优先低成本机械化,不生成伪精确分数。
|
||||
|
||||
### 收尾:低打扰与机械化优先
|
||||
|
||||
- 普通任务只在强信号成立时展示最高价值一条,首行固定 `晶化候选:{rule}`,并给证据、范围与
|
||||
建议归宿;无强信号完全不显示模板。没有记忆写入授权时不落盘,候选随会话结束消失。
|
||||
- 用户已明确说“记住 / 更新 / 退役”时同轮按 `cs-keep` 处理,不重复确认。
|
||||
- Epic 子项不展示、不询问;每个子项至多把一条去重候选写入既有游标证据区,最终毕业清单一次
|
||||
处理并复用最终 owner gate。
|
||||
- 当前任务范围内能直接落成 red -> green 测试/checker 的约束优先机械化,不另写重复 lesson;
|
||||
会扩大范围时只给候选,不借学习名义扩权。
|
||||
|
||||
## Lesson 生命周期与授权
|
||||
|
||||
新 lesson 最小格式:
|
||||
|
||||
```markdown
|
||||
---
|
||||
status: observed
|
||||
scope: 模块 / 命令 / 场景关键词
|
||||
date: YYYY-MM-DD
|
||||
---
|
||||
规则:未来可执行的结论。
|
||||
适用 / 不适用:边界与停止应用信号。
|
||||
证据:最多三个代表性路径、测试、diff 或任务指针。
|
||||
候选归宿:test | checker | attention | project-doc | adr | codestable-eval
|
||||
```
|
||||
|
||||
| status | 判据 |
|
||||
|---|---|
|
||||
| `observed` | 单次任务有证据,尚未在独立后续任务验证 |
|
||||
| `validated` | 非创建该 lesson 的任务和 agent invocation 中有效命中,真实改善行为并验证成功 |
|
||||
| `retired` | 被事实反证、范围完全失效或已被更强 owner 替代;不得应用且不再复活原结论 |
|
||||
|
||||
旧 lesson 缺 `status` 按 `observed` 读取,不批量迁移;只有真实状态变化或 `cs-keep` 本来就要更新
|
||||
时才补字段。不得保存原始对话、逐次命中日志或无限 evidence history。
|
||||
|
||||
创建、改写规则/scope、晋升、删除与跨项目反馈仍须用户显式 `cs-keep` 诉求、接受普通候选,或
|
||||
Epic 最终毕业 gate。为实现不中断的 read-repair,仅对已有且有效命中的 lesson 开放两种窄维护:
|
||||
|
||||
- `observed -> validated`:独立后续任务确实采用并验证成功,只补一次代表性证据;
|
||||
- `observed|validated -> retired`:当前仓库事实直接反证,只写原因与替代/反证指针。
|
||||
|
||||
窄维护不新建事实、不改规则、不扩 scope、不新增 gate,随当次代码、证据和游标进入同一语义原子
|
||||
milestone,最终报告文件变化;稳定 validated 命中不写文件。需要改写结论或证据不足时只给候选。
|
||||
任务内发现已有 canonical owner 时先 retire,删除留给 `cs-keep`;`cs-keep` 显式晋升则先验证新 owner,
|
||||
再在同一更新中直接删除重复 lesson。新结论不得通过复活 retired 条目获得 validated 身份。
|
||||
|
||||
`cs-keep` 继续负责查重、合并与约 50 条预算,并按以下顺序路由:机械 guard 优先;高频必读事实进
|
||||
`attention.md`(≤25 条);同时满足难回退、缺少上下文会令人意外、源于真实取舍的结构性决定进
|
||||
ADR;其他方法进项目既有文档。目标不存在时请 owner 选择,不发明目录。`codestable-eval` 只标记
|
||||
未来上游候选,本轮不导出、不上传、不改 skill。
|
||||
|
||||
## 项目内跨会话迁移实验
|
||||
|
||||
现有 runner 每 cell 只调用一次 agent。新场景增加 `answerType/task.kind: learning-transfer`,由独立
|
||||
sequence 模块承载;fixture 明确 A/B owning skill,每次 invocation 只注入该 skill 的冻结快照。
|
||||
|
||||
每个 paired cell:
|
||||
|
||||
1. 从 seed repo 运行 A,机械验证结果并捕获最多一条候选:普通任务读最终输出的 `晶化候选`,
|
||||
Epic 子项读既有游标证据区;A 失败计入失败,不得丢弃。
|
||||
2. 复制完全相同的 post-A repo 为 treatment/control。
|
||||
3. 先验证候选确属 lesson 类;若应进 attention/ADR,则标 fixture invalid,不算 skill failure。
|
||||
4. 仅 treatment 用 fresh `cs-keep` invocation 接收候选、证据和显式“记录”授权;除 lesson 外的
|
||||
mutation 视为失败。
|
||||
5. 可选 `between_tasks` hook 必须同样作用于两份 repo;stale guard 用它制造真实版本反证。
|
||||
6. treatment/control 各启动 fresh B;skill snapshot、任务文本和 prompt hash 相同,不点名 lesson,
|
||||
不继承 A、curation 或彼此上下文,唯一处理变量是 lesson。
|
||||
7. 临时目录销毁前跑 hidden/deterministic checks;B diff 白名单为任务改动、必要 work 证据,以及
|
||||
matched lesson 的窄状态/证据迁移,禁止改规则/scope 或破坏 schema。checkpoint key 含 phase,
|
||||
半 pair 不算完成,treatment/control 顺序按 k 交替;只存结构化指标、必要 diff 与哈希。
|
||||
|
||||
Epic 正向 fixture 不豁免 owner gate:seed 提供 `active` 永久 Epic、有效批准 hash、完整执行策略和至少
|
||||
两个已批准子项,A/B 只执行边界内子项。这样测试恢复与学习,不伪造 owner/reviewer 授权。
|
||||
|
||||
`cs-learning-transfer-001` 至少含四个正向场景(feat/issue/refactor/epic)和无关、stale 两个 guard。
|
||||
正向 fixture 的 golden 必须全绿,naive 只在目标不变量上红;真实运行前冻结 fixture、hypothesis、
|
||||
primary metric、预算与失败判据,禁止看到结果后删案例。
|
||||
|
||||
主 oracle 均为 `[measured]`:A 结果、候选唯一性、lesson schema/mutation、B treatment/control hidden
|
||||
pass、paired win/loss、stale retirement、prompt equality 和回归。语义质量只作 `[soft]`;统计不足时
|
||||
整体 verdict 标 `[underpowered]`。dry-run 成本必须累加 A、curation、B×2 及场景 hook 的实际 invocation,
|
||||
不得沿用 one-shot 估算。校准可用 `k=2`,但不能形成接受证据。
|
||||
|
||||
最终运行至少两个 model family、每 fixture `k >= 5`,使每个 family 在四个正向 fixture 上至少有
|
||||
20 个完成 pair;任一 primary aggregate 仍标 `[underpowered]` 时扩大 fixture/repeat 后重跑,不能接受
|
||||
Epic。只有 treatment 比 control 高至少 25pp、两个 family 都为正、losses 不多于 wins、两 guard
|
||||
无回退、隔离检查 100% 通过,才能完成;失败保留负结果并继续修正。
|
||||
|
||||
## 子项契约
|
||||
|
||||
- `LEARN-1`(feat):ADR-006、晶化算法、窄维护授权、四 task skills,以及 skill/architecture
|
||||
等集与负向契约测试;无依赖;测试先红,Epic 不新增暂停,lesson 状态变更进入当次 milestone。
|
||||
- `LEARN-2`(feat):`cs-keep` schema/lifecycle/晋升与清理;依赖 LEARN-1;同时拥有 WORKFLOW、
|
||||
README、SKILL_CATALOG、why-codestable 双语同步及 documentation tests;测试先红。
|
||||
- `LEARN-3`(feat):ADR-003 paired 增量、sequence runner/scorer、fixture 校验、成本模型、eval 单测与
|
||||
`cs-learning-transfer-001` 真实跨模型实验;依赖 LEARN-1/2;runner/fixture 测试先红。
|
||||
|
||||
## 影响面
|
||||
|
||||
必须修改:
|
||||
|
||||
- 五个 shipped skills:`cs-feat`、`cs-issue`、`cs-refactor`、`cs-epic`、`cs-keep`。
|
||||
- `docs/adr/003-cs-skill-evaluation-loop.md`;新建 `docs/adr/006-project-learning-lifecycle.md`。
|
||||
- `WORKFLOW*`、`README*`、`SKILL_CATALOG*`、`docs/why-codestable*` 中英文。
|
||||
- `tests/test_skill_contracts.py`、`test_v2_architecture_contract.py`、`test_v2_documentation_contract.py`。
|
||||
- `.claude/skills/eval-cs-skill/SKILL.md` 与 scripts 的 `runner.py`、`fixtures.py`、`buildprompt.py`、
|
||||
`_model.py`、`config.py`、`metrics.py`、scorer registry、新 sequence/scorer 模块。
|
||||
- `tests/test_cs_skill_eval.py`;新建 `experiments/cs-learning-transfer-001/`。
|
||||
|
||||
需要验证:`cs`、`cs-onboard`、`cs-review`、alias、AGENTS/CLAUDE 与 build-cs-skill 不变;8 skills、
|
||||
README 精简结构、全部 Markdown ≤300、plugin/package/distribution tests 继续成立。发布元数据只在 owner
|
||||
决定发布时处理。
|
||||
|
||||
仍待调查:LEARN-3 dry-run 核实两个 model family 的 adapter 与预算;不可用时按 ADR-003 报告,
|
||||
不得用单模型冒充跨模型结论。
|
||||
|
||||
## 验收标准
|
||||
|
||||
- 四 task skills 对有效命中报告路径、核验与具体影响;候选静默、普通最多一条、Epic 最终处理。
|
||||
- 三态可解析且按需迁移;退役不再应用,validated 稳定命中无 churn,机械化与单一 owner 优先。
|
||||
- 新 lesson 与跨项目分享保持显式授权;无 transcript、feedback runtime、global lessons 或新 skill。
|
||||
- paired 单测证明四类 invocation 独立、B prompt 相同、只有 lesson 差异、半 pair 不完成、成本不低估。
|
||||
- 冻结实验在两个 model family 上以非 `[underpowered]` 证据满足 verdict;否则本 Epic 保持未完成。
|
||||
- 中英文契约对称;相关/全量 pytest、分发测试、plugin check 与 `git diff --check` 通过。
|
||||
- 最终由 fresh reviewer 按最新批准版本做 acceptance review,再由 owner 整体验收。
|
||||
|
||||
## 关键决策
|
||||
|
||||
- 持续学习靠任务证据与按需 read-repair,不靠后台采集或每任务仪式。
|
||||
- 已有 lesson 的两种窄状态维护可静默进行;新知识与跨项目分享仍须显式授权。
|
||||
- 项目到全局的未来路径必须经过脱敏 packet、fixture、跨模型 eval 与 regression,本轮不实现。
|
||||
|
||||
## 最终交付索引
|
||||
|
||||
待执行后以 ADR、diff、测试与 `experiments/cs-learning-transfer-001/` 指针填写,不复制完整日志。
|
||||
|
||||
## 整体验收
|
||||
|
||||
待全部子项完成后填写。
|
||||
|
||||
## 遗留风险
|
||||
|
||||
- 模型可能漏掉信号;以低打扰换取较低召回,不用 transcript 扫描补偿。
|
||||
- thin harness 无 runtime 强制;契约测试与 paired eval 是主要回退防线。
|
||||
- 校准小样本可能只能给 `[underpowered]` 证据;必须扩大最终运行后才能接受,不得隐藏该标签。
|
||||
@@ -0,0 +1,52 @@
|
||||
---
|
||||
epic: ../epics/cs-continuous-learning-lifecycle.md
|
||||
phase: executing
|
||||
approved_revision: 4b0b8e8e0596e7ee42611864843512ecd9402970bb3682b5605f0dc0f8dcf01a
|
||||
current_item: LEARN-2
|
||||
next_action: implement LEARN-2 with tests first
|
||||
blocked_by: null
|
||||
item_progression: continuous
|
||||
milestone_commit: authorized
|
||||
remote_publish: each-milestone
|
||||
---
|
||||
|
||||
## 子项进度
|
||||
|
||||
- [x] LEARN-1
|
||||
- [ ] LEARN-2
|
||||
- [ ] LEARN-3
|
||||
|
||||
## 临时决策与证据
|
||||
|
||||
- 现有四个 task skill 只有 lesson 检索与笼统收尾推荐,没有 read-repair 或强信号筛选。
|
||||
- 现有 eval runner 每个 cell 只有一次 invocation,无法证明跨会话迁移。
|
||||
- 设计调研已核对 domain-modeling、teach、diagnosing-bugs、prototype、neat-freak 与现有 ADR-003;
|
||||
只借鉴晶化、证据晋级、机械化优先与 read-repair,不引入它们的默认目录或全局状态。
|
||||
- design review round 1:Paseo `ceb5d5d6-4c74-4825-b600-64d5111b2f48`,
|
||||
`claude-fable-5` / `plan-high`,冻结 SHA-256 `a660265a...e7ffd`;1 blocking / 4 important 已处理。
|
||||
- revised proposed Epic SHA-256:`a0107b6da2079556024c1a4807365e93a365149d37bedbbed7987188af45aa45`。
|
||||
- design review round 2:Paseo `50bf355c-fbbb-4ef0-a9fd-ec3d9c560e9f`,
|
||||
`claude-fable-5` / `plan-high`,冻结 SHA-256 `a0107b6d...aa45`;0 blocking / 3 important 已处理。
|
||||
- final design review round 3:Paseo `00358ef1-46a8-4976-abe6-8a2d4b783a07`,
|
||||
`claude-fable-5` / `plan-high`,冻结 SHA-256 `2c023c22...62cd`;0 blocking / 0 important / 3 nit,
|
||||
结论可交 owner 确认。
|
||||
- accepted nit interpretation:Epic 游标候选沿用 `晶化候选:` marker;25pp 是总体聚合阈值且每个
|
||||
model family 方向必须为正;“等集测试”指四 task skills 的一致契约断言。
|
||||
- owner 于 2026-08-01 确认 proposed Epic,并选择 `continuous` / `authorized` /
|
||||
`each-milestone`;激活后批准版本 SHA-256 为
|
||||
`4b0b8e8e0596e7ee42611864843512ecd9402970bb3682b5605f0dc0f8dcf01a`。
|
||||
- LEARN-1 tests-first:新增契约测试先得到 `4 failed, 2 passed`,实现后定向契约
|
||||
`25 passed`、全量 `130 passed, 1 skipped`、分发 `3 passed, 1 skipped`,plugin package check 与
|
||||
`git diff --check` 通过;四个 task skill 与 ADR-006 均未超过 300 行。
|
||||
- LEARN-1 晶化候选:无。Markdown 换行造成的锚点误判已通过空白归一化 helper 机械化,不另写
|
||||
重复 lesson。
|
||||
- LEARN-1 diff review round 1:Paseo `8a20cd70-9f55-4331-9b69-90e63bed4913`,
|
||||
`claude-fable-5` / `plan-high`,冻结 staged patch SHA-256 `eff4faae...5d02`;
|
||||
`0 blocking / 1 important / 3 nit`。已补齐 canonical-owner 退役、候选证据/范围/归宿、显式记忆
|
||||
诉求同轮处理、窄维护报告,并加入旧 lesson 缺 `status` 的独立安装兼容;新增锚点先红后绿。
|
||||
- LEARN-1 修复后验证:三份契约套件 `37 passed`、全量 `130 passed, 1 skipped`、分发
|
||||
`3 passed, 1 skipped`,plugin package check 与 `git diff --check` 通过。
|
||||
- LEARN-1 diff review round 2:fresh Paseo `76255cc7-43b3-44d7-86af-90a2fffd3284`,
|
||||
`claude-fable-5` / `plan-high`,冻结 staged patch SHA-256 `e3490e44...7deb`;
|
||||
`0 blocking / 0 important / 4 nit`,结论可合。保留的 nit 仅为排版、授权来源概括、测试冗余和
|
||||
范围外 cs-review 旧推荐句,不影响行为或授权边界。
|
||||
@@ -0,0 +1,155 @@
|
||||
---
|
||||
adr: "006"
|
||||
title: "CodeStable 项目内持续学习生命周期"
|
||||
status: Accepted
|
||||
date: 2026-08-01
|
||||
applies-to:
|
||||
- "plugins/codestable/skills/cs-feat/"
|
||||
- "plugins/codestable/skills/cs-issue/"
|
||||
- "plugins/codestable/skills/cs-refactor/"
|
||||
- "plugins/codestable/skills/cs-epic/"
|
||||
- "plugins/codestable/skills/cs-keep/"
|
||||
- ".codestable/lessons/"
|
||||
- ".codestable/work/"
|
||||
enforcement: test
|
||||
stage: [author, execute, keep, review]
|
||||
lint: "python3 -m pytest tests/test_skill_contracts.py tests/test_v2_architecture_contract.py tests/test_v2_documentation_contract.py"
|
||||
---
|
||||
|
||||
# ADR-006: CodeStable 项目内持续学习生命周期
|
||||
|
||||
## Context
|
||||
|
||||
四个 task skill 已会检索项目 lesson,`cs-keep` 也有证据、查重与合并门槛,但现有闭环只保证
|
||||
“读过”和“写下”。任务中不会稳定识别值得复用的晶化时刻;lesson 再次命中后没有统一的核验、
|
||||
纠偏与退役规则;命中次数和模型自评也无法证明旧经验真实改善了后续任务。
|
||||
|
||||
与此同时,自动保存对话、每次任务都询问是否记录,或把所有经验长期留在 lesson,会制造隐私、
|
||||
噪声、双重真相和流程中断。项目需要一个低打扰、证据驱动且最终收敛到更强 owner 的学习周期,
|
||||
而不是新的 feedback runtime、后台采集系统或全局知识库。
|
||||
|
||||
## Decision
|
||||
|
||||
### 生命周期对象与唯一 owner
|
||||
|
||||
项目内学习采用以下分层:
|
||||
|
||||
| 对象 | 生命周期与 owner |
|
||||
|---|---|
|
||||
| Learning signal | 当前任务内的可核实事件;未过门槛即丢弃 |
|
||||
| Crystallization candidate | 会话内有界候选;不是项目事实,也不自动获得写入授权 |
|
||||
| Lesson | 项目级 staging,一条一文件;只保留尚未被更强 owner 完整承接的经验 |
|
||||
| Canonical guard | 测试、checker、lint、类型或 deterministic helper,机械阻止同类错误 |
|
||||
| Canonical knowledge | `attention.md`、项目既有文档、glossary 或 ADR 中的唯一事实 owner |
|
||||
| Transfer evidence | fresh 后续任务在有、无 lesson 条件下产生的 paired 结果;实验机制归 ADR-003 |
|
||||
|
||||
检索次数、“讨论过”和模型自评置信度都不是学习证据。lesson 是可删除、可纠偏的暂存层;同一事实
|
||||
不得同时把 lesson 与 canonical guard/knowledge 当作并列真相。
|
||||
|
||||
### 强信号与晶化候选
|
||||
|
||||
四个 task skill 在任务中静默观察,内存中最多保留 3 条候选,并用新证据替换较低价值项,不为
|
||||
候选创建 work、transcript 或状态文件。强信号只包括:
|
||||
|
||||
- owner 纠正真实改变了方案、代码、术语或验证;
|
||||
- 可复现证据推翻根因,或同一路径失败两次后更换假设;
|
||||
- blocking/important finding 暴露尚未编码的不变量;
|
||||
- 新 red -> green 验证捕获了可复发失败;
|
||||
- 已有 lesson 真实改变本次行为,或被当前事实反证;
|
||||
- workaround 重复出现,或某方法显著降低重试、成本或风险。
|
||||
|
||||
候选还必须同时具备可追溯证据、可写成未来动作、适用于本次精确 diff 之外,且尚无现成
|
||||
canonical owner。网络波动、拼写、活动记录、泛化口号和已被机械 owner 完整覆盖的事实直接丢弃。
|
||||
排序先看失败后果,再看证据与复发可能,最后优先低成本机械化;不得生成伪精确分数。
|
||||
|
||||
普通任务仅在强信号成立时,于收尾展示最高价值的一条,首行固定为
|
||||
`晶化候选:{rule}`,并给出证据、范围和建议归宿;无强信号时不显示空模板。候选不暂停任务,
|
||||
没有记忆写入授权就随会话结束消失。用户已明确要求“记住 / 更新 / 退役”时,同轮按 `cs-keep`
|
||||
处理,不重复确认。
|
||||
|
||||
### Lesson 三态
|
||||
|
||||
新 lesson 必须声明 `status`、`scope` 与 `date`,正文只保留可执行规则、适用/停止应用边界、最多
|
||||
三个代表性证据指针和候选归宿。状态只允许:
|
||||
|
||||
| status | 判据 |
|
||||
|---|---|
|
||||
| `observed` | 单次任务有证据,尚未在独立后续任务验证 |
|
||||
| `validated` | 非创建该 lesson 的后续任务和 agent invocation 中有效命中,真实改善行为并验证成功 |
|
||||
| `retired` | 被仓库事实反证、范围完全失效,或已被更强 owner 替代;不得再应用 |
|
||||
|
||||
旧 lesson 缺少 `status` 时按 `observed` 读取,不批量迁移;只有真实状态变化或 `cs-keep` 本来就要
|
||||
更新时才补字段。`retired` 结论不得复活并继承 `validated` 身份;新结论必须重新从 `observed` 开始。
|
||||
|
||||
### Read-repair 与窄维护授权
|
||||
|
||||
task skill 应用 lesson 前必须 read-repair:`retired` 不应用;`observed` / `validated` 先用当前代码、
|
||||
测试或 canonical 文档核实。只有条目 scope 符合、事实仍成立且真实改变计划或验证时,才报告
|
||||
`经验命中:{path}({status});核验:{fact};影响:{plan_or_check}`;纯关键词碰撞或只是读过不算
|
||||
有效命中。
|
||||
|
||||
创建 lesson、改写规则或 scope、一般晋升、删除及跨项目反馈,仍需用户显式 `cs-keep` 诉求、接受
|
||||
普通任务候选,或 Epic 最终毕业 gate。为使 read-repair 不中断任务,仅对已有且有效命中的 lesson
|
||||
开放两种无需新增确认的窄维护:
|
||||
|
||||
- `observed -> validated`:独立后续任务确实采用并验证成功,只补一次代表性证据;
|
||||
- `observed|validated -> retired`:当前仓库事实直接反证,或发现已有 canonical owner,只写退役原因
|
||||
与替代/反证指针。
|
||||
|
||||
窄维护不得新建事实、改规则、扩 scope 或新增 gate,必须与当次代码、证据和游标组成同一语义原子
|
||||
milestone,并在最终报告列出文件变化。稳定的 `validated` 命中不写文件。证据不足或需要改写结论时
|
||||
只形成候选;发现 canonical owner 时 task skill 先 retire,删除与合并仍由 `cs-keep` 负责。
|
||||
|
||||
### 机械化优先与 canonical 归宿
|
||||
|
||||
当前任务范围内能直接落成 red -> green 测试或 checker 的约束,必须优先机械化,不再写重复
|
||||
lesson;机械化会扩大任务范围时只给候选,不借学习名义扩权。`cs-keep` 按以下顺序迁移:
|
||||
|
||||
1. 能机械阻止的规则进入测试、checker、lint、类型或 owning skill 的 deterministic helper;
|
||||
2. 高频必读且稳定的项目事实进入 `attention.md`,并维持不超过 25 条的预算;
|
||||
3. 同时满足难回退、缺少上下文会令人意外、源于真实取舍的结构性决定进入项目 ADR;
|
||||
4. 其他稳定方法进入项目既有文档;目标不存在时请 owner 选择,不发明目录;
|
||||
5. `codestable-eval` 仅标记未来上游候选,本轮不导出、不上传,也不修改 shipped skill。
|
||||
|
||||
新 owner 写入并验证后,应在同一更新中删除完全重复的 lesson;若由 task skill 发现,则先退役,留待
|
||||
显式 `cs-keep` 清理。`cs-keep` 继续执行查重、合并和约 50 条 lesson 预算。
|
||||
|
||||
### Epic 聚合
|
||||
|
||||
Epic 子项不得展示或询问晶化候选。每个子项至多把一条去重候选写入既有 Epic 游标的证据区,
|
||||
不得为此新建 work;该记录只是临时毕业输入,不是项目事实。全部子项完成后,毕业清单统一处理
|
||||
lesson、guard、项目文档与 ADR 的归宿,并复用 Epic 最终 owner gate,不新增逐项暂停或确认。
|
||||
|
||||
### 隐私与跨项目边界
|
||||
|
||||
不得保存原始对话、原始问答、完整思考过程、候选分支、逐次命中日志或无限 evidence history;
|
||||
不得扫描 transcript 来补召回率。除上述有界 Epic 游标证据外,未获写入授权的候选只存在于当前
|
||||
会话内。
|
||||
|
||||
本 ADR 只建立项目内 session candidate -> lesson -> canonical owner 的闭环。不创建
|
||||
`.codestable/learning/`、全局 lessons、常驻索引、后台 telemetry、集中 runtime 或第九个 skill,
|
||||
也不自动跨项目、团队或向 CodeStable 上游分享。未来跨项目路径必须另行获得显式授权,并经过脱敏
|
||||
packet、fixture、跨模型 eval 与 regression;本 Epic 只保留这一边界,不实现上传或同步。
|
||||
|
||||
## Consequences
|
||||
|
||||
- task skill 会说明经验如何被当前事实核验、又如何改变行为,避免把检索命中冒充学习效果。
|
||||
- lesson 可以随新证据晋升、纠偏和退役,最终迁移到单一机械或文档 owner,减少陈旧知识与双重真相。
|
||||
- 普通任务只有高价值候选才出现一次提示,Epic 则聚合到最终 gate,持续学习不会增加常规暂停点。
|
||||
- 两种窄维护会让已有 lesson 随任务 diff 一起变化;实现与审查必须核对其证据、状态转换和原子性。
|
||||
- 不做 transcript 扫描、后台采集和自动跨项目共享会降低召回率,但同时限制隐私、噪声和权限风险。
|
||||
- thin-harness skills 缺少集中 runtime 强制,契约测试与 ADR-003 的 paired cross-session eval 是主要
|
||||
回退防线;未达到跨模型、非 `[underpowered]` 的验收证据时,不得宣称学习迁移有效。
|
||||
|
||||
## Rejected alternatives
|
||||
|
||||
- **每个任务固定询问是否沉淀**。拒绝:高频仪式会打断主任务,并把弱信号升级成噪声。
|
||||
- **自动保存候选、对话或反馈流**。拒绝:扩大隐私与持久化边界,并重新引入本 Epic 明确排除的
|
||||
feedback runtime、状态机和后台采集。
|
||||
- **把 lesson 当作永久、只增不减的知识库**。拒绝:事实变化后会继续误导,且与测试、ADR、项目
|
||||
文档形成多个 owner。
|
||||
- **命中一次或模型自评后直接标记 validated**。拒绝:没有独立后续任务的行为与验证证据,无法
|
||||
区分复用效果和自我确认。
|
||||
- **自动同步到全局或其他项目**。拒绝:项目事实、隐私与适用范围尚未经过脱敏和跨模型回归验证。
|
||||
- **用更醒目的规则文本代替机械 guard**。拒绝:能由测试、checker、类型或 helper 阻止的错误,
|
||||
不应继续依赖 agent 记得阅读。
|
||||
@@ -18,6 +18,35 @@ argument-hint: "[大需求描述]"
|
||||
- handoff 只用于起草 proposed 永久 Epic 文档,不替代 fresh design review、批准 hash 或第一道 owner gate。
|
||||
- 澄清需求:只问会改变拆解方向的问题(目标边界、优先级、验收口径),一次最多 3 个,形成共识即停。
|
||||
|
||||
## 持续学习
|
||||
|
||||
检索到 lesson 后先做 read-repair。只有 scope 符合、未退役、经当前代码/测试/canonical 文档核实,
|
||||
并真实改变计划或验证的条目才算有效命中;按
|
||||
`经验命中:{path}({status});核验:{fact};影响:{plan_or_check}` 报告。`retired` 不应用;
|
||||
`observed` / `validated` 先核实再用;旧 lesson 缺 `status` 按 `observed` 读取,不批量迁移。只是相关
|
||||
但没有改变行为时不制造复用证据;当前事实明确反证时立即停止应用,证据不足时不猜。
|
||||
|
||||
任务内只在内存保留最多 3 条候选,按新证据替换低价值项,不暂停或询问。强信号只包括:owner
|
||||
纠正实际改变方案/代码/术语/验证;可复现证据推翻根因;同一路径失败两次后更换假设;
|
||||
blocking/important finding 暴露未编码不变量;新 red -> green 捕获可复发失败;lesson 真实改变本次行为
|
||||
或被反证;重复 workaround;方法显著降低重试、成本或风险。
|
||||
|
||||
候选还必须同时有可追溯证据、能写成未来动作、适用于本次精确 diff 之外、且没有现成 canonical
|
||||
owner。网络波动、拼写、泛化口号、活动记录,以及已被机械 owner 完整覆盖的事实直接丢弃。
|
||||
|
||||
创建、改写规则/scope、晋升、删除与跨项目反馈仍须用户显式授权。为不中断 read-repair,仅对已有且
|
||||
有效命中的 lesson 开放两种窄维护:`observed -> validated` 仅在独立后续任务确实采用并验证成功时
|
||||
发生,只补一次代表性证据;`observed|validated -> retired` 仅在当前仓库事实直接反证或发现已有
|
||||
canonical owner 时发生,只写原因与替代/反证指针。窄维护不新建事实、不改规则、不扩 scope、不新增
|
||||
gate,随当次代码、证据和
|
||||
游标进入同一语义原子 milestone;稳定 validated 命中不写文件。需要改写结论或证据不足时只给
|
||||
候选,新结论不得通过复活 retired 条目获得 validated 身份;窄维护必须在最终报告列出文件变化。
|
||||
|
||||
当前任务范围内能直接落成 red -> green 测试/checker 的约束优先机械化,不另写重复 lesson;会扩大
|
||||
范围时只给候选。用户已明确说“记住 / 更新 / 退役”时,同轮按 `cs-keep` 处理,不重复确认。Epic
|
||||
子项不展示、不询问;每个子项至多把一条去重候选写入既有游标证据区,使用 `晶化候选:{rule}`
|
||||
marker,最终毕业清单一次处理并复用最终 owner gate。
|
||||
|
||||
## 双层 Epic 文档
|
||||
|
||||
Epic 天然跨会话,但稳定上下文和活动状态不得混写:
|
||||
@@ -90,4 +119,3 @@ owner 确认 proposed 文档与上述策略后,主流程机械置 `active`,
|
||||
- owner 接受后先把最终范围、关键决策、交付索引、整体验收、遗留风险与毕业清单写入永久 Epic,再用终态更新置 `accepted` 并移除 `work` 指针。稳定产品契约进 canonical requirement/项目文档,结构性决策进 ADR,经验进 lessons;目标位置不存在时请 owner 选择,确定前结论留在永久 Epic。
|
||||
- 终态 `accepted` / `superseded` / `cancelled` 是不可恢复执行的持久信号。无论中断时还剩 work 指针、游标或所属子项 work,都从仓库事实幂等续做:补齐终态记录与毕业清单、移除指针、删除 Epic 游标,再按 frontmatter `epic:` 清理全部子项 work;不得恢复执行或创建重复 Epic,永久 Epic 文档不得删除。
|
||||
- 不恢复 `cs-goal` 入口、goal package、`state.yaml`、逐轮 iteration 报告或 legacy runtime gate;目标契约、恢复游标、owner gate 和终态验收都由上述双层文档承担。
|
||||
- 本轮若踩坑或被纠偏,推荐用 cs-keep 沉淀一条;用户拒绝即跳过。
|
||||
|
||||
@@ -18,6 +18,35 @@ argument-hint: "[功能描述]"
|
||||
- 动手前先定归属:这能力属于哪里、沿用现有词汇叫什么——不丢进最近的文件、不起新同义词。结构与取舍拿不准时读 `references/code-design.md` 与 `references/economy.md`(最小充分 ≠ 最小 diff;有界简化必须记上限、触发与方向)。
|
||||
- 对照检查:目标、现场上下文、边界与取舍、证据要求、验收标准。缺少会改变实现方向的事实时先问,一次最多 3 个问题,形成可执行共识即停;不问不影响方向的细节。
|
||||
|
||||
## 持续学习
|
||||
|
||||
检索到 lesson 后先做 read-repair。只有 scope 符合、未退役、经当前代码/测试/canonical 文档核实,
|
||||
并真实改变计划或验证的条目才算有效命中;按
|
||||
`经验命中:{path}({status});核验:{fact};影响:{plan_or_check}` 报告。`retired` 不应用;
|
||||
`observed` / `validated` 先核实再用;旧 lesson 缺 `status` 按 `observed` 读取,不批量迁移。只是相关
|
||||
但没有改变行为时不制造复用证据;当前事实明确反证时立即停止应用,证据不足时不猜。
|
||||
|
||||
任务内只在内存保留最多 3 条候选,按新证据替换低价值项,不暂停或询问。强信号只包括:owner
|
||||
纠正实际改变方案/代码/术语/验证;可复现证据推翻根因;同一路径失败两次后更换假设;
|
||||
blocking/important finding 暴露未编码不变量;新 red -> green 捕获可复发失败;lesson 真实改变本次行为
|
||||
或被反证;重复 workaround;方法显著降低重试、成本或风险。
|
||||
|
||||
候选还必须同时有可追溯证据、能写成未来动作、适用于本次精确 diff 之外、且没有现成 canonical
|
||||
owner。网络波动、拼写、泛化口号、活动记录,以及已被机械 owner 完整覆盖的事实直接丢弃。
|
||||
|
||||
创建、改写规则/scope、晋升、删除与跨项目反馈仍须用户显式授权。为不中断 read-repair,仅对已有且
|
||||
有效命中的 lesson 开放两种窄维护:`observed -> validated` 仅在独立后续任务确实采用并验证成功时
|
||||
发生,只补一次代表性证据;`observed|validated -> retired` 仅在当前仓库事实直接反证或发现已有
|
||||
canonical owner 时发生,只写原因与替代/反证指针。窄维护不新建事实、不改规则、不扩 scope、不新增
|
||||
gate,随当次代码、证据和
|
||||
游标进入同一语义原子 milestone;稳定 validated 命中不写文件。需要改写结论或证据不足时只给
|
||||
候选,新结论不得通过复活 retired 条目获得 validated 身份;窄维护必须在最终报告列出文件变化。
|
||||
|
||||
当前任务范围内能直接落成 red -> green 测试/checker 的约束优先机械化,不另写重复 lesson;会扩大
|
||||
范围时只给候选。用户已明确说“记住 / 更新 / 退役”时,同轮按 `cs-keep` 处理,不重复确认。普通任务
|
||||
只在强信号成立时展示最高价值一条,首行固定 `晶化候选:{rule}`,并给出证据、范围和建议归宿;无
|
||||
强信号完全不显示模板,没有记忆写入授权时不落盘。
|
||||
|
||||
## 默认执行
|
||||
|
||||
理解相关事实 → 实现 → 运行相称的验证 → 交付结果。普通任务不生成 CodeStable 产物,git diff、测试输出和交付说明就是证据。
|
||||
@@ -50,4 +79,3 @@ argument-hint: "[功能描述]"
|
||||
- 报告:做了什么、改动文件、验证结果、遗留事项。
|
||||
- 高风险任务的 work 文档在设计对齐时已建立;其余任务需要跨会话继续、多人交接或用户要求留痕时补建 `.codestable/work/feat-{slug}.md`(work 文档一律带类型前缀 feat- / issue- / refactor- / epic-,整理时按前缀分流去向)。work 文档含目标 / 现场 / 边界 / 证据 / 验收 / 状态与未决六节,随进展更新("状态与未决"记录进度与待用户确认项,供跨会话恢复);完成后先在最终报告列**毕业清单**——哪条结论进了哪个项目文档、沉了哪条 lesson,无可毕业内容则明说——然后才删除 work 文档;不列清单不得删。毕业目标位置不存在时不擅自发明目录:清单中给出建议落点请用户拍板,**拍板前 work 文档保留不删**。用户要求留档则保留。
|
||||
- 属于某个 Epic 的子功能时:独立子功能 work 文档的 frontmatter 标 `epic: {epic-slug}`;日常进展和完成状态只更新 Epic work 游标中对应稳定 ID 的进度与证据指针。永久 Epic 文档在 `active` 期间保持冻结,不因日常进度或子功能 work 回链而修改;需要改变子项定义、依赖或验收时交 `cs-epic` 走边界重确认。
|
||||
- 本轮若踩坑或被纠偏,推荐用 cs-keep 沉淀一条;用户拒绝即跳过。
|
||||
|
||||
@@ -16,6 +16,35 @@ argument-hint: "[问题描述]"
|
||||
- 对照检查:目标(期望行为)、现场(复现条件与环境)、边界(哪些不能动)、验收(怎么算修好)。缺少会改变修复方向的事实时先问用户,一次最多 3 个问题,形成共识即停。
|
||||
- 诉求其实是新增能力而不是坏掉的行为时,转 `cs-feat`,不在 issue 里偷做。
|
||||
|
||||
## 持续学习
|
||||
|
||||
检索到 lesson 后先做 read-repair。只有 scope 符合、未退役、经当前代码/测试/canonical 文档核实,
|
||||
并真实改变计划或验证的条目才算有效命中;按
|
||||
`经验命中:{path}({status});核验:{fact};影响:{plan_or_check}` 报告。`retired` 不应用;
|
||||
`observed` / `validated` 先核实再用;旧 lesson 缺 `status` 按 `observed` 读取,不批量迁移。只是相关
|
||||
但没有改变行为时不制造复用证据;当前事实明确反证时立即停止应用,证据不足时不猜。
|
||||
|
||||
任务内只在内存保留最多 3 条候选,按新证据替换低价值项,不暂停或询问。强信号只包括:owner
|
||||
纠正实际改变方案/代码/术语/验证;可复现证据推翻根因;同一路径失败两次后更换假设;
|
||||
blocking/important finding 暴露未编码不变量;新 red -> green 捕获可复发失败;lesson 真实改变本次行为
|
||||
或被反证;重复 workaround;方法显著降低重试、成本或风险。
|
||||
|
||||
候选还必须同时有可追溯证据、能写成未来动作、适用于本次精确 diff 之外、且没有现成 canonical
|
||||
owner。网络波动、拼写、泛化口号、活动记录,以及已被机械 owner 完整覆盖的事实直接丢弃。
|
||||
|
||||
创建、改写规则/scope、晋升、删除与跨项目反馈仍须用户显式授权。为不中断 read-repair,仅对已有且
|
||||
有效命中的 lesson 开放两种窄维护:`observed -> validated` 仅在独立后续任务确实采用并验证成功时
|
||||
发生,只补一次代表性证据;`observed|validated -> retired` 仅在当前仓库事实直接反证或发现已有
|
||||
canonical owner 时发生,只写原因与替代/反证指针。窄维护不新建事实、不改规则、不扩 scope、不新增
|
||||
gate,随当次代码、证据和
|
||||
游标进入同一语义原子 milestone;稳定 validated 命中不写文件。需要改写结论或证据不足时只给
|
||||
候选,新结论不得通过复活 retired 条目获得 validated 身份;窄维护必须在最终报告列出文件变化。
|
||||
|
||||
当前任务范围内能直接落成 red -> green 测试/checker 的约束优先机械化,不另写重复 lesson;会扩大
|
||||
范围时只给候选。用户已明确说“记住 / 更新 / 退役”时,同轮按 `cs-keep` 处理,不重复确认。普通任务
|
||||
只在强信号成立时展示最高价值一条,首行固定 `晶化候选:{rule}`,并给出证据、范围和建议归宿;无
|
||||
强信号完全不显示模板,没有记忆写入授权时不落盘。
|
||||
|
||||
## 硬门槛
|
||||
|
||||
- **没有稳定、快速、能明确变红的验证,不许猜根因、不许改代码。** 优先失败测试;无法自动化时与用户确认一个手工复现步骤。
|
||||
@@ -38,4 +67,3 @@ argument-hint: "[问题描述]"
|
||||
- reviewer 创建后绑定该运行并记录 run identity:目标有效、能力仍满足,且 reviewer 状态为 running,或 `Awaiting` 携带可查询的同一 run identity 且查询仍为活动态时为健康;状态健康时等待终态报告,不因后来发现更优创建方式而取消、重复创建或并行补发。仅在运行明确失败或终止无报告、idle / `Awaiting` 且无可恢复 run identity、能力不满足或目标失效时,本轮失败且不计轮次;不得盲目重发,先检查 task packet 与 agent 状态,再决定一次有界重试、更换创建方式或交用户。
|
||||
- 报告:根因一句话、改动文件、验证结果。
|
||||
- 需要跨会话继续时写 `.codestable/work/issue-{slug}.md`(目标 / 现场 / 边界 / 证据 / 验收 / 状态与未决六节;work 文档一律带类型前缀)。完成后先在报告列毕业去向(结论进哪、lesson 沉哪,或明说无可毕业)再删除;目标位置不存在时在清单中建议落点请用户拍板,拍板前不删。用户要求留档则保留。
|
||||
- 本轮若踩了新坑或被用户纠偏,推荐用 cs-keep 沉淀一条;用户拒绝即跳过。
|
||||
|
||||
@@ -15,6 +15,35 @@ argument-hint: "[重构目标]"
|
||||
- 先确认诉求真是行为不变:一旦包含"顺便支持 X / 改成 Y",把那部分拆出去转 `cs-feat` 或 `cs-issue`,不夹带。
|
||||
- 结构好坏用**深度**衡量:小接口承载大行为是深,接口和实现一样复杂是浅;重构应让调用方用更少认知换更多能力,不为"看起来干净"搬家,不把模块越拆越碎。
|
||||
|
||||
## 持续学习
|
||||
|
||||
检索到 lesson 后先做 read-repair。只有 scope 符合、未退役、经当前代码/测试/canonical 文档核实,
|
||||
并真实改变计划或验证的条目才算有效命中;按
|
||||
`经验命中:{path}({status});核验:{fact};影响:{plan_or_check}` 报告。`retired` 不应用;
|
||||
`observed` / `validated` 先核实再用;旧 lesson 缺 `status` 按 `observed` 读取,不批量迁移。只是相关
|
||||
但没有改变行为时不制造复用证据;当前事实明确反证时立即停止应用,证据不足时不猜。
|
||||
|
||||
任务内只在内存保留最多 3 条候选,按新证据替换低价值项,不暂停或询问。强信号只包括:owner
|
||||
纠正实际改变方案/代码/术语/验证;可复现证据推翻根因;同一路径失败两次后更换假设;
|
||||
blocking/important finding 暴露未编码不变量;新 red -> green 捕获可复发失败;lesson 真实改变本次行为
|
||||
或被反证;重复 workaround;方法显著降低重试、成本或风险。
|
||||
|
||||
候选还必须同时有可追溯证据、能写成未来动作、适用于本次精确 diff 之外、且没有现成 canonical
|
||||
owner。网络波动、拼写、泛化口号、活动记录,以及已被机械 owner 完整覆盖的事实直接丢弃。
|
||||
|
||||
创建、改写规则/scope、晋升、删除与跨项目反馈仍须用户显式授权。为不中断 read-repair,仅对已有且
|
||||
有效命中的 lesson 开放两种窄维护:`observed -> validated` 仅在独立后续任务确实采用并验证成功时
|
||||
发生,只补一次代表性证据;`observed|validated -> retired` 仅在当前仓库事实直接反证或发现已有
|
||||
canonical owner 时发生,只写原因与替代/反证指针。窄维护不新建事实、不改规则、不扩 scope、不新增
|
||||
gate,随当次代码、证据和
|
||||
游标进入同一语义原子 milestone;稳定 validated 命中不写文件。需要改写结论或证据不足时只给
|
||||
候选,新结论不得通过复活 retired 条目获得 validated 身份;窄维护必须在最终报告列出文件变化。
|
||||
|
||||
当前任务范围内能直接落成 red -> green 测试/checker 的约束优先机械化,不另写重复 lesson;会扩大
|
||||
范围时只给候选。用户已明确说“记住 / 更新 / 退役”时,同轮按 `cs-keep` 处理,不重复确认。普通任务
|
||||
只在强信号成立时展示最高价值一条,首行固定 `晶化候选:{rule}`,并给出证据、范围和建议归宿;无
|
||||
强信号完全不显示模板,没有记忆写入授权时不落盘。
|
||||
|
||||
## 硬门槛
|
||||
|
||||
- **先有能自证等价的验证,再动代码**:覆盖目标行为的测试、类型检查或可对照的输出基线。没有就先补验证或与用户确认等价判据,不许裸改。
|
||||
@@ -36,4 +65,3 @@ argument-hint: "[重构目标]"
|
||||
|
||||
- 报告:改了什么结构、等价性证据(验证输出)、遗留事项。
|
||||
- 需要跨会话继续时写 `.codestable/work/refactor-{slug}.md`(目标 / 现场 / 边界 / 证据 / 验收 / 状态与未决六节;work 文档一律带类型前缀)。完成后先在报告列毕业去向(结论进哪、lesson 沉哪,或明说无可毕业)再删除;目标位置不存在时在清单中建议落点请用户拍板,拍板前不删。用户要求留档则保留。
|
||||
- 本轮若踩坑或被纠偏,推荐用 cs-keep 沉淀一条;用户拒绝即跳过。
|
||||
|
||||
@@ -13,6 +13,7 @@ SKILLS = ROOT / "plugins/codestable/skills"
|
||||
LOCAL_SKILLS = ROOT / ".claude/skills"
|
||||
|
||||
TASK_SKILLS = ("cs-feat", "cs-issue", "cs-refactor", "cs-epic")
|
||||
ORDINARY_TASK_SKILLS = ("cs-feat", "cs-issue", "cs-refactor")
|
||||
LEGACY_KNOWLEDGE_DIRS = {
|
||||
".codestable/roadmap/",
|
||||
".codestable/features/",
|
||||
@@ -25,6 +26,54 @@ LEGACY_KNOWLEDGE_DIRS = {
|
||||
".codestable/feedback/",
|
||||
}
|
||||
|
||||
LESSON_READ_REPAIR_CONTRACT = {
|
||||
"经验命中:{path}({status});核验:{fact};影响:{plan_or_check}",
|
||||
"旧 lesson 缺 `status` 按 `observed` 读取",
|
||||
"`retired` 不应用",
|
||||
"`observed` / `validated` 先核实再用",
|
||||
"只是相关但没有改变行为时不制造复用证据",
|
||||
"当前事实明确反证时立即停止应用",
|
||||
"证据不足时不猜",
|
||||
}
|
||||
|
||||
CRYSTALLIZATION_SIGNAL_CONTRACT = {
|
||||
"任务内只在内存保留最多 3 条候选",
|
||||
"不暂停或询问",
|
||||
"owner 纠正实际改变方案/代码/术语/验证",
|
||||
"可复现证据推翻根因",
|
||||
"同一路径失败两次后更换假设",
|
||||
"blocking/important finding 暴露未编码不变量",
|
||||
"新 red -> green 捕获可复发失败",
|
||||
"lesson 真实改变本次行为或被反证",
|
||||
"重复 workaround",
|
||||
"方法显著降低重试、成本或风险",
|
||||
"可追溯证据",
|
||||
"能写成未来动作",
|
||||
"本次精确 diff 之外",
|
||||
"没有现成 canonical owner",
|
||||
"网络波动、拼写、泛化口号、活动记录",
|
||||
"已被机械 owner 完整覆盖",
|
||||
}
|
||||
|
||||
NARROW_LESSON_MAINTENANCE_CONTRACT = {
|
||||
"仅对已有且有效命中的 lesson",
|
||||
"`observed -> validated`",
|
||||
"独立后续任务确实采用并验证成功",
|
||||
"只补一次代表性证据",
|
||||
"`observed|validated -> retired`",
|
||||
"当前仓库事实直接反证",
|
||||
"发现已有 canonical owner",
|
||||
"只写原因与替代/反证指针",
|
||||
"不新建事实",
|
||||
"不改规则",
|
||||
"不扩 scope",
|
||||
"不新增 gate",
|
||||
"稳定 validated 命中不写文件",
|
||||
"需要改写结论或证据不足时只给候选",
|
||||
"新结论不得通过复活 retired 条目",
|
||||
"最终报告列出文件变化",
|
||||
}
|
||||
|
||||
THIN_SKILL_SAFETY_INVARIANTS = {
|
||||
"cs": (
|
||||
"同轮直转",
|
||||
@@ -103,6 +152,10 @@ def _read_skill(path: Path) -> tuple[dict[str, object], str]:
|
||||
return yaml.safe_load(frontmatter), body
|
||||
|
||||
|
||||
def _contains_contract(text: str, anchor: str) -> bool:
|
||||
return "".join(anchor.split()) in "".join(text.split())
|
||||
|
||||
|
||||
def test_active_skills_do_not_use_legacy_frontmatter_contracts() -> None:
|
||||
for root in (SKILLS, LOCAL_SKILLS):
|
||||
for path in sorted(root.glob("*/SKILL.md")):
|
||||
@@ -213,6 +266,96 @@ def test_task_skills_retrieve_legacy_knowledge_read_only() -> None:
|
||||
assert "批量迁移" in kickoff, skill_name
|
||||
|
||||
|
||||
def test_task_skills_share_the_complete_lesson_read_repair_contract() -> None:
|
||||
signatures = {}
|
||||
for skill_name in TASK_SKILLS:
|
||||
_, body = _read_skill(SKILLS / skill_name / "SKILL.md")
|
||||
signatures[skill_name] = {
|
||||
anchor
|
||||
for anchor in LESSON_READ_REPAIR_CONTRACT
|
||||
if _contains_contract(body, anchor)
|
||||
}
|
||||
|
||||
assert len({frozenset(signature) for signature in signatures.values()}) == 1
|
||||
for skill_name, signature in signatures.items():
|
||||
assert signature == LESSON_READ_REPAIR_CONTRACT, skill_name
|
||||
|
||||
|
||||
def test_task_skills_share_the_bounded_strong_signal_contract() -> None:
|
||||
signatures = {}
|
||||
for skill_name in TASK_SKILLS:
|
||||
_, body = _read_skill(SKILLS / skill_name / "SKILL.md")
|
||||
signatures[skill_name] = {
|
||||
anchor
|
||||
for anchor in CRYSTALLIZATION_SIGNAL_CONTRACT
|
||||
if _contains_contract(body, anchor)
|
||||
}
|
||||
|
||||
assert len({frozenset(signature) for signature in signatures.values()}) == 1
|
||||
for skill_name, signature in signatures.items():
|
||||
assert signature == CRYSTALLIZATION_SIGNAL_CONTRACT, skill_name
|
||||
|
||||
|
||||
def test_crystallization_closing_is_quiet_and_prefers_mechanical_guards() -> None:
|
||||
for skill_name in TASK_SKILLS:
|
||||
_, body = _read_skill(SKILLS / skill_name / "SKILL.md")
|
||||
for anchor in (
|
||||
"当前任务范围内能直接落成 red -> green 测试/checker",
|
||||
"优先机械化",
|
||||
"不另写重复 lesson",
|
||||
"会扩大范围时只给候选",
|
||||
):
|
||||
assert _contains_contract(body, anchor), skill_name
|
||||
|
||||
for skill_name in ORDINARY_TASK_SKILLS:
|
||||
_, body = _read_skill(SKILLS / skill_name / "SKILL.md")
|
||||
for anchor in (
|
||||
"普通任务只在强信号成立时展示最高价值一条",
|
||||
"`晶化候选:{rule}`",
|
||||
"证据、范围和建议归宿",
|
||||
"无强信号完全不显示模板",
|
||||
"没有记忆写入授权时不落盘",
|
||||
):
|
||||
assert _contains_contract(body, anchor), skill_name
|
||||
|
||||
for skill_name in TASK_SKILLS:
|
||||
_, body = _read_skill(SKILLS / skill_name / "SKILL.md")
|
||||
for anchor in (
|
||||
"用户已明确说“记住 / 更新 / 退役”",
|
||||
"同轮按 `cs-keep` 处理",
|
||||
"不重复确认",
|
||||
):
|
||||
assert _contains_contract(body, anchor), skill_name
|
||||
|
||||
_, epic = _read_skill(SKILLS / "cs-epic/SKILL.md")
|
||||
for anchor in (
|
||||
"Epic 子项不展示、不询问",
|
||||
"每个子项至多把一条去重候选写入既有游标证据区",
|
||||
"最终毕业清单一次处理",
|
||||
"复用最终 owner gate",
|
||||
"不得询问“是否继续下一项”",
|
||||
"不得把普通子项完成当作终态返回",
|
||||
):
|
||||
assert _contains_contract(epic, anchor)
|
||||
|
||||
|
||||
def test_task_skills_allow_only_two_narrow_lesson_maintenance_paths() -> None:
|
||||
signatures = {}
|
||||
for skill_name in TASK_SKILLS:
|
||||
_, body = _read_skill(SKILLS / skill_name / "SKILL.md")
|
||||
signatures[skill_name] = {
|
||||
anchor
|
||||
for anchor in NARROW_LESSON_MAINTENANCE_CONTRACT
|
||||
if _contains_contract(body, anchor)
|
||||
}
|
||||
assert _contains_contract(body, "创建、改写规则/scope、晋升、删除与跨项目反馈仍须")
|
||||
assert _contains_contract(body, "随当次代码、证据和游标进入同一语义原子 milestone")
|
||||
|
||||
assert len({frozenset(signature) for signature in signatures.values()}) == 1
|
||||
for skill_name, signature in signatures.items():
|
||||
assert signature == NARROW_LESSON_MAINTENANCE_CONTRACT, skill_name
|
||||
|
||||
|
||||
def test_keep_never_writes_v1_compound() -> None:
|
||||
_, keep = _read_skill(SKILLS / "cs-keep/SKILL.md")
|
||||
assert "`.codestable/compound/` 是只读历史知识源" in keep
|
||||
|
||||
@@ -8,6 +8,7 @@ import yaml
|
||||
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
SHIPPED_SKILLS = ROOT / "plugins/codestable/skills"
|
||||
|
||||
|
||||
def _frontmatter(path: Path) -> dict[str, object]:
|
||||
@@ -94,3 +95,61 @@ def test_v1_feedback_promoter_is_explicitly_legacy_only() -> None:
|
||||
assert "not a CodeStable v2 production-feedback entry" in promoter
|
||||
assert "仅用于显式导入冻结的 v1" in eval_skill
|
||||
assert "新反馈如何进入 regression 不在当前协议中定义" in eval_skill
|
||||
|
||||
|
||||
def test_project_learning_lifecycle_is_an_accepted_narrow_staging_contract() -> None:
|
||||
adr6 = ROOT / "docs/adr/006-project-learning-lifecycle.md"
|
||||
|
||||
assert adr6.is_file()
|
||||
assert _frontmatter(adr6)["status"] == "Accepted"
|
||||
text = adr6.read_text(encoding="utf-8")
|
||||
for anchor in (
|
||||
"在任务中静默观察",
|
||||
"最多保留 3 条候选",
|
||||
"read-repair",
|
||||
"必须优先机械化",
|
||||
"`observed -> validated`",
|
||||
"`observed|validated -> retired`",
|
||||
"显式授权",
|
||||
"feedback runtime",
|
||||
"transcript",
|
||||
"全局 lessons",
|
||||
"集中 runtime",
|
||||
"第九个 skill",
|
||||
"不新增逐项暂停或确认",
|
||||
):
|
||||
assert anchor in text
|
||||
|
||||
|
||||
def test_project_learning_does_not_restore_feedback_or_global_runtime_state() -> None:
|
||||
active_skills = {
|
||||
path.parent.name for path in SHIPPED_SKILLS.glob("*/SKILL.md")
|
||||
}
|
||||
assert active_skills == {
|
||||
"cs",
|
||||
"cs-code-review",
|
||||
"cs-epic",
|
||||
"cs-feat",
|
||||
"cs-issue",
|
||||
"cs-keep",
|
||||
"cs-onboard",
|
||||
"cs-refactor",
|
||||
"cs-review",
|
||||
}
|
||||
|
||||
for path in (
|
||||
SHIPPED_SKILLS / "cs-feedback",
|
||||
ROOT / ".codestable/learning",
|
||||
ROOT / ".codestable/global-lessons",
|
||||
ROOT / ".codestable/state.yaml",
|
||||
ROOT / ".codestable/session-state.yaml",
|
||||
):
|
||||
assert not path.exists(), path
|
||||
|
||||
runtime_artifacts = {
|
||||
path.relative_to(SHIPPED_SKILLS).as_posix().lower()
|
||||
for path in SHIPPED_SKILLS.rglob("*")
|
||||
if path.is_file()
|
||||
and ("transcript" in path.name.lower() or path.name == "state.yaml")
|
||||
}
|
||||
assert runtime_artifacts == set()
|
||||
|
||||
Reference in New Issue
Block a user