Skip to content

audit: close 8 correctness/robustness gaps across api, registry, and tooling - #521

Merged
t0k0sh1 merged 2 commits into
mainfrom
520-audit-fixes
Aug 9, 2026
Merged

audit: close 8 correctness/robustness gaps across api, registry, and tooling#521
t0k0sh1 merged 2 commits into
mainfrom
520-audit-fixes

Conversation

@t0k0sh1

@t0k0sh1 t0k0sh1 commented Aug 9, 2026

Copy link
Copy Markdown
Owner

Summary

全 Rust コード監査(#520)で見つかった 8 件の修正。各修正にミュータントを殺すテスト付き。

  • promote: sources に他のリスト入力と同じ overlong() 上限(1000 件)を適用 — 従来は入力サイズ比例の CPU/メモリを無制限に消費し得た
  • registry/embeddings: embeddings_status / semantic_twins / semantic_resolve / explain_semantic_resolve のサイドカー読みを tombstone フェンスで保護 — delete に負けた読みは context エンドポイントと同じ「存在しない」(None) を返し、unlink 済み・後継世代のサイドカーから状態を組み立てない。フェンスはスコープ限定で、プロバイダ呼び出しと O(N²) スイープはフェンス外(delete をネットワーク待ちにしない)
  • import: グループ復元タイムアウトにも integrity / durable_batches を機械可読で付与(バッチループ側のタイムアウトと同じ契約)
  • benchmark/compare: wall_seconds が end<start の壊れたサンプルを破棄。重複 end レコードは最後の記録が勝つ(start の keep-earliest と対称)
  • embedding: PassageAnnIndex::build が空ストアで空インデックスを返す(従来は範囲外スライスの潜在パニック)
  • evalset: case_id の空チェックを他フィールド同様 trim 付きに
  • metrics: note_replica_shipped がキャッチアップ時に behind_since_epoch をリセット(note_replica_lane と対称)

Closes #520

Test plan

  • cargo fmt / cargo clippy --all-targets(警告ゼロ)
  • cargo test フルスイート 3211 件パス(失敗 0)
  • diff スコープ mutation gate: 37 mutants — 32 caught / 5 unviable / missed 0(semantic_twins 既存ロジック由来の 508 件は変更範囲外のため除外。CI の 60 件予算も超過する規模なので、必要なら mutants-sweep.yml のモジュールスイープで別途カバー)

https://claude.ai/code/session_011NozdDS9JqgCpi9Z3wo4Pd

Summary by CodeRabbit

  • 新機能

    • 復元タイムアウト時に、処理済みバッチ数とデータ整合性情報を含む応答を返すようになりました。
    • 大量のソースを含むプロモーション要求を、処理開始前に検証・拒否するようになりました。
  • バグ修正

    • 削除済みデータに紐づく古い埋め込み情報が表示される問題を修正しました。
    • 空のデータからインデックスを作成する際のエラーを防止しました。
    • 不正な評価ケースIDや負の計測時間を適切に処理するよう改善しました。
    • レプリケーション遅延が回復した際、遅延状態が正しく解除されるようになりました。

…tooling

Findings from a full-code review (issue #520), each with a test that
kills its mutant:

- promote: `sources` now passes the same overlong() ceiling every
  sibling list-shaped input enforces — a request could previously buy
  CPU/memory proportional to an attacker-chosen id count.
- registry/embeddings: embeddings_status, semantic_twins,
  semantic_resolve, and explain_semantic_resolve now hold the entry's
  tombstone fence over their sidecar loads — a lost race with delete
  answers None (the context endpoint's own 404), never a status built
  from unlinked or successor-generation sidecars. The fence is scoped:
  provider round trips and the O(N²) sweep run outside it.
- import: the group-restore timeout arm now carries
  integrity/durable_batches machine-readably, like the batch loop's
  own timeout refusal.
- benchmark/compare: wall_seconds drops end-before-start samples
  instead of sinking the latency distribution; a re-processed
  document's second `end` record supersedes the first (mirroring
  start's keep-the-earliest, not repeating it).
- embedding: PassageAnnIndex::build on an empty store returns an empty
  index instead of panicking on an out-of-bounds slice.
- evalset: case_id emptiness is trimmed like every other field's.
- metrics: note_replica_shipped clears behind_since_epoch on a
  caught-up lane, the same three-way move note_replica_lane makes.

Closes #520

Claude-Session: https://claude.ai/code/session_011NozdDS9JqgCpi9Z3wo4Pd
@coderabbitai

coderabbitai Bot commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 967bce77-6ae9-4c80-a124-f3fe2f012307

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

APIの復元タイムアウトとプロモーション入力を検証します。ベンチマーク計測とレプリケーション遅延を修正します。空データ、評価ケースID、埋め込み削除競合の処理と回帰テストを追加します。

Changes

APIの検証と拒否応答

Layer / File(s) Summary
復元タイムアウトの構造化応答
src/api/import.rs, src/api.rs
復元タイムアウト時にintegritydurable_batchesを含む検証エラーを返し、応答を検証します。
プロモーション入力上限
src/api/promote.rs, tests/http_api/promote.rs
sourcesが上限を超えた場合、処理開始前にover_limitのHTTP 400応答を返します。

ベンチマークとメトリクスの正確性

Layer / File(s) Summary
ベンチマーク結果と時間計測
src/benchmark/compare.rs, src/benchmark/compare/tests.rs
後続の文書終了レコードを採用し、開始時刻より前の終了時刻を計測から除外します。
レプリケーション遅延の回復
src/metrics/record.rs, src/metrics.rs
レプリカが追随した場合にbehind_since_epochをクリアし、回復動作をテストします。

入力と空データの処理

Layer / File(s) Summary
空ストアのANNインデックス
src/embedding.rs
空のパッセージストアから空のセン​​トロイドとリストを持つインデックスを生成します。
評価ケースIDの検証
src/evalset.rs
空白だけのcase_idを拒否し、既存のエラーメッセージを検証します。

埋め込み読み取りの削除競合制御

Layer / File(s) Summary
削除フェンス内の埋め込み読み取り
src/registry/embeddings.rs
埋め込み状態、意味的ツイン、意味的解決、解決説明で、サイドカーと意味的フロアを削除フェンス内から読み取ります。
削除競合の回帰テスト
src/registry/embeddings/gloss_tests.rs
削除済みエントリの競合時に、4つの読み取り経路がNoneを返すことを検証します。

Estimated code review effort: 4 (Complex) | ~45 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed タイトルはAPI、レジストリ、ツールの8件の正確性・堅牢性修正という主変更を簡潔に示しています。
Linked Issues check ✅ Passed 8件すべての監査要件を実装し、各修正に対応するテストも追加しています。 [#520]
Out of Scope Changes check ✅ Passed 変更はリンクされた8件の監査項目と対応テストに限定され、無関係なコード変更は確認できません。
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch 520-audit-fixes

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/api/import.rs`:
- Around line 421-433: 追加された RestoreGroupsError::Timeout の拒否応答形状を、/import の
golden wire fixture と tests/http_api/contract.rs の契約テストで検証してください。restore_refusal
に渡す total は、全バッチ成功後の group restore であるため durable batch 数と一致させ、integrity と
durable_batches も応答内容に含めてください。HTTP_CONTRACT と MCP_CONTRACT は変更しないでください。

In `@src/metrics.rs`:
- Around line 498-514: Extend the test
a_shipped_report_at_or_below_applied_clears_the_behind_age to also call
note_replica_shipped with shipped_seq 4 while applied_seq remains 5, then assert
replica_lag[&key].behind_since_epoch is 0. Keep the existing equality case and
verify the less-than case explicitly.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 2e7984ac-c962-4ab7-9b7d-bbea30de7334

📥 Commits

Reviewing files that changed from the base of the PR and between b6b10b1 and b360f1a.

📒 Files selected for processing (12)
  • src/api.rs
  • src/api/import.rs
  • src/api/promote.rs
  • src/benchmark/compare.rs
  • src/benchmark/compare/tests.rs
  • src/embedding.rs
  • src/evalset.rs
  • src/metrics.rs
  • src/metrics/record.rs
  • src/registry/embeddings.rs
  • src/registry/embeddings/gloss_tests.rs
  • tests/http_api/promote.rs

Comment thread src/api/import.rs
Comment thread src/metrics.rs
… test

CodeRabbit on #521:

- New golden wire fixture (import_refusal_durable_prefix) + contract
  test pinning the /import refusal envelope's integrity/durable_batches
  — recorded from the deterministic mid-stream rejection, since the
  group-restore Timeout arm only fires when the deadline dies in the
  unhittable window between batch loop and group phase; that arm's
  field set stays pinned by the api.rs unit test. `response.integrity`
  joins shapes.json's enums.
- The replica-age test now also drives shipped_seq strictly below
  applied_seq, so a `>=` → `==` mutant in note_replica_shipped's
  caught-up arm no longer survives.

Claude-Session: https://claude.ai/code/session_011NozdDS9JqgCpi9Z3wo4Pd
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.

codebase audit: 8 correctness/robustness fixes (promote cap, embeddings tombstone fence, ほか)

1 participant