Skip to content

Background drift check introspects every federated datasource, not the one it was armed for — runDriftCheck filters validateAll() output #10961

Description

@os-elon

Found while implementing #10537 (out of scope there: that card is the REST route only).

What is true at head

packages/runtime/src/external-validation-plugin.tsExternalValidationPlugin.runDriftCheck(ctx, datasource) (:278-293) is armed per datasource by scheduleDriftChecks, one interval per datasource that declares external.validation.checkIntervalMs. Its body calls svc.validateAll() and then filters:

report=awaitsvc.validateAll();constdrifted=report.results.filter((r)=>!r.ok&&r.datasource===datasource);

validateAll() validates every federated object on every federated datasource, and per-object validation drives introspect(datasource) — a live remote-schema read. So a timer armed for datasource A performs live introspection against B and C as well, on every tick, and discards their rows.

This is the same defect class as #10537 (the REST route, fixed in PR #10960), one layer over: correct output, unscoped work. It is arguably worse here because it is periodic and unattended — the cost repeats on every interval of every armed datasource, and two datasources each armed at their own interval each sweep the whole farm.

Why it was not fixed as a rider on #10537

Different package, different consumer, its own verification surface (packages/runtime), and the dispatch for #10537 scoped that card to packages/rest. Filing rather than widening the diff.

A composed primitive now exists

PR #10960 added ExternalDatasourceService.validateDatasource(datasource) — the scoped twin of the sweep, composed from listObjects → filter → validateObject with the same federation predicate and the same per-object catch, returning row-for-row what validateAll() post-filtered to that datasource returned. If this card is taken, that is the primitive to call.

One wrinkle for whoever picks it up: this consumer types the service structurally as ExternalDatasourceServiceLike (:14) and probes svc?.validateAll before calling; validateDatasource is deliberately not on IExternalDatasourceService (#10537's triage ruled a contract expansion out of scope), so the same probe-or-degrade decision the REST registrar made has to be made here too — and the honest degradation for a background checker may not be the route's 503 answer.

Unassigned — filed for triage to level and route.


Generated by Claude Code

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions