Skip to content

drive-foundation-followups: レビュー nit 8 件の集約是正 (バリデーション・競合安全・キャッシュ・文書化) - #5

Merged
turtton merged 13 commits into
mainfrom
drive-foundation-followups
Sep 12, 2026
Merged

turtton merged 13 commits into
mainfrom
drive-foundation-followups

Conversation

@turtton

@turtton turtton commented Sep 12, 2026 •

Copy link
Copy Markdown
Member

概要

issue #4 (PR #2 レビュー nit 8 件の集約) を実装。バリデーション・競合安全・キャッシュ・文書化を 1 実行単位で是正する。issue #3 は本 PR で superseded として扱う。

変更内容 (8 項目)

  1. ファイル名バリデーション (fix(drive)): UploadQuery.name にフォルダ名と同一規約 (空白のみ拒否・Unicode 文字数 255 上限) を適用。drive::validate_name として共通化。
  2. ボディサイズ制御の整理 (fix(drive)): Body 直接抽出ハンドラでは no-op だった DefaultBodyLimit レイヤを撤去し、CountingBody に一本化。413 (max 超過) / 400 (宣言超過) を結合テストで固定。
  3. 課金解決キャッシュ (feat(billing)): in-memory TTL キャッシュ (既定 60 秒、BOOSKIFF_BILLING_CACHE_TTL_SECS、0 で無効) を導入し、管理者書き込み (ルール upsert/delete、プラン set/delete) で即時無効化。世代トークンで「読み込み中の無効化後に古い値が再登録される」競合も防止。分散共有キャッシュは導入しない (scope 外)。
  4. RateLimiters 制約の明記 (docs): プロセス内メモリ (レプリカ非共有)、rpm 変更時の limiter 再生成による burst リセットは意図的制約として docs/operations.md に明記 (コード変更なし・現行挙動維持)。
  5. upsert_rule 原子化 (fix(billing)): 2 段 upsert を単一 INSERT ... ON CONFLICT ((COALESCE(owner_type,'')), (COALESCE(owner_id,'')), key) DO UPDATE に置換。同時 INSERT 競合で unique violation 500 を返さない。
  6. フォルダ FK 競合の 404 化 (fix(drive)): files INSERT の 23503 (ensure_owned_folder 通過後にフォルダが削除された競合) を NotFound (404) にマップ。
  7. /public/{key} 仕様整備 (feat(public) + docs): 無認証・帯域計量初動外を文書化。DoS 緩和として per-IP レート制限 (既定 300 req/min、BOOSKIFF_PUBLIC_RATE_LIMIT_RPM) を付与。ConnectInfo 非提供環境では fail-open でスキップ。
  8. immutable キャッシュの文書化 (docs): unpublish/削除後も外部キャッシュが残り得ること (即時失効非保証)、publish ごとの public_key 再生成による緩和を docs/operations.md に明記。

検証

  • cargo fmt --check / cargo clippy --all-targets -- -D warnings / cargo test (113 passed) / cargo test -p core -- --include-ignored (130 passed、e2e_suite 含む) / just openapi ドリフトなし / git diff --check クリーン。
  • 追加テスト: ファイル名検証の同値テーブル (255 境界・空・超過・マルチバイト)、413 固定 (宣言超過 upfront + 実体超過 post-cleanup)、課金キャッシュ (stale-hit 非照会 + 即時無効化 + HTTP 経由無効化)、upsert_rule 並行競合、フォルダ消失 FK → 404、/public per-IP 429 (単体 + router + 実バイナリ curl)。
  • 実サーバ検証: BOOSKIFF_PUBLIC_RATE_LIMIT_RPM=2 で 404 → 404 → 429 (rate_limited) を確認。

スコープ外 (packet 準拠で未実施)

Redis 等の分散共有キャッシュ/レート制限、複数レプリカ対応、課金規定値の変更、帯域計量、公開制御の仕様変更、Misskey Drive API 互換、8 件以外のリファクタ、Web UI 変更。

前提確認メモ

各 nit は実施前に最新コードで成立を確認済み (例: upsert_rule の 2 段 upsert と誤ったコメント、DefaultBodyLimit no-op、/public 無制限は main 時点で現存)。既に解消済みでスキップした項目はなし。

Closes #4

前提確認で変質が判明した項目 (nit 6)

packet は「ensure_owned_folder の原子化 (同時フォルダ生成競合)」を想定していたが、最新コードでは ensure_owned_folder は read-only (SELECT EXISTS + 404) でフォルダ生成は行わない (生成は folders.rs 側で 23505→409 済み)。実在する競合は「存在チェック通過後のフォルダ削除 × files INSERT」の FK 23503 で、これを 404 にマップ (837c6d5) し、同時競合テスト pg_concurrent_folder_delete_and_upload_never_500 (8 ラウンドの join! で削除×persist を並行実行、Internal/500 を返さないことを固定) と静的テスト pg_upload_into_vanished_folder_is_not_found で担保した。

レビュー駆動の追加是正 (5 レーン並行レビューの blocker 対応)

  • fix(billing): BillingCache の owner キーを (owner_type, owner_id) の構造化キーに変更。従来の "{type}:{id}" 連結では ("a:b","c") と ("a","b:c") が衝突し、テナント間でキャッシュ済み課金制限が混同し得た (衝突回帰テスト付き)。
  • fix(admin): 空/空白の owner_type・owner_id を持つ owner scope を 400 で拒否。expression index 上で global ルール行と衝突し、ON CONFLICT が global 行を更新しつつ global キャッシュが無効化されない経路を塞いだ (global 行・キャッシュ不変の HTTP 回帰テスト付き)。
  • feat(public): BOOSKIFF_TRUST_PROXY_HEADERS (既定 false) 追加。同梱 Caddy 等の信頼プロキシ背後でのみ X-Forwarded-For 最左 IP を制限キーに使用 (無効時は XFF を完全に無視し peer IP のみ。偽装耐性はテストで固定)。セルフホスト compose では core 非公開・Caddy のみ公開のため compose 側では既定 true でパススルー。
  • test(public): 既定値 300 rpm を Config::default() と limiter 実挙動 (300 許可・301 拒否) の双方で固定。

既知の非ブロッキング事項 (別 packet 候補)

  • 既存 RateLimiters (owner レート制限) も Owner::key() 文字列連結キーで同一の衝突可能性を持つ。drive-foundation 既存コードのため今回の scope 外。
  • BillingCache / PublicRateLimiter の補助 API の pub → pub(crate) 絞り込み、limiter sweep の専用テストは未実施 (挙動はコードコメントと実 HTTP 検証で確認)。

CI インフラ修正 (スコープ外の既存障害)

初回 CI で e2e ジョブが minio/minio の Docker Hub pull 拒否で失敗 (main の最後の成功 CI 以降に MinIO が Docker Hub 公開を停止した既存障害。ローカルはキャッシュ済みで検出不能だった)。compose.yml の minio/mc イメージを quay.io/minio/* に切り替えて解消 (1372b30)。8 項目の nit 是正とは独立した変更だが、完了条件の CI green に必要だったため含めた。

turtton and others added 13 commits September 12, 2026 23:35
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/ohmy-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
@turtton turtton added the intent-pr-approved PR is approved by intent automation review; ready to merge + close out. label Sep 12, 2026
@turtton
turtton merged commit 5405a01 into main Sep 12, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

intent-pr-approved PR is approved by intent automation review; ready to merge + close out.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

drive-foundation-followups: レビュー nit 集約 (バリデーション・競合安全・キャッシュ・文書化)

1 participant