@codai/axiom-checks
Predicate-based checks engine for AXIOM v2 (design §3). Deterministic, offline,
data-driven by JSON CheckRefs — no expression language in 2.0.
import { loadProfile, runChecks } from "@codai/axiom-checks";
const profile = await loadProfile("strict", { searchDirs: [".axiom/profiles"] });
const report = await runChecks({ bundle, profile, root: realRoot, checks: plan.checks });
- Facts:
facts/manifest.ts (counts, bytes, paths), facts/content.ts (blobs → CAS, re-hashed,
never network), facts/repo.ts (exists/read/glob over a lazy .gitignore-aware index, package.json,
.git/HEAD read directly — no spawn; gitDirty is undefined in 2.0).
- Built-ins:
path.allow|deny|reservedNames, content.noSecrets|maxBytes|encodingUtf8,
manifest.maxArtifacts|maxTotalBytes|requireSigned|noDeletes, deps.max|deny,
repo.noOverwriteOf|requireCompanion, guard.external (spawns a repo-owned scripts/*.mjs|.ps1
or an allowlisted absolute executable, no shell; needs profile facts.allowGuards and
runChecks({ allowGuards: true, guardAllowlist }) — the CLI/server --allow-guards /
--guard-allowlist <abs> flags; stdout must be GuardOutput JSON; guard checks run in a pool
of min(4, cpus); see docs/checks.md), expr.cel (boolean CEL expression over
manifest/artifacts/content/repo via @marcbachmann/cel-js, lazily imported; closed
function allowlist — no timestamp/duration/now — literal RE2-safe matches(), AST depth
≤ 24, 100 ms budget; parse/type/runtime errors and non-bool results → error, never pass).
- Profiles:
default, strict (extends default), permissive; files <dir>/<name>.json shadow
builtins; extends chains are resolved parent-first, child checks override by id; cycles →
ERR_INVALID_PROFILE.
- Findings are sorted
(severity, id, path); factsDigest = sha256(JCS({manifestFacts, profileName, checkIds})).
Adding a predicate
- Create
src/predicates/<group>.ts (or extend one) and export
definePredicate<z.infer<typeof Params>>({ id: "group.name", params: Params, requires: [...], run }).
id must match ^[a-z][a-zA-Z0-9]*\.[a-zA-Z][a-zA-Z0-9]*$; params is a strict Zod object;
requires lists which facts you read (repo predicates are skipped when no root is given).
- Return
Finding[] via finding({...}) from util.ts. Emit facts.__provider = true only when the
predicate itself could not evaluate — that forces the error verdict.
- Add it to
BUILTIN_PREDICATES in src/predicates/index.ts and bump the count in run.test.ts.
- Add positive + negative tests in
src/predicates/predicates.test.ts.
tsconfig.json sets isolatedDeclarations: false (Zod-inferred param types cannot be annotated
explicitly); tsdown still emits .d.ts through tsgo.