@aipper/aiws-spec 0.0.45 → 0.0.47

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.
@@ -123,7 +123,19 @@ main → change/A → change/B → change/C (当前)
123
123
  |---|---|
124
124
  | 全部 HEALTHY | 放行,无需确认 |
125
125
  | 存在 STALE | 输出警告,允许继续 |
126
- | 存在 UNHEALTHY | 输出完整 chain 拓扑 + 健康报告,**必须用户显式确认**才能继续 |
126
+ | 存在 UNHEALTHY | **硬阻断**。输出完整 chain 拓扑 + 健康报告 + 按 link 分类的修复建议,goal status → blocked。用户必须按建议修复上游后重试,或变更 target_base_branch 剔除不健康 link |
127
+
128
+ **UNHEALTHY 修复建议格式**(每个不健康 link 附带):
129
+ ```text
130
+ link: change/A
131
+ 状态: UNHEALTHY (review 有 HIGH blocker)
132
+ 修复: 1) `aiws review` → 解决 blocker 后通过 review
133
+ 2) 或 `aiws change target_base_branch main` → 跳过此 link (如适用)
134
+ link: change/D
135
+ 状态: UNHEALTHY (50% WS:TODO 未完成,14 天无进展)
136
+ 修复: 1) `aiws dev` → 推进 TODO 到 <50%
137
+ 2) 或 `aiws change target_base_branch main` → 跳过此 link
138
+ ```
127
139
  | 父 change 不存在(孤儿分支)| 阻断,提示选择已知 base |
128
140
  | **实际 base_branch ≠ goal target_base_branch** | **阻断**。输出 "goal 声明 target_base_branch = X,但当前 base_branch = Y",必须用户修正或显式确认才能继续。此检查优先于链健康检查——如果 base_branch 本身就选错了,不需要继续追溯 |
129
141
 
@@ -132,7 +144,6 @@ main → change/A → change/B → change/C (当前)
132
144
  验证结果必须写入 goal artifact 的 `Dependency Chain` 字段(见 3.1 模板),包括:
133
145
  - 完整 chain 拓扑(从 main 到当前)
134
146
  - 每个 link 的健康状态与判定理由
135
- - 用户确认记录(若 UNHEALTHY 被显式放行)
136
147
 
137
148
  ### 2.5 Workspace State Analysis
138
149
 
@@ -171,25 +182,28 @@ ws-goal 在执行 pipeline delegation(管道委托,见 1.§ 第四步)之
171
182
  ═══════════════════════
172
183
  ```
173
184
 
174
- #### 2.5.4 确认门禁(分级处理)
185
+ #### 2.5.4 自动处理策略(分级自动处理,无阻断)
175
186
 
176
- 报告输出后,按影响等级分级处理:
187
+ 报告输出后,按影响等级自动处理:
177
188
 
178
189
  | 等级 | 行为 |
179
190
  |------|------|
180
191
  | **NONE** | 自动继续。发现项记录到 Audit Trail,不阻断 |
181
192
  | **LOW** | 自动继续。输出提示,发现项记录到 Audit Trail |
182
193
  | **MED** | 自动继续。输出警告信息,发现项记录到 Audit Trail |
183
- | **HIGH** | **阻断**。必须等待用户确认后才能继续 |
194
+ | **HIGH** | **自动解决**。按以下策略自动处理每种 HIGH 场景;仅自动化失败时才通知用户 |
184
195
 
185
- **HIGH 阻断确认选项**:
186
- - **继续** → 进入 pipeline delegation
187
- - **暂停** → goal status=paused,报告写入 Audit Trail
188
- - **先清理** → goal status=paused,输出清理建议步骤
196
+ **HIGH 场景自动解决策略**:
189
197
 
190
- 用户未确认 HIGH 阻断项,不得进入 delegation。
198
+ | HIGH 场景 | 自动解决行为 |
199
+ |-----------|-------------|
200
+ | Dirty 工作区(staged/unstaged 改动) | `git stash push --keep-index -m "ws-goal auto-stash: <goal-id>"` → 继续。完成后尝试 `git stash pop`,若冲突则输出恢复命令(`git stash drop && git stash pop`),不阻断 |
201
+ | 旧 change 分支未合并 | 输出警告 "检测到遗留 change: <branch>" → **自动继续**。不阻断 |
202
+ | Submodule dirty / detached | `git submodule update --recursive` 自动修复 → 若失败则输出警告并继续 |
203
+ | 同名 goal 冲突 | 追加时间戳后缀自动重命名 → 继续。记录原始 goal id 到 Audit Trail |
204
+ | Unpushed commits | 输出提示 "存在未推送提交" → **自动继续**。不阻断 |
191
205
 
192
- > **设计原则**:LOW/MED 发现项不应阻断工作流。它们被记录到 Audit Trail 供后续回溯,但不需要用户停下当前工作。HIGH 发现项才是真正的风险门禁,必须有用户显式授权放行。
206
+ > 设计原则:工作区问题不应该是 ws-goal 的阻断项。ws-goal 应尽可能自动处理,让用户专注于目标本身,而不是被工作区状态打断。只有自动化处理真正失败时才通知用户——且即使通知也不阻断,只输出提示。
193
207
 
194
208
  ---
195
209
 
@@ -571,7 +585,7 @@ Group 是 goal 内部的一个自包含执行单元:
571
585
  | **status** | enum | `pending \| in_progress \| complete \| paused \| failed` |
572
586
  | **design_context** | string | 该组的设计草稿/意图说明,委托 subagent 前必须填写 |
573
587
  | **internal_tasks** | string[] | 组内部可安全委托的自包含子任务列表,每项应 ≤ 3 文件改动粒度 |
574
- | **granularity_ok** | boolean | session DEV phase 前设置,true = 该组 scope 5 文件且不跨模块 |
588
+ | **granularity_ok** | boolean | ⚠️ **已废弃**(v2 起不再手动设置)。改为 Granularity Gate(§6.4 step c)自动计算二级评估(compliant / marginal)并递归自动分解。向后兼容:读取到 `granularity_ok=false` 时等价于 Level 2 MARGINAL(自动分解);`granularity_ok=true` 时等价于 Level 1 COMPLIANT |
575
589
 
576
590
  #### 6.2.2 Group Dependencies
577
591
 
@@ -633,6 +647,26 @@ phase 间的主 session 验证是门禁:
633
647
  - **失败隔离**:一个 phase 失败不影响其他 phase 的产出;只需重试失败的 phase
634
648
  - **可审计**:每个 phase 的产出有明确的验证标准,主 session 逐条核验
635
649
 
650
+ #### 6.2.5 Scope Advisory(INTAKE 阶段)
651
+
652
+ Group 结构应在 INTAKE 阶段确定,而非在 Granularity Gate 才暴露。Scope Advisory 在 INTAKE 结束时运行:
653
+
654
+ 1. **输入**:INTAKE 已冻结的目标范围、约束、边界
655
+ 2. **评估**:基于以下信号判断 scope 规模:
656
+ - 涉及文件数(估算)、模块数、跨层改动(API/DB/UI)
657
+ - 变更类型(重构 vs 新功能 vs 修复)
658
+ - 与历史 group 的比较经验
659
+ 3. **输出**:
660
+ - scope 合理(≤5 文件、≤2 模块、单层改动)→ 直接继续,单 group
661
+ - scope 较大(>5 文件或 >2 模块或跨层改动)→ 输出 scope 评估报告,建议分拆:
662
+ - 提供推荐方案:按模块 / 按阶段 / 其他边界
663
+ - 用户选择是否拆分及具体方案
664
+ 4. **结果**:
665
+ - 若用户选择拆分 → 在 goal 文件中定义 sub_groups(§6.3 模板)
666
+ - 若用户选择不拆分 → 单 group 处理,但**提示用户**:"注意:如果 scope 执行时 Granularity Gate 发现 >3 文件/多模块,仍会自动拆分为多个执行单元。你不需要管理这些拆分——它们是透明的执行细节。"
667
+
668
+ 设计原则:scope 拆分的决策应在用户参与度最高的 intake 阶段完成,而不是在执行阶段才被发现。Granularity Gate 的职责降为:对已确定结构的 group 做细粒度自动分解(MARGINAL),不做 scope 级的判断。
669
+
636
670
  ### 6.3 Goal File Extension
637
671
 
638
672
  启用 Pipeline Sequential Dispatch 的 goal,在 `Progress Notes` 字段上方或 `Tasks` 区域添加 groups 定义:
@@ -647,28 +681,88 @@ phase 间的主 session 验证是门禁:
647
681
  - "Replace hardcoded grid with <ProductGrid> component"
648
682
  - "Add category filter sidebar to category.tsx"
649
683
  - "Wire search API endpoint to search.tsx"
650
- - granularity_ok: false
651
684
  - verification:
652
685
  - "Home page renders product grid"
653
686
  - "Category page renders with filters"
654
687
  - "Search results show 10 items per page"
655
688
  - depends_on: []
656
689
  - status: pending
690
+ # granularity will be auto-assessed by Granularity Gate (§6.4 step c)
657
691
 
658
- ### group-2: Purchase Conversion
659
- - scope: cart.tsx, checkout.tsx, payment-form.tsx
692
+ ### group-2: Purchase Conversion (overload example — will auto-decompose)
693
+ - scope: cart.tsx, checkout.tsx, payment-form.tsx, order-history.tsx, return-flow.tsx, email-receipt.tsx
660
694
  - design_context: "Purchase flow is client-only, uses React context for cart state"
661
695
  - internal_tasks:
662
696
  - "Refactor cart context to persist to localStorage"
663
697
  - "Add shipping address form with validation"
664
698
  - "Implement card number validation with Luhn check"
665
- - granularity_ok: false
699
+ - "Add order history page with pagination"
700
+ - "Implement return request flow with RMA generation"
701
+ - "Generate email receipt PDF on order confirmation"
666
702
  - verification:
667
703
  - "Add to cart updates badge count"
668
704
  - "Checkout collects shipping address"
669
705
  - "Payment form validates card number"
706
+ - "Order history shows 20 items per page"
707
+ - "Return request generates RMA number"
708
+ - "Email receipt is sent on order confirmation"
709
+ - depends_on: [group-1]
710
+ - status: pending
711
+ # Granularity Gate: 6 files > 3 → MARGINAL, auto-split into sub-groups, recurse
712
+
713
+ ### group-3: Search Module (manual recursive nest example)
714
+ - scope: src/search/
715
+ - design_context: "Search module with 3 sub-modules. User pre-split to match team expertise."
716
+ - internal_tasks: []
717
+ - verification:
718
+ - "Full-text search returns results within 500ms"
719
+ - "Search history persists across sessions"
720
+ - "Filter panel updates result list reactively"
670
721
  - depends_on: [group-1]
671
722
  - status: pending
723
+ - sub_groups:
724
+ ### group-3/search-core
725
+ - scope: search.tsx, search-result.tsx, search-store.ts
726
+ - design_context: "Core search logic: debounced input, API call, result caching"
727
+ - internal_tasks:
728
+ - "Implement debounced search input with 300ms delay"
729
+ - "Wire search API endpoint with abort controller"
730
+ - "Add result caching layer to search-store"
731
+ - verification:
732
+ - "Search input debounces at 300ms"
733
+ - "API calls are cancellable on input change"
734
+ - "Cached results served on repeated query"
735
+ - status: pending
736
+
737
+ ### group-3/search-filter
738
+ - scope: filter-panel.tsx, filter-store.ts, filter-types.ts
739
+ - design_context: "Filter sidebar with multi-select categories, reactive updates"
740
+ - internal_tasks:
741
+ - "Build filter panel UI with multi-select checkboxes"
742
+ - "Wire filter-store to search-store for reactive result refresh"
743
+ - "Add URL-sync for filter state persistence"
744
+ - verification:
745
+ - "Filter panel shows/hides on toggle"
746
+ - "Changing filter refreshes search results"
747
+ - "Filter state restores from URL on page load"
748
+ - depends_on: [group-3/search-core]
749
+ - status: pending
750
+
751
+ ### group-3/search-history
752
+ - scope: history.tsx, history-store.ts, history-api.ts
753
+ - design_context: "Search history: recent queries list, local persistence, clear option"
754
+ - internal_tasks:
755
+ - "Implement history-store with localStorage persistence"
756
+ - "Build history dropdown UI with recent queries"
757
+ - "Add 'clear history' action with confirmation"
758
+ - verification:
759
+ - "Recent queries appear in history dropdown"
760
+ - "History persists after page reload"
761
+ - "Clear history removes all entries"
762
+ - depends_on: [group-3/search-core]
763
+ - status: pending
764
+ # group-3 manually defines 3 children. Granularity Gate skips parent (has sub_groups),
765
+ # validates each leaf independently. Completion propagates: leaves → parent → goal.
672
766
  ```
673
767
 
674
768
  ### 6.4 Dispatch Protocol (Phase-Level)
@@ -680,29 +774,104 @@ ws-goal 执行 Phase-Level Sequential Dispatch 时遵循以下协议:
680
774
  2. Validate group DAG (no cycles, deps resolve to known groups)
681
775
  3. FOR each group in topological order:
682
776
  a. Update group status → in_progress
683
- b. Group PHASE 1 - PLAN:
777
+ a1. **Container group check** (has sub_groups):
778
+ - If group has pre-defined `sub_groups` → mark as **container** but **proceed to PLAN** (step b)
779
+ - Container runs PLAN to produce a **single unified proposal** covering all children's scopes
780
+ - **Container never runs DEV/REVIEW/FINISH itself** — children handle execution
781
+ - After PLAN → step c processes children recursively → step g propagates completion
782
+ b. **PHASE 1 - PLAN** (leaf group or container group):
684
783
  i. Construct phase delegation prompt:
784
+ - **Container group**: include container's scope + all sub_groups' scopes + dependencies
785
+ - **Leaf group**: include current group scope and verification only
685
786
  - Goal outcome, verification (group-level), constraints, boundaries
686
- - Current group scope and verification
687
787
  - target_base_branch from goal
688
788
  - Dependency chain validation results (step 4)
689
789
  - Workspace state analysis results (step 4.5)
690
790
  - Phase scope: ONLY proposal.md + plan file + plan-verify
691
791
  - Phase constraints: NOT dev, NOT review, NOT commit/finish
692
792
  - output_manifest: proposal.md, plan file, plan-verify evidence
693
- ii. Delegate to sub-agent:
694
- - `task(category="unspecified-high", prompt="...")`
695
- - Wait for completion
696
- iii. Main session verify:
697
- - proposal.md exists
698
- - plan file exists with verification commands
699
- - plan-verify passed
700
- - Fail max 2x → group paused, blocker recorded, STOP
701
- c. Granularity Gate (before DEV):
702
- i. Read current group's granularity_ok field
703
- ii. If granularity_ok !== true: output block report (scope, file count, cross-module span), pause goal
704
- iii. Verify design_context and internal_tasks non-empty
705
- iv. If either empty: output warning (non-blocking), suggest filling
793
+ ii. Delegate to sub-agent:
794
+ - `task(category="unspecified-high", prompt="...")`
795
+ - Wait for completion
796
+ iii. Main session verify:
797
+ - proposal.md exists (covers ALL children if container)
798
+ - plan file exists with verification commands
799
+ - plan-verify passed
800
+ - Fail max 2x → group paused, blocker recorded, STOP
801
+ c. Granularity Gate & Decomposition (before DEV):
802
+ ⚠️ **Scope 边界已在 INTAKE 阶段确定(§6.2.5)**。此 Gate 只处理细粒度自动分解(MARGINAL),不做 scope 级的分拆决策。
803
+ i. Check if current group has pre-defined sub_groups:
804
+ - If `sub_groups` field exists and has entries → parent is a **container group**
805
+ - **Skip** granularity assessment for the container group
806
+ - For each child in sub_groups, recursively run step c (Granularity Gate on each child)
807
+ - Child groups with their own sub_groups → recurse deeper
808
+ - Leaf groups (no sub_groups) → run normal granularity assessment (steps ii-v)
809
+ - After all leaves pass → return to step d for the **first ready leaf** (topological order)
810
+ - **Leaves skip PLAN**: container's PLAN (step b) already covers all children; leaves go directly to DEV (step d)
811
+ - Skip container: it never has its own DEV phase (only children execute)
812
+ ii. **Leaf group**: compute granularity assessment:
813
+ - Count estimated files from scope description (file patterns listed)
814
+ - Count distinct modules/directories referenced
815
+ - Count internal_tasks and estimate per-task file scope
816
+ iii. Granularity classification (2-level assessment, no blocking):
817
+
818
+ **Level 1 — COMPLIANT** (≤3 files, single module, each internal_task ≤2 files)
819
+ → Proceed to DEV phase directly (step d)
820
+ → Record assessment: `granularity_assessment: "compliant"` in state.json
821
+
822
+ **Level 2 — MARGINAL** (>3 files, or multi-module, or any internal_task >2 files, or cannot estimate)
823
+ → Auto-decompose group into sub-groups:
824
+ a. Detect module boundaries from scope file paths (same directory prefix → same module)
825
+ b. If clear module boundaries exist → split by module affinity
826
+ c. If no clear boundaries (all files in one directory) → split evenly by file count (≤3 files per sub-group)
827
+ d. Assign each sub-group a compound id: `<group-id>/sub-<N>` (e.g. `group-1/sub-1`)
828
+ e. Each sub-group inherits parent's design_context and verification
829
+ f. Each sub-group goes through Granularity Gate recursively (back to step i)
830
+ - If sub-group also MARGINAL → split again. Recursion handles arbitrary depth.
831
+ - Leaf sub-groups eventually reach COMPLIANT → proceed to DEV
832
+ f1. **DAG re-validation**: After creating sub-groups (auto or manual), validate their local DAG:
833
+ - Ensure no cycles among sub-groups within the same parent
834
+ - Ensure all `depends_on` references resolve to known sibling sub-groups or root groups
835
+ - If cycle detected → auto-repair: break cycle by removing the longest dependency chain, log warning to Audit Trail
836
+ - If unresolved dependency → auto-repair: remove unknown reference, log warning
837
+ - Validation applies recursively at each nesting level (sub-groups of sub-groups also validated)
838
+ g. Parent group becomes container (has sub_groups) → skip DEV, pass-through to children
839
+ h. Update state.json:
840
+ - Parent group status → `in_progress`, `decomposed: true`
841
+ - First leaf status → `in_progress`
842
+ - `current_group` → first leaf
843
+ → Record assessment: `granularity_assessment: "marginal", decomposed: true` in state.json
844
+
845
+ **No user confirmation needed.** Recursive auto-split handles any scope size.
846
+
847
+ iv. Verify design_context and internal_tasks non-empty:
848
+ - If design_context empty: output warning (non-blocking), suggest filling before DEV
849
+ - If internal_tasks empty but scope is clear: MEDIUM warning, auto-generate task suggestions from scope
850
+ v. State.json sub-group entry format (for MARGINAL auto-decomposition):
851
+
852
+ ```json
853
+ "groups": {
854
+ "group-1": {
855
+ "status": "in_progress",
856
+ "design_context": "...",
857
+ "verification": ["..."],
858
+ "granularity_assessment": "marginal",
859
+ "decomposed": true,
860
+ "sub_groups": {
861
+ "group-1/sub-1": {
862
+ "scope": "src/a.ts, src/b.ts",
863
+ "internal_tasks": ["Task 1", "Task 2"],
864
+ "status": "in_progress"
865
+ },
866
+ "group-1/sub-2": {
867
+ "scope": "src/c.ts, src/d.ts",
868
+ "internal_tasks": ["Task 3", "Task 4"],
869
+ "status": "pending"
870
+ }
871
+ }
872
+ }
873
+ }
874
+ ```
706
875
  d. Group PHASE 2 - DEV:
707
876
  i. Construct phase delegation prompt:
708
877
  - Plan content, proposal links
@@ -755,8 +924,40 @@ ws-goal 执行 Phase-Level Sequential Dispatch 时遵循以下协议:
755
924
  iii. Main session verify:
756
925
  - Change branch merged to target_base_branch
757
926
  - Pushed to remote
758
- g. Update group status complete
759
- h. Update goal Progress Notes with group result
927
+ g. Recursive completion propagation (通用递归,不限于 sub-group):
928
+ i. Mark current node `status=complete`
929
+ ii. **Find next executable node** — depth-first traversal:
930
+ a. If current node is a leaf (no sub_groups) → check **next sibling** in parent's child list
931
+ b. If next sibling exists → set `status=in_progress`, `current_group` = sibling id
932
+ → Jump to step d (DEV phase)
933
+ c. If no next sibling → **propagate up**: parent complete → go to step ii-a with parent as current
934
+ d. If parent has no parent (back at root-level group list) → **check next root-level group**
935
+ → If found → step a (PLAN phase for next root group)
936
+ → If not found → all groups complete → go to step 4 (overall completion audit)
937
+ iii. **Container groups** (groups with sub_groups, never execute DEV themselves):
938
+ - A container group is marked `status=complete` **only** when all its children are complete
939
+ - The propagation in step ii-c automatically handles this: last child done → parent complete → check parent's sibling
940
+ iv. **Example propagation** (3-level nesting):
941
+ ```
942
+ root groups: [group-1, group-2, group-3]
943
+ group-3 children: [group-3/core, group-3/filter, group-3/history]
944
+ group-3/filter depends_on: [group-3/core]
945
+
946
+ Execution order:
947
+ 1. group-1 FINISH complete → step g
948
+ 2. check root sibling → group-2 → step a (PLAN)
949
+ 3. group-2 FINISH complete → step g
950
+ 4. check root sibling → group-3 → step a (PLAN)
951
+ 5. group-3 is container → skip → first leaf → group-3/core DEV
952
+ 6. group-3/core FINISH complete → step g
953
+ 7. leaf → check sibling → group-3/filter → DEV (depends on core, satisfied)
954
+ 8. group-3/filter FINISH complete → step g
955
+ 9. leaf → check sibling → group-3/history → DEV
956
+ 10. group-3/history FINISH complete → step g
957
+ 11. leaf → no sibling → propagate up: group-3 complete
958
+ 12. root sibling → none → all complete → step 4 audit
959
+ ```
960
+ h. Update goal Progress Notes with group result
760
961
  4. All groups complete:
761
962
  - Run overall completion audit (all verification + goal-level checks)
762
963
  - Update goal state → complete
@@ -925,6 +1126,241 @@ Goal (fully degraded):
925
1126
 
926
1127
  退出条件:同一 goal 中后续 group 未出现 §6.8.2 的 entry criteria,主 session 可选择恢复。
927
1128
 
1129
+ ### 6.9 Granularity Decomposition Protocol
1130
+
1131
+ #### 6.9.1 Motivation
1132
+
1133
+ §6.4 step c 将 Granularity Gate 从二进制 pass/block 门禁升级为三级分解机制。本协议定义了分解的具体流程、状态记录和子 group 生命周期,与 §6.4 step c 配合使用。
1134
+
1135
+ #### 6.9.2 Decomposition Flow
1136
+
1137
+ MARGINAL 自动分解执行流程(支持递归):
1138
+
1139
+ ```
1140
+ 1. 触发条件:叶子 group 通过 Granularity Gate 判定为 MARGINAL
1141
+ 2. 分解策略:
1142
+ a. 检测 scope 文件的模块边界(同目录前缀 → 同模块)
1143
+ b. 有清晰模块边界 → 按模块分组
1144
+ c. 无清晰边界(单目录多文件)→ 按文件数均分(≤3 files/sub-group)
1145
+ 3. OUTPUT: 子 group 列表
1146
+ - 每个子 group 包含:scope(≤3 files)、internal_tasks、verification(继承父级)、status
1147
+ - 子 group id = <parent-group-id>/sub-<N>
1148
+ 4. 每个子 group 递归进入 Granularity Gate(§6.4 step c-i)
1149
+ - COMPLIANT → 进入 DEV
1150
+ - MARGINAL → 继续分解,直到所有叶子为 COMPLIANT
1151
+ 5. 父 group 自动转为容器(pass-through),不执行自身 DEV
1152
+ ```
1153
+
1154
+ #### 6.9.3 Sub-Group Phase Execution
1155
+
1156
+ 每个子 group 独立执行完整的 DEV→REVIEW→FINISH 三阶段(**不**重新执行 PLAN,因为 decomposition 发生在 PLAN 之后):
1157
+
1158
+ ```
1159
+ 子 group 执行路径(跳过 PLAN):
1160
+ Granularity Gate passed (COMPLIANT)
1161
+ → PHASE 2 - DEV: 仅实现该子 group 的 internal_tasks
1162
+ → PHASE 3 - REVIEW: 审计该子 group 的改动
1163
+ → PHASE 4 - FINISH: 提交并合并该子 group 的改动
1164
+ ```
1165
+
1166
+ 设计原则:
1167
+ - **PLAN 只做一次**:整体 PLAN 在 decomposition 前已完成。子 group 不再重新规划,避免重复开销
1168
+ - **每个子 group 独立 DEV**:每个子 group 的改动范围 ≤3 文件,确保 DEV sub-agent 上下文可控
1169
+ - **有序合并**:子 group 按顺序执行 FINISH,每个 commit 聚焦一个子 group 的改动,降低 review 负担
1170
+ - **失败隔离**:一个子 group 失败不影响其他子 group。修复后只需重试该子 group
1171
+
1172
+ ```
1173
+ 整体时间线:
1174
+ PLAN (一次) → [sub-1: DEV → REVIEW → FINISH] → [sub-2: DEV → REVIEW → FINISH] → ...
1175
+ ```
1176
+
1177
+ #### 6.9.4 Sub-Group Dependency Within Same Parent
1178
+
1179
+ 同一父 group 的子 group 之间默认无依赖关系(所有 internal_tasks 在 PLAN 阶段已被认定为可独立执行)。
1180
+
1181
+ 例外处理:
1182
+ - 若 Granularity Gate 检测到子 group 间存在文件级依赖(如 sub-1 修改的文件被 sub-2 引用),自动添加 `depends_on`:
1183
+ - sub-2 `depends_on: [group-1/sub-1]`
1184
+ - 执行顺序自动调整为 sub-1 → sub-2
1185
+ - 文件级依赖检测方法:
1186
+ - 检查子 group scope 中的文件是否存在 import/reference 交叉
1187
+ - 若无法自动检测(非结构化 scope 描述)→ 按声明顺序执行(安全默认)
1188
+
1189
+ #### 6.9.5 State.json 更新规则
1190
+
1191
+ 子 group 的 checkpoint 在 state.json 中独立记录:
1192
+
1193
+ ```json
1194
+ {
1195
+ "goal_id": "refactor-pages",
1196
+ "current_phase": "dev",
1197
+ "current_group": "group-2/sub-1",
1198
+ "checkpoints": {
1199
+ "intake": { "status": "complete", "attempts": 0, "completed_at": "2026-07-16T...", "error": null },
1200
+ "goal_def": { "status": "complete", ... },
1201
+ "dep_check": { "status": "complete", ... },
1202
+ "ws_analysis": { "status": "complete", ... },
1203
+ "plan": { "status": "complete", ... },
1204
+ "dev": { "status": "in_progress", "attempts": 0, "completed_at": null, "error": null },
1205
+ "review": { "status": "pending", ... },
1206
+ "finish": { "status": "pending", ... }
1207
+ },
1208
+ "groups": {
1209
+ "group-1": {
1210
+ "status": "complete",
1211
+ "granularity_assessment": "compliant",
1212
+ "decomposed": false
1213
+ },
1214
+ "group-2": {
1215
+ "status": "in_progress",
1216
+ "granularity_assessment": "marginal",
1217
+ "decomposed": true,
1218
+ "sub_groups": {
1219
+ "group-2/sub-1": {
1220
+ "scope": "cart.tsx, checkout.tsx",
1221
+ "internal_tasks": ["Refactor cart context", "Add shipping form"],
1222
+ "status": "in_progress"
1223
+ },
1224
+ "group-2/sub-2": {
1225
+ "scope": "payment-form.tsx, order-history.tsx",
1226
+ "internal_tasks": ["Card validation", "Order history page"],
1227
+ "status": "pending"
1228
+ }
1229
+ }
1230
+ }
1231
+ }
1232
+ }
1233
+ ```
1234
+
1235
+ #### 6.9.6 Sub-Group and Degraded Mode Interaction
1236
+
1237
+ 子 group 也可以进入降级模式(§6.8):
1238
+
1239
+ - 子 group 的 entry criteria 和降级判定**独立于**父 group 和其他子 group
1240
+ - 一个子 group 进入降级模式不影响同父的其他子 group
1241
+ - 子 group 降级后,degraded-batch.md 记录在 `changes/<id>/patches/degraded-batch-<group-id>-sub-<N>.md`
1242
+ - 降级证据中的涉 group 列表改为涉子 group 路径(如 `group-2/sub-1`)
1243
+
1244
+ #### 6.9.7 Backward Compatibility (Updated)
1245
+
1246
+ | 现有 goal 配置 | 兼容性 |
1247
+ |---|---|
1248
+ | 含 `granularity_ok: true` 的 group | 兼容。Granularity Gate 读到该字段时降级为 COMPLIANT 处理,直接进入 DEV |
1249
+ | 含 `granularity_ok: false` 的 group | 兼容。读到该字段时降级为 MARGINAL(自动分解),不再阻断 |
1250
+ | 不含 `granularity_ok` 的 group(新格式) | 正常模式。Gate 按 scope/internal_tasks 自动计算三级评估 |
1251
+ | 无 groups 定义的 goal(单 group 模式) | 不受影响。Granularity Gate 仍对隐式 group 执行三级评估 |
1252
+ | 含 `sub_groups` 的 group(递归嵌套新格式) | 新增。Gate 跳过容器 group,递归验证叶子节点;自动升级到递归完成传播 |
1253
+
1254
+ #### 6.9.8 Recursive Nested Execution
1255
+
1256
+ **动机**:§6.4 step c 和 §6.9 的原始设计只支持一层 `group → sub-group` 的自动分解。但用户可能在 goal 定义时已经有一个自然的层级组织(如模块→子模块→文件),需要直接表达为嵌套结构,而不是等 Gate 拆平。
1257
+
1258
+ **方案**:group 的 `sub_groups` 字段递归 —— 任何 group 都可以包含 sub_groups,sub_groups 的成员也可以包含自己的 sub_groups,层层嵌套。深度不限。
1259
+
1260
+ ##### 执行规则
1261
+
1262
+ ```
1263
+ 1. 容器 group(有 sub_groups):不执行自己的 PLAN/DEV/REVIEW/FINISH
1264
+ - 它的 scope 只是描述性汇总,不作为 DEV 粒度依据
1265
+ - 它的 verification 是整体验收,在所有叶子完成后执行(不作为子 group 门禁)
1266
+
1267
+ 2. 叶子 group(无 sub_groups):正常执行 PLAN→DEV→REVIEW→FINISH
1268
+ - 叶子是实际的执行单元
1269
+ - Granularity Gate 只对叶子执行三级评估
1270
+
1271
+ 3. 中间 group(有 sub_groups,自己也是父级的 children):
1272
+ - 既是父级的 children,也是子级的 container
1273
+ - 不执行 DEV,但负责 propagate 完成状态
1274
+ - 状态流转:所有 children complete → 中间 group complete → propagate 给父级
1275
+
1276
+ 4. 递归执行入口:
1277
+ - 根层 FOR each group in topological order → 如果是容器 → 不 PLAN,直接找第一个叶子
1278
+ - 叶子走正常 PLAN→DEV→REVIEW→FINISH
1279
+ - 完成时 step g 递归 propagate
1280
+ ```
1281
+
1282
+ ##### 执行示例(3 层嵌套)
1283
+
1284
+ ```
1285
+ goal:
1286
+ group-A: 容器
1287
+ group-A/sub-1: 叶子 → PLAN→DEV→REVIEW→FINISH → complete → propagate
1288
+ group-A/sub-2: 容器(中间节点)
1289
+ group-A/sub-2/a: 叶子 → PLAN→DEV→REVIEW→FINISH → complete
1290
+ group-A/sub-2/b: 叶子 → 依赖 sub-2/a → 在其后执行
1291
+ # sub-2 的 children 全部 complete → sub-2 complete → 继续 propagate
1292
+ group-B: 叶子 → 正常执行
1293
+ ```
1294
+
1295
+ ##### 与自动分解的关系
1296
+
1297
+ 两种分解路径共存,在执行层收敛:
1298
+
1299
+ ```
1300
+ 用户手工嵌套 Granularity Gate 自动分解
1301
+ (group 含 sub_groups) (叶子 group 不含 sub_groups)
1302
+ │ │
1303
+ └──────────┬──────────────┘
1304
+
1305
+ 递归验证叶子粒度
1306
+ 容器 group 跳过
1307
+
1308
+
1309
+ 叶子走 DEV→REVIEW→FINISH
1310
+ 完成时递归 propagate
1311
+
1312
+
1313
+ 全部 complete → 整体审计
1314
+ ```
1315
+
1316
+ - 用户手工嵌套的 group,Gate **跳过**粒度评估(假设用户已合理拆分)
1317
+ - 仅对**叶子**做 COMPLIANT/MARGINAL 二级评估
1318
+ - MARGINAL 叶子可以进一步自动拆 sub-sub-group(递归)
1319
+ - 两种路径从执行层开始统一,叶子执行路径完全相同
1320
+
1321
+ ##### State.json 递归表示
1322
+
1323
+ ```json
1324
+ {
1325
+ "groups": {
1326
+ "group-A": {
1327
+ "status": "complete",
1328
+ "sub_groups": {
1329
+ "group-A/sub-1": {
1330
+ "status": "complete",
1331
+ "granularity_assessment": "compliant"
1332
+ },
1333
+ "group-A/sub-2": {
1334
+ "status": "complete",
1335
+ "sub_groups": {
1336
+ "group-A/sub-2/a": { "status": "complete" },
1337
+ "group-A/sub-2/b": { "status": "complete" }
1338
+ }
1339
+ }
1340
+ }
1341
+ },
1342
+ "group-B": {
1343
+ "status": "in_progress",
1344
+ "granularity_assessment": "compliant"
1345
+ }
1346
+ }
1347
+ }
1348
+ ```
1349
+
1350
+ ##### Auto-Advance 保证
1351
+
1352
+ 递归嵌套下的自动推进由 §6.4 step g(递归完成传播)保证,不需要额外配置:
1353
+
1354
+ | 事件 | 自动推进行为 |
1355
+ |------|------------|
1356
+ | 叶子 group FINISH 完成 | step g 自动检查兄弟 → 无则 propagate 父级 → 检查父级兄弟 → 持续到根 |
1357
+ | 中间节点所有 children 完成 | 自动标记 complete → propagate 给父级 |
1358
+ | 根层 group 完成 | 自动检查下一个根层 group → 进入其 PLAN (如果是叶子) 或递归找其第一个叶子 |
1359
+ | 所有 group 完成 | 触发整体 completion audit(§6.5) |
1360
+ | 叶子 Granularity Gate 发现 MARGINAL | 自动拆 sub-group,递归执行,同一套 propagate 机制 |
1361
+
1362
+ **保证**:一旦 DEV 开始,在整体审计前不需要任何人干预。递归嵌套 + 自动分解处理任意 scope 大小。无阻断点。
1363
+
928
1364
  ## 7. Persistence & Resume
929
1365
 
930
1366
  ### 7.1 Motivation & Gap Analysis
@@ -1067,10 +1503,42 @@ Instructions: Continue from the failed phase. Do NOT redo completed phases.
1067
1503
  3. 如果 status 为 complete 或 archived:
1068
1504
  - 不生成 state.json(不需要恢复)
1069
1505
 
1070
- ### 7.7 Limitations
1506
+ ### 7.7 State.json 生命周期管理
1507
+
1508
+ #### 7.7.1 原子写入协议
1509
+
1510
+ 所有 state.json 写入必须使用原子写入模式,防止进程崩溃导致文件损坏:
1511
+
1512
+ ```shell
1513
+ # 写入流程:
1514
+ 1. 构建完整 state.json 内容到内存
1515
+ 2. 序列化为 JSON 字符串
1516
+ 3. 写入临时文件: cat > ".aiws/goals/<goal-id>.state.json.tmp"
1517
+ 4. 原子重命名: mv ".aiws/goals/<goal-id>.state.json.tmp" ".aiws/goals/<goal-id>.state.json"
1518
+ ```
1519
+
1520
+ **规则**:
1521
+ - 从不直接原地编辑 state.json
1522
+ - 从不使用多步写入(如 write→read→write 循环)
1523
+ - 每次写入必须是一次完整的 JSON 对象替换
1524
+ - 临时文件与目标文件在同一文件系统(同一目录),保证 `mv` 原子性
1071
1525
 
1072
- - state.json 是当前工作区本地文件,不支持跨设备同步
1073
- - 如果用户手动删除或修改 state.json,ws-goal 降级为全量重跑(可重新生成)
1526
+ #### 7.7.2 损坏检测与恢复
1527
+
1528
+ 读取 state.json 时执行以下检测:
1529
+
1530
+ | 检测项 | 行为 |
1531
+ |--------|------|
1532
+ | 文件不存在 | 按 §7.7.3 处理 |
1533
+ | JSON 解析失败(语法错误) | 视为损坏,降级为全量重跑,输出警告"state.json 损坏,已忽略" |
1534
+ | JSON 结构校验失败(缺少必填字段) | 尝试修补默认值,若不可修补则降级为全量重跑 |
1535
+ | 多个 checkpoint 同时 in_progress | 阻断,输出诊断报告,要求手动修复 |
1536
+ | **状态机跃迁非法**(如从 `plan` 跳到 `finish` 跳过 `dev`)| 自动修复:重置所有后续 phase 为 `pending`,输出警告 |
1537
+
1538
+ #### 7.7.3 恢复策略
1539
+
1540
+ - 如果用户手动删除或修改 state.json,ws-goal 降级为全量重跑(从 PHASE 0 开始,可重新生成)
1541
+ - 如果 state.json 损坏且无法修复,ws-goal 降级为暂停,输出恢复指引,等待主 session 检查 goal .md 文件的 Progress Notes 手动判断下一步
1074
1542
  - 并行执行多个 goal 时,state.json 独立管理,互不依赖
1075
1543
  - state.json 不包含 secrets 或凭证信息
1076
1544
 
@@ -1083,12 +1551,14 @@ Instructions: Continue from the failed phase. Do NOT redo completed phases.
1083
1551
  当前协议依赖主 session 在 phase 完成后手动判断"已完成 phase X,现在开始 phase Y"。这个判断是纯机械的,每次都重复一样逻辑。Auto-Advance 将此机械工作自动化,减少阶段转换摩擦。
1084
1552
 
1085
1553
  **覆盖范围**:Auto-Advance 适用于完整 phase 生命周期,不仅限于 pipeline 内部的 PLAN→DEV→REVIEW→FINISH 阶段间推进。它同样适用于:
1086
- - INTAKE → GOAL_DEF(intake UNRESOLVED_BRANCH 时自动推进)
1554
+ - INTAKE → GOAL_DEF(intake 完成后自动推进。Scope Advisory(§6.2.5)是 intake 的正常对话部分,用户确认后自动继续,不视为阻断)
1087
1555
  - GOAL_DEF → DEP_CHECK(goal 定义完成后自动进入依赖链预检)
1088
1556
  - DEP_CHECK → WS_ANALYSIS(依赖链通过后自动进入工作区分析)
1089
- - WS_ANALYSIS → PLAN(工作区分析无 HIGH 阻断项时自动进入 PLAN)
1557
+ - WS_ANALYSIS → PLAN(工作区 HIGH 自动解决后自动进入 PLAN)
1558
+
1559
+ **所有 phase 边界均自动推进**。不应询问用户。INTAKE 问问题和 scope advisory 是正常流程(不是阻断);工作区问题自动解决(§2.5.4);scope 拆分的 OVERLOAD 在 INTAKE 阶段由 Scope Advisory 处理(§6.2.5),不延迟到 Granularity Gate;PLAN 多分支按序全部执行;依赖链 UNHEALTHY 是唯一硬阻断(§2.4.3),用户需修复上游或改 base_branch 才能继续,不提供"确认放行"选项。
1090
1560
 
1091
- 唯一需要人工确认的 phase 转换:**当前 phase 存在真实阻断项时**(UNRESOLVED_BRANCH、依赖链 UNHEALTHY、工作区分析 HIGH、PLAN 多分支无明确推荐)。这些阻断必须由 §2.5.4、§2.4.3 §7.9.2 的规则产生,不得在无阻断时额外询问用户。
1561
+ **CLI 编码**:此章节描述的自动推进决策逻辑由 `aiws goal advance` CLI 命令实现(§10)。CLI 读取 state.json,执行状态机校验,计算下一个 phase/group,然后写入更新后的 state.json。pre-commit hook 在每次提交时调用 `aiws goal validate-state` 校验 state.json 一致性。不再依赖 AI 对自然语言描述的理解来推导"下一步去哪"。
1092
1562
 
1093
1563
  #### 7.8.2 Mechanism
1094
1564
 
@@ -1112,6 +1582,11 @@ phase 完成 → checkpoint status=complete(写入 state.json)
1112
1582
  Current phase in_progress:
1113
1583
  1. Sub-agent completes current phase → main session 验证通过
1114
1584
  2. Main session 更新 checkpoint → status=complete + timestamp
1585
+ 2.5. **Budget check**(在推进前检查预算):
1586
+ a. 读取 goal 的 `token_budget` 和 `time_budget`(§3.4),与当前已消耗值比较
1587
+ b. 如果 token 或 time 预算耗尽 → `status=budget_limited`,生成进度报告,**停止**推进
1588
+ c. 如果预算未耗尽 → 进入 step 3
1589
+ d. 预算检查适用于所有 phase 边界(包括递归嵌套的子组推进)
1115
1590
  3. Main session 扫描 state.json checkpoints:
1116
1591
  a. 找到第一个 status=pending 且「所有依赖的 group phase 已 complete」的 checkpoint
1117
1592
  b. 若找到 → 设置 current_phase, current_group,checkpoint status=in_progress
@@ -1192,19 +1667,25 @@ Auto-Advance 在降级模式下仍然适用,但推进逻辑调整:
1192
1667
 
1193
1668
  #### 7.9.1 Motivation
1194
1669
 
1195
- 某些决策点(如 PLAN 产出后的多分支选择)需要业务判断,不能完全自动化。但是,当前模式要求用户从原始计划产出中自行推导选项和权衡,认知负担高。
1670
+ 某些决策点需要业务判断,不能完全自动化。但 ws-goal 的默认策略是:**能自动走的就不停**。只在两种情况下才需要用户决策:
1671
+ - 选项**互斥**(选择了 A 就不能选择 B)
1672
+ - ws-goal 自动处理失败(如工作区修复、分解方案估算)
1673
+
1674
+ 不在非互斥场景下询问用户"先做哪个"——所有非互斥路径按序全部执行。
1196
1675
 
1197
- **原则**:AI 做分析、结构化和建议,用户做决策。不在无阻断时提问,但在真正需要判断时提供预处理的选项。
1676
+ **原则**:AI 做分析、结构化和建议,用户做决策。但仅当路径真正互斥时才需要决策。
1198
1677
 
1199
1678
  #### 7.9.2 触发条件
1200
1679
 
1201
- 结构化决策支持适用于以下场景:
1680
+ 结构化决策支持适用于以下场景(**仅互斥路径**):
1202
1681
 
1203
- | 场景 | 产出物 | 说明 |
1204
- |------|--------|------|
1205
- | **PLAN 多分支选择** | PLAN 产出包含多个可行路径 | 如"Phase1&2 vs Phase3 vs P0 stub" |
1206
- | **修复方案选择** | 同一问题有多种修复方式 | 如"回滚 vs 热修复 vs 临时规避" |
1207
- | **优先级排序** | 多个独立任务需决定执行顺序 | "先修高风险 bug vs 先加固测试" |
1682
+ | 场景 | 产出物 | 说明 | 是否阻断 |
1683
+ |------|--------|------|---------|
1684
+ | **修复方案选择** | 同一问题有多种修复方式 | 如"回滚 vs 热修复 vs 临时规避" | 互斥,需用户选择 |
1685
+ | ~~Granularity OVERLOAD~~ | | 已移除:递归嵌套自动分解处理任意 scope 大小,不再需要用户确认 | 不再视为决策点 |
1686
+ | ~~依赖链 UNHEALTHY~~ | | 已移除:硬阻断,不提供"确认放行"选项,必须修复上游 | 非决策点 |
1687
+ | ~~PLAN 多分支选择~~ | — | 已移除:PLAN 产出所有路径按序执行 | ❌ 不再视为决策点 |
1688
+ | ~~优先级排序~~ | — | 已移除:多个独立 task 按声明顺序执行 | ❌ 不再视为决策点 |
1208
1689
 
1209
1690
  #### 7.9.3 输出格式
1210
1691
 
@@ -1255,9 +1736,9 @@ Oracle-Advisor 是一个可选的协议角色,用于在决策点提供分析
1255
1736
  |--------|---------|----------------|
1256
1737
  | Intake → Plan 转换 | ✅ 自动(无阻断时) | 无需 Oracle |
1257
1738
  | 工作区分析 LOW/MED | ✅ 自动(§2.5.4) | 无需 Oracle |
1258
- | 工作区分析 HIGH | 用户确认 | Oracle 可辅助分析 HIGH 项是否可降级 |
1259
- | 依赖链 UNHEALTHY | 用户确认(§2.4.3) | Oracle 可分析 UNHEALTHY 的实际影响范围 |
1260
- | PLAN 多分支选择 | 用户决策(§7.9) | **Oracle 生成结构化建议块(§7.9.3)** |
1739
+ | 工作区分析 HIGH | 自动解决(§2.5.4) | Oracle 仅在自动修复失败时辅助分析 |
1740
+ | 依赖链 UNHEALTHY | 🚫 硬阻断(§2.4.3) | Oracle 可分析 UNHEALTHY 的影响范围及修复方案 |
1741
+ | ~~PLAN 多分支选择~~ | 全部执行(§7.9.2) | 无需 Oracle |
1261
1742
  | 阶段间推进 | ✅ Auto-Advance(§7.8) | 无需 Oracle |
1262
1743
 
1263
1744
  #### 7.10.3 角色约束
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aipper/aiws-spec",
3
- "version": "0.0.45",
3
+ "version": "0.0.47",
4
4
  "description": "AIWS spec and templates (single source of truth).",
5
5
  "type": "module",
6
6
  "files": [
@@ -31,6 +31,15 @@ fi
31
31
 
32
32
  "$aiws_bin" validate .
33
33
 
34
+ # Goal state integrity check (blocking if errors)
35
+ if [[ -d "$root/.aiws/goals" ]]; then
36
+ if ! "$aiws_bin" goal validate-state >/dev/null 2>&1; then
37
+ echo "error: goal state validation failed — state machine integrity check" >&2
38
+ echo "hint: run 'aiws goal validate-state' to see details" >&2
39
+ exit 1
40
+ fi
41
+ fi
42
+
34
43
  # Quality gates (non-blocking warnings)
35
44
  if [[ -f "package.json" ]] && grep -q '"lint"' package.json 2>/dev/null; then
36
45
  npm run lint >/dev/null 2>&1 || echo "warn: lint found issues (non-blocking)" >&2
@@ -31,6 +31,20 @@ ws-goal 只做三件事,不做更多:
31
31
  - 若发现 status=active 或 status=paused 的 state.json,输出恢复选项(从失败的 phase 继续 / 跳过 / handoff)
32
32
  - 用户选择后设置 current_phase 到对应 phase 并继续执行
33
33
  c) 若未找到 state.json 但有 status=active 或 status=paused 的 .md 文件(旧格式迁移),按 §7.6 自动生成 state.json 后全量重跑
34
+ d) 若发现 status=complete 的 state.json 但 checkpoints 中仍有未完成项(status != complete):
35
+ - 读取对应 `.aiws/goals/<goal-id>.md` 文件,输出 goal 摘要
36
+ - 列出所有未完成的 checkpoints(status=in_progress/pending/failed 的项)
37
+ - 输出续跑选项:
38
+ - (a)跳过 PHASE 0,从依赖链预检(step 4)恢复执行
39
+ 自动跳过 step 1-3(真值读取/目标输入/文件生成),使用已有 goal 文件
40
+ - (b)查看 goal 详情
41
+ - (c)忽略,按新目标处理
42
+ - 若用户选择 a):
43
+ - 设置 state.json:status=active,current_phase 到最近一个未完成 checkpoint 对应 phase
44
+ - 输出"跳过 PHASE 0,从 step 4 依赖链预检恢复"
45
+ - 直接进入 step 4 继续执行
46
+ - 若用户选择 b):输出完整 goal 详情后回到选项
47
+ - 若用户选择 c):作为新目标正常走 step 0→1→2 完整流程
34
48
 
35
49
  1) 读取真值文件(`AI_PROJECT.md`、`REQUIREMENTS.md`、`AI_WORKSPACE.md`),确认项目规则与边界。
36
50
 
@@ -0,0 +1,285 @@
1
+ ---
2
+ description: 目标协议:设定可审计的 goal 目标;依赖链预检;完成审计
3
+ ---
4
+ <!-- AIWS_MANAGED_BEGIN:opencode:ws-goal -->
5
+ # ws goal
6
+
7
+ 用中文输出(命令/路径/代码标识符保持原样不翻译)。
8
+
9
+ ## 职责边界
10
+
11
+ ws-goal 只做三件事,不做更多:
12
+
13
+ | 做 | 不做 |
14
+ |---|---|---|
15
+ | 录入目标(写 `.aiws/goals/<id>.md`) | 直接在 main session 创建/驱动 change(通过 pipeline subagent 委托执行) |
16
+ | 依赖链预检(上游死 change → 阻断) | 评估复杂度、路由执行路径 |
17
+ | 完成审计(claim done 时验证 outcome) | git add/commit/push、finish |
18
+ | 记录 target_base_branch 约束 | auto-chain 到下一个 goal(但在同一 goal 内支持多组顺序调度 §6) |
19
+
20
+ 超出以上范围的需求,路由到对应 ws-* 技能,ws-goal 不碰。
21
+
22
+ ## 前置条件
23
+
24
+ 1) 先运行 `/ws-preflight`(对齐 `AI_PROJECT.md` / `REQUIREMENTS.md` / `AI_WORKSPACE.md`)。
25
+
26
+ ## 执行流程
27
+
28
+ 0) 检查 `.aiws/goals/` 目录(先扫描 `.state.json`,再扫描 `.md`):
29
+ a) 若用户仅查询状态(无明确目标),列出所有 goal 文件及其 status 字段,然后结束。
30
+ b) 扫描 `.aiws/goals/*.state.json`:
31
+ - 若发现 status=active 或 status=paused 的 state.json,输出恢复选项(从失败的 phase 继续 / 跳过 / handoff)
32
+ - 用户选择后设置 current_phase 到对应 phase 并继续执行
33
+ c) 若未找到 state.json 但有 status=active 或 status=paused 的 .md 文件(旧格式迁移),按 §7.6 自动生成 state.json 后全量重跑
34
+ d) 若发现 status=complete 的 state.json 但 checkpoints 中仍有未完成项(status != complete):
35
+ - 读取对应 `.aiws/goals/<goal-id>.md` 文件,输出 goal 摘要
36
+ - 列出所有未完成的 checkpoints(status=in_progress/pending/failed 的项)
37
+ - 输出续跑选项:
38
+ - (a)跳过 PHASE 0,从依赖链预检(step 4)恢复执行
39
+ 自动跳过 step 1-3(真值读取/目标输入/文件生成),使用已有 goal 文件
40
+ - (b)查看 goal 详情
41
+ - (c)忽略,按新目标处理
42
+ - 若用户选择 a):
43
+ - 设置 state.json:status=active,current_phase 到最近一个未完成 checkpoint 对应 phase
44
+ - 输出"跳过 PHASE 0,从 step 4 依赖链预检恢复"
45
+ - 直接进入 step 4 继续执行
46
+ - 若用户选择 b):输出完整 goal 详情后回到选项
47
+ - 若用户选择 c):作为新目标正常走 step 0→1→2 完整流程
48
+
49
+ 1) 读取真值文件(`AI_PROJECT.md`、`REQUIREMENTS.md`、`AI_WORKSPACE.md`),确认项目规则与边界。
50
+
51
+ 2) 接受用户输入的 goal objective,明确目标范围与验收标准。
52
+
53
+ 3) 按 ws-goal-contract.md 的目标模板生成目标文件,写入 `.aiws/goals/<goal-id>.md`。
54
+ 并同时创建 `.aiws/goals/<goal-id>.state.json`(§7.2 格式),初始状态 `status=active`、`current_phase=intake`、所有 checkpoints pending。
55
+ a) 生成时填入 `Target Base Branch` 字段:
56
+ - `target_base_branch`:从当前分支追踪或用户声明确定。默认 `main`
57
+ - `base_branch_mismatch_action`:默认 `block`
58
+ b) 生成时填入初始 `Dependency Chain` 字段:
59
+ - `base_branch`:当前检出分支或用户指定的基分支
60
+ - `chain`:追溯完整的 change 链到 main
61
+ - `chain_verified_at`:当前时间
62
+ - `user_confirmed_unhealthy`:初始为 null
63
+
64
+ 4) **Dependency Chain Validation**:上游依赖链健康检查(不创建任何 change/plan/commit)。
65
+ a) 确定 base_branch:
66
+ - 若当前已存在 change 分支,读取 `.ws-change.json` 或 proposal.md 的 `base_branch`
67
+ - 若用户显式指定 base_branch,以用户指定为准
68
+ - 否则默认 main
69
+ a1) **target_base_branch 一致性检查**(Rule C):
70
+ - 读取 goal 文件的 `Target Base Branch.target_base_branch`
71
+ - 若 `base_branch != target_base_branch`:
72
+ - 输出 "goal 声明 target_base_branch = X,但当前 base_branch = Y"
73
+ - 若 `base_branch_mismatch_action` 为 `block`(默认):**强制 blocker**,必须用户修正 base_branch 或显式确认 mismatch 才能继续
74
+ - 若为 `warn`:输出警告并允许继续
75
+ - 将 mismatch 记录到 goal 文件的 Audit Trail
76
+ - 若一致:继续 step b
77
+ b) 追溯 chain:从 base_branch 逐级向上追溯到 main
78
+ - 每级检查 `.ws-change.json` 的 `base_branch` 或 git 分支关系
79
+ - 若无法追溯(孤儿分支),标记 UNKNOWN 并输出警告
80
+ c) 对 chain 中每个 link 做健康检查(按 ws-goal-contract.md 2.4.2 标准):
81
+ - artifacts 完整性:proposal/tasks/design 是否存在
82
+ - task 完成率:WS:TODO 占比
83
+ - review 状态:是否有 HIGH blocker
84
+ - 活跃度:最后更新时间
85
+ - truth drift:`aiws validate .` 是否通过
86
+ d) 结果:
87
+ - ALL HEALTHY → 输出 "依赖链健康" 并继续
88
+ - 存在 STALE → 输出链拓扑 + 警告,允许继续
89
+ - 存在 UNHEALTHY → 输出完整 chain 拓扑 + 每级健康报告,**强制 blocker**,必须用户显式确认才能继续
90
+ - UNKNOWN(无法追溯)→ 输出警告"无法验证上游依赖链",不阻断但要求用户确认
91
+ e) 将验证结果写入 goal 文件的 `Dependency Chain` 字段:
92
+ - 更新 `chain` 中每个 link 的健康状态与判定理由
93
+ - 若用户放行 UNHEALTHY:设置 `user_confirmed_unhealthy: true` 并记录到 `Audit Trail`
94
+ - 若用户未放行:设置 goal status=paused 并结束
95
+
96
+ 4.5) **Workspace State Analysis**:依赖链预检通过后、delegation 前,分析工作区状态并输出报告。
97
+ 必须用户确认后才能进入 step 5。
98
+ a) 检查 dirty 状态:
99
+ - staged changes(`git diff --cached --stat`)
100
+ - unstaged changes(`git diff --stat`)
101
+ - untracked files(`git status --porcelain` 中 `??` 开头项)
102
+ b) 检查 submodule 状态:
103
+ - 每个 submodule 的 dirty 状态(`git submodule status`)
104
+ - detached HEAD(`git -C <path> symbolic-ref HEAD` 失败)
105
+ - unpushed 提交(`git -C <path> log @{u}..HEAD --oneline`)
106
+ c) 检查 change artifacts:
107
+ - 存在哪些 change 分支(`git branch --list 'change/*'`)
108
+ - 是否有未完成的 change(proposal/tasks 仍含 WS:TODO)
109
+ - 是否与当前 goal 冲突(同名、同域)
110
+ d) 检查 git 状态:
111
+ - 是否有 unpushed 提交(`git log @{u}..HEAD --oneline`)
112
+ - 是否有 stash(`git stash list`)
113
+ e) 评估影响:逐项判断与当前 goal 的关联度:
114
+ - HIGH:阻碍 goal 执行,必须处理
115
+ - MED:可能干扰或产生误报
116
+ - LOW:无影响,仅提示
117
+ - NONE:完全无关,忽略
118
+ f) 输出结构化分析报告:
119
+ 用格式化的文本块输出,每行标注影响等级:
120
+ ```
121
+ ═══ 工作区状态报告 ═══
122
+ [HIGH] 子模块 web/ dirty(7 文件)— 与 goal 同一目录,可能干扰
123
+ [MED] 旧 change contract-ai-rag 残留 — 可能干扰依赖链判断
124
+ [LOW] .aiws/journal/ 日志文件 — 无影响
125
+ ════════════════════════
126
+ ```
127
+ g) 展示报告后要求用户选择:
128
+ - **继续** → 更新 state.json checkpoint `ws_analysis=complete`,进入 step 5
129
+ - **暂停** → state.json status=paused,报告写入 Audit Trail,结束
130
+ - **先清理** → state.json status=paused,输出清理建议步骤,结束
131
+ 用户未确认前,不得进入 step 5。
132
+
133
+ 5) **Phase-Level Pipeline Delegation**:依赖链预检 + workspace 分析通过后,将 goal 拆分为 PLAN→DEV→REVIEW→FINISH 四个 phase 顺序执行,每个 phase 委托给独立轻量子 agent,主 session 验证每个 phase 产出后决定继续/重试/暂停。
134
+ 前置条件:step 4 必须通过(ALL HEALTHY 或 UNHEALTHY 已显式放行)。若 step 4 阻断,不允许 delegation。
135
+ 前置条件 2:不存在 status=active 的 change 分支。若有,让用户选择「使用已有 change 继续」或「暂停」。
136
+ 前置条件 3:每个 pipeline phase 开始前更新 state.json `current_phase` + checkpoint `status=in_progress`;完成/失败后对应更新 checkpoint。
137
+
138
+ 5a) **Check for Groups**:读取 goal 文件,检查是否定义了 `Groups` 区域。
139
+ - 若 goal **不含** groups → 走单组 phase-level pipeline(step 5b-5g)
140
+ - 若 goal **包含** groups → 走 Sequential Group Phase-Level Dispatch(step 5.1)
141
+
142
+ --- 以下为 phase-level pipeline(无 groups 的 goal) ---
143
+
144
+ 5b) **Phase-Level Sequential Execution**:主 session 按 PLAN→DEV→REVIEW→FINISH 顺序执行 4 个 phase,每个 phase 前检查当前进度(支持断点续跑)。共用一个 change 分支,change id = goal-id。
145
+
146
+ 5c) **PHASE 1 - PLAN**(主 session 执行 change start + 委托子 agent 做 plan):
147
+ 1. 主 session 执行 `aiws change start <goal-id> --allow-dirty`(若 change 已存在则跳过)
148
+ 2. 委托子 agent 执行 PLAN phase:
149
+ ```
150
+ task(
151
+ category="unspecified-high",
152
+ description="PLAN phase for goal <goal-id>",
153
+ prompt="TASK: Write proposal.md + plan file + run plan-verify for goal <goal-id>.
154
+ INPUT: goal file at .aiws/goals/<goal-id>.md, truth files at AI_PROJECT.md/REQUIREMENTS.md/AI_WORKSPACE.md.
155
+ CONSTRAINTS: Do NOT implement code. Do NOT do review. Do NOT commit.
156
+ COMPLETION: proposal.md exists, plan file exists, plan-verify passes."
157
+ )
158
+ ```
159
+ 3. 主 session 验证产出:
160
+ - proposal.md 文件存在
161
+ - plan 文件存在
162
+ - plan-verify 通过
163
+ 4. 验证通过 → 进入 PHASE 2
164
+ 5. 验证失败 → 可重试最多 2 次 → 仍失败则 goal state=paused,记录 blocker
165
+
166
+ 5d) **PHASE 2 - DEV**(委托子 agent 做 dev):
167
+ 1. 委托子 agent 执行 DEV phase:
168
+ ```
169
+ task(
170
+ category="deep",
171
+ description="DEV phase for goal <goal-id>",
172
+ prompt="TASK: Implement all code changes per plan for goal <goal-id>.
173
+ INPUT: proposal.md at .aiws/changes/<goal-id>/proposal.md, plan file.
174
+ CONSTRAINTS: Do NOT modify proposal or plan files. Do NOT commit.
175
+ COMPLETION: All changes implemented, lint/typecheck clean."
176
+ )
177
+ ```
178
+ 2. 主 session 验证产出:
179
+ - diagnostics 干净(`lsp_diagnostics` 检查改动文件)
180
+ - 改动范围与 plan 一致
181
+ 3. 验证通过 → 进入 PHASE 3
182
+ 4. 验证失败 → goal state=paused,记录 blocker
183
+
184
+ 5e) **PHASE 3 - REVIEW**(委托子 agent 做 review):
185
+ 1. 委托子 agent 执行 REVIEW phase:
186
+ ```
187
+ task(
188
+ category="unspecified-high",
189
+ load_skills=["review-work"],
190
+ description="REVIEW phase for goal <goal-id>",
191
+ prompt="TASK: Audit code changes for goal <goal-id>, produce review evidence.
192
+ INPUT: proposal.md, plan file, changed files.
193
+ CONSTRAINTS: Do NOT modify code. Do NOT commit.
194
+ COMPLETION: Review evidence files exist, no HIGH blockers."
195
+ )
196
+ ```
197
+ 2. 主 session 验证产出:
198
+ - review 证据文件存在
199
+ - 无未解决的 HIGH blocker
200
+ 3. 验证通过 → 进入 PHASE 4
201
+ 4. 验证失败 → goal state=paused,记录 blocker
202
+
203
+ 5f) **PHASE 4 - FINISH**(委托子 agent 做 commit + finish):
204
+ 1. 委托子 agent 执行 FINISH phase:
205
+ ```
206
+ task(
207
+ category="quick",
208
+ load_skills=["git-master"],
209
+ description="FINISH phase for goal <goal-id>",
210
+ prompt="TASK: Commit and finish (merge + push) for goal <goal-id> change branch.
211
+ CONSTRAINTS: Do NOT modify code. Git operations only.
212
+ COMPLETION: Change branch merged to target_base_branch and pushed."
213
+ )
214
+ ```
215
+ 2. 主 session 验证产出:
216
+ - 确认 change 分支已合并到 target_base_branch
217
+ - 确认已推送
218
+ 3. 验证通过 → goal state=complete,输出 "Goal <goal-id> complete"
219
+ 4. 验证失败 → goal state=paused,记录 blocker
220
+
221
+ 5g) **Simple Goal Escape Hatch**:若 goal 为简单改动(≤3 文件,配置/doc/规范变更,无架构风险):
222
+ - 可跳过 PHASE 3(REVIEW),在 PHASE 2 验证后直接进入 PHASE 4
223
+ - 必须在 goal 文件的 Progress Notes 标注 "skipped review phase (simple goal)"
224
+
225
+ --- 以下为 Sequential Group Phase-Level Dispatch(含 groups 的 goal) ---
226
+
227
+ 5.1) **Sequential Group Phase-Level Dispatch**:
228
+ 当 goal 文件包含 Groups 定义时,ws-goal 按依赖顺序逐个调度每个 group,每个 group 内按 5c-5f 的 4-phase 流程执行。主 session 负责编排每个 group 的 4 个 phase 并验证每个 phase 的产出。
229
+
230
+ 5.1a) **解析并验证 groups**:
231
+ - 提取 goal 文件中所有 group 定义(id, scope, verification, depends_on, status)
232
+ - 验证 DAG:无循环依赖,depends_on 引用正确的已知 group
233
+ - 将所有 group status 初始化为 `pending`
234
+ - 若解析失败(格式错误、循环依赖)→ 输出错误,不允许 delegation
235
+
236
+ 5.1b) **计算拓扑顺序**:
237
+ - 按 depends_on 确定执行顺序。默认:声明顺序
238
+ - 输出 group 执行计划列表:
239
+ ```
240
+ ═══ Group 执行计划 ═══
241
+ [1] group-1: Foundation Pages(depends_on: none)
242
+ [2] group-2: Purchase Conversion(depends_on: group-1)
243
+ [3] group-3: Account & Orders(depends_on: group-1)
244
+ ═══════════════════════════
245
+ ```
246
+ - 展示计划后要求用户确认是否继续。用户确认后才开始调度
247
+
248
+ 5.1c) **按顺序执行每个 group(phase-level)**:
249
+ FOR each group in 拓扑顺序:
250
+ 1. 更新 group status → `in_progress`,写入 goal 文件 Progress Notes
251
+ 2. **PHASE 1 - PLAN**(同 5c,但 change id = `<goal-id>-<group-id>`):
252
+ - 主 session 执行 `aiws change start <goal-id>-<group-id> --allow-dirty`
253
+ - 委托子 agent 写 proposal.md + plan 文件 + plan-verify
254
+ - 主 session 验证:proposal/plan 存在,plan-verify 通过
255
+ 3. **PHASE 2 - DEV**(同 5d,scope 限定到当前 group):
256
+ - 委托子 agent 按 plan 实现当前 group 的代码改动
257
+ - 主 session 验证:diagnostics 干净,改动匹配 group scope
258
+ 4. **PHASE 3 - REVIEW**(同 5e,scope 限定到当前 group):
259
+ - 委托子 agent 审计当前 group 改动
260
+ - 主 session 验证:review 证据存在,无 HIGH blocker
261
+ 5. **PHASE 4 - FINISH**(同 5f):
262
+ - 委托子 agent 做 commit + finish
263
+ - 主 session 验证:分支已合并推送
264
+ 6. 任一 phase 失败 → group status = paused/failed,记录 blocker,**STOP**(后续 group 不再调度)
265
+ 7. 全部 phase 通过 → 更新 group status → `complete`,更新 Progress Notes
266
+ - 若 goal 配置了多组并行:可在 PLANNING 通过且 DAG 无冲突前提下的顺序执行
267
+
268
+ 5.1d) **所有 group 完成后**:
269
+ - 运行整体完成审计:
270
+ - goal 级别的 outcome 是否满足
271
+ - 所有 group 均为 complete(无 paused/failed)
272
+ - 全局 lint/type 检查无新增错误
273
+ - 输出每 group 结果 + 整体结论
274
+ - 全部通过 → 更新 goal state=complete,输出 "Goal <id> complete(<N> groups executed)"
275
+ - 有未通过 → 更新 goal state=paused
276
+
277
+ 5.1e) **恢复机制**(下一 session 进入 step 0 时触发):
278
+ - 检测到 paused goal 且含 groups → 输出恢复选项:
279
+ - (a)重试失败的 group(从失败的 phase 重新开始)
280
+ - (b)跳过该 group(标记 complete,继续下游)
281
+ - (c)暂停并 handoff
282
+ - 用户选择后执行对应操作
283
+ <!-- AIWS_MANAGED_END:opencode:ws-goal -->
284
+
285
+ 可在下方追加本项目对 OpenCode 的额外说明(托管块外内容会被保留)。