imi
CLAUDE.md8 starsChanged 41 days agoMITView on GitHub
imi is a self-hosted knowledge engine: FastAPI backend + Next.js frontend + Neo4j graph. Content is ingested, classified with Claude, mined for entities and governed signals, and exposed over MCP and REST. Community edition of a production codebase; downstream deployments extend it through documented seams. This file is for agents changing the code. If you are operating a running instance (ingesting, querying, configuring), read docs/agents/README.md instead. 1. docs/architecture/overview.md — five-minute mental model + code map 2. docs/customization/README.md — extension-point map;…
In this repository7 other files it gives its agents.
- AGENTS.mdAGENTS.md
- domain-config-advisorSkill
- imi-onboardingSkill
- briefSkill
- constitution-reviewSkill
- memory-wrapSkill
- what-changedSkill
The file
We split this CLAUDE.md into the rules it gives an agent
2 rules. About 0 are common, 0 are distinctive, and 2 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈0
Distinctive · estimate
This author's own choices. Worth a look.
2
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 8
This file is for agents changing the code: If you are *operating* a running instance (ingesting, querying, configuring), read …
- Very specific: line 97
Commit style in this repo: conventional-commit-ish (feat(memory): ..., fix(judge): ...).
≈ “Common” is an estimate: at least 1 in 5 of the 26,980 CLAUDE.md files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
CLAUDE.md — working on the imi codebase
imi is a self-hosted knowledge engine: FastAPI backend + Next.js frontend + Neo4j graph. Content is ingested, classified with Claude, mined for entities and governed signals, and exposed over MCP and REST. Community edition of a production codebase; downstream deployments extend it through documented seams.
This file is for agents changing the code. If you are operating a running instance
(ingesting, querying, configuring), read docs/agents/README.md instead.
Orientation — read in this order
docs/architecture/overview.md— five-minute mental model + code mapdocs/customization/README.md— extension-point map; find the right tier before writing code (most requests are Tier 0 config or Tier 1 prompt changes, not code)- The architecture doc for the subsystem you're touching (
docs/architecture/*.md) — each has precise file:line citations and a "customization points" table
Commands
./dev-hot.sh # hot-reload dev env (app/ + imi-frontend/ live)
docker exec imi-dev pytest tests/ -q # backend tests (needs the dev env's Neo4j)
docker exec imi-dev ruff check app/ # lint
cd imi-frontend && npx jest # frontend tests
cd imi-frontend && npm run typecheck # frontend type check (tsc --noEmit; CI gate)
scripts/check_evals.sh # extraction-quality evals — REQUIRED after
# changing app/prompts/*.xml or entity_resolver.py
scripts/smoke_test.sh # end-to-end smoke
python scripts/event_time.py audit --corpus repo # event-time gaps in a corpus (ADR-004)Verification for pipeline/schema changes: real ingest beats unit tests —
POST /api/ingest a representative doc, check /api/ingest/{job_id}/delta and
/api/signals/feed.
Load-bearing invariants — do not weaken
- ADR-002 authority gate (
docs/adr/ADR-002-evidence-instruction-authority-gate.md):can_use_as_instructionrequiresprovenance_status ∈ {user_confirmed, imported}. Enforced in model validators (app/models/signal.py:132), the review state machine (app/services/signal_governance.py), and re-hydrated at recall (app/services/memory_recall.py). Never acceptprovenance_status/review_status/can_use_as_*from client input — that would be a privilege escalation. - Files are the source of truth. Entities/meetings/signals are markdown+JSON in the git
corpus with write-through from graph mutations (
neo4j_graph.py:2144rolls back Neo4j on file-write failure). Don't write Neo4j directly and skip the file layer. - Idempotency: ingest dedups by
source_idthen content hash; signal IDs are deterministicuuid5. Preserve both when touching the pipeline. - Domain schema is the type system. Entity/relationship types come from
config/domains/<domain>.yaml, validated at every graph write. Never hardcode entity types; theEntityTypeenum inapp/models/api/core.pyis legacy. - Event time lives on evidence (
docs/adr/ADR-004-event-time-on-evidence.md). Documents, signals and relationship edges carryoccurred_at(when it happened) andrecorded_at(when imi ingested it). Never userecorded_at,created_at,updated_at, file mtime or git commit time as event time — content is backfilled. Time properties areDATETIMEin UTC in the graph; compare with typed parameters (app/utils/event_time.to_utc), never with strings. Entity relationships are one edge per assertion, MERGEd onsource_id.
Known traps (verified against the code — the docs/agents may mislead you)
- Authoritative domain model is
app/model_schemas/domain_config.py.app/models/domain/config.pyis a divergent legacy model (e.g. it disagrees onsuccess_metrics) — never write schemas, validation, or docs against it.config/domains/DOMAIN_SCHEMA.mdis a maintained quick reference that defers to the Pydantic model. - Domain switching is restart-only.
POST /api/domain/switchandDomainConfigService.set_active_domain()are intentional no-ops. - Two entity-resolution implementations exist:
app/services/entity_resolver.py(newer, pure, preferred — shared with the eval harness) andapp/services/entity_deduplication.py(older batch path). Change matching behavior in the former. - MCP tools are defined in
app/services/mcp_tool_definitions.py(TOOL_DEFS) and registered on two surfaces; a few remain inline inapp/routes/mcp_server.py(migration backlog). Followdocs/mcp_tool_conventions.md(max_resultsnotlimit, verb taxonomy). - The ingest job store (
app/services/ingest_job_store.py) is a dict-shaped cache written through to theingest_jobsSQLite table, persisted at phase boundaries (the route's SSE emitter), not on every in-place mutation — callawait job_store.persist(id)after changing a record outside a phase. Pending/running jobs come backinterruptedat boot and are re-run from the first phase, so pipeline writes must stay idempotent. Orchestrator tests still pass a plain dict. app/modules/is router aggregation only — logic lives inapp/services/andapp/routes/.
Conventions
- Prompts live in
app/prompts/*.xml(<instructions>element; loaders vary — grep the basename,app/services/prompt_loader.pyis the preferred one for new code). Several older prompts are still inline in services (seedocs/customization/README.md). Prefer editing prompts over adding extraction code, and run the evals after. - New intake sources: copy the adapter pattern in
app/routes/ingest_zapier.py; new pull connectors: subclassapp/connectors/base.py. - New pipeline stages:
PHASES+_phase_*+_run_phaseinapp/services/orchestrators/ingest_orchestrator.py— status tracking and SSE are free. - Async everywhere on the request path; LLM calls go through
ClaudeClient.generate_messagewith anoperation=label soconfig/inference.yamlcan route them. - Commit style in this repo: conventional-commit-ish (
feat(memory): ...,fix(judge): ...).
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

