fix(rfc64): preserve Edge periodic sync scope - #2039
Conversation
c73afcc to
cd49cfe
Compare
| interface LifecycleSyncScopePlan { | ||
| readonly effectiveBatchSize: number; | ||
| readonly automaticContextGraphIds: readonly string[]; | ||
| readonly initialBootstrapContextGraphIds: readonly string[]; |
There was a problem hiding this comment.
🟡 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() { |
There was a problem hiding this comment.
🟡 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.
User impact
Edge nodes now keep the exact sync policy the operator selected:
always-ongraphs after restart;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 enabledAfter
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 endImplementation
SyncOnConnectScopePlandata;Validation
pnpm --filter @origintrail-official/dkg-agent buildsync-on-connect-retry.test.tssync-coverage-evidence-runtime.test.tssync-on-connect-churn.test.tsdiscovery-subscription-boundary.test.tsgit diff --checkStacked on #2038.