diff --git a/.agent/PLANS.md b/.agent/PLANS.md index 4f7d633e3..24ad090cf 100644 --- a/.agent/PLANS.md +++ b/.agent/PLANS.md @@ -40,8 +40,8 @@ ExecPlan の仕様書。複雑なタスクはこの仕様に従い `.agent/plans - **Outcomes & Retrospective**: 達成内容と教訓 - **Context and Orientation**: 対象コードの場所・前提条件(パスはリポジトリルート相対) - **Plan of Work**: 実装方針とその選定理由 -- **Concrete Steps**: 具体的な手順(コード例・コマンド含む) -- **Validation and Acceptance**: 観察可能な動作で定義した完了条件 +- **Concrete Steps**: 手順ごとに「編集対象ファイル」「実行コマンド」「期待される観測結果」を含む具体手順 +- **Validation and Acceptance**: 内部実装の説明ではなく、ユーザーが観察可能な動作で定義した完了条件 - **Idempotence and Recovery**: 中断時の復帰手順 - **Artifacts and Notes**: 関連ファイル・URL - **Interfaces and Dependencies**: 外部依存・他モジュールとのインターフェース @@ -53,12 +53,15 @@ ExecPlan の仕様書。複雑なタスクはこの仕様に従い `.agent/plans - Progress 以外ではチェックボックスを多用せず散文で記述 - 検証手順には具体的なコマンドと期待出力を含める - ネストしたコードブロックは使わずインデントで表現 +- 実装精度と再現性を維持したまま簡潔に書き、同一趣旨の重複記述を避ける +- 長大なコード全文の貼り付けは原則避け、対象箇所・変更意図・確認コマンドを優先する - 次のマイルストーンへ自律的に進む(「次は?」と確認しない) - 完了した ExecPlan は削除せずナレッジとして残す ## 成功基準 ステートレスなエージェントまたは初心者が、ExecPlan を通読して動作する成果物を生み出せること。 +過去チャットの文脈を知らない実装者でも、同じ結果に再現できること。 ## 関連 diff --git a/.agent/plans/2026-02-04-outputfilter-undefined-array-key.md b/.agent/plans/2026-02-04-outputfilter-undefined-array-key.md index f7545ff5a..e8ff1f8a9 100644 --- a/.agent/plans/2026-02-04-outputfilter-undefined-array-key.md +++ b/.agent/plans/2026-02-04-outputfilter-undefined-array-key.md @@ -1,81 +1,84 @@ -# ExecPlan: outputfilter の未定義配列キー警告修正 - -## 1. 概要 (Overview) - -- **Goal**: PHP 8.0+ で outputfilter 使用時に発生する `Undefined array key` 警告を解消する -- **Target Version**: v1.2.1J (バグ修正) -- **Reference**: https://forum.modx.jp/viewtopic.php?p=10705#p10705 -- **Context**: - - 関連: `AGENTS.md`, `.agent/PLANS.md` - - 対象: `manager/includes/docvars/outputfilter/*.inc.php` - -## 2. 原因 (Cause) - -outputfilter ファイル内で `$params` 配列のキーに直接アクセスしている箇所があり、キーが存在しない場合に PHP 8.0+ で Warning が発生する。 - -```php -// 問題のあるコード例 (image.inc.php:14) -'class' => $params['imgclass'], // キーが未定義だと Warning -``` - -PHP 7.x では未定義キーへのアクセスは Notice だったが、PHP 8.0 から Warning に昇格した。 - -## 3. 設計方針 (Design Strategy) - -- **既存への影響**: なし(動作は変わらず、警告のみ解消) -- **後方互換性**: 完全維持 -- **技術選定**: - - null 合体演算子 (`??`) を使用してデフォルト値を設定 - - 既存の配列構造・ロジックは変更しない - -## 4. 修正対象ファイル (Files to Fix) - -| ファイル | 修正が必要なキー | -|----------|------------------| -| `image.inc.php` | `imgclass`, `imgstyle`, `alttext`, `id`, `imgattrib`, `imgoutput` | -| `hyperlink.inc.php` | `title`, `linkclass`, `linkstyle`, `target`, `linkattrib`, `text` + `$o` 初期化 | -| `htmltag.inc.php` | `tagid`, `tagname`, `tagclass`, `tagstyle`, `tagattrib`, `tagoutput` + `$o` 初期化 | -| `datagrid.inc.php` | 全28プロパティ (`egmsg`, `chdrc`, `tblc`, etc.) | -| `date.inc.php` | `default`, `dateformat` | -| `delim.inc.php` | `delim` | -| `string.inc.php` | `stringformat` | -| `richtext.inc.php` | `w`, `h`, `edt` | - -## 5. 実装ステップ (Implementation Steps) - -- [x] **Step 1: image.inc.php の修正** - - [x] 全ての `$params['key']` アクセスに `?? ''` を追加 - - [x] `$params['align']` は `isset()` チェック済みなので変更不要 - -- [x] **Step 2: hyperlink.inc.php の修正** - - [x] 全ての `$params['key']` アクセスに `?? ''` を追加 - - [x] `$o` 変数の初期化漏れを修正 - -- [x] **Step 3: htmltag.inc.php の修正** - - [x] 全ての `$params['key']` アクセスに `?? ''` を追加 - - [x] `$o` 変数の初期化漏れを修正 - -- [x] **Step 4: 他の outputfilter ファイルの確認と修正** - - [x] `datagrid.inc.php` - 全28プロパティを修正 - - [x] `date.inc.php` - `default`, `dateformat` を修正 - - [x] `delim.inc.php` - `delim` を修正 - - [x] `string.inc.php` - `stringformat` を修正 - - [x] `richtext.inc.php` - `w`, `h`, `edt` を修正 - - [x] 修正不要: `dateonly.inc.php` (date.inc.php をinclude), `unixtime.inc.php`, `htmlentities.inc.php`, `custom_widget.inc.php` - -## 6. 検証方法 (Validation) - -1. PHP 8.0+ 環境で Image プロセッサーを持つ TV を作成 -2. TV をフロントエンドで表示し、Warning が発生しないことを確認 -3. 画像が正常に表示されることを確認 - -## 7. 副作用の可能性 (Impact) - -- **リスク**: 低 -- 動作ロジックの変更なし -- デフォルト値として空文字列を設定するため、従来の挙動と同一 - -## 8. 進捗ログ (Progress Log) - -- [2026-02-04]: 計画作成。フォーラム報告 #10705 に基づく。 -- [2026-02-04]: 実装完了。8ファイルを修正。 +# ExecPlan: outputfilter の未定義配列キー警告修正(発生源対処版) + +## Purpose / Big Picture +PHP 8.0+ で TV の outputfilter 実行時に発生する `Undefined array key` 警告を解消する。警告を局所的に握り潰すのではなく、`$params` の生成元を正規化して全 outputfilter の入力契約を安定化させる。 + +## Progress +- [x] (2026-02-04) 初版計画を作成し、影響ファイルを棚卸し +- [x] (2026-02-04) 対症療法(各 filter 内の `?? ''`)で一時的に警告を回避 +- [x] (2026-02-14) ExecPlan をテンプレート準拠に再構成 +- [x] (2026-02-14) 「発生源修正」方針に基づく改修案へ更新 +- [ ] (2026-02-14) 実装・検証結果を本 Plan に追記 + +## Surprises & Discoveries +`manager/includes/document.parser.class.inc.php` の `tvProcessor()` 内で、`$value` が空の場合に `datagrid` 分岐だけ `if ($params['egmsg'] === '')` を直接参照していた。ここが warning の発火点になり得る。また outputfilter 側が未定義キーを前提にしており、呼び出し契約が曖昧だった。 + +## Decision Log +2026-02-14 / AI / 対症療法(各 filter で未定義キーを空文字へ変換)を最終解としない。理由: エラー隠蔽になり、入力契約の不整合が残るため。代替案は「`tvProcessor()` で format ごとの既定値を明示し、`$params` を正規化してから filter を呼び出す」。 +2026-02-14 / AI / 既存の outputfilter インターフェース(`$value`, `$params`)は維持し、互換性を優先する。理由: 呼び出し側の一元修正で影響範囲を閉じられるため。 + +## Outcomes & Retrospective +実装完了後に記載する。 + +## Context and Orientation +対象は TV 表示処理の中心である `manager/includes/document.parser.class.inc.php` の `tvProcessor()`。ここで `display_params` をパースして `$params` を生成し、`manager/includes/docvars/outputfilter/*.inc.php` に引き渡している。 +warning は「filter 側でキー未定義」だけでなく「生成元が filter ごとの必須キーを保証していない」ことが本質的な原因。 + +用語: +outputfilter は TV 値を表示向けに整形する小さな変換モジュール。 +入力契約は「どのキーが常に存在し、どの型で渡るか」の取り決め。 +発生源修正は warning 発生箇所ではなく、異常データを生む上流を直すこと。 + +## Plan of Work +`tvProcessor()` に format ごとのパラメータスキーマ(既定値マップ)を追加し、`display_params` のパース結果をそのスキーマで正規化してから outputfilter を呼ぶ。これにより filter 側は「定義済みキーが渡る」契約に依存できる。 +同時に、`$value` 空判定の `datagrid` 早期 return 条件を未定義キー参照しない実装に変更し、warning 発火点を除去する。 + +## Concrete Steps +1. format ごとの既定値マップを `tvProcessor()` に追加する。 + 編集対象ファイル: `manager/includes/document.parser.class.inc.php` + 実行コマンド: `rg -n "function tvProcessor|datagrid|display_params" manager/includes/document.parser.class.inc.php` + 期待される観測結果: 既定値マップの配置場所と `tvProcessor()` の入力処理位置が特定できる。 +2. `$params` 生成直後に正規化処理(`array_replace($defaults, $params)` 相当)を挿入する。 + 編集対象ファイル: `manager/includes/document.parser.class.inc.php` + 実行コマンド: `php -l manager/includes/document.parser.class.inc.php` + 期待される観測結果: 構文エラーがなく、`$params` 参照前に必ず既定キーが存在する状態になる。 +3. `datagrid` の早期 return 判定で未定義キー参照を発生させない。 + 編集対象ファイル: `manager/includes/document.parser.class.inc.php` + 実行コマンド: `rg -n "egmsg|datagrid" manager/includes/document.parser.class.inc.php` + 期待される観測結果: `egmsg` 参照が正規化後の `$params` に対してのみ行われ、未定義キー warning の経路が消える。 +4. 主要 outputfilter の呼び出し契約が維持されることを点検する。 + 編集対象ファイル: `manager/includes/docvars/outputfilter/image.inc.php`, `manager/includes/docvars/outputfilter/hyperlink.inc.php`, `manager/includes/docvars/outputfilter/htmltag.inc.php`, `manager/includes/docvars/outputfilter/datagrid.inc.php`, `manager/includes/docvars/outputfilter/date.inc.php`, `manager/includes/docvars/outputfilter/delim.inc.php`, `manager/includes/docvars/outputfilter/string.inc.php`, `manager/includes/docvars/outputfilter/richtext.inc.php` + 実行コマンド: `php -l manager/includes/docvars/outputfilter/{image,hyperlink,htmltag,datagrid,date,delim,string,richtext}.inc.php` + 期待される観測結果: 対象 filter で構文エラーがなく、互換インターフェース(`$value`, `$params`)を維持している。 +5. 実測結果を Plan に反映する。 + 編集対象ファイル: `.agent/plans/2026-02-04-outputfilter-undefined-array-key.md` + 実行コマンド: `git diff -- .agent/plans/2026-02-04-outputfilter-undefined-array-key.md` + 期待される観測結果: Progress / Surprises / Decision Log / Outcomes が実装結果に追従して更新される。 + +## Validation and Acceptance +1. `php -l manager/includes/document.parser.class.inc.php` を実行し、`No syntax errors detected` が出ること。 +2. 主要 outputfilter 8ファイルに対する `php -l` で `No syntax errors detected` が出ること。 +3. 管理画面で `display_params` を省略した TV を各 outputfilter 形式で表示し、PHP warning(`Undefined array key`)が出ないこと。 +4. `datagrid` で `egmsg` 未指定の TV を表示し、warning なしで従来どおりレンダリングされること。 +5. `display_params` 指定あり TV でも表示 HTML が改修前と同等であること(回帰なし)。 +6. 上記検証結果(実行コマンドと観測結果)を本 Plan に追記し、過去チャットを見ずに再現できる状態にすること。 + +## Idempotence and Recovery +変更は `document.parser.class.inc.php` と必要最小限の outputfilter のみ。差分は `git diff` で確認し、想定外があれば対象コミットを revert して復旧できる。 +中断時は `Progress` の未完了項目を次回の再開点として扱う。 + +## Artifacts and Notes +関連ファイル: +`manager/includes/document.parser.class.inc.php` +`manager/includes/docvars/outputfilter/image.inc.php` +`manager/includes/docvars/outputfilter/hyperlink.inc.php` +`manager/includes/docvars/outputfilter/htmltag.inc.php` +`manager/includes/docvars/outputfilter/datagrid.inc.php` +`manager/includes/docvars/outputfilter/date.inc.php` +`manager/includes/docvars/outputfilter/delim.inc.php` +`manager/includes/docvars/outputfilter/string.inc.php` +`manager/includes/docvars/outputfilter/richtext.inc.php` + +## Interfaces and Dependencies +外部依存は追加しない。`tvProcessor()` と outputfilter の既存インターフェースを維持するため、管理画面・フロント双方への影響を最小化できる。 +関連ドキュメントは `AGENTS.md`, `.agent/PLANS.md`, `assets/docs/architecture.md`, `assets/docs/template-system.md`。 diff --git a/.agent/plans/2026-02-13-logging-paging-undefined-key.md b/.agent/plans/2026-02-13-logging-paging-undefined-key.md new file mode 100644 index 000000000..87f729b8e --- /dev/null +++ b/.agent/plans/2026-02-13-logging-paging-undefined-key.md @@ -0,0 +1,90 @@ +# ExecPlan: ログ閲覧画面のページング配列キー未定義エラー修正 + +## Purpose / Big Picture + +管理画面「ツール→イベントログ」でログが7ページ以上ある場合、1ページ目や最終ページ付近で `Undefined array key` 警告が発生する。この警告を解消し、全ページで正常にページネーションが表示されるようにする。 + +## Progress + +- [x] (2026-02-13) logging.static.php のページングウィンドウに境界チェックを追加 +- [x] (2026-02-13) paginate.inc.php の getNumberOfPage() に ceil() を適用 +- [x] (2026-02-13) 動作検証(対象2ファイルの `php -l` で構文エラーなし) + +## Surprises & Discoveries +- `Paging::getNumberOfPage()` が小数を返す設計のため、`getCurrentPage()` の計算が間接的に小数依存になっていた。`ceil()` + `int` 化で `getPagingRowArray()` のループ境界が明確化された。 +## Decision Log + +- 2026-02-13 / AI / `messages.static.php` も同じ `Paging` クラスを使用しているが、こちらは `foreach` でループしているため境界チェック不要。影響は `logging.static.php` のみ。 +- 2026-02-13 / AI / `logging.static.php` のページ番号表示は「常に5件表示」の既存UIを維持し、先頭・末尾でウィンドウをスライドさせる方式を採用した。 + +## Outcomes & Retrospective +- `manager/actions/report/logging.static.php` で配列アクセスを固定オフセットから境界付きループへ変更し、`Undefined array key` の発生条件を除去した。 +- `manager/includes/paginate.inc.php` で総ページ数を切り上げ整数化し、ページ配列生成の境界を安定化した。 +- 画面手動確認(イベントログ7ページ以上の実ブラウザ確認)は未実施。コード上の再発要因は解消済み。 +## Context and Orientation + +**エラー報告**: + +``` +PHP Warning: Undefined array key -2 +File: manager/actions/report/logging.static.php +Line: 306 +Source: $paging .= $array_row_paging[$current_row - 2]; +``` + +**関連ファイル**: + +- `manager/actions/report/logging.static.php` — ログ閲覧画面(修正対象) +- `manager/includes/paginate.inc.php` — `Paging` クラス(修正対象) +- `manager/actions/permission/messages.static.php` — 同じ `Paging` クラスを使用(修正不要) + +**再現条件**: ログが700件超(デフォルト100件/ページ×7ページ以上)で、1〜2ページ目または末尾1〜2ページ目を表示した場合に発生。 + +## Plan of Work + +2箇所を修正する。 + +**修正1: logging.static.php(主原因)** — 固定インデックス `$current_row - 2` 〜 `$current_row + 2` でページ番号配列にアクセスしている箇所を、境界クランプ付きのループに置き換える。表示するページ数(5ページ)は変わらず、端のページでもウィンドウがスライドして範囲外アクセスを防ぐ。 + +**修正2: paginate.inc.php(副次的)** — `getNumberOfPage()` が `$nbr_row / $num_result` を返しているが、`ceil()` を使っていないため端数がある場合にページ数が浮動小数点になる。`ceil()` を適用して正確な整数ページ数を返すようにする。また `$current_row` も `(int)` でキャストして型安全を確保する。 +この Plan は実装者が過去チャットを参照しなくても実施できるよう、対象ファイル・コマンド・期待観測結果を各手順に明記する。 + +## Concrete Steps + +1. ページング配列アクセスを境界クランプ付きループへ置換する。 + 編集対象ファイル: `manager/actions/report/logging.static.php`(305〜315行付近) + 実行コマンド: `php -l manager/actions/report/logging.static.php` + 期待される観測結果: 構文エラーなし。先頭/末尾ページで範囲外アクセス由来の warning が出ない。 +2. `$current_row` を整数で扱うよう型安全化する。 + 編集対象ファイル: `manager/actions/report/logging.static.php`(291行付近) + 実行コマンド: `rg -n "int_cur_position|current_row" manager/actions/report/logging.static.php` + 期待される観測結果: `$current_row` が整数化され、インデックス計算が小数依存しない。 +3. `getNumberOfPage()` を切り上げ整数返却へ修正する。 + 編集対象ファイル: `manager/includes/paginate.inc.php` + 実行コマンド: `php -l manager/includes/paginate.inc.php` + 期待される観測結果: 構文エラーなし。総ページ数が整数化され、ページ配列生成のループ境界が安定する。 + +## Validation and Acceptance + +管理画面「ツール→イベントログ」で以下を確認する: + +1. `php -l manager/actions/report/logging.static.php manager/includes/paginate.inc.php` を実行し、両ファイルで `No syntax errors detected` が出ること。 +2. ログが7ページ以上(700件超)ある状態で検索を実行し、1ページ目で `Undefined array key` 警告が出ないこと。 +3. 同条件で2ページ目を表示し、警告が出ないこと。 +4. 中間ページを表示し、現在ページ中心の5件ウィンドウでページ番号が表示されること。 +5. 最終ページを表示し、範囲外アクセス由来の警告が出ないこと。 +6. ログが6ページ以下の条件では、従来どおり全ページ番号が表示されること。 +7. 実行したコマンドと観測結果を本 Plan に追記し、過去チャットを見ずに検証を再現できること。 + +## Idempotence and Recovery + +変更は2ファイル・3箇所のみ。`git diff` で差分確認し、問題があれば `git checkout` で復元可能。 + +## Artifacts and Notes + +- `manager/actions/report/logging.static.php` — 管理画面アクション13(Viewing logging) +- `manager/includes/paginate.inc.php` — 汎用ページングクラス(2001年製、外部ライブラリ由来) + +## Interfaces and Dependencies + +`Paging` クラスの `getNumberOfPage()` は `private` メソッドのため、外部への影響なし。`messages.static.php` は `getPagingRowArray()` の戻り値を `foreach` で使用しているため、配列要素数が変わっても影響なし。 diff --git a/.claude/skills/issue-resolver/SKILL.md b/.claude/skills/issue-resolver/SKILL.md index f07da87ae..3be905928 100644 --- a/.claude/skills/issue-resolver/SKILL.md +++ b/.claude/skills/issue-resolver/SKILL.md @@ -8,33 +8,55 @@ description: 不具合報告(フォーラム/Issue)に基づく調査・再 不具合報告を起点に、調査から修正・記録までを行うワークフロー。 実装時のコーディング規約は `project-worker` スキルに従う。 +## 実行ルール + +1. このスキルはローカル開発環境専用として扱う。 +2. 調査と修正は効率優先・トークン節約優先で進める。 +3. 修正方針を先に判定し、軽微な修正は ExecPlan 作成を省略して実装へ進んでよい(ただし調査報告への承認後に限る)。 +4. 問題が分かりにくい場合や修正が複雑な場合は `exec-plan` を作成してから進める。 +5. 検証に必要な範囲でローカルDBの更新・削除・初期化を許容する。 +6. 本番接続情報や本番データを扱う前提は置かない。 +7. フォーラムURLの本文取得は最初から制限外実行で行い、`curl` / `wget` を順に試す。 +8. URL取得コマンド実行時は都度 `require_escalated` を使い、承認付きで実行する。 +9. `Could not resolve host` などDNS解決失敗時は、サンドボックス内制限として扱い、制限外実行へ切り替える。 +10. URL取得に失敗した状態でローカルコードだけから原因を推測しない。取得不能時は必ずエンジニアへ対応(本文提供・制限外実行)を依頼する。 +11. 原因が判明した時点で必ず先に調査報告を提出し、エンジニア承認前に修正へ進まない。 +12. `evo` コマンドとDB参照はホスト側で直接実行しない。必ず Docker コンテナ内で実行する。 +13. エラー隠蔽を目的とした修正を禁止する。警告/例外を消すための握りつぶしや無条件の値変換を行わず、原因となる不正データの発生源を修正する。 +14. 例: `strpos()` に `null` が渡って落ちる場合、`null` を空文字へ変換して通すのではなく、`null` が渡る経路を特定して上流で是正する。 + ## コマンド ### analyze-issue -1. URLならfetchで内容取得 +1. URLなら最初から制限外実行で本文取得し、HTMLタグを除去したテキストのみを扱う: `curl -fsSL -A "Mozilla/5.0" "" | php -r '$h=stream_get_contents(STDIN); $t=strip_tags($h); $t=preg_replace("/\s+/u"," ",$t); echo trim($t), PHP_EOL;'` を承認付きで実行 → 失敗時 `wget -qO- "" | php -r '$h=stream_get_contents(STDIN); $t=strip_tags($h); $t=preg_replace("/\s+/u"," ",$t); echo trim($t), PHP_EOL;'` を同様に承認付きで実行 2. `AGENTS.md` のドキュメントマップから関連ファイルを特定 -3. `evo config:show` で関連設定値、`evo db:describe` で関連テーブル構造を確認 +3. `docker compose exec php evo config:show` で関連設定値、`docker compose exec php evo db:describe` で関連テーブル構造を確認 4. 現象の要約と原因仮説を3つ提示 -5. 情報不足時はユーザーへの質問リストを作成 +5. 原因が判明した場合は、修正前に「原因・影響範囲・修正方針案」を短く報告 +6. URL本文を取得できない場合は、失敗理由を1行で記録し、環境制限またはアクセス制限の種別を明記する +7. 制限外実行でも取得できない場合は、本文貼り付けを依頼 +8. URL本文が得られるまでは原因推測や修正方針の断定を行わず、エンジニアの対応を待つ +9. 情報不足時はユーザーへの質問リストを作成 ### reproduce - 現象を再現する最小限のPHPコードを作成 -- `evo db:query` でデータ状態を確認し再現条件を特定 +- `docker compose exec php evo db:query` でデータ状態を確認し再現条件を特定 - デバッグ用ログ (`evo()->logEvent(...)`) の挿入箇所を提案 -- `evo cache:clear` でキャッシュクリアしてから再現確認 +- `docker compose exec php evo cache:clear` でキャッシュクリアしてから再現確認 ### create-branch - Issue番号・内容からブランチ名を提案(例: `fix/10705-tv-saving-error`) - mainから分岐して作成 -### draft-plan -- `exec-plan` スキルの `/create-plan` に委譲する +### draft-plan (必要時) +- 問題が分かりにくい場合や修正が複雑な場合のみ `exec-plan` スキルの `/create-plan` に委譲する - analyze-issue の調査結果をタスク概要として渡す ### implement-fix +- 調査報告に対するエンジニア承認を確認してから修正を開始 - draft-planに基づきコードを修正 - `project-worker` スキルの規約を厳守 -- 修正後 `evo cache:clear` でキャッシュクリア +- 修正後 `docker compose exec php evo cache:clear` でキャッシュクリア ### archive - Conventional Commits形式のコミットメッセージ生成(例: `fix(manager): resolve tv saving error on php8.2 (Ref forum#10705)`) diff --git a/.codex/skills/exec-plan/SKILL.md b/.codex/skills/exec-plan/SKILL.md new file mode 100644 index 000000000..86d4cacd6 --- /dev/null +++ b/.codex/skills/exec-plan/SKILL.md @@ -0,0 +1,51 @@ +--- +name: exec-plan +description: ExecPlan(実行計画)の作成・検証・更新を支援するスキル。複雑なタスク(新機能開発、リファクタリング、バグ修正)の設計フェーズで使用します。`/create-plan`でプラン作成を開始。 +--- + +# Exec Plan + +`.agent/PLANS.md` の仕様に準拠した ExecPlan を作成・管理するワークフロー。 +コーディング規約・ドキュメントマップは `AGENTS.md` を参照。 + +## コマンド + +### /create-plan <タスク概要> +1. `AGENTS.md` のドキュメントマップから関連ドキュメント・コードを探索 +2. プラン案の骨子を提示(重点: Purpose / Context / Plan of Work / Concrete Steps / Validation) + 複雑タスクはマイルストーン分割(目標→作業→成果→検証の物語構造、PoCを先行) +3. エンジニアと設計方針を確認し、非交渉要件(自己完結・初心者実行可能・動作する成果物・用語定義)を検討 +4. `.agent/PLANS.md` テンプレートに従い `.agent/plans/YYYY-MM-DD-task-name.md` を作成 + 全12セクション記載、Progress以外は散文、CMS用語を定義、Validationは観察可能な動作で定義 + 空セクションは見出しのみ残す(プレースホルダ説明は書かない) +5. `/validate-plan` を自動実行 + +トークン効率の原則(精度優先): +- 実装精度・再現性を落とさない範囲で簡潔に書く(必要十分な情報量を維持) +- 同一趣旨の説明を複数セクションに重複記載しない +- 長大なコード全文は原則避け、変更意図・対象箇所・確認コマンドに集約する +- `Concrete Steps` は「編集対象ファイル / 実行コマンド / 期待観測結果」を基本フォーマットにする + +探索の重点: `assets/docs/architecture.md`(処理フロー)、`assets/docs/events-and-plugins.md`(フック)、`assets/docs/core-issues.md`(既知の課題)、対象ファイルの既存パターン + +移行タスクでは追加で: 旧API使用箇所のGrep棚卸し、旧→新の置換パターン表、モジュール単位の分割 + +### 補助ツール(CLI導入済みの場合) +`php evo config:show [key]` / `db:tables [--pattern]` / `db:describe ` / `db:count
[--where]` + +### /validate-plan [path] +`references/quality-checklist.md` に基づき品質チェック: 必須12セクション、非交渉要件・アンチパターンを検出し改善提案 + +### /update-plan [path] +各マイルストーン完了時・中断時にこまめに呼び出す: +1. Progress をタイムスタンプ付きで更新(完了チェック、新規項目追加) +2. Surprises & Discoveries に追記(観察+根拠) +3. Decision Log に日付・著者・根拠・代替案を記録 +4. 完了マイルストーンの Progress 詳細を1行の要約に圧縮(トークン節約) +5. コア側の課題(UI結合・設計上の制約・技術的負債等)を発見した場合は `assets/docs/core-issues.md` に追記(発見日・発見元・ファイル・課題・改善案・関連ロードマップ) + +## 意思決定の閾値 + +**自律判断可能**: コードベース探索、関連ドキュメント読み込み、プランのフォーマット整形 + +**要相談**: 設計方針の選定、影響範囲の判断、実装の優先順位、代替案のトレードオフ diff --git a/.codex/skills/exec-plan/agents/openai.yaml b/.codex/skills/exec-plan/agents/openai.yaml new file mode 100644 index 000000000..5efe67162 --- /dev/null +++ b/.codex/skills/exec-plan/agents/openai.yaml @@ -0,0 +1,29 @@ +interface: + display_name: "ExecPlan" + short_description: "複雑な作業向けのExecPlanを設計・検証・更新する" + default_prompt: | + 入力コマンドに応じて以下を実行してください。 + + `/create-plan <タスク概要>`: + 1) `AGENTS.md` と `.agent/PLANS.md` を読み、`assets/docs/` と対象コードの既存パターンを確認する。 + 2) プラン骨子(Purpose / Context / Plan of Work / Concrete Steps / Validation)を整理し、必要用語を平易に定義する。 + 3) `.agent/plans/YYYY-MM-DD-task-name.md` を新規作成し、12セクションを記載する。`Progress` 以外は散文、空セクションは見出しのみ。 + 4) `Plan of Work` と `Concrete Steps` に対象ファイル・コマンド・変更方針を具体記述し、各手順に期待される観測結果を添える。 + 5) `Validation and Acceptance` は内部実装の説明ではなく、観察可能な検証手順(実行コマンドと期待結果)で定義する。 + 6) 不具合対応ではエラー隠蔽を避け、原因データの発生源を修正する方針を明記する。 + 7) 実装者が過去チャットを参照しなくても実行できる内容にする(hidden context を持ち込まない)。 + 8) 実装精度を落とさない範囲でトークンを節約する。重複説明を避け、長大なコード全文は原則書かず、必要箇所と参照先パスで表現する。 + 9) 作成後に `/validate-plan` 相当の自己検証を実施し、不足があれば同一ファイルを修正する。 + + `/validate-plan [path]`: + 1) 対象 ExecPlan を `references/quality-checklist.md` で検証する。 + 2) 必須12セクション、非交渉要件、アンチパターンを確認する。 + 3) トークン効率(重複説明、冗長なコード全文、過剰な長文)を確認し、精度を落とさず短縮できる箇所を特定する。 + 4) 指摘は「不足内容」「修正案」「修正後に確認すべき観点」の順で提示する。 + + `/update-plan [path]`: + 1) `Progress` をタイムスタンプ付きで更新し、完了項目は1行要約に圧縮する。 + 2) `Surprises & Discoveries` に観察事実と根拠を追記する。 + 3) `Decision Log` に日付・根拠・代替案を追記する。 + 4) 進捗反映時に重複説明を削除し、不要に長い記述を簡潔化する(根拠・再現性は維持)。 + 5) 必要に応じて `Validation and Acceptance` / `Idempotence and Recovery` を現状に合わせて更新する。 diff --git a/.codex/skills/exec-plan/references/quality-checklist.md b/.codex/skills/exec-plan/references/quality-checklist.md new file mode 100644 index 000000000..a68aeb6c6 --- /dev/null +++ b/.codex/skills/exec-plan/references/quality-checklist.md @@ -0,0 +1,39 @@ +# ExecPlan 品質チェックリスト + +`.agent/PLANS.md` の非交渉要件に基づく検証項目。 + +## 必須セクション + +- [ ] Purpose / Big Picture: ユーザーにとっての価値が1-2文で明記されている +- [ ] Progress: タイムスタンプ付きチェックリストがある +- [ ] Surprises & Discoveries: セクションが存在する(実装前は「なし」と記載) +- [ ] Decision Log: 設計判断が日付付きで記録されている +- [ ] Outcomes & Retrospective: セクションが存在する(実装前は「実装後に記載」と記載) +- [ ] Context and Orientation: 対象コードの場所がリポジトリルート相対パスで記載されている +- [ ] Plan of Work: 実装方針と選定理由が散文で記述されている +- [ ] Concrete Steps: 手順ごとに編集対象ファイル・実行コマンド・期待される観測結果が含まれている +- [ ] Validation and Acceptance: 内部実装の説明ではなく、観察可能な動作(ブラウザ確認、コマンド実行等)で定義されている +- [ ] Idempotence and Recovery: 中断時の復帰手順が記載されている +- [ ] Artifacts and Notes: 関連ファイル・URLが記載されている +- [ ] Interfaces and Dependencies: 外部依存・他モジュールとのインターフェースが明記されている + +## 非交渉要件・アンチパターン + +- [ ] **自己完結**: 必要な情報がすべてプラン内にあり、外部ブログ・ドキュメントに依存していない +- [ ] **hidden context 排除**: 過去チャット参照がなくても実装可能な情報量になっている +- [ ] **初心者実行可能**: CMS固有用語や技術用語が初出箇所で平易に定義されている +- [ ] **動作する成果物**: 検証手順に具体的なコマンドと期待出力があり、形式的な成果物を排除 +- [ ] **冪等性**: Concrete Steps を再実行しても問題が生じない設計になっている +- [ ] **判断の完結**: 重要な設計決定がプラン内で解決済みであり、実装者に委ねていない + +## フォーマット・簡潔性 + +- [ ] ファイル名が `YYYY-MM-DD-task-name.md` 形式 +- [ ] 保存先が `.agent/plans/` +- [ ] Progress 以外ではチェックボックスを多用せず散文で記述 +- [ ] ネストしたコードブロックはインデントで表現 +- [ ] 空セクションは見出しのみ(プレースホルダ説明なし) +- [ ] 完了マイルストーンの Progress が1行要約に圧縮されている +- [ ] 同一趣旨の説明が複数セクションに重複していない +- [ ] 長大なコード全文を不要に貼り付けていない(必要箇所の要点と参照先で表現) +- [ ] トークン節約が実装精度・再現性を損なっていない diff --git a/.codex/skills/issue-resolver/SKILL.md b/.codex/skills/issue-resolver/SKILL.md new file mode 100644 index 000000000..8fb3f0fef --- /dev/null +++ b/.codex/skills/issue-resolver/SKILL.md @@ -0,0 +1,90 @@ +--- +name: issue-resolver +description: 不具合報告(GitHub Issue、フォーラム投稿、社内報告)を起点に、調査・再現・修正・検証・記録までを一貫実行するスキル。症状の切り分け、原因仮説の整理、最小再現、修正実装、ExecPlan作成、PR下書き、ナレッジ追記が必要なときに使う。 +--- + +# Issue Resolver + +不具合対応を「再現可能な事実」ベースで前進させる。 +実装規約はプロジェクトの `AGENTS.md` を最優先とし、必要に応じて `project-worker` の規約へ委譲する。 + +## 実行ルール + +1. 先に現象と期待値を定義してから実装する。 +2. 推測で修正せず、再現手順か観測ログを必ず作る。 +3. 変更は最小単位に分割し、影響範囲を明示する。 +4. 修正方針を先に判定し、軽微な修正は ExecPlan 作成を省略して `implement-fix` へ進んでよい(ただし調査報告への承認後に限る)。 +5. 問題が分かりにくい場合、影響範囲が読みにくい場合、または実装が複雑な場合は `.agent/PLANS.md` に従って ExecPlan を作成する。 +6. 不具合調査では手動確認より先に `docker compose exec php evo` で設定・DB状態・キャッシュ状態を確認する。 +7. このスキルはローカル開発環境専用とし、本番環境を前提にした慎重運用は行わない。 +8. 調査と修正は効率優先・トークン節約優先で進め、過剰な説明や確認を省く。 +9. 検証に必要な範囲でローカルDBの更新・削除・初期化を許容し、必要なら即時にリセットする。 +10. フォーラムURLの本文取得は最初から制限外実行で行い、`curl` / `wget` を順に試す。 +11. URL取得コマンド実行時は都度 `require_escalated` を使い、承認付きで実行する。 +12. `Could not resolve host` や `Temporary failure in name resolution` はサンドボックス内制限として扱い、制限外実行へ切り替える。 +13. URL取得に失敗した状態でローカルコードだけから原因を推測しない。取得不能時は必ずエンジニアへ対応(本文提供・制限外実行)を依頼する。 +14. 原因が判明した時点で必ず先に調査報告を提出し、エンジニア承認前に修正へ進まない。 +15. `evo` コマンドとDB参照はホスト側で直接実行しない。必ず Docker コンテナ内で実行する。 +16. エラー隠蔽を目的とした修正を禁止する。警告/例外を消すための握りつぶしや無条件の値変換を行わず、原因となる不正データの発生源を修正する。 +17. 例: `strpos()` に `null` が渡って落ちる場合、`null` を空文字へ変換して通すのではなく、`null` が渡る経路を特定して上流で是正する。 + +## evo CLI(実用最小) + +- `docker compose exec php evo config:show ` +- `docker compose exec php evo db:describe
` +- `docker compose exec php evo db:count
--where=...` +- `docker compose exec php evo db:query "SELECT ..."` +- `docker compose exec php evo cache:clear` + +詳細リファレンスは `manager/includes/cli/README.md` を参照する。 +本番接続情報や本番データを扱う前提は置かない。 + +## Workflow + +### analyze-issue +1. 入力が URL の場合は、最初の取得を制限外実行(承認付き)で行う。 +2. 取得コマンドは `curl -fsSL -A "Mozilla/5.0" "" | php -r '$h=stream_get_contents(STDIN); $t=strip_tags($h); $t=preg_replace("/\s+/u"," ",$t); echo trim($t), PHP_EOL;'` を使う。 +3. `curl` が失敗した場合は、制限外実行(承認付き)で `wget -qO- "" | php -r '$h=stream_get_contents(STDIN); $t=strip_tags($h); $t=preg_replace("/\s+/u"," ",$t); echo trim($t), PHP_EOL;'` を実行する。 +4. 取得したテキストから事実情報(環境、手順、実際結果、期待結果)を抽出する。 +5. `AGENTS.md` のドキュメントマップを参照し、関連コンポーネントと確認ドキュメントを特定する。 +6. `docker compose exec php evo config:show ` で関連設定値を確認する。 +7. `docker compose exec php evo db:describe
` で対象テーブル構造を確認する。 +8. 必要時のみ `docker compose exec php evo db:count
--where=...` で件数を確認する。 +9. 現象の要約、再現条件、原因仮説(最大3件)を作る。 +10. 原因が判明した場合は、修正前に「原因・影響範囲・修正方針案」を短く報告する。 +11. URL本文を取得できない場合は、失敗理由を1行で記録し、環境制限またはアクセス制限の種別を明記する。 +12. 制限外実行でも取得できない場合は、投稿本文の貼り付けを依頼する。 +13. URL本文が得られるまでは原因推測や修正方針の断定を行わず、エンジニアの対応を待つ。 +14. 情報不足がある場合は、追加確認項目を短く列挙する。 + + +### reproduce +1. 失敗条件を固定し、最小再現コードまたは最小再現手順を作る。 +2. `docker compose exec php evo db:query "SELECT ..."` で再現に必要なレコード状態を確認する。 +3. 再現前後で `docker compose exec php evo cache:clear` を実行し、キャッシュ要因を切り分ける。 +4. 再現できない場合は「再現不能」のまま進めず、前提差分を明示する。 + +### create-branch +1. Issue 番号と症状からブランチ名を提案する(例: `fix/10705-tv-saving-error`)。 +2. ベースブランチを確認してから分岐する。 + +### draft-plan (必要時) +1. 問題が分かりにくい場合、影響範囲が読みにくい場合、または実装が複雑な場合にのみ ExecPlan を作成する。 +2. `analyze-issue` の結果を、目的・制約・検証方法つきで計画へ反映する。 + +### implement-fix +1. 調査報告に対するエンジニア承認を確認してから実装を開始する。 +2. `draft-plan` に沿って最小差分で実装する。 +3. 既存パターンを優先し、ヘルパー利用・DB安全性・イベント/キャッシュ影響を確認する。 +4. 必要なテストまたは手動確認を実施し、結果を記録する。 +5. 必要に応じて `docker compose exec php evo health:check` を実行し、基本健全性を確認する。 +6. CLI 実行結果は検証ログへ要約して残す。 + +### archive +1. 修正内容を再現条件とセットで要約する。 +2. Conventional Commits 形式のコミットメッセージ案を作る。 +3. 再発防止の観点で、必要なら `assets/docs/troubleshooting/solved-issues.md` を更新する。 + +### pull-request +1. PR タイトルと本文を `What / Why / How / Test` の順で下書きする。 +2. 破壊的変更、互換性影響、運用手順の有無を明記する。 diff --git a/.codex/skills/issue-resolver/agents/openai.yaml b/.codex/skills/issue-resolver/agents/openai.yaml new file mode 100644 index 000000000..22188ea67 --- /dev/null +++ b/.codex/skills/issue-resolver/agents/openai.yaml @@ -0,0 +1,14 @@ +interface: + display_name: "issue-resolver" + short_description: "不具合報告から修正完了までを一貫して進める" + default_prompt: | + 以下の順序で進めてください。 + 1) 不具合報告を分析し、再現手順と原因仮説(最大3件)を整理する。 + 2) URL調査が必要な場合は最初から制限外実行で取得する。 + 3) evo/DB確認は必ずDockerコンテナ内で実行する。 + 4) 原因判明後は、修正前に調査報告(原因・影響範囲・修正方針案)を提示する。 + 5) 修正着手は調査報告への承認後に限定する。勝手に修正を実施しないこと。 + 6) 軽微な修正はExecPlan作成を省略して進めてよい。 + 7) 問題が分かりにくい場合や修正が複雑な場合は先にExecPlanを作成する。 + 8) エラー隠蔽を目的とした修正は行わず、原因データの発生源を修正する。 + 例: `strpos()` へ渡る `null` を空文字へ変換して通すだけの対処は禁止。