/** * hasselink/tiling/transition.ts * ------------------------------------------------------ * Transition-first encoding vocabulary. * * Normative intent: * - We avoid storing "absolute" visible bits directly. * - We store / interpret bits THROUGH a parity lens so that: * - unchanged logical values can still visibly invert each tick, * - while logical value remains stable when decoded with time parity. * * This matches the core Möbius constraint: * EvenData <-> OddCode * and the existing ParseCtx/Oracle parity model. */ import type { Bit, Xor, Not } from "../bit/bit.ts"; import type { TimeParity } from "../oracle.ts"; /** * A single-step parity bit derived from the Oracle time parity. * * Convention: * - EvenData => 0 * - OddCode => 1 */ export type ParityBit

= P extends "EvenData" ? 0 : 1; /** * Physical (stored/visible) bit as a function of logical bit and parity. * * Core rule: * visible = logical XOR parity * * Consequence: * - when parity flips each tick, every unchanged logical bit flips visibly, * producing "motion" without requiring a logical change. */ export type VisibleBit = Xor>; /** * Recover the logical bit given a visible bit and the time parity. */ export type LogicalBit = Xor>; /** * Logical delta across time (t-1 -> t): * 0 = no logical change * 1 = logical flip */ export type LogicalDelta = Xor; /** * Visible delta across time (t-1 -> t): * * Under parity encoding, visible delta includes BOTH: * - parity flip, and * - logical changes. * * This is why monitoring layers must distinguish: * - "logical delta" (semantic change), vs * - "visible delta" (display / substrate change). */ export type VisibleDelta = Xor; /** * Convenience: the expected visible bit at the next tick * IF the logical bit did NOT change. */ export type ExpectedVisibleIfUnchanged = Not;