feat: hyp-001 blocked_by フィールド — 昇格停止装置の構造的固定 - #17
Conversation
- hyp-001.md frontmatter に blocked_by: [{id: DLW-55-56-yanase-verification, ...}] を追加
- blocks: promotion_to_verified(candidate→verified の昇格をブロック)
- condition: 柳瀬訳 DLW 55/56 の直接照合が完了するまで
- mechanism_mapping.py: blocked_by を読み込み、promotion_decision に
blocked_by / block_note フィールドを付与
- verified への昇格が検討される状況でも、blockerが残っていれば警告を出力
セッション跨ぎで固定文が風化するリスクへの対処:
固定文をノートに残すだけでなく、frontmatter の機械可読フィールドに移動し、
promotion_decision の出力に反映させる構造にした。
https://claude.ai/code/session_017WKYFbVsWhWZA3M8Jc1eKs
There was a problem hiding this comment.
Code Review
This pull request introduces a blocking mechanism to prevent hypotheses from being promoted to a verified status if they have unresolved blockers. Specifically, it adds a blocked_by field to hyp-001.md and implements the blocking logic in mechanism_mapping.py. Feedback on the changes highlights a potential TypeError crash if the blocked_by field is empty (parsed as None) in the YAML file, and suggests defensive coding practices to safely handle the parsed data structure.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| blocked_by = hypothesis.get("blocked_by", []) | ||
| promotion_blockers = [ | ||
| b for b in blocked_by | ||
| if b.get("blocks") == "promotion_to_verified" | ||
| ] | ||
| if promotion_blockers and promotion.get("to") not in ( | ||
| PromotionTarget.STAY_EXPLORATION.value, | ||
| PromotionTarget.REJECT.value, | ||
| ): | ||
| promotion["blocked_by"] = [b["id"] for b in promotion_blockers] | ||
| promotion["block_note"] = "; ".join( | ||
| b.get("description", b["id"]) for b in promotion_blockers | ||
| ) |
There was a problem hiding this comment.
YAMLのパースにおいて、blocked_by: のようにキーのみが定義されて値が空(null)の場合、hypothesis.get("blocked_by", []) は None を返します。この場合、後続のリスト内包表記で TypeError: 'NoneType' object is not iterable が発生してクラッシュする危険性があります。
また、blocked_by の各要素が辞書型(dict)であることを保証し、かつ "id" キーが存在しない場合の KeyError を防ぐために、安全なゲッター(.get())を使用し、型チェックを行う防衛的コーディングを推奨します。
blocked_by = hypothesis.get("blocked_by") or []
if not isinstance(blocked_by, list):
blocked_by = []
promotion_blockers = [
b for b in blocked_by
if isinstance(b, dict) and b.get("blocks") == "promotion_to_verified"
]
if promotion_blockers and promotion.get("to") not in (
PromotionTarget.STAY_EXPLORATION.value,
PromotionTarget.REJECT.value,
):
promotion["blocked_by"] = [b.get("id") for b in promotion_blockers if b.get("id")]
promotion["block_note"] = "; ".join(
b.get("description") or b.get("id") or "unknown" for b in promotion_blockers
)YAML で `blocked_by:` のみ定義されると None に parse される。
`hypothesis.get("blocked_by", [])` は None を返すため
後続のリスト内包表記で TypeError が発生する。
- `hypothesis.get("blocked_by") or []` で None を空リストに変換
- `isinstance(blocked_by, list)` チェックを追加
- `isinstance(b, dict)` チェックで非辞書要素を除外
- `b["id"]` を `b.get("id")` に置換して KeyError を防止
- `block_note` の fallback を "unknown" に統一
https://claude.ai/code/session_017WKYFbVsWhWZA3M8Jc1eKs
変更内容
問題
「固定文」(hyp-001 remains candidate until Yanase translation of DLW 55/56 is directly verified)をメッセージに残すだけでは、セッションを跨ぐと風化する。次のセッションの AI が文脈を持たない状態で hyp-001 を進行させるリスクがある。
解決策
固定文を 機械可読な frontmatter フィールド に移動し、
mechanism_mappingの出力に反映させる。research/hypotheses/hyp-001.mdresearch_os/tasks/mechanism_mapping.pyrun()がblocked_byを読み込み、promotion_to_verifiedをブロックする blocker が存在する場合、promotion_decisionに以下を付与:昇格解除条件
hyp-001.mdのblocked_byリストから該当エントリを削除するか、blocksフィールドを除去することで解除される。ロックの解除も宣言的に行う。背景
verified:false/unverified_referenceに降格削除ではなく降格、メッセージではなくデータ構造——観測系の汚染履歴を保存し、進行を構造的に止める設計。
https://claude.ai/code/session_017WKYFbVsWhWZA3M8Jc1eKs
Generated by Claude Code