Overview

Tacet is a personal assistant that runs in your terminal, on your own machine. These pages document the command line version, `tacet-cli`, which is written in Rust and published under MIT.

What Tacet is

Most tools described as local AI are a thin shell around a model file. Running the model is the easy part. The hard part is everything around it: deciding when a tool is needed, forcing the model to produce a call the schema will accept, executing that call without handing anything away, and keeping bulk data out of a context window measured in thousands of tokens rather than millions. Tacet is that layer.

  • Thirteen tools on a fresh install, covering documents, files, dates, arithmetic, git, code, archives, checksums and notes.
  • A constrained decoder that makes a malformed tool call impossible to generate rather than catching it afterwards.
  • Four gates on every call: the tool name, the argument schema, an approval question for outbound data, and cancellation.
  • Six direct dependencies, plus three more behind an off-by-default inference feature. The zip, deflate, CRC32, OOXML writing and MCP client are written by hand in this repository.
  • A hash-chained receipt for every tool execution, written by code the model cannot reach.
  • Scores published with the weights and the machine attached, including a run against an outside benchmark rather than only cases this project wrote itself.

The network monopoly

In a default install no command opens a socket. Exactly two crates in the workspace are permitted to, tacet-web and tacet-mcp, and the HTTP dependency appears in exactly those two manifests. This is meant to be checked rather than believed.

grep -v '^\s*#' crates/*/Cargo.toml | grep ureq
cargo test -p tacet-cli --test network_monopoly

The test is the same audit expressed as a failing build. It asserts that exactly those two manifests declare an HTTP client, that no other client was swapped in under a different name, and that nobody reached a socket through std::net instead, scanning every .rs file under crates/*/{src,tests,examples,benches} rather than only the library code.

One honest asterisk

If you install the shell addon and put curl on its allow list, you have handed a program the network yourself. That is why shell sits behind the approval gate.

Absent, not disabled

Everything with reach beyond your working directory is an addon you install on purpose. Until you do, its tools are not merely switched off: they are missing from the catalog the model is shown, so the model cannot call them, mention them, or claim that it did. The same is true of run_code on a machine with no usable sandbox.

What lives on disk

The config directory is $XDG_CONFIG_HOME/tacet or ~/.tacet on Unix and %APPDATA%\Tacet on Windows. TACET_HOME overrides it, and is ignored with a warning if the path is not absolute.

FileWhat it holds
config.jsonThe seven settings tacet config knows about
mcp.jsonConnections to MCP servers you run yourself
packages.jsonYour own additions to the model catalog
receipts.jsonlThe hash-chained record of every tool execution
skills/Your Markdown skill files
sessionsStored conversations, so tacet --continue works

Which build you have

Inference sits behind a cargo feature, and cargo does not remember features across an upgrade. A binary built without one refuses to answer rather than falling back to something that keeps talking, and tacet --version prints the engine in brackets so the build is never a guess.

tacet --version
# tacet 0.1.27 (metal)   <- the part in brackets is the engine

tacet doctor prints the same thing at more length, including the backend it found and whether a sandbox is available on this machine.