Skip to content

Extract the catch-up readiness proof model out of catchup-runner.ts #2008

Description

@Jurij89

Context

Deferred from PR #2007 (issue #2006). Raised there across three review rounds and declined on scope, not on merit — the reasoning is on-thread; this issue exists so it is tracked rather than lost in a closed PR's review history.

packages/cli/src/catchup-runner.ts now holds four unrelated concerns:

  1. Route-level durable catch-up helpers (classifyDurableCatchupRequest, runDurableCatchupLeg)
  2. The WorkerCatchupRunner class and its parent-side RPC bridge
  3. Per-peer accounting (catchupPeerResponded, catchupPeerSucceeded)
  4. The readiness proof/evidence modelCatchupPlaneCompletionEvidence, CatchupPlaneRoundDiagnostics, catchupPeerPlaneEvidence, addCatchupPlaneEvidence, catchupPlaneProvenByData, catchupPlaneProvenByUnanimousEmpty, catchupPlaneReady

A reader tracing readiness from context-graph-readiness.ts lands in a module whose name promises a runner, and adding a new evidence signal reads as a runner change when it is domain policy.

Proposed change

Extract (4) into packages/cli/src/catchup-proof.ts and have the worker impl and the readiness classifier import from there. The unit tests for those predicates already live together in catchup-runner.test.ts and would move as a block.

Two adjacent cleanups worth doing in the same change, since both are about how this file decomposes:

  • Collapse the parallel per-plane accumulators in catchup-runner-worker-impl.ts. Note they are not identical: durable carries metaOnlyResponses, verifiedPrivateOnlyResponses, dataRejectedMissingMeta, rejectedKcs and a complete flag that gates its evidence; shared memory carries droppedDataTriples and has no complete concept (SharedMemorySyncResult has no such field). A naive collapse trades duplication for per-plane branching.
  • Type the worker RPC protocol. The bridge currently uses raw method-name strings and positional unknown[], so an argument reordering compiles on both sides and surfaces as mislabelled scheduler diagnostics rather than a type error. Payloads are typed (invoke<DurableSyncResult>, CatchupPlaneContext, SyncPeerResolution); the method/arity contract is not.

Why it is cheap now

PR #2007 deliberately left it in a good position:

  • The proof model is cohesive and has no dependency on the runner class or the route helpers.
  • CatchupJobResult['cleanPlaneCompletions'] is now the shared CatchupPlaneCompletionEvidence rather than a structurally duplicated inline literal, so there is no second definition to move with it.
  • cleanCompletionHasResponse in context-graph-readiness.ts takes that same type, so a new evidence carrier cannot be added to the model and omitted from the pre-readiness gate without a type error — the bug class that produced one of fix(sync): walk catch-up peers progressively and fail closed on empty rounds (#2006) #2007's blockers.

Constraint to respect

catchup-runner.ts is imported by the readiness classifier, the worker impl, the subscribe route and seven test files. Land this on its own so the import churn is legible as import churn, not mixed into a behavioural change.

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions