本文へ移動
BlackOps1.xは試験的なバージョンです。Production Readyは2.xを予定しています。Releases
BlackOps
Esc
navigateopen⌘Jpreview
このページの内容

Observer Replay

Observer Replayをdry-run、confirm、resumeし、AuditとCanonical Journalの安全境界を検証する。

journal:observer:replay は、Canonical Journal の Record を指定した Observer へ現在の Projection で再配送する BlackOps CLI です。通常の Journal Observation や Outbox Retry とは別の、明示的な運用操作として実行します。

これは完了済みOperationをHandlerへ再実行するOperation Replayではありません。Journalの構造とCanonical/Observedの境界はJournalを参照してください。

実行場所と準備

ApplicationのProject Rootで、Application-owned config/journal.phpとObserver設定を確認します。Hostではphp blackopsを使い、Containerでは同じCommandをdocker compose run --rm appへ渡します。対象Database、Actor、ReasonをApplicationの運用Policyで決め、CredentialやProtected PayloadをShellへ書きません。

Selector と実行モード

Selector は次のいずれか一つだけを指定します。

  • --operation-id=<uuid>: Operation の sequence, record_id
  • --record-id=<uuid>: 一つの Canonical Record
  • --from=<RFC3339> --to=<RFC3339>: UTC へ正規化した [from,to) の範囲

Observer は --observer=<stable-name> を一つ以上指定します。Checkpoint ID は小文字英数字のセグメントを ._- でつないだ 1〜128 バイトの値に限られます。Batch は --batch-size で指定でき、範囲は 1〜1000 です。

新規実行の --dry-run は Selector と Observer だけを指定します。Checkpoint、Actor、Reasonは不要です。新規実行を適用する --confirm では、これら三つをすべて指定します。

php blackops journal:observer:replay \
  --operation-id=019f32ab-2be0-7b38-a0a7-1ab2f9687697 \
  --observer=application-jsonl --batch-size=100 --dry-run

php blackops journal:observer:replay \
  --from=2026-07-01T00:00:00Z --to=2026-07-02T00:00:00Z \
  --observer=application-jsonl --checkpoint=journal-replay-20260701 \
  --actor=operator --reason="restore projection" --confirm

--dry-run--confirm は必ずどちらか一つだけを選びます。Dry-runの出力は selecteddeliveredfailedhas-morecomplete と、候補がある場合の first-record-idlast-record-id です。出力にCheckpoint、Actor、Payloadは含みません。また、Observerへの配送、Audit、Checkpoint、Canonical JournalへのWriteは行いません。Exit Codeは0です。

Confirmの出力は同じ件数に加えて checkpoint を含み、配送後の deliveredfailedhas-morecomplete と先頭/末尾Record IDを返します。Checkpoint保存とObserver配送を行い、Canonical Journalは変更しません。

実行途中で停止した場合は、Selector と Observer を再指定せず、保存済み Binding を使って新しい Actor/Reason で再開します。

php blackops journal:observer:replay \
  --resume=journal-replay-20260701 \
  --actor=operator --reason="resume after maintenance" --confirm

Identity と安全な監査

Replay は Canonical recordId、Operation ID、Sequence、Occurred At を維持します。JSONL Envelope にも同じ recordId が含まれるため、Target は Record ID を冪等性キーとして扱えます。配送保証は at-least-once です。Observer が受け付けた直後に Process が落ちた場合、Resume で同じ Record ID が再配送されることがあります。

Audit には安全な Selector 境界(Operation/Record ID または時刻範囲)、Target 名、Operator Actor/Reason、Invocation ごとの件数、時刻、Version 付き Failure Fingerprint だけを保存します。Canonical Payload、Projection Data、Canonical Actor ID、Credential、SQL、Throwable の Message/Trace は保存せず、CLI 出力や例外にも漏らしません。

Replay Source は Canonical Journal を SELECT するだけです。Canonical Row の Append/Update/Delete や Lifecycle Record の追加は行いません。

配送が失敗した場合はFailure FingerprintとCheckpointだけを確認し、SelectorやRecordを直接変更せず、原因を修正して--resumeで再実行します。