@aipper/aiws-spec 0.0.32 → 0.0.33
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/docs/workflow-governance-rules.json +11 -7
- package/docs/workflow-governance-rules.md +19 -19
- package/docs/workflow-governance-rules.schema.json +1 -0
- package/docs/workflow-review-gates.json +5 -5
- package/docs/workflow-review-gates.md +4 -4
- package/docs/workflow-stage-contracts.json +2 -2
- package/docs/workflow-stage-contracts.md +2 -2
- package/docs/ws-goal-contract.md +239 -0
- package/package.json +1 -1
- package/templates/workspace/.agents/skills/using-aiws/SKILL.md +7 -0
- package/templates/workspace/.agents/skills/ws-goal/SKILL.md +89 -0
- package/templates/workspace/.agents/skills/ws-intake/SKILL.md +30 -11
- package/templates/workspace/.agents/skills/ws-research/SKILL.md +56 -0
- package/templates/workspace/.aiws/tools/ws_change_check.py +11 -4
- package/templates/workspace/.claude/commands/ws-goal.md +34 -0
- package/templates/workspace/.claude/skills/ws-intake/SKILL.md +26 -4
- package/templates/workspace/.opencode/command/ws-goal.md +39 -0
- package/templates/workspace/.opencode/lib/aiws-context.js +38 -4
- package/templates/workspace/.opencode/oh-my-opencode.json.example +5 -0
- package/templates/workspace/.opencode/skills/ws-intake/SKILL.md +61 -6
- package/templates/workspace/manifest.json +25 -20
- package/templates/workspace/tools/ws_tasks_plan.py +97 -0
|
@@ -32,13 +32,6 @@
|
|
|
32
32
|
"recommendedStage": "ws-finish",
|
|
33
33
|
"rationale": "finish already completed locally, but archive/push closeout is still pending; rerun finish to resume"
|
|
34
34
|
},
|
|
35
|
-
{
|
|
36
|
-
"id": "strict_blockers",
|
|
37
|
-
"when": { "signal": "blockers_strict_count", "gt": 0 },
|
|
38
|
-
"currentStage": "ws-plan-verify",
|
|
39
|
-
"recommendedStage": "ws-plan-verify",
|
|
40
|
-
"rationale": "strict blockers remain unresolved"
|
|
41
|
-
},
|
|
42
35
|
{
|
|
43
36
|
"id": "unchecked_tasks",
|
|
44
37
|
"when": { "signal": "tasks_unchecked", "gt": 0 },
|
|
@@ -77,6 +70,7 @@
|
|
|
77
70
|
{
|
|
78
71
|
"id": "review_missing",
|
|
79
72
|
"when": { "signal": "review_effective_count", "eq": 0 },
|
|
73
|
+
"phase": "deliver",
|
|
80
74
|
"currentStage": "ws-review",
|
|
81
75
|
"recommendedStage": "ws-review",
|
|
82
76
|
"rationale": "deliver-ready state has no review artifact yet"
|
|
@@ -84,6 +78,7 @@
|
|
|
84
78
|
{
|
|
85
79
|
"id": "dual_review_incomplete",
|
|
86
80
|
"when": { "signal": "dual_review_missing_count", "gt": 0 },
|
|
81
|
+
"phase": "deliver",
|
|
87
82
|
"currentStage": "ws-review",
|
|
88
83
|
"recommendedStage": "ws-review",
|
|
89
84
|
"rationale": "dual review gate incomplete (spec={spec_review_status}, quality={quality_review_status})"
|
|
@@ -91,6 +86,7 @@
|
|
|
91
86
|
{
|
|
92
87
|
"id": "review_conflicted",
|
|
93
88
|
"when": { "signal": "git_conflicted", "gt": 0 },
|
|
89
|
+
"phase": "deliver",
|
|
94
90
|
"currentStage": "ws-commit",
|
|
95
91
|
"recommendedStage": "ws-commit",
|
|
96
92
|
"rationale": "review exists but the change branch still has merge conflicts"
|
|
@@ -98,6 +94,7 @@
|
|
|
98
94
|
{
|
|
99
95
|
"id": "review_dirty",
|
|
100
96
|
"when": { "signal": "git_total", "gt": 0 },
|
|
97
|
+
"phase": "deliver",
|
|
101
98
|
"currentStage": "ws-commit",
|
|
102
99
|
"recommendedStage": "ws-commit",
|
|
103
100
|
"rationale": "review exists but the change branch is still dirty"
|
|
@@ -137,6 +134,13 @@
|
|
|
137
134
|
"recommendedStage": "ws-deliver",
|
|
138
135
|
"rationale": "delivery evidence exists but finish gate is incomplete (missing={finish_gate_missing_count})"
|
|
139
136
|
},
|
|
137
|
+
{
|
|
138
|
+
"id": "strict_blockers",
|
|
139
|
+
"when": { "signal": "blockers_strict_count", "gt": 0 },
|
|
140
|
+
"currentStage": "ws-plan-verify",
|
|
141
|
+
"recommendedStage": "ws-plan-verify",
|
|
142
|
+
"rationale": "strict blockers remain unresolved"
|
|
143
|
+
},
|
|
140
144
|
{
|
|
141
145
|
"id": "deliver_evidence_converged_submodules",
|
|
142
146
|
"when": {
|
|
@@ -16,25 +16,25 @@
|
|
|
16
16
|
|
|
17
17
|
## 阶段推断规则
|
|
18
18
|
|
|
19
|
-
| Rule ID | Match | Current | Next | Rationale |
|
|
20
|
-
| --- | --- | --- | --- | --- |
|
|
21
|
-
| `finish_resume_required` | `finish_resume_required` is truthy | `ws-finish` | `ws-finish` | finish already completed locally, but archive/push closeout is still pending; rerun finish to resume |
|
|
22
|
-
| `
|
|
23
|
-
| `
|
|
24
|
-
| `
|
|
25
|
-
| `
|
|
26
|
-
| `
|
|
27
|
-
| `
|
|
28
|
-
| `
|
|
29
|
-
| `
|
|
30
|
-
| `
|
|
31
|
-
| `
|
|
32
|
-
| `
|
|
33
|
-
| `
|
|
34
|
-
| `deliver_evidence_converged_submodules` | (`repo_submodules` > 0) AND ((`evidence_persistent_count` > 0) OR (`lifecycle_evidence_runs` > 0)) AND (`finish_gate_missing_count` == `0`) | `ws-deliver` | `ws-finish` | delivery evidence and finish gate are converged; next step is submodule-aware finish |
|
|
35
|
-
| `deliver_evidence_converged` | ((`evidence_persistent_count` > 0) OR (`lifecycle_evidence_runs` > 0)) AND (`finish_gate_missing_count` == `0`) | `ws-deliver` | `ws-finish` | delivery evidence and finish gate are converged; next step is safe finish |
|
|
36
|
-
| `deliver_evidence_pending_submodules` | `repo_submodules` > 0 | `ws-deliver` | `ws-deliver` | submodule-aware delivery/evidence convergence is still required |
|
|
37
|
-
| `deliver_evidence_pending` | (default) | `ws-deliver` | `ws-deliver` | delivery evidence is still required before finish |
|
|
19
|
+
| Rule ID | Match | Phase | Current | Next | Rationale |
|
|
20
|
+
| --- | --- | --- | --- | --- | --- |
|
|
21
|
+
| `finish_resume_required` | `finish_resume_required` is truthy | | `ws-finish` | `ws-finish` | finish already completed locally, but archive/push closeout is still pending; rerun finish to resume |
|
|
22
|
+
| `unchecked_tasks` | `tasks_unchecked` > 0 | | `ws-dev` | `ws-dev` | {tasks_unchecked} unchecked task(s) remain |
|
|
23
|
+
| `finish_completed` | `finish_state` == `done` | | `ws-finish` | `ws-handoff` | finish completed; archive should already exist and handoff is ready for follow-up |
|
|
24
|
+
| `finish_failed` | `finish_state` == `failed` | | `ws-finish` | `ws-finish` | finish started locally but push/cleanup failed; resolve and rerun finish |
|
|
25
|
+
| `finish_cleanup_pending` | `finish_state` == `cleanup_pending` | | `ws-finish` | `ws-finish` | push completed but cleanup is still pending ({finish_state_reason}); resolve and rerun finish |
|
|
26
|
+
| `finish_local` | `finish_state` == `local` | | `ws-finish` | `ws-finish` | finish started locally but is not fully completed yet |
|
|
27
|
+
| `review_missing` | `review_effective_count` == `0` | `deliver` | `ws-review` | `ws-review` | deliver-ready state has no review artifact yet |
|
|
28
|
+
| `dual_review_incomplete` | `dual_review_missing_count` > 0 | `deliver` | `ws-review` | `ws-review` | dual review gate incomplete (spec={spec_review_status}, quality={quality_review_status}) |
|
|
29
|
+
| `review_conflicted` | `git_conflicted` > 0 | `deliver` | `ws-commit` | `ws-commit` | review exists but the change branch still has merge conflicts |
|
|
30
|
+
| `review_dirty` | `git_total` > 0 | `deliver` | `ws-commit` | `ws-commit` | review exists but the change branch is still dirty |
|
|
31
|
+
| `deliver_finish_gate_pending_submodules` | (`repo_submodules` > 0) AND ((`evidence_persistent_count` > 0) OR (`lifecycle_evidence_runs` > 0)) AND (`finish_gate_missing_count` > 0) | | `ws-deliver` | `ws-deliver` | delivery evidence exists but finish gate is incomplete (missing={finish_gate_missing_count}) |
|
|
32
|
+
| `deliver_finish_gate_pending` | ((`evidence_persistent_count` > 0) OR (`lifecycle_evidence_runs` > 0)) AND (`finish_gate_missing_count` > 0) | | `ws-deliver` | `ws-deliver` | delivery evidence exists but finish gate is incomplete (missing={finish_gate_missing_count}) |
|
|
33
|
+
| `strict_blockers` | `blockers_strict_count` > 0 | | `ws-plan-verify` | `ws-plan-verify` | strict blockers remain unresolved |
|
|
34
|
+
| `deliver_evidence_converged_submodules` | (`repo_submodules` > 0) AND ((`evidence_persistent_count` > 0) OR (`lifecycle_evidence_runs` > 0)) AND (`finish_gate_missing_count` == `0`) | | `ws-deliver` | `ws-finish` | delivery evidence and finish gate are converged; next step is submodule-aware finish |
|
|
35
|
+
| `deliver_evidence_converged` | ((`evidence_persistent_count` > 0) OR (`lifecycle_evidence_runs` > 0)) AND (`finish_gate_missing_count` == `0`) | | `ws-deliver` | `ws-finish` | delivery evidence and finish gate are converged; next step is safe finish |
|
|
36
|
+
| `deliver_evidence_pending_submodules` | `repo_submodules` > 0 | | `ws-deliver` | `ws-deliver` | submodule-aware delivery/evidence convergence is still required |
|
|
37
|
+
| `deliver_evidence_pending` | (default) | | `ws-deliver` | `ws-deliver` | delivery evidence is still required before finish |
|
|
38
38
|
|
|
39
39
|
## Guidance 规则
|
|
40
40
|
|
|
@@ -51,6 +51,7 @@
|
|
|
51
51
|
"properties": {
|
|
52
52
|
"id": { "type": "string", "minLength": 1, "pattern": "^[a-z0-9_]+$" },
|
|
53
53
|
"when": { "$ref": "#/$defs/condition" },
|
|
54
|
+
"phase": { "type": "string", "pattern": "^(intake|planning|dev|review|deliver|completed)$" },
|
|
54
55
|
"currentStage": { "type": "string", "minLength": 1, "pattern": "^ws-[a-z0-9-]+$" },
|
|
55
56
|
"recommendedStage": { "type": "string", "minLength": 1, "pattern": "^ws-[a-z0-9-]+$" },
|
|
56
57
|
"rationale": { "type": "string", "minLength": 1 }
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
"stage": "review",
|
|
14
14
|
"focus": "requirements 归因、plan/change 绑定、证据路径、流程 gate 与危险操作边界",
|
|
15
15
|
"mustRead": "AI_PROJECT.md;REQUIREMENTS.md;AI_WORKSPACE.md;plan/...;changes/<change-id>/...",
|
|
16
|
-
"mustWrite": "changes/<change-id>/review/spec-review.md(无法识别 change 时回退 .
|
|
16
|
+
"mustWrite": "changes/<change-id>/review/spec-review.md(无法识别 change 时回退 .aiws/tmp/review/spec-review.md)",
|
|
17
17
|
"blockers": "无法定位真值文件;无法确认变更归因;无法写 review 证据",
|
|
18
18
|
"exitCriteria": "已给出流程/真值层 blockers、scope/gate 问题与最小修复建议",
|
|
19
19
|
"next": "ws-quality-review 或修复后重审"
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
"stage": "review",
|
|
25
25
|
"focus": "行为回归、边界条件、测试覆盖、实现质量、可维护性",
|
|
26
26
|
"mustRead": "git diff;验证结果;相关代码/配置;已有 review/analysis/patches 工件",
|
|
27
|
-
"mustWrite": "changes/<change-id>/review/quality-review.md(无法识别 change 时回退 .
|
|
27
|
+
"mustWrite": "changes/<change-id>/review/quality-review.md(无法识别 change 时回退 .aiws/tmp/review/quality-review.md)",
|
|
28
28
|
"blockers": "没有可审改动;没有验证上下文;无法写 review 证据",
|
|
29
29
|
"exitCriteria": "已给出高优先级缺陷/风险、测试缺口和最小验证建议",
|
|
30
30
|
"aiSlopChecks": [
|
|
@@ -40,8 +40,8 @@
|
|
|
40
40
|
"name": "ws-verify-before-complete",
|
|
41
41
|
"stage": "finish_gate",
|
|
42
42
|
"focus": "finish / handoff 前检查 review、validate、evidence 与 completion gate 是否齐全",
|
|
43
|
-
"mustRead": "changes/<change-id>/review/...;.
|
|
44
|
-
"mustWrite": "changes/<change-id>/evidence/verify-before-complete.md(无法识别 change 时回退 .
|
|
43
|
+
"mustRead": "changes/<change-id>/review/...;.aiws/tmp/aiws-validate/*.json;changes/<change-id>/evidence/...;git status",
|
|
44
|
+
"mustWrite": "changes/<change-id>/evidence/verify-before-complete.md(无法识别 change 时回退 .aiws/tmp/review/verify-before-complete.md)",
|
|
45
45
|
"blockers": "缺少 spec review;缺少 quality review;缺少 validate stamp;存在未关闭 blocker",
|
|
46
46
|
"exitCriteria": "已明确 pass/fail、缺失项与是否可进入 ws-finish / ws-handoff",
|
|
47
47
|
"next": "ws-finish / ws-handoff 或回退前置 gate"
|
|
@@ -64,7 +64,7 @@
|
|
|
64
64
|
},
|
|
65
65
|
{
|
|
66
66
|
"label": "validate stamp",
|
|
67
|
-
"value": ".
|
|
67
|
+
"value": ".aiws/tmp/aiws-validate/*.json"
|
|
68
68
|
},
|
|
69
69
|
{
|
|
70
70
|
"label": "pre-complete summary",
|
|
@@ -12,9 +12,9 @@
|
|
|
12
12
|
|
|
13
13
|
| Gate | Stage | Focus | Must Read | Must Write | Blockers | Exit | AI-Slop | Next |
|
|
14
14
|
| --- | --- | --- | --- | --- | --- | --- | --- | --- |
|
|
15
|
-
| `ws-spec-review` | review | requirements 归因、plan/change 绑定、证据路径、流程 gate 与危险操作边界 | AI_PROJECT.md;REQUIREMENTS.md;AI_WORKSPACE.md;plan/...;changes/<change-id>/... | changes/<change-id>/review/spec-review.md(无法识别 change 时回退 .
|
|
16
|
-
| `ws-quality-review` | review | 行为回归、边界条件、测试覆盖、实现质量、可维护性 | git diff;验证结果;相关代码/配置;已有 review/analysis/patches 工件 | changes/<change-id>/review/quality-review.md(无法识别 change 时回退 .
|
|
17
|
-
| `ws-verify-before-complete` | finish_gate | finish / handoff 前检查 review、validate、evidence 与 completion gate 是否齐全 | changes/<change-id>/review/...;.
|
|
15
|
+
| `ws-spec-review` | review | requirements 归因、plan/change 绑定、证据路径、流程 gate 与危险操作边界 | AI_PROJECT.md;REQUIREMENTS.md;AI_WORKSPACE.md;plan/...;changes/<change-id>/... | changes/<change-id>/review/spec-review.md(无法识别 change 时回退 .aiws/tmp/review/spec-review.md) | 无法定位真值文件;无法确认变更归因;无法写 review 证据 | 已给出流程/真值层 blockers、scope/gate 问题与最小修复建议 | N/A | ws-quality-review 或修复后重审 |
|
|
16
|
+
| `ws-quality-review` | review | 行为回归、边界条件、测试覆盖、实现质量、可维护性 | git diff;验证结果;相关代码/配置;已有 review/analysis/patches 工件 | changes/<change-id>/review/quality-review.md(无法识别 change 时回退 .aiws/tmp/review/quality-review.md) | 没有可审改动;没有验证上下文;无法写 review 证据 | 已给出高优先级缺陷/风险、测试缺口和最小验证建议 | 4 checks | ws-verify-before-complete 或修复后重审 |
|
|
17
|
+
| `ws-verify-before-complete` | finish_gate | finish / handoff 前检查 review、validate、evidence 与 completion gate 是否齐全 | changes/<change-id>/review/...;.aiws/tmp/aiws-validate/*.json;changes/<change-id>/evidence/...;git status | changes/<change-id>/evidence/verify-before-complete.md(无法识别 change 时回退 .aiws/tmp/review/verify-before-complete.md) | 缺少 spec review;缺少 quality review;缺少 validate stamp;存在未关闭 blocker | 已明确 pass/fail、缺失项与是否可进入 ws-finish / ws-handoff | N/A | ws-finish / ws-handoff 或回退前置 gate |
|
|
18
18
|
|
|
19
19
|
## AI-Slop Check Items
|
|
20
20
|
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
|
|
37
37
|
- spec review:changes/<change-id>/review/spec-review.md
|
|
38
38
|
- quality review:changes/<change-id>/review/quality-review.md
|
|
39
|
-
- validate stamp:.
|
|
39
|
+
- validate stamp:.aiws/tmp/aiws-validate/*.json
|
|
40
40
|
- pre-complete summary:changes/<change-id>/evidence/verify-before-complete.md
|
|
41
41
|
|
|
42
42
|
## 说明
|
|
@@ -137,11 +137,11 @@
|
|
|
137
137
|
},
|
|
138
138
|
{
|
|
139
139
|
"label": "review",
|
|
140
|
-
|
|
140
|
+
"value": "`changes/<change-id>/review/...` 或 `.aiws/tmp/review/...`"
|
|
141
141
|
},
|
|
142
142
|
{
|
|
143
143
|
"label": "validate",
|
|
144
|
-
|
|
144
|
+
"value": "`.aiws/tmp/aiws-validate/*.json`"
|
|
145
145
|
},
|
|
146
146
|
{
|
|
147
147
|
"label": "verify-before-complete",
|
|
@@ -48,8 +48,8 @@
|
|
|
48
48
|
最少证据集合:
|
|
49
49
|
|
|
50
50
|
- planning:`plan/...`、`changes/<change-id>/proposal.md`、`tasks.md`
|
|
51
|
-
- review:`changes/<change-id>/review/...` 或 `.
|
|
52
|
-
- validate:`.
|
|
51
|
+
- review:`changes/<change-id>/review/...` 或 `.aiws/tmp/review/...`
|
|
52
|
+
- validate:`.aiws/tmp/aiws-validate/*.json`
|
|
53
53
|
- verify-before-complete:`changes/<change-id>/evidence/verify-before-complete.md`;结构化逐项 gate 结果(spec-review ✓/✗, quality-review ✓/✗, validate ✓/✗, no-Critical ✓/✗, handoff ✓/✗)
|
|
54
54
|
- deliver / finish:`changes/<change-id>/evidence/...`、`state`、merge / push 结果
|
|
55
55
|
- handoff:`changes/archive/.../handoff.md`
|
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
# ws-goal-contract
|
|
2
|
+
|
|
3
|
+
ws-goal 协议层规范:目标定义、完成审计、预算约束与工具适配矩阵。
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 1. Background & Motivation
|
|
8
|
+
|
|
9
|
+
### Codex /goal 的五层架构
|
|
10
|
+
|
|
11
|
+
Codex 在 0.128.0+ 版本中引入了 `/goal` 指令。它的实现分五层:
|
|
12
|
+
|
|
13
|
+
| 层 | 实现 | 职责 |
|
|
14
|
+
|---|---|---|
|
|
15
|
+
| 持久化层 | Rust `thread_goals` 状态表 | 目标状态 pursuing/paused/achieved/budget_limited,token 用量,耗时 |
|
|
16
|
+
| App-Server API | `thread/goal/get/set/clear` + 通知 | 跨客户端同步,断线重连恢复 |
|
|
17
|
+
| Model Tools | `get_goal` / `create_goal` / `update_goal` | 模型只读 / 受限写入,不能暂停或清除 |
|
|
18
|
+
| Runtime | continuation 调度 + budget 追踪 | 自动续跑、interrupt 暂停、resume 恢复、soft-stop |
|
|
19
|
+
| TUI | `/goal` `/goal pause/resume/clear` | 创建、查看、控制生命周期 |
|
|
20
|
+
|
|
21
|
+
核心运行机制:用户输入 `/goal <objective>` 后,runtime 将目标持久化为 thread-level 状态。每轮结束时注入 `continuation.md` 模板,跟踪已用时间、已消耗 token、总预算、剩余 token。模型通过 `update_goal(complete)` 声明完成,runtime 在预算耗尽时注入 `budget_limit.md` 执行 soft stop(非 abort),整理进度报告而不是直接终止。
|
|
22
|
+
|
|
23
|
+
### aiws 的现状与机会
|
|
24
|
+
|
|
25
|
+
aiws 当前没有等价协议。OpenCode + oh-my-opencode 已经提供了 3 层递进的自执行机制:
|
|
26
|
+
|
|
27
|
+
- **L1 Todo Continuation Enforcer(Boulder 模式)**:session.idle + 未完成 todo 时自动注入 continuation 指令,5s 冷却 + 指数退避,最多 5 次连续失败后退出
|
|
28
|
+
- **L2 Ralph Loop(自引用迭代执行)**:通过 `/ralph-loop <task>` 触发,状态持久化在 `.opencode/ralph-loop.local.md`,持续注入 continuation prompt 直到模型输出 `<promise>DONE</promise>`
|
|
29
|
+
- **L3 Ultrawork(审计闭环)**:模型输出 DONE 后启动独立 Oracle 审查,必须输出 `<promise>VERIFIED</promise>` 才能通过;审查失败回 loop 继续修复
|
|
30
|
+
|
|
31
|
+
这三层机制已经提供了续跑调度和基本持久化,但没有标准的"目标设定"协议,没有预算约束定义,也没有可移植的完成审计规范。
|
|
32
|
+
|
|
33
|
+
### 方案:ws-goal 作为协议层
|
|
34
|
+
|
|
35
|
+
ws-goal 定义为**协议层**(prompt-template + artifact spec),不是运行时引擎。它负责任务目标的结构化定义、完成审计的证据规范、预算耗尽协议。续跑调度继续借用各平台已有的能力(OpenCode 的 Ralph Loop / Ultrawork,Codex 的 /goal runtime,Claude Code 的自然续跑)。
|
|
36
|
+
|
|
37
|
+
这样做的好处是:不重复造 runtime,不绑定特定工具,只写一份规范就能投影到所有平台。
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
## 2. Core Concepts
|
|
42
|
+
|
|
43
|
+
### 2.1 Goal Objective Contract
|
|
44
|
+
|
|
45
|
+
每个 goal objective 必须包含以下 6 个元素:
|
|
46
|
+
|
|
47
|
+
| 字段 | 类型 | 说明 |
|
|
48
|
+
|---|---|---|
|
|
49
|
+
| **outcome** | string | 具体的可交付物描述。必须是可验证的,不能是模糊意图 |
|
|
50
|
+
| **verification** | string | 如何证明完成。可以是文件路径 + 校验、测试命令 + 预期输出、benchmark 阈值、artifact URL |
|
|
51
|
+
| **constraints** | object | 预算限制:token_budget(token 上限)、time_budget(wall clock 上限)、max_iterations(turn 次数上限) |
|
|
52
|
+
| **boundaries** | string[] | 显式的非目标、范围限制。什么不在本次 goal 内 |
|
|
53
|
+
| **iteration_policy** | object | max_attempts(重试次数)、reaudit_frequency(每几次迭代重新审计一次) |
|
|
54
|
+
| **blocked_stop** | boolean | 遇到 blocker 时是否暂停并报告。true = 报告并等待,不能静默失败 |
|
|
55
|
+
|
|
56
|
+
### 2.2 Goal State Machine
|
|
57
|
+
|
|
58
|
+
```
|
|
59
|
+
active → paused (optional) → complete | budget_limited → archived
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
- **active**:目标正在执行中。可能有多个 iteration
|
|
63
|
+
- **paused**(可选):目标被暂停。运行时能力取决于平台(Codex 原生支持 pause/resume,OpenCode 只能 cancel)
|
|
64
|
+
- **complete**:完成审计通过,目标已被证明达成
|
|
65
|
+
- **budget_limited**:预算耗尽,目标未完成但无法继续。产生进度报告和 TODO 列表供继续
|
|
66
|
+
- **archived**:最终状态。goal artifact 归档到 evidence 目录
|
|
67
|
+
|
|
68
|
+
### 2.3 Completion Audit Protocol
|
|
69
|
+
|
|
70
|
+
改编自 Codex continuation.md 的 8 步完成审计方法:
|
|
71
|
+
|
|
72
|
+
1. **Derive requirements**:从 objective 推导出具体的、可验证的需求列表。不是重复 objective 原文,而是分解为可逐个检查的原子项
|
|
73
|
+
2. **Preserve scope**:保持原始目标范围。不要将"已经做了什么"重新定义为目标——audit 评判的是原始目标是否达成
|
|
74
|
+
3. **Identify evidence sources**:对每个需求,指定权威证据来源(文件内容、测试命令、benchmark 数据、artifact)
|
|
75
|
+
4. **Inspect current state**:检查当前状态中与每个需求相关的证据源
|
|
76
|
+
5. **Classify evidence**:对每个证据分类——proves completion(证明完成)/ contradicts(矛盾,证明未完成)/ incomplete(部分完成但不足)/ too weak(证据太弱,不能作为完成依据)/ missing(缺失,没有找到对应证据)
|
|
77
|
+
6. **Match scope**:验证范围必须匹配需求范围。窄验证不能推导出宽结论。例如"一个函数返回 200"不能证明"整个 API 端点正常工作"
|
|
78
|
+
7. **Uncertain = NOT achieved**:不确定的、间接的、推论性的证据不能作为完成依据。audit 需要确定的证明
|
|
79
|
+
8. **Prove, not disprove**:audit 必须正面证明完成,而不是反面证明"没找到未完成的工作"。找不出 bug 不等于代码正确
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
## 3. Protocol Specification
|
|
84
|
+
|
|
85
|
+
### 3.1 Goal Objective Markdown Template
|
|
86
|
+
|
|
87
|
+
```markdown
|
|
88
|
+
---
|
|
89
|
+
ws_goal:
|
|
90
|
+
version: 1
|
|
91
|
+
state: active # active | paused | complete | budget_limited | archived
|
|
92
|
+
created_at: <ISO 8601>
|
|
93
|
+
updated_at: <ISO 8601>
|
|
94
|
+
iteration: 1
|
|
95
|
+
max_iterations: <number>
|
|
96
|
+
---
|
|
97
|
+
|
|
98
|
+
# Goal: <简短标题>
|
|
99
|
+
|
|
100
|
+
## Outcome
|
|
101
|
+
|
|
102
|
+
<具体的可交付物描述。必须可验证>
|
|
103
|
+
|
|
104
|
+
## Verification
|
|
105
|
+
|
|
106
|
+
- **Type**: file | test | command | benchmark | artifact
|
|
107
|
+
- **Target**: <文件路径 / 测试命令 / benchmark ID 等>
|
|
108
|
+
- **Expected**: <预期结果>
|
|
109
|
+
|
|
110
|
+
## Constraints
|
|
111
|
+
|
|
112
|
+
- token_budget: <number> | null
|
|
113
|
+
- time_budget: <minutes> | null
|
|
114
|
+
- max_iterations: <number>
|
|
115
|
+
|
|
116
|
+
## Boundaries
|
|
117
|
+
|
|
118
|
+
- <不做什么 1>
|
|
119
|
+
- <不做什么 2>
|
|
120
|
+
|
|
121
|
+
## Iteration Policy
|
|
122
|
+
|
|
123
|
+
- max_attempts: <number>
|
|
124
|
+
- reaudit_frequency: <number> # 每 N 次 iteration 重新做一次完成审计
|
|
125
|
+
|
|
126
|
+
## Blocked Stop
|
|
127
|
+
|
|
128
|
+
- enabled: true | false
|
|
129
|
+
- report_to: user | log
|
|
130
|
+
|
|
131
|
+
## Progress Notes
|
|
132
|
+
|
|
133
|
+
<每次迭代更新,记录做了什么、什么阻塞、进度百分比>
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### 3.2 Evidence Type Registry
|
|
137
|
+
|
|
138
|
+
完成审计使用的证据类型:
|
|
139
|
+
|
|
140
|
+
| Type | Schema | 说明 |
|
|
141
|
+
|---|---|---|
|
|
142
|
+
| **file** | `{ path: string, checksum?: string }` | 文件存在且内容匹配。checksum 可选,用于精确内容验证 |
|
|
143
|
+
| **test** | `{ command: string, expected_exit: number, expected_output?: string }` | 运行测试命令,检查退出码和输出 |
|
|
144
|
+
| **command** | `{ command: string, stdout?: string, stderr?: string, exit_code: number }` | 运行任意命令,捕获标准输出、错误输出、退出码 |
|
|
145
|
+
| **benchmark** | `{ metric: string, before: number, after: number, threshold: string }` | 性能基准。threshold 格式 `"<N"` `">N"` `"±N%"` |
|
|
146
|
+
| **artifact** | `{ url: string, metadata?: object }` | 外部交付物(部署 URL、PR 链接、发布包等)。metadata 可包含版本号、commit sha 等 |
|
|
147
|
+
|
|
148
|
+
### 3.3 Budget Protocol
|
|
149
|
+
|
|
150
|
+
三个约束维度,全部为软停止(soft-stop,不 abort):
|
|
151
|
+
|
|
152
|
+
| 维度 | 类型 | 默认 | 软停止行为 |
|
|
153
|
+
|---|---|---|---|
|
|
154
|
+
| **token_budget** | number | null(无限制) | 接近上限时注入 budget 警告,到达上限时记录进度报告并暂停。**不**中断模型输出 |
|
|
155
|
+
| **time_budget** | number (minutes) | null(无限制) | 到达时限时发出超时信号,运行中的 tool 调用完成后自然停止,不走 kill |
|
|
156
|
+
| **max_iterations** | number | null(无限制) | 达到上限后阻止下次续跑,产出进度摘要和剩余 TODO |
|
|
157
|
+
|
|
158
|
+
token_budget 依赖平台的 token 计数器。aiws 不提供独立的 token 监控,只定义协议:平台应能声明当前 token 用量和剩余预算。当平台无法提供 token 计数时,此维度应标记为 `unsupported`。
|
|
159
|
+
|
|
160
|
+
### 3.4 Integration with Existing aiws Artifacts
|
|
161
|
+
|
|
162
|
+
| aiws 工件 | ws-goal 映射 |
|
|
163
|
+
|---|---|
|
|
164
|
+
| `changes/<id>/tasks.md` | tasks.md 中的每个 item 可携带 `ws_goal_id: <id>` 引用,表示该 task 通过 goal 自动执行。`update_plan` 的 progress tracking 反映 goal iteration 进度 |
|
|
165
|
+
| `.aiws/plan/...` proposal | proposal 中的 `Plan_File` 可以指向 goal objective markdown,表示该 change 使用 goal-driven 执行模式 |
|
|
166
|
+
| `aiws validate` + evidence | validate 的门禁检查可以包含对 goal 的完成审计证据的校验。goal 的 evidence 应落盘到 `changes/<id>/evidence/`,与其他 change 工件统一 |
|
|
167
|
+
|
|
168
|
+
---
|
|
169
|
+
|
|
170
|
+
## 4. Tool Integration Matrix
|
|
171
|
+
|
|
172
|
+
| Tool | Continuation Engine | Goal Persistence | Budget Tracking | Audit Method |
|
|
173
|
+
|---|---|---|---|---|
|
|
174
|
+
| **Codex** | `/goal` auto-continuation(Rust runtime,内置 turn 调度) | `thread_goals` DB(Rust 状态表,pursuing/paused/achieved/budget_limited) | 内置 token counter + `budget_limit.md` 软停止 | 模型自检 + continuation.md 8 步审计(prompt 内) |
|
|
175
|
+
| **OpenCode** | Ralph Loop L2(`/ralph-loop` 自引循环) / Ultrawork L3(Ralph Loop + Oracle 审计) | `.opencode/ralph-loop.local.md`(YAML frontmatter,active/iteration 状态) | max_iterations 硬限制(L2),无 token/time budget | L2: `<promise>DONE</promise>` 语义声明;L3: Oracle 独立审计 + `<promise>VERIFIED</promise>` |
|
|
176
|
+
| **Claude Code** | Claude Code 原生 session continuation(无特殊 runtime) | 无内置 goal 持久化。支持通过文件系统手动管理 | 无。用户手动控制 | 人工 review。无自动化审计链路 |
|
|
177
|
+
| **aiws ws-goal protocol** | 不提供。依赖各平台已有 continuation 引擎 | `.aiws/goals/<goal-id>.md`(标准模板工件)+ `changes/<id>/evidence/` 审计证据 | 定义协议但依赖平台 token 计数器。aiws 只做格式规范和软停止信号定义 | 8 步完成审计(协议层规范,平台层执行) |
|
|
178
|
+
|
|
179
|
+
### 关键说明
|
|
180
|
+
|
|
181
|
+
- **OpenCode L2 vs L3**:L2 只有自检声明(DONE),可信度较低;L3 引入独立审计者(Oracle),可信度较高但成本也高。ws-goal 协议推荐的审计模式是 L3,但允许 L2 作为轻度使用的降级
|
|
182
|
+
- **Codex 的特殊性**:Codex 的 `/goal` 和 ws-goal 协议不是竞争关系。ws-goal 协议可以投影到 Codex 时直接绑定 `/goal` 的 continuation 能力,只需补充完成审计的规范约束
|
|
183
|
+
- **Claude Code 的局限性**:Claude Code 没有等效的 Ralph Loop 或 /goal 运行时。ws-goal 在 Claude Code 上的能力受限于平台本身的续跑机制
|
|
184
|
+
|
|
185
|
+
---
|
|
186
|
+
|
|
187
|
+
## 5. Protocol Limitations
|
|
188
|
+
|
|
189
|
+
### 5.1 NOT a Runtime
|
|
190
|
+
|
|
191
|
+
ws-goal 协议层不实现任何 continuation/scheduling/pause/resume 机制。这些能力完全依赖于各平台:
|
|
192
|
+
|
|
193
|
+
- OpenCode:依赖 Ralph Loop(文件状态轮询 + prompt 注入)
|
|
194
|
+
- Codex:依赖 /goal 的 Rust runtime(turn 调度 + 数据库)
|
|
195
|
+
- Claude Code:依赖用户手动管理
|
|
196
|
+
|
|
197
|
+
这意味着跨工具的"暂停/恢复"行为会不一致。Codex 原生支持 Ctrl+C 暂停 + resume 恢复,OpenCode 只能 cancel 重跑,Claude Code 没有等效功能。
|
|
198
|
+
|
|
199
|
+
### 5.2 Budget Tracking 依赖平台能力
|
|
200
|
+
|
|
201
|
+
token_budget 和 time_budget 的监控需要平台提供接口。当前:
|
|
202
|
+
|
|
203
|
+
- Codex:内置 token counter,支持软停止
|
|
204
|
+
- OpenCode(oh-my-opencode):无 token 计数,只有 max_iterations
|
|
205
|
+
- Claude Code:无任何 budget tracking
|
|
206
|
+
|
|
207
|
+
aiws 只定义"预算耗尽时应该做什么"的协议,不提供跨平台的统一计费层。在缺少平台支持的维度上,goal 应标记为 unsupported 而不是假装能工作。
|
|
208
|
+
|
|
209
|
+
### 5.3 Cross-Tool Goal Persistence 是 Best-Effort
|
|
210
|
+
|
|
211
|
+
不同工具使用不同的持久化机制:
|
|
212
|
+
|
|
213
|
+
- Codex:服务端 `thread_goals` 数据库(跨客户端同步)
|
|
214
|
+
- OpenCode(Ralph Loop):文件 `.opencode/ralph-loop.local.md`(会话级)
|
|
215
|
+
- Claude Code:无内置持久化
|
|
216
|
+
|
|
217
|
+
没有共享数据库。如果一个目标在 Codex 中开始,无法在 OpenCode 中恢复。goal objective markdown 文件 `.aiws/goals/<goal-id>.md` 可以作为人类可读的参考,但状态同步不保证。
|
|
218
|
+
|
|
219
|
+
### 5.4 State Machine 的工具依赖
|
|
220
|
+
|
|
221
|
+
完整状态机 `active → paused → complete | budget_limited → archived` 中各状态的支持情况:
|
|
222
|
+
|
|
223
|
+
| 状态转换 | Codex | OpenCode (Ralph Loop) | Claude Code |
|
|
224
|
+
|---|---|---|---|
|
|
225
|
+
| active → paused | 原生支持(Ctrl+C) | 不支持(只能 cancel) | 不支持 |
|
|
226
|
+
| paused → active | 原生支持(resume) | 不支持 | 不支持 |
|
|
227
|
+
| active → complete | 支持(模型调用 update_goal) | 支持(DONE 声明 + oracle 验证) | 手动 |
|
|
228
|
+
| active → budget_limited | 支持(budget_limit.md 软停止) | 不支持 | 不支持 |
|
|
229
|
+
| complete → archived | 自动 | 手动 | 手动 |
|
|
230
|
+
|
|
231
|
+
aiws 协议层定义了完整的语义状态,但各平台只能实现其中一部分。goal 创建时应注意平台的能力边界。
|
|
232
|
+
|
|
233
|
+
### 5.5 Completion Audit 的执行成本
|
|
234
|
+
|
|
235
|
+
8 步完成审计方法在完整执行时需要独立审计者(在 OpenCode L3 中需要额外模型调用)。对于小目标(比如"修复一个 lint 错误"),完整审计的 overhead 可能超过实际工作的成本。建议根据目标复杂度选择审计级别:
|
|
236
|
+
|
|
237
|
+
- **轻量**(< 3 步,单文件改动):只做 step 1-2(derive + preserve),跳过完整证据链
|
|
238
|
+
- **标准**(3-10 步,多文件改动):完整 8 步审计
|
|
239
|
+
- **严格**(跨模块、跨 repo):8 步审计 + 独立审计者 + ws-review 门禁
|
package/package.json
CHANGED
|
@@ -37,6 +37,13 @@ description: 默认 workflow bootstrap/router:先读真值,再路由到正
|
|
|
37
37
|
- 无法明确当前任务意图
|
|
38
38
|
- 无法明确归因或验证入口,且不能安全推断
|
|
39
39
|
|
|
40
|
+
运行时上下文注入(inject-context):
|
|
41
|
+
|
|
42
|
+
- 当使用 `task()` 委托子 agent 时,`aiws-inject-context` 插件会自动拦截 `task()` 调用,从 `changes/<change-id>/analysis/<role>-context.jsonl` 读取上下文并注入到子 agent prompt。
|
|
43
|
+
- 若 `journal/` 目录(`changes/<change-id>/journal/`)或 `STATE.md` 不存在:降级为最小脚手架上下文(change ID + phase + spec index),不影响正常执行。
|
|
44
|
+
- 跨会话恢复时,优先读取 `changes/<change-id>/STATE.md`(若存在)获取阶段上下文;降级到目录扫描推导。
|
|
45
|
+
- 以上注入均不阻塞用户工作流,若任何环节失败仅记录并显式降级,不回退整个路由。
|
|
46
|
+
|
|
40
47
|
完成判定:
|
|
41
48
|
- 已经明确给出单一路由结果,并进入对应 `ws-*` skill;或已提出关键澄清问题并停止。
|
|
42
49
|
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ws-goal
|
|
3
|
+
description: 目标协议:设定可审计的 goal 目标并执行完成闭环(基于 ws-goal-contract.md)
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
用中文输出(命令/路径/代码标识符保持原样不翻译)。
|
|
7
|
+
|
|
8
|
+
## 目标
|
|
9
|
+
|
|
10
|
+
在 AIWS 约束下完成一个目标导向的自主执行闭环。基于 `packages/spec/docs/ws-goal-contract.md` 协议。
|
|
11
|
+
|
|
12
|
+
## 前置条件(Pre-requisites)
|
|
13
|
+
|
|
14
|
+
- `AI_PROJECT.md` / `REQUIREMENTS.md` / `AI_WORKSPACE.md` 已对齐
|
|
15
|
+
- 当前工作区状态已知(clean / dirty / change 上下文)
|
|
16
|
+
|
|
17
|
+
## 流程(Flow)
|
|
18
|
+
|
|
19
|
+
0. 检查 `.aiws/goals/` 目录:
|
|
20
|
+
a) 若用户仅查询状态(无明确目标),列出所有 goal 文件及其 status 字段,然后结束。
|
|
21
|
+
b) 若存在 status=active 或 status=paused 的 goal 文件,优先读取并恢复执行,不再新建 goal。
|
|
22
|
+
1. 读取真值文件(`AI_PROJECT.md` / `REQUIREMENTS.md` / `AI_WORKSPACE.md`),输出约束摘要,包括项目边界、验收标准入口和运行/测试方式。
|
|
23
|
+
2. 接受用户输入的 goal objective(自然语言),将其转化为结构化目标描述。
|
|
24
|
+
3. 按 ws-goal-contract.md 的 6 要素格式将目标写入文件:
|
|
25
|
+
- 文件路径:`.aiws/goals/<goal-id>.md`
|
|
26
|
+
- 6 要素:Objective(目标描述)/ Success Criteria(验收标准)/ Constraints(约束边界)/ Inputs(输入依赖)/ Outputs(产出物)/ Audit Trail(审计轨迹)
|
|
27
|
+
4. 输出 completion audit checklist,要求用户确认验收标准是否完整、可测量。
|
|
28
|
+
5. **Scope Assessment + 路由**:评估目标复杂度,自动选择执行路径:
|
|
29
|
+
a) 简单(≤5 文件、配置/doc/规范为主、低风险)→ 直行:后续步骤 6-8 auto-finish 闭环
|
|
30
|
+
b) 复杂(多模块、代码改动 >5 文件、架构/安全/迁移风险)→ 自动执行 `ws-plan` 启动 change 流水线(ws-plan → ws-dev → review → ws-commit → ws-finish),完成后更新 goal status=complete
|
|
31
|
+
c) 路由决策记入 goal 文件 Audit Trail
|
|
32
|
+
6. 建议续跑方式:简单路径继续直行;复杂路径进入 change 流水线后建议 `ws-dev`
|
|
33
|
+
7. 每轮结束后:要求用户或系统执行 completion audit(参考 ws-goal-contract.md 8 步法),确认目标是否达成或需要调整。
|
|
34
|
+
8. **Goal 自动闭环**:completion audit 确认达成后自动执行:
|
|
35
|
+
a) Review 检查(按改动类型):
|
|
36
|
+
- 配置/文档/规范类(markdown):内容一致性、引用完整性、内容正确性、无 secrets、格式统一
|
|
37
|
+
- 代码类(ts/js/py 等):lint/typecheck 通过、符合现有代码模式、无 secrets、测试通过或覆盖缺口已记录
|
|
38
|
+
- 混合类:以上两种合并
|
|
39
|
+
b) 简单路径:`git add` 目标产出文件 → `git commit -m "goal(<goal-id>): <objective 摘要>"` → `git push` → 更新 goal status=complete
|
|
40
|
+
c) 复杂路径:走 `ws-commit` → `ws-finish` → archive change → 更新 goal status=complete
|
|
41
|
+
d) 不通过:记录 blocker → 继续 fix 循环
|
|
42
|
+
|
|
43
|
+
## 约束(Constraints)
|
|
44
|
+
|
|
45
|
+
- 不修改现有 ws-* / p-aiws-* 入口,保持已有入口稳定
|
|
46
|
+
- 不写入任何 secrets(token、账号、内网端点等不得进入 git)
|
|
47
|
+
- 未运行验证不声称已完成;验证命令需可复现且预期结果明确
|
|
48
|
+
- Budget tracking 依赖工具自身能力(aiws 只定义协议,不实现预算跟踪)
|
|
49
|
+
|
|
50
|
+
## 阶段定位
|
|
51
|
+
|
|
52
|
+
- goal 阶段;负责将用户模糊目标收敛为结构化 audit trail,并引导闭环执行。
|
|
53
|
+
|
|
54
|
+
## 必需输入
|
|
55
|
+
|
|
56
|
+
- 当前任务描述(goal objective,自然语言)
|
|
57
|
+
- 真值文件:`AI_PROJECT.md` / `REQUIREMENTS.md` / `AI_WORKSPACE.md`
|
|
58
|
+
- 若已存在:`.aiws/changes/<change-id>/` 上下文
|
|
59
|
+
|
|
60
|
+
## 必需输出
|
|
61
|
+
|
|
62
|
+
- `Goal file:` 实际写入的目标文件路径
|
|
63
|
+
- `Audit checklist:` 验收标准清单
|
|
64
|
+
- `Next:` 建议的续跑方式
|
|
65
|
+
|
|
66
|
+
## 阻断条件
|
|
67
|
+
|
|
68
|
+
- 真值文件未对齐(缺失或内容不完整)
|
|
69
|
+
- 用户 goal objective 含义模糊,无法转化为 6 要素格式
|
|
70
|
+
- 无法将目标文件实际写入磁盘
|
|
71
|
+
|
|
72
|
+
## 完成判定
|
|
73
|
+
|
|
74
|
+
- 目标已按 6 要素格式写盘
|
|
75
|
+
- 验收标准已得到用户确认
|
|
76
|
+
- 续跑方式已明确
|
|
77
|
+
|
|
78
|
+
## 参考文献
|
|
79
|
+
|
|
80
|
+
- `packages/spec/docs/ws-goal-contract.md` — 目标协议完整定义
|
|
81
|
+
- `AI_PROJECT.md` — 项目规则与边界
|
|
82
|
+
- `REQUIREMENTS.md` — 需求与验收真值
|
|
83
|
+
- `AI_WORKSPACE.md` — 运行与测试入口真值
|
|
84
|
+
|
|
85
|
+
## 输出要求
|
|
86
|
+
|
|
87
|
+
- `Goal file:` <实际写入的路径>
|
|
88
|
+
- `Audit checklist:` <验收标准清单>
|
|
89
|
+
- `Next:` <推荐下一步:Ralph Loop / manual iteration / 其他>
|
|
@@ -26,6 +26,8 @@ description: 计划前置澄清(逐条冻结问题并产出 intake 草案,
|
|
|
26
26
|
|
|
27
27
|
必需输出:
|
|
28
28
|
- `Intake file:` 实际写入的 `plan/*.intake.md`
|
|
29
|
+
- `Deep Interview:` 9 维分析:Why/非目标/影响面/假设/替代方案/约束/优先级/成功度量/风险
|
|
30
|
+
- `Codebase Knowns:` 来自代码库的已知信息(通过 explore 已确认的事实、模式、配置值等,标注信息来源路径)
|
|
29
31
|
- `Current question:` 当前正在处理的问题
|
|
30
32
|
- `Open Questions:` 尚未冻结的问题列表
|
|
31
33
|
- `Frozen Decisions:` 已冻结结论
|
|
@@ -44,37 +46,54 @@ description: 计划前置澄清(逐条冻结问题并产出 intake 草案,
|
|
|
44
46
|
执行步骤(建议):
|
|
45
47
|
1) 先运行 `$ws-preflight`,读取真值文件并输出约束摘要。
|
|
46
48
|
2) 读取当前任务描述;若存在最新 `plan/*.intake.md`,先读取其中的:
|
|
49
|
+
- `Deep Interview`
|
|
47
50
|
- `Open Questions`
|
|
48
51
|
- `Resolved Questions`
|
|
49
52
|
- `Frozen Decisions`
|
|
50
53
|
- `Draft Scope`
|
|
51
54
|
- `Draft Verify`
|
|
52
|
-
3)
|
|
55
|
+
3) **Deep Interview 层**:在拆解问题前先收集高维信息:
|
|
56
|
+
a) **Why 探询**:问"为什么要做?不做会怎样?谁提出的?什么场景?"
|
|
57
|
+
b) **非目标(Non-goals)**:显式记录什么不在范围内,需用户确认
|
|
58
|
+
c) **影响面(Stakeholders)**:识别受影响的用户、模块、团队
|
|
59
|
+
d) **假设显式化**:列出隐含假设,请用户确认
|
|
60
|
+
e) **替代方案**:问"考虑过其他方案吗?为什么选这个?"
|
|
61
|
+
f) **约束挑战**:对每条约束问"如果不存在会怎样?"——区分硬约束与自设约束
|
|
62
|
+
g) **优先级**:Must-have / Should-have / Nice-to-have
|
|
63
|
+
h) **成功度量**:问"上线后怎么判断成功?"——量化指标,无法量化则记入风险
|
|
64
|
+
i) **风险预判**:识别 3-5 个最关键风险
|
|
65
|
+
j) 结果写入 intake 草案的 `Deep Interview` 小节
|
|
66
|
+
4) **探码后问**:在对每个 Open Question 提问或沟通前,先用 `explore` 检索代码库中是否已有足够信息回答该问题。探查到的已知信息记录在 intake 草案中(见输出要求的 Codebase Knowns),不再问用户。记录每个问题属于以下哪一类:
|
|
67
|
+
- `codebase: answered` — 代码库已可回答,跳过提问
|
|
68
|
+
- `codebase: partial` — 代码库有部分信息,补充提问未覆盖的部分
|
|
69
|
+
- `user: required` — 必须问用户
|
|
70
|
+
4) 初始化或续写问题队列:
|
|
53
71
|
- 把当前任务拆成 `N` 条待决问题
|
|
54
72
|
- 每条问题都要写成一句明确的决策句,而不是模糊话题
|
|
55
|
-
|
|
56
|
-
|
|
73
|
+
- 状态只允许:`open` / `in_discussion` / `frozen` / `deferred`
|
|
74
|
+
5) 选择唯一的当前问题:
|
|
57
75
|
- 优先取已有 `in_discussion`
|
|
58
|
-
|
|
59
|
-
|
|
76
|
+
- 否则取最影响 `Goal / Scope / Verify / Binding` 的 `open`
|
|
77
|
+
6) 对当前问题输出并沟通:
|
|
60
78
|
- `Current question:`
|
|
61
79
|
- `Why it matters:`
|
|
62
80
|
- `Current options / current understanding:`
|
|
63
|
-
|
|
64
|
-
|
|
81
|
+
- `Exit condition:` 这条问题在什么条件下算谈完
|
|
82
|
+
7) 只推进当前问题:
|
|
65
83
|
- 允许围绕这 1 条问题多轮问答
|
|
66
84
|
- 若用户回答引出新问题:加入 `Open Questions`
|
|
67
85
|
- 若当前问题已经有明确结论:标记为 `frozen`
|
|
68
|
-
|
|
69
|
-
|
|
86
|
+
- 若当前问题故意留到后面:标记为 `deferred`
|
|
87
|
+
8) 每次落盘 `plan/<timestamp>-<slug>.intake.md`,至少包含:
|
|
88
|
+
- `Deep Interview`
|
|
70
89
|
- `Context`
|
|
71
90
|
- `Open Questions`
|
|
72
91
|
- `Resolved Questions`
|
|
73
92
|
- `Frozen Decisions`
|
|
74
93
|
- `Draft Scope`
|
|
75
94
|
- `Draft Verify`
|
|
76
|
-
|
|
77
|
-
|
|
95
|
+
- `Ready for ws-plan: yes/no`
|
|
96
|
+
9) 判断是否可以移交给 `$ws-plan`:
|
|
78
97
|
- 若仍有关键问题未冻结:`Ready for ws-plan: no`,`Next: 继续 $ws-intake`
|
|
79
98
|
- 若关键问题已冻结,剩余仅是实现细节或已标记 `deferred`:`Ready for ws-plan: yes`,`Next: $ws-plan`
|
|
80
99
|
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ws-research
|
|
3
|
+
description: 使用时机:需要技术调研、定位影响面、收集实现信息但不直接改代码时。触发词:调研、研究、research、分析依赖、影响面、技术方案。注意:产物只落盘 changes/<id>/analysis/,不修改业务文件。
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
用中文输出(命令/路径/代码标识符保持原样不翻译)。
|
|
7
|
+
|
|
8
|
+
目标:在正式实现前,对不明确的技术问题做只读调研,并把结论落盘为可追溯的分析产物。
|
|
9
|
+
|
|
10
|
+
定位:
|
|
11
|
+
- ws-dev / ws-plan 的辅助入口,不是独立 workflow stage。
|
|
12
|
+
- 只读探索代码库、外部文档或依赖关系,不直接修改业务文件。
|
|
13
|
+
- 若分析过程中发现需要改代码,必须退出本 Skill 并回到 ws-dev 或 ws-plan。
|
|
14
|
+
|
|
15
|
+
必需输入:
|
|
16
|
+
- 真值文件:`AI_PROJECT.md` / `REQUIREMENTS.md` / `AI_WORKSPACE.md`
|
|
17
|
+
- 当前绑定到 `Req_ID` 或 `Problem_ID` 的 change 上下文
|
|
18
|
+
- 明确的调研问题清单
|
|
19
|
+
|
|
20
|
+
必需输出:
|
|
21
|
+
- 分析报告落盘:`changes/<id>/analysis/<timestamp>-research.md`
|
|
22
|
+
- 报告中必须包含:
|
|
23
|
+
- 调研问题与结论
|
|
24
|
+
- 信息来源(文件路径/外部文档链接)
|
|
25
|
+
- 不确定项与风险标记
|
|
26
|
+
- 对后续实现的建议或阻断项
|
|
27
|
+
- `Next:` 指向 ws-dev、ws-plan 或 ws-review
|
|
28
|
+
|
|
29
|
+
阻断条件:
|
|
30
|
+
- 没有明确的调研问题
|
|
31
|
+
- 当前不在 change 上下文中
|
|
32
|
+
- 调研过程中发现需要写代码(应回到 ws-dev)
|
|
33
|
+
- 调研深度超出本次 change scope(应记录原因并回到 ws-plan 更新范围)
|
|
34
|
+
|
|
35
|
+
完成判定:
|
|
36
|
+
- 分析报告已落盘到 `changes/<id>/analysis/`
|
|
37
|
+
- 报告中问题与结论一一对应
|
|
38
|
+
- `Next` 已给出明确路由
|
|
39
|
+
|
|
40
|
+
步骤(建议):
|
|
41
|
+
1) 先读取真值文件,确认 change 上下文与调研问题
|
|
42
|
+
2) 只读探索相关代码库区域:
|
|
43
|
+
- 用搜索工具定位关键文件/模块
|
|
44
|
+
- 阅读相关代码片段
|
|
45
|
+
- 必要时查阅外部文档
|
|
46
|
+
3) 汇总发现,标注不确定项:
|
|
47
|
+
- 对每个问题给出结论或待确认标记
|
|
48
|
+
- 标明信息来源(文件路径/行号/外部链接)
|
|
49
|
+
4) 落盘分析报告到 `changes/<id>/analysis/<timestamp>-research.md`
|
|
50
|
+
5) 回到主流程:`$ws-dev` 或 `$ws-plan`
|
|
51
|
+
|
|
52
|
+
安全:
|
|
53
|
+
- 不修改任何业务文件
|
|
54
|
+
- 不写入 secrets
|
|
55
|
+
- 不执行破坏性命令
|
|
56
|
+
- 不确定的结论必须显式标注
|
|
@@ -323,6 +323,13 @@ def extract_first_id(labels: List[str], text: str) -> str:
|
|
|
323
323
|
return ""
|
|
324
324
|
|
|
325
325
|
|
|
326
|
+
def normalize_optional_id(value: str) -> str:
|
|
327
|
+
normalized = (value or "").strip()
|
|
328
|
+
if normalized.upper() in {"N/A", "NA", "NONE", "NULL", "-"}:
|
|
329
|
+
return ""
|
|
330
|
+
return normalized
|
|
331
|
+
|
|
332
|
+
|
|
326
333
|
def split_declared_values(value: str) -> List[str]:
|
|
327
334
|
parts = re.split(r"[,;\n]+", value or "")
|
|
328
335
|
out: List[str] = []
|
|
@@ -910,8 +917,8 @@ def validate_change(
|
|
|
910
917
|
warnings.append("proposal.md does not reference AI_WORKSPACE.md (recommended)")
|
|
911
918
|
|
|
912
919
|
change_id_decl = extract_id("Change_ID", t)
|
|
913
|
-
req_id = extract_id("Req_ID", t)
|
|
914
|
-
prob_id = extract_id("Problem_ID", t)
|
|
920
|
+
req_id = normalize_optional_id(extract_id("Req_ID", t))
|
|
921
|
+
prob_id = normalize_optional_id(extract_id("Problem_ID", t))
|
|
915
922
|
contract_row_decl = extract_first_id(["Contract_Row", "Contract_Row(s)"], t)
|
|
916
923
|
plan_file_decl = extract_first_id(["Plan_File", "Plan file"], t)
|
|
917
924
|
evidence_path_decl = extract_first_id(["Evidence_Path", "Evidence_Path(s)"], t)
|
|
@@ -1009,8 +1016,8 @@ def validate_change(
|
|
|
1009
1016
|
else:
|
|
1010
1017
|
plan_text = read_text(plan_abs)
|
|
1011
1018
|
plan_change_id = extract_id("Change_ID", plan_text)
|
|
1012
|
-
plan_req_id = extract_id("Req_ID", plan_text)
|
|
1013
|
-
plan_prob_id = extract_id("Problem_ID", plan_text)
|
|
1019
|
+
plan_req_id = normalize_optional_id(extract_id("Req_ID", plan_text))
|
|
1020
|
+
plan_prob_id = normalize_optional_id(extract_id("Problem_ID", plan_text))
|
|
1014
1021
|
plan_contract_row = extract_first_id(["Contract_Row", "Contract_Row(s)"], plan_text)
|
|
1015
1022
|
plan_file_from_plan = extract_first_id(["Plan_File", "Plan file"], plan_text)
|
|
1016
1023
|
plan_evidence_path = extract_first_id(["Evidence_Path", "Evidence_Path(s)"], plan_text)
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
<!-- AIWS_MANAGED_BEGIN:claude:ws-goal -->
|
|
2
|
+
# ws goal
|
|
3
|
+
|
|
4
|
+
用中文输出(命令/路径/代码标识符保持原样不翻译)。
|
|
5
|
+
|
|
6
|
+
目标:
|
|
7
|
+
- 在 AIWS 约束下完成一个目标导向的自主执行闭环。
|
|
8
|
+
- 启动时自动恢复未完成的 goal。
|
|
9
|
+
|
|
10
|
+
执行建议:
|
|
11
|
+
0) 检查 `.aiws/goals/` 目录:
|
|
12
|
+
a) 若用户仅查询状态(无明确目标),列出所有 goal 文件及其 status 字段,然后结束。
|
|
13
|
+
b) 若存在 status=active 或 status=paused 的 goal 文件,优先读取并恢复执行。
|
|
14
|
+
1) 先运行 `/ws-preflight` 对齐真值文件(`AI_PROJECT.md` / `REQUIREMENTS.md` / `AI_WORKSPACE.md`)。
|
|
15
|
+
2) 接受用户输入的 goal objective。
|
|
16
|
+
3) 按 `ws-goal-contract.md` 的目标模板写入 `.aiws/goals/<goal-id>.md` 工件文件。
|
|
17
|
+
4) 输出 completion audit checklist(含验真步骤)。
|
|
18
|
+
5) **Scope Assessment + 路由**:评估目标复杂度,自动选择执行路径:
|
|
19
|
+
a) 简单(≤5 文件、配置/doc 为主、低风险)→ 直行:后续步骤 6-8 auto-finish 闭环
|
|
20
|
+
b) 复杂(多模块、代码改动 >5 文件、架构/安全/迁移风险)→ 自动触发 `ws-plan` 启动 change 流水线,完成后更新 goal status=complete
|
|
21
|
+
c) 路由决策记入 goal 文件 Audit Trail
|
|
22
|
+
6) 建议续跑方式:简单路径直行 auto-finish;复杂路径进入 change 流水线后建议 ws-dev
|
|
23
|
+
7) 每轮结束后自动执行 completion audit,确认目标是否完成。
|
|
24
|
+
8) 若 completion audit 确认 goal 达成,自动执行闭环 pipeline:
|
|
25
|
+
a) Review 检查(按改动类型):
|
|
26
|
+
- 配置/文档/规范类(markdown):内容一致性、引用完整性、内容正确性、无 secrets、格式统一
|
|
27
|
+
- 代码类(ts/js/py 等):lint/typecheck 通过、符合现有代码模式、无 secrets、测试通过或覆盖缺口已记录
|
|
28
|
+
- 混合类:以上两种合并
|
|
29
|
+
b) 简单路径:git add → commit → push,更新 goal status=complete
|
|
30
|
+
c) 复杂路径:走 ws-commit → ws-finish → archive change,更新 goal status=complete
|
|
31
|
+
d) 不通过:记录 blocker → 继续 fix 循环
|
|
32
|
+
<!-- AIWS_MANAGED_END:claude:ws-goal -->
|
|
33
|
+
|
|
34
|
+
可在下方追加本项目对 Claude Code 的额外说明(托管块外内容会被保留)。
|
|
@@ -10,22 +10,44 @@ description: 计划前置澄清(逐条冻结问题并产出 intake 草案,
|
|
|
10
10
|
- 采用“一题一线程”模式推进:每次只处理 1 个问题,允许该问题多轮往返,直到形成明确结论。
|
|
11
11
|
- 产出一份可被 `/ws-plan` 消费的轻量草案:`plan/<timestamp>-<slug>.intake.md`。
|
|
12
12
|
|
|
13
|
+
## Deep Interview 层(前置探询)
|
|
14
|
+
|
|
15
|
+
在逐题澄清前,先做一轮 Deep Interview 收集高维信息:
|
|
16
|
+
|
|
17
|
+
1. **Why 探询**:问"为什么要做?不做会怎样?谁提出的?什么场景?"——理解动机,追溯 trigger。
|
|
18
|
+
2. **非目标(Non-goals)**:显式记录什么不在范围内,防止 scope creep。需用户确认。
|
|
19
|
+
3. **影响面(Stakeholders)**:识别受影响的用户、模块、团队。
|
|
20
|
+
4. **假设显式化**:列出隐含假设,逐条请用户确认。
|
|
21
|
+
5. **替代方案**:问"考虑过其他方案吗?为什么选这个?"未探索则标记为风险。
|
|
22
|
+
6. **约束挑战**:对每条约束问"如果不存在会怎样?"——区分硬约束与自设约束。
|
|
23
|
+
7. **优先级**:Must-have / Should-have / Nice-to-have,明确 scope 底线。
|
|
24
|
+
8. **成功度量**:问"上线后怎么判断成功?"——量化指标,无法量化则记入风险。
|
|
25
|
+
9. **风险预判**:识别 3-5 个最关键风险,写入 intake 草案。
|
|
26
|
+
|
|
27
|
+
输出:以上 9 项归入 intake 草案的 `Deep Interview` 小节。
|
|
28
|
+
|
|
13
29
|
执行要求:
|
|
14
30
|
1) 先读 `AI_PROJECT.md` / `REQUIREMENTS.md` / `AI_WORKSPACE.md`,必要时先 `/ws-preflight`。
|
|
15
31
|
2) 若存在最新 `plan/*.intake.md`,先续写它;否则新建一份 intake 草案。
|
|
16
32
|
3) 把当前任务拆成 `Open Questions`,状态只允许 `open / in_discussion / frozen / deferred`。
|
|
17
|
-
4)
|
|
33
|
+
4) **探码后问**:在对每个 Open Question 提问或沟通前,先用 `explore` 检索代码库中是否已有足够信息回答该问题。探查到的已知信息记录在 intake 草案中,不再问用户。标记每个问题的信息来源:
|
|
34
|
+
- `codebase: answered` — 代码库已可回答,跳过提问
|
|
35
|
+
- `codebase: partial` — 代码库有部分信息,补充提问未覆盖的部分
|
|
36
|
+
- `user: required` — 必须问用户
|
|
37
|
+
5) 每次只推进 1 个当前问题,并显式输出:
|
|
18
38
|
- `Current question:`
|
|
19
39
|
- `Why it matters:`
|
|
20
40
|
- `Current options / current understanding:`
|
|
21
41
|
- `Exit condition:`
|
|
22
|
-
|
|
23
|
-
|
|
42
|
+
6) 当前问题在没有被标记成 `frozen` 或 `deferred` 前,不进入下一题。
|
|
43
|
+
7) 每轮都要把 intake 草案写盘,至少包含:
|
|
44
|
+
- `Deep Interview` — 9 维分析:Why/非目标/影响面/假设/替代方案/约束/优先级/成功度量/风险
|
|
24
45
|
- `Context`
|
|
46
|
+
- `Codebase Knowns` — 来自代码库的已知信息:通过 explore 已确认的事实、现有模式、配置值等。标注信息来源路径。
|
|
25
47
|
- `Open Questions`
|
|
26
48
|
- `Resolved Questions`
|
|
27
49
|
- `Frozen Decisions`
|
|
28
50
|
- `Draft Scope`
|
|
29
51
|
- `Draft Verify`
|
|
30
52
|
- `Ready for ws-plan: yes/no`
|
|
31
|
-
|
|
53
|
+
8) 若关键问题已冻结:`Next` 指向 `/ws-plan`;否则继续 `/ws-intake`。
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: 目标协议:设定可审计的 goal 目标并执行完成闭环
|
|
3
|
+
---
|
|
4
|
+
<!-- AIWS_MANAGED_BEGIN:opencode:ws-goal -->
|
|
5
|
+
# ws goal
|
|
6
|
+
|
|
7
|
+
用中文输出(命令/路径/代码标识符保持原样不翻译)。
|
|
8
|
+
|
|
9
|
+
目标:
|
|
10
|
+
- 将用户需求转化为可审计的 goal 目标,按 ws-goal-contract.md 的目标模板写入目标文件,驱动完成闭环。
|
|
11
|
+
|
|
12
|
+
前置条件:
|
|
13
|
+
1) 先运行 `/ws-preflight`(对齐 `AI_PROJECT.md` / `REQUIREMENTS.md` / `AI_WORKSPACE.md`)。
|
|
14
|
+
|
|
15
|
+
执行流程:
|
|
16
|
+
0) 检查 `.aiws/goals/` 目录:
|
|
17
|
+
a) 若用户仅查询状态(无明确目标),列出所有 goal 文件及其 status 字段,然后结束。
|
|
18
|
+
b) 若存在 status=active 或 status=paused 的 goal 文件,优先读取并恢复执行,不再新建 goal。
|
|
19
|
+
1) 读取真值文件(`AI_PROJECT.md`、`REQUIREMENTS.md`、`AI_WORKSPACE.md`),确认项目规则与边界。
|
|
20
|
+
2) 接受用户输入的 goal objective,明确目标范围与验收标准。
|
|
21
|
+
3) 按 ws-goal-contract.md 的目标模板生成目标文件,写入 `.aiws/goals/<goal-id>.md`。
|
|
22
|
+
4) 输出 completion audit checklist,列出每个 goal 的完成标准与验证方式。
|
|
23
|
+
5) **Scope Assessment + 路由**:评估目标复杂度,自动选择执行路径:
|
|
24
|
+
a) 简单(≤5 文件、配置/doc/规范为主、低风险)→ 直行:后续步骤 6-8 auto-finish 闭环
|
|
25
|
+
b) 复杂(多模块、代码改动 >5 文件、架构/安全/迁移风险)→ 自动触发 `ws-plan` 启动 change 流水线(ws-plan → ws-dev → review → ws-commit → ws-finish),完成后更新 goal status=complete
|
|
26
|
+
c) 将路由决策写入 goal 文件 Audit Trail
|
|
27
|
+
6) 建议续跑方式:简单路径直行 auto-finish;复杂路径进入 change 流水线后建议 `ws-dev`
|
|
28
|
+
7) 每轮 execution 结束后执行 completion audit,比对 checklist 判断 goal 是否达成;未达成则继续下一轮。
|
|
29
|
+
8) 若 completion audit 确认 goal 达成,自动执行闭环 pipeline:
|
|
30
|
+
a) Review 检查(按改动类型):
|
|
31
|
+
- 配置/文档/规范类(markdown):内容一致性、引用完整性、内容正确性、无 secrets、格式统一
|
|
32
|
+
- 代码类(ts/js/py 等):lint/typecheck 通过、符合现有代码模式、无 secrets、测试通过或覆盖缺口已记录
|
|
33
|
+
- 混合类:以上两种合并
|
|
34
|
+
b) 简单路径:`git add` 目标产出文件 → `git commit -m "goal(<goal-id>): <objective 摘要>"` → `git push` → 更新 goal status=complete
|
|
35
|
+
c) 复杂路径:走 `ws-commit` → `ws-finish` → archive change → 更新 goal status=complete
|
|
36
|
+
d) 不通过:记录 blocker → 继续 fix 循环
|
|
37
|
+
<!-- AIWS_MANAGED_END:opencode:ws-goal -->
|
|
38
|
+
|
|
39
|
+
可在下方追加本项目对 OpenCode 的额外说明(托管块外内容会被保留)。
|
|
@@ -833,10 +833,44 @@ Read and follow the context below.
|
|
|
833
833
|
|
|
834
834
|
const activeChange = ctx.getActiveChange()
|
|
835
835
|
if (activeChange) {
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
836
|
+
// Prefer STATE.md (derived from journal by aiws change state --write)
|
|
837
|
+
let stateContent = ""
|
|
838
|
+
try {
|
|
839
|
+
const statePath = join(ctx.directory, ".aiws", "changes", activeChange.id, "STATE.md")
|
|
840
|
+
if (existsSync(statePath)) {
|
|
841
|
+
stateContent = readFileSync(statePath, "utf8")
|
|
842
|
+
}
|
|
843
|
+
} catch {
|
|
844
|
+
// STATE.md not available, fall back to phase summary
|
|
845
|
+
}
|
|
846
|
+
|
|
847
|
+
if (stateContent) {
|
|
848
|
+
parts.push("<change-state-state-md>")
|
|
849
|
+
parts.push("## Current Change State (from STATE.md)")
|
|
850
|
+
parts.push(stateContent.trimEnd())
|
|
851
|
+
parts.push("</change-state-state-md>")
|
|
852
|
+
} else {
|
|
853
|
+
const phaseSummary = ctx.getPhaseSummary(activeChange.id)
|
|
854
|
+
parts.push("<change-context>")
|
|
855
|
+
parts.push(phaseSummary)
|
|
856
|
+
parts.push("</change-context>")
|
|
857
|
+
}
|
|
858
|
+
|
|
859
|
+
// .ws-change.json baseline
|
|
860
|
+
try {
|
|
861
|
+
const wsChangePath = join(ctx.directory, ".aiws", "changes", activeChange.id, ".ws-change.json")
|
|
862
|
+
if (existsSync(wsChangePath)) {
|
|
863
|
+
const wsChangeRaw = readFileSync(wsChangePath, "utf8")
|
|
864
|
+
const wsChange = JSON.parse(wsChangeRaw)
|
|
865
|
+
parts.push("<change-baseline>")
|
|
866
|
+
parts.push("## Change Baseline (.ws-change.json)")
|
|
867
|
+
parts.push(`Base Branch: ${wsChange.base_branch || "unknown"}`)
|
|
868
|
+
parts.push(`Template ID: ${wsChange.template_id || "unknown"}`)
|
|
869
|
+
parts.push("</change-baseline>")
|
|
870
|
+
}
|
|
871
|
+
} catch {
|
|
872
|
+
// .ws-change.json not available
|
|
873
|
+
}
|
|
840
874
|
|
|
841
875
|
// Continuation resume recommendation
|
|
842
876
|
try {
|
|
@@ -55,12 +55,17 @@
|
|
|
55
55
|
"git diff"
|
|
56
56
|
],
|
|
57
57
|
"write_allow_paths": [
|
|
58
|
+
".aiws/tmp/",
|
|
59
|
+
".aiws/changes/*/analysis/",
|
|
60
|
+
".aiws/changes/*/review/",
|
|
61
|
+
".aiws/changes/*/evidence/",
|
|
58
62
|
".agentdocs/tmp/",
|
|
59
63
|
"changes/*/analysis/",
|
|
60
64
|
"changes/*/review/",
|
|
61
65
|
"changes/*/evidence/"
|
|
62
66
|
],
|
|
63
67
|
"deny_paths": [
|
|
68
|
+
".aiws/secrets/",
|
|
64
69
|
"secrets/",
|
|
65
70
|
".env*"
|
|
66
71
|
],
|
|
@@ -10,6 +10,47 @@ description: 使用时机:新需求需要逐条澄清、冻结问题时。触
|
|
|
10
10
|
- 采用“一题一线程”模式推进:每次只处理 1 个问题,允许该问题多轮往返,直到形成明确结论。
|
|
11
11
|
- 产出一份可被 `/ws-plan` 消费的轻量草案:`plan/<timestamp>-<slug>.intake.md`。
|
|
12
12
|
|
|
13
|
+
## Deep Interview 层(前置探询)
|
|
14
|
+
|
|
15
|
+
在逐题澄清前,先做一轮 Deep Interview 收集高维信息:
|
|
16
|
+
|
|
17
|
+
### 1. Why 探询
|
|
18
|
+
先问"为什么要做这个?背后的业务/用户价值是什么?"——理解动机后再谈方案。延伸探询:
|
|
19
|
+
- "如果不做这个,会有什么后果?"(量化不做的代价,确认 urgency)
|
|
20
|
+
- "这个需求最早是谁提出的?在什么场景下触发的?"(追溯原始 trigger,避免需求被转述变形)
|
|
21
|
+
|
|
22
|
+
### 2. 非目标(Non-goals)
|
|
23
|
+
显式记录什么不在本次范围内——防止 scope creep 和后续争论。
|
|
24
|
+
例如:"这次不做用户权限管理,只做内容展示层""这个版本不做国际化"。
|
|
25
|
+
非目标与目标同等重要,需用户确认后写入 intake 草案。
|
|
26
|
+
|
|
27
|
+
### 3. 影响面(Stakeholders)
|
|
28
|
+
识别这个改动会影响谁:
|
|
29
|
+
- 终端用户(使用行为是否会变?)
|
|
30
|
+
- 其他模块或系统(API 耦合、数据依赖)
|
|
31
|
+
- 其他团队(是否需要跨团队协调?谁需要参与评审?)
|
|
32
|
+
|
|
33
|
+
### 4. 假设显式化
|
|
34
|
+
从当前理解中识别隐含假设,逐条列出并请用户确认。例如:你假设了用户已登录/有权限;你假设了数据规模不超过 X;你假设了这个功能只有 Y 场景用到。
|
|
35
|
+
|
|
36
|
+
### 5. 替代方案
|
|
37
|
+
在选定方案前,先问"是否考虑过其他方案?为什么选了当前这个?"——记录已探明的替代路径和淘汰理由。
|
|
38
|
+
如果用户明确没考虑过替代方案,在 intake 草案中标记 `Alternatives not explored` 作为风险项。
|
|
39
|
+
|
|
40
|
+
### 6. 约束挑战
|
|
41
|
+
对每条约束问"如果这条约束不存在会怎样?"——区分硬约束(不可变)和自设约束(可协商)。
|
|
42
|
+
|
|
43
|
+
### 7. 优先级
|
|
44
|
+
Must-have / Should-have / Nice-to-have 三层分类,明确 scope 底线。
|
|
45
|
+
|
|
46
|
+
### 8. 成功度量
|
|
47
|
+
不仅仅是"验收标准通过",更要问"这个功能上线后,怎么判断它成功了?"——量化指标(DAU、转化率、响应时间、错误率等)。如果无法量化则记入风险。
|
|
48
|
+
|
|
49
|
+
### 9. 风险预判
|
|
50
|
+
识别 3-5 个最关键风险(技术方案、时间窗口、外部依赖、安全合规),写入 intake 草案。
|
|
51
|
+
|
|
52
|
+
输出:以上 9 项归入 intake 草案的 `Deep Interview` 小节。
|
|
53
|
+
|
|
13
54
|
## 发散-收敛两子阶段
|
|
14
55
|
|
|
15
56
|
当需求模糊、方向不明确时,intake 分两子阶段推进:
|
|
@@ -18,6 +59,12 @@ description: 使用时机:新需求需要逐条澄清、冻结问题时。触
|
|
|
18
59
|
- 目标:快速探索 2-3 个可能方向,不深入任何单一方向
|
|
19
60
|
- 输出:每个方向的 1-2 段摘要 + 关键风险 + 依赖
|
|
20
61
|
- 时限:不超过 3 轮对话
|
|
62
|
+
- **探码前问**:在向用户提问前,先使用 `explore` agent 探查代码库中是否已有答案。需要探查的维度包括:
|
|
63
|
+
- 现有配置文件(`AI_PROJECT.md`、`REQUIREMENTS.md`、`AI_WORKSPACE.md`、`package.json`、`tsconfig.json` 等)
|
|
64
|
+
- 已有实现模式(grep 关键词、查找类似功能的实现文件)
|
|
65
|
+
- 已有文档或注释(相关模块的 README、代码注释)
|
|
66
|
+
- 已有测试文件(理解测试模式和边界条件)
|
|
67
|
+
- 探查到的信息直接作为发散阶段的输入,不需要再向用户重复确认已经在代码库中找到的事实。
|
|
21
68
|
|
|
22
69
|
### 收敛阶段(Converge)
|
|
23
70
|
- 目标:从发散结果中选择 1 个方向,逐条冻结具体问题
|
|
@@ -43,28 +90,36 @@ description: 使用时机:新需求需要逐条澄清、冻结问题时。触
|
|
|
43
90
|
1) 先读 `AI_PROJECT.md` / `REQUIREMENTS.md` / `AI_WORKSPACE.md`,必要时先 `/ws-preflight`。
|
|
44
91
|
2) 若存在最新 `plan/*.intake.md`,先续写它;否则新建一份 intake 草案。
|
|
45
92
|
3) 把当前任务拆成 `Open Questions`,状态只允许 `open / in_discussion / frozen / deferred`。
|
|
46
|
-
|
|
93
|
+
|
|
94
|
+
4) **探码后问**:在对每个 Open Question 提问前,先 spawn `explore` agent 探查代码库。如果代码库中已有足以回答该问题的信息,在 intake 草案的相应章节记录该信息,并跳过该问题的提问。只有当代码库无法回答时,才把该问题交给用户。记录每个问题属于以下哪一类:
|
|
95
|
+
- `codebase: answered` — 代码库已可回答,跳过提问
|
|
96
|
+
- `codebase: partial` — 代码库有部分信息,补充提问未覆盖的部分
|
|
97
|
+
- `user: required` — 必须问用户
|
|
98
|
+
|
|
99
|
+
5) 每次只推进 1 个当前问题,并显式输出:
|
|
47
100
|
- `Current question:`
|
|
48
101
|
- `Why it matters:`
|
|
49
102
|
- `Current options / current understanding:`
|
|
50
103
|
- `Exit condition:`
|
|
51
104
|
- 每个问题独立线程:在未标记 frozen/deferred 前,不进入下一题。问答往返不限轮数,但一次只处理一个维度的决策。
|
|
52
|
-
|
|
53
|
-
|
|
105
|
+
6) 若用户一次提出多个问题,必须显式排队:列出所有问题编号,按顺序逐个处理;不得同时推进多个问题的讨论。输出格式:`Queued questions: #1, #2, ... | Current: #1`
|
|
106
|
+
7) 每轮都要把 intake 草案写盘,至少包含:
|
|
107
|
+
- `Deep Interview` — 9 维分析:Why/非目标/影响面/假设/替代方案/约束/优先级/成功度量/风险
|
|
54
108
|
- `Context`
|
|
109
|
+
- `Codebase Knowns` — 来自代码库的已知信息:在提问前通过 explore 已确认的事实、现有模式、配置值等。标注每项的信息来源路径
|
|
55
110
|
- `Open Questions`
|
|
56
111
|
- `Resolved Questions`
|
|
57
112
|
- `Frozen Decisions`
|
|
58
113
|
- `Draft Scope`
|
|
59
114
|
- `Draft Verify`
|
|
60
115
|
- `Ready for ws-plan: yes/no`
|
|
61
|
-
|
|
116
|
+
8) 错误状态节点(Error States):
|
|
62
117
|
- 在 intake 草案中专设 `Error States` 小节,覆盖已知失败模式:
|
|
63
118
|
- 网络/超时/第三方依赖不可用时的系统行为
|
|
64
119
|
- 数据一致性(并发写入、部分失败、脏数据)
|
|
65
120
|
- 输入校验边界(空、超大、非预期类型)
|
|
66
121
|
- 若识别到需要回滚的场景:在 `Error States` 中写明回滚条件与回滚方式。
|
|
67
|
-
|
|
122
|
+
9) 回滚规范(Rollback Spec):
|
|
68
123
|
- 当 intake 涉及现有数据迁移、API 契约变更、配置漂移修复时,必须包含 `Rollback Plan` 小节。
|
|
69
124
|
- `Rollback Plan` 至少包含:触发条件、回滚步骤、验证回滚成功的方式、副作用清单。
|
|
70
|
-
|
|
125
|
+
10) 若关键问题已冻结:`Next` 指向 `/ws-plan`;否则继续 `/ws-intake`。
|
|
@@ -38,6 +38,7 @@
|
|
|
38
38
|
".claude/commands/ws-dev-lite.md",
|
|
39
39
|
".claude/commands/ws-dev.md",
|
|
40
40
|
".claude/commands/ws-finish.md",
|
|
41
|
+
".claude/commands/ws-goal.md",
|
|
41
42
|
".claude/commands/ws-handoff.md",
|
|
42
43
|
".claude/commands/ws-intake.md",
|
|
43
44
|
".claude/commands/ws-migrate.md",
|
|
@@ -88,26 +89,18 @@
|
|
|
88
89
|
".opencode/command/ws-deliver.md",
|
|
89
90
|
".opencode/command/ws-dev-lite.md",
|
|
90
91
|
".opencode/command/ws-dev.md",
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
".opencode/command/ws-req-contract-validate.md",
|
|
104
|
-
".opencode/command/ws-req-flow-sync.md",
|
|
105
|
-
".opencode/command/ws-req-review.md",
|
|
106
|
-
".opencode/command/ws-review.md",
|
|
107
|
-
".opencode/command/ws-rule.md",
|
|
108
|
-
".opencode/command/ws-spec-review.md",
|
|
109
|
-
".opencode/command/ws-submodule-setup.md",
|
|
110
|
-
".opencode/command/ws-verify-before-complete.md",
|
|
92
|
+
".opencode/command/ws-finish.md",
|
|
93
|
+
".opencode/command/ws-goal.md",
|
|
94
|
+
".opencode/command/ws-handoff.md",
|
|
95
|
+
".opencode/command/ws-intake.md",
|
|
96
|
+
".opencode/command/ws-plan.md",
|
|
97
|
+
".opencode/command/ws-delegate.md",
|
|
98
|
+
".opencode/command/ws-autonomy.md",
|
|
99
|
+
".opencode/command/ws-auto.md",
|
|
100
|
+
".opencode/command/ws-plan-verify.md",
|
|
101
|
+
".opencode/command/ws-spec-review.md",
|
|
102
|
+
".opencode/command/ws-quality-review.md",
|
|
103
|
+
".opencode/command/ws-verify-before-complete.md",
|
|
111
104
|
".opencode/plugins/aiws-inject-context.js",
|
|
112
105
|
".opencode/plugins/aiws-session-start.js",
|
|
113
106
|
".opencode/plugins/aiws-workflow-state.js",
|
|
@@ -150,6 +143,7 @@
|
|
|
150
143
|
"optional": [
|
|
151
144
|
".aiws/memory-bank/**",
|
|
152
145
|
".aiws/secrets/test-accounts.example.json",
|
|
146
|
+
".agents/skills/ws-delegate/SKILL.md",
|
|
153
147
|
".opencode/oh-my-opencode.json.example",
|
|
154
148
|
".claude/settings.json.example",
|
|
155
149
|
".opencode/helpers/approval-whitelist-check.sh",
|
|
@@ -185,6 +179,7 @@
|
|
|
185
179
|
".agents/skills/aiws-update/SKILL.md",
|
|
186
180
|
".agents/skills/aiws-validate/SKILL.md",
|
|
187
181
|
".agents/skills/ws-tasks-plan/SKILL.md",
|
|
182
|
+
".agents/skills/ws-research/SKILL.md",
|
|
188
183
|
".claude/commands/aiws-change-archive.md",
|
|
189
184
|
".claude/commands/aiws-change-finish.md",
|
|
190
185
|
".claude/commands/aiws-change-list.md",
|
|
@@ -257,6 +252,7 @@
|
|
|
257
252
|
".claude/commands/ws-spec-review.md",
|
|
258
253
|
".claude/commands/ws-quality-review.md",
|
|
259
254
|
".claude/commands/ws-verify-before-complete.md",
|
|
255
|
+
".claude/commands/ws-goal.md",
|
|
260
256
|
".claude/skills/using-aiws/SKILL.md",
|
|
261
257
|
".opencode/command/p-aiws-change-archive.md",
|
|
262
258
|
".opencode/command/p-aiws-change-finish.md",
|
|
@@ -272,6 +268,7 @@
|
|
|
272
268
|
".opencode/command/p-aiws-hooks-install.md",
|
|
273
269
|
".opencode/command/p-aiws-hooks-status.md",
|
|
274
270
|
".opencode/command/using-aiws.md",
|
|
271
|
+
".opencode/command/ws-goal.md",
|
|
275
272
|
".opencode/command/ws-intake.md",
|
|
276
273
|
".opencode/command/ws-plan.md",
|
|
277
274
|
".opencode/command/ws-delegate.md",
|
|
@@ -349,8 +346,10 @@
|
|
|
349
346
|
".agents/skills/ws-review/SKILL.md",
|
|
350
347
|
".agents/skills/ws-commit/SKILL.md",
|
|
351
348
|
".agents/skills/ws-delegate/SKILL.md",
|
|
349
|
+
".agents/skills/ws-research/SKILL.md",
|
|
352
350
|
".agents/skills/ws-deliver/SKILL.md",
|
|
353
351
|
".agents/skills/ws-finish/SKILL.md",
|
|
352
|
+
".agents/skills/ws-goal/SKILL.md",
|
|
354
353
|
".agents/skills/ws-handoff/SKILL.md",
|
|
355
354
|
".agents/skills/ws-migrate/SKILL.md",
|
|
356
355
|
".agents/skills/ws-pull/SKILL.md",
|
|
@@ -580,6 +579,9 @@
|
|
|
580
579
|
".claude/commands/ws-plan-verify.md": [
|
|
581
580
|
"claude:ws-plan-verify"
|
|
582
581
|
],
|
|
582
|
+
".claude/commands/ws-goal.md": [
|
|
583
|
+
"claude:ws-goal"
|
|
584
|
+
],
|
|
583
585
|
".claude/commands/ws-handoff.md": [
|
|
584
586
|
"claude:ws-handoff"
|
|
585
587
|
],
|
|
@@ -655,6 +657,9 @@
|
|
|
655
657
|
".opencode/command/ws-plan-verify.md": [
|
|
656
658
|
"opencode:ws-plan-verify"
|
|
657
659
|
],
|
|
660
|
+
".opencode/command/ws-goal.md": [
|
|
661
|
+
"opencode:ws-goal"
|
|
662
|
+
],
|
|
658
663
|
".opencode/command/ws-handoff.md": [
|
|
659
664
|
"opencode:ws-handoff"
|
|
660
665
|
],
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""ws_tasks_plan — parse tasks.md checkbox progress and emit structured status/plan payloads.
|
|
3
|
+
|
|
4
|
+
Usage:
|
|
5
|
+
python3 ws_tasks_plan.py status --file changes/<id>/tasks.md
|
|
6
|
+
python3 ws_tasks_plan.py plan --file changes/<id>/tasks.md [--explanation "<reason>"]
|
|
7
|
+
|
|
8
|
+
Output (stdout):
|
|
9
|
+
status → JSON: { "total": N, "done": N, "pending": N }
|
|
10
|
+
plan → JSON: { "plan": [{ "status": "...", "content": "..." }], "explanation": "..." }
|
|
11
|
+
|
|
12
|
+
Rules:
|
|
13
|
+
- Only parses checkbox items (`- [ ]` / `- [x]` / `- [X]`).
|
|
14
|
+
- In `plan` mode, derives status from checkbox: `[x]` → completed, unchecked → pending.
|
|
15
|
+
- If there is at least one unchecked item, the first unchecked item is inferred as in_progress.
|
|
16
|
+
- Ignores non-checkbox lines, comments, and blank lines.
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
import argparse
|
|
20
|
+
import json
|
|
21
|
+
import sys
|
|
22
|
+
import re
|
|
23
|
+
|
|
24
|
+
CHECKBOX_RE = re.compile(r'^\s*-\s*\[([ xX])\]\s*(.*)$')
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def parse_tasks(filepath):
|
|
28
|
+
"""Return list of { 'checked': bool, 'label': str } from tasks.md."""
|
|
29
|
+
tasks = []
|
|
30
|
+
try:
|
|
31
|
+
with open(filepath, 'r', encoding='utf-8') as f:
|
|
32
|
+
for line in f:
|
|
33
|
+
m = CHECKBOX_RE.match(line)
|
|
34
|
+
if m:
|
|
35
|
+
checked = m.group(1).lower() == 'x'
|
|
36
|
+
label = m.group(2).strip()
|
|
37
|
+
tasks.append({'checked': checked, 'label': label})
|
|
38
|
+
except FileNotFoundError:
|
|
39
|
+
print(f"Error: file not found: {filepath}", file=sys.stderr)
|
|
40
|
+
sys.exit(1)
|
|
41
|
+
return tasks
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def cmd_status(args):
|
|
45
|
+
tasks = parse_tasks(args.file)
|
|
46
|
+
total = len(tasks)
|
|
47
|
+
done = sum(1 for t in tasks if t['checked'])
|
|
48
|
+
pending = total - done
|
|
49
|
+
print(json.dumps({'total': total, 'done': done, 'pending': pending}, ensure_ascii=False))
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def cmd_plan(args):
|
|
53
|
+
tasks = parse_tasks(args.file)
|
|
54
|
+
plan_items = []
|
|
55
|
+
found_first_unchecked = False
|
|
56
|
+
|
|
57
|
+
for t in tasks:
|
|
58
|
+
if t['checked']:
|
|
59
|
+
status = 'completed'
|
|
60
|
+
elif not found_first_unchecked:
|
|
61
|
+
status = 'in_progress'
|
|
62
|
+
found_first_unchecked = True
|
|
63
|
+
else:
|
|
64
|
+
status = 'pending'
|
|
65
|
+
|
|
66
|
+
plan_items.append({'status': status, 'content': t['label']})
|
|
67
|
+
|
|
68
|
+
result = {
|
|
69
|
+
'plan': plan_items,
|
|
70
|
+
'explanation': args.explanation or 'sync tasks.md -> update_plan',
|
|
71
|
+
}
|
|
72
|
+
print(json.dumps(result, ensure_ascii=False))
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def main():
|
|
76
|
+
parser = argparse.ArgumentParser(description='Parse tasks.md for AIWS change workflow')
|
|
77
|
+
sub = parser.add_subparsers(dest='command')
|
|
78
|
+
|
|
79
|
+
stat = sub.add_parser('status', help='Emit total/done/pending counts')
|
|
80
|
+
stat.add_argument('--file', required=True, help='Path to tasks.md')
|
|
81
|
+
|
|
82
|
+
plan = sub.add_parser('plan', help='Emit update_plan JSON payload')
|
|
83
|
+
plan.add_argument('--file', required=True, help='Path to tasks.md')
|
|
84
|
+
plan.add_argument('--explanation', default='', help='Why this plan sync is being performed')
|
|
85
|
+
|
|
86
|
+
args = parser.parse_args()
|
|
87
|
+
if args.command == 'status':
|
|
88
|
+
cmd_status(args)
|
|
89
|
+
elif args.command == 'plan':
|
|
90
|
+
cmd_plan(args)
|
|
91
|
+
else:
|
|
92
|
+
parser.print_help()
|
|
93
|
+
sys.exit(1)
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
if __name__ == '__main__':
|
|
97
|
+
main()
|