Skip to content

149. Coalesce entity-source discovery queries and route candidates locally ​

Date: 2026-10-22

Status ​

Accepted

Partially supersedes ADR 0098's optional sharing of compatible entity-source queries and its use of queries for enumeration alone: discovery requires one combined logical search per source scope, and source-query membership gates both event-backed and eventless entity-source runs. ADR 0098's entity resolution, event authorization, and harness CEL decisions remain. ADR 0144 governs process lifecycles; ADR 0147 governs progressive acquisition after candidate discovery. This ADR extends ADR 0148's bounded role reuse and false-decision recheck to source-query membership.

Context ​

ADR 0098 lets harnesses declare entity sources that enumerate candidate identities, but only permits, rather than requires, shared provider queries. ADR 0144 relies on recurring repository-scoped discovery to recover work after a bound run exits. Searching separately for every harness increases provider calls, while a provider-only query cannot tell poll which harnesses should receive each result. The current fullsend poll command still uses event-reconstructing input drivers; harness entity-source discovery is a target design.

A combined search only finds possible candidates. It need not fetch every field or history record that ADR 0147 may later need for CEL. Provider result caps, incomplete pages, delayed index visibility, and changes between discovery and execution make search coverage and local rechecking part of the decision. Without a final query check, an event or stale search hit could run a harness outside its declared source scope.

Options ​

Search separately for each harness ​

This permits arbitrary provider-native queries, but provider search cost grows with the number of harnesses and results still need deduplication.

Combine admissible queries and route locally ​

This shares discovery work across harnesses, but limits query features to ones the adapter can combine and re-evaluate with the same semantics.

Decision ​

Adopt one logical candidate search per provider, tenant, repository or project, entity kind, and effective credential scope in each discovery cycle. fullsend poll combines all enabled harness entity-source queries in that scope into a search covering every entity that could match any query when re-evaluated locally over that harness's authorized facts. A trusted scope guard remains outside the harness-query union; neither harness syntax nor composition may widen it. poll verifies each hit's canonical provider, tenant, repository or project, and kind before routing. A broader search is permitted only within that guard and provider and platform bounds. One logical search may involve pagination or coverage partitions, but cannot disguise a separate full search for each harness.

An entity-source query is admissible only when the adapter can both combine it soundly and evaluate its membership locally from a defined routing projection and, when needed, selective follow-up reads. poll deduplicates candidates by canonical entity identity, checks each relevant harness query locally, and routes the candidate to every matching harness for its CEL check. It may enrich an unresolved query match or hand that candidate to the bound run; missing routing data or uncertain coverage never means false. Opaque provider-only operators, ranking or top-N membership, and filters that cannot be locally reproduced are unsupported. An adapter rejects a source it cannot plan this way instead of silently omitting it or issuing independent searches.

The query is a harness eligibility condition after discovery. Before each sandbox cycle, including one prompted directly by an event or wakeup, a bound run resolves current entity facts and locally evaluates both source-query membership and harness CEL. It may settle either check first, but both must be definitively true before a sandbox starts. An event supplies a candidate and retains its separate actor-authorization gate; it cannot bypass the declared source scope. A stale search hit is not evidence of current membership. Query dependencies that indicate an actor's action receive the provenance and stage-authorization gate specified for CEL facts by ADR 0147 and the Authorization Contract v2. A raw provider prefilter must not omit an entity whose query could become true after unauthorized facts are excluded locally. Cached actor-role verdicts used for membership obey ADR 0148's age bound and cache-dependent false-result recheck. Incomplete evidence remains unresolved under ADR 0147's progressive acquisition and retry rules. Each check's audit binds the query plan, membership outcome, source coverage, and actor-verdict evidence.

The combined search must preserve candidate coverage despite pagination, provider caps, delayed search indexing, and concurrent changes. Finishing all pages alone does not prove completeness; an adapter needs a stable covered range or a sound overlap and reconciliation path for possibly missed entities. An unproven range is neither empty nor completed. A checkpoint cannot exclude that range without durable scan retry or proven rediscovery; provisional handoffs separately retain ADR 0147's retry or rediscovery guarantee. A plan change must trigger a catch-up scan for newly eligible candidates. Time-dependent source queries, CEL conditions, and cache-dependent rechecks under ADR 0148 need periodic rediscovery or a durable due record even if the entity has not changed; an updated since filter alone does not provide that guarantee.

The versioned normative discovery/query protocol must define declaration syntax, allowed operators, routing projection, provider mappings, pagination and coverage evidence, bounds, and conformance cases before entity-source discovery is enabled. A new major authorization contract must specify the source-query admission gate and actor evidence under ADR 0015 before entity-source execution is enabled. This ADR does not choose query syntax or require full entity hydration during candidate search.

Forge scope ​

This applies to GitHub, GitLab, Forgejo, and Jira entity-source adapters. Each must prove combined-search and local-recheck semantics for the source queries it accepts; unsupported queries deny that entity-source path. Existing event-reconstructing poll drivers, including Jira's --jql override, remain under ADR 0063 and do not satisfy this new discovery contract by default. Event-only harnesses without an entity source are unaffected.

Consequences ​

  • The number of logical searches scales with source scopes rather than the number of harnesses; broader unions can increase result volume and local routing work.
  • Harness entity-source queries cannot use provider features that cannot be combined and rechecked locally; harness CEL retains its separate language.
  • A provider limit or partial scan remains visible and retryable instead of silently omitting candidates or advancing a completion checkpoint.
  • Event-backed runs also reject current query non-matches; actor-originated query conditions cannot bypass the entity authorization gate.