@aipper/aiws-spec 0.0.29 → 0.0.31

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (126) hide show
  1. package/docs/workflow-delegation-contracts.json +40 -1
  2. package/docs/workflow-delegation-contracts.md +10 -0
  3. package/docs/workflow-delegation-contracts.schema.json +57 -0
  4. package/docs/workflow-governance-rules.md +1 -1
  5. package/docs/workflow-review-gates.json +6 -0
  6. package/docs/workflow-review-gates.md +14 -5
  7. package/docs/workflow-review-gates.schema.json +4 -0
  8. package/docs/workflow-router-rules.json +46 -14
  9. package/docs/workflow-router-rules.md +19 -16
  10. package/docs/workflow-router-rules.schema.json +4 -0
  11. package/docs/workflow-stage-contracts.json +22 -2
  12. package/docs/workflow-stage-contracts.md +15 -13
  13. package/docs/workflow-stage-contracts.schema.json +12 -1
  14. package/package.json +1 -1
  15. package/templates/workspace/.agents/skills/p-aiws-change-archive/SKILL.md +1 -1
  16. package/templates/workspace/.agents/skills/p-aiws-change-finish/SKILL.md +1 -1
  17. package/templates/workspace/.agents/skills/p-aiws-change-new/SKILL.md +2 -2
  18. package/templates/workspace/.agents/skills/p-aiws-change-start/SKILL.md +1 -1
  19. package/templates/workspace/.agents/skills/p-aiws-change-sync/SKILL.md +2 -2
  20. package/templates/workspace/.agents/skills/p-aiws-change-validate/SKILL.md +1 -1
  21. package/templates/workspace/.agents/skills/p-aiws-validate/SKILL.md +1 -1
  22. package/templates/workspace/.agents/skills/p-tasks-plan/SKILL.md +7 -7
  23. package/templates/workspace/.agents/skills/using-aiws/SKILL.md +11 -7
  24. package/templates/workspace/.agents/skills/ws-analyze/SKILL.md +2 -2
  25. package/templates/workspace/.agents/skills/ws-bugfix/SKILL.md +8 -8
  26. package/templates/workspace/.agents/skills/ws-commit/SKILL.md +5 -5
  27. package/templates/workspace/.agents/skills/ws-delegate/SKILL.md +4 -4
  28. package/templates/workspace/.agents/skills/ws-deliver/SKILL.md +5 -5
  29. package/templates/workspace/.agents/skills/ws-dev/SKILL.md +32 -2
  30. package/templates/workspace/.agents/skills/ws-dev-lite/SKILL.md +2 -2
  31. package/templates/workspace/.agents/skills/ws-finish/SKILL.md +9 -5
  32. package/templates/workspace/.agents/skills/ws-frontend-design/SKILL.md +1 -1
  33. package/templates/workspace/.agents/skills/ws-handoff/SKILL.md +5 -5
  34. package/templates/workspace/.agents/skills/ws-migrate/SKILL.md +18 -0
  35. package/templates/workspace/.agents/skills/ws-plan/SKILL.md +5 -5
  36. package/templates/workspace/.agents/skills/ws-plan-verify/SKILL.md +5 -5
  37. package/templates/workspace/.agents/skills/ws-pull/SKILL.md +18 -0
  38. package/templates/workspace/.agents/skills/ws-push/SKILL.md +18 -0
  39. package/templates/workspace/.agents/skills/ws-quality-review/SKILL.md +5 -5
  40. package/templates/workspace/.agents/skills/ws-review/SKILL.md +8 -8
  41. package/templates/workspace/.agents/skills/ws-spec-review/SKILL.md +5 -5
  42. package/templates/workspace/.agents/skills/ws-submodule-setup/SKILL.md +18 -0
  43. package/templates/workspace/.agents/skills/ws-verify-before-complete/SKILL.md +5 -5
  44. package/templates/workspace/{changes → .aiws/changes}/README.md +13 -13
  45. package/templates/workspace/{changes → .aiws/changes}/templates/proposal.md +12 -12
  46. package/templates/workspace/{changes → .aiws/changes}/templates/tasks.md +8 -8
  47. package/templates/workspace/{issues → .aiws/issues}/problem-issues.csv +1 -1
  48. package/templates/workspace/.aiws/journal/.gitkeep +1 -0
  49. package/templates/workspace/{requirements → .aiws/requirements}/requirements-issues.csv +1 -1
  50. package/templates/workspace/.aiws/tmp/.gitkeep +0 -0
  51. package/templates/workspace/{tools → .aiws/tools}/requirements_contract.py +2 -2
  52. package/templates/workspace/{tools → .aiws/tools}/requirements_contract_sync.py +2 -2
  53. package/templates/workspace/{tools → .aiws/tools}/requirements_flow_gen.py +1 -1
  54. package/templates/workspace/{tools → .aiws/tools}/server_test_runner.py +10 -10
  55. package/templates/workspace/{tools → .aiws/tools}/ws_change_check.py +23 -23
  56. package/templates/workspace/{tools → .aiws/tools}/ws_resolve_sub_target.sh +2 -2
  57. package/templates/workspace/{tools → .aiws/tools}/ws_tasks_plan.py +3 -3
  58. package/templates/workspace/.claude/skills/ws-commit/SKILL.md +5 -5
  59. package/templates/workspace/.claude/skills/ws-deliver/SKILL.md +5 -5
  60. package/templates/workspace/.claude/skills/ws-finish/SKILL.md +9 -5
  61. package/templates/workspace/.claude/skills/ws-handoff/SKILL.md +5 -5
  62. package/templates/workspace/.claude/skills/ws-migrate/SKILL.md +18 -0
  63. package/templates/workspace/.claude/skills/ws-plan-verify/SKILL.md +5 -5
  64. package/templates/workspace/.claude/skills/ws-pull/SKILL.md +18 -0
  65. package/templates/workspace/.claude/skills/ws-push/SKILL.md +18 -0
  66. package/templates/workspace/.claude/skills/ws-submodule-setup/SKILL.md +18 -0
  67. package/templates/workspace/.claude/skills/ws-verify-before-complete/SKILL.md +5 -5
  68. package/templates/workspace/.githooks/pre-commit +13 -0
  69. package/templates/workspace/.githooks/pre-push +7 -0
  70. package/templates/workspace/.opencode/commands/ws-finish.md +66 -1
  71. package/templates/workspace/.opencode/helpers/approval-whitelist-check.sh +1 -1
  72. package/templates/workspace/.opencode/helpers/approval-whitelist-run.sh +1 -1
  73. package/templates/workspace/.opencode/helpers/approval-whitelist-watchdog.sh +1 -1
  74. package/templates/workspace/.opencode/helpers/tmux-swarm-rescue.sh +1 -1
  75. package/templates/workspace/.opencode/helpers/tmux-swarm-scan.sh +1 -1
  76. package/templates/workspace/.opencode/lib/aiws-context.js +953 -0
  77. package/templates/workspace/.opencode/plugins/aiws-inject-context.js +201 -0
  78. package/templates/workspace/.opencode/plugins/aiws-session-start.js +86 -0
  79. package/templates/workspace/.opencode/plugins/aiws-workflow-state.js +116 -0
  80. package/templates/workspace/.opencode/scripts/ws-plan-gen-submodule-targets.sh +27 -0
  81. package/templates/workspace/.opencode/scripts/ws-plan-setup-worktree.sh +31 -0
  82. package/templates/workspace/.opencode/skills/p-aiws-change-archive/SKILL.md +1 -1
  83. package/templates/workspace/.opencode/skills/p-aiws-change-finish/SKILL.md +1 -1
  84. package/templates/workspace/.opencode/skills/p-aiws-change-new/SKILL.md +2 -2
  85. package/templates/workspace/.opencode/skills/p-aiws-change-start/SKILL.md +1 -1
  86. package/templates/workspace/.opencode/skills/p-aiws-change-sync/SKILL.md +2 -2
  87. package/templates/workspace/.opencode/skills/p-aiws-change-validate/SKILL.md +1 -1
  88. package/templates/workspace/.opencode/skills/p-aiws-validate/SKILL.md +1 -1
  89. package/templates/workspace/.opencode/skills/p-tasks-plan/SKILL.md +7 -7
  90. package/templates/workspace/.opencode/skills/using-aiws/SKILL.md +40 -3
  91. package/templates/workspace/.opencode/skills/ws-analyze/SKILL.md +2 -2
  92. package/templates/workspace/.opencode/skills/ws-autonomy/SKILL.md +1 -1
  93. package/templates/workspace/.opencode/skills/ws-bugfix/SKILL.md +7 -7
  94. package/templates/workspace/.opencode/skills/ws-commit/SKILL.md +5 -5
  95. package/templates/workspace/.opencode/skills/ws-delegate/SKILL.md +26 -4
  96. package/templates/workspace/.opencode/skills/ws-deliver/SKILL.md +5 -5
  97. package/templates/workspace/.opencode/skills/ws-dev/SKILL.md +54 -6
  98. package/templates/workspace/.opencode/skills/ws-dev-lite/SKILL.md +6 -3
  99. package/templates/workspace/.opencode/skills/ws-finish/SKILL.md +9 -5
  100. package/templates/workspace/.opencode/skills/ws-frontend-design/SKILL.md +1 -1
  101. package/templates/workspace/.opencode/skills/ws-handoff/SKILL.md +5 -5
  102. package/templates/workspace/.opencode/skills/ws-intake/SKILL.md +32 -2
  103. package/templates/workspace/.opencode/skills/ws-migrate/SKILL.md +5 -5
  104. package/templates/workspace/.opencode/skills/ws-plan/SKILL.md +16 -58
  105. package/templates/workspace/.opencode/skills/ws-plan-verify/SKILL.md +5 -5
  106. package/templates/workspace/.opencode/skills/ws-pull/SKILL.md +5 -5
  107. package/templates/workspace/.opencode/skills/ws-push/SKILL.md +5 -5
  108. package/templates/workspace/.opencode/skills/ws-quality-review/SKILL.md +11 -6
  109. package/templates/workspace/.opencode/skills/ws-review/SKILL.md +33 -13
  110. package/templates/workspace/.opencode/skills/ws-spec-review/SKILL.md +5 -5
  111. package/templates/workspace/.opencode/skills/ws-submodule-setup/SKILL.md +5 -5
  112. package/templates/workspace/.opencode/skills/ws-verify-before-complete/SKILL.md +36 -5
  113. package/templates/workspace/AGENTS.md +32 -87
  114. package/templates/workspace/AI_PROJECT.md +4 -4
  115. package/templates/workspace/AI_WORKSPACE.md +1 -1
  116. package/templates/workspace/REQUIREMENTS.md +1 -1
  117. package/templates/workspace/gitignore +1 -1
  118. package/templates/workspace/manifest.json +96 -334
  119. /package/templates/workspace/{changes → .aiws/changes}/templates/design.md +0 -0
  120. /package/templates/workspace/{memory-bank → .aiws/memory-bank}/README.md +0 -0
  121. /package/templates/workspace/{memory-bank → .aiws/memory-bank}/architecture.md +0 -0
  122. /package/templates/workspace/{memory-bank → .aiws/memory-bank}/implementation-plan.md +0 -0
  123. /package/templates/workspace/{memory-bank → .aiws/memory-bank}/progress.md +0 -0
  124. /package/templates/workspace/{memory-bank → .aiws/memory-bank}/tech-stack.md +0 -0
  125. /package/templates/workspace/{requirements → .aiws/requirements}/CHANGELOG.md +0 -0
  126. /package/templates/workspace/{secrets → .aiws/secrets}/test-accounts.example.json +0 -0
@@ -7,7 +7,7 @@ description: 规范审查(requirements / plan / evidence / gate 完整性)
7
7
 
8
8
  目标:
9
9
  - 审查当前改动是否满足真值文件、change 绑定、证据路径和 gate 完整性要求
10
- - 把“流程/规范层 blocker”与“代码层问题”区分开,优先落盘到 `changes/<change-id>/review/spec-review.md`
10
+ - 把“流程/规范层 blocker”与“代码层问题”区分开,优先落盘到 `.aiws/changes/<change-id>/review/spec-review.md`
11
11
 
12
12
  阶段定位:
13
13
  - review 子 gate;负责 requirements / plan / evidence / workflow gate 完整性审查。
@@ -17,10 +17,10 @@ description: 规范审查(requirements / plan / evidence / gate 完整性)
17
17
  - `REQUIREMENTS.md`
18
18
  - `AI_WORKSPACE.md`
19
19
  - 当前 `git diff`
20
- - 若存在:`plan/...`、`changes/<change-id>/proposal.md`、`tasks.md`、`review/`、`evidence/`
20
+ - 若存在:`plan/...`、`.aiws/changes/<change-id>/proposal.md`、`tasks.md`、`review/`、`evidence/`
21
21
 
22
22
  必需输出:
23
- - `证据(Evidence):` `changes/<change-id>/review/spec-review.md` 或回退 `.agentdocs/tmp/review/spec-review.md`
23
+ - `证据(Evidence):` `.aiws/changes/<change-id>/review/spec-review.md` 或回退 `.aiws/tmp/review/spec-review.md`
24
24
  - `阻断项(Blockers):` requirements 归因 / gate / evidence 缺口
25
25
  - `下一步(Next):` 修复项与最小验证命令
26
26
 
@@ -40,8 +40,8 @@ description: 规范审查(requirements / plan / evidence / gate 完整性)
40
40
  - 是否存在越界目录改动、危险操作、未声明的非目标扩张
41
41
  - 是否已经准备好可复现验证入口
42
42
  3) 把结论落盘到:
43
- - 默认:`changes/<change-id>/review/spec-review.md`
44
- - 回退:`.agentdocs/tmp/review/spec-review.md`
43
+ - 默认:`.aiws/changes/<change-id>/review/spec-review.md`
44
+ - 回退:`.aiws/tmp/review/spec-review.md`
45
45
  4) 输出:
46
46
  - `证据(Evidence):`
47
47
  - `阻断项(Blockers):`
@@ -0,0 +1,18 @@
1
+ ---
2
+ name: ws-submodule-setup
3
+ description: `aiws submodule-setup` 的薄包装入口
4
+ ---
5
+
6
+ # ws-submodule-setup
7
+
8
+ `aiws submodule-setup` 的薄包装入口。
9
+
10
+ ```bash
11
+ if [[ -x "./node_modules/.bin/aiws" ]]; then
12
+ ./node_modules/.bin/aiws submodule-setup
13
+ elif command -v aiws >/dev/null 2>&1; then
14
+ aiws submodule-setup
15
+ else
16
+ npx @aipper/aiws submodule-setup
17
+ fi
18
+ ```
@@ -1,18 +1,18 @@
1
1
  ---
2
2
  name: ws-verify-before-complete
3
- description: `aiws ws-verify-before-complete` 的薄包装入口
3
+ description: `aiws verify-bc` 的薄包装入口
4
4
  ---
5
5
 
6
6
  # ws-verify-before-complete
7
7
 
8
- `aiws ws-verify-before-complete` 的薄包装入口。
8
+ `aiws verify-bc` 的薄包装入口。
9
9
 
10
10
  ```bash
11
11
  if [[ -x "./node_modules/.bin/aiws" ]]; then
12
- ./node_modules/.bin/aiws ws-verify-before-complete
12
+ ./node_modules/.bin/aiws verify-bc
13
13
  elif command -v aiws >/dev/null 2>&1; then
14
- aiws ws-verify-before-complete
14
+ aiws verify-bc
15
15
  else
16
- npx @aipper/aiws ws-verify-before-complete
16
+ npx @aipper/aiws verify-bc
17
17
  fi
18
18
  ```
@@ -9,7 +9,7 @@
9
9
 
10
10
  建议结构:
11
11
  ```
12
- changes/
12
+ .aiws/changes/
13
13
  README.md
14
14
  <change-id>/
15
15
  proposal.md
@@ -36,8 +36,8 @@ changes/
36
36
  - `aiws change start <change-id> --no-switch`(superproject + submodule 场景:不切分支,仅准备 `change/<change-id>` 分支与工件目录)
37
37
  - `aiws change start <change-id> --switch`(显式允许切换 superproject 分支;仅切 superproject,不递归切换 submodule)
38
38
  - `aiws change finish <change-id>`(安全合并:fast-forward 合并回目标分支;在 `change/<change-id>` 分支上执行时会尝试使用 `.ws-change.json` 的 `base_branch` 作为目标分支)
39
- - `aiws change finish <change-id> --push [--remote <name>]`(最小收尾闭环:若存在 `.gitmodules` 则先按 `changes/<id>/submodules.targets` 顺序 push submodule,再 push 目标分支;默认优先遵循 upstream 配置;push 成功后把 `changes/<id>/` 自动归档到 `changes/archive/...`,同时生成 `handoff.md` 与 archive commit)
40
- - 已 archive 的 `change/<change-id>` 才算真正终态;若只是“已 finish 但仍有 active `changes/<id>/` 未归档”,默认应重跑 `aiws change finish <change-id> --push` 续完收尾,而不是继续开发或复用旧 branch 做新需求。
39
+ - `aiws change finish <change-id> --push [--remote <name>]`(最小收尾闭环:若存在 `.gitmodules` 则先按 `.aiws/changes/<id>/submodules.targets` 顺序 push submodule,再 push 目标分支;默认优先遵循 upstream 配置;push 成功后把 `.aiws/changes/<id>/` 自动归档到 `.aiws/changes/archive/...`,同时生成 `handoff.md` 与 archive commit)
40
+ - 已 archive 的 `change/<change-id>` 才算真正终态;若只是"已 finish 但仍有 active `.aiws/changes/<id>/` 未归档",默认应重跑 `aiws change finish <change-id> --push` 续完收尾,而不是继续开发或复用旧 branch 做新需求。
41
41
  - `aiws change new <change-id>`
42
42
  - `aiws change list`
43
43
  - `aiws change status <change-id>`
@@ -45,24 +45,24 @@ changes/
45
45
  - `aiws change validate <change-id>`
46
46
  - `aiws change sync <change-id>`
47
47
  - `aiws change archive <change-id>`(手工恢复 / 历史兼容入口;标准链路一般不需要单独执行)
48
- - `aiws change evidence <change-id>`(收敛 review / validate / collaboration summary 到 `changes/<id>/evidence/`)
48
+ - `aiws change evidence <change-id>`(收敛 review / validate / collaboration summary 到 `.aiws/changes/<id>/evidence/`)
49
49
 
50
50
  Active change(推荐,团队共享):
51
51
  - 使用分支名声明当前变更:`change/<change-id>`(也支持 `changes/`、`ws/`、`ws-change/`)
52
52
  - 切到该分支后,可省略 `<change-id>` 执行:`aiws change status|next|validate|sync`
53
53
 
54
54
  计划质量门(推荐,执行前):
55
- - 先生成计划:`$ws-plan`(若尚未进入 `change/<change-id>` 上下文,应先由它调用 `aiws change start <change-id>` 建立分支,再在该上下文内写 `plan/...`)
55
+ - 先生成计划:`$ws-plan`(若尚未进入 `change/<change-id>` 上下文,应先由它调用 `aiws change start <change-id>` 建立分支,再在该上下文内写 `.aiws/plan/...`)
56
56
  - 再执行计划质检:`$ws-plan-verify`
57
57
  - 最后进入实现:`$ws-dev`
58
58
  - 若 `$ws-plan` 创建了独立 `change/<change-id>` 分支,后续 `$ws-plan-verify` / `$ws-dev` / `$ws-finish` 都应优先在该分支内继续
59
59
  - 目标:确保计划具备主索引绑定、步骤不过长、验证命令可复现且有预期结果
60
60
 
61
61
  模板覆盖(可选):
62
- - 在工作区创建 `changes/templates/` 可覆盖默认模板:
63
- - `changes/templates/proposal.md`
64
- - `changes/templates/tasks.md`
65
- - `changes/templates/design.md`
62
+ - 在工作区创建 `.aiws/changes/templates/` 可覆盖默认模板:
63
+ - `.aiws/changes/templates/proposal.md`
64
+ - `.aiws/changes/templates/tasks.md`
65
+ - `.aiws/changes/templates/design.md`
66
66
  - 快速初始化模板:`aiws change templates init`
67
67
  - 查看模板来源:`aiws change templates which`
68
68
 
@@ -77,7 +77,7 @@ Hooks/CI(推荐,硬约束):
77
77
  - submodule / 普通仓库:默认 `warn`,提示优先使用中文 commit message
78
78
  - 若执行 `git config aiws.commitMessagePolicy strict`,则会拒绝全英文首行(`Merge/Revert/fixup!/squash!` 例外)
79
79
  - `pre-commit` / `pre-push`:默认执行 `aiws validate .`
80
- - 还会安装门禁脚本(`tools/ws_change_check.py`、`tools/requirements_contract.py`)。
80
+ - 还会安装门禁脚本(`.aiws/tools/ws_change_check.py`、`.aiws/tools/requirements_contract.py`)。
81
81
  - **启用 hooks 需要本地配置**(不会自动提交到 git):
82
82
  - 直接启用:`git config core.hooksPath .githooks`
83
83
  - 或使用:`aiws hooks install .`(等价)
@@ -91,7 +91,7 @@ Hooks/CI(推荐,硬约束):
91
91
  - 若失败:先在 change 分支 `git rebase main`(或更新 main 后再 rebase),再重试 `--ff-only`
92
92
 
93
93
  协同交付建议:
94
- - 委托分析先落到 `changes/<id>/analysis/`,由主 agent 在 `ws-review` 或 `review/*.md` 中收敛结论。
95
- - patch 草案先落到 `changes/<id>/patches/`,未经审查不要直接应用。
96
- - 交付前建议执行:`aiws change evidence <change-id>`,让 `delivery-summary` 与 `collaboration-summary` 一起落到 `changes/<id>/evidence/`。
94
+ - 委托分析先落到 `.aiws/changes/<id>/analysis/`,由主 agent 在 `ws-review` 或 `review/*.md` 中收敛结论。
95
+ - patch 草案先落到 `.aiws/changes/<id>/patches/`,未经审查不要直接应用。
96
+ - 交付前建议执行:`aiws change evidence <change-id>`,让 `delivery-summary` 与 `collaboration-summary` 一起落到 `.aiws/changes/<id>/evidence/`。
97
97
  - finish 自动归档后生成的 `handoff.md` 会包含协同工件摘要,便于下一次会话继续接力。
@@ -18,8 +18,8 @@
18
18
  - 需求交付:`Req_ID` = <!-- WS:TODO (需求交付可填;例如 TOOLING-001B) -->
19
19
  - 问题修复:`Problem_ID` = <!-- WS:TODO (问题修复可填;例如 PROB-001) -->
20
20
  - `Contract_Row` = <!-- WS:TODO 绑定执行合同中的行 ID,可多项(逗号分隔);例如 Req_ID=TOOLING-001B -->
21
- - `Plan_File` = <!-- WS:TODO 例如 plan/2026-02-08_15-30-00-xxx.md -->
22
- - `Evidence_Path` = <!-- WS:TODO 证据路径,可多项(逗号分隔);优先写持久证据 changes/<change-id>/evidence/...;也可附带 changes/<change-id>/review/... 或 .agentdocs/tmp/... -->
21
+ - `Plan_File` = <!-- WS:TODO 例如 .aiws/plan/2026-02-08_15-30-00-xxx.md -->
22
+ - `Evidence_Path` = <!-- WS:TODO 证据路径,可多项(逗号分隔);优先写持久证据 .aiws/changes/<change-id>/evidence/...;也可附带 .aiws/changes/<change-id>/review/... 或 .aiws/tmp/... -->
23
23
 
24
24
  ## 依赖关系(可选)
25
25
 
@@ -33,7 +33,7 @@
33
33
 
34
34
  > 规则:
35
35
  > - `Req_ID` 与 `Problem_ID` 至少填写一项。
36
- > - `Contract_Row` 必须引用 `requirements/requirements-issues.csv` 或 `issues/problem-issues.csv` 中的真实行。
36
+ > - `Contract_Row` 必须引用 `.aiws/requirements/requirements-issues.csv` 或 `.aiws/issues/problem-issues.csv` 中的真实行。
37
37
  > - `Plan_File` 对应的计划文件必须存在,且其绑定字段与本文件一致。
38
38
  > - `Evidence_Path` 可先声明计划路径,交付前需完成证据落盘。
39
39
 
@@ -48,9 +48,9 @@
48
48
  ## 协同与委托(可选)
49
49
 
50
50
  - `analysis/`:
51
- - <!-- WS:TODO 如需委托分析,写明预计产物;例如 `changes/<change-id>/analysis/research-a.md` -->
51
+ - <!-- WS:TODO 如需委托分析,写明预计产物;例如 `.aiws/changes/<change-id>/analysis/research-a.md` -->
52
52
  - `patches/`:
53
- - <!-- WS:TODO 如需外部 patch 草案,写明预计文件;例如 `changes/<change-id>/patches/fix-a.patch` -->
53
+ - <!-- WS:TODO 如需外部 patch 草案,写明预计文件;例如 `.aiws/changes/<change-id>/patches/fix-a.patch` -->
54
54
  - `review/`:
55
55
  - <!-- WS:TODO 如需多审查者,写明 reviewer 文件命名或汇总策略 -->
56
56
 
@@ -96,17 +96,17 @@
96
96
  > 从 `AI_WORKSPACE.md` 选择最贴近本变更的验证入口,写成可直接复制执行的命令。
97
97
 
98
98
  - 命令:
99
- - <!-- WS:TODO 例如:`uv run tools/server_test_runner.py --workspace .` -->
99
+ - <!-- WS:TODO 例如:`uv run .aiws/tools/server_test_runner.py --workspace .` -->
100
100
  - 期望结果:
101
101
  - <!-- WS:TODO 例如:所有相关用例 DONE;无新增错误日志 -->
102
102
 
103
103
  ## 真值文件/合同更新清单
104
104
 
105
105
  - `REQUIREMENTS.md`:<!-- WS:TODO 需要/不需要;如需要,写明新增/修改的验收条款 -->
106
- - `requirements/CHANGELOG.md`:<!-- WS:TODO 需要/不需要 -->
107
- - `requirements/requirements-issues.csv`:<!-- WS:TODO 需要/不需要 -->
108
- - `issues/problem-issues.csv`:<!-- WS:TODO 需要/不需要 -->
106
+ - `.aiws/requirements/CHANGELOG.md`:<!-- WS:TODO 需要/不需要 -->
107
+ - `.aiws/requirements/requirements-issues.csv`:<!-- WS:TODO 需要/不需要 -->
108
+ - `.aiws/issues/problem-issues.csv`:<!-- WS:TODO 需要/不需要 -->
109
109
  - 证据落盘(推荐双层):
110
- - 持久(建议入库):`changes/<change-id>/evidence/...`(例如 validate 总结、review 总结、关键日志摘要)
111
- - 临时(可忽略入库):`.agentdocs/tmp/...`(例如 `aiws validate . --stamp` 的 JSON)
112
- - 协同(按需):`changes/<change-id>/analysis/...`、`patches/...`、`review/...`
110
+ - 持久(建议入库):`.aiws/changes/<change-id>/evidence/...`(例如 validate 总结、review 总结、关键日志摘要)
111
+ - 临时(可忽略入库):`.aiws/tmp/...`(例如 `aiws validate . --stamp` 的 JSON)
112
+ - 协同(按需):`.aiws/changes/<change-id>/analysis/...`、`.aiws/changes/<change-id>/patches/...`、`.aiws/changes/<change-id>/review/...`
@@ -9,16 +9,16 @@
9
9
  - [ ] 0.1 阅读并遵守 `AI_PROJECT.md` / `AI_WORKSPACE.md` / `REQUIREMENTS.md`
10
10
  - [ ] 0.2 运行门禁校验:`aiws validate .`(或 `npx -y @aipper/aiws validate .`)
11
11
  - [ ] 0.3 若真值文件发生变化(例如你更新了 REQUIREMENTS.md),同步基线:`aiws change sync {{CHANGE_ID}}`
12
- - [ ] 0.4 在 `changes/{{CHANGE_ID}}/proposal.md` 填写主索引绑定:`Change_ID` / (`Req_ID` or `Problem_ID`) / `Contract_Row` / `Plan_File` / `Evidence_Path`
13
- - [ ] 0.5 生成 `plan/...` 后,确认计划文件中的绑定字段与 proposal 一致
12
+ - [ ] 0.4 在 `.aiws/changes/{{CHANGE_ID}}/proposal.md` 填写主索引绑定:`Change_ID` / (`Req_ID` or `Problem_ID`) / `Contract_Row` / `Plan_File` / `Evidence_Path`
13
+ - [ ] 0.5 生成 `.aiws/plan/...` 后,确认计划文件中的绑定字段与 proposal 一致
14
14
  - [ ] 0.6 执行计划质检:在 AI 工具运行 `$ws-plan-verify`(或按同等清单手工检查“章节/步骤粒度/验证命令与预期”)
15
15
  - [ ] 0.7 严格校验:`aiws change validate {{CHANGE_ID}} --strict`
16
16
 
17
17
  ## 1. 需求/问题合同(如适用)
18
18
 
19
19
  - [ ] 1.1 需求交付:补齐/更新 `REQUIREMENTS.md` 验收条款(或确认不需要)
20
- - [ ] 1.2 同步 `requirements/requirements-issues.csv`(或更新 `issues/problem-issues.csv`)
21
- - [ ] 1.3 记录到 `requirements/CHANGELOG.md`(如需求发生变化)
20
+ - [ ] 1.2 同步 `.aiws/requirements/requirements-issues.csv`(或更新 `.aiws/issues/problem-issues.csv`)
21
+ - [ ] 1.3 记录到 `.aiws/requirements/CHANGELOG.md`(如需求发生变化)
22
22
 
23
23
  ## 2. 实现
24
24
 
@@ -27,9 +27,9 @@
27
27
 
28
28
  ## 2A. 协同(可选)
29
29
 
30
- - [ ] 2A.1 若使用委托分析:把结果落盘到 `changes/{{CHANGE_ID}}/analysis/`
31
- - [ ] 2A.2 若使用 patch 草案:把结果落盘到 `changes/{{CHANGE_ID}}/patches/`,并记录是否采用
32
- - [ ] 2A.3 若存在多审查者:把审查结果落盘到 `changes/{{CHANGE_ID}}/review/`
30
+ - [ ] 2A.1 若使用委托分析:把结果落盘到 `.aiws/changes/{{CHANGE_ID}}/analysis/`
31
+ - [ ] 2A.2 若使用 patch 草案:把结果落盘到 `.aiws/changes/{{CHANGE_ID}}/patches/`,并记录是否采用
32
+ - [ ] 2A.3 若存在多审查者:把审查结果落盘到 `.aiws/changes/{{CHANGE_ID}}/review/`
33
33
 
34
34
  ## 3. 验证(必须可复现)
35
35
 
@@ -38,7 +38,7 @@
38
38
 
39
39
  ## 4. 交付与归档
40
40
 
41
- - [ ] 4.1 证据落盘到 `.agentdocs/tmp/...`(报告/日志/请求响应等)
41
+ - [ ] 4.1 证据落盘到 `.aiws/tmp/...`(报告/日志/请求响应等)
42
42
  - [ ] 4.2 生成持久证据:`aiws change evidence {{CHANGE_ID}}`
43
43
  - [ ] 4.3 交叉审计(可选但推荐):在 AI 工具内运行 `/ws-review`(或按 `AI_PROJECT.md` 手工审计)
44
44
  - [ ] 4.4 收尾:`aiws change finish {{CHANGE_ID}} --push`(成功后自动归档并生成 handoff)
@@ -1,2 +1,2 @@
1
1
  Problem_ID,Type,Severity,Title,Symptom,Repro,Root_Cause,Fix_Plan,Files,Tests,Evidence,Status,Owner,Created_At,Updated_At,Notes
2
- PROB-000,BUG,P2,示例:/api/system/menu/routes 返回 500,"访问 routes 接口报 500;日志提示参数解析错误","curl -sS -H 'Authorization: Bearer <token>' 'http://localhost:8080/api/system/menu/routes?x=1'","Controller 入参类型与前端实际 query 不一致","对齐入参定义并补充单测;复测 runner 端点状态更新为 DONE","server/src/...","uv run tools/server_test_runner.py --workspace . --service backend --max-endpoints 10",".agentdocs/tmp/server-test/report.json",TODO,ab,YYYY-MM-DDTHH:MM:SSZ,YYYY-MM-DDTHH:MM:SSZ,"若该问题阻塞某个需求交付,在 requirements/requirements-issues.csv 的 Notes 里关联 Problem_ID"
2
+ PROB-000,BUG,P2,示例:/api/system/menu/routes 返回 500,"访问 routes 接口报 500;日志提示参数解析错误","curl -sS -H 'Authorization: Bearer <token>' 'http://localhost:8080/api/system/menu/routes?x=1'","Controller 入参类型与前端实际 query 不一致","对齐入参定义并补充单测;复测 runner 端点状态更新为 DONE","server/src/...","uv run .aiws/tools/server_test_runner.py --workspace . --service backend --max-endpoints 10",".aiws/tmp/server-test/report.json",TODO,ab,YYYY-MM-DDTHH:MM:SSZ,YYYY-MM-DDTHH:MM:SSZ,"若该问题阻塞某个需求交付,在 .aiws/requirements/requirements-issues.csv 的 Notes 里关联 Problem_ID"
@@ -1,2 +1,2 @@
1
1
  Req_ID,Title,Change_Type,Module,CRUD,Actor,Scenario,Preconditions,Inputs,Outputs,Data_Model,Business_Logic,API_Impact,NonFunctional,Spec_Status,Impl_Status,Tests,Evidence,Owner,Created_At,Updated_At,Notes
2
- REQ-000,示例:用户列表分页支持按部门筛选,ADD,system/user,R,admin,管理员在用户管理页按部门筛选列表,已登录且有 system:user:list 权限,"deptId=10&page=1&pageSize=20",返回包含 deptId=10 的用户列表,"user,dept 表(字段:dept_id)","查询条件增加 deptId;默认不传不筛选;分页参数边界:page>=1&pageSize<=100",GET /api/system/user/list 新增 query 参数 deptId(可选),响应字段不变,性能:分页查询需走索引;安全:权限不变,READY,TODO,"uv run tools/server_test_runner.py --workspace . --service demo-spring --max-endpoints 10",.agentdocs/tmp/server-test/report.json,ab,YYYY-MM-DDTHH:MM:SSZ,YYYY-MM-DDTHH:MM:SSZ,
2
+ REQ-000,示例:用户列表分页支持按部门筛选,ADD,system/user,R,admin,管理员在用户管理页按部门筛选列表,已登录且有 system:user:list 权限,"deptId=10&page=1&pageSize=20",返回包含 deptId=10 的用户列表,"user,dept 表(字段:dept_id)","查询条件增加 deptId;默认不传不筛选;分页参数边界:page>=1&pageSize<=100",GET /api/system/user/list 新增 query 参数 deptId(可选),响应字段不变,性能:分页查询需走索引;安全:权限不变,READY,TODO,"uv run .aiws/tools/server_test_runner.py --workspace . --service demo-spring --max-endpoints 10",.aiws/tmp/server-test/report.json,ab,YYYY-MM-DDTHH:MM:SSZ,YYYY-MM-DDTHH:MM:SSZ,
File without changes
@@ -198,9 +198,9 @@ def validate_rows(rows: List[Dict[str, str]]) -> List[ValidateProblem]:
198
198
 
199
199
 
200
200
  def main(argv: List[str]) -> int:
201
- p = argparse.ArgumentParser(description="Manage requirements execution contract CSV (requirements/requirements-issues.csv).")
201
+ p = argparse.ArgumentParser(description="Manage requirements execution contract CSV (.aiws/requirements/requirements-issues.csv).")
202
202
  p.add_argument("--workspace", default=".", help="workspace root")
203
- p.add_argument("--csv", default="requirements/requirements-issues.csv", help="contract CSV path (relative to workspace)")
203
+ p.add_argument("--csv", default=".aiws/requirements/requirements-issues.csv", help="contract CSV path (relative to workspace)")
204
204
  sub = p.add_subparsers(dest="cmd", required=True)
205
205
 
206
206
  sub.add_parser("init", help="create CSV with header if missing")
@@ -243,7 +243,7 @@ def main(argv: List[str]) -> int:
243
243
  p = argparse.ArgumentParser(description="Backfill requirements contract CSV from REQUIREMENTS.md FlowSpec.")
244
244
  p.add_argument("--workspace", default=".", help="workspace root")
245
245
  p.add_argument("--requirements", default="REQUIREMENTS.md", help="requirements markdown path (relative to workspace)")
246
- p.add_argument("--out-csv", default="requirements/requirements-issues.csv", help="output contract CSV path")
246
+ p.add_argument("--out-csv", default=".aiws/requirements/requirements-issues.csv", help="output contract CSV path")
247
247
  p.add_argument("--owner", default="", help="default Owner for new rows")
248
248
  p.add_argument(
249
249
  "--default-tests",
@@ -281,7 +281,7 @@ def main(argv: List[str]) -> int:
281
281
  print(f"- flows: {stats['total_flows']}")
282
282
  print(f"- created: {stats['created']}")
283
283
  print(f"- updated: {stats['updated']}")
284
- print("next: fill missing fields, then run: python3 tools/requirements_contract.py validate")
284
+ print("next: fill missing fields, then run: python3 .aiws/tools/requirements_contract.py validate")
285
285
  return 0
286
286
 
287
287
 
@@ -222,7 +222,7 @@ def main(argv: List[str]) -> int:
222
222
  p.add_argument("--workspace", default=".", help="workspace root")
223
223
  p.add_argument("--requirements", default="REQUIREMENTS.md", help="requirements markdown path (relative to workspace)")
224
224
  p.add_argument("--out-mermaid", default="docs/api-flow.mmd", help="output mermaid file (relative to workspace)")
225
- p.add_argument("--out-csv", default="issues/server-scenario-issues.csv", help="output scenario CSV (relative to workspace)")
225
+ p.add_argument("--out-csv", default=".aiws/issues/server-scenario-issues.csv", help="output scenario CSV (relative to workspace)")
226
226
  args = p.parse_args(argv)
227
227
 
228
228
  root = Path(args.workspace).resolve()
@@ -114,7 +114,7 @@ class WorkspaceConfig:
114
114
  health_path: str = "/health"
115
115
  openapi_path: str = "docs/openapi.json"
116
116
  openapi_url: str = "/openapi.json"
117
- log_path: str = ".agentdocs/tmp/server-test/app.log"
117
+ log_path: str = ".aiws/tmp/server-test/app.log"
118
118
  request_id_header: str = "X-Request-Id"
119
119
  server_dirs: Tuple[str, ...] = ()
120
120
  build_cmd: str = ""
@@ -359,7 +359,7 @@ def parse_ai_workspace_md(path: Path) -> WorkspaceConfig:
359
359
  health_path = find_scalar("health_path") or "/health"
360
360
  openapi_path = find_scalar("openapi_path") or "docs/openapi.json"
361
361
  openapi_url = find_scalar("openapi_url") or "/openapi.json"
362
- log_path = find_scalar("log_path") or ".agentdocs/tmp/server-test/app.log"
362
+ log_path = find_scalar("log_path") or ".aiws/tmp/server-test/app.log"
363
363
  request_id_header = find_scalar("request_id_header") or "X-Request-Id"
364
364
 
365
365
  server_dirs = tuple(find_list("server_dirs"))
@@ -703,9 +703,9 @@ def render_cmd(template: str, *, service_dir: Path, service_name: str) -> str:
703
703
 
704
704
  def resolve_log_file(log_path: str, *, workspace_root: Path, service_name: str) -> Path:
705
705
  """
706
- Resolve log file path with optional {service} placeholder; defaults to per-service log under .agentdocs/tmp/server-test.
706
+ Resolve log file path with optional {service} placeholder; defaults to per-service log under .aiws/tmp/server-test.
707
707
  """
708
- path_str = (log_path or "").strip() or ".agentdocs/tmp/server-test/{service}.log"
708
+ path_str = (log_path or "").strip() or ".aiws/tmp/server-test/{service}.log"
709
709
  path_str = path_str.replace("{service}", service_name)
710
710
  return (workspace_root / path_str).resolve()
711
711
 
@@ -1278,7 +1278,7 @@ def write_fix_issues_csv(
1278
1278
  )
1279
1279
 
1280
1280
  write_fix_csv_rows(fix_csv_path, out_rows)
1281
- triage_csv_path = (workspace_root / "issues" / "server-triage-issues.csv").resolve()
1281
+ triage_csv_path = (workspace_root / ".aiws" / "issues" / "server-triage-issues.csv").resolve()
1282
1282
  write_triage_issues_csv(triage_csv_path=triage_csv_path, fix_rows=out_rows, generated_at=generated_at)
1283
1283
 
1284
1284
 
@@ -1564,9 +1564,9 @@ def main(argv: List[str]) -> int:
1564
1564
  parser = argparse.ArgumentParser(description="Workspace server API test runner (OpenAPI -> CSV -> requests -> log correlation)")
1565
1565
  parser.add_argument("--workspace", default=".", help="workspace root (directory A)")
1566
1566
  parser.add_argument("--service", default="", help="optional: only run one service directory name")
1567
- parser.add_argument("--csv", default="issues/server-api-issues.csv", help="execution contract CSV path (relative to workspace)")
1568
- parser.add_argument("--out-dir", default=".agentdocs/tmp/server-test", help="output dir for responses (relative to workspace)")
1569
- parser.add_argument("--base-url", default="", help="override base_url (otherwise use secrets/test-accounts.json or AI_WORKSPACE.md)")
1567
+ parser.add_argument("--csv", default=".aiws/issues/server-api-issues.csv", help="execution contract CSV path (relative to workspace)")
1568
+ parser.add_argument("--out-dir", default=".aiws/tmp/server-test", help="output dir for responses (relative to workspace)")
1569
+ parser.add_argument("--base-url", default="", help="override base_url (otherwise use .aiws/secrets/test-accounts.json or AI_WORKSPACE.md)")
1570
1570
  parser.add_argument("--health-timeout", type=int, default=60, help="seconds to wait for health endpoint")
1571
1571
  parser.add_argument("--no-wait-health", action="store_true", help="skip health check wait")
1572
1572
  parser.add_argument("--refresh-openapi", action="store_true", help="always export OpenAPI from openapi_url into docs/openapi.json")
@@ -1582,7 +1582,7 @@ def main(argv: List[str]) -> int:
1582
1582
  ai_workspace_md = workspace_root / "AI_WORKSPACE.md"
1583
1583
  cfg = parse_ai_workspace_md(ai_workspace_md)
1584
1584
 
1585
- secrets_path = workspace_root / "secrets" / "test-accounts.json"
1585
+ secrets_path = workspace_root / ".aiws" / "secrets" / "test-accounts.json"
1586
1586
  secrets = load_secrets(secrets_path)
1587
1587
 
1588
1588
  csv_path = (workspace_root / args.csv).resolve()
@@ -1850,7 +1850,7 @@ def main(argv: List[str]) -> int:
1850
1850
  if openapi_used:
1851
1851
  report["openapi_used"] = openapi_used
1852
1852
  write_text_if_changed(report_path, json.dumps(report, ensure_ascii=False, indent=2) + "\n")
1853
- fix_csv_path = (workspace_root / "issues" / "server-fix-issues.csv").resolve()
1853
+ fix_csv_path = (workspace_root / ".aiws" / "issues" / "server-fix-issues.csv").resolve()
1854
1854
  write_fix_issues_csv(
1855
1855
  fix_csv_path=fix_csv_path,
1856
1856
  endpoint_rows=updated_rows,
@@ -213,7 +213,7 @@ def parse_archived_change_dir_name(entry_name: str) -> Optional[Tuple[str, str,
213
213
 
214
214
 
215
215
  def find_archived_change(root: Path, change_id: str) -> Optional[Path]:
216
- archive_root = root / "changes" / "archive"
216
+ archive_root = root / ".aiws" / "changes" / "archive"
217
217
  if not archive_root.exists():
218
218
  return None
219
219
  matches: List[Path] = []
@@ -283,7 +283,7 @@ def summarize_finish_state(change_dir: Path) -> str:
283
283
 
284
284
 
285
285
  def terminated_change_message(root: Path, change_id: str) -> Optional[str]:
286
- change_dir = root / "changes" / change_id
286
+ change_dir = root / ".aiws" / "changes" / change_id
287
287
  if change_dir.exists() and summarize_finish_state(change_dir) == "done":
288
288
  return (
289
289
  f"change/{change_id} already reached finish, but archive/push closeout is still pending; "
@@ -335,7 +335,7 @@ def split_declared_values(value: str) -> List[str]:
335
335
 
336
336
  def normalize_contract_ref(raw: str) -> Tuple[str, str]:
337
337
  token = raw.strip().strip("`").strip()
338
- token = re.sub(r"^(requirements/requirements-issues\.csv|issues/problem-issues\.csv)\s*[:#]\s*", "", token)
338
+ token = re.sub(r"^(\.aiws/requirements/requirements-issues\.csv|\.aiws/issues/problem-issues\.csv)\s*[:#]\s*", "", token)
339
339
  m = re.match(r"(?i)^(req[_-]?id|problem[_-]?id)\s*=\s*(.+)$", token)
340
340
  if m:
341
341
  key = m.group(1).lower()
@@ -560,7 +560,7 @@ def validate_change(
560
560
  check_evidence: bool,
561
561
  check_scope: bool,
562
562
  ) -> int:
563
- change_dir = root / "changes" / change_id
563
+ change_dir = root / ".aiws" / "changes" / change_id
564
564
  required_files = ["proposal.md", "tasks.md"]
565
565
 
566
566
  errors: List[str] = []
@@ -572,7 +572,7 @@ def validate_change(
572
572
  if subs:
573
573
  targets_path = change_dir / "submodules.targets"
574
574
  if not targets_path.exists() or targets_path.stat().st_size == 0:
575
- msg = "missing/empty: changes/<change-id>/submodules.targets (required when .gitmodules declares submodules)"
575
+ msg = "missing/empty: .aiws/changes/<change-id>/submodules.targets (required when .gitmodules declares submodules)"
576
576
  hint = f"hint: create it under {change_dir} (format: <sub_path> <target_branch> [remote])"
577
577
  if strict:
578
578
  errors.append(msg)
@@ -685,7 +685,7 @@ def validate_change(
685
685
  f"{sub_path}: gitlink commit {gitlink_sha} is not contained in declared target branch {remote}/{target_branch}"
686
686
  )
687
687
  errors.append(
688
- f"hint: fix `.gitmodules` / `changes/{change_id}/submodules.targets`, or move the submodule gitlink onto a commit reachable from {remote}/{target_branch}"
688
+ f"hint: fix `.gitmodules` / `.aiws/changes/{change_id}/submodules.targets`, or move the submodule gitlink onto a commit reachable from {remote}/{target_branch}"
689
689
  )
690
690
 
691
691
  def placeholder_scan(rel: str, text: str) -> None:
@@ -696,7 +696,7 @@ def validate_change(
696
696
 
697
697
  def evidence_is_persistent(p: str) -> bool:
698
698
  p2 = p.replace("\\", "/")
699
- return p2.startswith(f"changes/{change_id}/evidence/") or p2.startswith(f"changes/{change_id}/review/")
699
+ return p2.startswith(f".aiws/changes/{change_id}/evidence/") or p2.startswith(f".aiws/changes/{change_id}/review/")
700
700
 
701
701
  def parse_scope_patterns_from_plan(plan_text: str) -> List[str]:
702
702
  # Extract allow-list bullet items from a plan's scope section.
@@ -777,7 +777,7 @@ def validate_change(
777
777
  has_persistent = any(evidence_is_persistent(p) for p in paths)
778
778
  if not has_persistent:
779
779
  (errors if strict else warnings).append(
780
- f"{rel} Evidence_Path should include at least one persistent path under changes/<id>/evidence or changes/<id>/review"
780
+ f"{rel} Evidence_Path should include at least one persistent path under .aiws/changes/<id>/evidence or .aiws/changes/<id>/review"
781
781
  )
782
782
  for raw in paths:
783
783
  p = raw.strip()
@@ -819,7 +819,7 @@ def validate_change(
819
819
  base_branch = ""
820
820
  if not base_branch:
821
821
  (errors if strict else warnings).append(
822
- "scope check requires base_branch recorded in changes/<id>/.ws-change.json (run `aiws change start <id>` to record it)"
822
+ "scope check requires base_branch recorded in .aiws/changes/<id>/.ws-change.json (run `aiws change start <id>` to record it)"
823
823
  )
824
824
  return
825
825
 
@@ -879,11 +879,11 @@ def validate_change(
879
879
 
880
880
  # Always allow core workflow artifacts.
881
881
  always_allow = [
882
- f"changes/{change_id}/**",
883
- "plan/**",
882
+ f".aiws/changes/{change_id}/**",
883
+ ".aiws/plan/**",
884
884
  "REQUIREMENTS.md",
885
- "requirements/requirements-issues.csv",
886
- "issues/problem-issues.csv",
885
+ ".aiws/requirements/requirements-issues.csv",
886
+ ".aiws/issues/problem-issues.csv",
887
887
  ]
888
888
  all_patterns = patterns + always_allow
889
889
 
@@ -898,8 +898,8 @@ def validate_change(
898
898
  contract_row_decl = ""
899
899
  plan_file_decl = ""
900
900
  evidence_path_decl = ""
901
- req_csv = root / "requirements" / "requirements-issues.csv"
902
- prob_csv = root / "issues" / "problem-issues.csv"
901
+ req_csv = root / ".aiws" / "requirements" / "requirements-issues.csv"
902
+ prob_csv = root / ".aiws" / "issues" / "problem-issues.csv"
903
903
 
904
904
  if proposal_path:
905
905
  t = read_text(proposal_path)
@@ -936,18 +936,18 @@ def validate_change(
936
936
  try:
937
937
  ok = csv_has_id(req_csv, "Req_ID", req_id)
938
938
  except Exception as e:
939
- warnings.append(f"failed to read requirements/requirements-issues.csv: {e}")
939
+ warnings.append(f"failed to read .aiws/requirements/requirements-issues.csv: {e}")
940
940
  if not ok:
941
- (errors if strict else warnings).append(f"Req_ID not found in requirements/requirements-issues.csv: {req_id}")
941
+ (errors if strict else warnings).append(f"Req_ID not found in .aiws/requirements/requirements-issues.csv: {req_id}")
942
942
 
943
943
  if prob_id and prob_csv.exists():
944
944
  ok = False
945
945
  try:
946
946
  ok = csv_has_id(prob_csv, "Problem_ID", prob_id)
947
947
  except Exception as e:
948
- warnings.append(f"failed to read issues/problem-issues.csv: {e}")
948
+ warnings.append(f"failed to read .aiws/issues/problem-issues.csv: {e}")
949
949
  if not ok:
950
- (errors if strict else warnings).append(f"Problem_ID not found in issues/problem-issues.csv: {prob_id}")
950
+ (errors if strict else warnings).append(f"Problem_ID not found in .aiws/issues/problem-issues.csv: {prob_id}")
951
951
 
952
952
  normalized_contract_refs: List[Tuple[str, str]] = []
953
953
  for raw_ref in split_declared_values(contract_row_decl):
@@ -969,7 +969,7 @@ def validate_change(
969
969
  except Exception as e:
970
970
  warnings.append(f"failed to resolve Contract_Row reference {raw_ref}: {e}")
971
971
  if not found:
972
- (errors if strict else warnings).append(f"Contract_Row not found in requirements/problem CSVs: {raw_ref}")
972
+ (errors if strict else warnings).append(f"Contract_Row not found in .aiws/requirements/problem CSVs: {raw_ref}")
973
973
  continue
974
974
  normalized_contract_refs.append((resolved_kind, value))
975
975
 
@@ -995,8 +995,8 @@ def validate_change(
995
995
  plan_rel = plan_rel[2:]
996
996
  if os.path.isabs(plan_rel):
997
997
  (errors if strict else warnings).append(f"Plan_File must be workspace-relative, got absolute path: {plan_rel}")
998
- if not plan_rel.startswith("plan/"):
999
- (errors if strict else warnings).append(f"Plan_File should be under plan/: {plan_rel}")
998
+ if not plan_rel.startswith(".aiws/plan/"):
999
+ (errors if strict else warnings).append(f"Plan_File should be under .aiws/plan/: {plan_rel}")
1000
1000
 
1001
1001
  plan_abs = (root / plan_rel).resolve()
1002
1002
  try:
@@ -1178,7 +1178,7 @@ def main(argv: Optional[List[str]] = None) -> int:
1178
1178
  eprint(f"error: change-id does not match branch (branch={branch_arg}, change_id={change_id})")
1179
1179
  return 2
1180
1180
 
1181
- change_dir = root / "changes" / change_id
1181
+ change_dir = root / ".aiws" / "changes" / change_id
1182
1182
  terminated = terminated_change_message(root, change_id) if (inferred_from_branch or bool(branch_arg)) else None
1183
1183
  if terminated:
1184
1184
  eprint(f"error: {terminated}")
@@ -2,7 +2,7 @@
2
2
  # ws_resolve_sub_target.sh — Resolve the target branch & remote for a submodule path.
3
3
  #
4
4
  # Usage:
5
- # source tools/ws_resolve_sub_target.sh
5
+ # source .aiws/tools/ws_resolve_sub_target.sh
6
6
  # ws_resolve_sub_target <sub_path> <sub_name> <targets_file> <base_branch>
7
7
  #
8
8
  # Outputs two variables: _resolved_branch and _resolved_remote.
@@ -13,7 +13,7 @@ ws_resolve_sub_target() {
13
13
  _resolved_branch=""
14
14
  _resolved_remote=""
15
15
 
16
- # Priority 1: changes/<id>/submodules.targets (per-change override)
16
+ # Priority 1: .aiws/changes/<id>/submodules.targets (per-change override)
17
17
  local override=""
18
18
  if [[ -f "${targets}" ]]; then
19
19
  override="$(awk -v p="${sub_path}" '
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env python3
2
2
  """
3
- Generate an update_plan JSON payload from changes/<id>/tasks.md checkbox tasks.
3
+ Generate an update_plan JSON payload from .aiws/changes/<id>/tasks.md checkbox tasks.
4
4
 
5
5
  This script is intended to be used by the `p-tasks-plan` Codex skill.
6
6
  It reads tasks.md only and does not modify it.
@@ -116,11 +116,11 @@ def build_parser() -> argparse.ArgumentParser:
116
116
  sub = p.add_subparsers(dest="cmd", required=True)
117
117
 
118
118
  p_status = sub.add_parser("status", help="Print progress summary from tasks.md")
119
- p_status.add_argument("--file", required=True, help="Path to changes/<id>/tasks.md")
119
+ p_status.add_argument("--file", required=True, help="Path to .aiws/changes/<id>/tasks.md")
120
120
  p_status.set_defaults(fn=cmd_status)
121
121
 
122
122
  p_plan = sub.add_parser("plan", help="Generate update_plan JSON payload from tasks.md")
123
- p_plan.add_argument("--file", required=True, help="Path to changes/<id>/tasks.md")
123
+ p_plan.add_argument("--file", required=True, help="Path to .aiws/changes/<id>/tasks.md")
124
124
  p_plan.add_argument("--explanation", default="", help="Explanation for update_plan payload")
125
125
  p_plan.set_defaults(fn=cmd_plan)
126
126
 
@@ -1,18 +1,18 @@
1
1
  ---
2
2
  name: ws-commit
3
- description: `aiws ws-commit` 的薄包装入口
3
+ description: `aiws commit` 的薄包装入口
4
4
  ---
5
5
 
6
6
  # ws-commit
7
7
 
8
- `aiws ws-commit` 的薄包装入口。
8
+ `aiws commit` 的薄包装入口。
9
9
 
10
10
  ```bash
11
11
  if [[ -x "./node_modules/.bin/aiws" ]]; then
12
- ./node_modules/.bin/aiws ws-commit
12
+ ./node_modules/.bin/aiws commit
13
13
  elif command -v aiws >/dev/null 2>&1; then
14
- aiws ws-commit
14
+ aiws commit
15
15
  else
16
- npx @aipper/aiws ws-commit
16
+ npx @aipper/aiws commit
17
17
  fi
18
18
  ```