From 6a04fcadd0fd83896c4ade069eb4ba27b1062d18 Mon Sep 17 00:00:00 2001 From: qxbyte Date: Sun, 5 Jul 2026 17:11:23 +0800 Subject: [PATCH 1/3] test(specode): contract-lockstep gate for the 3-site MEMORY/frontmatter contract MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Turns the CLAUDE.md 变更纪律 prose into a CI gate. Reads knowledge.py's ACTUAL emitted MEMORY header (behavioral, via memory-rebuild on a fixture) and asserts it matches the columns documented in retrieval.md and distill's doc-template.md, plus that doc-template's frontmatter keys match what knowledge.py reads. The order-preserving extractor is negative-controlled to fail on a reordered or dropped column, so the gate can actually catch drift instead of passing trivially. Co-Authored-By: Claude Fable 5 Co-Authored-By: Qiang Xue --- .../specode/tests/test_contract_lockstep.py | 129 ++++++++++++++++++ 1 file changed, 129 insertions(+) create mode 100644 plugins/specode/tests/test_contract_lockstep.py diff --git a/plugins/specode/tests/test_contract_lockstep.py b/plugins/specode/tests/test_contract_lockstep.py new file mode 100644 index 0000000..1a09a7a --- /dev/null +++ b/plugins/specode/tests/test_contract_lockstep.py @@ -0,0 +1,129 @@ +"""Contract-lockstep tests — turn the "变更纪律" prose into a CI gate. + +The MEMORY/frontmatter contract is documented in three places that CLAUDE.md +requires to stay byte-identical: + 1. scripts/knowledge.py — `_COLS` (what memory-rebuild actually emits) + 2. skills/specode/references/retrieval.md — the columns the retrieval reader expects + 3. skills/distill/references/doc-template.md — the columns/frontmatter distill writes + +These tests read knowledge.py's ACTUAL emitted header (behavioral, not source +introspection) and compare it against the columns documented in the two .md +files, plus assert the doc-template frontmatter keys match what knowledge.py +reads. Reorder / add / drop a column in any one site → a test fails. +""" +from __future__ import annotations + +import re +from pathlib import Path + +PLUGIN_ROOT = Path(__file__).resolve().parents[1] +RETRIEVAL_MD = PLUGIN_ROOT / "skills" / "specode" / "references" / "retrieval.md" +DOC_TEMPLATE_MD = PLUGIN_ROOT / "skills" / "distill" / "references" / "doc-template.md" + +EXPECTED_COLS = ["标题", "类型", "描述", "来源", "路径", "tags"] +# frontmatter keys distill writes / knowledge.py reads (路径 is derived from the +# file path, not a frontmatter key, so it is NOT in this set) +EXPECTED_FM_KEYS = {"标题", "类型", "描述", "来源", "tags"} + + +def _write_doc(kb: Path, rel: str, *, 标题, 类型, 来源="", tags=None, 描述=""): + p = kb / rel + p.parent.mkdir(parents=True, exist_ok=True) + taglist = "[" + ", ".join(tags or []) + "]" + fm = ( + "---\n" + f"标题: {标题}\n" + f"类型: {类型}\n" + f"来源: {来源}\n" + f"tags: {taglist}\n" + f"描述: {描述}\n" + "---\n\n# body\n" + ) + p.write_text(fm, encoding="utf-8") + + +def _extract_memory_cols(text: str): + """Return the MEMORY column header as a list of cells, found generically + (order-preserving) so a reorder in any source is detectable. Matches the + first pipe-run (no backtick/newline inside) that contains both 标题 and + tags — works for a clean markdown table (knowledge.py output) and for an + inline-code row inside prose (the two .md files).""" + for m in re.finditer(r"\|(?:[^\n`|]*\|)+", text): + cells = [c.strip() for c in m.group(0).strip().strip("|").split("|")] + cells = [c for c in cells if c] + if "标题" in cells and "tags" in cells: + return cells + return None + + +def _first_frontmatter_keys(text: str): + """Keys of the first `--- ... ---` block (may sit inside a code fence).""" + keys = [] + in_fm = False + for line in text.splitlines(): + s = line.strip() + if s == "---": + if in_fm: + break + in_fm = True + continue + if in_fm and ":" in s: + keys.append(s.split(":", 1)[0].strip()) + return keys + + +def test_knowledge_emits_expected_columns(run_script, tmp_path: Path): + """knowledge.py's actual MEMORY header == the canonical contract.""" + kb = tmp_path / "knowledge-base" + _write_doc(kb, "cases/x.md", 标题="T", 类型="case", 来源="s", tags=["a"], 描述="d") + res = run_script("knowledge.py", "memory-rebuild", "--kb", str(kb)) + assert res.returncode == 0, res.stderr + emitted = _extract_memory_cols((kb / "MEMORY.md").read_text(encoding="utf-8")) + assert emitted == EXPECTED_COLS, f"knowledge.py emits {emitted}" + + +def test_retrieval_md_columns_match_knowledge(run_script, tmp_path: Path): + """The columns documented in retrieval.md == what knowledge.py emits.""" + kb = tmp_path / "knowledge-base" + _write_doc(kb, "cases/x.md", 标题="T", 类型="case", 来源="s", tags=["a"], 描述="d") + run_script("knowledge.py", "memory-rebuild", "--kb", str(kb)) + emitted = _extract_memory_cols((kb / "MEMORY.md").read_text(encoding="utf-8")) + documented = _extract_memory_cols(RETRIEVAL_MD.read_text(encoding="utf-8")) + assert documented is not None, "retrieval.md has no MEMORY column row" + assert documented == emitted, ( + f"retrieval.md columns {documented} != knowledge.py {emitted} — " + f"the 3-site contract drifted (变更纪律)" + ) + + +def test_doc_template_columns_match_knowledge(run_script, tmp_path: Path): + """The columns documented in distill's doc-template == what knowledge.py emits.""" + kb = tmp_path / "knowledge-base" + _write_doc(kb, "cases/x.md", 标题="T", 类型="case", 来源="s", tags=["a"], 描述="d") + run_script("knowledge.py", "memory-rebuild", "--kb", str(kb)) + emitted = _extract_memory_cols((kb / "MEMORY.md").read_text(encoding="utf-8")) + documented = _extract_memory_cols(DOC_TEMPLATE_MD.read_text(encoding="utf-8")) + assert documented is not None, "doc-template.md has no MEMORY column row" + assert documented == emitted, ( + f"doc-template.md columns {documented} != knowledge.py {emitted} — " + f"the 3-site contract drifted (变更纪律)" + ) + + +def test_doc_template_frontmatter_keys_match_contract(): + """distill's doc-template frontmatter keys == the canonical key set.""" + keys = set(_first_frontmatter_keys(DOC_TEMPLATE_MD.read_text(encoding="utf-8"))) + assert keys == EXPECTED_FM_KEYS, f"doc-template frontmatter keys {keys}" + + +def test_knowledge_reads_every_frontmatter_key(run_script, tmp_path: Path): + """Behavioral proof that knowledge.py surfaces every non-derived frontmatter + key into the MEMORY row (so a key documented in doc-template that knowledge + silently ignored would be caught).""" + kb = tmp_path / "knowledge-base" + _write_doc(kb, "cases/x.md", 标题="TITLE_V", 类型="case", + 来源="SRC_V", tags=["TAG_V"], 描述="DESC_V") + run_script("knowledge.py", "memory-rebuild", "--kb", str(kb)) + mem = (kb / "MEMORY.md").read_text(encoding="utf-8") + for value in ("TITLE_V", "case", "SRC_V", "TAG_V", "DESC_V"): + assert value in mem, f"{value} missing from MEMORY row (a frontmatter key was dropped)" From b06fb1bf7b766376c0fecbaf665cd878deb0c997 Mon Sep 17 00:00:00 2001 From: qxbyte Date: Sun, 5 Jul 2026 17:12:36 +0800 Subject: [PATCH 2/3] docs(specode): one-page knowledge-flow mental model + reference-tree fixups MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit New references/knowledge-flow.md — an ASCII producer→index→consumer map of the KB loop (distill writes / knowledge.py indexes / intake+design read; tasks+execution zero) with the 定位用非事实用 invariant and the pointers to each part's authoritative doc. Linked from SKILL + intake References and both README architecture trees (also surfacing autonomous-mode.md there). Co-Authored-By: Claude Fable 5 Co-Authored-By: Qiang Xue --- README.md | 2 + README.zh-CN.md | 2 + plugins/specode/skills/intake/SKILL.md | 1 + plugins/specode/skills/specode/SKILL.md | 1 + .../specode/references/knowledge-flow.md | 48 +++++++++++++++++++ 5 files changed, 54 insertions(+) create mode 100644 plugins/specode/skills/specode/references/knowledge-flow.md diff --git a/README.md b/README.md index e2845cf..9c2d35c 100644 --- a/README.md +++ b/README.md @@ -273,6 +273,8 @@ plugins/specode/ obsidian.md specsRoot path resolution + conventions superpowers-wiring.md phase ↔ superpowers skill mapping retrieval.md experience retrieval spec (intake primary node) + autonomous-mode.md non-interactive / CI defaults rule + knowledge-flow.md one-page knowledge-loop mental model skills/intake/ SKILL.md requirements phase engine (analysis + clarify + write) skills/distill/ diff --git a/README.zh-CN.md b/README.zh-CN.md index 3ca8cc8..c0a98c8 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -176,6 +176,8 @@ plugins/specode/ obsidian.md specsRoot 路径解析 + 惯例 superpowers-wiring.md 阶段 ↔ superpowers 技能映射 retrieval.md 经验检索规格(intake 为主节点) + autonomous-mode.md 非交互 / CI 默认值规则 + knowledge-flow.md 一页纸知识流心智模型 skills/intake/ SKILL.md 需求阶段引擎(项目分析 + 澄清 + 写需求) skills/distill/ diff --git a/plugins/specode/skills/intake/SKILL.md b/plugins/specode/skills/intake/SKILL.md index 1a4cf72..d132353 100644 --- a/plugins/specode/skills/intake/SKILL.md +++ b/plugins/specode/skills/intake/SKILL.md @@ -99,5 +99,6 @@ sh "$R/scripts/run.sh" "$R/scripts/resolve_root.py" ## §6 References - `skills/specode/references/retrieval.md` — 经验检索规格(Step 2b 的引擎;intake 是其**主节点**)。 +- `skills/specode/references/knowledge-flow.md` — 一页纸知识流心智模型(KB 谁产·谁读·何时的全局图)。 - `assets/templates/requirements.md` — 需求模板(Step 4 结构 + frontmatter 契约)。 - `skills/specode/references/autonomous-mode.md` — §3 判定的完整规则来源(gate→key→env + 伪代码)。 diff --git a/plugins/specode/skills/specode/SKILL.md b/plugins/specode/skills/specode/SKILL.md index 934037c..30f03bb 100644 --- a/plugins/specode/skills/specode/SKILL.md +++ b/plugins/specode/skills/specode/SKILL.md @@ -169,3 +169,4 @@ When writing / updating spec documents, **never** reprint the full text in chat. - `references/autonomous-mode.md` — the autonomous / CI defaults rule: gate→key→env mapping + the skip-the-prompt decision pseudo-code. - `references/superpowers-wiring.md` — the per-phase ↔ superpowers skill mapping, pre-instructions, and post-relocation instructions. - `references/retrieval.md` — 经验检索注入规格(intake 项目分析为主节点 / design 条件性 top-up)。 +- `references/knowledge-flow.md` — 一页纸知识流心智模型:distill / knowledge-base / MEMORY / ragkit / intake-检索 的谁产·谁索引·谁读·何时。 diff --git a/plugins/specode/skills/specode/references/knowledge-flow.md b/plugins/specode/skills/specode/references/knowledge-flow.md new file mode 100644 index 0000000..32daa8f --- /dev/null +++ b/plugins/specode/skills/specode/references/knowledge-flow.md @@ -0,0 +1,48 @@ +--- +description: One-page mental model of specode's experience/knowledge loop — who produces, who indexes, who reads, and when. Read this to understand how distill / knowledge-base / MEMORY / ragkit / intake-retrieval fit together. +--- + +# 知识流心智模型(谁产 · 谁索引 · 谁读 · 何时) + +一句话:**KB 是「定位用,非事实用」。** 它只提供指针(文件路径 + 调用链 + 导航经验)帮你更快跳到真实代码;**真实代码始终是唯一事实来源**。绝不允许仅凭 KB 内容推进新需求。 + +``` + 产出(写) 索引 消费(读) + ───────────────────────── ─────────────── ───────────────────────────── + /specode:distill MEMORY.md intake(requirements 项目分析) + (手动,验收末尾按 (小 md 索引,列 = 主检索节点 + auto_distill 提示; 标题/类型/描述/ · Tier-1 读 MEMORY 比对页面/字段/域 + 绝不自动跑) 来源/路径/tags) · 命中 → Tier-2 读 ≤5 点 → 跳真实代码 + │ ▲ · 若装 ragkit 且 chunks.json 存在 + ▼ │ memory-rebuild → Tier-0 ragkit:query 多路召回 + /knowledge-base/ (由各文档 frontmatter │ + ├── cases/.md ────────► 全量重建,不手改) ▼ + ├── navigation/.md .ragkit/(可选) design(条件性 top-up) + └── MEMORY.md chunks.json + vectors = 默认继承 intake 指针, + │ 由 /ragkit:embed 建 仅新领域才补查 + │(可选副本) (仅装 ragkit 时) │ + ▼ ▼ + Obsidian vault 把设计/需求 ground 到真实代码 + (knowledge.py copy-to, (tasks / 执行 / task-swarm = 零注入) + 人读镜像) +``` + +## 铁律 + +- **产出是手动的**:只有 `/specode:distill ` 写 KB;主流程绝不自动沉淀(验收末尾只*提示*入口,按 `auto_distill` 决定)。 +- **frontmatter 是单一事实源**:`MEMORY.md` 永远由 `knowledge.py memory-rebuild` 从各文档 frontmatter 全量重建,**不手改**(`memory-validate` 查漂移)。 +- **消费只在两处**:intake 的项目分析步(主节点)+ design(条件性 top-up)。**tasks / 执行 / task-swarm 零注入**——到那时文件路径已在 design.md / tasks.md 里。 +- **注入是指针非事实**:贴成「参考定位(非事实来源)」段,只用于定位、不写进 requirements.md 的事实结论。 +- **全程 opt-in**:无 `knowledge-base/MEMORY.md` → 检索静默跳过(默认成本 ≈ 一次小索引读)。无 ragkit → Tier-0 不生效,退到 Tier-1/2。 +- **`knowledge-base/` 不入仓**:本地私有定位资产(`ensure-gitignore` 保证);Obsidian 副本是可选的人读镜像。 + +## 契约锁步 🔒 + +MEMORY 列 + frontmatter 键在三处必须一致:`skills/distill/references/doc-template.md`(写)、`scripts/knowledge.py` `_COLS`(索引)、`skills/specode/references/retrieval.md`(读)。改一处 → 改三处。`tests/test_contract_lockstep.py` 是这条纪律的 CI 门禁。 + +## 各部件的权威文档 + +- 产出:`skills/distill/SKILL.md` + `skills/distill/references/doc-template.md` +- 索引 CLI:`scripts/knowledge.py`(`memory-rebuild` / `memory-validate` / `copy-to` / `ensure-gitignore`) +- 消费:`skills/specode/references/retrieval.md`(Tier-0 gate + 两级 gated) +- 主消费方:`skills/intake/SKILL.md` §Step 2b From 68cc0528947b5e85630c1ca4e983dd24dac53b76 Mon Sep 17 00:00:00 2001 From: qxbyte Date: Sun, 5 Jul 2026 17:13:48 +0800 Subject: [PATCH 3/3] =?UTF-8?q?release(specode):=206.1.1=20=E2=80=94=20con?= =?UTF-8?q?tract-lockstep=20gate=20+=20knowledge-flow=20mental=20model?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bump both manifests to 6.1.1, date both CHANGELOGs, refresh README version rows, and fix the stale specode version badge (drifted at 5.2.0 since 6.0.0). Co-Authored-By: Claude Fable 5 Co-Authored-By: Qiang Xue --- .claude-plugin/marketplace.json | 4 ++-- CHANGELOG.md | 5 +++++ README.md | 4 ++-- README.zh-CN.md | 4 ++-- plugins/specode/.claude-plugin/plugin.json | 4 ++-- plugins/specode/CHANGELOG.md | 5 ++++- 6 files changed, 17 insertions(+), 9 deletions(-) diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index 0f059bf..a6d6c0a 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -9,8 +9,8 @@ { "name": "specode", "source": "./plugins/specode", - "version": "6.1.0", - "description": "Lightweight spec-driven workflow: orchestrates superpowers skills per phase, lands 4 fixed docs (requirements/design/tasks/implementation-log). **v6.1.0**: 新增独立 intake skill(skills/intake/,同 distill,user-invocable:false)接管 requirements phase — 项目分析(agent-docs 扫描+经验检索+读真实代码)+基于分析的澄清+写 requirements.md(保留 spec_id/created_at/project_root frontmatter 契约);修正 6.0.0 的brainstorming 双产物错位 — brainstorming 从此只产 design.md(单产物),requirements 由 intake 产;检索主节点移到 intake 项目分析步、design 降为条件性 top-up;弊端修复 — writing-plans 结尾的执行方式提问改为「忽略而非抑制」;SKILL 轻量化 215→171 行(verb 表/autonomous-mode 细节下沉到 refs,零行为变化)。 **v6.0.0 BREAKING**: 固定产物 3→4 — design.md 重定义为**传统设计文档**(背景与目标/架构概览/模块划分/接口设计/数据流/错误处理/测试策略,散文无 checkbox);新增 tasks.md 承载可执行计划(writing-plans 格式 + Interfaces 契约块,引擎中立,task-swarm/superpowers/自执行统一消费,pipeline.yml 改从 tasks.md 推导);流水线变为 requirements→design→tasks→执行方式 selector→执行→验收,brainstorming 一次跨 requirements+design 双产物落盘(后置 relocate 检查两份);continue 改「加载即停」— 只读文档+汇报进度简报后停下等指令,绝不自动续跑;design-unchecked 更名 plan-unchecked(tasks.md 优先,design.md 含 checkbox 按 5.x legacy 兜底,旧名保留 alias)。5.x 存量 spec 由 continue 推断表 legacy 行兜底识别,不中断。 **v5.2.0**: 新增 Tier-0 RagKit gate — 检测到 ragkit 插件 + 已建索引(chunks.json)时,requirements/design 的经验检索走 `ragkit:query` 多路召回(模型自主提炼检索词、可多轮多角度、≤5 点封顶),未安装零成本跳过,zero-import。 **v5.1.3**: `list-specs` 让 intake 阶段(目录已建、requirements 未写)的 spec 可见 — 列出含任一固定产物的子目录 + 空子目录(intake),隐藏目录与无关内容目录仍排除;全库文档陈旧内容清理(README/CONTRIBUTING/SKILL 残留措辞)。 **v5.0.1**: distill skill 加 `user-invocable:false`(隐藏裸 `/distill` + 消除 `/specode:distill` 重复);distill 收敛为纯 md-only(移除 `--format yml|both` + codemap 死路径);清理全部 `.ai-memory`/codemap 文档残留 + requirements 模板删 recall 段。**v5.0.0 BREAKING**: 命令去 `specode-` 前缀 — `/specode:spec` / `/specode:continue` / `/specode:list` / `/specode:distill`(原 `/specode:specode-*`);内核 skill 加 `user-invocable:false` 隐藏裸 `/specode`。**v4.0.0 BREAKING**: 彻底拔出记忆注入工程 — 砍 P3-1 codemap recall / P3-2 rule-check / acceptance auto-distill prompt。保留 project-level CLAUDE.md scan。distill v4 完全重写为手动 md-only Obsidian wiki organizer, 默认写 `/Volumes/External HD/Obsidian/Notes/11-KnowledgeBase//`。如需 v3 行为 checkout `backup/specode-v3.4.0-task-swarm-v0.9.2`。", + "version": "6.1.1", + "description": "Lightweight spec-driven workflow: orchestrates superpowers skills per phase, lands 4 fixed docs (requirements/design/tasks/implementation-log). **v6.1.1**: 新增契约锁步 CI 门禁 tests/test_contract_lockstep.py(MEMORY 列 + frontmatter 键在 knowledge.py/retrieval.md/doc-template.md 三处一致,负控验证可抓 reorder/drop);新增 references/knowledge-flow.md 一页纸知识流心智模型(distill/knowledge-base/MEMORY/ragkit/intake-检索 的谁产·谁读·何时)。 **v6.1.0**: 新增独立 intake skill(skills/intake/,同 distill,user-invocable:false)接管 requirements phase — 项目分析(agent-docs 扫描+经验检索+读真实代码)+基于分析的澄清+写 requirements.md(保留 spec_id/created_at/project_root frontmatter 契约);修正 6.0.0 的brainstorming 双产物错位 — brainstorming 从此只产 design.md(单产物),requirements 由 intake 产;检索主节点移到 intake 项目分析步、design 降为条件性 top-up;弊端修复 — writing-plans 结尾的执行方式提问改为「忽略而非抑制」;SKILL 轻量化 215→171 行(verb 表/autonomous-mode 细节下沉到 refs,零行为变化)。 **v6.0.0 BREAKING**: 固定产物 3→4 — design.md 重定义为**传统设计文档**(背景与目标/架构概览/模块划分/接口设计/数据流/错误处理/测试策略,散文无 checkbox);新增 tasks.md 承载可执行计划(writing-plans 格式 + Interfaces 契约块,引擎中立,task-swarm/superpowers/自执行统一消费,pipeline.yml 改从 tasks.md 推导);流水线变为 requirements→design→tasks→执行方式 selector→执行→验收,brainstorming 一次跨 requirements+design 双产物落盘(后置 relocate 检查两份);continue 改「加载即停」— 只读文档+汇报进度简报后停下等指令,绝不自动续跑;design-unchecked 更名 plan-unchecked(tasks.md 优先,design.md 含 checkbox 按 5.x legacy 兜底,旧名保留 alias)。5.x 存量 spec 由 continue 推断表 legacy 行兜底识别,不中断。 **v5.2.0**: 新增 Tier-0 RagKit gate — 检测到 ragkit 插件 + 已建索引(chunks.json)时,requirements/design 的经验检索走 `ragkit:query` 多路召回(模型自主提炼检索词、可多轮多角度、≤5 点封顶),未安装零成本跳过,zero-import。 **v5.1.3**: `list-specs` 让 intake 阶段(目录已建、requirements 未写)的 spec 可见 — 列出含任一固定产物的子目录 + 空子目录(intake),隐藏目录与无关内容目录仍排除;全库文档陈旧内容清理(README/CONTRIBUTING/SKILL 残留措辞)。 **v5.0.1**: distill skill 加 `user-invocable:false`(隐藏裸 `/distill` + 消除 `/specode:distill` 重复);distill 收敛为纯 md-only(移除 `--format yml|both` + codemap 死路径);清理全部 `.ai-memory`/codemap 文档残留 + requirements 模板删 recall 段。**v5.0.0 BREAKING**: 命令去 `specode-` 前缀 — `/specode:spec` / `/specode:continue` / `/specode:list` / `/specode:distill`(原 `/specode:specode-*`);内核 skill 加 `user-invocable:false` 隐藏裸 `/specode`。**v4.0.0 BREAKING**: 彻底拔出记忆注入工程 — 砍 P3-1 codemap recall / P3-2 rule-check / acceptance auto-distill prompt。保留 project-level CLAUDE.md scan。distill v4 完全重写为手动 md-only Obsidian wiki organizer, 默认写 `/Volumes/External HD/Obsidian/Notes/11-KnowledgeBase//`。如需 v3 行为 checkout `backup/specode-v3.4.0-task-swarm-v0.9.2`。", "homepage": "https://github.com/qxbyte/pluginhub", "repository": "https://github.com/qxbyte/pluginhub", "license": "MIT", diff --git a/CHANGELOG.md b/CHANGELOG.md index ed9bed1..6c5b5a6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,11 @@ ## Unreleased +## 6.1.1 (2026-07-05) — specode + +- **契约锁步 CI 门禁**(`tests/test_contract_lockstep.py`):MEMORY 列 + frontmatter 键在 `knowledge.py` / `retrieval.md` / `doc-template.md` 三处一致,负控验证可抓 reorder/drop(+5 测,共 90)。 +- **一页纸知识流心智模型**(`references/knowledge-flow.md`):distill/knowledge-base/MEMORY/ragkit/intake-检索 的谁产·谁读·何时全图。 + ## 6.1.0 (2026-07-05) — specode - **新增独立 `intake` skill**(`skills/intake/`,同 `distill` 平级)接管 requirements phase:项目分析(agent-docs 扫描 + 经验检索 + 读真实代码)+ 基于分析的澄清 + 写 `requirements.md`(保留 `spec_id` / `created_at` / `project_root` frontmatter 契约,`project_root` 仍经 `write-project-root` 单写入口)。 diff --git a/README.md b/README.md index 9c2d35c..9d8effa 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ # pluginhub [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](./README.md#license) -[![specode](https://img.shields.io/badge/specode-5.2.0-blue.svg)](./plugins/specode/.claude-plugin/plugin.json) +[![specode](https://img.shields.io/badge/specode-6.1.1-blue.svg)](./plugins/specode/.claude-plugin/plugin.json) [![task-swarm](https://img.shields.io/badge/task--swarm-0.10.1-blue.svg)](./plugins/task-swarm/.claude-plugin/plugin.json) [![obsidian-wiki](https://img.shields.io/badge/obsidian--wiki-2.0.1-blue.svg)](./plugins/obsidian-wiki/.claude-plugin/plugin.json) [![Claude Code](https://img.shields.io/badge/Claude%20Code-compatible-8A2BE2)](https://github.com/qxbyte/pluginhub#installation) @@ -20,7 +20,7 @@ any plugin it hosts. More plugins will land here over time. | Plugin | Version | What it does | | --- | --- | --- | -| **specode** | 6.1.0 | A lightweight spec-driven **workflow** — orchestration shell that delegates each phase to [superpowers](https://github.com/obra/superpowers) skills (first-class native fallback) and lands 4 fixed docs per spec. **v6.1.0**: new standalone `specode:intake` skill (peer to `distill`) owns the requirements phase — project analysis (agent-docs scan + experience retrieval + reading located real code) + analysis-driven clarification + writes `requirements.md` preserving the `spec_id`/`created_at`/`project_root` frontmatter contract; fixes the 6.0.0 brainstorming dual-artifact mismatch (brainstorming now produces `design.md` only); retrieval's primary node moves to intake with design as a conditional top-up; writing-plans' execution-mode question is now ignored (not "suppressed"); SKILL.md lightened 215→171 lines (verb table + autonomous-mode detail sunk to references) and dead v3/codemap-term noise dropped from distill. **v6.0.0 BREAKING**: fixed docs 3 → 4 — `design.md` redefined as a **traditional design doc** (背景与目标/架构概览/模块划分/接口设计/数据流/错误处理/测试策略, prose only, no checkboxes); new `tasks.md` carries the executable plan (writing-plans format + `**Interfaces:**` contract blocks), engine-neutral — task-swarm (pipeline.yml now derived from it) / superpowers / specode self-execute all consume the same file; pipeline becomes requirements → design → tasks → 执行方式 selector → execute → acceptance, with brainstorming spanning requirements+design in one dual-artifact call; `/specode:continue` becomes **load-and-stop** — reads docs, reports a progress brief, then waits for the user's instruction (never auto-resumes); `design-unchecked` renamed `plan-unchecked` (tasks.md first, 5.x legacy design.md fallback, old name kept as alias); 5.x specs keep working via the legacy inference row. **v5.2.0**: Tier-0 RagKit gate tightened — probe changed from `test -d .ragkit` to `test -f .ragkit/chunks.json` (eliminates false-positive when only config.json exists after `backend set`); Tier-0 採纳条目 capped at Tier-2 discipline (≤5/phase, reasoned override allowed). **v5.1.3**: `list-specs` now surfaces intake-phase specs (dir created, requirements not yet written) — lists subdirs containing any fixed doc plus empty subdirs, hidden dirs still excluded; repo-wide stale-docs cleanup. **v5.1.2**: distill polish — `ensure-gitignore` skips in a non-git project with no existing `.gitignore` (no stray file); new `knowledge.py copy-to` verb (one-step dual-landing: copy cases/navigation + rebuild the dest's MEMORY) now used by distill Step 5; navigation `来源` keeps the origin slug (reusing specs listed in body). **v5.1.1**: validation-driven fixes — distill runs `design-unchecked` before sedimenting (warns if the spec isn't fully executed, so knowledge points don't reference unbuilt code); dedup navigation points against MEMORY before writing; retrieval emphasizes semantic relevance over tag-overlap. **v5.1.0**: reintroduces experience retrieval/injection on a new "pointers-not-facts" footing — new stdlib `knowledge.py` (ensure-gitignore/memory-rebuild/memory-validate); distill now emits **atomic case/navigation knowledge-points** to the project's `/knowledge-base/` (cases/ + navigation/ + a MEMORY index, gitignored), optionally copied to Obsidian; new `references/retrieval.md` two-tier gated retrieval wired into the requirements/design phases (inject pointers not facts, default reads only the small index, ≤5 docs on hit); acceptance re-hooks the distill prompt via the existing `auto_distill` default. **v5.0.1**: the `distill` skill is now `user-invocable: false` (hides the bare `/distill` + the duplicate `/specode:distill`, leaving one clean command entry); distill is now **md-only** (dropped the dead `--format yml|both` + `codemap knowledge write` path); purged all remaining `.ai-memory`/codemap doc references and removed the obsolete recall section from the requirements template. **v5.0.0 BREAKING**: commands dropped the redundant `specode-` prefix — `/specode:spec` / `/specode:continue` / `/specode:list` / `/specode:distill` (were `/specode:specode-*`); the `distill` skill dir + name were renamed to `distill`; the `specode` orchestration skill is now `user-invocable: false` so the bare `/specode` no longer shows in the slash menu (still auto-activates via its commands). Preserved AI-EDS-era features: project-level `CLAUDE.md` / `AGENT.md` filesystem scan injected as `## 项目级约束` section (痛点 #14 方案 D), SessionStart cache-vs-marketplace drift hint (M8), autonomous-mode defaults — 5 schema keys + 5 `SPECODE_*` env vars + `read-defaults` / `write-default` / `reset-default` verbs (M1+M9). **v4.0.0 BREAKING**: removed memory-injection pipeline — P3-1 `codemap recall` injection / P3-2 rule-acknowledgement post-check / acceptance auto-distill prompt all dropped; round 1/2 baseline showed the recall round-trip did not net save token. `distill` skill v4 rewritten as a **manual-only Obsidian organizer** — `/specode:distill ` writes md (default) to `/Volumes/External HD/Obsidian/Notes/11-KnowledgeBase//`, no `.ai-memory/` writes. To restore v3 behaviour: `git checkout backup/specode-v3.4.0-task-swarm-v0.9.2`. | +| **specode** | 6.1.1 | A lightweight spec-driven **workflow** — orchestration shell that delegates each phase to [superpowers](https://github.com/obra/superpowers) skills (first-class native fallback) and lands 4 fixed docs per spec. **v6.1.1**: contract-lockstep CI gate (`test_contract_lockstep.py`) keeps the MEMORY column + frontmatter contract byte-identical across knowledge.py / retrieval.md / doc-template.md (negative-controlled to catch reorder/drop); new `references/knowledge-flow.md` one-page knowledge-loop mental model. **v6.1.0**: new standalone `specode:intake` skill (peer to `distill`) owns the requirements phase — project analysis (agent-docs scan + experience retrieval + reading located real code) + analysis-driven clarification + writes `requirements.md` preserving the `spec_id`/`created_at`/`project_root` frontmatter contract; fixes the 6.0.0 brainstorming dual-artifact mismatch (brainstorming now produces `design.md` only); retrieval's primary node moves to intake with design as a conditional top-up; writing-plans' execution-mode question is now ignored (not "suppressed"); SKILL.md lightened 215→171 lines (verb table + autonomous-mode detail sunk to references) and dead v3/codemap-term noise dropped from distill. **v6.0.0 BREAKING**: fixed docs 3 → 4 — `design.md` redefined as a **traditional design doc** (背景与目标/架构概览/模块划分/接口设计/数据流/错误处理/测试策略, prose only, no checkboxes); new `tasks.md` carries the executable plan (writing-plans format + `**Interfaces:**` contract blocks), engine-neutral — task-swarm (pipeline.yml now derived from it) / superpowers / specode self-execute all consume the same file; pipeline becomes requirements → design → tasks → 执行方式 selector → execute → acceptance, with brainstorming spanning requirements+design in one dual-artifact call; `/specode:continue` becomes **load-and-stop** — reads docs, reports a progress brief, then waits for the user's instruction (never auto-resumes); `design-unchecked` renamed `plan-unchecked` (tasks.md first, 5.x legacy design.md fallback, old name kept as alias); 5.x specs keep working via the legacy inference row. **v5.2.0**: Tier-0 RagKit gate tightened — probe changed from `test -d .ragkit` to `test -f .ragkit/chunks.json` (eliminates false-positive when only config.json exists after `backend set`); Tier-0 採纳条目 capped at Tier-2 discipline (≤5/phase, reasoned override allowed). **v5.1.3**: `list-specs` now surfaces intake-phase specs (dir created, requirements not yet written) — lists subdirs containing any fixed doc plus empty subdirs, hidden dirs still excluded; repo-wide stale-docs cleanup. **v5.1.2**: distill polish — `ensure-gitignore` skips in a non-git project with no existing `.gitignore` (no stray file); new `knowledge.py copy-to` verb (one-step dual-landing: copy cases/navigation + rebuild the dest's MEMORY) now used by distill Step 5; navigation `来源` keeps the origin slug (reusing specs listed in body). **v5.1.1**: validation-driven fixes — distill runs `design-unchecked` before sedimenting (warns if the spec isn't fully executed, so knowledge points don't reference unbuilt code); dedup navigation points against MEMORY before writing; retrieval emphasizes semantic relevance over tag-overlap. **v5.1.0**: reintroduces experience retrieval/injection on a new "pointers-not-facts" footing — new stdlib `knowledge.py` (ensure-gitignore/memory-rebuild/memory-validate); distill now emits **atomic case/navigation knowledge-points** to the project's `/knowledge-base/` (cases/ + navigation/ + a MEMORY index, gitignored), optionally copied to Obsidian; new `references/retrieval.md` two-tier gated retrieval wired into the requirements/design phases (inject pointers not facts, default reads only the small index, ≤5 docs on hit); acceptance re-hooks the distill prompt via the existing `auto_distill` default. **v5.0.1**: the `distill` skill is now `user-invocable: false` (hides the bare `/distill` + the duplicate `/specode:distill`, leaving one clean command entry); distill is now **md-only** (dropped the dead `--format yml|both` + `codemap knowledge write` path); purged all remaining `.ai-memory`/codemap doc references and removed the obsolete recall section from the requirements template. **v5.0.0 BREAKING**: commands dropped the redundant `specode-` prefix — `/specode:spec` / `/specode:continue` / `/specode:list` / `/specode:distill` (were `/specode:specode-*`); the `distill` skill dir + name were renamed to `distill`; the `specode` orchestration skill is now `user-invocable: false` so the bare `/specode` no longer shows in the slash menu (still auto-activates via its commands). Preserved AI-EDS-era features: project-level `CLAUDE.md` / `AGENT.md` filesystem scan injected as `## 项目级约束` section (痛点 #14 方案 D), SessionStart cache-vs-marketplace drift hint (M8), autonomous-mode defaults — 5 schema keys + 5 `SPECODE_*` env vars + `read-defaults` / `write-default` / `reset-default` verbs (M1+M9). **v4.0.0 BREAKING**: removed memory-injection pipeline — P3-1 `codemap recall` injection / P3-2 rule-acknowledgement post-check / acceptance auto-distill prompt all dropped; round 1/2 baseline showed the recall round-trip did not net save token. `distill` skill v4 rewritten as a **manual-only Obsidian organizer** — `/specode:distill ` writes md (default) to `/Volumes/External HD/Obsidian/Notes/11-KnowledgeBase//`, no `.ai-memory/` writes. To restore v3 behaviour: `git checkout backup/specode-v3.4.0-task-swarm-v0.9.2`. | | **task-swarm** | 0.10.1 | Multi-agent **orchestration** driven by a `pipeline.yml`: semantic task groups with cross-group concurrency, fork coders, per-group reviewer + validator loops. **v0.10.1**: the `task-swarm` orchestration skill is now `user-invocable: false` so the bare `/task-swarm` no longer shows in the slash menu (the `/task-swarm:swarm` command is unchanged). Preserved AI-EDS-era features: frontmatter-first `project_root` + registry-based run lookup (0.7.x), `## 项目级约束(必读)` section + `_PROJECT_AGENT_DOCS.md` inbox sentinel (0.7.3 + 0.7.4), lifecycle group with `init` dedupe (`--on-existing {error/resume/abort-old/force-new}` flag) + `run.pipeline_end_validator` (0.8.0 + 0.8.1), M2 `run-loop` auto-driver (0.8.1), task.md `## 开发纪律 (范式参考)` section listing superpowers skill names as paradigm identifiers (0.9.0–0.9.2). **v0.10.0 BREAKING**: removed `_ingest_lessons.py` + `cmd_resolve` auto-ingest + `--no-ingest` flag — `cmd_resolve` no longer writes `/.ai-memory/knowledge/cases\|pitfalls/*.yml`. To restore v0.9.x behaviour: `git checkout backup/specode-v3.4.0-task-swarm-v0.9.2`. See [`plugins/task-swarm/`](./plugins/task-swarm). | | **obsidian-wiki** | 2.0.1 | Maintain an Obsidian LLM-Wiki with three skills: deterministic structure layer (`wiki-struct`: Home tree / READMEs / partition pages), content curation (`wiki-curate`: ingest / curate / lint), unified orchestrator (`wiki-orchestrate`). Generic code + per-vault config in the home-dir registry `~/.config/obsidian-wiki/` (falls back to `/.wiki/config.json`). **v2.0.0 BREAKING**: the spec-distill skill was extracted into specode's `/specode:distill`. See [`plugins/obsidian-wiki/`](./plugins/obsidian-wiki). | | **ragkit** | 0.1.0 | Standalone knowledge-base **RAG** — vector + lexical + metadata three-channel recall, RRF-fused, returns pointer cards. Optional downstream consumer of specode `distill` output; zero heavy deps (stdlib + numpy for lexical mode). See [`plugins/ragkit/`](./plugins/ragkit). | diff --git a/README.zh-CN.md b/README.zh-CN.md index c0a98c8..3b7abed 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -3,7 +3,7 @@ # pluginhub [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](./README.zh-CN.md#许可证) -[![specode](https://img.shields.io/badge/specode-5.2.0-blue.svg)](./plugins/specode/.claude-plugin/plugin.json) +[![specode](https://img.shields.io/badge/specode-6.1.1-blue.svg)](./plugins/specode/.claude-plugin/plugin.json) [![task-swarm](https://img.shields.io/badge/task--swarm-0.10.1-blue.svg)](./plugins/task-swarm/.claude-plugin/plugin.json) [![obsidian-wiki](https://img.shields.io/badge/obsidian--wiki-2.0.1-blue.svg)](./plugins/obsidian-wiki/.claude-plugin/plugin.json) [![Claude Code](https://img.shields.io/badge/Claude%20Code-compatible-8A2BE2)](https://github.com/qxbyte/pluginhub#installation) @@ -18,7 +18,7 @@ | 插件 | 版本 | 做什么 | | --- | --- | --- | -| **specode** | 6.1.0 | 轻量**规格驱动工作流**——编排外壳,每个阶段委托给 [superpowers](https://github.com/obra/superpowers) 技能(一等公民原生降级),每条规格固定产出 4 份文档。**v6.1.0**:新增独立 `specode:intake` skill(与 `distill` 平级)接管 requirements phase——项目分析(agent-docs 扫描 + 经验检索 + 读定位到的真实代码)+ 基于分析的澄清 + 写 `requirements.md`(保留 `spec_id`/`created_at`/`project_root` frontmatter 契约);修正 6.0.0 brainstorming 双产物错位(brainstorming 从此只产 `design.md`);检索主节点移到 intake、design 降为条件性 top-up;writing-plans 执行方式提问改为「忽略而非抑制」;SKILL.md 轻量化 215→171 行(verb 表 + autonomous-mode 细节下沉到 references),并清理 distill 里的 v3/codemap 死术语噪声。**v6.0.0 BREAKING**:固定产物 3→4——`design.md` 重定义为**传统设计文档**(背景与目标/架构概览/模块划分/接口设计/数据流/错误处理/测试策略,散文无 checkbox);新增 `tasks.md` 承载可执行计划(writing-plans 格式 + `**Interfaces:**` 契约块),引擎中立——task-swarm(pipeline.yml 改从它推导)/ superpowers / specode 自执行统一消费同一份文件;流水线变为 requirements → design → tasks → 执行方式 selector → 执行 → 验收,brainstorming 一次跨 requirements+design 双产物落盘;`/specode:continue` 改**加载即停**——只读文档 + 汇报进度简报后停下等指令,绝不自动续跑;`design-unchecked` 更名 `plan-unchecked`(tasks.md 优先,5.x legacy design.md 兜底,旧名保留 alias);5.x 存量 spec 经 legacy 推断行兜底不中断。**v5.2.0**:Tier-0 RagKit gate 收紧——探针从 `test -d .ragkit` 改为 `test -f .ragkit/chunks.json`(消除 `backend set` 只写 config.json 时的假阳性);Tier-0 采纳条目封顶 Tier-2 同等纪律(≤5 点/phase,复杂需求可标注理由突破)。 **v5.1.3**:`list-specs` 让 intake 阶段(目录已建、requirements 未写)的 spec 可见——列出含任一固定产物的子目录 + 空子目录,隐藏目录仍排除;全库文档陈旧内容清理。 **v5.1.2**:distill 打磨——非 git 且无 .gitignore 时 `ensure-gitignore` 跳过(不建 stray);新增 `copy-to` 一步 dual-landing(复制 + 重建 dest MEMORY),distill Step5 改用;navigation `来源` 单值保留 origin。 **v5.1.1**:试跑验证修复——distill 沉淀前 `design-unchecked` 检查是否执行完(未完告警,防指向未落地代码);写 navigation 前比对 MEMORY 去重;retrieval 强调语义相关而非 tag 命中。 **v5.1.0**:以全新「定位用·非事实用」路线重新引入经验检索注入——新增 stdlib `knowledge.py`(ensure-gitignore/memory-rebuild/memory-validate);distill 改产**原子 case/navigation 知识点**到项目 `/knowledge-base/`(cases/+navigation/+MEMORY 索引,不入仓),可选复制到 Obsidian;新增 `references/retrieval.md` 两级 gated 检索接入 requirements/design 阶段(注入指针非事实、默认只读小索引、命中才读≤5点);acceptance 末尾按 `auto_distill` 重新挂回 distill 提示。 **v5.0.1**:`distill` skill 改为 `user-invocable: false`(隐藏裸 `/distill` 与重复的 `/specode:distill`,只留命令一条);distill 收敛为纯 **md-only**(移除已死的 `--format yml|both` 与 `codemap knowledge write` 路径);清理全部 `.ai-memory`/codemap 文档残留,并从 requirements 模板删除已废弃的 recall 段。**v5.0.0 BREAKING**:命令去掉冗余 `specode-` 前缀——`/specode:spec` / `/specode:continue` / `/specode:list` / `/specode:distill`(原 `/specode:specode-*`);`distill` skill 目录与 `name` 同改为 `distill`;编排内核 skill `specode` 改为 `user-invocable: false`,斜杠菜单不再显示裸 `/specode`(仍经命令自动激活)。AI-EDS 时代保留至 v4.0.0 的能力:项目级 `CLAUDE.md` / `AGENT.md` filesystem 扫描注入「## 项目级约束」段(痛点 #14 方案 D)、SessionStart cache 与 marketplace drift 提示(M8)、autonomous-mode defaults(5 schema key + 5 个 `SPECODE_*` env var + `read-defaults` / `write-default` / `reset-default` verb,M1+M9)。**v4.0.0 BREAKING**:拔除记忆注入工程——P3-1 `codemap recall` 注入 / P3-2 rule-acknowledgement post-check / acceptance 后自动 distill 全部砍掉;round 1/2 baseline 实验证明 recall 注入未 net 节省 token。`distill` skill v4 完全重写为**仅手动**Obsidian 整理器——`/specode:distill ` 默认 md-only 写到 `/Volumes/External HD/Obsidian/Notes/11-KnowledgeBase//`,不再写 `.ai-memory/`。如需 v3 行为:`git checkout backup/specode-v3.4.0-task-swarm-v0.9.2`。 | +| **specode** | 6.1.1 | 轻量**规格驱动工作流**——编排外壳,每个阶段委托给 [superpowers](https://github.com/obra/superpowers) 技能(一等公民原生降级),每条规格固定产出 4 份文档。**v6.1.1**:契约锁步 CI 门禁(`test_contract_lockstep.py`)保证 MEMORY 列 + frontmatter 键在 knowledge.py / retrieval.md / doc-template.md 三处一致(负控可抓 reorder/drop);新增 `references/knowledge-flow.md` 一页纸知识流心智模型。**v6.1.0**:新增独立 `specode:intake` skill(与 `distill` 平级)接管 requirements phase——项目分析(agent-docs 扫描 + 经验检索 + 读定位到的真实代码)+ 基于分析的澄清 + 写 `requirements.md`(保留 `spec_id`/`created_at`/`project_root` frontmatter 契约);修正 6.0.0 brainstorming 双产物错位(brainstorming 从此只产 `design.md`);检索主节点移到 intake、design 降为条件性 top-up;writing-plans 执行方式提问改为「忽略而非抑制」;SKILL.md 轻量化 215→171 行(verb 表 + autonomous-mode 细节下沉到 references),并清理 distill 里的 v3/codemap 死术语噪声。**v6.0.0 BREAKING**:固定产物 3→4——`design.md` 重定义为**传统设计文档**(背景与目标/架构概览/模块划分/接口设计/数据流/错误处理/测试策略,散文无 checkbox);新增 `tasks.md` 承载可执行计划(writing-plans 格式 + `**Interfaces:**` 契约块),引擎中立——task-swarm(pipeline.yml 改从它推导)/ superpowers / specode 自执行统一消费同一份文件;流水线变为 requirements → design → tasks → 执行方式 selector → 执行 → 验收,brainstorming 一次跨 requirements+design 双产物落盘;`/specode:continue` 改**加载即停**——只读文档 + 汇报进度简报后停下等指令,绝不自动续跑;`design-unchecked` 更名 `plan-unchecked`(tasks.md 优先,5.x legacy design.md 兜底,旧名保留 alias);5.x 存量 spec 经 legacy 推断行兜底不中断。**v5.2.0**:Tier-0 RagKit gate 收紧——探针从 `test -d .ragkit` 改为 `test -f .ragkit/chunks.json`(消除 `backend set` 只写 config.json 时的假阳性);Tier-0 采纳条目封顶 Tier-2 同等纪律(≤5 点/phase,复杂需求可标注理由突破)。 **v5.1.3**:`list-specs` 让 intake 阶段(目录已建、requirements 未写)的 spec 可见——列出含任一固定产物的子目录 + 空子目录,隐藏目录仍排除;全库文档陈旧内容清理。 **v5.1.2**:distill 打磨——非 git 且无 .gitignore 时 `ensure-gitignore` 跳过(不建 stray);新增 `copy-to` 一步 dual-landing(复制 + 重建 dest MEMORY),distill Step5 改用;navigation `来源` 单值保留 origin。 **v5.1.1**:试跑验证修复——distill 沉淀前 `design-unchecked` 检查是否执行完(未完告警,防指向未落地代码);写 navigation 前比对 MEMORY 去重;retrieval 强调语义相关而非 tag 命中。 **v5.1.0**:以全新「定位用·非事实用」路线重新引入经验检索注入——新增 stdlib `knowledge.py`(ensure-gitignore/memory-rebuild/memory-validate);distill 改产**原子 case/navigation 知识点**到项目 `/knowledge-base/`(cases/+navigation/+MEMORY 索引,不入仓),可选复制到 Obsidian;新增 `references/retrieval.md` 两级 gated 检索接入 requirements/design 阶段(注入指针非事实、默认只读小索引、命中才读≤5点);acceptance 末尾按 `auto_distill` 重新挂回 distill 提示。 **v5.0.1**:`distill` skill 改为 `user-invocable: false`(隐藏裸 `/distill` 与重复的 `/specode:distill`,只留命令一条);distill 收敛为纯 **md-only**(移除已死的 `--format yml|both` 与 `codemap knowledge write` 路径);清理全部 `.ai-memory`/codemap 文档残留,并从 requirements 模板删除已废弃的 recall 段。**v5.0.0 BREAKING**:命令去掉冗余 `specode-` 前缀——`/specode:spec` / `/specode:continue` / `/specode:list` / `/specode:distill`(原 `/specode:specode-*`);`distill` skill 目录与 `name` 同改为 `distill`;编排内核 skill `specode` 改为 `user-invocable: false`,斜杠菜单不再显示裸 `/specode`(仍经命令自动激活)。AI-EDS 时代保留至 v4.0.0 的能力:项目级 `CLAUDE.md` / `AGENT.md` filesystem 扫描注入「## 项目级约束」段(痛点 #14 方案 D)、SessionStart cache 与 marketplace drift 提示(M8)、autonomous-mode defaults(5 schema key + 5 个 `SPECODE_*` env var + `read-defaults` / `write-default` / `reset-default` verb,M1+M9)。**v4.0.0 BREAKING**:拔除记忆注入工程——P3-1 `codemap recall` 注入 / P3-2 rule-acknowledgement post-check / acceptance 后自动 distill 全部砍掉;round 1/2 baseline 实验证明 recall 注入未 net 节省 token。`distill` skill v4 完全重写为**仅手动**Obsidian 整理器——`/specode:distill ` 默认 md-only 写到 `/Volumes/External HD/Obsidian/Notes/11-KnowledgeBase//`,不再写 `.ai-memory/`。如需 v3 行为:`git checkout backup/specode-v3.4.0-task-swarm-v0.9.2`。 | | **task-swarm** | 0.10.1 | 由 `pipeline.yml` 驱动的**多 agent 编排**:语义任务组 + 跨组并发、fork coder、按组 reviewer + validator 循环。**v0.10.1**:编排内核 skill `task-swarm` 改为 `user-invocable: false`,斜杠菜单不再显示裸 `/task-swarm`(命令 `/task-swarm:swarm` 不变)。AI-EDS 时代保留至 v0.10.0 的能力:frontmatter-first `project_root` + registry-based run 查找(0.7.x)、coder/reviewer/validator `task.md` 中「## 项目级约束(必读)」段 + `_PROJECT_AGENT_DOCS.md` inbox sentinel(0.7.3+0.7.4)、lifecycle group + `init` dedupe(`--on-existing` flag)+ `run.pipeline_end_validator`(0.8.0+0.8.1)、M2 `run-loop` 自动驱动器(0.8.1)、task.md 「## 开发纪律 (范式参考)」段列出 superpowers skill 名作为范式标识(0.9.0–0.9.2)。**v0.10.0 BREAKING**:拔除记忆注入工程——删 `_ingest_lessons.py` + `cmd_resolve` 自动 ingest + `--no-ingest` flag,`cmd_resolve` 不再写 `/.ai-memory/knowledge/cases\|pitfalls/*.yml`。如需 v0.9.x 行为:`git checkout backup/specode-v3.4.0-task-swarm-v0.9.2`。详见 [`plugins/task-swarm/`](./plugins/task-swarm)。 | | **obsidian-wiki** | 2.0.1 | 维护 Obsidian LLM-Wiki 的三个 skill:确定性结构层(`wiki-struct`:Home 树 / README / 分区页)、内容策展(`wiki-curate`:ingest / curate / lint)、统一编排器(`wiki-orchestrate`)。通用代码 + 家目录注册表 `~/.config/obsidian-wiki/` 按库配置(回退库内 `.wiki/config.json`)。**v2.0.0 BREAKING**:spec-distill 已剥离并迁入 specode 的 `/specode:distill`。详见 [`plugins/obsidian-wiki/`](./plugins/obsidian-wiki)。 | | **ragkit** | 0.1.0 | 独立知识库 **RAG**——向量 + 词汇 + 元数据三路召回,RRF 融合,返回定位卡片。specode `distill` 产出的 `knowledge-base/` 可直接消费;零重型依赖(词汇路仅需 stdlib + numpy)。详见 [`plugins/ragkit/`](./plugins/ragkit)。 | diff --git a/plugins/specode/.claude-plugin/plugin.json b/plugins/specode/.claude-plugin/plugin.json index ea2a56d..1273490 100644 --- a/plugins/specode/.claude-plugin/plugin.json +++ b/plugins/specode/.claude-plugin/plugin.json @@ -1,7 +1,7 @@ { "name": "specode", - "version": "6.1.0", - "description": "Lightweight spec-driven workflow: orchestrates superpowers skills per phase, lands 4 fixed docs (requirements/design/tasks/implementation-log). **v6.1.0**: 新增独立 intake skill(skills/intake/,同 distill,user-invocable:false)接管 requirements phase — 项目分析(agent-docs 扫描+经验检索+读真实代码)+基于分析的澄清+写 requirements.md(保留 spec_id/created_at/project_root frontmatter 契约);修正 6.0.0 的brainstorming 双产物错位 — brainstorming 从此只产 design.md(单产物),requirements 由 intake 产;检索主节点移到 intake 项目分析步、design 降为条件性 top-up;弊端修复 — writing-plans 结尾的执行方式提问改为「忽略而非抑制」;SKILL 轻量化 215→171 行(verb 表/autonomous-mode 细节下沉到 refs,零行为变化)。 **v6.0.0 BREAKING**: 固定产物 3→4 — design.md 重定义为**传统设计文档**(背景与目标/架构概览/模块划分/接口设计/数据流/错误处理/测试策略,散文无 checkbox);新增 tasks.md 承载可执行计划(writing-plans 格式 + Interfaces 契约块,引擎中立,task-swarm/superpowers/自执行统一消费,pipeline.yml 改从 tasks.md 推导);流水线变为 requirements→design→tasks→执行方式 selector→执行→验收,brainstorming 一次跨 requirements+design 双产物落盘(后置 relocate 检查两份);continue 改「加载即停」— 只读文档+汇报进度简报后停下等指令,绝不自动续跑;design-unchecked 更名 plan-unchecked(tasks.md 优先,design.md 含 checkbox 按 5.x legacy 兜底,旧名保留 alias)。5.x 存量 spec 由 continue 推断表 legacy 行兜底识别,不中断。 **v5.2.0**: Tier-0 RagKit gate tightened — probe changed from `test -d .ragkit` to `test -f .ragkit/chunks.json` (eliminates false-positive when only config.json exists after `backend set`); Tier-0 采纳条目 capped at Tier-2 discipline (≤5/phase, reasoned override allowed). **v5.1.3**: `list-specs` 让 intake 阶段(目录已建、requirements 未写)的 spec 可见 — 列出含任一固定产物的子目录 + 空子目录(intake),隐藏目录与无关内容目录仍排除;全库文档陈旧内容清理(README/CONTRIBUTING/SKILL 残留措辞)。 **v5.1.2**: distill 打磨 — ensure-gitignore 在非 git 且无既有 .gitignore 时跳过(不建 stray);新增 knowledge.py copy-to(一步 dual-landing:复制 cases/navigation + 重建 dest MEMORY),distill Step5 改用它;navigation 来源 单值保留 origin、复用 spec 写正文。 **v5.1.1**: 试跑验证修复 — distill 沉淀前用 design-unchecked 检查 spec 是否执行完(未完则告警,防知识点指向未落地代码);写 navigation 点前先比对 MEMORY 去重;retrieval 强调语义相关而非 tag 命中;F2(非 git project_root)评估为 by design 不修。 **v5.1.0**: 重新引入「经验检索注入」走全新「定位用·非事实用」路线 — 新增 stdlib knowledge.py(ensure-gitignore/memory-rebuild/memory-validate);distill 改产**原子 case/navigation 知识点**到项目 /knowledge-base/(cases/+navigation/+MEMORY 索引,不入仓),可选复制到 Obsidian;新增 references/retrieval.md 两级 gated 检索接入 requirements/design phase(注入指针非事实、默认只读小索引、命中才读≤5点);acceptance 末尾按 auto_distill 重挂 distill 提示。 **v5.0.1**: distill skill 加 `user-invocable:false`(隐藏裸 `/distill` + 消除 `/specode:distill` 重复项,只留命令一条);distill 收敛为纯 **md-only**(移除 `--format yml|both` + `codemap knowledge write` 死路径);清理全部 `.ai-memory`/codemap 文档残留,并从 requirements 模板删除已废弃的「已知约束/历史坑」recall 段。**v5.0.0 BREAKING**: 命令去 `specode-` 前缀 — `/specode:spec` / `/specode:continue` / `/specode:list` / `/specode:distill`(原 `/specode:specode-*`);distill skill 目录与名同改为 `distill`;编排内核 skill `specode` 加 `user-invocable:false`,斜杠菜单不再显示裸 `/specode`(仍经命令/自然语言自动激活)。**v4.0.0 BREAKING**: 彻底拔出记忆注入工程 — 砍掉 specode 主流程的 (1) P3-1 codemap recall 注入 `## 已知约束 / 历史坑` 段, (2) P3-2 rule-acknowledgement post-check, (3) acceptance 后自动 AskUser 触发 distill。round 1/2 baseline 实验证明 recall 注入未 net 节省 token。保留 project-level CLAUDE.md / AGENT.md filesystem scan (不涉及 .ai-memory)。distill skill v4 完全重写: 仅手动触发 `/specode:distill `, 默认 md-only, 默认写 `/Volumes/External HD/Obsidian/Notes/11-KnowledgeBase//` (--target-dir 可覆盖), 不再调 codemap recall, 不再默认写 .ai-memory yml。如需 v3 记忆注入行为, checkout `backup/specode-v3.4.0-task-swarm-v0.9.2`。", + "version": "6.1.1", + "description": "Lightweight spec-driven workflow: orchestrates superpowers skills per phase, lands 4 fixed docs (requirements/design/tasks/implementation-log). **v6.1.1**: 新增契约锁步 CI 门禁 tests/test_contract_lockstep.py(MEMORY 列 + frontmatter 键在 knowledge.py/retrieval.md/doc-template.md 三处一致,负控验证可抓 reorder/drop);新增 references/knowledge-flow.md 一页纸知识流心智模型(distill/knowledge-base/MEMORY/ragkit/intake-检索 的谁产·谁读·何时)。 **v6.1.0**: 新增独立 intake skill(skills/intake/,同 distill,user-invocable:false)接管 requirements phase — 项目分析(agent-docs 扫描+经验检索+读真实代码)+基于分析的澄清+写 requirements.md(保留 spec_id/created_at/project_root frontmatter 契约);修正 6.0.0 的brainstorming 双产物错位 — brainstorming 从此只产 design.md(单产物),requirements 由 intake 产;检索主节点移到 intake 项目分析步、design 降为条件性 top-up;弊端修复 — writing-plans 结尾的执行方式提问改为「忽略而非抑制」;SKILL 轻量化 215→171 行(verb 表/autonomous-mode 细节下沉到 refs,零行为变化)。 **v6.0.0 BREAKING**: 固定产物 3→4 — design.md 重定义为**传统设计文档**(背景与目标/架构概览/模块划分/接口设计/数据流/错误处理/测试策略,散文无 checkbox);新增 tasks.md 承载可执行计划(writing-plans 格式 + Interfaces 契约块,引擎中立,task-swarm/superpowers/自执行统一消费,pipeline.yml 改从 tasks.md 推导);流水线变为 requirements→design→tasks→执行方式 selector→执行→验收,brainstorming 一次跨 requirements+design 双产物落盘(后置 relocate 检查两份);continue 改「加载即停」— 只读文档+汇报进度简报后停下等指令,绝不自动续跑;design-unchecked 更名 plan-unchecked(tasks.md 优先,design.md 含 checkbox 按 5.x legacy 兜底,旧名保留 alias)。5.x 存量 spec 由 continue 推断表 legacy 行兜底识别,不中断。 **v5.2.0**: Tier-0 RagKit gate tightened — probe changed from `test -d .ragkit` to `test -f .ragkit/chunks.json` (eliminates false-positive when only config.json exists after `backend set`); Tier-0 采纳条目 capped at Tier-2 discipline (≤5/phase, reasoned override allowed). **v5.1.3**: `list-specs` 让 intake 阶段(目录已建、requirements 未写)的 spec 可见 — 列出含任一固定产物的子目录 + 空子目录(intake),隐藏目录与无关内容目录仍排除;全库文档陈旧内容清理(README/CONTRIBUTING/SKILL 残留措辞)。 **v5.1.2**: distill 打磨 — ensure-gitignore 在非 git 且无既有 .gitignore 时跳过(不建 stray);新增 knowledge.py copy-to(一步 dual-landing:复制 cases/navigation + 重建 dest MEMORY),distill Step5 改用它;navigation 来源 单值保留 origin、复用 spec 写正文。 **v5.1.1**: 试跑验证修复 — distill 沉淀前用 design-unchecked 检查 spec 是否执行完(未完则告警,防知识点指向未落地代码);写 navigation 点前先比对 MEMORY 去重;retrieval 强调语义相关而非 tag 命中;F2(非 git project_root)评估为 by design 不修。 **v5.1.0**: 重新引入「经验检索注入」走全新「定位用·非事实用」路线 — 新增 stdlib knowledge.py(ensure-gitignore/memory-rebuild/memory-validate);distill 改产**原子 case/navigation 知识点**到项目 /knowledge-base/(cases/+navigation/+MEMORY 索引,不入仓),可选复制到 Obsidian;新增 references/retrieval.md 两级 gated 检索接入 requirements/design phase(注入指针非事实、默认只读小索引、命中才读≤5点);acceptance 末尾按 auto_distill 重挂 distill 提示。 **v5.0.1**: distill skill 加 `user-invocable:false`(隐藏裸 `/distill` + 消除 `/specode:distill` 重复项,只留命令一条);distill 收敛为纯 **md-only**(移除 `--format yml|both` + `codemap knowledge write` 死路径);清理全部 `.ai-memory`/codemap 文档残留,并从 requirements 模板删除已废弃的「已知约束/历史坑」recall 段。**v5.0.0 BREAKING**: 命令去 `specode-` 前缀 — `/specode:spec` / `/specode:continue` / `/specode:list` / `/specode:distill`(原 `/specode:specode-*`);distill skill 目录与名同改为 `distill`;编排内核 skill `specode` 加 `user-invocable:false`,斜杠菜单不再显示裸 `/specode`(仍经命令/自然语言自动激活)。**v4.0.0 BREAKING**: 彻底拔出记忆注入工程 — 砍掉 specode 主流程的 (1) P3-1 codemap recall 注入 `## 已知约束 / 历史坑` 段, (2) P3-2 rule-acknowledgement post-check, (3) acceptance 后自动 AskUser 触发 distill。round 1/2 baseline 实验证明 recall 注入未 net 节省 token。保留 project-level CLAUDE.md / AGENT.md filesystem scan (不涉及 .ai-memory)。distill skill v4 完全重写: 仅手动触发 `/specode:distill `, 默认 md-only, 默认写 `/Volumes/External HD/Obsidian/Notes/11-KnowledgeBase//` (--target-dir 可覆盖), 不再调 codemap recall, 不再默认写 .ai-memory yml。如需 v3 记忆注入行为, checkout `backup/specode-v3.4.0-task-swarm-v0.9.2`。", "author": { "name": "xueqiang", "email": "xueqiang361@gmail.com" diff --git a/plugins/specode/CHANGELOG.md b/plugins/specode/CHANGELOG.md index c4e3b17..600f1ac 100644 --- a/plugins/specode/CHANGELOG.md +++ b/plugins/specode/CHANGELOG.md @@ -4,7 +4,10 @@ specode 是 spec-driven 轻量工作流插件:requirements → design → task ## Unreleased -## 6.1.0 (2026-07-05) +## 6.1.1 (2026-07-05) + +- **契约锁步 CI 门禁**(`tests/test_contract_lockstep.py`):把 CLAUDE.md 的「变更纪律」变成可执行测试——读 `knowledge.py` **真实**产出的 MEMORY 表头(跑 memory-rebuild,非源码内省),断言它与 `references/retrieval.md`、`skills/distill/references/doc-template.md` 文档化的列一致,并断言 doc-template 的 frontmatter 键 == knowledge.py 读的键。提取器经**负控验证**能抓 reorder/drop,门禁可真失败而非白过。三处任一漂移 → 测试红。(+5 测,共 90。) +- **一页纸知识流心智模型**(`references/knowledge-flow.md`):ASCII 产出→索引→消费全图(distill 写 / `knowledge.py` 索引 / intake+design 读、tasks+执行零注入)+ 「定位用非事实用」不变量 + 各部件权威文档指针。挂进 SKILL/intake References + 两 README 架构树(顺带把 `autonomous-mode.md` 补进树)。 - **新增独立 intake skill**(`skills/intake/`,与 `distill` 平级,`user-invocable: false`,由编排 SKILL 经 Skill 工具按名 `specode:intake` 调用)接管 **requirements phase**:项目分析(agent-docs 扫描 + 经验检索 + 读定位到的真实代码)→ 基于分析的澄清(brainstorming 级,非固定问卷)→ 写 `requirements.md`。**保留 frontmatter 契约不动**:`spec_id` / `created_at` / `project_root`(后者仍经 `write-project-root` 单一写入口)。 - **修正 6.0.0 的 brainstorming 双产物错位**:brainstorming 从此**只产 design.md(单产物)**,requirements 由 intake 产。requirements phase 不再分「superpowers 在/不在」——永远走 intake,消掉一个 fork。relocate 后置检查回到单文件。