This document is the orientation page for SADAR's bilateral matching algorithm: the mechanism by which requester and server manifests are evaluated for compatibility. It covers the two-direction structure that gives the algorithm its bilateral character, the three outcome levels that capture more than binary match/no-match, the strictest-rule composition that combines individual outcomes into a pair-level result, and the right-of-refusal pattern that runs through both discovery and invocation.
The normative basis lives across multiple sources. Scope §5.1.3 establishes bilateral matching as a core spec capability. NFR Schema §12 defines the algorithm in normative detail. The Website Narrative §Manifests and Matching provides the orientation framing this page builds on. The matching algorithm operates over manifest content — both NFR declarations (covered in Non-Functional Requirements) and first-class manifest elements (covered in Business Process and Data Semantic Meaning) — using the same uniform two-direction pattern.
Audience: enterprise architects and implementers who need to understand how discovery actually decides compatibility; integration teams reasoning about why specific pairs match or fail to match; and operators tuning matching policy for their deployments.
The matching algorithm is the function that takes a requester manifest and a server manifest as input and produces a match candidate list outcome as output. The outcome characterizes whether — and how completely — the two manifests are compatible for engagement. The algorithm is purely deterministic over the inputs: the same two manifests evaluated against each other always produce the same outcome, regardless of when or by whom the evaluation is performed. Partial matches are only returned for non-strict matching manifest attributes.
This determinism is structural. The matching algorithm does not consult external state, does not consider runtime conditions, does not factor in scoring or ranking. It evaluates the manifests against each other according to spec-defined rules and reports what those rules say. Reasoning that depends on runtime conditions, scoring, or ranking lives elsewhere — in selection, in operational policy, in invocation-time verification.
The algorithm operates over the entire manifest content: the NFR declarations across all four categories (Financial, Operational, Governance, Protocol — see Non-Functional Requirements), the first-class manifest elements (proccess declarations and data_fields declarations), and any other matchable content the manifest carries. The same two-direction pattern applies uniformly across all of these; what differs by NFR or element type is the per-rule matching semantics, not the algorithmic structure.
Bilateral matching evaluates compatibility in two directions. Each direction asks a structurally distinct question, and both must hold for a pair to match. The two directions are not symmetric inversions of each other — they consume different content from the manifests and answer different questions.
Direction 1 evaluates whether the server can do what the requester needs. The requester's manifest contains its requirements — what it expects from a counterparty. The server's manifest contains its provisions — what it advertises that it offers. Direction 1 walks each requirement in the requester's manifest and checks it against the corresponding provision in the server's manifest, applying the type-specific compatibility rule for that NFR or element.
This direction is what most people first think of when they think of “matching”: “I need X; does this candidate offer X?” But by itself it would only verify the server's capability— not whether the requester is qualified to engage. Direction 2 covers the other half.
Direction 2 evaluates whether the requester is qualified to invoke this server. The server's manifest contains requirements of the requester — properties the requester must have for the server to accept the invocation. These are not what the server provides but what it demands of any party invoking it. The requester's manifest contains its self-declarations — its own properties (industry, regulatory conformance, organizational identity, certifications). Direction 2 walks each requirements_of_requester item in the server's manifest and checks it against the corresponding self-declaration in the requester's manifest.
This direction matters because servers in real deployments do not accept invocations from anyone — they accept only from qualified requesters. A healthcare-data server may choose to accept only HIPAA-conformant requesters; a financial-services server may accept only requesters whose industry classification falls within a specific NAICS range; a regulated-export tool may choose to accept only requesters whose jurisdiction declarations include specific countries. By making the server's requirements-of-requester a first-class part of matching, the algorithm enforces these qualifications at discovery rather than relying on runtime rejection - or worse, a compliance issue.
Both directions are evaluated for every candidate pair. A pair where Direction 1 produces FULL_MATCH but Direction 2 produces NO_MATCH is not a valid pair: the server can do what the requester wants, but the requester is not qualified to invoke this server. The matching algorithm reports the combined outcome (NO_MATCH in this case, by the strictest-rule combination covered below).
Each individual requirement evaluation produces one of three outcomes. The three-level structure preserves more information than a binary match/no-match would; it lets matching distinguish full satisfaction from acceptable-but-imperfect satisfaction, and from outright incompatibility.
PARTIAL_MATCH is the architecturally interesting case. A binary match algorithm forces every imperfect alignment into either “yes” (overstating compatibility) or “no”(understating it). PARTIAL_MATCH preserves the truth of the situation: “some aspects work, some don't.” The selector can then apply policy to decide whether the partial fit is acceptable for its purposes — a selector working under tight regulatory constraints may refuse all PARTIAL_MATCH outcomes; a selector willing to accept degradation may take the best PARTIAL_MATCH on offer when no FULL_MATCH is available. Either decision considers what the candidate actually provides.
OPTIONAL strictness (see Non-Functional Requirements) interacts cleanly with the three-level outcomes: an OPTIONAL requirement does not produce NO_MATCH if unsatisfied, and does not produce PARTIAL_MATCH if not fully satisfied — it does not contribute to the binary match outcome at all, only informing scoring. The three-level outcome system applies to MANDATORY and MANDATORY_STRICT declarations; OPTIONAL declarations sit outside the match/no-match question by design.
A single requester-server pair has many individual requirements to evaluate (NFRs across four categories, plus first-class elements). Each individual evaluation produces one of the three outcomes. The combined pair-level outcome is computed by a uniform rule: take the strictest of the individual outcomes.
The strictness ordering is deterministic: NO_MATCH is strictest, PARTIAL_MATCH is intermediate, FULL_MATCH is least strict. The combination is the strictest individual outcome present. This is the standard “weakest-link” semantics applied to matching — a pair is no better than its worst individual evaluation.
The rule has clean operational consequences. A pair that is mostly compatible but fails on one MANDATORY requirement is a NO_MATCH overall; the algorithm does not paper over the failure with a softer combined result. A pair where every individual evaluation produces FULL_MATCH is a clean match without ambiguity. A pair with several FULL_MATCH and one PARTIAL_MATCH lands at PARTIAL_MATCH overall — accurately reflecting that the pair is acceptable but not perfectly aligned. Selectors interpreting the combined outcome do not need to dig into the individual evaluations to know whether the pair is workable; the combined outcome is sufficient for the binary engage-or-don't decision, with individual outcomes available for finer-grained selection logic.
Consider a requester evaluating a candidate server. Both manifests have been retrieved from the registry; the matching algorithm runs. The illustrative declarations and individual outcomes:
Applying the strictest-rule combination across all individual outcomes (excluding the OPTIONAL declaration, which does not affect the binary match): FULL_MATCH × 4 plus PARTIAL_MATCH× 1 yields a combined outcome of PARTIAL_MATCH. The pair is workable but with degradation on the availability requirement. The selector can then decide: is 9–17 EU coverage acceptable for this requester's needs? If yes, the pair is engaged. If no, the selector seeks another candidate. The matching algorithm has provided what it can — a characterization of the compatibility — and the selector applies policy from there.
A successful match outcome at discovery does not commit either party to actual engagement. Both parties retain the right of refusal at two distinct decision points. This is structural: the matching algorithm is a discovery-time filter, not a contractual commitment, and runtime conditions can change in ways the discovery-time evaluation could not anticipate.
At discovery, the matching algorithm runs over candidate pairs. Pairs that produce NO_MATCH are filtered out; pairs that produce FULL_MATCH or PARTIAL_MATCH are returned as candidates. The selector then chooses among the candidates using whatever scoring or ranking policy applies. The selector's choice is itself a refusal: by selecting one candidate, the requester is implicitly refusing the others. Selectors may also explicitly refuse all candidates if none meets policy beyond the matching outcome — for example, accepting only FULL_MATCH and rejecting PARTIAL_MATCH outcomes regardless of the partial fit's specifics.
Discovery-time refusal is bounded by the matching outcomes the algorithm provides. Candidates the algorithm rejects (NO_MATCH) cannot be selected; candidates the algorithm accepts (FULL_MATCH, PARTIAL_MATCH) can be refused by selection policy but no tby the algorithm itself.
At invocation — when the requester actually goes to engage the selected server — both parties perform afresh bilateral verification. This verification is not a re-run of the discovery-time matching; it is a runtime check that the manifests are still current, still authentic, and still compatible with the engagement that is about to occur.
Specifically, at invocation each side:
• Re-fetches or freshly verifies the counterparty's current manifest, confirming it has not been revoked, superseded by an incompatible version, or had its signing keys rotated in a way that changes trust.
• Verifies the cryptographic signature on the counterparty's manifest using the JWKS-published public keys current at this moment, not the keys cached at discovery time.
• Re-evaluates the matching outcome against its own current manifest. If the manifest content or context has changed since discovery, the runtime outcome may differ.
• Refuses the engagement if any verification step fails or if the runtime evaluation contradicts the discovery-time assumption that justified this engagement.
Either side can refuse independently. A requester that re-verifies and finds the server's manifest has been updated to declare a regulatory framework the requester does not satisfy refuses the engagement. A server that re-verifies and finds the requester's manifest now contains content that violates the server's requirements_of_requester refuses the engagement. Refusals at this point are clean signals — they prevent invocation rather than allowing flawed engagement to proceed and produce errors downstream.
The two-decision-point structure is what makes SADAR matching robust against stale-cache attacks, manifest-rotation race conditions, and policy drift. Discovery is fast and cacheable; invocation verification is fresh and authoritative. Together theyg ive the architecture both performance (discovery does not require live verification) and safety (engagement requires fresh verification).
This page covers the matching algorithm as an architectural mechanism. Several adjacent topics are intentionally out of scope here and live in dedicated documents:
• Core Functional Model — the architectural framing for manifests and bilateral matching that this page elaborates.
• Non-Functional Requirements — the four NFR categories (Financial, Operational, Governance, Protocol) and the three-tier strictness model the matching algorithm consumes.
• Business Process — the first-class manifest element with its own bilateral pattern: requester's own and target_business_process against server's provided processes and requirements_of_requester.business_process.
• Data Semantic Meaning — the first-class manifest element matched by exact-IRI comparison; selector-side interchangeability handles cross-standard equivalence.
• Taxonomy — the grounding standards whose IRIs are compared during matching.
• Core Security — manifest signing and JWKS-based key publication; the cryptographic substrate that invocation-time bilateral verification rests on.
• Registry Security — manifest validation at registry ingestion; the upstream check that ensures matchable content reaches the discovery layer.
• 2. Scope §5.1.3 — Bilateral matching as a core spec capability.
• 2. Scope §5.1.10 — Manifests and the entity model; the structural surface the algorithm operates over.
• 2. Scope §5.1.11 — Discovery and bilateral matching at the spec level.
• 3. NFR Schema §12 — full normative content for the matching algorithm including per-NFR rules, edge cases, and exact strictness semantics.