Skip to content

sync: require the page ledger and delete the token-checkpoint sync path - #1203

Open
kans wants to merge 14 commits into
mainfrom
refactor/1a-one-syncer
Open

kans wants to merge 14 commits into
mainfrom
refactor/1a-one-syncer

Conversation

@kans

@kans kans commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

Every production sync has run through the page ledger since it landed; the s.ledgered flag and the token-checkpoint handlers behind it were dead. This removes the flag, makes the ledger a hard requirement of setStore, and deletes the legacy bodies.

What changed

  • syncer.go (4453 → 3169 lines): setStore sets storeAttachErr unless the store is Pebble and implements c1zstore.PageLedgerStore. It is a plain error, not ErrArtifactUnusable, because the c1z is fine; the caller wired the wrong store. Checkpoint, checkpointInterval, lastCheckPointTime, testHooks.checkpointHook, the legacy Sync body, and the cascade it alone reached (listAllResourceTypes, getSubResources, syncResources, syncEntitlementsForResource, syncStaticEntitlementsForResourceType, syncAssetsForResource, syncGrantsForResource, filterFreshGrantResource, and friends) are gone. Sync* methods forward to syncLedger*. transitionActionState returns an error when no ledger commit key is present; invokeActionPage always installs one, so the removed arm was test-only.
  • ingest_filter.go, store_caps.go: unused cascade only.
  • Token format (marshalToken/unmarshalToken, GraphFromToken, compaction tokens) is untouched. ledger_takeover.go and compaction_token.go still read it; only the write/checkpoint path died.
  • Tests: ledgeredStore / withLedgerCaps / withTripwireLedgerCaps (ledgered_store_test.go) give doubles the ledger capabilities setStore now demands. Tests that existed to compare the ledger path against the token path lost their oracle, so the token handler's output on main at 8f8783c4 is captured under testdata/ledger_golden/ and TestLedgerExternalSelectionMatchesGolden (seven selection modes), TestLedgerExternalUsesMainHandler, and TestLedgerStaticEntitlementsMatchGolden assert against it. Deleting one grant from a golden file fails the matching subtest. Token-path-only scheduler tests are deleted where a ledger twin exists (listed per commit). TestParallelBatchSecondGenuineFailureStillLogs and TestParallelBatchFailureDuringStopStaysQuiet built a bare syncer{} and ran through the deleted !s.ledgered fallback; the first failed 81/200 on this branch (0/200 on main) because the handler never ran and the rendezvous never happened, the second passed because nothing ran. Both now use newLedgerSchedulerFixture and assert the handler ran: 200/200 and 50/50 under -race. Review follow-ups, one commit each: transitionActionState returns error (its action slice was always nil), checkpointOnStop alias inlined, parallelActionQueue.commitUnlocked removed (always true), the cold-resume materialization test compares against the uninterrupted run with equalProtoLists, and the two no-cancel-log assertions check WarnLevel, the level parallel_syncer.go logs at (they checked ErrorLevel and could not fail).

What to look at

  • setStore and the storeAttachErr check in Sync: this is the one behaviour change. A caller passing a non-Pebble or non-ledger store used to fall through to the token path and now gets an error: from NewSyncer with WithConnectorStore, from loadStore at the start of Sync with WithC1ZPath. dotc1z.RegisterEngine's doc now says so.
  • transitionActionState's new error return: confirm with me if you can see a production path that reaches it without a ledger commit key.
  • The golden JSON files are the spec for external selection; they were generated on main, not hand-written.

How checked

go vet, golangci-lint run ./pkg/sync/... 0 issues; go test ./pkg/sync/... -count=1: sync 1026s, expand 208s, all ok. Golden mutation check as above.

@kans
kans requested a review from a team October 29, 2026 20:25
@github-actions

github-actions Bot commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor
Superseded — see the current review report for commit 6d454d847ad1

General PR Review: sync: require the page ledger and delete the token-checkpoint sync path

Blocking Issues: 0 | Suggestions: 2 | Threads Resolved: 0
Criteria: Criteria status: loaded .claude/skills/ci-review.md from trusted base 8f8783c4e568.
Review mode: full
View review run

Review Summary

This PR removes syncer.ledgered and the token-checkpoint path that ran when it was false: Checkpoint, the legacy Sync/SkipSync bodies, the per-op token handlers, and the MarkSyncSupportsDiff write. Sync* methods now forward to syncLedger*. setStore now rejects any store that is not Pebble with a PageLedgerStore. I scanned the full PR diff for security and correctness. Every production if s.ledgered branch in parallel_syncer.go, initial_actions.go, ledger_pending.go, ledger_scheduler.go, ingest_invariants.go, session_binding.go and ledger_sync.go reduces to the old ledgered arm. The old Checkpoint was already a no-op when ledgered, so dropping the loop-top call and its stop-path rescue changes nothing for Pebble.

Notes on the PR's specific questions:

  • Stores in this repo: Pebble is the only engine, and pkg/dotc1z has the only Metadata() implementations, so every store attached in this repo already passed the new check. That covers the compactor, rollback-expansion and loadStore.
  • transitionActionState: it is reached only through nextPageOrFinishAction. Handler calls are staged by the ledgerInvocationKey early return. The commit call at ledger_scheduler.go:190 always carries ledgerCommitKey. I found no production path to the new error.
  • Token format: marshalToken/unmarshalToken, takeover and compaction readers are untouched.

Criteria applied (risk triage):

  • Silence: no. The one behaviour change fails loudly at Sync start.
  • Durability: no. No wire, token or c1z format change.
  • Uncontrolled dimensions: no new schedule or version-pair dependence.
  • Consumer distance: yes. Downstream callers passing custom stores via WithConnectorStore are affected.
  • Consequence: rung 1 (redeploy). Verdict: LOW.

Other criteria checks:

  • No exported Go API, proto or go.mod changes.
  • The cost-contract paths (expansion, per-checkpoint loop) only lose work, so no benchmark is needed.
  • The deleted token-path tests are replaced by golden fixtures and existing ledger twins, e.g. ledger_queue_commit_test.go, ledger_attempts_test.go, ledger_scheduler_test.go.

Coverage gaps:

  • I did not regenerate the golden JSON on main to confirm the claimed provenance.
  • I checked a sample of the deleted scheduler tests for ledger twins, not every one.

Security Issues

None found.

Correctness Issues

None found.

Suggestions

  • New — pkg/sync/syncer.go:2658: a store whose Metadata().Engine is "" or unknown (mocks, wrappers, gRPC-backed) used to run the token path. Passed via WithConnectorStore, it now fails Sync. Only downstream custom stores are affected, but the PR body should name the 0.x minor bump and add a migration note, per the repo criteria (confidence: medium).
  • New — cmd/baton-crash-harness/main.go:21-23, cmd/baton-crash-harness/driver_test.go:60-62: these comments justify -page-delay-ms by the "production checkpoint cadence (minCheckpointInterval)". This PR deletes that constant and the cadence it described, so the comments now describe a mechanism that no longer exists (confidence: high, low impact).
Prompt for AI agents
Verify each finding against the current code and only fix it if needed.

## Suggestions

In the PR description (setStore behaviour in `pkg/sync/syncer.go` around line 2651-2661):
- setStore now rejects any store that is not Pebble with PageLedgerStore. Previously, stores reporting an empty or unknown engine fell back to the token path. Add to the PR body that this is a compatibility break for downstream callers who pass custom c1zstore.Store implementations via WithConnectorStore. Name the 0.x minor version bump it requires and give a one-line migration note: such stores must report Engine "pebble" and implement c1zstore.PageLedgerStore.

In `cmd/baton-crash-harness/main.go`:
- Around line 21-23: the package comment refers to "the production checkpoint cadence (minCheckpointInterval)". This PR deletes that constant. Reword it to say the delay keeps sessions interruptible mid-page, or delete the clause.

In `cmd/baton-crash-harness/driver_test.go`:
- Around line 60-62: the harnessPageDelayMs comment refers to minCheckpointInterval and "the production checkpoint cadence". Update it the same way.

Comment thread pkg/sync/syncer.go
if s.caps.pageLedger != nil {
s.storeAttachErr = fmt.Errorf("sync store engine %q must not implement PageLedgerStore", store.Metadata().Engine)
}
if c1zstore.Engine(store.Metadata().Engine) != c1zstore.EnginePebble || s.caps.pageLedger == nil {

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.

🟡 Suggestion: This changes what WithConnectorStore accepts. Before this PR, a store whose Metadata().Engine was "" or unknown (mocks, in-memory wrappers, gRPC-backed stores) ran the token path. Now Sync fails for those stores. Every in-repo implementation is Pebble, so this only affects downstream custom c1zstore.Store implementations. Per the repo criteria, the PR body should name the 0.x minor bump and include a one-line migration note for custom-store callers. (confidence: medium)

@github-actions

github-actions Bot commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor
Superseded — see the current review report for commit 81dd6ca2c0cb

General PR Review: sync: require the page ledger and delete the token-checkpoint sync path

Blocking Issues: 0 | Suggestions: 2 | Threads Resolved: 0
Criteria: Criteria status: loaded .claude/skills/ci-review.md from trusted base 8f8783c4e568.
Review mode: full
View review run

Review Summary

This PR removes syncer.ledgered and the token-checkpoint path that ran when it was false: Checkpoint, the legacy Sync/SkipSync bodies, the per-op token handlers, and the MarkSyncSupportsDiff write. Sync* methods now forward to syncLedger*. setStore now rejects any store that is not Pebble with a PageLedgerStore. I scanned the full PR diff for security and correctness. Every production if s.ledgered branch in parallel_syncer.go, initial_actions.go, ledger_pending.go, ledger_scheduler.go, ingest_invariants.go, session_binding.go and ledger_sync.go reduces to the old ledgered arm. The old Checkpoint was already a no-op when ledgered, so dropping the loop-top call and its stop-path rescue changes nothing for Pebble.

Notes on the PR's specific questions:

  • Stores in this repo: Pebble is the only engine, and pkg/dotc1z has the only Metadata() implementations, so every store attached in this repo already passed the new check. That covers the compactor, rollback-expansion and loadStore.
  • transitionActionState: it is reached only through nextPageOrFinishAction. Handler calls are staged by the ledgerInvocationKey early return. The commit call at ledger_scheduler.go:190 always carries ledgerCommitKey. I found no production path to the new error.
  • Token format: marshalToken/unmarshalToken, takeover and compaction readers are untouched.

Criteria applied (risk triage):

  • Silence: no. The one behaviour change fails loudly at Sync start.
  • Durability: no. No wire, token or c1z format change.
  • Uncontrolled dimensions: no new schedule or version-pair dependence.
  • Consumer distance: yes. Downstream callers passing custom stores via WithConnectorStore are affected.
  • Consequence: rung 1 (redeploy). Verdict: LOW.

Other criteria checks:

  • No exported Go API, proto or go.mod changes.
  • The cost-contract paths (expansion, per-checkpoint loop) only lose work, so no benchmark is needed.
  • The deleted token-path tests are replaced by golden fixtures and existing ledger twins, e.g. ledger_queue_commit_test.go, ledger_attempts_test.go, ledger_scheduler_test.go.

Coverage gaps:

  • I did not regenerate the golden JSON on main to confirm the claimed provenance.
  • I checked a sample of the deleted scheduler tests for ledger twins, not every one.

Security Issues

None found.

Correctness Issues

None found.

Suggestions

  • New — pkg/sync/syncer.go:2658: a store whose Metadata().Engine is "" or unknown (mocks, wrappers, gRPC-backed) used to run the token path. Passed via WithConnectorStore, it now fails Sync. Only downstream custom stores are affected, but the PR body should name the 0.x minor bump and add a migration note, per the repo criteria (confidence: medium).
  • New — cmd/baton-crash-harness/main.go:21-23, cmd/baton-crash-harness/driver_test.go:60-62: these comments justify -page-delay-ms by the "production checkpoint cadence (minCheckpointInterval)". This PR deletes that constant and the cadence it described, so the comments now describe a mechanism that no longer exists (confidence: high, low impact).
Prompt for AI agents
Verify each finding against the current code and only fix it if needed.

## Suggestions

In the PR description (setStore behaviour in `pkg/sync/syncer.go` around line 2651-2661):
- setStore now rejects any store that is not Pebble with PageLedgerStore. Previously, stores reporting an empty or unknown engine fell back to the token path. Add to the PR body that this is a compatibility break for downstream callers who pass custom c1zstore.Store implementations via WithConnectorStore. Name the 0.x minor version bump it requires and give a one-line migration note: such stores must report Engine "pebble" and implement c1zstore.PageLedgerStore.

In `cmd/baton-crash-harness/main.go`:
- Around line 21-23: the package comment refers to "the production checkpoint cadence (minCheckpointInterval)". This PR deletes that constant. Reword it to say the delay keeps sessions interruptible mid-page, or delete the clause.

In `cmd/baton-crash-harness/driver_test.go`:
- Around line 60-62: the harnessPageDelayMs comment refers to minCheckpointInterval and "the production checkpoint cadence". Update it the same way.

Reviewed commit: 6d454d847ad1

@github-actions github-actions 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.

No blocking issues found — see the full review report

kans and others added 7 commits October 30, 2026 09:24
withLedgerCaps wraps a test double with the PageLedgerStore and
WriteHookStore of a real Pebble store so setStore attaches it as
ledgered; withTripwireLedgerCaps reports Pebble with nil ledger
embeds for doubles that must never reach the ledger.

Co-authored-by: Cursor <cursoragent@cursor.com>
setStore attached any engine and set ledgered only for Pebble with a
PageLedgerStore. Pebble is the only engine, so the flag was constant
true in production. Make the requirement explicit (storeAttachErr
otherwise) and delete the field, its branch sites, and the token-path
arm each site guarded: Checkpoint and its callers, the legacy Sync body,
and the legacy SyncResourceTypes/SyncTargetedResource/SyncResources/
SyncEntitlements/SyncStaticEntitlements/SyncAssets/SyncGrants bodies,
which now forward to their ledger handlers.

Co-authored-by: Cursor <cursoragent@cursor.com>
The token-path bodies of resource, entitlement, grant, and asset
collection had no caller once setStore required a Pebble page ledger.
Remove them and the helpers only those bodies reached.

Co-authored-by: Cursor <cursoragent@cursor.com>
setStore rejects a store that hides PageLedgerStore or reports an
empty engine. Wrap those doubles with withLedgerCaps or
withTripwireLedgerCaps, and forward the delete interfaces the double
itself implements so capability resolution still sees them. Drop the
checkpoint-token hooks; that writer is gone.

Co-authored-by: Cursor <cursoragent@cursor.com>
Bare syncParallel and the legacy checkpoint tests called arms that
require no page ledger. The ledger scheduler and takeover tests cover
that behavior. transitionActionState now returns an error unless the
context carries a ledger commit; production reaches it only from that
commit.

Co-authored-by: Cursor <cursoragent@cursor.com>
NewSyncer returns the attach error for a non-Pebble engine and for a
Pebble store that does not expose PageLedgerStore. Tests that forced
the token path now run the ledger path. Comparisons that existed only
to match that token path are gone.

Co-authored-by: Cursor <cursoragent@cursor.com>
The legacy token handler was the oracle for external selection and
static entitlement materialization. Its output on origin/main at
8f8783c is stored under testdata/ledger_golden, and the ledger path
must reproduce those lists.

Co-authored-by: Cursor <cursoragent@cursor.com>
@kans
kans force-pushed the refactor/1a-one-syncer branch from 6d454d8 to 81dd6ca Compare October 30, 2026 15:29
@github-actions

github-actions Bot commented Oct 30, 2026 •

Copy link
Copy Markdown
Contributor
Superseded — see the current review report for commit 81dd6ca2c0cb

General PR Review: sync: require the page ledger and delete the token-checkpoint sync path

Blocking Issues: 0 | Suggestions: 2 | Threads Resolved: 0
Criteria: Criteria status: loaded .claude/skills/ci-review.md from trusted base bdeb20d9644a.
Review mode: full
View review run

Review Summary

The s.ledgered flag is gone and the ledger path is now unconditional. setStore (pkg/sync/syncer.go:2650-2660) rejects any store that is not Pebble with a PageLedgerStore. Checkpoint and the token-path handlers are deleted, and Sync* methods forward to syncLedger*. transitionActionState errors when no ledger commit key is present. parallelSync, initializeAction, session binding and the ingest invariants now take their ledger arms unconditionally. Token read paths (marshalToken/unmarshalToken, takeover, compaction) are untouched. I scanned the full PR diff for security and correctness.

Repo criteria triage:

  • Silence: no. A rejected store fails loudly.
  • Durability: no. No change to c1z, token or proto format.
  • Uncontrolled dimensions: no. No new scheduling or version-pair dependence.
  • Consumer distance: yes. Downstream WithConnectorStore callers are affected.
  • Verdict: not HIGH. The default path for c1z/Pebble users is unchanged.

No exported API, proto, go.mod or version.go changes. The deleted token-path tests are replaced by golden fixtures (ledger_golden_test.go) and existing ledger twins.

Coverage gap: I did not regenerate the golden JSON on main to confirm its provenance. I also did not read every deleted test body line by line.

Security Issues

None found.

Correctness Issues

None found. transitionActionState's new error (syncer.go:753-755) is reached only through nextPageOrFinishAction. Ledger invocations stage early, and the commit call carries ledgerCommitKey.

Suggestions

  • Prior — still present — pkg/sync/syncer.go:2657-2658: a store attached via WithConnectorStore whose Metadata().Engine is "" or unknown (mocks, wrappers, gRPC-backed stores) used to run the token path. It is now rejected. The PR body says this surfaces "at the start of Sync", but for WithConnectorStore it actually surfaces from NewSyncer (syncer.go:3060-3061). Per the repo criteria, the PR body should name the 0.x minor bump and add a migration note for downstream callers (confidence: medium).
  • New — cmd/baton-crash-harness/main.go:21-23, cmd/baton-crash-harness/driver_test.go:61-62: these comments justify the page delay by the "production checkpoint cadence (minCheckpointInterval)". This PR deletes that constant and that cadence, so update or delete the comments. These files are outside the diff, so I left no inline comment (confidence: high, low impact).
Prompt for AI agents
Verify each finding against the current code and only fix it if needed.

## Suggestions

In `pkg/sync/syncer.go`:
- Around line 2657-2658: setStore now rejects any store that is not Pebble with PageLedgerStore. Before this PR, stores with an empty or unknown engine fell back to the token path. For WithConnectorStore callers the error is returned from NewSyncer (line ~3060), not from Sync. Update the PR description to call this out as a breaking change for downstream custom stores, name the 0.x minor bump it requires, and add a short migration note (wrap a Pebble c1z store, or use WithC1ZPath).

In `cmd/baton-crash-harness/main.go`:
- Around line 21-23: the comment cites "the production checkpoint cadence (minCheckpointInterval)". This PR removed minCheckpointInterval and the token checkpoint cadence. Reword the comment to describe the ledger's per-page commit, or delete the clause.

In `cmd/baton-crash-harness/driver_test.go`:
- Around line 61-62: same stale reference to minCheckpointInterval. Update or remove it.

@github-actions

github-actions Bot commented Oct 30, 2026 •

Copy link
Copy Markdown
Contributor
Superseded — see the current review report for commit 498298212ae2

General PR Review: sync: require the page ledger and delete the token-checkpoint sync path

Blocking Issues: 0 | Suggestions: 2 | Threads Resolved: 0
Criteria: Criteria status: loaded .claude/skills/ci-review.md from trusted base bdeb20d9644a.
Review mode: full
View review run

Review Summary

The s.ledgered flag is gone and the ledger path is now unconditional. setStore (pkg/sync/syncer.go:2650-2660) rejects any store that is not Pebble with a PageLedgerStore. Checkpoint and the token-path handlers are deleted, and Sync* methods forward to syncLedger*. transitionActionState errors when no ledger commit key is present. parallelSync, initializeAction, session binding and the ingest invariants now take their ledger arms unconditionally. Token read paths (marshalToken/unmarshalToken, takeover, compaction) are untouched. I scanned the full PR diff for security and correctness.

Repo criteria triage:

  • Silence: no. A rejected store fails loudly.
  • Durability: no. No change to c1z, token or proto format.
  • Uncontrolled dimensions: no. No new scheduling or version-pair dependence.
  • Consumer distance: yes. Downstream WithConnectorStore callers are affected.
  • Verdict: not HIGH. The default path for c1z/Pebble users is unchanged.

No exported API, proto, go.mod or version.go changes. The deleted token-path tests are replaced by golden fixtures (ledger_golden_test.go) and existing ledger twins.

Coverage gap: I did not regenerate the golden JSON on main to confirm its provenance. I also did not read every deleted test body line by line.

Security Issues

None found.

Correctness Issues

None found. transitionActionState's new error (syncer.go:753-755) is reached only through nextPageOrFinishAction. Ledger invocations stage early, and the commit call carries ledgerCommitKey.

Suggestions

  • Prior — still present — pkg/sync/syncer.go:2657-2658: a store attached via WithConnectorStore whose Metadata().Engine is "" or unknown (mocks, wrappers, gRPC-backed stores) used to run the token path. It is now rejected. The PR body says this surfaces "at the start of Sync", but for WithConnectorStore it actually surfaces from NewSyncer (syncer.go:3060-3061). Per the repo criteria, the PR body should name the 0.x minor bump and add a migration note for downstream callers (confidence: medium).
  • New — cmd/baton-crash-harness/main.go:21-23, cmd/baton-crash-harness/driver_test.go:61-62: these comments justify the page delay by the "production checkpoint cadence (minCheckpointInterval)". This PR deletes that constant and that cadence, so update or delete the comments. These files are outside the diff, so I left no inline comment (confidence: high, low impact).
Prompt for AI agents
Verify each finding against the current code and only fix it if needed.

## Suggestions

In `pkg/sync/syncer.go`:
- Around line 2657-2658: setStore now rejects any store that is not Pebble with PageLedgerStore. Before this PR, stores with an empty or unknown engine fell back to the token path. For WithConnectorStore callers the error is returned from NewSyncer (line ~3060), not from Sync. Update the PR description to call this out as a breaking change for downstream custom stores, name the 0.x minor bump it requires, and add a short migration note (wrap a Pebble c1z store, or use WithC1ZPath).

In `cmd/baton-crash-harness/main.go`:
- Around line 21-23: the comment cites "the production checkpoint cadence (minCheckpointInterval)". This PR removed minCheckpointInterval and the token checkpoint cadence. Reword the comment to describe the ledger's per-page commit, or delete the clause.

In `cmd/baton-crash-harness/driver_test.go`:
- Around line 61-62: same stale reference to minCheckpointInterval. Update or remove it.

Reviewed commit: 81dd6ca2c0cb

@github-actions github-actions 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.

No blocking issues found — see the full review report

The invokeActionPage fallback that returned the handler when the syncer
was not ledgered is gone, so these tests' handlers never ran.
TestParallelBatchFailureDuringStopStaysQuiet passed vacuously: there was
no cancel-cause line to suppress. TestParallelBatchSecondGenuineFailureStillLogs
missed the second warn when the first worker's queue.abort won the race.

Co-authored-by: Cursor <cursoragent@cursor.com>
@github-actions

github-actions Bot commented Oct 30, 2026 •

Copy link
Copy Markdown
Contributor
Superseded — see the current review report for commit 498298212ae2

General PR Review: sync: require the page ledger and delete the token-checkpoint sync path

Blocking Issues: 0 | Suggestions: 3 | Threads Resolved: 0
Criteria: Criteria status: loaded .claude/skills/ci-review.md from trusted base bdeb20d9644a.
Review mode: incremental since 81dd6ca
View review run

Review Summary

The PR makes the Pebble page ledger a hard requirement of setStore and deletes the token-checkpoint sync path. The new commit (49829821) changes tests only. It moves TestParallelBatchSecondGenuineFailureStillLogs and TestParallelBatchFailureDuringStopStaysQuiet off a bare syncer{} onto newLedgerSchedulerFixture + seedLedgerTestRun. It also adds assertions that the actions actually ran (arrived == 2, ran). I scanned the full PR diff again for security and correctness and found nothing new and blocking.

Repo criteria triage, carried over from the prior review: this is a default-path behaviour change with consumer distance (callers of WithConnectorStore). Token serialization is untouched, so there is no durable-format or version-pair risk. The new commit is test-only and does not change the triage. I did not re-read all of the large syncer.go deletion in this incremental pass. The incremental diff was complete (not partial).

Security Issues

None found.

Correctness Issues

None found.

Suggestions

  • Prior — still present — pkg/sync/syncer.go:2657-2658: a store attached via WithConnectorStore whose Metadata().Engine is not Pebble, or that lacks PageLedgerStore (mocks, wrappers, gRPC-backed stores), used to run the token path. It is now rejected. Per the repo criteria, the PR body should name the 0.x minor bump and add a migration note for downstream callers (confidence: medium).
  • Prior — still present — cmd/baton-crash-harness/main.go:21-23, cmd/baton-crash-harness/driver_test.go:61-62: these comments still justify the page delay by minCheckpointInterval / "production checkpoint cadence", which this PR deletes. Update or delete them. These files are outside the diff, so there is no inline thread (confidence: high, low impact).
  • New — pkg/sync/chaos_cancellation_test.go:389 (and :236): TestParallelBatchFailureDuringStopStaysQuiet asserts that no ErrorLevel "cancelling context due to error in action" entry is logged. Production logs that message at Warn (parallel_syncer.go:844), so the assertion is vacuous: the test passes even if the preBatchCtx.Err() == nil guard is removed. This predates the PR, but the test was rewritten in this commit (confidence: high).
Prompt for AI agents
Verify each finding against the current code and only fix it if needed.

## Suggestions

In `pkg/sync/syncer.go`:
- Around line 2645-2659: setStore now rejects any store that is not Pebble+PageLedgerStore, including stores passed via WithConnectorStore that previously ran the token path. No code change required. Update the PR description to name the 0.x minor version bump and add a migration note for downstream WithConnectorStore callers.

In `cmd/baton-crash-harness/main.go`:
- Around line 21-23: The comment references minCheckpointInterval and the "production checkpoint cadence", which this PR removed. Reword it to describe the ledger's per-page commit, or delete it.

In `cmd/baton-crash-harness/driver_test.go`:
- Around line 61-62: Same stale minCheckpointInterval reference. Update or delete it.

In `pkg/sync/chaos_cancellation_test.go`:
- Around line 389 (and line 236): The assertions check for zapcore.ErrorLevel, but parallel_syncer.go:844 logs "cancelling context due to error in action" with l.Warn, so they can never fail. Change them to zapcore.WarnLevel (or match on message regardless of level) so the tests actually pin the stop-suppression guard.


_, err := s.syncParallel(preBatchCtx, newTestRetryer(ctx), []*Action{action}, f)
_, err := s.syncParallel(preBatchCtx, newTestRetryer(ctx), s.run.peekMatchingActions(ctx, SyncGrantsOp), f)
require.True(t, ran.Load())

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.

🟡 Suggestion: The log check below this line (line 389) looks for an ErrorLevel entry, but parallel_syncer.go:844 logs this message with l.Warn. That means the assertion can never fail, and the test would still pass if the stop-suppression guard were removed. The same mismatch is at line 236. Assert on zapcore.WarnLevel (or on any level) so the test pins the suppression its doc comment describes. (confidence: high)

@github-actions

github-actions Bot commented Oct 30, 2026 •

Copy link
Copy Markdown
Contributor
Superseded — see the current review report for commit 7bd1201fe55d

General PR Review: sync: require the page ledger and delete the token-checkpoint sync path

Blocking Issues: 0 | Suggestions: 3 | Threads Resolved: 0
Criteria: Criteria status: loaded .claude/skills/ci-review.md from trusted base bdeb20d9644a.
Review mode: incremental since 81dd6ca
View review run

Review Summary

The PR makes the Pebble page ledger a hard requirement of setStore and deletes the token-checkpoint sync path. The new commit (49829821) changes tests only. It moves TestParallelBatchSecondGenuineFailureStillLogs and TestParallelBatchFailureDuringStopStaysQuiet off a bare syncer{} onto newLedgerSchedulerFixture + seedLedgerTestRun. It also adds assertions that the actions actually ran (arrived == 2, ran). I scanned the full PR diff again for security and correctness and found nothing new and blocking.

Repo criteria triage, carried over from the prior review: this is a default-path behaviour change with consumer distance (callers of WithConnectorStore). Token serialization is untouched, so there is no durable-format or version-pair risk. The new commit is test-only and does not change the triage. I did not re-read all of the large syncer.go deletion in this incremental pass. The incremental diff was complete (not partial).

Security Issues

None found.

Correctness Issues

None found.

Suggestions

  • Prior — still present — pkg/sync/syncer.go:2657-2658: a store attached via WithConnectorStore whose Metadata().Engine is not Pebble, or that lacks PageLedgerStore (mocks, wrappers, gRPC-backed stores), used to run the token path. It is now rejected. Per the repo criteria, the PR body should name the 0.x minor bump and add a migration note for downstream callers (confidence: medium).
  • Prior — still present — cmd/baton-crash-harness/main.go:21-23, cmd/baton-crash-harness/driver_test.go:61-62: these comments still justify the page delay by minCheckpointInterval / "production checkpoint cadence", which this PR deletes. Update or delete them. These files are outside the diff, so there is no inline thread (confidence: high, low impact).
  • New — pkg/sync/chaos_cancellation_test.go:389 (and :236): TestParallelBatchFailureDuringStopStaysQuiet asserts that no ErrorLevel "cancelling context due to error in action" entry is logged. Production logs that message at Warn (parallel_syncer.go:844), so the assertion is vacuous: the test passes even if the preBatchCtx.Err() == nil guard is removed. This predates the PR, but the test was rewritten in this commit (confidence: high).
Prompt for AI agents
Verify each finding against the current code and only fix it if needed.

## Suggestions

In `pkg/sync/syncer.go`:
- Around line 2645-2659: setStore now rejects any store that is not Pebble+PageLedgerStore, including stores passed via WithConnectorStore that previously ran the token path. No code change required. Update the PR description to name the 0.x minor version bump and add a migration note for downstream WithConnectorStore callers.

In `cmd/baton-crash-harness/main.go`:
- Around line 21-23: The comment references minCheckpointInterval and the "production checkpoint cadence", which this PR removed. Reword it to describe the ledger's per-page commit, or delete it.

In `cmd/baton-crash-harness/driver_test.go`:
- Around line 61-62: Same stale minCheckpointInterval reference. Update or delete it.

In `pkg/sync/chaos_cancellation_test.go`:
- Around line 389 (and line 236): The assertions check for zapcore.ErrorLevel, but parallel_syncer.go:844 logs "cancelling context due to error in action" with l.Warn, so they can never fail. Change them to zapcore.WarnLevel (or match on message regardless of level) so the tests actually pin the stop-suppression guard.

Reviewed commit: 498298212ae2

@github-actions github-actions 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.

No blocking issues found — see the full review report

@FeliLucero1 FeliLucero1 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.

Nice cleanup, nothing blocking from me. A few nits inline. Some leftovers outside the diff too:

  • pushChildResourceActions / childResourceActions / childSchedule.recordIfNew are test-only now, and the doc still says "Factored out of getSubResources" (that's gone)
  • runState.transitionAction has no prod callers anymore
  • stale refs: Sync doc comment still says we checkpoint runState into the datasource, crash-harness comments mention minCheckpointInterval, run_state.go:166 says "legacy path", and the span in ledger_assets.go is still named syncer.syncAssetsForResource

On your transitionActionState question: I couldn't find a prod path without the commit key. Every handler runs inside invokeActionPage, and commitFn builds commitCtx off the outer ctx, so it always hits the commit arm.
image
image
image

@@ -166,10 +157,6 @@ func TestLedgerStaticMaterializationOrderAndResume(t *testing.T) {
for _, ent := range response.GetList() {

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.

this one lost its proto.Equal oracle and didn't get a golden like the others. Now it only checks len + DisplayName, so an ID/slug/annotations regression would slip through. Maybe dump a static_materialization.json from main and use assertLedgerGolden? Or at least diff cold-resume against uninterrupted.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done in 88fefc9: the uninterrupted subtest's ListEntitlements result is held in the parent and the cold-resume subtest requires equalProtoLists against it (sorted by ID), keeping the len/DisplayName checks. Mutation check: appending to Description on the resume page fails on record 0 while len and DisplayName still pass.

Comment thread pkg/sync/syncer.go
if s.caps.pageLedger != nil {
s.storeAttachErr = fmt.Errorf("sync store engine %q must not implement PageLedgerStore", store.Metadata().Engine)
}
if c1zstore.Engine(store.Metadata().Engine) != c1zstore.EnginePebble || s.caps.pageLedger == nil {

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.

small thing on the PR description: with WithConnectorStore this error shows up at NewSyncer, not at the start of Sync (only WithC1ZPath defers it to loadStore). Also dotc1z.RegisterEngine still advertises adding engines, and the syncer will now reject those. Worth a line in its doc.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Body fixed (NewSyncer with WithConnectorStore, loadStore with WithC1ZPath). RegisterEngine doc names the setStore requirement in 7bd1201.

Comment thread pkg/sync/syncer.go Outdated
@@ -799,20 +750,15 @@ func (s *syncer) transitionActionState(
nextPageToken string,
childActions []Action,
) ([]*Action, error) {

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.

the []*Action is always nil now, so this could just return error. Right now admitLocked(batchOp, pushed) in the queue always gets nil.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

6540e24: returns error now. admitLocked keeps its slice parameter because TestParallelQueueExhaustiveInterleavings returns same-op children through the commit callback; production passes nil.

Comment thread pkg/sync/parallel_syncer.go Outdated
// checkpointOnStop persists run accounting on a context detached from the
// caller's cancellation. Failures are logged, never returned, and the stop
// reason reaches the runner unchanged (RFC 0009 §4.2).
func (s *syncer) checkpointOnStop(ctx context.Context) {

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.

this is just an alias for checkpointLedgerOnStop now, and both names get used side by side in the same select. I'd inline it so nobody goes looking for a difference.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

383f0fc: inlined, checkpointLedgerOnStop is the one name.

Comment thread pkg/sync/parallel_syncer.go Outdated
cancel(err)
}
return loaded, err
queue.commitUnlocked = true

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.

always true now, so the locked branch in transition only runs in ledger_queue_commit_test. The field doc ("Set only for a ledger batch") and the "token path performs here" comment in transition read like there are still two modes. Drop the flag or at least fix the comments?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

cdf1cad: flag removed, transition always releases q.mu around the commit. The stepper in ledger_queue_commit_test ran the locked branch; it now asserts only that next() completes during the commit.

@github-actions

github-actions Bot commented Oct 30, 2026 •

Copy link
Copy Markdown
Contributor
Superseded — see the current review report for commit 7bd1201fe55d

General PR Review: sync: require the page ledger and delete the token-checkpoint sync path

Blocking Issues: 0 | Suggestions: 2 | Threads Resolved: 0
Criteria: Criteria status: loaded .claude/skills/ci-review.md from trusted base bdeb20d9644a.
Review mode: incremental since 49829821
View review run

Review Summary

This PR deletes the token-checkpoint sync path. setStore now requires a Pebble store that implements PageLedgerStore, and every Sync* method forwards to syncLedger*.

The new commits since 49829821 do four things:

  • Remove the checkpointOnStop wrapper and the parallelActionQueue.commitUnlocked flag. transition now always releases q.mu around the ledger commit.
  • Narrow transitionActionState to return only error.
  • Fix the log-level assertions in the chaos tests.
  • Add a cold-resume vs. uninterrupted equality check to TestLedgerStaticMaterializationOrderAndResume, and extend the RegisterEngine doc.

I scanned the full PR diff for security and correctness, and audited both prior findings against the current code.

Repo criteria triage for the new commits:

  • Silence: no. The unlocked commit was already the only production path.
  • Durability: no change to the wire format, token format or c1z.
  • Uncontrolled dimensions: yes. The lock release depends on goroutine scheduling, but it was already the production behaviour, and TestLedgerQueueCommitDoesNotHoldQueueLock covers it.
  • Consumer distance: low.

Verdict for this increment: LOW. The PR as a whole still carries the default-path behaviour change tracked below.

Security Issues

None found.

Correctness Issues

None found.

Suggestions

  • Prior — still present — pkg/sync/syncer.go:2656-2657: WithConnectorStore used to accept stores that are not Pebble or lack PageLedgerStore (mocks, wrappers, gRPC-backed stores) and ran them on the token path. Sync now rejects them with an error. The PR body calls this "the one behaviour change", but it still does not name the 0.x minor bump the repo criteria require, and it gives downstream callers no migration note. The new RegisterEngine doc line helps, but it does not replace a migration note (confidence: medium).
  • Prior — still present — cmd/baton-crash-harness/main.go:22-23 and cmd/baton-crash-harness/driver_test.go:62: these comments still explain the page delay with minCheckpointInterval and "the production checkpoint cadence", both of which this PR deletes. Update or delete them. The files are outside the diff, so there is no inline thread (confidence: high, low impact).

Resolved prior findings

  • pkg/sync/chaos_cancellation_test.go:384 (the stop-time assertion was vacuous because it checked ErrorLevel): fixed. Lines 389 and 236 now check zapcore.WarnLevel, which matches l.Warn at pkg/sync/parallel_syncer.go:822. The assertion would now fail if the preBatchCtx.Err() == nil guard were removed.
Prompt for AI agents
Verify each finding against the current code and only fix it if needed.

## Suggestions

In the PR description (relates to `pkg/sync/syncer.go` around lines 2656-2657):
- setStore now rejects stores that are not Pebble or do not implement PageLedgerStore. Before this PR they fell through to the token path. Add a "Breaking change" note to the PR body that names the 0.x minor version bump this needs, plus a short migration note for downstream callers of WithConnectorStore (mocks, wrappers, gRPC-backed stores must now be Pebble-backed and implement c1zstore.PageLedgerStore).

In `cmd/baton-crash-harness/main.go`:
- Around lines 22-23: the comment still mentions "the production checkpoint cadence (minCheckpointInterval)". Both were removed. Rewrite the comment to give the real reason for the page delay, or delete it.

In `cmd/baton-crash-harness/driver_test.go`:
- Around line 62: same stale reference to minCheckpointInterval and the production checkpoint cadence. Update or delete it.

@github-actions

github-actions Bot commented Oct 30, 2026 •

Copy link
Copy Markdown
Contributor

General PR Review: sync: require the page ledger and delete the token-checkpoint sync path

Blocking Issues: 0 | Suggestions: 2 | Threads Resolved: 0
Criteria: Criteria status: loaded .claude/skills/ci-review.md from trusted base bdeb20d9644a.
Review mode: incremental since 49829821
View review run

Review Summary

This PR deletes the token-checkpoint sync path. setStore now requires a Pebble store that implements PageLedgerStore, and every Sync* method forwards to syncLedger*.

The new commits since 49829821 do four things:

  • Remove the checkpointOnStop wrapper and the parallelActionQueue.commitUnlocked flag. transition now always releases q.mu around the ledger commit.
  • Narrow transitionActionState to return only error.
  • Fix the log-level assertions in the chaos tests.
  • Add a cold-resume vs. uninterrupted equality check to TestLedgerStaticMaterializationOrderAndResume, and extend the RegisterEngine doc.

I scanned the full PR diff for security and correctness, and audited both prior findings against the current code.

Repo criteria triage for the new commits:

  • Silence: no. The unlocked commit was already the only production path.
  • Durability: no change to the wire format, token format or c1z.
  • Uncontrolled dimensions: yes. The lock release depends on goroutine scheduling, but it was already the production behaviour, and TestLedgerQueueCommitDoesNotHoldQueueLock covers it.
  • Consumer distance: low.

Verdict for this increment: LOW. The PR as a whole still carries the default-path behaviour change tracked below.

Security Issues

None found.

Correctness Issues

None found.

Suggestions

  • Prior — still present — pkg/sync/syncer.go:2656-2657: WithConnectorStore used to accept stores that are not Pebble or lack PageLedgerStore (mocks, wrappers, gRPC-backed stores) and ran them on the token path. Sync now rejects them with an error. The PR body calls this "the one behaviour change", but it still does not name the 0.x minor bump the repo criteria require, and it gives downstream callers no migration note. The new RegisterEngine doc line helps, but it does not replace a migration note (confidence: medium).
  • Prior — still present — cmd/baton-crash-harness/main.go:22-23 and cmd/baton-crash-harness/driver_test.go:62: these comments still explain the page delay with minCheckpointInterval and "the production checkpoint cadence", both of which this PR deletes. Update or delete them. The files are outside the diff, so there is no inline thread (confidence: high, low impact).

Resolved prior findings

  • pkg/sync/chaos_cancellation_test.go:384 (the stop-time assertion was vacuous because it checked ErrorLevel): fixed. Lines 389 and 236 now check zapcore.WarnLevel, which matches l.Warn at pkg/sync/parallel_syncer.go:822. The assertion would now fail if the preBatchCtx.Err() == nil guard were removed.
Prompt for AI agents
Verify each finding against the current code and only fix it if needed.

## Suggestions

In the PR description (relates to `pkg/sync/syncer.go` around lines 2656-2657):
- setStore now rejects stores that are not Pebble or do not implement PageLedgerStore. Before this PR they fell through to the token path. Add a "Breaking change" note to the PR body that names the 0.x minor version bump this needs, plus a short migration note for downstream callers of WithConnectorStore (mocks, wrappers, gRPC-backed stores must now be Pebble-backed and implement c1zstore.PageLedgerStore).

In `cmd/baton-crash-harness/main.go`:
- Around lines 22-23: the comment still mentions "the production checkpoint cadence (minCheckpointInterval)". Both were removed. Rewrite the comment to give the real reason for the page delay, or delete it.

In `cmd/baton-crash-harness/driver_test.go`:
- Around line 62: same stale reference to minCheckpointInterval and the production checkpoint cadence. Update or delete it.

Reviewed commit: 7bd1201fe55d

@github-actions github-actions 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.

No blocking issues found — see the full review report

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