Skip to content

Add live backup pin FSM substrate#1056

Open
bootjp wants to merge 1 commit into
mainfrom
design/live-backup-pin-substrate
Open

Add live backup pin FSM substrate#1056
bootjp wants to merge 1 commit into
mainfrom
design/live-backup-pin-substrate

Conversation

@bootjp

@bootjp bootjp commented Jul 10, 2026

Copy link
Copy Markdown
Owner

Summary

  • add a live-backup pin/extend/release FSM envelope for retaining read timestamps during future online logical backup scans
  • extend ActiveTimestampTracker with deadline-based backup pins, expiry sweeping, limits, and idempotent release/extend behavior
  • wire shard FSMs to the same ActiveTimestampTracker used by local compaction

Tests

  • go test ./kv -run 'Test(ActiveTimestampTracker|Backup|ApplyBackup)' -count=1 -timeout=240s
  • go test ./kv -count=1 -timeout=300s
  • go test . -run 'TestBuildShardGroupsWithEtcdEngineRoutesAcrossGroups|TestBuildShardGroupsWithEtcdEngineRestartsAcrossGroups' -count=1 -timeout=240s
  • go test . -run 'TestRaftBootstrapMembers_E2E|TestRaftBootstrapMembers_MultiGroup' -count=1 -timeout=300s
  • go test ./... -run TestNonexistent -count=0 -timeout=300s
  • go test . -count=1 -timeout=300s
  • golangci-lint run ./kv . --timeout=5m
  • git diff --check
  • git verify-commit HEAD

Author: bootjp

Summary by CodeRabbit

  • 新機能

    • バックアップ用ピンを期限付きで登録・延長・解放できるようになりました。
    • バックアップピンを考慮して、最古の参照可能時刻をより正確に追跡します。
    • ピンの有効期限切れを自動的に回収し、最大登録数を設定できます。
    • 複数のRaftグループごとにバックアップピンを管理できます。
    • バックアップ操作を分散環境間で適用できるようになりました。
  • 改善

    • 不正なピンや期限切れ操作を適切に検出し、安全に処理します。
    • トラッカーの終了処理を追加し、リソースを安全に解放できるようになりました。

@coderabbitai

coderabbitai Bot commented Jul 10, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@bootjp, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 56 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: c2faf6b0-9366-493f-ac95-a97ce41e9459

📥 Commits

Reviewing files that changed from the base of the PR and between b04b7fb and 26d45ba.

⛔ Files ignored due to path filters (2)
  • proto/admin.pb.go is excluded by !**/*.pb.go
  • proto/admin_grpc.pb.go is excluded by !**/*.pb.go
📒 Files selected for processing (29)
  • adapter/admin_grpc.go
  • adapter/admin_grpc_test.go
  • docs/design/2026_04_29_proposed_logical_backup.md
  • internal/raftadmin/server_test.go
  • internal/raftengine/engine.go
  • internal/raftengine/etcd/engine.go
  • internal/raftengine/etcd/wal_purge_test.go
  • kv/active_timestamp_tracker.go
  • kv/active_timestamp_tracker_test.go
  • kv/backup_codec.go
  • kv/backup_codec_test.go
  • kv/compactor.go
  • kv/compactor_test.go
  • kv/coordinator_retry_test.go
  • kv/fsm.go
  • kv/fsm_backup.go
  • kv/fsm_backup_test.go
  • kv/leader_proxy_test.go
  • kv/lease_read_test.go
  • kv/shard_store_test.go
  • kv/sharded_coordinator_txn_test.go
  • main.go
  • main_admin.go
  • main_admin_test.go
  • main_bootstrap_e2e_test.go
  • main_encryption_write_wiring.go
  • main_sqs_leadership_refusal_test.go
  • multiraft_runtime_test.go
  • proto/admin.proto
📝 Walkthrough

Walkthrough

ActiveTimestampTrackerに期限付きバックアップピン追跡を追加し、固定長ワイヤ形式、FSM適用処理、共有トラッカーの起動配線、関連テストを実装しました。

Changes

バックアップピン処理

Layer / File(s) Summary
バックアップピン追跡と期限管理
kv/active_timestamp_tracker.go, kv/active_timestamp_tracker_test.go
期限、上限、Raftグループ単位のスコープ、期限切れ回収、スイーパー、解放、期限延長、終了処理を追加し、各動作をテストします。
バックアップワイヤ形式
kv/backup_codec.go, kv/backup_codec_test.go
Pin、Extend、Releaseエントリの固定長エンコード・デコード、期限変換、不正ワイヤ検証を追加します。
FSMでのバックアップ適用
kv/fsm.go, kv/fsm_backup.go, kv/fsm_backup_test.go
バックアップオペコードをFSMで処理し、共有トラッカーへのPin、Extend、Release適用、エラー処理、揮発性判定を追加します。
共有トラッカーの起動配線
main.go, main_encryption_write_wiring.go, main_bootstrap_e2e_test.go, multiraft_runtime_test.go
起動時に生成したトラッカーをシャードグループと各FSMへ渡し、関連するテスト起動経路も更新します。

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant RaftApply
  participant kvFSM
  participant applyBackup
  participant decodeBackupEntry
  participant ActiveTimestampTracker
  RaftApply->>kvFSM: バックアップペイロードを適用
  kvFSM->>applyBackup: raftEncodeBackupを処理
  applyBackup->>decodeBackupEntry: エントリをデコード
  decodeBackupEntry-->>applyBackup: Pin/Extend/Releaseを返却
  applyBackup->>ActiveTimestampTracker: バックアップピン操作を適用
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 5.77% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed ライブバックアップ用のpin/extend/release FSM基盤を追加する変更で、PRの主目的と一致しています。
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@bootjp

bootjp commented Jul 10, 2026

Copy link
Copy Markdown
Owner Author

@codex review

@github-actions

Copy link
Copy Markdown
Contributor

TLA+ spec divergence review (auto-triggered)

This PR touches files that the TLA+ safety spec has an anchor on (per
docs/design/2026_05_28_implemented_tla_safety_spec.md §3),
so an AI review is requested below to verify the implementation has not drifted
from the model.

Anchored files changed in this PR head (9a7491c):

  • kv/fsm.go

What to check, by subsystem:

  • kv/hlc*.goNext() must respect the HLC-4 preconditions (i)/(ii)/(iii) from the design doc: bounded skew, logical-counter handoff on leader change (strategy (c) Observe(MaxAppliedHLC)), and the commit-time ceiling fence (fail-closed when wall_now >= physicalCeiling). Any change to the bit layout (48/16), the CAS loop, or the ceiling getter/setter is in scope.
  • kv/coordinator.go, kv/sharded_coordinator.goRunHLCLeaseRenewal, hlcRenewalInterval, hlcPhysicalWindowMs constants, and the new-term detection that calls Observe(fsm.MaxAppliedHLC()) (strategy (c)). Any change to renewal cadence, group selection, or fail-closed behaviour is in scope.
  • kv/transaction.go, kv/lock_resolver.go — OCC commit-ts assignment, lock-map encoding (key, lock_ts) -> start_ts, and the LockResolver action OCC-3 depends on. (M2 spec will land OCC-1..OCC-5; until then the spec doc §5.2 is the contract.)
  • kv/fsm.go — FSM apply of HLC lease entries (SetPhysicalCeiling), and any future MaxAppliedHLC() accessor that strategy (c) needs.
  • store/mvcc_store.go — version visibility, snapshot install, and the MVCC-1..MVCC-4 invariants (M3 scope).
  • distribution/** — route catalog versioning, SplitRange atomicity, and CatalogWatcher async fan-out (M4 scope).

If the change is correct but requires a spec update, edit tla/hlc/HLC.tla (or the corresponding M2..M5 module once landed) and the design doc in the same PR. The tla-check workflow runs the TLC model check on the same paths.


@claude review please verify TLA+ spec divergence per the checklist above.

@codex review please verify TLA+ spec divergence per the checklist above.

@chatgpt-codex-connector

Copy link
Copy Markdown

To use Codex here, create a Codex account and connect to github.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a backup pinning mechanism to the ActiveTimestampTracker and kvFSM to retain MVCC versions at live-backup read timestamps during background compaction. It adds FSM commands for pinning, extending, and releasing backup pins, alongside a background sweeper to reap expired pins. The reviewer provided critical feedback to improve robustness: first, expired backup pins should be ignored in Oldest() to avoid blocking compaction before the sweeper runs; second, validation and limit errors must not halt the FSM to prevent DoS vulnerabilities; and third, a graceful shutdown mechanism (Close() and stopCh) should be added to the tracker to prevent goroutine leaks from the background sweeper.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread kv/active_timestamp_tracker.go Outdated
Comment thread kv/fsm_backup.go
Comment thread kv/active_timestamp_tracker.go
Comment thread kv/active_timestamp_tracker.go
Comment thread kv/active_timestamp_tracker.go
@bootjp
bootjp force-pushed the design/live-backup-pin-substrate branch from 9a7491c to b9e3e10 Compare July 10, 2026 19:47
@bootjp

bootjp commented Jul 10, 2026

Copy link
Copy Markdown
Owner Author

Addressed latest-head review findings:

  • expired backup pins are ignored by Oldest() before the sweeper runs
  • invalid backup pins and active-backup limit failures now return non-fatal apply errors instead of halting the FSM
  • ActiveTimestampTracker now has an idempotent Close() path for the backup-pin sweeper

Validation:

  • go test ./kv -run 'Test(ActiveTimestampTracker|ApplyBackup|BackupPayload)' -count=1 -timeout=240s\n- go test ./kv -count=1 -timeout=300s\n- golangci-lint run ./kv --timeout=5m\n\n@codex review

@github-actions

Copy link
Copy Markdown
Contributor

TLA+ spec divergence review (auto-triggered)

This PR touches files that the TLA+ safety spec has an anchor on (per
docs/design/2026_05_28_implemented_tla_safety_spec.md §3),
so an AI review is requested below to verify the implementation has not drifted
from the model.

Anchored files changed in this PR head (b9e3e10):

  • kv/fsm.go

What to check, by subsystem:

  • kv/hlc*.goNext() must respect the HLC-4 preconditions (i)/(ii)/(iii) from the design doc: bounded skew, logical-counter handoff on leader change (strategy (c) Observe(MaxAppliedHLC)), and the commit-time ceiling fence (fail-closed when wall_now >= physicalCeiling). Any change to the bit layout (48/16), the CAS loop, or the ceiling getter/setter is in scope.
  • kv/coordinator.go, kv/sharded_coordinator.goRunHLCLeaseRenewal, hlcRenewalInterval, hlcPhysicalWindowMs constants, and the new-term detection that calls Observe(fsm.MaxAppliedHLC()) (strategy (c)). Any change to renewal cadence, group selection, or fail-closed behaviour is in scope.
  • kv/transaction.go, kv/lock_resolver.go — OCC commit-ts assignment, lock-map encoding (key, lock_ts) -> start_ts, and the LockResolver action OCC-3 depends on. (M2 spec will land OCC-1..OCC-5; until then the spec doc §5.2 is the contract.)
  • kv/fsm.go — FSM apply of HLC lease entries (SetPhysicalCeiling), and any future MaxAppliedHLC() accessor that strategy (c) needs.
  • store/mvcc_store.go — version visibility, snapshot install, and the MVCC-1..MVCC-4 invariants (M3 scope).
  • distribution/** — route catalog versioning, SplitRange atomicity, and CatalogWatcher async fan-out (M4 scope).

If the change is correct but requires a spec update, edit tla/hlc/HLC.tla (or the corresponding M2..M5 module once landed) and the design doc in the same PR. The tla-check workflow runs the TLC model check on the same paths.


@claude review please verify TLA+ spec divergence per the checklist above.

@codex review please verify TLA+ spec divergence per the checklist above.

@chatgpt-codex-connector

Copy link
Copy Markdown

To use Codex here, create a Codex account and connect to github.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b9e3e104a4

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread kv/active_timestamp_tracker.go Outdated
Comment on lines +149 to +150
if _, exists := t.backupPins[pinID]; !exists && len(t.backupPins) >= t.maxBackupPins {
return errors.WithStack(ErrTooManyActiveBackups)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Reap expired pins before enforcing the active limit

When a replica still has maxBackupPins expired entries that Oldest() already ignores but the sweeper has not deleted yet, this raw len(t.backupPins) check returns ErrTooManyActiveBackups for a new valid backup pin. Since applyBackup treats that error as non-fatal, the Raft entry is advanced without recording the pin on that replica; if it later compacts or becomes the backup-serving leader, the backup read timestamp is not retained. Reap or exclude expired pins before applying the cap.

Useful? React with 👍 / 👎.

Comment thread kv/active_timestamp_tracker.go Outdated
Comment on lines +170 to +171
pin.deadline = deadline
t.backupPins[pinID] = pin

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Reject late renewals for expired backup pins

If a BackupExtend arrives after the previous deadline but before the sweeper has deleted the entry, Oldest() has already stopped honoring this pin, so compaction may have advanced past the backup's read timestamp during that gap. This assignment makes the expired pin active again and reports a successful renewal, allowing a backup to continue even though its retention fence was temporarily absent. Treat expired pins as missing/invalid before extending them.

Useful? React with 👍 / 👎.

Comment thread kv/backup_codec.go
Comment thread main.go
@bootjp
bootjp force-pushed the design/live-backup-pin-substrate branch from b9e3e10 to 91a7d04 Compare July 10, 2026 20:01
@bootjp

bootjp commented Jul 10, 2026

Copy link
Copy Markdown
Owner Author

Addressed the latest-head findings:

  • backup pin capacity checks now reap expired pins before enforcing the limit
  • expired or missing backup renewals now return ErrInvalidBackupPin instead of reactivating a stale retention fence
  • deadline_ms=0 decodes to time.Time{} so apply validation rejects it as invalid
  • backup pin tracker entries are scoped by Raft group, so one group's Release cannot remove another group's pin for the same pin_id

Validation:

  • go test ./kv -run 'Test(ActiveTimestampTracker|BackupCodec|ApplyBackup|BackupPayload)' -count=1 -timeout=240s\n- go test ./kv -count=1 -timeout=300s\n- golangci-lint run ./kv --timeout=5m\n\n@codex review

@github-actions

Copy link
Copy Markdown
Contributor

TLA+ spec divergence review (auto-triggered)

This PR touches files that the TLA+ safety spec has an anchor on (per
docs/design/2026_05_28_implemented_tla_safety_spec.md §3),
so an AI review is requested below to verify the implementation has not drifted
from the model.

Anchored files changed in this PR head (91a7d04):

  • kv/fsm.go

What to check, by subsystem:

  • kv/hlc*.goNext() must respect the HLC-4 preconditions (i)/(ii)/(iii) from the design doc: bounded skew, logical-counter handoff on leader change (strategy (c) Observe(MaxAppliedHLC)), and the commit-time ceiling fence (fail-closed when wall_now >= physicalCeiling). Any change to the bit layout (48/16), the CAS loop, or the ceiling getter/setter is in scope.
  • kv/coordinator.go, kv/sharded_coordinator.goRunHLCLeaseRenewal, hlcRenewalInterval, hlcPhysicalWindowMs constants, and the new-term detection that calls Observe(fsm.MaxAppliedHLC()) (strategy (c)). Any change to renewal cadence, group selection, or fail-closed behaviour is in scope.
  • kv/transaction.go, kv/lock_resolver.go — OCC commit-ts assignment, lock-map encoding (key, lock_ts) -> start_ts, and the LockResolver action OCC-3 depends on. (M2 spec will land OCC-1..OCC-5; until then the spec doc §5.2 is the contract.)
  • kv/fsm.go — FSM apply of HLC lease entries (SetPhysicalCeiling), and any future MaxAppliedHLC() accessor that strategy (c) needs.
  • store/mvcc_store.go — version visibility, snapshot install, and the MVCC-1..MVCC-4 invariants (M3 scope).
  • distribution/** — route catalog versioning, SplitRange atomicity, and CatalogWatcher async fan-out (M4 scope).

If the change is correct but requires a spec update, edit tla/hlc/HLC.tla (or the corresponding M2..M5 module once landed) and the design doc in the same PR. The tla-check workflow runs the TLC model check on the same paths.


@claude review please verify TLA+ spec divergence per the checklist above.

@codex review please verify TLA+ spec divergence per the checklist above.

@chatgpt-codex-connector

Copy link
Copy Markdown

To use Codex here, create a Codex account and connect to github.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 91a7d04265

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread kv/fsm_backup.go Outdated
Comment on lines +27 to +28
if errors.Is(err, ErrTooManyActiveBackups) || errors.Is(err, ErrInvalidBackupPin) {
return err

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Do not drop committed backup pins as proposal errors

When this branch is reached for the local-state-dependent errors (capacity, missing/expired renewals), applyBackup returns a plain error instead of haltErr, so the Raft engine treats the entry as applied and only the proposer observes the response. In a multi-replica group, one replica can hit this branch because its tracker still has an unexpired pin or its clock has already expired a renewal while the leader installed the new/extended fence; that replica then advances without retaining read_ts, and after a leader change or local compaction the backup can lose the version it was meant to protect.

Useful? React with 👍 / 👎.

Comment thread kv/active_timestamp_tracker.go Outdated
t.mu.Lock()
expired := t.reapExpiredBackupPinsLocked(time.Now())
key := newBackupPinKey(pinID, groupID)
if _, exists := t.backupPins[key]; !exists && len(t.backupPins) >= t.maxBackupPins {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Count backup capacity by pin ID, not group entry

Now that backupPins is keyed by (pin_id, groupID) and every shard FSM shares this tracker, len(t.backupPins) charges one slot per Raft group. A single logical backup fan-out with the same pin_id across more than 64 groups will fill the default limit and the next group’s BackupPin returns ErrTooManyActiveBackups, so large sharded deployments cannot start even one backup unless the limit is raised by group count.

Useful? React with 👍 / 👎.

@bootjp
bootjp force-pushed the design/live-backup-pin-substrate branch from 91a7d04 to b04b7fb Compare July 10, 2026 20:19
@bootjp

bootjp commented Jul 10, 2026

Copy link
Copy Markdown
Owner Author

Addressed latest-head review findings:

  • committed backup Pin entries now use an apply path that does not enforce the local active-backup cap, so a replica does not advance without installing the retention fence
  • committed backup Extend entries treat missing/expired local pins as no-op apply results instead of proposal errors, while direct Extend still rejects missing/expired renewals
  • the active-backup limit now counts logical pin IDs rather than per-group tracker entries, so one backup fan-out across groups consumes one capacity slot

Validation:

  • go test ./kv -run 'Test(ActiveTimestampTracker|BackupCodec|ApplyBackup|BackupPayload)' -count=1 -timeout=240s
  • go test ./kv -count=1 -timeout=300s
  • golangci-lint run ./kv --timeout=5m
  • git diff --check
  • git verify-commit HEAD

@codex review

@github-actions

Copy link
Copy Markdown
Contributor

TLA+ spec divergence review (auto-triggered)

This PR touches files that the TLA+ safety spec has an anchor on (per
docs/design/2026_05_28_implemented_tla_safety_spec.md §3),
so an AI review is requested below to verify the implementation has not drifted
from the model.

Anchored files changed in this PR head (b04b7fb):

  • kv/fsm.go

What to check, by subsystem:

  • kv/hlc*.goNext() must respect the HLC-4 preconditions (i)/(ii)/(iii) from the design doc: bounded skew, logical-counter handoff on leader change (strategy (c) Observe(MaxAppliedHLC)), and the commit-time ceiling fence (fail-closed when wall_now >= physicalCeiling). Any change to the bit layout (48/16), the CAS loop, or the ceiling getter/setter is in scope.
  • kv/coordinator.go, kv/sharded_coordinator.goRunHLCLeaseRenewal, hlcRenewalInterval, hlcPhysicalWindowMs constants, and the new-term detection that calls Observe(fsm.MaxAppliedHLC()) (strategy (c)). Any change to renewal cadence, group selection, or fail-closed behaviour is in scope.
  • kv/transaction.go, kv/lock_resolver.go — OCC commit-ts assignment, lock-map encoding (key, lock_ts) -> start_ts, and the LockResolver action OCC-3 depends on. (M2 spec will land OCC-1..OCC-5; until then the spec doc §5.2 is the contract.)
  • kv/fsm.go — FSM apply of HLC lease entries (SetPhysicalCeiling), and any future MaxAppliedHLC() accessor that strategy (c) needs.
  • store/mvcc_store.go — version visibility, snapshot install, and the MVCC-1..MVCC-4 invariants (M3 scope).
  • distribution/** — route catalog versioning, SplitRange atomicity, and CatalogWatcher async fan-out (M4 scope).

If the change is correct but requires a spec update, edit tla/hlc/HLC.tla (or the corresponding M2..M5 module once landed) and the design doc in the same PR. The tla-check workflow runs the TLC model check on the same paths.


@claude review please verify TLA+ spec divergence per the checklist above.

@codex review please verify TLA+ spec divergence per the checklist above.

@chatgpt-codex-connector

Copy link
Copy Markdown

To use Codex here, create a Codex account and connect to github.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Nice work!

Reviewed commit: b04b7fb235

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
main.go (1)

389-416: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

readTracker.Close() を shutdown cleanup に追加してください。 ActiveTimestampTracker はスイーパー goroutine を持つため、cleanup.Add(readTracker.Close) で終了時に止める必要があります。

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@main.go` around lines 389 - 416, Register readTracker.Close with the shutdown
cleanup after creating the ActiveTimestampTracker, using
cleanup.Add(readTracker.Close), so its sweeper goroutine is stopped during
termination.
🧹 Nitpick comments (1)
kv/fsm.go (1)

372-373: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

applyBackup(data)applyHLCLease(data[1:]) でオペコードバイトの扱いが一貫していません。

applyHLCLeasedata[1:](オペコード除外)を渡すのに対し、applyBackupdata(オペコード含む)をそのまま渡しています。decodeBackupEntry がフルデータを期待しているため機能上は問題ありませんが、将来的な保守で混乱を招く可能性があります。

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@kv/fsm.go` around lines 372 - 373, applyBackup と applyHLCLease
で入力データのオペコード除外方法を統一してください。applyBackup 呼び出し側では applyHLCLease と同様にオペコードバイトを除いた
data[1:] を渡し、decodeBackupEntry の期待する入力形式も確認して関連処理を一貫させてください。
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@main.go`:
- Around line 389-416: Register readTracker.Close with the shutdown cleanup
after creating the ActiveTimestampTracker, using cleanup.Add(readTracker.Close),
so its sweeper goroutine is stopped during termination.

---

Nitpick comments:
In `@kv/fsm.go`:
- Around line 372-373: applyBackup と applyHLCLease
で入力データのオペコード除外方法を統一してください。applyBackup 呼び出し側では applyHLCLease と同様にオペコードバイトを除いた
data[1:] を渡し、decodeBackupEntry の期待する入力形式も確認して関連処理を一貫させてください。

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: b885a775-9adc-47fb-833c-e1990bc6fa44

📥 Commits

Reviewing files that changed from the base of the PR and between cd58354 and b04b7fb.

📒 Files selected for processing (11)
  • kv/active_timestamp_tracker.go
  • kv/active_timestamp_tracker_test.go
  • kv/backup_codec.go
  • kv/backup_codec_test.go
  • kv/fsm.go
  • kv/fsm_backup.go
  • kv/fsm_backup_test.go
  • main.go
  • main_bootstrap_e2e_test.go
  • main_encryption_write_wiring.go
  • multiraft_runtime_test.go

@bootjp

bootjp commented Jul 10, 2026

Copy link
Copy Markdown
Owner Author

Addressed latest-head review findings:

  • registered readTracker.Close with the shutdown cleanup stack so the backup-pin sweeper stops on termination
  • made backup FSM apply pass payload bytes consistently with the other reserved-opcode apply paths while preserving the full wire encoder/decoder contract

Validation:

  • go test ./kv -run 'Test(ActiveTimestampTracker|BackupCodec|ApplyBackup|BackupPayload)' -count=1 -timeout=240s\n- go test ./kv -count=1 -timeout=300s\n- go test . -count=1 -timeout=180s\n- golangci-lint run ./kv --timeout=5m\n- golangci-lint run . ./kv --timeout=5m\n- git diff --check\n- git verify-commit HEAD\n\n@codex review

@github-actions

Copy link
Copy Markdown
Contributor

TLA+ spec divergence review (auto-triggered)

This PR touches files that the TLA+ safety spec has an anchor on (per
docs/design/2026_05_28_implemented_tla_safety_spec.md §3),
so an AI review is requested below to verify the implementation has not drifted
from the model.

Anchored files changed in this PR head (a39218b):

  • kv/fsm.go

What to check, by subsystem:

  • kv/hlc*.goNext() must respect the HLC-4 preconditions (i)/(ii)/(iii) from the design doc: bounded skew, logical-counter handoff on leader change (strategy (c) Observe(MaxAppliedHLC)), and the commit-time ceiling fence (fail-closed when wall_now >= physicalCeiling). Any change to the bit layout (48/16), the CAS loop, or the ceiling getter/setter is in scope.
  • kv/coordinator.go, kv/sharded_coordinator.goRunHLCLeaseRenewal, hlcRenewalInterval, hlcPhysicalWindowMs constants, and the new-term detection that calls Observe(fsm.MaxAppliedHLC()) (strategy (c)). Any change to renewal cadence, group selection, or fail-closed behaviour is in scope.
  • kv/transaction.go, kv/lock_resolver.go — OCC commit-ts assignment, lock-map encoding (key, lock_ts) -> start_ts, and the LockResolver action OCC-3 depends on. (M2 spec will land OCC-1..OCC-5; until then the spec doc §5.2 is the contract.)
  • kv/fsm.go — FSM apply of HLC lease entries (SetPhysicalCeiling), and any future MaxAppliedHLC() accessor that strategy (c) needs.
  • store/mvcc_store.go — version visibility, snapshot install, and the MVCC-1..MVCC-4 invariants (M3 scope).
  • distribution/** — route catalog versioning, SplitRange atomicity, and CatalogWatcher async fan-out (M4 scope).

If the change is correct but requires a spec update, edit tla/hlc/HLC.tla (or the corresponding M2..M5 module once landed) and the design doc in the same PR. The tla-check workflow runs the TLC model check on the same paths.


@claude review please verify TLA+ spec divergence per the checklist above.

@codex review please verify TLA+ spec divergence per the checklist above.

@chatgpt-codex-connector

Copy link
Copy Markdown

To use Codex here, create a Codex account and connect to github.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. 👍

Reviewed commit: a39218b5b9

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@github-actions

Copy link
Copy Markdown
Contributor

TLA+ spec divergence review (auto-triggered)

This PR touches files that the TLA+ safety spec has an anchor on (per
docs/design/2026_05_28_implemented_tla_safety_spec.md §3),
so an AI review is requested below to verify the implementation has not drifted
from the model.

Anchored files changed in this PR head (4d56518):

  • kv/fsm.go

What to check, by subsystem:

  • kv/hlc*.goNext() must respect the HLC-4 preconditions (i)/(ii)/(iii) from the design doc: bounded skew, logical-counter handoff on leader change (strategy (c) Observe(MaxAppliedHLC)), and the commit-time ceiling fence (fail-closed when wall_now >= physicalCeiling). Any change to the bit layout (48/16), the CAS loop, or the ceiling getter/setter is in scope.
  • kv/coordinator.go, kv/sharded_coordinator.goRunHLCLeaseRenewal, hlcRenewalInterval, hlcPhysicalWindowMs constants, and the new-term detection that calls Observe(fsm.MaxAppliedHLC()) (strategy (c)). Any change to renewal cadence, group selection, or fail-closed behaviour is in scope.
  • kv/transaction.go, kv/lock_resolver.go — OCC commit-ts assignment, lock-map encoding (key, lock_ts) -> start_ts, and the LockResolver action OCC-3 depends on. (M2 spec will land OCC-1..OCC-5; until then the spec doc §5.2 is the contract.)
  • kv/fsm.go — FSM apply of HLC lease entries (SetPhysicalCeiling), and any future MaxAppliedHLC() accessor that strategy (c) needs.
  • store/mvcc_store.go — version visibility, snapshot install, and the MVCC-1..MVCC-4 invariants (M3 scope).
  • distribution/** — route catalog versioning, SplitRange atomicity, and CatalogWatcher async fan-out (M4 scope).

If the change is correct but requires a spec update, edit tla/hlc/HLC.tla (or the corresponding M2..M5 module once landed) and the design doc in the same PR. The tla-check workflow runs the TLC model check on the same paths.


@claude review please verify TLA+ spec divergence per the checklist above.

@codex review please verify TLA+ spec divergence per the checklist above.

@chatgpt-codex-connector

Copy link
Copy Markdown

To use Codex here, create a Codex account and connect to github.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 4d56518ea2

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread kv/active_timestamp_tracker.go Outdated
}
return errors.WithStack(ErrInvalidBackupPin)
}
pin.deadline = deadline

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Preserve the later backup deadline on renewals

When two BackupExtend proposals for the same pin are in flight, or a retry of an older renewal commits after a newer one, this unconditional assignment can move the deadline backwards. If that stale deadline expires before the next renewal, Oldest() stops honoring the pin and local compaction can advance past the backup read timestamp while the backup is still running; apply should keep max(existing deadline, requested deadline) rather than shortening it.

Useful? React with 👍 / 👎.

@github-actions

Copy link
Copy Markdown
Contributor

TLA+ spec divergence review (auto-triggered)

This PR touches files that the TLA+ safety spec has an anchor on (per
docs/design/2026_05_28_implemented_tla_safety_spec.md §3),
so an AI review is requested below to verify the implementation has not drifted
from the model.

Anchored files changed in this PR head (2f77c32):

  • kv/fsm.go

What to check, by subsystem:

  • kv/hlc*.goNext() must respect the HLC-4 preconditions (i)/(ii)/(iii) from the design doc: bounded skew, logical-counter handoff on leader change (strategy (c) Observe(MaxAppliedHLC)), and the commit-time ceiling fence (fail-closed when wall_now >= physicalCeiling). Any change to the bit layout (48/16), the CAS loop, or the ceiling getter/setter is in scope.
  • kv/coordinator.go, kv/sharded_coordinator.goRunHLCLeaseRenewal, hlcRenewalInterval, hlcPhysicalWindowMs constants, and the new-term detection that calls Observe(fsm.MaxAppliedHLC()) (strategy (c)). Any change to renewal cadence, group selection, or fail-closed behaviour is in scope.
  • kv/transaction.go, kv/lock_resolver.go — OCC commit-ts assignment, lock-map encoding (key, lock_ts) -> start_ts, and the LockResolver action OCC-3 depends on. (M2 spec will land OCC-1..OCC-5; until then the spec doc §5.2 is the contract.)
  • kv/fsm.go — FSM apply of HLC lease entries (SetPhysicalCeiling), and any future MaxAppliedHLC() accessor that strategy (c) needs.
  • store/mvcc_store.go — version visibility, snapshot install, and the MVCC-1..MVCC-4 invariants (M3 scope).
  • distribution/** — route catalog versioning, SplitRange atomicity, and CatalogWatcher async fan-out (M4 scope).

If the change is correct but requires a spec update, edit tla/hlc/HLC.tla (or the corresponding M2..M5 module once landed) and the design doc in the same PR. The tla-check workflow runs the TLC model check on the same paths.


@claude review please verify TLA+ spec divergence per the checklist above.

@codex review please verify TLA+ spec divergence per the checklist above.

@chatgpt-codex-connector

Copy link
Copy Markdown

To use Codex here, create a Codex account and connect to github.

@bootjp

bootjp commented Jul 18, 2026

Copy link
Copy Markdown
Owner Author

Addressed the current-head P1 and CI failure in signed commit 2f77c32f76e102d20b29b52b1aebb9eb05d26d45.

  • backup renewals now preserve max(existing_deadline, requested_deadline), so an older retry cannot shorten an already-extended retention fence
  • added a regression test that applies a stale renewal after a later deadline
  • updated the pinned TLA+ v1.8.0 jar checksum to the current official GitHub release asset digest (58d44845...bb3d); the previous CI failure was a download checksum mismatch, not a model violation
  • audited all Extend / ExtendForGroup / ApplyExtendForGroup callers; the only production apply path is kv/fsm_backup.go, and monotonic extension preserves its contract

Validation:

  • go test ./kv -count=1
  • go test -race ./kv -run TestActiveTimestampTrackerBackupPinExtend -count=1
  • golangci-lint run ./kv --timeout=5m --allow-parallel-runners
  • make tla-check (all expected pass/fail model outcomes matched)
  • git diff --check
  • signed commit verified for bootjp <contact@bootjp.me>

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 2f77c32f76

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +212 to +214
if !pin.deadline.After(time.Now()) {
delete(t.backupPins, key)
t.mu.Unlock()

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Preserve committed backup renewals after local expiry

In the FSM apply path (ApplyExtendForGroup(..., false) from kv/fsm_backup.go), this wall-clock expiry check makes a committed renewal disappear on any replica that applies or cold-start replays the BackupExtend after the previous deadline has passed locally, even when the extend entry carries a later future deadline. After that replica catches up, its compactor sees no backup pin and can compact away versions still needed by the live backup, while faster replicas keep the renewed fence. The apply/replay path should make the deadline monotonic from the log entry instead of deleting the pin based on local apply time.

Useful? React with 👍 / 👎.

Comment thread kv/active_timestamp_tracker.go Outdated
Comment on lines +138 to +143
for _, pin := range t.backupPins {
if !pin.deadline.After(now) {
continue
}
if oldest == 0 || pin.readTS < oldest {
oldest = pin.readTS

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Scope backup pin retention to the compacted group

In multi-group deployments where a backup covers only a subset of groups, this global scan feeds every group compactor: main.go passes one readTracker to startFSMCompactorIfEnabled, and FSMCompactor.safeMinTS calls tracker.Oldest() for each runtime. Because Oldest() returns the minimum backup pin across all groupIDs, a pin applied for group 1 also lowers the compaction watermark for unrelated groups, so a long or leaked group-local backup can freeze compaction and grow disk outside the backup scope. The backup-pin portion of the tracker should be queried by runtime.GroupID (while keeping ordinary active read pins global if needed).

Useful? React with 👍 / 👎.

Comment thread kv/active_timestamp_tracker.go Outdated
t.logExpiredBackupPins(expired)
return errors.WithStack(ErrTooManyActiveBackups)
}
t.backupPins[key] = backupDeadlinePin{readTS: readTS, deadline: deadline}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Keep duplicate pin applies monotonic

When a BeginBackup pin proposal is retried after the original commit response is lost, the stale BackupPin entry can be committed after a later BackupExtend; this assignment then overwrites the already-extended record with the old deadline (and can also move readTS forward if the ID is reused), shortening the retention fence while the backup is still scanning. Duplicate applies for an existing (pinID, groupID) should preserve the safest state, e.g. min(existing.readTS, requested.readTS) and max(existing.deadline, requested.deadline), or reject non-identical duplicate pins.

Useful? React with 👍 / 👎.

@github-actions

Copy link
Copy Markdown
Contributor

TLA+ spec divergence review (auto-triggered)

This PR touches files that the TLA+ safety spec has an anchor on (per
docs/design/2026_05_28_implemented_tla_safety_spec.md §3),
so an AI review is requested below to verify the implementation has not drifted
from the model.

Anchored files changed in this PR head (0584f06):

  • kv/fsm.go

What to check, by subsystem:

  • kv/hlc*.goNext() must respect the HLC-4 preconditions (i)/(ii)/(iii) from the design doc: bounded skew, logical-counter handoff on leader change (strategy (c) Observe(MaxAppliedHLC)), and the commit-time ceiling fence (fail-closed when wall_now >= physicalCeiling). Any change to the bit layout (48/16), the CAS loop, or the ceiling getter/setter is in scope.
  • kv/coordinator.go, kv/sharded_coordinator.goRunHLCLeaseRenewal, hlcRenewalInterval, hlcPhysicalWindowMs constants, and the new-term detection that calls Observe(fsm.MaxAppliedHLC()) (strategy (c)). Any change to renewal cadence, group selection, or fail-closed behaviour is in scope.
  • kv/transaction.go, kv/lock_resolver.go — OCC commit-ts assignment, lock-map encoding (key, lock_ts) -> start_ts, and the LockResolver action OCC-3 depends on. (M2 spec will land OCC-1..OCC-5; until then the spec doc §5.2 is the contract.)
  • kv/fsm.go — FSM apply of HLC lease entries (SetPhysicalCeiling), and any future MaxAppliedHLC() accessor that strategy (c) needs.
  • store/mvcc_store.go — version visibility, snapshot install, and the MVCC-1..MVCC-4 invariants (M3 scope).
  • distribution/** — route catalog versioning, SplitRange atomicity, and CatalogWatcher async fan-out (M4 scope).

If the change is correct but requires a spec update, edit tla/hlc/HLC.tla (or the corresponding M2..M5 module once landed) and the design doc in the same PR. The tla-check workflow runs the TLC model check on the same paths.


@claude review please verify TLA+ spec divergence per the checklist above.

@codex review please verify TLA+ spec divergence per the checklist above.

@chatgpt-codex-connector

Copy link
Copy Markdown

To use Codex here, create a Codex account and connect to github.

@bootjp

bootjp commented Jul 18, 2026

Copy link
Copy Markdown
Owner Author

Addressed all current-head findings in signed commit 0584f06437ce629c7f9620376c74145be91162db.

  • committed BackupExtend apply/replay no longer deletes an existing pin based on local wall-clock expiry; it applies the logged deadline monotonically
  • duplicate BackupPin applies preserve min(existing_read_ts, requested_read_ts) and max(existing_deadline, requested_deadline)
  • added OldestForGroup so each FSM compactor observes process-wide ordinary read pins plus only its own Raft group backup pins; capacity reservation records and unrelated group pins do not stall it
  • direct late renewal still fails closed with ErrInvalidBackupPin

Caller audit:

  • Pin/Extend production mutation path remains only kv/fsm_backup.go
  • compactor call chain is compactRuntime -> targetMinTS(groupID) -> safeMinTS(groupID) -> OldestForGroup(groupID)
  • ordinary Pin callers retain process-wide protection through every OldestForGroup result

Validation:

  • go test ./kv -count=1
  • go test -race ./kv -run Test(ActiveTimestampTracker|FSMCompactorScopesBackupPinsByGroup|ApplyBackup) -count=1
  • golangci-lint run ./kv --timeout=5m --allow-parallel-runners
  • git diff --check
  • signed commit verified for bootjp <contact@bootjp.me>

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Keep them coming!

Reviewed commit: 0584f06437

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

bootjp added a commit that referenced this pull request Jul 19, 2026
## Summary
- add the live-backup admin RPC surface for BeginBackup, RenewBackup,
EndBackup, ListAdaptersAndScopes, and GetNodeVersion
- expose the node build version through the gRPC Admin service and
surface leader node versions in GetRaftGroups via an async cache
- expose the Raft snapshot threshold through the engine interface so
backup headroom checks can use the configured value

Base: #1056

## Validation
- go test ./adapter -run
'Test(GetNodeVersion|GetRaftGroups|GroupOrdering|AdminTokenAuth|GetClusterOverview)'
-count=1
- go test . -count=1
- go test ./internal/raftengine/etcd -run
'Test(SnapshotEvery|EngineSnapshotEvery)' -count=1
- go test ./kv -run
'Test(CoordinateDispatch|LeaderProxy|LeaseRead|ShardedCoordinator|ValidateReadOnlyShards|LeaseWarmup)'
-count=1
- go test ./internal/raftadmin -count=1
- golangci-lint run --timeout=5m
- go test ./... -run '^$' -count=1
- git diff --check
- git verify-commit HEAD

Author: bootjp
@bootjp

bootjp commented Jul 19, 2026

Copy link
Copy Markdown
Owner Author

@copilot resolve the merge conflicts in this pull request

Copilot AI commented Jul 19, 2026

Copy link
Copy Markdown
Contributor

@copilot resolve the merge conflicts in this pull request

Merge conflicts resolved in commit merge: resolve conflicts with origin/main.

Changes made:

  • Makefile: adopted origin/main's stable TLA v1.7.4 pin (the rolling v1.8.0 pre-release asset is replaced on each upstream build)
  • adapter/admin_grpc.go: combined both sides — NewAdminServer now initialises capabilities (from main) alongside the leader-version probe fields and opts …AdminOption (from branch)
  • adapter/admin_grpc_test.go: kept both new tests (TestGetNodeVersionReturnsConfiguredVersion from branch and TestGetClusterOverviewReturnsCapabilities from main)
  • main.go: creates the admin server with leader-version opts and then calls SetCapability for S3 blob offload
  • proto/admin.pb.go: regenerated via buf generate so the descriptor now covers both capabilities in GetClusterOverviewResponse and all backup/GetNodeVersion RPCs
  • multiraft_runtime_test.go: added the missing readTracker (nil) argument to the buildShardGroups call added by origin/main

Build and tests (./kv/..., ./adapter/..., . -run TestBuildShardGroups|TestRaftBootstrap) all pass.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 471c6afe3f

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread kv/backup_codec.go
Comment on lines +47 to +49
type BackupExtendEntry struct {
PinID BackupPinID
Deadline time.Time

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Carry read_ts in backup renewals

When a backup is renewed long enough for Raft to snapshot/compact the original BackupPin, a restarted replica or one catching up via snapshot restores only MVCC data, not the in-memory tracker. The remaining BackupExtend entries carry only PinID and Deadline, and ApplyExtendForGroup no-ops when the pin is missing, so that replica cannot recreate the read_ts retention fence and its compactor can remove versions still being scanned. This affects long-running backups that cross a snapshot/restore boundary; include the read timestamp in renewals or persist the active pins in snapshots.

Useful? React with 👍 / 👎.

Comment thread kv/fsm.go
// RaftAppliedIndex from the engine's appliedIndex.
func (f *kvFSM) IsVolatileOnlyPayload(payload []byte) bool {
return len(payload) > 0 && payload[0] == raftEncodeHLCLease
return len(payload) > 0 && (payload[0] == raftEncodeHLCLease || payload[0] == raftEncodeBackup)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Validate backup payloads before volatile replay

This classifies every payload starting with the backup opcode as safe to replay during the cold-start skip path, but that path calls StateMachine.Apply and discards the returned value. If the skipped WAL tail contains an unknown future backup subtype, malformed backup payload, or a backup entry on an FSM without the tracker, normal apply would halt via applyBackup, while cold start silently seeds Raft past the entry without applying the intended fence/release effect. Decode known backup subtypes here, or make volatile replay honor HaltApply.

Useful? React with 👍 / 👎.

@github-actions

Copy link
Copy Markdown
Contributor

TLA+ spec divergence review (auto-triggered)

This PR touches files that the TLA+ safety spec has an anchor on (per
docs/design/2026_05_28_implemented_tla_safety_spec.md §3),
so an AI review is requested below to verify the implementation has not drifted
from the model.

Anchored files changed in this PR head (748c75b):

  • kv/fsm.go

What to check, by subsystem:

  • kv/hlc*.goNext() must respect the HLC-4 preconditions (i)/(ii)/(iii) from the design doc: bounded skew, logical-counter handoff on leader change (strategy (c) Observe(MaxAppliedHLC)), and the commit-time ceiling fence (fail-closed when wall_now >= physicalCeiling). Any change to the bit layout (48/16), the CAS loop, or the ceiling getter/setter is in scope.
  • kv/coordinator.go, kv/sharded_coordinator.goRunHLCLeaseRenewal, hlcRenewalInterval, hlcPhysicalWindowMs constants, and the new-term detection that calls Observe(fsm.MaxAppliedHLC()) (strategy (c)). Any change to renewal cadence, group selection, or fail-closed behaviour is in scope.
  • kv/transaction.go, kv/lock_resolver.go — OCC commit-ts assignment, lock-map encoding (key, lock_ts) -> start_ts, and the LockResolver action OCC-3 depends on. (M2 spec will land OCC-1..OCC-5; until then the spec doc §5.2 is the contract.)
  • kv/fsm.go — FSM apply of HLC lease entries (SetPhysicalCeiling), and any future MaxAppliedHLC() accessor that strategy (c) needs.
  • store/mvcc_store.go — version visibility, snapshot install, and the MVCC-1..MVCC-4 invariants (M3 scope).
  • distribution/** — route catalog versioning, SplitRange atomicity, and CatalogWatcher async fan-out (M4 scope).

If the change is correct but requires a spec update, edit tla/hlc/HLC.tla (or the corresponding M2..M5 module once landed) and the design doc in the same PR. The tla-check workflow runs the TLC model check on the same paths.


@claude review please verify TLA+ spec divergence per the checklist above.

@codex review please verify TLA+ spec divergence per the checklist above.

@chatgpt-codex-connector

Copy link
Copy Markdown

To use Codex here, create a Codex account and connect to github.

@bootjp

bootjp commented Jul 19, 2026

Copy link
Copy Markdown
Owner Author

Updated the signed HEAD to 748c75bb5d2eeb172041e657f55eedd3a4159a39 by merging current main.

Verification:

  • backup pin and compactor-focused kv tests pass
  • proto breaking and generation checks pass with no generated diff
  • current-head CI is green across tests, lint, proto, TLA+, build, and CodeQL
  • the merge commit has a valid bootjp signature

Please review the latest head.

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 748c75bb5d

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread kv/active_timestamp_tracker.go Outdated
@github-actions

Copy link
Copy Markdown
Contributor

TLA+ spec divergence review (auto-triggered)

This PR touches files that the TLA+ safety spec has an anchor on (per
docs/design/2026_05_28_implemented_tla_safety_spec.md §3),
so an AI review is requested below to verify the implementation has not drifted
from the model.

Anchored files changed in this PR head (13d22a8):

  • kv/fsm.go

What to check, by subsystem:

  • kv/hlc*.goNext() must respect the HLC-4 preconditions (i)/(ii)/(iii) from the design doc: bounded skew, logical-counter handoff on leader change (strategy (c) Observe(MaxAppliedHLC)), and the commit-time ceiling fence (fail-closed when wall_now >= physicalCeiling). Any change to the bit layout (48/16), the CAS loop, or the ceiling getter/setter is in scope.
  • kv/coordinator.go, kv/sharded_coordinator.goRunHLCLeaseRenewal, hlcRenewalInterval, hlcPhysicalWindowMs constants, and the new-term detection that calls Observe(fsm.MaxAppliedHLC()) (strategy (c)). Any change to renewal cadence, group selection, or fail-closed behaviour is in scope.
  • kv/transaction.go, kv/lock_resolver.go — OCC commit-ts assignment, lock-map encoding (key, lock_ts) -> start_ts, and the LockResolver action OCC-3 depends on. (M2 spec will land OCC-1..OCC-5; until then the spec doc §5.2 is the contract.)
  • kv/fsm.go — FSM apply of HLC lease entries (SetPhysicalCeiling), and any future MaxAppliedHLC() accessor that strategy (c) needs.
  • store/mvcc_store.go — version visibility, snapshot install, and the MVCC-1..MVCC-4 invariants (M3 scope).
  • distribution/** — route catalog versioning, SplitRange atomicity, and CatalogWatcher async fan-out (M4 scope).

If the change is correct but requires a spec update, edit tla/hlc/HLC.tla (or the corresponding M2..M5 module once landed) and the design doc in the same PR. The tla-check workflow runs the TLC model check on the same paths.


@claude review please verify TLA+ spec divergence per the checklist above.

@codex review please verify TLA+ spec divergence per the checklist above.

@chatgpt-codex-connector

Copy link
Copy Markdown

To use Codex here, create a Codex account and connect to github.

@bootjp

bootjp commented Jul 19, 2026

Copy link
Copy Markdown
Owner Author

Current signed HEAD 13d22a8171d828d6eed4bd87aceed69ece2e801a addresses the latest-head renewal finding.

  • BackupExtend carries read_ts and committed apply reconstructs a locally swept pin
  • pin merge remains monotonic: earliest read_ts, latest deadline
  • direct Extend continues to fail on missing or expired pins
  • the wire schema and focused design text now match the 34-byte extend entry

Caller audit:

  • ApplyExtendForGroup has one production caller in kv/fsm_backup.go
  • EncodeBackupExtendEntry has no production caller; live renewal already replays a complete BackupPin
  • direct Extend behavior is unchanged for its caller surface

Verification:

  • focused backup tracker/FSM/codec tests
  • go test ./kv -count=1 -timeout=300s
  • focused go test -race ./kv
  • golangci-lint run ./kv --timeout=5m --allow-parallel-runners
  • git diff --check

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Can't wait for the next one!

Reviewed commit: 13d22a8171

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@bootjp
bootjp force-pushed the design/live-backup-pin-substrate branch from 13d22a8 to 26d45ba Compare July 19, 2026 11:08
@github-actions

Copy link
Copy Markdown
Contributor

TLA+ spec divergence review (auto-triggered)

This PR touches files that the TLA+ safety spec has an anchor on (per
docs/design/2026_05_28_implemented_tla_safety_spec.md §3),
so an AI review is requested below to verify the implementation has not drifted
from the model.

Anchored files changed in this PR head (26d45ba):

  • kv/fsm.go

What to check, by subsystem:

  • kv/hlc*.goNext() must respect the HLC-4 preconditions (i)/(ii)/(iii) from the design doc: bounded skew, logical-counter handoff on leader change (strategy (c) Observe(MaxAppliedHLC)), and the commit-time ceiling fence (fail-closed when wall_now >= physicalCeiling). Any change to the bit layout (48/16), the CAS loop, or the ceiling getter/setter is in scope.
  • kv/coordinator.go, kv/sharded_coordinator.goRunHLCLeaseRenewal, hlcRenewalInterval, hlcPhysicalWindowMs constants, and the new-term detection that calls Observe(fsm.MaxAppliedHLC()) (strategy (c)). Any change to renewal cadence, group selection, or fail-closed behaviour is in scope.
  • kv/transaction.go, kv/lock_resolver.go — OCC commit-ts assignment, lock-map encoding (key, lock_ts) -> start_ts, and the LockResolver action OCC-3 depends on. (M2 spec will land OCC-1..OCC-5; until then the spec doc §5.2 is the contract.)
  • kv/fsm.go — FSM apply of HLC lease entries (SetPhysicalCeiling), and any future MaxAppliedHLC() accessor that strategy (c) needs.
  • store/mvcc_store.go — version visibility, snapshot install, and the MVCC-1..MVCC-4 invariants (M3 scope).
  • distribution/** — route catalog versioning, SplitRange atomicity, and CatalogWatcher async fan-out (M4 scope).

If the change is correct but requires a spec update, edit tla/hlc/HLC.tla (or the corresponding M2..M5 module once landed) and the design doc in the same PR. The tla-check workflow runs the TLC model check on the same paths.


@claude review please verify TLA+ spec divergence per the checklist above.

@codex review please verify TLA+ spec divergence per the checklist above.

@chatgpt-codex-connector

Copy link
Copy Markdown

To use Codex here, create a Codex account and connect to github.

@bootjp

bootjp commented Jul 19, 2026

Copy link
Copy Markdown
Owner Author

History-only author-compliance repair completed at 26d45baebb34ae6afbfaf39394e62deafcddc481.

  • final tree is byte-identical to prior head 13d22a8171d828d6eed4bd87aceed69ece2e801a
  • the PR now exposes one linear commit authored and committed by bootjp <contact@bootjp.me>
  • GitHub reports the commit signature as verified/valid
  • parent is current origin/main (37277ea86cb4cf66bf980b8a09427394f6de69e1)

No runtime or source-tree semantics changed. CI is running on the reconstructed head.

@codex review

@bootjp

bootjp commented Jul 19, 2026

Copy link
Copy Markdown
Owner Author

Current reconstructed head 26d45baebb34ae6afbfaf39394e62deafcddc481 is fully green. PR-visible authorship and signature verification pass, the final tree remains identical to the pre-rewrite head, and there are no current-head root findings. Please complete the latest-head review. @codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Delightful!

Reviewed commit: 26d45baebb

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants