Engine-level feature flags surfaced through CAUSL_* env vars and createCausl({ experimentalFlags }).

Every field on this interface is a deliberate, audit-tracked opt-in that gates a measured engine behaviour. Fields are added here only when a consumer module ships that needs them; the bar mirrors the one defended on CreateCauslOptions: name the unavoidable concept the engine cannot express without the flag, or take the teaching cost of growing every README and every consumer's mental model.

interface CauslFlags {
    assertDeterministicCompute: boolean;
    freezeOffInProd: boolean;
}

Properties

assertDeterministicCompute: boolean

Enable the SPEC §15.1 NonDeterministicComputeError invariant gate (#750). When on, every derived compute(get) is re-invoked a second time against the same dependency snapshot; if the second call's result !Object.is the first, the engine throws a NonDeterministicComputeError naming the offending node.

Driven by env var CAUSL_ASSERT_DETERMINISTIC_COMPUTE. The flag is true iff the env value is exactly '1'; truthy-coercion vectors ('true', 'yes', …) leave the flag at false.

Default false because re-running every compute() doubles derivation work — the gate is useful only in dev / test / CI environments where the cost is acceptable as the price of a structural invariant check. Production runs leave the flag off and pay zero overhead.

The audit's adversarial-fanin scenario (#718) injects 0.1% Math.random() returns and asks the engine to detect them via a NonDeterministicComputeError thrown at commit time; this flag is the seam that gates the detection at construction time so adopters opt into the cost only when they want the guarantee.

freezeOffInProd: boolean

Skip engine-internal defensive freezes on inner arrays nested inside frozen Commit / Explanation payloads (#702). Public-surface Commit / Explanation objects stay frozen at the outer boundary unconditionally; this flag controls only the inner defensive Object.freeze calls on changedNodes and deps.

Driven by env var CAUSL_FREEZE_OFF_IN_PROD. The flag is true iff the env value is exactly '1'. Adopters who set it accept that the engine will not freeze the inner arrays — those values are still readable like any other JS value, but they are not runtime-immutable.

Audit verdict (#702): land as opt-in measurement only; flip the default only if the measured drop on scrolling-viewport × 10000 AND batch-commit × 10000 is ≥ 10%. Until then this stays a deliberate opt-in for adopters running with their own immutability discipline.