skein-spec — 规则记忆库 (namespace × inclusion)
🔒 全局流程规则(状态机/调度/优先级等)以 skein-flow/references/ 为单一真值源。
差异化核心。不同于「按需沉淀单一 spec 文件」, SKEIN 记忆按两个正交维度组织, 基于 .skein/spec:
绑定 agent (按读/写拆两个, 均 frontmatter
skills: skein:skein-spec):
- 读路径默认归
skein-recaller(只读同步召回员): recall 检索 (planning) 派它, main 等召回结果进 planning (dispatch prompt「已知」段带上); executor/main 也可直跑skein-spec recallCLI 等价命令。- 写路径默认归
skein-specer(记忆写盘员): sediment/amend/reconstruct·maintain/prune 五类写作业 (finish 读 diff + subagent 回传摘要 跑判定门产候选 + 写盘 + reindex)。executor 踩到可复用约定也可直跑skein-spec sedimentCLI 等价命令。异步 fire-and-forget 模式 (被 skein-flow finish 阶段在 finish 闭环后派发): specer 自主跑判定门 +skein-spec sediment/amend写盘 + reindex, 无需 main 等待回传 (main 派发即结束回合, 回传到达后只补 output trace; 判定门通过即自主写, 不逐次询问用户)。仅 bootstrap/reconstruct 全局动作跑前一次征同意。
namespace × inclusion 正交两维
两者正交: namespace 决定放哪个目录 (内容分类), inclusion 决定怎么加载 (写在每篇 frontmatter 里, 与目录无关) —— 把文件从一个 namespace 目录搬到另一个不会改变它的加载策略, 这条曾被文档写反过, 教用户把文件搬目录来「降级」, 而那什么也不会发生。
| namespace \ inclusion | always 常驻注入 (SessionStart) | auto 按需召回 (默认) | fileMatch 按 globs 命中注入 | manual 纯手动检索 |
|---|---|---|---|---|
| rules (硬规 / 经验规则) | 硬约束 / 命令式契约 (软预算 spec.always_budget, 超则告警降级) |
长尾经验规则 (默认落点) | 特定路径触发的规则 | 极冷门参考 |
| product (需求现状 wiki) | 极少见 (核心边界铁律) | 功能域现状页 (默认落点, 见下文) | — | 历史存档快照 |
| map (代码结构语义页) | — | 职责 / 数据流说明页, 配合 map --skeleton 现算骨架 |
— | — |
| external (外部长文档) | — | 索引摘要 | — | 原文全文, 手动检索 (默认落点) |
namespace 开放不设白名单 (目录扫描得, 新增 namespace 不改代码, 常见 rules/product/map/external), inclusion 是封闭四值。索引: 每个 <namespace>/index.md (该 namespace 全规则, 带 category / inclusion / anchors 列) + 顶层 index.md 聚合概览。
寻找纪律 (planning/调研/找方案时)
动手前优先跑 skein-spec recall "<关键词>" — 现有规则沉淀比凭记忆重推快且准, inclusion: always 的规则已常驻无需 recall。
顺序: recall spec (全 namespace, FTS5 BM25 排序) → vault → 项目本地 (Read/Grep) → 外部搜索。
recall 命中 → model 读全文判相关 → 相关的注入当前 task 上下文 (dispatch prompt「已知」段带上)。
external 层 (不入 hook, 纯手动) 存长文档/外部资料, 同经 recall 跨层检索。
recall (planning 阶段, 派 skein-recaller)
默认派
skein-recaller(只读同步召回员) 承载, main 等其结果进 planning; main 也可直跑skein-spec recallCLI 等价命令。
skein-spec recall "<任务关键词>" [--src rules/product/map/code/all]
- grep
<namespace>/index.md输出命中行 → model 读命中规则全文, 判是否真相关 → 相关的注入当前 task 上下文 (dispatch prompt「已知」段带上)。 inclusion: always的规则已由 SessionStart hook 常驻, 无需 recall。--src分源:rules/product/map限定单 namespace,code专召 map namespace 语义页 + anchors 汇总, 缺省all跨 namespace 检索。
sediment (task finish 阶段, 异步 fire-and-forget) — 判定门 + 自主写盘
task finish 闭环后由 skein-flow finish 阶段异步 fire-and-forget 派 skein-specer 跑「判定门 checklist → 分层归类 → skein-spec sediment 自主写盘 + reindex」三步 (含升降级)。异步: main 派 skein-specer 即结束回合, 不等回传 (finish 已闭环, 禁为 sediment 阻塞); skein-specer 自主写盘, 回传到达后 main 只补 output trace 供审阅。判定门 (语义) 通过即写, 不逐次 AskUserQuestion —— 记忆积累高频, 每次询问是噪声; 误沉淀后续调 inclusion/删文件可逆纠正。完整判定 trace 模板、分层/归类规则、写盘命令详见 references/sediment-workflow.md。
sediment 只追加新章节 —— 现状类内容 (尤其 product wiki) 过时后要改写旧结论而非无限并存新版本, 追加 vs 改写的抉择见下文 amend。
prune (sediment 后自动精简, skein-specer) — 判定门 + 自主归档
sediment 写盘后 skein-specer 顺带跑一轮精简: 扫全 namespace, 按判据检出 candidate 并自动 archive (可逆) 而非只报告。异步 fire-and-forget: 同 sediment, main 派即放手, 不等回传。
- 判据分两层 —— 全局恒跑 (always 超预算 / 断链) + 按 namespace 分表 (product 只报告, 需求真值只有人知道该不该删)。完整判据表与判定顺序见 references/prune-workflow.md, 本文件不重抄。
- archive 即可逆, 不删文件 — 归档到
.skein/spec/.archive/<ts>/,restore <ts>可回滚。 - 保护标记: 规则头
protected: true跳过不精简。 - 无命中 → 跳过, 如实报「无精简项」, 不空跑 archive。
写盘参照模板 (软骨架, 非强制)
规则 body 各有脊柱, sediment 写盘前 skein-specer 参照对应模板填:
- always 规则 (命令式契约) 参照 references/templates/rules-always.md.tmpl: 铁律/禁 (MUST/禁, 一句一规则) + 反例表 (禁/改为) + 可选关联。
- auto 规则 (ADR/陷阱型) 参照 references/templates/rules-auto.md.tmpl: 触发场景 / 陷阱-正解 / 反例 / 案例 / 适用 / 关联。
- product 现状页参照 references/templates/product.md.tmpl: 现状 / 边界 / 为什么这样 / anchors / 关联。
- map 语义页参照 references/templates/map.md.tmpl: 职责 / 入口 / 数据流 / anchors。
参考骨架非强制 — sediment 是 fire-and-forget, 模板仅作 skein-specer 填 body 的结构引导, 不强校验、不阻塞写盘; 实际规则按内容取舍段名 (elastic spine), 缺段不报错。
product wiki (现状记忆, namespace=product)
编写 product wiki 时参考 skein-flow/references/writing-for-agents.md 的 information hierarchy — 现状页 (state) 用 in-file reference 格式,决策变更 (delta) 落 rules namespace 作 ADR 式记录。
区别于 rules 的「决策 / 规则」(为什么这样改), product namespace 只存当前系统现状 —— 单一功能域此刻是什么样, 不叠加历史决策链。
- delta vs state: sediment 沉淀的是「决策变更」(踩过的坑 / 为什么这样约定), 落 rules namespace; product 只留现状快照, 旧结论过时直接
amend改写, 不追加并存多个矛盾版本 (这一条决定了 product 与 rules 的判据也不同, 见上文 prune 分表)。 - 按功能域切页: 一个功能域 (登录 / 计费 / 权限...) 一个 topic 文件, 不与 rules 按类目混放。
- finish 时回写候选: skein-flow finish 阶段跑
skein-spec finish-candidates <tid>, 三路降级产候选 —— ① diff 改动文件反查 anchors 命中的既有 product 页 → ② 皆无命中则用 prd 关键词recall --src product找弱候选 → ③ 仍无则报「无候选, 可能是新功能域, 建议新建」, 禁硬凑。main 拿到候选后派 specer 用amend(改写既有页) 或sediment --namespace product(新建页) 落盘。 - 不自动精简: product 是需求真值, maintain 判据只有 anchors 失效才报告 (禁自动 archive, 需人判断), 无 stale / keywords 重复 / 废弃 / 孤立判据。
amend (改写既有章节, 而非追加)
sediment 只会追加新章节; 现状类内容 (product wiki 尤甚) 过时后要改写旧结论, 而非无限并存新版本, 用 amend:
skein-spec amend --topic <ns/cat/topic> --section <章节名> --body-file <正文文件> [--rename-section <新章节名>]
- 改前先
archive旧版本 (可逆), 其余章节与 frontmatter 逐字不动。 - 目标章节不存在 → 报错并列出该主题现有章节名, 不静默追加新章节 (❌ 静默追加; 追加新章节走
sediment)。 --rename-section同步更新库内反链 ([[topic#旧章节名]]→ 新名), 缺省不改章节名。- 写盘后自动
reindex。
amend vs sediment 抉择: 是「改写现状」(旧结论已过时, 只该有一份真值) 用 amend; 是「新增条目」(新踩的坑 / 新决策, 不否定旧条目) 用 sediment。详细抉择树见 references/sediment-workflow.md。
map (代码结构现算, namespace=map)
skein-spec map [--skeleton] [--paths <逗号分隔路径>]
现算目录树 + 符号 + 行数, 不写盘:
--skeleton: 仅顶层符号 (Pythondef/class/async def, JS/TSfunction/class/export ..., Gofunc/type), 正则非 AST (ponytail: 装饰器 / 嵌套 / 多行签名抓不准, 升级路径 tree-sitter)。--paths: 文件清单注入 (逗号分隔; 缺省git ls-files, 非 git 仓降级 rglob 并排除node_modules/__pycache__等衍生目录)。- map namespace 的语义页 (人写的职责 / 数据流说明) 与现算骨架合并展示;
recall --src code专召 map namespace 语义页 + anchors 汇总。
analyze (task 一致性核查, 只读)
skein-spec analyze <tid>
对齐 spec-kit /speckit.analyze, 五类只读检查 (不写任何盘), 全启发式关键词/子串匹配, 措辞统一带「候选」字样, 零命中就如实报零冲突, 禁断言违规:
| 检查 | 比对 |
|---|---|
| 验收覆盖率 | prd 验收标准 ↔ subtask 验收项, 报关键词无命中的验收条 (候选未覆盖) |
| 硬规冲突 | design.md ↔ inclusion: always 规则的否定式表述, 报候选 (不断言违规) |
| 范围蔓延 | subtask 名/desc ↔ prd 全文关键词, 报无命中的 subtask (候选蔓延) |
| proposed 置信度 | design.md 提及的规则标题 ↔ 该规则 status: proposed, 报未验证引用 |
| 接缝存在性 | design.md「测试接缝」段声明的路径/符号 ↔ codebase, 报未找到 |
缺省输出机器可读 JSON 供 skein-checker 消费 (--show 才是人读文本); for-check.md 的一致性核查段直接调这条, 不再手工 diff 比对。
migrate (旧两层结构 → namespace × inclusion)
旧 spec/core/ + spec/recall/ 两层结构迁移到 rules/product/map/external namespace × inclusion 新结构: skein-setup 在已初始化仓检出 spec/core/ 存在时提示跑迁移, init 对全新仓直接建新结构目录。两阶段全流程 —— 阶段 1 机械改名 (旧 core→rules/inclusion:always, 旧 recall→rules/inclusion:auto) / 阶段 2 语义分拣 (把该归 product 的现状类内容、该归 map 的结构说明从 rules 分拣出去) —— 详见 references/migration-v2.md。
restructure (碎片文件批量合并进主题文件)
skein-spec restructure --map <plan.json> [--dry-run]
映射 JSON ({"<namespace>/<类目>/<主题>.md": ["<namespace>/<类目>/<碎片>.md", ...]}) 把右侧碎片文件合并为左侧主题文件; 源文件自动归档到 .archive/ (可 restore <ts> 回滚), 写盘后自动 reindex。--dry-run 只打印计划不落盘。碎片规则文件批量归并走此命令, 禁一条规则一个文件手工搬。
空仓冷启动播种 (一次性, main)
新仓 .skein/spec 为空时前几十轮 planning 无规则可召回。此时 main 可提议从既有代码库提炼约定作冷启动基线 —— 派 skein-researcher 扫五维 (命名/错误处理/测试/架构边界/构建), 候选逐条定 namespace×inclusion 或 drop, 复用上文 sediment 写盘流程落盘 (bootstrap 跑前一次征同意覆盖整轮, 内部候选自动写)。
一次性动作, AskUserQuestion 征同意再跑 (禁自动); 用户拒 → 走正常 planning, 规则随 finish sediment 增量积累。完整流程 (触发条件 / 五维明细 / ns×inclusion 判定表 / 落盘) 见 references/bootstrap-seeding.md。
完全重构 (reconstruct, main) — 依代码/项目内容重建整库
既有记忆大面积失效 (大重构 / 换技术栈 / 记忆漂移 / 接手可疑旧库) 时, 把全库规则可逆归档后依当前代码 + 项目内容从零重建。区别于 bootstrap (仅空仓、纯增量): 重构多 skein-spec archive 前置 (可逆清库) + 按项目类型分型扫描。
六档深度 (--deep=<recall|low|full|deep|max|high>, 默认 full): 档位同时决定 ②archive 范围 (长尾 namespace / 全库) 与 ④扫描深度 (五维基线 / 全 8 型探针 / 加旧规则逐条比对), 逐档明细见 references/reconstruct-memory.md §1.5。
skein-spec archive --namespace <ns> # 只归档指定 namespace (recall/low 档)
skein-spec archive # 全 namespace 归档 (full/deep/max/high 档)
skein-spec restore <ts> # 回滚 (撞名不覆盖新规则, 加 restored- 前缀并存)
# 注: 深度档 (recall/low/full/deep/max/high) 是本 skill 的参数, 决定「归档多大范围 + 扫多深」,
# 不是 CLI 参数 —— archive 只认 --namespace。
流程: 快照 → 归档 → 识别项目类型 → 分型扫描 (researcher bootstrap 模式 + 类型侧重) → 逐条定 ns×inclusion → sediment 自动写盘 → 验证 + 保留归档。🛑 AskUserQuestion 征同意再跑 (归档全库虽可逆仍是全局动作 · STOP, 禁自动)。事无巨细设计 + 8 类项目 (backend/frontend/cli/monorepo/data-ml/infra/mobile/docs) 分型扫描侧重、探针、always 倾向、规则示例、陷阱 见 references/reconstruct-memory.md。
失败模式 (if-then 三段式: 触发 → 一线修复 → 仍失败兜底)
| 触发 | 一线修复 | 仍失败兜底 |
|---|---|---|
| recall grep 无命中 | 放宽 / 换关键词重 grep 一次 (同义词 / 上位类目) | 仍无 → planning 走无规则路径, 不阻塞; 靠 finish sediment 增量补 |
skein-spec sediment/amend/reindex 报错 |
读脚本 stderr 定位 (路径 / 权限 / 类目名非法 / amend 章节名不存在) | 仍失败 → 该候选暂存草案不落盘, 记 需要: 手工核对, 禁半写坏盘 |
always 常驻超预算告警 |
prune 自动降级最少复用的 always 规则到 auto (sediment 调 inclusion) |
仍超 → 停手, 提示用户 always 层膨胀, 需人工裁剪硬规集 |
| reconstruct 重建不满意 | skein-spec restore <ts> 从归档恢复 (撞名加 restored- 前缀并存) |
仍失败 → 归档目录仍在 .skein/spec/.archive/<ts>/, 手动核对取舍 |
✅ 正向配方 (命中反面=流程错误)
🔒 铁律: sediment+prune 异步 fire-and-forget 禁阻塞 finish;
inclusion: always只留命令式硬约束。
| 场景 | 正确做法 (❌ 反面) |
|---|---|
| sediment 写盘 / prune 自动 archive | 逐项输出判定 trace, skein-specer 回传后 main 补 (❌ 未输出判定 trace) |
| 判定门全否 | 跳过不沉淀 (❌ 无增量硬凑沉淀) |
| 判定门通过要不要问用户 | 自主写盘, 只输出 trace 不硬停 (❌ 逐次 AskUserQuestion 问用户批不批) |
| finish 闭环 vs sediment/prune | 异步 fire-and-forget, finish 先 archive (❌ 为等 sediment/prune 阻塞闭环) |
| 写盘更新 index.md | skein-spec sediment/amend 自动同步 (❌ 不同步 index.md / 手改绕过) |
| 规则分层 | 默认落 inclusion: auto, always 只留硬约束 (❌ 什么都塞 always 常驻) |
| product wiki 现状过期 | amend 改写既有章节 (❌ sediment 追加并存多个矛盾版本) |
| amend 目标章节不存在 | 报错列现有章节名, 改走 sediment 建新章节 (❌ 静默追加) |
maintain (手动体检, main)
规则库漂移时的手动全量体检 (供 user 在 sediment+prune 之外独立审查, 只报告不动手): skein-spec maintain [--namespace <ns>]。判据按 namespace 分表 (超预算/断链全局恒跑, stale/keywords 重复/废弃/孤立按上文 prune 分表规则, product 只报告) + 输出格式详见 references/maintain.md。加 --apply 则同一扫描自动修复可修项 (超预算→循环降级 always→auto / stale→归档 / keywords 重复→归档保留最新 / 废弃→归档 / product namespace 的 anchors 失效仍只报告), 每步写 .audit-log (7 天轮转), 详见 auto-fix 模式与 references/maintain.md。
auto-fix (Stop hook 触发, 异步 fire-and-forget) — 全自动 spec 修复
sediment+prune 是 finish 后顺跑一轮, 仍可能漏 (如 session 中途 always 层膨胀超预算 / 新增断链)。auto-fix 用 Stop hook + .pending-fix 标记 做异步兜底修复, 全程无需用户介入。
skein-spec maintain --apply # 同一次扫描自动修可修项 (product namespace/断链只报告)
流程:
- 检测 (Stop hook) — 回合结束 Stop hook 跑轻量 spec 体检, 检出任一可修项 (超预算 / stale / keywords 重复 / 废弃 / 断链) → 写
.skein/spec/.pending-fix标记 (含命中项摘要 + ts)。 - 派发 (main) — main 检测到
.pending-fix→ 异步 bg 派skein-specer(fire-and-forget, 派出即结束回合, 不等回传, 与 sediment 同模式)。 - 修复 (skein-specer) — 读标记 →
skein-spec maintain --apply一次性自动修可修项 (判据同 prune 分表, 见 references/prune-workflow.md; 处置动作见 references/maintain.md--apply段)。 - 收尾 — reindex → 清
.pending-fix标记。每步追加写.audit-log(7 天轮转)。所有动作可逆 (archive 可restore <ts>回滚, inclusion 可改回), 误修后续手工纠正。
双保险: skein-flow finish 阶段闭环后也检测一次 .pending-fix 标记 (防 Stop hook 漏检), 详见 skein-flow finish 阶段流程。
不修断链 / product: [[slug]] 目标缺失无法自动决断该修链还是建目标, product namespace 的 anchors 失效无法自动决断需求是否真已过时, 均只在回传里列清单待人判断; 其余判据 (rules/external 的 stale/keywords 重复/废弃, map 的 anchors) 明确、处置可逆, 直接自动修。