Files
workutils/docs/superpowers/plans/2026-08-04-ai-test-target-ref-and-async-race.md
T
2026-08-04 18:10:12 +08:00

85 lines
5.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# AI 单测目标引用与异步竞态修复实施计划
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** 让 AI 单测插件稳定按 `master...DEV_1156339215001460262` 分析真实 `ft-loancapital-core` 增量,并阻止较早的项目加载结果覆盖用户后来选择的项目。
**Architecture:** 将 Git 比较终点从隐式 `HEAD` 提升为 `AiTestRequest.targetRef`,增量分析和临时 worktree 均解析同一目标引用;工作区改动仅允许叠加在目标引用等于当前 `HEAD` 的场景。项目元数据加载使用单调递增的请求令牌,只有最新令牌可以更新 JavaFX 控件。
**Tech Stack:** Java 17(WorkUtils 运行时)、JavaFX、Spring、Maven、JUnit 5、Mockito、Git CLI
## Global Constraints
- 真实业务项目使用 `D:/bestpay-srdcloud/ft-loancapital-core`;该目录不存在时集成回归测试使用 JUnit assumption 跳过。
- 默认基线为 `master`;目标引用可填写分支或 Commit,并对当前真实场景使用 `DEV_1156339215001460262`。
- 不修改真实业务仓库、不切换其分支、不提交其文件。
- 不触碰 WorkUtils 中现有未跟踪的审计文档、截图和 SQL 文件。
- 全程单线程实施,不使用子代理。
---
### Task 1: 显式 baseline 与 targetRef 的增量分析
**Files:**
- Modify: `src/main/java/com/example/workutils/biz/aitest/git/GitIncrementAnalyzer.java`
- Modify: `src/main/java/com/example/workutils/biz/aitest/application/AiTestRequest.java`
- Modify: `src/main/java/com/example/workutils/biz/aitest/application/AiTestWorkflow.java`
- Modify: `src/main/java/com/example/workutils/biz/aitest/git/TemporaryWorktreeManager.java`
- Test: `src/test/java/com/example/workutils/biz/aitest/git/GitIncrementAnalyzerTest.java`
- Test: `src/test/java/com/example/workutils/biz/aitest/git/TemporaryWorktreeManagerTest.java`
- Test: `src/test/java/com/example/workutils/biz/aitest/application/AiTestWorkflowTest.java`
**Interfaces:**
- Produces: `GitIncrementAnalyzer.analyze(Path, String baseline, String targetRef, boolean includeWorkingTree)`
- Produces: `TemporaryWorktreeManager.create(Path, String targetRef, boolean includeWorkingTree)`
- Produces: `AiTestRequest.targetRef()`
- [ ] **Step 1: 写失败测试**:构造 `master` 与未检出的 `DEV_*` 分支,断言分析结果来自 DEV 而不是当前 HEAD;断言临时 worktree 检出目标引用。
- [ ] **Step 2: 运行聚焦测试确认 RED**:`mvn -Dtest=GitIncrementAnalyzerTest,TemporaryWorktreeManagerTest,AiTestWorkflowTest test`,预期因新签名或仍使用 HEAD 而失败。
- [ ] **Step 3: 最小实现**:解析 baseline/target commit,以其 merge-base 到 target commit 生成 patch;workflow 将 request 的 targetRef 贯穿到分析和 worktree。
- [ ] **Step 4: 运行聚焦测试确认 GREEN**:同一 Maven 命令全部通过。
### Task 2: 真实 ft-loancapital-core 回归
**Files:**
- Create: `src/test/java/com/example/workutils/biz/aitest/project/FtLoanCapitalCoreRegressionTest.java`
**Interfaces:**
- Consumes: `MavenProjectAnalyzer.analyze(Path)`
- Consumes: `GitIncrementAnalyzer.analyze(Path, "master", "DEV_1156339215001460262", false)`
- [ ] **Step 1: 写真实只读回归测试**:断言解析到 `ft-loancapital-core-start`,并断言 master 到 DEV 的增量包含已知 service Java 文件及新增行。
- [ ] **Step 2: 运行测试确认结果**:`mvn -Dtest=FtLoanCapitalCoreRegressionTest test`;真实仓库存在时必须通过,不存在时仅跳过。
### Task 3: 项目加载的最新请求获胜
**Files:**
- Create: `src/main/java/com/example/workutils/biz/aitest/LatestRequestGate.java`
- Modify: `src/main/java/com/example/workutils/biz/aitest/AiTestPane.java`
- Create: `src/test/java/com/example/workutils/biz/aitest/LatestRequestGateTest.java`
- Modify: `src/test/java/com/example/workutils/biz/aitest/AiTestPaneArchitectureTest.java`
**Interfaces:**
- Produces: `LatestRequestGate.next()` 返回请求令牌。
- Produces: `LatestRequestGate.isLatest(long)` 仅对最后发出的令牌返回 true。
- [ ] **Step 1: 写失败测试**:先申请旧令牌再申请新令牌,断言旧令牌失效、新令牌有效;架构测试断言项目加载成功与失败回调都经过 gate。
- [ ] **Step 2: 运行聚焦测试确认 RED**:`mvn -Dtest=LatestRequestGateTest,AiTestPaneArchitectureTest test`,预期类不存在或 Pane 未使用 gate。
- [ ] **Step 3: 最小实现**:`loadProject` 发出令牌,清空旧模块;后台成功或失败回到 FX 线程时仅允许最新请求更新 UI。
- [ ] **Step 4: 运行聚焦测试确认 GREEN**:同一 Maven 命令全部通过。
### Task 4: UI 参数与完整验证
**Files:**
- Modify: `src/main/java/com/example/workutils/biz/aitest/AiTestPane.java`
- Modify: `src/test/java/com/example/workutils/biz/aitest/AiTestPaneArchitectureTest.java`
**Interfaces:**
- UI 提供 `baselineField`(默认 `master`)与 `targetRefField`(默认 `HEAD`,加载项目后显示当前分支)。
- [ ] **Step 1: 写失败测试**:断言 Pane 存在独立 targetRef 字段,且 baseline 默认 master。
- [ ] **Step 2: 最小实现**:把 targetRef 写入 `AiTestRequest`,校验 baseline、targetRef、项目和模块均已选择。
- [ ] **Step 3: 运行 AI 单测插件测试**:`mvn -Dtest='com.example.workutils.biz.aitest.**' test`。
- [ ] **Step 4: 运行全量验证**:`mvn test`、`mvn -DskipTests package`、`git diff --check`。
- [ ] **Step 5: 检查 `git status` 仅包含本次文件和用户原有未跟踪文件,然后提交到 WorkUtils `master`。**