Projective gauge and strict decoding¶
The canonical equivalence is (P,Q) ~ (λP,λQ) for nonzero finite real λ.
canonical_l2_qpositive_v1 validates representation, promotes calculations to
float64, uses max-scaled L2 normalization, and chooses a deterministic global
orientation: Q is non-negative, with the first nonzero numerator as the Q=0
tie-breaker.
The all-zero tuple is not a valid pole; it is REPRESENTATION_FAULT. Non-finite
coordinates are execution faults. The dimensionless denominator score is the
absolute normalized denominator. Rejection thresholds apply to that score.
Array inputs are elementwise scalar pairs by default. A vector-valued
numerator with one shared denominator must pass coordinate_axis explicitly;
the selected axis is then normalized as one tuple, receives one orientation
witness, and requires the denominator to be identical across that axis. For
example, normalize_projective(P, Q, coordinate_axis=-1) is the canonical
multi-output-head boundary.
Schema-v3 ONNX export cannot preserve an eager Python equality assertion as a
runtime guard. A custom tuple model must therefore declare both
projective_coordinate_axis and
projective_denominator_contract="shared_denominator_by_construction_v1".
The latter is a reviewed capability assertion that every runtime input produces
one denominator by construction; export refuses an axis declaration without
it. Built-in shared-denominator rational heads carry this capability. The
exported graph still compares the denominator coordinates: disagreement becomes
REPRESENTATION_FAULT, rejects operationally, and records a task-domain-invalid
cause.
StrictDecodePolicy.coordinate_axis carries the same choice through typed
decoding and is included in policy serialization and hashing. Policy schema v1
is retained only as a read-only elementwise-pair identity; newly emitted
policies use schema v2. Shared-denominator projective models declare their axis,
and export refuses an explicitly mismatched policy.
The gauge is real-only. Python, NumPy, and Torch complex coordinates raise
TypeError before float64 promotion; no backend may discard an imaginary part.
Torch normalization replaces invalid coordinates before norm arithmetic, so
non-finite and all-zero cells contribute zero gradient rather than allowing an
inactive masked branch to inject NaN into shared parameters.
Every serialized gauge and decoder identity validates all algorithm-defining fields. A caller cannot relabel normalized-score execution as a raw-denominator threshold family or replace the global orientation rule under the same policy identifier.
canonical_denominator_v0.6 identifies legacy metadata only. Its raw
denominator thresholds are gauge-dependent and must be recalibrated before use
with the canonical gauge.
Strict decoding produces exact bottom only from proven exact-zero evidence.
An unproved machine zero is an ambiguous rejected NO_CORE result. Threshold
rejection preserves a finite decoded core whenever decoding itself is valid.