Memory for coding agents, with the evidence to keep it honest.
A decision made in one session should survive into the next. Tacit keeps project decisions, past mistakes and machine facts in a git repository, then gives your agents a small set of facts matched to the repo and prompt.
Run a local store on your laptop, or share one across machines. Works with Claude Code, Codex, Hermes, Grok, pi, Muse and agy on Linux, macOS and Windows.
- Files you own. One fact per Markdown file, with its source, scope and git history.
- Context that fits. Local full-text search and small context blocks. Hooks avoid repeating facts within a session.
- Recall after a compaction.
tacit episodeand the MCP tooltacit_episodefind the ids, commands, paths and errors a session already had, redacted. - Decisions with proof. Your own words and recorded review decisions establish your rulings. Agents leave changes to those rulings for you.
Install git 2.29+, then use a prebuilt release. Each archive includes the CLI, browser app and compatible scrump redactor. No Go or Rust build is needed. Model jobs need a supported agent CLI and its own provider setup. Search, owner edits and review work without a model account.
curl -fLsS https://github.com/agent-sh/tacit/releases/latest/download/install.sh -o tacit-install.sh
sh tacit-install.sh
export PATH="$HOME/.local/bin:$PATH"
tacit init
tacit app --browserInvoke-WebRequest -UseBasicParsing https://github.com/agent-sh/tacit/releases/latest/download/install.ps1 -OutFile tacit-install.ps1
powershell -NoProfile -ExecutionPolicy Bypass -File .\tacit-install.ps1
$env:PATH = "$env:LOCALAPPDATA\tacit\bin;$env:PATH"
tacit init
tacit app --browserThe installers select amd64 or arm64, verify the archive checksum and test the bundled redactor before replacing executables. They install into your account and leave PATH changes to you. For a specific release or another directory, use sh tacit-install.sh --version v0.1.0 --bin-dir PATH, or -Version v0.1.0 -BinDir PATH in PowerShell. Git and model CLIs remain separate dependencies. Source builds are also available.
init creates a local store. It needs no server, tailnet or enrollment keys. Open the app to add your own rulings, inspect facts and review changes. tacit review opens the same page: it is your channel for every edit, retirement, new rule and folder change in every build. Its link carries a one-run token; it goes to the browser the command opens and is printed only on a terminal, so an agent running the command sees no token and cannot drive the page.
Choose the integration for your agent:
| Agent | Install | Connection |
|---|---|---|
| Claude Code | tacit install claude |
Session-start, prompt, pre-tool and pre-compact hooks, and the MCP tools (--no-mcp: hooks only) |
| Codex | tacit install codex |
The same hooks; trust them once in /hooks |
| Hermes | tacit install hermes |
Memory provider; follow the printed configuration steps |
| Grok / pi / Muse | tacit install grok / pi / muse |
Prints the MCP configuration |
| agy | tacit install agy |
Prints the MCP registration command |
The browser app, using the public example store. Screenshot setup.
Record a failure and its fix. This example adds a sample note to your current local store:
tacit add --harness codex --kind observed --type past_mistake \
--scope projects/demo-api --desc 'Run one database migration worker at a time' \
--body 'Parallel migration workers contend for the database lock. Run one migration worker at a time.' migration-lock
tacit search --repo demo-api --inbox 'migration worker'
tacit app --browserOpen Inbox to inspect the note and its source. After curation, installed integrations can retrieve the reviewed fact in later sessions. search --inbox lets you inspect the note immediately. The codex source label records who wrote the note and does not require running a model for this example.
Portable setup covers dependencies, native jobs, build archives and platform validation. To exchange facts between machines, follow the shared-store setup.
- Collect. Agents write short inbox notes. Imports bring in existing memory files. An optional dreamer extracts candidates from redacted transcript deltas: from the prompt hook once a session's undreamed part fills a dream window, before a compaction, every 10 minutes for the sessions that went quiet, and every 4 hours as a backstop. It saves each successful window before the next call and recovers pending notes after interrupted runs.
- Curate. Notes become individual facts with sources and scopes. Contradictions and uncertain changes become review items. A quick run after the idle dream curates the last day's notes, so a session's fact reaches other sessions within about an hour.
- Deliver. A local SQLite FTS5 index matches facts to the repo, host and prompt. Hooks supply up to 6 of a repo's facts (10 for a host outside a repo) at session start, again after a compaction, resume, clear or fork, and up to 5 curated facts per prompt, with a separate match for a computed fact. Explicit search can return the full text.
- Check. A verifier reads code, git, docs and permitted machine sources. It records evidence for its decisions and leaves unresolved questions for you; a question that went moot is closed, and an agent that can prove the answer to one closes it (
tacit questions close), so you see only the ones no source settles. An answer you type in a session, under the question's own words, is your answer: an agent relays it (tacit questions close --proof words). A daily rotation sends the facts unchecked longest back to the curator's model with the proof code gathers, stamps eachlast_checked, and retires, redirects, notes or compresses only what the proof shows; it asks you about your own facts instead of changing them. - Organize. Every project folder has a record that code checks: what it is (a repository, a folder, an area of ongoing work, a bounded topic), its status and its history, decided by the curator's model on evidence from git and sessions, or by you on the Folders page. A folder suppressed into another moves its facts there. Dead and shipped folders go quiet in the hooks and stay searchable. An area's facts arrive before its tools are used, a topic's when the prompt names it, and each folder can carry an overview whose every line cites its facts.
Git also supplies hot spots, module maps, committed measurements and deletion-based staleness checks. Those steps need no model. The app brings facts, sources, history and review decisions together.
New local stores require evidence for owner rulings. Existing and server-created stores switch to that definition with the ruling audit.
The methods guide explains the ranker, curation, ruling proof and verification. The store contract defines the file format and write rules.
The Go client holds the git store and search index locally. Hooks and MCP read from that local copy. Model jobs run through your selected agent CLI on the machine you configure for them. The dreamer, curator, conflict judge and verifier can each use a different runner.
For shared stores, a small Elixir server adds git transport, signed writer identities and a change feed. Writers add notes to their own inboxes; the curator writes the rest of the store. Clients fetch changes and rebuild their local indexes. The server holds no model credentials.
Keep operator settings in an untracked file. The repository ignores config/local.yaml; config/example.yaml contains generic values:
cp config/example.yaml config/local.yaml
chmod 600 config/local.yaml
export TACIT_SETTINGS="$PWD/config/local.yaml"
tacit initOr use tacit --config /absolute/path/config/local.yaml <command>. On Windows, copy the example with Copy-Item and set $env:TACIT_SETTINGS to its absolute path. An explicit config selection is carried into installed hooks, MCP commands and jobs.
Without an override, Tacit reads ~/.config/tacit/config.yaml on Linux/macOS or %APPDATA%\tacit\config.yaml on Windows. A user-config symlink can point to the ignored repository file so it loads from any working directory. Relative paths resolve against the actual settings file, including a symlink's target. A dangling config link is an error. Tacit loads only the selected file; it does not search other project checkouts for settings.
Precedence: command flags, then environment values (including a job's --env-file), then YAML, then generic defaults. Unknown fields and missing explicitly selected files fail before model work. Hooks with bad settings fail open without output. Store provider credentials in the selected CLI or the job env file.
By default a lexical score decides which matching facts a prompt sees, with no model call, and that is what we recommend: in live agent sessions a model selector did no better (eval/VALUE.md, "The prompt selector in live sessions"). Optionally a model judges each candidate: does it add something useful for this request, beyond topic overlap? Of the models we measured for that, Jev (TypeSafe, hosted) was the most accurate and fastest. To keep data in your AWS account, Amazon Nova Micro on Bedrock never picked a wrong fact in our runs, but it kept fewer useful ones. Any System One-compatible server, Bedrock model or OpenAI-compatible endpoint can be plugged in:
utility:
provider: jev # or: bedrock, systemone, openai
key_file: ~/.config/tacit/typesafe.envCode still decides scope and limits first, and a failed or slow model falls back to the lexical selection. Setup for every provider, the thresholds and the full benchmark: Choosing what each prompt sees.
Every YAML option is listed here:
| Option | Environment equivalent | Meaning / default |
|---|---|---|
store |
TACIT_STORE |
Git store; ~/.local/share/tacit/store |
projects |
TACIT_PROJECTS |
Checkouts root; ~/projects |
index |
TACIT_INDEX |
Local search index; ~/.local/state/tacit/index |
keys |
TACIT_CONFIG |
Writer-key directory; ~/.config/tacit |
local_overlay |
TACIT_LOCAL |
Local notes for a read-only clone; ~/.local/share/tacit/local |
local_layer |
TACIT_LOCAL_LAYER |
on: a read-only clone dreams and curates its own sessions into its local overlay, which never leaves the machine; off (default) |
owner_names |
TACIT_OWNER_NAMES |
Owner name aliases; YAML list, comma-separated environment value |
memory_md |
TACIT_MEMORY_MD |
on (default): the curator's writes generate the flat MEMORY.md as before; off: they stop, and the next write removes the store's copy (tacit index too). For clients from before the folder indexes (_index.md); turn it off only once every client runs a version that reads them. The setting, and MEMORY.md, will be dropped then |
hermes_db |
TACIT_HERMES_DB |
Hermes session store the dreamer and the owner's words read; ~/.hermes/state.db when it exists, off for none |
delivery.repo_start |
TACIT_DELIVERY_REPO_START |
on (default): in a repo the SessionStart block is the repo's own rules and standards, then decisions and past mistakes; off: the release 0.7.1 block |
delivery.repo_aliases |
TACIT_DELIVERY_REPO_ALIASES |
on (default): a checkout also answers to every remote's repository name in its git config and its root manifest's package name |
delivery.prompt_metadata |
TACIT_DELIVERY_PROMPT_METADATA |
on (default): the prompt block adds the repo's fact whose applies_to paths or commands the prompt names |
delivery.prompt_action |
TACIT_DELIVERY_PROMPT_ACTION |
on (default): the prompt block adds the repo's best rule or decision for the request when it has none |
delivery.instruction |
TACIT_DELIVERY_INSTRUCTION |
on (default): the SessionStart title and the MCP server's instructions say what tacit holds and ask for one search before an action that changes something (the server's also point to tacit_tree); off: neither, and the server has no instructions |
delivery.tool_push |
TACIT_DELIVERY_TOOL_PUSH |
on (default): the PreToolUse hook gives the one matching rule or decision before an edit or a shell command |
delivery.tree_pointer |
TACIT_DELIVERY_TREE_POINTER |
on (default): when the SessionStart repo block shows fewer of the repo's facts than it has, its last line gives their count and the tree call that lists them |
| (environment only) | TACIT_DELIVERY_AREA_PUSH |
on (default): before an MCP tool call or shell command an area's tool patterns or commands match, the PreToolUse hook gives a few of the area's rules and decisions, once a session, in a repo or not |
| (environment only) | TACIT_DELIVERY_AREA_CEILING |
Most lines of one area push; default 3 |
| (environment only) | TACIT_DELIVERY_TOPICS |
on (default): a prompt that names a live topic searches its folder too |
| (environment only) | TACIT_DELIVERY_WORKSPACE |
on (default): a session started in a folder that is in no repository but holds several (a workspace whose packages are each a checkout under src/, a folder of checkouts) reads all of them; at most 8 repositories, never home or above |
| (environment only) | TACIT_DELIVERY_PROMPT_REPO_RANK |
on (default): at the prompt the session's repositories' rules and decisions weigh TACIT_DELIVERY_PROMPT_REPO_BOOST (1.5) times their score, another project's facts 1/TACIT_DELIVERY_PROMPT_OTHER_PENALTY (1.5); TACIT_DELIVERY_PROMPT_PENALIZE_MACHINES=on penalizes this machine's facts too |
| (environment only) | TACIT_ROTATION_MAX |
Facts one rotation run checks; default 0, every fact that is due |
| (environment only) | TACIT_ROTATION_AGE_DAYS |
Days a checked fact rests before the rotation checks it again; default 30 |
| (environment only) | TACIT_FORGE |
off to check no repository name on the forge; by default the checks ask GitHub through gh when it is installed and logged in (SPEC.md, Checked claims) |
| (environment only) | TACIT_OVERVIEW_MAX, TACIT_OVERVIEW_CHANGE_PCT |
Overviews one curate writes (default 10), and the share of a folder's facts that must change for a new one (default 20) |
delivery.start_ceiling |
TACIT_DELIVERY_START_CEILING |
Most lines of the SessionStart repo block; default 6 |
delivery.prompt_ceiling |
TACIT_DELIVERY_PROMPT_CEILING |
Most curated lines of the prompt block above its floor; default 5 |
delivery.prompt_relative |
TACIT_DELIVERY_PROMPT_RELATIVE |
A prompt line also needs this share of the best line's score; default 0.7, 0 for none |
delivery.meta_ceiling |
TACIT_DELIVERY_META_CEILING |
Most metadata lines per prompt and per tool call; default 1 |
delivery.log |
TACIT_DELIVERY_LOG |
on (default): each hook block, with what its gates left out, is a line of this machine's private delivery log (delivery/ in the state directory, mode 0600, never sent; a request's terms the store's index holds, never its text; SPEC.md, Delivery log) |
delivery.log_days |
TACIT_DELIVERY_LOG_DAYS |
Days of the delivery log kept; default 30 |
delivery.titles |
TACIT_DELIVERY_TITLES |
on (default): in a harness with tacit's MCP server (tacit install claude), the start, prompt and shell-command push blocks print an agent's note as a title (name, whose, type) the agent opens with tacit_fact; the owner's rules, rulings, statements and the notes holding their words or confirmed by them stay whole; off prints whole lines everywhere (SPEC.md, Titles) |
| (environment only) | TACIT_DELIVERY_MARK_RATE |
Share of prompt blocks that ask the agent to mark which lines helped (tacit_mark); default 0.05, 0 for none (SPEC.md, Self-marks) |
| (environment only) | TACIT_DELIVERY_JUDGE |
on (default): at the end of a full dream run, a model judges a sample of the delivered lines with hindsight (relevant, confused, novel) through claude -p on the dreamer's Bedrock route (Bedrock itself, or a Bedrock endpoint at a loopback address of the machine with the auth skipped), skipped where there is none; off for none (SPEC.md, The dreamer's judge) |
| (environment only) | TACIT_DELIVERY_JUDGE_DAILY |
Lines judged a day at most; default 36 |
| (environment only) | TACIT_DELIVERY_JUDGE_MODEL |
The judge's model for claude -p; default global.anthropic.claude-fable-5-2 |
verify_roots |
TACIT_VERIFY_ROOTS |
Extra permitted source directories; YAML list, PATH separator in environment; every directory must exist |
runner |
TACIT_RUNNER |
Default CLI for all model jobs; claude |
runners |
TACIT_<ROLE>_RUNNER |
Per-role CLI overrides |
models |
TACIT_<ROLE>_MODEL |
Per-role model IDs accepted by the CLI; Claude alias opus for dream, curate, judge and verify |
models.verify_fallback |
TACIT_VERIFY_FALLBACK_MODEL |
Legacy same-runner verifier fallback; an empty environment value disables it |
efforts |
TACIT_<ROLE>_EFFORT |
Per-role reasoning effort; omitted uses the CLI default, empty clears an override |
profiles |
TACIT_<ROLE>_PROFILE |
Per-role Codex profile name; empty clears it |
dream_max_runtime |
TACIT_DREAM_MAX_RUNTIME |
Extraction batch runtime; default 45m, 0 disables the batch limit; dream --max-runtime wins |
dream_agent_windows |
TACIT_DREAM_AGENT_WINDOWS |
Dream windows with no turn of the owner's: all (default), recent:<days> or none; an owner window whose agent content is not taken is cut to the owner's turns with 12 lines around each; dream --agent-windows wins (SPEC.md "Owner windows and agent windows") |
stale_workers |
TACIT_STALE_WORKERS |
Facts the stale step checks at once, each with its own git commands; default 4; set 1 on a busy machine; stale --workers wins |
timeouts |
TACIT_<ROLE>_TIMEOUT |
Positive Go duration per model attempt, such as 10m; default 20m |
commands |
TACIT_<TOOL>_COMMAND |
Executable name or path; default is the tool name |
runner_args |
TACIT_<TOOL>_ARGS |
Extra argv without a shell; YAML list or JSON array in the environment |
fallbacks |
TACIT_<ROLE>_FALLBACK |
One fallback route per role; JSON object in environment, null disables it |
<ROLE> is curate, judge, dream or verify (uppercase in environment names). <TOOL> is claude, codex, hermes, grok, pi, muse or agy. An explicit non-Claude runner uses its own model when no model is set. Per-role effort/profile options take precedence over general runner arguments. Accepted effort values are none, minimal, low, medium, high, xhigh, max and ultra, subject to the selected CLI/model. Effort adapters exist for Claude, Codex, Grok, Muse and pi; use runner_args for other tools.
A fallback route has these fields:
| Field | Meaning |
|---|---|
runner |
Required supported CLI name |
model |
Model ID; omitted uses that CLI's default |
effort |
Optional reasoning effort |
profile |
Optional Codex profile name |
The generic verifier fallback is Claude sonnet; other roles have none. An explicit runner or model selection disables that generic fallback unless one is configured. An explicit TACIT_<ROLE>_FALLBACK route wins over the legacy TACIT_<ROLE>_FALLBACK_MODEL override. Fallbacks run once for provider capacity, temporary service failures, expired authentication, a missing runner or an attempt deadline. Provider status and error codes decide whether to retry. They never start another fallback. Refusals, access denial and malformed output stop the job.
For example, users can choose different runners without publishing their settings:
runner: claude
runners:
dream: muse
models:
dream: your-model-id
commands:
muse: ./bin/muse
fallbacks:
dream:
runner: claude
model: haikuCheck a setup without sending model requests:
tacit doctor
tacit doctor --models
tacit doctor --role dream --jsondoctor checks Git 2.29+, scrump's text masking canaries (a scrump before 0.2.0, which leaves a quoted value a cut left open, fails) and its records mode (--records, scrump 0.2.0 and later; without it a warning, since batched texts then go joined by a boundary; a malformed answer fails), effective role arguments, attempt timeouts and Codex profiles. It checks primary and fallback executables with --version. Missing runners are warnings for a memory-only installation. --models requires every configured runner; --role requires only that role and its fallback. --json prints check records. Exit 0 means the requested offline checks passed, 1 means a check failed, and 2 means invalid command options or settings. Provider credentials, model availability and live completions need a separate live test. Grok preflight also checks the provider settings and native file references needed by its isolated runtime.
Malformed extraction or incomplete judge answers leave the batch pending. Every conflict verdict is validated before any fact is retired. A fresh installation can curate observations without Claude or Codex owner history. Unbacked owner notes stay pending; owner rulings still require proof.
Grok jobs use a fresh runtime home for every request. Provider/model settings come from GROK_HOME (default ~/.grok); native sign-in and requirements files are referenced without copying credentials. User hooks, plugins, memory and MCP servers stay outside the job. Managed defaults and mandatory policy hooks are retained. Provider keys and headers in copied settings must use environment references or native auth. On Windows, file references use hard links when symlinks are unavailable; put the job cache and Grok home on the same filesystem in that case.
Local job logs record each model attempt's role, route, fallback status, input tokens and reported cost. A batch reaching its runtime or call limit pauses successfully and resumes pending windows next run. Attempt deadlines and genuine model, redaction or persistence errors still fail. Accounting records pause_reason and remaining_windows.
A null cost means the runner did not report it; zero means a reported zero. Summaries label incomplete totals as reported cost. Logs contain no prompts or model answers in these accounting records.
~ expands to the current home directory. Windows paths can use forward slashes or single-quoted YAML strings. Command paths containing a directory separator resolve against the config file; bare command names use PATH. A CLI --model option overrides the configured model. tacit --runner TOOL overrides all role runners for that invocation.
| Variable | Meaning / default |
|---|---|
TACIT_SETTINGS |
Select the YAML file; same as --config FILE |
TACIT_FOLLOW_STATE |
Follower heartbeat file; ~/.local/state/tacit/follow.json |
TACIT_DERIVE_CONFIG |
Separate derive YAML; ~/.config/tacit/derive.yaml |
TACIT_WRITER |
Writer identity used to sign a shared-store push |
TACIT_SERVER |
Server URL for scripts/mac-setup.sh |
TACIT_ENROLL_SSH |
SSH enrollment target for scripts/mac-setup.sh |
TACIT_REPO |
Code checkout used by scripts/mac-setup.sh; script's checkout by default |
TACIT_BIN |
Hermes integration executable override; installer-captured path by default |
TACIT_MODEL_JOB |
Internal recursion guard; Tacit sets it for model subprocesses |
The separate derive file accepts branches (repo-to-branch map) and ordinary_names (repo names that need explicit evidence because they are common words). Command-specific options, including job --env-file, are in the client reference. Provider variables belong to the selected CLI and can be supplied through the private job env file.
The server reads its own settings at startup:
| Variable | Meaning / default |
|---|---|
TACIT_DATA |
State root; $XDG_STATE_HOME/tacit-server or ~/.local/state/tacit-server |
TACIT_BIND |
Bind IP; tailnet IPv4 when available, otherwise 127.0.0.1 |
TACIT_PORT |
Git/API port; 7447 |
TACIT_TAILSCALED |
Tailscale LocalAPI socket; /var/run/tailscale/tailscaled.sock |
TACIT_WHOIS |
Identity lookup; localapi, or static:<ip>=<login>,... for tests |
TACIT_ALLOW_LOOPBACK |
1 permits loopback in the tailnet check; testing only |
TACIT_PUBLIC_PORT |
Optional reader-only listener on 127.0.0.1; disabled when unset |
For background work, tacit install dream (the 4-hour dreamer and the 10-minute idle job) and tacit install curate write native job files and print start commands. Select the private config and provide the job environment before starting them. See portable job setup.
Folder records, areas/ and topics/, overviews and last_checked form store format 1. A binary from before it reads such a store wrong, so nothing writes them until the store holds the format marker. Install the new binary on every machine that reads the store first (tacit doctor shows each machine's format and the marker), then set the marker once with tacit format --set. The assessment, migration, overviews and rotation start with the next curate and maintain runs. The rotation checks every fact that is due unless TACIT_ROTATION_MAX is set; its cost per fact is logged in rotation.jsonl in the state directory (measured in eval/VALUE.md).
The initial evaluation uses one owner's private store and Claude Code/Codex sessions. Results cover that workload; the original data is private. The scripts and methods are available to run on your own data.
Those measurements shaped the client: lexical retrieval beat the dense variants tested, splitting notes into individual facts improved delivery, and larger context blocks cost more without helping. The verifier remains limited: in the held-out sample it agreed with the owner on a minority of findings and missed most of the owner's retirements. Human review remains part of the method.
Methods and decisions · Grep baseline · Run the synthetic sample
The synthetic sample runs without a server or model account. It demonstrates the formats and scoring. Long-session outcomes and delivery in other harnesses have not been measured.
At 64 MiB, tacit episode brings a median of 3.7K characters into context per task. grep prints whole transcript lines and brings 36K. Each task's matching events include one with a fake secret. Every grep output carried one. None reached tacit's output: scrump masked the ones it printed, and the rest lay outside what it printed. tacit found the right value in all 112 tasks, grep in 111 (the misses). Both counts assume the whole output reaches the agent, with no harness cap on tool output. Synthetic sessions, 16 tasks per size: python3 -I eval/recall/bench.py.
grep is faster: 1.9 ms per task at 1 MiB and 33 ms at 64 MiB, where tacit takes 617 ms and 1.0 s. Most of a small call's time is scrump loading its rules, which tacit starts before it reads the transcript. Times are from one machine; same run and command.
The numbers: median (min to max) of 16 tasks; a task's time is the median of 5 launches
| MiB | Arm | Right | Characters | Planted secrets | Calls | Time |
|---|---|---|---|---|---|---|
| 1 | tacit | 16 of 16 | 550 (386 to 11,190) | 0 (0 to 0) | 1 (1 to 3) | 617 ms (567 ms to 1.7 s) |
| 1 | grep | 16 of 16 | 3,416 (452 to 19,677) | 1 (1 to 2) | 1 (1 to 1) | 1.9 ms (1.5 ms to 3.8 ms) |
| 2 | tacit | 16 of 16 | 756 (388 to 9,474) | 0 (0 to 0) | 1 (1 to 3) | 629 ms (528 ms to 1.7 s) |
| 2 | grep | 16 of 16 | 9,876 (454 to 25,798) | 2 (1 to 3) | 1 (1 to 1) | 2.4 ms (2.1 ms to 3.6 ms) |
| 4 | tacit | 16 of 16 | 848 (459 to 12,720) | 0 (0 to 0) | 1 (1 to 4) | 648 ms (553 ms to 2.2 s) |
| 4 | grep | 16 of 16 | 7,131 (914 to 31,968) | 2 (1 to 2) | 1 (1 to 1) | 3.8 ms (3.1 ms to 5.2 ms) |
| 8 | tacit | 16 of 16 | 858 (459 to 16,723) | 0 (0 to 0) | 1 (1 to 4) | 593 ms (531 ms to 2.4 s) |
| 8 | grep | 16 of 16 | 10,400 (2,561 to 25,115) | 1 (1 to 2) | 1 (1 to 1) | 5.6 ms (4.9 ms to 7.8 ms) |
| 16 | tacit | 16 of 16 | 849 (461 to 18,937) | 0 (0 to 0) | 1 (1 to 4) | 612 ms (544 ms to 2.3 s) |
| 16 | grep | 16 of 16 | 12,636 (2,557 to 27,297) | 1 (1 to 2) | 1 (1 to 1) | 11 ms (9.8 ms to 14 ms) |
| 32 | tacit | 16 of 16 | 4,231 (509 to 17,692) | 0 (0 to 0) | 1.5 (1 to 5) | 822 ms (499 ms to 2.6 s) |
| 32 | grep | 16 of 16 | 25,626 (2,520 to 74,165) | 2 (1 to 2) | 1 (1 to 1) | 19 ms (16 ms to 27 ms) |
| 64 | tacit | 16 of 16 | 3,688 (465 to 30,474) | 0 (0 to 0) | 1.5 (1 to 10) | 1.0 s (689 ms to 5.8 s) |
| 64 | grep | 15 of 16 | 35,838 (2,597 to 384,925) | 2 (1 to 2) | 1 (1 to 1) | 33 ms (32 ms to 46 ms) |
Agent writes and model digests pass through scrump before storage or a model call. A failed redaction stops the write. Local commits and shared pushes also check for known token shapes.
Local mode uses your OS account for access. Shared mode adds tailnet identity, signed keys and per-writer inbox enforcement. An optional public listener accepts signed readers only.
Model jobs send redacted digests and fact excerpts to the provider configured in the selected CLI. The verifier can read permitted source files. Choose the provider with that access in mind.
Security policy and private reporting · Shared-store details
| Guide | Covers |
|---|---|
| Local and portable setup | Configuration, dependencies, native jobs and validation |
| Shared-store setup | Server deployment, keys, machine roles and job configuration |
| Client reference | Commands, flags, hooks and the app |
| Methods | How facts are collected, delivered and checked |
| Choosing what each prompt sees | The optional model selector: Jev, Bedrock, any System One or OpenAI-compatible model, and the benchmark |
| Evaluation | Scripts, samples and how to measure another store |
| Contributing | Development, tests and pull requests |
Agent configurations are checked in CI with agnix, including the hooks and MCP settings generated by the client.
Apache 2.0. Bundled fonts use the SIL Open Font License 1.1; see NOTICE.