PipeWhy Comparison Contract C6 version 1.0
October 30, 2026

PW-08.01 Comparison eligibility
A comparison context records snapshot ID, source namespace/version, configured scope,
full fingerprint context/algorithm ID, retained resolution and discovery completeness.
Source versions intentionally differ across history. Namespace and configured scope
must match before aligning numeric IDs. A namespace/scope mismatch returns a global
INCOMPARABLE result with no claimed row matches. No name or path heuristic bridges
different identity namespaces.

Within the same namespace/scope, align persistent IDs first. The initial content
profile requires the current C3 algorithm, a currently recognized strict/logical
normalization profile, equal algorithm/profile/schema identities and equal ordering
mode. Unknown algorithms and unrecognized profile identities are INCOMPARABLE,
even when their declared IDs match each other. No automatic normalization/schema conversion is
implemented. Incompatible content contexts make aligned rows INCOMPARABLE, including
one-sided presence rows; v1 deliberately keeps this eligibility rule conservative.
Ordered observations additionally require equal original start offsets; count/content
differences at the same offset can be CHANGED. Context compatibility is explicit.

Retained resolution ranks are dataset=1, record=2, value=3. Structural containers
have level=0. Dataset summaries remain comparable when one snapshot retained finer
detail. Finer historical selection requires both captures to retain that resolution;
otherwise drill-down returns UNAVAILABLE with a capture-limit reason. Never read
today's source to fabricate missing historical detail.
compare() defaults to dataset summaries and records its requested resolution
separately from each context's retained maximum. It excludes ordinary finer nodes
before hierarchy aggregation. Nodes whose level changes across that selection
boundary remain as explicit INCOMPARABLE evidence, so projection cannot hide them.

PW-08.02 State truth table and evidence
Stable row status codes are SAME=0, CHANGED=1, ADDED=2, REMOVED=3, UNKNOWN=4,
INCOMPARABLE=5. Rows retain a primary reason code plus independent evidence flags.
After namespace/scope checks, content incompatibility takes precedence. Otherwise:

Both present, level differs: INCOMPARABLE (level/schema meaning changed).
Both present, parent differs: CHANGED (observed containment change), retaining any
read uncertainty separately. This reports a structural fact, not observed corruption.
Both present, either read failed/missing/incomplete: UNKNOWN with explicit reason.
Both present, fully captured compatible states equal: SAME under C3 limitations.
Both present, fully captured compatible states differ: CHANGED.
Only after present, both discovery inventories complete: ADDED.
Only before present, both discovery inventories complete: REMOVED.
Only one present, either discovery inventory incomplete: UNKNOWN.
One-sided nodes finer than the other capture retained: UNKNOWN, never an inferred
ADDED/REMOVED merely because the older capture omitted that resolution.
Unseen artifacts never become REMOVED because of read/discovery failure. Absence
means absence from the configured scope, not proof of physical deletion everywhere.
Source capture failure strings are retained in the comparison context. They prevent
an overall SAME scope even if every represented direct row is equal; unresolved
failed or omitted observations remain explicit rather than disappearing.

Structural containers have no direct fingerprint observation. With complete scoped
discovery their own unchanged structural baseline can be derived from children.
Hierarchy aggregation preserves own ADDED/REMOVED facts. Otherwise any known own or
child change yields CHANGED; absent known change, INCOMPARABLE evidence dominates
UNKNOWN, which dominates SAME. Direct missing observations on data nodes remain
UNKNOWN even if children are equal. Containers with complete empty inventories can
be SAME. Incomplete discovery prevents an unsupported empty-container SAME.
Independent subtree flags retain change, unknown and incomparable evidence even
when one primary parent status takes precedence. No parent SAME masks uncertain
children. Derived parent changes are distinguished from direct observations.

PW-08.03 Persistent identity, input layout and hierarchy
IDs are stable non-sentinel uint64 keys within the recorded source namespace.
They are not row positions, snapshot-local name IDs or hashes inferred from labels.
The producer assigns stable unique keys to logical nodes at each retained level;
record/value identities must not collide with dataset IDs. Artifact display labels
are presentation metadata: a renamed label with the same stable ID does not create
an ADDED/REMOVED pair or change encoded content by itself.

An ArtifactObservations input borrows exact flat C6 columns:
artifact_id Q, parent_id Q, level B, observation_id Q, observed_at_ns Q,
observation_status B, read_complete B, fingerprint_offset Q, fingerprint_length Q;
auxiliary fingerprint_words Q. All row columns have equal length. Q denotes uint64,
B uint8. Inputs are one-dimensional contiguous native little-endian integer buffers
following C1 lifetime rules; callers finish writes and keep aliases stable during use.
No per-node Python graph or inferred object relationship is retained.

Observation codes match C1: UNKNOWN=0, CAPTURED=1, ERROR=2. read_complete is 0/1;
noncaptured rows cannot claim a complete read. Captured rows require a non-null
observation ID and nonempty bounded fingerprint slice. ERROR rows retain a real
observation ID; no-observation rows use NULL_ID and timestamp zero. Non-null
observation IDs are unique within the input. Level-0 containers have no direct
observation. Nodes cannot exceed the context's retained level. Known C3 states are
validated through FingerprintState.from_words; unknown algorithms remain opaque.

Input artifact IDs and observed containment links are acyclic; parent IDs outside
the selected inventory are explicit scope boundaries, not invented rows. Alignment
sorts index vectors and merges persistent IDs; original row order/labels are intact.
Results are sorted by persistent ID, with before/after row indices or NULL_ID.
The presentation forest uses after-parents for present-after nodes, retaining an
edge only if its parent is present after. Removed nodes use their before-parent
when present before. This avoids inventing a cycle from valid different historical
trees. Raw before/after parent IDs remain evidence, including scope boundaries.

Result rows use flat owned read-only columns: artifact_id Q, parent_id Q,
before_parent_id Q, after_parent_id Q, before_index Q, after_index Q,
before_observation_id Q, after_observation_id Q, before_observed_at_ns Q,
after_observed_at_ns Q, level B, status B, reason B, flags Q.
Snapshot/source/context references and discovery/retention limits accompany the
arrays. Missing observation IDs and indices use NULL_ID; timestamp zero is unknown
only when its observation ID is null. Exact stable values are published below and
in tests/fixtures/comparison_schema_v1.json for query/analysis consumer validation.

Discovery completeness covers the configured node inventory through the retained
resolution. Partial inventories retain observed row facts but cannot prove absence.
Drill-down filters only retained nodes in this forest at a requested finer level.
Complete empty inventories can yield an available empty selection. An unseen finer
selection under incomplete discovery is UNAVAILABLE, not an alleged empty result.
Retrievable but incompatible rows keep INCOMPARABLE; retrieval does not convert them.

PW-08.04 Schema and structural changes
Adding/removing/retyping selected fields, changing source widths/exclusions or
changing declared source-schema semantics requires a new schema identity and makes
content INCOMPARABLE. No field is silently dropped, widened or converted. A field
rename retains schema identity only under an explicit source policy declaring the
name cosmetic; otherwise record a new schema identity. This does not override the
user's strict typed-value normalization default.

Stable IDs survive reordering and cosmetic artifact-label renames. Containment moves
are reported as structural changes; node-level changes remain incomparable. Before/
after observation IDs/times and snapshot references support later evidence analysis.
SAME remains probabilistic fingerprint evidence under C3, not a security guarantee,
physical corruption diagnosis or permission to ignore incomplete source coverage.

PW-08.16 Published result schema and consumer handoff
Result schema_version is "1.0". Status values are listed in PW-08.02.
Reason codes (uint8):
  0 NONE                         1 VALUE_CHANGED
  2 PRESENCE_ADDED                3 PRESENCE_REMOVED
  4 DISCOVERY_INCOMPLETE          5 NOT_CAPTURED
  6 READ_ERROR                    7 PARTIAL_READ
  8 NAMESPACE_MISMATCH             9 SCOPE_MISMATCH
 10 ALGORITHM_UNSUPPORTED        11 PROFILE_MISMATCH
 12 SCHEMA_MISMATCH              13 MODE_MISMATCH
 14 ORDERED_OFFSET_MISMATCH      15 PARENT_CHANGED
 16 LEVEL_CHANGED               17 CHILD_CHANGED
 18 CHILD_UNKNOWN               19 CHILD_INCOMPARABLE
 20 RESOLUTION_UNAVAILABLE       21 CONTAINER_SAME
 22 SELECTION_UNAVAILABLE        23 PROFILE_UNSUPPORTED
 24 CAPTURE_INCOMPLETE
Flags use uint64 bit masks; the following are bit POSITIONS, not mask values:
  0 BEFORE_PRESENT                1 AFTER_PRESENT
  2 BEFORE_DISCOVERY_COMPLETE     3 AFTER_DISCOVERY_COMPLETE
  4 BEFORE_CAPTURED               5 AFTER_CAPTURED
  6 BEFORE_READ_COMPLETE          7 AFTER_READ_COMPLETE
  8 PARENT_CHANGED                9 LEVEL_CHANGED
 10 SUBTREE_UNKNOWN              11 SUBTREE_INCOMPARABLE
 12 SUBTREE_CHANGED              13 BEFORE_PARENT_OUTSIDE_SCOPE
 14 AFTER_PARENT_OUTSIDE_SCOPE
Consumers decode flags with bitwise AND; known change does not erase uncertainty.
No child capture flag implies that its parent was directly captured. The one primary
reason explains the selected row status; independent flags/context retain other facts.
Overall status summarizes the selected scope and need not equal every row's status.

Public API: pipewhy.compare exports ArtifactObservations, ComparisonContext,
Status, Reason, Flags, compare, Availability and drill_down. Construct input views
from the exact PW-08.03 columns and matching contexts. ComparisonContext.from_metadata
accepts C5 metadata plus an explicit discovery_complete boolean; read completeness
cannot substitute for discovery evidence. Generic C5 arrays have no inferred C6 role:
producers must store/reload C6 column names, inventory completeness and metadata
together and validate with ArtifactObservations. No live source reads occur here.
compare(before, after, resolution="dataset") returns ComparisonResult with both
contexts, overall status/reason, immutable columns and requested resolution.
drill_down(before, after, artifact_id, resolution=...) returns DrillResult with both
contexts, selected ID, resolution, availability/reason and a comparison or None.
AVAILABLE means retained detail can be selected; its comparison may still be UNKNOWN
or INCOMPARABLE. UNAVAILABLE always has comparison=None. Complete known empty detail
can be AVAILABLE with no rows. Invalid inputs/resolutions raise explicit errors.

Query/analysis consumer requirements: join on stable artifact_id within the recorded
namespace/scope, preserve both snapshot IDs and observation links/times, expose
uncertainty flags, distinguish direct and child-derived reasons, and keep retained
maximum separate from requested resolution. In JSON use decimal strings for uint64
IDs/indices/timestamps/flags so browser number rounding cannot corrupt evidence.
Do not infer causation, physical deletion or downstream corruption from C6 alone.
Unknown future schema/status/reason semantics must fail closed at a consumer boundary.

Qualification: 31 hand-authored truth-table cases and an independent numeric schema
fixture constrain implementation and consumer projections. Separate integration
tests carry C4 normalized values through C3, published/reopened C5 and C6 at two
batch sizes for baseline/mutation/missing versions. These are reference consumer
acceptance evidence; no independent human signoff or production collision approval
is claimed. Native CPU/CUDA, query CLI and lineage analysis remain later work orders.
