Codex 対 Claude コード:どのコーディング剤があなたのワークフローに適しているか?

codex-vs-claude-code-hero

「Codex」対「Claude」――重要なのは、唯一の絶対的な勝者を見つけることではなく、日々信頼して使える作業スタイルを選ぶことなのです。. どちらの製品も、リポジトリの検査、複数のファイルの編集、コマンドの実行、テストの実行、パッチの説明を行うことができます。両者の本質的な違いは、作業の委任方法、エージェントへの指示の頻度、確認できる証拠の量、そして各ツールが既存の開発環境にどの程度適合するかという点に現れます。.

当社が実施した4つのタスクを対象としたリポジトリテストでは、Codexは98/100、Claude Codeは99/100のスコアを記録しました。 両者とも中核となる作業を完了しました。Claude Codeはより広範な検証とエッジケースの網羅性を示しましたが、一方、Codexは当環境において、より狭い範囲で要求される結果に到達することが多く、実行レベルでの証拠をより強固に提示しました。小規模なPythonフィクスチャにおける1点の差だけで、全体的な勝者を決定する理由にはなりません。.

ワークフローの他の部分を特定のコーディングエージェントに縛られたくない開発者は、GlobalGPTを独立したマルチモデル・マルチモーダル層として追加することができます。 GlobalGPTは、GPT 5.6、Claude Opus 5、GPT Image 2など、100以上のトップモデルを1つのダッシュボードに統合しています。さらに、 GlobalGPT CLI, MCP、およびSkillルートは、セカンドオピニオン、計画立案、ドキュメント作成、またはその他のサポート対象モデルにおいて、CodexやClaude Codeから利用できますが、リポジトリの編集やテストの管理はネイティブコーディングホストが行います。.

この比較では、公式のプラン情報、リポジトリでの実地作業、拡張可能な完全な出力結果、そして明確にラベル付けされたコミュニティでの利用実績を組み合わせています。その目的は、独立系開発者が、サブスクリプションへのアクセス権、追加クレジット、APIの課金といった要素に惑わされることなく、主要なコーディングツールを選択できるよう支援することにあります。.

Codex 対 Claude コードの概要

決定要因コーデックスクロード・コード
リポジトリの主要な作業サポートされているCodexの各画面において、表示、編集、コマンドの実行、および変更内容の確認を行いますコマンドの閲覧、編集、実行、および変更内容の確認を行う対話型ターミナルエージェント
当社のテストで確認されたスタイル実装の一部やバグ修正において、よりコンパクトになりましたリポジトリの分析、テスト、およびレビューの範囲において、より網羅的である
リポジトリの理解凍結タスクにおける機能的な結びつき
コード・レビュー重大度の高い有効な不具合を2件発見し、修正しました再現性の高い問題をさらに報告し、20件中19件を20件中18件に改善した
観測速度評価はまちまち。各環境の条件が十分に同等ではなかったため、総合的な勝者を決定することはできなかった。
コンシューマー向けエントリーモデル関連する ChatGPT プランを通じて、毎月 $20Claude Pro:米国では月額$20
利用頻度の高い階層$100および$200のティア$100では最大5倍、$200では最大20倍

この表は購入判断の参考となるものであり、モデルのランキング表ではありません。モデルの設定、リポジトリ、権限設定、またはタスクの仕様が異なると、結果が変わる可能性があります。すでに特定の製品をご利用の場合は、同じ成功コマンドを使用し、品質再ロールを行わない、ご自身のコードベースからの限定的なタスクを用いて比較するのが最適です。.

制御されたテストプロファイル

最初の有効な結果。評価基準は前回と同じです。各タスクの満点に基づいて、棒グラフの値は正規化されています。.

コーデックスクロード・コード
T1 · リポジトリの理解
20 / 20
T2 · 複数ファイル機能
30 / 30
T3・DSTのバグ修正
30 / 30
T4 · 点検と修理
18 / 19

この図は、1ポイントの差がどこから生じたかを示しているものであり、小さな試合結果を普遍的な順位付けに変えるものではない。.

「Codex」と「Claudeコード」とは実際には何なのか

「Codex」および「Claude Code」はエージェント製品であり、単なるモデル名ではありません。その根底にある コーディング用AIモデル モデルも重要ですが、それを取り巻く環境もまた、エージェントがどのファイルを参照できるか、どのコマンドを実行できるか、承認の仕組み、コンテキストの保持方法、そしてタスク終了後にどのような証拠が残るかなどを決定します。モデルの評判だけを比較すると、開発者が購入している体験の多くが見落とされてしまいます。.

Codexは、コマンドライン、IDE、デスクトップ、クラウド指向のワークフローを網羅しています。その幅広い対応範囲により、直接的なローカルでの共同作業から、より範囲を限定した業務の委任まで、あらゆるシナリオに適しています。Claude Codeは、統合機能と豊富なカスタマイズ性を備えた、対話型のターミナルワークフローを中核としています。これは Claudeを用いたコーディングのガイド では、そのワークフローについてより広範な概要を紹介しています。開発者によっては、ターミナル上でエージェントが動作する様子を見ることで安心感を得る人もいます。一方で、継続的な対話そのものよりも、最終的な差分、テスト結果、および監査証跡こそが重要な成果物だと考える開発者もいます。.

この区別は、名目上は強力なモデルを用いた2つのテストの挙動が異なる理由も説明しています。ホストは、指示の提示方法、ツールの呼び出し方法、および人間がアクションを承認しなければならないタイミングを決定します。このハーネスを無視したコミュニティ間の比較では、製品レベルの挙動をモデルレベルの真実と誤認してしまう可能性があります。.

  • モデル 推論および生成能力を提供する。.
  • エージェント・ハーネス ファイル、コマンド、コンテキスト、承認、および復旧を管理します。.
  • ユーザーのタスク契約 範囲、成功判定、およびエージェントがいつ停止すべきかを決定します。.
エージェント・ハーネスがコーディングとエージェントの比較に影響を与える可能性があることを指摘した、注釈付きXの投稿
あるX氏のコメントは、比較を行う上での重要な注意点、すなわち「エージェント・ハーネスが結果に影響を与える可能性がある」ことを指摘しています。これは有用な背景情報であり、どちらの製品が優れているかを決定づける決定的な証拠というわけではありません。.

ワークフローと管理:権限委譲か、継続的な指導か?

CodexとClaudeコードに関する最も有益な問いは、多くの場合「どちらがより良いコードを書くか?」ではなく、「どのように活用したいか?」というものです。 明確で範囲が限定されたタスクであれば、正確な目標、許容される範囲、および検証手順を定めて委任することができます。一方、曖昧なリファクタリングの場合は、議論や中間段階での確認を行い、変更が過度になる前に担当者の進め方を修正する機会を設けることが有効です。.

要件が変化している場合や、アーキテクチャに関する判断がまだ協議中の段階では、継続的なステアリングが有効です。一方、リポジトリの指示から解決できたはずの決定をエージェントが繰り返し求めてくるようになると、それはコストとなります。タスク契約が安定している場合は、自律的な実行が有効です。しかし、エージェントが検証されていない仮定を立てたり、明確なロールバックの道筋がないまま範囲を拡大したりすると、リスクが生じます。.

2026年4月13日付のRedditにある詳細なレポートによると、テストが約2,800件ある、約80,000行のPythonおよびTypeScriptプロジェクトにおいて、Claude Codeの使用時間は約100時間、Codexの使用時間は約20時間だったという。 著者は、Claudeを「高速でインタラクティブだが、手のかかる作業が多い」と評し、Codexを「低速で慎重な動作をする」と評した。このレポートは、プロジェクトや経験の背景が含まれている点で非常に有用だが、あくまで1人の開発者のワークフローを表しているに過ぎない。.

8万行規模のプロジェクトにおけるClaudeコードとCodexの比較に関する、Redditでの体験談(解説付き)
ある開発者がClaude CodeおよびCodexを使用してプロジェクトで得た具体的な経験です。ここで取り上げた所見は、製品全体のパフォーマンスデータではなく、検証すべき仮説として捉えるべきです。.

我々の測定結果からは、明確な勝者は見出せなかった。Claudeは最初の2つのタスクをより速く完了させた一方、Codexは後半の2つのタスクをより速く完了させた。また、ClaudeはCLI認証パスが利用できない状況でサブエージェントへのフォールバックを行ったため、実行経路は実験室環境と同等ではなかった。 したがって、速度はタスク、選択したモデル、労力設定、コンテキスト、およびホストによって異なるという結論が妥当であり、どちらの製品が常に速いというわけではない。.

リポジトリの理解とコンテキスト管理

リポジトリの理解とは、単にフォルダに名前を付けること以上のものです。有用なエージェントは、ファイル間でデータがどのように移動するかを追跡し、変更を制約する契約を特定し、テストを見つけ出し、症状とその考えられる原因を区別し、間違ったレイヤーを編集することによるリスクを説明できなければなりません。網羅的なマップは隠れた不整合を明らかにし、簡潔なマップは開発者が安全な実装決定に迅速にたどり着く手助けとなります。.

読み取り専用のT1タスクでは、両方のエージェントが20問中20問正解し、その回答をリポジトリに基づいて裏付けました。Claude Codeはより網羅的であり、契約上の不整合をさらに多く指摘しました。一方、Codexはより簡潔でありながら、関連するファイル、リスク、および実装計画を的確に特定しました。どちらのスタイルも、自動的に優れているわけではありません。 網羅性は、不慣れな移行や監査の際に役立ちます。一方、簡潔さは、開発者がすでにアーキテクチャを理解しており、焦点を絞った変更計画を必要としている場合に役立ちます。.

T1 · 管理リポジトリのテスト

変更を加える前に、不慣れなリポジトリの内容を把握しておく

アーキテクチャをマッピングし、データフローを追跡し、優先度の高い機能に関するリスクを特定し、ファイルの変更は一切行わない。.

ネクタイ
コーデックス20/20
期間108秒
小切手2 ベースライン
スコープ読み取り専用
最初の有効な出力の抜粋
アーキテクチャ:モデル、リポジトリ、サービス、および配線されていない時間ユーティリティ。

主なリスク:優先順位の意味付けが未定義であること、互換性、順序、検証、およびスコープの不一致。.

レビュアーの見解: 簡潔で、事実に基づいており、凍結決定を行う上で十分なものである。.

クロード・コード20/20
期間61秒
小切手2 ベースライン
スコープ読み取り専用
最初の有効な出力の抜粋
3つのレイヤーと1つの孤立モジュール。サイクルは存在せず、依存性注入も最小限に抑えられている。

また、識別子の割り当て、非対称なエラー契約、およびテストカバレッジの低さも明らかになった。.

レビュアーの見解: 同じ読み取り専用契約を満たしつつ、より網羅的である。.

Codexの出力をすべて表示

完全にサニタイズされた、最初の有効な出力

## アーキテクチャ

これは、標準ライブラリのみを使用した小規模な Python パッケージであり、4 つの機能レイヤーで構成されています:

- **データモデル:** [`Job`]() は、`identifier`、`name`、`owner` を含む不変のデータクラスです。`Job.to_dict()` は、`dataclasses.asdict()` を通じてこれをシリアライズします。
- **リポジトリ:** [`JobRepository`]() は、identifier をキーとして、ジョブをメモリ内の辞書に格納します。データベースや永続的な保存機能はありません。
- **サービス:** [`SchedulerService`]() は、識別子の割り当て、入力の正規化、ジョブの作成、一覧表示、および削除を担当します。
- **時間ユーティリティ:** [`next_daily_run()`]() は次回の実行時刻を計算しますが、これを `Job`、`SchedulerService`、または `JobRepository` にインポートしたり関連付けたりするものは何もありません。
- **公開 API:** [`scheduler.__init__`]() は `SchedulerService` のみをエクスポートしています。

リポジトリ名とは裏腹に、ジョブには現在スケジューリング情報が含まれておらず、実行キューも存在しません。 したがって、優先度は保存されたメタデータや一覧表示の順序には影響を与えますが、システムを大幅に拡張しない限り、実際のジョブの実行には影響を与えません。

## 作成および一覧表示のデータフロー

`SchedulerService.create_job(name, owner)` による作成:

1. [`create_job()`]() は、空白のみで構成される名前を拒否します。
2. `name` と `owner` をトリミングし、サービスの `_next_identifier` を使用して不変の `Job` オブジェクトを構築します。
3. [`JobRepository.save()`]() は、オブジェクトを `_jobs[job.identifier]` に書き込みます。
4. サービスは `_next_identifier` をインクリメントし、同じ `Job` を返します。

`SchedulerService.list_jobs()` による一覧表示:

1. [`list_jobs()`]() は、`repository.all()` に直接委譲します。
2. [`JobRepository.all()`]() は、辞書のキーを数値順にソートします。
3. したがって、ジョブはスケジュール順や優先度順ではなく、識別子/作成日時順(昇順)で返されます。

## ジョブの優先順位の影響を受ける可能性のあるファイル

必須:

- [`scheduler/models.py`](): priority フィールドとデフォルト値を追加する。 `to_dict()` は `asdict()` を使用しているため、自動的にこれを含めます。
- [`scheduler/service.py`](): 優先度を受け入れ、検証し、`Job` に渡します。
- [`tests/test_scheduler.py`](): デフォルト、明示的、無効、シリアライズ済み、および順序付けの挙動をテストしてください。

条件付き:

- [`scheduler/repository.py`](): 優先度がリストの順序を制御することを意図している場合にのみ、`all()` を変更する。同順位の場合は、`identifier` のような決定論的なセカンダリキーで処理すべきである。
- [`scheduler/__init__.py`](): 優先度がパブリックな列挙型または値オブジェクトになる場合にのみ更新する。
- [`README.md`](): 許容される値、デフォルト値、および順序付けのセマンティクスについて文書化してください。

影響を受けない可能性が高いもの:

- `scheduler/time_rules.py`。このファイルの唯一のシンボルは、渡された datetime を操作するものであり、ジョブやリスト表示とは関係がないためです。

## 主なリスク

- **定義されていないセマンティクス:** コードには、値が大きいほど優先順位が高いのか、小さいほど高いのか、どの値が有効なのか、あるいは優先順位がリスト表示に影響を与えるのかどうかについて、前例が示されていない。
- **互換性:** `Job` または `create_job()` に必須引数を追加すると、現在のテストにある `create_job("Daily report", "Alex")` のような既存の呼び出しが動作しなくなります。デフォルト値を設定すれば、その呼び出しは維持されます。
- **位置指定コンストラクタによる不具合:** 現在、`Job` は `SchedulerService.create_job()` 内で位置指定によって生成されています。フィールドの配置や将来の位置指定による呼び出しにより、誤った値が黙って割り当てられる可能性があります。キーワードによるコンストラクタの方が安全です。
- **順序の変更:** `JobRepository.all()` における識別子の順序を変更すると、確立された動作が変わります。優先度が等しい場合、安定した決定基準が必要です。
- **検証の曖昧さ:** 制限のない Python 値では、文字列、ブール値、または任意の整数が許容される可能性があり、これらを一貫して比較することは困難です。
- **実行スコープの不一致:** ディスパッチャや実行キューが存在しません。優先順位によってどのジョブが先に実行されるかが決まるという主張は、現在のどのシンボルによってもサポートされません。
- **メモリ内での制限:** `_jobs` は単なるインスタンス辞書であるため、優先度も他のジョブフィールドと同様に、プロセスが終了すると消滅します。

## 実装および検証計画

1. まず契約を定義する:表現形式、許容値、デフォルト値、優先順位の方向、同順位時の決定方法、およびリストの順序を変更するかどうか。
2. `Job` に `priority` を追加する。できれば下位互換性のあるデフォルト値を設定する。
3. `SchedulerService.create_job()` を拡張し、デフォルト値が設定された優先度パラメータを追加する。その妥当性を検証し、キーワード引数を使用して `Job` を生成する。
4. リスト表示が優先順位を考慮する場合、`JobRepository.all()` を変更し、優先順位を第一に、識別子を第二に並べ替える。そうでない場合は、リポジトリの順序を変更しない。
5. 以下の項目に対するテストを追加する:
   - 既存の 2 引数による作成。
   - 明示的な優先順位の保持。
   - デフォルトの優先順位。
   - 無効な型および範囲外の値。
   - `Job.to_dict()` の出力。
   - 複数の優先度がある場合の一覧表示順序。
   - 優先度が等しい場合の安定した順序。
   - 既存の空白名に対する動作。
6. README を更新し、正確な公開契約を記載する。
7. `python3 -m unittest discover -s tests -v` を実行して、オフラインテストスイート全体を実行する。

## 検証完了

- ベースラインテストスイート:**2 つのテストが合格**。
- リポジトリ全体のシンボル検索により、`next_daily_run()` が切り離されており、既存の優先度シンボルが存在しないことが確認されました。
- 変更されたファイル:**なし**。
- 機能の実装:要件通り、**未実施**。

> **結論 + 決定**
>
> 優先順位が単なるメタデータまたはリストの順序に過ぎない場合、変更は小規模です。主に `models.py`、`service.py`、`repository.py`、およびテストが対象となります。実装に先立ち、優先順位が単にジョブを記述するだけなのか、それとも `list_jobs()` の順序を変更するものなのか、さらに値のスケール、デフォルト値、方向性、および同点時の決定ルールを決定する必要があります。.
Claudeコードの出力をすべて表示

最初の有効な出力を逐語的に含んだ、完全なハンドオフ記録

# T1 実行記録 — 未知のリポジトリの理解

## 実行パラメータ

| フィールド | 値 |
| --- | --- |
| タスク | `T1` |
| 凍結プロンプト | `01-prompts/T1.md` |
| 凍結プロンプトの SHA-256 | `a571ff15c2502ec29b172ae2e77dd9ab0caca2869b91f9468d47571434d16c17` |
| 実行ユニット | 隔離された Claude サブエージェント、`general-purpose`、新規コンテキスト |
| 隔離方法 | **サブエージェントのフォールバック**(文書化されたダウングレード — `results/isolation-decision.md` を参照) |
| 割り当てられたクリーンコピー | `runtime/workspaces/T1` |
| Claude コードバージョン | `2.1.220` |
| モデル設定 | `claude-opus-5` |
| start_utc | `2026-07-28T10:27:31Z` |
| end_utc | `2026-07-28T10:28:32Z` |
| 所要時間 | 61 秒(T2~T4と並行して実行されたため、正確なレイテンシ測定値ではない) |
| 試行回数 | 1 |
| ステータス | `有効` |
| 人的介入 | なし |

## セーフツールの概要

`date`、`find`、`ls`、`wc`、`stat`、`grep`、ワークスペース内の7つのファイルに対する`Read`、`python3 -V`、
`python3 -m unittest discover -s tests -v`。すべての読み取りは割り当てられたワークスペース内に限定されています。
ネットワーク接続なし、インストールなし、書き込みなし。

## オフラインチェック結果

`python3 -m unittest discover -s tests -v` → 2 つのテスト、OK (終了コード 0)。 ワークスペース外から
コーディネーターによって再検証済み:`results/checks/T1-public.txt`を参照。

## パッチ

なし。`results/T1/patch.diff` は空であり、`diff -ru 02-fixture runtime/workspaces/T1`
を実行しても差異は検出されませんでした。このタスクでは、ファイルを変更せずに検査を行う必要がありましたが、これは
アサーションではなく確認済みです。

## 修正済みエラー

回復可能なシェルエラーが1件:最初の `grep` で、引用符で囲まれていない `--include=*.py` パターンが使用され、
シェルがグロブ処理を試みた。パターンを引用符で囲んで再実行したところ成功した。調査結果への影響はない。

## 表示された出力(原文のまま)

### 1. このリポジトリについて

`local-scheduler-1.0.0`(`fixture-manifest.json`)という名前の、自己完結型のPython標準ライブラリ用フィクスチャです。MITライセンスで、ネットワークや本番環境への依存関係はありません(`README.md`、`"network_required": false`)。 非常にコンパクトで、ソースファイル・ドキュメントファイル8つとマニフェストを合わせ、合計103行です。使用されているインタプリタは **Python 3.9.6** です。 `pyproject.toml`、`setup.py`、CI設定、リンター、型チェッカーの設定は存在しません。宣言されているワークフローは `python3 -m unittest discover -s tests -v` のみです(`README.md`)。

### 2. アーキテクチャ

3つのレイヤーと1つの孤立モジュールがあり、すべて `scheduler/` 配下に配置されています:

| レイヤー | ファイル | シンボル | 役割 |
|---|---|---|---|
| パッケージファサード | `scheduler/__init__.py` | `__all__ = ["SchedulerService"]` | `SchedulerService`のみを再エクスポートします。`Job`、`JobRepository`、および`time_rules`は公開インターフェースの一部ではありません |
| ドメインモデル | `scheduler/models.py` | `Job` (`@dataclass(frozen=True)`) | `identifier: int`、`name: str`、`owner: str` のフィールドを持つ不変の値オブジェクト。さらに、`to_dict()` は `asdict(self)` として実装されている |
| 永続化 | `scheduler/repository.py` | `JobRepository` | `identifier` をキーとするメモリ内の `dict`;`save`、`get`、`all`、`delete` |
| アプリケーションサービス | `scheduler/service.py` | `SchedulerService` | 検証、識別子の割り当て、オーケストレーション:`create_job`、`list_jobs`、`delete_job` |
| 孤立モジュール | `scheduler/time_rules.py` | `next_daily_run` | 繰り返し計算 — **他のモジュールからインポートされていない** |

依存関係の方向性は明確で一方向です:`service.py`は`.models`および`.repository`からインポートし、`repository.py`は`.models`からインポートし、`models.py`は`dataclasses`のみをインポートします。循環はありません。 依存性注入は存在しますが最小限です — `SchedulerService.__init__(self, repository=None)` では `self.repository = repository or JobRepository()` が行われるため、テストでは偽のリポジトリを代用できます。

なお、`scheduler/time_rules.py` は現在、デッドコードとなっています。 ツリー全体を `time_rules` および `next_daily_run` で検索しましたが、ヒットしたのはその定義自体と、`fixture-manifest.json` の `expected_files` への記載のみでした。同梱されていますが、配線はされていません。

### 3. データフロー

**ジョブの作成** — `SchedulerService.create_job(name, owner)`:
1. ガード: `if not name.strip(): raise ValueError('name is required")`。 これがシステム内の*唯一*の検証です — `owner`は一切チェックされないため、空の所有者も受け入れられます。
2. 構築: `Job(self._next_identifier, name.strip(), owner.strip())` — 位置指定による構築であり、両方の文字列は先頭文字を削除して正規化されます。
3. 永続化: `self.repository.save(job)`。これは `self._jobs[job.identifier] = job` を実行し、ジョブを返します。
4. カウンタのインクリメント: `self._next_identifier += 1` — これは保存の*後*に行われるため、例外が発生してもカウンタは消費されないまま残ります。
5. `Job`インスタンスを返す(サービスはリポジトリの戻り値ではなく、自身のローカルな`job`を返します)。

識別子の割り当ては、リポジトリではなく**サービス**側で行われます(`SchedulerService.__init__` 内の `self._next_identifier = 1`)。これは重要な境界です。すでにジョブを含むリポジトリを注入すると、新しいサービスが番号付けを 1 から再開するため、既存のジョブが黙って上書きされてしまいます。

**ジョブのリスト表示** — `SchedulerService.list_jobs()` は `JobRepository.all()` への単純なパススルーであり、`[self._jobs[key] for key in sorted(self._jobs)]` を返します。 したがって、順序は**整数識別子による昇順**となり、これは現在のところ挿入順と一致しています。呼び出しごとに新しいリストが構築されますが、`Job`オブジェクトは共有参照です。これは`Job`が凍結されているため、安全です。

**削除** — `SchedulerService.delete_job(identifier)` は `JobRepository.delete` に委譲します。これは `self._jobs.pop(identifier)` であり、デフォルト値がないため、ID が存在しない場合は `KeyError` を発生させます。 これは、同じ条件下で `None` を返す `JobRepository.get` と一貫性がありません。

**これらのパスに対するテストカバレッジ** — `tests/test_scheduler.py` には、正確に 2 つのケースがあります: `test_create_and_list_jobs`(`job.identifier == 1` および `[job] == service.list_jobs()` をアサート)と `test_blank_name_is_rejected` です。現在のツリーでは、どちらもパスしています。

### 4. ジョブの優先順位追加によって影響を受ける可能性のあるファイル

確実性の高い順に:

1. **`scheduler/models.py`** — 確実。 `Job` には `priority` フィールドが必要です。dataclass は `frozen=True` であり、フィールドは位置指定型であるため、新しいフィールドにはデフォルト値(例: `priority: int = 0`)を指定するか、既存の 3 つのフィールドの後に配置する必要があります。そうしないと、既存のすべての位置指定型構文が破綻してしまいます。 `to_dict()` は修正不要 — `asdict(self)` がフィールドを自動的に検出するため、これはコードの変更ではなく、シリアライゼーション契約の静的な変更にあたる。
2. **`scheduler/service.py`** — 確実。 `create_job` には `priority` パラメータが必要であり、13 行目の `Job(...)` の位置指定コンストラクタにこれを渡す必要があります。優先度が検証される場合(範囲、列挙型のメンバーシップなど)、そのガードは既存の `name.strip()` チェックの隣に配置する必要があります。 リストを優先順位順に並べる必要がある場合、リポジトリを単純なストレージとして維持したいのであれば、順序付けのロジックは `list_jobs` に配置すべきです。
3. **`scheduler/repository.py`** — 可能性が高い。 `JobRepository.all()` の `sorted(self._jobs)` は、辞書の *キー*、つまり識別子をソートしています。優先度順にリスト表示するには、これを `(-job.priority, job.identifier)` のようなキーで値をソートするように変更するか、別の順序付きアクセサを追加する必要があります。 同順位時の処理を暗黙のままで残さないでください。辞書の挿入順序は、依存できる安定した契約ではありません。
4. **`tests/test_scheduler.py`** — 確実。 デフォルトの優先度、明示的な優先度、順序付け、および無効な優先度による拒否に関する新しいテストケース。既存の `assertEqual([job], service.list_jobs())` は*同じ*オブジェクトを比較しているため、フィールドの追加後も機能し続けますが、新しく構築された `Job` リテラルを比較していた場合は機能しなくなる点に注意してください。
5. **`README.md`** — 優先順位のセマンティクス(範囲のどちらの端が優先されるか、デフォルト値など)をどこかに明記する必要がある場合、追加される可能性が高い。
6. **`scheduler/__init__.py`** — `SchedulerService` とともに優先順位の列挙型や定数をエクスポートする必要がある場合のみ。
7. **`fixture-manifest.json`** — 新しいモジュールファイルを追加する場合のみ。その `expected_files` 配列は明示的なインベントリであり、内容がずれてしまう可能性があるため。
8. **`scheduler/time_rules.py`** — 変更してはいけません。優先順位は再発と直交しており、このモジュールは切り離されています。

### 5. 主なリスク

- **順序のセマンティクスは、黙示的な動作変更です。** `JobRepository.all()` は現在、識別子の昇順を保証しており、`list_jobs` もこれを継承しています。この保証に依存しているコンシューマーは、再ソートによって動作しなくなります。 明示的に決定してください:`list_jobs()` の意味を変更するのか、それとも新しい `list_jobs_by_priority()` を併設するのか? 前者の方がリスクが高く、既存のテスト `test_create_and_list_jobs` は、回帰(要素が1つのリスト)を検出するには不十分です。
- **ソートの方向性は本質的に曖昧です。** 「優先度 1」は、システムによっては慣例的に *最高* を意味し、別のシステムでは *最低* を意味します。このリポジトリには、これを明確に定めているもの(コメント、docstring、README の記述など)が一切ありません。 いずれかの規約を決定し、`models.py`に文書化し、ソートの方向が明確に固定されるよう、少なくとも3つの異なる優先度を用いたテストに組み込んでください。
- **ソートの同順位処理が不安定です。** 2つのジョブが同じ優先度を持つ場合でも、結果は決定論的でなければなりません。Pythonの`sorted`は安定していますが、安定性は入力の順序自体が定義されている場合にのみ有用です。常に`identifier`を明示的なセカンダリキーとして含めてください。
- **Frozen-dataclassのフィールド順序。** `Job`は`@dataclass(frozen=True)`で3つの位置指定フィールドを持ち、`service.py:13`では位置指定で構築されます。`priority`を最後以外の位置に挿入したり、デフォルト値なしで挿入したりすると、既存の2つのテストでは十分に検出されない可能性のある互換性を破る変更となります。
- **`to_dict()` の契約拡大。** `asdict(self)` はすべてのフィールドを反映します。`priority` を追加すると、`models.py` のメソッド本体を目に見える形で変更することなく、シリアライズされたすべてのペイロードが変更されます。辞書の形状が正確であることをアサートしているものはすべて動作しなくなります。
- **Python 3.9.6 の制約。** `@dataclass(slots=True)`(3.10+)や `kw_only=True`(3.10+)は使用不可であり、PEP 604 の `int | None` アノテーションは、`from __future__ import annotations` を指定しない限り実行時に失敗します。 優先度を列挙型(enum)としてモデル化する場合、`enum.StrEnum` は 3.11 以降で利用可能となるため、このインタプリタでは利用できません。これらのいずれかが原因で、このフィクスチャは動作しなくなります。
- **識別子の割り当てが不適切なレイヤーで行われている。** `SchedulerService._next_identifier` は、リポジトリが保存を担当しているのに対し、サービスが ID 生成を所有していることを意味する。優先順位に関する作業が、2つ目のリポジトリの実装やプリロードされたフィクスチャを必要とする場合、この分離により ID の衝突やジョブの上書きが発生する。
- **非対称なエラー契約。** `JobRepository.get` はヒットしない場合に `None` を返すのに対し、`JobRepository.delete` は `KeyError` を発生させます。優先度に関連する新しい検索機能では、誤ってこの不整合を継承するのではなく、意図的にいずれかの規約を採用すべきです。
- **検証の不備に関する前例。** `create_job` は `name` を検証しますが、`owner` は検証しません。この緩い検証を `priority` に適用しないでください。検証されていない優先度はソートキーに伝播し、呼び出し元ではなく `sorted` の奥深くで `TypeError` を発生させる可能性があります(例:`int` と `None` の比較)。
- **デッドコードの罠。** `scheduler/time_rules.py` はスケジューリングロジックのように見え、編集の誘因となる。 しかし、このファイルは他のどこからもインポートされておらず、そのドキュメント文字列自体にもバグが明記されています。つまり、UTCで24時間の経過時間を加算し、「夏時間の切り替えに伴い、ローカルの実時間をずらす」という動作をするのです。これを変更しても、テスト対象のシステムには目に見える影響は一切ありません。したがって、そこに労力を費やすのは無駄であり、これに基づいて書かれたテストは、リリースされるコードの妥当性を一切検証できません。
- **脆弱なセーフティネット。** テストは2つだけで、CIもリンターも型チェックもありません。自分で書いたコード以外で回帰を検出する手段は何もありません。既存のテストスイートは、ゲートとしてではなく、不十分なベースラインカバレッジとして扱ってください。

### 6. 実装計画(未実行)

1. **まず、セマンティクスを文書化して確定する。** 優先度型(`int` 対 enum)、有効範囲、既存/未指定のジョブのデフォルト値、およびソート方向。 これを `scheduler/models.py` 内の `Job` の docstring として記録する。これは、すべてのレイヤーがすでに依存している唯一の場所である。
2. **モデルを拡張する。** `scheduler/models.py` 内の `Job` の *最後の* フィールドとして `priority: int = 0` を追加する。この際、`service.py:13` との位置互換性を維持し、`to_dict()` には手を加えない。
3. **サービス全体に反映させる。** `SchedulerService.create_job` にデフォルト値が設定された `priority` パラメータを追加し、既存の `name.strip()` ガードの横で検証を行い(確立されたエラー型に合わせて `ValueError` を発生させる)、それを `Job` のコンストラクタに渡す。
4. **リストの契約を明示的に決定する。** 推奨される低リスクな選択肢:`JobRepository.all()` を識別子順のプリミティブとしてそのまま残し、優先度順のアクセサを別途追加する。 もし代わりに `list_jobs()` の意味を変更する必要がある場合は、`JobRepository.all()` のリスト内包表記を変更し、同値時の判定基準として `identifier` を含む明示的な複合キーで値をソートするようにし、その変更を `README.md` に記載してください。
5. **`scheduler/__init__.py` を同期させる**のは、パブリックな列挙型や定数が導入された場合に限る。
6. **`scheduler/time_rules.py`には手を加えない**こと。また、同じ変更で `fixture-manifest.json` の `expected_files` が更新されない限り、ファイルを追加しないこと。

### 7. 検証計画

- **まずベースラインを確認。** 編集を行う前に `python3 -m unittest discover -s tests -v` を実行し、2つのテストがパスすることを確認してください。私はすでにこれを行っており、問題なくパスしています。
- **回帰テストのゲート。** 既存のテストは両方とも、変更を加えずに引き続きパスする必要があります。もし `test_create_and_list_jobs` を編集する必要がある場合、それは変更によって回帰が発生しているというシグナルであり、テストを編集する理由にはなりません。
- **`tests/test_scheduler.py` への新規テストケース:**
  - 旧式の 2 引数シグネチャで `create_job` が呼び出された際のデフォルトの優先度(下位互換性を検証するため)。
  - `create_job` → `list_jobs` を経由する明示的な優先度の往復検証。
  - **3つ以上**の異なる優先度による並べ替え。完全なリストをアサーションします。これにより、ソート方向が確定します。
  - 同順位時の処理:優先度が等しい2つのジョブは、識別子の昇順で返されます。
  - 無効な優先度を指定すると、名前が空の場合と同様に `ValueError` が発生します。
  - `to_dict()` には、期待される値を持つ `priority` が含まれます。
  - リポジトリの注入パス: `SchedulerService(repository=fake)` でも優先順位が正しく割り当てられ、`repository or JobRepository()` のシームが機能します。
- **互換性チェック。** 特に Python 3.9.6 上ですべてが正常に動作することを確認する — `slots=`、`kw_only=`、PEP 604 のユニオン(裸の形式)、`StrEnum` は使用しない。
- **インベントリチェック。** `fixture-manifest.json` を再読み込みし、ディスク上のファイルセットが依然として `expected_files` と一致していることを確認します。
- **決定性。** テストスイートを 2~3 回実行します。辞書の反復順序に関わるバグは、断続的に発生する可能性があります。
- **クリーンさ。** `PYTHONDONTWRITEBYTECODE=1` を指定して実行し、`__pycache__` ディレクトリがマニフェストに対して追跡されていないドリフトとして表示されないようにします。.

フィクスチャの制限事項:これは小規模なオフラインのPythonリポジトリでした。Claudeでは、CLI OAuthの有効期限が切れた後にサブエージェントのフォールバックが使用されていたため、分離状態とトークンの可視性は一致していませんでした。.

この結果は、大規模なモノレポや1週間にわたる自律的なセッションにおけるパフォーマンスを証明するものではありません。今回のテスト環境は、意図的に小規模かつ制御されたものに設定されました。実際の評価を行う場合は、まず読み取り専用のプロンプトから始めてください。各ツールに対し、編集を許可する前に、呼び出しパスをマッピングし、変更されるファイル名を特定し、テストを識別し、未解決の仮定を列挙するよう求めます。.

実装スタイル、パッチの適用範囲、およびバグ修正

複数ファイルの機能に関する作業

異なる設計上の選択によって、同じ合格結果が得られる場合があります。T2では、両製品とも30/30を獲得し、凍結された隠れバリデータに合格しました。Claude Codeは、複数の境界にバリデーションを配置し、より広範な直接モデルテストおよびしきい値テストを追加しました。Codexは、契約要件を満たす、より小規模なサービス中心の実装を採用しました。.

独立系開発者にとって、これはまさにトレードオフです。検証範囲を広げることで、複数の経路を通じてオブジェクトが作成される場合でも不変条件を守ることができます。一方、意図したエントリポイントが1つのサービスに限定されている場合は、パッチを小さくすることで、回帰リスクの範囲とレビュー時間を削減できます。正しい答えは、変更された行数やテスト数を単独で数えることではなく、リポジトリの所有権に関するルールによって決まります。.

T2 · 管理リポジトリのテスト

複数のファイルにまたがる優先順位機能を実装する

凍結された挙動を追加し、互換性を維持し、パブリックおよび非公開のチェックに合格する。.

機能的なネクタイ
コーデックス30/30
期間115秒
小切手7 + 非表示
スコープより小さなパッチ
最初の有効な出力の抜粋
不変モデルに優先順位を追加し、サービス境界で検証を行い、リポジトリ内の順序を維持しました。

7つのパブリックテストすべてと、凍結された非公開バリデータがすべて合格しました。.

レビュアーの見解: すべての固定化された挙動を満たす、サービス中心のより小規模な実装。.

クロード・コード30/30
期間101秒
小切手14 + 非表示
スコープより広範な検査
最初の有効な出力の抜粋
サービス境界と不変モデルの両方で優先順位が検証され、リポジトリのフィルタリングが維持され、しきい値カバレッジが追加されました。

14件の公開テストと非公開のバリデータがすべて合格しました。.

レビュアーの見解: 機能スコアにおける優位性はないものの、ダイレクトモデルおよび閾値のカバー範囲がより広くなっている。.

Codexの出力をすべて表示

完全にサニタイズされた、最初の有効な出力

スケジュールされたジョブの優先度機能を実装しました。

変更されたファイル:

- [scheduler/models.py](./scheduler/models.py:5) — シリアライズされた `priority` を追加し、デフォルト値を `0` に設定しました。
- [scheduler/service.py](./scheduler/service.py:11) — 識別子の順序を維持したまま、検証、保存、および `list_jobs(min_priority=0)` によるフィルタリングを追加しました。
- [tests/test_scheduler.py](./tests/test_scheduler.py:16) — デフォルト値、シリアライズ、保存、境界条件、無効な値、およびフィルタリングに関するカバレッジテストを追加しました。

テスト実行結果:

```text
python3 -m unittest discover -s tests -v
7 件のテストを実行 — OK
```

**結論:** フリーズされたタスクは完了し、検証済みです。  
**必要な決定事項:** なし。.
Claudeコードの出力をすべて表示

最初の有効な出力を逐語的に含んだ、完全なハンドオフ記録

# T2 実行記録 — マルチファイル優先機能

## 実行パラメータ

| フィールド | 値 |
| --- | --- |
| タスク | `T2` |
| 凍結プロンプト | `01-prompts/T2.md` |
| 凍結プロンプトの SHA-256 | `8476a56034c4e719b97ee4081b32b4c73efd45feafe1bda9d477c83cb8fdb698` |
| 実行ユニット | 隔離された Claude サブエージェント、`汎用`、新規コンテキスト |
| 隔離方法 | **サブエージェントのフォールバック**(文書化されたダウングレード — `results/isolation-decision.md` を参照) |
| 割り当てられたクリーンコピー | `runtime/workspaces/T2` |
| Claude コードバージョン | `2.1.220` |
| モデル設定 | `claude-opus-5` |
| start_utc | `2026-07-28T10:27:52Z` |
| end_utc | `2026-07-28T10:29:33Z` |
| 所要時間 | 101 秒(T1、T3、T4と並行実行;純粋なレイテンシ測定ではない) |
| 試行回数 | 1 |
| ステータス | `valid` |
| 人的介入 | なし |

## セーフツールの概要

`date`、割り当てられたワークスペース内での `Read`/`Edit`/`Write` のみ、`grep`、
`python3 -m unittest discover`、`python3 -m compileall`、インライン `python3 -c` による簡易テスト。
ネットワーク接続なし、インストールなし、標準ライブラリのみ。

## 変更されたファイル

`scheduler/models.py`、`scheduler/repository.py`、`scheduler/service.py`、
`tests/test_scheduler.py`。 ファイルの追加や削除はないため、`fixture-manifest.json`は
正確なままです。完全なパッチ:`results/T2/patch.diff`。

## オフラインチェックの結果

タスクランナーによる報告:

| チェック | 結果 |
| --- | --- |
| `python3 -m unittest discover -s tests -v` (ベースライン、変更前) | 2 件合格、0 件失敗 |
| `python3 -m compileall -q scheduler tests` | 問題なし |
| インライン・スモークチェック(レガシーな 3 引数構文、キーワード/位置指定のしきい値、`to_dict`) | 合格 |
| `python3 -m unittest discover -s tests -v` (最終) | **14 件合格、0 件失敗** |

ワークスペース外からコーディネーターが独立して再検証:

| チェック | 終了 | 結果 |
| --- | --- | --- |
| パブリックスイート (`results/checks/T2-public.txt`) | 0 | 14 テスト、OK |
| 非公開バリデータ `03-checks/test_t2_hidden.py` (`results/checks/T2-hidden.txt`) | 0 | 2 テスト、OK |

非公開バリデータは、初期状態のフィクスチャのコピーに対して失敗(終了コード 1)し、この合格が
有意義であることを確認しています。`results/checks/validator-controls.md` を参照してください。

## ゴールドマップの動作カバレッジ

`03-checks/gold-map.json` に規定された 5 つの必須挙動がすべて満たされています:

| 必須挙動 | 証拠 |
| --- | --- |
| 優先度のデフォルト値 0 | `Job.priority: int = MIN_PRIORITY`; `create_job(..., priority=MIN_PRIORITY)`; `test_priority_defaults_to_zero` |
| 0 から 9 までの整数範囲 | `validate_priority` は整数以外および範囲外の値を拒否します; `test_out_of_range_priority_is_rejected`、`test_non_integer_priority_is_rejected` |
| シリアライズされた優先度 | `asdict` 経由の `to_dict()`; `test_priority_appears_in_serialized_output` は正確な辞書をアサート |
| 最小優先度によるフィルタリング | `list_jobs(min_priority=0)` → `JobRepository.all(min_priority)`; `test_filter_is_inclusive_of_the_threshold` |
| 識別子の順序 | 既存の `sorted(self._jobs)` リスト内包表記内でフィルタを適用; `test_filter_preserves_ascending_identifier_order` |

## エラーの修正

なし。テスト実行による `__pycache__` アーティファクトはタスクランナーによって削除されました。コーディネーターによる
スイープにより、ワークスペースがクリーンであることが確認されました。

## 表示された出力(原文のまま)

ローカルスケジューラフィクスチャのモデル、リポジトリ、サービス各レイヤーにわたるスケジュール済みジョブに、整数型の `priority` フィールドを追加し、フィルタリングされた一覧にも反映しました。

**`scheduler/models.py`** — モジュール定数 `MIN_PRIORITY = 0` / `MAX_PRIORITY = 9` および、整数でない場合や 0~9(両端を含む)の範囲外の値に対して `ValueError` を発生させる再利用可能な関数 `validate_priority(priority)` を追加しました。 `bool` は `int` のサブクラスであるにもかかわらず明示的に拒否されるため、`True` が優先度 1 としてすり抜けることはありません。 凍結された `Job` データクラスには、デフォルト値を持つ末尾フィールドとして `priority: int = MIN_PRIORITY` が追加されました。これにより、既存の 3 引数によるコンストラクタの動作が維持されます。また、バリデータ呼び出しを行う `__post_init__` が追加され、いかなる経路からも無効な優先度が生成されないようになっています。 `to_dict()` は `asdict(self)` のままにされたため、優先度はシリアライズされた出力に自動的に、かつフィールド順で表示される。

**`scheduler/repository.py`** — `JobRepository.all()` はオプションの `min_priority` を受け取り、既存の `sorted(self._jobs)` リスト内包表記内でフィルタリングを行います。これにより、フィルタリング後に改めて順序を確立するのではなく、すでに昇順の識別子順序を保証していたのと同じ単一のコードパスによって、その順序が保証されます。 デフォルトの引数は、既存の呼び出し元に対して従来の引数なしの挙動を維持します。ストレージ自体に変更は必要ありませんでした。リポジトリは `Job` インスタンス全体を格納するため、優先度は保持され、`save`/`get`/`all` を通じて往復します。

**`scheduler/service.py`** — `create_job` は、末尾にオプションの `priority` 引数(デフォルトは 0)を受け取り、`Job` を構築する前にその有効性を検証します。これにより、既存の空白名チェックと同じ `ValueError` 契約に基づき、サービス境界で例外がスローされます。 `list_jobs(min_priority=0)` はリポジトリに処理を委譲します。順序付けとフィルタリングは重複することなく、一箇所に集約されています。

**`min_priority` の検証に関する設計上の注記:** 整数として型チェックされますが、意図的に 0~9 の範囲に制限されていません。 0~9のルールは、ジョブが格納できる値に制約を課します。しきい値はクエリパラメータであり、例えば `min_priority=10` を拒否すると、正当な「一致する結果なし」のクエリがエラーになってしまうからです。 優先度 9 のジョブが存在しない場合に `list_jobs(min_priority=9)` が `[]` を返す動作については、テストでカバーされています。

`scheduler/time_rules.py` は確認しましたが、変更は加えませんでした。ドキュメントに記載されている夏時間への切り替えは、以前から実装されていた動作であり、今回のタスクの範囲外であるため、これを変更することは本件とは無関係な動作変更となるためです。 ファイルの追加や削除は行われていないため、`fixture-manifest.json` は正確なままです(プログラムで検証済み)。

### テストカバレッジを追加

デフォルト値は 0;`JobRepository` 経由のストレージ往復処理;`to_dict()` 出力における優先度;境界値 0 および 9 は受け入れ;範囲外(−1/10/100)は拒否; 非整数の `"3"`/`3.5`/`None`/`True` は拒否;モデルレベルでの直接検証;フィルタリングされていないリスト順;識別子の昇順を維持したフィルタリング済みリスト;包括的なしきい値;空の結果;非整数の `min_priority` は拒否。.

フィクスチャの制限事項:これは小規模なオフラインのPythonリポジトリでした。Claudeでは、CLI OAuthの有効期限が切れた後にサブエージェントのフォールバックが使用されていたため、分離状態とトークンの可視性は一致していませんでした。.

エッジケースにおけるバグ修正

T3は、夏時間に関するスケジューリングの欠陥をテストしました。両エージェントとも30/30のスコアを獲得し、春と秋の隠しチェックをともに通過しました。Claudeコードでは、曖昧な現地時間やスキップされた現地時間、単純な入力、および複数日にわたるロールオーバーに対する明示的なカバレッジが追加されました。Codexは、暦日の変更範囲を狭め、凍結された契約を通過しました。.

ライブラリが広く再利用される場合や、スケジューリングエラーによるコストが高い場合には、エッジケースのテスト範囲を広げることで信頼性が高まります。一方、不具合が明確に特定されており、チームが動作の変更を最小限に抑えたい場合には、変更範囲を狭くすることが望ましいです。 実務上のレビューの焦点は、「どちらがより多くのコードを書いたか」ではありません。重要なのは、そのパッチが指摘された根本原因を修正し、周辺の契約を保持し、リスクのある境界を検証できているかどうかです。.

T3 · 管理リポジトリのテスト

夏時間への移行に伴う日次スケジューリングの修正

春と秋の季節の変わり目においても、指定されたニューヨーク式の壁掛け時計の時刻を維持してください。.

ネクタイ・さまざまな太さ
コーデックス30/30
期間99秒
小切手4 + 2(非表示)
スコープ部分的な修正
最初の有効な出力の抜粋
根本原因:実装により、UTC時間が24時間分加算されてしまった。

修正:ローカルカレンダー上で1日分進めた。凍結された春と秋のチェックの両方に合格した。.

レビュアーの見解: より範囲の狭い修正案が、凍結された契約案全体を可決した。.

クロード・コード30/30
期間118秒
小切手10 + 2(非表示)
スコープエッジのカバー範囲
最初の有効な出力の抜粋
春と秋、欠落および不明確な現地時間、単純な入力、および複数日にわたるロールオーバーについて検証しました。

回帰テストの範囲を拡大した結果、凍結されていた隠れたチェックが両方とも合格しました。.

レビュアーの見解: エッジケースの網羅性が向上。固定された評価基準の下では、機能スコアは変わらない。.

Codexの出力をすべて表示

完全にサニタイズされた、最初の有効な出力

夏時間(DST)の修正を実装しました。

変更されたファイル:

- [scheduler/time_rules.py](./scheduler/time_rules.py)
- [tests/test_time_rules.py](./tests/test_time_rules.py)

変更点:

- UTC 24時間ではなく、ローカルカレンダーで1日分進めるように変更しました。
- ニューヨークの夏時間開始および終了に関する回帰テストを追加しました。
- 経過したUTC間隔が、それぞれ23時間および25時間であることを確認しました。

検証結果:

- ユニットテスト:4件が合格。
- メモリ内構文チェック:7つのPythonファイルが合格。
- Pythonがキャッシュを割り当てられたワークスペース外にリダイレクトするため、バイトコードのコンパイルがブロックされました。外部ファイルへの書き込みは行われませんでした。

**結論:** `next_daily_run`は、夏時間(DST)の切り替え時においても、指定された実時間(wall-clock)の時間を維持するようになりました。決定事項はありません。.
Claudeコードの出力をすべて表示

最初の有効な出力を逐語的に含んだ、完全なハンドオフ記録

# T3 実行記録 — DST のバグ修正

## 実行パラメータ

| フィールド | 値 |
| --- | --- |
| タスク | `T3` |
| 凍結プロンプト | `01-prompts/T3.md` |
| 凍結プロンプトの SHA-256 | `3fee50d0230f27f8d6dd7f12e050fa3f0b7f5fb77d9559361fee96e5f1a47307` |
| 実行ユニット | 隔離された Claude サブエージェント、`汎用`、新規コンテキスト |
| 隔離方法 | **サブエージェントのフォールバック**(文書化されたダウングレード — `results/isolation-decision.md` を参照) |
| 割り当てられたクリーンコピー | `runtime/workspaces/T3` |
| Claude コードバージョン | `2.1.220` |
| モデル設定 | `claude-opus-5` |
| start_utc | `2026-07-28T10:28:05Z` |
| end_utc | `2026-07-28T10:30:03Z` |
| 所要時間 | 118 秒(T1、T2、T4と並行実行;純粋なレイテンシ測定ではない) |
| 試行回数 | 1 |
| ステータス | `valid` |
| 人的介入 | なし |

## Safe ツール概要

`date`、割り当てられたワークスペース内での `Read`/`Edit` のみ、`python3 -m unittest discover`、
`python3 -m compileall`、メモリ内での陰性対照実行、マニフェストの整合性チェック。
標準ライブラリのみ(`datetime`、`zoneinfo`、`unittest`)。ネットワーク接続なし、インストールなし。

## 変更されたファイル

`scheduler/time_rules.py`(修正箇所 — `next_daily_run` の本体と docstring のみ)、
`tests/test_scheduler.py`(`NextDailyRunTests` を追加、8 つのテスト、および `_elapsed` ヘルパー;
既存のテストは変更なし)。他のモジュールには手を加えず、ファイルの追加もありません。完全なパッチ:
`results/T3/patch.diff`。

## オフラインチェックの結果

タスクランナーによる報告:

| チェック | 結果 |
| --- | --- |
| `python3 -m unittest discover -s tests -v` | **10 件が合格、0 件が失敗** (既存 2 件 + 新規 8 件) |
| `python3 -m compileall -q scheduler tests` | 問題なし |
| `fixture-manifest.json` とのマニフェスト整合性 | 欠落 0、予期しない項目 0 |
| ネガティブコントロール:メモリ内でパッチ適用されたシード実装、`NextDailyRunTests` のみ | 8 件実行、**意図通り 5 件が失敗**(DST テストの両方を含む) |

ワークスペース外からコーディネーターが独立して再検証:

| チェック | 終了 | 結果 |
| --- | --- | --- |
| パブリックスイート (`results/checks/T3-public.txt`) | 0 | 10 テスト、OK |
| 非公開バリデータ `03-checks/test_t3_hidden.py` (`results/checks/T3-hidden.txt`) | 0 | 2 テスト、OK |

非公開バリデータは、未変更のフィクスチャのコピーに対して失敗(終了コード 1)しています。詳細は
`results/checks/validator-controls.md` を参照してください。

## ゴールドマップの動作カバレッジ

`03-checks/gold-map.json` に定義された 4 つの必須動作すべてが満たされています:

| 必須動作 | 検証結果 |
| --- | --- |
| 実時計の時間が保持される | 単純なローカル実時計にインクリメントが適用され、タイムゾーンが再設定される;すべての夏時間テストでアサート |
| 春時間の移行がカバーされている | `test_spring_forward_keeps_requested_hour` — 時刻 09:30 を保持、オフセット `-04:00`、経過時間 23 時間 |
| 秋時間の移行がカバーされている | `test_fall_back_keeps_requested_hour` — 時刻 09:30 が保持され、オフセット `-05:00`、経過時間 25 時間 |
| IANA タイムゾーンが使用されている | 標準ライブラリの `ZoneInfo("America/New_York")` |

必須のセットに加え、ランナーは PEP 495 の 2 つのエッジケース — サマータイム開始により
スキップされた実時間と、サマータイム終了時の曖昧な実時間 — に加え、各移行期間にまたがる
7 日間のロールオーバーおよびナイーブ入力時の挙動も網羅しました。

## 修正済みエラー

2つの自己招いたテストアサーションの失敗:同じ
`tzinfo`を共有する2つのdatetimeに対する `following - previous` は、ナイーブな実時間を差し引くため、経過時間のアサーションが1日と読み取られ、失敗した。
実装は正しく、アサーションが誤っていた。両オペランドをまずUTCに変換する `_elapsed`
ヘルパー関数を用いて修正した。ツール、インポート、環境に関するエラーはなかった。
実行後、`__pycache__` のアーティファクトは削除された。

## 可視出力 (原文のまま)

**再現手順**

2024年の夏時間移行の前後で、`America/New_York` の日時を両側に指定して `scheduler/time_rules.py::next_daily_run` が呼び出されました:

```
2024-03-09T09:30:00-05:00 -> 2024-03-10T10:30:00-04:00   # 1時間のずれ +1
2024-11-02T09:30:00-04:00 -> 2024-11-03T08:30:00-05:00   # 時刻が -1 ずれた
```

現地時間の09:30に実行が要求されたジョブが、サマータイム開始後は10:30に、サマータイム終了後は08:30に実行されました。

**根本原因**

初期実装では、「daily」を固定の絶対期間として扱っていました:

```python
elapsed = previous_run.astimezone(timezone.utc) + timedelta(hours=24)
return elapsed.astimezone(previous_run.tzinfo)
```

最初にUTCに変換すると、`timedelta(hours=24)`は正確に24時間の経過時間となります。 しかし、IANAタイムゾーンにおける現地の暦日は、夏時間への切り替え日には23時間、冬時間への切り替え日には25時間となるため、24時間という定数のオフセットを適用すると、必然的に要求された実時間から1時間ずれてしまいます。

**修正方法** (`scheduler/time_rules.py`)

毎日の繰り返しはカレンダールールであるため、増分処理はまず単純なローカル実時間に適用され、その後でタイムゾーン情報が再設定されるようにしました:

```python
tzinfo = previous_run.tzinfo
naive_next = previous_run.replace(tzinfo=None) + timedelta(days=1)
if tzinfo is None:
    return naive_next
candidate = naive_next.replace(tzinfo=tzinfo, fold=0)
return candidate.astimezone(timezone.utc).astimezone(tzinfo)
```

これが正しい理由:
- 単純な値に対する実時計の演算はオフセットに依存しないため、指定された時:分は構造上保持される。 `zoneinfo` は、新しい日付で有効な UTC オフセットを供給します(検証済み:夏時間開始後は `-04:00`、冬時間開始後は `-05:00`、それぞれ経過実時間は 23 時間および 25 時間)。
- `fold=0` と UTC の往復処理により、純粋な実時間演算では定義が不明確となる 2 つの境界ケースが処理されます。PEP 495 では、*スキップされた*実時間 (2024-03-10 02:30)は、`fold=0` の場合、移行前のオフセットを持つため、ラウンドトリップ処理によって、特定の瞬間を指定しない datetime を返すのではなく、実際の瞬間である 03:30 EDT に正規化されます。 *曖昧な*実時間(2024-11-03 01:30)は、恣意的な値となるのではなく、最初の発生時刻(EDT)に決定論的に解決されます。
- 単純な入力については従来通りの意味(純粋に+1暦日)が維持されます。呼び出し元に対して新たな `tzinfo` の要件は課されません。

変更範囲は最小限に抑えられました:`next_daily_run` の本体およびドキュメント文字列のみが変更されました。 `service.py`、`models.py`、`repository.py`、および `__init__.py` は変更されておらず、新しいファイルも追加されていません。また、フィクスチャのマニフェストも依然として完全に一致しています(欠落や予期しないファイルはありません)。使用されているのは標準ライブラリのみです(`datetime`、`zoneinfo`、`unittest`)。

**回帰テスト**(`tests/test_scheduler.py`、 新しい `NextDailyRunTests`、8つのテスト)は、通常日の安定性、夏時間への切り替え(時刻+オフセット+経過23時間)、冬時間への切り替え(時刻+オフセット+経過25時間)、各切り替え期間をまたぐ7日間のロール、スキップされた実時間、曖昧な実時間、および単純な入力を網羅しています。

記録しておくべき点が2つあります。まず、当初の経過時間アサーションでは `following - previous` を使用していました。Pythonは共有の `tzinfo` を無視し、ナイーブな実時間を差し引くため、どちらも1日と返され、テストは失敗しました。 実装は正しく、アサーションが間違っていた――両オペランドをUTCに変換する `_elapsed` ヘルパー関数を使用して修正した。 次に、シード済みの実装のメモリ内コピーに対して `NextDailyRunTests` を再実行し、テストが実際に元の欠陥を捕捉していることを確認しました。8件中5件が失敗し、その中には両方の夏時間(DST)テストも含まれていました。 バグのあるバージョンで合格した3つのケース(通常の日、スキップ、曖昧)は、回帰バグを検出するというよりは動作を文書化したものに過ぎません。スキップおよび曖昧なケースが偶然一致しているのは、+24時間の絶対的なシフトがたまたま同じ正規化された瞬間に当たったためです。.

フィクスチャの制限事項:これは小規模なオフラインのPythonリポジトリでした。Claudeでは、CLI OAuthの有効期限が切れた後にサブエージェントのフォールバックが使用されていたため、分離状態とトークンの可視性は一致していませんでした。.

コードレビューの品質と人的検証

コードレビューのタスクには、機能の実装とは異なるスキルが求められます。優れたレビューアは、再現可能な問題を見つけ出し、その影響度を評価し、正確なコードパスを特定し、実際の不具合と推測に基づく警告を見分ける必要があります。問題を修正する際には、さらに別のテストが加わります。つまり、パッチによって新たな回帰不具合が生じてはならないということです。.

T4では、Claude Codeが最も明確な優位性を示した。 同チームは、仕込まれたレビュー対象を含む5つの独立して再現可能な不具合を報告し、20点中19点を獲得した。一方、Codexは2つの有効な高深刻度の不具合を報告・修正したが、仕込まれたペアについては言及せず、20点中18点を獲得した。Codexの報告は誤検知ではなく、両者の違いは基本的な正確さではなく、検出範囲の広さによるものであった。.

T4 · 管理リポジトリのテスト

再現可能な不具合を見つけ出し、信頼度の高い問題を修正する

テストケースを確認し、実際の不具合を再現し、許可された修正を適用し、回帰テストによってその動作が確実に反映されていることを確認する。.

Claudeのカバレッジエッジ
コーデックス18/20
期間223秒
小切手4が合格した
スコープ2 修正済み
最初の有効な出力の抜粋
1. 高 — 既存のジョブが気付かれないうちに上書きされる可能性がある。

2. 中 — 夏時間への切り替えに伴い、毎日の実行スケジュールがずれてしまった。

検証結果:4つのテストが成功し、失敗は0件。.

レビュアーの見解: 有用な高深刻度の問題が発見され、的を絞った修正も行われたが、2つの優先レビュー対象は見落とされていた。.

クロード・コード19/20
期間235秒
小切手9件が合格しました
スコープ5件の報告
最初の有効な出力の抜粋
D1 DSTのずれ · 高
D2 単純なタイムゾーンの取得 · 中
D3 識別子の衝突 · 高
D4 削除処理の欠落によりKeyErrorが発生 · 中
D5 所有者の検証不足 · 低

レビュアーの見解: 再発した偽陽性がゼロとなり、レビューの対象範囲が拡大した。契約に起因する2件の所見については、修正されなかった。.

Codexの出力をすべて表示

完全にサニタイズされた、最初の有効な出力

## 対応が必要な発見事項

1. **高 — 既存のジョブが気付かれないうちに上書きされる可能性がある**

   - 根拠:[service.py](./scheduler/service.py:8) での識別子の初期化と、[repository.py](./scheduler/repository.py:9) での辞書の置換が組み合わさっていること。
   - 影響:既存のリポジトリを使用してサービスを作成すると、識別子 `1` が再利用され、保存済みのジョブが上書きされてデータ損失が発生する可能性があります。
   - 最小限の再現手順:`Job(1, ...)` を保存し、`SchedulerService(repository)` を構築した後、別のジョブを作成します。修正前は、新しいジョブのみが残っていました。
   - 修正: リポジトリ内の既存の識別子の中で最も大きいものから、次の識別子を初期化するようにしました。
   - 回帰テスト: [test_scheduler.py](./tests/test_scheduler.py:22)。

2. **中程度 — 夏時間への移行に伴い、毎日実行されるジョブの実行時刻がずれた**

   - 証拠:[time_rules.py](./scheduler/time_rules.py:4) 内の計算を修正しました。
   - 影響:09:00にスケジュールされていたデイリージョブが、春の夏時間移行後に10:00に実行された。
   - 最小限の再現手順:`2026-03-07 09:00 America/New_York` 以降の次の実行時刻を計算する。 修正前は、結果は `2026-03-08 10:00` となっていました。
   - 修正:経過したUTC時間24時間ではなく、ローカルカレンダー上の1日を追加しました。
   - 回帰テスト:[test_scheduler.py](./tests/test_scheduler.py:33)。

## 変更されたファイル

- [scheduler/service.py](./scheduler/service.py)
- [scheduler/time_rules.py](./scheduler/time_rules.py)
- [tests/test_scheduler.py](./tests/test_scheduler.py)

## 検証

- 修正前は、2つの回帰テストがともに失敗することが確認された。
- それぞれの修正後、各テストは合格した。
- `PYTHONDONTWRITEBYTECODE=1 python3 -m unittest discover -s tests -v`
- 結果:**4件のテストが合格、0件の失敗**。
- 生成された Python キャッシュアーティファクトは残っていません。

## 結論と決定

- **結論:** 確認された 2 つの不具合は修正され、対象を絞った回帰テストによってカバーされています。
- **必要な決定:** なし。.
Claudeコードの出力をすべて表示

最初の有効な出力を逐語的に含んだ、完全なハンドオフ記録

# T4 実行記録 — テストおよびコードレビュー

## 実行パラメータ

| フィールド | 値 |
| --- | --- |
| タスク | `T4` |
| 凍結プロンプト | `01-prompts/T4.md` |
| フローズンプロンプトのSHA-256 | `5e69546007ea776f40b3d334ddb75671ff684c151c77551bad27de3b0fdce640` |
| 実行ユニット | 隔離された Claude サブエージェント、`汎用`、新規コンテキスト |
| 隔離方法 | **サブエージェント・フォールバック**(文書化されたダウングレード — `results/isolation-decision.md`を参照) |
| 割り当てられたクリーンコピー | `runtime/workspaces/T4` |
| Claude コードバージョン | `2.1.220` |
| モデル設定 | `claude-opus-5` |
| start_utc | `2026-07-28T10:28:22Z` |
| end_utc | `2026-07-28T10:32:17Z` |
| 所要時間 | 235 秒(T1~T3と並行して実行されたため、純粋なレイテンシ測定値ではない) |
| 試行回数 | 1 |
| ステータス | `有効` |
| 人的介入 | なし |

フリーズされたプロンプト内の条件文 — 「フリーズされた実行構成が修正を許可する場合は、
それらを修正する」 — は、コーディネーターによって `00-control/run-config.json` および
`00-control/safety-policy.json` からコーディネーターによって解決され、これにより隔離されたフィクスチャのコピーへの書き込みが許可されました。ランナーには
修正が許可されていることが通知されました。制御ファイルは一切提示されませんでした。

## 安全なツールの概要

`date`、割り当てられたワークスペース内での `Read`/`Edit`/`Write` のみ、`grep`、
`python3 -m unittest discover`、`python3 -m compileall`、スクラッチコピーによる空の実行、
マニフェストの存在確認。ネットワークなし、インストールなし、標準ライブラリのみ。

## 変更されたファイル

`scheduler/time_rules.py`(変更済み)、`scheduler/service.py`(変更済み)、
`tests/test_scheduler.py`(変更済み、テスト2件追加)、`tests/test_time_rules.py`(新規追加、テスト5件)。
完全なパッチ:`results/T4/patch.diff`。

## オフライン検証結果

タスクランナーによる報告:

| 検証項目 | 結果 |
| --- | --- |
| `python3 -m unittest discover -s tests -v` | **9 件合格、0 件失敗、0 件スキップ** (ベースライン 2) |
| `python3 -m compileall -q scheduler tests` | 合格 |
| `expected_files` に対するマニフェスト存在確認 | 8つすべて存在 |
| 復元された元の実装に対する vacuity 実行 | 5件の失敗、4件の合格、想定通り |

ワークスペース外からコーディネーターが独立して再検証した結果:

| チェック | 終了 | 結果 |
| --- | --- | --- |
| パブリック・スイート (`results/checks/T4-public.txt`) | 0 | 9 テスト、OK |

参考用のクロスチェック(スコア対象外):T3の非公開バリデータもこの
ワークスペースに対して合格(終了コード 0)しています。これは、T4が独立して同じ`next_daily_run`の欠陥を修正したためです。詳細は
`results/checks/validator-controls.md`を参照してください。

## ゴールドマップ欠陥カバレッジ

`03-checks/gold-map.json` は、T4 スコアリング用に 2 つの欠陥をシードしています。両方が検出されました:

| シードされた欠陥 | 検出 | 報告内容 |
| --- | --- | --- |
| 所有者未設定で受け入れ済み | はい | **D5**, `scheduler/service.py:11,13`, 重大度 Low, 報告済みで意図的に修正されていない |
| 存在しない識別子の削除により `KeyError` が発生 | はい | **D4**, `scheduler/repository.py:19` → `service.py:22`, 重大度 Medium, 報告済みで意図的に修正されていない |

仕込まれたセット以外に、さらに3件の不具合が報告されました。いずれも誤検知ではありません:

- **D1** — `next_daily_run` における夏時間(DST)のずれ。これは
  `03-checks/seeded-defects.md` に記載されている3番目の欠陥です(スコアは T4 ではなく T3 ですが、これは本物のシードされたバグです)。
- **D2** — `next_daily_run` への単純な入力により、ホストのタイムゾーンが黙って取得され、
  それを反映した datetime が返される。実在する不具合であり、ホストに依存する。コーディネーターがフィクスチャのソースコードと照合して検証済み。
- **D3** — サービスと注入された、または共有されたリポジトリの間で識別子の衝突が発生し、
  無警告の上書きを引き起こす。実在する不具合:`SchedulerService._next_identifier` は常に 1 から開始される一方、
  `JobRepository.save` はガードのない辞書代入である。 T1は、未改変のフィクスチャから独立して同じ
  不具合を特定した。

誤検知数:**0**。ランナーも、フィクスチャにネットワーク、I/O、デシリアライゼーション、サブプロセス、または認証情報の脆弱性が存在しないことを指摘し、
セキュリティ上の問題がないことを正しく報告した。

## 記録すべき逸脱

固定されたプロンプトでは、「信頼度の高い 2 つの欠陥」に対するテストと修正が求められていた。 実行者は、
ゴールドマップに埋め込まれた2つの欠陥 D4 と D5 ではなく、D1/D2(1つの修正、同一関数)および D3 を選択した。
その理由として挙げられた説明は妥当である。D4 と D5 はどちらも未指定の API
契約に依存しているため、これらを修正するのは推測に頼ることになるからだ。 検出実績には影響がない — シードされた2つの欠陥は
いずれも、ファイル、行番号、重大度、影響度、再現手順とともに検出された。適用された修正は実際の
欠陥に対するものであり、空虚性チェックによって裏付けられている。

## サニタイズされたエラー

`tzinfo`を共有する日付時刻に対する、実時間と絶対時間の引き算による2件の自己起因のテスト失敗。
修正し、再検証済み。ツールや環境のエラーはなし。実行後に`__pycache__`
アーティファクトが削除された。

## 可視出力(原文のまま)

### 不具合報告

**D1 — `scheduler/time_rules.py:10-11` — 夏時間(DST)の切り替えに伴い、日次スケジュールが1時間ずれる — 重大度:高**

`next_daily_run` は、暦日を前進させる代わりに、UTC 往復通信を介して 24 *経過* 時間を加算しています。 デイリージョブは実時間で定義されているため、夏時間を採用するタイムゾーンでは、移行日以降、すべてのジョブが1時間早まったり遅れたりして黙って実行され、このエラーは継続します(各実行で、ずれた時刻から再シードされます)。ドキュメント文字列自体にもこの挙動が記載されていました。

```
prev = datetime(2024, 3, 9, 9, 0, tzinfo=ZoneInfo("America/New_York"))
next_daily_run(prev)   # -> 2024-03-10 10:00:00-04:00、期待値 09:00-04:00
prev = datetime(2024, 11, 2, 9, 0, tzinfo=ZoneInfo("America/New_York"))
next_daily_run(prev)   # -> 2024-11-03 08:00:00-05:00、予想 09:00-05:00
```

**D2 — `scheduler/time_rules.py:10-11` — 単純な入力の場合、マシンのローカルタイムゾーンが黙って取得される — 重大度: 中**

同じ2行です。ナイーブなdatetimeに対する`.astimezone(timezone.utc)`はシステムのローカルタイムを仮定し、`.astimezone(None)`はタイムゾーンを意識したdatetimeを返します。 Naiveな値で呼び出すと、タイムゾーンを意識した値が返されるため、結果は呼び出し元の他のNaiveな値と比較できず(比較時に`TypeError`が発生)、答えはホストの`TZ`に依存します。

```
next_daily_run(datetime(2024, 1, 1, 9, 0))
# -> datetime(2024, 1, 2, 9, 0, tzinfo=timezone(timedelta(hours=8), "CST"))  # ホスト依存
```

**D3 — `scheduler/service.py:8,13,15` (pre-fix) — 識別子の競合により、保存されたジョブが黙って破棄される — 深刻度: 高**

ID カウンターは `SchedulerService` ごとに設定され、注入されたリポジトリの内容を無視して常に 1 から開始されていました。共有リポジトリ上の 2 つ目以降のサービス、または事前にデータが格納されたリポジトリ上のサービスは、ID 1 を再発行していました。 `JobRepository.save`は辞書の代入であるため、既存のジョブはエラーなしで上書きされていました。データ損失が発生します。

```
repo = JobRepository()
SchedulerService(repo).create_job("Nightly backup", 'Alex')    # ID 1
SchedulerService(repo).create_job("給与明細のエクスポート", "Blake")   # 再び ID 1
repo.all()   # -> [Job(1, "給与明細のエクスポート", "Blake")]  — アレックスのジョブが消えた
```

**D4 — `scheduler/repository.py:19` → `scheduler/service.py:22` — `delete_job` が未知の ID に対して `KeyError` を発生させる — 重大度: 中**

`delete` はデフォルト値なしで `dict.pop` を使用しているが、同階層の `get`(13行目)はヒットしなかった場合に `None` を返す。 この不整合により、`SchedulerService.delete_job` を通じて生の `KeyError` が漏洩しており、呼び出し側がこれをキャッチすることはまずないでしょう。再現例: `SchedulerService().delete_job(999)` → `KeyError: 999`。 修正方法としては `pop(identifier, None)` または明示的なドメイン例外の発生が考えられますが、正しい契約(静的なノーオペレーション対型付きエラー)は所有者のAPI設計上の判断であるため、意図的に未修正のままとしています。

**D5 — `scheduler/service.py:11,13` — ownerフィールドの検証が行われていない — 重大度: 低**

`name` には空文字列チェックがありますが、`owner` にはありません:`create_job('ok', '   ')` は `owner=""` を格納します。また、両方のパラメータで `.strip()` がガードなしで呼び出されているため、`None` が `AttributeError: "NoneType" オブジェクトには 'strip' 属性がありません` として表示され、APIが通常不正な入力に対して使用する `ValueError` とは異なります。修正せず放置 — 意図された所有者に関する契約は、フィクスチャ内のどこにも明記されていません。

**セキュリティ:** 問題なし。このフィクスチャには、ネットワーク、I/O、デシリアライゼーション、サブプロセス、または認証情報の公開箇所はなく、ストレージはプロセス内の辞書です。

**カバレッジの不足:** `scheduler/time_rules.py` および `scheduler/repository.py` は、今回の実行前はテストカバレッジがゼロでした。シードされた 2 つのテストは、サービスの正常経路のみを検証していました。

### テストおよび修正の適用

信頼度の高い2つの欠陥は、**D1/D2**(同一関数、1つの修正)および**D3**でした。

**修正 1 — `scheduler/time_rules.py`:** UTC の往復計算を `previous_run + timedelta(days=1)` に置き換えました。 Pythonは、時間情報を認識したdatetimeに対して実時間演算を行い、`zoneinfo`は新しい実時間からUTCオフセットを遅延的に再解決します。そのため、09:00は09:00のまま維持され、オフセットは正しく`-05:00 → -04:00`へと変更されます。 これにより、D1とD2が同時に修正されます。単純な入力はそのまま単純なままとなり、ローカルタイムゾーンが推測されることはなくなりました。「到達不能」と「曖昧」の境界となる移行時間については、tzinfoのフォールドルールに委ねられることが文書化されています。

**修正 2 — `scheduler/service.py`:** インスタンスごとの `_next_identifier` カウンターを削除しました。識別子は、作成時にリポジトリの状態から `max(既存の ID, デフォルト=0) + 1` として割り当てられるようになりました。これは、共有リポジトリと事前入力済みリポジトリの両方で正しい動作です。 トレードオフ:作成ごとに O(1) ではなく O(n) となるが、辞書(dict)をバックエンドとするインメモリストアでは許容範囲であり、書き込み先のストアを認識できないカウンタを使用するよりも正確性が高い。

**テスト — `tests/test_time_rules.py`(新規、5 つのテスト):** 春進・秋戻し時の実時間保持、それらの遷移における絶対経過時間(23時間/25時間)、UTCオフセットの再解決、「naive-stays-naive」ルール、および単純なUTCの日進。IANAデータベースが存在しない場合は正常にスキップされる。

**テスト — `tests/test_scheduler.py` (拡張、テスト2件追加):** 1つのリポジトリを共有する2つのサービスは、異なるIDを発行し、両方のジョブを維持しなければならない。ID 1と7が事前に登録されたリポジトリを管理するサービスは、ID 8を発行し、既存のジョブをそのまま残さなければならない。

**欠陥確認:** スクラッチコピーに元の実装を両方復元し、テストスイートを再実行しました。5つの新しいテストはすべて失敗(`FAILED (failures=5)`)しましたが、修正後のコードではすべて合格しました。これらのテストは、実際に欠陥を特定しています。

実行中に1点修正しました。最初の草案では、経過したDST時間を `result - previous` としてアサーションしていましたが、両オペランドが同じ tzinfo を共有している場合、Python はこれを実時間演算として評価するため、`24h` と解釈され、テストが失敗していました。現在のアサーションでは、減算する前にUTCに変換するよう修正しました。 この失敗は修正箇所ではなく、私のテストに起因するものでした。

### オーナーへの注記

`fixture-manifest.json` は変更されていないため、`tests/test_time_rules.py` は `expected_files` にリストされていない正当な新規ファイルです。チェックで正確なファイルセットが強制される場合は、マニフェストを更新してください。 また、D4/D5は報告されましたが、意図的に修正は行っていません。これらはいずれも、フィクスチャ内のどこにも明記されていないAPI契約の決定(削除時の挙動、所有者の検証ルール)に依存しているため、どちらか一方を選択することは修正というよりは推測に過ぎなかったでしょう。.

フィクスチャの制限事項:これは小規模なオフラインのPythonリポジトリでした。Claudeでは、CLI OAuthの有効期限が切れた後にサブエージェントのフォールバックが使用されていたため、分離状態とトークンの可視性は一致していませんでした。.

どちらのスコアも、人間による確認の必要性を排除するものではありません。いずれかのエージェントが修復を完了したら、変更されたインターフェース、予期しないファイルの範囲、欠落しているネガティブテスト、権限やコマンド履歴、およびロールバックパスを確認してください。確信に満ちた説明は、再現可能なテストの代わりにはなりません。.

権限、サンドボックス化、および運用上の安全性

コーディングエージェントは、非公開のコードを読み取り、シェルコマンドを実行し、多数のファイルを変更し、外部ツールを呼び出すことができます。そのため、権限設計は製品の品質を左右する要素となります。ここで重要なのは、どの操作に承認が必要か、エージェントがデフォルトで何にアクセスできるか、リスクを伴う操作がどの程度明確に警告されるか、そして開発者がその結果生じた変更内容を確認できるかどうか、といった点です。.

承認の確認画面が少ないからといって、必ずしもそれが良いとは限りません。認証情報や本番環境への接続がない、孤立したテスト環境では、操作の煩わしさを軽減することは有益です。しかし、デプロイメントスクリプトや実際の顧客データ、あるいは広範なクラウド権限に接続されたリポジトリでは、同じ動作が危険を招く可能性があります。逆に、承認の手順が多すぎると、安全な自動化が現実的ではなくなり、ユーザーがリクエストの内容を確認せずに承認してしまう原因にもなりかねません。.

今回のテストでは、本番システムやデプロイメントは一切行わず、有効な実行における人的介入も排除し、新たに作成したローカルコピーのみを使用しました。したがって、このテストは2つの製品の相対的なセキュリティではなく、安全な条件下でのタスク完了状況を評価するものです。 重要な作業でいずれかのツールを使用する前に、まずは読み取り専用アクセスから始め、許可されるディレクトリとコマンドを定義し、差分を確認した上で、復旧可能な環境で客観的なチェックを実行してください。.

  • まずは読み取り専用アーキテクチャから始めるか、リスクを冒すかの選択です。.
  • その範囲と結果を理解しているコマンドのみを承認してください。.
  • 認証情報、本番データ、およびデプロイメントへのアクセス権は、トライアル環境の外に保管してください。.
  • 結果を受け入れる前に、差分、テスト、および明確なロールバック手順を要求する。.

MCP、スキル、プロジェクトの指示、およびカスタマイズ

どちらのエコシステムも拡張可能ですが、拡張という用語を同義語として扱うべきではありません。プロジェクトの指示は、エージェントに対してリポジトリ内での振る舞い方を指示するものです。再利用可能なスキルは、繰り返し可能なワークフローや専門知識をパッケージ化したものです。MCPは、ホストを外部ツールやデータに接続します。フックやコマンドは、開発ループの特定の段階を自動化することができます。 ある製品は、あるレイヤーにおいて優れていても、別の機能と一対一で対応していなくてもよいのです。.

購入の判断基準は、統合用ロゴの有無ではありません。重要なのは、実際に使用しているホスト上で、その接続をインストール、認証、承認し、運用できるかどうかです。また、失敗時の挙動が理解しやすいことも必要です。 対話モードでは動作するが、無人セッションでは承認を待つMCPサーバーも有用ではありますが、それを「摩擦のない自動化」と表現すべきではありません。.

再利用可能な指示にも同様の注意点があります。指示ファイルが長ければコンプライアンスが保証されるわけではなく、ルールセットが過度に複雑になると、文脈が失われたり矛盾が生じたりする可能性があります。リポジトリのガイダンスは、簡潔でテスト可能であり、コードに密接に関連した内容にしましょう。必要な検証コマンド、保護対象領域、スタイルルール、およびエージェントが処理を中断して確認を求めるべきタイミングを明記してください。.

  • プロジェクトの指示: リポジトリ固有のルールおよび検証コマンド。.
  • スキル: 再利用可能なプロシージャや専門知識のパッケージ。.
  • MCP: 外部ツールやデータとの連携。.
  • フックとコマンド: 定義されたワークフローイベントに基づく自動化。.

Codex 対 Claude コードの価格設定と利用制限

「クリーン・コンシューマー」プランの比較は、月額$20から始まります。関連する$20 ChatGPTプランにはCodexへのアクセス権が含まれていますが、Claude Proは米国では月額$20で、Claude Codeが含まれています。 どちらのプランも、利用量の多いユーザー向けの「$100」および「$200」という料金プランを用意しています。表示価格が類似しているからといって、容量が同一であるとは限りません。.

Claude Max 5x の月額料金は $100、Max 20x の月額料金は $200 です。 「5x」および「20x」という名称は、保証されたコーディングタスクの数ではなく、Proプランと比較したセッションごとの利用量を表しています。ClaudeおよびClaude Codeは、セッション制限および週単位の制限を共有しています。コンテキストの長さ、添付ファイル、モデルの選択、および機能の使用状況によって、利用枠の消費速度が変わる場合があります。.

Max 5x および Max 20x の利用容量について説明した「Claude Max」プランのページ
Claudeの公式「Max」プランページには、利用容量が5倍および20倍のオプションについて記載されています。月額料金は同公式記事に記載されており、プランの詳細は2026年7月に確認されました。.

Claudeのオプション利用クレジットは、有効化されている場合、含まれる利用量を超えた後も対象となる作業を継続することができ、これらのクレジットは標準のAPI料金に基づいて別途課金されます。APIキーによる認証も、これとは別の課金ルートとなります。いずれのルートも「無制限」と呼ぶことは、実際の限界コストを隠してしまうことになります。.

Claude プランの説明資料(共有セッションおよび週ごとの利用制限について)
Claude コードでは、接続された Pro または Max サブスクリプションの割り当て量(共有セッションおよび週単位の制限を含む)が使用されます。実際の容量はワークロードによって異なります。.

Codex では同様に、含まれるコンシューマープランの利用量、対象となる購入クレジット、および API 課金を区別しています。ローカルメッセージとクラウドチャットは 5 時間の利用枠を共有しており、週ごとの制限が適用される場合もあります。CLI ログ内のトークンフィールドは、5 時間あたりの割合、サブスクリプションクレジットの残高、または API 請求額に直接換算することはできません。.

たまに一人でコーディングを行う場合、どちらのプランでも「$20」ティアが妥当なスタート地点となります。 コンテキストが長いリポジトリ作業を毎日行う場合は、より高い使用量ティアを選択する正当な理由となるかもしれませんが、それは実際のリセットやタスク消費状況を観察した上で判断すべきです。並列処理を多用する作業では、さらに細心の注意が必要です。より大きなティアに料金を支払ったとしても、コンテキストの管理、タスクの分割、そして判断力を要する作業のためにリソースを節約する必要性はなくなるわけではありません。.

「Codex」と「Claude」コードの比較試験で判明したこと

どちらのエージェントも実行を開始する前に、4つの英語のプロンプト、公開されているPythonフィクスチャ、客観的チェック、採点基準、および「最初の有効な結果」ルールを固定しました。タスクの内容は、見慣れないリポジトリの理解、複数ファイルの機能、DSTのバグ修正、および修正を伴うコードレビューでした。 有効な結果に対しては人間の介入は行われず、不十分ではあるが有効な出力については、より高いスコアを得るために再実行することはできませんでした。.

Codexは、生のJSONLとCLIによって生成されたトークンフィールドを保持した状態で、独立したCLIプロセスを実行しました。同僚のClaude CLI OAuthセッションは期限切れになっていたため、Claude Codeは新しいサブエージェントコンテキストを持つコーディネーターを使用しました。 クリーンな監査用コピーでClaudeのパッチを再現し、公開チェックと非公開チェックを再実行しました。これにより、信頼性の高い実用的な証拠が得られましたが、隔離環境やモデル制御面は同一ではありませんでした。.

タスクコーデックスクロード・コード有界解釈
T1: リポジトリの理解20/2020/20同点:コンパクトなアプローチ対網羅的なアプローチ
T2:複数ファイル対応機能30/3030/30機能的な結びつき;検証およびテストの範囲の違い
T3:DSTの修理30/3030/30どちらも合格した。狭いパッチと広いエッジカバレッジの比較
T4:点検と修理18/2019/20Claudeコードは、レビューの範囲がより広いことが示された

管理下での試験・固定評価基準

Codex 98/100 対 Claude Code 99/100

1ポイントの差は、必ずしも「勝つ」というシグナルとは限りません。有用な違いは、課題ごとに異なります。.

コーデックス98/100
クロード・コード99/100
意思決定領域観測結果実用的な読書
リポジトリの理解タイ・各20/20Claudeはより網羅的でしたが、Codexはよりコンパクトでした。.
複数ファイル機能引き分け・各30/30どちらも隠しチェックに合格しました。Claudeでは、より広範なテストが追加されました。.
DSTのバグ修正引き分け・各30/30Claudeはより多くのエッジをカバーしていたが、Codexではより狭いパッチが使用された。.
点検と修理Claude 19/20;コーデックス 18/20Claudeでは、より再現性の高い欠陥が発見された。.
観測速度ミックスClaudeがT1/T2を率い、CodexがT3/T4を率いた。.

開示事項: プロンプトとフィクスチャは同じですが、分離パスが異なります。この小規模なテストの結果を、すべてのリポジトリ、モデル層、または自律セッションに一般化しないでください。.

このテスト環境は規模が小さすぎるため、大規模なリポジトリ、あらゆる言語、あらゆるモデル階層、あるいは長時間の自律実行セッションにおけるパフォーマンスを評価することはできません。1ポイントの総合的な差は、普遍的な順位付けとしてではなく、「両者とも成功したが、レビューの範囲に違いがあった」と解釈するのが適切です。.

実際のユーザーからの報告――そして、それをどの程度信頼すべきか

コミュニティからのフィードバックは、プロジェクト、タスク、モデル、取り組みの設定、および期間といった情報が含まれている場合に価値があります。一方、ある製品が「より賢く感じる」や「はるかに高速だ」といった点だけを報告する投稿は、説得力に欠けます。ユーザーによって、比較対象となるリポジトリ、サブスクリプションプラン、プロンプト、拡張機能、および監督のレベルは異なります。.

上記のRedditの事例は、インタラクションにおけるトレードオフを示唆しています。つまり、高速で会話調のやり取りはより多くの注意を必要とする一方で、慎重な実行は遅く感じられるかもしれませんが、修正の回数は少なくて済むということです。 我々の対照実験は、その報告と部分的にしか重なりません。有効な実行では速度にばらつきが見られ、人為的な介入も確認されなかったため、「手助け」の主張を裏付けることはできません。これこそが、コミュニティからの証拠と対照実験による証拠を、混同することなく併せて提示すべき理由なのです。.

Xハーネスのコメントからは、もう1つ有益な点が指摘されています。それは、コーディングの結果はモデルラベルだけでなく、システム全体に属するものであるということです。個々の投稿を調査データとして扱うべきではありません。それらを活用して、自身の試験における検討事項――介入回数、差の大きさ、試験の質、誤った仮定からの回復――を特定してください。.

CodexおよびClaudeコードをGlobalGPTで拡張する

GlobalGPTは マルチモデル・マルチモーダルワークスペース, 、ネイティブのリポジトリアジェントの代替となるものではありません。その実用的な役割は、既存のホスト機能を拡張することにあります。つまり、セカンドオピニオン、計画のレビュー、ドキュメントの確認、あるいは特殊な出力を得るために、利用可能な別のエージェントモデルを活用する一方で、リポジトリへのアクセス、シェルコマンド、テスト、および承認については、引き続きCodexまたはClaude Codeが担当します。.

GlobalGPTは、以下の製品向けの公式CLIガイドを公開しています。 コーデックス そして クロード・コード, 、およびCursorも同様です。当社の安全なT5統合テストにおいて、CLIは両方の比較環境において、同じフリーズされたタスクを完了しました。また、Codexでは、読み取り専用のMCPモデルリスト呼び出しを検証し、GlobalGPTスキルのインストール、読み込み、および使用も行いました。.

GlobalGPTの統合 · コーディングスコアから除外

CLIは両方のワークフローで検証済み。MCPおよびSkillはCodexで検証済み。

これは統合経路を測定するものであり、GlobalGPTがいずれかの固有のコーディング因子を置き換えるかどうかを測定するものではありません。.

パスCodex環境Claude 同僚による運営
GlobalGPT CLIgpt-5.6-sol および gpt-5.6-luna を用いて検証済み同じ凍結タスクを用いて検証済み
MCPインタラクティブな読み取り専用モデル一覧の検証が完了しました実行中は接続されていません
スキル設置、読み込み、および動作確認を完了しましたインストール済みだが、通話停止機能には使用されていない
無人MCP承認の制限が確認された未検証
統合に関する証拠をすべて表示
# GlobalGPT 統合テストの概要

# # の範囲

T5 は GlobalGPT の統合度を測定するものであり、ネイティブの Codex コーディングスコアからは除外されます。Yukie は使用されませんでした。

## モデルのロックと準備状況

- モデル A: `gpt-5.6-sol`
- モデル B: `gpt-5.6-luna`
- 両モデルともライブモデルリストに表示されました。
- 両方の軽量レディネスプローブから、有効で解析可能なテキストが返されました。
- モデルは、正式な T5A および T5B 出力呼び出しの前にロックされていました。

## 正式な CLI 結果

| タスク | モデル | ステータス | 所要時間 | プロンプトトークン数 | 完了トークン数 | 必須見出し |
|---|---|---|---:|---:|---:|---:|
| T5A | gpt-5.6-sol | 有効 | 27 秒 | 2,116 | 1,207 | 6/6 |
| T5B | gpt-5.6-luna | 有効 | 14 秒 | 2,116 | 1,441 | 6/6 |

両方の正式な呼び出しは、`glbgpt exec` を通じて同じ凍結済みの英語製品企画タスクを使用し、英語のみの可視出力を返し、認証情報を一切公開しませんでした。品質再実行は発生しませんでした。

## MCP 結果

- `codex mcp list` の結果、`globalgpt` が有効になっていることが確認されました。
- 非対話型のCodexセッションが`mcp__globalgpt__glbgpt_list_models`を検出して実行を試みたが、無人でのMCP承認が利用できなかったため、呼び出しはキャンセルされた。安全設定の緩和は行われなかった。
- アクティブな対話型 Codex セッションは、同じ読み取り専用の GlobalGPT MCP ツールを正常に呼び出し、9 つのチャットモデルを取得しました。
- 結果:対話型 MCP へのアクセスは確認されました。無人での非対話型 MCP 実行には、引き続き承認の制限があります。

## スキル結果

- GlobalGPT および GlobalGPT Coding スキルは、バンドルされた CLI スキルパッケージへのリンクを通じて、Codex スキルディレクトリにインストールされました。
- GlobalGPTスキルが読み込まれ、設定済みセッションの確認、ライブモデルの選択、準備状況、クレジットセーフオプション、および障害処理について検証が行われました。
- 結果:アクティブなCodexワークフローにインストールされ、動作確認が完了しました。

## 限定的な結論

この実行により、GlobalGPT CLI 呼び出しの動作、Codex からの対話型 GlobalGPT MCP 読み取り専用呼び出し、およびインストール済みかつ使用中の GlobalGPT スキルパスが検証されました。 ただし、すべてのモデル、メディアツール、ホスト、アカウント、または無人MCP構成が機能することを証明するものではありません。また、Yukieのテストを行うものではなく、GlobalGPTがCodexやClaude Codeに取って代わるという主張を裏付けるものでもありません。.

検証範囲:特定のCLI呼び出し、1回の対話型MCP読み取り、および1つのインストール済み/使用中のスキルパス。これは、すべてのモデル、メディアツール、ホスト、または無人構成が検証されたことを示すものではありません。.

境界が重要です。同僚によるClaudeでの実行では、CLIパスが検証されましたが、Claude側のMCPは検証されていませんでした。そのスキルはそこにインストールされていましたが、フリーズした通話では使用されていませんでした。 無人でのCodex MCP実行でも、依然として手動による承認が必要でした。モデルの利用可能性やクレジットも現在のGlobalGPTプランに依存するため、開発者はすべてのモデルが含まれていると仮定するのではなく、実際のリストを確認する必要があります。.

GlobalGPTでは、画像、動画、音声、およびガイド付きエージェントワークフローも対象としています。 Yukieの「スライド」、「ドキュメント」、「画像」のエントリは別のカテゴリーに属します。これらは、コーディングを伴わないタスク向けに、明確なテンプレートとブラウザ上でのステップバイステップのガイダンスを提供します。プレゼンテーションや構造化されたドキュメントを作成する際、コーディング用のCLIを開くよりも簡単かもしれませんが、リポジトリの閲覧、テストの実行、コードレビューに取って代わるものではありません。.

異なるワークフローカテゴリ

ユキエが主導したブラウザエージェントのテスト

特定のタスクに特化したWebワークフローに有用です。リポジトリのコーディングエージェントの代替としてテストは行っていません。.

ワークフロー基準を満たしました最初の有効な結果
スライド5/65枚のスライドからなるプレゼンテーション資料が生成されました。スピーカーノートについては確認できませんでした。.
文書6/6エクスポート機能とバージョン履歴を備えた、体系的な研究概要。.
画像+キャプション5/6印象的な正方形の画像ですが、必要なキャプションが欠けていました。.

妥当な結論:明確なエントリポイントと、ガイド付きのマルチモーダルワークフロー。根拠のない結論:無制限の利用、正確な価格、あるいはCodex/Claudeコードの完全な代替。.

独立系開発者は、どのコーディングツールを選ぶべきでしょうか?

  • 「コーデックス」を選択 コンパクトで範囲が限定された実行、利用可能なサーフェスの組み合わせ、あるいはお使いの環境設定で利用可能な実行エビデンスが、ご自身の作業スタイルに合っている場合。.
  • Claudeコードを選択してください 会話型ターミナルループの場合、ユーザーが確認済みのカスタマイズ機能や、当社のフィクスチャで見られるようなより広範なレビュー動作の方が重要になります。.
  • 見慣れないリポジトリには、どちらでも使用してください 読み取り専用アーキテクチャの検証とリスク評価を経て初めて可能となります。どちらのツールも、そのタスクをうまくこなしました。.
  • 両方を状況に応じて使い分ける セカンドエージェントによるレビューが、追加のサブスクリプション費用や調整コストに見合う場合。2つ目のツールには、単にタスクを盲目的に繰り返すのではなく、差分や計画に対して異議を唱えるよう依頼してください。.
  • GlobalGPTを追加 マルチモデルルーティングやマルチモーダル処理が必要な場合。ネイティブなリポジトリ操作はコーディングホスト側で行うようにしてください。.

7日間のトライアルは、ランキング表よりも多くの情報を得られます。 本番環境以外の実際の機能やバグを1つ選び、レビューを行ってください。プロンプトと成功コマンドを固定します。最初の有効なdiff、テストの合格状況、所要時間、人的介入、予期せぬ範囲、およびその作業が利用可能な使用量にどのような影響を与えたかを記録してください。より優れた製品とは、ミスを検出でき、かつそのワークフローを維持できるものです。.

Codex 対 Claude コードに関するよくある質問

CodexはClaudeコードよりも優れているのでしょうか?

必ずしもそうとは限りません。両者とも、当プロジェクトの4つのタスクを完了しました。Claude Codeはレビューの範囲の広さでリードしましたが、実装やバグ修正の一部においては、Codexの方がよりコンパクトでした。.

大規模なリポジトリにはどちらが適していますか?

当方の小さなフィクスチャではその質問にはお答えできません。変更を許可する前に、ご自身のリポジトリから読み取り専用アーキテクチャタスクで両方を評価してください。.

どのコーディング担当者は、監督をあまり必要としないでしょうか?

それは、タスクの明確さ、モデルの設定、リポジトリの指示、および望ましい対話スタイルによって異なります。あるRedditユーザーがさまざまな監督パターンを報告していましたが、その個人の体験は製品全体に当てはまるルールというわけではありません。.

どちらが安いですか?

主な消費者向け料金プランは、月額$20、$100、$200で統一されていますが、含まれる容量や利用制限の仕組みは異なります。オプションのクレジットおよびAPI課金は別途となります。.

ClaudeとClaudeのコードシェアには利用制限がありますか?

はい。ClaudeおよびClaude Codeでは、接続されているProまたはMaxプランにおいて、共有セッションおよび週単位の利用制限が適用されます。.

Codexのローカルタスクとクラウドタスクは、制限を共有していますか?

ローカルメッセージとクラウドチャットには5時間の利用枠が共通で設定されており、週ごとの制限が適用される場合もあります。.

GlobalGPTは、CodexやClaude Codeの代わりになりますか?

いいえ。追加のモデル、CLI、MCP、スキル、マルチモーダルツールなどを活用して、どちらのワークフローも拡張することは可能ですが、リポジトリへのアクセスやコーディングエージェントの動作はホスト側で処理されます。.

両方の製品からGlobalGPTを使用することはできますか?

GlobalGPTでは、両環境向けの公式CLIチュートリアルを提供しています。両環境でのCLIの使用、およびCodexでのMCPとSkillの併用について検証済みですが、無人MCPについては承認に関する制限があります。.

価格、プランの規定、連携機能、および出典情報は2026年7月に確認されました。製品の詳細は変更される場合があります。.

GlobalGPTを開く 既存のコーディングワークフローに、マルチモデルおよびマルチモーダルな要素を取り入れたい場合。.

記事を共有する

関連記事