fullseye

同じ段を 4 つの入口が別々に読んでいた

症状

GenSpark 第 53 報(0.2.0 の clone 調査、2026-09-20)。0.2.1 でも再現。

なぜ門が通したか

段の書き方 5 形は api._normalise_stages の docstring に書かれ、run_pipeline の門(第 1 陣)で固定されていた。 しかし段を読む場所は 4 つ(api._normalise_stages / FullseyeEngine.__init__ / diagnose_stages / unified.Pipeline)で、 門は最初の 2 つにしか無かった。GenSpark の設計パターン提案 ②「段の正規化を 1 本に」はこの数え方の指摘で、 [[feedback_count_wrapper_families_not_mechanisms]] と同じ —— 仕組みがあることと、全経路が通ることは別。

直し

  1. engine.stage_name(stage) を唯一の入口に: 文字列 / タプル・リスト / dict(op か name)から op 名だけを 取り出し、外した形は「the op must be a non-empty name: a stage is …, got …」の TypeError。ノブの読み方 (engine は a / b、unified は kwargs)は呼ぶ側に残す。
  2. diagnose_stages は壊れた段を raise せず error 行 に(検証器の答えは Problems 欄に出るべきもの)。
  3. FullseyeEngine.__init__ は名前の取り出しを stage_name に(ValueError の文は同じ 1 文)。
  4. unified.Pipeline は list 段と dict 段 {"op": name, **kwargs} を受け、(op, 3) のような形は「(op, {kwargs})」と言う。 _resolve_op は op 名・UnifiedOp・callable 以外を TypeError で止める(unhashable を利用者に見せない)。

同じ報で分けたもの: N182(apply_cmap の名前)= master で動く / N183 blend_mode のモード名検証順・N184 attempt* の docstring・N187 algo run の --seq 必須 = 候補(低)/ N185 = 第 6 陣で済 / N186 = 非不具合。