走完一個 AIT 任務

一個需求,走到真正完成的 Task。

看 AIT 開啟隔離工作區、驗證一個小修改,再把完成的結果帶回原始專案。

2026-09-07 實際執行 AIT 命令的節錄重播。路徑已簡化;播放時間不代表任務執行效能。
閱讀完整命令紀錄
AIT first-task command recording — 2026-09-07
Actual command output. Absolute example roots are shortened to ~/ait-first-task.
The replay is edited for readability; playback is not an execution-time measurement.

Working directory: ~/ait-first-task
$ ait --version
ait 1.1.2
Exit code: 0

Working directory: ~/ait-first-task
$ node --test tests/baseline.test.mjs
✔ task titles preserve the input order and data (1.168458ms)
✔ the existing board title is unchanged (0.063583ms)
✔ the existing priorities are unchanged (0.046333ms)
ℹ tests 3
ℹ suites 0
ℹ pass 3
ℹ fail 0
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 63.568458
Exit code: 0

Working directory: ~/ait-first-task
$ ait init
Initialized empty AIT repository in ~/ait-first-task/.ait (plan=zh-Hant-TW/concise)
Exit code: 0

Working directory: ~/ait-first-task
$ ait config set --user-name 'AIT Demo'
ait config set
user-name: AIT Demo
Exit code: 0

Working directory: ~/ait-first-task
$ cat docs/sprints/open-tasks.md
# Open tasks [plan-ref: example/open-tasks]

## Intent
Add openTasks(tasks) to src/tasks.mjs. Return a new array of tasks whose done property is not true, preserving order and object references without mutating the input. Keep taskTitles unchanged.

## Constraints
Only edit this Task worktree. Do not edit checks/, remove tests, or add packages. The root agent executes this task without subagents.

## Acceptance
Add a focused regression test for done true, false, missing, empty input, preserved order and identity. Run node --test tests/*.test.mjs and node checks/first-task.mjs before Task finish; verify acceptance again in the original directory afterward.

- [ ] Add non-mutating openTasks and focused tests. [ref: open-tasks]
Exit code: 0

Working directory: ~/ait-first-task
$ ait task start --from 'docs/sprints/open-tasks.md#open-tasks' --intent 'Add openTasks without mutating input'
ait task start
task: LT-0001
title: Add non-mutating openTasks and focused tests
next: cd ~/ait-first-task/.ait-worktree-links/lt-0001
Exit code: 0

Working directory: ~/ait-first-task/.ait-worktree-links/lt-0001
$ node --test tests/baseline.test.mjs tests/open-tasks.test.mjs
✔ task titles preserve the input order and data (1.041042ms)
✔ the existing board title is unchanged (0.053041ms)
✔ the existing priorities are unchanged (0.048583ms)
✔ openTasks returns unfinished tasks without changing input or objects (1.224417ms)
ℹ tests 4
ℹ suites 0
ℹ pass 4
ℹ fail 0
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 63.11
Exit code: 0

Working directory: ~/ait-first-task/.ait-worktree-links/lt-0001
$ node checks/first-task.mjs
FIRST_TASK_ACCEPTED
Exit code: 0

Working directory: ~/ait-first-task/.ait-worktree-links/lt-0001
$ ait snapshot create LT-0001 --message 'Add non-mutating openTasks'
ait snapshot create
snapshot_id: SNP-0B558114ECDB
task_id: LT-0001
line_name: feature/lt-0001
parent_snapshot_id: SNP-2B43A5F97E11
message: Add non-mutating openTasks
Exit code: 0

Working directory: ~/ait-first-task/.ait-worktree-links/lt-0001
$ ait task finish LT-0001 --local
finished: LT-0001 -> main @ SNP-0B558114ECDB
closed: task, worktree, line, sprint
title: Add non-mutating openTasks and focused tests
Exit code: 0

Working directory: ~/ait-first-task
$ node --test tests/baseline.test.mjs tests/open-tasks.test.mjs
✔ task titles preserve the input order and data (0.987959ms)
✔ the existing board title is unchanged (0.050417ms)
✔ the existing priorities are unchanged (0.042292ms)
✔ openTasks returns unfinished tasks without changing input or objects (0.963875ms)
ℹ tests 4
ℹ suites 0
ℹ pass 4
ℹ fail 0
ℹ cancelled 0
ℹ skipped 0
ℹ todo 0
ℹ duration_ms 61.445542
Exit code: 0

Working directory: ~/ait-first-task
$ node checks/first-task.mjs
FIRST_TASK_ACCEPTED
Exit code: 0

Working directory: ~/ait-first-task
$ ait blame src/tasks.mjs --line 7
target: current line main
resolved snapshot: SNP-0B558114ECDB
path: src/tasks.mjs
blame parent: SNP-2B43A5F97E11
range: 7-7

7         SNP-0B558114ECDB task=LT-0001 confidence=durable_snapshot_binding
Exit code: 0

Implementation recorded in the completed Task:
// Small, existing behavior to preserve while adding your first feature.
export function taskTitles(tasks) {
  return tasks.map((task) => task.title);
}

export function openTasks(tasks) {
  return tasks.filter((task) => task.done !== true);
}

Bound sprint after Task finish:
# Open tasks [plan-ref: example/open-tasks]

## Intent
Add openTasks(tasks) to src/tasks.mjs. Return a new array of tasks whose done property is not true, preserving order and object references without mutating the input. Keep taskTitles unchanged.

## Constraints
Only edit this Task worktree. Do not edit checks/, remove tests, or add packages. The root agent executes this task without subagents.

## Acceptance
Add a focused regression test for done true, false, missing, empty input, preserved order and identity. Run node --test tests/*.test.mjs and node checks/first-task.mjs before Task finish; verify acceptance again in the original directory afterward.

- [x] Add non-mutating openTasks and focused tests. [ref: open-tasks]

互動式走查

把一次完整的改動看一遍。

選個場景

流程示意 · 此頁不會執行真實 agent 或 AIT 程序。選擇步驟,依自己的速度閱讀。

sprint 卡 · 記下需求
閱讀完整流程文字 1 / 4 docs/sprints/password_visibility.md
agent + 本地執行 3 張卡 · 3 個工作區

閱讀完整流程文字

三張任務卡並行

將這三個需求分成獨立 Task 同時進行。保留登入 API 與既有行為;變更重疊時,明確呈現衝突,讓我審查。

  1. 三個需求,各自定義邊界

    先為每張卡記錄預期結果與驗收條件,再啟動對應的 Task。

    • 卡片 01 · 密碼顯示控制 · 記下範圍與驗收條件
    • 卡片 02 · session 驗證器 · 記下範圍與驗收條件
    • 卡片 03 · 驗證設定更名 · 記下範圍與驗收條件
  2. 每個 Task 一個可寫入工作區

    每個 Task 有自己的 worktree。agent 必須在回傳的 edit_root 內修改。

    • 卡片 01 · 密碼顯示控制 · agent A · 工作區 1
    • 卡片 02 · session 驗證器 · agent B · 工作區 2
    • 卡片 03 · 驗證設定更名 · agent C · 工作區 3
  3. 檢查對應修改後的版本

    卡片 01 先完成。卡片 02 更新至較新的目標並檢查整合結果;卡片 03 在相同設定處有不相容的修改。

    • 卡片 01 · 密碼顯示控制 · 檢查通過 · 準備完成
    • 卡片 02 · session 驗證器 · 目標前進 · 乾淨 rebase · 重新檢查
    • 卡片 03 · 驗證設定更名 · 與卡片 02 的設定變更不相容
  4. 兩個 Task 完成,衝突保持可見

    相容的工作完成;卡片 03 停止並保留工作,等待修正與再次審查。乾淨 rebase 本身不代表語意正確。

    • 卡片 01 · 密碼顯示控制 · 已完成 · 工作區已清理
    • 卡片 02 · session 驗證器 · rebase 後完成 · 工作區已清理
    • 卡片 03 · 驗證設定更名 · 衝突停止 · 保留未完成的工作

兩個 Task 完成 · 一個明確衝突待處理 · 沒有靜默覆寫

做一個新功能

你: 加一個「顯示密碼」按鈕。登入 API 和鍵盤行為都別變,把相關測試補上。

  1. 記下需求

    agent: 我會用一個繫結 sprint 的 Task 把這件事做完,驗證過再在本地完成收尾。

    docs/sprints/password_visibility.md
    # Password Visibility [plan-ref: login/password-visibility/root]
    - [ ] Add the accessible control and focused tests. [ref: login/password-visibility/implement]
  2. 開 Task

    agent: sprint 條目寫好了。我開它的 Task,進到隔離的工作區。

    $ ait task start --from docs/sprints/password_visibility.md#login/password-visibility/implement --intent "Add accessible password visibility control"
    task: LT-0042
    next: cd .ait-worktree-links/lt-0042
    
    $ cd .ait-worktree-links/lt-0042
    working tree: LT-0042
  3. 改動並驗證

    agent: 我只在 Task 工作區裡動登入表單和它對應的測試。

    src/LoginForm.tsx
    + <button type="button" aria-pressed={visible}>
    +   {visible ? "Hide password" : "Show password"}
    + </button>
    
    tests/LoginForm.test.tsx
    + toggles password visibility with keyboard and pointer input
    
    $ npm test -- LoginForm
    3 tests passed

    agent: 針對性的檢查過了。收尾之前,我先把這個確切修訂記下來。

    $ ait snapshot create --message "Add accessible password visibility control"
    Snapshot: SNP-7E21A4C8
  4. 完成 Task

    agent: 驗證過的 Snapshot 好了。我正在完成 Task,並更新本地目標 Line。

    $ ait task finish LT-0042 --local
    Status: completed
    Target: main (local)
    Task: completed
    Sprint item: completed
    Worktree: cleaned

    agent: 好了。密碼開關和對應測試已經在本地完成,Task 和那條 sprint 條目都結掉了。

結果: 改動完成 → Task 關閉 → sprint 條目關閉 → 工作區清掉

確認並修回歸

你: 上次改登入表單之後,密碼顯隱用鍵盤就按不動了。確認一下是回歸,修掉它,別動登入提交。

  1. 先復現失敗

    agent: 我先復現你說的現象,追出是哪個 Snapshot 造成的,再決定怎麼修。

    $ npm test -- LoginForm
    1 failed: activates password visibility with Space
  2. 追出是哪個 Snapshot

    agent: 針對性的測試確實掛在鍵盤這條路徑上。我這就去看改動的那一行。

    $ ait blame src/LoginForm.tsx --line 84
    resolved snapshot: SNP-5C91D2B4
    path: src/LoginForm.tsx
    84 SNP-5C91D2B4 · Refactor login form actions
  3. 繫結並修復

    agent: 回歸確認在 SNP-5C91D2B4。我把這次修復和它的回歸測試綁到一條確切的 sprint 條目上。

    docs/sprints/password_keyboard_regression.md
    # Password Keyboard Regression [plan-ref: login/password-keyboard-regression/root]
    - [ ] Restore native keyboard activation and lock it with a regression test. [ref: login/password-keyboard-regression/repair]
    
    $ ait task start --from docs/sprints/password_keyboard_regression.md#login/password-keyboard-regression/repair --intent "Restore password-control keyboard activation"
    task: LT-0043
    next: cd .ait-worktree-links/lt-0043
    
    $ cd .ait-worktree-links/lt-0043
    working tree: LT-0043

    agent: 我把原生 button 語義改回來,那個掛掉的鍵盤用例就留著當回歸測試。

    src/LoginForm.tsx
    - <span role="button" onClick={toggleVisibility}>
    + <button type="button" onClick={toggleVisibility}>
    
    tests/LoginForm.test.tsx
    + activates password visibility with Space
    
    $ npm test -- LoginForm
    4 tests passed

    agent: 原本掛掉的現在過了,登入行為也沒動。我把修好的修訂記下來。

    $ ait snapshot create --message "Restore password-control keyboard activation"
    Snapshot: SNP-9B42C1E6
  4. 完成修復

    agent: 這次回歸修復驗證過了。我正在完成 Task,並更新本地目標 Line。

    $ ait task finish LT-0043 --local
    Status: completed
    Target: main (local)
    Task: completed
    Sprint item: completed
    Worktree: cleaned

    agent: 確認了,也修好了。鍵盤觸發有回歸測試蓋著,修復已經在本地完成。

結果: 回歸修復完成 → Task 關閉 → sprint 條目關閉 → 工作區清掉

試跑第一個 Task 查看已量測的評測證據

多個 Task 並行時,如何保持清楚?

每張任務卡都有自己的意圖、工作區與檢查。相容的修改可以完成,實質衝突則停止並保留工作;日後透過版本紀錄追查問題。

三條 Task 路徑串起任務定義、隔離 worktree、測試審查與整合。兩條路徑更新 main;一條在衝突時停止。Binary DB 保存紀錄,供 ait blame 追溯責任版本。
流程示意:完成的兩個 Task 清理工作區;發生衝突的 Task 保留工作以供修正。乾淨 rebase 本身不證明語意正確。

開啟完整工作流說明圖 →