Core Concepts
Context Personas
One runtime, many verticals. A persona reshapes the whole context surface — tool set, read mode, compressor, chunker, intent taxonomy and sensitivity floor — for a domain in a single switch, while the coding default stays exactly as it was.
LeanCTX ships tuned for software work: the full Power tool surface, a code-oriented
intent taxonomy, identity compression. A persona reshapes that whole context
surface for a different domain (prospecting, research, support, data) in one switch, and leaves the
coding default untouched.
Built-in personas
Each persona is a real, shipped bundle. The tool surface, read mode, compressor, chunker, intent taxonomy and sensitivity floor all move together:
| Persona | Tool surface | Read mode | Compressor · chunker | Sensitivity floor |
|---|---|---|---|---|
coding (default) | Power profile — full surface | auto | identity · lines | public |
research | Standard profile | map | markdown · paragraph | public |
support | Standard profile | auto | prose · paragraph | internal |
data-analysis | Standard profile | map | identity · lines | internal |
lead-gen (alias sales) | Custom 6-tool surface | map | prose · paragraph | confidential |
The lead-gen surface is genuinely narrowed to six prospecting tools (the
refactor/code tools are gone):
ctx_read · ctx_search · ctx_url_read · ctx_knowledge · ctx_semantic_search · ctx_session Selecting a persona
Set it via environment variable (or config.persona):
export LEAN_CTX_PERSONA=lead-gen # or: research · support · data-analysis · coding Persona::resolve reads LEAN_CTX_PERSONA › config.persona ›
default coding. An unknown name falls back to coding, never an error. An
explicit tool profile (set with lean-ctx tools) always wins, so existing coding installs
are never disturbed.
Ship your own vertical — no fork
Not one of the built-ins? Drop a declarative persona file in your personas directory (default
<OS-config-dir>/lean-ctx/personas, override with LEAN_CTX_PERSONAS_DIR)
and select it by name:
# <personas_dir>/compliance.toml
name = "compliance"
tool_profile = "custom"
tools = ["ctx_read", "ctx_search", "ctx_semantic_search", "ctx_knowledge"]
default_read_mode = "map"
compressor = "prose"
chunker = "paragraph"
intent_taxonomy = ["scan", "flag", "cite", "report"]
sensitivity_floor = "confidential" export LEAN_CTX_PERSONA=compliance Under the hood runtime-wired since v3.9.2
Persona resolution lives in rust/src/core/persona.rs. Since v3.9.2,
every field is wired into the runtime — none of this is a prompt hint:
- Tool surface — the resolved profile drives
list_tools, so the advertised tool set genuinely shrinks or grows per persona. An explicit profile (lean-ctx tools) still wins. - Read mode —
ctx_readresolves its mode as: explicitmodeargument > policy pack > persona > profile default.automeans the persona has no opinion. - Compressor & chunker —
ctx_url_readruns flowing-text modes (auto/markdown/text/transcript) through the persona compressor, and token-budget cuts land on the persona chunker's boundaries (paragraphs, line windows) instead of mid-sentence. Extractive modes (facts/quotes/links) stay verbatim to protect citations. - Intent taxonomy — non-coding personas append a
PERSONA/INTENTS/DEFAULTSblock to the MCP session instructions, so the agent speaks the domain's vocabulary. Thecodingdefault leaves the prompt byte-identical to a persona-less install. - Sensitivity floor — folded into
[sensitivity]enforcement: a floor abovepublicswitches enforcement on and can only tighten the configured floor, never loosen it. Same governance layer as roles and budgets.
The active persona is reported at GET /v1/capabilities under server.persona,
so orchestrators can branch on it instead of guessing.
Where to go next
- Configuration — the
LEAN_CTX_PERSONAandLEAN_CTX_PERSONAS_DIRreference. - Context Personas journey — the end-to-end story.
- Security & Governance — roles, scopes and the sensitivity floor.