JACKAL is a deterministic, offline mathematical evidence kernel — an epistemic claim
compiler for Hermes and machine consumers that is also a full STEM calculator. Its one
unusual property: every answer tells you what kind of answer it is — exact, bounded
(a conditional interval enclosure), formal-bounded (a proved-checker-accepted enclosure),
checked, estimated, or model-based — and what it would take to trust it. When JACKAL
cannot stand behind a number, it refuses with a named reason instead of printing something
plausible.
New here? Start with GETTING-STARTED.md — install (released binary for Apple Silicon macOS, or build from source with an Anubis compiler), first commands, and how to read the trust labels. License: MIT.
JACKAL is written in Anubis Safe mode. It does not try to win by adding another wall of buttons. It treats a serious calculation as a bounded scientific claim: value, units, uncertainty, method, assumptions, sensitivity, residual, non-claims, and a reproducible fingerprint where applicable.
Every product model, formula, validation rule, unit policy, algorithm, formatter, command route,
claim-card generator and executable invariant is in jackal_calc.anb. Python is only an external
black-box launcher used to compare observed stdout.
See RESEARCH.md for the primary-source comparison against TI-Nspire CX II CAS,
Qalculate!, Soulver and SpeedCrunch. JACKAL does not claim parity with a general CAS,
arbitrary-precision-float engine, or interactive graphing system. Its differentiated implemented
surface is claim-aware and measurement-aware computation.
Language models are demonstrably unreliable at the arithmetic layer. OpenAI's own GSM8K repository states that "our models frequently fail to accurately perform calculations" and mitigated it by training models to call a calculator (GSM8K README; Cobbe et al. 2021). The failure is structural, not incidental: transformers solve multi-digit arithmetic by pattern-matching rather than systematic computation (Dziri et al. 2023). The winning paradigm is delegation — offloading computation to a deterministic runtime beat chain-of-thought by 15 absolute points on GSM8K (PAL, Gao et al. 2022); models can teach themselves to call calculator APIs (Toolformer, Schick et al. 2023); and structured tool use is now a first-class production interface (Anthropic tool-use docs).
So the calculator an AI needs is not more buttons. It is the properties JACKAL implements:
- Determinism — identical input, byte-identical output; claim cards carry SHA-256 fingerprints.
- Exactness flags —
ratandbig-*results are exact;approx=is labeled IEEE f64; the single most common downstream error is a model treating a truncated decimal as exact. - A five-tier assurance ladder for numerical integration —
integrateprints a Richardson estimate taggedassurance=estimate-not-bound(grid-limited)(heuristic; a feature narrower than the grid can evade both grids — verified: a width~0.0007 Gaussian peak on a 100-panel grid underestimated its own error ~256×);integrate-adaptiveprints a local estimate with refusal semantics (it refuses rather than print unearned confidence, but agreement is still not a bound);integrate-boundprints a conditional enclosure under the stated f64/libm model;jackal-gaussian-releaseadds a distinct zero-libm formal enclosure for checker-accepted canonicalexp(-A*(x-mu)^2)requests and refuses every unsupported formal request without downgrade (see "Formal Gaussian integration" below); andjackal-int-cert-release(v1.7.2) emits a Lean-checked composed enclosure over the certified fragment — the compiled proved checker binds the exact raw expression/bounds/tolerance, re-checks the entire subdivision tree (theoremint_cert_sound), and refuses every v1.7.0 request-unbound receipt whileintegrate-bounditself stays conditional/bounded. Bisection ships residuals; symbolic derivatives ship their own numeric verification line. Only therat/big-*lanes are exact. - Machine-readable epistemic classes — metadata-bearing lanes print
status=as the first field:exact(rat),bounded(integrate-bound),formal-bounded(proved range/Gaussian release wrappers, and the certified composed-integral laneintegrate-bound-certviajackal-int-cert-release— proved composed enclosure, theoremint_cert_sound),checked(diff),estimated(integrate, integrate-adaptive, derivative, solve, integrate-x2, derivative-x3),model-based(claim-card).jackal maturityprints the full graded command inventory — every lane's class, oracle, evidence, and known residual — so strong evidence in one lane cannot silently inflate trust in another. - Echoed parse —
ratechoesparsed=,diffechoesd/dx[input]: the dominant failure at the model-tool boundary is transcription, not computation, and the echo lets the caller confirm the engine evaluated the expression it intended. - Fail-closed typed errors — no silent NaN, no wraparound, no clamping; every domain violation is a named refusal on stderr with nonzero exit.
git clone https://github.com/AnubisQuantumCipher/jackal.git
cd jackal
./jackal help
./jackal self-testThe ./jackal launcher prefers a prebuilt native artifact (jackal-native) and otherwise
runs the Anubis source through a compiler it resolves in this order:
$ANUBIS_BIN— an explicit path you set;- the pinned compiler at
$HOME/anubis-lang/vm/pins/anubis-a733565f237d, if present; - an
anubisexecutable on yourPATH.
If none is found it prints exactly how to fix it and exits non-zero — it never fails silently or
misleadingly. jackal-native is not committed (it is a build artifact; its SHA-256 is
sealed in PROVENANCE.md); obtain it from the public GitHub release
(Apple Silicon macOS), verify the release checksums and pinned identities, or build from
source (see below and GETTING-STARTED.md).
Formal-release paths (v1.5.0). jackal-cert-release "<expr in x>" <lo> <hi> [formal-receipt.json]
emits status=formal-bounded only when the shared
release validator (tests/release_validate.py)
confirms the whole bound chain: the exact request commitment, the exact jackal-native
evaluator identity, the pinned executables, and the proved checker's ACCEPT, TOCTOU stability,
and no status escalation. Any break refuses with a stable class, never a bounded fallback.
The bundled plugin/hermes adapter exposes the same release and verification
path. See NON-CLAIMS.txt for the exact scope. Formal-status soundness (an
accepted certificate implies a true enclosure) is Lean-proved; runtime
provenance (request/evaluator identity) is validator-enforced, not theorem-proved. See
PROVENANCE.md "Seal v1.5.0" for the receipts and preserved predecessor scars.
The zero-libm transcendental fragment (v1.5.0). Seven standalone release
wrappers emit pure-ℚ, Lean-checker-verified enclosures with no libm on the
proof-decision path; every producer is untrusted and every claim is
re-validated by the compiled proved checker jackal_cert_check:
| Wrapper | Admits | Domain | Strategy (all exact ℚ) |
|---|---|---|---|
jackal-sqrt-rat-release "sqrt(x)" lo hi |
sqrt(x) |
lo ≥ 0 |
Newton square bracket (v1.4.0) |
jackal-exp-rat-release "exp(x)" lo hi |
exp(x) |
all rationals (general-sign since v1.5.0) | Taylor partial + certified remainder; exact reciprocal for negatives |
jackal-ln-rat-release "ln(x)" lo hi |
ln(x) |
lo > 0 |
inverse exponential bracket (exp(out_lo) ≤ lo, hi ≤ exp(out_hi), decided in ℚ) |
jackal-sin-rat-release "sin(x)" lo hi |
sin(x) |
midpoint within [-1,1] |
Mathlib sin_bound midpoint Taylor + Lipschitz-1 widening |
jackal-cos-rat-release "cos(x)" lo hi |
cos(x) |
midpoint within [-1,1] |
Mathlib cos_bound midpoint Taylor + Lipschitz-1 widening |
jackal-atan-rat-release "atan(x)" lo hi |
atan(x) |
all rationals | cap / tan-bracket / reciprocal strategies over 20-digit rational π bounds |
jackal-tanh-rat-release "1-2/(exp(2*x)+1)" lo hi |
the tanh-defining composite | ` | x |
tanh is not an engine grammar token: the wrapper admits the explicit
composite expression 1-2/(exp(2*x)+1) (mathematically equal to tanh(x)),
the receipt binds that expression string, and the tanh reading is a
documented identity — never a checker claim. Requests spelled tanh(x)
fail closed at parse in every lane. Every unsupported expression refuses
without downgrade. Documented enclosure-width residuals (soundness is never
affected): sin/cos point enclosures carry the fixed-degree Mathlib remainders
(|m|⁵/100, |m|⁴·5/96), and tan-bracketed atan endpoints near |x| = 1
are certified to ~5·10⁻²; ln/exp/sqrt/tanh brackets are tight (~10⁻⁹ or
better at defaults). Arguments outside a fragment's stated domain refuse
with a named reason — sin/cos beyond |midpoint| ≤ 1 (2πk argument
reduction is future work), ln at lo ≤ 0, tanh beyond |x| ≤ 20.
The separate jackal-gaussian-release "exp(-A*(x-mu)^2)" <lo> <hi> <tolerance> <formal-receipt.json>
path admits only canonical nonnegative rational tokens, a checker-verified positive rational
scale with scale^2=A, and a transformed interval containing [-6,6]. Its untrusted producer
emits exact-rational witness bytes; jackal_gaussian_check parses and recomputes them. The Lean
theorem gaussian_integral_check_sound proves that checker acceptance binds the source tokens and
encloses the requested real integral. It uses Mathlib's Gaussian-integral and pi-bound theorems,
a proved exp(-36) tail bound, and no platform exp/libm result. Unsupported formal integration
requests refuse with no fallback to integrate-bound.
Formal receipt + Hermes plugin. When the optional fourth path is supplied,
the wrapper emits a canonical jackal-formal-receipt-v1 JSON receipt with
the certificate embedded (base64) and every field a downstream reverifier
needs: exact canonical request (including integration tolerance), exact enclosure,
producer/evaluator/checker/plugin identities, matching theorem id (cert_check_sound or
gaussian_integral_check_sound), Lean kernel axiom list, admitted
operator set, coverage-row ids, assumptions, non-claims, and an outer
receipt_digest_sha256. The independent verifier tools/receipt_verify.py
re-hydrates the embedded certificate and re-runs the matching pinned Lean-proved
checker on this machine — recomputing the outer digest alone is not
sufficient. The Hermes/MCP-style plugin (plugin/hermes/jackal_hermes) threads every
call through the same shared validator, the same formal-status gate, the same
pinned executables, and additionally bind the plugin's OWN bundle hash into the
receipt via identities.plugin_sha256. The Hermes plugin exposes thirty-eight
tools — eleven formal (jackal_range_bound, jackal_gaussian_integral,
jackal_integrate_bound_cert,
jackal_sqrt_rat_bound, jackal_exp_rat_bound, jackal_ln_rat_bound,
jackal_sin_rat_bound, jackal_cos_rat_bound, jackal_atan_rat_bound,
jackal_tanh_rat_bound, jackal_verify_receipt), twenty-one weaker-lane
adapters (the seven numeric lanes jackal_exact, jackal_evaluate,
jackal_diff, jackal_integrate, jackal_integrate_adaptive,
jackal_integrate_bound, jackal_solve, and fourteen exact-CAS lanes from
jackal_canon through jackal_prime_cert) that thread through the pinned
evaluator with identity checks and return the engine's honest inventory-derived
epistemic class (exact/checked/estimated/bounded/model-based) with
formal: false — status inflation is structurally impossible — the two
v1.6.0 claim-kernel front doors (jackal_claim, jackal_verify_bundle; see
"The claim-bundle evidence kernel" below), and four domain-pack lanes
(jackal_test_exists, jackal_claim_cites_test, jackal_decision_rank,
jackal_decision_rank_v2) that carry the same refusal discipline outside
mathematics: assurance ceiling exact, consequence ceiling capped at
informational or decision-boundary, routed through
pack-route <pack_id> <operation_id> <args...>, and each re-running its
manifest-pinned independent checker over the emitted certificate so only an
ACCEPT verdict returns success. A test-exists-cert is an exact statement
about bytes and never evidence that the code under test is correct.
The eleven-category A→B→A mutation harness (tests/cert_mutations_11.py)
plus the receipt-semantic mutation harness (tests/receipt_semantic_mutations.py,
42/42 including the two §487 audit locks for U+2028 parser-differential
injection and const_rounded release-fragment admission, and the §490
v1.5.0 variant locks incl. the ln_rat→ln TCB-op smuggle) prove that every
trust-boundary gate — request/AST/enclosure/certificate/limits/formal-status/
checker/evaluator/outer-digest/stale-success/plugin-bundle — is load-bearing:
the mutation harness disables one governing gate (still-compiling), the poison
is admitted only under that disablement, and the exact pre-mutation bytes are
restored hash-verified before A(post). See release/evidence/ for the durable
transcripts (positive_corpus.jsonl, negative_controls.jsonl,
plugin_smoke.jsonl, mutations_11.json, receipt_semantic_mutations.json,
fail_closed_sweep.jsonl, gaussian_formal_v150.json (v1.3.0 record preserved), and aba_mutations.json).
JACKAL is written in the Anubis language, so building or running it from a clean checkout requires the Anubis compiler. There is no way around this: the engine is Anubis source.
1. Get an Anubis compiler. Use the pinned build the committed engine was verified against
(anubis-a733565f237d; SHA-256 in PROVENANCE.md), or any Anubis toolchain that accepts
anubis run <file> --out <dir> -- <args>. The Anubis compiler is not yet publicly
distributed — without one, use the released jackal-native binary instead; the engine source
it was built from is this repo's jackal_calc.anb, and the build chain is sealed in
PROVENANCE.md.
2. Point JACKAL at it — either put anubis on your PATH, place the pin at
$HOME/anubis-lang/vm/pins/anubis-a733565f237d, or set ANUBIS_BIN explicitly:
export ANUBIS_BIN=/path/to/anubis
./jackal self-test # first run compiles the engine, then runs it
./jackal eval "sqrt(2)*exp(sin(pi/7))"3. (Optional) produce a standalone native binary. The first source run compiles a native
executable under the Anubis out-dir; copy it to jackal-native so later invocations skip the
compiler entirely:
ANUBIS_BIN=/path/to/anubis JACKAL_FORCE_SOURCE=1 JACKAL_OUT=./.build ./jackal self-test
cp ./.build/anubis_run ./jackal-native && chmod +x ./jackal-native
./jackal self-test # now uses the native artifact, no Anubis neededReproducibility — verified, byte for byte. With the pinned compiler
anubis-a733565f237d, clean builds of the committed source are fully byte-identical —
same SHA-256 every time, linker UUID included (verified across repeated builds and differing
out-dir paths, including one containing spaces). Anyone holding the pin can rebuild
jackal-native and compare hashes against PROVENANCE.md. The
nondeterminism in earlier pins (a randomized per-build package name feeding the crate-metadata
hash) was root-caused and fixed upstream on 2026-08-13; the diagnosis trail, including the
byte-deterministic transpile stage and tests/content_hash.py for segment-level comparison,
is preserved in PROVENANCE.md. JACKAL_FORCE_SOURCE=1 always bypasses any prebuilt binary
and runs through the compiler; JACKAL_OUT overrides the scratch out-dir (default:
$TMPDIR/jackal-calc-run).
./jackal claim-card projectile 20 45 9.80665The Anubis program emits:
- canonical model identity;
- typed inputs and units;
- explicit assumptions;
- observed outputs;
- dimensionless sensitivity elasticities;
- explicit non-claims;
- SHA-256 fingerprint of canonical model inputs and results.
This does not magically prove the physical model. It makes the model boundary inspectable and the exact calculation reproducible.
JACKAL evaluates arbitrary arithmetic expressions with an explicit, documented grammar — tokenizer, recursive-descent parser, and evaluator all written in Anubis:
./jackal eval "2+3*sin(pi/6)^2"
./jackal integrate "sin(x)" 0 3.141592653589793 200 # general Simpson + Richardson error estimate
./jackal integrate-bound "sin(x)" 0 3.141592653589793 1e-9 # certified interval enclosure
./jackal-int-cert-release "sin(x)" 0 1 1/100 receipt.json # Lean-checked composed integral enclosure (theorem int_cert_sound)
./jackal derivative "x^3" 2 0.001 # central difference + Richardson probe
./jackal solve "x^2-2" 1 2 # bisection + residual + first-order root-error estimateGrammar: + - * / %, ^ (power, right-associative), unary minus (binds looser than ^,
so -3^2 = -9, the calculator convention), parentheses, function calls, and comma-separated
arguments. Functions: sin cos tan asin acos atan sqrt cbrt ln log10 log2 exp abs floor ceil round trunc (one argument) and hypot pow atan2 min max (two). Constants: pi e tau c g0 h na kb r. The variable x is bound only inside integrate/derivative/solve.
The 2026-08-13 adversarial campaign (1,402 cases against a frozen artifact) proved the
distinction that now defines this engine: JACKAL's Richardson estimates were superbly
calibrated (median actual-error/estimate ratio 0.99981 across 120 independently solved
oscillatory integrals) — and still not bounds, because a fixed grid cannot certify what it
never sampled. integrate-bound closes that gap with mathematics instead of sampling:
./jackal integrate-bound "exp(0-1000000*(x-0.1225)^2)" 0 1 1e-9
# status=bounded integral-enclosure=[0.0017724538498025575,0.0017724538524225815] ...
# — the same narrow off-grid Gaussian that silently beat fixed-grid Simpson by 256×
# now carries a certified enclosure containing the true sqrt(pi)/1000·erf-term value
./jackal range-bound "sin(x)" 0 6.4
# status=bounded range-enclosure=[-1.000000000000001,1.000000000000001]
# assurance=certified-superset-of-range(outward-rounded-f64;libm<=2ulp-model;implementation-tested-not-mechanized)How it works, and exactly what it claims:
- Every expression is evaluated in outward-rounded interval arithmetic over the AST:
each operation's result interval is padded outward by 1e-15 relative + 1e-300 absolute
(~4.5 ulp) — strictly more than the worst-case rounding of the operation that produced it.
sin/cosranges detect interior extrema with slack-widened critical-point tests (doubt can only widen the enclosure) and clamp to [-1,1];tanrefuses any interval that may contain a pole; division refuses any denominator interval containing zero. - The integrator adaptively bisects; each accepted subinterval contributes a proven piece via
the sharpest valid form: Taylor-4 midpoint
h·F(m) + h³/24·F″(m) + h⁵/1920·F⁗([a,b])when the symbolic chain f…f⁗ interval-evaluates over the closed subinterval (which certifies C⁴ there — the derivative formulas come from the samederiv()that powersdiff, simplified by a sound simplifier that never applies a where-defined convention), degrading to Taylor-2, then to the always-valid pure range formh·F([a,b]). All successful forms are enclosures, so they are intersected. - Refusal is the answer whenever certification fails: budget (60000 subintervals), depth
(60 levels), f64 resolution, domain hazards (
1/xthrough zero,lntouching 0,tanpoles), unknown identifiers, or a final width above the requested tolerance. The refusal names the reason. - The residual trust assumptions are stated, not hidden: IEEE-754 correctly-rounded basic
ops; math-library calls within 2 ulp (including argument reduction); and the
implementation itself is tested, not mechanized — a seeded containment campaign
(
tests/bound_campaign.py) checks every printed enclosure against an independent symbolic-antiderivative oracle, and a differential gate (tests/iv_differential.py) checks every range enclosure against 40-digit point sampling and mpmath's independent interval arithmetic. The only fatal verdict in either is a bound that excludes the truth. - The model is machine-checked — universally quantified, conditionally stated.
proofs/lean/is a Lean 4 + Mathlib development (20 modules, ~6,200 lines, 170+ theorems, zerosorry, flagship theorems axiom-audited to Lean's standard three) proving, over the stated rounding model: the pad-beats-rounding core; containment of every arithmetic interval op (add/sub/neg/mul/div, integer and negative powers, general powers on positive bases); the monotone-endpoint rule with exp/sqrt/log/arctan/arcsin/arccos instances; the exact ops (abs/min/max/floor-family/hypot/atan2); sin/cos range soundness across all widening branches; conservativity of the float critical-point test on the engine's parameter range (a maybe can only widen, never miss); bisection bracket soundness and the backward-error bound behindsolve's conditioning diagnostics; the float-midpoint containment chain; the Taylor-2/Taylor-4 midpoint enclosures (h³/24andh⁵/1920are theorems, not constants); a deep-embedded composition theorem (runs_encloses: every execution of the modeled evaluator core over every interval yields a true enclosure — all-quantifiers, no sampling, now with ~30 operators wired in); the evaluability-certifies-smoothness chain; and — implementation-correspondence bridge #1 — a mechanized parser and lowerer on one canonical syntax:parsemirrors the engine's recursive-descent grammar (determinism + structural rejection lemmas),lowermirrors the certified-lane simplifier with a provedlower_preserves_sem(lowering never changes the real semantics on the defined domain), andparse_lower_denotes/parse_lower_enclosescompose them so the admitted source string — not just an abstract tree — is what the theorem covers. Implementation-correspondence bridge #2: the engine'srange-bound-certcommand performs exact-rational interval evaluation and emits a canonical evaluation certificate; the compiled Lean checkerjackal_cert_check— built directly from the provedcheckCert, no@[implemented_by]on the trust path — verifies it, and the theoremcert_check_soundproves that acceptance mechanically induces aRunsderivation, hence a true enclosure under the namedModelTCB. The fail-closedjackal-cert-releasegate emitsstatus=boundedonly when the checker accepts, so an error in the actual evaluator causes refusal, never an unsupported certified release — verified by a positive corpus, 30 negative controls (each failing for its intended semantic reason,tests/cert_controls.py), and an A→B→A tamper where a deliberately non-enclosing emitter is rejected then restored by hash (tests/cert_tamper.sh). The certified release fragment is the exact-ℚ operators +sin/cos+ the six pure-ℚ checker strategies —sqrt(v1.4.0,sqrt_rat: Newton square bracket),exp(v1.4.1,exp_rat; general-sign since v1.5.0 §490 via the exact reciprocal identity),ln(v1.5.0,ln_rat: inverse exponential bracket), tightsin/cos(v1.5.0,sin_rat/cos_rat: Mathlib midpoint Taylor + Lipschitz-1, |midpoint| ≤ 1), andatan(v1.5.0,atan_rat: cap / tan-bracket / reciprocal over 20-digit rational π bounds) — all with NO libm TCB; the remaining true-transcendentals (tan/cbrt/asin/acos/log10/log2/…) AND named constants (pi/e/tau) fail closed (const excluded 2026-08-15, §487-const audit — their value is bound only by the undischargedConstTCBpremise, not ℚ-decidable). What is not proven is enumerated inproofs/lean/JackalIv/Ledger.lean: libm meeting its 2-ulp model; the still-fail-closed operators; the bigint/rational lanes (checked in-language by the Anubis SMT checker, outside this Lean scope); that the Anubis emitter faithfully produces its certificate (tested, not proven);bound_steprelease composition — now mechanized for the request-bound certificate lane (v1.7.2: theoremint_cert_sound, re-checked by the compiledjackal_int_cert_checkagainst the exact caller expression/bounds/tolerance on everyjackal-int-cert-releasereceipt; the request-unbound v1.7.0 epoch is revoked); and the one remaining bridge, source→native refinement, which remains open and unclaimed. The engine's printedimplementation-tested-not-mechanizedresidual therefore stays, accurately: the model is proven for all inputs,range-bound-certresults carry a proof-checked witness, and the broader implementation is campaign-tested and differential-gated against the model.
integrate-bound is deliberately the slowest lane — certification costs evaluations. For a
fast heuristic with refusal semantics use integrate-adaptive; for raw speed use integrate
and treat the estimate as an estimate.
diff parses the expression to an AST, differentiates symbolically, simplifies conservatively,
and then refuses to print a derivative that fails its own numeric check: the result is
compared against a central difference (h = 1e-5, the optimal cube-root-of-epsilon scale for
f64) at sample points, skipping points outside the domain. Sampled agreement is a check, not a
proof of identity — the output says so (assurance=numeric-sample-check(not-proof-of-identity)).
./jackal diff "x^2*sin(x)"
# d/dx[x^2*sin(x)] = 2*x*sin(x)+x^2*cos(x)
# status=checked check=numeric points=9 max-rel-dev=0.00000000005999646518118516 tolerance=0.0001 assurance=numeric-sample-check(not-proof-of-identity)
./jackal diff "x^x"
# d/dx[x^x] = x^x*(ln(x)+1)The verifier validates its own instrument before it is allowed to veto: a sample point where
the h and h/2 central differences disagree beyond 1% of scale is a broken probe, not
evidence against the derivative — it is skipped and disclosed
(skipped-unstable-probe=N). The skip criterion never reads the symbolic candidate, so it
cannot launder a wrong rule through; wrong rules are still refused at every point where the
probe converges, and fewer than 3 usable points refuses outright. (Field-adjudicated
2026-08-13: a nested-tan composition was refused by the old verifier solely because
pole-adjacent probes diverged — tan(tan(x)) now releases, and is sympy-cross-checked in the
suite.)
Rules cover + - * / ^ (constant and general exponents via ln), sin cos tan asin acos atan sqrt cbrt ln log10 log2 exp hypot atan2. Non-differentiable functions (abs floor ceil round trunc min max, %) fail closed rather than guess. In the black-box suite, every printed
derivative is additionally cross-checked against sympy as an independent symbolic oracle.
rat evaluates in exact big-rational arithmetic (big-integer numerator/denominator,
gcd-reduced canonical form, sign flag, den > 0). Decimal literals become exact rationals —
which makes float error visible:
./jackal rat "0.1 + 0.2"
# status=exact parsed=0.1+0.2 exact=3/10 approx=0.3
./jackal rat "123456789123456789/987654321987654321 + 1/3"
# status=exact parsed=... exact=150891632/329218107 approx=0.4583333321942708The exact= field is the truth; approx= is the same expression through IEEE f64, printed so
the discrepancy is inspectable. Supports + - * /, ^ with integer exponents (negative
allowed), parentheses, and decimals/scientific notation. Everything else fails closed.
JACKAL's integer core has been run inside the RISC0 zkVM through Anubis's proving backend.
proofs/jackal_proof_guest.anb re-executes the gcd,
exact-binomial, primality and lcm invariants inside the guest and commits how many held; the
resulting receipt (proofs/zk-receipt/) binds the output
(journal = 8, all invariants) to the exact program (ImageID derived from the guest ELF).
Anyone can re-verify with anubis verify-receipt — no trust in this host or author required.
Flipping a single byte of the receipt makes verification fail; that negative control was
performed and recorded. No mainstream calculator ships a cryptographic proof that its
arithmetic core does what it claims.
Semicolon-separated statements with persistent variables, Soulver-style:
./jackal worksheet "a = 5; b = a^2; a+b"
# a = 5
# b = 25
# 30Assignments print name = value; bare expressions print their value; reserved names
(constants, functions) cannot be shadowed and fail closed.
Arbitrary-precision nonnegative integer arithmetic implemented in Anubis as base-1e9 limb lists — every result exact, never rounded:
./jackal big-fact 1000 # all 2568 digits, exact
./jackal big-ncr 1000 500
./jackal big-pow 2 512
./jackal big-mul 123456789012345678901234567890 987654321098765432109876543210
./jackal big-add 999999999999999999999999 1Compute budgets fail closed: big-fact/big-ncr accept n <= 10000, big-pow exponents
<= 10000 on bases <= 1000 digits. The legacy fact/ncr stay on the documented i64
register model; the big- lane is the exact model.
The v1.5.0 exact CAS lane turns the bigint/rational core into a small
certifiable computer-algebra surface. Every command computes EXACTLY
(big-rational / big-integer arithmetic, never floats), prints status=exact,
and — where a compact witness exists — emits a final
exact-cert={...} line: a canonical jackal-exact-cert-v1 JSON certificate
that the small, stdlib-only, independent verifier
tools/exact_verify.py re-checks by full recomputation (its own parser,
its own polynomial arithmetic, its own Sturm chains — it never trusts the
engine):
./jackal poly-eq "(x+1)^2" "x^2+2*x+1" # status=exact equal=true + cert
./jackal poly-eq "x^2-1" "(x-1)^2" # equal=false — counterexample-proof coefficients in the cert
./jackal ratfunc-canon "(x^2-1)/(x-1)" # num=1,1 den=1 side-condition=denominator-nonzero
./jackal roots-isolate "(x^2-2)*(x-3)" # 3 disjoint rational isolating intervals + Sturm-checkable cert
./jackal alg-cmp "x^2-2" 1 3/2 "x^2-3" 3/2 2 # order=less — sqrt(2) < sqrt(3), decided exactly
./jackal xgcd 240 -46 # g=2 u=-9 v=-47 + Bezout certificate
./jackal prime-cert 1000003 # verdict=prime + recursive Pratt certificate
./jackal prime-cert 561 # verdict=composite divisor=3 (Carmichael numbers cannot pass)
./jackal mod-inv 3 7 && ./jackal crt 2 3 3 5 2 7
./jackal canon "2+3*sin(pi/6)^2" # canonical s-expression + SHA-256
# independent replay of any emitted certificate:
./jackal xgcd 240 -46 | sed -n 's/^exact-cert=//p' | python3 -I -S -B tools/exact_verify.py -
# exact-verify=ACCEPT kind=xgcd cert_sha256=... method=independent-recomputeSemantics and honest labels: exact here means exact integer/rational
computation with an independently re-checkable certificate — it is NOT a
Lean-mechanized claim (those are the formal-* lanes), and the verifier's
ACCEPT line says method=independent-recompute. Polynomial identity over
ℚ[x] is DECIDED (canonical-form comparison, degree ≤ 64); rational-function
canonicalization records the denominator-nonzero side condition because
(x²-1)/(x-1) = x+1 only where the original denominator is nonzero;
roots-isolate reports distinct real roots (multiplicities are not
claimed); prime-cert refuses beyond its factoring budget (trial division +
Pollard rho, n ≤ 10^60) instead of downgrading — a Pratt certificate or a
divisor, never a probabilistic verdict labeled exact. General symbolic
simplification and equality outside these fragments remain refused, exactly
as before.
v1.7.0 introduced the composed-integral artifact checker, but that checker did not bind the raw caller expression to the Q-expression inside the artifact. Its formal replay epoch is therefore revoked: historical v1.7.0 receipts and checker bytes are retained only as negative evidence and cannot produce a current formal result.
v1.7.2 closes that boundary for a dedicated certificate lane:
./jackal-int-cert-release "<expr>" <lo> <hi> <tol> <receipt.json>
(plugin tool jackal_integrate_bound_cert). The producer
(tools/int_cert_producer.py) is untrusted: it mirrors the engine's
adaptive subdivision in exact rational arithmetic and emits a
jackal-int-cert v1 certificate. The trust anchor is the independently
compiled Lean-proved checker jackal_int_cert_check (checker pin
jackal-iv-bound-step-v1), whose public checkIntCertRequest path parses and
lowers the exact raw expression, checks canonical bounds and tolerance, ties
that lowered expression to the tree root, re-checks the whole subdivision
tree, and accepts only under theorem int_cert_sound; the resulting
jackal-formal-receipt-v1 receipt (variant int_cert) is
status=formal-bounded. Certified fragment:
num/var/neg/add/sub/mul/div/pow (exponent 0..4096)/
sin/cos/abs in x — everything else refuses, never downgrades.
The weaker float lane (integrate-bound / jackal_integrate_bound,
status=bounded, conditional on the stated f64/libm rounding model) is
unchanged and never inherits the formal status. Residual non-claims:
producer fidelity is tested, not proved (an unfaithful producer can only
cause refusal, because the checker recomputes everything), and
source→native refinement remains OPEN.
v1.6.0 turns the engine and its lanes into a typed claim compiler: every consequential quantitative conclusion either carries a canonical, independently replayable evidence graph that preserves every weaker class and assumption, or refuses.
# Compile a structured claim request into a content-addressed bundle:
./jackal-claim --request request.json --emit-bundle bundle.json
# Independently replay it against caller-pinned expectations:
./jackal-claim-verify --bundle bundle.json \
--expected-release-epoch v1.6.0 \
--expected-root-proposition root_prop.json \
--expected-policy-sha256 <hex> \
--verification-time-unix "$(date +%s)"The kernel is deliberately small and closed:
- Canonical bytes are load-bearing. One canonical JSON function (RFC 8785-compatible on the admitted value space; no floats, NFC-only strings, duplicate keys refused); node identity = SHA-256 of canonical node bytes; bundles bind nodes, root, policy, registries, and engine identity into one digest.
- Provenance is a graph, not a badge. Fifteen registered inference
rules (
release/claim/inference_registry_v1.json) — evidence admission, conjunction, typed substitution, exact-rational interval arithmetic (division only off zero), linear/affine unit conversion, threshold derivation, robust decisions, model conditioning, provenance passthrough, attestation attach. Anything else refuses; this is not a theorem prover. - Assurance is multidimensional and non-launderable. Four ordered
axes (input provenance, model validity, mathematical class,
implementation) propagate by pointwise meet with rule caps; artifact
flags AND; residual non-claims union and never disappear. A declared
vector that diverges from the recomputed one refuses. A signature can
only ever affect artifact provenance. Exact math over an assumed
model stays
model_validity=assumed; formal math over supplied input staysinput_provenance=supplied. - Decisions carry structured consequence classes (
informational,advisory,decision-boundary,safety-critical) with kernel-mandated minimum axis floors and exact certified margins —safety-criticalover a merely assumed physical model refuses. - Legacy lanes ride unmodified.
jackal-formal-receipt-v1receipts andjackal-exact-cert-v1certificates enter graphs only through adapters that re-run the EXISTING independent verifiers (receipt_verify.py+ pinned Lean checker,exact_verify.py); a bounded machine-integer fragment (jackal-machine-int-cert-v1: w8-w64, signed/unsigned, wrap/checked two's-complement) is fully recomputed by the claim verifier with the engine's exact bitwise commands as drift alarms. - The verifier trusts nothing.
tools/claim_bundle_verify.pyis dependency-free, runs underpython3 -I -S -B, requires caller-pinned epoch/root-proposition/policy/registries/time/nonce, recomputes every hash, rule, axis, floor, and the deterministic rendering, and returnsverified,refused, orindeterminatewith one of 70 stable reason classes — never a bare VERIFIED badge. - Interval-composed enclosures cap at
mathematical=bounded: hull arithmetic is recomputed by the Python verifier, not the Lean checker; formal parents keepformal-boundedin their own nodes. The graph never flattens. Current request-bound v1.7.2int_certreceipts enter the graph atformal-boundedthrough their dedicated checker/proof context; revoked v1.7.0 receipts refuse. The claim kernel's own hull arithmetic still caps atbounded.
Hermes exposes the kernel as two additive tools — jackal_claim and
jackal_verify_bundle — alongside the 31 unchanged v1.5.0 tools (33 at
the v1.6.0 seal; the v1.7.0 jackal_integrate_bound_cert brings the
inventory to thirty-four). Hostile controls
(108-row matrix: serialization, graph identity, laundering, units,
consequence floors, freshness/replay, machine arithmetic, legacy
compatibility, rendering), A→B→A tamper gates over the seven claim trust
layers, ten end-to-end dogfood graphs, and a fresh-extraction three-way
parity gate ship in release/evidence/claim_*_v160.json.
Everything above certifies mathematics. A domain pack is the mechanism for
carrying the same epistemic discipline into claims that are not arithmetic at
all — without letting them inherit arithmetic's strength. A pack is a
digest-sealed manifest (jackal-domain-pack-manifest-v1) that declares, per
operation, the engine command it routes to, the exact argument schema, the
response schema, the independent checker, the evidence kind, an assurance
ceiling, a separate consequence ceiling, the enumerated refusal classes,
resource budgets, and permanent nonclaims. fallback.allowed is always false
with reason exactly fallback_forbidden: a pack that cannot answer refuses, and
never degrades to a weaker lane behind the caller's back. The protocol, its v1
ceilings and its mandatory nonclaims are specified in
domain_packs/PACK_SPEC.md and bound by
domain_packs/registry_v1.json; the declared compatibility window is
v1.8.0 <= release < v2.0.0.
One route ABI for every pack:
./jackal pack-route <pack_id> <operation_id> <args...>A route MUST preserve the direct command's stdout bytes exactly — a route is
an addressing mechanism, never a second implementation. Verified for all five
operations by capturing both stdouts and running cmp: byte-identical in every
case.
| pack | operation | command | args | evidence kind | assurance ceiling | consequence ceiling |
|---|---|---|---|---|---|---|
jackal.core.exact |
core.exact.mod_pow.v1 |
mod-pow |
3 | exact-cert |
exact |
safety-critical |
jackal.programming.source |
programming.source.test_exists.v1 |
test-exists |
5 | test-exists-cert |
exact |
informational |
jackal.programming.source |
programming.source.claim_cites_test.v1 |
claim-cites-test |
6 | test-exists-cert |
exact |
informational |
jackal.decision.matrix |
decision.matrix.rank.v1 |
decision-rank |
7..15 | decision-cert |
exact |
decision-boundary |
jackal.decision.matrix |
decision.matrix.rank.v2 |
decision-rank-v2 |
8..16 | decision-cert |
exact |
decision-boundary |
The anti-laundering boundary — the point of the whole protocol. Assurance
and consequence are two different axes and a pack must declare both.
test-exists-cert carries assurance ceiling exact and consequence ceiling
informational. The exact is honest: whether a declaration-shaped
occurrence of a symbol exists in a file at a claimed content hash is a
byte-exact structural fact, decided by recomputation, with no estimate anywhere
in it. The informational is equally honest, and it is the load-bearing half:
a test existing is never evidence that the code under test is correct. So a
structural programming fact may be as strong as arithmetic about what the bytes
say and must still never reach a safety-critical conclusion about what the
code does. tools/domain_pack_verify.py enforces the consequence ceiling
mechanically, not only the assurance ceiling — the comparison against each
evidence contract's consequence_bound is a hard refusal in the verifier itself,
not advice. The full observed accept/refuse matrix, and the control showing the
refusal comes from that guard rather than from a digest check (flip only the
bound and the identical digest-coherent tree becomes accepted), are recorded in
docs/W3_W4_W6_W10_COMPLETION_RECORD.md
§1. exact-cert keeps safety-critical and decision-cert sits between at
decision-boundary; a ceiling is an upper bound on what a consumer may declare,
never a grant.
# Structural fact about source bytes — exact, and deliberately informational.
./jackal test-exists tools/lcm_differential_gate.py <sha256> _run 108 1
# status=structural-exact symbol=_run line=108 count=1
# consequence=informational note=a-test-existing-is-not-evidence-the-code-is-correct
# test-exists-cert={"claim":{...},"kind":"test-exists","schema":"jackal-test-exists-cert-v1",...}
# The same fact through the pack route — byte-identical stdout.
./jackal pack-route jackal.programming.source programming.source.test_exists.v1 \
tools/lcm_differential_gate.py <sha256> _run 108 1
# Does a document's claim cite a test that actually exists?
./jackal claim-cites-test <doc> <doc_sha256> "<claim text>" <test> <test_sha256> <symbol>
# status=structural-exact cited_symbol=_run
# consequence=informational note=citation-resolves-it-does-not-establish-the-cited-test-covers-the-claim
# Order options by a caller-declared numeric criterion, with the margin recorded.
./jackal decision-rank d1 latency_ms min alpha 120 beta 90
# status=exact selected=beta margin=30
# consequence=decision-boundary note=the-declared-criterion-remains-the-callers-...
# decision-cert={"claim":{...},"kind":"decision-rank","schema":"jackal-decision-cert-v1",...}
# Same, in the closed-unit lane: the criterion needs a unit from a fixed vocabulary.
./jackal decision-rank-v2 d1 latency_ms ms min alpha 120 beta 90
# status=exact selected=beta margin=30 unit=ms
# consequence=decision-boundary note=the-declared-criterion-and-unit-remain-the-callers-...
# decision-cert={"claim":{...,"unit":"ms"},"kind":"decision-rank-v2","schema":"jackal-decision-cert-v2",...}
# Independent replay — each checker recomputes every field from the real bytes:
./jackal test-exists ... | sed -n 's/^test-exists-cert=//p' > cert.json
python3 -I -S -B tools/test_exists_verify.py --cert cert.json --root . # ACCEPT / REFUSE <class>
python3 -I -S -B tools/decision_verify.py --cert decision.json # ACCEPT / REFUSE <class>The engine validates canonical form only; the checkers are what make a claim
un-mintable by lying. tools/test_exists_verify.py re-hashes the file, re-finds
the declaration, re-counts it, and refuses a symlinked or escaping path
(cert-path-symlink, cert-path-escape, cert-content-hash-mismatch,
cert-symbol-absent, cert-declaration-count-mismatch,
cert-declaration-line-mismatch, cert-absence-as-existence,
cert-claim-text-absent, cert-citation-dangling).
tools/decision_verify.py recomputes the selection, runner-up and margin from
the certificate's own option array (cert-selection-mismatch,
cert-margin-mismatch, cert-margin-zero, cert-value-judgment) and, in the v2
lane, refuses any unit outside the closed vocabulary (cert-unit-not-admitted).
Both print ACCEPT or REFUSE <class> and exit 0 only on ACCEPT.
decision-rank refuses rather than ranks whenever ranking would be a value
judgment (decision-value-judgment), a tie (decision-margin-zero), an
ambiguous label set (decision-duplicate-label), or an unknown sense
(decision-sense-unknown). Accepting a caller's numeric criterion is not a
claim that the criterion is the right one to optimise, and the certificate's own
consequence line says so. Known gap in v1, stated rather than hidden: that
screen is a substring blocklist and is incomplete — measured, both
decision-rank d1 optimal min alpha 120 beta 90 and
decision-rank d1 b3st min alpha 120 beta 90 are ACCEPTED. A longer word list
never fixes this, because free text can always be spelled around one.
decision-rank-v2 is the lane where that gap is closed, by a different
mechanism: it requires a declared unit and refuses any unit outside a closed
vocabulary — exactly the 66 canonical ids of release/claim/unit_registry_v1.json
minus one, the dimensionless identity, which is excluded because declaring it
says nothing about what the numbers measure. Nobody can name a unit for elegance,
so decision-rank-v2 d1 most_elegant elegance max a 1 b 2 refuses with
decision-unit-unknown, and so does b3st, optimal_score one, the alias
millisecond, and the case variant Ms. The v1 word list is retained as a
second gate, not replaced: decision-rank-v2 d1 best_score ms min a 120 b 90
still refuses with decision-value-judgment. v1 is retained unchanged, gap and
all, because narrowing a shipped operation's accepted inputs breaks its callers.
What v2 does not establish: that the values were measured in the declared
unit. most_elegant in ms is admitted — the certificate then says exactly that,
a ranking over caller-declared millisecond values, and nothing more. Manifest
nonclaim: a_declared_unit_is_not_a_measurement.
Finally, the verifier is honest about its own limits — it checks metadata, identity and policy, and says so in its own output rather than letting a reader assume more:
python3 -I -S -B tools/domain_pack_verify.py
# {"pack_count":3,"operation_count":5,"status":"accepted",
# "anubis_execution_status":"NOT_EXECUTED","assurance_status":"NOT_MINTED", ...}| World | Commands |
|---|---|
| Trust and metrology | claim-card self-test maturity measure-mul uncertain-ohm kinetic-sensitivity |
| Expression engine | eval integrate integrate-adaptive derivative solve |
| Certified enclosures | integrate-bound range-bound (proven interval bounds, refuse-on-doubt) |
| Proof-carrying | range-bound-cert plus release wrappers jackal-cert-release, jackal-gaussian-release, jackal-int-cert-release (composed integral enclosure, theorem int_cert_sound), and the seven zero-libm fragment wrappers jackal-{sqrt,exp,ln,sin,cos,atan,tanh}-rat-release (matching Lean checker required) |
| Provenance | parse-dump lower-dump (canonical s-expr of the parse/lowering — drives the Lean parser-correspondence gate) |
| Symbolic | diff (self-verifying d/dx) |
| Exact rationals | rat (canonical p/q + labeled f64 approx) |
| Exact algebra (certificate-bearing) | canon poly-canon poly-eq poly-gcd ratfunc-canon roots-isolate alg-sign alg-cmp |
| Number theory (certificate-bearing) | xgcd mod-pow mod-inv crt divides prime-cert |
| Domain packs (routed, certificate-bearing) | pack-route plus the routed commands test-exists claim-cites-test decision-rank decision-rank-v2 — structural-source and decision certificates whose consequence ceilings are declared separately from their assurance ceilings (see "Domain packs" above) |
| Worksheet | worksheet (persistent variables across ;) |
| Exact integers | big-add big-mul big-pow big-fact big-ncr |
| Numerical laboratory | matrix2 solve2 integrate-x2 derivative-x3 |
| Mathematics | quadratic lerp percent-error ncr gcd lcm fact prime |
| Vector algebra | dot cross norm3 |
| Data science | stats describe linreg |
| Unit laboratory | convert for length, mass, temperature, pressure and energy |
| Electrical engineering | ohm parallel-r uncertain-ohm |
| Mechanics and space | kinetic projectile orbit relativity |
| Physics and chemistry | ph dilute photon blackbody ideal-gas molarity decibel-power |
| Programmer | hex bin band bor bxor shl shr |
| Scientific core | add sub mul div pow sqrt cbrt sin cos tan sin-deg hypot ln log10 exp |
# Measurements and propagated worst-case relative uncertainty
./jackal measure-mul 12 0.1 3 0.05 m2
./jackal uncertain-ohm 12 0.1 3 0.05
# Linear algebra with residual reporting
./jackal matrix2 1 2 3 4
./jackal solve2 2 1 5 1 -1 1
# Numerical methods with method metadata/error probes
./jackal integrate-x2 0 3 100
./jackal derivative-x3 2 0.001
# Chemistry and physics
./jackal ph 0.001
./jackal dilute 2 0.5 0.25
./jackal relativity 0.6
./jackal blackbody 5778
# Sensitivity: K = 1/2 m v²
./jackal kinetic-sensitivity 2 3ANUBIS=$HOME/anubis-lang/vm/pins/anubis-a733565f237d
$ANUBIS check jackal_calc.anb --out /tmp/jackal-check
./jackal self-test
ANUBIS_BIN=$ANUBIS python3 tests/test_calculator.py
python3 tests/bound_campaign.py 250 20260813 # seeded containment gate for integrate-boundThe containment campaign is the permanent release gate for the certified lane: seeded
generation, an independent symbolic-antiderivative oracle at 60 digits, immutable JSONL rows
with a printed SHA-256, refusals counted rather than hidden — and a hard failure if any
printed enclosure ever excludes the independently computed truth. See
PROVENANCE.md for the sealed source → compiler → binary chain.
- Numeric calculations use Anubis's current IEEE-754 floating-point runtime, not arbitrary precision.
ncrcomputes exactly every binomial coefficient representable in i64 (gcd-reduced multiply) and fails closed at the i64 boundary rather than wrapping;C(66,33)is the largest central case.lcmwas a mislabeled epistemic class and was fixed, not documented around. It computedpositive_abs(a / gcd * b)ini64, which wraps once the true least common multiple exceeds2^63 - 1, whilematuritydeclared the commandclass=exactwithresidual=none-observed-within-grammar-and-budgets. Measured on shipped binaries:lcm 4611686018427387904 3returned4611686018427387904— smaller than one of its own inputs, which no least common multiple can be. The quotienta / gis still reduced ini64(exact, since|a/g| <= |a|) and the final product now goes through the same arbitrary-precision lane that backsbig-mul, so noi64product remains on the path; the same request now returns13835058055282163712. Guarded bytools/lcm_differential_gate.py: a frozen 39-case boundary corpus, 10 rows of which exceedi64, comparinglcmagainst the engine's ownratlane, and refusing to report PASS if no row exceededi64— so the gate cannot decay into a rubber stamp.gcdandlcmnow refusei64::MINwithint-min-unrepresentable.positive_abswraps ati64::MIN, and therequirescontract ongcd_safeis not runtime-enforced on this toolchain: measured,gcd -9223372036854775808 6previously returned-2, and a negative gcd is impossible. An unenforced precondition under aclass=exactlabel is the same defect as thelcmwrap, so the precondition is now checked where it belongs instead of being left to a downstream string validator that happened to reject the interpolated text.shl/shruse the i64 two's-complement register model; shift counts outside 0..63 fail closed.divby zero fails closed rather than printing IEEE infinity.- The claim card prints its canonical preimage (
canonical=), so the SHA-256 fingerprint is recomputable with any external tool; Anubis interpolates floats in default form (e.g.20.0). - Domain violations abort through the Anubis runtime's panic channel: nonzero exit with the reason on stderr, wrapped in a runtime trace. Fail-closed, not pretty-printed.
- Every CLI number enters through strict ingestion (
strict_float/strict_intover the language'sparse_*_opt): malformed text (abc,12abc,4.5where an integer is required) and non-finite literals (nan,inf) are refused at the boundary instead of being leniently coerced to 0 — closing an entire silent-wrong-value class (add abc 5once printed5). - The
diffrelease gate verifies against Richardson-extrapolated central differences (h and h/2, combined to cancel the h² term), so stiff-but-correct derivatives such ascos(exp(x^3))pass while a mutation-tested wrong rule (sin for cos) is still refused. - The adversarial campaign (
python3 tests/campaign.py, seeded) fuzzes every lane against Python/SymPy/Fraction oracles — ~990 cases across eval/precedence/rat/bigint/diff/atlas/ hostile/cross-lane/determinism — and must report zero findings. - Measurement multiplication/division uses conservative first-order addition of relative absolute uncertainties; it does not infer distributions, covariance or confidence levels.
- The
eval/worksheetexpression engine is numeric, not symbolic: no general CAS, no general simplification. The v1.5.0 exact-algebra lane is a deliberately small CERTIFIABLE fragment on top of it — polynomial/rational-function canonicalization and decidable identity over ℚ[x] (degree ≤ 64), Sturm root isolation, and the number-theory kernel — each claim carried by ajackal-exact-cert-v1certificate an independent verifier recomputes. Everything outside those fragments (trig identities, factoring, general symbolic equality) refuses, exactly as before. Expression arithmetic inevalis IEEE-754 f64; thebig-integer,rat, and exact-algebra lanes are arbitrary precision. Numbers require a leading digit (0.5, not.5). Expression division/modulo by zero and non-finite results (NaN/inf) fail closed — deliberately stricter than the underlying language's documented IEEE leniency. - The exact integer lane covers nonnegative integers on its command surface; internally it also implements comparison, subtraction, binary GCD, and schoolbook base-10 long division (correctness-first, compute-budget capped) to power the rational engine. Expected test values are generated at test time by Python and sympy — independent oracles.
- The simplifier is conservative and adopts documented conventions:
u^0 -> 1and0^0 -> 1follow the C/IEEE pow() library convention (not a mathematical identity);u/u -> 1,u-u -> 0,0*u -> 0hold whereveruis defined (measure-zero caveats at singularities). The numeric self-verification still checks every printed derivative. diffdifferentiates with respect tox; other free variables are treated as constants and bound to 1.5 during the numeric verification pass. Symbolic simplification is minimal — no trig identities, no factoring, no collection.ratexponents are capped at 10000 (compute budget); non-rational operations (functions, constants,%) fail closed rather than approximate.- Worksheet state lives for one invocation; there is no persistent session file.
- Richardson values are error estimates from grid refinement, not proven bounds — both grids
can miss structure narrower than the panel width, so agreement is necessary but not sufficient.
Fixed-grid
integratesays so (assurance=estimate-not-bound(grid-limited)). For integrands with localized or fine structure, useintegrate-adaptive "expr" a b tol: recursive adaptive Simpson over a 32-interval seed that subdivides until each region meets its local tolerance and refuses (budget, depth, or f64-resolution exhaustion) rather than print unearned confidence. The narrow-Gaussian case that beat the fixed grid by 256× resolves to 12 significant figures under the adaptive lane. The estimate is still local, not a proven bound: structure below seed/f64 resolution can evade even adaptivity. Bisection requires a bracketing sign change and reports its residual; it correctly refuses even-multiplicity roots. Because a tiny residual FLATTERS an ill-conditioned root (|x−r| ≈ |f(x)|/|f′(r)|),solvealso reports aderivative-estimate, thecondition-amplification1/|f′(r)|, and a first-orderroot-error-estimate— field-adjudicated 2026-08-13 on a near-parabolic Kepler equation where a 2.3e-20 residual accompanied a 1.3e-12 root error (amplification ≈6.06×10⁷; the printed estimate matched the independently measured error to two significant figures). The estimate uses a point sample of f′, so it remainsestimate-not-bound(first-order); the sound form it instantiates (m ≤ |f′| on the bracket ⇒ |x−r| ≤ |f(x)|/m) is mechanized inproofs/lean. integrate-boundis the only lane whose output is a mathematical bound, and its claim is conditional exactly on: (a) IEEE-754 correctly-rounded+ - * /; (b) math-library functions within 2 ulp including argument reduction; (c) the outward-padding constants exceeding both; (d) the correctness of this implementation, which is campaign-tested (tests/bound_campaign.py), not mechanized — there is no machine-checked proof of the interval code itself.0^0 = 1follows the same documented pow() convention as the simplifier. Non-smooth integrands (abs,floor,min, …) get the pure range form, whose certified width converges only linearly — practical tolerances there are ~1e-4 on unit spans, and the budget refusal names that honestly.- The
status=epistemic classes (exact,structural-exact— the domain-pack source lanes, whose separateconsequence=line is the load-bearing half —bounded,formal-bounded,checked,estimated,model-based) are printed on metadata-bearing lanes only; bare-number lanes (eval,big-*, single-command arithmetic) keep their historical byte-stable output and are graded injackal maturityinstead. Refusals exit nonzero with a named reason on stderr through the Anubis runtime's panic channel — fail-closed by construction; the runtime trace wrapping is cosmetic, not a crash. A future typed-refusal surface (distinct exit codes per epistemic state) would require a clean-exit primitive in the language. parallel-rdocuments its physical-domain policy: ideal passive elements. A zero-ohm branch is a legal ideal short (equivalent resistance exactly0 ohm, field-adjudicated 2026-08-13); negative resistance implies an active element and is refused rather than silently reinterpreted.- The
diffverifier's probe self-convergence gate (skip a sample point when the h and h/2 central differences disagree >1% of scale) validates the instrument before the number; the criterion is independent of the symbolic candidate, so it cannot mask a wrong rule. - Memory is bounded by design constants, not by hoping the host is big: the certified lane's work is capped at 60000 subintervals with recursion depth ≤ 60 and derivative-formula size ≤ 20000 nodes (oversize formulas degrade to a lower Taylor form — a cost decision, never a soundness one), so the engine's footprint stays in transient tens-of-megabytes territory on any host. The test harness applies the same discipline to its oracles: each independent truth computation runs in a disposable subprocess with a hard RSS cap (3 GB) and timeout, because a symbolic-integration oracle that eats the machine is a harness bug, not evidence.
- A calibration note from adversarial field testing: on
sin(100*x)*exp(-x)over [0,10], a probe's independent reference claimed the sign was wrong — exact symbolic integration proved the reference wrong and JACKAL right, with the printed Richardson estimate (2.1865e-7) matching the true error (2.1857e-7) to 0.04%. Trust claims here are tested in both directions. - All numeric output routes through a finite gate: NaN/inf reaching any printer is a fail-closed panic, and claim cards additionally refuse non-finite inputs at admission — a fingerprint authenticates bytes, it is not an accept verdict.
diffprints adomain-caveat=line whenever simplification applied a where-defined convention (u/u, u−u, u^0, 0·u), because the emitted derivative does not carry the original expression's domain restrictions.- The legacy
integrate-x2/derivative-x3commands are kept for compatibility;integrate,derivative, andsolveaccept arbitrary expressions inx. describereports population variance and standard deviation.- Orbital output assumes an ideal circular two-body orbit.
- Projectile output assumes equal launch/landing elevation, vacuum, constant gravity and a point mass.
- Claim-card hashes bind canonical bytes; they do not prove that the physical assumptions match reality.
- Targeted checker/runtime evidence is not a universal Anubis soundness or calculator-correctness claim.