Evidence acquisition · NexusScholar.Search
Search
Raw, reconstructable acquisition traces from local imports, recorded provider bytes, or bounded OpenAlex and Semantic Scholar adapters—before any deduplication decision.
Purpose and authority boundary
Search records what was asked, attempted, observed, normalized, skipped, and warned about. Its primary output is a SearchTrace, not a deduplicated corpus. Duplicate sightings stay visible; no-ID records stay unresolved. Search never elects a representative or calls Deduplication.
Acquisition modes: deterministic stubs; user-supplied RIS, BibTeX, and Scopus-like CSV; retained Crossref fixtures; and opt-in OpenAlex or Semantic Scholar transport through exact-host outward adapters. There is no live Crossref adapter, Google Scholar scraping, or provider-completeness claim.
Key types and services
SearchQueryInput,SearchTraceRequest, andSearchPlanBindingcapture explicit request and plan origin.SearchServicevalidates provider selection/year bounds, builds provider-order-insensitive cache identity, executesISearchProvideradapters, and preserves attempts, failures, stats, and sightings.SearchProviderCatalogholds local providers;DataProviderandFailingProvidersupport deterministic fixture scenarios.SearchTrace,SearchSighting,SearchProviderAttempt, andSearchSummaryare the raw trace surface.SearchPlanParserparses the schema-closed local plan and an explicitly separate legacy-import profile.SearchImportServiceparses user-supplied RIS, BibTeX, and Scopus-like CSV bytes intoSearchImportTracewith source-file/raw-record digests and parser notices.ProviderAcquisitionRequest,ProviderPageRequest,ProviderAttemptEvidence, andRuntimeProviderResponseEvidencebind sanitized requests, page continuity, observed response facts, parser identity, exact response digests, timestamps, and completeness.ProviderEvidenceCacheKey,ProviderEvidenceCachePolicy, andProviderEvidenceCacheEntrydefine provider- and operation-specific retention without making cache state scientific authority.
Core source: NexusScholar.Search. Outward adapters: Crossref, OpenAlex, Semantic Scholar, live host, and cache store. Contracts: ADR 0039, ADR 0040, and ADR 0041.
Trace and import model
query + selected active providers
→ ordered attempts (success / partial failure / all failed)
→ ordered raw sightings + normalized stable identifiers
→ SearchTrace with explicit nonclaims
user export bytes
→ raw source-file digest
→ versioned parser + per-record raw digest/notices
→ SearchImportTrace
→ Deduplication input later
sanitized provider request
→ exact-host transport + bounded identity-encoded response
→ response digest + parser/pagination/attempt evidence
→ normalized raw sightings
→ optional policy-admitted immutable cache entryProvider-local result order and cross-provider attempt order are semantic. Raw payload material is included only when requested. Source-specific IDs such as Scopus EID or Web of Science accession remain source evidence unless the Shared identity contract admits their namespace.
Two cache identities, two responsibilities
Cache identity includes query, year range, language, limit, offset, sorted active provider aliases, and include_raw_data. It excludes generated trace/query IDs, runtime duration, failure prose, raw bytes, app IDs, paths, URLs, configuration, and credentials. Including raw-data intent intentionally differs from PHP behavior because it changes the evidence surface.
Imported source identity is the exact source-file byte digest plus parser id/version and source metadata. Local path is not identity. Each raw record can carry its own digest. Parser output is a projection over preserved raw evidence, not a replacement for it.
FE-09E’s provider evidence cache is separate from Search result identity. Its key binds provider, operation, sanitized request digest, page request digest, and parser id/version. Only complete 200 responses are eligible. OpenAlex openalex.works may retain exact bodies for 14 days; Semantic Scholar bulk and batch are digest-only; Crossref runtime caching is denied. Expiry prevents a fresh hit but does not erase the verifiable evidence entry.
Typical developer flows
- For local provider scenarios, construct a catalog and explicit validation year/clock, then call
SearchService. - For imported evidence, read bytes in an adapter and call
SearchImportServicewith format, source tool/database, query/export metadata, and actor/time. - For provider acquisition, build a sanitized request and page descriptor; select a recorded adapter or an exact-host live host; then preserve the returned attempt, response, parser, and pagination evidence.
- Resolve credentials outside Core. The live host injects them only at send time and never emits them into descriptors, records, errors, or logs.
- Evaluate the provider/operation cache policy before any body write. Treat a cache hit as replay of the original request/receipt evidence, not as a new provider observation.
- Persist source bytes or their raw-byte identity alongside the trace.
- Display warnings and failed attempts without hiding successful sightings.
- Pass the complete verified trace/import records to Deduplication; do not pre-collapse them.
Failure and refusal behavior
Search rejects blank query, invalid/inverted year range, unknown provider alias, invalid limits/offsets, schema-open authoritative plans, unsupported import formats, empty or malformed source data, duplicate source record IDs, and Google Scholar scraping. Provider paths additionally reject wrong scheme/host/port/path/method, redirects, IP literals, user info, fragments, credential-shaped descriptors, encoded or oversized bodies, parser drift, pagination drift, and response-order assumptions. Parser failures retain bounded response evidence but produce no successful page.
Tests, extension points, and nonclaims
SearchServiceTests and SearchImportServiceTests cover local selection, imports, warnings, and trace identity. Provider-specific suites cover recorded Crossref, OpenAlex, Semantic Scholar, transport security, and cache invariants. Live smokes are opt-in and excluded from CI.
Current code makes no live Crossref, automatic retry, background refresh, Semantic Scholar body-retention right, Google Scholar scraping, provider coverage/completeness/parity, Search-time deduplication, corpus membership, API, cloud, production, or broad PHP compatibility claim.