{"_id":"@caesarlo/sdlc-harness","_rev":"5-c35adb60b3c7f6855fe29ee80cf73ff8","name":"@caesarlo/sdlc-harness","dist-tags":{"latest":"0.3.2"},"versions":{"0.1.0":{"name":"@caesarlo/sdlc-harness","version":"0.1.0","license":"MIT","_id":"@caesarlo/sdlc-harness@0.1.0","maintainers":[{"name":"caesarlo","email":"ganjiaxin8670@gmail.com"}],"bin":{"sdlc-harness":"src/cli.js"},"dist":{"shasum":"46987023efc4bf9bf9ef4c0921bb5af87f613b81","tarball":"https://registry.npmjs.org/@caesarlo/sdlc-harness/-/sdlc-harness-0.1.0.tgz","fileCount":83,"integrity":"sha512-R5Mn/SAIkJ3m0PA9q7giYkMVIL9tltUQMQFVgCvR4z2Sb/mOHYtUmZ79VuViQyUhTJwzt++vgg7Ifc/Qqdwqyg==","signatures":[{"sig":"MEUCIQDmn9yCA2P/o5HAxsEWvnS0h1Nd1l84DUV20ojnH8UcDgIgDWa2lLOoiCSBPH4OyAoGYIRcytj46P/AsecD41dlpww=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":241916},"type":"module","engines":{"node":">=22"},"gitHead":"820e7344129646b5d8d399d2949f0b33fa6201dc","scripts":{"test":"node --test"},"_npmUser":{"name":"caesarlo","email":"ganjiaxin8670@gmail.com"},"_npmVersion":"11.5.1","description":"Portable CLI and workflow docs for a requirements-to-deployment coding-agent harness","directories":{},"_nodeVersion":"24.2.0","dependencies":{"ajv":"^8.20.0"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/sdlc-harness_0.1.0_1786716549067_0.78469578487307","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@caesarlo/sdlc-harness","version":"0.2.0","license":"MIT","_id":"@caesarlo/sdlc-harness@0.2.0","maintainers":[{"name":"caesarlo","email":"ganjiaxin8670@gmail.com"}],"bin":{"sdlc-harness":"src/cli.js"},"dist":{"shasum":"bfe10dfa4c76115bc3d5025eac3dc7ba3e7aa6e1","tarball":"https://registry.npmjs.org/@caesarlo/sdlc-harness/-/sdlc-harness-0.2.0.tgz","fileCount":83,"integrity":"sha512-nc/95sNOSfGdiDWrYo2IlNkCqtGYglbnhEaCcm3Wa5yJC8tYStgPYgOe7ZF3RROGPo12/6AExzx88azyNQZ4Dg==","signatures":[{"sig":"MEYCIQC4eCszpugpJfG8U6jCPSpE6Qyj4ECkxSr6BuUX9pgoFAIhAI0L6WLqjJBHlHt7uuPAefCe4sLdzlRFOUvEzTVI7gm/","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":241916},"type":"module","engines":{"node":">=22"},"gitHead":"eb90c1791f96445964c7b0160993eba813caab92","scripts":{"test":"node --test"},"_npmUser":{"name":"caesarlo","email":"ganjiaxin8670@gmail.com"},"_npmVersion":"11.5.1","description":"Portable CLI and workflow docs for a requirements-to-deployment coding-agent harness","directories":{},"_nodeVersion":"24.2.0","dependencies":{"ajv":"^8.20.0"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/sdlc-harness_0.2.0_1787189799114_0.6525305323966188","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"name":"@caesarlo/sdlc-harness","version":"0.3.0","license":"MIT","_id":"@caesarlo/sdlc-harness@0.3.0","maintainers":[{"name":"caesarlo","email":"ganjiaxin8670@gmail.com"}],"bin":{"sdlc-harness":"src/cli.js"},"dist":{"shasum":"edffd44f9b1b107e5fb7056371c3d7d7d0a74a99","tarball":"https://registry.npmjs.org/@caesarlo/sdlc-harness/-/sdlc-harness-0.3.0.tgz","fileCount":84,"integrity":"sha512-nLbK4tthoTQng8g+M4krQibH+nznkdPbheRlLNRRfNRGAYYNrQujpBpDHrtUTQRUr8Eaixiwq/E4nLfyITscnA==","signatures":[{"sig":"MEYCIQDiNJ6O2Hl359AFOH0HKcXItH5mmg73J/35+rcAE4xGKgIhALsL9S+5ZmYRdzcQuz1bhm+QFvzJbRA5q/YNCFoXsCNq","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":257026},"type":"module","engines":{"node":">=22"},"gitHead":"a8b046eb0a7f4dfc94c3fa61a621be8d3f0566e1","scripts":{"test":"node --test"},"_npmUser":{"name":"caesarlo","email":"ganjiaxin8670@gmail.com"},"_npmVersion":"11.5.1","description":"Portable CLI and workflow docs for a requirements-to-deployment coding-agent harness","directories":{},"_nodeVersion":"24.2.0","dependencies":{"ajv":"^8.20.0"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/sdlc-harness_0.3.0_1787196911607_0.6118460347596422","host":"s3://npm-registry-packages-npm-production"}},"0.3.1":{"name":"@caesarlo/sdlc-harness","version":"0.3.1","license":"MIT","_id":"@caesarlo/sdlc-harness@0.3.1","maintainers":[{"name":"caesarlo","email":"ganjiaxin8670@gmail.com"}],"bin":{"sdlc-harness":"src/cli.js"},"dist":{"shasum":"6edeb4eb4cb2747965bdefef397827aff231a72f","tarball":"https://registry.npmjs.org/@caesarlo/sdlc-harness/-/sdlc-harness-0.3.1.tgz","fileCount":84,"integrity":"sha512-kHKHZ7uy+QHuqIa4c8jgN9C++OC76W2qVpUecC10pYsC9ALO0clcyrl7MXpvwSmlr72Rop0sM6sJIdQk+3Hbog==","signatures":[{"sig":"MEUCIDUjXvT8Q8OV11vjaPX0fU00ti/meoygt3BtwehL4nR4AiEA8OGEUF6XxHzGfpAHjUUEGFy/LlbEyFojMpXUaCaRqEs=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":257499},"type":"module","engines":{"node":">=22"},"gitHead":"b43bfb07e192a413a581e40b4309821c9a8b37a2","scripts":{"test":"node --test"},"_npmUser":{"name":"caesarlo","email":"ganjiaxin8670@gmail.com"},"_npmVersion":"11.5.1","description":"Portable CLI and workflow docs for a requirements-to-deployment coding-agent harness","directories":{},"_nodeVersion":"24.2.0","dependencies":{"ajv":"^8.20.0"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/sdlc-harness_0.3.1_1787646381904_0.7057795379315543","host":"s3://npm-registry-packages-npm-production"}},"0.3.2":{"name":"@caesarlo/sdlc-harness","version":"0.3.2","description":"Portable CLI and workflow docs for a requirements-to-deployment coding-agent harness","type":"module","bin":{"sdlc-harness":"src/cli.js"},"engines":{"node":">=22"},"scripts":{"test":"node --test"},"license":"MIT","dependencies":{"ajv":"^8.20.0"},"_id":"@caesarlo/sdlc-harness@0.3.2","gitHead":"278450e70b14ff808b30c4659d2e55fb55ce65d8","_nodeVersion":"24.2.0","_npmVersion":"11.5.1","dist":{"integrity":"sha512-QxCkcaBWUhDds9ximgwusJXB3xvBO6hiM8ZisVD/Z4kx3eQZsNSPUPs5yLT1hSK0Zz/piDQ6J5juj82TtLHqcw==","shasum":"c02e68ac041818c7f13c9b32300630e230838875","tarball":"https://registry.npmjs.org/@caesarlo/sdlc-harness/-/sdlc-harness-0.3.2.tgz","fileCount":84,"unpackedSize":258549,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQDp3SOLJqeaH7K1IIWTmhhCWrhJ2VfQrIFJKsKDKIbNLAIhAKHK+1Bh39KnVuZWez/pW9SBTRYMgZPndhlEWtxfe0wt"}]},"_npmUser":{"name":"caesarlo","email":"ganjiaxin8670@gmail.com"},"directories":{},"maintainers":[{"name":"caesarlo","email":"ganjiaxin8670@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/sdlc-harness_0.3.2_1787646797733_0.4231641745382364"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-14T14:09:08.925Z","modified":"2026-08-25T08:33:18.032Z","0.1.0":"2026-08-14T14:09:09.218Z","0.2.0":"2026-08-20T01:36:39.270Z","0.3.0":"2026-08-20T03:35:11.764Z","0.3.1":"2026-08-25T08:26:22.126Z","0.3.2":"2026-08-25T08:33:17.879Z"},"license":"MIT","description":"Portable CLI and workflow docs for a requirements-to-deployment coding-agent harness","maintainers":[{"name":"caesarlo","email":"ganjiaxin8670@gmail.com"}],"readme":"<p align=\"center\">\n  <picture>\n    <source media=\"(prefers-color-scheme: dark)\" srcset=\"docs/assets/sdlc-harness-banner-dark.png\">\n    <source media=\"(prefers-color-scheme: light)\" srcset=\"docs/assets/sdlc-harness-banner-light.png\">\n    <img src=\"docs/assets/sdlc-harness-banner-light.png\" alt=\"包含分支路径和验证检查点的软件开发生命周期\" width=\"100%\">\n  </picture>\n</p>\n\n<h1 align=\"center\">SDLC-Harness</h1>\n\n<p align=\"center\">\n  <a href=\"package.json\"><img src=\"https://img.shields.io/badge/version-0.1.0-f59e0b?style=flat-square&labelColor=262626\" alt=\"版本 0.1.0\"></a>\n  <a href=\"package.json\"><img src=\"https://img.shields.io/badge/Node.js-%3E%3D22-339933?style=flat-square&logo=nodedotjs&logoColor=white&labelColor=262626\" alt=\"Node.js 22 或更高版本\"></a>\n  <a href=\"LICENSE\"><img src=\"https://img.shields.io/badge/license-MIT-2563eb?style=flat-square&labelColor=262626\" alt=\"MIT 许可证\"></a>\n  <a href=\"https://www.gump.top/sdlc-harness-docs/\"><img src=\"https://img.shields.io/badge/docs-www.gump.top-8b5cf6?style=flat-square&labelColor=262626\" alt=\"文档站点\"></a>\n</p>\n\n<p align=\"center\">\n  <a href=\"README.md\"><img src=\"https://img.shields.io/badge/README-English-6b7280?style=flat-square&labelColor=262626\" alt=\"Read in English\"></a>\n  <a href=\"README.zh-CN.md\"><img src=\"https://img.shields.io/badge/README-%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87-2563eb?style=flat-square&labelColor=262626\" alt=\"阅读简体中文版本\"></a>\n</p>\n\n<p align=\"center\">\n  <strong>给编码 Agent 一套可持续、可验证的软件开发工作流。</strong>\n</p>\n\n<p align=\"center\">\n  面向编码 Agent 的仓库原生<strong>软件开发生命周期</strong>（Software Development Life Cycle，SDLC）治理工具。\n</p>\n\n<p align=\"center\">\n  <a href=\"#快速开始\">快速开始</a>  · \n  <a href=\"#完整-sdlc-工作流\">工作流</a>  · \n  <a href=\"#命令\">命令</a>  · \n  <a href=\"https://www.gump.top/sdlc-harness-docs/\">完整文档</a>\n</p>\n\n<p align=\"center\"><code>npx @caesarlo/sdlc-harness adopt</code></p>\n\n**软件开发生命周期**（Software Development Life Cycle，SDLC）是软件从需求与架构设计，经过\n实现、验证和部署，再到上线后反馈的完整过程。`sdlc-harness` 将这套过程转化为一套安装在代码\n仓库中的编码 Agent 工作协议。\n\n需求、架构决策、功能状态、依赖关系、验证记录和进度检查点都与代码一起保存，不再随着聊天\n记录消失。\n\n它不绑定特定 Agent：任何能够读取 `AGENTS.md` 和仓库文件的编码 Agent 都可以遵循这套流程。\nClaude Code 还会获得轻量的 skill 包装，方便发现和调用各个阶段。\n\n## 它解决什么问题\n\n编码 Agent 可以快速编写代码，但工作很容易在跨会话时发生漂移：\n\n- 下一个 Agent 不知道一次改动为什么开始；\n- 尚未完成的功能被报告为已经完成；\n- 功能失去与需求和架构决策的关联；\n- 多项任务同时处于“进行中”；\n- 进度只存在于之后可能无法访问的对话里。\n\n`sdlc-harness` 让仓库成为唯一状态源，并提供一个能被 Git hook 或 CI 调用的命令，用于拒绝\n不一致的状态。\n\n## 快速开始\n\n需要 **Node.js 22 或更高版本**。\n\n> [!TIP]\n> `adopt` 只创建缺失文件，不会覆盖已有文件；被跳过的文件会列出来供你手动检查。如果仓库\n> 已经有自己的 `AGENTS.md`，adopt 不会修改它，而是把 harness 的路由/规则内容写入\n> `AGENTS.sdlc-harness.md`，并提示你需要在已有的 `AGENTS.md` 里加一行引用。在补上这行引用\n> 之前，`validate` 会一直报 `agents-onboarding` 错误，所以这件事不会被悄悄遗忘。\n\n### 添加到已有仓库\n\n```bash\ncd your-project\nnpx @caesarlo/sdlc-harness adopt\ngit config core.hooksPath .githooks\nnpx @caesarlo/sdlc-harness validate\nnpx @caesarlo/sdlc-harness status\n```\n\n### 在空仓库中开始\n\n```bash\nmkdir your-project && cd your-project\nnpx @caesarlo/sdlc-harness init\ngit config core.hooksPath .githooks\nnpx @caesarlo/sdlc-harness validate\n```\n\n然后让你的编码 Agent 先阅读 `AGENTS.md`，协助定义或拆解第一个实际里程碑。\n\n## Agent 的工作方式会发生什么变化\n\n```mermaid\nflowchart LR\n    Goal[\"开发者提出目标\"] --> Guide[\"Agent 读取 AGENTS.md\"]\n    Guide --> State[\"读取当前功能、依赖和 source_refs\"]\n    State --> Work[\"实现并验证一个功能\"]\n    Work --> Evidence[\"记录验证与 review 证据\"]\n    Evidence --> Validate[\"sdlc-harness validate\"]\n    Validate -->|通过| Ship[\"提交 / CI / 部署\"]\n    Validate -->|失败| Work\n    Ship --> Checkpoint[\"更新 progress.md\"]\n    Checkpoint --> Guide\n```\n\n这套 harness 提供三层能力：\n\n- **持久上下文** — `AGENTS.md`、`feature_list.json`、ADR、工作流文档和 `progress.md`\n  可以跨 Agent、跨会话保留。\n- **明确的完成规则** — 每个 owner 同时最多只能有 `wip_limit_per_owner`（默认 1）个活动功能；\n  依赖必须有效；标记为 `passing` 的功能必须记录证据，并包含 review 条目。\n- **可执行的治理** — 当仓库状态违反协议时，`sdlc-harness validate` 会以非零状态退出，\n  因此同一套规则可以同时用于本地和 CI。\n\n## 实际效果\n\n`status` 为 Agent 和开发者提供同一份机器可读的当前工作视图：\n\n```bash\nnpx @caesarlo/sdlc-harness status\n```\n\n```json\n{\n  \"project\": \"checkout-service\",\n  \"counts\": {\n    \"not_started\": 4,\n    \"in_progress\": 1,\n    \"blocked\": 0,\n    \"passing\": 6\n  },\n  \"activeFeatures\": [\n    {\n      \"id\": \"M1-CHECKOUT-003\",\n      \"title\": \"Handle payment timeout\",\n      \"behavior\": \"A timed-out payment returns a recoverable error.\",\n      \"owner\": null\n    }\n  ],\n  \"milestoneCount\": 2\n}\n```\n\n不符合规则的完成声明会被拒绝，并给出具体原因：\n\n```text\nFAILED with 1 error(s):\n  - [pass-gate] Feature M1-CHECKOUT-003 is passing but has no evidence entry with kind \"review\"\n```\n\n## `validate` 会检查什么\n\n验证器会检查：\n\n- 必需字段、合法状态、唯一功能 ID 和有效的里程碑引用；\n- 每个功能都声明了验证方式；\n- 依赖指向已知功能，并且不存在依赖环；\n- 功能没有依赖更晚里程碑中的功能；\n- 每个 owner 同时最多只有 `rules.wip_limit_per_owner`（默认 1）个 `in_progress` 功能；\n- 每个 `passing` 功能都有证据和一条 `review` 记录；\n- 完成状态单调递增：之前已经通过的功能不能悄悄退回未完成状态；\n- ADR 覆盖 `harness.config.json` 要求的主题；\n- 非占位功能的 `source_refs` 指向真实文件；\n- 追踪矩阵中不存在需求/故事/验收标准的缺口——规划占位符拆分完成后，漏覆盖的需求、\n  孤立故事、孤立功能、未关联验证的验收标准都会让 `validate` 失败；\n- 每一条 artifact 级批准（`sdlc-harness evidence approval`）仍然匹配其批准文件当前的\n  SHA-256 内容哈希。\n\n验证成功后，当前功能状态会记录在 `.harness/` 下，供后续验证检测状态倒退——`passing_is_monotonic`\n检查优先使用 git 历史（`origin/main`/`main`，或 `$HARNESS_BASE_REF`/`$GITHUB_BASE_REF`）而不是本地\n`.harness/` 快照缓存，这样一次全新的 CI checkout（没有历史快照可比对）也不会让回归 PR 蒙混过关。\n`.harness/` 目录大部分是刻意纳入 Git 追踪的：`events/*.jsonl`（审计日志）和 claim/lease 数据\n（直接嵌在每个功能对象里，位于 `feature_list.json` 中）需要跨机器同步才能支持团队协作。只有\n`.harness/last-validated-features.json`——一份由每次成功 `validate` 重新生成的派生缓存——会被\ngitignore；脚手架生成的 `.gitignore` 就是这么配置的。\n\n> [!IMPORTANT]\n> `validate` 验证的是仓库状态和证据记录，它本身不会执行任何命令。真正运行功能声明的验证命令、\n> 并记录真实、不可伪造证据的是 `sdlc-harness verify <feature-id>`——见下方命令表。\n\n## 完整 SDLC 工作流\n\n仓库包含九个阶段指南，但它们不是一条必经流水线。第 4、6、7 阶段是任何功能都\n**必须经过**的核心循环；第 1、2、3、5 阶段是**按需触发**的——每个阶段文档开头都写明了\n何时适用，`AGENTS.md` 的 Routing Map 也会告诉 Agent 应该从哪个阶段进入（新能力、小\n修复、生产事故，还是继续一个已有功能）。第 8、9 阶段则由 `harness.config.json` 的\n`deploymentMode`/`observabilityMode` 控制（默认都是必须，已有仓库行为不变）——没有部署\n目标或发布后受众的库、CLI、内部脚本可以把两者设为 `\"none\"`，跳过不适用的阶段。\n\n1. 需求（Requirements）*（范围不明确时）*\n2. 架构与技术设计（Architecture & Technical Design，ADR）*（改动影响架构时）*\n3. 用户故事设计（User Story Design）*（能力值得先拆解时）*\n4. 功能拆解（Feature Breakdown）— **必须**\n5. 里程碑规划（Milestone Planning）*（确实需要新规划或重新排序时）*\n6. 敏捷开发（Agile Development，TDD）— **必须**\n7. 自验收测试（Self-Acceptance Testing）— **必须**\n8. 部署（Deployment）*（由 `deploymentMode` 决定；默认必须）*\n9. 可观测性与反馈闭环（Observability & Feedback Loop）*（由 `observabilityMode` 决定；默认必须）*\n\n```mermaid\nflowchart TB\n    Slice[\"功能切片\\n（第 4 阶段）\"]\n    A[\"1 需求\"] -.可选.-> Slice\n    B[\"2 架构设计 / ADR\"] -.可选.-> Slice\n    C[\"3 用户故事\"] -.可选.-> Slice\n    E[\"5 里程碑规划\"] -.可选.-> Slice\n    Slice --> F[\"6 敏捷 TDD\"]\n    F --> G[\"7 自验收\"]\n    G --> H[\"8 部署\"]\n    H --> I[\"9 可观测性与反馈\"]\n    I -.\"反馈可能重新打开 1 或 2\".-> A\n```\n\n这些文档负责指导工作；目前机器强制执行的规则主要集中在功能状态、依赖、证据记录、来源引用、\n里程碑顺序和配置要求的 ADR 覆盖范围。\n\n## 生成的仓库协议\n\n运行 `init` 或 `adopt` 后，仓库中会包含：\n\n<details>\n<summary><strong>查看生成的文件和 Git hook 配置</strong></summary>\n\n```text\nAGENTS.md                    # 启动、路由、功能和会话规则\nfeature_list.json            # 里程碑、功能、依赖、状态和证据\nfeature_list.schema.json     # feature list 的机器可读 schema\nharness.config.json          # 项目级治理配置\nprogress.md                  # 按会话保存的检查点\ndocs/\n  adr/                       # 架构决策记录\n  workflow/                  # 九个 SDLC 阶段的指南\n.gitignore                   # 只忽略派生的 .harness/ 快照缓存和 .worktrees/\n.githooks/pre-commit         # 提交前运行验证\n.github/workflows/ci.yml     # 运行验证（在真实检查接入之前会主动失败，不会假装通过）\n.github/workflows/deploy.yml # 在生成的部署任务前运行验证\n.claude/skills/              # 可选的 Claude Code 发现包装\n```\n\n生成的 pre-commit hook 默认不会自动启用，需要配置一次：\n\n```bash\ngit config core.hooksPath .githooks\n```\n\n</details>\n\n## 命令\n\n运行 `sdlc-harness --help`（或 `-h`）查看完整命令列表；运行 `sdlc-harness <command> --help`（`-h` 也可以，出现在参数任意位置都生效）查看某个命令自己的用法，例如 `sdlc-harness feature --help` 或 `sdlc-harness milestone archive --help`。\n\n| 命令                           | 作用                                               |\n| ------------------------------ | -------------------------------------------------- |\n| `sdlc-harness init`          | 在空仓库或新仓库中生成完整 harness。               |\n| `sdlc-harness adopt`         | 添加缺失的 harness 文件，不覆盖已有文件。          |\n| `sdlc-harness validate`      | 运行全部结构与治理检查；失败时以非零状态退出。     |\n| `sdlc-harness status`        | 以 JSON 输出功能状态、artifact 批准状态、追踪缺口和建议的下一步动作。 |\n| `sdlc-harness traceability`  | 以 JSON 输出需求 → US → AC → feature → verification 追踪矩阵；规划占位符拆分完成后，存在漏覆盖或孤立项时非零退出。 |\n| `sdlc-harness new-feature`   | 通过交互问答向 `feature_list.json` 添加功能，供人工调试使用。 |\n| `sdlc-harness new-feature --input <json-file>` | 面向 Agent 的非交互创建方式；输入必须是仓库内 JSON，且不能注入 claim、evidence、workspace 或已完成状态。 |\n| `sdlc-harness new-milestone` | 通过交互问答向`feature_list.json` 添加里程碑。   |\n| `sdlc-harness milestone archive <milestone-id> [--actor <id>]` | 将一个 milestone 及其全部 feature 从 `feature_list.json` 移入 `.harness/archive/<milestone-id>.json`，前提是该 milestone 下所有 feature 都已 `passing`。归档后的 feature id 仍会被当作已满足的依赖，`traceability` 和 `validate` 的 `passing_is_monotonic` 检查也仍将其计入——归档只是把已完成的工作挪个地方存放，让新 milestone 从一份精简的 `feature_list.json` 开始，绝不会使已交付的成果失效。 |\n| `sdlc-harness milestone list-archived` | 以 JSON 列出已归档的 milestone（id、标题、feature 数量、归档时间/操作人）。 |\n| `sdlc-harness feature start <feature-id>` | 原子认领一个 ready 功能并推进到 `in_progress`。 |\n| `sdlc-harness feature complete <feature-id>` | 原子检查有效 claim、依赖、当前提交上的验证证据和后置 review，再推进到 `passing`。 |\n| `sdlc-harness feature block <feature-id> --reason <text>` | 记录阻塞原因、释放 claim 并推进到 `blocked`。 |\n| `sdlc-harness feature reopen <feature-id>` | 清除阻塞，将功能恢复到 `not_started`。 |\n| `sdlc-harness verify <feature-id>` | 真正运行一个功能声明的 *automated* 验证命令，并记录真实的通过/失败证据（含退出码和 commit sha）——这是添加\"测试类\"证据唯一支持的方式。同一 feature 里的 `manual` 条目会被跳过，既不执行也不要求已提前记录。 |\n| `sdlc-harness evidence manual <feature-id> --verification <1-based 序号> ...` | 为声明为 `manual` 的检查记录具名证据，不把描述当 shell 命令执行。`--verification` 是该条目在 feature 的 `verification` 数组里的位置，从 1 开始计数。 |\n| `sdlc-harness evidence approval <artifact> --actor <id> --summary <text>` | 将人的业务批准记录为项目级 evidence，绑定 artifact 的 SHA-256 内容哈希和当前 commit；文件变化后批准自动失效，重新批准前 `validate` 失败。 |\n| `sdlc-harness review record <feature-id> ...` | 记录绑定当前 commit 的结构化 review 证据。 |\n| `sdlc-harness claim <feature-id>` | 原子化地认领一个功能（设置 `owner`，把状态从 `not_started` 推进到 `in_progress`），受 owner 的 WIP 上限约束。 |\n| `sdlc-harness claim --next` | 原子化地认领优先级最高的可认领功能（未开始、依赖已通过、未被占用）。 |\n| `sdlc-harness claim renew <feature-id>` | 在租约过期前续期。 |\n| `sdlc-harness claim <feature-id> --takeover-expired` | 接管一个租约已过期的 claim。 |\n| `sdlc-harness release <feature-id>` | 释放一个 claim（把状态从 `in_progress` 还原为 `not_started`）。 |\n| `sdlc-harness workspace create <feature-id>` | 为一个已认领的功能创建独立的 `git worktree`，分支名为 `feature/<id>`（`--base <branch>`，默认 `main`）。 |\n| `sdlc-harness workspace remove <feature-id>` | 移除一个 workspace。如果存在未提交或未推送的内容会拒绝执行（加 `--force` 强制覆盖）。 |\n| `sdlc-harness workspace prune` | 移除 claim 已释放或已过期的 workspace；有未提交/未推送内容的会跳过并报告，而不是被强制删除。永远不会碰仍在有效 claim 下的 workspace。 |\n| `sdlc-harness workspace status` | 以 JSON 形式列出所有 workspace 及其 claim/磁盘状态。 |\n| `sdlc-harness env` | 列出 `harness.config.json` 的 `commands` 字段中配置的项目级环境命令。 |\n| `sdlc-harness env check` | 真正运行配置好的 `bootstrap`/`verify`/`e2e`/`health` 命令（按此顺序），遇到第一个失败就停止——用来证明项目本身能装、能编译、能跑，而不仅仅是 `feature_list.json` 结构合法。 |\n| `sdlc-harness session close` | 只读的会话收尾报告：运行 `validate`、运行 `env check`（如已配置）、汇总 git 状态和 `status` 的 ready/blocked/next-action 视图——`validate` 失败或某个已配置的环境命令失败时以非零状态退出。 |\n| `sdlc-harness feedback log --source <text> --severity <S1\\|S2\\|S3\\|S4> --observation <text> --disposition <Actioned\\|Deferred\\|Declined\\|Monitoring> [--detail <text>]` | 向 `docs/product/feedback-log.md`（第 9 阶段）追加一条格式正确的记录——从结构上保证格式正确，而不是依赖手写 Markdown；即便有人手改了日志，`validate` 也会检查格式。 |\n\n所有 claim 相关命令都支持 `--owner <name>`（默认取 `harness.config.json` 的 `defaultOwner`）、\n`--actor <id>`（用来区分同一个 owner 名下的多个 Agent 会话——claim 的唯一性始终按 feature 判断，\n从不按 actor 判断）、以及 `--ttl <minutes>`（租约时长，默认 120 分钟）。\n\n### 跨机器认领（git provider）\n\n`sdlc-harness claim <feature-id> --push` 会提交 claim 并推送（`--remote`/`--branch`，默认\n`origin`/`main`）。Git 没有实时的跨机器锁，所以两台机器可能都在各自本地成功认领了同一个\n功能——真正的冲突只会在第二次 push 时才暴露出来。`--push` 会检测到这次 push 被拒绝，丢弃\n那个没能推送成功的本地 commit，与远程重新同步，然后自动改为认领 ready 队列里的下一个功能\n并推送，而不是让你手里攥着一个永远推不上去的 claim。\n\n### GitHub provider 检查\n\n`sdlc-harness provider github check [--owner <o>] [--repo <r>] [--branch <b>]`（如果不传\nowner/repo，会尝试从 `origin` 远程推断）通过 `gh api` 检查分支保护、必需状态检查、是否禁止\n强制推送、`CODEOWNERS`、以及 ruleset。需要管理员权限才能查看的检查项（分支保护细节、\nruleset）在 token 权限不足时会报告 `unknown` 而不是 `fail`——这样普通开发者 token 也能正常\n使用这个命令，不会因为权限问题让所有检查项都报错。\n\n`sdlc-harness evidence import <feature-id> --ci-run <run-id> [--owner <o>] [--repo <r>]`\n从一次 GitHub Actions 运行导入“测试类”证据——但前提是通过 `gh api` 独立确认该次运行确实\n存在、已经完成、且状态为成功。调用方除了 run id 之外，其余信息一律不被信任；仍在运行中、\n已失败、或不存在的 run 会被直接拒绝，且不会写入任何证据。\n\n### Solo 与 Team 模式\n\n`harness.config.json` 的 `collaborationMode` 字段决定 claim/lease 是否对用户可见：\n\n- **`\"solo\"`**（默认）：使用高层的 `feature start` 和 `feature complete` 命令即可，不需要\n  用到底层的 `claim`/`release`。临时的 `verify` 仍然可以自动认领，但要真正完成功能，\n  始终需要先明确执行过 `feature start`，让生命周期的归属可被观察到。\n- **`\"team\"`**：使用同一组高层 feature 命令，或者在协调多个并发 Agent/机器时使用底层的\n  claim 和 workspace 命令。\n\n### 项目环境命令\n\n`sdlc-harness validate` 只检查 `feature_list.json` 及其依赖的文档——它从不执行项目代码，\n所以 `validate` 通过并不能证明项目本身能装、能编译、能跑。`harness.config.json` 的\n`commands` 字段用来补上这个缺口：\n\n```json\n{\n  \"commands\": {\n    \"bootstrap\": \"npm install\",\n    \"verify\": \"npm test && npm run lint\",\n    \"e2e\": \"npm run test:e2e\",\n    \"health\": \"curl -f http://localhost:3000/health\"\n  }\n}\n```\n\n四项都是可选的；`sdlc-harness env check` 会按顺序运行已配置的项，遇到第一个失败就停止。\n`start` 和 `cleanup` 也是识别的字段名，但 `env check` 不会运行它们——它们是场景化的操作\n（启动一个长期运行的开发服务器、清理状态），而不是通过/失败检查；需要时直接引用即可。\n`commands` 留空时行为和现在完全一样——`env check` 会报告“未配置任何命令”而不是失败。\n\n## Agent 兼容性\n\n| Agent                                  | 核心工作流 | 额外集成                               |\n| -------------------------------------- | ---------: | -------------------------------------- |\n| Claude Code                            |       支持 | 每个工作流阶段都有轻量 skill 包装      |\n| Codex 及其他支持`AGENTS.md` 的 Agent |       支持 | 直接使用仓库协议                       |\n| 其他能够读取文件的编码 Agent           |       支持 | 需要先明确要求 Agent 阅读`AGENTS.md` |\n\n`.claude/skills/` 中的包装不包含独立流程逻辑。规范流程仍然位于 `AGENTS.md` 和\n`docs/workflow/` 中，避免不同 Agent 的行为逐渐分叉。\n\n## 它不是什么\n\n`sdlc-harness` 不是编码 Agent、测试运行器、托管项目管理服务，也不能证明产品需求本身正确。\n它是仓库级的协议与验证层，让 Agent、开发者、Git hook 和 CI 基于同一份声明状态协作。\n\n## 贡献\n\n欢迎提交 Issue 和 Pull Request。运行测试套件：\n\n```bash\nnpm test\n```\n\n## 许可证\n\n[MIT](LICENSE)\n","readmeFilename":"README.zh-CN.md"}