Thanks for helping build looprun. This guide covers dev setup, the governance model, and the exact order to add or change a guard.
Requirements: Node ≥ 22 and pnpm (see packageManager in package.json).
pnpm install
pnpm -r --if-present build
pnpm -r --if-present typecheck
pnpm test # all package tests + the law tests
pnpm test:proofs # the deterministic guard-proof suiteEverything in this repo is written in English — code, docs, records, comments.
looprun's guards are deterministic (check() = machine gate, prose() = the same rule in the prompt).
To keep them trustworthy, a change to a governed surface ships with a passing proof record:
- Governed (needs a record):
packages/core/src/**,packages/core/GUARDS.md,packages/mastra/src/**. - Not governed (no record): docs, examples, tests-only (any
/test/path), the governance tooling (governance/**,scripts/**,skills/looprun-governance/**), CI (.github/**), changesets, lockfiles, manifests.
A record is one file at governance/proofs/YYYY-MM-DD-<slug>.md, indexed in governance/MATRIX.md.
Full policy: governance/GOVERNANCE.md. The governance skill automates the
scaffold → run → record loop (skills/looprun-governance/SKILL.md).
Author the proof before the implementation — the proof cases are the spec.
- Author proof cases FIRST in
packages/core/test/proofs/— aGuardProofcatalog entry for the new kind with positive / negative / neutral L1 cases plus at least one L3 loop case (and the collective non-interference expectation). Seeskills/looprun-governance/references/proof-case-authoring.md. - Implement the guard in
packages/core/src/guards.tsuntil the cases pass. - Update the catalog doc:
packages/core/GUARDS.md. - Run the suite:
pnpm test:proofs(green, ratchet not lowered). - Generate the record:
pnpm proofs:run pnpm proofs:record -- --slug <kebab> --change "<one-liner>" --scope guard:<kind>
- Commit the record +
governance/MATRIX.mdtogether with your code.
Changing an existing guard, the runtime, or the agentspec skill? Same loop — update/extend the proof
cases for the affected kind(s), then run + record with the matching --scope
(guard:<kind> · runtime · skill).
Proofs run against a deterministic scripted fake LLM and a fixture world — no API keys, no
network. That is what makes a proof a durable statement about behavior rather than a flaky snapshot.
pnpm proofs:run writes a summary to governance/.artifacts/proofs.json (gitignored) and fails if any
proof is red or the coverage ratchet dropped.
pnpm proofs:canary is an optional, report-only lane that replays the same scenarios against a
real small local model — it NEVER gates a PR. Contributors do not need it: it requires local
model weights, so on a machine without them it prints canary skipped … and exits 0. Maintainers with
the weights run it to sanity-check that guard prose holds up in front of a live small model; the result
lands in the proof record's advisory slm_canary field. See
governance/GOVERNANCE.md.
A governed-path diff that genuinely cannot change guard behavior (a comment, a docstring in a src
file) can be exempted: a maintainer applies the no-proof-needed label to the PR and CI skips the
gate. It is maintainer-restricted on purpose — use it deliberately, not to route around a real change.
pnpm test:proofsgreen;node tests/no-bench-drift.test.mjsclean;pnpm proofs:matrixcommitted.- Fill in
.github/pull_request_template.md(Summary / Type of change / Governance checklist / matrix row). - Links:
governance/GOVERNANCE.md·governance/MATRIX.md.