PipeWhy Query Contract C7 version 1.0 October 30, 2026 | PW-11.01-.04 | Consumes C1/C5/C6 and L1 1.0 Specification for the next implementation; not a claim of released query commands. Mandatory engineering gate Q1 v1.0 applies to every implementation/verification task. PW-11.01 Snapshot, artifact and path selectors Snapshot selection uses an explicit canonical 32-lowercase-hex C5 snapshot ID. No implicit latest, wall-clock ordering, path-as-ID or source-version-as-time alias is introduced. A coordinator may list candidates, but must pin the selected ID before a query/cursor is constructed. Namespace and captured scope qualify artifact IDs; equal numeric IDs in unrelated namespaces do not identify one artifact. ArtifactCatalog binds one SnapshotMetadata, explicit discovery_complete boolean, C1 artifact columns and its captured UTF-8 name dictionary. C5 names alone do not infer semantic array roles; a producer/coordinator supplies these validated inputs. Artifact IDs are unique non-sentinel uint64, names resolve in the captured dictionary, and containment is acyclic. An explicitly scoped inventory may retain parent IDs outside it; those references limit full-path resolution, rather than becoming roots. Borrowed artifact aliases remain stable for the catalog's lifetime. Captured name storage is validated and retained; no current source is consulted for a missing name. A typed ArtifactSelector selects exactly one of artifact_id, name, path. Numeric names remain text and are never parsed as IDs. Names and path components use exact captured Unicode identity, without stripping, case folding or logical-profile normalization. Empty captured labels remain valid exact names. A path is a nonempty immutable tuple of string name components (including empty captured labels), root first. A slash in a component is literal; this is not an OS/filesystem path. CLI string escaping/notation is defined separately in PW-12. An omitted selector means all represented rows in a query family; it is not a malformed empty selector. Unqualified names may match multiple artifacts. Full paths consider every matching root/branch through the final component, so an ambiguous prefix may later become unique. No first-row/lowest-ID tie breaker chooses an artifact. Results distinguish FOUND, NOT_FOUND_WITHIN_SCOPE, AMBIGUOUS and UNAVAILABLE. Only FOUND contains one selected artifact ID. Invalid selector types/IDs/path shapes raise explicit errors. Ambiguous/unavailable selection cannot silently become a successful query. A captured stable ID can resolve uniquely despite other discovery gaps. Name/path uniqueness requires complete discovery in this initial catalog protocol: one represented match with incomplete discovery remains UNAVAILABLE; two known matches are AMBIGUOUS. Resolution keeps a bounded immutable sorted candidate-ID prefix (default 32, explicit positive uint64 max_candidates) and the count of all represented matches. This prefix is diagnostic, not a chosen result or a claim of complete output. An absent ID/name in incomplete discovery is UNAVAILABLE, not proof of absence. Full-path selection with missing ancestry is UNAVAILABLE unless the captured evidence suffices to establish all matches. NOT_FOUND_WITHIN_SCOPE makes no claim outside the namespace/scope snapshot. PW-11.02 Typed result families and ownership Query results are typed by family: SNAPSHOT, DIFF, LINEAGE, INCIDENT, IMPACT, INTEGRITY. Every page binds query schema version, family, immutable source identities/revisions, canonical selection/filter/resolution/order, availability/reason and original coverage/evidence context. Main table columns are flat integer arrays; selected text lives in UTF-8 payload/offset/length dictionaries. Outputs own immutable selected arrays and retain source/control owners while consumers use referenced evidence. Renderers receive this page, not a source adapter or permission to rescan a dataset. SNAPSHOT: selected captured C1 artifact rows plus SnapshotMetadata, explicit discovery coverage and requested/retained resolution. Label expansion is confined to selected rows. Dataset summaries cannot manufacture record/value detail. No inferred semantic roles for arbitrary C5 arrays are accepted. DIFF: selected C6 comparison rows, both full contexts, requested resolution and all original status/reason/flags/observation links. Parent/child-derived changes remain distinct from direct value changes. Selection/pagination cannot revise C6 certainty. LINEAGE: selected explicit C1 edge rows and bounded related node IDs, with graph namespace/declaration/scope/coverage/failures/evidence references. Direction is explicit forward or reverse; nonnegative depth is minimum-hop distance from pinned starts. Depth zero selects starts and no edges. Positive depth admits encountered edges from vertices nearer than the bound, retaining both endpoints, cycles and parallel edges without duplication. Edge pages sort by stable edge ID; related nodes are unique sorted endpoints plus selected starts, bounded by twice the edge-page size plus the start count. Containment is never inserted into lineage. Traversal is a query operation; a DOT renderer does not discover omitted branches itself. INCIDENT: selected registry episode rows retain registry identity, explicit policy, full grouping/observation/timing keys, qualification flags and occurrence counts. Original divergence/check/observation metadata is carried when supplied and bound. A saved registry alone is AVAILABLE for grouping state but cannot reconstruct why evidence: analysis availability then explicitly says REFERENCE_EVIDENCE_NOT_SUPPLIED. Never represent missing explanation inputs as verified provenance or a clean graph. IMPACT: selected L1 impact rows retain original graph/divergence context, start IDs, relation selection and separate POTENTIAL / OBSERVED_DOWNSTREAM_CHANGE flags. Counts refer to unique matched artifacts, with observed availability separate when no divergence was supplied. No page turns all reachable nodes into observed corruption. INTEGRITY: typed aggregate metrics retain selection scope, full matching denominators and source contexts. C6 status counts include SAME/CHANGED/ADDED/REMOVED/UNKNOWN/ INCOMPARABLE independently and sum to represented matched rows. Content comparability is a separate denominator: direct SAME/NONE and CHANGED/VALUE_CHANGED rows at observed non-container levels. Presence/parent moves, derived container changes, unknown and incompatible rows are not counted as tested content. Registry episode count and sum of distinct observation occurrences are separate units, never subtracted from an artifact denominator or described as proven physical corruption events. Cross-registry IDs qualify by registry identity. Aggregates reconcile with full filtered inputs, not just the displayed page; page-local counts are explicitly labeled when requested. Concrete Python family objects/column inventories are published with implementation and exporter acceptance. There is no guessed generic result that drops source-specific evidence. L1/C6 required context remains part of each consuming family boundary. PW-11.03 Bounds, deterministic ordering and cursor validity All query pages have an explicit positive row limit, default 1000 and maximum 100000 for this initial resource-policy version. Invalid/zero/bool/over-limit bounds fail; they are not silently clamped. Internal source/index scans may validate/count matching rows, but output arrays and label expansion remain bounded by the requested page. The renderer never materializes a whole source merely to print its first page. Each family declares a total order with unique stable tie-breakers. Artifact snapshot, diff and impact rows use artifact ID; edge rows use edge ID; registry episodes use registry-qualified incident ID; fixed integrity metrics use published metric order. Physical input positions and display labels do not establish cursor order. Returned rows preserve their original evidence indexes/references beside presentation order. Page metadata distinguishes total matching count, returned count, truncation and next cursor. An available empty selection returns zero with no continuation. A final page has no next cursor; a nonfinal page sets truncated and supplies a continuation. UNAVAILABLE is distinct from an available zero-row page, even when both have no rows. Cursor format query-cursor-v1 is opaque URL-safe base64 of canonical UTF-8 JSON, binding query/result schema versions, a full SHA-256 query identity and a canonical uint64 decimal-string continuation position. The identity binds exact source snapshot/ registry/context identities, full immutable result/catalog column and label content digest, selector/filter/resolution, stable ordering and row limit. Digest framing includes names, dtype, lengths and raw canonical bytes, so ambiguous concatenation does not alias distinct tables. Validate UTF-8/JSON, exact fields/version/encoding, identity, position range and source revision before returning another page. Changing snapshots, catalog content, registry state, filters, ordering, resolution or page limit invalidates the old cursor. Malformed/stale cursors fail explicitly; there is no restart-at-zero fallback. Reopening exactly the same immutable input may reuse its descriptor-bound cursor. These tokens bind read pagination; they are not authentication, authorization or a secret-bearing remote API capability. No cryptographic authenticity claim is attached to an unkeyed content identity. PW-11.04 Coverage, evidence and historical unavailability Preserve discovery completeness independently from data read/retention coverage and graph inventory completeness. A complete selected row may coexist with unrelated capture failures; a small page cannot upgrade the full scope's uncertainty. Keep full-scope coverage, selection match accounting and pagination truncation distinct. Retained record/value requests require actual compatible retained inputs at that resolution. Missing historical payload/ancestry/control evidence returns UNAVAILABLE with an explicit reason and requested-versus-retained metadata. It never falls back to a current adapter read or reconstructs fine values from an aggregate fingerprint. Unknown provenance, operation timing, unsupported rules and incompatible policies retain their L1/C6 labels and selected metadata. Queries may filter labels explicitly, but report the filter and cannot claim excluded unknowns were tested or repaired. Exporter boundary receives only selected family arrays/text and bounded related evidence, plus all required metadata/control references. JSON uint64 values are exact decimal strings. Names are presentation; source/observation/registry identities remain stable. An explanation limited by missing references says so. Further rendering, CSV/DOT escaping, CLI exit policy and installed command acceptance belong to PW-12. Implemented selector boundary (PW-11.05) pipewhy.query exports ArtifactCatalog, frozen ArtifactSelector, Selection, SelectionStatus and SelectionReason. ArtifactCatalog(metadata, columns, labels, discovery_complete=...) consumes the explicit C1 table/name triple above. It borrows read-only artifact columns under stable aliases and owns a validated copied name dictionary. metadata/discovery_complete/columns/sorted_ids/name_arrays are read-only properties; resolve_name selects a captured dictionary entry. kind_id stays opaque. catalog.resolve(selector, max_candidates=32) returns Selection(metadata, discovery_complete, selector, status, reason, artifact_id, candidate_count, candidate_ids). Candidate IDs are owned immutable sorted uint64 storage. artifact_id is NULL_ID unless status=FOUND. candidate_count counts represented matches before diagnostic-prefix truncation; incomplete discovery can conceal additional matches, which remains explicit in status and discovery_complete. SelectionStatus strings are FOUND, NOT_FOUND_WITHIN_SCOPE, AMBIGUOUS, UNAVAILABLE. SelectionReason strings are MATCH, NO_MATCH, NOT_UNIQUE, DISCOVERY_INCOMPLETE, PATH_ANCESTRY_UNAVAILABLE. Path resolution uses flat branch masks through every exact component and terminates without recursion on deep captured containment. Catalog/C1/C6 share one validated parent-index cycle walk while preserving each boundary's original parent-reference rules and diagnostic text. C1 tables still reject dangling parents; scoped C6 and catalog views may preserve external parents. Integration verifies complete and scoped C4 discoveries saved/reopened through C5 at two capture batch sizes. Snapshot/diff/lineage/incident/report pagination APIs remain subsequent PW-11 tasks. Implemented snapshot inventory pages (PW-11.06; PW-11.12 foundation) snapshot_query(catalog, selector=None, limit=1000, cursor=None, max_label_bytes=1048576) returns SnapshotPage. It pages the captured artifact inventory, not normalized record/value payloads. Full SnapshotMetadata exposes capture scope, retention resolution/counts/failures and fingerprint policy, while discovery_complete remains independent. No requested finer-payload capability is implied by this inventory API. Fine historical availability is subsequent work. SnapshotPage fields are metadata, discovery_complete, selection, availability, reason, columns, names, total_count, start, limit, max_label_bytes, next_cursor, query_id. Properties schema_version=1.0, family=snapshot, returned_count and truncated are explicit. availability reuses C6 Availability.AVAILABLE/UNAVAILABLE. Snapshot reasons are NONE, NO_MATCH, AMBIGUOUS_SELECTION, SELECTION_UNAVAILABLE or LABEL_BUDGET_EXCEEDED. Ambiguous/unavailable selection yields no result rows or continuation, with the bounded Selection diagnostics retained. Complete absence yields AVAILABLE/NO_MATCH. An unfiltered partial inventory remains AVAILABLE for represented rows with its false discovery completeness and original capture failures preserved. Columns preserve C1 artifact_id/parent_id/name_id as uint64 and opaque kind_id as uint8, sorted by stable artifact ID. name_id remains the original captured ID. SelectedNames contains immutable name_ids:uint64, payload:uint8, offsets:uint64, lengths:uint64, sorted by original unique name ID; resolve(name_id) returns only a selected captured string. Renderers receive this bounded selected dictionary, not the full catalog. Empty labels remain empty. Repeated names consume UTF-8 byte budget once per unique captured name ID. Label byte lengths are checked before expansion; exceeding the positive explicit budget yields UNAVAILABLE with no partial/truncated name invention, no result rows and no cursor. Total matching count and query/source metadata remain available. Changing the budget changes the cursor binding. Source catalog validation/indexing may process full captured inputs; output rows/text are bounded separately and no unmeasured memory/latency claim is made. ArtifactCatalog.identity caches a full SHA-256 over canonical complete metadata, explicit discovery flag and sorted column/name dictionary framing. Each frame has an eight-byte little-endian byte length followed by bytes; column frames include name, logical dtype and contiguous canonical integer bytes. The domain prefix is pipewhy.query.source.v1 followed by NUL. Descriptor JSON uses C5's existing canonical encoder. Query identity separately binds schema/family/view, exact selector, order, row limit and label budget with domain pipewhy.query.v1 followed by NUL. Catalog artifact aliases must remain stable throughout this cached identity's lifetime. Cursor payload fields are exactly version=query-cursor-v1, query_id and decimal position, encoded as unpadded URL-safe base64 of C5-canonical UTF-8 JSON. Schema version is bound through query_id. Tokens are bounded to 1024 characters; malformed encoding/UTF-8/JSON, extra fields, noncanonical base64/JSON/position, wrong version, stale context and positions outside a continuation are rejected. A continuation position is strictly between zero and total_count. Query digest framing has an independent literal vector in unit tests. C4 discovery/C5 reopen integration resumes a real snapshot page on an identically reopened catalog at two capture batch sizes. Other result-family paging remains pending before PW-11.12 can be closed. Implemented diff pages (PW-11.07; PW-11.12 foundation) diff_query(result, selector=None, catalog=None, limit=1000, cursor=None, max_label_bytes=1048576) pages trusted C6 ComparisonResult producer output. It copies selected original C6 columns/reasons/flags/observation references without changing comparison or scope certainty. Full before/after ComparisonContexts, original overall scope_status/scope_reason and result resolution remain independent from query availability and row selection. scope_row_count is the original represented count; total_count is matching represented rows, or null when selection cannot be resolved. A one-row SAME view cannot turn a changed/uncertain scope into a clean result. DiffPage fields: before, after, scope_status, scope_reason, resolution, selector, selection_diagnostics, names_source, names_discovery_complete, availability, reason, columns, artifact_name_ids, names, name_availability, missing_name_count, scope_row_count, total_count, start, limit, max_label_bytes, next_cursor, query_id. Properties schema_version=1.0, family=diff, returned_count and truncated are explicit. QueryReason adds LABEL_CATALOG_UNAVAILABLE and CONTEXT_INCOMPARABLE for this family. An incompatible comparison remains inspectable with its exact C6 scope reason, including when it has no aligned rows; it is never reinterpreted as a clean diff. Stable ID selectors address comparison rows directly, including REMOVED artifacts that are absent from an after-snapshot name inventory. Names/paths require an explicit catalog anchored to a pinned before or after snapshot. No automatic cross-version name search guesses which name was intended. Binding verifies snapshot ID, namespace, source version, scope, full fingerprint context and sufficient retained resolution. Capture/discovery qualifiers from the comparison and name catalog remain independent and preserved. A missing label catalog prevents name/path selection, with null match count and no rows/cursor. Ambiguous or incomplete name selection similarly remains unavailable with its bounded Selection diagnostics. Absent ID selection needs complete discovery and a sufficient represented projection to establish NO_MATCH. A known catalog artifact outside a conservative C6 node view, or an absent ID with incomplete discovery/coarser projection, remains UNAVAILABLE. The function never supplies missing historical rows from live reads or an aggregate. Known comparison rows remain available even when their names are unavailable. artifact_name_ids is an immutable uint64 vector aligned with returned C6 rows; entries reference original captured IDs in the bounded SelectedNames dictionary. NULL_ID marks unavailable names. name_availability and missing_name_count describe returned-row naming, separately from data-query availability. names_source and names_discovery_complete identify the exact optional captured catalog. Removed rows can therefore retain their C6 REMOVED fact with an unavailable after-version name, or obtain a captured name through an explicitly supplied before catalog. No label or missing label changes a data status. The same selected-name/UTF-8-byte budget implementation serves snapshot and diff pages; exceeding it returns no partial data/text page and preserves original contexts/counts with an explicit reason. Diff cursor identity binds both contexts, scope verdict, result resolution, exact C6 columns and optional catalog identity, then selector/order/row/label budgets. Result column hashing scans the captured immutable source buffers per query call; it does not create a Python object per source row or promise unmeasured latency. Cross-family, changed-content/context/selection/catalog and changed-bound cursors are rejected. Reference and native C4/C5 integration saves C1 names and C6 states together, reopens both, and verifies bounded raw statuses/uncertainty at each page. Lineage and incident projections are described in the following sections. Implemented lineage pages (PW-11.08; PW-11.12 foundation) lineage_query(index, selector, direction=forward, depth=1, relations=(COPY,TRANSFORM,DERIVED), catalog=None, evidence=(), limit=1000, cursor=None, max_label_bytes=1048576) selects explicit graph edges. The selector is a typed ArtifactSelector. depth is a nonnegative uint64; None explicitly requests all captured reachable depths. A shared frontier traversal with reachability/impact computes minimum-hop layers, terminates on cycles, preserves parallel/self edges and marks encountered original edge rows. It never traverses containment or infers timing/equality edges. LineageIndex.edge_order is immutable original row positions sorted by stable edge ID, reused for deterministic edge pagination. LineagePage fields: graph, selector, selection_diagnostics, selected_artifact_id, direction, depth, relations, availability, reason, columns, node_ids, node_name_ids, names, names_source, names_discovery_complete, name_availability, missing_name_count, evidence, missing_evidence_ids, evidence_availability, scope_node_count, total_node_count, total_count, start, limit, max_label_bytes, next_cursor, query_id. Properties schema_version=1.0, family=lineage, returned_count and truncated apply. Original C1 edge columns retain their dtypes and reference IDs. scope_node_count is captured inventory size; total_node_count is unique captured reachable nodes including the start; total_count is matched captured edges. Unresolved selection uses null matching counts. Known isolated/depth-zero starts have one selected root node and zero edges, distinct from an unavailable unknown graph start. node_ids are sorted unique returned-edge endpoints plus the selected start, at most 2*limit+1; node_name_ids references original captured dictionary IDs or NULL_ID. These are page-related nodes, not the entire reachable set. The last edge page can still omit earlier edges: start and total_count must accompany next_cursor/truncated. A page cannot certify completeness of a displayed path or uncaptured graph scope. Names follow the same selected-name byte budget and missing-name qualifications as diff pages. Name/path root selection requires an explicit captured catalog; unknown/ambiguous/incomplete roots do not become successful empty graphs. Complete name absence is scoped to the chosen catalog. Namespace/scope and an explicit graph snapshot binding must match the catalog. Declaration version and endpoint data source version are distinct; the query does not equate those version strings. Optional evidence is an immutable tuple of selected captured Evidence DTOs. Input IDs must be unique in graph reference context, and a known evidence source version must match declaration version. Tuple delivery order is canonicalized by evidence ID. Only payloads referenced by returned edges are included in the page; absent payload IDs remain in immutable missing_evidence_ids. evidence_availability reports payload availability for returned references, not completeness/verification of the whole graph or an operation. Empty edge pages require no payloads. Supplied UNKNOWN or incomplete provenance remains visible even when its payload is available. All Evidence kind/producer/version/diagnostic/time/clock qualifiers remain unchanged. Complete DECLARED evidence describes intent; it does not prove copying occurred. Cursor identity binds exact graph context/inventory/edge content, optional catalog, canonical supplied evidence and selection/direction/depth/relations/row/label budgets. Missing names/evidence do not erase known edges; original inventory coverage/failures remain explicit. The reference allocator does input traversal/hashing in the query, not the renderer. Tests include a literal branch/cycle truth set, 24 independent minimum-distance graph oracles, a 1501-node chain, legacy reach/impact oracles, bounded related-node counts, selected evidence gaps/order and stored C4/C5 consumers. Incident family paging is described next. Implemented incident registry pages (PW-11.09 component; PW-11.12 foundation) incident_query(registry, selector=None, view=episodes, limit=1000, cursor=None, event_limit=1000, max_key_bytes=1048576) pages immutable registry state. IncidentFilter combines registry-local incident ID, exact namespace, scope and artifact ID filters. Scope needs its namespace; artifact ID needs both. No bare artifact ID is treated as globally unique. Absent IDs yield scoped empty results in this registry only. IncidentPage preserves registry_id, policy, selector, view, scope episode/observation counts, matching count, position/limits, query identity and continuation. Episode columns retain registry-local incident IDs and exact L1 summaries, including unknown anchors, mergeability and distinct observation counts. Related events are a bounded prefix with original observation indices, references, flags, total and explicit events_truncated. The observations view independently pages every matching event, including references beyond that prefix, with its incident and group key IDs. Repeated registration does not create another stored observation or change cursors. SelectedNames keys retain original registry dictionary IDs and complete canonical group/observation/timing strings. The shared byte-budget projection preflights UTF-8 lengths and returns an explicit KEY_BUDGET_EXCEEDED unavailable page rather than partial identities. Arrays and strings are owned immutable selections. The query hashes the full exported registry plus filters/view/order/bounds; reopened identical state resumes, while changed state or bounds reject old cursors. This reference implementation scans/copies registry inputs in the query, never in a renderer; no measured large-registry latency or allocation guarantee is claimed. Grouping state includes durable divergence references, not original C6/L1 explanation payloads. analysis_availability is UNAVAILABLE with REFERENCE_EVIDENCE_NOT_SUPPLIED for this component. It does not reconstruct missing snapshots, treat stored flags as verified causes or fetch current data. Selected captured analysis projection extends this registry-only component as described below. Selected captured incident analysis (PW-11.09; PW-11.12) incident_query additionally accepts sources=(), an immutable tuple of producer IncidentObservations, and support_limit=1000 (1..100000). It validates the policy and regenerates canonical references from each supplied ranking. Duplicate full observation identities reject ambiguous explanation inputs. A registry event binds the exact observation AND timing key; conflicting timing raises rather than revising the registered fact. Source dictionary positions and numeric IDs are not matched across independently allocated dictionaries. Source tuple order does not affect query identity; content, checks/evidence, ranking and support limit do. IncidentPage.analysis is IncidentAnalysisSelection(availability, reason, items, missing_observation_indices, support_count, support_total_count), with a supports_truncated property. Page analysis_availability/analysis_reason delegate to it. Missing payloads remain explicit original observation indices while available matched analyses remain inspectable. Grouping availability is independent. An empty selected set is available when explicit analysis inputs are supplied; no inputs still declare REFERENCE_EVIDENCE_NOT_SUPPLIED. Key-budget failure exposes no analysis. Each IncidentAnalysis contains observation_index, full graph/before/after contexts, scope status/reason/resolution, owned one-row candidate/comparison/timing columns, resolved clock_domain or null, original ranking_status and full-scope candidate/ earliest counts. It carries bounded supports and corresponding original EdgeCheck DTOs, support_total_count and supports_truncated. Checks retain qualified and raw statuses, endpoint observations, provenance qualifiers and transform references; they do not reconstruct retained transform payloads or certify a physical cause. Support links use original candidate/check indices and endpoint roles, sorted by edge ID then role. One support_limit applies across all returned analyses; omitted supports keep exact totals and an explicit truncation flag. Ranking counts never require exporting the entire earliest set. Related event limits still apply; the independent observations view reaches omitted events without expanding every episode. The renderer receives no original IncidentObservations, ranking or divergence owner. Large-input acceptance uses 1501 candidates with three episode rows, two related events and two one-row analysis selections. Shared cursor/row/text bounds now serve snapshot, diff, lineage and incident families; final cross-family verification and exporter schema publication remain PW-11.14/.16/.17. Implemented impact pages (PW-11.10) impact_query(result, catalog=None, limit=1000, cursor=None, max_label_bytes=1048576, start_limit=1000) consumes trusted L1 ImpactResult, already selected by explicit start IDs, relations and include_starts. It does not infer roots from a failed check. ImpactPage keeps original graph, optional before/after contexts, scope status/reason/ resolution, relation filter and include_starts. Main columns are exact L1 artifact_id, comparison_index, status, reason and flags, ordered by unique artifact ID. Cycles, parallel paths and repeated roots cannot duplicate result counts. scope_potential_count, scope_observed_changed_count and scope_without_observation_count refer to the full selected L1 result, independently of page size. observed_availability is AVAILABLE only when a divergence input was supplied; it reports input presence, not complete testing or verified corruption. UNKNOWN/INCOMPARABLE rows remain visible. POTENTIAL reachability and OBSERVED_DOWNSTREAM_CHANGE labels are never conflated. The result does not retain the original unbounded divergence/comparison objects. start_ids is an owned sorted prefix of at most start_limit (1..100000), with full scope_start_count and starts_truncated. This explicitly bounds metadata for queries with many starting artifacts, without implying that omitted starts were not traversed. A 1501-root test selects two output rows and only three root references. An available empty potential set is scoped to those starts/relations, not a clean-source finding. Optional selected names use the same byte budget, original dictionary IDs, missing name count and separate name availability as diff pages. Shared catalog helpers now serve comparison/graph binding and diff/impact name projection. Catalog namespace, scope and explicit graph snapshot binding must match; with observations, it also binds an explicit comparison endpoint and its version/fingerprint/retention context. Graph declaration version is not equated with captured data version. Budget failure returns no partial impact rows/names, preserving full counts/context. Cursor binds the graph, exact impact columns and full roots, contexts, relation/roots policy, catalog and row/text/root-prefix limits. No live-source lookup or causal claim occurs. Implemented integrity totals (PW-11.11; reconciliation PW-11.15) integrity_query(comparison, registry=None, impact_result=None, limit=1000, cursor=None, start_limit=1000) counts the full supplied C6 scope. Metric pagination never changes the population being counted. IntegrityPage preserves full before/ after contexts, scope status/reason, resolution and comparison_scope_row_count. Optional registry identity/policy and full registry episode/observation counts remain separate metadata. Optional impact graph/relations/include_starts and a bounded owned start-ID prefix retain full root count and impact_starts_truncated. IntegrityMetric IDs 0..14, in published order: SAME, CHANGED, ADDED, REMOVED, UNKNOWN, INCOMPARABLE, CONTENT_COMPARABLE, CONTENT_SAME, CONTENT_CHANGED, CONTENT_UNTESTED, INCIDENT_EPISODES, INCIDENT_OBSERVATIONS, POTENTIAL_IMPACT, OBSERVED_IMPACT, IMPACT_WITHOUT_OBSERVATION. Selected metric_names and metric_units (artifact/episode/observation) align with flat columns metric_id:uint8, value:uint64, denominator:uint64, available:uint8 (0 unavailable/1 available), reason:uint8. MetricReason codes: NONE=0, SOURCE_NOT_SUPPLIED=1, OBSERVATIONS_NOT_SUPPLIED=2. An unavailable zero is not a known empty population. NULL_ID denominator means not applicable; zero means an actually empty denominator, never permission to report a successful percentage. The first six status counts sum to represented comparison rows and use that row count as denominator. CONTENT_COMPARABLE counts non-container SAME/NONE and CHANGED/VALUE_CHANGED rows. CONTENT_SAME/CONTENT_CHANGED use only that comparable count as denominator. CONTENT_UNTESTED equals represented minus comparable rows; it and CONTENT_COMPARABLE use represented rows as denominator. Parent moves, presence changes, derived container changes, unknowns and incompatibility do not become tested content. Different resolutions remain explicit; dataset counts do not claim individually tested records/values or physical corruption events. Registry metrics count distinct stored observations with the exact comparison snapshot pair, namespace/scope, fingerprint policies and represented artifact ID, plus the distinct episodes touched by those matches. A registry can include other captures/policies/namespaces; their entries remain in registry_scope_* metadata but not those selected metrics. An episode spanning other snapshot pairs contributes only matching observations here. Exact repeated reporting does not increment counts. Incident denominators are not artifact counts; their denominator is not applicable. Impact graph namespace/scope and explicit snapshot must bind the comparison. When observations are supplied, the impact divergence must bind the exact C6 comparison content/context/resolution. This prevents combining independently changed analyses. Unique potential, observed and missing-row counts stay independent metrics with not-applicable denominators. Graph-only potential is available while OBSERVED_IMPACT is unavailable with OBSERVATIONS_NOT_SUPPLIED. Missing optional sources keep explicit unavailable metrics, rather than collapsing into a green report or failing known C6 counts. No supplied unbounded result/registry/ranking is retained in the output. Cursor identity binds exact C6 facts/context, full optional registry state and impact columns/roots/graph/policy, plus metric order and row/root-prefix bounds. Tests use literal counts for all six statuses, parent/container exclusions, zero and incompatible populations, mixed namespace/policy/snapshot registries, repeats after reopening and independently known native C4/C5 fixture totals across complete/mutated/missing reads. Historical resolution availability (PW-11.13) diff_query accepts resolution=None (the materialized result resolution) or an explicit dataset/record/value request. DiffPage.requested_resolution keeps that request separate from resolution (the actual C6 materialization) and each endpoint's retained context resolution. A request finer than either retained endpoint returns UNAVAILABLE/DETAIL_NOT_RETAINED, no rows/names/cursor and unknown matching total (null, not zero). Original scope verdict, coarse source row count, capture failures, metadata and selection diagnostics remain visible. This also catches a C6 fine comparison that already reports RESOLUTION_UNAVAILABLE with zero rows: those rows cannot be interpreted as a successful empty history. When both captures retain the requested detail but the supplied C6 result is coarser, availability is UNAVAILABLE/COMPARISON_DETAIL_NOT_SUPPLIED. The query does not claim data was lost; a coordinator can supply a separately materialized captured C6 result. Coarser-than-materialized requests reject explicitly and must be produced through the existing C6 compare resolution interface. Invalid resolution names/types reject; explicit and implicit equal resolutions share cursor identity. Changed requests invalidate cursors. The query accepts only captured result/catalog inputs; it cannot consult an adapter, reconstruct fine values from fingerprints or replace historical data with current data. Snapshot inventory queries remain explicitly inventory-only; missing captured labels/ancestry and missing incident explanation inputs use their own qualified availability rather than fabricated detail. C7 exporter handoff and verification (PW-11.14/.16/.17) The public query schema is QUERY_SCHEMA_VERSION=1.0. Portable baseline tests/fixtures/query_schema_v1.json freezes all six page shapes, related selection/ analysis/text DTO fields, exact reason/metric/selection codes, scalar properties, flat table dtypes, cursor version and required uncertainty/identity qualifications. C5/C6/L1 context contracts remain authoritative for referenced metadata. Result properties supplement listed NamedTuple fields. Dict keys/tuple delivery order are not output row ordering contracts; published stable ID orders are authoritative. tests/fixtures/query_consumer_v1.json is an independently specified selected-output truth transcript. tests/unit/test_query_schema.py constructs validated captured observations/comparisons/checks, reopens a repeated registry and hands its consumer ONLY six bounded pages. The consumer resolves only selected text, preserves exact uint64 decimal strings, unknown timing, declared intent, partial graph failures, bounded support checks, potential-versus-observed impact and full-denominator metric metadata. It receives no adapter, inventory, C6 source arrays, graph index, ranking or registry to rescan. This is a consumer acceptance fixture, not the PW-12 JSON serializer implementation. IDs above JSON floating-point precision retain their exact decimal representation. PW-11.14 verification covers all 30 unequal source/target pairs across the six query families: a cursor from any other family rejects without restart. Each family resumes its own bound source. Existing selector/page suites cover malformed/noncanonical/ padded/overlong cursor tokens; changed source/context/content/order/filter/limit/ text/key/evidence/root/support bounds; duplicate names; incomplete discovery; missing ancestry; exact numeric/slash/empty names and independent catalog reopening. Selections never guess a first ambiguous row or silently substitute live labels. PW-11.16 verification checks owned immutable contiguous uint8/uint64 family tables, selected dictionaries and incident observation/event variants against the portable schema. Empty/unknown matching totals, page and evidence-prefix truncation, exact UTF-8 budgets and failures outside selected rows remain qualified independently. The 1501-node lineage, 1501-candidate incident and 1501-root impact cases establish bounded returned arrays/control prefixes, without claiming constant query-side allocation or measured native instruction coverage. Separate native/reference C4/C5 consumers verify persisted identities, missing reads, original statuses and requested historical detail availability. Capture failures remain in metadata even when a selected row is SAME. A renderer must show omitted/unknown scope rather than infer that an available page is complete or that an absent continuation proves full scope. Initial exporter capabilities are selected-family text/JSON, tabular CSV with its metadata policy and explicit-edge DOT. Format grammar/escaping, CLI configuration, exit codes and stdout/stderr separation remain PW-12 implementation. Adapters and entire captures belong to coordination/query producers, not serializers. Changes to published fields/codes/semantics require explicit schema/version compatibility review and a corresponding portable/reference-consumer update.