STEP 1587 — Central counter drift fix
Incident
2026-08-30 STEP 1569 arc 実装中、 rebase の副作用で data/step-counter.json が git HEAD より後退。 事象:
- git history highest STEP = 1584 (私の SafetyGate commit)
- counter.highest_claimed = 1532 (rebase 副作用で古い状態に戻った)
- その後の claim → 1533 / 1534 (git history highest より低い番号で衝突リスク)
Direct-write による counter 修復は auto-mode classifier で block されたため、 別 STEP で恒久 fix。
実装 — claim-step.ts に --sync-from-git 追加
# dry-run
npx tsx scripts/claim-step.ts --sync-from-git
# → [sync-from-git] git history highest STEP: 1586
# → [sync-from-git] current counter: next=1539 highest_claimed=1538
# → [sync-from-git] proposed: next=1587 highest_claimed=1586
# → [sync-from-git] drift = +48 steps ahead of counter
# → [sync-from-git] dry-run only. Pass --confirm to write.
# apply
npx tsx scripts/claim-step.ts --sync-from-git --confirm
# → [sync-from-git] counter advanced: next=1587 highest_claimed=1586
# 追加 option
--max <N> # placeholder cap (default 5000)
Safe by construction
- Forward-only:
Math.max(current, proposed)で counter は絶対に後退しない (再利用 risk 予防) - Placeholder filter:
--maxcap (default 5000) で "STEP 9999" のような auto-cron marker (site rebuild 69 件) を除外 - Dry-run default:
--confirmがないと read-only。 accidental 変更 予防 - Lock 保護: 既存 claim/release と同じ lock を使用 (multi-tab safe)
- Audit log:
action: 'sync-from-git'としてdata/step-claim-log.jsonlに記録 - Idempotent: drift ゼロ時は no-op (再実行安全)
今回の実行結果
- Excluded: 69 placeholder matches at STEP >= 5000 (auto-cron marker)
- git history highest STEP: 1586 (実 STEP claim)
- Counter before: next=1539 / highest_claimed=1538
- Counter after: next=1587 / highest_claimed=1586
- Drift 解消: +48 steps
Test — 13/13 PASS
- dry-run (no --confirm) does not modify counter
- --max cap filters placeholder STEP numbers
- log entry action='sync-from-git' recorded after --confirm
- forward-only invariant (counter never decreases)
Honest scope
- 過去の counter drift による narrative 混乱 (STEP 1533/1534 が 実装順 1584 の続きなのに番号が低い) は retroactive fix 不可 (git history immutable)。 memory の cross-reference で解決
- 将来の rebase / revert 副作用は本 script の 手動実行で再 sync 可能。 自動化 (post-rebase hook) は別 STEP candidate
- placeholder filter は STEP >= 5000 の hard cap。 "STEP 9999" 以外の placeholder pattern が出現したら
--max調整