Skip to content

About

Reference implementation for The Careful Machine: models propose, deterministic components certify. One question, two machines, and each core test is a book claim made executable.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

The Careful Machine: reference implementation

TypeScript Node Dependencies CI License

In plain English: the AI drafts an answer, plain code checks it and verifies the citations, and if the check fails it refuses instead of guessing. This is a small working example of that idea.

Recorded runs and live tamper bench · Working rules · More tools

Companion code for The Careful Machine: Engineering AI Systems That Cannot Certify Themselves (Miguel Sanchez, forthcoming, 2026). One question is answered twice:

Who has this account paid most often this quarter, and are any of those counterparties new?

  • src/fused/ is the chapter-1 machine, deliberately ordinary: a capped read nobody owns, a ranking narrated as the quarter, novelty answered from the window. Its tests demonstrate the failure: the confident wrong answers being produced while every component works as documented.
  • src/careful/ is the same question through the book's spine: contract and gate with the two standings (ch. 3-4), capability registry (ch. 5), scope intersection (ch. 6), action classifier and interception (ch. 12), evidence with coverage (ch. 7-8), derived results (ch. 9), the claim turnstile (ch. 11), the routed no (ch. 13), and replay (ch. 17).

This is a demonstration, not a framework: hold src/fused and src/careful in your head in an afternoon. src/serve.ts and src/web are the local demo UI, deliberately kept out of that claim - the page is the exhibit, not the argument. The "model" is a deterministic stub that emits proposals, including hostile and over-confident ones; the architecture is what decides.

Run

npm install        # dev-only: typescript + @types/node
npm run demo       # both machines answer the question; ground truth printed first
npm run serve      # local web UI at http://127.0.0.1:8787 (see below for the live model)
npm test           # node's built-in runner; no runtime dependencies
npm run typecheck  # the compile-time gates live here too

Node 22.6+ (uses --experimental-strip-types; the source is erasable-syntax TypeScript, so node runs it directly).

The tests are the point

Each core test is a book claim made executable:

Test Book claim
capped read truncates; narrated top payee wrong ch. 1: the failure is in the empty space between working components
window read calls an old counterparty new ch. 1/5: nothing owns the question being answered
type gate: ExecutionRecord takes a CertId, never a ProposalId ch. 2: executions execute certifications
requester-confirmed unmintable except via the requester record ch. 3: standing integrity; policy never certifies meaning
partial-read ranking struck unqualified; qualified form certified with subset named ch. 8/11: claims carry the coverage they can support
no-occurrence fails on incomplete read and on unknown population ch. 8: unknown is not zero
a complete read certifies the unqualified ranking, naming the true top payee ch. 8/11: coverage is what a claim may lean on
novelty ask lands cannot-execute with nearest-serviceable facts ch. 5: capability is a record; honest refusal beats invented ability
a least-frequent ask certifies nothing, end to end ch. 5: the nearest registered operation is not the one asked for
a presence ask certifies no ranking claim, and ranOperations names what ran ch. 5/12: what the registry selected is what executes
a subject no grant covers is a routed no, not a crash ch. 13: outside-authority is an answer, with the scope owner named
every read is intercepted and logged under the certification it ran under ch. 12: reads are classified and recorded, not assumed
a certified claim names the window and subject that were actually read ch. 9/11: a claim carries its own provenance, not a house style
hostile "search every account" widens the proposal, not the scope ch. 6: authority is an intersection the proposal cannot move
disposition derives from records only, by fixed precedence ch. 13: the no is routed, not narrated
renderer cannot leak a struck claim ch. 11: narration is constrained to the certified set
hostile drafts are rejected with the ground named, never repaired ch. 3-4: the interpreter proposes; validation decides
the answer record replays with every reference resolving ch. 17: an answer is a join over records
the package declares no runtime dependencies the zero-dependency decision below, checked rather than asserted

Every test in the suite backs a row above; the largest block is the interpreter's hostile-draft table (test/interpreter.test.ts), one test per draft. CLAIMS.md maps every claim on this page to the test that enforces it, and names the few that no test can. All identifiers and numbers are invented and illustrative.

Running with a real model (opt-in)

The core repo makes zero model calls; demo:live swaps the interpreter stub for a real one. The model drafts the RequestContract through a forced tool schema, the draft is validated mechanically (malformed drafts are rejected, never repaired), ids are minted locally, and the actual model identity lands in proposedBy and the AnswerRecord. Every other station is byte-for-byte the same code the stub runs through, which is the demonstration: the proposer got smarter and less predictable; the guarantees did not move.

ANTHROPIC_API_KEY=sk-... npm run demo:live                 # hostile question, policy-admitted
ANTHROPIC_API_KEY=sk-... npm run demo:live -- --confirmed  # same, requester-confirmed
ANTHROPIC_API_KEY=sk-... npm run demo:live -- "your own question"

ANTHROPIC_MODEL overrides the default (claude-sonnet-5); ANTHROPIC_BASE_URL is honoured. The key is read from the environment for that run's requests and never stored or printed. npm test stays fully offline.

The web UI defaults to live mode when the key is set (an "Offline stub" toggle sits next to Run). In live mode the SAME model runs on both sides: as the fused machine it is handed the question plus every row for the account, history included, and one unvalidated generation ships as the answer; as the careful machine's interpreter it drafts the reading only, and plain code does the rest. The fight is deliberately fair: nothing is withheld from the fused side, so any failure there is the generation's own, and the cap toggle re-imposes the silent 500-row page one on BOTH machines at once. Nothing is sent on page load; a run happens only when you press Run or pick a scenario, and each live run makes two small API calls (one per machine), or three when a draft is rejected and the interpreter takes its one fresh try. The "Model exchange" panel on every result shows both calls verbatim: what was sent (system prompts, question, data, tool schemas), what came back, and what each side was allowed to do with it. The key stays in the server process; the browser only ever sees the model's output. With no key, both machines run offline: the fused side is the original no-AI pipeline and the interpreter is the deterministic stub.

Non-goals

No LLM calls outside the one opt-in interpreter above, no persistence beyond in-memory records, no config system, no CLI polish, no framework extraction. If a change makes this less readable in one sitting, it is the wrong change.

Decisions

  • Reject, never repair. A malformed draft is refused with the reason named. Repairing it would launder the malformation into the record, and the record is the product.
  • The model never runs inside the verifier. Drafts are input; plain code decides what they become. That boundary is what makes the recorded runs replayable and the tamper bench honest.
  • Zero runtime dependencies. Every guarantee here is carried by code a reader can finish; a dependency would move part of the argument outside the afternoon.

About

Reference implementation for The Careful Machine: models propose, deterministic components certify. One question, two machines, and each core test is a book claim made executable.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages