ライフスタイル

不具合修正の一連の流れ

不具合修正は再現する症状から始め、根拠で原因を絞って検証します。入力、操作、期待、実際を伝えます。

読了目安 14 分 · 操作 25 分

作業の流れを表す図です。製品画面の画像ではありません。
画像:Mokaair (© Mokaair)
総目次へ:Codex 学習ガイド:全記事の目次

実践 · Desktop / CLI / VS Code / JetBrains / cloud

この記事の目次
  1. 目標と準備
  2. 手順1:故障版と再現手順を固定
  3. 手順2:画面を使わない最小再現
  4. 手順3:最小修正と原因説明を依頼
  5. 手順4:同じ証拠で回帰確認
  6. 調査の習慣、復元と引渡し

目標と準備

この段落の教材・資料:

手順1:故障版と再現手順を固定

broken の5ファイルを新しい codex-bug-lab へコピーし原版を残します。Completed の条件が逆で、start の未実装とは異なります。Get-Location/pwd で場所を確認し、2成功1失敗を実測します。

ターミナル:基準テスト · sh
node --test core.test.mjs

ローカルプレビューは Windows で py -m http.server 4173 --bind 127.0.0.1、macOS/Linux で python3 -m http.server 4173 --bind 127.0.0.1 を使います。URL を開き、残したい架空データがあれば先に記録します。Reset practice data を選び、All tasks で空の一覧を確認してから Read、Build を追加し、Read 完了、Completed 選択の順に進めます。期待は Read、故障版の実際は Build です。この順序を残します。データのリセットはソースファイルを復元しません。

環境、起点、操作、期待、実際、証拠を記し、先にキャッシュ原因と決めません。日付とテストは実測で埋めます。違う画面なら教材と場所を確認し、記事の期待を自分の実測にしません。

文書テンプレート:不具合報告 · markdown
# Bug: Completed shows unfinished tasks
Environment/date: fill from this run
Fixture: broken copied to codex-bug-lab
Steps: reset practice data; add Read and Build; complete Read; select Completed.
Expected: Read only.
Observed: Build only, if reproduced.
Baseline: node --test core.test.mjs; fill actual result.
Scope: keep UI, storage format, ordering and tests unchanged.
Root cause: not confirmed yet.
Unperformed checks: list explicitly.

手順2:画面を使わない最小再現

次の repro.mjs を直下へ追加します。完了・未完了を直接渡し、保存、DOM、キャッシュ、通信を通りません。別端末で node repro.mjs を実行すると b を表示し a との不一致で非ゼロ終了するのが故障の証拠です。

新規ファイル:repro.mjs · javascript
import assert from "node:assert/strict";
import { visibleTasks } from "./core.mjs";

const tasks = [
  { id: "a", title: "Read", completed: true },
  { id: "b", title: "Build", completed: false },
];
const actual = visibleTasks(tasks, "completed").map((task) => task.id);
console.log("Completed IDs:", JSON.stringify(actual));
assert.deepEqual(actual, ["a"]);
console.log("Reproduction passed.");
ターミナル:最小再現 · sh
node repro.mjs

ブラウザーなしで誤答するため、この故障にキャッシュやボタンは不要です。全 UI 正常の証明ではありませんが Completed を先に調べる根拠です。未完了を選ぶ理由を説明させ、偶然の再読込成功を根因発見にしません。

動作の失敗と環境の失敗を分ける

node repro.mjs が ERR_MODULE_NOT_FOUND を返す場合、Completed の検証まで進んでいません。現在のフォルダーと core.mjs の名前を確認します。SyntaxError なら貼り付け漏れを調べます。読み込みに成功し、b を表示し、a を期待する検証で失敗したときに、この欠陥を再現できたと言えます。最初から通過しても修正済みとは限らず、expected をコピーした可能性があります。色や「失敗」だけでなく、コマンド、終了コード、実出力、コピーの場所を記録します。

手順3:最小修正と原因説明を依頼

デスクトップでは codex-bug-lab の Codex タスクを作ります。CLI はそのフォルダーを確認して codex を起動します。その後、次の限定依頼を送り、既存テストと repro.mjs は固定します。修正後に古くなる故障コメント一行は消してよいものの、他関数の整理や画面・フレームワーク変更はしません。失敗未確認なら先に確認させます。

Codex への依頼:範囲を限定した修正 · text
Fix the reproduced Completed-filter bug in this codex-bug-lab.
First read core.mjs, core.test.mjs and repro.mjs. Run node repro.mjs and node --test core.test.mjs to confirm the current failure.
Explain the predicate error using the actual a/b IDs. Modify only the completed predicate in core.mjs and remove its obsolete deliberate-bug comment. Do not change tests, repro.mjs, active behavior, storage or UI.
Rerun both commands, inspect the final diff and report actual results. Browser checks must be marked NOT RUN unless actually performed. Do not publish or deploy.

Completed が Active と同じ !task.completed を使うことが原因です。次の行だけにして Active の ! は残します。表示名交換では repro が失敗し、表面変更と挙動修正を区別できます。

参考修正:Completed 分岐 · javascript
if (filter === "completed") return tasks.filter((task) => task.completed);

手順4:同じ証拠で回帰確認

修正後 repro は ["a"] と成功文、終了0、既存3テスト成功です。同じ画面操作で Completed Read、Active Build、All 両方を確認します。先に同入力で原故障の解消を証明し、次に空や未完了戻しを追加します。

証拠修正前修正後
最小再現b、assertion 失敗a、終了0
既存テスト2成功1失敗3成功0失敗
Completed 画面BuildRead
Active/All実測を記録Build/両方維持
未実施未実施と明記自動で成功にしない

差分で addTask、decodeTasks、期待値の不変を確認します。修正済み主張だけなら命令、終了状態、失敗要約を求め、実行不能は理由を残します。成功命令は画面確認の代わりでなく、環境と URL を付けて実施します。

完了の解除と空のリストも確認する

元の再現が通過したら、次の内容で regression.mjs を別途作り、node regression.mjs を実行します。Completed の a を確認し、a の完了を解除した後、Completed は空、Active は a/b になることを検証します。元入力の保持と3種類の空リストも確認し、Regression passed と終了コード 0 が期待結果です。独立した検証プログラムなので、node --test core.test.mjs のテスト件数は自動では増えません。

ファイル:regression.mjs · javascript
import assert from "node:assert/strict";
import { toggleTask, visibleTasks } from "./core.mjs";

const tasks = Object.freeze([
  Object.freeze({ id: "a", title: "Read", completed: true }),
  Object.freeze({ id: "b", title: "Build", completed: false }),
]);
const ids = (items, filter) => visibleTasks(items, filter).map((task) => task.id);
assert.deepEqual(ids(tasks, "completed"), ["a"]);
const changed = toggleTask(tasks, "a");
assert.deepEqual(ids(changed, "completed"), []);
assert.deepEqual(ids(changed, "active"), ["a", "b"]);
assert.deepEqual(ids(changed, "all"), ["a", "b"]);
assert.deepEqual(tasks.map((task) => task.completed), [true, false]);
for (const filter of ["all", "active", "completed"]) {
  assert.deepEqual(ids(Object.freeze([]), filter), []);
}
console.log("Regression passed.");
ターミナル:境界条件の回帰確認 · sh
node regression.mjs

原版 broken/core.mjs に戻す練習でも regression.mjs は残します。repro.mjs の b と一致して、再び非ゼロで失敗するはずです。テスト、ラベル、保存処理も変更して通過させたなら、保存した原版から単一修正をやり直し、捨てた仮説をに残します。完全な回帰確認には実画面と再読み込みの確認も必要で、未実施はそのまま記録します。

調査の習慣、復元と引渡し

検証できる仮説を一つずつ変え、試行と結果を残して無効修正の反復を防ぎます。別原因の証拠なら範囲を絞り直し、一行という教材へ無理に合わせません。実案件の時間、認証、通信の違いもあり、私的データを除いて再現を渡します。

報告、最小再現、原因、差分、回帰表を渡します。再実行は自分のプレビュー停止後 broken/core.mjs だけ戻し、repro と元2成功1失敗を確認します。詳しい例はへ。図1再現、2原因修正、3回帰で、参考検証と各自の Codex 実行を分けます。

20. 不具合修正の一連の流れ — 作業の流れを表す図です。製品画面の画像ではありません。 Reproduce → Fix → Regression
20. 不具合修正の一連の流れ — 作業の流れを表す図です。製品画面の画像ではありません。 Reproduce → Fix → Regression · 画像:Mokaair (© Mokaair)
詳しい説明を読む

Reproduce to Fix to Regression

総目次へ

  • ライフスタイル

    Codex 学習ガイド:全記事の目次

    導入と最初のタスクから MD の指示、高度な連携まで、60 レッスン・十単元を予定しています。習熟度、環境、目的、コマンドで次の記事を探せます。未公開の記事には状態を表示します。

  • ライフスタイル

    Worktree とタスクの分離

    Worktree は一つの Git リポジトリに別ブランチの作業場所を作ります。ファイルは分かれても DB、ポート、外部サービスは共有される場合があります。

  • ライフスタイル

    実践:小さな Web サイトを作る

    brief.md から Small Steps のタスクサイトを計画・制作し、追加、完了、削除、絞り込み、ローカル保存を実装します。HTML、CSS、データ関数、画面イベント、テストを分け、Node とブラウザーで検証して再起動・復元の手順を残します。

  • ライフスタイル

    使用量と効率:やり直しを減らす

    条件、モデル設定、時間、成果を記録し、不要な再試行と過剰な文脈を減らします。

最新の旅の情報・ガイド

出典

ライフスタイル