agentflowctl 0.17.0 → 0.17.1
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/README.md +2 -2
- package/dist/engine.js +35 -5
- package/dist/planReview.js +1 -0
- package/dist/schemas.js +1 -1
- package/dist/tasks.js +14 -0
- package/package.json +1 -1
- package/prompts/implement-direct.md +1 -1
- package/prompts/implement-tests.md +3 -4
- package/prompts/plan-review-group.md +1 -1
- package/prompts/plan-review.md +1 -1
- package/prompts/plan.md +1 -1
- package/prompts/task-review.md +2 -0
package/README.md
CHANGED
|
@@ -33,7 +33,7 @@ npx agentflowctl run --req-file ./requirement.md
|
|
|
33
33
|
## 執行時會發生什麼
|
|
34
34
|
|
|
35
35
|
1. agent 整理需求與驗收條件,接著寫計畫,交給其他 agent 審查。
|
|
36
|
-
2. 依計畫逐個任務寫出會失敗的測試,再由另一位 agent 實作到測試通過;每個任務都會經過審查與驗證。計畫 agent 會依改動內容在任務標記 `tdd
|
|
36
|
+
2. 依計畫逐個任務寫出會失敗的測試,再由另一位 agent 實作到測試通過;每個任務都會經過審查與驗證。計畫 agent 會依改動內容在任務標記 `tdd`:建置流程、設定、文件、型別、純重構,以及實作前就會通過的特徵化測試,會略過紅綠燈直接實作,改由任務審查與驗證把關。描述寫明不要求紅燈卻沒標 `tdd: false` 的計畫不會通過。已定案的計畫若仍帶著這個衝突,執行到該任務時仍會寫測試,但測試一開始就通過也算完成,不會再要求紅燈、也不會因此讓 run 失敗。專案沒有測試框架時,所有任務都略過紅綠燈,也不跑 `test` 檢查。
|
|
37
37
|
3. 全部任務完成後,再執行專案檢查與整體程式碼審查。未通過的項目會交回修正。
|
|
38
38
|
4. 有 `origin` 時會推送分支;若 `gh` 可用,會嘗試建立 PR。沒有 `origin` 時,完成的分支留在本機。
|
|
39
39
|
|
|
@@ -255,7 +255,7 @@ pnpm release minor # 確認後建立 v0.x+1.0 的 GitHub Release
|
|
|
255
255
|
pnpm release 1.0.0 # 指定版本,必須大於目前最新的 tag
|
|
256
256
|
```
|
|
257
257
|
|
|
258
|
-
腳本會先檢查目前在 `main`、工作區乾淨、與 `origin/main` 同步、`gh` 已登入、新 tag 不存在,再跑 typecheck、test、build(通過只顯示 ✓,失敗才印出完整輸出),列出自上個 tag 以來的 commit 並等你輸入 `y`
|
|
258
|
+
腳本會先檢查目前在 `main`、工作區乾淨、與 `origin/main` 同步、`gh` 已登入、新 tag 不存在,再跑 typecheck、test、build(通過只顯示 ✓,失敗才印出完整輸出),列出自上個 tag 以來的 commit 並等你輸入 `y` 確認,接著把 `package.json` 的 `version` 更新為新版號、commit 並 push 到 `main`,再用 `gh release create --generate-notes` 建立 Release。npm 由 Release 觸發的 `npm-publish.yml` 發布。
|
|
259
259
|
|
|
260
260
|
## 更多文件
|
|
261
261
|
|
package/dist/engine.js
CHANGED
|
@@ -17,7 +17,7 @@ import { AcceptanceList, ArbiterResult, ConsistentReviewResult, RepoConfig, Task
|
|
|
17
17
|
import { addRetry, addSubstitution, addUsage, agentRuns, saveRun } from "./store.js";
|
|
18
18
|
import { clearModelReviewFailure, clearModelReviewStage, recordModelReviewFailure, selectModel } from "./modelSelection.js";
|
|
19
19
|
import { applyReviewVerdicts, dirtyGroups, dirtyTaskIds, extractPlanEvidence, groupReviewerCount, layeredReview, neighborTasks, planContentKey, planOverview, planReviewIndex, readPendingArbitration, readPlanReviewState, repliesForTasks, reviewFingerprint, roundProgress, } from "./planReview.js";
|
|
20
|
-
import { orderTasks, taskAcceptance, validateTaskComplexity } from "./tasks.js";
|
|
20
|
+
import { descriptionWaivesRed, orderTasks, taskAcceptance, validateTaskComplexity, validateTddFlag } from "./tasks.js";
|
|
21
21
|
import { readJsonFile, renderPrompt, tail } from "./util.js";
|
|
22
22
|
// ───────────────────────── 共用工具 ─────────────────────────
|
|
23
23
|
const info = (run, msg) => console.log(`[${run.id}] ${msg}`);
|
|
@@ -204,6 +204,27 @@ function hasTestFramework() {
|
|
|
204
204
|
function taskUsesTdd(task, framework) {
|
|
205
205
|
return framework && task.tdd !== false;
|
|
206
206
|
}
|
|
207
|
+
/** 已定案的任務寫明不要求紅燈:仍寫測試,但通過也算完成紅燈階段。 */
|
|
208
|
+
function testsRedGuidance(testCmd, waiveRed) {
|
|
209
|
+
if (!waiveRed) {
|
|
210
|
+
return {
|
|
211
|
+
roleGoal: "你的測試要精準描述任務要新增的行為,並且在功能實作前確實失敗;之後會由另一位工程師實作到通過,而且對方不能修改你的測試。",
|
|
212
|
+
redGuidance: [
|
|
213
|
+
"3. 測試必須驗證這個任務要新增的行為,並且因為功能尚未實作而**失敗**。",
|
|
214
|
+
`4. 可以先執行本任務相關的測試,確認失敗原因是斷言或找不到尚未實作的模組,而不是語法錯誤或測試本身寫錯。外部流程會再執行 \`${testCmd}\` 驗證紅燈,不需要自行重跑全套測試。`,
|
|
215
|
+
].join("\n"),
|
|
216
|
+
verifyNote: "驗證測試是否失敗",
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
return {
|
|
220
|
+
roleGoal: "這個任務不要求紅燈。請直接寫出鎖定既有行為的測試;測試一開始就通過是預期結果,不要停下來,也不要為了製造失敗而改產品程式。",
|
|
221
|
+
redGuidance: [
|
|
222
|
+
"3. 這個任務的描述已寫明不要求紅燈。請寫出鎖定既有行為的測試;測試一開始就通過是預期結果,不要為了製造失敗而改產品程式,也不要停下來不寫。",
|
|
223
|
+
`4. 可以先執行本任務相關的測試,確認它們能跑完。外部流程會再執行 \`${testCmd}\`,通過即可,不需要自行重跑全套測試。`,
|
|
224
|
+
].join("\n"),
|
|
225
|
+
verifyNote: "確認測試能跑完。這個任務不要求測試失敗",
|
|
226
|
+
};
|
|
227
|
+
}
|
|
207
228
|
function loadOrderedTasks(run) {
|
|
208
229
|
const r = readJsonFile(flowFile(run, "tasks.ordered.json"), TaskList);
|
|
209
230
|
if (!r.ok)
|
|
@@ -274,6 +295,9 @@ function validatePlan(run) {
|
|
|
274
295
|
const complexityError = validateTaskComplexity(tasks.data, run.modelMode ?? "balanced");
|
|
275
296
|
if (complexityError)
|
|
276
297
|
return complexityError;
|
|
298
|
+
const tddError = validateTddFlag(tasks.data);
|
|
299
|
+
if (tddError)
|
|
300
|
+
return tddError;
|
|
277
301
|
return orderTasks(tasks.data, new Set(ids));
|
|
278
302
|
}
|
|
279
303
|
function acceptPlan(run, ordered) {
|
|
@@ -790,6 +814,7 @@ async function implementStage(run) {
|
|
|
790
814
|
if (!acceptance.ok)
|
|
791
815
|
throw new Error(acceptance.error);
|
|
792
816
|
const acceptanceJson = JSON.stringify(taskAcceptance(task, acceptance.data), null, 2);
|
|
817
|
+
const waiveRed = task.tdd !== false && descriptionWaivesRed(task.description);
|
|
793
818
|
if (run.taskPhase === "review")
|
|
794
819
|
return taskReviewStep(run, task, progress, taskJson, acceptanceJson);
|
|
795
820
|
if (run.taskPhase === "verify")
|
|
@@ -808,9 +833,12 @@ async function implementStage(run) {
|
|
|
808
833
|
if (run.taskPhase === "tests") {
|
|
809
834
|
const key = `${task.id}:tests`;
|
|
810
835
|
info(run, `🧪 [${progress}] 撰寫測試(${agents.tests})`);
|
|
836
|
+
if (waiveRed && existsSync(flowFile(run, "feedback.md")) && readFileSync(flowFile(run, "feedback.md"), "utf8").includes("請撰寫會因功能尚未實作而失敗的測試")) {
|
|
837
|
+
rmSync(flowFile(run, "feedback.md"));
|
|
838
|
+
}
|
|
811
839
|
const before = await headCommit(repo);
|
|
812
840
|
const snap = snapshotPlan(run, LOCKED_FILES);
|
|
813
|
-
const outcome = await agentStep(run, agents.tests, `${task.id}-tests`, renderPrompt("implement-tests", { task: taskJson, acceptance: acceptanceJson, testPattern: cfg.testPattern, testCmd }), { kind: "write", reset: async () => { await resetTo(repo, before); restorePlan(run, snap); } });
|
|
841
|
+
const outcome = await agentStep(run, agents.tests, `${task.id}-tests`, renderPrompt("implement-tests", { task: taskJson, acceptance: acceptanceJson, testPattern: cfg.testPattern, testCmd, ...testsRedGuidance(testCmd, waiveRed) }), { kind: "write", reset: async () => { await resetTo(repo, before); restorePlan(run, snap); } });
|
|
814
842
|
const { r, agent: testsAuthor } = outcome;
|
|
815
843
|
const tampered = restorePlan(run, snap);
|
|
816
844
|
if (!r.ok) {
|
|
@@ -830,7 +858,7 @@ async function implementStage(run) {
|
|
|
830
858
|
return retry(run, key, `沒有新增或修改任何符合 /${cfg.testPattern}/ 的測試檔。`, "implement", "tests_not_written");
|
|
831
859
|
}
|
|
832
860
|
const red = await runCommand(target(run, `${task.id}-red`, CMD_AGENT), testCmd);
|
|
833
|
-
if (red.ok) {
|
|
861
|
+
if (red.ok && !waiveRed) {
|
|
834
862
|
await resetTo(repo, before);
|
|
835
863
|
return retry(run, key, "測試在功能尚未實作前就全部通過,代表測試沒有驗證到新行為。請撰寫會因功能尚未實作而失敗的測試。", "implement", "tests_not_red");
|
|
836
864
|
}
|
|
@@ -839,8 +867,10 @@ async function implementStage(run) {
|
|
|
839
867
|
await resetTo(repo, before);
|
|
840
868
|
return retry(run, key, handoffError, "implement", "handoff_invalid");
|
|
841
869
|
}
|
|
842
|
-
writeFileSync(flowFile(run, "red-output.txt"), red.
|
|
843
|
-
|
|
870
|
+
writeFileSync(flowFile(run, "red-output.txt"), waiveRed && red.ok
|
|
871
|
+
? "此任務不要求紅燈,測試在既有實作下已經通過。不要為了製造失敗而修改產品程式;若沒有其他必須的實作,保持現況即可。"
|
|
872
|
+
: red.output);
|
|
873
|
+
info(run, waiveRed && red.ok ? `✅ [${progress}] 測試已寫好(此任務不要求紅燈)` : `🔴 [${progress}] 測試如預期失敗`);
|
|
844
874
|
return { ...succeed(run, key, "implement"), taskPhase: "code", taskBase: before, testsCommit: commit, lastTestsAuthor: testsAuthor };
|
|
845
875
|
}
|
|
846
876
|
// ── 綠燈:實作到測試通過,而且不可動測試 ──
|
package/dist/planReview.js
CHANGED
|
@@ -192,6 +192,7 @@ export function taskFingerprint(task, acceptance, planMd) {
|
|
|
192
192
|
complexity: task.complexity ?? null,
|
|
193
193
|
dependsOn: task.dependsOn,
|
|
194
194
|
acceptance: task.acceptance.map((id) => ({ id, description: byId.get(id) ?? "" })),
|
|
195
|
+
tdd: task.tdd ?? null,
|
|
195
196
|
evidence: extractPlanEvidence(planMd, [task.id]),
|
|
196
197
|
});
|
|
197
198
|
}
|
package/dist/schemas.js
CHANGED
|
@@ -74,7 +74,7 @@ export const TaskItem = z.object({
|
|
|
74
74
|
dependsOn: z.array(z.string()).default([]),
|
|
75
75
|
acceptance: z.array(z.string()).min(1, "每個任務至少要對應一條驗收條件"),
|
|
76
76
|
complexity: z.enum(["low", "medium", "high"]).optional(),
|
|
77
|
-
/** false
|
|
77
|
+
/** false=這個任務不適合先寫會失敗的測試(建置流程、設定、文件、純重構、實作前就會通過的特徵化測試等),略過紅燈直接實作;沒寫視為 true。描述寫明不要求紅燈時必須為 false */
|
|
78
78
|
tdd: z.boolean().optional(),
|
|
79
79
|
});
|
|
80
80
|
/** Agent 在 plan 階段產出的 .flow/tasks.json */
|
package/dist/tasks.js
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
/** 一個任務最多做兩件事:對應的驗收條件超過這個數量就要再拆 */
|
|
2
2
|
export const MAX_TASK_ACCEPTANCE = 2;
|
|
3
|
+
/** 描述已明確放棄紅燈。新計畫必須把 tdd 標成 false;已定案的任務則仍寫測試,但不要求先失敗。 */
|
|
4
|
+
const RED_WAIVED = /不要求紅燈|不必紅燈|不需紅燈|無需紅燈|不用紅燈|略過紅燈|略過紅綠燈/;
|
|
5
|
+
export function descriptionWaivesRed(description) {
|
|
6
|
+
return RED_WAIVED.test(description);
|
|
7
|
+
}
|
|
8
|
+
/** 描述與 tdd 矛盾時退回計畫:寫明不要求紅燈就必須標 false。 */
|
|
9
|
+
export function validateTddFlag(tasks) {
|
|
10
|
+
const conflicts = tasks.filter((task) => task.tdd !== false && descriptionWaivesRed(task.description));
|
|
11
|
+
if (!conflicts.length)
|
|
12
|
+
return undefined;
|
|
13
|
+
return conflicts
|
|
14
|
+
.map((task) => `${task.id} 的描述寫明不要求紅燈,但 tdd 不是 false。這種任務在實作前就會通過,請改成 "tdd": false。`)
|
|
15
|
+
.join("\n");
|
|
16
|
+
}
|
|
3
17
|
/** adaptive 的新計畫必須明確標註難度;舊 run 仍可讀取缺少欄位的 task。 */
|
|
4
18
|
export function validateTaskComplexity(tasks, mode) {
|
|
5
19
|
if (mode === "balanced")
|
package/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<role>
|
|
2
|
-
你是任務實作者,負責完成一個**不走 TDD**
|
|
2
|
+
你是任務實作者,負責完成一個**不走 TDD** 的任務。這個任務不適合先寫會失敗的測試(例如建置流程、設定、文件、型別、純重構,或鎖定既有行為的特徵化測試),或專案沒有測試框架,所以沒有紅燈測試可依循。你要依任務描述與驗收條件,用符合專案風格的最小改動完成它。若任務是補一個現有實作下就會通過的測試,寫出該測試即可,不要為了製造失敗而去改產品程式。
|
|
3
3
|
</role>
|
|
4
4
|
|
|
5
5
|
<context>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<role>
|
|
2
|
-
你是測試工程師,在 TDD
|
|
2
|
+
你是測試工程師,在 TDD 的紅燈階段**只寫測試,不寫實作**。{{roleGoal}}
|
|
3
3
|
</role>
|
|
4
4
|
|
|
5
5
|
<context>
|
|
@@ -37,13 +37,12 @@
|
|
|
37
37
|
<steps>
|
|
38
38
|
1. 若 .flow/feedback.md 存在,先閱讀,並依內容調整做法。
|
|
39
39
|
2. 依任務描述撰寫測試,檔名必須符合正規表示式 `{{testPattern}}`。
|
|
40
|
-
|
|
41
|
-
4. 可以先執行本任務相關的測試,確認失敗原因是斷言或找不到尚未實作的模組,而不是語法錯誤或測試本身寫錯。外部流程會再執行 `{{testCmd}}` 驗證紅燈,不需要自行重跑全套測試。
|
|
40
|
+
{{redGuidance}}
|
|
42
41
|
</steps>
|
|
43
42
|
|
|
44
43
|
<constraints>
|
|
45
44
|
- 不可實作功能本身。可以建立讓測試能編譯所需的最小型別或空殼匯出,但不可以有真正的邏輯。
|
|
46
|
-
- 不要執行 git commit
|
|
45
|
+
- 不要執行 git commit(權限設定已禁止),外部流程會提交並{{verifyNote}}。
|
|
47
46
|
- **不可修改** .flow/spec.md、.flow/acceptance.json、.flow/plan.md、.flow/tasks.json、.flow/tasks.ordered.json,修改會被自動還原並視為失敗。若認為規格或驗收條件有誤,請寫進 .flow/handoff-response.json 的 newIssues。
|
|
48
47
|
</constraints>
|
|
49
48
|
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
|
|
47
47
|
<review_focus>
|
|
48
48
|
只看這一群:
|
|
49
|
-
1. 每個任務是否只做一件事(最多兩件),小到一次 TDD
|
|
49
|
+
1. 每個任務是否只做一件事(最多兩件),小到一次 TDD 循環就能完成,而且能寫出實作前會失敗的測試。無法先失敗的(特徵化、實作前就會通過、描述寫明不要求紅燈)必須是 `tdd: false`。只在描述補註、卻留下 `tdd: true` 或沒寫 `tdd`,仍是 `changes_requested`,`note` 要要求改成 `tdd: false`。
|
|
50
50
|
2. 任務描述是否對得上上面的驗收條文。
|
|
51
51
|
3. 對照描述點名、已存在的檔案與難度摘錄,獨立核對 `complexity`。`low` 是沿用既有做法、侷限單一行為且失敗可由局部測試發現;`medium` 包括多模組或介面協調、非典型邊界、相容性或狀態遷移;`high` 包括跨系統契約、架構或資料模型變更、未知的關鍵路徑,或資料遺失、權限、難以回復的風險。摘錄是空的,而且高低估會影響選模時,要求在 .flow/plan.md 該 task 的「## T-<數字>」標題下補上證據。
|
|
52
52
|
4. 做法是否符合那些檔案中已存在者的慣例。
|
package/prompts/plan-review.md
CHANGED
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
<review_focus>
|
|
31
31
|
1. **需求覆蓋**:規格是否完整涵蓋原始需求?有沒有遺漏、誤解,或加入需求沒要求的範圍?
|
|
32
32
|
2. **驗收條件**:每一條是否具體、可以用自動化測試驗證,而且只描述一個行為?把多個行為寫在同一條的,要求拆開。有沒有重要的邊界情況或錯誤處理沒被列入?
|
|
33
|
-
3. **任務拆解**:每個任務是否只做一件事(最多兩件),小到一次 TDD 循環就能完成,而且能寫出「實作前會失敗」的測試(標 `tdd: false`
|
|
33
|
+
3. **任務拆解**:每個任務是否只做一件事(最多兩件),小到一次 TDD 循環就能完成,而且能寫出「實作前會失敗」的測試(標 `tdd: false` 的任務除外:核對它的改動內容確實不適合先寫失敗測試,例如建置流程、設定、文件、型別、純重構,或實作前就會通過的特徵化測試,並有寫明驗收方式;會改變程式行為卻標成 `false` 的,要求改回 `true`。描述寫明不要求紅燈,`tdd` 卻不是 `false` 的,要求改成 `false`)?任務太大、一次要動很多檔案或驗證很多行為的,要求拆成更小的任務。相依順序是否合理?
|
|
34
34
|
同時依 .flow/plan.md 的逐項理由及實際程式碼,獨立核對每個 task 的 `complexity`:分別看影響範圍、技術不確定性與失敗後果,取最高等級。`low` 須是沿用既有做法、侷限單一行為或模組且失敗可由局部測試發現;`medium` 包括多模組或介面協調、非典型邊界、相容性或狀態遷移風險;`high` 包括跨系統契約、架構或資料模型變更、未知的關鍵技術路徑,或資料遺失、權限、難以回復的風險。不要只憑檔案數、程式碼行數或驗收條件數判定。
|
|
35
35
|
理由缺漏、與程式碼不符,或高低估會影響選模時,要求修正;在 `note` 指出 task ID、具體證據、建議等級及須修改的 .flow/plan.md/.flow/tasks.json 部分。不要為缺少高價值證據的細微措辭差異要求修改。
|
|
36
36
|
4. **技術方向**:是否符合專案既有的架構與慣例?有沒有更簡單的做法,或明顯的風險?
|
package/prompts/plan.md
CHANGED
|
@@ -52,7 +52,7 @@
|
|
|
52
52
|
- 每個任務是一個可獨立測試的垂直切片,小到一次 TDD 循環就能完成;只動少數幾個檔案,測試只驗證一兩個行為。
|
|
53
53
|
- `title` 用一句話說出這件事;需要用「並且」「以及」串起來的,就是兩個任務。
|
|
54
54
|
- `description` 寫清楚要動哪些檔案(寫含目錄的路徑,例如 `src/form.ts`,不要只寫檔名)、測試要驗證哪個行為,以及這個任務不做什麼。計畫審查會依這些路徑把任務分群。
|
|
55
|
-
- 依改動內容標記 `tdd`:會改變程式行為、能寫出「在實作前會失敗」的測試的任務標 `true`(預設);改動內容不適合先寫失敗測試的任務標 `false`,這類任務會略過紅燈直接實作,改由任務審查與驗證指令把關。適合標 `false` 的例子:建置流程與打包設定(build、CI、bundler、tsconfig)、依賴與版本設定、文件與 prompt
|
|
55
|
+
- 依改動內容標記 `tdd`:會改變程式行為、能寫出「在實作前會失敗」的測試的任務標 `true`(預設);改動內容不適合先寫失敗測試的任務標 `false`,這類任務會略過紅燈直接實作,改由任務審查與驗證指令把關。適合標 `false` 的例子:建置流程與打包設定(build、CI、bundler、tsconfig)、依賴與版本設定、文件與 prompt 文字、樣式與靜態資源、型別宣告、不改變行為的重構與搬移檔案,以及鎖定既有行為的特徵化測試(實作前就會通過、不要求紅燈、通常不需改產品程式)。能併入相關行為任務的設定或重構,仍請併入,不要獨立成任務。描述寫了「不要求紅燈」卻沒把 `tdd` 設成 `false`,計畫不會通過。標 `false` 時要在 .flow/plan.md 該 task 的節裡寫明理由,以及這個任務要怎麼驗收(例如「`npm run build` 通過」或「新增的測試在現有實作下通過」)。
|
|
56
56
|
- 專案沒有測試框架時,所有任務都會略過 TDD(程式會強制),此時仍請照實標記 `tdd`,並在 `description` 寫清楚驗收方式。
|
|
57
57
|
- 每個任務先檢查預計修改的程式碼,再依「影響範圍、技術不確定性、失敗後果」三個面向判定 `complexity`,取其中最高的等級;不要只憑檔案數、程式碼行數或驗收條件數判定。
|
|
58
58
|
- `low`:沿用現有做法,變更侷限在單一行為或模組,失敗容易由局部測試發現且不影響既有資料或對外契約。
|
package/prompts/task-review.md
CHANGED
|
@@ -35,6 +35,8 @@
|
|
|
35
35
|
2. 是否有明顯的錯誤、邊界情況遺漏、安全問題或效能問題。
|
|
36
36
|
3. 是否符合專案既有的架構與慣例,以及任務說明的範圍(沒有做到一半,也沒有做了其他任務的事)。
|
|
37
37
|
|
|
38
|
+
4. 任務描述寫明不要求紅燈時,測試在既有實作下一開始就通過是允許的。不要因為沒有紅燈、或 `tdd` 不是 `false`,就 `changes_requested`。只審查測試是否鎖定任務描述的行為。
|
|
39
|
+
|
|
38
40
|
只審查本任務的變更;其他任務的驗收條件不在這次審查範圍內。先根據 diff 與驗收條件定位需要查閱的檔案,只在證據不足時讀取其他檔案。不必為了審查重跑全套檢查。
|
|
39
41
|
|
|
40
42
|
風格偏好與無關緊要的小問題不需要要求修改。
|