@aipper/aiws-spec 0.0.29 → 0.0.30
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-delegation-contracts.json +40 -1
- package/docs/workflow-delegation-contracts.md +10 -0
- package/docs/workflow-delegation-contracts.schema.json +57 -0
- package/docs/workflow-governance-rules.md +1 -1
- package/docs/workflow-review-gates.json +6 -0
- package/docs/workflow-review-gates.md +14 -5
- package/docs/workflow-review-gates.schema.json +4 -0
- package/docs/workflow-router-rules.json +46 -14
- package/docs/workflow-router-rules.md +19 -16
- package/docs/workflow-router-rules.schema.json +4 -0
- package/docs/workflow-stage-contracts.json +22 -2
- package/docs/workflow-stage-contracts.md +15 -13
- package/docs/workflow-stage-contracts.schema.json +12 -1
- package/package.json +1 -1
- package/templates/workspace/.agents/skills/using-aiws/SKILL.md +10 -6
- package/templates/workspace/.agents/skills/ws-commit/SKILL.md +5 -5
- package/templates/workspace/.agents/skills/ws-deliver/SKILL.md +5 -5
- package/templates/workspace/.agents/skills/ws-dev/SKILL.md +30 -0
- package/templates/workspace/.agents/skills/ws-finish/SKILL.md +9 -5
- package/templates/workspace/.agents/skills/ws-handoff/SKILL.md +5 -5
- package/templates/workspace/.agents/skills/ws-migrate/SKILL.md +18 -0
- package/templates/workspace/.agents/skills/ws-plan-verify/SKILL.md +5 -5
- package/templates/workspace/.agents/skills/ws-pull/SKILL.md +18 -0
- package/templates/workspace/.agents/skills/ws-push/SKILL.md +18 -0
- package/templates/workspace/.agents/skills/ws-submodule-setup/SKILL.md +18 -0
- package/templates/workspace/.agents/skills/ws-verify-before-complete/SKILL.md +5 -5
- package/templates/workspace/{changes → .aiws/changes}/README.md +13 -13
- package/templates/workspace/{changes → .aiws/changes}/templates/proposal.md +12 -12
- package/templates/workspace/{changes → .aiws/changes}/templates/tasks.md +8 -8
- package/templates/workspace/{issues → .aiws/issues}/problem-issues.csv +1 -1
- package/templates/workspace/.aiws/journal/.gitkeep +1 -0
- package/templates/workspace/{requirements → .aiws/requirements}/requirements-issues.csv +1 -1
- package/templates/workspace/.aiws/tmp/.gitkeep +0 -0
- package/templates/workspace/{tools → .aiws/tools}/requirements_contract.py +2 -2
- package/templates/workspace/{tools → .aiws/tools}/requirements_contract_sync.py +2 -2
- package/templates/workspace/{tools → .aiws/tools}/requirements_flow_gen.py +1 -1
- package/templates/workspace/{tools → .aiws/tools}/server_test_runner.py +10 -10
- package/templates/workspace/{tools → .aiws/tools}/ws_change_check.py +23 -23
- package/templates/workspace/{tools → .aiws/tools}/ws_resolve_sub_target.sh +2 -2
- package/templates/workspace/{tools → .aiws/tools}/ws_tasks_plan.py +3 -3
- package/templates/workspace/.claude/skills/ws-commit/SKILL.md +5 -5
- package/templates/workspace/.claude/skills/ws-deliver/SKILL.md +5 -5
- package/templates/workspace/.claude/skills/ws-finish/SKILL.md +9 -5
- package/templates/workspace/.claude/skills/ws-handoff/SKILL.md +5 -5
- package/templates/workspace/.claude/skills/ws-migrate/SKILL.md +18 -0
- package/templates/workspace/.claude/skills/ws-plan-verify/SKILL.md +5 -5
- package/templates/workspace/.claude/skills/ws-pull/SKILL.md +18 -0
- package/templates/workspace/.claude/skills/ws-push/SKILL.md +18 -0
- package/templates/workspace/.claude/skills/ws-submodule-setup/SKILL.md +18 -0
- package/templates/workspace/.claude/skills/ws-verify-before-complete/SKILL.md +5 -5
- package/templates/workspace/.githooks/pre-commit +13 -0
- package/templates/workspace/.githooks/pre-push +7 -0
- package/templates/workspace/.opencode/commands/ws-finish.md +66 -1
- package/templates/workspace/.opencode/helpers/approval-whitelist-check.sh +1 -1
- package/templates/workspace/.opencode/helpers/approval-whitelist-run.sh +1 -1
- package/templates/workspace/.opencode/helpers/approval-whitelist-watchdog.sh +1 -1
- package/templates/workspace/.opencode/helpers/tmux-swarm-rescue.sh +1 -1
- package/templates/workspace/.opencode/helpers/tmux-swarm-scan.sh +1 -1
- package/templates/workspace/.opencode/lib/aiws-context.js +953 -0
- package/templates/workspace/.opencode/plugins/aiws-inject-context.js +201 -0
- package/templates/workspace/.opencode/plugins/aiws-session-start.js +86 -0
- package/templates/workspace/.opencode/plugins/aiws-workflow-state.js +116 -0
- package/templates/workspace/.opencode/scripts/ws-plan-gen-submodule-targets.sh +27 -0
- package/templates/workspace/.opencode/scripts/ws-plan-setup-worktree.sh +31 -0
- package/templates/workspace/.opencode/skills/using-aiws/SKILL.md +39 -2
- package/templates/workspace/.opencode/skills/ws-commit/SKILL.md +5 -5
- package/templates/workspace/.opencode/skills/ws-delegate/SKILL.md +22 -0
- package/templates/workspace/.opencode/skills/ws-deliver/SKILL.md +5 -5
- package/templates/workspace/.opencode/skills/ws-dev/SKILL.md +52 -4
- package/templates/workspace/.opencode/skills/ws-dev-lite/SKILL.md +4 -1
- package/templates/workspace/.opencode/skills/ws-finish/SKILL.md +9 -5
- package/templates/workspace/.opencode/skills/ws-handoff/SKILL.md +5 -5
- package/templates/workspace/.opencode/skills/ws-intake/SKILL.md +32 -2
- package/templates/workspace/.opencode/skills/ws-migrate/SKILL.md +5 -5
- package/templates/workspace/.opencode/skills/ws-plan/SKILL.md +11 -53
- package/templates/workspace/.opencode/skills/ws-plan-verify/SKILL.md +5 -5
- package/templates/workspace/.opencode/skills/ws-pull/SKILL.md +5 -5
- package/templates/workspace/.opencode/skills/ws-push/SKILL.md +5 -5
- package/templates/workspace/.opencode/skills/ws-quality-review/SKILL.md +6 -1
- package/templates/workspace/.opencode/skills/ws-review/SKILL.md +25 -5
- package/templates/workspace/.opencode/skills/ws-submodule-setup/SKILL.md +5 -5
- package/templates/workspace/.opencode/skills/ws-verify-before-complete/SKILL.md +36 -5
- package/templates/workspace/AGENTS.md +32 -87
- package/templates/workspace/AI_PROJECT.md +4 -4
- package/templates/workspace/AI_WORKSPACE.md +1 -1
- package/templates/workspace/REQUIREMENTS.md +1 -1
- package/templates/workspace/gitignore +1 -1
- package/templates/workspace/manifest.json +96 -334
- /package/templates/workspace/{changes → .aiws/changes}/templates/design.md +0 -0
- /package/templates/workspace/{memory-bank → .aiws/memory-bank}/README.md +0 -0
- /package/templates/workspace/{memory-bank → .aiws/memory-bank}/architecture.md +0 -0
- /package/templates/workspace/{memory-bank → .aiws/memory-bank}/implementation-plan.md +0 -0
- /package/templates/workspace/{memory-bank → .aiws/memory-bank}/progress.md +0 -0
- /package/templates/workspace/{memory-bank → .aiws/memory-bank}/tech-stack.md +0 -0
- /package/templates/workspace/{requirements → .aiws/requirements}/CHANGELOG.md +0 -0
- /package/templates/workspace/{secrets → .aiws/secrets}/test-accounts.example.json +0 -0
|
@@ -55,8 +55,8 @@ description: 默认 workflow bootstrap/router:先读真值,再路由到正
|
|
|
55
55
|
- finish / merge / push / cleanup:`$ws-finish`
|
|
56
56
|
- handoff / archive summary:`$ws-handoff`
|
|
57
57
|
- 新需求或中大型变更,且存在多条待确认问题 / 用户要求逐条多轮沟通:`$ws-intake`
|
|
58
|
-
- 需要先出设计方案(design
|
|
59
|
-
- 需要更新规范/验收标准(必须先过 review):`$ws-
|
|
58
|
+
- 需要先出设计方案(design 作为 plan 阶段一部分):`$ws-plan`
|
|
59
|
+
- 需要更新规范/验收标准(必须先过 req-review):`$ws-req-change`
|
|
60
60
|
- 中大型实现、需要方案、需要 change/worktree,且需求已经冻结:`$ws-plan`
|
|
61
61
|
- 小步明确实现/修复/配置调整:`$ws-dev`(若是 simple/local 单点修复,且用户明确希望走轻量入口,可显式进入 `$ws-dev-lite`)
|
|
62
62
|
4) 若任务意图或归因不明确:
|
|
@@ -81,10 +81,14 @@ description: 默认 workflow bootstrap/router:先读真值,再路由到正
|
|
|
81
81
|
- 否则:
|
|
82
82
|
- `Next:` 进入对应主 skill
|
|
83
83
|
- 然后在同一轮中继续遵循对应 skill 的契约
|
|
84
|
-
7) 路由约束:
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
84
|
+
7) 路由约束:
|
|
85
|
+
- router 自己不是实现阶段;不要在给出 route 之前直接改代码
|
|
86
|
+
- 除非用户只想听判断结果,否则给出 route 后应继续按对应 skill 的规则推进
|
|
87
|
+
- 一次只选择一个主 route;不要把 `ws-plan` / `ws-dev` / `ws-review` / `ws-finish` 混成并行终态
|
|
88
|
+
- **上下文先于判决**:路由 `direct_implementation` 前必须先收集项目上下文——具体检查:`git status --porcelain`(已改动文件数)、`git diff --stat`(改动行范围)。仅当改动文件数 ≤ 3 且改动总行数 ≤ 100 且验证入口明确时,才可判 direct。
|
|
89
|
+
- **Subagent 不可用时**:降级为当前 agent 直接执行,但必须在 evidence 中记录降级原因
|
|
90
|
+
- **上下文先于判决**:路由 `direct_implementation` 前必须先收集项目上下文——`git status --porcelain`(已改动文件数)、`git diff --stat`(改动行范围)。仅当改动文件数 ≤ 3 且改动总行数 ≤ 100 且验证入口明确时,才可判 direct。
|
|
91
|
+
- Subagent 不可用时的降级路径:`ready-for-dev` → 当前 agent 直接执行 ws-dev;`in-progress` → 当前 agent 自审(evaluate-optimize 1 轮);`review` → 当前 agent 本地 review(不阻断)。降级时必须在 evidence 中记录降级原因
|
|
88
92
|
8) 若执行过程中发现复杂度升高:
|
|
89
93
|
- 从 `$ws-dev` 回退到 `$ws-plan`
|
|
90
94
|
- 从 `$ws-plan` 回退到 `$ws-intake`(当发现需求并未冻结)
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: ws-commit
|
|
3
|
-
description: `aiws
|
|
3
|
+
description: `aiws commit` 的薄包装入口
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# ws-commit
|
|
7
7
|
|
|
8
|
-
`aiws
|
|
8
|
+
`aiws commit` 的薄包装入口。
|
|
9
9
|
|
|
10
10
|
```bash
|
|
11
11
|
if [[ -x "./node_modules/.bin/aiws" ]]; then
|
|
12
|
-
./node_modules/.bin/aiws
|
|
12
|
+
./node_modules/.bin/aiws commit
|
|
13
13
|
elif command -v aiws >/dev/null 2>&1; then
|
|
14
|
-
aiws
|
|
14
|
+
aiws commit
|
|
15
15
|
else
|
|
16
|
-
npx @aipper/aiws
|
|
16
|
+
npx @aipper/aiws commit
|
|
17
17
|
fi
|
|
18
18
|
```
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: ws-deliver
|
|
3
|
-
description: `aiws
|
|
3
|
+
description: `aiws deliver` 的薄包装入口
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# ws-deliver
|
|
7
7
|
|
|
8
|
-
`aiws
|
|
8
|
+
`aiws deliver` 的薄包装入口。
|
|
9
9
|
|
|
10
10
|
```bash
|
|
11
11
|
if [[ -x "./node_modules/.bin/aiws" ]]; then
|
|
12
|
-
./node_modules/.bin/aiws
|
|
12
|
+
./node_modules/.bin/aiws deliver
|
|
13
13
|
elif command -v aiws >/dev/null 2>&1; then
|
|
14
|
-
aiws
|
|
14
|
+
aiws deliver
|
|
15
15
|
else
|
|
16
|
-
npx @aipper/aiws
|
|
16
|
+
npx @aipper/aiws deliver
|
|
17
17
|
fi
|
|
18
18
|
```
|
|
@@ -43,6 +43,17 @@ description: 开发(按需求实现并验证;适用于任何需要修改代
|
|
|
43
43
|
- 已有计划:先 `$ws-plan-verify`,通过后进入实现。
|
|
44
44
|
- `$ws-plan` 已创建 worktree:直接在该 worktree 中继续。
|
|
45
45
|
|
|
46
|
+
### 1.5 Design Gate(入口检查)
|
|
47
|
+
|
|
48
|
+
在进入实现前,先验证绑定工件是否完整:
|
|
49
|
+
|
|
50
|
+
- 若计划或实际改动超过 2 个文件:**必须**检查 `changes/<change-id>/` 下是否存在 `proposal.md` 和 `tasks.md`
|
|
51
|
+
- 若缺失:**阻断**并输出信息 `Design Gate: proposal.md and tasks.md required for multi-file implementations. Run $ws-plan first.`
|
|
52
|
+
- 若为单文件/小改动(≤2 文件):此检查为 advisory 级别,缺失仅在输出中提示但不阻断
|
|
53
|
+
- Design Gate 检查结果需记录在输出中,作为实现入口证据
|
|
54
|
+
|
|
55
|
+
Design Gate 通过后,继续进入变更归因与实现。
|
|
56
|
+
|
|
46
57
|
### 2. 建立变更归因
|
|
47
58
|
|
|
48
59
|
- 若 `git status --porcelain` 仅有计划/工件文件,属于预期行为,继续即可。
|
|
@@ -60,9 +71,28 @@ description: 开发(按需求实现并验证;适用于任何需要修改代
|
|
|
60
71
|
- 根据 review 结果决定 fix 或收敛 evidence
|
|
61
72
|
- **Inline escape hatch**:如果用户明确说"你直接改"或"do it inline",主 session 可直接写代码,但必须落盘 evidence 记录理由
|
|
62
73
|
|
|
74
|
+
### 3.1 自我修正循环(evaluate-optimize)
|
|
75
|
+
|
|
76
|
+
收到 sub-agent 或自行产出实现后,执行自我修正循环:
|
|
77
|
+
|
|
78
|
+
1. **Evaluate** — 检查实现质量:
|
|
79
|
+
- lint / typecheck 是否通过
|
|
80
|
+
- 是否遵循现有代码模式(文件结构、命名约定、错误处理风格)
|
|
81
|
+
- 是否有明显 bug 或边界缺失
|
|
82
|
+
2. **Optimize** — 修复发现的问题(最多 2 轮)
|
|
83
|
+
- 每轮修复后重新 evaluate
|
|
84
|
+
- 若 2 轮后仍有问题 → escalate 到 `$ws-review`
|
|
85
|
+
3. **TDD 优先** — 对于中大型改动,优先按 RED→GREEN→REFACTOR 顺序:
|
|
86
|
+
- RED:先写一个会失败的测试
|
|
87
|
+
- GREEN:实现最小代码让测试通过
|
|
88
|
+
- REFACTOR:在测试保护下重构
|
|
89
|
+
|
|
90
|
+
注意:TDD 在简单修复时不强制,但对新增功能/中等以上复杂度变更建议遵循。
|
|
91
|
+
|
|
63
92
|
### 4. 其他规则
|
|
64
93
|
|
|
65
94
|
- 需求调整:先 `$ws-req-review` → 确认后 `$ws-req-change`
|
|
95
|
+
- **TDD 约束**:新增功能必须补测试(RED→GREEN→REFACTOR);bug fix 至少补一条回归测试
|
|
66
96
|
- 最小改动:每处改动必须归因到 `REQUIREMENTS.md` 或 `issues/problem-issues.csv`
|
|
67
97
|
- 验证:运行 `AI_WORKSPACE.md` 声明的命令;未运行不声称已运行
|
|
68
98
|
- 多步任务:使用 `update_plan` 工具跟踪状态
|
|
@@ -1,18 +1,22 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: ws-finish
|
|
3
|
-
description: `aiws
|
|
3
|
+
description: `aiws finish` 的收尾入口(finish_resume_required)
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# ws-finish
|
|
7
7
|
|
|
8
|
-
`aiws
|
|
8
|
+
`aiws finish` 的收尾入口。
|
|
9
|
+
|
|
10
|
+
关键契约:
|
|
11
|
+
- 若 `aiws change status <change-id>` 输出 `governance_rule: finish_resume_required`,继续执行 `aiws change finish <change-id> --push`
|
|
12
|
+
- 普通 finish 的 `validate/evidence/state` 仍应在 `change/<change-id>` worktree 完成,不要在目标 worktree 里跑 `aiws validate . --stamp`
|
|
9
13
|
|
|
10
14
|
```bash
|
|
11
15
|
if [[ -x "./node_modules/.bin/aiws" ]]; then
|
|
12
|
-
./node_modules/.bin/aiws
|
|
16
|
+
./node_modules/.bin/aiws finish
|
|
13
17
|
elif command -v aiws >/dev/null 2>&1; then
|
|
14
|
-
aiws
|
|
18
|
+
aiws finish
|
|
15
19
|
else
|
|
16
|
-
npx @aipper/aiws
|
|
20
|
+
npx @aipper/aiws finish
|
|
17
21
|
fi
|
|
18
22
|
```
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: ws-handoff
|
|
3
|
-
description: `aiws
|
|
3
|
+
description: `aiws handoff` 的薄包装入口
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# ws-handoff
|
|
7
7
|
|
|
8
|
-
`aiws
|
|
8
|
+
`aiws handoff` 的薄包装入口。
|
|
9
9
|
|
|
10
10
|
```bash
|
|
11
11
|
if [[ -x "./node_modules/.bin/aiws" ]]; then
|
|
12
|
-
./node_modules/.bin/aiws
|
|
12
|
+
./node_modules/.bin/aiws handoff
|
|
13
13
|
elif command -v aiws >/dev/null 2>&1; then
|
|
14
|
-
aiws
|
|
14
|
+
aiws handoff
|
|
15
15
|
else
|
|
16
|
-
npx @aipper/aiws
|
|
16
|
+
npx @aipper/aiws handoff
|
|
17
17
|
fi
|
|
18
18
|
```
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ws-migrate
|
|
3
|
+
description: `aiws migrate` 的薄包装入口
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# ws-migrate
|
|
7
|
+
|
|
8
|
+
`aiws migrate` 的薄包装入口。
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
if [[ -x "./node_modules/.bin/aiws" ]]; then
|
|
12
|
+
./node_modules/.bin/aiws migrate
|
|
13
|
+
elif command -v aiws >/dev/null 2>&1; then
|
|
14
|
+
aiws migrate
|
|
15
|
+
else
|
|
16
|
+
npx @aipper/aiws migrate
|
|
17
|
+
fi
|
|
18
|
+
```
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: ws-plan-verify
|
|
3
|
-
description: `aiws
|
|
3
|
+
description: `aiws plan-verify` 的薄包装入口
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# ws-plan-verify
|
|
7
7
|
|
|
8
|
-
`aiws
|
|
8
|
+
`aiws plan-verify` 的薄包装入口。
|
|
9
9
|
|
|
10
10
|
```bash
|
|
11
11
|
if [[ -x "./node_modules/.bin/aiws" ]]; then
|
|
12
|
-
./node_modules/.bin/aiws
|
|
12
|
+
./node_modules/.bin/aiws plan-verify
|
|
13
13
|
elif command -v aiws >/dev/null 2>&1; then
|
|
14
|
-
aiws
|
|
14
|
+
aiws plan-verify
|
|
15
15
|
else
|
|
16
|
-
npx @aipper/aiws
|
|
16
|
+
npx @aipper/aiws plan-verify
|
|
17
17
|
fi
|
|
18
18
|
```
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ws-pull
|
|
3
|
+
description: `aiws pull` 的薄包装入口
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# ws-pull
|
|
7
|
+
|
|
8
|
+
`aiws pull` 的薄包装入口。
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
if [[ -x "./node_modules/.bin/aiws" ]]; then
|
|
12
|
+
./node_modules/.bin/aiws pull
|
|
13
|
+
elif command -v aiws >/dev/null 2>&1; then
|
|
14
|
+
aiws pull
|
|
15
|
+
else
|
|
16
|
+
npx @aipper/aiws pull
|
|
17
|
+
fi
|
|
18
|
+
```
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ws-push
|
|
3
|
+
description: `aiws push` 的薄包装入口
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# ws-push
|
|
7
|
+
|
|
8
|
+
`aiws push` 的薄包装入口。
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
if [[ -x "./node_modules/.bin/aiws" ]]; then
|
|
12
|
+
./node_modules/.bin/aiws push
|
|
13
|
+
elif command -v aiws >/dev/null 2>&1; then
|
|
14
|
+
aiws push
|
|
15
|
+
else
|
|
16
|
+
npx @aipper/aiws push
|
|
17
|
+
fi
|
|
18
|
+
```
|
|
@@ -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
|
|
3
|
+
description: `aiws verify-bc` 的薄包装入口
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# ws-verify-before-complete
|
|
7
7
|
|
|
8
|
-
`aiws
|
|
8
|
+
`aiws verify-bc` 的薄包装入口。
|
|
9
9
|
|
|
10
10
|
```bash
|
|
11
11
|
if [[ -x "./node_modules/.bin/aiws" ]]; then
|
|
12
|
-
./node_modules/.bin/aiws
|
|
12
|
+
./node_modules/.bin/aiws verify-bc
|
|
13
13
|
elif command -v aiws >/dev/null 2>&1; then
|
|
14
|
-
aiws
|
|
14
|
+
aiws verify-bc
|
|
15
15
|
else
|
|
16
|
-
npx @aipper/aiws
|
|
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` 则先按
|
|
40
|
-
- 已 archive 的 `change/<change-id>`
|
|
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 到
|
|
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>` 建立分支,再在该上下文内写
|
|
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
|
-
- 在工作区创建
|
|
63
|
-
-
|
|
64
|
-
-
|
|
65
|
-
-
|
|
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
|
-
-
|
|
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
|
-
- 委托分析先落到
|
|
95
|
-
- patch 草案先落到
|
|
96
|
-
- 交付前建议执行:`aiws change evidence <change-id>`,让 `delivery-summary` 与 `collaboration-summary` 一起落到
|
|
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/... 或 .
|
|
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` 必须引用
|
|
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 如需委托分析,写明预计产物;例如
|
|
51
|
+
- <!-- WS:TODO 如需委托分析,写明预计产物;例如 `.aiws/changes/<change-id>/analysis/research-a.md` -->
|
|
52
52
|
- `patches/`:
|
|
53
|
-
- <!-- WS:TODO 如需外部 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
|
-
-
|
|
107
|
-
-
|
|
108
|
-
-
|
|
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
|
-
-
|
|
111
|
-
- 临时(可忽略入库):`.
|
|
112
|
-
-
|
|
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 在
|
|
13
|
-
- [ ] 0.5 生成
|
|
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 同步
|
|
21
|
-
- [ ] 1.3 记录到
|
|
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 若使用委托分析:把结果落盘到
|
|
31
|
-
- [ ] 2A.2 若使用 patch 草案:把结果落盘到
|
|
32
|
-
- [ ] 2A.3 若存在多审查者:把审查结果落盘到
|
|
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 证据落盘到 `.
|
|
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",".
|
|
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"
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -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",.
|
|
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 = ".
|
|
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 ".
|
|
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 .
|
|
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 ".
|
|
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=".
|
|
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,
|