audit-program について
audit-programは、既存のFoldkitプログラムを読み取り専用でレビューするスキルです。Foldkitのガイドやサンプルとの適合性を段階的に調べ、修正は承認後にのみ行います。
主な機能
- 01パスまたは観点で監査範囲を指定
- 02Foldkitのガイドやサンプルと比較
- 03lint設定と診断結果を確認
- 04機械的スキャンと構造レビュー
- 05修正前に明示的な同意を要求
活用シーン
- 01Foldkitの画面を対応する階層のサンプルと比較
- 02変更を承認する前に品質上の問題を発見
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ foldkit/ foldkit --skill audit-programインストール後、Claude Code で/audit-programを入力して読み込まれたか確認します。
同梱ファイルagents/openai.yaml
詳細
既存の Foldkit プログラムを、generate-program が目指すのと同じ基準で監査します。このコードは packages/typing-game/client/src/ または packages/website/src/ の手書きコードと見分けがつかない品質である必要があります。「動く」だけでは不十分です。「構造的に有効」なだけでも不十分です。タイピングゲーム品質が求められます。
推奨セットアップ: 監査対象プロジェクトに
repos/foldkit/を Git サブツリーとして取り込んでおくと、監査の忠実度が大幅に高まります。取り込まれていない場合は、generate-program/architecture.mdとconventions.mdのスナップショットを基準に評価します。取り込まれている場合は、ライブの模範例(examples/、packages/typing-game/、packages/website/)を基準に評価できます。これらは、そもそも各スナップショットが要約している内容です。サブツリーがない場合は、監査を始める前に追加することを推奨してください。インストール済みのfoldkitパッケージに一致するリリースの Git タグに固定すると、模範例とプロジェクトがコンパイル対象とする API が一致します:git subtree add --prefix=repos/foldkit https://github.com/foldkit/foldkit.git "foldkit@$(node -p "require('./node_modules/foldkit/package.json').version")" --squash。タグのないバージョン(x.y.z-canary.<commit>)を使ったカナリアインストールの場合は、代わりにそのバージョンが示すコミットの完全なハッシュに固定します。GitHub ではhttps://github.com/foldkit/foldkit/commit/<commit>でコミットが確認できます。
運用原則:まず報告し、同意なしに変更しない
監査は Phase 6 まで読み取り専用です。出力は構造化されたレポートです。指摘がどれほど明白に見えても、変更がどれほど些細でも、どれほど自信があっても、ユーザーがレポートを確認し、修正を明示的に承認する前に、ファイルを編集してはいけません。Phase 7(修正の提案)は任意で、項目ごとまたは一括でのユーザーの同意が前提です。
具体的には、次のとおりです。
- Phase 1 から 6 は、コードの読み取り、grep の実行、レビュー用サブエージェントの起動、指摘事項の統合のみを行う調査フェーズです。
Edit、Write、ファイルを変更するBashコマンドは使用しません。 - Phase 6 の最後にレポートを提出したら、そこで止まり、待ちます。修正を適用するかどうかを尋ねてください。レポートと同じ応答に修正を含めてはいけません。
- ユーザーが修正を依頼した後でも、構造的または意味的な変更には、項目ごとの確認が必要です。機械的な修正を一括で行えるのは、ユーザーがその一括実施を明示的に承認した場合に限ります。
- ユーザーが指摘事項を確認する前に「直して」や「変更を加えて」と言った場合でも、まずレポートを提示してください。レポートこそが監査の価値であり、編集に飛びつくと、ユーザーが項目に優先順位を付けたり、却下したりできる相談の機会を飛ばしてしまいます。
監査の役割は、ユーザーが対応できる指摘事項を明らかにすることであり、黙って修正することではありません。
$ARGUMENTS を解決します。
- 空の場合 → あらゆる観点から
src/全体を監査します - パス(ファイルまたはディレクトリ)の場合 → そのパスに範囲を絞り、あらゆる観点から監査します
- 焦点領域(
a11y、effects、naming、decomposition、forms、routing、subscriptions、submodels、types、testing)の場合 → その観点に限り、src/を監査します - パスと焦点領域の両方が指定された場合 → 両方の範囲に絞ります
引数が曖昧で、パスとも焦点領域とも解釈できる場合は、どちらなのか尋ねてください。推測してはいけません。
Phase 1: 監査範囲の確認
コードを読む前に、監査計画を一文で示して確認します。
「
src/page/room/を対象に、命名、分解、Effect-TS のイディオムとの一貫性を監査し、typing-game のルームページと比較します。この内容でよいですか?」
対象が明確な場合(単一ファイルまたは単一の焦点領域)に限り、この確認を省略します。それ以外の場合は、監査計画を示す手間はわずかです。これにより、見当違いの対象に時間をかける前にユーザーが方向を修正できます。
フェーズ 2:基準となるリファレンスを読む
以下を順番に読んでください。すべての監査で省略はできません。監査の評価基準となる仕様です。
- アーキテクチャガイド:TEA の不変条件、Submodel と OutMessage のパターン、Flags、Subscriptions、Mount/Command/ManagedResource/CustomElement の選択
- 規約ガイド:命名、Effect-TS の慣用表現、Schema のパターン、ビューの規約
- 検証チェックリスト:標準の機械的チェックと品質基準のリファレンス
- 見落としやすい点:型チェック、リンター、テストをすり抜ける失敗パターン
この 4 つのファイルは、ある時点のスナップショットです。監査対象プロジェクトに repos/foldkit/ が含まれている場合は、ここにある内容よりも現在のソースを優先してください。記憶しているシグネチャを基準に評価するのではなく、.d.ts またはサンプルを読んでください。
流し読みはしないでください。監査のシグナル対ノイズ比は、監査担当者が監査対象コードを読む前に基準を十分理解しているかどうかに左右されます。
フェーズ 3:プロジェクトを把握する
詳細なレビューに入る前に、監査対象コードの全体像を把握してください。
- ファイルツリー。対象範囲内のすべてのファイルと、各ファイルの説明を 1 行で記載します(
update.ts: ClickedSubmit、UpdatedEmail などのハンドラー)。 - Tier。generate-program の Tier 段階に照らし合わせます。
- Tier 1:単一ページ、非同期処理なし、単一ファイル
- Tier 2:タイマー、サブスクリプション、シンプルな状態管理
- Tier 3:非同期処理、ローディング/エラー、フォーム
- Tier 4:ルーティング、複数ページ
- Tier 5:ネストされたドメイン、CRUD
- Tier 6:Submodel、OutMessage、複数ステップのフロー
- Tier 7:リアルタイム、WebSocket、ManagedResources
- 使用している Foldkit モジュール。
foldkitからのAsyncData、Calendar、File、Http、Update、Port、Subscription、Command、Mount、ManagedResource、CustomElement、Domのインポートと、foldkit/fieldValidationおよび@foldkit/uiからインポートされているコンポーネントを grep します。HTTP の使用箇所はfoldkitからのインポートではなく、effect/httpからインポートされたHttpClient/HttpClientRequestとして現れるため、これらは別途 grep してください。foldkitのHttpはクライアントを提供するlayerにすぎません。これにより、どのチェックリストの項目が該当するかがわかります。 - Tier に合った見本。監査対象コードと並べて読むため、少なくとも 1 つ選びます。
- Tier 1-2 →
${CLAUDE_SKILL_DIR}/../../examples/counter/src/main.ts、${CLAUDE_SKILL_DIR}/../../examples/stopwatch/src/main.ts - Tier 3 →
${CLAUDE_SKILL_DIR}/../../examples/weather/src/main.ts、${CLAUDE_SKILL_DIR}/../../examples/form/src/main.ts - Tier 4 →
${CLAUDE_SKILL_DIR}/../../examples/routing/src/main.ts - Tier 5 →
${CLAUDE_SKILL_DIR}/../../examples/kanban/src/ - Tier 6 →
${CLAUDE_SKILL_DIR}/../../examples/auth/src/、${CLAUDE_SKILL_DIR}/../../examples/job-application/src/ - Tier 7 →
${CLAUDE_SKILL_DIR}/../../packages/typing-game/client/src/page/room/
- Tier 1-2 →
- Foldkit UI の統合。
@foldkit/uiから何かをインポートしている場合は、配線パターンを確認するために${CLAUDE_SKILL_DIR}/../../examples/ui-showcase/src/main.tsと${CLAUDE_SKILL_DIR}/../../examples/ui-showcase/src/ui/も読んでください。
見本が比較対象です。違和感のあるパターンを見つけたら、**見本では異なる実装になっていないか?**と確認してください。異なる場合は指摘します。
フェーズ 4:リンターを実行してから、機械的なスキャンを行う
まずリンターを確認する
@foldkit/oxlint-plugin には、この監査で評価する項目の多くを網羅する AST ルールが 24 個用意されています。キー付きのマップ行、配列インデックスをキーにしないこと、ハードコードされたルート文字列、空オブジェクトを渡すタグ付き呼び出し、外部リンクの Rel、modifyFields 内のスプレッド、子の出力を Got* でラップすること、PascalCase の Command.define バインディング、execute が要素を無視する Mount、モジュールレベルの可変状態、NoOp Messages などを検出します。コードを解析するため、grep では見逃すものも検出できます。
パッケージ名が見つかったかどうかではなく、ルールが実際に有効かを確認してください。ここで基準となるのは設定ファイルであり、リンターの出力ではありません。 設定ファイルを特定してから、その中身を確認してください。リンタースクリプトで --config を指定している場合があり、ワークスペースでは設定ファイルが通常、アプリの隣ではなく、その上の階層にあります。
grep -n '"lint"' package.json
find . .. ../.. -maxdepth 1 -name '.oxlintrc.json' 2>/dev/null
設定ファイルが見つからない場合と、Foldkit の記載がない設定ファイルが見つかった場合は、異なる結果です。標準出力だけを読んでいると、どちらも同じに見えます。 存在しないファイルに対する grep も、Foldkit の記載がない設定ファイルに対する grep も、何も出力しません。find でファイルが見つかったかどうかに応じて分岐してください。
- 設定ファイルが見つからない:結果は Undetermined です。Not active にはなりません。この監査でたどり着けなかった親ワークスペースから、プロジェクトがリンターを実行している可能性は十分にあります。
- 設定ファイルが見つかった:そのファイルで
foldkitを grep します。スキャフォールドが書き込むプラグインのrecommended.jsonを指すextendsの記載、またはモノレポやベンダー導入環境でプラグインを接続するパス指定子によるjsPluginsエントリ(Foldkit リポジトリ自体もこの方法を使用しています)が見つかった場合、ルールは Active です。見つからず、別の場所を指すextendsエントリがある場合は、そのファイルをたどって同じ確認を繰り返してください。共有の内部設定が一つ上の階層でプラグインを接続している可能性があります。何も見つからず、たどる先も残っていなければ Not active です。
リンターの出力で有効化を確認できますが、有効化されていないと判断することは決してできません。診断には foldkit(rule-name) と表示されるため、foldkit( が見つかればルールが実行された証拠になります。一方、foldkit/ を grep しても、すべてのルールが実行されている場合でさえ何も見つかりません。foldkit( が 0 件でも、何も証明できません。問題のないプロジェクトでは、それが当然の結果です。静かなリンター実行から「有効ではない」と推測してはいけません。
- Active:プロジェクトのリンタースクリプトを実行します。
foldkit(...)の診断はすべて指摘事項として、ほかの診断と同様に報告してください。同じ対象に対する grep の結果より優先されます。ルールが実際にコードを解析した結果だからです。これらの指摘事項を手作業で再導出してはいけません。 - Not active:これを最初の QUALITY 項目として、ツールに関する問題として記載してください。BLOCKER には分類しないでください。このカテゴリは構造的に誤ったコードを対象としており、項目の書式では
file:lineが必要ですが、devDependency がない場合には該当する位置がありません。また、そこに分類すると、ツールの問題だけで手書きのアプリがすべて失格になってしまいます。それでも通常、監査において最も効果の高い改善策なので、QUALITY の先頭に記載してください。devDependency を一つ追加し、extends行を一つ加えるだけで、この監査が一時点の確認であるのに対し、24 個の不変条件を継続的に適用できます。そのうえで grep に切り替え、ラップされた呼び出しや名前が変更されたヘルパーを見逃すため、より弱い代替手段であることをレポートに記載してください。リンターが有効でないプロジェクトで grep の結果がきれいでも、合格を示す強い根拠にはなりません。 - Undetermined:リンタースクリプトを実行し、
foldkit(...)の診断があれば Active の場合として扱ってください。診断が一つでもあれば、判断が確定するためです。診断がなければ、前述のとおり grep に切り替えてください。ただし、設定の接続状況は見つからなかったのではなく未確定だったと記載し、検索したパスを明記してください。これらのルールがすでに適用されている可能性があるプラグインのインストールは推奨しないでください。
create-foldkit-app でスキャフォールドされたプロジェクトでは、デフォルトでプラグインがインストールされ、接続されています。そのため、監査対象のプロジェクトにプラグインがない場合、通常はスキャフォールドより前に作成されたか、設定ファイルが削除されています。
次にスキャンを実行します
../generate-program/checklist.md の 機械的スキャン ブロックにある標準の grep を実行してください。このチェックリストが唯一の正確な情報源です。ルールではカバーされない領域(API のドリフト、@foldkit/ui の採用、Effect のイディオム、アクセシビリティの詳細、テストの構成)に加え、意図的に範囲を絞ったルールの境界もカバーします。それぞれの grep には、補完するルールと、そのルールが対象としない範囲が明記されています。ここにコマンドを重複して記載したり、ルールと対象が重なるという理由だけでスキャンを削除したりしないでください。ルールが実際にそのケースをカバーしているか確認してください。また、recommended.json では **/*.test.ts と **/*.test.tsx に対するすべてのルールが無効になっているため、Subagent E のテスト構成チェックにはリンターが何も寄与しない点にも注意してください。各ヒットは、指摘事項か // NOTE: による正当化のいずれかでなければなりません。説明のないヒットは認められません。
ヒットごとに、次の点を判断してください。
- その箇所の上に、逸脱を正当化する
// NOTE:がありますか? - ある場合、その正当化を評価してください。実際に妥当な理由ですか、それとも自分を納得させるための弁明ですか?よくある誤った正当化は、「状態を重複させる必要がある」(ほとんどの
@foldkit/uiコンポーネントには、インラインで簡単に構築できる小さなモデルがあり、制御されたレンダーヘルパーにはモデルがまったくありません)、「インタラクションが特殊すぎる」(toViewコールバックは任意の HTML に対応します)、「toParentMessage をつなぎたくない」(アクセシビリティに正しく対応したインタラクティブなウィジェットでは避けられないコストであり、使用箇所ごとに一度だけ負担します)などです。 - NOTE がなければ、指摘事項です。
機械的スキャンで検出できるのは、簡単に見つかる問題です。監査の最低ラインであり、上限ではありません。
フェーズ 5:構造レビュー
../generate-program/checklist.md の各カテゴリを、コードと照合してください。すべてのカテゴリ、すべての項目を、実際のファイルと照らし合わせます。
サブエージェントで並列化する(Tier 4 以上)
重要な監査では、作業を並列化してください。1 つのメッセージでサブエージェントを起動し、同時に実行します。それぞれが 1 つの観点を担当し、標準の参照資料と監査対象の関連ファイルを並行して読み込みます。
subagent_type: general-purpose を指定して Agent を使用してください。分担案は次のとおりです。
-
Subagent A(構造的な正しさ)。モデルスキーマが完全か、Message のユニオンが網羅されているか、
Message.matchが網羅性を検査しているか、すべてのSucceeded*に対応するFailed*があるか、すべての Command の ID がCommand.defineによって PascalCase の定数として定義されているか、すべてのルートのバリアントがレンダリングされているか、使用されない状態バリアントがないかを確認します。ネイティブの Web コンポーネントは、OnMount+ Subscription + タグ名レジストリではなく、CustomElement.defineでバインドしてください。表面が型付きプロパティ、監視対象属性、ディスパッチされるCustomEventだけで構成されているカスタム要素が、OnMount経由で接続されていないか指摘してください。 -
Subagent B(Effect-TS のイディオム)。
pipeが、通常の呼び出しを並べ替えるだけでなく、変換後の値を明確な左から右へのデータフローの主体として維持しているか確認してください。既存の update の戻り値に OutMessage を付加する場合など、その順序に意味があれば、単一の変換でも有効です。Option.map(...).pipe(Option.getOrElse(...))よりOption.matchを優先し、空/非空の分岐にはArray.matchを使ってください。Model の配列に対する分岐では、.length === 0/.length > 0よりArray.matchを優先してください(isArrayEmpty/isArrayNonEmptyの述語は可変のArray<A>を受け取り、ReadonlyArrayには使用できません)。スプレッド構文よりmodifyFieldsを優先し、現在のフィールドを変換するだけならポイントフリーのmodifyFieldsセッターを使ってください。as Typeより呼び出し可能なコンストラクターを優先し、「Command が 0 個または 1 個」の場合はArray.fromOptionを使い、述語ではEqual.equalsを使ってください。失敗しない Effect にEffect.ignoreを使用しないでください。手書きのリモートデータのユニオンよりAsyncDataを優先してください。Message.matchでしか使われない場合は、update の戻り値の型をインラインで指定してください。別の matcher、ヘルパー、またはエクスポートされたシグネチャでも型を再利用する場合は、UpdateReturnのエイリアスを作成してください。Message.match<UpdateReturn>によって型がすでに制約されている update に、戻り値の注釈を重ねて指定しないでください。 更新が OutMessage を出力できない場合はUpdate.Return<Model, Message>を使用します。outMessageフィールドが欠けている場合、その更新は何も出力しなかったことを意味します。outMessage?: neverガードは、OutMessage を含む結果が、その Model と Commands だけを保持するコードに入り込むのを防ぎます。手書きのエイリアスはそのガードを保持しなければなりません。プロデューサーは、静的に何も生成しない場合はcommandsを省略します。計算された Commands コレクションを、空かどうかを確認せずに返し、リテラルのcommands: []を決して書きません。各結果は操作名を付けた値に束縛し、ドットアクセスで消費します。
model、commands、outMessageを分割代入したり名前を変更したりしないでください。オプションの Commands はそのままCommand.mapMessagesに渡します。result.commands ?? []は、具体的な配列を必要とする操作に使います。ドットアクセスは操作とその返されたすべてのフィールドを一緒に見える状態に保ちますが、outMessageを無視することを防ぐものではありません。blindSpots.md のrepeated-scaffoldingとmanual-update-return-unpackingを参照してください。同じ Model の操作で、先行する操作が生成した Model を後続の操作が消費するときに、
result.modelとresult.commandsを手動でつないでいる場合は指摘してください。それらはUpdate.combineを使うべきです。Update.combineには 2 つ以上の Step が必要です。1 つの Step をUpdate.combineで包まないでください。その操作を直接呼び出し、複数を組み合わせるときはインラインの Step パラメータをstepModelと名付けてください。新しい結果を構築するときに OutMessage がすでに分かっている場合は、それを直接含めてください。既存のプレーンな return、またはOutMessage | undefined型の値にはUpdate.withOutMessageを使用します。既存の return をヘルパーにパイプし、新しい結果リテラルを最初の引数として渡します。Update.withOutMessageを重複させるローカルヘルパーや条件付きスプレッドを指摘してください。子フォールドが
toParentOutMessageを含むのは、少なくとも 1 つの子 OutMessage が現在の Submodel の親へ続くべき場合だけです。部分的な転送では、すべての子バリアントにマッチし、ここで止まるバリアントにはundefinedを返します。すべてのバリアントがここで止まる場合は、そのプロパティを省略します。foldOutMessageは、上方向へ続くバリアントも含め、各バリアントをローカルで処理します。toParentOutMessage: () => undefinedを指摘してください。 -
Subagent C (Naming and decomposition)。
maybe*はOption<T>用に予約し、is*はブール値用、不透明な略語や説明のない 1 文字名は不可、慣習的なドメイン省略形は許可、Changed*ではなくUpdated*、Completed*は Command 名の動詞を先頭にした形を反映、名前付きヘルパーは汎用的な動詞ではなく具体的な動詞を使用、約 15 行を超えるハンドラーは抽出、約 30 行を超える view 分岐は抽出、約 40 行を超える関数は不可。 -
Subagent D (Foldkit UI and accessibility)。手書きの
input/textarea/button/dialogは NOTE で正当化されない限り指摘、label/input のペアリングはFor(id)+Id(id)で、動的エラーはRole('alert')またはAriaLive('polite')で通知、アイコンのみのボタンにはAriaLabel、外部リンクにはRel('noopener noreferrer')、ルートごとにh1はちょうど 1 つ、divの寄せ集めではなくセマンティックなランドマーク (main、nav、header、footer)、フォーカスの可視性を保持 (focus-visible:の代替なしでoutline-noneは不可)。 -
Subagent E (Testing, Tier 3+)。
storyパイプラインを備えたstory.test.tsが存在、すべての失敗しうる Command がSucceeded*とFailed*の両方のパスでテスト済み、少なくとも 1 つの複数ステップのインタラクションテスト、Submodel テストはoutMessageをアサート、Commands は Effects を直接実行するのではなくCommand.resolve(Definition, resultMessage)で解決。scene.test.tsは Tier 3+ で必須であり、存在しない場合は BLOCKER です。各sceneブロックには少なくとも 1 つのexpect(...)またはインタラクティブな解決を含める必要があります。ロケーターはplaceholderや CSS セレクターよりもアクセシブル (role、label、text) でなければなりません。
各サブエージェントのプロンプトは自己完結しています。読むべき正規のリファレンス、監査するファイルリスト、評価する次元、そして Phase 6 のレポート形式です。各サブエージェントは、最終的なレポートの一部として所見を返します。 Tier 1~2 または対象を絞った監査では、レビューをインラインで行ってください。対象範囲が小さいため、サブエージェントに作業を分散すると、得られる効果よりオーバーヘッドのほうが大きくなります。
これらの見落としやすい点を確認する
../generate-program/blindSpots.md の項目をすべて確認してください。このファイルは generate-program のレビューサイクルと共有される正規のリストです。そのため、2つのスキルは同じ基準で評価します。各項目について、メモに次の形式で1行出力してください:<slug>: clean | flagged at <file:line>: <issue>。何も書かれていないからといって合格ではありません。
最終的な模範例との比較
監査対象のファイルを1つランダムに選び、同じティアに対応する模範例のファイルと並べて読んでください。次の点を確認します。
- 監査対象のファイルは、同じ人が書いたように見えますか?
- 分割の仕方は必然的に感じられますか、それとも恣意的ですか?
- どれか1行を削除した場合、レビュー担当者は不足に気づきますか?
どれかへの答えが「いいえ」または「気づくと思う」であれば、そのファイルをレポートで指摘してください。
Phase 6: 指摘事項をまとめる
レポートは、以下の構成に完全に一致する形で出力してください。意見や水増しは不要です。すべての行を、ユーザーが実行に移せる指摘事項にしてください。
## BLOCKERS
Items that are structurally wrong, logically buggy, or violate
Foldkit invariants. Must fix.
Each item: `path/to/file.ts:line: <what's wrong>. Fix: <action>`.
If none: write `None.`
## QUALITY
Items that work but fall short of the bar: generic naming, inline
handlers that should be extracted, native methods instead of Effect
modules in pipes, views that should be decomposed, branch keys or
key-only wrapper elements that view identity makes redundant, etc. Should fix.
Each item: `path/to/file.ts:line: <the gap>. Idiomatic version: <what to write>`.
Cite the exemplar when relevant: "typing-game does this as X at
page/home/update/handleKeyPressed.ts:33-40".
If none: write `None.`
## NICE-TO-HAVE
Polish items that would push quality further but aren't required:
additional tests, slightly better names, minor refactors.
If none: write `None.`
## VERDICT
One of:
- `PASS`: the code is at the bar.
- `NEEDS-WORK`: there are BLOCKERS or QUALITY items to address.
具体的に、容赦なく指摘してください。甘い評価はしないでください。基準を満たしているか判断に迷う場合は、模範例と比較してください。模範例がそのように書かないのであれば、指摘してください。
各指摘には、ファイルを読み直さなくても対応できるだけの情報を含めてください。
- 悪い例:
update.ts:47: 命名の問題 - 良い例:
update.ts:47: Message 名の 'ChangeEmail' は、このファイル内の他の箇所で使われている動詞を先頭に置いた過去形の規則(UpdatedPassword、UpdatedUsername)に合わせて 'UpdatedEmail' にするべきです
複数の問題が重なる場合(例:1つのヘルパーに命名の問題と長さの問題がある場合)は、それぞれ別々に報告してください。まとめてはいけません。ユーザーは個別に対応する必要があります。
Phase 7: 修正を提案する(オプトイン)
レポートを提出したら、そこで止めてください。 レポートは独立したメッセージとして送信してください。編集をステージングしたり、変更をまとめた修正計画を先に書いたり、レポートと同じ応答に「これから修正を適用します」と含めたりしないでください。
その後、別のターンで修正を適用するか確認してください。可逆性と影響範囲に応じて分類します。
- 機械的な修正(1行の編集、名前の変更、インポート順序の変更、
({})→()):まとめて1回で適用することを提案します。まとめて適用する場合も、明示的な同意が必要です。「機械的な修正を12件すべて適用しますか?」は、明確な回答を求める質問です。暗黙の了承とみなして進めてはいけません。 - 構造的な修正(ハンドラーの抽出、Submodel の導入、ビューの分割、手作りのウィジェットを
@foldkit/uiコンポーネントに置き換えること):1件ずつ提案し、それぞれ確認を得てから、適用前に差分を提示してください。 - 意味的な修正(状態の形の変更、ブール値を判別可能なユニオンに置き換えること、更新ロジックの再構成):変更内容を文章で説明し、明示的な承認を得てから適用してください。
修正を黙って適用してはいけません。ユーザーが承認していない修正を適用してはいけません。構造的な変更を「機械的な」一括適用に含めてはいけません。ユーザーが「アプリを監査して」とだけ依頼し、「見つかった問題を修正して」とは言っていない場合、レポートの提出のみを行い、それ以外の作業に進む前に確認してください。
ユーザーが修正を断った場合は、レポートをもって監査を終了します。
一部の修正が承認された場合は、それらを適用した後、4つのゲートコマンドを実行し、成功したかどうかを報告してください。
npm run format # FIRST: rewrites files
npm run lint
npm run typecheck
npm run test
ファイルを書き換えるため、最初にフォーマットを実行してください。その後、Lint、型チェック、テストを実行して、コミット対象となるコードそのものを検証します。修正の適用後にいずれかのゲートが失敗した場合は、その失敗内容を一字一句そのまま示してください。自動で元に戻してはいけません。失敗を隠してはいけません。
最後に差分の概要を示してください。どの指摘が解決済みか、どれが見送られたか、どれが未解決のままかを記載します。
対象範囲に関する補足
$ARGUMENTS で対象を特定の領域に絞る場合、Phase 5 では関連するサブエージェントと見落としやすい点だけを扱います。レポートは引き続き、対象範囲に限定した BLOCKERS / QUALITY / NICE-TO-HAVE / VERDICT の構成にします。
見落としやすい点は ../generate-program/blindSpots.md のスラッグで識別します。位置ではなく、必ずスラッグで相互参照してください。
| 注目点 | サブエージェント | 見落としがちな点 |
|---|---|---|
a11y | D | hand-rolled-widgets、a11y-gaps、aria-role-confusion |
effects | B | repeated-scaffolding、manual-update-return-unpacking、functions-doing-two-things、effect-module-inconsistency、stuttery-modifyFields-setters、hand-rolled-async-state、manual-cache-orchestration |
naming | C | naming-drift、messages-naming-the-effect、view-named-after-namespace |
decomposition | C | repeated-scaffolding、functions-doing-two-things |
forms | D + フォーム固有(Input / Textarea の採用、fieldValidation の使用、ラベルと入力欄の組み合わせ) | hand-rolled-widgets、a11y-gaps |
routing | A + ルーティング固有(双方向パーサーの使用、キー付きルート分岐のない、ID 境界としてのルートビュー、Internal ケースでの urlToString) | hard-coded-route-paths、data-derived-keys |
subscriptions | A + サブスクリプション固有(Subscription.make の形式、常時アクティブな場合の {} フィールド、Stream.map 内でのメッセージマッピング) | state-machine-edges |
testing | E | missing-scene-test |
submodels | A + サブモデル固有(Got* によるラッピング、省略可能な outMessage の戻り値、親 ↔ 子の Message の分離) | manual-update-return-unpacking、flat-parent-message-union、view-named-after-namespace |
types | (インライン)型の形状とエイリアス | manual-update-return-unpacking、array-type-syntax、unearned-type-aliases、hand-rolled-async-state |
対象を絞った監査では、Phase 4 の grep ブロック全体を省略し、対象に関連する grep のみを実行します(たとえば a11y の場合は、label without For、outline-none without focus-visible、および _blank のスキャンを実行し、各ヒットの属性ブロックを確認して Rel があるか調べます)。 |