RFC-64 M1 5/7: activate role-aware adaptive Core capacity - #2014
RFC-64 M1 5/7: activate role-aware adaptive Core capacity#2014branarakic wants to merge 12 commits into
Conversation
9c848db to
c5b9ec1
Compare
85ca405 to
69c1dec
Compare
c5b9ec1 to
5685115
Compare
69c1dec to
072249e
Compare
4b83ea1 to
e7bbbac
Compare
072249e to
b166ef8
Compare
a6fa200 to
264d92d
Compare
8be9d57 to
13759eb
Compare
264d92d to
aa41669
Compare
13759eb to
5793aed
Compare
aa41669 to
4376835
Compare
otReviewAgent
left a comment
There was a problem hiding this comment.
Operational Notice: Review Agent could not complete this review.
Business logic reviewer failed: retry_exhausted
5793aed to
6992dd3
Compare
otReviewAgent
left a comment
There was a problem hiding this comment.
Operational Notice: Review Agent could not complete this review.
Business logic reviewer failed: retry_exhausted
| diagnosticsAvailable: '/api/diagnostics/backpressure', | ||
| }, | ||
| corePublicSyncCoverage, | ||
| syncCapacity, |
There was a problem hiding this comment.
🟡 Issue: Public status now exposes detailed adaptive sync pressure
What's wrong
The new status field publishes detailed node-local resource and sync-capacity information on an endpoint that is explicitly public. That creates an information disclosure surface for operational pressure and capacity limits, which can help external callers time load against the node or fingerprint its resource envelope.
Example
An unauthenticated caller can poll GET /api/status and observe syncCapacity.lastDecision.reason === 'critical_heap' or currentInflight dropping from 4 to 1, revealing when the node is under resource pressure and how much sync capacity remains. Previously the public status response kept detailed backpressure diagnostics behind /api/diagnostics/backpressure.
Suggested direction
Return only a coarse public capacity state from /api/status, or require/admin-gate the detailed syncCapacity fields alongside the existing backpressure diagnostics.
Confidence note
This assumes /api/status is intentionally unauthenticated for remote callers, which is supported by the route/auth allowlist in the surrounding code.
For Agents
Look at packages/cli/src/daemon/routes/status.ts where syncCapacity is added to the public status body. Preserve a coarse public health signal if needed, but move detailed capacity numbers and lastDecision to an admin-authenticated diagnostics route or redact them from unauthenticated status. Add a route-level test proving unauthenticated /api/status does not expose pressure reasons or capacity internals, while admin diagnostics can still inspect them.
M1 stack
This is PR 5 of 7 in the RFC-64 M1 stack.
Exact stack provenance:
43768351aee0d4c93e86bddf065197ed6aced4966992dd36ec23bf298e039ad5fd7a9b517b7a855dstopSampling()in the lifecycle test double; no production constructor or runtime behavior changesDKGAgent.start()starts adaptive sampling and supplies the live coverage-demand callbackSummary
This PR activates the adaptive-capacity primitives for Core nodes only and exposes the policy actually enforced at runtime through
/api/status.It adjusts two independent forms of Core synchronization pressure:
Edge nodes remain static and continue synchronizing only their explicitly selected CGs. This PR does not turn Edge nodes into all-public-CG replicas.
User and operator impact
For Core nodes:
/api/status.syncCapacityreports the canonical agent-owned mode, state, current/min/max concurrency, current/configured coverage batch, store-telemetry availability, and last decision.For Edge nodes:
Before this PR
sequenceDiagram participant A as DKGAgent participant P as Core coverage planner participant Q as Global admission participant S as Triple store A->>A: Resolve one static sync limit A->>P: Plan selected CGs plus fixed public batch P->>Q: Submit all planned work Q->>Q: Apply static inflight limit Q->>S: Run admitted workThe static limit and fixed automatic batch could not react to host, event-loop, heap, or store pressure.
After this PR
sequenceDiagram actor O as Operator participant A as DKGAgent participant R as SyncCapacityRuntime participant M as Host and store sampler participant C as Adaptive controller participant P as Core coverage planner participant Q as Global admission policy participant S as Triple store A->>R: Resolve role, config, hardMax, and queue bound alt Edge or statically configured Core R->>Q: Install static policy else Adaptive Core R->>Q: Install policy-owned currentLimit callback loop Bounded sampling interval R->>Q: Read inflight and queued demand R->>P: Check truncated automatic coverage R->>M: Sample demand, CPU, heap, event loop, and store queues M->>C: Report bounded pressure signals C-->>R: Current requester limit and coverage batch R->>Q: Notify admission when capacity grows end end A->>P: Plan selected CGs with current automatic batch Note over P: Explicit selections are never capped P->>Q: Submit planned work Q->>Q: Enforce current limit and hardMax-bounded backlog Q->>S: Run admitted work Note over Q,S: Downshifts drain without cancelling running work O->>A: GET /api/status A->>R: getStatus() R-->>O: Return exact enforced syncCapacity stateResolution policy
0Global-limit precedence remains:
DKG_SYNC_GLOBAL_MAX_INFLIGHTDKG_SYNC_GLOBAL_LIMITsyncGlobalMaxInflightsyncGlobalLimitMalformed adaptive min/max values fail fast instead of silently widening load. The public
syncAdaptiveCapacityconfig shape is preserved through CLI-to-agent wiring and remains omitted when the operator does not configure it.Controller behavior and compatibility
syncCorePublicBatchSize;0remains disabled.hardMaxalso bounds its admission backlog; the queue cannot grow to a ceiling the runtime can never drain.hardMaxas final and cannot reapply a larger global-limit environment value; the independently configured queue limit still retains its normal precedence.SyncCapacityRuntimeowns admission options, pressure and ceiling observation, demand aggregation, sampling, queue-pump notification, status, and timer cleanup.Review feedback incorporated
SyncCapacityRuntime./api/statusno longer fabricates a second fallback capacity model.resolveSyncGlobalBackpressure(config, currentLimit)boundary.planAutomaticCoverageWithOptionsboundary and the runtime-owned effective batch. The existing three-argumentplanAutomaticCoveragewrapper remains unchanged for outside callers.stopSampling()method expected during agent shutdown. Production construction was already correct; this is test-double parity only.1queues a second request even when raw config would allow2.SyncCapacityRuntime; the branded raw policy is private.DKGAgentBaseis now the single owner of Core coverage-batch resolution. The scheduler andSyncCapacityRuntimereceive the same resolved value, so an environment change during startup cannot make their effective limits diverge.Validation on final head
7unrelated tests skipped by the focused status filter).git diff --check: passed.Rollout risk
Moderate but bounded. The default changes only for Core nodes without an explicit global limit. It cannot enable automatic coverage on Edge, exceed the configured Core batch, exceed the lowest applicable capacity ceiling, or queue beyond the effective adaptive hard maximum.
Review focus