cowork-flow 2.3.0 → 2.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. package/CHANGELOG.md +31 -1
  2. package/README.en.md +34 -18
  3. package/README.md +8 -5
  4. package/docs/architecture.en.md +95 -0
  5. package/docs/architecture.md +7 -3
  6. package/docs/direction.en.md +71 -0
  7. package/docs/direction.md +6 -1
  8. package/docs/hosts.en.md +299 -0
  9. package/docs/hosts.md +3 -1
  10. package/docs/index.en.md +30 -0
  11. package/docs/index.md +2 -0
  12. package/docs/release.en.md +108 -0
  13. package/docs/release.md +2 -0
  14. package/package.json +2 -2
  15. package/presets/claude-code/.claude-plugin/plugin.json +1 -1
  16. package/presets/claude-code/skills/cowork-flow-bootstrap/SKILL.md +4 -0
  17. package/presets/codex/.codex-plugin/plugin.json +1 -1
  18. package/presets/codex/skills/cowork-flow-bootstrap/SKILL.md +4 -0
  19. package/presets/kimi-code/.kimi-plugin/plugin.json +1 -1
  20. package/presets/kimi-code/skills/cowork-flow-bootstrap/SKILL.md +4 -0
  21. package/presets/opencode/cowork-flow/skills/cowork-flow-bootstrap/SKILL.md +4 -0
  22. package/presets/qoder/.qoder-plugin/plugin.json +1 -1
  23. package/presets/qoder/skills/cowork-flow-bootstrap/SKILL.md +4 -0
  24. package/presets/zcode/.zcode-plugin/plugin.json +1 -1
  25. package/presets/zcode/skills/cowork-flow-bootstrap/SKILL.md +4 -0
  26. package/src/commands/init.js +129 -2
  27. package/src/commands/registry.js +3 -1
  28. package/src/commands/source-refresh.js +5 -1
  29. package/src/commands/sync.js +3 -0
  30. package/src/lib/copy-template.js +23 -5
  31. package/src/lib/host-assets.js +117 -2
  32. package/src/lib/language.js +162 -0
  33. package/template/.cowork-flow/.version +1 -1
  34. package/template/.cowork-flow/config.yaml +8 -0
  35. package/template/.cowork-flow/scripts/adapters/cli/task_create_command.py +5 -3
  36. package/template/.cowork-flow/scripts/adapters/host/host_manifest.py +71 -2
  37. package/template/.cowork-flow/scripts/infra/config.py +85 -0
  38. package/template/.cowork-flow/scripts/services/decision_anchor_schema.py +228 -0
  39. package/template/.cowork-flow/scripts/services/fact_view.py +27 -15
  40. package/template/.cowork-flow/scripts/services/plan_binding.py +34 -0
  41. package/template/.cowork-flow/scripts/services/plan_schema.py +182 -0
  42. package/template/.cowork-flow/scripts/services/task_context.py +84 -12
  43. package/template/.cowork-flow/scripts/services/task_creation.py +89 -30
  44. package/template/.cowork-flow/scripts/services/task_gate_profiles.py +7 -24
  45. package/template/.cowork-flow/spec/contracts/context-injection.md +5 -4
  46. package/template/.cowork-flow/spec/contracts/decision-anchor.md +35 -19
  47. package/template/.cowork-flow/spec/contracts/plan-binding.md +27 -4
  48. package/template/.cowork-flow/spec/index.md +26 -26
  49. package/template/.cowork-flow/spec/references/definition-of-done.md +26 -26
  50. package/template/.cowork-flow/spec/references/index.md +16 -16
  51. package/template/.cowork-flow/spec/references/orchestration-patterns.md +71 -71
  52. package/template/.cowork-flow/spec/references/security-checklist.md +37 -37
  53. package/template/.cowork-flow/spec/references/testing-checklist.md +32 -32
  54. package/template/.cowork-flow/spec/runtime/contract-registry.json +1 -0
  55. package/template/.cowork-flow/spec/runtime/host-assets.json +23 -4
  56. package/template/.cowork-flow/spec/runtime/index.md +10 -12
  57. package/template/.cowork-flow/spec/schemas/host-assets.schema.json +31 -0
  58. package/template/.cowork-flow/spec/schemas/index.md +5 -5
  59. package/template/.cowork-flow/templates/plan-template.md +91 -0
  60. package/template/locales/en-US/.cowork-flow/spec/contracts/decision-anchor.md +169 -0
  61. package/template/locales/en-US/.cowork-flow/templates/plan-template.md +91 -0
  62. package/template/skills/runtime-health/scripts/doctor.py +110 -0
  63. package/template/skills/task-planning/SKILL.md +21 -94
@@ -1,51 +1,51 @@
1
1
  # Security Quick Reference
2
2
 
3
- > 安全快速参考。当处理用户输入/认证/数据存储/外部集成时按需加载。
3
+ > Security quick reference. Load on demand when handling user input, authentication, data storage, or external integrations.
4
4
 
5
- 契约: ERROR_OUTPUT_AS_DATA_V1 (详见 .cowork-flow/spec/contracts/error-output-as-data.md)
5
+ Contract: ERROR_OUTPUT_AS_DATA_V1 (see .cowork-flow/spec/contracts/error-output-as-data.md)
6
6
 
7
- ## 输入验证
7
+ ## Input validation
8
8
 
9
- - 所有外部输入在边界验证(API 入口、文件上传、CLI 参数)
10
- - 错误信息不泄漏内部实现细节(栈追踪、路径、库版本)
11
- - 参数化查询,禁止字符串拼接 SQL
12
- - 长度/类型/范围白名单,而非仅黑名单
9
+ - Validate all external input at the boundary (API entry points, file uploads, CLI arguments)
10
+ - Error messages must not leak internal implementation details (stack traces, paths, library versions)
11
+ - Use parameterized queries; never concatenate SQL strings
12
+ - Prefer length/type/range allowlists over blocklists
13
13
 
14
- ## 认证授权
14
+ ## Authentication and authorization
15
15
 
16
- - 认证状态不在客户端存储(仅 httpOnly secure cookie)
17
- - 权限检查在每次受保护操作时执行(不依赖前端隐藏)
18
- - 认证失败不区分用户名错/密码错(统一提示"认证失败")
19
- - Session 有过期时间 + rotation on privilege change
16
+ - Authentication state is not stored on the client (httpOnly secure cookie only)
17
+ - Perform permission checks on every protected operation (do not rely on the frontend to hide controls)
18
+ - Authentication failures do not distinguish wrong username from wrong password (use a uniform "authentication failed" message)
19
+ - Sessions have an expiry time and rotate on privilege change
20
20
 
21
- ## 依赖与供应链
21
+ ## Dependencies and supply chain
22
22
 
23
- - 第三方依赖来自可信来源
24
- - 无已知 CVE(`pip audit` / `npm audit`)
25
- - Lockfile 提交到版本控制
23
+ - Third-party dependencies come from trusted sources
24
+ - No known CVEs (`pip audit` / `npm audit`)
25
+ - Lockfiles are committed to version control
26
26
 
27
- ## 数据与隐私
27
+ ## Data and privacy
28
28
 
29
- - 日志中不出现敏感数据(密码、token、PII)
30
- - 传输加密(TLS),存储加密(bcrypt/argon2)
31
- - 错误输出视为不可信数据(参见 ERROR_OUTPUT_AS_DATA_V1)
29
+ - Logs contain no sensitive data (passwords, tokens, PII)
30
+ - Encrypt in transit (TLS) and at rest (bcrypt/argon2)
31
+ - Treat error output as untrusted data (see ERROR_OUTPUT_AS_DATA_V1)
32
32
 
33
- ## OWASP Top 10 快速映射
33
+ ## OWASP Top 10 quick mapping
34
34
 
35
- | 编号 | 类别 | 检查 | 缺失风险 |
35
+ | ID | Category | Check | Risk if missing |
36
36
  |---|---|---|---|
37
- | A01 | 注入 | 参数化查询 | 数据泄露或丢失 |
38
- | A02 | 失效认证 | bcrypt + session rotation | 账号劫持 |
39
- | A03 | 敏感数据暴露 | 传输加密+存储加密+不泄漏 | 数据泄露 |
40
- | A04 | XXE | 禁用外部实体解析 | XML 注入 |
41
- | A05 | 失效访问控制 | 每次请求重新验权 | 越权操作 |
42
- | A06 | 安全配置错误 | 默认安全+无调试头 | 信息泄漏 |
43
- | A07 | XSS | 输入输出编码+CSP | 浏览器端代码执行 |
44
- | A08 | 不安全反序列化 | 不反序列化不可信数据 | RCE |
45
- | A09 | 已知漏洞组件 | 定期 audit | 已知 exploit |
46
- | A10 | 未授权重放 | nonce + rate limit | 自动化滥用 |
47
-
48
- ## 参见
49
-
50
- - `spec/contracts/error-output-as-data.md` — 防御 prompt injection
51
- - `skills/test-first/SKILL.md` — 安全回归测试证据
37
+ | A01 | Injection | Parameterized queries | Data disclosure or loss |
38
+ | A02 | Broken authentication | bcrypt + session rotation | Account takeover |
39
+ | A03 | Sensitive data exposure | Encryption in transit + at rest + no leakage | Data disclosure |
40
+ | A04 | XXE | Disable external entity parsing | XML injection |
41
+ | A05 | Broken access control | Re-authorize on every request | Unauthorized operations |
42
+ | A06 | Security misconfiguration | Secure defaults + no debug headers | Information disclosure |
43
+ | A07 | XSS | Input/output encoding + CSP | Browser-side code execution |
44
+ | A08 | Insecure deserialization | Do not deserialize untrusted data | RCE |
45
+ | A09 | Vulnerable components | Regular audits | Known exploits |
46
+ | A10 | Unauthorized replay | Nonce + rate limit | Automated abuse |
47
+
48
+ ## See also
49
+
50
+ - `spec/contracts/error-output-as-data.md` — defending against prompt injection
51
+ - `skills/test-first/SKILL.md` — security regression test evidence
@@ -1,45 +1,45 @@
1
1
  # Testing Checklist
2
2
 
3
- > 测试质量快速参考。审查测试文件、编写测试用例或检查行为覆盖时按需加载。
3
+ > Quick reference for test quality. Load on demand when reviewing test files, writing test cases, or checking behavior coverage.
4
4
 
5
- ## 测试结构检查
5
+ ## Test structure
6
6
 
7
- - 测试名称描述行为:`test_<unit>_<scenario>_<expected>`
8
- - AAA 排列(Arrange/Act/Assert 之间有视觉分隔)
9
- - 一个测试只验证一个行为
10
- - 断言行为契约,而非实现细节
11
- - mock 验证行为调用,而非 call-count
7
+ - Test names describe behavior: `test_<unit>_<scenario>_<expected>`
8
+ - AAA layout (visual separation between Arrange/Act/Assert)
9
+ - One test verifies one behavior
10
+ - Assert behavior contracts, not implementation details
11
+ - Mocks verify behavior calls, not call counts
12
12
 
13
- ## 深度检查
13
+ ## Depth
14
14
 
15
- - 不是 `assert True` 通过的测试
16
- - 不是"只检查函数是否存在"的测试
17
- - 不是通过 `unittest.mock` 调用计数代替行为验证的测试
18
- - 不是快照空结构(`assert result == {}`)的测试
19
- - 不依赖测试执行顺序
20
- - 不跳过必要的 setup/teardown
21
- - 断言精确值或行为契约,而非 truthy/falsy
22
- - 异常路径有至少一个测试覆盖
15
+ - Not a test that passes via `assert True`
16
+ - Not a test that only checks whether a function exists
17
+ - Not a test that uses `unittest.mock` call counts instead of behavior verification
18
+ - Not a test that snapshots an empty structure (`assert result == {}`)
19
+ - Does not depend on test execution order
20
+ - Does not skip necessary setup/teardown
21
+ - Asserts exact values or behavior contracts, not truthy/falsy
22
+ - Has at least one test for the error path
23
23
 
24
- ## 反模式
24
+ ## Anti-patterns
25
25
 
26
- | 反模式 | 问题 | 替代方案 |
26
+ | Anti-pattern | Problem | Alternative |
27
27
  |---|---|---|
28
- | 设置期望值为硬编码输出 | 测试与实现耦合,实现变更但行为相同时测试失败 | 验证行为契约:输入 -> 期望输出关系 |
29
- | mock 受测函数的内部调用 | 测试实现而非行为 | mock 留在边界层(API/文件系统/时间) |
30
- | 多个不相关行为塞一个测试 | 失败时不知道是什么坏了 | 每行为独立测试,名称描述行为 |
31
- | 断言 `assert True` | 总是通过 | 改为语义断言(assertEqual/assertGreater 等) |
32
- | 只检查函数存在 `assert module.func` | 不验证行为 | 调用函数验输出或异常 |
33
- | 不清理全局状态 / fixtures | 测试间污染导致顺序依赖 | 使用 setup/teardown 清理 |
28
+ | Hard-coding expected values to implementation output | Test couples to implementation; it fails when implementation changes but behavior does not | Verify the behavior contract: input -> expected output |
29
+ | Mocking internal calls of the function under test | Tests implementation instead of behavior | Keep mocks at boundaries (API/filesystem/time) |
30
+ | Packing unrelated behaviors into one test | A failure does not reveal what broke | One test per behavior, with a descriptive name |
31
+ | Asserting `assert True` | Always passes | Use semantic assertions (assertEqual/assertGreater, etc.) |
32
+ | Only checking that a function exists (`assert module.func`) | Does not verify behavior | Call the function and verify output or exceptions |
33
+ | Not cleaning up global state / fixtures | Cross-test pollution causes order dependence | Clean up in setup/teardown |
34
34
 
35
- ## 范围
35
+ ## Scope
36
36
 
37
- - 当前修改的函数/模块有直接单元测试
38
- - 下游依赖有集成测试
39
- - 边界条件(空值/极值/并发)有至少一个测试覆盖
37
+ - The changed function/module has a direct unit test
38
+ - Downstream dependencies have integration tests
39
+ - Boundary conditions (empty/extreme values/concurrency) have at least one test
40
40
 
41
- ## 参见
41
+ ## See also
42
42
 
43
- - `spec/backend/quality-guidelines.md` — 后端测试规范
44
- - `skills/test-first/SKILL.md` — 完整的 TDD 流程
45
- - `references/security-checklist.md` — 测试中的安全边界检查
43
+ - `spec/backend/quality-guidelines.md` — backend testing rules
44
+ - `skills/test-first/SKILL.md` — full TDD workflow
45
+ - `references/security-checklist.md` — security boundary checks in tests
@@ -108,6 +108,7 @@
108
108
  "digest": [
109
109
  "Plan binding records repo-relative task.json.meta.planFile.",
110
110
  "Task start blocks clear missing plan facts for non-Tiny tasks.",
111
+ "Strict non-Tiny start requires the configured-language plan template shape and a filled spec-check line.",
111
112
  "V1 does not parse plan steps, AC text, or verification evidence."
112
113
  ],
113
114
  "readWhen": [
@@ -442,16 +442,36 @@
442
442
  ],
443
443
  "excludedPrefixes": [
444
444
  "skills/",
445
+ "locales/",
445
446
  ".zcode/",
446
447
  ".qoder/"
447
448
  ],
449
+ "localization": {
450
+ "default": "zh-CN",
451
+ "supported": [
452
+ "zh-CN",
453
+ "en-US"
454
+ ],
455
+ "assets": {
456
+ "en-US": [
457
+ ".cowork-flow/spec/contracts/decision-anchor.md",
458
+ ".cowork-flow/templates/plan-template.md"
459
+ ]
460
+ }
461
+ },
448
462
  "syncPolicy": {
449
463
  "protectedFiles": [
450
464
  ".cowork-flow/config.yaml",
451
465
  ".cowork-flow/.developer"
452
466
  ],
467
+ "forceProtectedFiles": [
468
+ ".cowork-flow/config.yaml"
469
+ ],
453
470
  "protectedPrefixes": [
454
- ".cowork-flow/spec/",
471
+ ".cowork-flow/spec/backend/",
472
+ ".cowork-flow/spec/frontend/",
473
+ ".cowork-flow/spec/guides/",
474
+ ".cowork-flow/spec/references/",
455
475
  ".cowork-flow/tasks/",
456
476
  ".cowork-flow/plans/"
457
477
  ],
@@ -459,9 +479,7 @@
459
479
  ".cowork-flow/.gitignore",
460
480
  ".cowork-flow/.version",
461
481
  ".cowork-flow/run",
462
- ".cowork-flow/run.cmd",
463
- ".cowork-flow/spec/contracts/workflow-state-templates.md",
464
- ".cowork-flow/spec/runtime/scope-rules.json"
482
+ ".cowork-flow/run.cmd"
465
483
  ],
466
484
  "safePrefixes": [
467
485
  ".cowork-flow/"
@@ -511,6 +529,7 @@
511
529
  ".claude/skills/update-spec",
512
530
  ".claude/skills/using-cowork-flow",
513
531
  ".claude/skills/writing-plans",
532
+ ".cowork-flow/plan-template.md",
514
533
  ".cowork-flow/project-context.md",
515
534
  ".cowork-flow/scripts/application",
516
535
  ".cowork-flow/scripts/services/batch_execution.py",
@@ -1,19 +1,17 @@
1
1
  # Runtime Specs
2
2
 
3
- 本目录存放 workflow runtime 直接读取的机器配置。
3
+ This directory holds machine configuration read directly by the workflow runtime.
4
4
 
5
- - `contract-registry.json`: hook/plugin 注入 contract digest 的注册表。
6
- - `host-assets.json`: 宿主平台、资产归属、技能读取根与宿主发现通道(`skillReadRoot` / `skillDiscovery[]`,条目为仓库内路径加 `gates` / `evidence`;机器级载荷不作为技能来源参与)、机器级插件载荷声明(`payload`:载荷在包内的目录与插件清单名,无插件载荷的宿主为 `null`;机器安装位置不在此声明)、同步保护策略和旧资产迁移清单的单源;结构由 `../schemas/host-assets.schema.json` 约束。`capabilityMatrix.hosts` 必须覆盖 `platforms` 声明的每一个 id——必需宿主集合由平台数据派生,运行时不维护宿主名单常量。
5
+ - `contract-registry.json`: registry of the contract digests injected by hooks/plugins.
6
+ - `host-assets.json`: single source for host platforms, asset ownership, skill read roots and host discovery channels (`skillReadRoot` / `skillDiscovery[]`, entries are repo-relative paths plus `gates` / `evidence`; machine-level payloads do not participate as skill sources), machine-level plugin payload declarations (`payload`: the package-relative payload directory and plugin manifest name; `null` for hosts without a plugin payload; machine install locations are not declared here), the sync protection policy, and the obsolete-asset migration list. The structure is constrained by `../schemas/host-assets.schema.json`. `capabilityMatrix.hosts` must cover every id declared in `platforms` — the required host set is derived from platform data; the runtime does not maintain a host-name constant.
7
7
 
8
- 缺少或损坏的 runtime 文件不能静默放行关键流程能力。宿主插件可使用最小 fallback
9
- 避免崩溃,但必须在 digest 中暴露 warning;doctor/tests 负责发现缺失。
8
+ Missing or corrupted runtime files must not silently grant critical workflow capabilities. Host plugins may use a minimal fallback to avoid crashing, but must expose a warning in the digest; doctor/tests are responsible for detecting absence.
10
9
 
11
- 用户自然语言规范不在本目录注册;`task-review` skill 直接读取
12
- `spec/backend/`、`spec/frontend/`、`spec/guides/` 并输出审查结论。
10
+ User natural-language specs are not registered in this directory; the `task-review` skill reads `spec/backend/`, `spec/frontend/`, and `spec/guides/` directly and reports review findings.
13
11
 
14
- 运行时写入边界:
12
+ Runtime write boundaries:
15
13
 
16
- - CLI/宿主/Git 适配层位于 `scripts/adapters/`,用例服务位于 `scripts/services/`。
17
- - JSON 状态通过 `scripts/infra/storage/` 读写并显式使用 UTF-8。
18
- - init/sync 通过 Asset Plan、staging、备份和 rollback 提交资产,版本文件最后更新。
19
- - 旧状态只允许在带迁移测试的读取边界兼容;新写入必须使用当前 schema 和权威路径。
14
+ - CLI/host/Git adaptation lives in `scripts/adapters/`; use-case services live in `scripts/services/`.
15
+ - JSON state is read and written through `scripts/infra/storage/` with explicit UTF-8.
16
+ - init/sync commit assets through Asset Plan, staging, backup, and rollback; the version file is updated last.
17
+ - Old state is only allowed at read boundaries with migration tests; new writes must use the current schema and authoritative paths.
@@ -56,6 +56,9 @@
56
56
  "excludedPrefixes": {
57
57
  "$ref": "#/$defs/stringList"
58
58
  },
59
+ "localization": {
60
+ "$ref": "#/$defs/localization"
61
+ },
59
62
  "syncPolicy": {
60
63
  "$ref": "#/$defs/syncPolicy"
61
64
  }
@@ -68,6 +71,31 @@
68
71
  "minLength": 1
69
72
  }
70
73
  },
74
+ "localization": {
75
+ "description": "Per-language asset overrides. Paths are canonical project-relative paths; the base template is the default language.",
76
+ "type": "object",
77
+ "additionalProperties": false,
78
+ "required": [
79
+ "default",
80
+ "supported",
81
+ "assets"
82
+ ],
83
+ "properties": {
84
+ "default": {
85
+ "type": "string",
86
+ "minLength": 1
87
+ },
88
+ "supported": {
89
+ "$ref": "#/$defs/stringList"
90
+ },
91
+ "assets": {
92
+ "type": "object",
93
+ "additionalProperties": {
94
+ "$ref": "#/$defs/stringList"
95
+ }
96
+ }
97
+ }
98
+ },
71
99
  "capabilities": {
72
100
  "type": "object",
73
101
  "minProperties": 1,
@@ -342,6 +370,9 @@
342
370
  "protectedFiles": {
343
371
  "$ref": "#/$defs/stringList"
344
372
  },
373
+ "forceProtectedFiles": {
374
+ "$ref": "#/$defs/stringList"
375
+ },
345
376
  "protectedPrefixes": {
346
377
  "$ref": "#/$defs/stringList"
347
378
  },
@@ -1,9 +1,9 @@
1
1
  # Schema Specs
2
2
 
3
- 本目录存放 JSON Schema。
3
+ This directory holds JSON Schemas.
4
4
 
5
- - `adapter.schema.json`: 宿主适配器声明 schema。
6
- - `host-assets.schema.json`: Host Asset Manifest schema(`runtime/host-assets.json` 的结构约束)。
7
- - `party-mode-v2-actions.schema.json`: Party Mode V2 action schema。
5
+ - `adapter.schema.json`: host adapter declaration schema.
6
+ - `host-assets.schema.json`: Host Asset Manifest schema (structural constraints for `runtime/host-assets.json`).
7
+ - `party-mode-v2-actions.schema.json`: Party Mode V2 action schema.
8
8
 
9
- Schema 只描述数据合同,不承载流程说明;流程和行为边界写入 `contracts/`、Skill command manifests 或 `AGENTS.md`。
9
+ Schemas describe data contracts only, not workflow guidance; workflow and behavior boundaries belong in `contracts/`, Skill command manifests, or `AGENTS.md`.
@@ -0,0 +1,91 @@
1
+ # <功能> 实施计划
2
+
3
+ > 执行规则:本计划用于防止实现漂移,实现者必须按任务顺序推进。
4
+ > 如果计划与当前代码事实冲突、需要计划外文件,或测试因未计划的原因失败,停止并报告,不要扩大范围。
5
+ >
6
+ > 正式固定代理工作:使用 `.cowork-flow/run subagent init` 创建 runtime context,通过当前 Host Adapter 传入 `cowork_runtime_context_id: <runtime_context_id>`,再派发 `cowork-implement` 或 `cowork-check`;验证完成后关闭 runtime context。
7
+
8
+ | 字段 | 内容 |
9
+ |----|------|
10
+ | **任务类型** | Tiny / Normal / High-risk:<理由> |
11
+ | **执行策略** | Serial / Parallel:<理由> |
12
+ | **成功标准** | AC-001 / AC-002 / AC-003 |
13
+ | **最终验证** | `<command>` → exit 0;逐条核对适用的 `.cowork-flow/spec/<dev_type>/` 规范与项目门禁 → 每条 `pass` / `not_applicable` |
14
+ | **主要风险** | Low / Medium / High:<一句话> |
15
+
16
+ **目标:** <一句话描述可观察的行为变化>
17
+
18
+ ## 目标
19
+
20
+ <1-3 句话描述预期可观察行为。>
21
+
22
+ ## 验收标准
23
+
24
+ - AC-001: <可验证行为>
25
+ - AC-002: <可验证行为>
26
+
27
+ ## 全局约束
28
+
29
+ - <必须保留的架构边界、兼容要求、命令或输出字段>
30
+ - <明确禁止的范围扩张>
31
+
32
+ ## 文件边界
33
+
34
+ - `path/a.py`:<职责;只改这个函数或区域>
35
+ - `tests/test_a.py`:<职责;只新增或修改这些测试>
36
+
37
+ ## 任务
38
+
39
+ Tiny 任务可保留简化 brief,但仍须写明精确文件边界、完成条件和一条验证命令。
40
+
41
+ ### 任务 N:<小目标>
42
+
43
+ **目的**
44
+ - <本任务完成后的可观察行为>
45
+
46
+ **代码事实来源**
47
+ - Read: `path/a.py::function_name`
48
+ - Read: `tests/test_a.py::test_existing_behavior`
49
+
50
+ **文件边界**
51
+ - Create / Modify / Test: `path/a.py`(只改 <函数/区域>)
52
+ - Test: `tests/test_a.py`(只改 <测试/区域>)
53
+
54
+ **关键符号**
55
+ - Change: `function_name()`、`ClassName.method()`、`<config-key>`
56
+ - Preserve: `existing_helper()`、输出字段 `<field>`
57
+
58
+ **实现说明**
59
+ ```python
60
+ # 核心控制流草图;按现有代码调整名称。
61
+ # 不要把完整实现复制进计划。
62
+ ...
63
+ ```
64
+
65
+ **测试证明**
66
+ - `tests/test_a.py::test_x`:证明 <具体行为>
67
+ - 核心断言:<一句话描述断言,不只有测试名>
68
+
69
+ **验证命令**
70
+ ```bash
71
+ <command>
72
+ ```
73
+
74
+ 当改动文件受 `.cowork-flow/spec/<dev_type>/` 规则覆盖时,在这里加入决定命令或规范门禁核对行(`pass` / `not_applicable` 并附理由)。strict 非 Tiny 任务启动前必须把 `<pass / not_applicable + 理由>` 替换为实际核对结果;保留模板占位符会被 start 门禁阻断。
75
+
76
+ **完成条件**
77
+ - <2-4 条可检查条件>
78
+
79
+ **禁止漂移**
80
+ - <2-5 条明确禁止的改动>
81
+
82
+ **偏差条件**
83
+ - 如果 <计划外文件/层> 变得必要,必须停止并报告,因为文件边界有误。
84
+
85
+ ## 最终验证
86
+
87
+ ```bash
88
+ <command>
89
+ ```
90
+
91
+ 规范核对:逐条核对 `.cowork-flow/spec/<dev_type>/` 适用规范 → <pass / not_applicable + 理由>。
@@ -0,0 +1,169 @@
1
+ # Decision Anchor Contract
2
+
3
+ **Every task must have a `decision-anchor.md`: the single authoritative decision
4
+ source that prevents drift during execution.**
5
+
6
+ It merges and replaces the former `prd.md`, carrying both "what to do" and "why not
7
+ the alternatives", which compresses the number of task artifacts.
8
+
9
+ ## Schema
10
+
11
+ These section names are machine-readable. The runtime parser accepts both the
12
+ Chinese and English heading sets, and new anchors use the language configured in
13
+ `.cowork-flow/config.yaml` (`zh-CN` is the default).
14
+
15
+ ```markdown
16
+ # Decision Anchor
17
+
18
+ ## Goal
19
+ <one sentence>
20
+
21
+ ## Acceptance Criteria
22
+ - [ ] AC-001: <verifiable>
23
+ - [ ] AC-002: <verifiable>
24
+
25
+ ## Rejected Options
26
+ - **Option B**: <summary> — rejected because: <why>
27
+
28
+ ## Key Assumptions
29
+ - <assumption 1>
30
+
31
+ ## Scope Boundary
32
+ - In scope: <list>
33
+ - Out of scope: <list>
34
+
35
+ ## Verification Commands
36
+ - `<command>` → <expected>
37
+ - Spec check: clause-by-clause check against applicable `.cowork-flow/spec/<dev_type>/` rules → pass / not_applicable (with reason)
38
+ ```
39
+
40
+ ## Section requirements
41
+
42
+ Both heading columns below are accepted; the right column is the `en-US` output
43
+ and the left column the `zh-CN` output.
44
+
45
+ | Section | Required | Why |
46
+ |------|------|------|
47
+ | `## Goal` / `## 目标` | required | no goal, no acceptance baseline |
48
+ | `## Acceptance Criteria` / `## 验收标准` | required | `task_start` is blocked without acceptance criteria |
49
+ | `## Rejected Options` / `## 被拒方案` | optional | required for brainstorming tasks, so a rejected option is not reconsidered during execution |
50
+ | `## Key Assumptions` / `## 关键假设` | optional | filled in for complex tasks to surface implicit constraints; not read by the runtime parser |
51
+ | `## Scope Boundary` / `## 范围边界` | optional | prevents scope creep |
52
+ | `## Verification Commands` / `## 验证命令` | required for strict non-Tiny; optional for legacy/Tiny | filled in for complex tasks, as the basis for automated verification; a strict non-Tiny task also needs the configured-language section and a filled spec/gate check for the task's `dev_type` (deciding command, or clause-by-clause `pass` / `not_applicable` with reason) |
53
+
54
+ ### Machine-readable line formats (for injection)
55
+
56
+ `## Verification Commands` and `## Scope Boundary` are parsed by stage-contract
57
+ injection and by the MCP fact view (`services/fact_view.parse_decision_anchor`).
58
+ Line-format conventions:
59
+
60
+ - `## Verification Commands`: one command per line (an optional `- ` prefix),
61
+ truncated to 120 characters, at most 10 lines; the implementing agent runs them
62
+ itself (self-declared, self-checked) and the reviewer verifies the execution
63
+ evidence. A strict non-Tiny task must also carry a `Spec check:` line in the
64
+ configured language's section, with the actual `pass` / `not_applicable` result
65
+ and a reason. The template placeholder (`<pass / not_applicable + reason>`) does
66
+ not satisfy the start gate. This line is a hard start gate for strict non-Tiny
67
+ tasks, while its content remains self-declared and is reviewed by the check
68
+ agent. The fact view recognizes the line and does not return it as a shell
69
+ command.
70
+ - `## Scope Boundary`: only the first non-empty line is taken, truncated to 160
71
+ characters.
72
+
73
+ ## Scenarios
74
+
75
+ | Scenario | Source | What gets filled in |
76
+ |------|------|---------|
77
+ | Has brainstorming | extracted from the discussion outcome | every section |
78
+ | No brainstorming (requirements already clear) | extracted from the requirement description and the plan | the minimum: goal + acceptance criteria |
79
+
80
+ ## Artifact compression
81
+
82
+ Before merging (6 files): `prd.md` + `implement.jsonl` + `check.jsonl` +
83
+ `debug.jsonl` + `task.json`
84
+
85
+ After merging (5 files): `decision-anchor.md` + `implement.jsonl` + `check.jsonl` +
86
+ `debug.jsonl` + `task.json`
87
+
88
+ **A net reduction of one file type. Related-file tracking is now owned entirely by
89
+ `implement.jsonl`.**
90
+
91
+ ## Lifecycle check coupling
92
+
93
+ - The preflight for `task next <dir> --run` checks that `decision-anchor.md` is
94
+ non-empty and requires the `## Goal` / `## 目标` and `## Acceptance Criteria` /
95
+ `## 验收标准` sections to be present.
96
+ - **Gate profile `meta.gateProfile`**: a newly created task is written as
97
+ `"strict"`; an unmarked task is treated as `"legacy"` — existing tasks are not
98
+ retro-fitted with the stricter gate, and the profile is queryable through the
99
+ fact view. On top of the section check, a strict task additionally requires: at
100
+ least one parseable `- [ ] AC-xxx: ...` row in `## Acceptance Criteria` /
101
+ `## 验收标准`, no duplicate AC ids, no non-AC list rows in that section, and a
102
+ declared `dev_type` (otherwise `task specs` dev-type dispatch silently comes
103
+ back shorter).
104
+ - A strict non-Tiny task also requires the configured-language
105
+ `## Verification Commands` / `## 验证命令` section with a filled
106
+ `Spec check:` / `规范核对:` line. A missing section, the other-language
107
+ heading, or the template placeholder blocks start. Tiny tasks and legacy tasks
108
+ are exempt. The bound plan's `## Final Verification` / `## 最终验证` section
109
+ carries the same filled check; plan structure and language are covered by
110
+ `plan-binding.md`.
111
+ - An acceptance row's checkbox state (`- [ ]` / `- [x]`) and the evidence records
112
+ (the task directory's `evidence.jsonl`) are the fact source of the completion
113
+ gate: completion is blocked when an unchecked AC exists (`LIFECYCLE-AC-001`), a
114
+ declared AC has no evidence (`LIFECYCLE-AC-002`), a strict task cannot read any
115
+ AC row (`LIFECYCLE-AC-003`), or the AC-evidence module is unavailable
116
+ (`LIFECYCLE-AC-004`). Schema and exemptions are in `evidence-completion.md`.
117
+ - **Review receipt change fingerprint** (a strict task requires its latest receipt
118
+ to match the current state at completion, `LIFECYCLE-REVIEW-003`). Input = the
119
+ git-visible change set (paths + content digests) + this anchor's goal and AC text
120
+ + the content digest of the bound plan + `dev_type` + the **content digest** of
121
+ every referenced spec + the content digest of `implement.jsonl`. Both `spec/**`
122
+ and `tasks/**` are gitignored, which is why the last two must enter the
123
+ fingerprint explicitly — otherwise rewriting a referenced spec's prose, or
124
+ widening the declared scope, would leave a stale receipt valid.
125
+ - Fingerprint **exclusions** (mechanism): the change set excludes the whole
126
+ `.cowork-flow/tasks/**` tree, `.cowork-flow/.runtime/**`, and
127
+ `.cowork-flow/logs/**` — task-directory artifacts (`task.json`,
128
+ `evidence.jsonl`, `review.jsonl`, `check.jsonl`, `debug.jsonl`, and the anchor's
129
+ **path entry**) and runtime metadata are not counted, or a receipt would
130
+ invalidate itself the moment it was recorded. `implement.jsonl`'s path entry is
131
+ excluded the same way; its **content** is counted instead through the `scope`
132
+ component.
133
+ A **consequence** (expected cost, not a defect): **any byte change in
134
+ `implement.jsonl`** (appending or removing a scope entry, rewording a `reason`,
135
+ a domain-guide entry) **or a rewrite of a
136
+ referenced spec's prose invalidates an existing receipt**, requiring one more
137
+ review run against the final state. Appending evidence, ticking ACs, and runtime
138
+ metadata are not in that set.
139
+ - **Light profile `meta.taskType: "tiny"`**: applies to `strict` tasks only
140
+ (`legacy` + `tiny` stays a compatibility path). A light task **is still strict**
141
+ — what it waives are three things: the review receipt, AC evidence, and
142
+ `dev_type`. It does **not** waive the file-scope gate or "AC rows
143
+ are non-empty" (`LIFECYCLE-AC-003`/`004` still apply). Plan-file binding is not
144
+ among the three, but the pre-existing field-level exemption for tiny applies, so
145
+ a light task does not require `planFile` either. `tiny` **can only be declared at
146
+ creation time** (`task next --run --task-type tiny`) with no later edit path; the
147
+ light profile is visible in `task next --list` (a `[light]` text marker and
148
+ `lightProfile` in `--json`) and in doctor's task-hygiene output. The single
149
+ decision source is `task_gate_profiles.is_light_task` (`strict` + the field is
150
+ `tiny`); the start-preflight plan-file exemption still uses the field-level
151
+ `declares_light_profile` so existing pre-strict tiny tasks keep behaving as
152
+ before. The light profile **must not** be used for a task touching runtime /
153
+ gates / specs — that rule rests on visibility and review, not on a machine gate.
154
+ - Read by `cowork-implement`: see .cowork-flow/spec/contracts/subagent-dispatch.md
155
+ - Read by `cowork-check`: same as above
156
+ - `debug.jsonl` reference: optional; on deviation diagnosis it records the anchor
157
+ delta
158
+
159
+ ## Formal-release behavior
160
+
161
+ The formal release does not auto-migrate a legacy `prd.md`. When a task is
162
+ started, only `decision-anchor.md` is recognized as the authoritative decision
163
+ source; if a task directory has only `prd.md` and no `decision-anchor.md`,
164
+ `task next <dir> --run` must fail-closed and report
165
+ `decision-anchor.md is missing or empty`.
166
+
167
+ An existing legacy task needs a human to convert the `prd.md` content into
168
+ `decision-anchor.md`, fill in `## Goal` / `## 目标` and
169
+ `## Acceptance Criteria` / `## 验收标准`, and only then start.