cowork-flow 0.0.47 → 0.0.49
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.
- package/CHANGELOG.md +41 -0
- package/README.md +102 -23
- package/package.json +8 -3
- package/src/cli.js +6 -0
- package/src/commands/init.js +0 -83
- package/src/commands/source-refresh.js +40 -0
- package/src/commands/sync.js +6 -0
- package/src/commands/update.js +59 -6
- package/src/lib/copy-template.js +200 -50
- package/src/lib/host-assets.js +367 -64
- package/src/lib/plan-applier.js +47 -0
- package/template/.claude/hooks/inject-workflow-state.py +7 -0
- package/template/.codex/hooks/inject-workflow-state.py +7 -0
- package/template/.codex/hooks.json +1 -1
- package/template/.cowork-flow/.version +1 -1
- package/template/.cowork-flow/config.yaml +0 -11
- package/template/.cowork-flow/scripts/adapters/cli/init_developer.py +0 -1
- package/template/.cowork-flow/scripts/adapters/cli/subagent.py +7 -4
- package/template/.cowork-flow/scripts/adapters/cli/task.py +8 -484
- package/template/.cowork-flow/scripts/adapters/cli/task_archive_commands.py +15 -134
- package/template/.cowork-flow/scripts/adapters/cli/task_context_commands.py +7 -1
- package/template/.cowork-flow/scripts/adapters/cli/task_lifecycle_commands.py +388 -0
- package/template/.cowork-flow/scripts/adapters/cli/task_navigation.py +163 -2
- package/template/.cowork-flow/scripts/adapters/git/git_context.py +16 -193
- package/template/.cowork-flow/scripts/adapters/host/host_manifest.py +170 -84
- package/template/.cowork-flow/scripts/infra/config.py +0 -17
- package/template/.cowork-flow/scripts/infra/developer_profile.py +0 -95
- package/template/.cowork-flow/scripts/infra/paths.py +0 -79
- package/template/.cowork-flow/scripts/infra/skill_manifest.py +23 -3
- package/template/.cowork-flow/scripts/infra/storage/operation_log.py +40 -0
- package/template/.cowork-flow/scripts/infra/storage/state_store.py +356 -1
- package/template/.cowork-flow/scripts/kernel/workflow_route.py +15 -15
- package/template/.cowork-flow/scripts/run.py +0 -5
- package/template/.cowork-flow/scripts/services/context_discovery.py +156 -0
- package/template/.cowork-flow/scripts/services/context_jsonl.py +119 -0
- package/template/.cowork-flow/scripts/services/context_paths.py +186 -0
- package/template/.cowork-flow/scripts/services/lifecycle_checks.py +186 -69
- package/template/.cowork-flow/scripts/services/lifecycle_policy.py +128 -0
- package/template/.cowork-flow/scripts/services/plan_binding.py +146 -0
- package/template/.cowork-flow/scripts/services/readiness.py +3 -170
- package/template/.cowork-flow/scripts/services/task_archive.py +115 -24
- package/template/.cowork-flow/scripts/services/task_context.py +103 -365
- package/template/.cowork-flow/scripts/services/task_creation.py +40 -5
- package/template/.cowork-flow/scripts/services/task_lifecycle.py +155 -18
- package/template/.cowork-flow/scripts/services/task_routing.py +80 -67
- package/template/.cowork-flow/scripts/services/task_utils.py +0 -146
- package/template/.cowork-flow/scripts/services/workflow_runtime.py +1 -1
- package/template/.cowork-flow/spec/contracts/capabilities.md +23 -0
- package/template/.cowork-flow/spec/contracts/decision-anchor.md +2 -2
- package/template/.cowork-flow/spec/contracts/error-output-as-data.md +8 -0
- package/template/.cowork-flow/spec/contracts/index.md +1 -0
- package/template/.cowork-flow/spec/contracts/party-mode-v2-board.md +20 -0
- package/template/.cowork-flow/spec/contracts/plan-binding.md +50 -0
- package/template/.cowork-flow/spec/contracts/skill-owned-actions.md +31 -7
- package/template/.cowork-flow/spec/guides/index.md +3 -1
- package/template/.cowork-flow/spec/index.md +5 -4
- package/template/.cowork-flow/spec/references/definition-of-done.md +2 -3
- package/template/.cowork-flow/spec/references/orchestration-patterns.md +1 -1
- package/template/.cowork-flow/spec/runtime/contract-registry.json +14 -0
- package/template/.cowork-flow/spec/runtime/host-assets.json +73 -3
- package/template/.cowork-flow/spec/runtime/index.md +1 -1
- package/template/.cowork-flow/spec/schemas/host-assets.schema.json +150 -8
- package/template/.zcode/.zcode-plugin/plugin.json +1 -1
- package/template/skills/batch-execution/SKILL.md +37 -3
- package/template/skills/batch-execution/scripts/batch_action.py +4 -0
- package/template/skills/batch-execution/scripts/batch_execution.py +120 -499
- package/template/skills/batch-execution/scripts/batch_recovery.py +94 -0
- package/template/skills/batch-execution/scripts/batch_state_machine.py +201 -0
- package/template/skills/batch-execution/scripts/batch_verification.py +326 -0
- package/template/skills/brainstorming/SKILL.md +8 -7
- package/template/skills/cowork-flow/SKILL.md +3 -0
- package/template/skills/party-mode/scripts/party_action_contract.py +113 -0
- package/template/skills/party-mode/scripts/party_actions.py +95 -0
- package/template/skills/party-mode/scripts/party_board_store.py +148 -0
- package/template/skills/party-mode/scripts/party_mode_v2.py +345 -317
- package/template/skills/party-mode/scripts/party_reports.py +177 -0
- package/template/skills/party-mode/scripts/party_state_machine.py +189 -0
- package/template/skills/runtime-health/SKILL.md +14 -2
- package/template/skills/runtime-health/scripts/doctor.py +278 -41
- package/template/skills/task-planning/SKILL.md +105 -61
- package/template/skills/task-review/SKILL.md +4 -4
- package/template/skills/task-review/scripts/review_check.py +277 -20
- package/template/skills/test-first/SKILL.md +18 -3
- package/template/skills/test-first/manifest.json +8 -4
- package/template/.cowork-flow/changes/archive/.gitkeep +0 -1
- package/template/.cowork-flow/scripts/adapters/cli/add_session.py +0 -465
- package/template/.cowork-flow/scripts/adapters/cli/change.py +0 -412
- package/template/.cowork-flow/workspace/index.md +0 -102
- package/template/.zcode/scaffold/AGENTS.md +0 -145
- package/template/.zcode/scaffold/CLAUDE.md +0 -5
|
@@ -3,76 +3,13 @@
|
|
|
3
3
|
Task utility functions.
|
|
4
4
|
|
|
5
5
|
Provides:
|
|
6
|
-
is_safe_task_path - Validate task path is safe to operate on
|
|
7
6
|
find_task_by_name - Find task directory by name
|
|
8
|
-
archive_task_dir - Archive task to monthly directory
|
|
9
7
|
"""
|
|
10
8
|
|
|
11
9
|
from __future__ import annotations
|
|
12
10
|
|
|
13
|
-
import sys
|
|
14
|
-
from datetime import datetime
|
|
15
11
|
from pathlib import Path
|
|
16
12
|
|
|
17
|
-
from infra.archive_utils import archive_directory_resumable
|
|
18
|
-
from infra.paths import get_repo_root
|
|
19
|
-
|
|
20
|
-
PATH_TRAVERSAL_PREFIXES = ("./", "../")
|
|
21
|
-
PATH_TRAVERSAL_PART = ".."
|
|
22
|
-
UNSAFE_TASK_PATHS = (".", "..")
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
# =============================================================================
|
|
26
|
-
# Path Safety
|
|
27
|
-
# =============================================================================
|
|
28
|
-
|
|
29
|
-
def is_safe_task_path(task_path: str, repo_root: Path | None = None) -> bool:
|
|
30
|
-
"""Check if a relative task path is safe to operate on.
|
|
31
|
-
|
|
32
|
-
Args:
|
|
33
|
-
task_path: Task path (relative to repo_root).
|
|
34
|
-
repo_root: Repository root path. Defaults to auto-detected.
|
|
35
|
-
|
|
36
|
-
Returns:
|
|
37
|
-
True if safe, False if dangerous.
|
|
38
|
-
"""
|
|
39
|
-
if repo_root is None:
|
|
40
|
-
repo_root = get_repo_root()
|
|
41
|
-
|
|
42
|
-
# Check empty or null
|
|
43
|
-
if not task_path or task_path == "null":
|
|
44
|
-
print("Error: empty or null task path", file=sys.stderr)
|
|
45
|
-
return False
|
|
46
|
-
|
|
47
|
-
# Reject absolute paths
|
|
48
|
-
if task_path.startswith("/"):
|
|
49
|
-
print(f"Error: absolute path not allowed: {task_path}", file=sys.stderr)
|
|
50
|
-
return False
|
|
51
|
-
|
|
52
|
-
# Reject ".", "..", paths starting with "./" or "../", or containing ".."
|
|
53
|
-
has_path_traversal = (
|
|
54
|
-
task_path in UNSAFE_TASK_PATHS
|
|
55
|
-
or task_path.startswith(PATH_TRAVERSAL_PREFIXES)
|
|
56
|
-
or PATH_TRAVERSAL_PART in task_path
|
|
57
|
-
)
|
|
58
|
-
if has_path_traversal:
|
|
59
|
-
print(f"Error: path traversal not allowed: {task_path}", file=sys.stderr)
|
|
60
|
-
return False
|
|
61
|
-
|
|
62
|
-
# Final check: ensure resolved path is not the repo root
|
|
63
|
-
abs_path = repo_root / task_path
|
|
64
|
-
if abs_path.exists():
|
|
65
|
-
try:
|
|
66
|
-
resolved = abs_path.resolve()
|
|
67
|
-
root_resolved = repo_root.resolve()
|
|
68
|
-
if resolved == root_resolved:
|
|
69
|
-
print(f"Error: path resolves to repo root: {task_path}", file=sys.stderr)
|
|
70
|
-
return False
|
|
71
|
-
except (OSError, IOError):
|
|
72
|
-
pass
|
|
73
|
-
|
|
74
|
-
return True
|
|
75
|
-
|
|
76
13
|
|
|
77
14
|
# =============================================================================
|
|
78
15
|
# Task Lookup
|
|
@@ -102,86 +39,3 @@ def find_task_by_name(task_name: str, tasks_dir: Path) -> Path | None:
|
|
|
102
39
|
return candidate
|
|
103
40
|
|
|
104
41
|
return None
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
# =============================================================================
|
|
108
|
-
# Archive Operations
|
|
109
|
-
# =============================================================================
|
|
110
|
-
|
|
111
|
-
def archive_task_dir(task_dir_abs: Path, repo_root: Path | None = None) -> Path | None:
|
|
112
|
-
"""Archive a task directory to archive/{YYYY-MM}/.
|
|
113
|
-
|
|
114
|
-
Args:
|
|
115
|
-
task_dir_abs: Absolute path to task directory.
|
|
116
|
-
repo_root: Repository root path. Defaults to auto-detected.
|
|
117
|
-
|
|
118
|
-
Returns:
|
|
119
|
-
Path to archived directory, or None on error.
|
|
120
|
-
"""
|
|
121
|
-
if not task_dir_abs.is_dir():
|
|
122
|
-
print(f"Error: task directory not found: {task_dir_abs}", file=sys.stderr)
|
|
123
|
-
return None
|
|
124
|
-
|
|
125
|
-
# Get tasks directory (parent of the task)
|
|
126
|
-
tasks_dir = task_dir_abs.parent
|
|
127
|
-
archive_dir = tasks_dir / "archive"
|
|
128
|
-
year_month = datetime.now().strftime("%Y-%m")
|
|
129
|
-
month_dir = archive_dir / year_month
|
|
130
|
-
|
|
131
|
-
# Create archive directory
|
|
132
|
-
try:
|
|
133
|
-
month_dir.mkdir(parents=True, exist_ok=True)
|
|
134
|
-
except (OSError, IOError) as e:
|
|
135
|
-
print(f"Error: Failed to create archive directory: {e}", file=sys.stderr)
|
|
136
|
-
return None
|
|
137
|
-
|
|
138
|
-
# Move task to archive
|
|
139
|
-
task_name = task_dir_abs.name
|
|
140
|
-
archive_dest = month_dir / task_name
|
|
141
|
-
|
|
142
|
-
result = archive_directory_resumable(task_dir_abs, archive_dest)
|
|
143
|
-
if not result.ok:
|
|
144
|
-
level = "Warning" if result.partial else "Error"
|
|
145
|
-
print(f"{level}: {result.message}", file=sys.stderr)
|
|
146
|
-
return None
|
|
147
|
-
|
|
148
|
-
return archive_dest
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
def archive_task_complete(
|
|
152
|
-
task_dir_abs: Path,
|
|
153
|
-
repo_root: Path | None = None
|
|
154
|
-
) -> dict[str, str]:
|
|
155
|
-
"""Complete archive workflow: archive directory.
|
|
156
|
-
|
|
157
|
-
Args:
|
|
158
|
-
task_dir_abs: Absolute path to task directory.
|
|
159
|
-
repo_root: Repository root path. Defaults to auto-detected.
|
|
160
|
-
|
|
161
|
-
Returns:
|
|
162
|
-
Dict with archive result info.
|
|
163
|
-
"""
|
|
164
|
-
if not task_dir_abs.is_dir():
|
|
165
|
-
print(f"Error: task directory not found: {task_dir_abs}", file=sys.stderr)
|
|
166
|
-
return {}
|
|
167
|
-
|
|
168
|
-
archive_dest = archive_task_dir(task_dir_abs, repo_root)
|
|
169
|
-
if archive_dest:
|
|
170
|
-
return {"archived_to": str(archive_dest)}
|
|
171
|
-
|
|
172
|
-
return {}
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
# =============================================================================
|
|
176
|
-
# Main Entry (for testing)
|
|
177
|
-
# =============================================================================
|
|
178
|
-
|
|
179
|
-
if __name__ == "__main__":
|
|
180
|
-
from infra.paths import get_tasks_dir
|
|
181
|
-
|
|
182
|
-
repo = get_repo_root()
|
|
183
|
-
tasks = get_tasks_dir(repo)
|
|
184
|
-
|
|
185
|
-
print(f"Tasks dir: {tasks}")
|
|
186
|
-
print(f"is_safe_task_path('.cowork-flow/tasks/test'): {is_safe_task_path('.cowork-flow/tasks/test', repo)}")
|
|
187
|
-
print(f"is_safe_task_path('../test'): {is_safe_task_path('../test', repo)}")
|
|
@@ -15,6 +15,29 @@
|
|
|
15
15
|
|
|
16
16
|
## Required capabilities
|
|
17
17
|
|
|
18
|
+
`host-assets.json` has two capability layers:
|
|
19
|
+
|
|
20
|
+
- Adapter capabilities (`platforms[].capabilities`) describe low-level Host
|
|
21
|
+
primitives that an adapter can compare against its `adapter.yaml`.
|
|
22
|
+
- Host-neutral capabilities (`capabilityMatrix`) describe workflow actions that
|
|
23
|
+
product/runtime code can ask a Host to perform without naming Host-specific
|
|
24
|
+
primitives.
|
|
25
|
+
|
|
26
|
+
The Host-neutral matrix is the canonical product contract for these actions:
|
|
27
|
+
|
|
28
|
+
- `task_action`: run a lifecycle or Skill-owned action.
|
|
29
|
+
- `subagent_dispatch`: dispatch a runtime-context-bound formal child agent.
|
|
30
|
+
- `file_write`: let the Host produce repository file mutations.
|
|
31
|
+
- `party_board_action`: execute Party Mode v2 board actions through supported
|
|
32
|
+
child-control primitives or an explicit fallback.
|
|
33
|
+
|
|
34
|
+
Every Host entry in `capabilityMatrix.hosts` must declare all four actions.
|
|
35
|
+
If an action is `unsupported`, the declaration must include a non-empty
|
|
36
|
+
`fallback` value. Runtime-health treats missing declarations, unknown status
|
|
37
|
+
values, and unsupported actions without fallback as Host validation failures.
|
|
38
|
+
|
|
39
|
+
## Adapter capabilities
|
|
40
|
+
|
|
18
41
|
- `dispatchSubagent`: create a child agent for formal workflow work.
|
|
19
42
|
- `freshChildContext`: start child with bounded context, not inherited full session history.
|
|
20
43
|
- `runtimeContextDispatch`: create a runtime context before child dispatch.
|
|
@@ -58,7 +58,7 @@
|
|
|
58
58
|
|
|
59
59
|
## Lifecycle Check 联动
|
|
60
60
|
|
|
61
|
-
- `task
|
|
61
|
+
- `task next <dir> --run` 启动任务时的 preflight 检查 `decision-anchor.md` 非空,并要求 `## 目标` 和 `## 验收标准` 章节存在。
|
|
62
62
|
- `cowork-implement` 读取:见 .cowork-flow/spec/contracts/subagent-dispatch.md
|
|
63
63
|
- `cowork-check` 读取:同上
|
|
64
64
|
- `debug.jsonl` 引用:可选,偏差诊断时写入 anchor 锚点差异
|
|
@@ -67,7 +67,7 @@
|
|
|
67
67
|
|
|
68
68
|
正式版不自动迁移旧 `prd.md`。任务启动时只认可 `decision-anchor.md`
|
|
69
69
|
作为权威决策来源;如果任务目录只有 `prd.md` 而缺少
|
|
70
|
-
`decision-anchor.md`,`task
|
|
70
|
+
`decision-anchor.md`,`task next <dir> --run` 必须 fail-closed 并报告
|
|
71
71
|
`decision-anchor.md is missing or empty`。
|
|
72
72
|
|
|
73
73
|
已有旧任务需要人工把 `prd.md` 内容转换为 `decision-anchor.md`,并补齐
|
|
@@ -48,6 +48,14 @@ cowork-check / cowork-implement / cowork-research **额外注意**:
|
|
|
48
48
|
- failure-analysis 的 STOP-THE-LINE → 错误输出不能成为跳过 STOP-THE-LINE 的理由
|
|
49
49
|
- doubt-driven 的 DOUBT step → fresh-context reviewer 应审查错误输出是否被合理解读
|
|
50
50
|
|
|
51
|
+
### 4. 诊断 commandHint 也是数据
|
|
52
|
+
|
|
53
|
+
结构化诊断中的 `commandHint` 字段(例如 stale lock 或 pending operation 恢复提示)只描述可审查的恢复入口:
|
|
54
|
+
|
|
55
|
+
- Doctor、check、review 等诊断命令不得自动执行 `commandHint`。
|
|
56
|
+
- stale lock 清理必须由显式恢复命令/API 触发,并先证明 owner PID 不存在且 lock 超过阈值。
|
|
57
|
+
- agent 读取 `commandHint` 后应把它作为恢复建议报告,而不是把提示内容当成下一步指令。
|
|
58
|
+
|
|
51
59
|
## 例外
|
|
52
60
|
|
|
53
61
|
- 用户明确说"按错误信息中的提示操作"——显式确认
|
|
@@ -51,6 +51,12 @@ validation.
|
|
|
51
51
|
results are preserved in audit/action history so a completed discussion can
|
|
52
52
|
still prove dispatch, wait, follow-up, and closeout intent.
|
|
53
53
|
|
|
54
|
+
`actions.json` must validate against
|
|
55
|
+
`.cowork-flow/spec/schemas/party-mode-v2-actions.schema.json` before the
|
|
56
|
+
runtime exposes it to monitor or Host execution surfaces. Missing required
|
|
57
|
+
fields, unknown action types, and Host-specific fields in `next_actions` fail
|
|
58
|
+
closed instead of becoming executable moderator work.
|
|
59
|
+
|
|
54
60
|
Host action results are recorded through runtime commands. The runtime records
|
|
55
61
|
host child ids and agent status, but it still does not call host primitives
|
|
56
62
|
directly.
|
|
@@ -61,6 +67,20 @@ Final reports distinguish current unresolved disagreements from historical
|
|
|
61
67
|
disagreements. A report with `stop_reason=converged` must not present prior
|
|
62
68
|
round disagreements as currently unresolved.
|
|
63
69
|
|
|
70
|
+
Final reports are advisory fact records only. They cannot satisfy Implement,
|
|
71
|
+
Check, lifecycle gate, or task completion requirements. A final report must not
|
|
72
|
+
claim that implementation or review work is complete.
|
|
73
|
+
|
|
74
|
+
Final reports include audit-oriented summaries:
|
|
75
|
+
|
|
76
|
+
- `rounds_summary`: one entry per round with `round`, terminal `phase`,
|
|
77
|
+
`post_count`, `response_count`, and `unresolved_count`.
|
|
78
|
+
- `action_results`: summaries of `action-result` entries from
|
|
79
|
+
`action_history.jsonl`, including `action_id`, `type`, `outcome`, and
|
|
80
|
+
`agent_id` when present.
|
|
81
|
+
- `accepted_evidence`: evidence accepted by `concede` responses, linked to
|
|
82
|
+
`agent_id` and `target_post_id`.
|
|
83
|
+
|
|
64
84
|
## Moderator Boundary
|
|
65
85
|
|
|
66
86
|
The moderator monitors runtime status, executes host-neutral next actions, and
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# Plan Binding Contract
|
|
2
|
+
|
|
3
|
+
计划绑定让开发计划进入实施路径,但不把计划变成第二套流程内核。
|
|
4
|
+
|
|
5
|
+
## 权威边界
|
|
6
|
+
|
|
7
|
+
- `decision-anchor.md` 继续承载目标、验收标准和范围判断。
|
|
8
|
+
- `implement.jsonl` 继续承载 review/complete 的硬文件范围。
|
|
9
|
+
- `.cowork-flow/plans/*.md` 承载实施顺序、文件边界、验证命令和禁止漂移说明。
|
|
10
|
+
- `task.json.meta.planFile` 只记录 repo-relative 计划路径。
|
|
11
|
+
|
|
12
|
+
## 创建阶段
|
|
13
|
+
|
|
14
|
+
- 普通 `task create` 可以创建没有计划的 planning task。
|
|
15
|
+
- `task create --from-plan <path>` 是显式绑定请求;`<path>` 必须存在、位于仓库内,并位于 `.cowork-flow/plans/` 下。
|
|
16
|
+
- 成功绑定后,runtime 写入:
|
|
17
|
+
|
|
18
|
+
```json
|
|
19
|
+
{
|
|
20
|
+
"meta": {
|
|
21
|
+
"planFile": ".cowork-flow/plans/YYYY-MM-DD-slug.md"
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## 启动实施前
|
|
27
|
+
|
|
28
|
+
Normal / High-risk task 从 `planning` 进入 `in_progress` 前必须满足:
|
|
29
|
+
|
|
30
|
+
- `task.json.meta.planFile` 存在。
|
|
31
|
+
- `planFile` 是 repo-relative `.cowork-flow/plans/` 路径。
|
|
32
|
+
- 计划文件存在且非空。
|
|
33
|
+
- `decision-anchor.md` 包含 `## 目标` 和 `## 验收标准`。
|
|
34
|
+
- `implement.jsonl` 通过既有 context validation。
|
|
35
|
+
|
|
36
|
+
Tiny task 可以没有 planFile,但仍必须满足现有 anchor 与 implement 范围要求。
|
|
37
|
+
|
|
38
|
+
## 实施恢复
|
|
39
|
+
|
|
40
|
+
当 active task 绑定了 `meta.planFile`,恢复清单必须提示先读取当前计划,再读取 `decision-anchor.md` 和 JSONL context。恢复输出只列路径,不展开计划正文。
|
|
41
|
+
|
|
42
|
+
## v1 非目标
|
|
43
|
+
|
|
44
|
+
- 不解析计划 step 状态。
|
|
45
|
+
- 不做 Markdown AST 或 DSL。
|
|
46
|
+
- 不比较 AC 文本与计划任务正文。
|
|
47
|
+
- 不匹配验证命令和证据记录。
|
|
48
|
+
- 不引入 plan approval 数据模型。
|
|
49
|
+
|
|
50
|
+
这些能力只能在 warning 噪音和真实收益被验证后再考虑。
|
|
@@ -24,8 +24,11 @@ At load time every managed action and command must have exactly one owner.
|
|
|
24
24
|
Lifecycle state, session/runtime-context, file scope, approval checks, and
|
|
25
25
|
transactional persistence remain in the shared runtime. After shared Batch
|
|
26
26
|
approval, the adapter invokes the manifest-owned `batch-action start`; Batch
|
|
27
|
-
resume and result recording are also Skill commands rather
|
|
28
|
-
handlers.
|
|
27
|
+
resume, read-only inspect, and result recording are also Skill commands rather
|
|
28
|
+
than task CLI handlers. `batch-action inspect <operation_id>` may report
|
|
29
|
+
existing operation facts, including current phase, current task, failed action,
|
|
30
|
+
next action, and recovery hints, but it must not advance, resume, create, or
|
|
31
|
+
save Batch state.
|
|
29
32
|
|
|
30
33
|
Review-oriented Skill commands may provide advisory facts, such as changed-file
|
|
31
34
|
coverage, applicable spec sources, and test-intent signals. An action-level
|
|
@@ -33,6 +36,10 @@ coverage, applicable spec sources, and test-intent signals. An action-level
|
|
|
33
36
|
it does not make the helper runnable as a lifecycle action. They must remain
|
|
34
37
|
read-only helpers: no task-local review evidence file, lifecycle state mutation,
|
|
35
38
|
natural-language spec hard gate, or pass/fail completion verdict.
|
|
39
|
+
`task-review` JSON output may add `normalizedIssues` for machine consumers. Each
|
|
40
|
+
normalized issue uses the stable envelope `code`, `severity`, `path`, `message`,
|
|
41
|
+
and `source`, while existing `scopeFacts` and `testIntentSignals` fields remain
|
|
42
|
+
the compatibility contract for older consumers.
|
|
36
43
|
|
|
37
44
|
Text and JSON task navigation render the same resolved action contract. Text
|
|
38
45
|
adapters may show the action label, owner, command, and blockers, but must not
|
|
@@ -41,15 +48,32 @@ Skill contains the detailed phase guidance. Context consumers use the
|
|
|
41
48
|
manifest-selected entries and a stable lexical order; services do not maintain
|
|
42
49
|
Skill-id priority tables.
|
|
43
50
|
|
|
51
|
+
Route services use `lifecycleCheck` as the internal lifecycle-check field.
|
|
52
|
+
`runtimeGate` is a compatibility alias owned by task-navigation adapters and may
|
|
53
|
+
be emitted in text or JSON route payloads for older consumers. Kernel and
|
|
54
|
+
service-layer contracts must not depend on `runtimeGate`; they compare Skill
|
|
55
|
+
manifest ownership against `lifecycleCheck` and add compatibility aliases only
|
|
56
|
+
when rendering adapter output.
|
|
57
|
+
|
|
58
|
+
Lifecycle checks may expose structured issue facts in addition to blocker
|
|
59
|
+
messages. The blocker messages remain the human-facing compatibility contract,
|
|
60
|
+
while advisory helpers such as `task-review` should prefer structured issue
|
|
61
|
+
codes and paths when classifying protected workflow files, unlisted changed
|
|
62
|
+
files, or task-context problems.
|
|
63
|
+
|
|
44
64
|
Runtime Health has two scopes. An installed project validates its installed
|
|
45
65
|
runtime, detected host platforms, and installed Skill manifests without
|
|
46
66
|
requiring a `template/` directory. A cowork-flow source checkout distinguishes
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
67
|
+
ignored local live runtime from the template distribution source. Source
|
|
68
|
+
checkout health must not force-track `.cowork-flow/` runtime files: local live
|
|
69
|
+
runtime is compared only when present, and Skill replica parity is checked for
|
|
70
|
+
every detected installed Skill target.
|
|
51
71
|
|
|
52
72
|
Runtime Health also reports stale task hygiene read-only. It may warn about
|
|
53
73
|
completed-unarchived tasks, active-unbound tasks, and missing task context, and
|
|
54
74
|
it may include command hints. These warnings must not mutate task lifecycle
|
|
55
|
-
state, write evidence files, or become completion gates.
|
|
75
|
+
state, write evidence files, or become completion gates. Runtime Health JSON
|
|
76
|
+
issues use a stable envelope: `code`, `severity`, `path`, `message`,
|
|
77
|
+
`commandHint`, and `contract`. Task hygiene output keeps its compatibility
|
|
78
|
+
fields such as `kind`, `task`, `status`, and `hint`; host-adapter JSON output
|
|
79
|
+
uses the same envelope for asset validation failures.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# 思考指引
|
|
2
2
|
|
|
3
|
-
>
|
|
3
|
+
> 本目录不讲实现细节,只提醒最容易出问题的思考点;主要供 brainstorming 与 task-planning 在编码前使用。
|
|
4
4
|
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -16,6 +16,8 @@
|
|
|
16
16
|
|
|
17
17
|
## 使用方式
|
|
18
18
|
|
|
19
|
+
- 需求不清晰时,在 brainstorming 阶段用这些指引收敛目标、非目标、边界和验收标准
|
|
20
|
+
- 编写计划时,在 task-planning 阶段把选中的结论写进 decision-anchor 或任务计划
|
|
19
21
|
- 写代码前先看 [编码前检查表](./pre-implementation-checklist.md)
|
|
20
22
|
- 涉及跨模块、异步链路、权限或状态流转时,看 [跨层思考指引](./cross-layer-thinking-guide.md)
|
|
21
23
|
- 涉及公共能力、常量、错误码、查询模板、校验逻辑时,看 [代码复用思考指引](./code-reuse-thinking-guide.md)
|
|
@@ -8,15 +8,16 @@
|
|
|
8
8
|
| `runtime/` | runtime 读取的机器配置,包括 contract registry 和 host asset manifest。 |
|
|
9
9
|
| `schemas/` | runtime 配置和宿主合同的 JSON Schema。 |
|
|
10
10
|
| `backend/` | 后端实现规范;由 review skill 按需读取并逐条审查。 |
|
|
11
|
-
| `frontend/` |
|
|
12
|
-
| `guides/` |
|
|
11
|
+
| `frontend/` | 前端实现规范;由 review skill 按需读取并逐条审查。 |
|
|
12
|
+
| `guides/` | brainstorming/task-planning 阶段的编码前思考、跨层设计和复用判断指引。 |
|
|
13
13
|
| `references/` | 按需参考材料(DoD、测试清单、安全清单、协作模式);不自动加载。加载条件见 contract-registry.json 的 references 数组。 |
|
|
14
14
|
|
|
15
15
|
流程内核只负责任务状态、文件范围、runtime context、归档一致性等可机器判断的事实。
|
|
16
16
|
动作、阶段指导和专属运行时由各 Skill 的 `manifest.json` 声明;不维护集中式
|
|
17
17
|
Skill registry。
|
|
18
|
-
`backend/`、`frontend
|
|
18
|
+
`backend/`、`frontend/` 中的自然语言规范不注册为 runtime gate;
|
|
19
19
|
`task-review` skill 根据当前 diff 和任务范围读取并逐条审查。
|
|
20
|
+
`guides/` 属于前置澄清与计划参考;选用后的结论应进入 `decision-anchor.md` 或任务计划。
|
|
20
21
|
|
|
21
22
|
## references/
|
|
22
23
|
|
|
@@ -25,7 +26,7 @@ Skill registry。
|
|
|
25
26
|
reference 文件之作用是:
|
|
26
27
|
1. 为 skill 入口提供补充上下文(main skill 是入口,reference 是补充)
|
|
27
28
|
2. 减少每次会话需加载的内容(spec/backend/ 等窄域规范只有实际需要时才加载)
|
|
28
|
-
3. 在 check 或 review 阶段提供快速对照清单
|
|
29
|
+
3. 在 planning、check 或 review 阶段提供快速对照清单
|
|
29
30
|
|
|
30
31
|
加载规则:
|
|
31
32
|
- contract-registry 中 loadWhen 之一被匹配时读取
|
|
@@ -24,8 +24,7 @@
|
|
|
24
24
|
| # | 检查项 |
|
|
25
25
|
|---|---|
|
|
26
26
|
| L1-1 | brainstorming 记录存在 |
|
|
27
|
-
| L1-2 |
|
|
28
|
-
| L1-3 | 修改未扩散到无关模块(git diff 范围与 task.scope 一致)|
|
|
27
|
+
| L1-2 | 修改未扩散到无关模块(git diff 范围与 task.scope 一致)|
|
|
29
28
|
|
|
30
29
|
## L2 专属(跨层 / 架构 / 迁移)
|
|
31
30
|
|
|
@@ -33,7 +32,7 @@
|
|
|
33
32
|
|---|---|
|
|
34
33
|
| L2-1 | proposal.md / spec.md / design.md 齐全 |
|
|
35
34
|
| L2-2 | 结构化决策审查已按 Skill 指导完成或明确记录不适用 |
|
|
36
|
-
| L2-3 | readiness gate
|
|
35
|
+
| L2-3 | readiness gate 全部通过(`task next <dir> --run` 无 blocker)|
|
|
37
36
|
| L2-4 | spec-sync Skill 已确认规格同步或明确记录无需更新 |
|
|
38
37
|
|
|
39
38
|
## DoD 与 per-task AC 的区别
|
|
@@ -52,7 +52,7 @@
|
|
|
52
52
|
## 模式 3:顺序 skill 链(已实现,用户驱动)
|
|
53
53
|
|
|
54
54
|
```
|
|
55
|
-
用户执行:
|
|
55
|
+
用户执行: task next --run --title ... -> brainstorming -> task-planning -> task next <dir> --run -> implement -> check -> task next <dir> --run --intent review
|
|
56
56
|
```
|
|
57
57
|
|
|
58
58
|
**使用场景**: 阶段之间有依赖关系,用户在阶段间判断有价值。
|
|
@@ -89,6 +89,20 @@
|
|
|
89
89
|
"when debugging production errors",
|
|
90
90
|
"when handling errors from third-party tools or services"
|
|
91
91
|
]
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
"id": "PLAN_BINDING_LITE_V1",
|
|
95
|
+
"path": ".cowork-flow/spec/contracts/plan-binding.md",
|
|
96
|
+
"digest": [
|
|
97
|
+
"Plan binding records repo-relative task.json.meta.planFile.",
|
|
98
|
+
"Task start blocks clear missing plan facts for non-Tiny tasks.",
|
|
99
|
+
"V1 does not parse plan steps, AC text, or verification evidence."
|
|
100
|
+
],
|
|
101
|
+
"readWhen": [
|
|
102
|
+
"when changing task creation plan binding",
|
|
103
|
+
"when changing task start readiness",
|
|
104
|
+
"when changing resume context for active tasks"
|
|
105
|
+
]
|
|
92
106
|
}
|
|
93
107
|
],
|
|
94
108
|
"references": [
|
|
@@ -8,6 +8,74 @@
|
|
|
8
8
|
"experimental",
|
|
9
9
|
"unsupported"
|
|
10
10
|
],
|
|
11
|
+
"capabilityMatrix": {
|
|
12
|
+
"required": [
|
|
13
|
+
"task_action",
|
|
14
|
+
"subagent_dispatch",
|
|
15
|
+
"file_write",
|
|
16
|
+
"party_board_action"
|
|
17
|
+
],
|
|
18
|
+
"hosts": {
|
|
19
|
+
"codex": {
|
|
20
|
+
"task_action": {
|
|
21
|
+
"status": "native"
|
|
22
|
+
},
|
|
23
|
+
"subagent_dispatch": {
|
|
24
|
+
"status": "native"
|
|
25
|
+
},
|
|
26
|
+
"file_write": {
|
|
27
|
+
"status": "native"
|
|
28
|
+
},
|
|
29
|
+
"party_board_action": {
|
|
30
|
+
"status": "native"
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
"opencode": {
|
|
34
|
+
"task_action": {
|
|
35
|
+
"status": "native"
|
|
36
|
+
},
|
|
37
|
+
"subagent_dispatch": {
|
|
38
|
+
"status": "native"
|
|
39
|
+
},
|
|
40
|
+
"file_write": {
|
|
41
|
+
"status": "native"
|
|
42
|
+
},
|
|
43
|
+
"party_board_action": {
|
|
44
|
+
"status": "experimental"
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
"claude-code": {
|
|
48
|
+
"task_action": {
|
|
49
|
+
"status": "native"
|
|
50
|
+
},
|
|
51
|
+
"subagent_dispatch": {
|
|
52
|
+
"status": "native"
|
|
53
|
+
},
|
|
54
|
+
"file_write": {
|
|
55
|
+
"status": "native"
|
|
56
|
+
},
|
|
57
|
+
"party_board_action": {
|
|
58
|
+
"status": "native"
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
"zcode": {
|
|
62
|
+
"task_action": {
|
|
63
|
+
"status": "plugin"
|
|
64
|
+
},
|
|
65
|
+
"subagent_dispatch": {
|
|
66
|
+
"status": "plugin"
|
|
67
|
+
},
|
|
68
|
+
"file_write": {
|
|
69
|
+
"status": "unsupported",
|
|
70
|
+
"fallback": "project_root_init_or_sync"
|
|
71
|
+
},
|
|
72
|
+
"party_board_action": {
|
|
73
|
+
"status": "unsupported",
|
|
74
|
+
"fallback": "inline_or_manual"
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
},
|
|
11
79
|
"platforms": [
|
|
12
80
|
{
|
|
13
81
|
"id": "codex",
|
|
@@ -131,9 +199,7 @@
|
|
|
131
199
|
],
|
|
132
200
|
"protectedPrefixes": [
|
|
133
201
|
".cowork-flow/spec/",
|
|
134
|
-
".cowork-flow/workspace/",
|
|
135
202
|
".cowork-flow/tasks/",
|
|
136
|
-
".cowork-flow/changes/",
|
|
137
203
|
".cowork-flow/plans/"
|
|
138
204
|
],
|
|
139
205
|
"safeFiles": [
|
|
@@ -253,7 +319,11 @@
|
|
|
253
319
|
".cowork-flow/spec/schemas/rules.schema.json",
|
|
254
320
|
".cowork-flow/spec/runtime/skill-registry.json",
|
|
255
321
|
".cowork-flow/spec/schemas/skill-registry.schema.json",
|
|
256
|
-
".cowork-flow/workflow.md"
|
|
322
|
+
".cowork-flow/workflow.md",
|
|
323
|
+
".cowork-flow/scripts/adapters/cli/add_session.py",
|
|
324
|
+
".cowork-flow/workspace/index.md",
|
|
325
|
+
".cowork-flow/scripts/adapters/cli/change.py",
|
|
326
|
+
".cowork-flow/changes/"
|
|
257
327
|
]
|
|
258
328
|
}
|
|
259
329
|
}
|
|
@@ -14,6 +14,6 @@
|
|
|
14
14
|
运行时写入边界:
|
|
15
15
|
|
|
16
16
|
- CLI/宿主/Git 适配层位于 `scripts/adapters/`,用例服务位于 `scripts/services/`。
|
|
17
|
-
- JSON 状态通过 `scripts/
|
|
17
|
+
- JSON 状态通过 `scripts/infra/storage/` 读写并显式使用 UTF-8。
|
|
18
18
|
- init/sync 通过 Asset Plan、staging、备份和 rollback 提交资产,版本文件最后更新。
|
|
19
19
|
- 旧状态只允许在带迁移测试的读取边界兼容;新写入必须使用当前 schema 和权威路径。
|