[ドラフト縮小 2/7] ドラフトの選定順を「継続期間 × 実装量」へ変更しノイズ判定を付与 - #581
Conversation
📝 WalkthroughWalkthroughThe resume-draft mapper returns deterministic noise verdicts and ranks repositories by active duration, language byte volume, push time, and full name. Tests cover thresholds, topic normalization, invalid dates, tie-breaking, and candidate retention. ChangesResume draft repository selection
Estimated code review effort: 3 (Moderate) | ~20 minutes 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
ADR-0026 決定 3。select_repos の第 1 キーが最終 push 日時だったため、 「昨日 README を直しただけのチュートリアル」が「作り込んで完成させた本命」に 勝っていた。継続期間を主キーに据え、直近性はタイブレークへ降格する。 - select_repos: 継続期間(pushed_at − created_at)→ 言語バイト合計 → 最終 push 日時 → full_name の段階比較に変更。重み付き和や積は係数の恣意性が 入るため採らない。stars は判別力が無いので使わない(ADR-0026 決定 3) - 実装量は #561 で永続化した language_bytes_total を参照する - evaluate_noise を追加。継続期間が閾値未満 / 学習用途 topics をデフォルト 非選択にし、理由を返す。topics は小文字化 + 区切り除去して完全一致で判定 - 機械は候補を落とさない。判定はデフォルト選択状態と理由表示にのみ影響させ、 select_repos の結果からは除外しない(ADR-0026 決定 2) - mapper.py を [tool.mutmut] only_mutate に追加 TDD: 並び順・ノイズ判定それぞれで red('o/tutorial' != 'o/flagship' / assert True is False)を確認してから実装した。閾値・語彙・スコア式は mapper.py の定数が正本で、ADR には数値を複製していない。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
0b4d9cc to
2a4bd58CompareNote GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer. |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 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 `@backend/app/services/agent/resume_draft/mapper.py`:
- Around line 93-94: Update the timestamp parsing in the mapper around created
and pushed so it parses complete repository timestamps rather than slicing to
dates, then calculate duration as pushed_at minus created_at. Add a boundary
test covering a sub-day difference that falls just below the 30-day threshold.
🪄 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: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 21da54b8-e4e9-4da2-ab26-676f9b458b66
📒 Files selected for processing (3)
backend/app/services/agent/resume_draft/mapper.pybackend/pyproject.tomlbackend/tests/test_resume_draft_mapper.py
🚧 Files skipped from review as they are similar to previous changes (2)
- backend/pyproject.toml
- backend/tests/test_resume_draft_mapper.py
| created = date.fromisoformat(repo.created_at[:10]) | ||
| pushed = date.fromisoformat(repo.pushed_at[:10]) |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Calculate the duration from complete timestamps.
repo.created_at[:10] and repo.pushed_at[:10] discard the time component. A repository created at 2026-06-01T23:59:00Z and pushed at 2026-07-01T00:00:00Z has a duration of 29 days and 1 minute. The current code returns 30 days and incorrectly selects it by default at the 30-day threshold.
Parse the complete timestamps before subtraction. Add a sub-day boundary test.
Based on PR objectives, the duration is pushed_at − created_at.
🤖 Prompt for 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.
In `@backend/app/services/agent/resume_draft/mapper.py` around lines 93 - 94,
Update the timestamp parsing in the mapper around created and pushed so it
parses complete repository timestamps rather than slicing to dates, then
calculate duration as pushed_at minus created_at. Add a boundary test covering a
sub-day difference that falls just below the 30-day threshold.
yusuke0610
commented
Aug 5, 2026
本 PR の内容は #585 に取り込まれ、main へマージ済みのためクローズします。 #585 には本 PR のコミットに加えて、本 PR で CodeRabbit が指摘した「 コンフリクト表示について: #585 が squash マージされたため本 PR の Generated by Claude Code |
#585(PR #581 相当)が main に squash マージされ、同じ #562 の実装が両側に 別コミットとして入ったためコンフリクトしていた。 - mapper.py / test_resume_draft_mapper.py: 本ブランチ側を採用した。main 側の select_repos / evaluate_noise は本ブランチの rank_repos / evaluate_default_selection / build_candidates に置き換わっており、候補一覧 API・ 選択 UI がこちらの API に依存しているため - ただし main 側にしか無かった修正(継続期間の時刻成分切り捨て / PR #581 の CodeRabbit 指摘)は本ブランチの duration_days へ移植した。_parse_datetime を 追加して UTC の aware datetime で減算する。日粒度でよい「参画中」判定は _parse_date のまま残す - 移植分のテスト 2 件(閾値直下 29 日 1 分の境界 / タイムゾーン混在表記)を 本ブランチの evaluate_default_selection の契約に合わせて追加した - pyproject.toml: only_mutate の同一エントリで、コメント文言のみ本ブランチ側を採用 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KaqnCny4wsD6AkBkJeTEEV
Closes#562
概要
ADR-0026 決定 3。
select_reposの第 1 キーが最終 push 日時の降順だったため、「昨日 README を直しただけのチュートリアル」が「半年前に作り込んで完成させた本命」に勝っていた。チュートリアル・todo アプリ・写経リポジトリが上位を占めうる状態を解消する。変更内容
1. 選定順(
select_repos)pushed_at − created_at)language_bytes_totalrepo_technologiesからの都度算出をやめた)pushed_atfull_name昇順重み付き和や積は採らなかった。係数の恣意性が入り、「継続 1000 日 × 1KB」と「10 日 × 100KB」が並んでしまう。段階比較なら「まず続いたか、次に作り込んだか」という判断順を素直に表せる。
stars は使わない(ADR-0026 決定 3。個人開発では本命でも 0〜1 が普通で判別力が無い)。
2. ノイズ判定(
evaluate_noise/ 新規)NoiseVerdict(selected_by_default: bool, reasons: tuple[str, ...])を返す純関数。topics は小文字化 + 区切り除去して完全一致で判定する。
hands-on/Hands_On/HANDSONを同一視しつつ、部分一致は採らない(sample-api-serverのような本命を誤判定するため)。機械は候補を落とさない(ADR-0026 決定 2)。本判定は UI のデフォルト選択状態と理由表示にのみ影響させ、
select_reposの結果からは除外しない。専用テストで「判定が結果件数を変えない」ことを固定している。3. 定義事項
issue が「本 issue で定義しテストで固定する」としていた項目を確定した。正本は
mapper.pyの定数で、ADR に数値は複製していない。language_bytes_total(単一フィールド・重みなし)threshold_days=で注入可)tutorialpracticesamplestudylearninghandsonexampledemoplaygroundboilerplate-_除去 → 完全一致full_name昇順で一意4. mutmut スコープ
backend/pyproject.tomlの[tool.mutmut] only_mutateにresume_draft/mapper.pyを追加した。以降この経路はmake lint-tddの対象になる。TDD(ADR-0019)
2 サイクル実施し、いずれも red の失敗出力を確認してから実装した。
At index 0 diff: 'o/tutorial' != 'o/flagship'assert True is False/assert [] == ['継続期間が短い', '学習用途の topics']2 サイクル目は関数未定義で collection error になったため、
.claude/rules/common/tdd.mdの指示(collection error はテスト自体の不備)に従い最小スタブを置き直し、振る舞いで落ちる red を確認してから green へ進んでいる。テストは 30 件 pass。旧契約(
pushed_at第 1 キー)を固定していた既存テスト 2 件は新契約へ置き換え、旧契約を固定化したテストは残していない。検証
make ci(lint-tdd含む): pass注意点
evaluate_noiseは現時点で呼び出し元が無い。issue [ドラフト縮小 2/7] backend: ドラフトの選定順を「継続期間 × 実装量」へ変更しノイズ判定を付与 #562 の作業項目として先行実装しており、消費するのは [ドラフト縮小 4/7] backend: 候補一覧 API と選択付きドラフト生成 #564(候補一覧 API)・[ドラフト縮小 5/7] web: リポジトリ候補の選択 UI #565(選択 UI)_LEARNING_TOPICSにsample/demo/exampleを含めたため、これらを付けた本命が誤ってデフォルト非選択になりうる。ただし候補からは落ちず理由も表示されるので人間が覆せる。語彙は運用してからの方が精度が出るため現時点では調整しない🤖 Generated with Claude Code
Summary by CodeRabbit