Skip to content

fix(rfc64): preserve Edge periodic sync scope - #2039

Open
branarakic wants to merge 2 commits into
codex/rfc64-m1-swm-retirement-correctnessfrom
codex/rfc64-m1-edge-periodic-scope-plan
Open

fix(rfc64): preserve Edge periodic sync scope#2039
branarakic wants to merge 2 commits into
codex/rfc64-m1-swm-retirement-correctnessfrom
codex/rfc64-m1-edge-periodic-scope-plan

Conversation

@branarakic

Copy link
Copy Markdown
Contributor

User impact

Edge nodes now keep the exact sync policy the operator selected:

  • with normal sync-on-connect enabled, periodic recovery still bootstraps system graphs and includes configured/runtime-selected graphs;
  • with normal sync-on-connect disabled, an Edge node resumes only its explicitly persisted always-on graphs after restart;
  • on-demand graphs remain dormant until explicitly requested.

This prevents the persisted-subscription recovery path from accidentally narrowing every Edge periodic round.

Before

sequenceDiagram
    participant Timer as Periodic reconciler
    participant Edge as Edge node
    participant Peer as Sync peer
    Timer->>Edge: Start periodic round
    Edge->>Edge: Detect Edge periodic trigger
    Edge->>Edge: Replace normal plan with persisted always-on scope
    Edge->>Peer: Sync only persisted always-on CGs
    Note over Edge,Peer: System and configured runtime scope can be dropped even when broad sync is enabled
Loading

After

sequenceDiagram
    participant Timer as Periodic reconciler
    participant Edge as Edge node
    participant Peer as Sync peer
    Timer->>Edge: Start periodic round
    alt Broad sync-on-connect enabled
        Edge->>Edge: Preserve normal data-driven scope plan
        Edge->>Peer: Bootstrap system CGs and sync configured or selected CGs
    else Broad sync-on-connect disabled
        Edge->>Edge: Load persisted explicit always-on CGs
        Edge->>Peer: Resume only those CGs without system bootstrap
    end
Loading

Implementation

  • moves initial system bootstrap CGs into SyncOnConnectScopePlan data;
  • limits the scoped Edge resume policy to periodic rounds where broad sync-on-connect is disabled;
  • preserves the normal Core and Edge scope plan on unchanged paths;
  • adds regression evidence for both broad periodic scope and scoped always-on recovery.

Validation

  • pnpm --filter @origintrail-official/dkg-agent build
  • focused sync suite: 4 files, 114 tests passed
    • sync-on-connect-retry.test.ts
    • sync-coverage-evidence-runtime.test.ts
    • sync-on-connect-churn.test.ts
    • discovery-subscription-boundary.test.ts
  • git diff --check

Stacked on #2038.

Comment thread packages/agent/src/sync/on-connect/sync-on-connect.ts Outdated
Comment thread packages/agent/src/sync/on-connect/sync-on-connect.ts Outdated
Comment thread packages/agent/test/sync-coverage-evidence-runtime.test.ts Outdated
@branarakic
branarakic force-pushed the codex/rfc64-m1-edge-periodic-scope-plan branch from c73afcc to cd49cfe Compare August 3, 2026 03:46
interface LifecycleSyncScopePlan {
readonly effectiveBatchSize: number;
readonly automaticContextGraphIds: readonly string[];
readonly initialBootstrapContextGraphIds: readonly string[];

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 Issue: Make the peer-round scope contract canonical instead of cloning it across layers

What's wrong
This change improves the boolean flag by making bootstrap graphs explicit, but it does so by adding the same new concept to multiple duplicated scope interfaces. That spreads the invariant across layers instead of making the scope model the canonical abstraction, which makes the next scope change harder to reason about and easier to implement inconsistently.

Example
A future change that adds another peer-round scope dimension would need to update PeerSyncScope, LifecycleSyncScopePlan, SyncOnConnectScopePlan, and the legacy adapter shape separately. Missing one would still compile in some paths because these are structurally typed aliases, leaving the drift to show up as control-flow special casing later.

Suggested direction
Define the durable/on-connect scope shape once, then have lifecycle/base plans compose or extend that shape for their extra evidence fields. The legacy adapter can still normalize optional/deprecated input into the canonical plan at the boundary, but the main orchestration should not carry several near-identical interfaces.

Confidence note
This is a structural maintainability finding based on the changed scope model; I did not have an origin/main ref locally, so the before/after comparison uses the supplied PR diff plus surrounding file reads.

For Agents
Look at packages/agent/src/sync/on-connect/sync-on-connect.ts, packages/agent/src/dkg-agent-base.ts, and packages/agent/src/dkg-agent-lifecycle.ts. Preserve the current behavior: normal sync includes Agents/Ontology in the first durable request, periodic Edge scoped resume can pass an empty bootstrap list, and the legacy adapter keeps its compatibility default. Extract one canonical peer-round scope type or a small shared base type plus lifecycle-only evidence fields, and centralize the default bootstrap graph constant so adding scope fields is not a multi-file structural edit.

throw new Error('condition did not become true');
}

function cleanDurableSyncResult() {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 Issue: Avoid duplicating the coverage-evidence agent test harness

What's wrong
The new file copies a large, fragile setup pattern rather than reusing the existing coverage-evidence harness. These fixtures contain many detailed counter fields and private as any stubs, so duplicating them increases the maintenance surface for every future sync-result or agent-lifecycle test change.

Example
If a durable progress summary field is added or renamed, both sync-coverage-evidence-runtime.test.ts and this new file now need the same long fixture object updated. The same applies to the private-agent stubbing around rehydrateContextGraphSubscriptions, planSharedMemorySyncContextGraphs, and detailed sync methods.

Suggested direction
Extract the common evidence-agent fixtures/result factories into a test helper for this sync coverage area, or fold this scenario into the existing runtime coverage-evidence suite. The new test should only supply the differing config and assertions.

For Agents
Look at packages/agent/test/sync-coverage-evidence-runtime.test.ts and this new periodic test. Preserve the asserted durable/shared-memory scopes. Move the shared clean result factories and evidence-agent setup into a small local test helper, or place this scenario in the existing coverage-evidence runtime suite so it can reuse the current helpers. Keep the test assertion focused on the new periodic Edge scope behavior.

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