Agent instructions
Connecting the Engrym MCP server hands your agent the tools. Agent instructions tell it how to use them: a short, stable contract written into the config files your AI tools already read, so every agent that opens the repo follows the same five practices.
This page is organized in three tiers. Read only as far as you need: the first command gets a beginner running, the middle section is for an intermediate user with a config they've already tuned, and the last section is the full picture for power users and teams.
Tier 1: The fastest path
If you just want it to work, run the setup command from the dashboard in your repo folder, the folder where your .git lives. You'll need Node.js 18 or newer (node --version to check):
ENGRYM_SETUP_TOKEN=<your-token> npx @engrym/cli@latest setup claude-code
Name your agent in place of claude-code: cursor, codex, gemini or windsurf. The command connects the Engrym MCP server, so your agent has the tools the contract tells it to call, then writes into the folder:
- the contract as a managed block in your agent's config (
CLAUDE.mdfor Claude Code,AGENTS.mdfor Codex and Windsurf,GEMINI.mdfor Gemini CLI,.cursor/rules/engrym.mdfor Cursor); - a deep
ENGRYM.mdreference at your repo root; - the
engrym-extractcommand, which you run in your agent (/engrym-extract, or$engrym-extractin Codex) to extract your documents on its own model.
The terminal reports each file as created, updated or unchanged; from then on, every agent that opens the repo works from the same five practices. See CLI reference for the exact paths and flags.
It is non-destructive. The contract lives inside delimited markers; everything you've written outside those markers is preserved untouched. If a file already has writing in it that Engrym did not put there, the command lists those files and asks once before it changes any of them, and --yes answers yes ahead of time. Run it again any time and it refreshes the block in place rather than duplicating it.
Already connected, or using several agents in one repo? npx @engrym/cli@latest init --write-instructions writes the block into every agent config it detects, plus ENGRYM.md, without touching the MCP registration.
Tier 2: I already have a tuned config
If you'd rather place the block yourself (say you keep your config files just so) print it instead of writing it:
npx @engrym/cli@latest setup --print
That prints the contract block; copy it and paste it where you want. Add --copy to send it straight to your clipboard:
npx @engrym/cli@latest setup --print --copy
(engrym init takes the same flags, --print-instructions and --print-instructions --copy, if you prefer one command for everything.)
The block itself
Here is the exact block the CLI prints, so you can grab it without running anything. Paste it inside whichever config file your tool reads.
<!-- BEGIN ENGRYM MANAGED BLOCK — auto-generated, do not edit by hand -->
<!-- engrym-contract v2 15f1227e0159 -->
<!-- This block is managed by Engrym (`engrym setup`). Edits inside it are overwritten on the next refresh. Add your own instructions OUTSIDE the markers. -->
# ENGRYM: the shared knowledge contract
This project keeps its decisions, conventions, and constraints in Engrym, so
every agent that touches the code works from the same source of truth. You are
one of those agents. Four practices keep that source of truth honest. Follow
all four.
1. **Query before you decide.** Before any non-trivial decision, read what the
project already settled (call `get_project_brief`, then `get_relevant_knowledge`
for the area you are in). It is fail-soft: if the brain is empty or a call
fails, proceed on your best judgment; the brief informs your work, it never
gates it.
2. **Write what you learn back.** When your work produces durable knowledge,
persist it through `write_document` (plain markdown; the brain re-derives it,
born provisional, a human ratifies it) so the next session inherits it.
3. **Scope by folder.** Ask for the knowledge that bears on the files in front of
you, not the whole project: a narrow, on-point answer keeps the signal sharp.
4. **Declare your intents.** Before a substantial change, call `broadcast_intent`
to tell other agents what you are taking on, and release it when you are done.
At session start, `get_project_brief` reports how many documents are waiting for
extraction. If any are, ask the user before you extract them, and never extract
unprompted unless this project has opted in to auto-pull. On that call, pass the
stamp from this block's `engrym-contract` line as `contractStamp`.
The live tool list comes from the Engrym MCP server: connect it and the current
tools are available to you every session, always in sync.
<!-- END ENGRYM MANAGED BLOCK -->
Where the block goes
Each agent reads its instructions from a different file. engrym setup <agent> writes to the one for the agent you name, and init --write-instructions writes to all of them; if you're pasting by hand, here's the destination per tool:
| Tool | Config file |
|---|---|
| Claude Code | CLAUDE.md |
| OpenAI Codex | AGENTS.md |
| Gemini CLI | GEMINI.md |
| Cursor | .cursor/rules/engrym.md |
| Windsurf | AGENTS.md |
Managed-block semantics
- Delimited. The block is bounded by
<!-- BEGIN ENGRYM MANAGED BLOCK -->and<!-- END ENGRYM MANAGED BLOCK -->markers. - Non-clobbering. Anything outside those markers (your own house rules, notes, prompts) is left exactly as you wrote it.
- Refreshed in place. Re-running
engrym setup <agent>, bareengrym setup, orengrym init --write-instructionsre-renders the contract between the markers to the latest version. It never appends a second copy.
Tier 3: Understand it
What ENGRYM.md is
ENGRYM.md is the deep reference file Engrym writes at your repo root. The managed block (above) is the short contract that goes into each tool's config; ENGRYM.md is the longer version: the five practices spelled out, followed by the full tool taxonomy. The counts differ on purpose: the managed block lists four practices and gives the fifth, checking for extraction work at session start, as one line under them, while ENGRYM.md spells it out as practice 5. An agent that wants the detail behind a practice reads ENGRYM.md; an agent that just needs the contract reads the block in its own config file.
The four practices
The contract is four practices, verbatim from the block the CLI ships:
- Query before you decide. Before any non-trivial decision, read what the project already settled (call
get_project_brief, thenget_relevant_knowledgefor the area you are in). It is fail-soft: if the brain is empty or a call fails, proceed on your best judgment; the brief informs your work, it never gates it. - Write what you learn back. When your work produces durable knowledge, persist it through
write_document(plain markdown; the brain re-derives it, born provisional, a human ratifies it) so the next session inherits it. - Scope by folder. Ask for the knowledge that bears on the files in front of you, not the whole project: a narrow, on-point answer keeps the signal sharp.
- Declare your intents. Before a substantial change, call
broadcast_intentto tell other agents what you are taking on, and release it when you are done.
Lean by design: the tool list stays live
The block written into your host config stays lean on purpose. It carries the stable contract (the four practices) and nothing that churns. The volatile part, the list of tools, is discovered live from the Engrym MCP server at session start, not baked into your config.
That separation is the whole point: when Engrym ships a new MCP tool, your agent picks it up the next session automatically. Adding a tool never forces you to hand-edit ENGRYM.md or re-paste a block. Your config holds the contract that rarely changes; the server holds the roster that does.
Refresh and staleness
The contract evolves slowly, but it does evolve. After you upgrade the CLI, refresh the block:
engrym setup
Run it in your repo folder. It re-renders the blocks Engrym wrote there (with engrym setup <agent> or init --write-instructions) to the latest version, preserving your out-of-marker content; a block you pasted yourself is left for you to replace. The block carries a version stamp (the engrym-contract line under the BEGIN marker). Your agent reports that stamp to Engrym at the start of a session, and the dashboard shows it per agent under Settings → Connected agents: Up to date, Out of date when the block is behind, or Not seen yet when the agent has not reported, which is what an older block shows. If you pasted the block yourself, grab the latest with engrym setup --print.
One Brain, many agents
The contract is the same wherever you write it: CLAUDE.md, AGENTS.md, GEMINI.md, or .cursor/rules/engrym.md. So Claude, Codex, Gemini, Cursor, and Windsurf all work the same project through one contract: they read the same decisions before acting, write what they learn back the same way, and declare intents the others can see. Many agents, one Brain, one set of rules: that's how their work corroborates instead of colliding.
Windsurf reads AGENTS.md too, the same file as Codex, so engrym setup windsurf writes the block there, and a repo set up for both carries one copy. ChatGPT and Claude Desktop have no repo folder for a file to live in. They pick up the live tool list from the MCP server the same way, so the practices still apply; to hand them the contract too, grab the block with engrym setup --print and paste it into the instructions you give that app for this project.
The full ENGRYM.md
This is the complete deep reference, copy it to your repo root if you'd rather place it by hand than run engrym setup <agent>. The tool taxonomy at the end is generated from the canonical registry, so it stays in sync with the server.
<!-- engrym-owned: managed by engrym setup, do not edit -->
# ENGRYM: the shared knowledge contract
This project keeps its decisions, conventions, and constraints in Engrym, so
every agent that touches the code works from the same source of truth. You are
one of those agents. Five practices keep that source of truth honest. Follow the
first four always; the fifth applies when this project extracts on your compute.
## 1. Query before you decide
Before any non-trivial decision (an architecture choice, a convention, a
dependency, a data shape) read what the project already decided. Call
**`get_project_brief`** and read its five sections: the north star, the active
constraints, the active conventions, the recent decisions, and the current
focus. When you need the detail behind a specific area, call
**`get_relevant_knowledge`** for the knowledge scoped to that topic. Let what is
already settled shape what you do next.
This consult is **fail-soft**. If the brain is empty, or the call fails, do not
block. Proceed on your best judgment and capture what you learn below. The brief
informs your work; it never gates it.
## 2. Write what you learn back
When your work produces durable knowledge (a decision and its rationale, a
convention, a constraint, a piece of orienting context) write it back, so the
next session (yours, or a teammate's agent) inherits it instead of relearning it.
Persist through **`write_document`**: author plain markdown, and the brain
re-derives the knowledge from it. What you write is born **provisional**; a human
ratifies it before it becomes canonical. That review is the point, not a delay:
it is what lets the next agent trust this source of truth.
Do **not** reach for `add_brain_entry` to record your work. That tool writes a
single raw entry that skips the document-and-review loop; it is for narrow,
already-structured facts, not for the knowledge your work produces as you go.
When you are unsure which shape a capture deserves, the rule in "Document or
atom: the shape of a write" below decides it.
## 3. Scope your queries to the work in front of you
Ask for the knowledge that bears on the files you are actually changing, not the
whole project at once. Scope your retrieval to the relevant folder or topic. A
narrow, on-point answer beats a broad one you have to wade through, and it keeps
the brain's signal sharp.
## 4. Declare what you are about to do
Before you start a substantial change, tell the other agents working this
project what you are taking on. Call **`broadcast_intent`** to declare your
intent, and release it when you are done. Coordination only works if intents are
visible: a declared intent is how two agents avoid editing the same surface into
a conflict.
## 5. Check for extraction work at session start, and ask
A project in **agent mode** (the default for new projects) has you, the connected
agent, run its extraction on your own model and subscription, instead of a
server. Nothing pushes that work to you. Call **`pull_extraction_work`** and it
hands you the pending documents and the prompt to extract them with; run that
prompt over each document, then post the result back with
**`submit_extraction`**, one call per document. Keep pulling until a pull
returns no `nextCursor`.
**At session start, check and ask.** `get_project_brief` (practice 1) reports how
many documents are waiting for extraction. If that number is above zero, tell
the user and ask before you start, for example: "Engrym has 12 new documents
waiting. Extract them now?" Extract only if they say yes. If they say no, carry
on with the session and do not ask again in it. Never extract unprompted.
The user can also ask you to extract at any time, in their own words or with the
`engrym-extract` command where their agent has one. Their request is all the
permission you need.
**The one exception: the project's auto-pull opt-in.** A project's admins can
record, in the Engrym dashboard, consent for you to pull without asking. That
recorded opt-in counts as the user's answer. The signal is `autoPull`
(`{ consent, reconfirm, eagerness }`) in the extraction config, which you can
read from **`get_team_context`** or the extraction config read. Read it **live**
before each unprompted pull: never assume it, and never cache it across
sessions.
- If `autoPull.consent` is **false** (the default): ask first, as above.
- If `autoPull.consent` is **true**: you **may** pull and process pending work
without asking, governed by two fields. **`eagerness`**: `opportunistic` means
pull at session start **and** again whenever you next work on or touch this
project; `session_start` means pull once, at the start of the session, only.
**`reconfirm`**: if true, get an OK from the user before **each** auto-pull,
including later ones in the same session; if false, proceed (the dashboard
opt-in is the consent).
What you submit lands **provisional** and is human-ratified, exactly like
practice 2: you are proposing knowledge, not publishing it. However the pull was
authorized, everything downstream is the same: submissions stay
ratification-gated, the agent-extraction cap still applies, and you run the
model on your own subscription. If `pull_extraction_work` reports the project
uses its own API key (`byok` mode), there is nothing for you to pull and this
practice does not apply. That is normal, not an error.
## Document or atom: the shape of a write
Engrym has two write shapes, and the choice matters more than it looks. A
**document** (`write_document`) is versioned prose the brain re-derives atoms
from; a **single atom** (`add_brain_entry` for a fact, `log_decision` for a
decision) is one claim minted directly, final as written. Choose by these
signals:
| Signal | Write a document (`write_document`) | Log a single atom (`add_brain_entry` / `log_decision`) |
| --- | --- | --- |
| Unit of knowledge | a page, a body a human would read | one self-contained fact |
| Carries a why, rationale, or alternatives considered | yes | no |
| Has examples, edge cases, caveats | yes | no |
| Will be reconciled against code (needs a durable source anchor) | yes | rarely |
| Evolves over time / benefits from version history | yes; documents are versioned | atoms supersede, but carry no narrative history |
| Should be re-derivable (regenerate atoms if the model improves) | yes; atoms re-project from the doc | no; a hand-logged atom is final |
| In-the-moment capture where a full doc would be overkill | no | yes; a decision just made, or a lone constraint |
The one-line rule: **does it carry a why, examples, or a page a human would
read? Write a document. Is it one self-contained fact with nothing to preserve
beyond the claim itself? Log an atom.** And when in doubt, write the document:
atoms are a re-derivable projection of documents. A document can always
regenerate its atoms; a bare atom can never recover its document, and the why,
the source, and the reconciliation anchor are lost for good.
Two refinements:
- **One home per fact-class.** Before you write, check whether the fact's
authoritative home already exists (query first, practice 1) and update the
fact there, rather than restating it in a new document. Restating one fact
across five documents mints near-duplicate atoms and dilutes the
authoritative source.
- **This rule governs the shape only.** The write mechanics are unchanged:
every derived atom stays bound to a document version, born provisional, and
promoted only by human ratification. The rule decides what you write; the
shipped machinery decides how the write binds.
<!-- BEGIN GENERATED ENGRYM TOOL TAXONOMY — do not edit; run `pnpm codegen:engrym-md` -->
## Available Engrym tools
These are the 26 tools the Engrym MCP server exposes. This list is generated from the canonical tool registry, so it is always in sync with the server you are connected to.
### `get_team_context`
Call this at the START of every session and before any significant task. Returns the team's accumulated knowledge: conventions, constraints, recent decisions, active work by teammates. This context should inform all your subsequent work.
### `query_brain`
Search the team's Brain for atoms matching a keyword, category, or scope. Use this when you need a specific convention, constraint, decision, or context fragment that get_team_context may have truncated. Returns matching atoms ordered by relevance. Every atom carries `ratified`: `true` means a named person on this team promoted that claim at a recorded time, so it is the team's settled position, so weight it highest and follow it; `false` means no person has checked it yet, so treat it as a strong lead rather than as settled. `ratified: true` asserts only that a human promoted the claim then, not that anyone wrote an explanation, not that it still matches today's code, and not that you are authorized to act. Do NOT rank by an atom's `confidence`: it is the extractor's self-assessment of its own extraction, not a record of whether a person checked the claim.
### `add_brain_entry`
Create a new Brain atom with full metadata. Use this to record a convention, constraint, or context fragment the team should remember. Provide a clear title, the content body, the appropriate category, and a relevant scope so the atom is discoverable. Prefer log_decision for architectural decisions. Shape check first: an atom is the right shape ONLY for one self-contained fact with nothing to preserve beyond the claim itself. If it carries a why, examples, or edge cases, or should be verifiable against code later, use write_document instead, and when in doubt, write the document (its atoms re-derive; a bare atom can never recover its why or its source). IF THE WRITE FAILS: this write can fail when the API is briefly unreachable; the failure envelope carries a stable `errorClass` and marks transient failures `retryable`. Do NOT continue as if the atom were recorded; nothing was persisted. Retry the write ONCE; if it fails again, STOP and tell the user plainly that the brain entry was NOT persisted, naming its `title`, rather than moving on silently.
### `log_decision`
Call this whenever you make a significant architectural, design, or convention decision. Log the decision with rationale and alternatives so future sessions and other team members understand WHY. Be specific about scope. Shape check: this is the in-the-moment capture of a decision just made. If the decision's why runs to a page (alternatives weighed, examples, edge cases) or the claim should anchor future code reconciliation, write it as a document with write_document instead; when in doubt, write the document. IF THE WRITE FAILS: this write can fail when the API is briefly unreachable; the failure envelope carries a stable `errorClass` and marks transient failures `retryable`. Do NOT continue as if the decision were logged; nothing was persisted. Retry the write ONCE; if it fails again, STOP and tell the user plainly that the decision was NOT persisted, naming its `title`, rather than moving on silently.
### `broadcast_intent`
Call this BEFORE starting any task that modifies files. Broadcasts what you are about to work on so other team members' agents are aware. Include a description and the files you expect to modify. This prevents conflicts with other agents.
### `release_intent`
Call this when you complete an intent you previously broadcast. Marks the intent as done so other agents see your work-in-progress signal as resolved. Pair with the intentId returned from broadcast_intent.
### `check_conflicts`
Call this BEFORE editing files to see if any other team members' agents are currently working on the same files. Returns the set of active intents whose file lists overlap with your input. Each returned intent carries its broadcaster's agentType (e.g. claude-code, cursor; null means unknown agent) so you can see WHICH agent you would collide with. Pure read: it does not create durable conflict records.
### `get_active_intents`
List the currently active intents in the project so you can see what other agents are working on. Each intent carries its broadcaster's agentType (e.g. claude-code, cursor; null means unknown agent) so you can see WHICH agent holds it. Use this for situational awareness, not as a substitute for check_conflicts (which filters by your file list).
### `save_session_state`
Persist your session state (last task description, recently modified files, recently authored atom IDs, unfinished work, optional custom MCP state) so the next session, possibly on a different machine, can resume from where you left off. Call this near the end of meaningful work.
### `get_session_state`
Retrieve the latest persisted session state for the current user. Use this at session start (after get_team_context) to resume continuity from a prior session, including across machines.
### `get_related_atoms`
Walk the connections out from one atom. Call this when you want to see everything connected to a decision, constraint, or context atom (what it was DERIVED FROM, what EXTENDS it, what CONTRADICTS it, and what is otherwise RELATED) so you understand the reasoning around it instead of reading it in isolation. Pass the atomId (e.g. from query_brain or get_team_context). Returns one entry per connecting edge: the neighbour atom plus the edge's kind (derived-from | contradicts | extends | related), direction (outgoing = this atom points at the neighbour; incoming = the neighbour points at this atom), and a confidence band + score. Read the kind and direction to follow the chain (derived-from + incoming traces what LED TO a decision; contradicts flags tension to resolve), and weigh each edge by its confidence. That edge `confidence` is about the LINK, and is not the same field as the neighbour atom's own `confidence`. Each edge ALSO carries its own three-state `trust`, never a boolean, and it answers a different question from either confidence field: `confidence` is how sure the writer was of the connection, `trust` is who has looked at the connection since. `unreviewed`: no policy admitted this link and no person has looked at it. `policy-accepted`: this project has a link policy an owner or admin switched on, and the link was recorded under that policy WITH NO PERSON HAVING READ IT, so do not weight it as a person's judgment. `human-ratified`: a named person promoted the edge at a recorded time, and that outranks the other two. Keep the edge's `trust` apart from the neighbour atom's `ratified` below: `trust` is about the CONNECTION, `ratified` is about the CLAIM at the other end, and a `policy-accepted` edge can point at an atom no person has looked at. Those are two facts, not one. Each neighbour atom carries `ratified`: `true` means a named person on this team promoted that claim at a recorded time, so it is the team's settled position, so weight it highest and follow it; `false` means no person has checked it yet, so treat it as a strong lead rather than as settled. `ratified: true` asserts only that a human promoted the claim then, not that anyone wrote an explanation, not that it still matches today's code, and not that you are authorized to act. Do NOT rank neighbours by an atom's `confidence`: it is the extractor's self-assessment of its own extraction, not a record of whether a person checked the claim. Edge `trust` and endpoint liveness are two different axes, and neither one tells you the other. Each neighbour also carries `status` and `supersededBy`: read them before you act on that neighbour's claim. This call returns `superseded` neighbours on purpose and does not filter them out, because an edge to a retracted claim is still a real record of the relationship. Whatever an edge's `trust` says about who has looked at the CONNECTION, it says nothing about whether the claim at the far end still stands, so when a neighbour is `superseded` follow its `supersededBy` to the claim that replaced it. Do not read a `contradicts` edge as a liveness signal either: it is a claim about two atoms' content, not about whether either one is current. The anchor atom's own liveness is NOT in this response, which carries its neighbours only, so read the anchor's `status` and `supersededBy` from the payload that handed you its atomId (query_brain, get_relevant_knowledge, get_team_context, or an atom you just wrote). If you hold the id with no such payload, you do not know whether the anchor is current, and nothing here tells you. A hub atom can have many edges, so the result is CAPPED and PAGINATED so it never floods your context: pass an optional limit (smaller-only; a larger value is clamped down to the server ceiling) to keep the payload lean, and when the returned truncated is true, pass the returned nextCursor back as cursor to page through the rest. An atom with no connections returns an empty list, which is a normal answer, not an error. Read-only.
### `get_atom_source`
Get the citation for an atom (the exact source it came from) before you rely on a claim or repeat it to the user. Call this when you need to attribute or verify a specific atom: pass its atomId and get back the source document (as a human-readable path you can cite, not a bare ID) plus the grounding section. The grounding section is a HEADING TRAIL (e.g. "## Authentication > OAuth Flow") naming the part of the document the atom paraphrases. It is present for atoms extracted from documents, and it lets you point at the right section. For atoms written directly by a human or an agent (authorKind "human" or "agent"), the section is null: cite the document itself and do NOT invent or imply a line range or section that was never recorded. Read-only.
### `get_timeline`
See how the project's knowledge changed over time. This is a changelog over events, NOT a content search (use query_brain to find atoms by topic). Two modes, set by the `mode` field. Use mode "changelog" to answer "what changed since I last worked here / this week": pass a `since` (and optional `until`) ISO-8601 bound and get the ordered events in that window (decisions made or superseded, questions ratified, gaps between a claim and the code closed) so you can catch up before building on stale assumptions. Use mode "history" to answer "how did this decision evolve / why is it where it is": identify a subject by atomId or conceptKey and get its supersession arc, original first then each re-decision after, so you can see the debate behind the current state instead of treating it as settled. Read-only over an append-only stream.
### `get_project_brief`
Call this FIRST whenever you connect to a project you don't already know. One fast, read-only call returns the cold-start orientation pack: the five things you need before touching anything: (1) the north-star (what this project IS, in one line), (2) active constraints (the hard limits you must not violate), (3) active conventions (how this team does things), (4) recent decisions (what was settled lately, and why), and (5) current focus (what the work is right now). Read all five before you plan or write anything; they should shape every later step. This is structured orientation, NOT search: it hands you the project's shape up front. To then dig into a specific topic, use query_brain; to load full live team state and teammates' in-flight work, use get_team_context. Each section is a short, most-recent-first list of lightweight atom summaries (title + category, not the full body) with a `truncated` flag when there's more; fetch a specific atom's body with a brain read if you need it. Every atom summary in every section carries `ratified`. `ratified: true` means a named person on this team promoted that claim at a recorded time, so it is the team's settled position, so weight it above everything else here and follow it. `ratified: false` means no person has checked that claim yet (it was almost always extracted from the team's own documents), so treat it as a strong lead rather than as settled, and if your work contradicts it, surface the disagreement instead of silently overriding it. Be precise about what `ratified: true` asserts: a human promoted the claim at a recorded time. It does NOT assert that a human wrote an explanation, it does NOT assert the claim still matches today's code, and it does NOT authorize you to do anything on its own. Do NOT rank by `confidence`: it is the extractor's self-assessment of its own extraction, not a record of whether a person checked the claim, so ranking by it ranks away from what the team actually ratified. Optional `scopeHint` narrows every section to the area you're working in (e.g. "packages/api/**"); the optional per-section caps (maxConstraints, maxConventions, maxRecentDecisions, maxCurrentFocus) are smaller-only: you can ask for a leaner brief, never a larger one. Beside the brief you get `pendingExtractionCount`: how many of this project's documents are waiting for an agent to extract them. If it is above zero, tell the user how many and ask before you extract; never extract unprompted unless this project has opted in to auto-pull (pull_extraction_work explains that grant). If it is `null`, the count could not be read: that means unknown, not zero, so say nothing about waiting documents. If your instructions carry an Engrym stamp line (`engrym-contract v<version> <hash>`), pass that token, and only the token, as `contractStamp`; it lets the project's dashboard show whether your instructions are current, and it never changes what this call returns. Assembled deterministically with no model calls; a pure read that changes no project knowledge (a reported stamp is kept only as a record of when your instructions were last seen).
### `get_init_brief`
Call this ONCE on first run, the moment you arrive in a project and want an honest, populated-on-arrival summary of what the Brain already knows AND what it doesn't. One fast, read-only call returns: a plain `headline` (e.g. "Your Brain already knows 12 decisions, 3 conflicts, 5 constraints, and here are 4 decisions nobody explained"); truthful `counts` of active decisions, unresolved conflicts, and active constraints (read, never estimated); the composed `brief` orientation pack (the same five-section north-star + constraints + conventions + recent-decisions + current-focus shape as get_project_brief); the honest `rationaleGaps` list, one `{ decisionRef, title }` entry per decision that has NO recorded rationale; the `retrievalMode` the Brain is on (`semantic` or `fts-only`, reported, never something you set); and an optional `importSummary` if a recent import is associated. The rationaleGaps list reports ABSENCE: it is the set of decisions nobody wrote down the WHY for. It carries no "why" field by design: do NOT invent, infer, or fill in a rationale for any gap; treat each as an open question for a human (or, if you genuinely know why, log it with log_decision). A greenfield project returns zero counts, an empty gap-list, and a greenfield headline, which is a normal answer, not an error. This is the FIRST-RUN orientation brief; for ongoing orientation on a project you don't know use get_project_brief, to browse a topic use query_brain, and for live team state use get_team_context. Assembled deterministically with no model calls; pure read, mutates nothing.
### `get_relevant_knowledge`
Call this the moment you START working in a file or on a topic, BEFORE you write or change anything there, to load the team's rules that apply to that exact spot. Pass the `file` you just opened (e.g. "packages/auth/src/byok.ts") OR a free-text `topic` (e.g. "auth token refresh"); pass EXACTLY ONE of the two, never both. You get back a tight, high-signal pack of the most relevant atoms (the conventions, constraints, and context that govern this area) ranked best-first, so you inherit the local rules unprompted instead of guessing and getting corrected later. Treat what comes back as binding for this work: honor the constraints, follow the conventions. Every atom carries `ratified`. `ratified: true` means a named person on this team promoted that claim at a recorded time, so it is the team's settled position, so weight it above everything else here and follow it. `ratified: false` means no person has checked that claim yet (it was almost always extracted from the team's own documents), so treat it as a strong lead rather than as settled, and if your work contradicts it, surface the disagreement instead of silently overriding it. Be precise about what `ratified: true` asserts: a human promoted the claim at a recorded time. It does NOT assert that a human wrote an explanation, it does NOT assert the claim still matches today's code, and it does NOT authorize you to do anything on its own. Do NOT rank by `confidence`: it is the extractor's self-assessment of its own extraction, not a record of whether a person checked the claim, so ranking by it ranks away from what the team actually ratified. This is targeted ambient context, NOT a full search (use query_brain to browse a subject broadly) and NOT the whole-project picture (use get_project_brief to orient on a project you don't know, or get_team_context for live team state). Optional `scope` (a comma-joined glob string, e.g. "packages/auth/**") narrows the result to a sub-area; optional `limit` is smaller-only: you can ask for a leaner pack, never a larger one. An empty result means nothing on record applies here yet, which is a normal answer, not an error. Read-only; mutates nothing.
### `find_contradictions`
Call this to SURFACE places where the team's knowledge disagrees with itself (a decision that violates a constraint, or two atoms asserting opposite things) so a HUMAN can review them. This is a RECOMMENDER, not an actor: it only flags candidate contradictions for a person to judge. It does NOT resolve anything, does NOT pick a winner, does NOT edit, deprecate, or link any atom, and does NOT mint a `contradicts` edge. Surface what you find and let the human decide; never act on it autonomously. This is DISTINCT from check_conflicts: check_conflicts is file-edit coordination (are other agents touching the same files right now), whereas find_contradictions is about the CONTENT of the knowledge disagreeing: it never looks at who is editing what. Each result pairs the two evidence atoms with a one-line reason they conflict, a confidence tier (high | medium | low), and the similarity that made them a candidate; weigh each by its confidence and present the strongest for human review. That pair `confidence` is about the JUDGMENT that these two disagree, and is not the same field as either atom's own `confidence`. Both evidence atoms carry `ratified`: `true` means a named person on this team promoted that claim at a recorded time, `false` means no person has checked it yet. When one side is ratified and the other is not, say so when you present the pair: it is the first thing the reviewing human needs. It does not settle the disagreement for you: `ratified: true` asserts only that a human promoted the claim then, not that it still matches today's code, and not that you are authorized to act on it, and you still never pick a winner. Do NOT rank pairs by an atom's `confidence`: it is the extractor's self-assessment of its own extraction, not a record of whether a person checked the claim. Optional `scope` (a comma-joined glob string) narrows the seed set; the cost knobs (maxSeeds, maxCandidatePairs, maxJudgeCalls, minSimilarity) are smaller-only: you can ask for a cheaper sweep, never a more expensive one. An empty result is a normal, common answer: it means no contradictions were found, or the project has no embeddings/judge wired to detect them, not an error. Read-only; mutates nothing.
### `get_reconciliation_claims`
Call this to run the knowledge-truth check: fetch the project's documented CLAIMS so you can verify whether the actual CODE still honors them. The team's Brain records decisions, conventions, and constraints ("we enforce RLS on every project route", "BYOK keys never leave the device") that were true when written but quietly stop being true as the code changes. This tool hands you those claims; your job is to READ THE ACTUAL CODE YOURSELF (you have the repo in this session; Engrym does not and never will) and judge, per claim, whether the code still upholds it. Each returned claim carries its `atomId` (you will quote this back when you submit a verdict), its `kind` (decision | convention | constraint), its `title` and full `content` (WHAT to check), and its `scope` globs (WHERE in the tree it applies; point your reading there). Each claim also carries `ratified`: `true` means a named person on this team promoted that claim at a recorded time; `false` means no person has checked it yet. `ratified: true` asserts only that a human promoted the claim then, not that anyone wrote an explanation, not that it still matches today's code, and not that you are authorized to act. Read it as WHO VOUCHED for the claim, never as the answer you are being asked to produce: `ratified` and the reconciliation verdict are ORTHOGONAL AXES, and this is the tool where they are easiest to conflate. A claim a person ratified can still be flatly contradicted by today's code, and a claim nobody has ratified can still be perfectly honored by it, so `ratified: true` is NOT a reason to skip reading, `ratified: false` is NOT evidence of a violation, and you read the code for EVERY claim you are served. Where `ratified` does belong is in what you hand back: when you report a verdict on a claim a person ratified, say so: the human triaging it needs to know someone stood behind that claim. After you read the code, report your findings with submit_reconciliation_verdict, one verdict per claim. Optional `scope` (a comma-joined glob string, e.g. "packages/api/src/routes/**") narrows the served claims to one area so you can reconcile a slice at a time; optional `kinds` narrows to specific atom kinds (defaults to the code-checkable set: decision, convention, constraint); optional `limit` is smaller-only: you can ask for a leaner pack, never a larger one. An empty result means nothing on record applies to that scope yet, which is a normal answer, not an error. This tool reads claims only; it reads NO code and is best used in Claude Code or any client that actually holds the repo (on a repo-less surface you can fetch claims but cannot ground a verdict against code). Read-only; mutates nothing.
### `submit_reconciliation_verdict`
Call this to report ONE knowledge-truth verdict after you have READ THE ACTUAL CODE YOURSELF for a claim served by get_reconciliation_claims. Read this contract before calling: it is strict and the wire enforces it. YOU read the code locally: you have the repo in this session, Engrym does NOT and never will see the source. You return ONLY a verdict plus a pointer to where you looked, NEVER the code itself. Fields: `atomId` (the claim's id, quoted back from get_reconciliation_claims); `verdict`, exactly one of `upheld` (the code still honors the claim), `violated` (the code no longer honors it), or `uncertain` (you could not confidently judge; use this honestly instead of guessing); `evidencePointer`, a short LOCATOR string naming WHERE you looked, e.g. "packages/api/src/routes/brain.ts:142", a path-and-line POINTER and nothing more; and an optional short prose `note` for the human reviewer, e.g. "route handler skips the requireProjectAccess guard". CRITICAL: NEVER paste code, a snippet, a diff, an AST, a call graph, or any code text into `evidencePointer` or `note`. The `evidencePointer` is a pointer to a location, not the contents of that location; the `note` is plain-English rationale, not source. The API REJECTS (400) any payload whose `evidencePointer` looks like code (it is multi-line, fence-marked, or punctuation-dense), and rejects any extra field, so a verdict carrying code text simply fails. This is a RECOMMENDER, not an actor: a `violated` or `uncertain` verdict routes the claim into the human review queue for a person to triage (deprecate, supersede, or dismiss); an `upheld` verdict affirms the claim. You never auto-fix code, never mutate or deprecate the atom yourself, and never open a PR: you submit a recommendation and a human decides. If you do NOT have the repo in this session (e.g. a repo-less Desktop connection), do NOT fabricate a verdict; say you cannot ground one against code rather than guessing. Best used in Claude Code, where you actually hold the repo.
### `list_projects`
Call this to discover which Engrym projects you can reach, so you can read knowledge from a project other than the one you're connected to by default. It returns the list of projects your credential is a member of; each entry includes the project's `id`, `name`, `slug`, `teamId` (null for personal projects), `description`, and timestamps. Take the `id` of the project you want and pass it as the `projectId` argument to the read tools (query_brain, get_relevant_knowledge, get_team_context, get_project_brief, get_active_intents, etc.) to pull that project's Brain. The read tools default to your connected project when `projectId` is omitted, and read the project you name when it is supplied (you can only reach projects you're a member of; others are fenced server-side). By default this lists EVERY project you can reach: the ones you own plus every project belonging to a team you are a member of, so a project someone shared with you appears here. Pass an optional `teamId` to narrow to one team's projects instead. Use this for cross-project orientation, e.g. before you start work that may need a sibling repo's conventions, or when the user names a project you aren't currently pointed at. This is READ-ONLY discovery: it lists projects, it does not create, rename, or delete them, and it mutates nothing.
### `write_document`
Call this to WRITE a project document: the way knowledge enters the Brain. Use it to author the first canonical docs of an empty project (the genesis loop), or to keep an existing doc current as you learn. You write PLAIN MARKDOWN only: a `path` (e.g. "docs/architecture/auth.md") and the document `content` as a markdown string. Do NOT send rich text, HTML, embeds, comments, or formatting widgets. This is a document store, not a document editor; anything beyond plain markdown is rejected. CREATE vs UPDATE is automatic from what you pass: OMIT `docId` to CREATE a brand-new document at `path` (first write); pass the `docId` AND the `expectedVersion` you last saw to UPDATE that document. `expectedVersion` is optimistic concurrency: if someone else wrote since you read, your update is rejected (409) so you re-read and retry rather than clobber; on CREATE leave it out. The response returns the document's `id` and its new `currentVersionNumber`. KEEP BOTH: pass them back as `docId` + `expectedVersion` on your next update to the same doc. What happens after you write is the important part: your prose is NOT stored as Brain knowledge directly. The document is saved, a new version is recorded, and the Brain RE-DERIVES atoms from your markdown asynchronously, so a write here is a PROPOSAL, not a publication. Every atom your document produces is born PROVISIONAL (in review, low confidence, agent-authored) and bound to the version you just wrote; NOTHING you write becomes canonical team knowledge until a HUMAN ratifies it in the dashboard. This is a RECOMMENDER, not an actor: you draft, a person promotes. SHAPE RULE (doc vs atom): reach for write_document when the knowledge carries a WHY (rationale, alternatives considered), has examples or edge cases, will be reconciled against code (the document is the durable source anchor), or reads as a page a human would read; use add_brain_entry / log_decision only for one self-contained fact with nothing to preserve beyond the claim itself. When in doubt, write the document: a document can always regenerate its atoms, but a bare atom can never recover its why, its source, or its reconciliation anchor. Set `genesis: true` ONLY on the very first docs of an empty, never-before-populated project. It marks those atoms for the stricter cold-start ratification bar (every genesis atom reviewed individually, never in batch), since at cold start there is no prior knowledge to check the agent's first guesses against. Leave `genesis` unset for all ordinary work. Optional `scope` (a glob list, e.g. ["packages/auth/**"]) ties the document to the part of the tree it governs. Mutates: creates or updates a document and enqueues re-derivation. IF THE WRITE FAILS: this write can fail when the API is briefly unreachable; the failure envelope carries a stable `errorClass` and marks transient failures `retryable`. Do NOT continue as if the document were saved; nothing was persisted. Retry the write ONCE; if it fails again, STOP and tell the user plainly that the document was NOT persisted, naming the exact `path` you tried to write, rather than moving on silently.
### `pull_extraction_work`
Call this to pull agent-mode extraction work: the documents that need extraction PLUS the prompt to extract them with. You then run the extraction yourself, on your own agent's plan and on your own model from whichever provider you use, and post the results back with submit_extraction. WHEN TO CALL: this gate is the load-bearing rule; read it before anything else. Call this tool only under one of two authorizations: (1) the USER asks you to work on this project's extraction in this session, either on their own or by saying yes when you ask them; or (2) the project's auto-pull consent, a per-project permission the project's humans set in the Engrym dashboard, explicitly authorizes the pull. Do not call it outside those two grants: every pull is user-authorized, by a direct ask, by a yes to your question, or by the recorded dashboard consent, never by your own initiative. CHECKING THE CONSENT GRANT: before any pull the user did not just ask for, read the project's `autoPull` consent (`{ consent, reconfirm, eagerness }`) from the extraction config; `get_team_context` and the extraction config read both carry it. If `autoPull.consent` is FALSE (the default for most projects): there is NO standing permission; ask the user first, and pull only when the user explicitly asks or says yes, never otherwise. If `autoPull.consent` is TRUE: the project's humans have granted standing permission for consent-authorized pulls, bounded by two fields you must honor. `eagerness`: `opportunistic` means the grant covers a pull at session start AND again whenever you next work on or touch this project; `session_start` means it covers one pull, at the start of the session, only. `reconfirm`: if TRUE, tell the user you are about to act on the grant and get an OK before EACH auto-pull, including later ones in the same session; if FALSE, the dashboard grant itself is the user's confirmation and you proceed. Read the consent LIVE before each consent-authorized pull: never cache it across sessions, and never auto-pull when it is false. WHAT THIS TOOL IS: in agent mode the extraction LLM work happens in YOU, the agent, not on Engrym's servers. Engrym never holds, replays, or sees your subscription or your model credentials; it only hands you the document text and the prompt, and you do the thinking. What you get back: `mode` (`agent` when there is work to do, a label that covers a project configured as either `agent` or `mix` mode; or `byok` when this project uses its own API key instead, see below); `systemPrompt` (the exact extraction prompt to run); `promptVersion` (the version of that prompt; remember it, you pass it to submit_extraction); and `documents`, each with a `documentId`, a `documentVersionId` (the immutable version you are extracting, and you BIND your submission to this), a `path`, a `body` (the document's markdown TEXT, which is knowledge prose, never code), and `priorAtoms`, the knowledge atoms that ALREADY STAND for that same document (empty on a document nothing has been extracted from yet), each with its `id`, `category`, `title`, `content`, `scope`, `tags` and `confidence`, plus `unsettled` (`proposal`, `checkpoint` or `unpublished`) only on an atom the document last presented as not settled; and `nextCursor`, the 'more work remains' signal, present when more documents still need extraction than this bounded batch returned, absent when the queue is drained. Each pull is server-bounded (at most 25 documents AND at most 2 MiB of document bodies), so keep looping: pull, extract, submit, then pull again, until a pull returns no `nextCursor`; that absence means the extraction queue is fully drained. Pass an optional `limit` to pull an even smaller batch and keep each extraction session token-frugal. WHAT TO DO with the result: for EACH document, run `systemPrompt` on your own compute over that document's `body` AND its `priorAtoms` TOGETHER, and RECONCILE the one against the other. The result is a KEEP/CHANGE/ADD/REMOVE diff of knowledge atoms (decisions, conventions, constraints, context) measured AGAINST that document's `priorAtoms`, not a fresh read of the body on its own. Walk EVERY prior atom and place it. Still accurate as written: its `id` goes in `keptAtomIds`. The body now says something different: it goes in `changedAtoms`, as that prior atom's `predecessorId` plus the new `successor` draft, so the successor REPLACES the atom it came from instead of standing beside it. The body no longer supports it at all: its `id` goes in `removedAtomIds` with a short `reason`. ADD only a claim that NO prior atom already covers. A claim a prior atom ALREADY COVERS but now states DIFFERENTLY belongs in `changedAtoms` carrying that atom's `predecessorId`, never in `addedAtoms`, because an ADD leaves the outdated atom standing next to its replacement with nothing linking the two, and that is the exact failure `priorAtoms` is handed to you to prevent. If a document's `priorAtoms` is empty, everything you extract is an ADD. A prior atom's `unsettled` is part of its claim: KEEP that atom only while the body still presents the claim the same way, and when the body now presents it as settled, send a CHANGE whose successor leaves `unsettled` out. Set `unsettled` on a draft only when the body itself presents the claim as proposed, as work in progress, or as unpublished, never because you doubt it (that is `confidence`); submit_extraction spells out the three values. Then call submit_extraction ONCE per document with that document's `documentId`, `documentVersionId`, the `promptVersion` from this pull, your `diff`, and the `model` id you ran with its `provider`. Extract only what the document says. Do not invent claims, and never read or include source code (this tool is about the project's written knowledge, not its code). Everything downstream is identical whether the pull was user-requested or consent-authorized: submissions land PROVISIONAL (review/agent), ratification-gated; the agent-extraction submission cap still applies; and you never spend the project's paid key, because the model runs on your side, under your own account. If `mode` is `byok`, this project extracts on the server using its own API key and there is nothing for you to pull. This is normal, not an error; the `notice` explains it, and you simply do not run extraction for this project. If `documents` is empty in agent mode, everything is already up to date. That is also normal; there is nothing to submit.
### `submit_extraction`
Call this ONCE PER DOCUMENT after you have run the extraction prompt (from pull_extraction_work) over a document's body on your own compute, to submit the knowledge atoms you extracted. This is how agent-mode extraction results re-enter the Brain, and the contract is the same whichever agent, model or provider you run on. Fields: `documentId` and `documentVersionId`, quote these BACK from the document you pulled (the submission is pinned to that exact version); `promptVersion`, the version pull_extraction_work served (quote it back, for provenance); `model` and `provider` (see REPORT WHAT YOU RAN below); and `diff`, your extraction result as a KEEP/CHANGE/ADD/REMOVE over the document's prior atoms: `keptAtomIds` (prior atoms still accurate, unchanged), `changedAtoms` (a prior atom's `predecessorId` plus the new `successor` draft), `addedAtoms` (net-new claims; you do NOT supply an id, the server mints it), and `removedAtomIds` (prior atoms the document no longer supports, each with a short `reason`). Each atom draft carries `category` (decision/convention/constraint/context), `title`, `content`, `scope`, `tags`, `confidence`, `extra`, and, only when it applies, `unsettled`. REPORT WHAT YOU RAN: on every submission, send `model`, the exact model id you ran this extraction on, and `provider`, the id of the provider that served it (for example `claude-opus-4-8` with `anthropic`, `gpt-5-codex` with `openai`, or `gemini-2.5-pro` with `google`; send your own values, not these examples). Both are self-reported. Engrym records each exactly as you send it, on the run and in the provenance of every atom the run lands, and checks neither against any list, so the record says what you reported and nothing more. Both stay optional so an older client keeps working, but an omitted one is recorded as `unreported`, never as the project's configured model or provider. If you do not know a value, leave it out rather than guess. UNSETTLED CLAIMS: `unsettled` records how the DOCUMENT presents a claim, as one of three values: `proposal` when it presents the claim as proposed, recommended, a provisional default, or an option not yet decided; `checkpoint` when it presents the claim as the state of work in progress that it expects to change; `unpublished` when it says the work exists only where others cannot reach it, such as one machine or an unpushed branch. Set it ONLY when the document itself presents the claim that way, never because you doubt the claim: your own doubt goes in `confidence`. Leave it out for a settled claim. Prior atoms from pull_extraction_work carry `unsettled` when it is set. While the document still presents such a claim the same way, KEEP it. When the document now presents it as settled, send a CHANGE whose successor leaves `unsettled` out, which clears the marker; when it now presents it as a different one of the three, send a CHANGE carrying the new value. Atom CLAIMS ONLY: never put source code, snippets, diffs, or any code text in any field; this tool moves knowledge, not code. Do NOT send an author, user id, agent type, cost, token count, or run status. There is no field for them: the server stamps WHO submitted (you, the authenticated principal), records which agent client your credential was set up for, and records the run itself. WHAT HAPPENS NEXT, read this carefully: the atoms you submit land PROVISIONAL (in review, agent-authored), NOT canonical. A submission is a PROPOSAL, not a publication. They run the same judge/reconciliation as every other extraction, and a HUMAN ratifies them in the dashboard before they become part of the team's ratified knowledge. You are NOT writing canonical knowledge and you have NO authority to promote, ratify, reinstate, or deprecate an atom: you propose, a person decides. If the submission is rejected because the document version moved on (409), the document changed since you pulled, so re-pull with pull_extraction_work and re-extract against the new version rather than retrying the stale one. If you hit a submission cap (429), you have reached this account's agent-extraction ceiling for the period; the document stays pending for an agent, it is never silently charged to a paid key.
### `get_conflicts`
Call this AFTER a collision warning (an overlap surfaced by check_conflicts or by a conflict on your broadcast_intent) and BEFORE resuming contested work: it tells you whether a human has arbitrated the collision and what they decided. Also call it to see how past collisions on this project were settled. Returns the project's conflict records: each entry carries the conflict (status, severity, overlapping file paths), BOTH colliding intents with their agent identities (server-stamped from each credential; 'unknown agent' when none was declared), and, for resolved or dismissed conflicts, the human's resolution: who resolved it, when, the REQUIRED rationale, and any chosen action. COMPLY with the resolution: when a conflict involving your work has been resolved or dismissed, read the rationale, honor the human's decision, and do NOT re-litigate it: do not re-broadcast an intent that recreates the same collision, and do not resume work the resolution assigned elsewhere. Filter with status. It DEFAULTS to 'active' (open, un-arbitrated collisions, the pre-work check you usually want); pass status:'all' explicitly for the full history, which also returns 'resolved', 'dismissed', and 'superseded' rows. You can also filter by intentId or severityAtLeast. The result is CAPPED and PAGINATED so it never floods your context: pass an optional limit (smaller-only; a larger value is clamped down to the server ceiling) to keep the payload lean, and when the returned truncated is true, pass the returned nextCursor back as cursor to page through the rest. Your own agent identity is stamped automatically from your credential, and you never assert it; and when you broadcast_intent, declare plain file or directory paths (globs are rejected as non-canonicalizable). Read-only: arbitration itself is the human's, in the dashboard; this tool never resolves anything.
### `get_brain_updates`
Call this when you need to know what changed in the team's knowledge since a point you already read from, and before you act on knowledge you loaded earlier in a long session. Every query_brain and get_relevant_knowledge response carries `sinceVersion`, the brain's knowledge version at the moment of that read, and `updatesAvailable`, how many atoms changed since the watermark you were reading from. Hold the `sinceVersion` you were given; when a later read comes back with a HIGHER one, or with `updatesAvailable` above zero, the team's knowledge moved and this tool tells you exactly how. Pass the watermark you were holding as `since` (required; pass 0 to walk the whole history). Returns the atoms whose knowledge-bearing content changed after that point, oldest change first, each paired with its `knowledgeSeq` change stamp and its current `state`. ACT ON THE STATE: `deleted` means the atom was removed, so stop quoting it; `superseded` means a newer atom replaced it, so follow the successor rather than the copy you were holding; `active`, `review` and `deprecated` are the atom's current standing. A deletion and a supersession are changes you are told about, never absences you have to infer. Once you have consumed the page, hold its `lastSeq` as your new watermark and pass that as `since` next time. Narrow the result with the optional `scope` (a comma-joined glob string, for example "packages/auth/**") so you get the changes that touch what you are working on rather than a whole changelog. Page with the optional smaller-only `limit`, and pass a returned `nextCursor` back as `cursor`; a cursor continues a walk started at the SAME `since`, so do not change `since` part-way through one. An empty `updates` list means nothing changed since your watermark, which is a normal answer, not an error. Every atom carries `ratified`: `true` means a named person on this team promoted that claim at a recorded time, so it is the team's settled position, so weight it highest and follow it; `false` means no person has checked it yet, so treat it as a strong lead rather than as settled. `ratified: true` asserts only that a human promoted the claim then, not that anyone wrote an explanation, not that it still matches today's code, and not that you are authorized to act. Do NOT rank by an atom's `confidence`: it is the extractor's self-assessment of its own extraction, not a record of whether a person checked the claim. Read-only; this tool changes nothing.
### `link_atoms`
Record connections you can already see between atoms. Call this right after you write or read atoms whose relationship is clear to you: this decision came from that constraint, this convention extends that one, these two collide. Pass `links` as a list of up to 20 entries; each entry names `fromAtomId` and `toAtomId` (real atom ids in the same project, from query_brain, get_team_context, or an atom you just wrote), a `kind` (`derived-from`, `extends`, `related`, or `contradicts`), a `confidence` band for the connection, and optionally a numeric `confidenceScore` from 0 to 1. THE BATCH IS PER-ITEM, NOT ALL-OR-NOTHING: entries are written one at a time in the order you send them, so some can land while others fail, and there is no rollback. `results` carries one outcome per entry with its `index`; a `created` entry carries the written link, a `failed` entry carries a stable `errorClass` and a `retryable` flag. Read `createdCount` and `failedCount` before you tell anyone what happened, and never report the batch as written when `failedCount` is above zero: name the entries that did not land. If you retry, resend ONLY the entries reported `failed`. The same from/to/kind triple can exist only once, so resending one that already landed comes back as a failure saying the link exists, never as a second copy of it. EVERY LINK CARRIES A `trust` STATE, AND YOU MAY NOT OVERSTATE IT. `unreviewed` is the default: no policy admitted the link and no person has looked at it. `policy-accepted` means this project has a link policy an owner or admin switched on, and the link was recorded under that policy WITH NO PERSON HAVING READ IT, so it is not a person's judgment and must not be described as one. You cannot produce `human-ratified`: that stamp has a single writer and it refuses a machine principal, whatever the project's settings say. A `contradicts` link you write always lands `unreviewed`, on every project, because it claims one of two live atoms is wrong. And `contradicts` is atom against atom only: if you have read the repository and the CODE disagrees with a documented claim, that is a reconciliation verdict (submit_reconciliation_verdict, with its evidence pointer), not a link. ENDPOINT LIVENESS IS NOT A CONDITION OF WRITING, AND THAT IS DELIBERATE. An endpoint whose `status` is `superseded` is permitted, because recording that a retracted claim was connected to something is still a real record. The link's `trust` is about who has looked at the CONNECTION and says nothing about whether either endpoint's claim still stands. So read each endpoint's `status` and `supersededBy` on the payload that gave you its id, and when one is `superseded`, choose on purpose: use the atom that replaced it when you mean the claim that holds now, and the superseded one only when you mean the historical claim. Who wrote the link is recorded from your credential, so there is no author field to send and an entry carrying one is rejected.
<!-- END GENERATED ENGRYM TOOL TAXONOMY -->
Flag reference
| Command | What it does |
|---|---|
engrym setup <agent> | Connects the agent, then writes its block, ENGRYM.md and the engrym-extract command into the current folder; asks once before changing a file with your own writing (--yes skips the question) |
engrym init --write-instructions | Writes the managed block into every detected host config + an ENGRYM.md at the repo root |
engrym init --print-instructions | Prints the block (writes nothing) so you can paste it yourself |
--copy | Pairs with a print flag; also copies the block to your clipboard |
engrym setup --print | Prints the latest block for paste users (same output as init --print-instructions) |
engrym setup | Refreshes the blocks Engrym wrote in the current folder, preserving your out-of-marker text |
Next steps
- MCP setup: wire the Engrym MCP server into your tool first; that's what makes the live tool list available.
- Getting started: the five-minute on-ramp.
- CLI reference: the full command and flag reference.