| 項目 | 内容 | ||
|---|---|---|---|
| 実行環境 | ★Cursor 内の Claude が実装します★(.claude/commands/d-watch.md の役割分担表を参照) |
||
| 実行状態 | ★★完了(2026-09-11)★★ — ★4群すべて実行済み(群1=D-119 / 群2=D-120 / 群3=D-118 / 群4=D-117)。詳細は文末の「実行状態」表★ | ||
| 位置づけ | ★★統合指示書★★ — ★ユーザー指示(2026-09-11)「ZからACまでを一気にできる指示書を作ってください」★に対応する1本です。★★4つの群を頭から順に実行します★★ | ||
| 実行順 | ★★群1 → 群2 → 群3 → 群4(★崩さないこと★。理由は後述「実行順とその理由」)★★ | ||
| 対象 | ★群1★ = docs/handoff/指示書Z_エリア別完了率を実装する.md(★その指示書を頭から実行する★。本書に内容は写しません)/ ★群2★ = docs/handoff/指示書AA_一覧にページ送りを付ける.md(★同上★)/ ★群3★ = ★本書に全部書いてあります★(エラー率の分子を本清掃側にする)/ ★群4★ = ★本書に全部書いてあります★(小さな積み残し3件) |
||
| ★着手前確認★ | ★★なし★★ — ★群1・群2 はそれぞれの指示書が「着手前確認なし」で確定済み★。★群3・群4 は本書の「群3 で決めたこと」「群4 の3件」がすべて確定済み(ユーザー指示 2026-09-11 + 監督判断)★。★★ユーザーの回答を待たずに群1 から通しで実行してよい★★ | ||
| 取得する決定番号 | ★★**着手直前に `grep -nE "^### D-(0\ | 1)[0-9][0-9]" docs/decisions.md \ | tail -3で最終番号を実測すること**★★。★★^### D-0だけでは3桁台(D-100 以降)を拾えない★★。★2026-09-07 にD-068` の二重採番が実際に起きています★。★★本書には見込み番号を書きません★★ — ★必ず自分で実測してから採番すること★。★★群ごとに別の番号を取るか、4群まとめて1つにするかは実行者が決めてよい★★(★群1・群2 の指示書はそれぞれ自前の記録段階を持っているので、その指示書を実行したならその指示書の指示に従って1つ取るのが自然です★) |
| 段階数 | ★群1★ = 指示書Z の段階0〜8(9段階)/ ★群2★ = 指示書AA の段階0〜7(8段階)/ ★群3★ = ★本書の段階3-0〜3-5(6段階。コミットは4つ)★/ ★群4★ = ★本書の段階4-0〜4-2(3段階。コミットは1つ)★ | ||
| 着手前の基準 | ★★着手直前に自分で npm test / npx tsc --noEmit / npm run lint を実行し、その実測値を基準にすること★★。★作成時点の実測(2026-09-11。★★鵜呑みにしない★★): npm test = 45ファイル / 1023テスト(全パス) / tsc = 0 / lint = 0 / db.cleanLogs() = 259件 / db.prechecks() = 27件(precheck 14 / launch_failed 13)★ |
||
| 作成 | 2026-09-11(作成時点の決定事項最終番号 D-116(docs/decisions.md:7291)/ docs/handoff.md の最新は 追記36(docs/handoff.md:3050)/ HEAD = d1b7fec。★着手時に実測すること★) |
実行後はこの表と、文書末尾の「実行状態」表を更新してください。
★この指示書を読んでいるあなたへ★ —
.claude/commands/d-watch.mdの「実装は Cursor 側」は 2つの環境の役割分担です。Cursor の中で動いている Claude は実装担当です。 ★調査や改訂ではなく実装を行ってください。★ ★★途中で止めてよい指示書です★★ — ★群1 だけ終わって群2 に入れなくても、それまでの成果は完結しています★。 ★各群の終わりに「★ここで止めてもよい★」と明記してあります★。
本書は ★★4つの独立した作業を1本の順序に並べた統合指示書★★です。
| 群 | 内容 | 詳細の所在 | 触る場所 |
|---|---|---|---|
| ★群1★ | ★エリア別完了率★(501 仮実装をやめる) | ★★docs/handoff/指示書Z_エリア別完了率を実装する.md(1063行)★★ |
d-watch-api.yaml / lib/types/ / lib/db/ / lib/fixtures/ / ★components/features/detail-log/★ / app/api/clean-logs/[id]/areas/ |
| ★群2★ | ★一覧6画面のページ送り★(201件目以降が見えない) | ★★docs/handoff/指示書AA_一覧にページ送りを付ける.md(993行)★★ |
★lib/i18n.ts★ / components/ui/ / ★components/features/detail-log/★ ほか5画面 |
| ★群3★ | ★エラー率の分子を本清掃側にする★ | ★★本書(後述)★★ | lib/db/report-mapping.ts / lib/db/index.ts / scripts/seed-local-db.ts |
| ★群4★ | ★小さな積み残し3件★ | ★★本書(後述)★★ | lib/judge/kpi.ts(コメント)/ lib/fixtures/clean-logs.ts(比較演算子1つ)/ lib/db/__tests__/clean-log-mapping.test.ts(1ケース追加) |
★★既存の指示書が詳細(期待値表・段階割り・禁止事項・実測手順)を全部持っています★★。 ★本書に二重に書くと、片方だけ直したときに食い違いが生まれます★(★D-103 が禁じた「規則を2箇所に書く」状態★)。
★★群1・群2 でやることは1つだけです — その指示書を頭から実行してください★★。 ★本書の「実行順とその理由」「禁止事項」「群ごとのコミット規律」だけが上乗せされます★。
★★これが本書で一番踏みやすい落とし穴です★★。
lib/i18n.ts / d-watch-api.yaml / lib/types/index.ts / lib/db/report-mapping.ts / components/features/reports/ReportsScreen.tsx が変わっています★★ (★指示書W 段階1・段階7 が ContinuousProblem の型とキーを足し、i18n に3キーを追加しました★)★★対処(必ずやること)★★:
★★各群の段階0 で、その指示書が「実測して控えること」と書いている項目を自分で測り直す★★。 ★★指示書に書かれた行番号をそのまま信じて編集しないこと★★ — ★必ず
grep/Readで現物を見てから編集する★。 ★★数字が指示書と食い違っていても、それだけでは「壊れている」ことにはなりません★★ (★指示書W がその間に入っているため★)。★食い違いの内容を作業メモに控えてから進むこと★。
★群1・群2 の仕様上の分かれ目は、それぞれの指示書の「採る方針」「監督が決めたこと」節で確定済みです★。 ★★本書がそれを上書きすることはありません★★。★食い違ったら、その群の指示書が正★。
群1(エリア別完了率) → 群2(ページ送り) → 群3(エラー率の分子) → 群4(積み残し3件)
| 群 | components/features/detail-log/ |
lib/i18n.ts |
|---|---|---|
| ★群1(Z)★ | ★★触る★★(AreaModal の配線。段階6) |
触る可能性あり |
| ★群2(AA)★ | ★★触る★★(F-02 清掃詳細ログにページ送りを入れる。段階3) | ★★触る★★(段階2 で共通部品の文言を足す) |
components/features/detail-log/ は、 群1 がモーダルの中身を作り替え、群2 が一覧の下にページ送りを足す★。 ★片方を後から当てると、マージではなく「読み直して当て直す」作業になります★lib/i18n.ts は指示書W が直近で3キー足したばかり★★(docs/decisions.md の D-116)。 ★群2 の段階2 はここに追記します★ — ★行番号を実測してから触ること★lib/db/report-mapping.ts / lib/db/index.ts / scripts/seed-local-db.ts が中心★lib/judge/kpi.ts(コメントのみ)/ lib/fixtures/clean-logs.ts(演算子1つ)/ lib/db/__tests__/clean-log-mapping.test.ts(テスト追加)★components/)とは重なりません★★★群3 の段階3-1(シード)と群4 の②(lib/fixtures/clean-logs.ts の比較演算子)は、 どちらも「検証データ」まわりですが ★★別のファイル・別の目的★★です★ — ★混ぜないこと★。 ★★群3 が触るのは scripts/seed-local-db.ts(ローカルDB)、群4 が触るのは lib/fixtures/clean-logs.ts(USE_FIXTURES 用)★★。
npx tsc --noEmit / npm run lint / npm test の3つが通ること★★ (★群の中の各段階でも通すこと。段階割りはそうなるように組んであります★)git add -A 禁止★★(CLAUDE.md §7。★過去に別作業の途中ファイルを巻き込む事故あり★)— ★★必ずファイルパスを明示して git add すること★★docs/decisions.md をコミットするときは git diff docs/decisions.md を先に見ること★★ — ★未コミットの追記が同居していると巻き込みます★(★指示書W で実際に起きた★)git add -A の使用★★ — ★ファイルパスを明示する★(CLAUDE.md §7)prisma/schema.prisma は db pull の生成物)robot_error_reports / control_error_histories の status / comment / responded_at / resolved_at ★以外★への DB 書き込み★★(D-042)。 ★★本書のどの群も、アプリコードから DB に書き込みません★★ (★scripts/seed-local-db.ts はローカル検証用のシードであり、アプリの書き込みではない★)lib/config/ から読む★(CLAUDE.md §7)。 ★群3 で CLEAN_TIMETABLE_PRECHECK.main を 0 と直書きしないこと★CLAUDE.md §4.3)lib/fixtures/ の既存の値を変更すること★★ — ★群4 ② で変えるのは生成式の比較演算子1つだけで、出力される値は1件も変わりません★ (★変わったら手が滑っています。段階4-1 の実測で確認します★)kpiFromSummaryRatios() / errorBreakdownRowsFromSummary() / facility_*_summaries を読む経路★。 ★群3 は当期(詳細テーブル由来)だけを直します★prechecks())の分子を変えること★★ — ★群3 の「変えないもの」を参照★CLAUDE.md §4.8)README.md / docs/code-map.md / docs/handoff/管理画面_設計検討_20260910.md / ★.claude/worktrees/**★scripts/tmp-measure.ts が残った★。★一時ファイルは作業用ディレクトリに置き、 終わったら消すこと★。★★成功時にも必ず process.exit(0) を書くこと★★ (★Prisma の接続が残ってハングした事故あり★)CLAUDE.md §7)— ★止めて確認を求める★★★
docs/handoff/指示書Z_エリア別完了率を実装する.mdを頭から実行してください。★★
★本書はその内容を写しません★(重複させると片方だけ直したときに食い違うため)。
| 段階 | 内容 | コミット |
|---|---|---|
| 段階0 | 前提の確認と実測 | なし |
| 段階1 | d-watch-api.yaml を直す |
あり |
| 段階2 | 型と純粋関数と期待値表テスト | あり |
| 段階3 | fixtures を追加する | あり |
| 段階4 | データ層(DataSource.areaCompletions()) |
あり |
| 段階5 | APIルート(501 を外す) | あり |
| 段階6 | 画面(AreaModal の配線) |
あり |
| 段階7 | 実測での検証 | なし |
| 段階8 | 記録と push | あり |
★★指示書Z は指示書W より前に書かれています★★(前述)。★次を自分で実測してから段階1 に進むこと★:
# ★決定番号の最終(見込みを書かない)★ grep -nE "^### D-(0|1)[0-9][0-9]" docs/decisions.md | tail -3 # ★指示書Z が挙げている前提決定の行番号(ずれている)★ grep -nE "^### D-(102|103|106|107|109|110|111|112|113|114|115|116) " docs/decisions.md # ★触る予定のファイルの現状(行番号を信じない)★ grep -n "areaCompletions" lib/db/index.ts lib/types/index.ts d-watch-api.yaml ls components/features/detail-log/
d-watch-api.yaml は指示書W 段階1 が ContinuousProblem を触っています★★ — ★行番号がずれます★lib/types/index.ts も同様★★(ContinuousProblem に launch_failed_days が増えています)npm test の件数は指示書Z の記述より増えています★★(★W がテストを足したため★)— ★自分で測った値を基準にすること★npx tsc --noEmit = 0 / npm run lint = 0 / npm test 全パス★★/detail-log のエリアモーダルが 501 を出さなくなっていること★★★★
docs/handoff/指示書AA_一覧にページ送りを付ける.mdを頭から実行してください。★★
★本書はその内容を写しません★。
| 段階 | 内容 | コミット |
|---|---|---|
| 段階0 | 前提の確認と実測 | なし |
| 段階1 | ページ番号の並びを組み立てる純粋関数 | あり |
| 段階2 | 共通部品 Pagination と i18n |
あり |
| 段階3 | 清掃詳細ログ F-02 に入れる(作法を確定させる) | あり |
| 段階4 | summary 系3画面(F-03 / F-06 / F-07) | あり |
| 段階5 | ListResponse 系2画面(F-08 / F-09) |
あり |
| 段階6 | 6画面の実測検証 | なし |
| 段階7 | 記録と push | あり |
# ★i18n は指示書W が直近で3キー足した(D-116)★ — 行番号も件数もずれている grep -c "" lib/i18n.ts grep -n "continuous" lib/i18n.ts # ★群1(指示書Z)が detail-log を触った直後★ — 現物を見てから足すこと ls components/features/detail-log/ grep -rn "per_page\|meta" app/api --include=route.ts | head -30
components/features/detail-log/ は指示書AA が書かれた時点と 違う状態になっています★★ — ★★AA の段階3 に書かれている行番号・コード断片は必ず現物で確かめること★★lib/i18n.ts は指示書W と、場合によっては群1 が触っています★★ — ★末尾に追記する前に構造を見る★npx tsc --noEmit = 0 / npm run lint = 0 / npm test 全パス★★★★ここからは本書に全部書いてあります。参照先の指示書はありません。★★
Q7. robot_error_reports.clean_timetable_id は事前チェックの行と本清掃の行のどちらを指すか
A7. どちらも指しています. ただし事前チェックは本清掃を円滑に実施できるためのものなので,
サマリには含めない, とするのが正しいでしょう.
★★つまり clean_timetable_id は事前チェック行も本清掃行も指しうる。そして エラー率の分子に入れるべきなのは本清掃行を指すものです。★★
| 箇所 | 当期の分子 | 何が起きるか |
|---|---|---|
★reportKpis() / facilityPerformance() の error_rate★ |
★★事前チェック行に紐づくエラーだけ★★ | ★★本清掃行を指すエラーを黙って捨てている★★ |
★errorBreakdown()★ |
★★全件★★(clean_timetable_id を一切見ていない) |
★★事前チェック行のエラーも数えている★★ |
★機序(★実測して裏を取ること★)★:
// lib/db/report-mapping.ts — mainIdByPrecheckId() は 事前チェック行id → 本清掃id の対応表 // errorCountByMainId() は その対応表を引く const mainId = mainIdByPrecheck.get(report.clean_timetable_id.toString()); if (mainId === undefined) continue; // ★★本清掃行を指すエラーはここで落ちる★★
★★clean_timetable_id が本清掃行の id だと、事前チェック行の表には無いので undefined になり continue します★★ — ★例外もログも出ません★。
★errorBreakdown() の側(lib/db/index.ts の当期ブランチ)は countErrorTypesInRange() を呼んでいますが、この関数は clean_timetable_id を 一切参照しません★ — ★★全件数えます★★。
scripts/seed-local-db.ts が事前チェック行にだけエラーを作るため)★質問した時点(第8回 Q7 を出す前)では「clean_timetable_id は事前チェック行を指す」と 仮定して書いたものです★。★その仮定は lib/db/report-mapping.ts の CleanStatsBucket.errorCount の docstring に明記されています★:
/** エラー発生回数(事前チェック行に紐づく robot_error_reports の件数) */ errorCount: number;
★★仮定を明記してあったから、回答が来たときに直す場所が特定できました★★。 ★★同じやり方を続けること★★ — ★ただし直した後は古い仮定を残さないこと(後述 決定5)★。
★★「本清掃行(
precheckがCLEAN_TIMETABLE_PRECHECK.main)を指すrobot_error_reportsの件数」★★
clean_timetable_id がその Set にあるものだけ数える」★★clean_timetable_id には dangling(参照先が消えている)値もありうる★ (★prisma/schema.prisma の clean_timetable_id には ★FK も KEY も無い★。 lib/db/index.ts の落とし穴1★)。★★「本清掃行の集合に入っている」という肯定条件で数えること★★errorBreakdown() の当期も同じ定義に揃える★errorBreakdown() の確定期間(サマリ由来)は触りません★★(決定6)clean_timetable_id が null のエラー行は分子に入れない★★現在、3箇所で扱いが違います★:
| 箇所 | 現状の null の扱い |
|---|---|
errorCountByMainId()(率) |
★捨てる★(if (report.clean_timetable_id === null) continue;) |
prechecks()(アラート) |
★捨てる★(scheduled_at を決められないため行が作れない) |
countErrorTypesInRange()(内訳) |
★★数える★★(clean_timetable_id を見ていないので素通り) |
★★3箇所とも「捨てる」に揃えます★★。
★理由★: ★「本清掃行の id の Set に入っているか」で数えると、null は自動的に落ちます★ — ★★特別扱いのコードを足すのではなく、肯定条件の自然な帰結として落ちる形にすること★★。
★★申し送りに残すこと★★: ★facility_id と errored_at を持っているので、 「施設・期間には割り当てられる」— ★★入れる選択肢は技術的にあります★★★。 ★今回は「清掃1回に紐づかないエラーは清掃のエラー率の分子ではない」という理由で捨てます★。
★★これが無いと、直した後のローカル画面のエラー率が一律 0% になり、 「直ったのか壊したのか」が区別できません★★。
CleanStatsBucket.errorCount の docstring を書き換える★★古い仮定(「事前チェック行に紐づく」)を残さないこと★ — ★★次に読む人が両方を信じてしまいます★★ (★指示書Y / 指示書R が同じ理由で「古い記述を残さない」と書いています★)。
facility_error_summaries / kpiFromSummaryRatios() / errorBreakdownRowsFromSummary() はそのまま★start_at の JST 日付」に揃える★countErrorTypesInRange() は detectedAtFromError()(errored_at ?? created_at)で期間を決めています★start_at の JST 日付」に変えます★★CLAUDE.md §4.2)★。 ★分母が清掃を基準にしているのに分子が検知時刻基準だと、深夜清掃が日をまたいだときに 分子と分母が別の期間に入ります★ — ★★分子も清掃を基準にするのが整合的★★reportKpis() / facilityPerformance() はすでにこの帰属になっています★★ (aggregateCleanStatsByFacility() が本清掃行を期間で絞ってからエラー件数を足すため)— ★★errorBreakdown() をそちらに揃える、という向きです★★detectedAtFromError() 自体は削除しないこと★ — ★prechecks()(アラート)が使っています★★★シードを先に直すこと★★(本書は段階3-1 をシードにしてあります)。
★読み出しだけ先に変えると、ローカルのエラー率が一律 0% になり「壊れた」ように見えます★。 ★★シードを先に入れておけば、読み出しを直した瞬間に「0% だった当期のエラー率に数字が入る」という 直ったことの証拠が得られます★★。
| 対象 | 理由 |
|---|---|
★prechecks()(アラート画面)★ |
★アラートは「事前チェックで検知した異常」を出す画面★。★★分子の話とは別★★(D-104。本清掃行を指すエラーを launch_failed に読み替えない、も維持) |
★lib/judge/kpi.ts の errorRate()★ |
★純粋関数。rate(errors, executed) のまま★。★★分子の作り方が変わるだけで、率の計算は変わりません★★ |
★d-watch-api.yaml★ |
★★レスポンスの形は変わりません★★。★★変えたくなったら、それは解釈が違うサインです — 止めて確認を求めること★★ |
★lib/fixtures/ の既存値★ |
★USE_FIXTURES=true の画面は変わりません★ |
| ★確定期間(サマリ由来)のコード★ | ★決定6★ |
★detectedAtFromError()★ |
★prechecks() が使っている★ |
| 段階 | 内容 | コミット |
|---|---|---|
| 段階3-0 | 前提の確認と実測 | ★なし★ |
| 段階3-1 | ★シードに本清掃エラーを足して再シードする★ | ★あり★ |
| 段階3-2 | ★期待値表 → 純粋関数(新規追加のみ)とテスト★ | ★あり★ |
| 段階3-3 | ★配線(3箇所)+ docstring + 旧関数の削除★ | ★あり★ |
| 段階3-4 | ★実測での検証★ | ★なし★ |
| 段階3-5 | ★記録★ | ★あり★ |
# ★A7 の原文(本書の出所)★ grep -n "Q7\|A7" docs/handoff/TeamWorks確認事項_第8回_20260911.md # ★現状の実装(★行番号は必ず実測すること★)★ grep -n "mainIdByPrecheckId\|errorCountByMainId\|countErrorTypesInRange\|CleanStatsBucket" \ lib/db/report-mapping.ts lib/db/index.ts # ★決定事項★ grep -nE "^### D-(042|077|088|102|107|114|116) " docs/decisions.md
★★一時スクリプトは作業用ディレクトリに置き、★成功時にも process.exit(0) を書くこと★★★ (★Prisma の接続が残ってハングした事故あり★)。★終わったら消すこと★。
// 例(★DB は SELECT のみ★。書き込まない)
import { db } from "@/lib/db";
async function main() {
const kpis = await db.reportKpis();
const perf = await db.facilityPerformance();
const breakdown = await db.errorBreakdown();
console.log("reportKpis rows:", kpis.length);
console.log("当期のerror_rate:", kpis.filter(/* 当期の期間キー */).map((r) => r.kpi.error_rate));
console.log("errorBreakdown 当期 items:", breakdown.filter(/* 当期 */).length);
process.exit(0); // ★★成功時にも必ず書く★★
}
main().catch((e) => { console.error(e); process.exit(1); });
★控える数字★:
| # | 何を | 控える理由 |
|---|---|---|
| ★1★ | ★robot_error_reports の件数(★14 のはず★)と、そのうち clean_timetable_id が 本清掃id / 事前チェックid / null / dangling の内訳★ |
★段階3-1 で「既存14件が変わっていないこと」を示す★ |
| ★2★ | ★当期(今週・今月)の error_rate の値★ |
★★直った後に数字が増えることが合否です★★ |
| ★3★ | ★errorBreakdown() の当期の items と件数★ |
★同上★ |
| ★4★ | ★db.cleanLogs() の件数(★259 のはず★)と db.prechecks() の件数(★27 のはず★)★ |
★★回帰していないことの確認★★(群3 はどちらも変えません) |
| ★5★ | ★npm test のファイル数・件数 / tsc / lint★ |
★基準★ |
scripts/seed-local-db.ts に、★★本清掃行(clean_timetables.precheck === CLEAN_TIMETABLE_PRECHECK.main) を指す robot_error_reports の行★★を追加します。
★★加えて、決定3(null を捨てる)を実データで確認するための行を2件足します★★:
| 種類 | 件数 | 目的 |
|---|---|---|
| ★A: 本清掃行を指すエラー★ | ★複数(下記の規則)★ | ★★直した後にエラー率に数字が入ること★★ |
★B: clean_timetable_id が null のエラー★ |
★1件★ | ★★3箇所すべてで捨てられること★★(決定3) |
★C: dangling(存在しない clean_timetable_id)★ |
★1件★ | ★★例外を出さずに捨てられること★★(FK が無い列。落とし穴1) |
★★errorReportCount を本清掃エラーで増やしてはいけません★★。
// 既存コード(事前チェック行のエラー) const slot = errorReportCount % ERROR_RESOLUTION_ROTATION.length; // ... errorReportCount += 1;
errorReportCount は ★★status / comment / responded_at / resolved_at の ローテーションのスロット★★を決めています★mainErrorReportCount)を用意すること★★。 ★最後の集計ログは両方を足して出す(ログの数字が増えるのは構いません)★await prisma.cleanStatusHistory.create({ ... });
historyCount += 1;
// ★★ここに本清掃エラーの作成を置く★★
// ★`clean_statuses` は当日分だけ(D-093 項1)★
if (log.scheduled_at.slice(0, 10) !== todayJstDate) continue;
if (... !== todayJstDate) continue; より前に置くこと★★ — ★後ろに置くと、当日以外の行がすべて飛ばされて1〜2件しか作られません★cleanError が決まった後に置くこと★(★選定規則で使う場合★)| 項目 | 値 |
|---|---|
| ★どの行に作るか★ | ★★実施済み(log.completion_rate !== null)の本清掃行のうち、Number(log.id) % MAIN_CLEAN_ERROR_EVERY === 0 の行★★(★モジュール定数にすること。直書き禁止★) |
★id / error_id★ |
★RER-${log.id}-main★(★既存の RER-<id>-<分数> と衝突しない★。★明示採番=冪等★) |
★clean_timetable_id★ |
★★BigInt(log.id)(=本清掃行の id)★★ |
★facility_id / section_id / robot_id / serial_number★ |
★既存の事前チェックエラーと同じ作り方★ |
★error_type★ |
★★MAIN_CLEAN_ERROR_TYPE_ROTATION から決定的に選ぶ★★(下記) |
★error_level / error_detail★ |
★既存のプレースホルダ定数を使い回す★ |
★status / comment / responded_at / resolved_at★ |
★mainErrorReportCount を使って既存と同じローテーションで散らす★ |
★errored_at★ |
★addMinutes(startAt, MAIN_CLEAN_ERROR_AFTER_MINUTES)★(★清掃中に起きた体にする。定数化★) |
★★error_type に入れる値★★:
CLAUDE.md §4.8)lib/fixtures/reports.ts の errorBreakdown items が持っている生値を使うこと★★ — ★EmergencyStop / LostLocalization / RobotHardwareErrorToAdmin / LowBatteryLevel 等★。 ★★これらは英語識別子であり、D-077 の「生値をそのまま表示する」に沿っています★★facility_error_summaries の投入部)が同じ値を使っているので、 ★★当期の内訳と確定期間の内訳が同じ語彙になり、画面の比較がしやすくなります★★★★件数の受け入れ条件(★これを満たすまで MAIN_CLEAN_ERROR_EVERY を調整すること★)★★:
| # | 条件 |
|---|---|
| ★1★ | ★★当週(今週)の本清掃行に最低1件★★ |
| ★2★ | ★★当月(今月)の本清掃行に最低3件★★ |
| ★3★ | ★2種類以上の error_type が当期に現れる★(★内訳が1行だけだと rate が常に100%になり検証にならない★) |
| ★4★ | ★★2回流しても同じ行・同じ値になる★★(冪等) |
★★MAIN_CLEAN_ERROR_EVERY は「調整してよいモジュール定数」であることを docstring に書くこと★★。
null と dangling の1件ずつ★★id / error_id★: ★RER-NULL-1 / RER-DANGLING-1 のような明示採番★clean_timetable_id★: ★null★clean_timetable_id★: ★★どの clean_timetables.id とも一致しない値★★ (★例: 本清掃id の最大値 + 大きめの定数。★定数化し、衝突しないことをコードで確かめること★)npm run seed:local
★★実測して確認すること★★:
| # | 確認 | 期待 |
|---|---|---|
| ★1★ | ★robot_error_reports の総件数★ |
★14 + A の件数 + 2★ |
| ★2★ | ★★既存14件(RER-<id>-<分数>)の status / comment / responded_at / resolved_at が段階3-0 で控えた値と1つも変わっていないこと★★ |
★★完全一致★★ |
| ★3★ | ★db.prechecks() の件数★ |
★★27 のまま★★(★A/B/C は本清掃・null・dangling なので prechecks() が全部落とす★) |
| ★4★ | ★db.cleanLogs() の件数★ |
★★259 のまま★★ |
| ★5★ | ★当期の error_rate★ |
★★まだ変わらない★★(読み出しは未修正。★★これが正常★★) |
| ★6★ | ★errorBreakdown() の当期の件数★ |
★★増える★★(まだ全件数えているため。★★これも正常★★) |
| ★7★ | ★もう1回 npm run seed:local を流して、DB の中身が同じになること★ |
★冪等★ |
npx tsc --noEmit = 0 / npm run lint = 0 / npm test 全パス★git add scripts/seed-local-db.ts — ★パスを明示★)★★★★この段階では既存の関数を消しません/既存の呼び出し側も変えません★★ — ★新しい関数を追加するだけにして、
tscを緑のまま保ちます★。 ★★配線は段階3-3 です★★。
mainTimetableStartAtById()★ — ★本清掃行 → id(文字列) → start_at★| # | 入力 | ★期待★ |
|---|---|---|
| ★a1★ | 本清掃行2件(id=1001, 1002) | ★Map { "1001" => Date, "1002" => Date }(size === 2)★ |
| ★a2★ | 空配列 | ★size === 0★ |
| ★a3★ | ★BigInt の id が文字列キーになっていること★ |
★map.has("1001") === true / map.has(1001 as never) === false★ |
★★
BigIntは===でキー比較できないので文字列化する★★(既存コードの作法と同じ)。
errorCountByMainTimetable()★ — ★エラー行 + 本清掃idマップ → 本清掃id → 件数★★★これが分子の本体です。★★
| # | ケース | 入力(本清掃id = 1001, 1002。事前チェックid = 101001) | ★期待★ |
|---|---|---|---|
| ★b1★ | ★★本清掃行を指すエラー★★ | clean_timetable_id = 1001 |
★★Map { "1001" => 1 }★★ |
| ★b2★ | ★★事前チェック行を指すエラー★★ | clean_timetable_id = 101001 |
★★size === 0(数えない)★★ |
| ★b3★ | ★★clean_timetable_id が null★★ |
null |
★★size === 0(数えない。決定3)★★ |
| ★b4★ | ★★dangling(存在しない id)★★ | clean_timetable_id = 999999 |
★★size === 0(例外を投げない)★★ |
| ★b5★ | ★同じ本清掃に2件★ | 1001 が2行 |
★Map { "1001" => 2 }★ |
| ★b6★ | ★本清掃と事前チェックが混在★ | 1001 / 101001 / 1002 |
★★Map { "1001" => 1, "1002" => 1 }(size === 2)★★ |
| ★b7★ | ★0件★ | [] |
★size === 0★ |
| ★b8★ | ★本清掃マップが空★ | エラー3件・マップ空 | ★size === 0★ |
countMainErrorTypesInRange()★ — ★当期の内訳(error_type → 件数)★★★期間帰属は「そのエラーが指す本清掃行の start_at の JST 日付」★★(決定7)。 ★範囲は [from, to] の両端を含む★。
| # | ケース | ★期待★ |
|---|---|---|
| ★c1★ | ★本清掃行を指し、その start_at が範囲内★ |
★数える★ |
| ★c2★ | ★★事前チェック行を指す★★ | ★★数えない★★ |
| ★c3★ | ★★clean_timetable_id が null★★ |
★★数えない★★ |
| ★c4★ | ★★dangling★★ | ★★数えない・例外を投げない★★ |
| ★c5★ | ★本清掃の start_at が ★range.from ちょうど★★ |
★★数える★★ |
| ★c6★ | ★本清掃の start_at が ★range.to ちょうど★★ |
★★数える★★ |
| ★c7★ | ★本清掃の start_at が range.from の前日★ |
★数えない★ |
| ★c8★ | ★本清掃の start_at が range.to の翌日★ |
★数えない★ |
| ★★c9★★ | ★★errored_at は範囲外だが、本清掃の start_at は範囲内★★ |
★★数える★★(★★決定7 が効いていることの証拠。errored_at 基準なら落ちる★★) |
| ★c10★ | ★同じ error_type が2件★ |
★Map { type => 2 }★ |
| ★c11★ | ★0件★ | ★size === 0★ |
★★c9 はこの段階の肝です★★ — ★これが無いと決定7 を実装したか確かめられません★。 ★深夜清掃(
start_atが 02:00)のエラーが翌日のerrored_atを持つ、という現実的な形で書くこと★。
kpiFromCleanStats() 側(★分母0 と 0件★。既存の挙動の確認)★| # | ケース | ★期待★ |
|---|---|---|
| ★d1★ | ★executed = 0 / errorCount = 0★ |
★★error_rate.value === null★★(★分母0 は率を出さない。0% にしない★) |
| ★d2★ | ★executed = 10 / errorCount = 0★ |
★error_rate.value === 0★ |
| ★d3★ | ★executed = 10 / errorCount = 3★ |
★error_rate.value === 30(★丸めない生値★)★ |
★d1〜d3 は既存の
errorRate()の挙動です★ — ★★変えません★★。 ★★分子の作り方を変えても分母0の扱いが変わっていないこと★★を固定するために書きます。
lib/db/__tests__/report-mapping.test.ts(既存ファイルに追記)★describe は新しい関数名で切ること★lib/db/report-mapping.ts に追加する★)/**
* 本清掃行(`precheck === CLEAN_TIMETABLE_PRECHECK.main`)の id(文字列) → `start_at`。
*
* ★2つの用途を1本で賄う★ —
* 1. ★キーの集合★が「本清掃行の id の Set」になる(エラーの分子の判定に使う)
* 2. ★値★が期間帰属の基準になる(決定7。エラーの期間は本清掃の `start_at` の JST 日付)
*
* ★BigInt は `===` でキー比較できないので文字列化する★(`mainIdByPrecheckId()` と同じ作法)。
*/
export function mainTimetableStartAtById(
mainRows: readonly MainTimetableLike[]
): Map<string, Date> { /* ... */ }
/**
* `robot_error_reports` を ★本清掃id単位★ の件数に集計する。
*
* ★★分子の定義(TeamWorks 第8回 A7。2026-09-11)★★:
* ★本清掃行を指すエラーだけを数える★。★事前チェック行を指すものは含めない★
* (「事前チェックは本清掃を円滑に実施できるためのもの」なのでサマリに含めない)。
*
* ★★「本清掃行の集合に**入っている**」という肯定条件で数えること★★ —
* `clean_timetable_id` には FK も KEY も無く(`prisma/schema.prisma`。落とし穴1)、
* ★`null` も dangling もありうる★ので、「事前チェックでない=本清掃」と推測してはいけない。
* ★`null` と dangling はこの条件の自然な帰結として落ちる★(決定3。特別扱いのコードを足さない)。
*/
export function errorCountByMainTimetable(
errorReports: readonly { clean_timetable_id: bigint | null }[],
mainStartAtById: ReadonlyMap<string, Date>
): Map<string, number> { /* ... */ }
/**
* 当期(詳細テーブル)のエラー内訳を `error_type` ごとに数える。
*
* ★★期間帰属は「そのエラーが指す本清掃行の `start_at` の JST 日付」★★(決定7)—
* エラー率の分母が「清掃実施回数」(`CLAUDE.md` §4.2)なので、分子も清掃を基準にする。
* ★`errored_at` 基準ではない★(深夜清掃が日をまたぐと分子と分母が別の期間に入るため)。
* ★`jstIsoFromDb()` で日本時間の壁時計値に補正してから日付の桁を取る★
* (TeamWorks 第8回 A2。指示書Y)。
* ★`type` / `label` は生値のまま。7分類・日本語への変換はしない(D-077 / D-088)★
*/
export function countMainErrorTypesInRange(
errorReports: readonly (ErrorReportLike & { clean_timetable_id: bigint | null })[],
mainStartAtById: ReadonlyMap<string, Date>,
range: { from: string; to: string }
): Map<string, number> { /* ... */ }
★★注意★★:
YYYY-MM-DD は辞書順=日付順★(既存コードと同じ比較の仕方)CLEAN_TIMETABLE_PRECHECK.main を 0 と直書きしないこと★★ — ★lib/config から読む★mainIdByPrecheckId / errorCountByMainId / countErrorTypesInRange)を 消さないこと★★ — ★消すのは段階3-3★npx tsc --noEmit = 0 / npm run lint = 0 / npm test 全パス★git add lib/db/report-mapping.ts lib/db/__tests__/report-mapping.test.ts)★★reportKpis() / facilityPerformance()(lib/db/index.ts)★★2箇所とも同じ形です★:
// 変更前 const mainIdByPrecheck = mainIdByPrecheckId(precheckRows); const errCountByMainId = errorCountByMainId(errorReports, mainIdByPrecheck); // 変更後 const mainStartAtById = mainTimetableStartAtById(mainRows); const errCountByMainId = errorCountByMainTimetable(errorReports, mainStartAtById);
precheckRows がこの2メソッドで他に使われていないなら、変数ごと消すこと★★ (★★使われているか必ず実測すること★★。★消してよいかは grep で確かめる★)aggregateCleanStatsByFacility() の引数名・型は変わりません★errorBreakdown()(lib/db/index.ts)★★★当期ブランチだけを変えます★★(★確定期間ブランチは触らない。決定6★)。
// 変更前 const errorReports = await prisma.robotErrorReport.findMany(); // 変更後(★本清掃行が要るので clean_timetables も読む★) const [errorReports, timetables] = await Promise.all([ prisma.robotErrorReport.findMany(), prisma.cleanTimetable.findMany(), ]); const mainRows = timetables.filter( (row) => row.precheck === CLEAN_TIMETABLE_PRECHECK.main ); const mainStartAtById = mainTimetableStartAtById(mainRows); // ... const currentWeekItems = errorBreakdownItemsFromCounts( countMainErrorTypesInRange(errorReports, mainStartAtById, currentWeekRange) );
CLEAN_TIMETABLE_PRECHECK は lib/config からのインポート。0 と直書きしない★★rate の分母は「その Map 内の全件数の合計」のまま★★ (errorBreakdownItemsFromCounts() は変えません)— ★分子の集合が変わるので rate の値は変わります★errorBreakdown() の docstring も直すこと★★ — ★「当期(今週・今月): robot_error_reports を期間で絞って error_type ごとに数える (期間判定は detectedAtFromError())」という記述が古くなります★CleanStatsBucket.errorCount の docstring を書き換える★(決定5)/** * エラー発生回数。 * * ★★本清掃行(`precheck === CLEAN_TIMETABLE_PRECHECK.main`)を指す * `robot_error_reports` の件数★★(TeamWorks 第8回 A7。2026-09-11)— * ★事前チェック行を指すエラーは含めない★(「事前チェックは本清掃を円滑に実施できる * ためのもの」なのでサマリに含めない、という回答)。 * ★`clean_timetable_id` が `null` の行 / dangling の行も含めない★(決定3)。 * * ★★以前ここには「事前チェック行に紐づく」と書いてあった★★ — ★第8回で質問する前の * **仮定**であり、回答で逆だと分かった。★古い記述を残さない★(次に読む人が両方を信じるため)。 * * ★注意: `clean_error` が 2(セキュリティ有効)/ 3(D-S制御盤異常)の清掃は * `robot_error_reports` の行が作られないため、この件数に入らない★(第8回 A6-1)— * ★★したがって「エラー発生率」は実質「ロボット異常の発生率」になる★★。 */ errorCount: number;
★★削除するもの★★(★削除前に grep で参照が0件になったことを確かめること★):
| 関数 | 置き換え先 |
|---|---|
★mainIdByPrecheckId()★ |
★mainTimetableStartAtById()★ |
★errorCountByMainId()★ |
★errorCountByMainTimetable()★ |
★countErrorTypesInRange()★ |
★countMainErrorTypesInRange()★ |
describe("mainIdByPrecheckId / errorCountByMainId") / describe("countErrorTypesInRange"))も一緒に消すこと★★ — ★消し忘れると tsc が落ちるので気づけます★PrecheckTimetableLike が他で使われていないなら、それも消すこと★★(★必ず grep で確認★)detectedAtFromError() は消さないこと★★(prechecks() が使っている)npx tsc --noEmit = 0 / npm run lint = 0 / npm test 全パス★grep で確認した)★git add lib/db/index.ts lib/db/report-mapping.ts lib/db/__tests__/report-mapping.test.ts)★★| # | 確認 | ★期待★ |
|---|---|---|
| ★1★ | ★当期(今週・今月)の error_rate★ |
★★段階3-0 で控えた値より増えている★★(★段階3-1 で足した本清掃エラーが分子に入った★) |
| ★2★ | ★errorBreakdown() の当期の type★ |
★★段階3-1 で入れた英語識別子(EmergencyStop 等)になっている★★ |
| ★3★ | ★errorBreakdown() の当期に、事前チェック行由来の error_type が★出ていない★★ |
★★出ていないこと★★ |
| ★4★ | ★B(null)と C(dangling)の2行が、★率にも内訳にもアラートにも出ていない★★ | ★★3箇所すべてで出ていない★★(決定3) |
| ★5★ | ★db.prechecks() の件数★ |
★★27 のまま★★(★アラートは変えていない★) |
| ★6★ | ★db.cleanLogs() の件数★ |
★★259 のまま★★ |
| ★7★ | ★確定期間(先週・先月)の error_rate と内訳★ |
★★段階3-0 と同じ値★★(★決定6。サマリは触っていない★) |
/reports★: ★★エラー発生率に数字が入っていること★★ / ★エラー種別内訳が英語識別子で出ていること★ (★★D-077 の通り。日本語に見えなくても正しい★★)/alerts★: ★27件のまま★/detail-log★: ★259件のまま★(★群1・群2 を先に実行しているのでページ送りは付いています★)USE_FIXTURES=true での確認★lib/fixtures/ を触りません★)git status にゴミが出ていない)★docs/decisions.md に追記★★着手直前に実測した空き番号を使うこと★★(見込み番号は本書に書いていません)。
★書くこと★:
null のエラーを施設・期間に割り当てて分子に入れる案★ → ★「清掃1回に紐づかないエラーは清掃のエラー率の分子ではない」ので捨てる★docs/handoff.md に追記★番号は実測すること★(★作成時点の最新は 追記36★)。
git add docs/decisions.md docs/handoff.md(★パスを明示。-A 禁止★)★git diff docs/decisions.md を先に見て、別作業の未コミット追記を巻き込んでいないこと★★★群4 に入らなくても、エラー率の分子の修正は単体で完結しています★。
★★3件とも独立しています。1コミットにまとめてよい★★。
# ①「TeamWorks確認事項の回答待ち」という記述が事実に反することの再確認 grep -rn "算出基準はTeamWorks" lib/ docs/ grep -rn "判定なし\|FACILITY_STATUS_THRESHOLDS" docs/handoff/TeamWorks確認事項_第*.md # ② fixtures の生成式 grep -n "GRADE_THRESHOLDS" lib/fixtures/clean-logs.ts lib/db/clean-log-mapping.ts # ③ 足りないテストの場所 grep -n "describe(\"foldProblemDaysByDate\"\|a7:\|a2:" lib/db/__tests__/clean-log-mapping.test.ts
★控えること★: ★npm test のファイル数・件数(★基準★)★。
lib/judge/kpi.ts の judgeFacilityStatus() のコメントが事実に反する★/** * 施設別パフォーマンスの 良好 / 注意 / 要改善 / 判定なし * * 算出基準はTeamWorks確認事項の回答待ちのため、暫定で稼働率ベース。 ← ★★事実に反する★★ * 閾値は `lib/config` の FACILITY_STATUS_THRESHOLDS から読む。
FACILITY_STATUS_THRESHOLDS に寄せたもの★★★「TeamWorks 回答待ち」ではない旨に書き換えること★★。★次の要素を含めること★:
lib/config から読む、という既存の記述は残すこと★null(分母0=判定なし)についての既存の説明はそのまま残すこと★★ (★決定1。2026-09-11 ユーザー確定。★消さない★)★同じ文言が docs/handoff/analysis/code-analysis-pure.md にも転記されています★ (★2977 / 3071 / 3195 行付近。★行番号は実測すること★)。
docs/decisions.md の記録に「分析資料側は古い文言のまま」と書くこと★★docs/decisions.md:6577 の「⑦ 判定なしステータスの算出基準(暫定で稼働率ベース)」という 申し送り行は消さないこと★★(★過去の記録であり、履歴として正しい★)— ★新しい記録の側で「TeamWorks 回答待ちではなかった」と訂正すること★lib/fixtures/clean-logs.ts の生成式★ — ★★取り下げ。直さない★★★★監督判断(2026-09-11)で本項は取り下げました。手を付けないでください。★★
lib/fixtures/clean-logs.ts の生成式が < のままで、実装側の <=(D-109 決定3)とずれている」 として直す予定でしたlib/db/clean-log-mapping.ts の isProblemCompletion() の docstring に ★「fixtures の生成式は < のままだが、生成される完了率に 70.0 ちょうどは現れないので矛盾しない (lib/fixtures/ は変更禁止)」★ と明記されています5 + r*40 / 72 + r*15 / 90.5 + r*9)lib/fixtures/ は変更禁止★という取り決めもあります。 ★記録済みの判断を、実益なしに覆すことになる★ので取り下げます★★同じ日に「履歴が無い行」と「正常終了の行」が混在するケース★★が固定されていません。
lib/db/__tests__/clean-log-mapping.test.ts の describe("foldProblemDaysByDate") には a1〜a9 が揃っています★ — ★★a2(問題行 50 + 正常行 95)と a7(未実施 null 単独)はあるが、 その2つを組み合わせた形(null + 正常行)が無い★★completionRateFromHistory() が null を返します★★ (★出発失敗・データ収集の欠落のどちらでも null になる★)isProblemCompletion(null) === true★ なので、 ★★同じ日の行を OR で畳むとその日は問題日になります★★| # | ケース | 入力(施設1・同一日) | ★期待★ |
|---|---|---|---|
| ★★a10★★ | ★★同一日に「履歴が無い行(completion_rate === null)」と「正常終了の行(95)」が混在★★ |
09-01(null) + 09-01(95) |
★★[{ date: "2026-09-01", isProblem: true }](1要素)★★ |
★★併せて computeConsecutiveProblemDays() 側でも固定すること★★(★同じ入力で連続日数が 1 になる★):
| # | ケース | 入力 | ★期待★ |
|---|---|---|---|
| ★★b12★★ | ★同一日に null 行と正常行 → その日は問題日★ | id1: 09-01(null) / id2: 09-01(95) |
★★map.get(1) === 1 / map.get(2) === 1★★(★★両方 1。id2 が 0 にならないこと★★) |
★★テストのコメントに理由を書くこと★★:
// ★★「正常終了した行があっても、同じ日に履歴が無い行があればその日は問題日」★★ // `isProblemCompletion(null) === true` なので OR で畳むと true になる(D-109 決定)。 // ★★気づいた人が「正常終了しているのだから false では」と直さないように固定する★★
describe("foldProblemDaysByDate") の a9 の前(a7 の近く)/ describe("computeConsecutiveProblemDays") の b11 の後★npx tsc --noEmit = 0 / npm run lint = 0★npm test 全パス。★★件数が段階4-0 の基準 +1 または +2 になっていること★★★lib/ から消えていること★★(①):
grep -rn "算出基準はTeamWorks" lib/ # ★0件★
git add lib/judge/kpi.ts lib/fixtures/clean-logs.ts lib/db/__tests__/clean-log-mapping.test.ts(★
docs/handoff/analysis/code-analysis-pure.md も直したならそれも明示的に追加★)docs/decisions.md に追記★(★★群3 と同じ番号にまとめてもよい★★。実行者判断)docs/handoff/analysis/code-analysis-pure.md を直したか直さなかったか★docs/handoff.md に追記★| # | 論点 | 状態 |
|---|---|---|
| ★①★ | ★★サマリ(確定期間)が事前チェックを除外しているか★★ | ★★未確認★★。★第8回 A7 は「除外するのが正しいでしょう」という見解であって、現行の集計バッチがそうなっているという事実の確認ではない★。★★第9回の確認事項に載せること★★。★確定期間と当期で分子の定義が食い違っている可能性が残る★ |
| ★②★ | ★★clean_error が 2(セキュリティ有効)/ 3(D-S制御盤異常)の清掃はエラー行が作られない★★(第8回 A6-1) |
★★仕様として受け入れる★★。★★帰結として「エラー発生率」は実質「ロボット異常の発生率」になる★★ — ★この定義を docs/decisions.md と CleanStatsBucket.errorCount の docstring の両方に明記すること★ |
| ★③★ | ★clean_timetable_id が null のエラー行を捨てる判断★ |
★本書で「捨てる」に確定★。★ただし facility_id と errored_at を持つので施設・期間には割り当てられる(入れる選択肢は技術的にある)★。★★実データで null がどれくらい出るかが分かった時点で見直す余地がある★★ |
| ★④★ | ★errorBreakdown() の当期の rate の分母★ |
★「その期間の全エラー件数」のまま★。★分子の集合を絞ったので、★★確定期間(サマリ由来)の rate と母集団の定義が違う可能性★★がある — ①と同じ照会で解消する★ |
| ★⑤★ | ★lib/fixtures/clean-logs.ts の生成式と isProblemCompletion() の共通化★ |
★★本書ではやらない★★(群4 ② は演算子1つだけ)。★共通化すると fixtures の値が変わりうるので、別作業として切り出すこと★ |
| ★⑥★ | ★docs/handoff/analysis/code-analysis-pure.md の古い転記★ |
★実行者判断(群4 ①)★。★直さなかった場合は記録に書くこと★ |
| ★⑦★ | ★群1・群2 の指示書と現状の行番号のずれ★ | ★★各群の段階0 で実測して埋める運用にした★★。★指示書Z / AA 自体は本書では改訂しません★(★別のエージェントが並行して前提の点検を行っています★) |
| # | 条件 |
|---|---|
| ★1★ | ★★群1(指示書Z)を頭から実行し、その指示書の完了条件を満たした★★ |
| ★2★ | ★★群2(指示書AA)を頭から実行し、その指示書の完了条件を満たした★★ |
| ★3★ | ★★群3 の段階3-1〜3-5 を実行した★★(★当期の error_rate が段階3-0 より増えている★) |
| ★4★ | ★★群4 の①②③ を実行した★★(★grep -rn "算出基準はTeamWorks" lib/ が0件★) |
| ★5★ | ★★npx tsc --noEmit = 0 / npm run lint = 0 / npm test 全パス★★ |
| ★6★ | ★db.cleanLogs() = 259件 / db.prechecks() = 27件(★群3・群4 で変わらない★)★ |
| ★7★ | ★★確定期間(先週・先月)の数字が群3 の前後で変わっていない★★ |
| ★8★ | ★docs/decisions.md / docs/handoff.md に記録した(★実測した番号で★)★ |
| ★9★ | ★★git status にゴミ(一時スクリプト・計測用 JSON)が残っていない★★ |
| ★10★ | ★★README.md / docs/code-map.md / docs/handoff/管理画面_設計検討_20260910.md / |
.claude/worktrees/** に触っていない★★ |
★★途中で止めた場合★★: ★どの群のどの段階まで終わったかを作業メモに残し、 本書末尾の「実行状態」表を更新すること★。★★止めた状態でも
tsc/lint/testは 緑であること★★(段階割りはそうなるように組んであります)。
| 群 | 段階 | 状態 | 決定番号 | 備考 |
|---|---|---|---|---|
| 群1 | 指示書Z 段階0〜8 | ★★完了(2026-09-11)★★ | ★D-119★ | 3bfed11 / 9edc547 / 49b27cf / 53a6d21 / 82d98d5 / 828afe6 + 記録コミット。★指示書Z の実行状態表も更新済み★。★★push は未実施(監督確認待ち)★★ |
| 群2 | 指示書AA 段階0〜7 | ★★完了(2026-09-11)★★ | ★D-120★ | fd4ca5b / fcdcb07 / 9e9704c / 78fbfac / 77693c4 + 記録コミット。★指示書AA の実行状態表も更新済み★。★★これで4群すべて完了★★。★★push は未実施(監督確認待ち)★★ |
| 群3 | 段階3-0 | ★★完了(2026-09-11)★★ | — | ★着手前の実測。コミットなし★ |
| 群3 | 段階3-1(シード) | ★★完了★★ | ★D-118★ | b669af7。本清掃エラー33件 + null/dangling 各1件。★既存14件は不変★ |
| 群3 | 段階3-2(純粋関数) | ★★完了★★ | ★D-118★ | fc3d789。期待値表 a/b/c/d をテストに転記(+25件) |
| 群3 | 段階3-3(配線) | ★★完了★★ | ★D-118★ | 355fe0d。旧関数3本と PrecheckTimetableLike を削除(参照0件を確認) |
| 群3 | 段階3-4(実測) | ★★完了★★ | — | ★★当期の error_rate は 50%→10.714% / 19.44%→12.5% と減った★★(本書の想定は「増える」。★理由と、それでも直っている根拠は D-118 項4★) |
| 群3 | 段階3-5(記録) | ★★完了★★ | ★D-118★ | docs/decisions.md D-118 / docs/handoff.md 追記38。★push は未実施(監督確認待ち)★ |
| 群4 | 段階4-0〜4-2 | ★★完了(2026-09-11)★★ | ★D-117★ | ★①③ のみ実施。★②は取り下げ済みなので lib/fixtures/ には触っていない★。テスト 1023→★1025★ / tsc 0 / eslint 0 / grep "算出基準はTeamWorks" lib/ = ★0件★。★code-analysis-pure.md は古い文言のまま★(実行者判断)。★push は未実施(監督確認待ち)★ |