# Captured identity selection

`pipewhy.query.ArtifactCatalog` binds explicit captured C1 artifact/name arrays to
snapshot metadata and discovery completeness. `catalog.resolve(ArtifactSelector(...))`
selects an exact `artifact_id`, `name` or root-first tuple `path`. It returns FOUND,
NOT_FOUND_WITHIN_SCOPE, AMBIGUOUS or UNAVAILABLE with bounded candidate IDs and full
scope metadata. Partial discovery cannot prove unique names; missing ancestry stays
unavailable for full paths. Empty and slash-containing labels retain their literal
identity. The catalog never looks up a current source to fill historical gaps.
`snapshot_query(catalog, limit=..., cursor=...)` pages the artifact inventory and
only its selected captured labels. Cursors reject changed input, scope or limits;
an explicit label-byte budget prevents silent text truncation. Capture/discovery
uncertainty and retained resolution remain in the page metadata. This view does
not fetch record/value payloads. See [blueprint/QUERY_CONTRACT.txt](../development/architecture.rst).
`diff_query(comparison, catalog=...)` pages
original comparison facts and full scope uncertainty. A name catalog is optional
for ID-based inspection; missing names remain separate from missing data. Names or
paths require an explicitly pinned before/after catalog. Counts, selected labels
and cursors preserve the same output bounds.
`diff_query(..., resolution="record"|"value")` explicitly reports unavailable when
that history was not retained, or when a finer captured comparison was not supplied.
Requested, materialized and retained resolutions stay distinct; zero missing-detail
rows never imply a successful empty history.
`lineage_query(index, selector, direction=..., depth=...)` pages explicit edges and
related node IDs. Missing names and evidence payloads remain separate qualifications;
captured declared evidence never becomes proof that an operation occurred. Graph
coverage and unique reachable counts remain visible beside the bounded page.
`incident_query(registry, view="episodes"|"observations", ...)` pages saved grouping
state and full observation identities. Recurrence counts exclude repeat scans;
unknown timing remains unknown. A separate observation cursor reaches references
beyond the related-event prefix. Registry state alone reports explanation evidence
as unavailable. Supplying `sources=(captured_incident_observations, ...)` attaches
bounded original divergence rows, timing and supporting checks. Missing inputs and
truncated supporting checks remain explicit; no whole source result is given to a
renderer, and no explanation is described as a proven physical cause.
`impact_query(captured_impact, ...)` pages unique potential artifacts and keeps
observed downstream changes separate. Full-scope counts, missing observation rows,
graph coverage and captured comparison contexts remain visible. With no comparison,
observed availability is unavailable. Starting IDs use their own bounded prefix.
`integrity_query(comparison, registry=..., impact_result=...)` reports full-scope
status counts and a separate tested-content denominator. Missing inputs, unknowns,
incompatibility and empty denominators remain explicit. Incident episodes and
observations use separate units, and repeated reporting does not increase them.
The C7 schema and independent consumer fixtures in `tests/fixtures/query_*_v1.json`
freeze the selected-result boundary. Scan, comparison and lineage commands are
implemented. `report integrity BEFORE AFTER --store DIRECTORY --format json`
adds coverage-aware direct-observation totals and separate incident/impact units.
Optional `--impact-from-id` roots supply declared exposure; `--registry-snapshot`
supplies saved incident evidence. Unrequested metric sources remain unavailable,
not measured zero. `export snapshot|diff|lineage|incidents|impact|report` selects a
captured result with an explicit format. Snapshot text shows containment; lineage
supports directed text and DOT. Incident exports add source receipts, integrity
qualifiers and registry persistence beside the selected C7 result, including in
CSV companions, so an empty table does not hide failed source reads.

`pipewhy.export.json_result(page)` serializes any selected query page as versioned
JSON with full metadata and exact integer values. `json_receipt(metadata)` uses the
C5 metadata representation; `json_fingerprint(state)` retains full context and all
eight C3 words. These Python APIs use selected text only. Command and output-format behavior is specified in [blueprint/CLI_CONTRACT.txt](../development/architecture.rst).
`csv_result(page)` returns a `CsvExport(text, metadata)` pair: a CSV primary table
and a JSON companion carrying the remaining evidence plus the CSV byte checksum.
Keep both artifacts together. It supports the six selected query families.
`dot_result(lineage_page)` exports selected directed edges and nodes, retaining
parallel edges/cycles and complete metadata in a base64 JSON graph attribute.
Graphviz is used for verification, and is not required to create the DOT text.
`text_result(page, width=100, ascii_only=False)` renders aligned selected tables
and complete qualified metadata. `text_receipt(metadata)` presents scan metadata.
Text wraps complete values and fails explicitly at its configurable output byte limit.
`hierarchy_text(snapshot_page)` renders selected containment as a tree, marking
parents outside the page and preserving exact IDs/depths without fetching ancestry.
`graph_text(lineage_page)` shows selected directed edges with page-local cycle,
self-loop and parallel-edge markers. These annotations do not certify omitted scope.
See [blueprint/LINEAGE_CONTRACT.txt](../development/architecture.rst) for the initial exact transform and evidence rules.
