Status: v1 Review cadence: On change Owner: Engineering / Governance Issue: #195 PBI-HI-001 Related: docs/ai/metrics-privacy.md, docs/ai/eval-baselines/2026-05-04-baseline.md
PlanGate workflow event を構造化 metrics として保存・集計可能にする。Hook violation / C-3 / V-1 / C-4 の最小集計から始め、後続の Eval expansion (#196) / Model Profile v2 (#197) / Keep Rate (#198) / Dynamic Context Engine (#199) の効果測定基盤として機能させる。
opt-in: 既存 workflow を壊さず、bin/plangate metrics を呼んだときのみ動く。
| ファイル | 役割 |
|---|---|
schemas/plangate-event.schema.json |
event の JSON Schema |
scripts/metrics_collector.py |
TASK ディレクトリから event を導出して NDJSON へ append |
scripts/metrics_reporter.py |
events.ndjson から TASK 別 / aggregate summary を生成 |
bin/plangate metrics |
上記のラッパ CLI |
docs/working/_metrics/events.ndjson |
append-only metrics log(.gitignore 対象、commit 禁止) |
bin/plangate metrics TASK-0061 --collect
実行内容: docs/working/TASK-0061/ の以下ファイル群を読み、event を抽出して docs/working/_metrics/events.ndjson に append する。
| 対象ファイル / ソース | 導出 event |
|---|---|
pbi-input.md |
task_initialized |
plan.md |
plan_generated (plan_hash 含む、mode 自動検出) |
approvals/c3.json |
c3_decided (verdict: APPROVED/CONDITIONAL/REJECTED) |
evidence/ |
exec_started (最初の evidence 作成時刻) |
handoff.md |
v1_completed (AC PASS/FAIL カウント) + handoff_completed |
review-external.md |
external_review_completed |
docs/working/_audit/hook-events.log |
hook_violation (v8.6.0 PR3、A-1: VIOLATION/WARNING を自動変換、PASS/BYPASS は emit せず、message column は privacy §4 のため emit せず) |
git log on handoff.md |
pr_created (v8.6.0 PR3、A-2: squash-merge subject 末尾の (#NN) から PR 番号抽出、pr_number のみ emit) |
dry-run で append 前に内容確認:
bin/plangate metrics TASK-0061 --collect --dry-run
# TASK 単位
bin/plangate metrics TASK-0061 --report
# 全 TASK 集約
bin/plangate metrics --report --aggregate
# JSON 出力(baseline 比較用)
bin/plangate metrics TASK-0061 --report --json
bin/plangate metrics --collect 実行時、docs/working/_audit/hook-events.log を自動的に読み込み、対象 TASK の VIOLATION / WARNING ログを hook_violation event に変換して emit する。
| audit log level | hook_result |
|---|---|
VIOLATION / BLOCK |
block |
WARNING / WARN |
warn |
PASS / BYPASS |
emit しない(success / bypass はノイズ) |
hook script 名は schema 準拠の hook_id に変換される(例: check-c3-approval → EH-2、check-merge-approvals → EH-7、check-metrics-privacy → EH-8)。audit log の message 列は metrics-privacy.md §4 違反を避けるため emit しない。
手動 append が必要な場合は schema 準拠 NDJSON を >> で追記可能:
echo '{"schema_version":"1.0","ts":"2026-05-04T07:00:00Z","task_id":"TASK-0061","event":"hook_violation","hook_id":"EH-1","hook_result":"block"}' \
>> docs/working/_metrics/events.ndjson
handoff.md をタッチした最新 git commit を対象に、subject 末尾の (#NN) パターン(squash-merge convention)から PR 番号を抽出し、pr_created event を emit する。pr_number のみ記録され、commit ハッシュ・ブランチ名・著者・本文は emit しない(privacy §4 準拠)。
git が無い / commit が見つからない場合は silent に skip。
bin/plangate metrics --report --aggregate または --report --json の出力に By mode セクション / by_mode フィールドが追加される。
mode を解決して、各 mode の C-3 / V-1 / C-4 verdict と hook violation を別々に集計出力例(aggregate text):
### 3.6 整合性検証(v8.6.0 PR5 / H-1)
`bin/plangate metrics --validate` で `events.ndjson` 全行を `plangate-event.schema.json` で validate。違反は line:reason 形式で最大 20 件報告、exit 1。jsonschema 未導入時は SKIP(exit 0)。
### 3.7 機械可読化と時刻フィルタ(v8.6.0 PR7)
#### K-1: `--markdown-section`(handoff §7 用)
```bash
bin/plangate metrics TASK-XXXX --report --markdown-section
handoff template §7 に直接貼り付けられる markdown 表(events / modes / C-3 / V-1 / C-4 / hook violations / fix_loop_max + by_mode 表 + privacy 注記)を出力する。
--since <date>bin/plangate metrics --report --aggregate --since 2026-05-04
bin/plangate metrics --report --aggregate --since 2026-05-04T12:00:00Z
ts >= 指定 ISO 日時の event のみで集計する。YYYY-MM-DD 略記時は T00:00:00Z 補完。改善前後の比較や週次レポートに利用。
bin/plangate doctor --jsonbin/plangate doctor --json
# {
# "scope": "v8.6.0 Metrics & Privacy",
# "checks": [...16 件...],
# "failures": 0,
# "warnings": 0,
# "passed": true
# }
CI 統合用。v8.6.0 metrics & privacy セクション 16 check の結果を JSON で返す。failures > 0 で exit 1。
ツール失敗は tool_error event(schema 1.1 additive)として記録する。
category は tool-error-taxonomy.md §2 の enum
(tool_error_category)。Privacy(metrics-privacy.md
§4)に従い message / stack trace / command output は emit しない
(tool_error_category と tool_name / phase のみ)。unknown_tool_error
は harness improvement backlog 還流の入力(taxonomy §6)。
echo '{"schema_version":"1.1","ts":"2026-05-17T00:00:00Z","task_id":"TASK-XXXX","event":"tool_error","tool_error_category":"edit_patch_failure","tool_name":"Edit","phase":"D"}' \
>> "$EVENTS_LOG"
metrics-privacy.md 準拠。metrics_collector.py は §3 (Allowed) のフィールドのみ emit する。
| 保存される | 例 |
|---|---|
| event 種別、phase、mode | task_initialized, B, light |
| TASK ID | TASK-0061 |
| plan_hash | sha256:... (内容そのものは保存しない) |
| AC count | ac_total: 6, ac_pass: 6, ac_fail: 0 |
| verdict | APPROVED, PASS, FAIL, WARN |
| timestamp | UTC ISO 8601 |
| 保存されない | 理由 |
|---|---|
| ファイルパス、ファイル名 | privacy §4 Forbidden |
| stack trace、command output | 同上 |
| user prompt、handoff 本文 | 同上 |
| provider raw response | 同上 |
docs/working/_metrics/events.ndjson は .gitignore で除外。commit されない。
python3 -c "import json,jsonschema,sys; \
schema=json.load(open('schemas/plangate-event.schema.json')); \
events=[json.loads(l) for l in open('docs/working/_metrics/events.ndjson') if l.strip()]; \
[jsonschema.validate(e,schema) for e in events]; \
print(f'{len(events)} events valid')"
docs/ai/eval-baselines/2026-05-04-baseline.json と互換のフィールド命名:
| baseline.json | metrics summary |
|---|---|
tasks[].ac_coverage_pct |
summary.v1 から算出 (PASS/FAIL/WARN ratio) |
tasks[].approval_discipline |
summary.c3 の APPROVED 有無 |
aggregate.release_blocker_total |
hook_violations.total + c3 REJECTED + v1 FAIL |
baseline と metrics summary を組み合わせると、改善前後の差分が機械比較可能。
| Roadmap | metrics v1 への接続 |
|---|---|
| #196 Eval expansion | summary.v1 / summary.hook_violations を mode 別に判定 |
| #197 Model Profile v2 | event に model_profile 追加で profile 別比較 |
| #198 Keep Rate v1 | plan_hash 履歴と handoff 後の差分で算出 |
| #199 Dynamic Context | task_initialized 時に context manifest 識別子を記録 |
experimental: debug / audit 用途限定。quickstart / README には掲載しない。 自己進化機能を OSS 利用者に押し付けない方針(v8.7.0)。
events.ndjson は schema_version 1.0(baseline)に加え 1.1(additive)を
受理する。1.1 で追加される optional top-level field:
gate_id(Gate event 識別子。語彙正規化は #230 v8.8.0)parent_event_id(因果リンク)phase(1.0: A..C-4 / 1.1 additive: WF-01..WF-06, handoff)additionalProperties: false と Metrics Privacy Policy(#202)は維持。
1.0 event は 1.1 schema でも後方互換で valid。
# experimental: phase / gate / ts 順に正規化した timeline JSON
bin/plangate metrics TASK-XXXX --timeline --json
出力は {task_id, schema_version:"1.1", experimental:true, count, timeline[]}。
Run Outcome Review v1(#228)の補助・Dogfooding Eval v1(#231 v8.8.0)の入力。