====================================================================
依頼 v10b の報告：台帳に会計待ちを足し、時間帯ごとの記録 timeline.csv を足した
2026-10-25 10:48
====================================================================

結論：1・2 章を入れました。組み立ては通っています（54 本・エラー 0）。
Check-in は済みで、**番号は cs:144** です（これが段階Bの unity_cs になります）。
店の回し方は 1 つも変えていません。記録だけ足しました。

確かめ A は、依頼の「Site Run の短い試し」が **できませんでした**
（Unity Editor がプロジェクトを押さえていて、私からは Play に入れません）。
代わりに、数え方のコードを Unity 抜きで走らせて合計が崩れないことを確かめ、
同じ確かめを **回すたびに自動で走る形** にして summary.json と Console に出しました。
3 章 (2)・(3) に書いてあります。


====================================================================
1. 段階Bの台帳に 10 列足した（台帳の版 1 → 2）
====================================================================

直したファイル：Editor/ServiceSimLedger.cs（列の名前と並び・SchemaVersion）
                Editor/ServiceSimStageB.cs（値を入れる所）

足した列（**ledger_schema_version より後ろ**。前の行の列の位置はずれません）:

  pay_wait_mean           Unity の会計待ち（分。site_metrics から）
  site_pay_wait_mean      試算の会計待ち（分。site_result から）
  blocked_wait_mean       Unity の「卓は空いたのに片付けが終わらず待った」（分）
  site_blocked_wait_mean  試算の同じ値
  turn_mean               Unity の「客が帰ってから卓が使えるまで」（分）
  site_turn_mean          試算の同じ値
  clear_wait_mean_s       片付けの仕事が板に載ってから取られるまで（秒・平均）
  clear_wait_max_s        同じく、いちばん長かった秒数
  clear_wait_over_count   同じく、600 秒を超えた数
  pay_job_wait_mean_s     会計の仕事が板に載ってから取られるまで（秒・平均）

  49 列 → 59 列。clear_* / pay_job_* の仕事の名前は StaffAgent.JobKindName から
  取るので、「片付け」「会計」という字をコードに手で書いていません。
  600 秒を超えた片付けが 1 件も無い回は、summary.json にその名前が出ないので 0 を書きます
  （空欄と区別できるように）。

★ 台帳の実体（KIOXIA）の 1 行めも差し替えました。

  追記ガードが「実体のヘッダとコードの列が 1 字でも違えば追記しない」決まりなので、
  実体のヘッダを直さないと 18 回とも台帳に残りません。
  直したのは **1 行めだけ**で、前の 36 行は 49 列のまま触っていません。
  念のため写しを置いてあります。

    /Volumes/KIOXIA/r2r2r-data/service_sim/unity/unity_ledger_v1.csv            （1 行めを 59 列に）
    /Volumes/KIOXIA/r2r2r-data/service_sim/unity/unity_ledger_v1_schema1_backup_20261025.csv（差し替える前の写し）

  前の 36 行は新しい 10 列が無いまま（短い行）です。pandas で読むと空欄（NaN）になります。
  集計の次の版でそこだけ気をつけてください。

あわせて「押す前の確かめ（回さない）」を、依頼 3 章 B 2 のとおりに出るようにしました。
いま押すと、こう出ます:

  台帳: /Volumes/KIOXIA/.../unity_ledger_v1.csv
  台帳にある回（ぜんぶの版）: 36 件
  列（59 列・台帳の版 2）: timestamp,run_folder,…,pay_job_wait_mean_s
  試算の版 (meta.model): v2.8 / 店の形の版 (meta.layout_generation): 8a5b2f6a016a
  条件: 6 件 / レジ: 1 つ（6条件とも同じ）
  合わないもの: なし
  Unity の版: cs:144（…）
  この版の18回: まだ 18 回 / 済 0 回
    01. fam_p1・ロボット 2 台・種 0 … まだ
    02. fam_p5・ロボット 2 台・種 0 … まだ
    …（18 行）


====================================================================
2. 時間帯ごとの記録（新しいファイル timeline.csv）
====================================================================

新しいファイル：Experiment/TimelineLogger.cs
直したファイル：Experiment/ExperimentRunner.cs（60 秒ごとに数えて書き出す）
                Service/ServiceOps.cs（仕事板を読むだけの Jobs を足した）
                Experiment/TripLogger.cs（summary.json に timeline_check を足した）

店の中の時間で 60 秒ごとに 1 行。来客が始まってから（サイトの条件では t_s = 0）
全員が店を出るまで。そのコマの様子をそのまま数えます（平均にしません）。
段階Bと Site Run で同じ作りで、1 回の出力フォルダに 1 つできます。

列（24 列。condition_id と seed を先頭に付けて、ほかの CSV とそろえました）:

  condition_id,seed,t_s,arrived,waiting_groups,seated_groups,
  pay_waiting_seat,pay_in_line,
  tables_free,tables_dirty_untaken,tables_clearing,
  board_guide,board_serve,board_call,board_pay,board_clear,
  staff_idle,staff_guide,staff_serve,staff_call,staff_pay,staff_clear,staff_rescue,
  robots_busy

数え方の決め方:

  卓は TableSlot の中身で 4 つに分けます（取りこぼし・二重数えが出ない形）
    tables_free          groupId が無く、片付け中でもない（TableSlot.Free）
    tables_dirty_untaken 片付け中で、片付けの仕事を **誰も取っていない**
                         ＝ふつうの片付け待ち。v10 の B で平均 511 秒だった所
    tables_clearing      片付け中で、片付けの仕事をスタッフが取っている
    seated_groups        groupId があり、片付け中でない（組が卓にいる）
  この 4 つを足すと、いつでも卓の数（③42・⑦48）になります。

  会計待ちは 2 つに分けます
    pay_waiting_seat  食べ終えたが、レジの並ぶ点が取れず **席で** 待っている
    pay_in_line       並ぶ点に立っている（会計の最中も入る）

  board_* は「板に載っていて、まだ誰も取っていない」仕事の数。
  staff_* は StaffAgent.All を、仕事なし（待機）と仕事の種類 6 つに分けた人数。
  robots_busy は robot_util と同じ見方（待機場所の Idle と、往復を終えた Done は数えない）。

  seated_groups を「組」ではなく「卓」から数えているのは、
  合計がいつでも卓の数になる形にしておきたかったからです。
  組と卓は 1 対 1 なので数は同じです（案内の途中の組も、卓を押さえているので入ります）。


====================================================================
3. 確かめ A
====================================================================

(1) 組み立て

Unity 同梱の csc（Roslyn・2022.3.62f3）で ServiceSim の .cs を 54 本ぜんぶ組み立てました。
エラー 0・警告 0。Unity に切り替えたら Console は見てください。

(2) 合計の確かめ（Unity 抜きで走らせた）

依頼の「Site Run の短い試し」は、Unity Editor がプロジェクトを押さえていて
私からは Play に入れないので、できませんでした。かわりに、
**ServiceSim を組み立てた dll の数え方をそのまま呼ぶ試し** を書いて走らせました。
数える所は MonoBehaviour を触らない作りにしてあるので、Unity 無しで動きます。

  試しのファイル（残してあります）:
    /private/tmp/claude-501/-Users-shimazueiichi/d0d60c2a-d756-4c07-a05b-13221e3d700f/scratchpad/TimelineCheck.cs … 卓・板・スタッフの数え方と、timeline.csv の書き出し
    /private/tmp/claude-501/-Users-shimazueiichi/d0d60c2a-d756-4c07-a05b-13221e3d700f/scratchpad/LedgerCheck.cs   … 台帳の追記ガードと、前の行が読めるか

  TimelineCheck の結果（32 件ぜんぶ OK）:
    1. 卓の4つの分け方の合計（42卓を、起こりうる4つの形にばらして入れた）
         座 16 / 空 10 / 片付け待ち 9 / 片付け中 7 = 42        ← 卓の数と同じ
       ・片付け中なのに仕事が板に無い卓（卓を空けた直後の形）も、片付け待ちに入って
         取りこぼしません
       ・同じ卓に片付けの仕事が 2 件ある形（あきらめて戻ったあとに取られた形）でも
         二重に数えません
       ・案内・料理・呼び出し・会計・立ち往生の仕事は、卓の数え方に混ざりません
    2. 板の数え方：取られている仕事は数えない（案内1・料理1・呼び出し1・会計1・片付け9）
    3. スタッフの合計：待機＋仕事の種類 6 つで、1 人ごとに合計がちょうど 1 増える。
       StaffJobKind の範囲の外の値（6〜9）を入れても崩れない
       （仕事の種類が増えても合計が合うように、知らない種類は待機に入れています）
       スタッフ4人の形でも合計 4
    4. timeline.csv を 6 行 書いて、6 行ぜんぶ 卓 42・スタッフ 4 で合った。
       列は 24・1 行めは TimelineLogger.Header と同じ

  書いた timeline.csv（**中身は私が作った数字。実際に回した値ではありません**。
  列の形と、合計が合うことを見るためのものです）:

    condition_id,seed,t_s,arrived,waiting_groups,seated_groups,pay_waiting_seat,pay_in_line,tables_free,tables_dirty_untaken,tables_clearing,board_guide,board_serve,board_call,board_pay,board_clear,staff_idle,staff_guide,staff_serve,staff_call,staff_pay,staff_clear,staff_rescue,robots_busy
    fam_p1_s4_r0_a42,1,0,0,0,0,0,0,42,0,0,1,0,0,0,0,4,0,0,0,0,0,0,0
    fam_p1_s4_r0_a42,1,60,14,1,8,0,1,33,1,0,1,0,0,0,1,2,1,1,0,0,0,0,0
    fam_p1_s4_r0_a42,1,120,28,2,20,1,1,18,3,1,1,1,0,0,3,1,1,1,0,0,1,0,1
    fam_p1_s4_r0_a42,1,180,42,3,34,2,1,0,6,2,1,1,0,0,6,0,1,1,0,1,1,0,1
    fam_p1_s4_r0_a42,1,240,56,4,37,3,1,0,4,1,1,1,0,0,4,0,1,1,0,1,1,0,1
    fam_p1_s4_r0_a42,1,300,70,5,30,4,1,9,2,1,1,1,0,0,2,0,1,1,0,1,1,0,1

  この試しは空まわりではありません。はじめに書いた試しのデータが
  座 38 ＋ 片付け待ち 4 ＋ 片付け中 1 = 43 になっていて、確かめがその 1 行を
  「合わない」と見つけました（直してから上の結果になっています）。
  「卓の数を 41 と言うと 6 行ぜんぶ合わないと出る」ことも確かめました。

  LedgerCheck の結果（9 件ぜんぶ OK）:
    ・台帳の 1 行めが ServiceSimLedger.HeaderLine と 1 字も違わない → 追記ガードが通る
    ・前の行は 36 行・ぜんぶ 49 列のまま（書き換えていない）
    ・列が 10 増えても、前の行の照合キーを読める
      （cs:143 の ③0台・種1 を引ける ／ cs:144 は引けない＝18回とも「まだ」になる）

(3) 回すたびに自動で走る確かめ（短い試しの代わり）

同じ合計の確かめを、回すたびに走るようにしました。
summary.json に timeline_check が出ます:

  "timeline_check": {
    "rows": 行数, "step_s": 60, "tables": 42, "staff": 4,
    "bad_table_rows": 0, "bad_staff_rows": 0, "first_bad": "",
    "note": "…"
  }

  bad_table_rows・bad_staff_rows は **どちらも 0 になるはず** です。
  0 でなければ Console に警告を出すので、夜にまとめて回したあとでも気づけます。
  first_bad に、合わなかったいちばん早い行の時刻と中身が入ります。

  ★ お願い：18 回を回したあと、どれか 1 回の summary.json の timeline_check を見て、
    bad_table_rows と bad_staff_rows が 0 であることを確かめてください。
    依頼の「30 分の短い試し」を私がやれなかった分の埋め合わせです。
    先に確かめておきたいときは、Run All の前に
    ServiceSim/Site Run/③ スタッフ4人・ロボット0台 を 1 回だけ押してください
    （trialSeed は v10 で 1 にしてあるので、種1 で回ります）。


====================================================================
4. Check-in
====================================================================

  番号：**cs:144**（これが段階Bの unity_cs になります）
  入れたもの（v10 の分がまだ入っていなかったので、v10 と v10b を一緒に入れました）:
    Service/GroupManager.cs        逃がし弁の数え方（v10 の 1）・tableForceFreed
    Service/ServiceOps.cs         板で待った最大と 600 秒超え（v10 の 2）・Jobs（v10b の 2）
    Experiment/SimParams.cs       版とレジの数の突き合わせ（v10 の 0）
    Experiment/SimParams.asset    expectModel: v2.8 / registersSupported: 1
    Experiment/serving-robot-params.json  試算 v2.8
    Experiment/ExperimentRunner.cs pay_wait_mean・timeline の数え取りと書き出し
    Experiment/TripLogger.cs      summary.json（pay_wait_mean・job_wait_*・timeline_check）
    Experiment/TimelineLogger.cs  新しい（＋ .cs.meta も作って一緒に入れました）
    Experiment/ExperimentPlan.asset trialSeed: 1（v10 の B のため）
    Editor/ServiceSimLedger.cs    台帳の 10 列・版 2
    Editor/ServiceSimStageB.cs    新しい列の値・押す前の確かめを詳しくした

  入れなかったもの（私の分ではないので触っていません）:
    Assets/ServiceSim/Store/Materials/Mat_MonitorBoard.mat（と .meta）… 置いてあるだけ 2 件
    このまま Run All を押すと、台帳の pendingNote が
    「保留あり 2 件（管理下 0 件・置いてあるだけ 2 件）」になります。
    回り方には効きませんが、気になるなら先に入れるか消すかしてください。

  TimelineLogger.cs.meta は私が作りました（TripLogger.cs.meta と同じ形・新しい guid）。
  Unity に切り替えたとき、この .meta がそのまま使われます
  （Unity が作り直すと guid が変わって、入れ直しになるので先に作っています）。


====================================================================
5. エイイチにお願いすること
====================================================================

1. Unity に切り替える（新しい .cs が取り込まれる）。Console に赤い字が無いか見る。

2. ServiceSim → Stage B → 押す前の確かめ（回さない）。
   1 章の終わりに書いた形で出るはず。次を確かめてください。
     試算の版 v2.8 ／ 店の形 8a5b2f6a016a ／ レジ 1 つ（6条件とも同じ）
     合わないもの: なし
     Unity の版: cs:144
     この版の18回: まだ 18 回 / 済 0 回（18 行とも「まだ」）
     列（59 列・台帳の版 2）
   ここで「回せません」と出たら押さないで、そのまま見せてください。

3.（できれば）ServiceSim → Site Run → ③ スタッフ4人・ロボット0台 を 1 回。
   出力の timeline.csv と summary.json の timeline_check を見て、
   bad_table_rows・bad_staff_rows が 0 であることを確かめる。
   ※ これを飛ばして 4 に進んでもよいです。そのときは 18 回のあとで見てください

4. ServiceSim → Stage B → Run All（18回）。夜にまとめて回して大丈夫です。
   1 回ごとに Play を出入りし、caffeinate でスリープを止めます。
   1 回の実時間の上限は 40 分。途中で止めても、もう一度押せば続きから回ります。


====================================================================
6. 直したファイルの一覧
====================================================================

  Assets/ServiceSim/Experiment/TimelineLogger.cs       新しい（時間帯ごとの記録）
  Assets/ServiceSim/Experiment/TimelineLogger.cs.meta  新しい
  Assets/ServiceSim/Experiment/ExperimentRunner.cs     60 秒ごとに数える・書き出す・合計の確かめ
  Assets/ServiceSim/Experiment/TripLogger.cs           summary.json に timeline_check
  Assets/ServiceSim/Service/ServiceOps.cs              Jobs（仕事板を読むだけ）
  Assets/ServiceSim/Editor/ServiceSimLedger.cs         台帳の 10 列・版 2
  Assets/ServiceSim/Editor/ServiceSimStageB.cs         新しい列の値・押す前の確かめ
  （KIOXIA）unity_ledger_v1.csv                        1 行めを 59 列に。写しを別名で残した

  店の回し方（GroupManager・StaffAgent・ServingRobotController の決まり）は
  1 行も変えていません。


====================================================================
7. 気づいたこと（今回は手を付けていません）
====================================================================

1. v10 の B で「片付けの仕事が取られるまで 平均 511 秒・最大 1145 秒・600 秒超え 37 件」でした。
   timeline.csv の tables_dirty_untaken が、その 511 秒を時間帯ごとにばらして見せる列です。
   ピークのどこで何卓たまっていたかが、これで並べられます。

2. job_wait_* は「板に載ってから取られるまで」なので、取られないまま終わった仕事は
   入りません。v10 で卓を空けるのが 0 になったので、いまはほぼ取りこぼしが無いはずですが、
   打ち切りで止まった回（status が stopped）では、最後まで取られなかった仕事が
   数に入らない点だけ覚えておいてください。

3. 台帳の前の 36 行が 49 列・新しい行が 59 列になります。
   集計の次の版（b1_collect.py）で、列の数で読み分けるか pandas の NaN で済ませるか
   決めてください。私は NaN で済むと思っています。

18 回が終わったら、集計と試算との並べは私がやります。
