037 スコア式を0点に合わせたら逆に必要なものが見えてきた話
ある日、記録すべき内容を読み込んだCCが「タグマッチ 0.8、ハブマッチ 0.3、特性マッチ 0.6——総合 0.62 で T2 確定」と自信満々に書いた瞬間、設計者が顔をしかめた。プロジェクトを断定できるタグが付いていないのに、T2 は「警告つきではあるが自動確定」を意味する。プロジェクト不明の記録が警告なく流れ落ちる——それは誰も望まない挙動だった。
背景には「タグマッチ」という名前から来る思い込みがある。タグが部分一致すれば加点、必須タグが無くても満点に近い数字が出る。当時の CC は機械的に 0.8 を返していた。
設計者は数字をじっと見て、こう言った。「プロジェクトが特定できない記録は T3(LLM 仲裁)に流す設計のはずだ、でしょ」。CC は計算式を見直した。案Aは一行の追加だった——必須タグがどれか一つでも一致していなければ、算出スコアの上限を 0.6 に切る。それだけで、総合値は 0.51 に落ち、T3 へ流れる。
同時に行われたのが重みの再検討だった。タグ・ハブ・特性で 0.4・0.3・0.3 としていた配分は据え置き。タグマッチの影響力は確かに大きいが、それは「タグが在るか否か」という二値判定で動くからだ。特性マッチは特性カタログという動的な表と突き合わせる——両者は別の意味層を見ている。比重を動かしたところで問題1(必須タグ不一致のペナルティ不足)は悪化しない、悪化するのは別の話。だから重みは触らなかった。
もう一つ、ハブマッチの実装で苦労があった。設計書に embed() と cosine_similarity が並ぶ書き方をしていたが、embedding 依存のテストは外部LLMを呼べない環境では動かない。そこで案X——キーワードベースの単純なマッチに切り替え、必須タグ/追加タグの構造をそのまま流用した。意味的類似性は犠牲になるが、まずは動くものを出して運用データを取る。将来は類義語辞書で埋める。
調整後の3ケースで再計算すると、完全一致のケース1は 0.82 で T1、必須不一致のケース2は 0.51 で T3、タグ不一致のケース3は 0.33 で T4。ケース2 だけが意図どおり一段降りる。
スコア式は「最大化の道具」ではなく「早期発見の道具」だったと、この調整は教えた。満点設計の誘惑に負けず、敢えて 0.62 を 0.51 へ沈める——そこに本来やりたかった「プロジェクトの輪郭を曖昧にしない」が宿る。数字を少し下げた日、設計が一番きれいだった。
<details><summary>▶ 技術的にどうなってるか</summary>
compute_tag_match() に必須タグ判定 has_required_match を導入し、False 時に score = min(score, 0.6) のクランプを挿入。重み配分 0.4+0.3+0.3 は維持。ハブマッチは embed ベースから extract_keywords + 必須/追加タグの二段判定に置換(セクション 4 案X)。関連: 01_DECISIONS/claude-code/2026-07-12_ssot-recordマルチ起点再設計-セクション3-データフロー判定アルゴリズム.md / 01_DECISIONS/claude-code/2026-07-11_ssot-recordマルチ起点再設計-01_DECISIONS中心バイアス根絶.md。残課題: T1-T5 閾値の1ヶ月後再評価・LLM 仲裁プロンプト実機検証。
</details>