Skip to content

chore(deps): SqlClient を 5.2.3 へ上げ、テスト側ロックファイルも同時に再生成する - #181

Merged
izumacha merged 5 commits into
mainfrom
claude/dreamy-brown-cf3fi2
Aug 24, 2026
Merged

izumacha merged 5 commits into
mainfrom
claude/dreamy-brown-cf3fi2

Conversation

@izumacha

@izumacha izumacha commented Aug 24, 2026 •

Copy link
Copy Markdown
Owner

背景

Dependabot の #180(Microsoft.Data.SqlClient 5.1.7 → 5.2.3)は CI が赤でマージできない状態でした。

error NU1004: The project references incidentinsight.web whose dependencies has changed.
The packages lock file is inconsistent with the project dependencies so restore can't be run in locked mode.

原因は Dependabot が src/IncidentInsight.Web/packages.lock.json しか更新しないこと。このリポジトリは
tests/IncidentInsight.Tests も RestorePackagesWithLockFile を宣言しており、そちらは web プロジェクトを
ProjectReference で参照しているため、web の依存が変わるとテスト側のロックファイルも同時に再生成が要ります。
過去にロックファイルへ触れたコミット(#166 / #172 / 導入時)はすべて 2 ファイルを同一変更セットで
更新していました。#180 はその不変条件だけが欠けています。

バージョン更新そのものは妥当なので、#180 の内容を取り込んだうえでテスト側ロックファイルを補ったのがこの PR です。

変更内容

1. 依存更新(27695a6)

ファイル 内容
src/IncidentInsight.Web/IncidentInsight.Web.csproj Dependabot 生成のピン(5.1.7 → 5.2.3)
src/IncidentInsight.Web/packages.lock.json Dependabot 生成物をそのまま採用(NuGet が解決した権威ある内容)
tests/IncidentInsight.Tests/packages.lock.json 同じ解決結果を反映(この PR で新規に補った差分)

テスト側で連動する解決結果:

  • Microsoft.Data.SqlClient 5.1.7 → 5.2.3、SNI.runtime 5.1.2 → 5.2.0
  • System.Configuration.ConfigurationManager 6.0.1 → 8.0.0、System.Runtime.Caching 6.0.0 → 8.0.0、System.Security.Cryptography.ProtectedData 6.0.0 → 8.0.0
  • System.Security.Cryptography.Cng 5.0.0 → 4.5.0 — この更新で唯一の「版が下がる」箇所。SqlClient 5.2.3 が要求をやめ、残る要求元 Microsoft.IdentityModel.Tokens 6.35.0 の 4.5.0 に落ちたもの。net8.0 では共有フレームワーク側の実装が優先されるためパッケージ版に実行時の意味は無く、確認のうえ許容(csproj のコメントに明記)
  • 要求元を失った 8 パッケージを削除: Microsoft.Win32.SystemEvents / System.Drawing.Common / System.Security.AccessControl / System.Security.Permissions / System.Security.Principal.Windows / System.Text.Encoding.CodePages / System.Windows.Extensions / System.Runtime.CompilerServices.Unsafe
  • System.Diagnostics.EventLog は 8.0.1 のまま(テスト側だけに居る Microsoft.Extensions.Logging.EventLog 8.0.1 が web 側の 8.0.0 より上位を要求するため)

System.Runtime.CompilerServices.Unsafe がテスト側でだけ消えるのは、web 側では
Microsoft.EntityFrameworkCore.Design 経由の Microsoft.CodeAnalysis.Common が要求元として残るのに対し、
Design は PrivateAssets=all でテストプロジェクトへ流れないためです。

2. 検出網の追加と、規約の記録(79bc85e 〜 c4437fc)

レビューで「床値検査が守れていない範囲」が判明したため、書ける分を機械化しました。

  • SqlClientPin_StaysADirectReference を追加。既存の床値検査が比べる相手は EF Core SqlServer の宣言(5.1.6)であってピンの値ではないため、ピンを「冗長だから」と削除しても 5.1.6 >= 5.1.6 で素通りし、SQL Server 配備だけが静かに古いドライバへ戻ります。ロックファイルの type が Direct のままであることを見れば削除も推移依存への差し戻しも捕まえられ、期待する版をテストに書かずに済むので「期待値は宣言側から読む」方針とも両立します。
  • 残る穴を正確に記録。上記を追加しても「ピンの値を EF Core の宣言版以上・現在のピン未満(今なら 5.1.6 以上 5.2.3 未満、例: この更新を revert して 5.1.7 に戻す)へ下げる」変更は全検査を素通りします。レビューでしか止まらないため csproj と CLAUDE.md の両方に明記しました。
  • CLAUDE.md §3 に「ロックファイルは全プロジェクト分を同時に再生成する」を追記。今回手作業で直した手順がどこにも残っていなかったため、不変条件として記録し csproj / dependabot.yml から参照します。検出項目の一覧は CLAUDE.md を唯一の参照元にし、写しが古くなる経路を減らしました。
  • LockEntriesFor を切り出して ID 照合の重複を解消。

不変条件への影響

CLAUDE.md「SQL Server の ADO.NET ドライバのメジャー版は EF Core の SqlServer プロバイダに合わせる」は維持されます。

  • major は 5 のまま(Microsoft.EntityFrameworkCore.SqlServer 9.0.19 の宣言 5.1.6 と一致)
  • 床値は 5.1.7 → 5.2.3 と前進のみ
  • dependabot.yml の保留は major 限定のため、この minor 更新は意図どおり通る対象(ignore エントリは無改変)
  • EF Core 系パッケージの解決版(9.0.19、および理由付きで除外されている 2 つの 8.0.30)は一切動いていません

検証

このセッションでは .NET SDK を実行できていません(dotnet 未導入で、配布元 builds.dotnet.microsoft.com
が egress ポリシーで遮断されているため導入も不可)。ローカルでは --locked-mode が見るのと同じ性質を機械的に検査し、
最終的な検証は CI に委ねました。CI(build-and-test / Docker image build & smoke test)は全コミットでグリーンで、
これによりテスト側ロックファイルが dotnet restore --locked-mode の受け入れる内容であることと、
追加したテストが実際に通ることが確認できています。

ローカルで実施した検査:

  • 両ロックファイルについて (a) 参照される依存がすべてロック内に存在する、(b) Direct / Project ルートから全パッケージが到達可能(孤児なし)、(c) resolved が全要求元の下限の最大値と一致する — の 3 点が成立
  • 2 ファイル間で解決版が食い違うのは上記 System.Diagnostics.EventLog と、変更前から存在する Microsoft.Bcl.AsyncInterfaces の 2 件のみ
  • EfCorePackageAlignmentTests のメジャー一致・床値検査を両ファイルに対してシミュレート(いずれも成立)
  • テスト側ロックファイルは NuGet の出力書式(末尾改行なし・BOM なし・2 スペース)をバイト単位で維持
  • csproj は XML として、dependabot.yml は YAML として妥当(ignore エントリが 1 件・update-types 有り・versions 無しであることも確認)

/code-review ultra と /security-review ultra を push のたびに実行し、指摘は 4 巡で反映しました
(セキュリティは 2 回とも HIGH / MEDIUM ゼロ)。見送りは 1 件のみ:MajorOf と MajorVersionOf の重複は
本 PR 以前からある実装で、依存更新とは無関係なリファクタになるため(§6「変更は最小スコープに保つ」)。

なお Vercel – incident-insight / Vercel – incident-insight-jjt5 の 2 つの status は赤ですが、
これは .NET アプリに紐づいた Vercel プロジェクト由来のこの PR 以前からの失敗で、
直前にマージされた #179 でも同じ 2 件が赤のままでした。本 PR の差分とは無関係です。

#180 の扱い

この PR がマージされたら #180 は不要になるため、superseded としてクローズします。

Dependabot の PR #180 は src/IncidentInsight.Web 側の packages.lock.json しか
更新しないため、tests/IncidentInsight.Tests/packages.lock.json が 5.1.7 のまま
取り残され、CI の `dotnet restore --locked-mode` が NU1004 で落ちていた
(「The project references incidentinsight.web whose dependencies has changed」)。
ロックファイルは全プロジェクト分を同一変更セットで更新する必要がある。

- src/: Dependabot が生成した csproj / ロックファイルをそのまま採用(5.1.7 → 5.2.3)
- tests/: 同じ解決結果を反映。SqlClient 5.2.3 が依存を整理した結果、
  SNI.runtime 5.2.0 / ConfigurationManager 8.0.0 / Runtime.Caching 8.0.0 /
  ProtectedData 8.0.0 へ上がり、Cng は他要求元(IdentityModel.Tokens)の
  4.5.0 に落ち着く。要求元を失った 8 パッケージは削除する。
  うち System.Runtime.CompilerServices.Unsafe はテスト側だけで消える
  (web 側は PrivateAssets の EF Design 経由 CodeAnalysis.Common が要求元として残るため)。
- csproj のコメントが旧ピン 5.1.7 を指したままだったので現状に合わせる。

major は据え置き(5 のまま)なので dependabot.yml の保留と
EfCorePackageAlignmentTests のメジャー一致・床値検査はいずれも維持される。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VWXdwuq13R27U1P6fYwp4i
@vercel

vercel Bot commented Aug 24, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
incident-insight Error Error Aug 24, 2026 8:49am
incident-insight-jjt5 Error Error Aug 24, 2026 8:49am

/code-review ultra の指摘 3 件に対応する(コメントとドキュメントのみ、依存関係の変更なし)。

1. 床値検査の過大表現: EfCorePackageAlignmentTests の「床値の後退」検査が比べる相手は
   EF Core の宣言(5.1.6)であって、いま書いてあるピンの値ではない。つまりピンを 5.1.6 まで
   下げる/丸ごと消す変更はテストを素通りする。5.1.7 のときは高々 1 パッチ分だった穴が、
   5.2.3 で 1 マイナー分に広がるため、限界を csproj に明記する。
   (期待値をテストに書かない方針とのトレードオフなので、テスト側は変更しない)
2. 手順が記録されていない: Dependabot の nuget PR は src/ 側のロックファイルしか更新せず、
   毎回 NU1004 で赤くなる。今回手作業で直した内容が CLAUDE.md にも csproj にも
   残っていなかったため、§3 に不変条件として追記し csproj から参照する。
3. 誤った説明: 「Relational は上位版を採用する」は Relational から SqlClient への依存辺が
   無く機構の説明として誤り。実際に 5.2.3 が選ばれるのは EF Core SqlServer の 5.1.6 要求と
   直接参照の [5.2.3, ) を NuGet が突き合わせる highest-wins のため。正しい機構に直す。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VWXdwuq13R27U1P6fYwp4i
2 巡目の /code-review ultra の指摘 3 件に対応する。

1 巡目で「床値検査の比較相手は EF Core の宣言(5.1.6)であってピンの値ではない」という
穴を csproj のコメントに書き残したが、このリポジトリの流儀は穴を文章で残さず機械化する
ことなので、書ける範囲を検査に落とす。

- SqlClientPin_StaysADirectReference を追加。ロックファイルの type が Direct のまま
  であることだけを見る。ピンを「冗長だから」と削除すると解決版は EF Core の宣言どおり
  5.1.6 まで落ちるが、5.1.6 >= 5.1.6 で既存の床値検査は素通りしてしまう。type を見れば
  削除も推移依存への差し戻しも捕まえられ、期待する版をテストに書かずに済むので
  「期待値は宣言側から読む」方針とも両立する。
- CLAUDE.md §3 が「床値の後退を検出する」と無条件に書いていて csproj のコメントと
  矛盾していたため、検出できる 5 つと、残る穴(値を 5.1.6 ちょうどまで下げる変更)を
  明記する。
- Dependabot / NU1004 の手順を csproj と CLAUDE.md の両方に全文で書いていたのを
  CLAUDE.md 側に一本化し、csproj からは参照だけにする(DRY)。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VWXdwuq13R27U1P6fYwp4i
3 巡目の /code-review ultra の指摘 2 件に対応する。

- 残る穴の記述が狭すぎた。床値検査は resolved >= EF Core の宣言(5.1.6)を見るので、
  素通りするのは「5.1.6 ちょうど」だけでなく 5.1.6 以上・現在のピン未満の範囲すべて。
  たとえば今回の更新を revert して 5.1.7 に戻す差分は 5.1.7 >= 5.1.6 が成立して全て緑で
  通り、5.2.x のサービシングパッチを静かに失う。この書き方だとレビュアーが「5.1.6 に
  なっている差分」しか警戒せず 5.1.7 を素通しさせるため、csproj と CLAUDE.md の両方を
  正確な範囲に直す。
- ID でロックファイルの記録を集める処理が ReadResolvedVersion と新テストに重複していた
  ので LockEntriesFor へ切り出す(このファイルが LockFilePathOf で既に踏んでいる前例と
  同じ理由。照合規則を片方だけ直して他方が静かに意味を変えるのを防ぐ)。
  YAML 側の ReadIgnoreEntriesFor と役割が紛れないよう Lock を冠した名前にする。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VWXdwuq13R27U1P6fYwp4i
4 巡目の /code-review ultra の指摘のうち 2 件に対応する(コメントのみ)。

- この更新で唯一「版が下がる」System.Security.Cryptography.Cng 5.0.0 → 4.5.0 を
  csproj に明記する。SqlClient 5.2.3 が要求をやめ、残る要求元 IdentityModel.Tokens の
  4.5.0 に落ちたもの。net8.0 では共有フレームワーク側が優先されるため実行時の意味は無いが、
  「版を後退させない」ことが主題の変更で唯一の後退なので、見落としでなく確認済みだと分かるようにする。
- dependabot.yml に検出項目を書き写していた行が、SqlClientPin_StaysADirectReference を
  足したときに 1 件少ないまま取り残されていた。同じ一覧が 3 箇所に散っているのが原因なので、
  一覧は CLAUDE.md §3 を唯一の参照元とし、dependabot.yml からは参照だけにする。

見送り: MajorOf と MajorVersionOf の重複(本 PR 以前からある実装で、依存更新とは無関係な
リファクタになるため。§6「変更は最小スコープに保つ」)。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VWXdwuq13R27U1P6fYwp4i
@izumacha
izumacha merged commit 46ed35e into main Aug 24, 2026
4 of 6 checks passed
@izumacha
izumacha deleted the claude/dreamy-brown-cf3fi2 branch August 24, 2026 08:52
izumacha added a commit that referenced this pull request Aug 28, 2026
#173 で優先度を MeasurePriorityScale へ集約した際、隣の有効性評価には
EffectivenessScale を見ていない経路が 2 つ残っていた。

1. IncidentMeasuresController.RateMeasure が範囲を 1〜5 と直書き。詳細画面のラジオと
   PreventiveMeasuresController.Review は尺度から引いているため、同じ項目の 3 か所の
   うちここだけがずれていた。段階を増やすと画面は新しい段階を描くのにこの経路だけが
   弾き、評価が黙って捨てられる。
2. PreventiveMeasure.EffectivenessRating の [Range(1,5)] / [Display] も直書きのまま。

これを検出できなかったテスト側の穴も塞いだ。範囲外は下限しか回さず、成功経路も
評価値を直書きしていたため、上限・下限どちらの取り違えも緑のまま通っていた。
範囲外・成功のいずれも下限と上限の Theory にした。

あわせて、同じ「写経の取り残し」に当たるコメント 3 件(Delete 2 経路の部署スコープに
関する誤った記述、Details.cshtml の段階数の直書き)を実態に合わせて訂正した。

検証: 尺度の Max を 7 へ変える変異、および境界比較の < → <= / > → >= の変異の
いずれでもテストが落ちることを確認。変異なしで 463 passed / 0 failed、ビルド 0 warning。

なお Vercel の 2 件は .NET アプリを Vercel がビルドできないことによる恒常的な失敗で、
無関係な PR #181 でも同一に失敗したままマージされている(PR コメントに詳細を記載)。
izumacha pushed a commit that referenced this pull request Aug 30, 2026
PR #184 の 2 巡目レビュー指摘 3 件を反映する。

1. EnumLabels.AuditEntityJa が導出できない 4 つ目の写しだった
   AllowedEntityNames を宣言から導出するようにしたぶん、そのすぐ隣で使う日本語ラベルの
   変換表だけが手書きの写しとして残った。JapaneseAuditEntity は辞書に無いキーを元の値の
   まま返すフォールバックを持つため、監査対象を足してラベルを書き忘れても例外にならず、
   監査ログ画面の 3 箇所(ドロップダウン / 一覧の各行 / 詳細)に CLR の型名が英語のまま出る。
   ビルドも全テストも緑のまま通る。

   フォールバック自体は残す(監査対象から外したエンティティの過去行を表示するときに、
   例外で画面を落とすより元の値を出す方が安全)。代わりに AuditEntityLabelCoverageTests が
   「ラベル表は監査対象を全網羅する」ことを機械的に固定する。

2. fluent の HasMaxLength() が裸の数値の抜け道になっていた
   前コミットで上限の充足判定を EF のモデル(GetMaxLength())へ寄せたため、fluent で
   設定した上限も「上限あり」として通るようになった。ところが裸の数値を検出する
   FieldLengthsTests は CLR の [MaxLength] 属性しか見ていないので、「上限はある(緑)/
   その値は FieldLengths 由来ではない(誰も見ていない)」という状態が作れてしまう。
   実際 ApplicationDbContext の 20 / 50 が既にその状態だった。

   ——エスケープハッチを足したぶん既存の検出網が黙って狭くなるという、この PR 自身が
   塞いだのとまったく同じ形。属性側と同じ許容集合でモデル側も見る検査を足し、
   20 / 50 を FieldLengths.EnumCode / EnumCodeJapanese として名前付き定数にした
   (値は変えていないのでスキーマは不変。マイグレーション不要)。

3. PartitionStringColumns のコメントが実際の挙動を過大に述べていた
   「呼び出し側が同じ走査を 2 回しない」と書いていたが、2 つの薄い射影はそれぞれ独立に
   呼ぶので両方使えば 2 回走る。実際の挙動と、メモ化せず素直に再計算する判断の理由へ直した。

なお同レビューが挙げた EffectivenessScale の文言と EfCorePackageAlignmentTests の 2 件は
本 PR の差分ではなくマージ済みコミット(#182 / #181)由来のため、ここでは扱わない。

変異 2 通り(ラベル表から 1 件落とす / fluent の上限を裸の 48 へ戻す)で、それぞれ対応する
検査だけが赤になることを実測済み。
dotnet restore --locked-mode / build (警告 0) / test 484 件 / npm run typecheck すべて緑。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AAEwHDpPsNzmEnxHPmzKf5

This branch had an error being deployed

2 failed deployments
Preview – incident-insight — c4437fca Deployed Aug 24, 2026 by vercel[bot]
Preview – incident-insight-jjt5 — c4437fca Deployed Aug 24, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants