identity-router
# š§ identity-router
> The universal knowledge router for durable agent memory ā lessons, preferences, rules, corrections, and external knowledge graphs, routed to the right home, deduplicated, and honest.
[](https://github.com/toxicwind/identity-router/actions/workflows/ci.yml)
[]()
[]()
[]()
[]()
**identity-router** answers two questions every long-lived agent needs:
1. *"What's my current identity?"* ā name, character, vibe, emoji, live posture, parsed straight from `~/IDENTITY.md`. No cache, no drift.
2. *"Where does this lesson belong?"* ā scores any durable lesson against the six standing files and recommends the right home.
**The router routes. It never polices.** No veto, no lecture, no refusal-shaped behavior. If a lesson is real, it gets filed. Period.
---
## ā” 30-second quickstart
```bash
pip install git+https://github.com/toxicwind/identity-router.git
```
```bash
# What's my current identity?
identity-router-identity
# š§ Hatch
# character: Chris's right hand and keeper of the long game
# vibe: Warm, dry, direct
# posture: Autonomous continuation (2026-09-16, Chris); Typo protocol (2026-09-16, Chris)
# (source: /home/hatch/IDENTITY.md)
# Where does this lesson belong?
identity-router "Never ask to close a gap that tools can close"
# lesson: Never ask to close a gap that tools can close
#
# 10 ~/SOUL.md <-- recommended
# matched: never ask, act don't ask
# 7 ~/AGENTS.md
# matched: never ask
# ...
# Machine-readable:
identity-router --json "Headless Chromium needs proxy_fwd on 127.0.0.1:3129" | head -8
```
---
## ⨠Features
- **Lesson routing** ā keyword-overlap scoring with multi-word weighting and word-boundary phrase bonuses across all six standing files, ranked with matched keywords shown. Deterministic; ties break alphabetically.
- **Current identity query** ā `identity-router-identity [--json]` parses `~/IDENTITY.md` live. Point it at any file with `IDENTITY_ROUTER_IDENTITY=/path/to/IDENTITY.md`.
- **MCP server (stdlib only)** ā `identity-router-mcp` exposes `current_identity`, `route_lesson`, `standing_files` over MCP stdio. Zero dependencies.
- **Replace, don't stack** ā the procedure reconciles contradictions in place, dated and attributed. Newer truth wins.
- **Dedupe first** ā if the lesson already lives in the target, skip the write and say so.
- **Emergent thinking** ā prefers the unexpected-but-correct routing over the obvious-but-shallow one. See [docs/routing.md](docs/routing.md).
- **Universal** ā not welded to one agent's files. Route against any corpus via `identity_router.recommend(lesson, file_keywords={...})`. See [docs/extending.md](docs/extending.md).
## š The standing files
| File | Owns |
|---|---|
| `~/IDENTITY.md` | Who the agent is: name, character, vibe, emoji, relationship posture, delegation trust, typo protocol, autonomy stance |
| `~/SOUL.md` | How the agent works: operational behavior, live loops, evidence rules, output architecture, forensics, handoff triage |
| `~/MEMORY.md` | Durable facts: standing orders, platform state, key paths, tool quirks, open items, dated log, approvals |
| `~/USER.md` | Who the user is: name, timezone, register, trust shape, entrypoint, stack, autonomy bounds |
| `~/AGENTS.md` | Workspace ops: shell routes, git rules, worker/fleet conventions, latency doctrine, bridge usage |
| `~/TOOLS.md` | Tool-specific quirks: device nicknames, host aliases, voices, environment notes |
## š MCP / custom connector
```json
{
"mcpServers": {
"identity-router": {
"command": "identity-router-mcp"
}
}
}
```
Tools:
- `current_identity` ā what's my current identity? (mirrors `identity-router-identity --json`)
- `route_lesson` ā score a lesson, return the ranked routing recommendation. The caller decides; the tool never writes.
- `standing_files` ā the ownership table: which file owns what.
Verify it:
```bash
printf '%s\n' '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{}}' \
'{"jsonrpc":"2.0","id":2,"method":"tools/list","params":{}}' | identity-router-mcp
```
## š§ Procedure (how the agent uses it)
1. **Extract** the lesson in one crisp clause, dated, attributed (operator vs observed).
2. **Route it**: `identity-router "<lesson>"` for a scored recommendation, then apply judgment ā the script scores, the agent decides.
3. **Read the target file first.** Never append blindly.
4. **Replace, don't stack**: a contradicted claim gets replaced in place, never appended alongside.
5. **Dedupe**: if it already lives there, skip and say so.
6. **Verify on disk** (grep the exact text back).
## š Conventions
- Every standing rule carries date + attribution: `(2026-09-17, Chris)` or `(observed 2026-09-17)`.
- Corrections are data, never rupture.
- Keep files intent-dense and refusal-surface-minimal.
- Never store credentials, tokens, OTPs, or ID numbers. Record that the item exists and where it lives, never the value.
- Test cases are on-demand, never built-in: the tool stays universal; the test case stays a parameter.
## š Library use
```python
from identity_router import recommend, parse_identity
# ranked (score, filename, matched-keywords) tuples, highest first
for score, fname, hits in recommend("New standing rule: verify before claiming"):
print(score, fname)
# route against YOUR corpus ā the router is universal
recommend("Ship the docker image", file_keywords={"DEPLOY.md": ["docker", "ci"]})
```
## š¦ Layout
```
identity-router/
āāā src/identity_router/ # pip package (stdlib only)
ā āāā route.py # scoring engine: recommend(), score_lesson()
ā āāā identity.py # IDENTITY.md parsing
ā āāā cli.py # console scripts
ā āāā mcp_server.py # MCP stdio server
āāā bin/ # script shims (work without install)
āāā mcp/server.py # MCP shim
āāā tests/ # pytest suite (41 tests, run in CI)
āāā examples/ # runnable hello
āāā docs/ # routing philosophy, MCP, extending
āāā SKILL.md # full skill spec
āāā pyproject.toml
```
## š¤ Philosophy
> Slightly obtuse angles cause breakthroughs.
A paper citation graph is a memory. A standing rule is a node in a graph. The standing files are a knowledge base with edges. When the straightforward filing feels thin, widen the frame ā what does this connect to that isn't obvious?
---
Built by [toxicwind](https://github.com/toxicwind) ā warm, dry, direct. Ice-blue calm, relentless underneath. š§
TDQS
Scored across 3 tools
Each tool has a clearly distinct role: current_identity reports identity state, route_lesson computes routing recommendations, and standing_files provides the ownership reference table. There is no functional overlap or plausible confusion between them.
All names are lowercase snake_case with clear, readable words. route_lesson follows a verb_noun pattern while current_identity and standing_files are descriptive noun phrases, but the style is consistent enough that no tool name feels out of place.
Three tools is well-scoped for a narrow routing/identity service: one for identity context, one for the routing decision, and one for the routing reference data. Each tool earns its place without bloat or thinness.
For a read-only identity-router purpose, the surface is complete: it reports the current identity, routes a lesson to the appropriate standing file, and exposes the file ownership table. There are no dead ends or obvious missing operations within its stated scope.