diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/.nojekyll @@ -0,0 +1 @@ + diff --git a/.sopify/blueprint/README.md b/.sopify/blueprint/README.md index 911b1d33..87ef594d 100644 --- a/.sopify/blueprint/README.md +++ b/.sopify/blueprint/README.md @@ -13,7 +13,7 @@ ## 当前焦点 -- 当前无活动 plan;EvidentLoop 可选配套安装、Codex 公开版本 dogfood 与正式 receipt 已收口,归档见 `../history/2026-07/20260718_evidentloop_optional_audit_integration/`。 +- 当前活动 plan:`../plan/20260720_plain_language_output/`;Skill、推广页、产品形态和架构图文字边界已最小收口,方案内审计发现的两项问题已修复并通过全量验证;当前交付只执行已授权的本地 commit 与当前分支 push。 - MCP tool plane 已完成 Codex-first 持久注册验证和 Claude 会话级只读调用验证,Qoder / Claude / Copilot 的后续持久注册仍按证据推进。 - P8 Protocol Kernel & Runtime Retirement 已归档至 `../history/2026-06/20260605_p8_protocol_kernel_runtime_retirement`。 - history 归档:已可用;最近归档:`../history/2026-07/20260717_sopify_entry_preflight`。 diff --git a/.sopify/blueprint/design.md b/.sopify/blueprint/design.md index e4c60e8a..f381d12b 100644 --- a/.sopify/blueprint/design.md +++ b/.sopify/blueprint/design.md @@ -123,20 +123,20 @@ Sopify 不默认提示、安装或执行任何 Verifier。独立审计可不绑 所有线共享一个知识面(blueprint / history)。知识面是跨 session/model/host 的共享工作记忆。 -在多模型、多云、多宿主逐步解耦的环境下,Surface-shared 的目标是让项目连续性绑定到共享文件协议,而不是绑定到某个模型、云或聊天上下文。任意 host/model 只要正确消费 blueprint/history 与 handoff 暴露的机器事实,就能基于同一项目记忆继续工作;但推进 pending checkpoint 或产生副作用仍必须回到 Wire-composable 的机器接力与 protocol admission。 +在多模型、多云、多宿主逐步解耦的环境下,Surface-shared 的目标是让项目连续性绑定到共享文件协议,而不是绑定到某个模型、云或聊天上下文。受支持的宿主可在用户明确要求后读取 blueprint、plan、history 与 receipts,基于同一项目记录继续工作;本地 handoff 只提供当前环境的恢复提示,推进 pending checkpoint 或产生副作用仍必须经过 protocol admission。 **Sopify 的不可替代性 = 线 + 面的组合。** Protocol 定义证据规范,sopify_writer 做协议准入,Receipts 提供审计证据。 ## 三层定位 (ADR-016: Protocol-first) -> **P8 Final**:Protocol-first 是已完成的产品形态。`blueprint/protocol.md` 定义最小可携带协议。Runtime 已在 P8 中退场(W2.10 物理删除 46 文件 / ~15.6K LOC)。Protocol kernel(sopify_writer + sopify_contracts + protocol.md)是唯一的真相源和写路径。 +> **P8 Final**:Protocol-first 是已完成的产品形态。`blueprint/protocol.md` 定义最小可携带协议。Runtime 已在 P8 中退场(W2.10 物理删除 46 文件 / ~15.6K LOC)。Protocol kernel(sopify_writer + sopify_contracts + protocol.md)是协议真相源和受控写入边界。 > > **Blueprint Truth Cutover 原则**:Blueprint 是产品合法边界和预算的唯一定义源。Protocol kernel 定义 how it currently runs,blueprint 定义 what is valid。 | 层 | 内容 | 体量 | 可替代性 | |----|------|------|---------| | **Protocol Kernel** | `.sopify/` 目录约定、schema、sopify_writer、sopify_contracts | ~2K 行 + 纯文档 | 不可替代 | -| **Default Workflow** | analyze / design / develop / finalize skill prompts + host prompt assets | 纯文档/prompt | 可替换(宿主可用自有工作流) | +| **Default Workflow** | analyze / design / develop 三个主阶段 Skill、辅助 Skill 与显式 finalize 动作 + host prompt assets | 纯文档/prompt | 可替换(宿主可用自有工作流) | | **Host / Skill Adapters** | installer / host adapters / payload / doctor | ~3K 行 | 可按宿主扩展 | **Convention 模式(当前唯一模式)**:宿主读 prompt 指令 → 自行推进 → sopify_writer 做结构化写入校验 → receipts 提供审计证据。 @@ -160,7 +160,7 @@ Sopify 不默认提示、安装或执行任何 Verifier。独立审计可不绑 - Host LLM 是执行者,**不是 authorizer** - Protocol admission 做**结构级校验**(sopify_writer:schema 合法、plan_id 有效、receipt 命名规范);host prompt 做**语义级引导** - sopify_writer **不是 executor**:不生成或修改方案语义;唯一目录迁移例外是 `finalize_plan` 在版本校验后执行标准归档 -- 宿主执行层**按协议文件做事**:读 plan.md / handoff / receipts,写回通过 sopify_writer +- 宿主执行层**按协议文件做事**:读 plan.md / handoff / receipts;协议状态、handoff 与 receipts 通过 sopify_writer 写回 ### Subject Identity(主体身份) @@ -561,6 +561,15 @@ output.py 渲染层逐字段分类。只做分类,不做改造决策(改造 - prompt asset 属于 payload/install surface - `skills/{zh,en}` 是 prompt-layer source of truth;宿主安装产物由 installer / host adapter 渲染 - 新宿主不进 legacy 目录树结构;新宿主如需 prompt asset,走 host adapter / payload 机制 +- 宿主可按请求直接路由 Analyze、Design、Develop、KB 或 Templates;单个 Skill 只完成自身职责,仍共享正式协议、授权和输出边界,不作为独立产品运行 +- Analyze 负责目标、交付物与证据交接;Design 负责方案取舍、readiness 和方案正文模板;Develop 负责批准范围内的实施与验证;KB 负责长期知识和 `knowledge_sync`;Templates 只提供知识库文档形状 +- Copilot 单文件产物只展开 header、Skill 入口、references 和 assets。`scripts/` 只属于具备 Skill tree 的宿主;单文件使用 references 中的等价规则,不内联 Python 或暴露不可执行脚本路径 + +### 公开推广页 + +- 仓库根目录的 `index.html` 与 `zh-CN.html` 是同一静态产品页的英文和中文入口,共用 `assets/sopify-site.css` 与 `assets/sopify-site.js` +- 页面只陈述当前正式能力与宿主梯度;GitHub Pages 的发布源为 `main / root`,实际启用仍是独立发布动作 +- 首页在现有接续区说明产品形态,并以架构图作为唯一技术结构入口;Product Form 中英文 SVG 原路径保留,仅供 README 说明 Host、Skill、Assets、Handoff、Archive 五个组成,不进入首页重复展示 --- diff --git a/.sopify/plan/20260720_plain_language_output/audits/plan/audit.html b/.sopify/plan/20260720_plain_language_output/audits/plan/audit.html new file mode 100644 index 00000000..89d62517 --- /dev/null +++ b/.sopify/plan/20260720_plain_language_output/audits/plan/audit.html @@ -0,0 +1,1635 @@ + + + + + + + Sopify 代码变更审计 · EvidentLoop + + + +
+
+
+
+
EvidentLoop · 代码变更
+

Sopify 代码变更审计

+
+运行:run-c08dcb466f7d41d79030659d64e2410d · 来源:staged · schema:0.4 · 审查状态:输出完整 +
+
+
+ 当前结论 + 存在待处理问题 +
来自模型审查
+
+
+ +
+
+ 模型原判断 + 存在待处理问题 +
原风险分:28
+
+
+ 我的裁定 + 尚未写入报告 +
可在问题卡片中记录待更新裁定
+
+
+ 当前剩余问题 + 2 项 +
当前结论:存在待处理问题 · 风险分:28
+
+
+ +
+
+ 已计分风险分 + 28 + +
+
+ 待处理问题 + 2 + 待处理 +
+
+ 未计分问题 + 0 + +
+
+ 影响文件 + 50 + 已采集 +
+
+ +
+ 审查输出已完整接收 +
这只表示审查者输出满足结构契约,不代表上下文覆盖充分;请结合结论、问题与未计分项人工判断。
+
+
+ +
+
+

1. 变更摘要与审计结论

+ 变更目标:未审计 +
+

改动整体边界清楚,中英文 Skill 所有权、单文件渲染和静态页面均增加了针对性约束,但当前还不是无 finding 的交付候选:应先统一公开页面对 handoff 持久化边界的表述,并补上 Open Graph 图片真实尺寸验证。

+
+
+

Sopify 变更

+

共 50 个文件发生变更(+2941/-1655,其中 2 个二进制文件)。

+
+
+ 影响文件(50)· 查看全部 +
+
+ .nojekyll + + +1 + -0 + · 新增 +
+
+ .sopify/blueprint/README.md + + +1 + -1 + · 修改 +
+
+ .sopify/blueprint/design.md + + +13 + -4 + · 修改 +
+
+ .sopify/plan/20260720_plain_language_output/plan.md + + +145 + -0 + · 新增 +
+
+ .sopify/plan/20260720_plain_language_output/tasks.md + + +108 + -0 + · 新增 +
+
+ README.md + + +6 + -7 + · 修改 +
+
+ README.zh-CN.md + + +6 + -7 + · 修改 +
+
+ assets/sopify-architecture.svg + + +10 + -10 + · 修改 +
+
+ assets/sopify-og-en.jpg + + +0 + -0 + · 二进制 +
+
+ assets/sopify-og-zh-CN.jpg + + +0 + -0 + · 二进制 +
+
+ assets/sopify-product-form-release-en.svg + + +17 + -17 + · 修改 +
+
+ assets/sopify-product-form-release.svg + + +24 + -24 + · 修改 +
+
+ assets/sopify-site.css + + +979 + -0 + · 新增 +
+
+ assets/sopify-site.js + + +52 + -0 + · 新增 +
+
+ assets/sopify-workflow-cn.svg + + +99 + -101 + · 修改 +
+
+ assets/sopify-workflow.svg + + +99 + -102 + · 修改 +
+
+ index.html + + +274 + -0 + · 新增 +
+
+ installer/hosts/base.py + + +30 + -3 + · 修改 +
+
+ skills/en/header.md.template + + +5 + -94 + · 修改 +
+
+ skills/en/skills/sopify/analyze/SKILL.md + + +3 + -3 + · 修改 +
+
+ skills/en/skills/sopify/analyze/assets/success-output.md + + +10 + -7 + · 修改 +
+
+ skills/en/skills/sopify/analyze/references/analyze-rules.md + + +34 + -83 + · 修改 +
+
+ skills/en/skills/sopify/design/SKILL.md + + +6 + -5 + · 修改 +
+
+ skills/en/skills/sopify/design/assets/output-summary.md + + +6 + -7 + · 修改 +
+
+ skills/en/skills/sopify/design/assets/plan-template.md + + +2 + -7 + · 修改 +
+
+ skills/en/skills/sopify/design/references/design-rules.md + + +27 + -63 + · 修改 +
+
+ skills/en/skills/sopify/develop/references/develop-rules.md + + +4 + -31 + · 修改 +
+
+ skills/en/skills/sopify/kb/SKILL.md + + +37 + -138 + · 修改 +
+
+ skills/en/skills/sopify/references/output-contract.md + + +27 + -63 + · 修改 +
+
+ skills/en/skills/sopify/references/shared-writing-dna.md + + +19 + -27 + · 修改 +
+
+ skills/en/skills/sopify/templates/SKILL.md + + +62 + -160 + · 修改 +
+
+ skills/zh/header.md.template + + +5 + -94 + · 修改 +
+
+ skills/zh/skills/sopify/analyze/SKILL.md + + +3 + -3 + · 修改 +
+
+ skills/zh/skills/sopify/analyze/assets/success-output.md + + +10 + -7 + · 修改 +
+
+ skills/zh/skills/sopify/analyze/references/analyze-rules.md + + +34 + -83 + · 修改 +
+
+ skills/zh/skills/sopify/design/SKILL.md + + +6 + -5 + · 修改 +
+
+ skills/zh/skills/sopify/design/assets/output-summary.md + + +5 + -6 + · 修改 +
+
+ skills/zh/skills/sopify/design/assets/plan-template.md + + +2 + -7 + · 修改 +
+
+ skills/zh/skills/sopify/design/references/design-rules.md + + +27 + -63 + · 修改 +
+
+ skills/zh/skills/sopify/develop/references/develop-rules.md + + +4 + -31 + · 修改 +
+
+ skills/zh/skills/sopify/kb/SKILL.md + + +37 + -138 + · 修改 +
+
+ skills/zh/skills/sopify/references/output-contract.md + + +31 + -67 + · 修改 +
+
+ skills/zh/skills/sopify/references/shared-writing-dna.md + + +19 + -27 + · 修改 +
+
+ skills/zh/skills/sopify/templates/SKILL.md + + +43 + -141 + · 修改 +
+
+ tests/behavior-scenarios/plain-language-output-v1.json + + +76 + -0 + · 新增 +
+
+ tests/golden-snapshots.json + + +8 + -8 + · 修改 +
+
+ tests/test_golden_snapshots.py + + +6 + -6 + · 修改 +
+
+ tests/test_plain_language_contracts.py + + +245 + -0 + · 新增 +
+
+ tests/test_plan_contract_assets.py + + +7 + -5 + · 修改 +
+
+ zh-CN.html + + +267 + -0 + · 新增 +
+
+
+
+
+ 暂无摘要声明审计 + 未生成结构化 claim +
+
+
+
+ +
+
+

2. 风险

+ 1 条 +
+
+
+
+ + 风险 +
+ Open Graph 图片测试只验证文件存在,没有验证图片实际为声明的 `1200×630`。 + +tests/test_plain_language_contracts.py:173 +
+ 待处理 +
+
+
+
+
+为什么是问题: 测试只检查 HTML 中的宽高 metadata 和 JPG 的 `.is_file()`;任意尺寸或损坏的 JPG 都能通过,同时页面仍会发布错误的分享图尺寸声明。 +
+ +
+
+ @@ -0,0 +1,245 @@ + 可信节选 · 展示 17/245 行 · 橙色标记:新文件第 173 行 +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
旧行新行代码
… 省略 164 行可信 diff 内容 …
165+ page: str, image_name: str, canonical: str
166+) -> None:
167+ html = (REPO_ROOT / page).read_text(encoding="utf-8")
168+ assert f'<link rel="canonical" href="{canonical}"' in html
169+ assert 'hreflang="en"' in html and 'hreflang="zh-CN"' in html
170+ assert f"/assets/{image_name}" in html
171+ assert 'property="og:image:width" content="1200"' in html
172+ assert 'property="og:image:height" content="630"' in html
173+ assert (REPO_ROOT / "assets" / image_name).is_file()
174+ assert (REPO_ROOT / ".nojekyll").is_file()
175+
176+
177+@pytest.mark.parametrize(
178+ "page,readme,asset,label,required",
179+ [
180+ (
181+ "index.html",
… 省略 64 行可信 diff 内容 …
+
+
+
+ + +
+ + +
+
+ 模型原判断 + 待处理 · 低 +
+
+ 我的裁定 + +
+
+ 当前状态 + 待处理 · 低 +
+
+ + +
+
+
+
+
+
+

3. 范围

+ 1 条 +
+
+
+
+ + 范围 +
+ 公开页面声称 handoff 会随仓库携带,与本次变更明确规定的本地 handoff 边界冲突。 + +index.html:9 +
+ 待处理 +
+
+
+
+
+为什么是问题: 同一 diff 中的 README、架构图和 FAQ 都说明 handoff 指针只留在当前机器且不进入 Git,但英文页面的 description、Open Graph 文案和 Hero 仍写着 “Plans, handoffs, and evidence stay with your repo”,中文页面也重复了“方案、交接和证据跟着项目走”。用户可能因此误以为跨机器或跨队友时 handoff 本身会随仓库恢复。 +
+ +
+
+ @@ -0,0 +1,274 @@ + 可信节选 · 展示 17/274 行 · 橙色标记:新文件第 9 行 +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
旧行新行代码
1+<!doctype html>
2+<html lang="en">
3+ <head>
4+ <meta charset="utf-8" />
5+ <meta name="viewport" content="width=device-width, initial-scale=1" />
6+ <meta name="theme-color" content="#f7f3ea" />
7+ <meta
8+ name="description"
9+ content="Sopify is a resumable, traceable workflow for AI coding. Plans, handoffs, and evidence stay with your repo across tools and sessions."
10+ />
11+ <link rel="canonical" href="https://evidentloop.github.io/sopify/" />
12+ <link rel="alternate" hreflang="en" href="https://evidentloop.github.io/sopify/" />
13+ <link rel="alternate" hreflang="zh-CN" href="https://evidentloop.github.io/sopify/zh-CN.html" />
14+ <link rel="alternate" hreflang="x-default" href="https://evidentloop.github.io/sopify/" />
15+ <meta property="og:type" content="website" />
16+ <meta property="og:site_name" content="Sopify" />
17+ <meta property="og:locale" content="en_US" />
… 省略 257 行可信 diff 内容 …
+
+
+
+ + +
+ + +
+
+ 模型原判断 + 待处理 · 中 +
+
+ 我的裁定 + +
+
+ 当前状态 + 待处理 · 中 +
+
+ + +
+
+
+
+ +
+
+

把裁定交给 AI 更新报告

+

待更新内容仅保存在当前浏览器,并按 graph、run 与 finding fingerprint 隔离;点击复制前不会离开本页。

+

0 项决策 · 0 条评论 · 不自动上传

+

本地保存可用

+
+ +
+ + + +
+
+

4. 审查依据详情

+ 2 条 +
+
+ 查看全部 2 条审查依据 +
+ + + + + + + + + + + + + + + + +
证据来源状态关联
宿主语义审查结论:公开页面声称 handoff 会随仓库携带,与本次变更明确规定的本地 handoff 边界冲突。
同一 diff 中的 README、架构图和 FAQ 都说明 handoff 指针只留在当前机器且不进入 Git,但英文页面的 description、Open Graph 文案和 Hero 仍写着 “Plans, handoffs, and evidence stay with your repo”,中文页面也重复了“方案、交接和证据跟着项目走”。用户可能因此误以为跨机器或跨队友时 handoff 本身会随仓库恢复。
宿主语义审查发现问题finding-001
宿主语义审查结论:Open Graph 图片测试只验证文件存在,没有验证图片实际为声明的 `1200×630`。
测试只检查 HTML 中的宽高 metadata 和 JPG 的 `.is_file()`;任意尺寸或损坏的 JPG 都能通过,同时页面仍会发布错误的分享图尺寸声明。
宿主语义审查发现问题finding-002
+
+
+
+
+ + + diff --git a/.sopify/plan/20260720_plain_language_output/audits/plan/audit.json b/.sopify/plan/20260720_plain_language_output/audits/plan/audit.json new file mode 100644 index 00000000..266ae25c --- /dev/null +++ b/.sopify/plan/20260720_plain_language_output/audits/plan/audit.json @@ -0,0 +1,874 @@ +{ + "schema_version": "0.4", + "graph_id": "audit:run-c08dcb466f7d41d79030659d64e2410d", + "source": { + "type": "git_diff", + "ref": "staged", + "description": "Sopify 本地 Git diff 审计" + }, + "runs": [ + { + "id": "run-c08dcb466f7d41d79030659d64e2410d", + "label": "Sopify 代码变更审计", + "status": "concerns", + "summary": "改动整体边界清楚,中英文 Skill 所有权、单文件渲染和静态页面均增加了针对性约束,但当前还不是无 finding 的交付候选:应先统一公开页面对 handoff 持久化边界的表述,并补上 Open Graph 图片真实尺寸验证。", + "kind": "model_review" + } + ], + "nodes": [ + { + "id": "change-001", + "type": "change", + "title": "Sopify 变更", + "summary": "共 50 个文件发生变更(+2941/-1655,其中 2 个二进制文件)。" + }, + { + "id": "file-001", + "type": "file", + "path": ".nojekyll", + "change_type": "added", + "additions": 1, + "deletions": 0 + }, + { + "id": "file-002", + "type": "file", + "path": ".sopify/blueprint/README.md", + "change_type": "modified", + "additions": 1, + "deletions": 1 + }, + { + "id": "file-003", + "type": "file", + "path": ".sopify/blueprint/design.md", + "change_type": "modified", + "additions": 13, + "deletions": 4 + }, + { + "id": "file-004", + "type": "file", + "path": ".sopify/plan/20260720_plain_language_output/plan.md", + "change_type": "added", + "additions": 145, + "deletions": 0 + }, + { + "id": "file-005", + "type": "file", + "path": ".sopify/plan/20260720_plain_language_output/tasks.md", + "change_type": "added", + "additions": 108, + "deletions": 0 + }, + { + "id": "file-006", + "type": "file", + "path": "README.md", + "change_type": "modified", + "additions": 6, + "deletions": 7 + }, + { + "id": "file-007", + "type": "file", + "path": "README.zh-CN.md", + "change_type": "modified", + "additions": 6, + "deletions": 7 + }, + { + "id": "file-008", + "type": "file", + "path": "assets/sopify-architecture.svg", + "change_type": "modified", + "additions": 10, + "deletions": 10 + }, + { + "id": "file-009", + "type": "file", + "path": "assets/sopify-og-en.jpg", + "change_type": "binary", + "additions": 0, + "deletions": 0 + }, + { + "id": "file-010", + "type": "file", + "path": "assets/sopify-og-zh-CN.jpg", + "change_type": "binary", + "additions": 0, + "deletions": 0 + }, + { + "id": "file-011", + "type": "file", + "path": "assets/sopify-product-form-release-en.svg", + "change_type": "modified", + "additions": 17, + "deletions": 17 + }, + { + "id": "file-012", + "type": "file", + "path": "assets/sopify-product-form-release.svg", + "change_type": "modified", + "additions": 24, + "deletions": 24 + }, + { + "id": "file-013", + "type": "file", + "path": "assets/sopify-site.css", + "change_type": "added", + "additions": 979, + "deletions": 0 + }, + { + "id": "file-014", + "type": "file", + "path": "assets/sopify-site.js", + "change_type": "added", + "additions": 52, + "deletions": 0 + }, + { + "id": "file-015", + "type": "file", + "path": "assets/sopify-workflow-cn.svg", + "change_type": "modified", + "additions": 99, + "deletions": 101 + }, + { + "id": "file-016", + "type": "file", + "path": "assets/sopify-workflow.svg", + "change_type": "modified", + "additions": 99, + "deletions": 102 + }, + { + "id": "file-017", + "type": "file", + "path": "index.html", + "change_type": "added", + "additions": 274, + "deletions": 0 + }, + { + "id": "file-018", + "type": "file", + "path": "installer/hosts/base.py", + "change_type": "modified", + "additions": 30, + "deletions": 3 + }, + { + "id": "file-019", + "type": "file", + "path": "skills/en/header.md.template", + "change_type": "modified", + "additions": 5, + "deletions": 94 + }, + { + "id": "file-020", + "type": "file", + "path": "skills/en/skills/sopify/analyze/SKILL.md", + "change_type": "modified", + "additions": 3, + "deletions": 3 + }, + { + "id": "file-021", + "type": "file", + "path": "skills/en/skills/sopify/analyze/assets/success-output.md", + "change_type": "modified", + "additions": 10, + "deletions": 7 + }, + { + "id": "file-022", + "type": "file", + "path": "skills/en/skills/sopify/analyze/references/analyze-rules.md", + "change_type": "modified", + "additions": 34, + "deletions": 83 + }, + { + "id": "file-023", + "type": "file", + "path": "skills/en/skills/sopify/design/SKILL.md", + "change_type": "modified", + "additions": 6, + "deletions": 5 + }, + { + "id": "file-024", + "type": "file", + "path": "skills/en/skills/sopify/design/assets/output-summary.md", + "change_type": "modified", + "additions": 6, + "deletions": 7 + }, + { + "id": "file-025", + "type": "file", + "path": "skills/en/skills/sopify/design/assets/plan-template.md", + "change_type": "modified", + "additions": 2, + "deletions": 7 + }, + { + "id": "file-026", + "type": "file", + "path": "skills/en/skills/sopify/design/references/design-rules.md", + "change_type": "modified", + "additions": 27, + "deletions": 63 + }, + { + "id": "file-027", + "type": "file", + "path": "skills/en/skills/sopify/develop/references/develop-rules.md", + "change_type": "modified", + "additions": 4, + "deletions": 31 + }, + { + "id": "file-028", + "type": "file", + "path": "skills/en/skills/sopify/kb/SKILL.md", + "change_type": "modified", + "additions": 37, + "deletions": 138 + }, + { + "id": "file-029", + "type": "file", + "path": "skills/en/skills/sopify/references/output-contract.md", + "change_type": "modified", + "additions": 27, + "deletions": 63 + }, + { + "id": "file-030", + "type": "file", + "path": "skills/en/skills/sopify/references/shared-writing-dna.md", + "change_type": "modified", + "additions": 19, + "deletions": 27 + }, + { + "id": "file-031", + "type": "file", + "path": "skills/en/skills/sopify/templates/SKILL.md", + "change_type": "modified", + "additions": 62, + "deletions": 160 + }, + { + "id": "file-032", + "type": "file", + "path": "skills/zh/header.md.template", + "change_type": "modified", + "additions": 5, + "deletions": 94 + }, + { + "id": "file-033", + "type": "file", + "path": "skills/zh/skills/sopify/analyze/SKILL.md", + "change_type": "modified", + "additions": 3, + "deletions": 3 + }, + { + "id": "file-034", + "type": "file", + "path": "skills/zh/skills/sopify/analyze/assets/success-output.md", + "change_type": "modified", + "additions": 10, + "deletions": 7 + }, + { + "id": "file-035", + "type": "file", + "path": "skills/zh/skills/sopify/analyze/references/analyze-rules.md", + "change_type": "modified", + "additions": 34, + "deletions": 83 + }, + { + "id": "file-036", + "type": "file", + "path": "skills/zh/skills/sopify/design/SKILL.md", + "change_type": "modified", + "additions": 6, + "deletions": 5 + }, + { + "id": "file-037", + "type": "file", + "path": "skills/zh/skills/sopify/design/assets/output-summary.md", + "change_type": "modified", + "additions": 5, + "deletions": 6 + }, + { + "id": "file-038", + "type": "file", + "path": "skills/zh/skills/sopify/design/assets/plan-template.md", + "change_type": "modified", + "additions": 2, + "deletions": 7 + }, + { + "id": "file-039", + "type": "file", + "path": "skills/zh/skills/sopify/design/references/design-rules.md", + "change_type": "modified", + "additions": 27, + "deletions": 63 + }, + { + "id": "file-040", + "type": "file", + "path": "skills/zh/skills/sopify/develop/references/develop-rules.md", + "change_type": "modified", + "additions": 4, + "deletions": 31 + }, + { + "id": "file-041", + "type": "file", + "path": "skills/zh/skills/sopify/kb/SKILL.md", + "change_type": "modified", + "additions": 37, + "deletions": 138 + }, + { + "id": "file-042", + "type": "file", + "path": "skills/zh/skills/sopify/references/output-contract.md", + "change_type": "modified", + "additions": 31, + "deletions": 67 + }, + { + "id": "file-043", + "type": "file", + "path": "skills/zh/skills/sopify/references/shared-writing-dna.md", + "change_type": "modified", + "additions": 19, + "deletions": 27 + }, + { + "id": "file-044", + "type": "file", + "path": "skills/zh/skills/sopify/templates/SKILL.md", + "change_type": "modified", + "additions": 43, + "deletions": 141 + }, + { + "id": "file-045", + "type": "file", + "path": "tests/behavior-scenarios/plain-language-output-v1.json", + "change_type": "added", + "additions": 76, + "deletions": 0 + }, + { + "id": "file-046", + "type": "file", + "path": "tests/golden-snapshots.json", + "change_type": "modified", + "additions": 8, + "deletions": 8 + }, + { + "id": "file-047", + "type": "file", + "path": "tests/test_golden_snapshots.py", + "change_type": "modified", + "additions": 6, + "deletions": 6 + }, + { + "id": "file-048", + "type": "file", + "path": "tests/test_plain_language_contracts.py", + "change_type": "added", + "additions": 245, + "deletions": 0 + }, + { + "id": "file-049", + "type": "file", + "path": "tests/test_plan_contract_assets.py", + "change_type": "modified", + "additions": 7, + "deletions": 5 + }, + { + "id": "file-050", + "type": "file", + "path": "zh-CN.html", + "change_type": "added", + "additions": 267, + "deletions": 0 + }, + { + "id": "finding-001", + "type": "finding", + "category": "scope", + "severity": "medium", + "status": "open", + "title": "公开页面声称 handoff 会随仓库携带,与本次变更明确规定的本地 handoff 边界冲突。", + "detail": "同一 diff 中的 README、架构图和 FAQ 都说明 handoff 指针只留在当前机器且不进入 Git,但英文页面的 description、Open Graph 文案和 Hero 仍写着 “Plans, handoffs, and evidence stay with your repo”,中文页面也重复了“方案、交接和证据跟着项目走”。用户可能因此误以为跨机器或跨队友时 handoff 本身会随仓库恢复。", + "fingerprint": "sha256:6f3e40a0db63ea8f509392375ad126cab8816a00bdad6a761f6d917d5006c3b7", + "model_judgment": { + "status": "open", + "severity": "medium" + }, + "extensions": { + "evidentloop": { + "review_finding_id": "f-001", + "original_category": "spec_mismatch", + "confidence": "speculative" + } + }, + "file_path": "index.html", + "hunk_id": "hunk:0eb547304658805a:1:1", + "start_line": 9, + "end_line": 9, + "line_side": "new", + "highlight_lines": [ + 9 + ], + "hunk": "@@ -0,0 +1,274 @@\n+\n+\n+ \n+ \n+ \n+ \n+ \n+ \n+ \n+ \n+ \n+ \n+ \n+ \n+ \n+ \n+ \n+ \n+ \n+ \n+ \n+ \n+ Sopify — Resumable, traceable AI coding\n+ \n+ \n+ \n+ \n+ \n+ Skip to content\n+\n+
\n+ \n+
\n+\n+
\n+
\n+
\n+

Sopify / workflow protocol

\n+

Resumable, traceable AI coding

\n+

\n+ Ask before writing. Resume after approval. Plans, handoffs, and evidence stay\n+ with your repo—even when you switch AI coding tools.\n+

\n+ \n+

No new editor. No new CLI. Start with ~go in the host you already use.

\n+
\n+\n+
\n+ \n+
plan → checkpoint → handoff → resume
\n+
\n+
\n+\n+
\n+
\n+

What it prevents

\n+

Move fast without avoidable rework

\n+

Sopify keeps fast AI coding from outrunning the facts, the decision, or the project history.

\n+
\n+\n+
\n+
\n+ 01 / ASK\n+

Premature coding

\n+

When a requirement or key choice is unresolved, Sopify pauses instead of guessing.

\n+
\n+
\n+ 02 / RESUME\n+

Lost context

\n+

Plans and evidence live with the repo, so a new session, tool, machine, or teammate can continue from the same record.

\n+
\n+
\n+ 03 / TRACE\n+

Forgotten decisions

\n+

Requirements, tradeoffs, reviews, and verification evidence remain inspectable project assets.

\n+
\n+
\n+
\n+\n+
\n+
\n+

How it works

\n+

A workflow with deliberate stopping points

\n+

Simple requests stay simple. Work that needs a plan moves through four explicit stages and pauses when you need to decide.

\n+
\n+\n+
\n+
\n+ STEP 01\n+

Analyze

\n+

Clarify the outcome, evidence, and unresolved boundaries.

\n+
\n+
\n+ STEP 02\n+

Design

\n+

Choose the smallest sufficient path and make decisions visible.

\n+
\n+
\n+ STEP 03\n+

Develop

\n+

Implement the approved tasks and attach focused verification.

\n+
\n+
\n+ STEP 04\n+

Finalize

\n+

Close the plan only when delivery evidence is ready.

\n+
\n+
\n+\n+
\n+ \n+
\n+
\n+\n+
\n+
\n+
\n+

Product form

\n+

The host executes. Sopify keeps the work resumable

\n+

\n+ Sopify is a workflow protocol layer for the AI coding host you already use. It supplies shared rules and\n+ preserves plans, decisions, and verification evidence as project files in .sopify/.\n+

\n+

\n+ Ask to continue or run ~go in a supported host to resume an unfinished plan. A local handoff pointer\n+ provides a same-workspace resume hint.\n+

\n+ .sopify/plan/…\n+
    \n+
  • Codex · verified
  • \n+
  • Claude · verified
  • \n+
  • Qoder · verified
  • \n+
  • Copilot · baseline
  • \n+
\n+
\n+ \n+ \n+ Open the technical architecture →\n+ \n+
\n+
\n+\n+
\n+
\n+

Install

\n+

Add Sopify to the host you already use

\n+

The installer checks for Python 3.11 or newer before downloading. You can inspect the script before running it.

\n+
\n+\n+
\n+
\n+
\n+ \n+ Copy\n+
\n+
$ curl -fsSL https://github.com/evidentloop/sopify/releases/latest/download/install.sh | bash -s -- --target codex:en-US
\n+
\n+\n+ \n+
\n+\n+ \n+
\n+\n+
\n+
\n+

FAQ

\n+

The short version

\n+
\n+\n+
\n+
\n+ Is Sopify another editor or agent CLI?\n+

No. Sopify installs workflow instructions and project conventions into supported AI coding hosts.

\n+
\n+
\n+ Does every question start a plan?\n+

No. Ordinary questions and small fixes are handled directly. Sopify resumes an unfinished plan only when you ask to continue or use ~go.

\n+
\n+
\n+ What actually travels with the repo?\n+

Plans, decisions, and verification receipts can be tracked under .sopify/. The active-plan and handoff pointers stay gitignored by design.

\n+
\n+
\n+ Does switching hosts give every host identical capabilities?\n+

Codex, Claude, and Qoder have protocol-verified paths. Copilot currently has baseline prompt support; its payload path is more limited.

\n+
\n+
\n+ Is EvidentLoop required?\n+

No. Sopify works on its own. EvidentLoop is an optional companion for auditable reviews of local Git changes.

\n+
\n+
\n+
\n+
\n+\n+ \n+ \n+" + }, + { + "id": "evidence-001", + "type": "evidence", + "source": "host_llm", + "status": "fail", + "summary": "宿主语义审查结论:公开页面声称 handoff 会随仓库携带,与本次变更明确规定的本地 handoff 边界冲突。", + "detail": "同一 diff 中的 README、架构图和 FAQ 都说明 handoff 指针只留在当前机器且不进入 Git,但英文页面的 description、Open Graph 文案和 Hero 仍写着 “Plans, handoffs, and evidence stay with your repo”,中文页面也重复了“方案、交接和证据跟着项目走”。用户可能因此误以为跨机器或跨队友时 handoff 本身会随仓库恢复。" + }, + { + "id": "finding-002", + "type": "finding", + "category": "risk", + "severity": "low", + "status": "open", + "title": "Open Graph 图片测试只验证文件存在,没有验证图片实际为声明的 `1200×630`。", + "detail": "测试只检查 HTML 中的宽高 metadata 和 JPG 的 `.is_file()`;任意尺寸或损坏的 JPG 都能通过,同时页面仍会发布错误的分享图尺寸声明。", + "fingerprint": "sha256:11cbbb629e14adaae49701e9fc2e81ff0b29207ff32863b6d3cb1aced92fdd73", + "model_judgment": { + "status": "open", + "severity": "low" + }, + "extensions": { + "evidentloop": { + "review_finding_id": "f-002", + "original_category": "missing_validation", + "confidence": "plausible" + } + }, + "file_path": "tests/test_plain_language_contracts.py", + "hunk_id": "hunk:ece9fe95cc9ccd93:1:1", + "start_line": 173, + "end_line": 173, + "line_side": "new", + "highlight_lines": [ + 173 + ], + "hunk": "@@ -0,0 +1,245 @@\n+from __future__ import annotations\n+\n+import json\n+from pathlib import Path\n+import tempfile\n+\n+import pytest\n+\n+from installer.hosts.base import HEADER_TEMPLATE_NAME, install_host_assets, render_single_file\n+from installer.hosts.copilot import COPILOT_ADAPTER\n+from installer.hosts.qoder import QODER_ADAPTER\n+from installer.validate import validate_host_install\n+\n+\n+REPO_ROOT = Path(__file__).resolve().parents[1]\n+SCENARIOS = REPO_ROOT / \"tests\" / \"behavior-scenarios\" / \"plain-language-output-v1.json\"\n+\n+\n+def _skill_file(language: str, relative: str) -> str:\n+ return (\n+ REPO_ROOT / \"skills\" / language / \"skills\" / \"sopify\" / relative\n+ ).read_text(encoding=\"utf-8\")\n+\n+\n+def test_bilingual_skill_trees_have_the_same_files() -> None:\n+ roots = [REPO_ROOT / \"skills\" / language / \"skills\" / \"sopify\" for language in (\"zh\", \"en\")]\n+ trees = [\n+ {path.relative_to(root).as_posix() for path in root.rglob(\"*\") if path.is_file()}\n+ for root in roots\n+ ]\n+ assert trees[0] == trees[1]\n+\n+\n+def test_behavior_scenarios_are_versioned_and_bounded() -> None:\n+ payload = json.loads(SCENARIOS.read_text(encoding=\"utf-8\"))\n+ assert payload[\"schema_version\"] == 1\n+ assert len(payload[\"scenarios\"]) == 6\n+ assert len(payload[\"comparison\"]) == 6\n+ assert len(payload[\"source_revision\"]) == 40\n+\n+ required = {\n+ \"scenario_id\",\n+ \"language\",\n+ \"surface\",\n+ \"input\",\n+ \"evidence\",\n+ \"expected_behavior\",\n+ \"allowed_write_set\",\n+ }\n+ assert all(required <= scenario.keys() for scenario in payload[\"scenarios\"])\n+ readonly = [\n+ scenario\n+ for scenario in payload[\"scenarios\"]\n+ if scenario[\"surface\"] == \"host/consult_readonly\"\n+ ]\n+ assert {scenario[\"language\"] for scenario in readonly} == {\"zh-CN\", \"en-US\"}\n+ assert all(scenario[\"allowed_write_set\"] == [] for scenario in readonly)\n+ for language, locale in ((\"zh\", \"zh-CN\"), (\"en\", \"en-US\")):\n+ source_root = REPO_ROOT / \"skills\" / language\n+ rendered = render_single_file(\n+ source_root / HEADER_TEMPLATE_NAME,\n+ source_root / \"skills\" / \"sopify\",\n+ COPILOT_ADAPTER,\n+ )\n+ current = {\n+ \"characters\": len(rendered),\n+ \"bytes\": len(rendered.encode(\"utf-8\")),\n+ \"lines\": len(rendered.splitlines()),\n+ }\n+ baseline = payload[\"copilot_baseline\"][locale]\n+ observed_after = payload[\"copilot_after\"][locale]\n+ assert current.keys() == baseline.keys() == observed_after.keys()\n+ assert all(current[metric] < baseline[metric] for metric in current)\n+ assert all(observed_after[metric] < baseline[metric] for metric in observed_after)\n+\n+\n+@pytest.mark.parametrize(\"language\", [\"zh\", \"en\"])\n+def test_design_owns_plan_templates_and_uses_readiness(language: str) -> None:\n+ design_rules = _skill_file(language, \"design/references/design-rules.md\")\n+ plan_template = _skill_file(language, \"design/assets/plan-template.md\")\n+ summary = _skill_file(language, \"design/assets/output-summary.md\")\n+ templates = _skill_file(language, \"templates/SKILL.md\")\n+\n+ assert \"Ready\" in design_rules and \"Needs decision\" in design_rules\n+ assert \"`strict`\" in design_rules and \"`adaptive`\" in design_rules\n+ assert \"Ready\" in plan_template and \"Needs decision\" in plan_template\n+ assert \"Ready\" in summary and \"Needs decision\" in summary\n+ assert \"Solution quality\" not in plan_template\n+ assert \"方案质量\" not in plan_template\n+ assert \"## A2\" not in templates\n+ assert \"Protocol\" in templates\n+ assert \"plan//plan.md\" not in templates\n+\n+\n+@pytest.mark.parametrize(\"language\", [\"zh\", \"en\"])\n+def test_phase_owners_keep_their_boundaries(language: str) -> None:\n+ analyze = _skill_file(language, \"analyze/references/analyze-rules.md\")\n+ analyze_output = _skill_file(language, \"analyze/assets/success-output.md\")\n+ develop = _skill_file(language, \"develop/references/develop-rules.md\")\n+ kb = _skill_file(language, \"kb/SKILL.md\")\n+ output_contract = _skill_file(language, \"references/output-contract.md\")\n+\n+ assert \"consult_readonly\" in analyze\n+ assert \"`strict`\" in analyze and \"`adaptive`\" in analyze\n+ assert \"证据来源不限\" in analyze or \"not an exhaustive source list\" in analyze\n+ assert \"Deliverable:\" in analyze_output or \"交付物:\" in analyze_output\n+ assert \"Assumptions used\" in analyze_output or \"本次采用的假设\" in analyze_output\n+ assert \"Type:\" not in analyze_output and \"类型:\" not in analyze_output\n+ assert \"explicit assumptions when used\" in output_contract or \"实际采用的假设\" in output_contract\n+ assert \"common root cause\" in develop or \"共同根因\" in develop\n+ assert \"knowledge_sync\" in kb\n+ assert \"sopify_writer\" in kb\n+\n+\n+@pytest.mark.parametrize(\"language\", [\"zh\", \"en\"])\n+def test_copilot_single_file_has_no_script_source_or_dangling_path(language: str) -> None:\n+ source_root = REPO_ROOT / \"skills\" / language\n+ rendered = render_single_file(\n+ source_root / HEADER_TEMPLATE_NAME,\n+ source_root / \"skills\" / \"sopify\",\n+ COPILOT_ADAPTER,\n+ )\n+\n+ assert \" Sopify Architecture - File-based development protocol — no runtime, rules live in .sopify/ + File-based development protocol — no runtime; project assets live in .sopify/ @@ -47,7 +47,7 @@ Copilot - Any Host ... + Other adapters @@ -55,7 +55,7 @@ PROTOCOL KERNEL - Schema, contracts, sole write path — irreplaceable core + Schema, contracts, validated protocol writes — irreplaceable core protocol.md @@ -67,19 +67,19 @@ sopify_writer - Sole write path + Validated protocol writes receipts Post-exec evidence - - 4-STEP PROTOCOL ENTRY - 1. active_plan.json → locate plan - 2. plan.md → semantic entry point - 3. current_handoff.json → resume hint - 4. receipts/ → latest evidence + + MANAGED PLAN 4-STEP ENTRY + 1. active_plan.json → locate plan + 2. plan.md → semantic entry point + 3. current_handoff.json → resume hint + 4. receipts/ → latest evidence @@ -87,7 +87,7 @@ DEFAULT WORKFLOW - Built-in skills guide host behavior — replaceable per project + Managed plan path — three phase skills + explicit finalize action analyze @@ -102,7 +102,7 @@ - finalize + ~go finalize (action) @@ -125,15 +125,15 @@ History - Archived decisions + Archived plans + receipts - project.md - Conventions + Project + Conventions · project.md - Plans, decisions, handoffs, and receipts persist as project assets — not chat history - Same work, any host — stop, resume, and trace from .sopify/ state + Plans, decisions, and receipts persist as project assets — not chat history + Supported hosts resume from project records when asked; handoff pointers stay local diff --git a/assets/sopify-og-en.jpg b/assets/sopify-og-en.jpg new file mode 100644 index 00000000..3ef10e2b Binary files /dev/null and b/assets/sopify-og-en.jpg differ diff --git a/assets/sopify-og-zh-CN.jpg b/assets/sopify-og-zh-CN.jpg new file mode 100644 index 00000000..f7964435 Binary files /dev/null and b/assets/sopify-og-zh-CN.jpg differ diff --git a/assets/sopify-product-form-release-en.svg b/assets/sopify-product-form-release-en.svg index 35c20607..885bb288 100644 --- a/assets/sopify-product-form-release-en.svg +++ b/assets/sopify-product-form-release-en.svg @@ -32,14 +32,14 @@ Sopify Product Form - HOST ASKS · SKILL GUIDES · ASSETS PRESERVED · ANY HOST RESUMES + HOST EXECUTES · SKILL GUIDES · ASSETS PERSIST · RESUME WHEN ASKED I HOST - User asks from any host + User asks in a supported host One protocol, four entry points @@ -69,8 +69,8 @@ Same .sopify/ project - Any host can consume it - Same protocol assets + Supported hosts load the same rules + Project records stay consistent ~go · user starts the work @@ -92,7 +92,7 @@ analyze - Score first · stop for missing facts + Read evidence · score · ask if blocked @@ -107,12 +107,12 @@ kb / templates - Knowledge sync · output rules + Knowledge policy · document structure - Score first · converge first + Evidence first · converge deliberately Shared practice as workflow rules More than prompts: a method @@ -127,7 +127,7 @@ III ASSETS Assets persist in .sopify/ - Plans · decisions · handoffs · evidence + Plans · decisions · receipts · knowledge @@ -166,8 +166,8 @@ IV HANDOFF - Stop · switch host · continue - Pause for facts, resume anywhere + Stop · switch host · resume + Pause for facts, resume when asked @@ -178,7 +178,7 @@ RESUME - state → plan → handoff → receipts + Plan first · handoff is only a hint @@ -189,14 +189,14 @@ - RESUMES + FINALIZES V ARCHIVE - Archive · always auditable + Archive · inspectable evidence Plans and receipts move to history @@ -207,8 +207,8 @@ A month later or a year later - Any teammate, any host - Can follow project evolution + Teammates can inspect the record + And follow project evolution @@ -220,8 +220,8 @@ - "Host executes. Skills guide. .sopify/ preserves audit-ready assets." - Host executes · skills guide · .sopify/ keeps audit-ready assets · any host resumes · work stays traceable + "Host executes. Skills guide. .sopify/ preserves project records." + Host executes · skills guide · project records travel with Git · explicit resume · explicit finalize diff --git a/assets/sopify-product-form-release.svg b/assets/sopify-product-form-release.svg index e85132da..7ccc59f6 100644 --- a/assets/sopify-product-form-release.svg +++ b/assets/sopify-product-form-release.svg @@ -32,14 +32,14 @@ Sopify 产品形态 - HOST ASKS · SKILL GUIDES · ASSETS PRESERVED · ANY HOST RESUMES + HOST EXECUTES · SKILL GUIDES · ASSETS PERSIST · RESUME WHEN ASKED I HOST - 用户在任意宿主提需求 + 用户在受支持宿主提需求 同一协议,四个入口 @@ -69,8 +69,8 @@ 同一 .sopify/ 项目 - 任一宿主打开即消费 - 同一份协议资产 + 受支持宿主加载同一套规则 + 项目记录保持一致 ~go · 用户发出请求 @@ -86,13 +86,13 @@ II SKILL Skill 约束宿主做事 - 内置 workflow skill 沉淀社区哲学 + 内置 workflow skill 承载共享规则 analyze - 需求评分 · 缺事实则停下追问 + 先读证据 · 评分 · 必要时追问 @@ -107,14 +107,14 @@ kb / templates - 知识库回写 · 输出模板强约束 + 知识政策 · 文档结构 - 评分机制 · 收敛优先 · 证据前置 - 来自社区经验的哲学依据 - 不是 prompt,是方法论 + 证据优先 · 评分辅助 · 收敛决策 + 共享实践写成工作流规则 + 不只给提示,也约束行为 @@ -127,7 +127,7 @@ III ASSETS 过程资产沉淀 .sopify/ - 方案 · 决策 · 交接 · 验证 全部留痕 + 方案 · 决策 · 收据 · 知识按需留存 @@ -166,8 +166,8 @@ IV HANDOFF - 停下 · 换宿主 · 继续 - 缺事实时停下,换 session / host 仍接续 + 停下 · 换宿主 · 接续 + 缺事实时停车,明确要求后再接续 @@ -178,7 +178,7 @@ 能接 RESUME - state → plan → handoff → receipts + 先读 plan · handoff 只作提示 @@ -189,15 +189,15 @@ - RESUMES + FINALIZES V ARCHIVE - 归档 · 永久可审计 - 方案与证据入 history,永久可回看 + 归档 · 证据保持可检查 + 显式 finalize 后移入 history @@ -206,22 +206,22 @@ - 一个月后、一年后 - 任何人、任何宿主 - 都能看懂项目演进 + 一段时间之后 + 团队仍可检查项目记录 + 理解方案如何演进 - 审计链不是附加物 - 是项目的第二价值 + 方案与证据共同归档 + 便于后续检查 ~go finalize - "Host executes. Skill guides with community philosophy. .sopify/ preserves well-formed audit assets." - 宿主做事 · Skill 把哲学变成方法 · .sopify/ 留高质量的审计资产 · 任意宿主接续 · 永久可查 + "宿主负责执行,Skill 提供工作流规则,.sopify/ 保留项目记录。" + 宿主做事 · Skill 约束流程 · 项目记录随 Git 携带 · 明确要求后接续 · 显式收口 diff --git a/assets/sopify-site.css b/assets/sopify-site.css new file mode 100644 index 00000000..2c226e4c --- /dev/null +++ b/assets/sopify-site.css @@ -0,0 +1,979 @@ +:root { + color-scheme: light; + --paper: #f7f3ea; + --paper-deep: #efe9dc; + --surface: rgba(255, 253, 248, 0.88); + --ink: #172033; + --muted: #626b78; + --line: #d8d1c3; + --blue: #2f67d8; + --blue-soft: #e7eefc; + --green: #147a64; + --green-soft: #e2f2ec; + --violet: #7357b6; + --violet-soft: #eee8f8; + --orange: #c7652b; + --shadow: 0 22px 60px rgba(35, 42, 54, 0.11); + --radius: 24px; + --mono: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, monospace; + --sans: Inter, ui-sans-serif, -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", sans-serif; +} + +* { + box-sizing: border-box; +} + +html { + scroll-behavior: smooth; +} + +body { + min-width: 320px; + margin: 0; + color: var(--ink); + background: + linear-gradient(rgba(35, 42, 54, 0.035) 1px, transparent 1px), + linear-gradient(90deg, rgba(35, 42, 54, 0.035) 1px, transparent 1px), + var(--paper); + background-size: 32px 32px; + font-family: var(--sans); + font-kerning: normal; + line-height: 1.65; + text-rendering: optimizeLegibility; +} + +img { + display: block; + max-width: 100%; + height: auto; +} + +a { + color: inherit; +} + +button, +a { + -webkit-tap-highlight-color: transparent; +} + +:focus-visible { + outline: 3px solid rgba(47, 103, 216, 0.42); + outline-offset: 4px; +} + +.skip-link { + position: fixed; + top: 12px; + left: 12px; + z-index: 50; + padding: 10px 14px; + border-radius: 10px; + color: #fff; + background: var(--ink); + transform: translateY(-150%); +} + +.skip-link:focus { + transform: translateY(0); +} + +.site-header { + position: sticky; + top: 0; + z-index: 20; + border-bottom: 1px solid rgba(216, 209, 195, 0.84); + background: rgba(247, 243, 234, 0.88); + -webkit-backdrop-filter: blur(16px); + backdrop-filter: blur(16px); +} + +.nav, +.section, +.site-footer { + width: min(1160px, calc(100% - 40px)); + margin-inline: auto; +} + +.nav { + min-height: 72px; + display: flex; + align-items: center; + gap: 28px; +} + +.brand { + min-width: 44px; + min-height: 44px; + display: inline-flex; + align-items: center; + gap: 10px; + margin-right: auto; + font-size: 1rem; + font-weight: 760; + letter-spacing: -0.02em; + text-decoration: none; +} + +.brand img { + width: 34px; + height: 34px; + border-radius: 50%; + box-shadow: 0 4px 12px rgba(23, 32, 51, 0.16); +} + +.nav-links, +.language-switcher { + display: flex; + align-items: center; + gap: 20px; +} + +.nav-links a, +.language-switcher a { + min-height: 44px; + color: var(--muted); + font-size: 0.9rem; + font-weight: 640; + text-decoration: none; +} + +.nav-links a { + min-width: 44px; + justify-content: center; +} + +.nav-links a, +.language-switcher a { + display: inline-flex; + align-items: center; +} + +.language-switcher a { + min-width: 44px; + justify-content: center; +} + +.nav-links a:hover, +.language-switcher a:hover, +.language-switcher a[aria-current="page"] { + color: var(--ink); +} + +.language-switcher { + gap: 8px; + padding-left: 18px; + border-left: 1px solid var(--line); +} + +.language-switcher a[aria-current="page"] { + text-decoration: underline; + text-decoration-color: var(--green); + text-decoration-thickness: 2px; + text-underline-offset: 5px; +} + +.section { + padding-block: 112px; +} + +.hero { + min-height: calc(100svh - 72px); + display: grid; + grid-template-columns: minmax(0, 1fr) minmax(390px, 0.86fr); + align-items: center; + gap: clamp(44px, 7vw, 92px); + padding-block: 84px 96px; +} + +.hero-copy { + min-width: 0; +} + +.eyebrow { + display: inline-flex; + align-items: center; + gap: 9px; + margin: 0 0 18px; + color: var(--green); + font-family: var(--mono); + font-size: 0.78rem; + font-weight: 700; + letter-spacing: 0.11em; + text-transform: uppercase; +} + +.eyebrow::before { + width: 22px; + height: 2px; + background: currentColor; + content: ""; +} + +h1, +h2, +h3, +p { + margin-top: 0; +} + +h1 { + max-width: 750px; + margin-bottom: 24px; + font-size: clamp(3.1rem, 6.4vw, 6.5rem); + line-height: 0.98; + letter-spacing: -0.065em; + text-wrap: balance; +} + +[lang="zh-CN"] h1 { + font-size: clamp(2.8rem, 4.8vw, 4.65rem); + line-height: 1.08; + letter-spacing: -0.045em; +} + +.hero-lede { + max-width: 710px; + margin-bottom: 32px; + color: var(--muted); + font-size: clamp(1.06rem, 1.6vw, 1.26rem); +} + +.hero-lede strong { + display: block; + margin-bottom: 4px; + color: var(--ink); + font-weight: 720; +} + +[lang="zh-CN"] h1, +[lang="zh-CN"] h2, +[lang="zh-CN"] h3, +[lang="zh-CN"] p, +[lang="zh-CN"] summary, +[lang="zh-CN"] li { + line-break: strict; + word-break: auto-phrase; +} + +[lang="zh-CN"] p, +[lang="zh-CN"] li { + text-wrap: pretty; +} + +.hero-actions { + display: flex; + flex-wrap: wrap; + align-items: center; + gap: 12px; +} + +.button { + min-height: 48px; + display: inline-flex; + align-items: center; + justify-content: center; + gap: 9px; + padding: 11px 18px; + border: 1px solid var(--ink); + border-radius: 12px; + font-weight: 720; + text-decoration: none; + transition: transform 160ms ease, box-shadow 160ms ease, background-color 160ms ease; +} + +.button:hover { + transform: translateY(-2px); +} + +.button-primary { + color: #fff; + background: var(--ink); + box-shadow: 5px 5px 0 var(--green); +} + +.button-secondary { + border-color: var(--line); + background: rgba(255, 253, 248, 0.68); +} + +.hero-note { + margin: 22px 0 0; + color: var(--muted); + font-size: 0.86rem; +} + +.hero-note code { + color: var(--ink); + font-family: var(--mono); +} + +.hero-visual { + position: relative; + padding: 18px; + border: 1px solid var(--line); + border-radius: 30px 14px 28px 16px; + background: var(--surface); + box-shadow: var(--shadow); + transform: rotate(1.2deg); +} + +.hero-visual::before, +.hero-visual::after { + position: absolute; + z-index: 2; + width: 82px; + height: 24px; + background: rgba(223, 205, 142, 0.5); + content: ""; +} + +.hero-visual::before { + top: -10px; + left: 18%; + transform: rotate(-4deg); +} + +.hero-visual::after { + right: 12%; + bottom: -9px; + transform: rotate(3deg); +} + +.hero-visual img { + width: 100%; + border-radius: 18px 8px 16px 10px; +} + +.hero-visual figcaption { + margin-top: 12px; + color: var(--muted); + font-family: var(--mono); + font-size: 0.72rem; +} + +.section-rule { + border-top: 1px solid var(--line); +} + +.section-heading { + max-width: 760px; + margin-bottom: 52px; +} + +.section-heading h2 { + margin-bottom: 16px; + font-size: clamp(2.1rem, 3.8vw, 3.8rem); + line-height: 1.08; + letter-spacing: -0.045em; + text-wrap: balance; +} + +.section-heading p { + max-width: 760px; + margin-bottom: 0; + color: var(--muted); + font-size: 1.05rem; +} + +[lang="zh-CN"] .section-heading { + max-width: 940px; +} + +[lang="zh-CN"] .section-heading h2, +[lang="zh-CN"] .resume-copy h2 { + font-size: clamp(2rem, 3.5vw, 3.65rem); + line-height: 1.12; + letter-spacing: -0.035em; +} + +.keep-together { + white-space: nowrap; +} + +.card-grid { + display: grid; + grid-template-columns: repeat(3, minmax(0, 1fr)); + gap: 18px; +} + +.card { + position: relative; + min-height: 250px; + padding: 28px; + overflow: hidden; + border: 1px solid var(--line); + border-radius: var(--radius); + background: var(--surface); +} + +.card::after { + position: absolute; + right: -24px; + bottom: -24px; + width: 96px; + height: 96px; + border-radius: 50%; + background: var(--accent-soft, var(--blue-soft)); + content: ""; +} + +.card:nth-child(2) { + --accent-soft: var(--green-soft); +} + +.card:nth-child(3) { + --accent-soft: var(--violet-soft); +} + +.card-index { + display: block; + margin-bottom: 54px; + color: var(--accent, var(--blue)); + font-family: var(--mono); + font-size: 0.76rem; + font-weight: 700; +} + +.card:nth-child(2) .card-index { + color: var(--green); +} + +.card:nth-child(3) .card-index { + color: var(--violet); +} + +.card h3 { + margin-bottom: 10px; + font-size: 1.35rem; + letter-spacing: -0.025em; +} + +.card p { + margin: 0; + color: var(--muted); +} + +.steps { + display: grid; + grid-template-columns: repeat(4, minmax(0, 1fr)); + gap: 10px; + margin-bottom: 34px; +} + +.step { + position: relative; + min-height: 180px; + padding: 24px 22px; + border: 1px solid var(--line); + border-radius: 18px; + background: rgba(255, 253, 248, 0.68); +} + +.step:not(:last-child)::after { + position: absolute; + top: 28px; + right: -9px; + z-index: 2; + width: 16px; + color: var(--orange); + background: var(--paper); + font-family: var(--mono); + font-weight: 800; + text-align: center; + content: "→"; +} + +.step-number { + display: block; + margin-bottom: 28px; + color: var(--muted); + font-family: var(--mono); + font-size: 0.72rem; +} + +.step h3 { + margin-bottom: 8px; + font-size: 1.08rem; +} + +.step p { + margin: 0; + color: var(--muted); + font-size: 0.91rem; +} + +.diagram-frame { + padding: clamp(12px, 2vw, 24px); + border: 1px solid var(--line); + border-radius: var(--radius); + background: #fff; + box-shadow: 0 16px 42px rgba(35, 42, 54, 0.08); +} + +.diagram-frame img { + width: 100%; +} + +.architecture-preview { + display: block; + color: var(--ink); + text-decoration: none; +} + +.preview-link { + display: inline-flex; + min-height: 44px; + align-items: center; + margin: 12px 4px 0; + color: var(--blue); + font-size: 0.88rem; + font-weight: 720; +} + +.resume-layout { + display: grid; + grid-template-columns: minmax(290px, 0.72fr) minmax(0, 1.28fr); + align-items: center; + gap: clamp(40px, 7vw, 84px); +} + +.resume-copy h2 { + margin-bottom: 18px; + font-size: clamp(2.1rem, 3.2vw, 3.2rem); + line-height: 1.08; + letter-spacing: -0.045em; + text-wrap: balance; +} + +.resume-copy > p { + color: var(--muted); +} + +.repo-path { + display: inline-flex; + margin: 8px 0 22px; + padding: 8px 12px; + border: 1px solid rgba(47, 103, 216, 0.24); + border-radius: 9px; + color: var(--blue); + background: var(--blue-soft); + font-family: var(--mono); + font-size: 0.85rem; +} + +.host-list { + display: flex; + flex-wrap: wrap; + gap: 8px; + margin: 0; + padding: 0; + list-style: none; +} + +.host-list li { + padding: 7px 10px; + border: 1px solid var(--line); + border-radius: 999px; + background: rgba(255, 253, 248, 0.74); + font-family: var(--mono); + font-size: 0.75rem; +} + +.host-list .baseline { + color: var(--muted); + border-style: dashed; +} + +.install-panel { + display: grid; + grid-template-columns: minmax(0, 1.3fr) minmax(260px, 0.7fr); + gap: 22px; + align-items: stretch; +} + +.terminal { + position: relative; + min-width: 0; + padding: 20px; + border-radius: var(--radius); + color: #e8edf8; + background: #172033; + box-shadow: var(--shadow); +} + +.terminal-bar { + display: flex; + align-items: center; + justify-content: space-between; + gap: 16px; + margin-bottom: 22px; +} + +.terminal-dots { + display: inline-flex; + gap: 6px; +} + +.terminal-dots span { + width: 9px; + height: 9px; + border-radius: 50%; + background: #e98a65; +} + +.terminal-dots span:nth-child(2) { + background: #e6bc5c; +} + +.terminal-dots span:nth-child(3) { + background: #62b78d; +} + +.copy-button { + min-height: 44px; + min-width: 72px; + padding: 7px 10px; + border: 1px solid rgba(255, 255, 255, 0.2); + border-radius: 8px; + color: #fff; + background: rgba(255, 255, 255, 0.08); + font: 650 0.76rem var(--sans); + cursor: pointer; +} + +.copy-button:hover { + background: rgba(255, 255, 255, 0.15); +} + +.command { + display: block; + overflow-x: auto; + color: #d9e4ff; + font: 0.9rem/1.75 var(--mono); + white-space: pre-wrap; + overflow-wrap: anywhere; +} + +.prompt { + color: #6bd3aa; +} + +.install-note { + padding: 26px; + border: 1px solid var(--line); + border-radius: var(--radius); + background: var(--surface); +} + +.install-note h3 { + margin-bottom: 12px; +} + +.install-note ul { + margin: 0 0 20px; + padding-left: 20px; + color: var(--muted); +} + +.install-trust { + margin: 0 0 16px; + color: var(--ink); + font-size: 0.92rem; +} + +.install-links { + display: flex; + flex-wrap: wrap; + gap: 8px 18px; +} + +.install-links .text-link { + min-height: 44px; + display: inline-flex; + align-items: center; +} + +.text-link { + color: var(--blue); + font-weight: 700; + text-underline-offset: 4px; +} + +.companion { + display: grid; + grid-template-columns: auto minmax(0, 1fr) auto; + align-items: center; + gap: 18px; + margin-top: 28px; + padding: 22px 24px; + border: 1px dashed rgba(115, 87, 182, 0.55); + border-radius: 18px; + background: rgba(238, 232, 248, 0.5); +} + +.companion-mark { + display: grid; + width: 42px; + height: 42px; + place-items: center; + border-radius: 12px; + color: var(--violet); + background: var(--violet-soft); + font-family: var(--mono); + font-weight: 800; +} + +.companion h3, +.companion p { + margin: 0; +} + +.companion p { + color: var(--muted); + font-size: 0.92rem; +} + +.companion .text-link { + min-height: 44px; + display: inline-flex; + align-items: center; +} + +.faq-list { + max-width: 880px; + border-top: 1px solid var(--line); +} + +.faq-list details { + border-bottom: 1px solid var(--line); +} + +.faq-list summary { + position: relative; + padding: 24px 42px 24px 0; + font-weight: 730; + cursor: pointer; + list-style: none; +} + +.faq-list summary::-webkit-details-marker { + display: none; +} + +.faq-list summary::after { + position: absolute; + top: 22px; + right: 8px; + color: var(--green); + font-family: var(--mono); + font-size: 1.2rem; + content: "+"; +} + +.faq-list details[open] summary::after { + content: "−"; +} + +.faq-list details p { + max-width: 720px; + padding: 0 0 24px; + color: var(--muted); +} + +.site-footer { + display: flex; + align-items: center; + justify-content: space-between; + gap: 24px; + padding-block: 36px; + border-top: 1px solid var(--line); + color: var(--muted); + font-size: 0.86rem; +} + +.footer-links { + display: flex; + flex-wrap: wrap; + gap: 18px; +} + +.footer-links a { + text-underline-offset: 4px; +} + +.visually-hidden { + position: absolute !important; + width: 1px !important; + height: 1px !important; + padding: 0 !important; + margin: -1px !important; + overflow: hidden !important; + clip: rect(0, 0, 0, 0) !important; + white-space: nowrap !important; + border: 0 !important; +} + +@media (max-width: 1080px) { + .steps { + grid-template-columns: repeat(2, 1fr); + } + + .step:nth-child(2)::after { + display: none; + } +} + +@media (max-width: 900px) { + .nav-links { + display: none; + } + + .hero, + .resume-layout, + .install-panel { + grid-template-columns: 1fr; + } + + .hero { + min-height: auto; + padding-top: 72px; + } + + .hero-copy { + max-width: 760px; + } + + .hero-visual { + width: min(650px, 92%); + margin-inline: auto; + } + + .card-grid { + grid-template-columns: 1fr; + } + + .card { + min-height: 210px; + } + + .card-index { + margin-bottom: 32px; + } + +} + +@media (max-width: 620px) { + .nav, + .section, + .site-footer { + width: min(100% - 28px, 1160px); + } + + .nav { + min-height: 64px; + gap: 12px; + } + + .brand span { + display: none; + } + + .language-switcher { + padding-left: 12px; + } + + .section { + padding-block: 78px; + } + + .hero { + padding-block: 60px 72px; + } + + h1 { + font-size: clamp(2.75rem, 14vw, 4.15rem); + } + + [lang="zh-CN"] h1 { + font-size: clamp(2.55rem, 12vw, 3.5rem); + } + + .keep-together { + white-space: normal; + } + + [lang="zh-CN"] .section-heading h2, + [lang="zh-CN"] .resume-copy h2 { + font-size: clamp(2rem, 8.8vw, 2.6rem); + } + + .hero-actions { + align-items: stretch; + flex-direction: column; + } + + .button { + width: 100%; + } + + .hero-visual { + width: 100%; + padding: 10px; + border-radius: 20px 10px; + transform: none; + } + + .section-heading { + margin-bottom: 34px; + } + + .steps { + grid-template-columns: 1fr; + } + + .step:not(:last-child)::after { + top: auto; + right: 22px; + bottom: -13px; + transform: rotate(90deg); + } + + .step:nth-child(2)::after { + display: block; + } + + .terminal { + padding: 16px; + } + + .command { + font-size: 0.8rem; + } + + .companion { + grid-template-columns: auto 1fr; + } + + .companion .text-link { + grid-column: 1 / -1; + } + + .site-footer { + align-items: flex-start; + flex-direction: column; + } +} + +@media (prefers-reduced-motion: reduce) { + html { + scroll-behavior: auto; + } + + *, + *::before, + *::after { + scroll-behavior: auto !important; + transition-duration: 0.01ms !important; + } +} diff --git a/assets/sopify-site.js b/assets/sopify-site.js new file mode 100644 index 00000000..6f3247e8 --- /dev/null +++ b/assets/sopify-site.js @@ -0,0 +1,52 @@ +(function () { + "use strict"; + + async function copyText(text) { + if (navigator.clipboard && window.isSecureContext) { + try { + await navigator.clipboard.writeText(text); + return; + } catch (error) { + // Permission may be denied even when the API exists; use the local fallback. + } + } + + const textarea = document.createElement("textarea"); + textarea.value = text; + textarea.setAttribute("readonly", ""); + textarea.style.position = "fixed"; + textarea.style.opacity = "0"; + document.body.appendChild(textarea); + textarea.select(); + const copied = document.execCommand("copy"); + textarea.remove(); + + if (!copied) { + throw new Error("Copy command was not available"); + } + } + + document.querySelectorAll("[data-copy-target]").forEach(function (button) { + const defaultLabel = button.textContent.trim(); + const successLabel = button.getAttribute("data-copy-success") || "Copied"; + const errorLabel = button.getAttribute("data-copy-error") || "Select command"; + + button.addEventListener("click", async function () { + const target = document.getElementById(button.getAttribute("data-copy-target")); + if (!target) { + return; + } + + try { + await copyText(target.textContent.trim()); + button.textContent = successLabel; + } catch (error) { + button.textContent = errorLabel; + } + + window.setTimeout(function () { + button.textContent = defaultLabel; + }, 1800); + }); + }); +})(); diff --git a/assets/sopify-workflow-cn.svg b/assets/sopify-workflow-cn.svg index 8fd79cee..4b0a205c 100644 --- a/assets/sopify-workflow-cn.svg +++ b/assets/sopify-workflow-cn.svg @@ -1,101 +1,99 @@ - - - - - - - - - -Sopify — 工作流与检查点 -(Evidence-driven · Checkpoint-based) - -用户输入 - -协议入口 - -路由 - -咨询 / 问答 - -代码任务 - -复杂度 - -快速修复 - -轻量迭代 - -完整三阶段流程 - -需求分析 - -方案设计 - -实现 -↓ 检查点详情 - -输出 + 交接 - -.sopify/state/ - - - - - - - - - - - - - - - - -检查点详情 — 完整三阶段流程 - -需求分析 - - -缺少 -事实? - -No - -方案设计 - - -设计 -分支? - -No - -实现 - -Yes - -Yes - -answer_questions - -confirm_decision - -恢复 - -恢复 - -核心规则: -缺少事实 → 停下来问(不猜测)· 设计分支 → 暂停等待确认 - -图例 - -协议 - -汇聚 - -检查点 - \ No newline at end of file + + Sopify 请求路由与托管任务恢复流程 + 只读咨询给出结论和证据后停车,快速修复保持局部,托管方案经过分析、设计、开发和收口,并从项目证据恢复。 + + + + + + + + + + 一个请求,匹配刚刚好的工作流 + Sopify 按当前请求路由,不被旧方案状态带偏。 + + + + + + + + + 你的当前请求 + + + 按当前请求路由,不被旧方案状态带偏 + + + 直接请求 · 只读 + 咨询 / 查看 + 给出结论和证据,然后停车。 + + 不写方案 · state · Git index + + + 局部修改 + 快速修复 + 修改 → 聚焦验证 → 报告 + + 不自动接续旧方案 + + + 托管任务 + 新建或继续方案 + + + + + + 分析 + 设计 + 开发 + 收口 + + + 缺事实或待决策时先停车 + + + 托管任务恢复链 · 仅继续 / 收口时读取 + + + + + + active_plan + 可选本地指针 + plan.md + 语义真相 + current_handoff + 可选恢复提示 + receipts/ + 已验证证据 + + + + + 方案与收据纳入 Git;state 指针仅在本地,缺失也可恢复。 + diff --git a/assets/sopify-workflow.svg b/assets/sopify-workflow.svg index ab2608b5..2f16002d 100644 --- a/assets/sopify-workflow.svg +++ b/assets/sopify-workflow.svg @@ -1,102 +1,99 @@ - - - - - - - - - -Sopify — Workflow & Checkpoints -(Evidence-driven task lifecycle · Checkpoint-based execution) - -User Input - -Protocol Entry - -Route - -Consult / Q&A - -Code Task - -Complexity - -Quick Fix - -Light Iteration - -Full Three-Phase Flow - -Requirements - -Solution Design - -Implementation -↓ Checkpoint detail - -Output + Handoff - -.sopify/state/ - - - - - - - - - - - - - - - - -Checkpoint Detail — Full Three-Phase Flow - -Requirements -Analysis - - -Missing -facts? - -No - -Solution Design - - -Design -branch? - -No - -Implementation - -Yes - -Yes - -answer_questions - -confirm_decision - -resume - -resume - -Core Rule: -Missing facts → stop and ask (never guess) · Design branch → pause for confirmation - -Legend - -Protocol - -Converge - -Checkpoint - \ No newline at end of file + + Sopify request routing and managed resume workflow + Direct read-only questions stop after an evidence-based answer. Quick fixes stay scoped. Managed plans pass through analyze, design, develop, and finalize, and resume from repository evidence. + + + + + + + + + + One request. The right amount of workflow + Sopify routes by what you ask now—not by stale task state. + + + + + + + + + Your request + + + Route by the request — not by stale plan state + + + DIRECT · READ ONLY + Consult / inspect + Answer with evidence, then stop. + + No plan · no state · no Git index + + + SCOPED CHANGE + Quick Fix + Change → focused verify → report + + Does not resume an old plan + + + MANAGED WORK + Plan or continue + + + + + + Analyze + Design + Develop + Finalize + + + Pauses for missing facts or decisions + + + MANAGED RESUME · CONTINUE / FINALIZE ONLY + + + + + + active_plan + optional local pointer + plan.md + semantic truth + current_handoff + optional resume hint + receipts/ + verified evidence + + + + + Plans and receipts are Git tracked. State pointers are local and may be absent. + diff --git a/index.html b/index.html new file mode 100644 index 00000000..d30e065b --- /dev/null +++ b/index.html @@ -0,0 +1,274 @@ + + + + + + + + + + + + + + + + + + + + + + + Sopify — Resumable, traceable AI coding + + + + + + + + + +
+
+
+

Sopify / workflow protocol

+

Resumable, traceable AI coding

+

+ Ask before writing. Resume after approval. Plans, decisions, and verification evidence stay + with your repo—even when you switch AI coding tools. +

+ +

No new editor. No new CLI. Start with ~go in the host you already use.

+
+ +
+ Hand-drawn Sopify workspace showing an AI workflow that pauses, records a plan, and resumes +
plan → checkpoint → handoff → resume
+
+
+ +
+
+

What it prevents

+

Move fast without avoidable rework

+

Sopify keeps fast AI coding from outrunning the facts, the decision, or the project history.

+
+ +
+
+ 01 / ASK +

Premature coding

+

When a requirement or key choice is unresolved, Sopify pauses instead of guessing.

+
+
+ 02 / RESUME +

Lost context

+

Plans and evidence live with the repo, so a new session, tool, machine, or teammate can continue from the same record.

+
+
+ 03 / TRACE +

Forgotten decisions

+

Requirements, tradeoffs, reviews, and verification evidence remain inspectable project assets.

+
+
+
+ +
+
+

How it works

+

A workflow with deliberate stopping points

+

Simple requests stay simple. Work that needs a plan moves through four explicit stages and pauses when you need to decide.

+
+ +
+
+ STEP 01 +

Analyze

+

Clarify the outcome, evidence, and unresolved boundaries.

+
+
+ STEP 02 +

Design

+

Choose the smallest sufficient path and make decisions visible.

+
+
+ STEP 03 +

Develop

+

Implement the approved tasks and attach focused verification.

+
+
+ STEP 04 +

Finalize

+

Close the plan only when delivery evidence is ready.

+
+
+ +
+ Sopify workflow showing direct requests, managed plans, checkpoints, and finalization +
+
+ +
+
+
+

Product form

+

The host executes. Sopify keeps the work resumable

+

+ Sopify is a workflow protocol layer for the AI coding host you already use. It supplies shared rules and + preserves plans, decisions, and verification evidence as project files in .sopify/. +

+

+ Ask to continue or run ~go in a supported host to resume an unfinished plan. A local handoff pointer + provides a same-workspace resume hint. +

+ .sopify/plan/… +
    +
  • Codex · verified
  • +
  • Claude · verified
  • +
  • Qoder · verified
  • +
  • Copilot · baseline
  • +
+
+ + Sopify architecture showing host adapters, shared workflow skills, writer boundaries, and repository state + Open the technical architecture → + +
+
+ +
+
+

Install

+

Add Sopify to the host you already use

+

The installer checks for Python 3.11 or newer before downloading. You can inspect the script before running it.

+
+ +
+
+
+ + +
+
curl -fsSL https://github.com/evidentloop/sopify/releases/latest/download/install.sh | bash -s -- --target codex:en-US
+
+ + +
+ + +
+ +
+
+

FAQ

+

The short version

+
+ +
+
+ Is Sopify another editor or agent CLI? +

No. Sopify installs workflow instructions and project conventions into supported AI coding hosts.

+
+
+ Does every question start a plan? +

No. Ordinary questions and small fixes are handled directly. Sopify resumes an unfinished plan only when you ask to continue or use ~go.

+
+
+ What actually travels with the repo? +

Plans, decisions, and verification receipts can be tracked under .sopify/. The active-plan and handoff pointers stay gitignored by design.

+
+
+ Does switching hosts give every host identical capabilities? +

Codex, Claude, and Qoder have protocol-verified paths. Copilot currently has baseline prompt support; its payload path is more limited.

+
+
+ Is EvidentLoop required? +

No. Sopify works on its own. EvidentLoop is an optional companion for auditable reviews of local Git changes.

+
+
+
+
+ + + + diff --git a/installer/hosts/base.py b/installer/hosts/base.py index eea23dc1..c6c8b341 100644 --- a/installer/hosts/base.py +++ b/installer/hosts/base.py @@ -257,6 +257,30 @@ def _install_single_file_assets( _TEXT_SUFFIXES = {".md", ".py", ".yaml", ".yml", ".txt", ".json", ".toml"} _SKILL_DIRS_ORDER = ("analyze", "design", "develop", "kb", "templates") +_SINGLE_FILE_SCRIPT_HEADINGS = { + "## 确定性逻辑(脚本优先)", + "## Deterministic logic first", +} + + +def _render_single_file_skill_entry(content: str) -> str: + """Remove tree-only script navigation from a flattened skill entry.""" + rendered: list[str] = [] + skipping_script_section = False + for line in content.splitlines(): + if line in _SINGLE_FILE_SCRIPT_HEADINGS: + skipping_script_section = True + continue + if skipping_script_section: + if line.startswith("## "): + skipping_script_section = False + else: + continue + if "`scripts/" in line: + continue + line = line.replace("references/assets/scripts", "references/assets") + rendered.append(line) + return "\n".join(rendered).rstrip("\n") def render_single_file( @@ -294,10 +318,13 @@ def render_single_file( skill_md = skill_dir / "SKILL.md" if not skill_md.is_file(): continue - skill_content = skill_md.read_text(encoding="utf-8").rstrip("\n") + skill_content = _render_single_file_skill_entry( + skill_md.read_text(encoding="utf-8") + ) parts.append(skill_content) - # Inline text assets from references/, assets/, scripts/ - for subdir_name in ("references", "assets", "scripts"): + # Scripts are tree-only executable helpers. The flattened product keeps + # the equivalent rules from references/ and the user-facing assets. + for subdir_name in ("references", "assets"): subdir = skill_dir / subdir_name if not subdir.is_dir(): continue diff --git a/skills/en/header.md.template b/skills/en/header.md.template index 1e7839a8..35e53739 100644 --- a/skills/en/header.md.template +++ b/skills/en/header.md.template @@ -1,5 +1,5 @@ - + # Sopify - Adaptive AI Programming Assistant @@ -90,6 +90,7 @@ Next: {Next step hint} - Detailed content in files - Avoid redundant descriptions - The title line can be lightly colored via `title_color` (title line only); fallback to plain text when color is unsupported +- `consult_readonly` gives the conclusion and necessary evidence, includes blockers or decisions only when they exist, then stops. It writes no code, plan, state, knowledge base, audit, receipt, or Git index. ### C3 | Workflow Modes @@ -244,99 +245,9 @@ progressive: Create files as needed (default) --- -## Phase Execution +## Phase Routing -### P1 | Requirements Analysis - -**Goal:** Verify requirement completeness, analyze code status - -**Execution Flow:** -``` -1. Check knowledge base status -2. Acquire project context -3. Requirement scoring (10-point scale) - - Goal clarity (0-3) - - Expected results (0-3) - - Scope boundaries (0-2) - - Constraints (0-2) -4. Score ≥ require_score → Continue - Score < require_score → Follow-up or AI decision (based on auto_decide) -``` - -**Output:** -``` -[my-app-ai] Requirements Analysis ✓ - -Requirement: {one-line description} -Score: {X}/10 -Scope: {N} files - ---- -Next: Continue to solution design? (Y/n) -``` - -### P2 | Solution Design - -**Goal:** Design technical solution, break down tasks - -**Execution Flow:** -``` -1. Read design Skill -2. Determine plan package level (light/standard/architecture) -3. Generate plan files -4. Output summary -``` - -**Output:** -``` -[my-app-ai] Solution Design ✓ - -Plan: .sopify/plan/20260115_feature/ -Summary: {one-line technical solution} -Tasks: {N} items -Solution quality: {X}/10 -Implementation readiness: {Y}/10 -Scoring rationale: {1 line} - ---- -Changes: 3 files - - .sopify/plan/20260115_feature/plan.md - - .sopify/plan/20260115_feature/tasks.md - - .sopify/plan/20260115_feature/design.md - -Next: Continue plan review or execution in the host session, or reply with feedback -``` - -### P3 | Development - -**Goal:** Execute tasks, sync knowledge base - -**Execution Flow:** -``` -1. Read develop Skill -2. Execute in tasks.md order -3. Update knowledge base -4. Mark the plan ready_to_archive and keep it in plan/ -5. Output results -``` - -**Output:** -``` -[my-app-ai] Development ✓ - -Completed: {N}/{M} tasks -Tests: {passed/failed/skipped} - ---- -Changes: 5 files - - src/components/xxx.vue - - src/types/index.ts - - src/hooks/useXxx.ts - - .sopify/blueprint/design.md - - .sopify/plan/20260115_feature/plan.md - -Next: Please verify the functionality; run ~go finalize explicitly when the plan should be archived -``` +The host selects the current entry and loads the matching skill. Phase decisions, output shape, and resource navigation come from that skill. The header keeps routing, protocol, authorization, and the shared footer contract without duplicating phase procedures or templates. --- @@ -348,9 +259,9 @@ Next: Please verify the functionality; run ~go finalize explicitly when the plan | `design` | Enter solution design | Plan generation, task breakdown | | `develop` | Enter development | Code execution, KB sync | | `kb` | Knowledge base operations | Init, update strategies | -| `templates` | Create documents | All template definitions | +| `templates` | Create KB documents | Knowledge-base templates and navigation | -**Loading:** The above are all current builtin skills — workflow skills consumed as prompt/skill assets by the host. Standalone invocation is not supported. The authoritative skill catalog is `skills/catalog/builtin_catalog.generated.json`. +**Loading:** These are the current builtin skills consumed by the host. The host may also route a request directly to one skill. They share Sopify's protocol and writing boundaries; they are not five standalone products. The authoritative skill catalog is `skills/catalog/builtin_catalog.generated.json`. --- diff --git a/skills/en/skills/sopify/analyze/SKILL.md b/skills/en/skills/sopify/analyze/SKILL.md index 52a89f44..d46db9f1 100644 --- a/skills/en/skills/sopify/analyze/SKILL.md +++ b/skills/en/skills/sopify/analyze/SKILL.md @@ -5,7 +5,7 @@ description: Analyze phase entry. Aggregates scoring, follow-up, and scope-check # Analyze (Entry) -> Core philosophy: Distinguish the user's "goal" from their "implementation path" — only commit to the goal. +> Read the evidence first, then separate the objective, deliverable, and candidate path. ## When to activate @@ -15,11 +15,11 @@ description: Analyze phase entry. Aggregates scoring, follow-up, and scope-check ## Execution skeleton 1. Load `references/analyze-rules.md` first. -2. Run Phase A (KB check, context acquisition, requirement typing, completeness scoring). +2. Read user-supplied material and relevant code, separate the objective, deliverable, and candidate path, then score completeness. 3. If the score is below threshold, follow `auto_decide`: - `false`: ask follow-up questions with `assets/question-output.md`. - `true`: state explicit assumptions, then continue. -4. After the score passes, run Phase B (objective extraction, code analysis, technical prep). +4. After the score passes, hand off confirmed success criteria, scope, evidence, and unknowns that could still affect the result. 5. Render the phase summary with `assets/success-output.md`. ## Resource navigation diff --git a/skills/en/skills/sopify/analyze/assets/success-output.md b/skills/en/skills/sopify/analyze/assets/success-output.md index 2a1f8776..365aada3 100644 --- a/skills/en/skills/sopify/analyze/assets/success-output.md +++ b/skills/en/skills/sopify/analyze/assets/success-output.md @@ -1,19 +1,22 @@ [{BRAND_NAME}] Requirements Analysis ✓ -Requirement: {one-line description} -Type: {requirement type} +Objective: {one-line description} +Deliverable: {current deliverable} Score: {X}/10 Scope: {estimated file count} -Assumptions: - - {assumption} (source: {code analysis / user input / AI supplement}) +Confirmed evidence: + - {evidence} (source: {user material / code / governing contract}) -Identified gaps: +Assumptions used to continue (omit when none): + - {assumption} (safe to proceed because: {low-risk and reversible basis}) + +Material gaps (omit when none): - {gap} (impact: {impact}, recommendation: {action}) -Next step rationale: {why proceed to design / need follow-up / can execute directly} +Next step rationale: {why proceed to Design / ask a follow-up / handle as a quick fix or consult} --- Changes: 0 files -Next: Continue to solution design? (Y/n) +Next: {next action} diff --git a/skills/en/skills/sopify/analyze/references/analyze-rules.md b/skills/en/skills/sopify/analyze/references/analyze-rules.md index 17de5da0..da8d6831 100644 --- a/skills/en/skills/sopify/analyze/references/analyze-rules.md +++ b/skills/en/skills/sopify/analyze/references/analyze-rules.md @@ -1,104 +1,55 @@ -# Analyze Detailed Rules +# Analyze Rules ## Goal -Verify requirement completeness, analyze the current codebase, and provide stable input for downstream design. +Turn the request and accessible evidence into a stable objective, deliverable, and boundary for host routing or Design. Analyze decides what must be solved; it does not choose the implementation. -## Overall flow +## 1. Read evidence first -```text -Phase A (steps 1-4) -> check score >= require_score? - ├─ yes -> Phase B (steps 5-6) -> render summary - └─ no -> check auto_decide - ├─ true -> continue with explicit assumptions - └─ false -> ask follow-up questions and wait for user input -``` +1. Read the current request, material and links the user supplied, and confirmed long-term preferences. +2. As the task requires, read relevant evidence supplied by the user or available in the current environment, such as documents, API material, designs, code, tests, previous plans, and governing protocols. These examples are not an exhaustive source list. Do not ask for an answer already present in accessible evidence. +3. Separate the desired outcome, the deliverable for this task, and any suggested implementation path. A suggested path becomes a boundary only when the user states it as one. +4. When sources conflict, state the conflict, its effect on this delivery, and a recommendation. Do not block on differences that cannot change the result. -## Phase A: Requirement assessment +The `kb` skill owns knowledge-base loading and materialization. Analyze consumes only the context relevant to the current objective. -### Step 1: Check knowledge-base status +## 2. Assess completeness -- Condition: project code exists and the task is not "new project bootstrap". -- Action: check whether `.sopify/` exists. -- Mark the KB as missing when the directory does not exist. +The score totals 10 points: goal clarity 0–3, expected outcome 0–3, scope boundary 0–2, and constraints 0–2. -### Step 2: Acquire project context +- `score >= require_score`: continue and prepare the handoff. +- Below the threshold with `auto_decide=true`: make only explicit assumptions that are low-risk, reversible, and do not change the objective. +- Below the threshold with `auto_decide=false`: stop and ask. -- Read `.sopify/user/preferences.md` and KB files first. -- Scan the codebase only when KB context is insufficient. -- Follow the `kb` skill for KB-specific rules. +Ask only when the answer can change the objective, deliverable, scope, success criteria, or whether the current path is safe to execute. Explain the impact of each question. Let the evidence determine the number of questions. -Preference rules: +## 3. Prepare the handoff -1. Use only explicit long-term user preferences. -2. Current-task instructions override historical preferences. -3. Fall back to defaults when no preference matches. +Analyze returns: -### Step 3: Determine requirement type +- A one-sentence objective and the current deliverable. +- Confirmed success criteria, scope, and constraints. +- The key material or code evidence behind the conclusion. +- Unknowns that can still change the result; omit this section when there are none. +- The reason to continue as a consult, quick fix, or Design task. -Candidate types: +If the suggested path clearly adds cost or risk, Analyze may identify a safer direction and its tradeoff. Design still owns the technical choice. -1. New project bootstrap -2. New feature development -3. Feature modification / enhancement -4. Bug fix -5. Refactor / optimization -6. Technical change +## 4. Routing signal -### Step 4: Score requirement completeness +- Clear, simple work, usually no more than 2 files: quick fix may be enough. +- Local work that needs a plan, usually 3–5 files: light plan. +- More than 5 files, a new feature, cross-module work, or architecture change: standard or architecture Design. -Scoring dimensions (10 total): +File count is a signal, not an override for safety, protocol, or actual complexity. -- Goal clarity: 0-3 -- Expected outcome: 0-3 -- Scope boundary: 0-2 -- Constraints: 0-2 +Workflow transition: -Scoring rules: +- In `strict` mode, render the Analyze summary and wait for confirmation before Design. +- In `adaptive` mode, return the routing signal to the host, which follows the current request and protocol state. -- `score >= require_score`: continue to Phase B. -- `score < require_score` and `auto_decide=true`: continue with explicit assumptions. -- `score < require_score` and `auto_decide=false`: ask follow-up questions with `assets/question-output.md`. +## Boundaries -Follow-up rules: - -1. Do not ask for information that code can already provide. -2. Ask only for user-facing gaps: business logic, target behavior, constraints. -3. Ask 3-5 questions. -4. Do not re-ask preferences that are already captured as long-term preferences. - -## Phase B: Code analysis - -### Step 5: Extract key objectives - -- Compress the request into one core objective sentence. -- Distinguish whether the user provided a real goal or only an implementation path. -- When the input is mostly a path, treat that path as a candidate approach rather than the success criterion itself. -- Define verifiable success criteria, and close them in a SMART-style form: deliverable, boundary, constraints, verification, and next stop-point. - -### Step 6: Code analysis and technical preparation - -- Estimate project and change scale. -- Locate related modules and key files. -- Run baseline quality checks (stale information, security risks). -- Pull external documentation only when necessary. - -Stable subset rules: - -1. When the goal is still fuzzy, clarify key facts first; only continue with explicit assumptions when `auto_decide=true`. -2. When the current path is clearly suboptimal, include at least one lower-cost or lower-risk alternative in the analysis summary. -3. Every alternative path should state the tradeoff instead of giving a bare conclusion. -4. Do not force deep challenge mode for `quick_fix`, pure state explanation, or lightweight consult flows. - -## Adaptive routing - -- Simple task (`<=2` files and clear scope): go straight to quick fix. -- Medium task (`3-5` files): enter the light plan path. -- Complex task (`>5` files or architectural change): enter full design. - -## Phase transitions - -- Score below threshold and no auto-decide: keep asking until the score passes or the user cancels. -- `workflow.mode=strict`: render summary and wait for confirmation. -- `workflow.mode=adaptive`: continue automatically according to complexity. -- User says `cancel`: terminate with the cancellation path. +- Do not generate a plan package or modify code. +- Do not add host intent types, keyword rules, or regex routing. +- The host handles `consult_readonly` through the existing protocol; Analyze does not turn a read-only request into a write path. diff --git a/skills/en/skills/sopify/design/SKILL.md b/skills/en/skills/sopify/design/SKILL.md index 45d97daa..86dcba59 100644 --- a/skills/en/skills/sopify/design/SKILL.md +++ b/skills/en/skills/sopify/design/SKILL.md @@ -5,7 +5,7 @@ description: Design phase entry. Aggregates plan-level selection, task breakdown # Design (Entry) -> Core philosophy: A plan's value lies in the clarity of its trade-offs, not in its coverage. +> Check the current system first, then choose the smallest sufficient path. ## When to activate @@ -15,10 +15,11 @@ description: Design phase entry. Aggregates plan-level selection, task breakdown ## Execution skeleton 1. Load `references/design-rules.md`. -2. Decide `light/standard/architecture` from explicit change signals. -3. Generate the plan files from the matching templates in `assets/`. -4. Produce the task list and validate task granularity. -5. Add the scoring block to the formal plan package and render the scored summary with `assets/output-summary.md`. +2. Check existing implementation, governing contracts, applicable platform capabilities, and installed dependencies. +3. Choose the smallest sufficient path and select `light/standard/architecture`. +4. Generate the plan files from the matching `assets/` templates. +5. Produce tasks with explicit dependencies and verification. +6. Report `Ready` or `Needs decision` with evidence using `assets/output-summary.md`. ## Resource navigation diff --git a/skills/en/skills/sopify/design/assets/output-summary.md b/skills/en/skills/sopify/design/assets/output-summary.md index f1f6a42b..909fe460 100644 --- a/skills/en/skills/sopify/design/assets/output-summary.md +++ b/skills/en/skills/sopify/design/assets/output-summary.md @@ -1,14 +1,13 @@ -[{BRAND_NAME}] Solution Design ✓ +[{BRAND_NAME}] Solution Design {status symbol} Plan: .sopify/plan/{YYYYMMDD}_{feature}/ -Summary: {one-line technical solution} -Tasks: {N} items -Solution quality: {X}/10 -Implementation readiness: {Y}/10 -Scoring rationale: {1 line} +Approach: {one-sentence solution} +Tasks: {N} +Readiness: {Ready / Needs decision} +Evidence: {why the path is settled, or which choice can still change scope, the solution path, or acceptance} --- Changes: {N} files - .sopify/plan/... -Next: Continue the review or execution flow in the host session, or reply with feedback +Next: {continue review or implementation; name the required choice for Needs decision} diff --git a/skills/en/skills/sopify/design/assets/plan-template.md b/skills/en/skills/sopify/design/assets/plan-template.md index e6913a35..89364b47 100644 --- a/skills/en/skills/sopify/design/assets/plan-template.md +++ b/skills/en/skills/sopify/design/assets/plan-template.md @@ -11,13 +11,8 @@ archive_ready: false # {Feature Name} -Scoring: -- Solution quality: {X}/10 -- Implementation readiness: {Y}/10 - -Scoring rationale: -- Strengths: {1 line} -- Deductions: {1 line} +Readiness: {Ready / Needs decision} +Evidence: {why the path is settled, or which choice can still change scope, the solution path, or acceptance} ## Context / Why diff --git a/skills/en/skills/sopify/design/references/design-rules.md b/skills/en/skills/sopify/design/references/design-rules.md index 3278f650..d121ed88 100644 --- a/skills/en/skills/sopify/design/references/design-rules.md +++ b/skills/en/skills/sopify/design/references/design-rules.md @@ -1,84 +1,48 @@ -# Design Detailed Rules +# Design Rules ## Goal -Design the technical solution, break work into executable tasks, and generate a replayable plan package. +Turn the objective and boundaries confirmed by Analyze into the smallest executable, verifiable solution. Design owns technical tradeoffs and task breakdown. It does not manage protocol state or implement code. -## Overall flow +## 1. Check the current system -1. Decide the plan level (`light/standard/architecture`). -2. Generate the plan file scaffold. -3. Break down tasks and mark verification criteria. -4. Render the summary and wait for the next host action. +Before proposing new implementation, inspect the existing code, callers, and tests; governing protocol, public contracts, and compatibility boundaries; applicable language or platform capabilities; and dependencies already installed and used by the project. -## Step 1: Decide the plan level +This is not a fixed technology ladder. The goal is to avoid duplicate capability and unnecessary dependencies without weakening correctness, safety, or user value. -Auto-detection rules (`plan.level=auto`): +## 2. Choose the smallest sufficient solution -- `light`: 3-5 files, no architectural change, scope is explicit. -- `standard`: more than 5 files, or a new feature, or a cross-module change. -- `architecture`: architectural change, major refactor, or new system design. +- State the recommended path, its material tradeoffs, and explicit non-goals. +- Prefer the narrowest shared boundary; explain why a cross-module change is necessary when it is. +- Do not build frameworks, state, or extension points for hypothetical future work. +- Ask the user only about choices that can change scope, the solution path, or acceptance. Develop may decide reversible implementation details within the approved boundary. -## Step 2: Generate plan files +## 3. Select the plan level -- `light`: generate `plan.md`. -- `standard`: generate `plan.md + tasks.md`. -- `architecture`: generate `plan.md + tasks.md + design.md`. -- Every formal package puts its `level` frontmatter, semantic entry, and scoring block in `plan.md`. -- Create ADRs, diagrams, assets, and receipts only when evidence requires them; no level requires empty supporting directories. -- the plan summary must also surface: - - `Solution quality` - - `Implementation readiness` - - `Scoring rationale` +- `light`: `plan.md` for clear local work. +- `standard`: `plan.md + tasks.md` for a feature, cross-module work, or substantial delivery. +- `architecture`: `plan.md + tasks.md + design.md` only for an actual architecture change, new system, or major refactor. -Template sources live in `assets/`: +Create ADRs, diagrams, assets, and receipts only when evidence requires them. Plan-body templates come only from this skill's `assets/` directory. -1. `assets/plan-template.md` -2. `assets/tasks-template.md` -3. `assets/design-template.md` -4. `assets/adr-template.md` (only for an actual architecture decision) +## 4. Determine readiness -## Step 3: Break down tasks +- `Ready`: no unresolved user choice can still change scope, the solution path, or acceptance. State the supporting evidence. +- `Needs decision`: list the concrete options, their impact, and a recommendation, then stop. -Task constraints: +A dynamic version, Git delivery, release, or another irreversible action is an execution checkpoint. It does not make a settled plan `Needs decision` by itself. -1. Each task should fit within about 30 minutes. -2. Each task must have a verifiable completion criterion. -3. Dependencies must be explicit. +Workflow transition: -Suggested categories: +- In `strict` mode, render the Design summary and wait for confirmation before Develop. +- In `adaptive` mode, `~go` may continue through the host workflow; `~go plan` stops after the summary. -1. Core feature work -2. Supporting work -3. Security checks -4. Testing -5. Documentation updates (`project.md / blueprint/*`) +## 5. Break down tasks -Task markers: +Each task needs a clear deliverable, dependency, and acceptance method. Follow real boundaries instead of splitting work to fit an arbitrary duration. Include documentation and knowledge sync only when the plan's `knowledge_sync` requires them. -- `[ ]` pending -- `[x]` completed -- `[-]` skipped -- `[!]` blocked +Task markers: `[ ]` pending, `[x]` completed, `[-]` skipped, `[!]` blocked. -## Phase transitions +## Protocol boundary -- `workflow.mode=strict`: render the summary and wait for confirmation. -- `workflow.mode=adaptive`: - - `~go`: continue into execution confirmation or the downstream host flow. - - `~go plan`: stop after rendering the plan summary. -- If the user gives plan feedback, stay in this phase, update the files, and render again. - -## Protocol entry boundary - -Plan structure and task splitting are owned by this skill; protocol state writes (active_plan / current_handoff / receipts) go through `sopify_writer`, not this skill directly. - -## Naming rules - -Plan directory format: `YYYYMMDD_feature_name` - -Examples: - -- `20260115_user_auth` -- `20260115_fix_login_bug` -- `20260115_refactor_api` +Design creates or updates plan semantic files only. The host writes `active_plan`, handoff, and receipts through `sopify_writer` under the governing protocol. diff --git a/skills/en/skills/sopify/develop/references/develop-rules.md b/skills/en/skills/sopify/develop/references/develop-rules.md index 0a335c92..8bab4015 100644 --- a/skills/en/skills/sopify/develop/references/develop-rules.md +++ b/skills/en/skills/sopify/develop/references/develop-rules.md @@ -46,6 +46,9 @@ Hard requirements: - No verification evidence means the task is not complete. - Subjective claims such as `overbuild`, `underbuild`, or "it should be fine" never replace verification or review evidence. - Do not silently skip verification and do not retry indefinitely. +- For a bug or shared-boundary change, inspect affected callers, fix the narrowest common root cause, and verify equivalent paths. +- Develop decides reversible implementation details inside the approved boundary. Replan only when new facts change scope, the solution path, or acceptance. +- When a Quick Fix has no Design artifact, make only the local choices required for the request. Do not create a plan or copy the full Design rules. ### 2.2 Minimum verify contract @@ -160,37 +163,7 @@ After completing the two-stage review, before outputting the final summary: ## Step 3: Sync the knowledge base -Sync timing: - -1. After each module-level task batch. -2. Once again during phase close-out. - -Sync targets: - -- `project.md` -- `blueprint/background.md` -- `blueprint/design.md` -- `blueprint/tasks.md` -- `user/preferences.md` (long-term preferences only) -- `user/feedback.jsonl` - -Formal rule: - -- `knowledge_sync.skip`: no sync required -- `knowledge_sync.review`: at least review before finalize -- `knowledge_sync.required`: finalize must block until updated - -Conservative preference writes: - -Allowed: - -- Explicit long-term user preferences such as "use this by default going forward". - -Disallowed: - -- One-off instructions. -- Guesses from incomplete context. -- Generalized conclusions unrelated to the task. +During implementation close-out, invoke KB, apply the current plan's declared `knowledge_sync`, and record the result. KB is the sole owner of sync targets, long-lived knowledge criteria, and preference-write policy; Develop does not redefine them here. ## Step 4: Plan completion state diff --git a/skills/en/skills/sopify/kb/SKILL.md b/skills/en/skills/sopify/kb/SKILL.md index e8b2ac9d..060fe2ca 100644 --- a/skills/en/skills/sopify/kb/SKILL.md +++ b/skills/en/skills/sopify/kb/SKILL.md @@ -1,126 +1,61 @@ --- name: kb -description: Knowledge base management skill; read during KB operations; includes init, update, sync strategies +description: Manage long-lived `.sopify/` knowledge, including bootstrap, progressive materialization, reads, retention, and knowledge_sync policy. --- -# Knowledge Base Management - V2 Rules +# Knowledge Base Management -**Goal:** manage the V2 layers in `.sopify/` so long-lived knowledge, the active plan, and finalized archives stay clearly separated. +KB owns long-lived knowledge. It does not make Analyze, Design, or Develop decisions, and it does not manage the active plan, handoff, receipts, or finalize directly. Document structures come from Templates; protocol state is managed through `sopify_writer`. -## Knowledge Base Structure +## Directory responsibilities ```text .sopify/ -├── blueprint/ -│ ├── README.md # Pure index page with index-required sections only -│ ├── background.md # Long-term goals, scope, non-goals -│ ├── design.md # Module / host / directory / consumption contracts -│ └── tasks.md # Unfinished long-term items and explicit deferrals -├── project.md # Project technical conventions -├── user/ -│ ├── preferences.md # Long-term user preferences -│ └── feedback.jsonl # Raw feedback events -├── plan/ -│ └── YYYYMMDD_feature/ # Current active plan -├── history/ -│ ├── index.md # Archive index -│ └── YYYY-MM/ -└── state/ # Runtime machine truth +├── project.md # reusable technical conventions +├── user/ # long-term preferences and raw feedback +├── blueprint/ # long-term goals, design boundaries, open work, and index +├── plan/ # current plan semantic files +├── history/ # archived plans and index +└── state/ # local protocol state ``` -## Initialization Strategy +`blueprint/README.md` keeps only status, maintenance guidance, current goal, current focus, and reading links. Put detailed content in the relevant blueprint file. -### Full mode (`kb_init: full`) +## Bootstrap and progressive materialization -Create on the first bootstrap: +`kb_init: full` creates `project.md`, `user/preferences.md`, `user/feedback.jsonl`, and the four blueprint files on first use. It does not pre-create plan content, history, or empty directories. -```yaml -Create: - - .sopify/project.md - - .sopify/user/preferences.md - - .sopify/user/feedback.jsonl - - .sopify/blueprint/README.md - - .sopify/blueprint/background.md - - .sopify/blueprint/design.md - - .sopify/blueprint/tasks.md -``` - -Notes: - -- Do not pre-create `plan/` content. -- Do not pre-create `history/index.md` or any archive. +`kb_init: progressive` is the default: -### Progressive mode (`kb_init: progressive`) [default] +- First real project use: create `project.md`, `user/preferences.md`, and `blueprint/README.md`. +- First plan lifecycle: add `blueprint/background.md`, `blueprint/design.md`, `blueprint/tasks.md`, and the current plan directory. +- First explicit `~go finalize`: let the protocol flow create `history/index.md` and the archive directory. +- First explicit long-term feedback: create `user/feedback.jsonl` when needed. -Materialize by lifecycle: +## Knowledge context reads -```yaml -First real-project trigger: - - .sopify/project.md - - .sopify/user/preferences.md - - .sopify/blueprint/README.md - -First plan lifecycle: - - .sopify/blueprint/background.md - - .sopify/blueprint/design.md - - .sopify/blueprint/tasks.md - - .sopify/plan/YYYYMMDD_feature/ - -First explicit ~go finalize: - - .sopify/history/index.md - - .sopify/history/YYYY-MM/YYYYMMDD_feature/ - -First explicit long-term preference: - - .sopify/user/feedback.jsonl -``` - -## Read Order +The host completes the governing Protocol entry for a managed plan, handoff, and receipts before invoking KB. This section defines only KB's long-lived context order: 1. `project.md` 2. `user/preferences.md` 3. `blueprint/README.md` -4. `blueprint/background.md` -5. `blueprint/design.md` -6. `blueprint/tasks.md` -7. `state/active_plan.json` → `plan//plan.md` - -Rules: +4. Relevant parts of `blueprint/background.md`, `design.md`, and `tasks.md` -- consult / clarification routes prefer `L0/L1` and must not require deep blueprint files -- planning / develop may enter `L2 active plan` -- `active_plan.json` provides only `plan_id`; `plan.md` is the active plan's semantic entry. Read handoff and receipts only when continuation needs them, and never fall back to the retired current-plan projection. -- `history/` is not the default long-lived context source; read it only for finalize lookups or human traceability +Consult and quick fix do not fail when deep blueprint files are absent. Read `history/` only for trace-back or finalize. -## Update Rules +## Retention and updates -### L0 Index Guardrails +Keep information only when it remains useful across tasks: -- `blueprint/README.md` keeps only `status / maintenance / current goal / current focus / read next`. -- Do not write absolute workspace paths, long-form architecture prose, or formal contract bodies into `blueprint/README.md`. -- If extra long-lived topic docs exist at the `blueprint/` root, `blueprint/README.md` must list them explicitly. +- `project.md`: reusable technical conventions. +- `background.md`: long-term goals, scope, and non-goals. +- `design.md`: module, host, directory, and consumption contracts. +- `tasks.md`: unfinished long-term work and explicit deferrals with a revisit condition. +- `preferences.md`: explicit long-term user preferences. -### `blueprint/tasks.md` Boundaries +Do not store one-off implementation details, current-plan task breakdowns, temporary tradeoffs, completed tasks, or copies of history content. When code and documentation conflict, verify the code and then correct the documentation. Current user instructions override historical preferences. -- Keep only unfinished long-term items and explicit deferrals. -- `[x]` completed items must not remain in `blueprint/tasks.md`. - -### Must update - -- `project.md`: reusable technical conventions changed -- `blueprint/background.md`: long-term goals, scope, or non-goals changed -- `blueprint/design.md`: module, host, directory, or consumption contracts changed -- `blueprint/tasks.md`: unfinished long-term items or explicit deferrals changed -- `user/preferences.md`: the user explicitly stated a long-term preference - -### Must not be written into long-lived knowledge - -- one-off implementation details -- short-term task breakdown from the current plan -- temporary tradeoffs that belong only to this task -- completed task checklists lingering in `blueprint/tasks.md` -- copying history body text back into blueprint - -## `knowledge_sync` Sync Contract +## `knowledge_sync` ```yaml knowledge_sync: @@ -130,48 +65,12 @@ knowledge_sync: tasks: skip|review|required ``` -Execution rules: - -- `skip`: no sync required for this round -- `review`: at least review before finalize -- `required`: finalize must block until updated - -## Conflict Handling - -- code vs docs: code is the source of truth, then update docs -- current task vs long-term preference: current explicit task > `user/preferences.md` > default rules - -## Output Format - -**Initialization complete:** - -```text -[{BRAND_NAME}] Knowledge Base Init ✓ - -Created: {N} files -Strategy: {full/progressive} - ---- -Changes: {N} files - - .sopify/project.md - - .sopify/blueprint/README.md - - ... - -Next: KB is ready -``` - -**Sync complete:** +- `skip`: do not inspect that file for this plan. +- `review`: decide whether it needs an update before finalize. +- `required`: update it before the delivery candidate; block finalize while incomplete. -```text -[{BRAND_NAME}] Knowledge Base Sync ✓ +KB applies the plan's sync policy without changing the plan lifecycle. Update the narrowest long-lived location and avoid duplicating the same content across files. -Updated: {N} files +## Output ---- -Changes: {N} files - - .sopify/project.md - - .sopify/blueprint/design.md - - ... - -Next: Docs updated -``` +After bootstrap or sync, state the actual result, list `Changes`, and end with `Next:`. Use `Changes: 0 files` when nothing changed. diff --git a/skills/en/skills/sopify/references/output-contract.md b/skills/en/skills/sopify/references/output-contract.md index 38946dca..5f9ac00d 100644 --- a/skills/en/skills/sopify/references/output-contract.md +++ b/skills/en/skills/sopify/references/output-contract.md @@ -1,74 +1,38 @@ # Sopify Output Contract -All stages (analyze / design / develop / consult) must follow this contract for final replies. Each section governs one output decision dimension. +The final response should make the result, evidence, and next step easy to find. Phase templates define required information, not empty sections that must always be rendered. -## 1. Output Path Responsibilities +## Output path -- **Gate summary**: Routing status from the gate/routing phase. Contains phase title, status line, Context, Changes, Next. Does not contain verification tables, review conclusions, or other skill-level content. -- **Host completion reply**: The final summary after skill execution. Must follow the corresponding template, including required sections and enhancements when triggered. -- Gate summary ≠ final reply. The gate tells the host what to do; the host outputs results per template after completing the work. +- A gate summary reports routing, current state, and the next action only. +- After a skill or consult finishes, the host renders the final response from the actual outcome. Gate text is not a delivery report. -## 2. Required Sections +## Required content -| Output Type | Required Sections | Required Tables | Status Symbol | -|------------|------------------|----------------|---------------| -| develop/success | Review conclusion, verification summary, Changes, Next | Verification table | ✓ only when all passed | -| develop/partial | Incomplete items, verification summary, Changes, Next | Incomplete table + verification table | Must use ! | -| develop/quick-fix | Verification summary, Changes, Next | Simplified verification table | ✓ only when all passed | -| analyze/success | Assumptions, identified gaps, next-step rationale, Changes, Next | — | — | -| analyze/question | Question list, Next | — | Must use ? | -| design/summary | Score lines, Changes, Next | — | — | -| consult | Changes, Next | — (adaptive) | — | +| Output | Required content | Status rule | +|--------|------------------|-------------| +| `analyze/success` | Objective, deliverable, completeness score, confirmed evidence, explicit assumptions when used, material gaps, next step | Do not mark incomplete input as complete | +| `analyze/question` | A few decision-relevant questions, their impact, `Next` | `?` | +| `design/summary` | Approach, task count, `Ready` or `Needs decision` with evidence, `Changes`, `Next` | Do not use `Ready` while a material choice remains | +| `develop/success` | Result, review conclusion, verification summary, `Changes`, `Next` | Use `✓` only when all checks pass | +| `develop/partial` | Incomplete work, reason, completed verification, `Changes`, `Next` | `!` | +| `develop/quick-fix` | Result, relevant verification, `Changes`, `Next` | Use `✓` only when all checks pass | +| `consult` | Conclusion, necessary evidence, `Changes`, `Next` | Match the actual state | -Table column rule: only show columns that carry meaningful information for the current scenario. Column omission only affects final display, not internal verification logic. `reason_code` is an internal verification field and is not shown in user-facing output. +`consult_readonly` writes no code, plan, state, knowledge base, audit, receipt, or Git index. Give the conclusion and necessary evidence first; include blockers or decisions only when they exist, then stop. -## 3. Conditional Enhancement & Format Selection +## Structure and density -Do not force structure on every scenario. Decide whether and how to enhance based on information shape and trigger conditions: +- Use short paragraphs for a simple answer or one-file change. Do not add a table merely to fill a template. +- Use a comparison table for several options, numbered steps for a process, or a tree for a directory relationship. Choose at most one main structure per response. +- Group repeated results by deliverable instead of listing the same “passed” line for every task. +- Put `Changes` before the final `Next:` line. Use `Changes: 0 files` when nothing changed. -| Trigger Condition | Recommended Format | Typical Scenarios | -|------------------|-------------------|-------------------| -| Multi-item comparison/tradeoff (>2 options) | Table | Solution tradeoffs, risk comparison, host capability comparison | -| Flow/invocation/lifecycle | Numbered sequence | SDK flows, gate → route → handoff | -| File/component/module composition | Tree structure | Component breakdown, module structure, plan file organization | -| Score dimensions need visibility | Score table | analyze scoring | -| Simple Q&A/status confirmation | Keep concise | Single question answers, status confirmations | +## Before sending -Constraint: use at most one primary structure per reply; avoid stacking table + tree + flow. - -### 3.1 Output Density Gradient - -Select output density based on scenario complexity. Avoid heavy output for simple tasks: - -| Density Level | Applicable Scenarios | Verification Summary | -|--------------|---------------------|---------------------| -| Minimal | quick-fix, single-file change, Q&A | Simplified table (≤3 columns), omit review conclusion | -| Standard | 3-5 task regular develop | Table, omit zero-info columns | -| Full | 6+ tasks or cross-module delivery | Full table + phased review conclusions | - -Density level is auto-inferred from task count and change scope; no user specification needed. - -**DO:** -- Use a comparison table when multi-option tradeoffs are present — make differences visible at a glance -- Simplify verification summary on success when all passed — omit columns with no information -- Keep plain text when information shape does not match any structure -- Trim output by density gradient: quick-fix should not produce a full verification table -- Group by deliverable when completing 3+ independent tasks; merge same conclusions into one line -- No decorative emoji in body text (verification summaries, review conclusions, Changes section) - -**DON'T:** -- Multi-option tradeoffs without comparison structure = missed enhancement -- Forcing tables on simple Q&A = over-enhancement -- Mixing two or more primary structures in one reply = cognitive overload -- Expanding 5 identical `passed` conclusions item-by-item = information dilution - -## 4. Pre-output Self-check - -Before outputting the final reply, verify: - -1. Required sections present: check §2 for the current output type. -2. Status symbol correct: `✓` only when all verifications passed with no degradation or skips; otherwise `!`. -3. Footer complete: `Changes:` + `Next:` must be present. -4. Conditional enhancement applied: if the reply meets a §3 trigger condition, use the corresponding structured format. -5. Density level matched: quick-fix should not produce a full verification table; complex delivery should not lack review conclusions. -6. Desensitization: rewrite raw `root_cause` enums as human descriptions; do not expose internal scoring weights; do not display gate/handoff JSON fields (`resolution_id`, `run_stage`, etc.). +1. Does the opening answer the current question? +2. Does the status symbol match the verification result? +3. Does `Ready / Needs decision` follow the Design rule? +4. Have empty sections, repeated conclusions, and internal fields been removed? +5. Are paths, commands, numbers, and references verifiable? +6. Are `Changes` and the final `Next:` line present? diff --git a/skills/en/skills/sopify/references/shared-writing-dna.md b/skills/en/skills/sopify/references/shared-writing-dna.md index 68d5ea60..d5539750 100644 --- a/skills/en/skills/sopify/references/shared-writing-dna.md +++ b/skills/en/skills/sopify/references/shared-writing-dna.md @@ -1,36 +1,28 @@ -# Sopify Shared Writing Standards +# Sopify Shared Writing Rules -All skills (analyze / design / develop) must follow these 6 rules. Each prevents one class of LLM output accident. +These rules apply to every skill and consult response. They shape the writing; they do not make phase-specific decisions. -## Rule 1: Separate Facts from Inference +## Lead with the result -- Inferences must be labeled "inferred" or "likely" -- Quantitative claims need a source or calculation method; otherwise use "approximately N" or omit -- Never present guesses as conclusions +- Answer the user's immediate question before adding evidence or next steps. +- Name the actor and action: what changed, who must decide, and why. Avoid abstract updates such as “optimization completed” or “closure advanced.” +- Separate facts, inferences, and recommendations. State the basis for an inference instead of presenting it as fact. -## Rule 2: One Concept, One Term +## Keep only useful information -- Use the same name for the same entity throughout; no synonym switching -- Use backticks for code identifiers: ✅ `app_access_token` ❌ application access token +- Match the response to the task. Do not add sections the user did not ask for. +- Omit empty optional sections instead of leaving headings or boilerplate. +- Use one term for one concept. Preserve exact identifiers, paths, and commands, and verify references before citing them. +- Give a source or calculation for numbers. Label estimates as estimates. -## Rule 3: Minimize Output Scope +## Write naturally -- Output scope = task scope; do not add unrequested sections -- No speculative abstractions — do not expand extension points that are not currently needed -- Optional template blocks with no content should be omitted entirely, not left as empty shells +- Prefer concrete subjects and verbs. Avoid noun stacks, corporate filler, slogans, and forced conversational phrasing. +- Chinese and English outputs share facts, boundaries, and conclusions, but should each follow their own language rather than mirror sentence structure. +- Keep one point per paragraph. Use a table or extra headings only when the information is easier to scan that way. -## Rule 4: Formatting +## Formatting -- Use consistent capitalization for proper nouns: ✅ `GitHub` `JavaScript` -- Use standard punctuation consistently -- Code identifiers in backticks - -## Rule 5: Paragraph Constraints - -- Paragraphs must not exceed 7 lines; one point per paragraph -- Use at most three heading levels (`#` `##` `###`); do not use `####` - -## Rule 6: Verifiable References - -- File paths, function names, and class name references must actually exist -- Do not reference fabricated APIs, configuration keys, or documentation sections +- Preserve official capitalization such as `GitHub` and `JavaScript`. +- Use no more than three heading levels. +- Do not use decorative emoji in the body. diff --git a/skills/en/skills/sopify/templates/SKILL.md b/skills/en/skills/sopify/templates/SKILL.md index 1fa1bcc4..04603d36 100644 --- a/skills/en/skills/sopify/templates/SKILL.md +++ b/skills/en/skills/sopify/templates/SKILL.md @@ -1,223 +1,125 @@ --- name: templates -description: Document template collection; read when creating docs; includes all KB templates and plan file templates +description: Knowledge-base document templates, loaded when long-lived knowledge files are created or materialized. --- -# Document Template Collection +# Knowledge Base Templates -**Usage notes:** -1. Replace `{...}` with actual content. -2. Formal plan packages include the scoring block by default. -3. `blueprint/README.md` stays as a lightweight index only. -4. If extra long-lived topic docs exist at the `blueprint/` root, they must be linked explicitly from `blueprint/README.md`. -5. `blueprint/tasks.md` keeps only unfinished long-term items and explicit deferrals; completed items do not remain in that file. +The Templates skill defines stable knowledge-base document structures. It does not decide when to write, how to apply `knowledge_sync`, or how a plan moves through its lifecycle. -## A1 | Knowledge Base Templates +- For knowledge-base policy and `knowledge_sync`, read the `kb` skill. +- For `light / standard / architecture` levels and plan-body templates, read Design `assets/`. +- For active-plan, handoff, and receipt reads and writes, follow the governing Protocol. -### project.md +Replace placeholders and remove empty optional sections. Do not store one-off implementation detail as long-lived knowledge. + +## `project.md` ```markdown -# Project Technical Conventions +# Project Conventions -## Tech Stack -- Core: {language version} / {framework version} +## Technology +- Core: {language or framework version} - Build: {build tool} - Test: {test framework} -## Working Agreement -- Keep this file focused on reusable technical conventions. -- Do not treat one-off implementation choices as project-wide rules. +## Conventions +- {reusable technical convention} -## Document Boundaries -- `project.md`: reusable conventions -- `blueprint/background.md`: long-term goals, scope, non-goals -- `blueprint/design.md`: module / host / directory / consumption contracts -- `blueprint/tasks.md`: unfinished long-term items and explicit deferrals +## Document boundaries +- `project.md`: technical conventions +- `blueprint/background.md`: long-term goals, scope, and non-goals +- `blueprint/design.md`: module, host, directory, and consumption contracts +- `blueprint/tasks.md`: unfinished long-term work and explicit deferrals ``` -### blueprint/README.md +## `blueprint/README.md` ```markdown # Project Blueprint Index Status: {current status} -Maintenance: keep only status, current goal, current focus, and read-next links on this page; move long explanations into other blueprint files - -## Current Goal -- Project: `{project_name}` -- Long-term goals and scope live in `./background.md` - -## Current Focus -- Active plan: {present/none} -- History archive: {status} - -## Read Next -- [Technical Conventions](../project.md) -- [Blueprint Background](./background.md) -- [Blueprint Design](./design.md) -- [Blueprint Tasks](./tasks.md) -- [Blueprint Topic](./{extra_blueprint_doc}.md) # list each additional long-lived topic doc when present -- [Change History](../history/index.md) +Maintenance: keep only status, current goal, current focus, and reading links + +## Current goal +- {long-term goal summary} + +## Current focus +- Active plan: {none / link to plan.md} +- Archive status: {status} + +## Read next +- [Project conventions](../project.md) +- [Background](./background.md) +- [Design](./design.md) +- [Tasks](./tasks.md) +- [History](../history/index.md) ``` -### blueprint/background.md +List each long-lived topic document in “Read next” when the `blueprint/` root contains one. + +## `blueprint/background.md` ```markdown # Blueprint Background -## Long-Term Goals -- {goal1} -- {goal2} +## Long-term goals +- {goal} ## Scope - In scope: {content} - Out of scope: {content} -## Non-Goals +## Non-goals - {content} ``` -### blueprint/design.md +## `blueprint/design.md` ```markdown # Blueprint Design -## Formal Contracts -- `knowledge_sync` is the only formal sync contract. -- `state/active_plan.json` provides only `plan_id`; the active plan semantic entry is always `plan//plan.md`. - -## Consumption Contract +## Governing contracts +- {contract that remains valid across plans} -| Context Profile | Reads | Fail-open Rule | Notes | -|-----|------|------|------| -| `consult` | `project.md`, `preferences.md`, `blueprint/README.md` | missing deep blueprint does not fail | do not force plan materialization | -| `plan` | `L1` + `active_plan.json → plan.md` | materialize deep blueprint by lifecycle when missing | history is not default context | -| `finalize` | `active_plan.json → plan.md`, `knowledge_sync`, `blueprint/*`, `history/index.md` | create `history/index.md` on demand when missing | block when `required` sync is not satisfied | +## Module and consumption boundaries +- {module, host, or directory responsibility} ``` -### blueprint/tasks.md +## `blueprint/tasks.md` ```markdown # Blueprint Tasks -Status: keep only unfinished long-term items and explicit deferrals; completed items do not remain in this file. +## Unfinished long-term work +- [ ] {item} -## Unfinished Long-Term Items -- [ ] {long-term item} - -## Explicit Deferrals -- [-] {deferred item} +## Explicit deferrals +- [-] {item and revisit condition} ``` -### history/index.md +Keep only unfinished long-term work and explicit deferrals. Remove `[x]` items. + +## `history/index.md` ```markdown # Change History Index -| Timestamp | Feature | Status | Plan Package | -|-----------|---------|--------|--------------| -| {YYYYMMDD} | {feature} | ✓ | [Link](YYYY-MM/...) | +| Date | Feature | Status | Plan package | +|------|---------|--------|--------------| +| {YYYY-MM-DD} | {feature} | {status} | [link](YYYY-MM/...) | ``` -### user/preferences.md +## `user/preferences.md` ```markdown -# Long-Term User Preferences - -> Record only explicitly stated long-term preferences. One-off instructions stay out of this file. +# Long-term User Preferences -No confirmed long-term preferences yet. +- {explicit preference that applies across tasks} ``` -### user/feedback.jsonl +## `user/feedback.jsonl` ```json -{"timestamp":"2026-01-15T10:30:00Z","source":"chat","message":"Use the smallest change list by default going forward","scope":"planning","promote_to_preference":true,"preference_id":"pref-002"} -{"timestamp":"2026-01-15T11:10:00Z","source":"chat","message":"Make the output more detailed for this task","scope":"current_task","promote_to_preference":false} +{"timestamp":"{ISO-8601}","source":"chat","message":"{raw feedback}","scope":"{scope}","promote_to_preference":false} ``` - -## A2 | Plan Package Templates - -Every level starts with a `plan.md` carrying `level` frontmatter. Standard adds `tasks.md`; architecture adds `design.md`. Create supporting ADRs, diagrams, and evidence only when needed, without empty directories. - -### All Levels - plan.md - -```markdown ---- -title: {Feature Name} -plan_id: {YYYYMMDD_feature} -level: {light|standard|architecture} ---- - -# {Feature Name} - -Scoring: -- Solution quality: {X}/10 -- Implementation readiness: {Y}/10 - -## Context / Why -{Why this change is needed} - -## Scope -{What this plan includes} - -## Approach -{Smallest viable approach} - -## Waves / Steps -- [ ] {Step 1} - -## Key Decisions -- {Confirmed decision} - -## Constraints / Not-in-scope -- {Explicit exclusion} - -## Status / Progress -- [ ] {Current status} - -## Next -{Next action or decision checkpoint} -``` - -### Standard / Architecture - tasks.md - -```markdown -# Task List: {Feature Name} - -Directory: `.sopify/plan/{YYYYMMDD}_{feature}/` - -## 1. {Module Name} -- [ ] 1.1 Implement {feature} in `{file path}` -- [ ] 1.2 Implement {feature} in `{file path}` - -## 2. Testing -- [ ] 2.1 {test task} - -## 3. Documentation Update -- [ ] 3.1 Update `project.md / blueprint/background.md / blueprint/design.md / blueprint/tasks.md` -``` - -### Architecture - design.md - -```markdown -# Technical Design: {Feature Name} - -## Technical Solution -- {Implementation point} - -## Architecture Boundaries -{Module relationships and responsibilities} - -## Verification Strategy -- {Verification method} -``` - -## A3 | Task Markers - -| Marker | Meaning | -|--------|---------| -| `[ ]` | Pending | -| `[x]` | Completed | -| `[-]` | Skipped | -| `[!]` | Blocked | diff --git a/skills/zh/header.md.template b/skills/zh/header.md.template index 73db5226..fab4647d 100644 --- a/skills/zh/header.md.template +++ b/skills/zh/header.md.template @@ -1,5 +1,5 @@ - + # Sopify - 自适应 AI 编程助手 @@ -90,6 +90,7 @@ Next: {下一步提示} - 详细内容写入文件 - 避免冗余描述 - 标题行可根据 `title_color` 轻量着色(仅标题行),不支持颜色时自动回退纯文本 +- `consult_readonly` 只给结论和必要证据;阻塞项或待决策项仅在存在时展示,然后停车。不得写代码、方案、state、知识库、audit、receipt 或 Git index。 ### C3 | 工作流模式 @@ -244,99 +245,9 @@ progressive: 按需创建文件 (默认) --- -## 阶段执行 +## 阶段路由 -### P1 | 需求分析 - -**目标:** 验证需求完整性,分析代码现状 - -**执行流程:** -``` -1. 检查知识库状态 -2. 获取项目上下文 -3. 需求评分 (10分制) - - 目标清晰 (0-3) - - 预期结果 (0-3) - - 边界范围 (0-2) - - 约束条件 (0-2) -4. 评分 ≥ require_score → 继续 - 评分 < require_score → 追问或 AI 决策 (看 auto_decide) -``` - -**输出:** -``` -[my-app-ai] 需求分析 ✓ - -需求: {一句话描述} -评分: {X}/10 -范围: {N} files - ---- -Next: 继续方案设计?(Y/n) -``` - -### P2 | 方案设计 - -**目标:** 设计技术方案,拆分任务 - -**执行流程:** -``` -1. 读取 design Skill -2. 确定方案包级别 (light/standard/architecture) -3. 生成方案文件 -4. 输出摘要 -``` - -**输出:** -``` -[my-app-ai] 方案设计 ✓ - -方案: .sopify/plan/20260115_feature/ -概要: {一句话技术方案} -任务: {N} 项 -方案质量: {X}/10 -落地就绪: {Y}/10 -评分理由: {1 行} - ---- -Changes: 3 files - - .sopify/plan/20260115_feature/plan.md - - .sopify/plan/20260115_feature/tasks.md - - .sopify/plan/20260115_feature/design.md - -Next: 在宿主会话中继续评审或执行方案,或直接回复修改意见 -``` - -### P3 | 开发实施 - -**目标:** 执行任务,同步知识库 - -**执行流程:** -``` -1. 读取 develop Skill -2. 按 tasks.md 顺序执行 -3. 更新知识库 -4. 将方案更新为 ready_to_archive,保留在 plan/ -5. 输出结果 -``` - -**输出:** -``` -[my-app-ai] 开发实施 ✓ - -完成: {N}/{M} 任务 -测试: {通过/失败/跳过} - ---- -Changes: 5 files - - src/components/xxx.vue - - src/types/index.ts - - src/hooks/useXxx.ts - - .sopify/blueprint/design.md - - .sopify/plan/20260115_feature/plan.md - -Next: 请验证功能;需要归档时显式运行 ~go finalize -``` +宿主选择当前入口并加载对应 Skill。阶段判断、输出结构和资源导航以该 Skill 为准;header 只保留路由、协议、授权和通用 footer 契约,不复制阶段流程或模板。 --- @@ -348,9 +259,9 @@ Next: 请验证功能;需要归档时显式运行 ~go finalize | `design` | 进入方案设计 | 方案生成、任务拆分 | | `develop` | 进入开发实施 | 代码执行、KB同步 | | `kb` | 知识库操作 | 初始化、更新策略 | -| `templates` | 创建文档 | 所有模板定义 | +| `templates` | 创建知识库文档 | 知识库模板与导航 | -**读取方式:** 以上为当前全部 builtin skill,均为 host 消费的工作流 prompt/skill 资产,不支持独立调用。权威技能清单以 `skills/catalog/builtin_catalog.generated.json` 为准。 +**读取方式:** 以上为当前全部 builtin skill,均由宿主消费;宿主也可按请求直接路由单个 Skill。它们共享 Sopify 的协议与表达边界,不是五个独立产品。权威技能清单以 `skills/catalog/builtin_catalog.generated.json` 为准。 --- diff --git a/skills/zh/skills/sopify/analyze/SKILL.md b/skills/zh/skills/sopify/analyze/SKILL.md index ec9a1266..72b22887 100644 --- a/skills/zh/skills/sopify/analyze/SKILL.md +++ b/skills/zh/skills/sopify/analyze/SKILL.md @@ -5,7 +5,7 @@ description: 需求分析阶段入口;聚合评分、追问与范围判定规 # Analyze(入口文档) -> 核心哲学:区分用户给的"目标"与"实现路径"——只对目标负责。 +> 先读证据,再把目标、交付物和候选路径分开。 ## 何时激活 @@ -15,11 +15,11 @@ description: 需求分析阶段入口;聚合评分、追问与范围判定规 ## 执行骨架 1. 先加载 `references/analyze-rules.md`。 -2. 执行 Phase A(知识库检查、上下文获取、需求类型判定、完整性评分)。 +2. 读取用户提供的材料和相关代码,区分目标、交付物与候选路径,再做完整性评分。 3. 若评分不足,按 `auto_decide` 处理: - `false`:使用 `assets/question-output.md` 追问。 - `true`:显式补充假设后继续。 -4. 评分达标后执行 Phase B(目标提炼、代码分析与技术准备)。 +4. 评分达标后,交接已确认的成功标准、范围、证据和仍会影响结果的未知项。 5. 输出阶段摘要,格式参考 `assets/success-output.md`。 ## 资源导航 diff --git a/skills/zh/skills/sopify/analyze/assets/success-output.md b/skills/zh/skills/sopify/analyze/assets/success-output.md index b58e4e23..48f90abd 100644 --- a/skills/zh/skills/sopify/analyze/assets/success-output.md +++ b/skills/zh/skills/sopify/analyze/assets/success-output.md @@ -1,19 +1,22 @@ [{BRAND_NAME}] 需求分析 ✓ -需求: {一句话描述} -类型: {需求类型} +目标: {一句话描述} +交付物: {本次交付} 评分: {X}/10 范围: {预估文件数} -假设与前提: - - {assumption}(来源:{代码分析 / 用户输入 / AI 补充}) +已确认依据: + - {evidence}(来源:{用户材料 / 代码 / 正式契约}) -已识别信息缺口: +本次采用的假设(没有则省略): + - {assumption}(可继续的依据:{低风险且可逆的理由}) + +仍会影响结果的缺口(没有则省略): - {gap}(影响:{impact},建议:{action}) -下一步理由: {为什么建议进入 design / 需要追问 / 可直接执行} +下一步理由: {为什么建议进入 Design / 需要追问 / 可作为 quick fix 或 consult 处理} --- Changes: 0 files -Next: 继续方案设计?(Y/n) +Next: {下一动作} diff --git a/skills/zh/skills/sopify/analyze/references/analyze-rules.md b/skills/zh/skills/sopify/analyze/references/analyze-rules.md index 0bf45ce3..f6790230 100644 --- a/skills/zh/skills/sopify/analyze/references/analyze-rules.md +++ b/skills/zh/skills/sopify/analyze/references/analyze-rules.md @@ -1,104 +1,55 @@ -# Analyze 详细规则 +# Analyze 规则 ## 目标 -验证需求完整性,分析代码现状,为后续方案设计提供稳定输入。 +把用户的请求和可访问证据整理成稳定的目标、交付物与边界,供宿主路由或 Design 使用。Analyze 判断“要解决什么”,不替 Design 选择实现。 -## 总流程 +## 1. 先读证据 -```text -Phase A (步骤 1-4) -> 检查评分 >= require_score? - ├─ 是 -> Phase B (步骤 5-6) -> 输出摘要 - └─ 否 -> 检查 auto_decide - ├─ true -> 补充假设后继续 - └─ false -> 发起追问并等待用户输入 -``` +1. 读取当前请求、用户明确提供的文档和链接,以及已确认的长期偏好。 +2. 按任务需要读取用户提供或当前可访问的相关证据,例如文档、接口资料、设计稿、代码、测试、历史方案和正式协议。证据来源不限于这些例子;先读能回答当前问题的材料,不把其中已有答案再问用户。 +3. 区分三件事:用户想得到的结果、本次要交付的内容、用户提出的候选实现路径。候选路径只有在用户明确把它设为约束时才是边界。 +4. 发现材料冲突时,说明冲突、对当前交付的影响和推荐处理。不会影响结果的小差异不阻塞。 -## Phase A:需求评估 +知识库的读取和物化规则由 `kb` Skill 负责。Analyze 只消费与当前目标有关的内容。 -### 步骤 1:检查知识库状态 +## 2. 评估完整性 -- 判定条件:存在项目代码,且需求不是“新项目初始化”。 -- 执行方式:检查 `.sopify/` 是否存在。 -- 异常标记:若不存在,标记需初始化知识库。 +评分维度共 10 分:目标清晰 0–3、预期结果 0–3、范围边界 0–2、约束条件 0–2。 -### 步骤 2:获取项目上下文 +- `score >= require_score`:继续分析并形成交接。 +- 分数不足且 `auto_decide=true`:只对低风险、可逆且不改变目标的缺口作显式假设。 +- 分数不足且 `auto_decide=false`:停车追问。 -- 优先读取 `.sopify/user/preferences.md` 与知识库文件。 -- 信息不足时再扫描代码。 -- 详细知识库策略以 `kb` skill 为准。 +只在答案会改变目标、交付物、范围、成功标准,或决定当前路径能否安全落地时追问。问题应说明影响,数量由真实缺口决定,不规定凑满几项。 -偏好应用规则: +## 3. 形成交接 -1. 只使用用户明确声明的长期偏好。 -2. 当前任务明确要求优先于历史偏好。 -3. 无匹配偏好时按默认规则执行。 +Analyze 输出以下事实: -### 步骤 3:需求类型判定 +- 一句话目标和本次交付物。 +- 已确认的成功标准、范围和约束。 +- 支撑结论的关键材料或代码证据。 +- 仍会影响结果的未知项;没有则省略。 +- 建议进入 consult、quick fix 或 Design 的理由。 -候选类型: +若现有候选路径明显增加成本或风险,可以指出更稳妥的方向和取舍,但不在本阶段拍板技术方案。 -1. 新项目初始化 -2. 新功能开发 -3. 功能修改/增强 -4. Bug 修复 -5. 重构优化 -6. 技术变更 +## 4. 路由提示 -### 步骤 4:需求完整性评分 +- 简单且明确、通常不超过 2 个文件:可进入 quick fix。 +- 局部但需要方案、通常涉及 3–5 个文件:进入 light plan。 +- 超过 5 个文件、新功能、跨模块或架构变更:进入 standard 或 architecture Design。 -评分维度(总分 10): +文件数只是信号,不能覆盖安全、协议或真实复杂度。 -- 目标清晰:0-3 -- 预期结果:0-3 -- 边界范围:0-2 -- 约束条件:0-2 +阶段转换: -评分处理规则: +- `strict` 模式在输出 Analyze 摘要后停车,确认后再进入 Design。 +- `adaptive` 模式把路由提示交给宿主,由宿主结合当前请求和协议状态继续。 -- `score >= require_score`:进入 Phase B。 -- `score < require_score` 且 `auto_decide=true`:显式补充假设后继续。 -- `score < require_score` 且 `auto_decide=false`:发起追问(模板见 `assets/question-output.md`)。 +## 边界 -追问规则: - -1. 不问可从代码直接获得的信息。 -2. 只问用户相关关键缺口(业务、目标、约束)。 -3. 问题数量 3-5 个。 -4. 不重复追问已在长期偏好里明确的信息。 - -## Phase B:代码分析 - -### 步骤 5:提取关键目标 - -- 把需求压缩成一句话核心目标。 -- 先区分用户给的是“目标”还是“实现路径”。 -- 若当前输入主要是路径而不是目标,把路径记为候选方案,不直接当成成功标准。 -- 给出可验证成功标准,并按 SMART 风格收口交付物、边界、约束、验证方式与下一停点。 - -### 步骤 6:代码分析与技术准备 - -- 估算项目规模与改动规模。 -- 定位相关模块与关键文件。 -- 做基础质量检查(过时信息、安全风险)。 -- 必要时补充外部文档检索。 - -稳定子规则: - -1. 目标模糊时优先补关键事实;只有 `auto_decide=true` 才允许带显式假设继续。 -2. 若已知当前路径明显次优,在分析摘要中至少给出 1 个更低成本或更低风险的替代路径。 -3. 替代路径必须说明 tradeoff,避免只给结论不给理由。 -4. `quick_fix`、纯状态解释和轻咨询场景不强制展开深度挑战。 - -## 路由判定(adaptive) - -- 简单任务(<=2 文件且需求明确):直入快速修复。 -- 中等任务(3-5 文件):进入 light 方案。 -- 复杂任务(>5 文件或架构变更):进入完整方案设计。 - -## 阶段转换 - -- 评分不足且不可自动决策:循环追问直到达标或取消。 -- `workflow.mode=strict`:达标后输出摘要并等待确认。 -- `workflow.mode=adaptive`:达标后按复杂度自动推进。 -- 用户输入“取消”:按取消模板结束流程。 +- 不生成方案包,不修改代码。 +- 不新增宿主意图类型、关键词或正则路由。 +- `consult_readonly` 由宿主按现有协议处理;Analyze 不把只读请求升级为写入流程。 diff --git a/skills/zh/skills/sopify/design/SKILL.md b/skills/zh/skills/sopify/design/SKILL.md index 08945f43..91551861 100644 --- a/skills/zh/skills/sopify/design/SKILL.md +++ b/skills/zh/skills/sopify/design/SKILL.md @@ -5,7 +5,7 @@ description: 方案设计阶段入口;聚合方案分级、任务拆分与方 # Design(入口文档) -> 核心哲学:方案的价值在取舍的清晰度,不在覆盖面。 +> 先核对现状,再选择最小充分路径。 ## 何时激活 @@ -15,10 +15,11 @@ description: 方案设计阶段入口;聚合方案分级、任务拆分与方 ## 执行骨架 1. 加载 `references/design-rules.md`。 -2. 基于变更信号判定 `light/standard/architecture`。 -3. 按级别选取 `assets/` 中对应模板生成方案文件。 -4. 产出任务清单并做粒度检查(每项可验证、依赖明确)。 -5. 在正式 plan 包中补齐评分区块,并输出带评分的方案摘要,格式参考 `assets/output-summary.md`。 +2. 核对现有实现、正式契约、适用的原生能力和已安装依赖。 +3. 选择最小充分路径,并判定 `light/standard/architecture`。 +4. 按级别选取 `assets/` 中对应模板生成方案文件。 +5. 产出任务清单,确认每项可验证、依赖明确。 +6. 给出 `Ready` 或 `Needs decision` 及依据,格式参考 `assets/output-summary.md`。 ## 资源导航 diff --git a/skills/zh/skills/sopify/design/assets/output-summary.md b/skills/zh/skills/sopify/design/assets/output-summary.md index 59fdbe9d..ebd54ac5 100644 --- a/skills/zh/skills/sopify/design/assets/output-summary.md +++ b/skills/zh/skills/sopify/design/assets/output-summary.md @@ -1,14 +1,13 @@ -[{BRAND_NAME}] 方案设计 ✓ +[{BRAND_NAME}] 方案设计 {状态符} 方案: .sopify/plan/{YYYYMMDD}_{feature}/ -概要: {一句话技术方案} +路径: {一句话方案} 任务: {N} 项 -方案质量: {X}/10 -落地就绪: {Y}/10 -评分理由: {1 行} +就绪状态: {Ready / Needs decision} +依据: {为什么已收敛,或哪项选择仍会改变范围、方案路径或验收标准} --- Changes: {N} files - .sopify/plan/... -Next: 在宿主会话中继续评审或执行方案,或直接回复修改意见 +Next: {继续评审或执行;Needs decision 时写明待确认事项} diff --git a/skills/zh/skills/sopify/design/assets/plan-template.md b/skills/zh/skills/sopify/design/assets/plan-template.md index 1276933f..062ba212 100644 --- a/skills/zh/skills/sopify/design/assets/plan-template.md +++ b/skills/zh/skills/sopify/design/assets/plan-template.md @@ -11,13 +11,8 @@ archive_ready: false # {功能名称} -评分: -- 方案质量: {X}/10 -- 落地就绪: {Y}/10 - -评分理由: -- 优点: {1 行} -- 扣分: {1 行} +就绪状态: {Ready / Needs decision} +依据: {为什么已收敛,或哪项选择仍会改变范围、方案路径或验收标准} ## Context / Why diff --git a/skills/zh/skills/sopify/design/references/design-rules.md b/skills/zh/skills/sopify/design/references/design-rules.md index 8d32456b..2beb2df5 100644 --- a/skills/zh/skills/sopify/design/references/design-rules.md +++ b/skills/zh/skills/sopify/design/references/design-rules.md @@ -1,84 +1,48 @@ -# Design 详细规则 +# Design 规则 ## 目标 -设计技术方案,拆分可执行任务,生成可回放的方案包。 +把 Analyze 确认的目标和边界转成最小、可执行、可验证的方案。Design 负责技术取舍和任务拆分,不管理协议状态,也不执行代码。 -## 总流程 +## 1. 核对现状 -1. 判定方案包级别(`light/standard/architecture`)。 -2. 生成方案文件骨架。 -3. 拆分任务并标注验证标准。 -4. 输出摘要并等待宿主后续动作。 +在提出新实现前,按任务需要检查:项目已有代码、调用方和测试;正式协议、公开契约和兼容边界;适用的语言或平台原生能力;已安装且项目正在使用的依赖。 -## 步骤 1:方案包级别判定 +检查顺序不是固定技术梯子。目标是避免重复能力和不必要依赖,同时保证正确性、安全和用户价值。 -自动判定规则(`plan.level=auto`): +## 2. 选择最小充分方案 -- `light`:文件数 3-5,且无架构级变更,修改范围明确。 -- `standard`:文件数 >5,或新功能开发,或跨模块改动。 -- `architecture`:架构级变更、重大重构、新系统设计。 +- 说明推荐路径、关键取舍和明确非目标。 +- 优先修改最窄的共同边界;需要跨模块时说明原因。 +- 不为未知未来预建框架、状态或扩展点。 +- 只有会改变范围、方案路径或验收标准的选择才交给用户拍板。可逆的实现细节由 Develop 在批准边界内处理。 -## 步骤 2:生成方案文件 +## 3. 判定方案级别 -- `light`:生成 `plan.md`。 -- `standard`:生成 `plan.md + tasks.md`。 -- `architecture`:生成 `plan.md + tasks.md + design.md`。 -- 所有正式 plan 包都在 `plan.md` 中写入 `level` frontmatter、统一语义入口和评分区块。 -- ADR、diagram、assets、receipts 仅在真实需要时创建,不是任何级别的空目录或必备文件。 -- 方案摘要也必须显式输出: - - `方案质量` - - `落地就绪` - - `评分理由` +- `light`:`plan.md`,适合范围明确的局部工作。 +- `standard`:`plan.md + tasks.md`,适合新功能、跨模块或较复杂工作。 +- `architecture`:`plan.md + tasks.md + design.md`,只用于真实架构变更、新系统或重大重构。 -模板来源统一使用 `assets/` 目录: +ADR、图、assets 和 receipts 均按证据创建,不预建空目录。方案正文模板唯一来自本 Skill 的 `assets/`。 -1. `assets/plan-template.md` -2. `assets/tasks-template.md` -3. `assets/design-template.md` -4. `assets/adr-template.md`(仅在确有架构决策时使用) +## 4. 判定 readiness -## 步骤 3:任务拆分 +- `Ready`:没有仍需用户选择、且会改变范围、方案路径或验收标准的事项。给出支撑依据。 +- `Needs decision`:列出具体选择、各自影响和推荐,随后停车。 -任务约束: +动态版本、Git 交付、发布或其他不可逆动作属于执行期 checkpoint;只要方案路径已经确定,它们不自动把方案降为 `Needs decision`。 -1. 每项建议 30 分钟内可完成。 -2. 每项需具备可验证完成标准。 -3. 依赖关系清晰,避免隐藏前置条件。 +阶段转换: -任务分类建议: +- `strict` 模式在输出 Design 摘要后停车,确认后再进入 Develop。 +- `adaptive` 模式下,`~go` 可由宿主继续后续流程;`~go plan` 在摘要后停车。 -1. 核心功能实现 -2. 辅助功能 -3. 安全检查 -4. 测试 -5. 文档更新(`project.md / blueprint/*`) +## 5. 拆分任务 -任务状态符号: +每项任务应有明确产物、依赖和验收方式。按真实边界拆分,不为追求固定时长制造碎片。文档和知识同步只在方案的 `knowledge_sync` 要求时纳入。 -- `[ ]` 待执行 -- `[x]` 已完成 -- `[-]` 已跳过 -- `[!]` 阻塞中 +任务状态:`[ ]` 待执行、`[x]` 已完成、`[-]` 已跳过、`[!]` 阻塞。 -## 阶段转换 +## 协议边界 -- `workflow.mode=strict`:输出方案摘要后等待确认。 -- `workflow.mode=adaptive`: - - `~go` 触发:进入执行前确认或后续宿主链路。 - - `~go plan` 触发:只输出方案摘要并停止。 -- 用户反馈修改意见:留在本阶段,更新文件后再次输出摘要。 - -## 协议入口边界 - -方案结构与任务拆分由本技能负责;协议状态写入(active_plan / current_handoff / receipts)统一走 `sopify_writer`,不在本技能直接写入。 - -## 命名规则 - -方案目录格式:`YYYYMMDD_feature_name` - -示例: - -- `20260115_user_auth` -- `20260115_fix_login_bug` -- `20260115_refactor_api` +Design 只生成或更新方案语义文件。`active_plan`、handoff 和 receipts 由宿主按正式协议通过 `sopify_writer` 写入。 diff --git a/skills/zh/skills/sopify/develop/references/develop-rules.md b/skills/zh/skills/sopify/develop/references/develop-rules.md index bfd05afc..0ca7ffbf 100644 --- a/skills/zh/skills/sopify/develop/references/develop-rules.md +++ b/skills/zh/skills/sopify/develop/references/develop-rules.md @@ -46,6 +46,9 @@ - 没有验证证据,不算完成。 - `overbuild`、`underbuild`、`应该没问题` 这类主观判断不能替代验证或复审结果。 - 不允许静默跳过验证,也不允许无限重试。 +- Bug 或共享边界变更先检查受影响调用方,在最窄的共同根因处修复,并验证同类路径。 +- 批准范围内的可逆实现细节由 Develop 处理;只有新事实会改变范围、方案路径或验收标准时才重新规划。 +- Quick Fix 没有 Design 产物时,只做完成当前请求所需的局部选择,不补建方案或复制 Design 规则。 ### 2.2 最小 verify contract @@ -160,37 +163,7 @@ Stage B `code_quality` 至少检查: ## 步骤 3:知识库同步 -同步时机: - -1. 每完成一个模块任务后。 -2. 阶段收尾时做统一复核。 - -同步目标: - -- `project.md` -- `blueprint/background.md` -- `blueprint/design.md` -- `blueprint/tasks.md` -- `user/preferences.md`(仅长期偏好) -- `user/feedback.jsonl` - -正式判断口径: - -- `knowledge_sync.skip`:本轮不要求同步。 -- `knowledge_sync.review`:finalize 前至少复核。 -- `knowledge_sync.required`:未更新则 finalize 阻断。 - -偏好写入(保守策略): - -允许写入: - -- 用户明确表达长期偏好(如“以后默认...”)。 - -禁止写入: - -- 一次性指令。 -- 上下文不完整的猜测。 -- 与任务无关的泛化结论。 +实施收尾时调用 KB,按当前方案声明的 `knowledge_sync` 执行并记录结果。同步目标、长期知识判据和偏好写入政策由 KB 唯一负责;Develop 不在这里重新定义。 ## 步骤 4:方案完成态 diff --git a/skills/zh/skills/sopify/kb/SKILL.md b/skills/zh/skills/sopify/kb/SKILL.md index d94f805f..53df1f8c 100644 --- a/skills/zh/skills/sopify/kb/SKILL.md +++ b/skills/zh/skills/sopify/kb/SKILL.md @@ -1,126 +1,61 @@ --- name: kb -description: 知识库管理技能;知识库操作时读取;包含初始化、更新、同步策略 +description: 管理 `.sopify/` 长期知识;负责初始化、渐进物化、读取、保留和 knowledge_sync 政策。 --- -# 知识库管理 - V2 规则 +# 知识库管理 -**目标:** 管理 `.sopify/` 的 V2 分层知识,保持长期知识、活动方案与归档层职责清晰。 +KB 负责长期知识,不替 Analyze、Design 或 Develop 做阶段判断,也不直接管理活动方案、handoff、receipt 或 finalize。文档结构来自 Templates,协议状态由 `sopify_writer` 管理。 -## 知识库结构 +## 目录职责 ```text .sopify/ -├── blueprint/ -│ ├── README.md # 纯索引页,只保留索引必需区块 -│ ├── background.md # 长期目标、范围、非目标 -│ ├── design.md # 模块/宿主/目录/消费契约 -│ └── tasks.md # 未完成长期项与明确延后项 -├── project.md # 项目技术约定 -├── user/ -│ ├── preferences.md # 用户长期偏好 -│ └── feedback.jsonl # 原始反馈事件 -├── plan/ -│ └── YYYYMMDD_feature/ # 当前活动方案 -├── history/ -│ ├── index.md # 归档索引 -│ └── YYYY-MM/ -└── state/ # protocol state +├── project.md # 跨任务技术约定 +├── user/ # 长期偏好与原始反馈 +├── blueprint/ # 长期目标、设计边界、未完成长期项及索引 +├── plan/ # 当前方案语义文件 +├── history/ # 已归档方案与索引 +└── state/ # 本地协议状态 ``` -## 初始化策略 +`blueprint/README.md` 只保留状态、维护方式、当前目标、当前焦点和阅读入口。深层内容进入对应 blueprint 文件。 -### Full 模式 (`kb_init: full`) +## 初始化与渐进物化 -首次 bootstrap 直接创建: +`kb_init: full` 首次创建 `project.md`、`user/preferences.md`、`user/feedback.jsonl` 和四个 blueprint 文件;不预建方案正文、history 或空目录。 -```yaml -创建文件: - - .sopify/project.md - - .sopify/user/preferences.md - - .sopify/user/feedback.jsonl - - .sopify/blueprint/README.md - - .sopify/blueprint/background.md - - .sopify/blueprint/design.md - - .sopify/blueprint/tasks.md -``` - -注意: - -- 不预建 `plan/` 正文。 -- 不预建 `history/index.md` 或任何 archive。 +`kb_init: progressive` 为默认策略: -### Progressive 模式 (`kb_init: progressive`) [默认] +- 首次真实项目触发:创建 `project.md`、`user/preferences.md`、`blueprint/README.md`。 +- 首次进入 plan 生命周期:补齐 `blueprint/background.md`、`blueprint/design.md`、`blueprint/tasks.md` 和当前方案目录。 +- 首次显式 `~go finalize`:由协议流程创建 `history/index.md` 和归档目录。 +- 首次出现明确长期反馈:按需要创建 `user/feedback.jsonl`。 -按生命周期创建: +## 知识上下文读取 -```yaml -首次真实项目触发: - - .sopify/project.md - - .sopify/user/preferences.md - - .sopify/blueprint/README.md - -首次进入 plan 生命周期: - - .sopify/blueprint/background.md - - .sopify/blueprint/design.md - - .sopify/blueprint/tasks.md - - .sopify/plan/YYYYMMDD_feature/ - -首次显式 ~go finalize: - - .sopify/history/index.md - - .sopify/history/YYYY-MM/YYYYMMDD_feature/ - -首次出现明确长期偏好: - - .sopify/user/feedback.jsonl -``` - -## 上下文读取顺序 +宿主先按正式 Protocol 完成 managed plan、handoff 和 receipts 的入口读取。本节只规定 KB 自己的长期知识顺序: 1. `project.md` 2. `user/preferences.md` 3. `blueprint/README.md` -4. `blueprint/background.md` -5. `blueprint/design.md` -6. `blueprint/tasks.md` -7. `state/active_plan.json` → `plan//plan.md` - -读取规则: +4. 与当前任务有关的 `blueprint/background.md`、`design.md`、`tasks.md` -- 咨询/澄清优先消费 `L0/L1`,不强制要求 deep blueprint。 -- planning / develop 才进入 `L2 active plan`。 -- `active_plan.json` 只提供 `plan_id`;`plan.md` 是活动方案语义入口。接续时再按协议读取 handoff 与 receipts,不能回退到已退役的 current-plan 投影。 -- `history/` 不是默认长期上下文,只在 finalize 后查询或人工追溯时读取。 +Consult 和 quick fix 不因缺少深层 blueprint 失败。`history/` 只在追溯或 finalize 时读取。 -## 更新规则 +## 保留与更新 -### L0 索引约束 +只保留跨任务仍有价值的信息: -- `blueprint/README.md` 只保留 `状态 / 维护方式 / 当前目标 / 当前焦点 / 深入阅读入口`。 -- 不把绝对工作目录、架构正文、正式契约正文写进 `blueprint/README.md`。 -- 若 `blueprint/` 根层存在额外长期专题文档,必须在 `blueprint/README.md` 显式列出入口。 +- `project.md`:可复用技术约定。 +- `background.md`:长期目标、范围和非目标。 +- `design.md`:模块、宿主、目录和消费契约。 +- `tasks.md`:未完成长期项及有重访条件的明确延后项。 +- `preferences.md`:用户明确声明的长期偏好。 -### `blueprint/tasks.md` 边界 +不要写入一次性实现细节、当前 plan 的任务拆解、临时取舍、已完成任务或 history 正文副本。代码与文档冲突时先核对代码事实,再修正文档;当前用户指令优先于历史偏好。 -- 只保留未完成长期项与明确延后项。 -- `[x]` 已完成项不应继续保留在 `blueprint/tasks.md`。 - -### 必须更新 - -- `project.md`:跨任务可复用的技术约定变化。 -- `blueprint/background.md`:长期目标、范围、非目标变化。 -- `blueprint/design.md`:模块/宿主/目录/消费契约变化。 -- `blueprint/tasks.md`:长期未完成项或明确延后项变化。 -- `user/preferences.md`:用户明确声明长期偏好。 - -### 不应写入长期知识 - -- 一次性实现细节。 -- 当前 plan 的短期拆解。 -- 仅属于本轮任务的临时取舍。 -- 已完成任务清单继续滞留在 `blueprint/tasks.md`。 -- history 正文回灌到 blueprint。 - -## `knowledge_sync` 同步契约 +## `knowledge_sync` ```yaml knowledge_sync: @@ -130,48 +65,12 @@ knowledge_sync: tasks: skip|review|required ``` -执行要求: - -- `skip`:本轮不要求同步。 -- `review`:finalize 前至少复核。 -- `required`:未更新则 finalize 阻断。 - -## 冲突处理 - -- 代码与文档冲突:以代码现状为准,文档随后修正。 -- 当前任务与长期偏好冲突:当前任务明确要求 > `user/preferences.md` > 默认规则。 - -## 输出格式 - -**初始化完成:** - -```text -[{BRAND_NAME}] 知识库初始化 ✓ - -创建: {N} 文件 -策略: {full/progressive} - ---- -Changes: {N} files - - .sopify/project.md - - .sopify/blueprint/README.md - - ... - -Next: 知识库已就绪 -``` - -**同步完成:** +- `skip`:本轮不检查该文件。 +- `review`:finalize 前确认是否需要更新。 +- `required`:交付候选形成前必须更新;未完成时阻断 finalize。 -```text -[{BRAND_NAME}] 知识库同步 ✓ +KB 只执行方案声明的同步政策,不改变 plan 生命周期。同步时更新最窄的长期知识位置,避免在多个文件重复同一正文。 -更新: {N} 文件 +## 输出 ---- -Changes: {N} files - - .sopify/project.md - - .sopify/blueprint/design.md - - ... - -Next: 文档已更新 -``` +初始化或同步完成后,先说明实际结果,再列 `Changes`,最后给 `Next:`。没有变化时明确写 `Changes: 0 files`。 diff --git a/skills/zh/skills/sopify/references/output-contract.md b/skills/zh/skills/sopify/references/output-contract.md index 00568c42..8b98e1c4 100644 --- a/skills/zh/skills/sopify/references/output-contract.md +++ b/skills/zh/skills/sopify/references/output-contract.md @@ -1,74 +1,38 @@ # Sopify 输出契约 -所有阶段(analyze / design / develop / consult)的最终回复遵循以下契约。每节约束一个输出决策维度。 +最终回复应让用户快速知道结果、证据和下一步。阶段模板只规定必要信息,不要求机械填满所有区块。 -## 1. 输出路径说明 +## 输出路径 -- **Gate 摘要**:gate/routing 阶段的路由状态。只含阶段标题、状态行、Context、Changes、Next。不含验证表格、复审结论等 skill 级别内容。 -- **宿主最终回复**:skill 完成后的收口摘要。必须遵循对应模板,包含必需 section 和触发条件下的增强。 -- Gate 摘要 ≠ 最终回复。Gate 告诉宿主"做什么",宿主做完后按模板输出结果。 +- Gate 摘要只说明路由结果、当前状态和下一动作。 +- Skill 或咨询完成后,由宿主给出最终回复。最终回复必须反映实际结果,不能把 gate 文案当成交付结果。 -## 2. 必需 section 契约 +## 必要内容 -| 输出类型 | 必需 section | 必需表格 | 状态符约束 | -|---------|-------------|---------|-----------| -| develop/success | 复审结论行、验证摘要、Changes、Next | 验证摘要表 | ✓ 仅当全部 passed | -| develop/partial | 未完成项、验证摘要、Changes、Next | 未完成项表 + 验证摘要表 | 必须 ! | -| develop/quick-fix | 验证摘要、Changes、Next | 验证摘要简表 | ✓ 仅当全部 passed | -| analyze/success | 假设与前提、信息缺口、下一步理由、Changes、Next | — | — | -| analyze/question | 问题列表、Next | — | 必须 ? | -| design/summary | 评分行、Changes、Next | — | — | -| consult | Changes、Next | — (adaptive) | — | - -表格列约束:只展示当前场景有信息量的列。列省略只影响最终展示,不影响内部验证判断。`reason_code` 是内部验证字段,不在用户面输出中展示。 - -## 3. 条件增强与格式选择 - -不强制所有场景结构化。按信息形状和触发条件决定是否增强、用什么结构: - -| 触发条件 | 推荐表达 | 典型场景 | +| 输出类型 | 必要内容 | 状态要求 | |---------|---------|---------| -| 多项对比/取舍(>2 方案) | 表格 | 方案取舍、风险对比、宿主能力对比 | -| 流程/调用/生命周期 | 编号序列 | SDK 流程、gate → route → handoff | -| 文件/组件/模块组成 | 树状结构 | 组件拆分、模块结构、方案文件组织 | -| 评分维度需可见化 | 评分表 | analyze 评分 | -| 简单问答/状态确认 | 保持简洁 | 单一问题回答、状态确认 | - -约束:同一回复最多选一种主结构,避免表格 + 树 + 流程叠加。 - -### 3.1 输出密度梯度 - -按场景复杂度选择输出密度,避免简单任务输出过重: - -| 密度级别 | 适用场景 | 验证摘要形式 | -|---------|---------|------------| -| 精简 | quick-fix、单文件修改、咨询问答 | 简化表格(≤3 列),省略复审结论 | -| 标准 | 3-5 任务的常规 develop | 表格,省略无信息量列 | -| 完整 | 6+ 任务或跨模块交付 | 完整表格 + 分阶段复审结论 | - -密度级别由任务数和改动范围自动推断,不需要用户指定。 - -**DO:** -- 满足多方案取舍时用对比表,让差异一目了然 -- success 全部 passed 时简化验证摘要,省略无信息量列 -- 信息形状不匹配任何结构时保持纯文本 -- 按密度梯度裁剪输出:quick-fix 不输出完整验证表 -- 3+ 独立任务时按交付物分组输出,同类结论合并为一行 -- 正文(验证摘要、复审结论、Changes 区)不使用装饰性 emoji - -**DON'T:** -- 满足多方案取舍却无对比结构 = 漏增强 -- 强制在简单问答上叠加表格 = 过度增强 -- 同一回复混用两种以上主结构 = 认知过载 -- 5 个任务结果逐项展开相同 `passed` 结论 = 信息稀释 - -## 4. 输出前自检 - -输出最终回复前检查: - -1. 必需 section 是否存在:按 §2 核对当前输出类型的必需 section。 -2. 状态符是否正确:`✓` 仅当全部验证通过且无降级/跳过;否则必须 `!`。 -3. footer 是否完整:`Changes:` + `Next:` 必须存在。 -4. 条件增强是否触发:如当前回复满足 §3 增强触发条件,应使用对应结构化表达。 -5. 密度级别是否匹配:quick-fix 不应输出完整验证表;复杂交付不应缺少复审结论。 -6. 脱敏:`root_cause` 枚举值转人话描述;内部评分权重不外露;gate/handoff JSON 字段(`resolution_id`、`run_stage` 等)不展示。 +| `analyze/success` | 目标、交付物、完整性评分、已确认依据、实际采用的假设、实质缺口、下一步 | 信息不足时不能写成完成 | +| `analyze/question` | 少量关键问题、每个问题的影响、`Next` | `?` | +| `design/summary` | 方案路径、任务数、`Ready` 或 `Needs decision` 及依据、`Changes`、`Next` | 有实质未决选择时不能写 `Ready` | +| `develop/success` | 结果、复审结论、验证摘要、`Changes`、`Next` | 全部通过才用 `✓` | +| `develop/partial` | 未完成项、原因、已有验证、`Changes`、`Next` | `!` | +| `develop/quick-fix` | 结果、必要验证、`Changes`、`Next` | 全部通过才用 `✓` | +| `consult` | 结论、必要证据、`Changes`、`Next` | 按实际状态 | + +`consult_readonly` 不写代码、方案、state、知识库、audit、receipt 或 Git index。先给结论和必要证据;阻塞项或待决策项仅在存在时展示,然后停车。 + +## 结构和密度 + +- 简单问答和单文件修改用短段落;不要为了模板完整而加表格。 +- 多项取舍适合对比表,流程适合编号步骤,目录关系适合树状结构。同一回复只选一种主要结构。 +- 任务较多时按交付物合并结果,不逐项重复“通过”。 +- `Changes` 后必须以 `Next:` 收尾。没有文件变化时写 `Changes: 0 files`。 + +## 输出前检查 + +1. 开头是否直接回答当前问题。 +2. 状态符是否与实际验证一致。 +3. `Ready / Needs decision` 是否符合 Design 判据。 +4. 是否删掉了空区块、重复结论和内部字段。 +5. 文件、命令、数字和引用是否可核验。 +6. 是否包含完整 `Changes` 和最后一行 `Next:`。 diff --git a/skills/zh/skills/sopify/references/shared-writing-dna.md b/skills/zh/skills/sopify/references/shared-writing-dna.md index ca8e421e..344970cd 100644 --- a/skills/zh/skills/sopify/references/shared-writing-dna.md +++ b/skills/zh/skills/sopify/references/shared-writing-dna.md @@ -1,37 +1,29 @@ # Sopify 共享写作规范 -所有 skill(analyze / design / develop)的文字输出遵循以下 6 条规则。每条防止一类 LLM 输出事故。 +这些规则适用于所有 Skill 和咨询回复。它们约束表达,不替任何阶段做判断。 -## 规则 1:事实与推断分离 +## 先说结果 -- 推断必须标注"推断"或"可能" -- 量化指标需有来源或计算方式,否则用"约 N"或省略 -- 不把猜测写成结论 +- 先回答用户当前最关心的问题,再给必要证据和下一步。 +- 明确写出谁做什么、改了什么、为什么;避免只有“完成优化”“推进闭环”一类抽象结论。 +- 事实、推断和建议分开。推断说明依据,不把可能性写成事实。 -## 规则 2:一概念一术语 +## 只写有用的信息 -- 同一实体全文同名,不做同义词切换 -- 首次出现注释英文:✅ `飞书认证(Feishu Auth)` ❌ `Feishu 认证` -- 代码标识符用反引号:✅ `app_access_token` ❌ 应用访问令牌 +- 输出范围跟随任务范围,不补用户没有要求的章节。 +- 可选内容为空时整段省略,不保留占位标题或套话。 +- 同一概念使用同一术语;代码标识符、真实路径和命令保持原样并可核验。 +- 引用文件、函数、配置或数字前先确认存在;估算应标明依据或明确为估算。 -## 规则 3:最小化输出范围 +## 自然表达 -- 输出范围 = 任务范围,不加未要求的 section -- 不做投机抽象——当前不需要的扩展点不展开 -- 模板中的可选区块,无内容时整块省略而非留空壳 +- 中文使用完整、顺畅的句子。少用口号式短句、连续括号和抽象名词堆叠;技术词保留必要英文,不逐字翻译。 +- 英文按英语习惯组织句子。优先使用清楚的动词和具体主语,避免 noun stacks、corporate filler 和伪口语。 +- 中英文共享事实、边界和结论,但不要求逐句对应。 +- 段落围绕一个论点;结构能用短段落说清时,不强行使用表格或多级标题。 -## 规则 4:中英文排版 +## 排版 -- 中文与半角字符之间加空格:✅ `使用 API 获取 3 个 token` -- 中文正文使用全角标点:✅ `,。:;!?` -- 专有名词保持官方大小写:✅ `GitHub` `JavaScript` - -## 规则 5:段落约束 - -- 段落不超过 7 行,一段一个论点 -- 最多三级标题(`#` `##` `###`),不使用 `####` - -## 规则 6:引用可验证 - -- 文件路径、函数名、类名引用需确保实际存在 -- 不引用臆造的 API、配置项或文档章节 +- 中文与半角英文、数字之间留空格,使用全角中文标点。 +- 专有名词保持官方拼写,例如 `GitHub`、`JavaScript`。 +- 标题最多三级;正文不使用装饰性 emoji。 diff --git a/skills/zh/skills/sopify/templates/SKILL.md b/skills/zh/skills/sopify/templates/SKILL.md index b8322e0b..bea5aa6b 100644 --- a/skills/zh/skills/sopify/templates/SKILL.md +++ b/skills/zh/skills/sopify/templates/SKILL.md @@ -1,73 +1,70 @@ --- name: templates -description: 文档模板集合;创建文档时读取;包含所有知识库模板和方案文件模板 +description: 知识库文档模板;创建或补齐长期知识文件时按需读取。 --- -# 文档模板集合 +# 知识库模板 -**模板使用说明:** -1. 将 `{...}` 内容替换为实际内容。 -2. 正式 plan 包默认带评分区块。 -3. `blueprint/README.md` 只保留轻量入口索引。 -4. 若 `blueprint/` 根层存在额外长期专题文档,必须在 `blueprint/README.md` 里显式列入口。 -5. `blueprint/tasks.md` 只保留未完成长期项与明确延后项;已完成项不继续保留在该文件。 +Templates 只定义稳定的知识库文档结构,不决定写入时机、同步政策或方案生命周期。 -## A1 | 知识库文档模板 +- 知识库规则与 `knowledge_sync`:读取 `kb` Skill。 +- 方案级别 `light / standard / architecture` 及方案正文模板:读取 Design `assets/`。 +- 活动方案、handoff 和 receipts 的读取与写入:遵循正式 Protocol。 -### project.md +使用模板时替换占位符,删掉无内容的可选区块。不要把一次性实现细节写进长期知识。 + +## `project.md` ```markdown # 项目技术约定 ## 技术栈 -- 核心: {语言版本} / {框架版本} +- 核心: {语言或框架版本} - 构建: {构建工具} - 测试: {测试框架} ## 使用约定 -- 这里只沉淀可复用的长期技术约定。 -- 一次性实现细节不默认写入本文件。 +- {跨任务可复用的技术约定} ## 文档边界 -- `project.md`: 可复用技术约定 -- `blueprint/background.md`: 长期目标、范围、非目标 -- `blueprint/design.md`: 模块/宿主/目录/消费契约 +- `project.md`: 技术约定 +- `blueprint/background.md`: 长期目标、范围与非目标 +- `blueprint/design.md`: 模块、宿主、目录与消费契约 - `blueprint/tasks.md`: 未完成长期项与明确延后项 ``` -### blueprint/README.md +## `blueprint/README.md` ```markdown # 项目蓝图索引 状态: {当前状态} -维护方式: 仅保留状态、当前目标、当前焦点与阅读入口;长说明进入其他 blueprint 文件 +维护方式: 只保留状态、当前目标、当前焦点和阅读入口 ## 当前目标 -- 项目:`{项目名}` -- 长期目标与范围进入 `./background.md` +- {长期目标摘要} ## 当前焦点 -- 当前活动 plan:{有/无} -- history 归档:{状态} +- 活动方案: {无 / 链接到 plan.md} +- 归档状态: {状态} -## 深入阅读入口 +## 深入阅读 - [项目技术约定](../project.md) -- [蓝图背景](./background.md) -- [蓝图设计](./design.md) -- [蓝图任务](./tasks.md) -- [长期专题蓝图](./{extra_blueprint_doc}.md) # 如存在额外长期专题文档,则逐项列出 +- [背景](./background.md) +- [设计](./design.md) +- [任务](./tasks.md) - [变更历史](../history/index.md) ``` -### blueprint/background.md +如 `blueprint/` 根目录有长期专题文档,在“深入阅读”中逐项列出。 + +## `blueprint/background.md` ```markdown # 蓝图背景 ## 长期目标 -- {目标1} -- {目标2} +- {目标} ## 范围 - 范围内: {内容} @@ -77,147 +74,52 @@ description: 文档模板集合;创建文档时读取;包含所有知识库 - {内容} ``` -### blueprint/design.md +## `blueprint/design.md` ```markdown # 蓝图设计 ## 正式契约 -- `knowledge_sync` 是唯一正式同步契约。 -- `state/active_plan.json` 只提供 `plan_id`,活动方案语义入口固定为 `plan//plan.md`。 - -## 消费契约 +- {跨方案持续有效的契约} -| Context Profile | Reads | Fail-open Rule | Notes | -|-----|------|------|------| -| `consult` | `project.md`, `preferences.md`, `blueprint/README.md` | 缺 deep blueprint 不报错 | 不强制物化 plan | -| `plan` | `L1` + `active_plan.json → plan.md` | 缺 deep blueprint 时按生命周期补齐 | history 不是默认上下文 | -| `finalize` | `active_plan.json → plan.md`, `knowledge_sync`, `blueprint/*`, `history/index.md` | 缺 `history/index.md` 时现场创建 | `required` 未满足则阻断 | +## 模块与消费边界 +- {模块、宿主或目录职责} ``` -### blueprint/tasks.md +## `blueprint/tasks.md` ```markdown # 蓝图任务 -状态: 只保留未完成长期项与明确延后项;已完成项不继续留在本文件。 - ## 未完成长期项 - [ ] {长期项} ## 明确延后项 -- [-] {延后项} +- [-] {延后项与重访条件} ``` -### history/index.md +只保留未完成长期项和明确延后项,不保留 `[x]` 项。 + +## `history/index.md` ```markdown # 变更历史索引 -| 时间戳 | 功能名称 | 状态 | 方案包 | -|--------|----------|------|--------| -| {YYYYMMDD} | {功能} | ✓ | [链接](YYYY-MM/...) | +| 日期 | 功能 | 状态 | 方案包 | +|------|------|------|--------| +| {YYYY-MM-DD} | {功能} | {状态} | [链接](YYYY-MM/...) | ``` -### user/preferences.md +## `user/preferences.md` ```markdown # 用户长期偏好 -> 仅记录用户明确声明的长期偏好;一次性指令不入库。 - -当前暂无已确认的长期偏好。 +- {用户明确声明、可跨任务复用的偏好} ``` -### user/feedback.jsonl +## `user/feedback.jsonl` ```json -{"timestamp":"2026-01-15T10:30:00Z","source":"chat","message":"以后默认先给最小改动清单","scope":"planning","promote_to_preference":true,"preference_id":"pref-002"} -{"timestamp":"2026-01-15T11:10:00Z","source":"chat","message":"这次把输出写详细点","scope":"current_task","promote_to_preference":false} +{"timestamp":"{ISO-8601}","source":"chat","message":"{原始反馈}","scope":"{范围}","promote_to_preference":false} ``` - -## A2 | 方案文件模板 - -所有级别都先生成带 `level` frontmatter 的 `plan.md`;standard 再增加 `tasks.md`,architecture 再增加 `design.md`。支持性 ADR、图和证据按需创建,不预建空目录。 - -### 所有级别 - plan.md - -```markdown ---- -title: {功能名称} -plan_id: {YYYYMMDD_feature} -level: {light|standard|architecture} ---- - -# {功能名称} - -评分: -- 方案质量: {X}/10 -- 落地就绪: {Y}/10 - -## Context / Why -{为什么要做} - -## Scope -{本次包含什么} - -## Approach -{最小可行方法} - -## Waves / Steps -- [ ] {步骤 1} - -## Key Decisions -- {已确认决策} - -## Constraints / Not-in-scope -- {明确不做什么} - -## Status / Progress -- [ ] {当前状态} - -## Next -{下一步或等待确认事项} -``` - -### Standard / Architecture - tasks.md - -```markdown -# 任务清单: {功能名称} - -目录: `.sopify/plan/{YYYYMMDD}_{feature}/` - -## 1. {模块名称} -- [ ] 1.1 在 `{文件路径}` 中实现 {功能} -- [ ] 1.2 在 `{文件路径}` 中实现 {功能} - -## 2. 测试 -- [ ] 2.1 {测试任务} - -## 3. 文档更新 -- [ ] 3.1 更新 `project.md / blueprint/background.md / blueprint/design.md / blueprint/tasks.md` -``` - -### Architecture - design.md - -```markdown -# 技术设计: {功能名称} - -## 技术方案 -- {实现要点} - -## 架构边界 -{模块关系与责任边界} - -## 验证策略 -- {验证方式} -``` - -## A3 | 任务状态符号 - -| 符号 | 含义 | -|-----|------| -| `[ ]` | 待执行 | -| `[x]` | 已完成 | -| `[-]` | 已跳过 | -| `[!]` | 阻塞中 | diff --git a/tests/behavior-scenarios/plain-language-output-v1.json b/tests/behavior-scenarios/plain-language-output-v1.json new file mode 100644 index 00000000..339884db --- /dev/null +++ b/tests/behavior-scenarios/plain-language-output-v1.json @@ -0,0 +1,76 @@ +{ + "schema_version": 1, + "source_revision": "ea92482cec1e93f41cbe63b68e1b067805f5dfd0", + "copilot_baseline": { + "zh-CN": {"characters": 36745, "bytes": 56414, "lines": 1919}, + "en-US": {"characters": 60734, "bytes": 61071, "lines": 1918} + }, + "copilot_after": { + "zh-CN": {"characters": 24154, "bytes": 41941, "lines": 1227}, + "en-US": {"characters": 45879, "bytes": 46086, "lines": 1226} + }, + "scenarios": [ + { + "scenario_id": "consult-readonly-zh-v1", + "language": "zh-CN", + "surface": "host/consult_readonly", + "input": "分析下,不改,等我确认。", + "evidence": [".sopify/blueprint/protocol.md#8"], + "expected_behavior": ["给出结论和必要证据", "仅在存在时列阻塞项或待决策项", "停车等待确认"], + "allowed_write_set": [] + }, + { + "scenario_id": "consult-readonly-en-v1", + "language": "en-US", + "surface": "host/consult_readonly", + "input": "Analyze this only. Do not change anything; wait for my confirmation.", + "evidence": [".sopify/blueprint/protocol.md#8"], + "expected_behavior": ["state the conclusion and necessary evidence", "include blockers or decisions only when present", "stop for confirmation"], + "allowed_write_set": [] + }, + { + "scenario_id": "analyze-user-material-v1", + "language": "bilingual", + "surface": "skill/analyze", + "input": "The user supplies a document, API material, design context, and a suggested implementation.", + "evidence": ["user material", "repository code", "governing contract"], + "expected_behavior": ["read accessible evidence first", "separate objective, deliverable, and candidate path", "ask only decision-relevant questions"], + "allowed_write_set": [] + }, + { + "scenario_id": "design-smallest-sufficient-v1", + "language": "bilingual", + "surface": "skill/design", + "input": "Choose between existing project capability and adding a new dependency.", + "evidence": ["existing implementation", "governing contract", "installed dependencies"], + "expected_behavior": ["check the current system", "choose the smallest sufficient path", "report Ready or Needs decision with evidence"], + "allowed_write_set": [".sopify/plan//"] + }, + { + "scenario_id": "develop-common-root-v1", + "language": "bilingual", + "surface": "skill/develop", + "input": "A bug crosses a shared boundary and affects several callers.", + "evidence": ["call sites", "tests", "approved plan"], + "expected_behavior": ["inspect affected callers", "fix the narrowest common root cause", "verify equivalent paths without widening scope"], + "allowed_write_set": ["approved implementation", "approved tests", "required knowledge sync"] + }, + { + "scenario_id": "managed-plan-knowledge-sync-v1", + "language": "bilingual", + "surface": "host/managed-plan", + "input": "Finish implementation while preserving protocol and knowledge ownership.", + "evidence": ["active plan", "knowledge_sync", "verification results"], + "expected_behavior": ["keep plan lifecycle in protocol and writer", "write only reusable knowledge", "stop at explicit checkpoints"], + "allowed_write_set": ["approved implementation", "plan semantic files", "required knowledge sync", "approved audit evidence"] + } + ], + "comparison": [ + {"scenario_id": "consult-readonly-zh-v1", "baseline": "protocol existed but no explicit host example", "after": "explicit zero-write contract in header and shared output contract"}, + {"scenario_id": "consult-readonly-en-v1", "baseline": "protocol existed but no explicit host example", "after": "equivalent zero-write contract in English"}, + {"scenario_id": "analyze-user-material-v1", "baseline": "context rules prioritized KB and could ask before reading supplied material", "after": "evidence-first handoff separates objective, deliverable, and candidate path"}, + {"scenario_id": "design-smallest-sufficient-v1", "baseline": "subjective dual scores and duplicated plan templates", "after": "Ready or Needs decision with evidence; Design assets are the sole plan-template owner"}, + {"scenario_id": "develop-common-root-v1", "baseline": "verification loop did not state the shared-root behavior", "after": "caller check, narrow common-root fix, and equivalent-path verification are explicit"}, + {"scenario_id": "managed-plan-knowledge-sync-v1", "baseline": "KB and Templates entry files repeated responsibilities and plan shapes", "after": "KB owns long-lived policy, Templates owns KB shapes, and protocol owns lifecycle"} + ] +} diff --git a/tests/golden-snapshots.json b/tests/golden-snapshots.json index 7e542ae1..0608c89c 100644 --- a/tests/golden-snapshots.json +++ b/tests/golden-snapshots.json @@ -8,13 +8,13 @@ }, "protocol_version": "1.0", "snapshots": { - "codex:zh-CN:header": "896aeabaa8fd9cad5d5ba6012625e8079763d9280bad635bb30f94cf8d84596e", - "codex:en-US:header": "b14eb827816af17b13ddce7d0f799e21b57c12607ff2a6311f6ddfc4b2d639cc", - "claude:zh-CN:header": "0456c105cc51dcdf2ac2ee94324d32e04ded54b0b5ca8f47a630b9e4ffe98f12", - "claude:en-US:header": "212a04e1d15ec1417ede205aeb74d71790fa5e1d4678b51fc7ab9f60a6e3afc5", - "copilot:zh-CN:managed_block_payload": "6ba7e87904473dc3138d49e7f681aeb4aae37e32bb81e04002879a36c5713017", - "skills:zh-CN:tree": "4869836b785233879fa62a6c101a4634ce7f3ac6ec6e18cef6f96f6e65629447", - "copilot:en-US:managed_block_payload": "6b16ed4893d90ae1bbb8793def8db136d4bb098c366032701500cde51e1b1408", - "skills:en-US:tree": "76da619fd73029fe30c842515c82a13252fd497a7f8dd3550c56e7656454a999" + "codex:zh-CN:header": "b70f95b07b89c5eb4c91db6b79cb2b9924d7dde5ce087a45eceb9c79fe0eb4ba", + "codex:en-US:header": "a8dced69b654d5dc9fc81034fda7fefc9b686a02004e2996bc52e04fb1c7ee03", + "claude:zh-CN:header": "b25b09db3cfc17b76b721090f8418ca732c84c1cbd483868f28e2c7512e18176", + "claude:en-US:header": "fd00126d0b0d3b15b6d3e610aef3876fa0c2d4f401ec8e99426aa190673d7ae6", + "copilot:zh-CN:managed_block_payload": "5cc188b8d78de5a10a09e2b5b16fc34193757c295b9ef33f6d43883f054b0dfe", + "skills:zh-CN:tree": "cd21df587f683acc612c833fc5d57e5d6fb8d954f69e68585b62f4bf5fd571c3", + "copilot:en-US:managed_block_payload": "6a6a3b9a227a789ccdc96e34f1b4d7d911ae7185eec7a0dfbad0f6ac0fd4b5e9", + "skills:en-US:tree": "601ab7dacf8157848dc9d85f7420089c287a788d6746575115bcf74114b8113f" } } diff --git a/tests/test_golden_snapshots.py b/tests/test_golden_snapshots.py index 4073cb48..327e1f9a 100644 --- a/tests/test_golden_snapshots.py +++ b/tests/test_golden_snapshots.py @@ -142,16 +142,16 @@ def test_skill_tree_snapshot(lang_dir: str, locale: str) -> None: ("develop/assets/output-success.md", ["| 任务 |", "| 验证来源 |", "Changes:", "Next:"]), ("develop/assets/output-partial.md", ["| 任务 |", "| 阻塞原因 |", "| 验证来源 |", "Changes:", "Next:"]), ("develop/assets/output-quick-fix.md", ["| 验证来源 |", "Changes:", "Next:"]), - ("analyze/assets/success-output.md", ["假设与前提:", "已识别信息缺口:", "Changes:", "Next:"]), - ("design/assets/output-summary.md", ["方案质量:", "落地就绪:", "Changes:", "Next:"]), + ("analyze/assets/success-output.md", ["已确认依据:", "仍会影响结果的缺口", "Changes:", "Next:"]), + ("design/assets/output-summary.md", ["就绪状态:", "依据:", "Changes:", "Next:"]), ] _EN_TEMPLATE_MARKERS: list[tuple[str, list[str]]] = [ ("develop/assets/output-success.md", ["| Task |", "| Source |", "Changes:", "Next:"]), ("develop/assets/output-partial.md", ["| Task |", "| Block reason |", "| Source |", "Changes:", "Next:"]), ("develop/assets/output-quick-fix.md", ["| Source |", "Changes:", "Next:"]), - ("analyze/assets/success-output.md", ["Assumptions:", "Identified gaps:", "Changes:", "Next:"]), - ("design/assets/output-summary.md", ["Solution quality:", "Implementation readiness:", "Changes:", "Next:"]), + ("analyze/assets/success-output.md", ["Confirmed evidence:", "Material gaps", "Changes:", "Next:"]), + ("design/assets/output-summary.md", ["Readiness:", "Evidence:", "Changes:", "Next:"]), ] @@ -192,8 +192,8 @@ def _render_full(adapter: HostAdapter, lang_dir: str) -> str: return render_single_file(header_source, skills_source, adapter) -_OUTPUT_CONTRACT_ZH_MARKERS = ["输出契约", "必需 section", "条件增强与格式选择"] -_OUTPUT_CONTRACT_EN_MARKERS = ["Output Contract", "Required Sections", "Conditional Enhancement & Format Selection"] +_OUTPUT_CONTRACT_ZH_MARKERS = ["输出契约", "必要内容", "结构和密度"] +_OUTPUT_CONTRACT_EN_MARKERS = ["Output Contract", "Required content", "Structure and density"] @pytest.mark.parametrize( diff --git a/tests/test_plain_language_contracts.py b/tests/test_plain_language_contracts.py new file mode 100644 index 00000000..621f72b7 --- /dev/null +++ b/tests/test_plain_language_contracts.py @@ -0,0 +1,270 @@ +from __future__ import annotations + +import json +from pathlib import Path +import tempfile + +import pytest + +from installer.hosts.base import HEADER_TEMPLATE_NAME, install_host_assets, render_single_file +from installer.hosts.copilot import COPILOT_ADAPTER +from installer.hosts.qoder import QODER_ADAPTER +from installer.validate import validate_host_install + + +REPO_ROOT = Path(__file__).resolve().parents[1] +SCENARIOS = REPO_ROOT / "tests" / "behavior-scenarios" / "plain-language-output-v1.json" + + +def _jpeg_dimensions(path: Path) -> tuple[int, int]: + data = path.read_bytes() + assert data.startswith(b"\xff\xd8") + offset = 2 + start_of_frame = {0xC0, 0xC1, 0xC2, 0xC3, 0xC5, 0xC6, 0xC7, 0xC9, 0xCA, 0xCB, 0xCD, 0xCE, 0xCF} + + while offset < len(data): + assert data[offset] == 0xFF + while offset < len(data) and data[offset] == 0xFF: + offset += 1 + marker = data[offset] + offset += 1 + if marker in start_of_frame: + height = int.from_bytes(data[offset + 3 : offset + 5], "big") + width = int.from_bytes(data[offset + 5 : offset + 7], "big") + return width, height + if marker in {0xD9, 0xDA}: + break + segment_length = int.from_bytes(data[offset : offset + 2], "big") + offset += segment_length + + raise AssertionError(f"JPEG dimensions not found: {path}") + + +def _skill_file(language: str, relative: str) -> str: + return ( + REPO_ROOT / "skills" / language / "skills" / "sopify" / relative + ).read_text(encoding="utf-8") + + +def test_bilingual_skill_trees_have_the_same_files() -> None: + roots = [REPO_ROOT / "skills" / language / "skills" / "sopify" for language in ("zh", "en")] + trees = [ + {path.relative_to(root).as_posix() for path in root.rglob("*") if path.is_file()} + for root in roots + ] + assert trees[0] == trees[1] + + +def test_behavior_scenarios_are_versioned_and_bounded() -> None: + payload = json.loads(SCENARIOS.read_text(encoding="utf-8")) + assert payload["schema_version"] == 1 + assert len(payload["scenarios"]) == 6 + assert len(payload["comparison"]) == 6 + assert len(payload["source_revision"]) == 40 + + required = { + "scenario_id", + "language", + "surface", + "input", + "evidence", + "expected_behavior", + "allowed_write_set", + } + assert all(required <= scenario.keys() for scenario in payload["scenarios"]) + readonly = [ + scenario + for scenario in payload["scenarios"] + if scenario["surface"] == "host/consult_readonly" + ] + assert {scenario["language"] for scenario in readonly} == {"zh-CN", "en-US"} + assert all(scenario["allowed_write_set"] == [] for scenario in readonly) + for language, locale in (("zh", "zh-CN"), ("en", "en-US")): + source_root = REPO_ROOT / "skills" / language + rendered = render_single_file( + source_root / HEADER_TEMPLATE_NAME, + source_root / "skills" / "sopify", + COPILOT_ADAPTER, + ) + current = { + "characters": len(rendered), + "bytes": len(rendered.encode("utf-8")), + "lines": len(rendered.splitlines()), + } + baseline = payload["copilot_baseline"][locale] + observed_after = payload["copilot_after"][locale] + assert current.keys() == baseline.keys() == observed_after.keys() + assert all(current[metric] < baseline[metric] for metric in current) + assert all(observed_after[metric] < baseline[metric] for metric in observed_after) + + +@pytest.mark.parametrize("language", ["zh", "en"]) +def test_design_owns_plan_templates_and_uses_readiness(language: str) -> None: + design_rules = _skill_file(language, "design/references/design-rules.md") + plan_template = _skill_file(language, "design/assets/plan-template.md") + summary = _skill_file(language, "design/assets/output-summary.md") + templates = _skill_file(language, "templates/SKILL.md") + + assert "Ready" in design_rules and "Needs decision" in design_rules + assert "`strict`" in design_rules and "`adaptive`" in design_rules + assert "Ready" in plan_template and "Needs decision" in plan_template + assert "Ready" in summary and "Needs decision" in summary + assert "Solution quality" not in plan_template + assert "方案质量" not in plan_template + assert "## A2" not in templates + assert "Protocol" in templates + assert "plan//plan.md" not in templates + + +@pytest.mark.parametrize("language", ["zh", "en"]) +def test_phase_owners_keep_their_boundaries(language: str) -> None: + analyze = _skill_file(language, "analyze/references/analyze-rules.md") + analyze_output = _skill_file(language, "analyze/assets/success-output.md") + develop = _skill_file(language, "develop/references/develop-rules.md") + kb = _skill_file(language, "kb/SKILL.md") + output_contract = _skill_file(language, "references/output-contract.md") + + assert "consult_readonly" in analyze + assert "`strict`" in analyze and "`adaptive`" in analyze + assert "证据来源不限" in analyze or "not an exhaustive source list" in analyze + assert "Deliverable:" in analyze_output or "交付物:" in analyze_output + assert "Assumptions used" in analyze_output or "本次采用的假设" in analyze_output + assert "Type:" not in analyze_output and "类型:" not in analyze_output + assert "explicit assumptions when used" in output_contract or "实际采用的假设" in output_contract + assert "common root cause" in develop or "共同根因" in develop + assert "knowledge_sync" in kb + assert "sopify_writer" in kb + + +@pytest.mark.parametrize("language", ["zh", "en"]) +def test_copilot_single_file_has_no_script_source_or_dangling_path(language: str) -> None: + source_root = REPO_ROOT / "skills" / language + rendered = render_single_file( + source_root / HEADER_TEMPLATE_NAME, + source_root / "skills" / "sopify", + COPILOT_ADAPTER, + ) + + assert "