Summary
現在の ztd ddl diff では、riskNotes を structured risks に置き換え、summary と責務分離し、applyPlan / renderApplySql / buildRisks までの内部整理が入った。
これは reviewability 改善としては十分前進しているが、リスク評価はまだ diff.ts 内の内部関数に留まっており、独立した evaluator としては扱えていない。
そのため現状では、
ztd ddl diff が生成した migration に対する評価
- 人間が手修正した migration SQL に対する再評価
- 将来的な他コマンドや他入口からの再利用
がまだできない。
本課題では、migration 生成処理と risk 評価処理を明確に分離し、ddl diff からは統合利用しつつ、独立した risk evaluator として再利用可能な形に整理する。
あわせて、手修正後 migration SQL に対しても同じ risks contract で事後評価できる入口を用意する。
Background
今回の structured risks 導入で、少なくとも次は整った。
summary は logical diff
risks は apply-plan based structured risks
destructiveRisks / operationalRisks
guidance / avoidable
buildApplyPlan(...)
renderApplySql(...)
buildRisks(applyPlan, summary)
ただし、このままだと risk 判定が migration 生成の内部都合に閉じやすい。
review-first の信頼性をさらに高めるには、
- 生成器が自分で作ったものを自分で「安全」と言う構造から一歩離れること
- 生成結果そのものを別責務で評価できること
- 人間が SQL を手修正したあとでも、同じ基準で再評価できること
が重要である。
とくに migration は、現実運用では自動生成後に人間が少し手直しすることがある。
その最終成果物に対して independent に risk を再評価できることは、隠ぺいしていないことの説明にもなり、review artifact としての信頼性も上がる。
Goal
- risk evaluator を
diff.ts の内部関数から切り出し、独立責務にする
ddl diff はその evaluator を利用して risks を出す
- 手修正後 migration SQL に対しても、同じ
risks contract で事後評価できる入口を追加する
- 将来的に他入口から再利用しやすい API 境界を作る
Non-goals
今回の課題では、次は主目的にしない。
- DB 方言ごとの実行計画レベルの高精度性能推定
- migration 実行時間の正確な見積もり
- すべての手書き SQL を完全に意味解析すること
- CLI option の全面再設計
ddl diff 自体の migration 生成アルゴリズム変更
Desired Outcome
少なくとも次の形に整理されていること。
- migration 生成
- migration SQL render
- risk 評価
が内部責務として分離されている。
イメージとしては次のような境界を目指す。
buildApplyPlan(...)
renderApplySql(plan)
analyzeMigrationPlanRisks(plan, summary?)
analyzeMigrationSqlRisks(sql)
ddl diff は従来どおり summary / SQL / risks をまとめて出してよいが、risk 判定自体は独立 evaluator 経由にする。
Scope
1. risk evaluator を diff.ts 外へ切り出す
現在の buildRisks(applyPlan, summary) 相当の責務を、diff.ts の内部実装ではなく、独立した evaluator module に移す。
最低限の要件:
DdlDiffRisks contract を維持する
destructiveRisks / operationalRisks を返す
guidance / avoidable を維持する
ddl diff は切り出した evaluator を使う
2. plan ベース evaluator を独立化する
まずは既存実装に最も近い、applyPlan を入力とする evaluator を独立化する。
例:
analyzeMigrationPlanRisks(plan, summary?): DdlDiffRisks
ここでは、現在 buildRisks(...) に入っている判定規則を移送すればよい。
3. SQL ベースの事後評価入口を追加する
次に、migration SQL 文字列を入力として risk を出す入口を追加する。
例:
analyzeMigrationSqlRisks(sql): DdlDiffRisks
これは「手修正後 migration SQL の再評価」のための入口である。
v1 では、完全な SQL 意味復元は不要とする。
まずは少なくとも次が拾える形を目指す。
DROP TABLE
DROP COLUMN
CASCADE
- table recreate 相当のパターン
- index rebuild 相当のパターン
- alter type 相当のパターン
必要なら、plan-based evaluator より判定精度が落ちる項目は docs / contract 上で明示する。
とくに rename_candidate のような文脈依存 risk は、SQL 単体では省略または精度低下を許容する。
4. ddl diff は plan-based evaluator を利用する
ddl diff コマンド自体は引き続き
- summary
- generated SQL
- risks
をまとめて返してよい。
ただし内部では、
buildApplyPlan(...)
renderApplySql(...)
analyzeMigrationPlanRisks(...)
の順に呼ぶ構造へ揃える。
5. 事後評価用の入口を CLI または内部 API として持てるようにする
最低限、内部 API として analyzeMigrationSqlRisks(sql) を使える状態にする。
CLI 入口はあると望ましいが、この課題の必須条件ではなく stretch goal とする。
候補:
ztd ddl risk --file migration.sql
ztd ddl diff --risk-from <file>
- あるいは describe / agent interface から触れる内部 command
CLI 名称の最終確定はこの課題内で必須ではない。まずは API 境界を優先する。
Design Notes
独立性の意味
この課題の狙いは単に関数分割することではない。
重要なのは、risk 評価が migration 生成ロジックの自己説明で終わらないことにある。
- generator は migration を作る
- evaluator は migration plan または migration SQL を評価する
という構図を明確にすることで、
- 隠ぺいしていないことの説明になる
- 最終成果物に対する independent review ができる
- 人手修正後の再評価が可能になる
plan と sql の両系統を持つ理由
plan-based evaluator は、rename_candidate や summary 文脈を使えるため、ddl diff の内部評価には向いている。
一方で sql-based evaluator は、生成器に依存せず、最終的な migration SQL に直接かけられるため、手修正後評価や将来の汎用 analyzer として有用である。
したがって、どちらか一方ではなく、次の 2 層にするのが望ましい。
analyzeMigrationPlanRisks(...)
analyzeMigrationSqlRisks(...)
Acceptance Criteria
diff.ts 内部に閉じていた risk 判定処理が独立 module に切り出されている
ddl diff がその独立 evaluator を使って risks を返す
applyPlan を入力とする evaluator API が存在する
- migration SQL を入力とする evaluator API が存在する
- 少なくとも代表的な destructive / operational risk を SQL から再検出できる
guidance / avoidable の contract が維持される
- 既存の
ddl diff text/json 契約が壊れていない
- docs / help / agent interface に新しい責務分離が反映される
- テストで「手修正後 SQL の再評価」が確認できる
Test Plan
Unit tests
- plan-based evaluator が既存
ddl diff の risk 判定結果を維持する
- sql-based evaluator が次を検出できる
drop_table
cascade_drop
drop_column
alter_type
table_rebuild 相当
guidance / avoidable が plan-based evaluator で維持される
- text/json の contract が従来どおり通る
CLI / integration tests
ddl diff が独立 evaluator 経由で同じ risks を返す
- 事後評価用入口を追加した場合、その output contract が固定される
- docs examples が新構成に一致する
Regression tests
- 既存の
structured risks 契約が壊れていない
riskNotes が復活していない
summary と risks の責務分離が維持されている
Open Questions
- SQL ベース evaluator の CLI 入口は今回の課題で一緒に入れるか、API だけ先に切るか
rename_candidate のような文脈依存リスクを SQL ベース評価でどう扱うか
- sql-based evaluator の精度差を contract / docs にどう表現するか
Suggested Implementation Order
buildRisks(...) 相当を独立 module へ切り出す
ddl diff が新 evaluator を使うように差し替える
- plan-based evaluator の unit tests を固定する
- sql-based evaluator を最小実装で追加する
- 手修正後 SQL 再評価の tests を追加する
- 必要なら CLI 入口を追加する
- docs / help / agent interface を更新する
Why this matters
今回の structured risks は reviewability を大きく改善した。
次は、その risk 評価自体を独立させることで、
- migration generator の自己評価に見えにくくする
- 人間が手修正した migration の再評価を可能にする
- 将来の汎用 migration risk analyzer へ育てやすくする
という、信頼性と運用性の強化に進みたい。
Summary
現在の
ztd ddl diffでは、riskNotesを structuredrisksに置き換え、summaryと責務分離し、applyPlan/renderApplySql/buildRisksまでの内部整理が入った。これは reviewability 改善としては十分前進しているが、リスク評価はまだ
diff.ts内の内部関数に留まっており、独立した evaluator としては扱えていない。そのため現状では、
ztd ddl diffが生成した migration に対する評価がまだできない。
本課題では、migration 生成処理と risk 評価処理を明確に分離し、
ddl diffからは統合利用しつつ、独立した risk evaluator として再利用可能な形に整理する。あわせて、手修正後 migration SQL に対しても同じ
riskscontract で事後評価できる入口を用意する。Background
今回の
structured risks導入で、少なくとも次は整った。summaryは logical diffrisksは apply-plan based structured risksdestructiveRisks/operationalRisksguidance/avoidablebuildApplyPlan(...)renderApplySql(...)buildRisks(applyPlan, summary)ただし、このままだと risk 判定が migration 生成の内部都合に閉じやすい。
review-first の信頼性をさらに高めるには、
が重要である。
とくに migration は、現実運用では自動生成後に人間が少し手直しすることがある。
その最終成果物に対して independent に risk を再評価できることは、隠ぺいしていないことの説明にもなり、review artifact としての信頼性も上がる。
Goal
diff.tsの内部関数から切り出し、独立責務にするddl diffはその evaluator を利用してrisksを出すriskscontract で事後評価できる入口を追加するNon-goals
今回の課題では、次は主目的にしない。
ddl diff自体の migration 生成アルゴリズム変更Desired Outcome
少なくとも次の形に整理されていること。
が内部責務として分離されている。
イメージとしては次のような境界を目指す。
ddl diffは従来どおり summary / SQL / risks をまとめて出してよいが、risk 判定自体は独立 evaluator 経由にする。Scope
1. risk evaluator を
diff.ts外へ切り出す現在の
buildRisks(applyPlan, summary)相当の責務を、diff.tsの内部実装ではなく、独立した evaluator module に移す。最低限の要件:
DdlDiffRiskscontract を維持するdestructiveRisks/operationalRisksを返すguidance/avoidableを維持するddl diffは切り出した evaluator を使う2. plan ベース evaluator を独立化する
まずは既存実装に最も近い、
applyPlanを入力とする evaluator を独立化する。例:
ここでは、現在
buildRisks(...)に入っている判定規則を移送すればよい。3. SQL ベースの事後評価入口を追加する
次に、migration SQL 文字列を入力として risk を出す入口を追加する。
例:
これは「手修正後 migration SQL の再評価」のための入口である。
v1 では、完全な SQL 意味復元は不要とする。
まずは少なくとも次が拾える形を目指す。
DROP TABLEDROP COLUMNCASCADE必要なら、plan-based evaluator より判定精度が落ちる項目は docs / contract 上で明示する。
とくに
rename_candidateのような文脈依存 risk は、SQL 単体では省略または精度低下を許容する。4.
ddl diffは plan-based evaluator を利用するddl diffコマンド自体は引き続きをまとめて返してよい。
ただし内部では、
buildApplyPlan(...)renderApplySql(...)analyzeMigrationPlanRisks(...)の順に呼ぶ構造へ揃える。
5. 事後評価用の入口を CLI または内部 API として持てるようにする
最低限、内部 API として
analyzeMigrationSqlRisks(sql)を使える状態にする。CLI 入口はあると望ましいが、この課題の必須条件ではなく stretch goal とする。
候補:
ztd ddl risk --file migration.sqlztd ddl diff --risk-from <file>CLI 名称の最終確定はこの課題内で必須ではない。まずは API 境界を優先する。
Design Notes
独立性の意味
この課題の狙いは単に関数分割することではない。
重要なのは、risk 評価が migration 生成ロジックの自己説明で終わらないことにある。
という構図を明確にすることで、
plan と sql の両系統を持つ理由
plan-based evaluator は、
rename_candidateやsummary文脈を使えるため、ddl diffの内部評価には向いている。一方で sql-based evaluator は、生成器に依存せず、最終的な migration SQL に直接かけられるため、手修正後評価や将来の汎用 analyzer として有用である。
したがって、どちらか一方ではなく、次の 2 層にするのが望ましい。
analyzeMigrationPlanRisks(...)analyzeMigrationSqlRisks(...)Acceptance Criteria
diff.ts内部に閉じていた risk 判定処理が独立 module に切り出されているddl diffがその独立 evaluator を使ってrisksを返すapplyPlanを入力とする evaluator API が存在するguidance/avoidableの contract が維持されるddl difftext/json 契約が壊れていないTest Plan
Unit tests
ddl diffの risk 判定結果を維持するdrop_tablecascade_dropdrop_columnalter_typetable_rebuild相当guidance/avoidableが plan-based evaluator で維持されるCLI / integration tests
ddl diffが独立 evaluator 経由で同じrisksを返すRegression tests
structured risks契約が壊れていないriskNotesが復活していないsummaryとrisksの責務分離が維持されているOpen Questions
rename_candidateのような文脈依存リスクを SQL ベース評価でどう扱うかSuggested Implementation Order
buildRisks(...)相当を独立 module へ切り出すddl diffが新 evaluator を使うように差し替えるWhy this matters
今回の
structured risksは reviewability を大きく改善した。次は、その risk 評価自体を独立させることで、
という、信頼性と運用性の強化に進みたい。