実レビュー由来のソースコード改修実例

ソースコード改修実例

このページは、AIミスパターンの総合説明ではなく、実際のコードレビュー、 レーンレビュー、統合レビューを通じて改修したソースコード例だけを切り出した確認面。 「何がまずかったか」を先に読み、再発防止先を後で確認する。

ソースコード改修実例の絞り込み

表示対象

全18件中11件を表示中(表示対象: 実業務PRコードレビュー)

18 掲載した改修実例
6 主な問題領域
0 一般論だけの項目
1 総合ビューと分離

dbt / KPI 契約の改修実例

dbtの構文解析やコンパイルでは見えにくい、スキーマ/汎用テスト、シード契約、過去の個別SQLテスト案の証跡境界を中心に見る。

F-01

率KPIの危険な再集計を固定する個別SQLテスト案が現候補に残っていなかった

契約不一致
問題種別 契約不一致 構成図ノード dbtテスト / KPI定義 発生ファイル 過去レビュー証跡: dbt/tests/singular/kpi_definitions_reaggregation_contract.sql案 / 現候補: dbt/tests/singular/未配置
レビュー指摘

gross_margin_rate の分子分母再計算やカテゴリ率平均禁止を固定する個別SQLテスト案が過去レビューで出たが、この候補作業ツリーには実体ファイルがない。

影響

スキーマ/汎用テストがあっても、後段のセマンティック/評価が率KPIの誤集計を許す可能性は残る。

検知証跡

FB-077、FB-085の過去レビュー文脈と、現候補で dbt/tests/singular/ が存在しないことの棚卸し。

再発防止

過去レビューのテスト案を現物証跡として扱わず、実体化するまで将来テスト候補として表示する。

問題のある証跡扱い

HTML / 現候補の証跡不一致: docs/project-management/code-review-findings.html
<span class="tag-chip file">
  dbt/tests/singular/kpi_definitions_reaggregation_contract.sql
</span>

修正後の証跡扱い

HTML / 証跡境界: docs/project-management/code-review-findings.html
過去レビュー証跡:
  dbt/tests/singular/kpi_definitions_reaggregation_contract.sql案
現候補:
  dbt/tests/singular/未配置

修正方針: 率KPIは「値が存在する」だけでなく、上位粒度で平均してはいけないという再集計ルールまでdbt契約に固定する。ただし実体ファイルがない間は、現物証跡ではなく将来テスト候補として扱う。

F-02

KPI再集計契約が説明文に寄りすぎ、テストで守る粒度が不足していた

契約不一致
問題種別 契約不一致 構成図ノード KPI定義 / セマンティックKPIモデル 発生ファイル dbt/seeds/kpi_definitions.csv
レビュー指摘

カテゴリ率の平均禁止や分子分母再計算の警告が、シード文言とテスト契約候補の両方で十分に固定されていなかった。

影響

セマンティックモデルやゴールデン評価が、率KPIを誤集計してもレビューで通してしまう恐れがある。

検知証跡

FB-085、INV-20260630-003。レーンAレビューでKPI契約の弱さを検出。

再発防止

重要KPIは説明文、シード契約、スキーマ/汎用テスト、将来の個別SQLテストを同じ警告粒度で揃える。

問題のあるコード抜粋

CSV / dbt seed: dbt/seeds/kpi_definitions.csv
gross_margin_rate,Gross margin divided by net sales,Uses TPCH partsupp supply cost as a cost proxy and recomputes from additive numerator and denominator,true,AI architecture MVP,usable_proxy,Supply cost is not a retail cost accounting model

修正後コード抜粋

CSV / dbt seed: dbt/seeds/kpi_definitions.csv
gross_margin_rate,Gross margin divided by net sales,Uses TPCH partsupp supply cost as a cost proxy and recomputes from additive numerator and denominator rather than averaging category rates,true,AI architecture MVP,usable_proxy,Supply cost is not a retail cost accounting model

修正方針: シードをLLM/セマンティック/評価が共有する契約面として扱い、計算式だけでなく禁止したい誤用まで自然文で明示する。

F-03

レーンAのdbt範囲が曖昧で、ゴールデン評価やSnowpark判断まで触れそうだった

スコープ境界
問題種別 スコープ境界 構成図ノード dbtテスト / ゴールデン評価 / Snowpark実行層 発生ファイル docs/project-management/parallel-session-task-split-20260630.md 文面所在 レーンAブリーフ / dbt実装範囲
レビュー指摘

dbt実装者のブリーフで、シードテスト、ゴールデン評価追加、準備度更新、Snowpark将来対応の境界が暗黙だった。

影響

実装者レーンがアーキテクト判断まで進め、mainセッションの設計統制が弱くなる。

検知証跡

FB-082。委任前レビューで実装範囲と提案だけの範囲を分離。

再発防止

実装者ブリーフは「編集してよいもの」と「提案だけにするもの」を明記する。

問題のある記述抜粋

Markdown / レーンAブリーフ: docs/project-management/parallel-session-task-split-20260630.md
- `order_count`、`gross_margin_rate`、`avg_discount` の再集計危険を
  dbt個別SQLテストで見る範囲と後段ゴールデン評価へ提案する範囲に分ける
- 現在のシード行と個別SQLテスト期待値が一致しているか確認する

修正後記述抜粋

Markdown / レーンAブリーフ: docs/project-management/parallel-session-task-split-20260630.md
- ゴールデン評価追加、セマンティック準備度更新、構成図tooltip/準備度更新、
  Backlog本文更新、Obsidian同期は mainセッション への提案だけ返す
- `RAIOPS-4` ではSnowpark実装をしない
- Snowparkを意識した観点では、`llm_contract`、`semantic_input`、`eval_input`、
  将来のトレース接続を壊さないことだけ確認する

修正方針: 実装者に考えてよい余地を残しつつ、構成判断、準備度更新、Backlog/Obsidian同期はmainへ戻す境界を明文化する。

F-09

dbt実装開始後も構成図のdbt進捗が0%のままだった

進捗率過小評価
問題種別 進捗率過小評価 構成図ノード dbtステージング / dbtマート / dbtテスト 発生ファイル docs/architecture/retail-ai-ops-copilot-architecture.html / dbt/models/** / dbt/tests/**
レビュー指摘

ステージングSQLモデル、中間モデル、マートモデル、スキーマテスト、汎用テストが存在するのに、構成図のdbt系ノードが0%の未実装表示に残っていた。

影響

実装済みのレビュー対象が公開面から見えず、逆に未実施の実環境dbtビルド/テストやSnowflake実行との境界も曖昧になる。

検知証跡

DISPATCH_L6_PUBLIC_SURFACE_RECALIBRATE_DBT_PROGRESS_20260702_002。対象作業ツリーの dbt/models/**dbt/tests/generic/** を棚卸し。

再発防止

進捗更新時は実ファイル棚卸しを先に行い、ソース実装あり・実環境未証明をツールチップで分離して低率に補正する。

問題のあるHTML抜粋

HTML / 構成図ノード属性: docs/architecture/retail-ai-ops-copilot-architecture.html
<div class="service small orange" data-progress="0%" data-status="dbt stagingは未実装">
<div class="service small orange" data-progress="0%" data-status="dbt martsは未実装">
<div class="service small orange" data-progress="0%" data-status="dbt testsは未実装">

修正後HTML抜粋

HTML / 構成図ノード属性: docs/architecture/retail-ai-ops-copilot-architecture.html
data-progress="25%" data-status="実装証跡あり: stg_tpch_* SQL model 7本..."
data-progress="25%" data-status="実装証跡あり: int_order_line_enrichedとmart_retail_monthly_kpi..."
data-progress="20%" data-status="実装証跡あり: staging/intermediate/mart schema.yml..."
data-note="live dbt build/test、Snowflake実行、SQL結果正当性、answer-quality証跡は未実施。"

修正方針: dbtステージング/マート/テストは0%から低率へ上げる。ツールチップでは実装証跡ありと未実施証跡を分ける。ただし、この候補作業ツリーでは dbt/tests/singular/dbt/target/ 生成物は見つからないため、実環境dbtビルド/テスト、Snowflake実行、SQL結果正当性、回答品質証跡は未実施として扱う。

F-10

率KPIの保存済み率を平均/合計する負例テストがまだ不足している

将来テスト候補
問題種別 レビュワー指摘 / 将来テスト候補 構成図ノード セマンティックKPIモデル / dbtテスト 発生ファイル semantic/retail_kpi_semantic_model.yaml / tests/**
レビュー指摘

gross_margin_rateavg_discount はマートで分子分母から再計算しているが、セマンティックモデルや生成SQLが保存済み率を avg() / sum() しないことを壊す負例テストがまだない。

影響

構造化SQLやセマンティックYAMLの変更で率KPIの誤集計が混入しても、現行のプランナー/トレーステストだけでは検出できない可能性がある。

検知証跡

L3レビュー指摘。semantic/retail_kpi_semantic_model.yaml の率KPI定義と tests/test_planner_and_trace.py の現行assertを確認。

再発防止

次のテストパターン更新で、保存済み率の平均/合計を禁止する負例変異テストを追加候補として扱う。

不足が残る定義・テスト抜粋

YAML + pytest: semantic/retail_kpi_semantic_model.yaml / tests/test_planner_and_trace.py
- name: gross_margin_rate
  expr: gross_margin_rate
  default_aggregation: avg
- name: avg_discount
  expr: avg_discount
  default_aggregation: avg

assert plan.metric == "gross_margin_rate"
assert "MART_RETAIL_MONTHLY_KPI" in (plan.sql or "")

追加候補の負例テスト抜粋

pytest / 将来の負例変異候補: tests/**
sql = (plan.sql or "").lower()

assert "avg(gross_margin_rate)" not in sql
assert "sum(gross_margin_rate)" not in sql
assert "avg(avg_discount)" not in sql
assert "sum(avg_discount)" not in sql

修正方針: 重大指摘ではなく将来テスト候補として保持する。セマンティックKPIモデルが保存済み率をそのまま平均・合計しないことを、負例変異で壊れた時に失敗させる。

ゴールデン評価 / ルーティング / トレースの改修実例

ローカル静的評価、実環境トレース準備、失敗時の記録で証明できることと、既知ギャップとして残すことを分けて見る。

F-11

ローカル静的評価の成功と既知ギャップを分けて表示した

評価境界
問題種別 評価境界 構成図ノード ゴールデン評価 / エージェントルーター / トレース保存 / セマンティックKPIモデル 発生ファイル data/golden_eval.json / retail_ai_ops/eval_runner.py / tests/test_planner_and_trace.py / semantic/retail_kpi_semantic_model.yaml 文面所在 統合候補 b8321eb = L5 9f0924c + L2/L4 6d7fb0b
レビュー指摘

レビューでは重大指摘なしだったが、total=26を品質合格数として読まないよう注意した。16件の品質通過と10件の既知ギャップを分ける必要がある。

影響

既知ギャップ許容モードの failed=0 だけを強調すると、Cortex Search文書根拠、未対応KPIの安全停止改善、外部経路品質まで済んだように見える。

検知証跡

統合候補 b8321ebpytest -q は43件成功、セマンティック契約は SEMANTIC_CONTRACT_OK、評価ランナーはローカル静的フィクスチャとして再実行済み。

再発防止

quality_passed=16known_gaps_observed=10unexpected_failures=0、allow-known-gapsの failed=0、strict-known-gapsの failed=10 をセットで表示する。

誤読しやすい表示抜粋

評価サマリー / 公開文言不足
total=26
failed=0

公開面に出す検証内訳

評価サマリー / ローカル静的の統合候補検証
quality_passed=16
known_gaps_observed=10
unexpected_failures=0
failed=0 under allow-known-gaps
failed=10 under strict-known-gaps
total=26
evaluation_mode=local_static_fixture
live_external_executed=false

修正方針: b8321eb はローカル静的の統合候補検証として表示する。ゴールデン評価、ルーティング、セマンティック契約のローカル静的候補証跡は進捗へ反映するが、Snowflake実行、Cortex実呼び出し、Pages公開、プッシュ済みの証跡としては扱わない。

F-17

request_textに生成SQLを入れると、ユーザー入力と実行SQLの監査境界が崩れる

トレース本文混入
問題種別 レビュワー指摘 / トレース本文混入 構成図ノード トレースロガー / ツールアダプタ / ゴールデン評価 発生ファイル retail_ai_ops/live_trace.py / retail_ai_ops/trace.py / tests/test_live_trace_runner.py / tests/test_planner_and_trace.py レビュー所在 RAIOPS-7 report / INV-20260702-032 / DISPATCH_L2_FIX_RAIOPS7_TRACE_REQUEST_TEXT_20260702_037
レビュー指摘

生成SQLを request_text に入れると、ユーザーが実際に依頼した文、実行候補SQL、前提不足チェック文が同じ意味に見えてしまう。

影響

トレース監査、ゴールデン評価、実環境失敗分析で「ユーザーが何を聞いたか」と「システムが何を実行しようとしたか」を分けて確認できない。

検知証跡

RAIOPS-7 L2修正で、明示ローカルトレースの構造化KPI行は request_text が元の質問と一致し、生成SQLとは一致しないことを確認。missing-prerequisite行もSQLなしの前提確認文として残した。

再発防止

トレースでは question / request_text / sql を別フィールドにし、SQLを含む行でも request_text は元の質問として固定する。

問題のあるトレース形

JSON / 修正前に起きうるトレース混入: .local-private/traces/*.jsonl
{
  "question": "日本の売上を月次で見て",
  "request_text": "select month_start, net_sales from MART_RETAIL_MONTHLY_KPI ...",
  "sql": "select month_start, net_sales from MART_RETAIL_MONTHLY_KPI ..."
}

修正後トレース形

JSON / RAIOPS-7 request_text分離: docs/project-management/raiops7-live-trace-report.md
{
  "question": "日本の売上を月次で見て",
  "request_text": "日本の売上を月次で見て",
  "request_text_equals_question": true,
  "request_text_equals_sql": false,
  "sql_prefix": "select"
}

修正方向: request_text は利用者または明示的なシステム前提確認の文として残し、生成SQLは sql だけに入れる。これにより、実環境トレースを始める前から監査本文と実行候補を分けられる。

F-18

実環境クエリ失敗の生例外を回答やトレースに残すと秘密情報が漏れる

ライブエラー墨消し漏れ
問題種別 レビュワー指摘 / 実環境エラー墨消し 構成図ノード ツールアダプタ / トレースロガー / エラー分類 発生ファイル retail_ai_ops/live_trace.py / tests/test_live_trace_runner.py レビュー所在 RAIOPS-7 report / INV-20260702-032 / DISPATCH_L2_FIX_RAIOPS7_LIVE_ERROR_REDACTION_20260702_039
レビュー指摘

Snowflake実行に進んだ後の例外をそのまま error_messageanswerfinal_answer へ書くと、秘密情報らしい文字列や接続内部情報が公開面や後続証跡へ残りうる。

影響

実環境失敗を安全にレビューできず、ユーザー向け回答、トレース保存、公開レポートのどこに秘密情報が混ざったか追いにくくなる。

検知証跡

RAIOPS-7 L2修正後の疑似実環境失敗では、実行試行は記録するが成功扱いにせず、秘密情報形の文字列は error_messageanswerfinal_answer に残らないことを確認した。

再発防止

ライブクエリ失敗は分類と試行有無だけを残し、生例外本文は公開/トレース用メッセージへ変換する。実環境成功とは別の失敗証跡として扱う。

問題のある方向性

Python / 生例外をそのまま証跡化する危険パターン: retail_ai_ops/live_trace.py
except Exception as exc:
    logger.append_event(build_failure_trace_event(
        error_category=category,
        error_message=str(exc),
        live_external_attempted=live_attempted,
        live_external_executed=False,
    ))

修正後コード抜粋

Python / ライブ失敗の公開用メッセージ化: retail_ai_ops/live_trace.py
public_error_message = sanitize_error_message(category, str(exc))
logger.append_event(
    build_failure_trace_event(
        error_category=category,
        error_message=public_error_message,
        live_external_attempted=live_attempted,
        live_external_executed=False,
        plan=plan,
    )
)

def sanitize_error_message(error_category: str, error_message: str) -> str:
    if error_category == "live_query_failed":
        return LIVE_QUERY_REDACTED_MESSAGE
    return SECRET_ASSIGNMENT_PATTERN.sub(r"\1=<redacted>", error_message)

修正方向: 失敗分類、実行試行、ローカル代替なしは残すが、生例外は回答やトレースへ渡さない。これにより、実環境前の疑似失敗テストでも秘密情報を出さない境界を確認できる。

F-12

Snowpark失敗時に、後から読めるJSON証跡が残っていなかった

失敗証跡境界
問題種別 失敗証跡境界 構成図ノード Snowpark実行層 / 評価トレース補強 / トレース保存 発生ファイル tools/run_snowpark_enrichment.py / tests/test_snowpark_enrichment.py / retail_ai_ops/snowpark_enrichment.py レビュー所在 James パターン認識レビュー、修正コミット 6eb57f7
レビュー指摘

Snowpark実行が失敗した時は、非0終了だけでは足りない。前提不足、入力欠落、不正JSONL、一般CLI失敗でも、後続処理が読める失敗JSONをできるだけ残す必要があった。

影響

画面やログのエラー文だけだと、ゴールデン評価、トレース保存、公開面が失敗分類、疑わしい層、local_fallback_used=falsesnowpark_live_proof=false を機械的に確認できず、ローカルフィクスチャ成功との境界が曖昧になる。

検知証跡

RAIOPS-12実装コミット 1471323 / ea7ac07 後のJamesレビューで検出。修正コミット 6eb57f7 後はJamesの重大指摘なし、Harveyの合格判定、対象pytest 9 passed、全体pytest 83 passed, 2 skipped

修正方向

CLI例外時に build_cli_failure_summary を作り、出力パスへ失敗証跡を書く。成功/失敗の共通キー、失敗分類/疑わしい層のペア、暗黙フォールバックなし、実環境未証明フラグをテストで固定する。

問題のあるコード抜粋

Python / CLI失敗経路: tools/run_snowpark_enrichment.py
except Exception as exc:
    print(f"RAIOPS-12 enrichment failed: {exc}", file=sys.stderr)
    return 1

修正後コード抜粋

Python / CLI失敗証跡: tools/run_snowpark_enrichment.py
except Exception as exc:
    failure_bucket, suspected_layer = classify_cli_failure(exc)
    summary = build_cli_failure_summary(
        source,
        runtime_mode=args.runtime_mode,
        failure_bucket=failure_bucket,
        suspected_layer=suspected_layer,
        message=str(exc),
    )
    write_summary(args.output, summary)
    print(json.dumps(summary, ensure_ascii=False, indent=2))
    print(f"RAIOPS-12 enrichment failed: {exc}", file=sys.stderr)
    return 1

修正方針: 実行失敗は「落ちた」だけでなく「どの層で、どの分類で、ローカル代替なしに、実環境成功未証明として落ちたか」をJSON契約で残す。これはローカル契約/負例境界の証跡であり、実環境Snowpark成功の証明ではない。

RBAC / コストガードレールの改修実例

RAIOPS-13でレビュー検出された、LLM安全境界、生データ/個人情報フィールド拒否、Snowflakeクライアント設定、トレースメタデータ整合の修正を分けて見る。

F-13

LLM安全フィールドの上書きで生データ/個人情報フィールドを計画とトレースへ混入できた

LLM安全境界
問題種別 レビュワー指摘 / LLM安全境界 構成図ノード RBAC / エージェントルーター / プランナー / トレースロガー 発生ファイル retail_ai_ops/config.py / retail_ai_ops/models.py / tests/test_planner_and_trace.py レビュー所在 FB-092 / INV-20260702-044 / RAIOPS-13 report F2
レビュー指摘

RETAIL_AI_OPS_LLM_SAFE_FIELDS が任意CSVを受けるだけだと、customer_idemailQuestionPlan.llm_safe_fields とトレースメタデータへ安全フィールドとして残る。

影響

SQL投影が固定でも、公開説明やトレース監査では生データ/個人情報フィールドがLLM安全に見えるため、RBACとデータ最小化の説明責任が崩れる。

検知証跡

RAIOPS-13のパターン認識レビューで高重大度指摘。修正後は Settings(llm_safe_fields=("month_start", unsafe_field)) と環境変数上書き負例が ValueError を確認。

再発防止

許可リスト上書きは正規サブセットだけ許可し、生データ/個人情報ヒントまたは未知フィールドは設定生成時点で安全側停止にする。

問題コード抜粋

Python / レビューで検出した危険パターン: retail_ai_ops/config.py
llm_safe_fields=_csv_tuple("RETAIL_AI_OPS_LLM_SAFE_FIELDS", LLM_SAFE_FIELDS)

def _csv_tuple(name: str, default: tuple[str, ...]) -> tuple[str, ...]:
    raw = os.environ.get(name)
    if raw is None or raw.strip() == "":
        return default
    return tuple(value.strip() for value in raw.split(",") if value.strip())

修正コード抜粋

Python / 安全側停止検証器: retail_ai_ops/config.py
def validate_llm_safe_fields(fields: tuple[str, ...]) -> tuple[str, ...]:
    normalized = tuple(dict.fromkeys(field.strip() for field in fields if field.strip()))
    canonical = set(LLM_SAFE_FIELDS)
    raw_or_personal = set(RAW_OR_PERSONAL_FIELD_HINTS)
    unsafe = sorted(set(normalized) & raw_or_personal)
    unsupported = sorted(set(normalized) - canonical)
    if unsafe or unsupported:
        raise ValueError(
            "llm_safe_fields must be a subset of canonical LLM_SAFE_FIELDS; "
            f"unsafe={unsafe}; unsupported={unsupported}"
        )

修正方向: 環境変数/直接上書きを禁止するのではなく、正規のLLM安全サブセットとして検証する。生データ/個人情報ヒントと未知フィールドは計画やトレースへ到達させない。

F-14

生データ/個人情報フィールドヒントが機微情報判定へ入らず安全停止をすり抜けた

生データ/個人情報拒否漏れ
問題種別 レビュワー指摘 / 生データ・個人情報検出漏れ 構成図ノード エージェントルーター / プランナー / RBAC / トレースロガー 発生ファイル retail_ai_ops/planner.py / retail_ai_ops/models.py / tests/test_planner_and_trace.py レビュー所在 FB-091 / INV-20260702-044 / RAIOPS-13 report F1
レビュー指摘

customer_idemailraw_order_row などを危険フィールドとして定義しても、プランナーの SENSITIVE_OR_RAW_KEYWORDS に入らないと sensitive_or_raw_data_request で止まらない。

影響

生データ/個人情報要求が曖昧質問や通常ルーティングへ流れ、トレース墨消しや人間レビュー候補の前提が過大主張になる。

検知証跡

RAIOPS-13のパターン認識レビューで高重大度指摘。修正後は全フィールドヒントの負例pytestと代表ヒントのトレース墨消しpytestを追加。

再発防止

拒否リストと許可リストを別々に増やさず、生データ/個人情報フィールドヒントはルーター/プランナー拒否判定とトレース墨消しテストへ同時に接続する。

問題コード抜粋

Python / 修正前キーワード集合: retail_ai_ops/planner.py
SENSITIVE_OR_RAW_KEYWORDS = (
    "顧客個人",
    "メールアドレス",
    "個票",
    "個人情報",
    "生データ",
    "明細",
    "raw row",
    "raw data",
    "pii",
)

修正コード抜粋

Python / 生データ・個人情報ヒントをルーティングへ接続: retail_ai_ops/planner.py
from .models import RAW_OR_PERSONAL_FIELD_HINTS

SENSITIVE_OR_RAW_KEYWORDS = (
    "顧客個人",
    "顧客名",
    "メールアドレス",
    "raw rows",
    "personal data",
    "personally identifiable",
    *RAW_OR_PERSONAL_FIELD_HINTS,
)

修正方向: フィールド名そのものをユーザーが聞いた場合もsafe_refusalへ送る。墨消し済みトレースでは questionrequest_text の両方を [redacted_sensitive_or_raw_request] にする。

F-15

クエリタグとタイムアウトを定義してもSnowflakeクライアントセッションへ適用していなかった

Snowflakeクライアント設定漏れ
問題種別 レビュワー指摘 / コストガードレール適用漏れ 構成図ノード ツールアダプタ / コストガードレール / トレース保存 発生ファイル retail_ai_ops/clients.py / retail_ai_ops/config.py / tests/test_planner_and_trace.py レビュー所在 FB-093 / INV-20260702-044 / RAIOPS-13 report F3
レビュー指摘

query_tagquery_timeout_seconds を設定、トレース、セットアップSQLに書いても、SnowflakeKpiClient のコネクタセッションへ渡さなければアプリクエリのコスト境界としては証明できない。

影響

ウェアハウス履歴とトレースを相関できず、長時間クエリをセッション側で止める基本前提もローカル契約上は抜ける。

検知証跡

RAIOPS-13レビューで中高重大度指摘。修正後は疑似コネクタテストで session_parameters を検査。実環境実行は未実施。

再発防止

コストメタデータはトレースだけでなく、クライアントアダプタの呼び出し引数にも負例/スパイテストを置く。

問題コード抜粋

Python / 修正前Snowflake接続呼び出し: retail_ai_ops/clients.py
conn = snowflake.connector.connect(
    account=self.settings.snowflake_account,
    user=self.settings.snowflake_user,
    password=os.environ.get("SNOWFLAKE_PASSWORD", ""),
    role=self.settings.snowflake_role,
    warehouse=self.settings.snowflake_warehouse,
    database=self.settings.snowflake_database,
    schema=self.settings.snowflake_schema,
)

修正コード抜粋

Python / セッションパラメータ適用: retail_ai_ops/clients.py
conn = snowflake.connector.connect(
    account=self.settings.snowflake_account,
    user=self.settings.snowflake_user,
    password=os.environ.get("SNOWFLAKE_PASSWORD", ""),
    role=self.settings.snowflake_role,
    warehouse=self.settings.snowflake_warehouse,
    database=self.settings.snowflake_database,
    schema=self.settings.snowflake_schema,
    session_parameters={
        "QUERY_TAG": self.settings.query_tag,
        "STATEMENT_TIMEOUT_IN_SECONDS": self.settings.query_timeout_seconds,
    },
)

修正方向: 疑似コネクタで引数を固定し、実環境Snowflake成功とは分ける。リソースモニター作成、ウェアハウス履歴確認、実クエリ停止は別レーンの実環境証跡にする。

F-16

メタデータなしTraceLoggerでSQL上限とトレースガードレール値がずれうる

トレースメタデータ不整合
問題種別 レビュワー指摘 / トレースメタデータ整合 構成図ノード トレースロガー / トレース保存 / コストガードレール / プランナー 発生ファイル retail_ai_ops/copilot.py / retail_ai_ops/trace.py / tests/test_planner_and_trace.py レビュー所在 INV-20260702-046 / INV-20260702-047 / RAIOPS-13 Trace Metadata Repair Follow-up
レビュー指摘

Settings(max_result_rows=7) でSQLは limit 7 になる一方、メタデータなし TraceLogger(settings.trace_path) ではトレースが既定のガードレール値を記録しうる。

影響

クエリ上限、タイムアウト、クエリタグ、ロール、LLM安全フィールドの監査値が実行設定とずれ、コスト/RBACガードレールの回帰証跡として信用できない。

検知証跡

Mill再レビューでトレースメタデータ不整合の修正を確認。Parfit/Sartreの契約フローE2Eは、メタデータなしTraceLoggerの設定整合を合格判定。

再発防止

通常呼び出しでは設定由来メタデータを補完し、明示メタデータは上書きされないことを回帰テストにする。

問題コード抜粋

Python / 修正前トレース追記: retail_ai_ops/copilot.py
if trace_logger:
    trace_logger.append(copilot_answer)

修正コード抜粋

Python / 設定メタデータ整合: retail_ai_ops/copilot.py
if trace_logger:
    trace_metadata = {**build_trace_metadata(settings), **trace_logger.metadata}
    trace_logger.append(copilot_answer, metadata=trace_metadata)

assert payload["sql"].endswith("limit 7")
assert payload["query_tag"] == "raiops13_trace_metadata_repair"
assert payload["max_result_rows"] == 7
assert payload["query_timeout_seconds"] == 12

修正方向: トレースイベントは実行設定を基本メタデータとして持ち、明示的に渡されたケースメタデータを尊重する。SQL上限とトレースメタデータを同じテストで確認する。

並列セッション運用の改修実例

受理、レビュー、統合判断の状態を混ぜると、タスクが進んだように見えて実際は崩れる。

F-04

委任ブリーフが整って見えても、新規作業ツリーが古いHEADを見るリスクがあった

ブランチリスク
問題種別 ブランチリスク 構成図ノード GitHubリポジトリ / CI-CD 発生ファイル docs/project-management/parallel-session-implementation-plan.md
レビュー指摘

正本ドキュメントやスキルが未コミット、未追跡のままでは、別セッションが必要な設計を読めない。

影響

受理済みに見えるレーンが、実際には古い指示や古いスキルで作業を進める。

検知証跡

FB-080。委任前レビューで委任元、ブランチ、HEAD、プッシュ方針不足を検出。

再発防止

委任前に基準参照、作業ツリー、ブランチ、HEAD、対象コミットを確認する。

問題のある記述抜粋

Markdown / 並列セッション親計画: docs/project-management/parallel-session-implementation-plan.md
ただし `accepted` / `reported` / `reviewed` / `integration_ready` はTerminalごとに
別々に判定する。1つのTerminalが報告しても、他のTerminalの受理や完了の証拠には
しない。

修正後記述抜粋

Markdown / 並列セッション親計画: docs/project-management/parallel-session-implementation-plan.md
dispatch前に正本docs/skillsが未コミットまたは未追跡の場合は、次のどちらかを選ぶ。

- dispatch base commit/branchを作る
- brief本文に必要な正本内容を省略せず含める

別worktreeがHEADやbase_refから作られる場合、未コミット正本は読めないため、
この確認がないまま `accepted` へ進めない。

修正方針: 状態語の分離だけでは足りないため、別作業ツリーが読む正本コミットを明示し、未コミット正本はブリーフ本文に完全同梱させる。

F-05

レビュワーが integration_ready を結論として使いかけた

状態語混同
問題種別 状態語混同 構成図ノード GitHubリポジトリ / LLMOps運用 発生ファイル skills/ai-architecture-learning/child-skills/code-review-ai-mistake-patterns/SKILL.md 文面所在 FB-081 / レビュワー結論
レビュー指摘

レビュワーレーンが最終統合判断に近い語を使うと、mainセッションの独立確認を飛ばしやすい。

影響

reviewedintegration_ready が混ざり、重大指摘やブランチ鮮度確認を抜かす。

検知証跡

FB-081。レビュワーは判定や推奨だけを返すルールに修正。

再発防止

統合可能判断はmainセッションだけが行い、レビュワーは reviewer_verdict に留める。

問題を示すレビュー記録

Markdown表 / フィードバック台帳のレビュワー指摘: .agent-feedback/FEEDBACK_LEDGER.md#FB-081
FB-081 | The reviewer lane used `integration_ready` as a reviewer conclusion even though that state belongs only to the orchestrator after independent review.

修正後ルール抜粋

スキルMarkdown / レビュワールール: skills/ai-architecture-learning/child-skills/code-review-ai-mistake-patterns/SKILL.md
Reviewer sessions must not declare `integration_ready`. That state belongs to
the orchestrating main session after independent artifact review, checks,
branch/worktree inspection, and blocking-finding triage.

修正方針: レビュワーは結論を推奨に留め、mainセッションだけが成果物確認、チェック、ブランチ状態を見て統合可否を決める。

Backlog / Slack 周辺の改修実例

チケット本文、通知シミュレーター、実サービス監査を同じ進捗として扱わない。

F-06

Backlog本文がRAIOPS-4実装後の状態に追従していなかった

文書陳腐化
問題種別 文書陳腐化 構成図ノード 構成図外: Backlogチケット運用 発生ファイル docs/project-management/backlog-ticket-bodies.md 文面所在 RAIOPS-4チケット本文 / 旧108テスト記述
レビュー指摘

RAIOPS-4本文に古い 108 data tests やシードテスト未決扱いが残っていた。

影響

チケットを見た別セッションが、実装済み範囲と未実施範囲を誤解する。

検知証跡

FB-084、INV-20260630-004。レーンCがBacklogチケット陳腐化を指摘。

再発防止

実装やテスト数が変わったら、該当チケット本文も同じタイミングでレビューする。

問題のあるMarkdown抜粋

Markdown / Backlogチケット本文: docs/project-management/backlog-ticket-bodies.md
RAIOPS-3ではdbt scaffoldと97 data testsの定義、parse/compileまでは確認済み。RAIOPS-4でKPI定義seed契約を取り込むと108 data testsの静的metadataになる見込みだが、live dbt build/testはまだ通していない

- KPI定義seedのtest方針を決める

未決事項:
- seed testsをRAIOPS-4に含めるかRAIOPS-5へ寄せるか

修正後Markdown抜粋

Markdown / Backlogチケット本文: docs/project-management/backlog-ticket-bodies.md
RAIOPS-3ではdbt scaffoldと97 data testsの定義、parse/compileまでは確認済み。RAIOPS-4でKPI定義seed契約を取り込み、静的metadataは9 models、1 seed、111 data tests、7 sourcesになっている。ただし、live dbt build/testはまだ通していない

- KPI定義seedのtestをRAIOPS-4範囲として維持し、現行seed行とsingular test期待値を一致させる

未決事項:
- KPI定義seed契約をlive `dbt seed/test` で通し、Snowflake上の型・値・gap文言が期待通りか確認する

修正方針: 実装後の静的メタデータ、シードテストの扱い、実環境未実施範囲を同じチケット本文で更新し、古い見込み値を残さない。

F-07

レーンCがレビュー専用からRAIOPS-15実装へ滑る余地があった

スコープ境界
問題種別 スコープ境界 構成図ノード 構成図外: Backlog / Slack通知運用 発生ファイル docs/project-management/parallel-session-task-split-20260630.md 文面所在 FB-083 / レーンCレビュー指摘
レビュー指摘

Backlog/Slackレビューのブリーフで、tools/fixtures/tests/、実Backlog、実Slackを触らない境界が弱かった。

影響

レビュー専用レーンが実装や外部サービス操作を始め、証跡と責任範囲が混ざる。

検知証跡

FB-083。Backlogの持続的な確認面とレビュー専用境界を修正。

再発防止

レビュー専用レーンは「編集禁止」「外部操作禁止」「提案だけ」をブリーフに明記する。

問題を示すレビュー記録

Markdown表 / フィードバック台帳のレビュワー指摘: .agent-feedback/FEEDBACK_LEDGER.md#FB-083
FB-083 | Backlog wording still used `正本` for task state and acceptance criteria, and Lane C could slide from review into RAIOPS-15 implementation.

修正後Markdown抜粋

Markdown / レーンCレビュー専用ブリーフ: docs/project-management/parallel-session-task-split-20260630.md
直接編集してよいのは、main sessionが明示した小さな提案ファイルだけにする。
原則として、Backlog台帳、feedback ledger、project skill、Obsidian mirrorは
main sessionが統合する。

Lane Cは `RAIOPS-15` を実装しない。`tools/`、`fixtures/`、`outputs/`、
`tests/`、実Backlog設定、実Slack設定、Issue投稿は触らない。RAIOPS-15に関する
指摘は提案として返す。

修正方針: レビュー専用レーンは実装・外部操作・共有ファイル更新を禁止し、検出した改善はmainセッションへの提案として返す。

F-08

Backlog運用移行の監査とSlack通知シミュレーター実装証跡が混ざりかけた

証跡境界
問題種別 証跡境界 構成図ノード 構成図外: Backlog / Slack通知運用 発生スクリプト tools/simulate_backlog_slack_notification.mjs 文面所在 IMP-100 / UR・LR報告比較
レビュー指摘

LRのローカル private_simulation 成果は実装証跡だが、実Backlogや実Slackの運用監査証跡ではない。

影響

ローカルCLIの成功を、ブラウザやアカウント状態の確認が必要な運用移行準備度と誤読する。

検知証跡

IMP-100。UR報告はBacklog運用移行を needs-fix と判定。

再発防止

ローカルシミュレーター、Backlog UI、Slack UI、API、実投稿を別証跡としてラベル付けする。

問題を示すMarkdown抜粋

Markdown / 3レーン分割計画: docs/project-management/parallel-session-task-split-20260630.md
Backlogチケット管理は、実装者へ作業を渡すための設計面としては移行可能に近い。
ただし、Backlog運用そのものを別sessionへ任せるには、まだ一度
`Backlog/チケット運用QA` laneでレビューさせるのが安全である。

修正後Markdown / 実装抜粋

Markdown表 + JavaScriptガード / IMP-100 と tools/simulate_backlog_slack_notification.mjs
| UR | `reported` | Backlog/チケット運用QAは `needs-fix`。実Backlog説明欄diff監査、実同期確認、更新権限、Backlogコメント品質チェックが未完 | `rejected` ではないが `integration_ready` ではない。次は同laneへQA不足の補強指示を返す |
| LR | `reported` | `9c5e748` で `private_simulation` 通知シミュレーターを実装。main側で `node --test`、二重通知抑止、`sent_external=false`、`git diff --check` を再確認 | `reviewed`。外部Slack/Backlogの確認は別laneまたはbrowser-capable sessionで扱う |

if (options.mode !== DEFAULT_MODE) {
  throw new Error(`Only ${DEFAULT_MODE} mode is implemented. Refusing mode=${options.mode}`);
}

修正方針: ローカルシミュレーターの成功は実装証跡として扱い、Backlog/Slack実運用への移行可否はブラウザまたはAPIで別監査する。

ページ分離ルール

  • 総合ビューはレビュー観点、状態語、証跡レベル、反映先を扱う
  • ソースコード改修実例ビューは実レビュー由来の改修実例だけを扱う
  • 抽象カテゴリだけの項目はソースコード改修実例ビューに入れない
  • 新しい実指摘が出たら、このページへ追加するか、別ページ化を検討する

更新時の確認

  • 実レビューで確認した改修対象か確認する
  • 検知証跡とフィードバック台帳IDを残す
  • 修正済みでも、何を防ぐべきだったかを残す
  • 総合ビューと内容重複しすぎたら、説明を削って改修実例に戻す