cross_lens_verify
A2 — the cross-lens join. TunnelMind owns multiple halves of the open-web graph: Scry sees who is on every IP (attacker intelligence, actor class, Augur threat-intel overlap); Sigil sees the supply graph (publishers, SSPs, DSPs, ads.txt + sellers.json + SupplyChain Object); GhostRoute sees routing integrity & sovereignty (RPKI origin validity, BGP prefix, claimed sovereign zone, sanctions, AI-infrastructure ownership, certificate CA). This endpoint fuses them into one verdict on a single node key.
Streaming mode (P56): send Accept: application/x-ndjson and the
same verdict computation streams as one JSON object per line — a
{"t":"lens",...,"state":"start"} line when each lens query is
dispatched, a "state":"result" line as each lens actually resolves
(real completion order, never reordered or paced), then the final
{"t":"verdict",...} line with the fused verdict, trust score, and
attestation tier. The default single-JSON response is unchanged and
the two modes return the identical verdict for the same node.
The response leads with a base record, then the lens views:
ip_intel— the BASE: the commodity IP-intelligence + WHOIS record (geo/ASN/company/WHOIS/routing/cert), every field provenance-tagged{value, tier, source}(verified/derived/trusted) with a behaviour axis from Scry. The lens blocks below are augmentation beside it. Committed in the receipt payload. Seedocs/IP-INTEL-RECORD.md.scry— the single-lens Scry view (transparency).sigil— the single-lens Sigil view (transparency).ghostroute— the single-lens GhostRoute view (transparency).cross_lens— the fused verdict (the moat).
Fusion math: weighted-mean over evaluated components plus a
co_observation_bonus when both lenses independently flag the node.
GhostRoute adds a routing-integrity component with two hard safety
floors that cannot be averaged away: an RPKI-INVALID origin (a BGP
hijack signal) caps its trust at 0.15, and a sanctions match zeroes it.
Weights and thresholds are per-request overridable.
Lens unavailability is reported in-band: each lens fails independently and the cross_lens block reflects degraded confidence when fewer lenses have data (0.55 one lens / 0.80 two / 0.94 three). GhostRoute has no routing surface for a bare entity_slug, so it drops out and the remaining weights re-normalise. Returns 503 only when ALL lenses are unavailable.
v1 lens coverage matrix:
IP node — Scry: full; Sigil: not_indexed (v2 will reverse-DNS); GhostRoute: full.
Domain node — Scry: deferred; Sigil: full (publisher/ssp/dsp + entity); GhostRoute: full (resolves to IP).
entity_slug node — Scry: n/a; Sigil: full (entity + sell/buy presence); GhostRoute: n/a (no routing surface).
ASN node — Scry: deferred (v2); Sigil: not_indexed; GhostRoute: origin-AS lookup.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| ait | No | Optional ATAP AIT id (`AIT-<uuidv7>`). When present, the verdict is wrapped in a witness-tier `cross_lens:verified` event chained onto the AIT and signed by Sigil (witness OAI-2026-0000201). Independent of the AIT, a short-lived signed `sigil_token` is always issued on a successful verify, and a durable TunnelMind `receipt` (v1.0) commits to the verdict for long-term audit. | |
| node | Yes | The node to verify. Type is auto-detected: IPv4/IPv6 address, domain, ASN with optional `AS` prefix, or entity_slug. | |
| weights | No | Per-component weight overrides | |
| thresholds | No | { pass, fail } verdict cutoffs (defaults 0.7 / 0.3) | |
| claimed_zone | No | Caller-asserted sovereign zone for the subject (e.g. `EU`) — "the vendor's contract says EU-only; score the routing against that claim." Validated against the sovereign-zone reference; an unknown code is ignored with caveat `claimed_zone_unrecognised_ignored` (garbage input never creates penalties). Takes precedence over the corpus's public claim; the response and signed receipt record who asserted it in `ghostroute.claimed_sovereign_zone_source` (`caller` | `corpus`). Claim-bearing calls bypass the shared lens cache and are never written back to the corpus (ADR-012). |