CAVEAT Language

A programming language whose decisions record what they rest on: the evidence they used, what permitted them, and why they were reopened.

Available now: CAVEAT 0.1.0-rc.14. Run CAVEAT in Node.js or the browser. Get started · Release notes.

The problem

A program, or an agent, decides to act: cover the seedlings tonight, merge a change, send a crew. Later someone asks:

  1. What was the decision based on?
  2. What allowed it to go ahead?
  3. One of its inputs turned out to be wrong. What rested on it, and does the decision still stand?

You can record these answers in ordinary code, and the project's own TypeScript comparison records what a decision was based on and when it was reopened. But you write and maintain that bookkeeping yourself, and nothing checks it against the logic that made the decision unless you write that check too. A go-ahead folded into the decided value also blurs why the action was safe with who allowed it.

In Caveat the program declares these answers, and the runtime records them as it runs:

Caveat is not an agent framework: it does not call models or tools. Your code, or your agent's harness, sends a Caveat program events through the Node or browser library, or as JSON lines with caveat serve, and acts on what the program decides.

Integrating Caveat with an agent? Start with the Python caveat serve example. If a real integration exposes a missing capability, please open an agent feature request for the project owner to evaluate. Check existing issues and include the exact version, a small reproduction, and expected versus actual behavior.

One example: covering seedlings

The worked example is one program of about 60 lines. Two instruments read the soil temperature: a probe, and a survey drone whose readings carry the caveat uncalibrated. When the probe reads 2 °C or colder and the grower has given a go-ahead, the program decides to cover the seedlings. A probe or drone reading above 2 °C reopens that decision, and so does finding out that the reading it rested on was taken wrongly.

The decision, from the program (line breaks added):

on decide when latest(soil) <= 2
    commit cover because enough
    using latest(soil)
    permitted by latest(approvals);

After a cold probe reading, a go-ahead from "sam", the decision, a cold drone reading and then a warm probe reading, caveat explain prints this for the decision (an excerpt, with its indentation trimmed):

cover@1 = 1  reopened
  based on soil@1
  permitted by approvals@1
  could also have been influenced by approvals@1
  #3 decide: committed because soil@1
  #5 probe_read: reopened because soil@2

"Based on" is the grounds. The cold drone reading came after the decision, and it would not be among the grounds anyway, because the decision's value was computed from the probe alone. "Could also have been influenced by" lists the rest of the decision's lineage: other evidence that could have affected it, here the grant, kept conservatively. The example's scenario file also checks that without a go-ahead the decision is refused, as policy/not_permitted; that withdrawing the reading it rested on lets a rule reopen it, with the original grounds kept; and that refused events change nothing.

Run it

You need Node 20 or later. In an empty directory:

npm init -y
npm install caveat-lang@0.1.0-rc.14

Save the three files shown in the worked example as frost.cav, frost.scenarios.json and events.jsonl. Then:

npx --no-install caveat test frost.scenarios.json
npx --no-install caveat explain frost.cav events.jsonl

The test prints 4 passed, 0 failed (frost.scenarios.json), and the explanation is the one in the worked example. The package's own tests follow the worked example the same way.

Limitations

0.1.0-rc.14 changes only the package's MCP server name, so the MCP Registry lists it as io.github.WSattazahn/caveat-lang; its language is rc.13's. rc.13 reports a program's interface as JSON and writes TypeScript declarations from it, makes restore refuse a caveat the source cannot attach and a membership without its record, and turns id_text of a non-handle into a refused event instead of a fatal failure. Restoring a save still does not authenticate its history. Hosts must handle rejected outcomes explicitly. Existing Lean proofs cover the documented model; the comparison is not a proof of the entire Rust runtime. No npm runtime dependency is added. See the rc.14 verified release record. The rc.14 GitHub prerelease retains the exact tested Linux tarball and its checksum. rc.14 is published by the repository's publish workflow, with an npm provenance attestation; the registry bytes, the provenance, the registry signatures and a fresh exact-version installation are verified.

Culture

Caveatism is the philosophy that grew up around Mr. Caveat, a mechanical fortune teller who always has a caveat; it lives in the repository's caveatism directory and is culture, not a contract of the language. The Archive and Atlas are its texts, and the canon keeps the Archive as a Caveat program with scenarios.

Games on this site

The rest of this site is games written in Caveat and run in the browser. The glowcap explainer, Trail Rescue and Light the Way use the same form of Caveat as the package. Moon Garden, Mr. Caveat and others use an earlier form that the package does not load. They are demonstrations, not part of the package.