Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ tree-sitter-python = "0.25"
rusqlite = { version = "0.31", features = ["bundled"] }
reqwest = { version = "0.12", default-features = false, features = ["blocking", "json", "rustls-tls"] }
toml = "0.8"
tar = "0.4"
flate2 = "1"

[dev-dependencies]
tempfile = "3"
Expand Down
452 changes: 452 additions & 0 deletions dev-reports/design/issue-77-design-policy.md

Large diffs are not rendered by default.

6 changes: 6 additions & 0 deletions dev-reports/issue/77/issue-review/hypothesis-verification.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# 仮説検証レポート - Issue #77

## 結果: スキップ

Issue #77 は新機能提案(インデックス共有モード)であり、仮説・原因分析の記載はありません。
仮説検証フェーズをスキップします。
1 change: 1 addition & 0 deletions dev-reports/issue/77/issue-review/original-issue.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"body":"## 概要\n\nCI/CDパイプラインやチーム共有サーバーでインデックスを事前生成し、チームメンバーが再利用できる仕組みを提供する。\n\n## 背景・動機\n\n大規模リポジトリでは `commandindex index` の初回実行に時間がかかる。CIでインデックスを事前生成し、チームメンバーがダウンロードして利用できると、オンボーディングや日常利用が効率化する。\n\n## 提案する解決策\n\n### インデックスのエクスポート/インポート\n\n```bash\n# インデックスをtar.gzにエクスポート\ncommandindex index --export index-snapshot.tar.gz\n\n# エクスポートされたインデックスをインポート\ncommandindex index --import index-snapshot.tar.gz\n\n# インデックスの整合性チェック\ncommandindex status --verify\n```\n\n### CI連携例\n\n```yaml\n# GitHub Actions\n- name: Build CommandIndex\n run: |\n commandindex index\n commandindex index --export /tmp/commandindex-snapshot.tar.gz\n\n- name: Upload artifact\n uses: actions/upload-artifact@v4\n with:\n name: commandindex-snapshot\n path: /tmp/commandindex-snapshot.tar.gz\n```\n\n### エクスポートフォーマット\n\n- `.commandindex/` ディレクトリをtar.gzで圧縮\n- `state.json` にエクスポート時のメタデータ(コミットハッシュ、タイムスタンプ)を追加\n- インポート時にコミットハッシュの一致を確認(不一致の場合は警告)\n\n### --verify オプション\n\n- tantivy インデックスの整合性チェック\n- `manifest.json` とファイルシステムの一致確認\n- `symbols.db` のスキーマバージョン確認\n\n## 受け入れ基準\n\n- [ ] `--export` でインデックスをtar.gzにエクスポートできる\n- [ ] `--import` でインデックスをインポートできる\n- [ ] インポート後の検索が正常に動作する\n- [ ] `status --verify` でインデックスの整合性チェックができる\n- [ ] コミットハッシュ不一致時に警告メッセージが表示される\n- [ ] cargo test / clippy / fmt 全パス\n\n## 依存 Issue\n\n- #76 チーム共有設定ファイル","title":"[Feature] インデックス共有モード(--shared / CI連携)"}
81 changes: 81 additions & 0 deletions dev-reports/issue/77/issue-review/stage1-review-context.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
{
"must_fix": [
{
"id": "M1",
"title": "CLIインターフェース設計がサブコマンド構成と不整合",
"detail": "Issueでは `commandindex index --export` / `commandindex index --import` と既存の `index` サブコマンドにフラグを追加する形を提案しているが、既存の `Index` サブコマンドは `--path` と `--with-embedding` のみを持つインデックス構築用コマンドであり、エクスポート/インポートはインデックス構築とは本質的に異なる操作である。--export/--import を index のフラグにすると、--path や --with-embedding との排他制御が必要になり、clap定義が複雑化する。",
"suggestion": "エクスポート/インポートは独立したサブコマンド `commandindex export <OUTPUT_PATH>` / `commandindex import <INPUT_PATH>` として設計するか、`commandindex index export` / `commandindex index import` のようにネストしたサブコマンドにする方が既存のCLI設計パターンと整合する。"
},
{
"id": "M2",
"title": "state.jsonにコミットハッシュのフィールドが存在しない",
"detail": "Issueでは「state.json にエクスポート時のメタデータ(コミットハッシュ、タイムスタンプ)を追加」と記載しているが、現在の IndexState 構造体には git_commit_hash フィールドが存在しない。追加時の後方互換性への影響を考慮する必要がある。",
"suggestion": "IndexState にオプショナルフィールド `#[serde(default)] pub git_commit_hash: Option<String>` を追加するか、エクスポート専用のメタデータファイル(export_meta.json)をアーカイブ内に別途含める設計を明記すべき。"
},
{
"id": "M3",
"title": "セキュリティ: tar展開時のパストラバーサル対策が未記載",
"detail": "信頼できないソースからのtar.gzアーカイブをインポートする場合、パストラバーサル攻撃が成立する可能性がある。受け入れ基準にセキュリティ要件が含まれていない。",
"suggestion": "受け入れ基準に「インポート時、アーカイブ内の全エントリが展開先ディレクトリ内に収まることを検証し、パストラバーサルを検出した場合はエラーで中断する」を追加する。"
}
],
"should_fix": [
{
"id": "S1",
"title": "既存インデックスがある場合のインポート動作が未定義",
"detail": "インポート先に既に .commandindex/ が存在する場合の挙動が未記載。",
"suggestion": "「既存インデックスがある場合は警告を表示し、--force フラグがなければ中断する」を追加する。"
},
{
"id": "S2",
"title": "index_root パスの不整合問題が未考慮",
"detail": "state.json の index_root にはインデックス作成時の絶対パスが保存されるが、インポート先では異なるパスになる。",
"suggestion": "インポート時に index_root をインポート先のパスに自動書き換える処理を仕様に含めるべき。"
},
{
"id": "S3",
"title": "symbols.db と embeddings.db のポータビリティ考慮不足",
"detail": "SQLiteデータベースファイル内のファイルパスが相対パスか絶対パスかによってポータビリティが変わる。",
"suggestion": "エクスポート対象ファイル一覧と各ファイル内のパスが相対パスであることの前提条件を明記する。"
},
{
"id": "S4",
"title": "--verify の検証範囲が曖昧",
"detail": "「manifest.json とファイルシステムの一致確認」が具体的に何を指すか不明確。",
"suggestion": "各チェック項目を具体的に定義する。例: (1) state.json の schema_version 確認、(2) tantivy ディレクトリの存在と読み取り可能性、(3) manifest.json に記載されたファイルの存在確認、(4) symbols.db の schema_version 確認。"
},
{
"id": "S5",
"title": "tar.gz の依存クレート選定が未検討",
"detail": "Cargo.toml に tar/flate2 等の圧縮関連クレートが含まれていない。",
"suggestion": "使用予定のクレート(tar + flate2)を明記する。"
}
],
"nice_to_have": [
{
"id": "N1",
"title": "エクスポートファイルのバージョニング",
"detail": "将来のスキーマ変更に備え、エクスポートファイル自体にフォーマットバージョンを含めると便利。",
"suggestion": "アーカイブ内に export_meta.json を含め、export_format_version, commandindex_version 等を記録する。"
},
{
"id": "N2",
"title": "差分インポートとの連携",
"detail": "インポート後に commandindex update で差分更新できるかどうかが未記載。",
"suggestion": "インポート後に差分更新が正常動作することを確認する旨を追記する。"
},
{
"id": "N3",
"title": "エクスポート/インポートの進捗表示",
"detail": "大規模リポジトリでは圧縮・展開に時間がかかる可能性がある。",
"suggestion": "初期実装ではサイズ表示のみとし、将来的にプログレスバーを追加する。"
},
{
"id": "N4",
"title": "config.local.toml の除外",
"detail": "エクスポート時に個人設定やAPIキーを含む可能性のある config.local.toml を含めるべきでない。",
"suggestion": "エクスポート対象から config.local.toml を明示的に除外する旨を記載する。"
}
],
"summary": "Issue #77 は大規模リポジトリでのオンボーディング効率化という明確な価値を持つ良いFeatureリクエストである。ただし、(1) CLIインターフェース設計の不整合、(2) state.jsonへのコミットハッシュフィールド追加方針、(3) tar展開時のセキュリティ対策の3点が必須修正。加えて、index_rootの環境間差異、既存インデックスの上書きポリシー、--verifyの検証範囲、依存クレートの選定等の明確化が推奨される。"
}
20 changes: 20 additions & 0 deletions dev-reports/issue/77/issue-review/stage2-apply-result.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"stage": 2,
"applied_fixes": [
{"id": "M1", "action": "CLIインターフェースを独立サブコマンド (export/import) に変更"},
{"id": "M2", "action": "export_meta.json をアーカイブ内に含める設計に変更、state.jsonへの直接変更を回避"},
{"id": "M3", "action": "セキュリティ要件セクションを追加、受け入れ基準にパストラバーサル検出を追加"},
{"id": "S1", "action": "既存インデックスがある場合の動作セクションを追加、--force フラグ追加"},
{"id": "S2", "action": "インポート時の index_root 自動書き換えを仕様に追加"},
{"id": "S3", "action": "エクスポート対象ファイル一覧テーブルを追加、パス形式を明記"},
{"id": "S4", "action": "--verify の各チェック項目を具体的に定義"},
{"id": "S5", "action": "依存クレート(tar + flate2)セクションを追加"},
{"id": "N1", "action": "export_meta.json にフォーマットバージョンを含める設計に採用"},
{"id": "N4", "action": "config.local.toml の除外を明記"}
],
"deferred": [
{"id": "N2", "reason": "差分インポートは将来のエンハンスメントとして別Issue化が適切"},
{"id": "N3", "reason": "進捗表示は初期実装のスコープ外"}
],
"issue_updated": true
}
81 changes: 81 additions & 0 deletions dev-reports/issue/77/issue-review/stage3-review-context.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
{
"must_fix": [
{
"id": "M1",
"title": "tantivy インデックスの export/import 後の整合性検証が必要",
"detail": "tantivy の meta.json やセグメントファイルが export/import 後に正常にオープンできるかの検証が必須。",
"suggestion": "統合テストを追加し、export → import 後に tantivy インデックスが開けること・検索が動作することを検証する。"
},
{
"id": "M2",
"title": "symbols.db / embeddings.db 内のパス整合性",
"detail": "SQLite 内のファイルパスは相対パスで格納されているが、index_root 書き換えのみで全検索ロジックが正常動作するか検証が必要。",
"suggestion": "index_root の書き換えのみで動作する設計方針をドキュメント化し、統合テストで検証する。"
},
{
"id": "M3",
"title": "パストラバーサル防止の実装",
"detail": "tar クレートの Archive::unpack はデフォルトでパストラバーサルを防止しない。エントリごとのパス検証が必要。",
"suggestion": "エントリごとに path().starts_with(target_dir) をチェックし、悪意あるアーカイブのテストケースも追加する。"
},
{
"id": "M4",
"title": "cli_args.rs テストへの新サブコマンド検証追加",
"detail": "help_flag_shows_usage テストに export/import の存在検証を追加すべき。",
"suggestion": "テストに .stdout(predicate::str::contains(\"export\")) と import の検証を追加。"
}
],
"should_fix": [
{
"id": "S1",
"title": "status --verify と既存 StatusFormat への影響",
"detail": "run() の関数シグネチャ変更で既存テスト (cli_status.rs 11個) の修正が発生する可能性。",
"suggestion": "StatusOptions 構造体を導入し後方互換性を保つ設計を推奨。"
},
{
"id": "S2",
"title": "export_meta.json のバージョン互換性チェック",
"detail": "将来のバージョンアップ時に古いエクスポートをインポートできるよう設計が必要。",
"suggestion": "export_schema_version フィールドを設け、import 時にバージョン互換性チェックを実施。"
},
{
"id": "S3",
"title": "cli/mod.rs へのモジュール宣言追加",
"detail": "export.rs / import.rs を追加する場合、mod.rs への宣言追加が必要。",
"suggestion": "アルファベット順で追加。"
},
{
"id": "S4",
"title": "大規模インデックスのメモリ使用量",
"detail": "tar/gzip のストリーミング API を使用してメモリ使用量を抑制すべき。",
"suggestion": "ストリーミング圧縮/展開を使用する設計にする。"
},
{
"id": "S5",
"title": "--force フラグなしでの既存インデックス保護",
"detail": "import 前に既存インデックスの存在チェックとエラーメッセージが必要。",
"suggestion": "IndexState::exists() でチェックし、明確なエラーメッセージで中断。"
}
],
"nice_to_have": [
{
"id": "N1",
"title": "tar/flate2 は既にトランジティブ依存として存在",
"detail": "lindera-dictionary の build-dependencies として既に依存ツリーに存在。バイナリサイズへの影響は最小限。",
"suggestion": "Cargo.toml に tar = \"0.4\" と flate2 = \"1\" を追加。"
},
{
"id": "N2",
"title": "クロスコンパイルへの影響なし",
"detail": "tar/flate2 は純 Rust クレートでありC依存がないため問題なし。",
"suggestion": "特に対応不要。"
},
{
"id": "N3",
"title": "embeddings.db の export 可否オプション",
"detail": "embeddings.db はモデル依存データであり、異なる環境では意味をなさない可能性がある。",
"suggestion": "デフォルトでは embeddings.db を含めず、--with-embeddings フラグで明示的に含める設計を推奨。"
}
],
"summary": "新規サブコマンド追加が中心で既存機能への影響は低い。最も注意が必要なのは tantivy インデックスの整合性、パストラバーサル防止、index_root 書き換えの3点。依存クレートは既にトランジティブに存在しており、CI/CDへの影響は最小限。"
}
20 changes: 20 additions & 0 deletions dev-reports/issue/77/issue-review/stage4-apply-result.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"stage": 4,
"applied_fixes": [
{"id": "M1", "action": "tantivy インデックスの export/import 後の整合性検証を受け入れ基準に追加"},
{"id": "M2", "action": "SQLite内のパスが相対パスであることの注記を追加"},
{"id": "M3", "action": "セキュリティ要件にエントリごとのパス検証方法と悪意あるアーカイブのテストケースを追記"},
{"id": "M4", "action": "実装上の注意点に cli_args.rs テスト更新を追記"},
{"id": "S1", "action": "StatusOptions 構造体導入の方針を実装注意点に追記"},
{"id": "S2", "action": "export_format_version の互換性チェックを受け入れ基準に追加"},
{"id": "S3", "action": "cli/mod.rs へのモジュール追加を実装注意点に追記"},
{"id": "S4", "action": "ストリーミングAPIの使用をエクスポートフォーマットセクションに追記"},
{"id": "S5", "action": "明確なエラーメッセージ表示を既存インデックス保護セクションに追記"},
{"id": "N3", "action": "embeddings.db をデフォルト除外、--with-embeddings フラグを追加"}
],
"deferred": [
{"id": "N1", "reason": "tar/flate2 のトランジティブ依存情報は依存クレートセクションに注記追加"},
{"id": "N2", "reason": "クロスコンパイル影響なしの注記を依存クレートセクションに追加"}
],
"issue_updated": true
}
9 changes: 9 additions & 0 deletions dev-reports/issue/77/issue-review/stage5-review-context.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"stage": 5,
"status": "skipped",
"reason": "Codex (commandmatedev) がレスポンスを生成しなかったため、Stage 5 をスキップ。Stage 1-4 の Claude opus レビューで十分な品質改善が達成済み。",
"must_fix": [],
"should_fix": [],
"nice_to_have": [],
"summary": "Codex 通常レビュー(2回目)はスキップ。1回目レビュー (Stage 1-4) で Must Fix 7件を全て反映済み。"
}
5 changes: 5 additions & 0 deletions dev-reports/issue/77/issue-review/stage6-apply-result.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"stage": 6,
"status": "skipped",
"reason": "Stage 5 がスキップされたため、Stage 6 もスキップ。"
}
9 changes: 9 additions & 0 deletions dev-reports/issue/77/issue-review/stage7-review-context.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"stage": 7,
"status": "skipped",
"reason": "Codex がレスポンスを生成しなかったため、Stage 7 をスキップ。Stage 3-4 の Claude opus 影響範囲レビューで十分なカバレッジを達成済み。",
"must_fix": [],
"should_fix": [],
"nice_to_have": [],
"summary": "Codex 影響範囲レビュー(2回目)はスキップ。1回目影響範囲レビュー (Stage 3-4) の指摘事項は全て反映済み。"
}
5 changes: 5 additions & 0 deletions dev-reports/issue/77/issue-review/stage8-apply-result.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"stage": 8,
"status": "skipped",
"reason": "Stage 7 がスキップされたため、Stage 8 もスキップ。"
}
Loading
Loading