Files
as4-411/docs/architecture/resolution-algorithm.md
defiQUG c24ae925cf
Some checks failed
CI / lint (push) Has been cancelled
CI / build (push) Has been cancelled
Initial commit: AS4/411 directory and discovery service for Sankofa Marketplace
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-08 08:44:20 -08:00

5.4 KiB
Raw Blame History

Resolution Algorithm

Deterministic resolution pipeline that produces ordered routing directives. Input/output contracts are defined in the OpenAPI spec; persistence shape is in the data model.

Precedence ladder (per rail)

When multiple sources can contribute a directive, apply this order. The first successful source wins unless overridden by tenant/contract config:

  1. Tenant override — Tenant-specific routing artifact or endpoint override.
  2. Contract-specific config — Contract or connectivity-group mapping.
  3. Internal curated directory — Participants/endpoints stored in the directory (admin or connector).
  4. External authoritative directory — SMP/SML, GTT feed, or other external source (cached).
  5. Fallback heuristics — Optional, disabled by default (e.g. default route).

Log and expose resolution_trace in the response so callers see which source(s) contributed (e.g. "tenant override", "internal directory", "SMP cache"). See route-directive.md.

Source-driven mappings (e.g. SS7): Data from connectors (GTT, NP/range feeds) is only as good as the ingested sources. Expose confidence and last_verified in directives; tag edges with provenance. No implied authority—see connectors.md.

Pipeline (steps 19)

  1. Normalize input
    Parse and validate all identifiers in the request. Validate formats per type (E.164, PartyId, PC/SSN, etc.). Reject invalid or unsupported types early.

  2. Expand context
    Infer candidate identifier equivalences using the mapping graph (same participant: multiple identifier types pointing to the same participant). Build a set of "equivalent" identifiers for lookup.

  3. Candidate retrieval
    Query the directory store for participants and endpoints matching any of the normalized/expanded identifiers, within the requested tenant and constraints.

  4. Capability filter
    Retain only participants/endpoints whose capabilities match the requested service context (service, action, process, document type) and any constraints in the request. Constraints may include requiredCapability, messageType (e.g. ISO8583 MTI), and networkBrand for card rails.

  5. Policy filter
    Apply tenant-scoped policies (ABAC). Enforce trust domain, geo, compliance, and allow/deny rules. Remove any candidate that is denied or out of scope.

  6. Score and rank
    Score remaining candidates (see Scoring). Sort by score descending; apply tie-break rules for stable ordering.

  7. Assemble directives
    For each ranked candidate, build a RouteDirective: map endpoint + participant to target_protocol, target_address, transport_profile, attach security refs (from credentials), service_context, qos, ttl_seconds, and evidence (source, lastVerified, confidenceScore).

  8. Sign response (optional)
    In multi-party setups, optionally sign the response for non-repudiation. Not required for MVP.

  9. Cache
    Store result in positive cache (keyed by normalized request + tenant) with TTL. On cache hit, return cached directives and skip steps 27. Negative results (no candidates after filters) may be cached with shorter TTL and invalidation hooks.

Determinism and tie-break

  • Invariant: Same inputs + same store state ⇒ same ordered list of directives.
  • Tie-break order when scores are equal (aligned with data-model conflict resolution):
    1. Explicit priority (endpoint/identifier priority from store) — higher first.
    2. Policy (allow/deny and policy priority).
    3. Freshness (updated_at / verified_at / valid_from).
    4. Confidence (edge or evidence confidence score).
    5. Lexical — stable sort by deterministic key (e.g. participant id + endpoint id).

Implementation must use a fixed ordering (e.g. sort by (score DESC, priority DESC, updated_at DESC, id ASC)).

Scoring

Factors that contribute to the score (combined by weighted sum or ordered rules; exact weights are implementation/config):

Factor Description
Explicit priority From identifiers.priority / endpoints.priority in the store.
Endpoint health/status Prefer active over draining over inactive.
Freshness/verification Higher score when identifiers.verified_at or evidence is recent.
Trust domain affinity Match between requested trust domain and endpoint/participant metadata.

Scoring must be deterministic: same inputs and same data ⇒ same scores and thus same order after tie-break.

Caching

  • Positive cache: Key = hash or canonical form of (normalized identifiers, serviceContext, constraints, tenant). Value = ordered list of directives + TTL. Reuse until TTL expires or explicit invalidation.
  • Negative cache: When no candidates survive filters, cache "no result" with a shorter TTL to avoid thundering herd on missing keys. Invalidation: on participant/identifier/endpoint/policy change for that tenant or key scope.
  • Invalidation hooks: Connectors or admin updates that change participants/endpoints/policies should invalidate affected cache keys (by tenant, participant id, or key prefix). Optional: publish events for external caches.