course-analysis
Free会場別のコース適性を分析する。会場を省略すると全会場の成績を表示する。「コース分析」「会場別の適性を見たい」といった依頼で発動する。
The English summary is being prepared. Showing the original description.
有馬記念分析システム(Bun + TypeScript CLI)のコード品質・コードスタイルレビュー。
機械検証の通過(bun run c / bun run lint / bun test)、非推奨 API の使用、死にコード・消し残し、マジックナンバーと固定語彙の constants 集約、コメントの why 品質(足し算側)、既定値・フォールバックの規律、非同期とエラーハンドリング(握り潰し catch・await 漏れ)、関数構成とファイル構成(メイン関数先頭・400行)、制御フロー(条件連鎖・ガード節の羅列)、コレクション操作(reduce・entries・長チェーン)、否定条件 + else、オーケストレーションの平坦化、型安全(any・as)、import の一貫性、CLI 出力(console)の置き場所を検証。
Use when user says 'コードレビュー', 'review code', '規約チェック', 'スタイルチェック', or '死にコード確認'.
The English summary is being prepared. Showing the original description.
See how to installReview the instructions the agent will receive before you install.
src/ 配下の TypeScript を探索し、docs/DEVELOPMENT.md のコーディング規約と以下のチェックリストに基づいてレビューする。
src/(src/commands/__test__/ src/domain/**/__test__/ src/models/__test__/ src/test/ を含む)を Glob で探索するpackage.json の scripts(c / lint / test)と biome.json(および biome-plugins/*.grit)のルール設定を確認するbun run c で実行する(bun c は bun create と解釈されて失敗する)。lint は bun run lint、テストは bun testベースラインはレビュー開始時にその場で取る。
bun run lintとbun testを 1 回流し、warning 件数とテスト pass 件数を控える。base(比較対象リビジョン)と変更後で差分を見たいときは、base 側でも同じ 2 コマンドを流して比較する。件数は日々動くので本スキルには数値を書かない。
bun run c(型チェック)がエラーゼロかbun run lint(Biome)が error ゼロか(error が 1 件でもあれば FAIL)bun test が全通過し、pass 件数が base から減っていないか(減った・落ちた場合は FAIL)biome.json での off 化・severity 引き下げ・// biome-ignore コメントの追加・biome-plugins/*.grit の弱体化・overrides の除外追加)で警告を回避していないかlint(error レベル)が担保する規約 — 以下は Biome が機械検出するため、各レビュースキルのチェックリストからは外してある。本項で bun run lint の error ゼロを確認することが、そのまま以下の担保になる:
| ルール | 担保する規約 |
|---|---|
style/noRestrictedImports(src/domain/**) | domain 層は commands を import しない |
style/noRestrictedImports(src/domain/entities/** src/domain/valueObjects/**) | entities / valueObjects は bun:sqlite・repositories・database・commands・models・utils・node の fs / http / child_process を import しない(純粋性) |
suspicious/noConsole(src/domain/entities/** src/domain/valueObjects/**) | entities / valueObjects に console 出力を持ち込まない |
style/noRestrictedImports(src/repositories/**) | repositories は commands / models / domain に依存しない |
style/noRestrictedImports(src/constants/** src/types/**) | constants / types は依存の末端で、他層を import しない |
style/noRestrictedImports(src/models/** src/utils/** src/features/** src/database/**) | 下位層は commands を import しない(依存は index.ts → commands → 下位層 の一方向) |
plugin no-database-connection-construction | new DatabaseConnection(...) は commands / src/index.ts / models のフォールバック / src/database のファクトリ / テストのみ |
suspicious/noFocusedTests / suspicious/noSkippedTests | .only / .skip をテストに残さない |
security/noGlobalEval / nursery/noImpliedEval | eval() / new Function / 文字列を渡す setTimeout を導入しない |
nursery/noExcessiveNestedCallbacks | コールバックのネストは 3 段まで(__test__ / src/test/ は除外) |
style/noRestrictedImports(kysely) | Kysely は repositories / database 層だけで使う(domain / commands / models / features / utils / constants / types からは禁止) |
style/noRestrictedImports(src/database/QueryRunner) | QueryRunner(queryBuilder と実行ヘルパー)は repositories / database 層とテストだけで import する |
plugin no-kysely-builder-execution | Kysely ビルダーの .execute() / .executeTakeFirst() / .executeTakeFirstOrThrow() / .stream() を呼ばない(DummyDriver のため空の結果が返る。実行は src/database/QueryRunner.ts のヘルパー経由) |
plugin no-kysely-raw-sql | sql.raw( / sql.lit( を使わない(sql タグ付きテンプレートの ${value} はバインドされるので可) |
plugin no-sql-template-interpolation | db.prepare / db.exec / db.query に補間つきテンプレートを渡さない(? の並びを組み立てる placeholders 変数は除く) |
plugin no-ambient-time(src/domain/**) | domain 層で引数なしの new Date() / Date.now() を使わない |
plugin no-reduce-entries | reduce / .entries() を使わない |
plugin no-js-import-extension | 内部モジュールの import に .js 拡張子を付けない(./ と @/ の両方) |
plugin no-parent-relative-import | ディレクトリをまたぐ import は @/ で書く(../ で親をたどらない。静的 import・再 export・動的 import が対象) |
plugin no-direct-statement-preparation | db.prepare / db.exec / db.query を直接呼ばない(src/database/**・テスト・テストヘルパは対象外。クエリは Kysely で組み立て実行ヘルパーに渡す) |
lint が見ないもの(引き続き人手で見る): ブロックのネスト深さ、命名規約(Biome の useNamingConvention は本リポジトリの日本語混在・DB カラム名由来の識別子で誤検出が大量に出るため不採用)、import の並び順(assist の organizeImports は書き換えを伴うため無効)。
@deprecated が付いていないか(型定義の JSDoc / エディタの取り消し線を確認)@deprecated 付きメソッドを新規コードから呼んでいないかNG例: MachineLearningModel.optimizeWeights(@deprecated・「予測には使わない。説明用の in-sample 射影」と明記)の戻り値を、新しい予測経路から使う
OK例: 予測は MachineLearningModel.predict() / walkForwardValidate()、特徴量取得は FeatureBuilder.buildForRace(raceId, asOf) / extractFeaturesForRace(horseId, raceId, asOf) を使い、null を呼び出し側で扱う
bun run lint の correctness/noUnusedVariables / noUnusedImports(warn)の該当件数が本変更で純増していないかで見る。export された未使用シンボル(未参照の定数モジュール等)は lint が検出しないので、こちらは Grep で確認するdocs/ 配下・src/database/schema.sql・CLI のコマンド定義(src/index.ts)に残っていないかNG例: src/domain/services/ScoringOrchestrator.ts の // TODO: Trainerエンティティの構築は将来実装 — 実装保留の TODO とコメントアウトされた旧コードが同居(既存債務。コメントの引き算そのものは review-comments 管轄で、本項は「機能削除・実装保留に伴う消し残し」としてのみ見る)
OK例: 削除時に Grep で全参照(コード・docs/・スキーマ・CLI 定義)を洗い、同一変更で除去する
src/constants/ の定数になっているか(src/constants/ScoringConstants.ts / DistanceConstants.ts / MLConstants.ts)良/稍重/重/不良、レース種別 芝/ダート/障害、会場名、G1 レース名)がロジック中に配列リテラル・文字列リテラルで散らばっていないか。語彙集合は constants に置き、判定は名前の付いた述語にまとめるNG例: Horse.calculateVenueAptitudeScore の if (venueStats.runs === 0) return 50;(初出走馬の既定スコア 50 が裸のリテラル)/ImportData.parseTrackCondition の ['良', '稍重', '重', '不良'].includes(condition)(馬場状態の語彙がインラインの配列リテラル)
OK例: Horse.calculateDistanceAptitudeScore の DISTANCE_THRESHOLDS.aptitudeRange、Horse.calculateLast3FAbilityScore の LAST_3F_PARAMS.baseTime のように constants から名前付きで引く
コメントは省略が既定。コードは名前と構造で語らせ、コメントは「コードから導出できない事実」(why・不変条件・責務の所在・戻り値の特殊な意味)を言うときだけ 1 行で足す。判定軸は「付いているか」ではなく「その1行がコードに無い意味を持つか」。過剰・不要・陳腐化の引き算は review-comments の責務(足りない why=本項 / 多すぎ・不要=review-comments で切り分ける)。
execute、ScoringOrchestrator.calculateScoresForRace)だけ、骨格数ステップのフローコメントや @remarks を許容するNG例: src/domain/entities/Horse.ts のプロパティアクセサ区画 — /** 馬ID */ get id() のように getter 名と同義の JSDoc が並ぶ
OK例: Horse.calculateVenueAptitudeScore 冒頭の // 芝ダ・距離カテゴリ別の集計を会場単位に合算する。 と // 会場での出走実績がない場合は中間値を返す(初出走馬対応)(コードから読めない意図を 1 行で述べている)
NG例: 特徴量取得に失敗したとき全要素を中間値(50)で埋めて返す(予測がデータ欠損由来か実力由来か判別できなくなる)
OK例: MachineLearningModel.extractFeaturesForRace / FeatureBuilder.buildForRace は取得に失敗した馬を null で返し、呼び出し側が対象から除外できる
async メソッドの呼び出しに await が付いているか(src/index.ts の各 action は await command.execute() の形が正)。bun run lint の nursery/noFloatingPromises(warn)の該当件数が本変更で純増していないかを見るcatch {} を増やしていないか。握り潰す場合は、原因を出力するか、縮退したことが利用者に分かる形にするScoringOrchestrator.calculateScoresForRace の throw new Error('Race not found: ...') が前例)src/utils/JRAFetcher.ts)に明示的なタイムアウトと失敗時の後始末があるかprocess.exit を CLI エントリ(src/index.ts / コマンド入口)以外の深い層で呼んでいないかNG例: MachineLearningModel / Backtest / JRAFetcher に残る } catch { return null; } — 失敗理由が一切残らない(既存債務。新規に同型を増やさない。件数は Grep catch { で確認する)
OK例: catch (error) { console.error('スコア計算に失敗:', error); } のように原因を残したうえで縮退する(CalculateScore.execute の catch が前例)
execute / 主要な計算)を上に、private ヘルパを下に置いているか// ===== プロパティアクセサ ===== 等)でファイルを上から追える形になっているか(src/domain/entities/Horse.ts の区画コメントが前例)bun run lint の style/noExcessiveLinesPerFile / complexity/noExcessiveLinesPerFunction / complexity/noExcessiveCognitiveComplexity(いずれも warn。__test__ は除外)が機械検出する。該当ルールの warning が本変更で純増していないかを見る(既に超過しているファイルをさらに長くした場合も純増側に現れる)|| / && の長い連鎖で判定を組み立てていないか。判定条件は意図の名前が付いた述語関数か説明変数にまとめるif (...) return null を 3 つ並べるようなガード節の羅列になっていないか(段階ごとに関数を分け、メイン関数は段の流れだけを見せる)NG例: src/domain/entities/RaceResult.ts の isG1() — 特定レース名の includes(...) を || で連ねた長い判定(既存債務)
OK例: 語彙を constants の集合に出し、isG1() は「格が G1 か、または G1 レース名の集合に含まれるか」の 2 条件に畳む
集約は
let+for-ofの加算で書く。index が必要なループはfor (let i = 0; ...)+ 先頭で要素を取り出し undefined ガードする。
reduce / .entries() / Object.entries を使っていないか。合計・集約は let sum = 0; for (const r of results) sum += ...、キー走査は Object.keys + 添字 + ガードで書く。plugin no-reduce-entries(warn)が機械検出するので、該当 warning が本変更で純増していないかを見る(既存の該当箇所は既存債務).includes() になっていないか(語彙集合は new Set([...]) を constants に置き .has() で判定する。2.4 と一体で、語彙の配置は 2.4、判定手段の書き方は本項)filter(...).length で件数を数える等)はそのままでよい。機械的に全部 for 文にしないstyle/noNegationElse)と多段ネスト三項(style/noNestedTernary)は lint が warn で機械検出する。該当ルールの warning が本変更で純増していないかを見る。純増していれば、分岐を入れ替えて肯定形を先にするか、対応表・関数に出すexecute / 主要メソッドが名前付きステップの平坦な列挙になっているか(引数解釈・取得・計算・保存・表示が上から順に読める)。try/catch の中身や手続きの詳細は専用メソッド・説明関数へ追い出すconst detail = this.data.detail; if (!detail) return 0; の形)OK例: src/domain/services/ScoringOrchestrator.ts:68-120 — レース取得 → 出走馬取得 → バッチ取得 → エンティティ構築 → 計算委譲、が上から順に読める
any(suspicious/noExplicitAny)と非 null アサーション(style/noNonNullAssertion)は lint が warn で機械検出する(後者は __test__ では off)。該当ルールの warning が本変更で純増していないかを見る。純増していれば、any は具体型へ、! は ?? の既定値か早期 return へsrc/types/RepositoryTypes.ts の型が付いているか(db.prepare(...).all() の結果を無検証で as T 確定していないか。確定させる場合は列名と型の対応をその場で確認できる形にする)。as T による無検証の型確定は lint が見ないので、本項が唯一の検出手段as T で確定させず、必須フィールドの欠落を実行時にガードしているかdocs/DEVELOPMENT.md の規約(1. Node/Bun 組み込み → 2. サードパーティ → 3. @/ の内部モジュール → 4. ./ の同ディレクトリ配下)に従っているか(lint は見ない。assist の organizeImports は書き換えを伴うため無効にしてある。本項が唯一の検出手段で、目視で見る)@/(plugin no-parent-relative-import)、拡張子なし(plugin no-js-import-extension)、型のみ import が import type(style/useImportType)になっているかは lint が error で機械検出する。本項では同ディレクトリ配下を指す ./ が @/ に書き換わっていないか(自ファイルの隣を遠回りに参照していないか)を目視で見る本システムは CLI であり、
console出力はsrc/commands/とsrc/index.tsの表示責務として正当。禁止するのではなく、置き場所と粒度を見る。
src/commands/ と src/index.ts に留まっているかsrc/utils/ src/models/ src/domain/services/ src/features/ の既存 console は既存債務。新規の計算・取得ロジックでは、結果を戻り値で返し表示は呼び出し元の command に任せる形を優先したかsrc/domain/entities/ src/domain/valueObjects/ への console 混入は lint(suspicious/noConsole = error)が落とすため本項では見ない。lint の通過確認は 2.1console.error、警告は console.warn と使い分けているか(成功ログと失敗ログが同じ console.log に混ざっていないか)error オブジェクト)を握り潰さず出力しているか(2.7 と一体。原因が残らないこと自体は 2.7 で計上し、出力先・レベルの妥当性を本項で見る)reduce/entries の新規使用・400行超過・import 拡張子の不統一・lint warning の純増)bun run c / bun run lint(error)/ bun test の不通過、非推奨 API の新規使用、消し残しによる実害(参照切れ・誤動作)、正常系を上書きするフォールバック、原因の残らない例外握り潰しの新規追加reduce / .entries()、400 行超のファイル、any、.js 拡張子、握り潰し catch {} 等)は、本変更で悪化させていなければ FAIL にせず、備考に「既存債務(本変更非起因)」と明記して WARN 以下に留める。基準は「新規変更で悪化させない」こと(= 2.1 で取ったベースラインからの純増がないこと)Summary: SKIPPED層構造・配置・依存方向は review-arch、名前の語の選択は review-naming、コメントの引き算(過剰・不要・陳腐化)は review-comments、テスト品質は review-test、SQL 注入・取得先 URL 制限・パス操作は review-security、時刻の注入可能性・再実行の冪等性は review-recovery、重み合計や特徴量統一などスコアリングのドメイン正しさは review-scoring
SQL 文字列の組み立てに関する安全性は review-security へ申し送る(本スキルでは計上しない)。plugin no-sql-template-interpolation が warn で機械検出する
コードスタイル規約(2.5 / 2.8〜2.12)は本スキルが正。コードを書く前の参照にも本スキルを使う(設計上の判断は design-principles)
チェック表の行は SKILL.md のチェックリスト項目のみで構成する。チェックリストに無い独自の行を表に追加しない(チェック項目外の気づきは「他観点への申し送り」へ。自観点に関連するが項目化されていない所見は「詳細所見」に書き、Summary には数えない)
表には全チェックリスト項目(2.1〜2.15)を列挙する。該当変更が無い項目も N-A 行として残し省略しない(レビュー網羅性の担保)。Summary には OK/WARN/FAIL のみ計上し N-A は除外する
同一の行・欠陥でも、自観点のチェックリスト項目に明示的に該当する側面だけを自分の表・Summary に計上する(多面評価は可)。チェックリストの項目名から読めない拡大解釈(ドキュメントや一般原則からの引き込み)で FAIL を増やさない
自観点の項目に該当しない問題は計上せず、レポート末尾の「### 他観点への申し送り」節に「対象スキル名: 1行説明」で記載するだけにする(FAIL/WARN を付けない)
同一事象が自観点の複数チェック項目に該当する場合は、最も特異的な 1 項目だけで計上し、他項目は備考で相互参照する(Summary で重複カウントしない)。特異性の判定: 違反種別を最も具体的に名指す項目を選ぶ(例: 固定語彙の配列 .includes() は「コレクション操作」2.10 が判定手段として具体的だが、語彙がロジック中に直書きされている点は 2.4 が根本のため 2.4 で計上する)。優劣が付けにくいときはチェックリスト番号の小さい方で計上する(決定論的に揃える)
差分内コードが依存する差分外の既存実装は、確認してよいが新たな指摘対象にはしない(当該チェック項目を OK とし、備考に「依存先は差分外・確認済み」と書く)
## コード品質 レビュー結果
| # | チェック項目 | ステータス | 該当箇所 | 備考 |
| - | ------------ | ------------ | --------- | ---- |
### 詳細所見
### 他観点への申し送り
### 推奨アクション
- HIGH / MEDIUM / LOW
Summary: OK=<n> WARN=<n> FAIL=<n>
No reviews yet. Tell others what you thought.
No login needed. Share how it worked for you, ask a question, or note where it did not run.
No comments yet. Be the first to write one.
会場別のコース適性を分析する。会場を省略すると全会場の成績を表示する。「コース分析」「会場別の適性を見たい」といった依頼で発動する。
The English summary is being prepared. Showing the original description.
抽出済みJSONファイル(馬・血統・レース出走データ)をSQLiteデータベースにインポートする。「DBインポート」「データベースに保存」「JSONをDBに登録」といった依頼で発動する。
The English summary is being prepared. Showing the original description.
実装前に参照する設計原則。理解容易性 = 読み手の思考量の少なさを基準に、AI が作りがちな失敗4パターン(引数・依存5個以上、コマンド層肥大・ドメイン貧血症、ポリモーフィズム機会の見逃し、トリッキーな実装)と、実装後セルフチェックの7観点(名称・役割・参照・状態・面積・階層・秩序)を言語化。Use when starting any implementation task, when user says '設計原則', 'design principles', or before writing new entities/commands/repositories.
The English summary is being prepared. Showing the original description.
agent 向けテキスト指示(skill / slash command / task プロンプト / コード生成プロンプト)を、バイアスを排した実行者に動かしてもらい、両面(実行者の自己申告 + 指示側メトリクス)で評価して反復改善する手法。改善が頭打ちになるまで回す。Use when user says 'プロンプトを改善して', 'スキルをチューニング', 'empirical-prompt-tuning', or after creating/heavily revising a skill or prompt.
The English summary is being prepared. Showing the original description.
JRA公式サイトから特定レースの出馬表HTMLを取得して馬データを抽出する。「データ取得」「JRAからデータを取ってきて」「出馬表を取得して」といった依頼で発動する。
The English summary is being prepared. Showing the original description.
有馬記念分析システムで利用可能なスキル一覧と使い方、スコア配分、基本ワークフローを表示する。「ヘルプ」「使い方を教えて」「何ができるの」といった依頼で発動する。
The English summary is being prepared. Showing the original description.