measure-before-you-fix について
measure-before-you-fixは、古さ、遅延、タイムアウト、停止の疑いに関するアラートに対応する運用者向けエージェントスキルです。具体的な処理時間としきい値を確認してから構造変更を提案し、コードや設定は変更せず測定結果を示します。
主な機能
- 01疑わしい処理を個別に計測
- 02実測時間と予算の比較
- 03正式なしきい値の確認
- 04遅延と停止の判別
- 05読み取り専用の測定結果
活用シーン
- 01繰り返す鮮度アラートの調査
- 02ジョブが実際に停止したかの確認
- 03タイムアウト変更前の必要性評価
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ garrytan/ gbrain --skill measure-before-you-fixインストール後、Claude Code で/measure-before-you-fixを入力して読み込まれたか確認します。
同梱ファイルrouting-eval.jsonl
詳細
修正の前に測定する
規約: conventions/brain-first.md を参照してください。 診断をやり直す前に、同じアラートの過去の事例がないか、brain を
searchしてください。繰り返し発生するアラートには、すでに判定結果が 記録されていることがよくあります。
主張が時間に関するものであるアラート(「X が古い」「ステップがタイムアウトした」 「パイプラインが停止した」「ジョブが遅い」「N 時間遅れている」など)は、すべてここに 振り分けます。こうしたアラートは、タイムアウトの延長、ステップの分割、 パイプラインの並べ替えといった、すぐに構造を変更する修正を促します。まず測定してください。 測定のほうがほとんどの場合、修正よりも安上がりであり、修正が不要だと判明することも よくあります。(振り分けはハーネスの規約であり、機械的に保証されるものではありません。 以下の契約を守ることで、規約が定着します。)
gbrain の各サーフェスでは、これには gbrain doctor の鮮度チェック(同期の鮮度や
サイクルの鮮度など)、autopilot サイクルのアラート、同期停止のウォッチドッグ
(reason: 'stall_timeout')、およびそれらを基盤とするあらゆる cron モニターが含まれます。
ルール
コードを変更する前に、疑わしいステップをストップウォッチで一度測定してください。
遅いと主張する対象の所要時間を測定値で示せないなら、まだ根本原因は分かっていません。 その状態で書く修正は、diff をまとった推測にすぎません。
契約
このスキルでは、次を保証します。
- 問題があるとされたステップの所要時間を測定する前に、構造的な修正 (タイムアウトの延長、ステップの分割、パイプラインの並べ替え、ラッパーの 書き換え)が提案されることはありません。
- 測定対象は、アラートが指定した特定の対象です。集計対象
(
--allを指定すると、どのメンバーが遅いのか分からなくなります)は対象にしません。 - システムが正常でないと判断する前に、アラートのしきい値を権威あるしきい値
(
gbrain doctorの警告/失敗の値)と比較します。 - 判定では、「もっと時間が必要」と「停止している」を明確に区別します。 この2つに必要な修正は正反対です。
- 読み取り専用です。このスキルはタイムアウト、しきい値、コードを変更しません。 修正の規模を決めるための測定結果を出します。修正自体は、情報に基づいて 別途行います。
手順
-
アラートに記載された数値を確認します。 数値を見るだけで、すでに仮説と 食い違っていることがよくあります。 (
Locks: noneなら、ロック競合ではありません。その点を記録し、この可能性は除外します。) -
疑わしいステップを直接計測します。 アラートが問題としている最小単位を切り分け、 時計を使って実行します。
time gbrain sync --source source-a --no-embed集計対象ではなく、名前が指定された特定の対象で実行します。brain 全体の実行では どのメンバーが遅いのか分かりませんが、
--source source-aなら確認できます。gbrain sources statusで状態(ソースごとの同期遅延)を照合します。 -
実測値と予算値を比較します。 ヘルパーのシグネチャにあるデフォルト値だけでなく、 ラッパー内のタイムアウトをすべて grep します。
grep -n "timeoutMs\|timeout:" <the wrapper or cron script>呼び出しごとの上書き値が大きければ、ヘルパーのデフォルト値は関係ありません。 デフォルト値を原因とする前に、呼び出し箇所を確認してください。
-
アラートのしきい値を権威あるしきい値と照合します。 システムに問題があると 結論づける前に、アラートと監査で「異常」の定義が一致していることを確認します。
gbrain doctorの同期鮮度チェックは、デフォルトで警告が 24h、失敗が 72h です (GBRAIN_SYNC_FRESHNESS_WARN_HOURS/GBRAIN_SYNC_FRESHNESS_FAIL_HOURSで環境変数による上書きが可能です)。 12h でページングする cron モニターは、権威ある警告ラインより手前で通知しています。 早めに動作するモニターは適切ですが、動作ラインに達した時点で通知するモニターは 偽陽性を生み出します。 -
修正を設計するのはその後です。 実測した数値に基づいて設計してください。
しきい値の不一致による障害パターン
cron モニターが、ドクターの失敗判定より早く動作するのは、ドリフトが FAIL の領域に 入るのを防ぐためです。これは適切な設計です。問題は、動作しきい値をアラートのしきい値 にも使うことです。「動作」と「警告」の間にあるものがすべて、正常なシステムについての 繰り返しページングになります。
2つの定数を分けてください。 厳しいしきい値で動作し、権威あるしきい値で通知します。
const ACT_HOURS = Number(env.MONITOR_ACT_HOURS || 12); // act early — fine
const ALERT_HOURS = Math.max(ACT_HOURS, DOCTOR_WARN_HOURS); // speak at the audit's line
すぐに見抜くべき症状:ドクター自身の警告ラインより低い数値を示すアラートが繰り返し発生する一方で、 リソースを直接確認すると正常に見えることです。
理論を立てているだけで、診断していないことを示す危険信号
- 根本原因は特定できているのに、所要時間を測定していません。
- 修正内容が書き直しなのに、対象のステップを一度も実行していません。
- 新たな測定を挟まずに、仮説を2回修正しています。
- アラートに「復旧処理が実行中ではありません」と表示されています。これを信じる前に、実際に復旧処理が実行中か確認してください(ワーカーには
psを実行し、起動フラグを確認し、キューに入った作業にはgbrain jobs listを実行します)。 - ステップの出力に「すでに最新です」と表示されています。そのステップはボトルネックではありません。
失敗した場合
gbrain のエラー code、終了コード、[AGENT] ブロック、または通知ブロックがある場合は、エージェントオペレータープロトコルに従ってください。このスキルに固有の注意事項は次のとおりです。
gbrain doctorが警告または失敗を報告した場合:システムに問題があると判断する前に、該当するチェック項目としきい値を正確に記録してください。doctor の24時間/72時間の同期鮮度しきい値は、cron モニターのものと異なる場合があります。gbrain sources statusに保留中の項目やlock_busyが表示された場合:それが測定で確認された原因です。タイムアウトを延ばすのではなく、修正して再測定してください。
アンチパターン
- 停止を解決するためにタイムアウトを延ばす。 ステップが実際にハングしているなら、予算を増やしても、より長くハングするだけです。測定してから、「もっと時間が必要」なのか「処理が固まっている」のか判断してください。この2つに必要な修正は正反対です。(gbrain の同期停止ウォッチドッグも、経過時間ではなく進捗に基づいて判定するため、同じ区別を標準で行います。)
- 測定していないリソース枯渇の仮説に基づいてパイプラインを書き直す。 存在しないリソース枯渇を解消するためにステップを分割しても、複雑さが増すだけで、何も解決しません。
- アラートの因果関係の主張を信じる。 アラートは症状を正確に報告しますが、原因の報告は不正確です。古さを示す数値は事実ですが、添えられた理由は推測です。
- 測定していない根本原因をスキル化したり、記録として残したりする。 自信満々の誤診をプレイブックに組み込むのは、元のバグよりも悪い結果を招きます。
対処済みの既知の障害モード
- 鮮度アラートに対する三重の誤診。 cron モニターが、何時間も古いと報告された2つのソース(
source-a、source-b)について、繰り返しページ通知を送信しました。測定を行う前に、根本原因が3つ続けて断定され、ラッパーの書き直しが承認されました。測定結果は次のとおりです。time gbrain sync --source source-a --no-embedは1桁秒で完了し、「すでに最新です」と表示されました(source-bも同様)。さらに、gbrain sources statusでは、その朝の時点ですべてのソースが同期済みと表示されていました。すべての仮説が一度に崩れました。実際の原因は、モニターがgbrain doctorの信頼できる警告しきい値より数時間低い、アクションしきい値でアラートを出していたことでした。修正は2行(ALERT_HOURS = max(ACT_HOURS, WARN_HOURS))で済み、書き直しは不要でした。教訓:健全と測定されているシステムについてページ通知が繰り返される場合は、システム本体よりも、まずしきい値を疑ってください。 - 同じ確認で判明した、競合仮説に関する補足: 優先度を下げた(
niceを設定した)ステップで CPU 競合が起きているという懸念にも根拠がありませんでした。ホストに継続的な同時負荷がかかっている間も、そのステップは数秒で完了しました。競合の仮説にも、古さの仮説と同じようにストップウォッチによる測定が必要です。
出力形式
出力は測定結果の判定です(会話単位。このスキルは brain ページを書き込みません)。判定後にのみ、測定した数値に見合った修正を提案します。
## Measurement verdict
- Alert: <the alert text and which monitor emitted it>
- Claim: <the temporal claim, e.g. "source-a 14h stale">
- Measured: <exact command> → <duration> (<key output, e.g. "Already up to date">)
- Budgeted: <timeout constant + any call-site override, file:line>
- Thresholds: monitor act-line <X>h vs doctor warn-line <Y>h → <match | MISMATCH>
- Verdict: false page on healthy system | needs more time | wedged | genuine regression
- Fix: <the change, justified by the measured number — or "none; adjust the alert line">
重複の整理(明確な境界)
- GStack
investigate— コードのバグを体系的にデバッグします(「なぜ動かないのか」、500 エラー、誤った出力)。境界:investigateはコードの動作の根本原因を特定します。このスキルは、タイムアウトやしきい値に手を加える前に実行する、時間に関する運用アラート(古さ/タイムアウト/鮮度/停止状態)のための、まず測定するという判断基準です。ストップウォッチで実際の遅延や性能低下が確認された場合は、測定値を添えてinvestigateに引き継ぎます。 skills/maintain/SKILL.md— 脳の健全性チェックと修復(doctor、抽出、夢のサイクル)を実行します。境界:maintain は健全性チェックの結果を出力して対応します。このスキルは、予算やラッパーを変更する前に、チェックのいずれかから通知が届いたときの対応方法を定めます。- smoke-test(ホスト側) — 再起動後のバイナリの健全性チェックを自動修復付きで実行します。境界:smoke-test は「再起動後に稼働しているか」に答えます。このスキルは「遅い/古いという主張は本当なのか」に答えます。
skills/cron-scheduler/SKILL.md— モニターとジョブをスケジュールします。境界:cron-scheduler はモニターをいつ実行するかを決めます。このスキルは、しきい値に反映すべき、実行ラインとアラートラインのルールを定めます。skills/conventions/test-before-bulk.md— 変更をまとめて行う前に試験します。考え方は同じです(行動の前に証拠を得る)が、対象は異なります。この規約は一括書き込みを制御し、このスキルはタイムアウト/しきい値/パイプラインの変更を制御します。