3 点＋記録を直しました。変更は pi05/run_policy_client.py のみ（未コミット、176
  insertions / 43 deletions）。

  変えた行
     
  行: 239, 257-273
  変更: plan_vias(..., final_raw_index=None)。各中継点に raw_index（actions  
  の何行目を使ったか）を持たせる（codex A1）
  ────────────────────────────────────────                                   
  行: 526-531
  変更: final_raw_index を計算（開閉チャンクは used-1、used==0 なら None、通常は
  used）して plan_vias に渡す                                                
  ────────────────────────────────────────
  行: 545-549
  変更: rec["vias"] のキーを変更: sent/arrived → called / success /          
  retried、raw_index と planned_target を追加（codex A6）                    
  ────────────────────────────────────────
  行: 569 
  変更: 構造変更: if not unsafe and args.execute:
  にして、停止ブロックを送信ループの後ろに 1                                 
  か所だけ置く（計画の検査と送信直前の検査で同じ処理を使うため）。計画が危険なと
  きに確認入力より前で止まる順番は従来どおり
  ────────────────────────────────────────
  行: 588-619
  変更: 中継点ごとに、送る直前に read_angles() → apply_limits(v["raw"], 実測角, 
  …)
  でかけ直し → check_send_safe を通し直す（codex A2）。かけ直しで notes
  が変わったら [LIMIT] step k (実測から): … を表示し、記録の target/notes    
  をかけ直し後に更新。読めなければその点も残りも送らず [WARN] 2 
  行＋rec["arrived"]=False（--auto なら従来の未到達と同じく終了コード 1 で停止）
  ────────────────────────────────────────
  行: 619-625
  変更: 送らない判定を tgt - 実測角 で行う（codex ❌1。--via-stride 0 
  のときは従来どおり計画の Δ）
  ────────────────────────────────────────
  行: 627-647
  変更: 送信後の記録を called/success/retried/actual_after に変更
  ────────────────────────────────────────
  行: 648-655
  変更: 最後の中継点を送らなかった場合も、チャンクの最後の目標について 
  rec["arrived"]（実測との最大差 ≤ 3.0°）と settle を必ず行う（codex ❌2）
  ────────────────────────────────────────
  行: 656-664
  変更: broke のときはグリッパーと executed をスキップ
  ────────────────────────────────────────
  行: 665-690
  変更: 停止ブロック（送信直前の検査で引っかかった場合もここに合流。[ABORT]→記録→
  flush→exit_code=1→h
  の選択→break）

  --via-stride 0 のときは、送る直前の読み直し・かけ直し・再検査・item 3
  の後処理をすべて行いません（今までと同じ動き・新しい停止条件なし）。_send_and_w
  ait_arrival 本体・HOME・SPEED・SEND_WAIT・J4_SAFE・J1_SAFE_MAX・max_move
  の値・plan_chunk・Enter/s/h/q・ドライランは未変更です。

  確認結果（偽の daemon・11 ケースすべて OK）

  OK 1_stride0   OK 2_stride3_used9   OK 3_gripper_at6   OK 3b_gripper_at7
  OK 4_unsafe_middle   OK 5_unsafe_first   OK 6_dryrun
  OK 8_accumulate   OK 9_reclamp_from_actual   OK 10_last_skipped   OK
  11_read_fail_before_send

  8. 0.4° ずつ積み重なる中継点（1 ステップ 0.133°、中継点は累積 +0.4 / +0.8 /
  +1.2 / +1.33）

  step 2  Δ +0.4  送らず (0.5° 以下)      ← 実測は動かないまま
  step 5  Δ +0.8  着いた                   ← 積み重なって 0.5°
  を超えたので送られる
  step 8  Δ +0.4  送らず
  step 9  Δ +0.5  着いた                   ← 最後の点も送られる
  chunk: arrived=True settle=within_tol
  計画の Δ（毎回 0.4°）で見ていた前の版では 4 
  点とも送られず動きが消えていました。

  9. 直前の中継点で手前に止まった場合（j1 が毎回 25° 手前で止まる腕）

  [LIMIT] step 5 (実測から): j1 移動量 +43.0° を ±20° に制限
  via step=5 target=[... 7.0 ...] planned=[... 30.0 ...]
  [LIMIT] step 8 (実測から): j1 移動量 +66.0° を ±20° に制限
  via step=8 target=[... 2.0 ...] planned=[... 48.0 ...]
  target（かけ直し後）と planned_target（計画時）が別々に残り、移動量が実測から
  ±20° に制限されています。

  10. 最後の中継点が重複で送られない場合（開閉が index 6 → step 6 の目標が step 5
  と同値）

  via step=6 raw_index=5 called=False
  chunk: arrived=True settle=within_tol executed=True
  送信は 2 回のままで、チャンクの最後の目標について arrived と settle 
  が記録されています（raw_index=5 が step 6 とずれていることも記録）。

  11. 送る直前の読み取りに失敗

  [VIA   ] step  2  Δ= -3.0 ...  着いた
  [WARN] 送る直前の関節角を読めない. この中継点も残りの中継点も送りません
  [WARN] 未到達. j4 の発熱などを確認してください
  イベント順: 爪を開く → 送信 via02        ← 残り 3 点は送らない
  chunk: arrived=False settle=None executed=False / 終了コード 1 (--auto)

  前回の 7 ケース（stride 0 で送信 1 回・vias キーなし／2・5・8・9
  の順／開閉チャンク／検査で 0 回送信／範囲外からの開始／ドライラン）も引き続き
  OK です。

  判断を 1 つ確認させてください: 読み取り失敗で中断したとき、手動モードでもグリッ
  パーの開閉を行わないようにしました（executed=False）。今の未到達（手動）はグリ
  ッパーまで進みますが、腕の位置が読めず目標にも着いていない状態で爪を動かすのは
  危ないと判断しています。従来どおり爪を動かす方がよければ直します。
