Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

ox build is fail-closed

A built artifact evaluates every rule it contains, or it does not exist. ox build runs three gates in order; any gate that fails aborts the build and writes no .oxbin. A wrong artifact is worse than no artifact.

  1. Parse gate. Elaboration is error-tolerant — it recovers from malformed input by dropping the broken construct. Left unchecked, a parse error would silently produce an .oxbin missing whatever the parser choked on. So ox build first collects every error-severity parse diagnostic; if any exist, it prints them and exits 1 before resolution runs (oxc-driver/src/lib.rs:759).

  2. Resolution and type gate. It then runs the full resolve/typecheck pass (collect_check_diagnostics). Any error-severity diagnostic — an unresolved predicate, a type error — aborts the build with no artifact.

  3. Un-evaluable-rule oracle gate. The lowering pipeline admits some rule shapes the runtime’s rule compiler then refuses. Such a rule is silently dropped from evaluation, so an artifact containing one returns wrong (under-derived) query answers with no runtime error. To prevent that, ox build loads the elaborated artifact and re-runs the runtime’s own compile_rule as an oracle over every rule (Module::uncompilable_rules). If any rule will not evaluate, the build fails loudly and writes nothing. ox check enforces the same oracle through the driver’s internal validate_runtime_evaluable_rules path, so editor/CI validation cannot green-light a package that ox build later rejects. This intentionally makes ox check do the extra work needed for artifact-parity validation: package elaboration, stdlib loading, comptime lifting, event encoding, and Module::load. Refused shapes:

    ShapeDiagnostic
    Unsafe rule — a head / negated / comparison / compute variable not bound by a positive body atom (range-restriction)OE1303
    Nested aggregate (count { count { … } > N })OE1311
    Collection/string aggregate kind (collect/set_collect/string_join/percentile); the folding kinds count/sum/min/max/avg/count_distinct evaluateOE1312
    not wrapping an aggregate subqueryOE1313
    Empty aggregate body (count { })OE1314
    Unsupported quantifier shape (exists binder, forall(path, T), under-specified forall)OE1315

    Rule bodies the semi-naive executor does not compile — a type-test atom or a meta-equality (== on meta(x)) — are recorded the same way and surface as the same load-time refusal (oxc-runtime/src/lib.rs:299).

    The oracle reports executor-capability failures. A hard Module::load failure surfaces through normal artifact load/build diagnostics.

    The fix is always to rephrase the rule into a supported shape — typically by exposing the offending subterm through an intermediate pub derive rule. The supported universal forall v: T where Body, Head (the last where atom is the consequent, the rest the domain) does evaluate; it lowers to a count-equality.