course-analysis
Free会場別のコース適性を分析する。会場を省略すると全会場の成績を表示する。「コース分析」「会場別の適性を見たい」といった依頼で発動する。
The English summary is being prepared. Showing the original description.
外部データ取得と取り込み経路のセキュリティレビュー。
JRA 以外のホストへ取りに行かせない URL 検証(SSRF)、スクレイピングの作法(User-Agent・リクエスト間隔・タイムアウト)、外部由来 HTML/JSON を無検証で DB に入れない、クエリを Kysely で組み立て生の SQL 文字列を増やさないこと、CLI 由来のファイルパスの扱い、生成物(*.db / data/extracted-*.json / data/jra-page.html)と .env をコミットさせないことを検証。
Use when user says 'セキュリティレビュー', 'review security', 'セキュリティチェック', 'SSRF確認', or 'SQLインジェクション確認'.
The English summary is being prepared. Showing the original description.
See how to installReview the instructions the agent will receive before you install.
外部(JRA サイト・ローカル JSON ファイル・CLI 引数)から入ってくるデータの経路を探索し、危険な取り扱いが無いかレビューする。
起動時に「対象スコープ」と「対象ファイル一覧」が渡される場合がある(review-all 等からの dispatch 時)。その扱いは次の通り:
N-A で残し、備考に根拠を書く。行を省かない)Summary: SKIPPED の最小出力でよい(テーブル骨格は不要)node_modules/ は除外)を対象にするsrc/utils/JRAFetcher.ts(唯一のネットワーク出口。URL 検証・User-Agent・タイムアウト・保存先)src/utils/HorseDataExtractor.ts / src/commands/ExtractData.ts(外部 HTML の正規表現パース・JSON 出力)src/commands/ImportData.ts(外部 JSON の読み込みと DB 投入)/ src/index.ts(CLI 引数の受け口)src/repositories/ 全体(SQL の組み立て)/ src/database/DatabaseConnection.tsdb.prepare / db.exec / db.run / db.query・readFileSync / writeFileSync / mkdirSync・process.env・child_process / Bun.spawn / eval( / new Function.gitignore と git ls-files の突き合わせ(生成物がトラックされていないか)JRAFetcher に一本化され、別経路で http.get / https.get / fetch を直に書いていないかALLOWED_HOST_SUFFIXES)で検証され、リクエスト前に弾かれているかendsWith('go.jp') 等)になっていないかhttp.get / https.get で自動追従しない。非 200 はエラー扱い。リダイレクト追従を足すなら追従先も再検証が要る)NG例: CLI 引数の URL をそのまま https.get(url) に渡す(file:// やイントラネットのホストを踏ませられる)
OK例: JRAFetcher.validateUrl() が ALLOWED_HOST_SUFFIXES(['jra.go.jp'])でスキームとホストを検証し、fetchHTML の冒頭で失敗を即返す
JRAFetcher の defaultOptions.timeout = 30000ms と request.setTimeout(...) → request.destroy())src/utils/JRAFetcher.ts を使う新規コマンド等)に、リクエスト間隔(sleep / レートリミット)が入っているか。間隔制御なしのループ取得・一括取得を新設・拡張する変更は WARN 以上JRAFetcher.defaultOptions.userAgent はデスクトップ Chrome を騙る固定値。相手サイトの規約・robots の観点で、これを新たに増やす・偽装を強める変更は理由が要る)JRAFetcher.convertEncoding はオプション既定の Shift_JIS で decode し、未知指定時は Shift_JIS → UTF-8 のフォールバック。HTTP ヘッダの charset は見ていない点を踏まえた変更か)NG例: 出馬表の全レースを for ループで連続取得し、sleep もタイムアウトも入れない(相手サイトへの負荷・アクセス遮断のリスク)
OK例: JRAFetcher.fetchHTML — request.setTimeout(opts.timeout, ...) で待ち続けずに destroy() する
HorseDataExtractor)と外部 JSON(ImportData.importExtractedJSON)が、DB 投入前に必須項目・型・値域を確認されているかJSON.parse(...) の結果に付けた型注釈を検証済みの根拠にしていないか(ImportData.importExtractedJSON の const jsonData: ExtractedRaceData = JSON.parse(...) はコンパイル時の断言にすぎず、実行時は何も保証しない)Number / parseInt / parseFloat)に NaN・範囲の防御があるか。欠損が undefined に落ちる設計なら、その undefined が DB 制約と整合するかHorseDataExtractor.generateWarnings は馬名欠落とオッズ0のみ。新しい必須項目を足すならここも増やす)NG例(現状 — 既存債務): ImportData.importExtractedJSON が JSON.parse の結果を型注釈だけで信用し、jsonData.raceInfo / jsonData.horses の存在も型も確認せずトランザクションに入れる
OK例: src/index.ts の score コマンド — const raceId = parseInt(options.race, 10); if (isNaN(raceId)) { ... return; } と、外部入力を使う前に明示的に弾いている
新規・変更クエリは Kysely で組み立てる(src/database/QueryRunner.ts の queryBuilder)。
値はビルダーがバインドパラメータにするため、SQL 本文に値が混ざらない。
db.exec(...) に渡す SQL が静的文字列か(外部由来の値が混ざっていないか)pragma_table_xinfo(?) のようなテーブル値関数)が無いか検討したかNG例: テーブル名や値を SQL 本文に補間する(SELECT ... FROM ${table} / LIMIT ${limit})
OK例: JockeyQueryRepository — as-of の日付を .where('races.race_date', '<', beforeDate) で渡し、値は Kysely がバインドする
※ sql.raw( / sql.lit(・db.prepare 等への補間つきテンプレート・Kysely ビルダーの .execute() 系は
lint(error)が機械検出するため本項では見ない(一覧は review-code 2.1)。直接の prepare / exec / query
は移行途中のため warn。lint の通過確認は review-code 2.1。
.. や絶対パスを弾いているか)mkdirSync(..., { recursive: true }))が、検証していないパスに対して行われていないかDatabaseConnection の既定 ./arima.db)NG例(現状 — 既存債務): fetch-jra の -o/--output(src/index.ts)が検証なしで JRAFetcher.saveToFile の writeFileSync / mkdirSync まで届き、../ を含むパスや絶対パスもそのまま書き込める
OK例: src/commands/ExtractData.ts — 出力先を 'data/horse-extracted-data.json' の固定値にして、外部からパスを受け取らない
*.db / *.sqlite / data/extracted-*.json / data/horse-extracted-data.json / data/jra-page.html)が .gitignore に残っており、差分に混ざっていないか.gitignore も同時に更新しているか(無視パターンと実際の出力パスがズレると生成物がコミットされる).env を読み書きするコード・スクリプトを追加していないか(このリポジトリでは hook でブロックされる運用。確認は Read ツールで行う)NG例: 抽出 JSON の出力先を data/extracted-2025.json から output/race.json に変えたが .gitignore を更新せず、取得データがそのままコミットされる
OK例: .gitignore の data/extracted-*.json / data/horse-extracted-data.json / data/jra-page.html が、ExtractData と JRAFetcher.fetchAndSave の実際の既定出力パスと一致している
child_process / Bun.spawn を新たに導入していないか(eval() / new Function / 文字列を渡す setTimeout は lint(security/noGlobalEval・nursery/noImpliedEval = error)が落とすため本項では見ない。lint の通過確認は review-code 2.1)import() のパスが静的なリテラルのままか(外部入力・CLI 引数から組み立てていないか)NG例: 取り込み元の指定を await import(userSuppliedPath) で解決する(任意コード実行に直結する)
OK例: ImportData の await import('@/utils/HorseDataExtractor') のように、遅延読み込みでもパスは静的リテラル
.env の差分混入Summary: SKIPPEDeval / new Function / 文字列 setTimeout の非導入、sql.raw / sql.lit の不使用、SQL への補間つきテンプレートの不使用は lint(error)が担保するため本スキルでは見ない。lint の通過確認は review-code 2.1## セキュリティ レビュー結果
| # | チェック項目 | ステータス | 該当箇所 | 備考 |
| - | ------------ | ------------ | --------- | ---- |
### 詳細所見
### 推奨アクション
- HIGH / MEDIUM / LOW(該当が無い優先度は「なし」と明示)
レポート末尾に必ず以下の 1 行を出力する:
Summary: OK=<n> WARN=<n> FAIL=<n>
Summary: SKIPPEDNo 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.