Skip to content

fix(sync): give durable meta and data phases independent deadline budgets - #2118

Merged
branarakic merged 3 commits into
mainfrom
fix/sync-per-phase-deadlines
Aug 6, 2026
Merged

fix(sync): give durable meta and data phases independent deadline budgets#2118
branarakic merged 3 commits into
mainfrom
fix/sync-per-phase-deadlines

Conversation

@branarakic

@branarakic branarakic commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Problem

Durable sync's meta and data phases draw down one shared per-CG deadline. On the affected live 10.0.12 node, the large system-CG meta stream consumed the whole window; the data phase then reported a timeout with zero triples received without sending a request, every reconciler cycle.

Fix

Introduce an optional per-phase deadline inside the existing per-CG budget:

  • For system Context Graphs (agents and ontology), meta gets at most 40% of the remaining CG window and never consumes the data floor (DURABLE_DATA_PHASE_MIN_BUDGET_MS).
  • Data runs to the full CG deadline. If meta finishes early, its unused time rolls into data; total wall clock never exceeds the previous per-CG deadline.
  • A capped meta timeout no longer exits before the reserved data phase runs. The normal post-phase timeout gate still stops later-CG fanout when requested.
  • Verified user CGs deliberately keep the full deadline for both phases. Their meta/data cursors advance only after joint verification, so capping a partial descriptor stream could pin both cursors on the same window.
  • Tiny/clamped windows preserve the former shared-deadline behavior. Meta-skipping agents sync still gives its only data phase the full window.

User/runtime impact

A large system directory can no longer consume the complete durable-sync window before the node even asks for its data, while verified user CGs retain their fail-closed cursor semantics. This is additive scheduling behavior; no protocol, storage, or configuration migration is required.

Validation

  • full dependency-closure build: 17/17 packages green
  • agent build: TypeScript, type tests, and package-root checks green
  • focused deadline/bailout/rootless suites: 45/45 tests green
  • combined four-PR main-based suite: 5 files / 101 tests green before the follow-up; targeted follow-up suites green
  • current testnet-canary composition builds cleanly; network smoke follows after merge/promotion

🤖 Generated with Claude Code and completed by Codex.

…gets

On a live 10.0.12 Base-mainnet edge node (2026-08-06) a trivial 604-triple
CG could not receive its curator's SWM updates for hours. One contributing
defect: the durable requester gave meta and data ONE shared per-CG fetch
deadline, so the system-CG meta streams (agents/ontology, ~16k+ triples)
over circuit relays burned the whole window and every cycle ended with
"Sync timeout for durable data phase (0 triples received)" — the data
request was never even sent.

Split the per-CG fetch budget into per-phase deadlines, requester-side
scheduling only:

- DURABLE_META_PHASE_BUDGET_FRACTION (0.4): meta gets at most 40% of the
  remaining CG budget, so data always keeps the majority share while meta
  retains enough room to finish or at least advance its resume checkpoint.
- DURABLE_DATA_PHASE_MIN_BUDGET_MS (SYNC_MIN_GRAPH_BUDGET_MS / 2): the
  meta deadline additionally never intrudes on this floor when an
  operation deadline clamps the CG window below the normal minimum; a
  window too small to reserve the floor keeps the shared deadline and
  degrades exactly as before.
- Deadlines stay absolute: the data phase runs to the unchanged per-CG
  fetchDeadline, so a meta phase that finishes early hands its unused
  time to data automatically and the combined phases can never exceed
  the prior single-deadline total — no regression in global pacing.
- runDurableSync threads a per-phase fetch context (meta gets the bounded
  deadline, clamped to the CG deadline even for custom budgets), so
  page-fetch phase timeout logs report against the correct boundary.
- DurableSyncContextGraphBudget.metaFetchDeadline is optional: legacy
  deep-import budgets and the compat adapter keep their single shared
  deadline, and meta-skipping system CGs keep the full window for their
  only (data) phase. Wire format untouched.

Tests: meta exhausting its slice leaves data exactly the floor; early
meta finish rolls unused time into data (95s of a 100s window after a 5s
meta); phase deadlines never extend the prior total; skip-agents-meta CGs
and legacy positional-ABI callers unaffected. Verified 7/8 new tests fail
without the src change (the 8th guards the clamp invariant).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

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

Operational Notice: Review Agent could not complete this review.

Business logic reviewer failed: WARNING: failed to clean up stale arg0 temp dirs: Permission denied (os error 13)

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

Operational Notice: Review Agent could not complete this review.

Business logic reviewer failed: WARNING: failed to clean up stale arg0 temp dirs: Permission denied (os error 13)

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

Operational Notice: Review Agent could not complete this review.

Business logic reviewer failed: WARNING: failed to clean up stale arg0 temp dirs: Permission denied (os error 13)

@branarakic
branarakic merged commit 61459c0 into main Aug 6, 2026
8 of 11 checks passed
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