会場別のコース適性を分析する。会場を省略すると全会場の成績を表示する。「コース分析」「会場別の適性を見たい」といった依頼で発動する。
中文简介正在准备中。当前显示原文说明。
スコアリング / ML のドメイン正しさのレビュー。
SCORE_WEIGHTS の単一定義と合計1.0・ドキュメント追随、スコアリングと ML の10要素の一致(手書きで並ぶ全箇所の同時更新)、未来情報リーク(as-of カットオフを通していない取得経路の新設)、値域0〜100とゼロ除算、データ欠損時の既定値、学習・予測の決定性と再現性、JRA 枠番割当規則、バックテスト指標(1位的中率・上位3頭精度・順位相関・ROI)の計算を検証。
Use when user says 'スコアリングレビュー', 'review scoring', 'ML レビュー', 'スコア計算チェック', '特徴量チェック', or 'バックテスト検証'.
中文简介正在准备中。当前显示原文说明。
查看安装方法安装前可以查看交给 AI 代理的指令内容。
src/domain/ src/constants/ src/models/ src/commands/(Backtest / CalculateScore / Predict)を探索し、スコアリングと機械学習のドメインとしての正しさをレビューする。規約の正は docs/MODELS.md と docs/ARCHITECTURE.md。
起動時に「対象スコープ」と「対象ファイル一覧」が渡される場合がある(review-all 等からの dispatch 時)。その扱いは次の通り:
N-A で残し、備考に根拠を書く。行を省かない)Summary: SKIPPED の最小出力でよい(テーブル骨格は不要)node_modules/ は除外)を対象にするsrc/constants/ScoringConstants.ts / src/constants/MLConstants.ts(重み・閾値・既定値の唯一の置き場)src/domain/entities/Horse.ts Jockey.ts Trainer.ts / src/domain/valueObjects/ScoreComponents.ts Score.tssrc/domain/services/ScoringOrchestrator.ts(エンティティ組み立て・枠番算出)src/features/FeatureBuilder.ts(ML 特徴量の組み立て・FEATURE_SPECS)と src/models/MachineLearningModel.ts(L2正則化ロジスティック回帰・学習/予測・walk-forward 検証)src/commands/Backtest.ts CalculateScore.ts Predict.tssrc/repositories/queries/HorseQueryRepository.ts / JockeyQueryRepository.ts / src/repositories/aggregates/ScoreAggregateRepository.ts(特徴量の供給元。リーク判定はここを読まないとできない)docs/MODELS.md(配分表・計算式)と README.md / docs/ARCHITECTURE.md / .claude/skills/help / .claude/skills/score-calc の配分記述SCORE_WEIGHTS(src/constants/ScoringConstants.ts)だけで定義され、エンティティ・コマンド・ML 側に数値が直書きされていないかSCORE_WEIGHTS の合計が 1.0 のままか(要素の追加・削除・変更で合計が崩れていないか)docs/MODELS.md の配分表と計算式、docs/ARCHITECTURE.md、README.md、.claude/skills/help/SKILL.md、.claude/skills/score-calc/SKILL.md)が同じ変更で追随しているかScoreComponentsData(src/domain/valueObjects/ScoreComponents.ts)のコメントに書かれたパーセンテージが実際の SCORE_WEIGHTS と一致しているかNG例: calculateTotalScore() 内で recentPerformance * 0.22 と直書きする(定数と二重管理になり、片方だけ動いてズレる)
OK例: ScoreComponents.calculateTotalScore() — 全要素が SCORE_WEIGHTS.<key> を参照して加重和を取る
10 要素(直近成績 / コース適性 / 距離適性 / 上がり3F / G1実績 / ローテ適性 / 騎手能力 / 馬場適性 / 枠順効果 / 調教師)は、同じ並びが複数ファイルに独立して手書きされている。要素の追加・削除・改名は、以下をすべて同時に更新しないと片側だけズレる:
src/constants/ScoringConstants.ts の SCORE_WEIGHTS(正本。重みキー)src/domain/valueObjects/ScoreComponents.ts の ScoreComponentsData のフィールドと calculateTotalScore() の加重和src/types/RepositoryTypes.ts の interface ScoreComponents(ScoreComponentsData と別に手書きされている重複定義)src/domain/entities/Horse.ts の calculateTotalScore() が組み立てる componentsDatasrc/features/FeatureBuilder.ts の FEATURE_SPECS の R:* エントリと emptyRuleScores()src/models/MachineLearningModel.ts の ruleFeatureNames(表示用の日本語名)・getCurrentWeights()・getOptimizedWeightsAsConstants() の keys・prepareRuleScoreRegressionData()src/commands/CalculateScore.ts の interface HorseScore・スコア詰め替え・updateHorseScore の DB カラム名マッピング(course_aptitude_score / rotation_score など別名になっている点に注意)・表示用の要素一覧src/commands/Backtest.ts の components 組み立てと calculateElementContribution の elementNamesFEATURE_SPECS の並びと重み側の並びがズレると、重要度表示や重みの射影が別要素に割り当たる)NG例: スコア要素を1つ足して SCORE_WEIGHTS と ScoreComponentsData だけ更新し、FEATURE_SPECS の R:* が10個のまま → 特徴量ベクトルの次元と要素名の対応がズレる
OK例: FeatureBuilder.FEATURE_SPECS の R:* 10 行が ScoreComponentsData の 10 フィールドを同じ順で列挙している
過去レースを評価・学習に使うとき、そのレース当日以降の成績(当該レース自身の着順・上がり3F・人気を含む)が特徴量に混入していないか。混入していれば的中率・改善率の数字は実力より高く出る。
as-of カットオフは既に実装されている: ScoringOrchestrator.calculateScoresForRace(raceId, asOf?) / calculateScoreForEntry(entry, race, asOf?) が asOf ?? レース日 を cutoff として下流へ流し、HorseQueryRepository.getHorseRaceResults(horseId, limit?, beforeDate?) / getHorsesRaceResultsBatch(horseIds, beforeDate?) / getHorsesCourseStatsAsOf / getHorsesTrackStatsAsOf / getPreviousRacesAsOf と JockeyQueryRepository の beforeDate 付きメソッドが r.race_date < ? で絞る。FeatureBuilder.buildForRace(raceId, asOf?) も同じ経路を使う。本項は「この規律から外れる経路を新設していないか」を見る。
beforeDate / asOf 引数を通しているか。値を返す前に「この値は対象レースの発走前に確定しているか」を答えられる形(日付引数を取る/日付で絞った集計を使う)になっているかbeforeDate を渡さずに新しい経路から呼んでいないか(getHorseRaceResults / getHorsesRaceResultsBatch / JockeyQueryRepository の各メソッドは beforeDate が省略可能なので、渡し忘れても型エラーにならない)horse_course_stats / horse_track_stats)を評価・学習経路で使っていないか。これらは全期間で集計されるため、as-of 経路では getHorsesCourseStatsAsOf / getHorsesTrackStatsAsOf(race_results から都度集計する版)を使うBacktest.evaluateRace が、そのレース時点で入手可能な情報だけでスコアを組み立てているか(確定オッズのような発走後に確定する値を特徴量側に入れていないか。払戻オッズは ROI 計算にだけ使う)getHorsesRaceResultsBatch のバッチ版、JockeyQueryRepository の beforeDate 系)に変更を入れるなら、リーク遮断のテストを同じ変更で足したか(review-test 5.7 と一体)NG例: 新しい集計メソッドを getHorseCourseStats(horseId) のように基準日を取らない形で追加し、評価・学習経路から呼ぶ/既存の getHorseRaceResults(horseId, 5) を beforeDate 省略のまま新経路から呼ぶ(全戦績が返り、対象レース自身とそれ以降の着順が「直近5戦」に入る)
OK例: ScoringOrchestrator.buildHorseEntity(horseId, asOf) — asOf があれば getHorsesCourseStatsAsOf / getHorsesTrackStatsAsOf を使い、集計テーブル版へは as-of 無しのときだけフォールバックする。遮断は src/domain/services/__test__/AsOfLeakage.test.ts(対象レース/後続レースの結果を投入してもスコア・特徴量が変わらない)と src/models/__test__/MachineLearningModel.e2e.test.ts(未来レースを削除しても学習サンプルが変わらない)で固定されている
Math.min(score, 100)、ボーナス加算後も超えないか。下限は負にならないか)runs === 0 / length === 0 / totalIntervals === 0)validResults.length で割るべき所を全件数で割っていないか)NG例: const winRate = stats.wins / stats.runs; を 0 判定なしで書く(runs=0 で NaN が伝播し、以降の比較がすべて false になってスコアが静かに壊れる)
OK例: Horse.calculateTrackConditionScore — if (!stats || stats.runs === 0) return TRACK_CONDITION_DEFAULT_SCORE; の後に除算し、最後に Math.min(score, 100) で上限を締める
src/constants/ の定数(*_DEFAULT_SCORE の形)に置かれ、直書きされていないかnull を返して除外する、が現在の方針)src/constants/MLConstants.ts から引こうとしていないか。このファイルは現在どのエクスポートも参照されていない死にコードなので、新規参照を足す前に「この定数が実装の正なのか」を確認する(実装側の値と二重管理になる)NG例(現状 — 既存債務): 欠損時の既定値が要素ごとに不統一。コース適性は Horse.calculateVenueAptitudeScore で裸の return 50、馬場適性は TRACK_CONDITION_DEFAULT_SCORE(50)、一方で距離適性とローテ適性は return 0、G1実績は G1_DEFAULT_SCORE(30)
OK例: 既定値をすべて定数化し(TRACK_CONDITION_DEFAULT_SCORE / G1_DEFAULT_SCORE の形)、「実績なしを 0 とするか中間値とするか」の判断理由を JSDoc に残す
現在の ML はランダムフォレストではなく、L2正則化ロジスティック回帰(trainL2Logistic。特徴量標準化 + full-batch 勾配降下 + 収束判定。単勝はレース内 softmax)。アンサンブルは無い。本番コードに乱数は無く、学習・予測は入力だけで決まる。
Map/Set の反復順に依存する処理を持ち込んでいないかsrc/test/helpers/syntheticRaces.ts の mulberry32(seed) が前例)src/models/__test__/MachineLearningModel.e2e.test.ts の「検証結果は決定論的(同じDBなら同じ数値)」が前例)NG例(現状 — 既存債務): 正則化パラメータが optimizeWeights(lambda: number = 0.1) のデフォルト引数に直書きされている/ラベル定義の除数がマジックナンバーで置かれている
OK例: trainL2Logistic(X, y, options) が options.l2 ?? 1.0 として受け取り、呼び出し側が値を明示できる形になっている
calculateFrameNumber(src/constants/ScoringConstants.ts)に一元化され、各所で Math.ceil(horseNumber / 2) のような自前計算をしていないかframe_number を優先し、無いときだけ算出しているか(entry.frame_number ?? calculateFrameNumber(...)。ScoringOrchestrator.calculateScoresForRace と calculateScoreForEntry の両経路)race.totalHorses ?? entries.length)NG例: 枠番を Math.ceil(horseNumber / 2) で算出する(16頭立てでしか合わず、14頭立てでは1〜2枠が1頭である規則に反する)
OK例: ScoringOrchestrator — entry.frame_number ?? calculateFrameNumber(entry.horse_number, race.totalHorses ?? entries.length)
top1Hit)が「スコア1位の馬の実着順が1着」で判定されているか(Backtest.calculateMetrics)Backtest.calculateSummary)calculateSpearmanCorrelation)。相関の符号の向き(高スコア=小さい着順=負の相関が良い)が calculateElementContribution で正しく反転されているかsimulateROI)が使うオッズの出どころが表示・コメントで明示されているか。現在は DB の払戻オッズ(payoutWinOdds)を使い、オッズが無いレースは continue で母数から外れるので、除外された件数が出力から分かるかcalculateMarketBaseline)との比較が、同じレース集合・同じ母数で行われているかgetRacesWithResults / slice)が結果の解釈と一致しているか(「最新10レース」「重賞のみ」といった前提が出力に表示されているか)Backtest の catch { return null; })で、評価対象が黙って減っていないか(件数が表示されるか)NG例: オッズが無いレースを黙って母数から外したまま「回収率」とだけ表示する(対象レース数が分からず、実測と誤読される) OK例: 仮定や母数(対象レース数・オッズの出どころ)を出力に明示する
beforeDate の渡し忘れ)、重み合計が 1.0 でない、10要素の片側だけ更新、ゼロ除算で NaN が伝播する経路、学習・予測の非決定化、枠番規則の誤実装、指標の分母・符号の誤りsrc/domain/entities/ src/domain/valueObjects/ src/domain/services/・src/constants/・src/models/・src/commands/Backtest.ts src/commands/CalculateScore.ts src/commands/Predict.ts のいずれにも変更が無い場合 Summary: SKIPPED## スコアリング / ML レビュー結果
| # | チェック項目 | ステータス | 該当箇所 | 備考 |
| - | ------------ | ------------ | --------- | ---- |
### 詳細所見
### 推奨アクション
- HIGH / MEDIUM / LOW(該当が無い優先度は「なし」と明示)
レポート末尾に必ず以下の 1 行を出力する:
Summary: OK=<n> WARN=<n> FAIL=<n>
Summary: SKIPPED还没有评价。欢迎分享你的使用感受。
无需登录即可发表。欢迎分享使用感受、提问,或说明在哪些环境下无法运行。
还没有评论。来写第一条吧。
会場別のコース適性を分析する。会場を省略すると全会場の成績を表示する。「コース分析」「会場別の適性を見たい」といった依頼で発動する。
中文简介正在准备中。当前显示原文说明。
抽出済みJSONファイル(馬・血統・レース出走データ)をSQLiteデータベースにインポートする。「DBインポート」「データベースに保存」「JSONをDBに登録」といった依頼で発動する。
中文简介正在准备中。当前显示原文说明。
実装前に参照する設計原則。理解容易性 = 読み手の思考量の少なさを基準に、AI が作りがちな失敗4パターン(引数・依存5個以上、コマンド層肥大・ドメイン貧血症、ポリモーフィズム機会の見逃し、トリッキーな実装)と、実装後セルフチェックの7観点(名称・役割・参照・状態・面積・階層・秩序)を言語化。Use when starting any implementation task, when user says '設計原則', 'design principles', or before writing new entities/commands/repositories.
中文简介正在准备中。当前显示原文说明。
agent 向けテキスト指示(skill / slash command / task プロンプト / コード生成プロンプト)を、バイアスを排した実行者に動かしてもらい、両面(実行者の自己申告 + 指示側メトリクス)で評価して反復改善する手法。改善が頭打ちになるまで回す。Use when user says 'プロンプトを改善して', 'スキルをチューニング', 'empirical-prompt-tuning', or after creating/heavily revising a skill or prompt.
中文简介正在准备中。当前显示原文说明。
JRA公式サイトから特定レースの出馬表HTMLを取得して馬データを抽出する。「データ取得」「JRAからデータを取ってきて」「出馬表を取得して」といった依頼で発動する。
中文简介正在准备中。当前显示原文说明。
有馬記念分析システムで利用可能なスキル一覧と使い方、スコア配分、基本ワークフローを表示する。「ヘルプ」「使い方を教えて」「何ができるの」といった依頼で発動する。
中文简介正在准备中。当前显示原文说明。