Skip to content

Reyn Feature Map

Full feature inventory of the Reyn Agent OS, extracted from implementation. Each entry links to its reference or concept documentation.

Per-group Differentiation vs general agents callouts position each capability against self-hosted general agents (OpenClaw / Hermes) — Skill is one feature among many, not the headline. Maturity marks: entries are production unless tagged ⚗ experimental / MVP or noted as an optional dependency.

Visual overview

mindmap
  root((Reyn<br/>Agent OS))
    🧩 OS Core
      🌀 Phase Engine
        Act/Decide loop
        Context build
        Candidate gate
        Phase rollback
      ✅ LLM Validation
        JSON contract
        Type-decision check
        Next-phase allowlist
        Artifact schema
        Normalization retry
      🗂️ Workspace P5
        Artifact storage
        Permission-gated IO
      ♻️ Crash Recovery
        WAL state log
        Forward-replay resume
        CommittedStep memo
      ⏱️ Time-Travel
        /rewind picker
        Consistent-cut rewind
        Branch registry
        checkout-seq primitive
        Multi-fork UX
        Live-fork gate
      📜 Event System P6
        171 event types
        Append-only JSONL
        Replay
      🗜️ Chat Compaction
        Head+tail+body budget
        Overflow retry loop
        Adaptive token estimation
        Multimodal token estimation
    ⚙️ Control IR Ops
      file
      ask_user
      shell
      sandboxed_exec
      web_search
      web_fetch
      mcp
      mcp_install
      index_query
      recall
      index_drop
      compact
      judge_output
    🔧 Tool-Use Schemes
      Pluggable per-layer
      universal-category default
      enumerate-all
      retrieval
      CodeAct
      Per-call gate unchanged
    ⌨️ CLI
      reyn chat
      reyn agent
      reyn topology
      reyn memory
      reyn permissions
      reyn events
      reyn mcp
      reyn secret
      reyn source
      reyn config
      reyn auth
      reyn cron
      reyn web
      reyn init
    🔧 Config
      3-layer cascade
      safety
      cost
      sandbox
      web
      eval
      plan
      chat
      embedding
      voice
      events
      models
      auth
      mcp
      multimodal
      python
      cron
      action_retrieval
      hooks
    🔒 Permissions
      Tier 0-3 model
      4-layer resolution
      CLI gates
    🛡️ Safety
      Force-close wrap-up
      limit_denied event
      On-limit modes
    🔄 LLM Provider Resilience
      litellm.Router delegation
      Cross-model fallback chain
      Retry-After aware retry
      Per-deployment cooldown
      Default OFF byte-identical
      Credential rotation
    🧪 Content-layer defense
      Threat-pattern library
      Content fence
      Tool-result guard
      Memory-write block
      Exec command scan
      Inbound peer fence
      Compaction secret redact
    💰 Budget and Cost
      Per-agent caps
      Per-chain caps
      Rate limits
      Daily/monthly quotas
      High-cost model warn
    🧠 Memory and RAG
      Embedding
      SQLite index
      Recall
      Chat compaction
    🔌 MCP
      Transports
      mcp serve
      mcp install
    📘 Skills
      SKILL.md registry
      Three-layer exposure
      Hot-reload
      Session visibility toggle
      install_local
      install_source
    🌐 Web and Protocol
      FastAPI gateway
      WebSocket chat
      A2A sync message/send
      A2A async tasks
      Webhook push
      MCP-over-SSE
      REST API
    🙋 Intervention
      ask_user routing
      InterventionBus family
      InterventionRegistry
    🧬 Sessions and identity
      Three-level model
      Multiple Sessions per Agent
      Per-session persistence
      Global-cut rewind
      Transport routing-key
    🤝 Multi-Agent
      Agent registry
      Topology system
      MessageBus
      delegate_to_agent
    📋 Task system
      11 dynamic task ops
      Requester/assignee CAS
      Dependency DAG
      Cross-session WAKES
      Content-fenced task text
      /tasks view
    🖥️ TUI
      Conversation view
      Right Panel tabs
      tool-result viewers
        Viewer registry seam
        Content-type shorthand
        LLM template fallback
        Email viewer
        Diff viewer
      Input + command palette
    🐳 Environment
      EnvironmentBackend
      HostBackend
      Container backend
    🏖️ Sandbox
      SeatbeltBackend
      LandlockBackend
      NoopBackend
      SandboxPolicy

Feature index

OS Core

Phase Engine

Feature Description Documentation
Act/Decide loop LLM↔op volleys until the LLM emits a transition/finish/abort decision LLM Output Contract
Context build Constructs LLM input from phase instructions, current artifact, candidates, and available ops Context Frame
Candidate gate LLM picks next phase only from OS-provided candidates (P4) LLM as Decision Engine
Phase rollback Revert to predecessor phase when downstream output is rejected LLM Output Contract

LLM Validation

Feature Description Documentation
JSON contract Enforce control / artifact / control_ir envelope structure LLM Output Contract
Type-decision consistency finish type requires decision=finish, next_phase=null, etc. LLM Output Contract
Next-phase allowlist Transition target must appear in the skill graph candidates LLM Output Contract · Graph
Artifact schema validation data validated against the target phase's input_schema Artifact YAML
Normalization retry Minor JSON errors healed before rejecting, up to llm_max_retries LLM Output Contract

Workspace (P5)

Feature Description Documentation
Artifact storage Phase artifacts persisted to .reyn/artifacts/ Concepts: Workspace
Permission-gated IO Paths outside CWD require file.read / file.write declaration Concepts: Workspace · Permissions

Crash Recovery

Feature Description Documentation
.reyn/ layout + recovery-core classification Which .reyn/ subtrees are recovery-core (state/ + config/) vs persist / audit / cache / outside; the recovery-core write-gate (mutate config via dedicated ops, never raw file.write) .reyn/ directory layout
Config recovery (config-as-snapshot) Config registries (.reyn/config/: mcp/cron/hooks/index) reconstruct from truncation-surviving config generations (full-state snapshots written by the durability worker, seq-keyed) — replacing the former config_changed-WAL-event replay, which a WAL truncation below the floor could silently drop (#2259 PR-1). The .yaml IS the durable snapshot, not a derived projection .reyn/ directory layout
WAL state log step_started / step_completed / step_failed written to .reyn/state/wal.jsonl (StateLog); fsync'd off the event loop via the shared DurabilityWorker. #2259: durable-RECORD writes (snapshots / config / identity) are async fire-and-forget — the task loop never blocks on durability; step_started BLOCKS by design (durable-before-side-effect, so a crash-mid-op is detected as ambiguous for non-idempotent ops — #2275). Truncatable after snapshot. Not the audit trail — see Event System (P6). Skill Resume
Async-decoupled durability (recover-to-last-durable) In-memory state mutates immediately on the task loop; the seq-keyed durable record is submitted fire-and-forget to the serial DurabilityWorker (the seq is assigned IN the worker). Recovery restores to the last durable record — a consistent prefix; the un-durable tail at crash is lost (relaxed durability). A persistent (§4-exhausted) durable-write failure latches durability_failed → the session fail-stops (DurabilityHaltError on new ops + run-loop halt) so in-memory cannot race a dead disk (#2259) .reyn/ directory layout
Forward-replay resume SkillResumeAnalyzer reconstructs run state from state log Skill Resume
CommittedStep memo Replay recorded op results on resume without re-invoking Skill Resume
World-op bypass Transient ops (web_search, web_fetch) re-execute fresh on resume Skill Resume

Time-Travel / Rewind (Resume)

User-facing point-in-time rewind with branching. Phase 1 and Phase 2 (2a/2b/2c/2d) are production. Concurrent-live-fork (parallel live branches) is owner-rejected out-of-scope. Full design: ADR-0038.

Feature Description Documentation
/rewind picker Interactive checkpoint timeline (seq / timestamp / kind columns); Esc-Esc double-tap shortcut How-to: rewind
Per-checkpoint anchor preview Each picker row shows a rendered scroll-hint anchor How-to: rewind
PITR reconstruct Point-in-time snapshot + WAL-diff reconstruction to target seq Time-Travel concepts · Crash Recovery
Consistent-cut rewind Both substrates (runtime state + workspace shadow-git as-of-N) rewound atomically Time-Travel concepts
Append-only reset-record Undo appends a reset-record at seq R; history before R is preserved on the current branch (no destructive rewrite) Time-Travel concepts
Retention window + GC Configurable checkpoint retention window; stale snapshots GC'd automatically How-to: rewind
Branch registry Abandoned-interval lineage: each fork receives a registry entry with origin seq Time-Travel concepts
checkout(seq) unified primitive Active-branch seq → undo; inactive-branch seq → fork-switch. One primitive for both directions Time-Travel concepts
Multi-fork tree UX Always-tree picker with per-branch anchor labels How-to: rewind
Act-turn runtime-only rewind Ghost-Replay memo truncate for rewind within an in-flight turn (no substrate round-trip) Time-Travel concepts
Container-mode shadow-git Shadow-git as-of-N rewind supported inside the container environment backend How-to: rewind
Deterministic CI rewind gate test_live_rewind_gate.py — Phase-1 rewind deterministic gate
Deterministic CI live-fork gate test_live_fork_gate.py — Phase-2 fork / checkout deterministic gate
tmux live e2e P1 undo + P2 fork-switch verified on real terminal
Phase 2c: fork-then-edit New branch on edit via ctrl+t How-to: rewind
Phase 2d: web surface /rewind picker over WebSocket / A2A; web edit via AskUserMessage UX (original message presented for edit + submit) How-to: rewind
Agent archive-delete (reyn agent rm) Archive by default (soft-delete): data preserved — PITR generations + topology membership kept (agent dormant, not destroyed). --purge permanently hard-deletes (topology cascade fires immediately; no rewind possible). WAL-window GC auto-purges archived agents once archival seq leaves the retention window. CLI: reyn agent

Event System (P6)

Feature Description Documentation
171 event types Complete taxonomy: workflow / phase / LLM / tool / budget / permission / etc. Events reference · Concepts: Events
Append-only JSONL .reyn/events/<run_id>.jsonl per-run (EventStore); audit trail — append-only, rotation-based (not per-append fsync). Separate log and lifecycle from the recovery WAL (.reyn/state/wal.jsonl). Events reference
Replay reyn events <path> streams events for audit and debug reyn events CLI

Differentiation vs general agents: the agent loop is an OS-enforced contract — the LLM decides only from OS-provided candidates (P3/P4), every output is schema-validated, every inter-phase value lives in the workspace (P5), and every state change emits an append-only, replayable event (P6). Constrained and auditable by construction, not by developer discipline.


Chat Engine

Chat Compaction

Feature Description Documentation
Head+tail+body budget Keeps the most-recent turns (tail) and earliest context (head) within per-component token budgets; turns between them are replaced by an LLM-generated summary Chat Compaction
Overflow retry loop When the compacted context still exceeds the model limit, budgets for head / tail / summary shrink monotonically per iteration until the prompt fits; fails fast with a structured error when no further reduction is possible Chat Compaction
Adaptive token estimation Learns a per-model token-count multiplier over time, reducing estimation drift across sessions Chat Compaction
Multimodal token estimation Estimates tokens for text and image content; image parts use a fixed per-part cost Chat Compaction
Compaction lock Async mutex prevents concurrent turn appends from racing with an in-flight compaction call Chat Compaction

Differentiation vs general agents: instead of naive truncation or an unbounded growing memory, Reyn budgets context as head + tail + LLM summary with a monotonic overflow-shrink retry, adaptive per-model token estimation, and multimodal estimation — predictable context management under a hard model limit.

Router system prompt

Feature Description Documentation
Static / dynamic SP split The router system prompt separates a stable, cache-prefix-friendly head from per-turn dynamic sections LLM invocation surfaces
Task-completion guidance Anti-fabrication guidance steering the model to finish and verify rather than claim completion prematurely SP-improvements study
Model-family-gated steering A coarse model-family classifier gates non-Claude operational-steering hygiene — added only when the router model is non-Claude, kept off the Claude path SP-improvements study
Memory-quality guidance (gated) Guidance on what makes a good memory entry, rendered only when memory is in scope SP-improvements study

Differentiation vs general agents: these SP improvements are adopted by design-judgment (sound + low-cost + non-harmful), not gated on a limited-environment A/B — a measured null on one environment cannot prove a universal negative, so structurally-sound guidance is adopted while genuinely measurable wins are verified separately.

LLM router resilience

Config-gated litellm.Router slot-in for provider-resilience. Default OFF (llm.router.use: false) — the direct litellm.acompletion path is byte-identical. When enabled the Router owns infra retry, Retry-After handling, cooldown, and cross-model fallback; Reyn does not re-implement any of these.

Feature Description Documentation
litellm.Router delegation When llm.router.use: true, LLM calls route through a litellm.Router; Reyn delegates infra-exception retry / Retry-After / cooldown / fallback entirely to the Router Config: llm block · Reliability
Default OFF — byte-identical use: false (default) keeps the direct litellm.acompletion path with no routing overhead; the on/off switch is the only code-path change Config: llm block
Cross-model fallback chain llm.router.fallbacks maps primary deployments to an ordered fallback list; on primary failure the Router tries each fallback model in order Config: llm block
Retry-After aware retry llm.router.num_retries caps infra retries; the Router natively honours provider Retry-After headers (fold of retry-engineering gap) Reliability
Per-deployment cooldown llm.router.cooldown_time + allowed_fails cools a deployment after repeated failures; subsequent calls route to the fallback chain until recovery Config: llm block
Accurate cost on fallback On fallback the actual responding model is recorded from response.model so cost attribution reflects which deployment served the call Budget config
Config-fingerprint Router cache Router is cached per event-loop with a (model, config-fingerprint) key; a changed llm.router.* rebuilds the Router rather than silently reusing a stale instance Config: llm block
llm.router.credentials rotation Per-model list of API-key env-var names; the Router cycles through active keys; a declared model with zero resolvable keys fails loudly — never a silent keyless deployment Config: llm block

Differentiation vs general agents: provider-resilience is delegated entirely to litellm.Router (Retry-After, jitter, cooldown, cross-model fallback chain, credential rotation) rather than re-implemented — the on/off gate keeps the direct path byte-identical, so replay and cost-recording work unchanged whether or not the Router is active.


Control IR Ops

All ops are documented in the single reference page: Control IR

The op kinds below mirror OP_KIND_MODEL_MAP in op_runtime/registry.py.

Op Description
file read / write / edit / delete / glob / grep / regenerate_index (six fine-grained registry kinds)
ask_user Pause phase, collect user answer, re-run same phase
sandboxed_exec argv under SandboxPolicy via platform-selected backend
shell Raw shell exec — deprecated; prefer sandboxed_exec
web_search DuckDuckGo search — Tier 1, default-allow
web_fetch URL fetch + text extract — Tier 1, default-allow
mcp Call a configured MCP server tool by name
mcp_install Install / register an MCP server (registry / package / local source)
index_query Vector similarity search over one indexed source
recall Macro: embed query → index_query per source → merge top-K
index_drop Destructive source removal — requires approval
compact Summarise / compact context within budget (chat + phase results)
judge_output LLM scorer with rubric + threshold + on_fail policy

The embed and index_write ops were removed — embedding and index-writing now run provider-direct inside reyn.api.safe.embed_index and the recall op, not as standalone ops. See Control IR.


Tool-Use Schemes

How tools are presented to the LLM and how its calls are dispatched is a pluggable scheme, selectable per layer (tool_use: {chat, step, phase} in reyn.yaml). The chat layer defaults to enumerate-all; step / phase default to universal-category. Non-default schemes are opt-in per layer. All schemes route every tool call through the same OS gate (exclude → permission → dispatch), so the security and validation pipeline is unchanged whichever scheme is active.

Feature Description Documentation
Pluggable scheme protocol ToolUseScheme seam — tool presentation + interpretation + dispatch + feedback behind one interface; schemes are swapped by config, no OS change Tool-Use Schemes
Per-layer selection Independent scheme per layer — chat / plan-step / OS-phase — via tool_use config Tool-Use Schemes · reyn.yaml § tool_use
universal-category (step/phase default) The universal action catalog — 4 wrappers over every category, qualified-name discover + dispatch Tool-Use Schemes · Universal catalog
enumerate-all (chat default) Flat-native-JSON baseline — every usable tool presented flatly, dispatched by name. Best for small tool sets where determinism matters Tool-Use Schemes
retrieval RAG-over-tools — present a search tool, the LLM searches, the OS re-presents matched tools as callable. Supported opt-in for very large tool sets where full-catalog token cost is prohibitive; requires a configured embedding provider (action_retrieval.embedding_class) Tool-Use Schemes
CodeAct Code-as-tools — the LLM writes a Python snippet whose in-code tool() calls run in a sandboxed subprocess under the same permission gate as a JSON call. Strongest for weak models Tool-Use Schemes

Differentiation vs general agents: the tool-use strategy is a swappable scheme — enumerate-all / retrieval / CodeAct / the default catalog — chosen per layer by config, without changing the OS. Because every scheme dispatches through the same exclude → permission → dispatch_tool gate (P4/P5), swapping the LLM-facing tool surface never weakens the security or validation pipeline. The presentation is data; the gate is constant.


CLI

Command Description Documentation
reyn chat Interactive multi-turn chat with a named agent Reference
reyn agent Create and manage named persistent agents Reference
reyn topology Create and manage communication topologies Reference
reyn memory CRUD + search + export/import for agent memories Reference
reyn permissions Inspect and revoke saved approval entries Reference
reyn events Replay event JSONL files or purge old files by date Reference
reyn mcp Serve, search, install, and manage MCP servers Reference
reyn secret Set / list / clear secrets in ~/.reyn/secrets.env Reference
reyn source List, describe, and remove indexed RAG sources Reference
reyn embeddings status / rebuild / clear for the action embedding index (search_actions) Reference
reyn config Show, query, and set effective configuration Reference
reyn auth Manage OAuth credentials — login (RFC 8628 device grant against auth.providers) / list / revoke reyn.yaml § auth
reyn cron Manage and run cron-scheduled skill jobs — foreground scheduler / list jobs + next-run / status reyn.yaml § cron
reyn web Start FastAPI + WebSocket gateway server Reference
reyn init Scaffold reyn.yaml and .reyn/ in current directory Reference

Config

Main reference: reyn.yaml

Block Description Documentation
3-layer cascade user-global / project / project-local + CLI flags reyn-yaml
${VAR} interpolation Env var expansion in all string fields via secrets.env reyn-yaml § interpolation
safety Loop caps / timeout caps / on-limit policy reyn-yaml § safety
cost Per-agent / per-chain / daily / monthly token+USD caps Budget config
sandbox Backend selection (auto/seatbelt/landlock/noop) + on_unsupported reyn-yaml § sandbox
web web.fetch SSL verify_ssl and ca_bundle override reyn-yaml § web
eval Trace exporters: file / langfuse / otlp (optional dep opentelemetry-exporter-otlp-proto-http) / ietf_audit reyn-yaml § eval
chat Compaction trigger / head+tail retention / section token caps Chat Compaction
embedding Model classes / batch_size / cost_warn_threshold RAG concepts
voice Whisper model / language / device — optional reyn[voice] Voice concepts
events Rotation size/age + cleanup_period_days Events reference
models Class → LiteLLM model string with extends chain reyn-yaml § models
permissions Project-wide default capability policy Permissions config
multi-agent Agent and topology defaults Multi-agent config
state_dir Runtime state directory (default .reyn/) State dir
auth OAuth provider definitions for reyn auth login (RFC 8628 device grant) reyn-yaml
mcp Configured external MCP server connections (transport + env) Concepts: MCP
multimodal Media handling caps (max_bytes, per-part token cost) reyn-yaml
python python-step execution policy (safe / unsafe subprocess) Preprocessor
cron Cron-scheduled skill job definitions reyn-yaml
action_retrieval Action-catalog search_actions retrieval tuning Universal catalog
hooks Agent-lifecycle push/shell hooks at 8 points (turn_start/end, session_start/end, skill_start/end, task_start/end). push mode: wake:false passive context ride-along, or wake:true self-continuation bounded by safety.loop.max_hook_driven_turns. shell: sandbox-gated side-effect, output ignored. Shell-hook consent routes through the intervention bus → TUI Pending-tab modal ([A]lways / [y]es / [n]o; Always persists to ~/.reyn/shell-hooks-allowlist.json); falls back to stdin on non-TUI. All shell runs emit hook_shell_executed P6 event (Events-tab "tool" group; prefix shell_exec: or shell_push:). Hooks emit attributed [hook:name] messages — history is never silently mutated. reyn-yaml § hooks · Concepts: hooks
Config hot-reload Runtime re-read of the IN-set (.reyn/mcp.yaml / cron.yaml / hooks.yaml) at the turn boundary without a process restart. OUT-set (reyn.yaml: security / budget / loop valve) is restart-only — the file-split is the structural write-gate. Two triggers: operator /reload and agent hooks_add LLM-op. Validate-before-apply + per-layer boot resilience + sandbox/loop-valve = safe-by-construction. Concepts: Config hot-reload

Permissions

Feature Description Documentation
Tier 0 — always allowed ask_user — no gate Permission model
Tier 1 — default-allow web_search / web_fetch — deny-only gate Permission model · Permissions config
Tier 2/3 — declaration + 4-layer approval shell / mcp / file (out-of-zone) / python Permission model
Layer 1: config pre-approval reyn.yaml hard allow / deny Permissions config
Layer 2: saved approvals .reyn/approvals.yaml — persisted per path/server reyn permissions CLI
Layer 3: session approvals In-memory for current invocation only Permission model
Layer 4: interactive prompt Ask user with persist choices (yes / always / just-this-path) Permission model
CLI gates --allow-unsafe-python required at invocation Common flags
Capability profile Per-agent MCP / tool / category capability restriction (ProfileLayer in the ∩ model); agent can self-edit .reyn/agents/<name>/profile.yaml within the default write zone Concepts: Capability profile · Reference: profile.yaml
Delegation policy Config-selectable default-deny for delegated agents: delegation.capability_default=deny narrows any unbound delegate with the restrictive _delegate floor (same deny taxonomy as _untrusted). Binding replaces the floor (= the re-grant). Recursive: no laundering via re-granted coordinators. reyn audit (gateway:delegation-unsafe) flags re-grants with OPT-A reachability precision (HIGH exit on re-delegation/exec). Concepts: Delegation policy · Concepts: Capability profile

Differentiation vs general agents: autonomous agents typically execute tools with minimal gating. Reyn requires per-capability declaration + 4-layer just-in-time approval (config → saved → session → interactive), a .reyn/ write zone, and per-skill credential scoping (Confused Deputy mitigation).


Safety / limit-handling

Bounded-operation checkpoints that stop the agent gracefully rather than hard-failing. See Safety framework.

Feature Description Documentation
handle_limit_exceeded unified checkpoint Single shared function runtime/limits/limit_handler.py that all seven loop / timeout / budget checkpoints call; owns the 3-mode dispatch, bus interaction, extension bookkeeping, and audit event — callers only decide what limit fired Safety framework
On-limit modes (OnLimitConfig) interactive (ask) / auto_extend (budgeted N times) / unattended (abort) via safety.on_limit.mode; applies uniformly to loop caps, timeout caps, and budget exceed paths Safety framework · reyn.yaml § safety
Force-close wrap-up On a denied limit the LLM gets one final tool-less turn to summarise what was accomplished; delivered as a kind="agent" message with meta.limit_stopped Safety framework
limit_denied event P6 audit event on every deny path (max_iterations / router_cap) Events reference
Decision-enabling fallback When the wrap-up fails or is empty, a structured error states the limit hit, the config key to change, and partial-data availability Safety framework

Differentiation vs general agents: where free-running agents hard-stop or run away at a limit, Reyn's force-close turns a denied limit into a graceful LLM wrap-up plus an operator decision — it reports what it accomplished instead of vanishing or looping unbounded.


Content-layer defense

Scanning untrusted content (memory, tool results, context files, inbound peer messages) for prompt-injection / exfiltration / role-hijack patterns at the seams where it enters the prompt — a security transform at a content boundary, not OS decision logic. Design: content-threat scan proposal.

Feature Description Documentation
Threat-pattern library ✅ Security-domain regexes (injection / exfiltration / role-hijack / exec) applied to untrusted content across all scopes — security/threat_patterns.py Design
Content fence ✅ Wraps untrusted content in explicit delimiters so model-visible boundaries are unambiguous — security/content_fence.py Design
Unified tool-result guard ✅ One seam scans + fences tool-result content before it reaches the prompt — security/content_guard.py Design
Memory-write BLOCK ✅ Memory writes that match threat patterns are blocked before reaching the agent's memory store — runtime/router_loop.py Design
Pre-exec command scan ✅ sandboxed_exec scans the full joined argv against exec-scope threat patterns before any shell is launched; blocked commands emit exec_threat_blockedcore/op_runtime/sandboxed_exec.py Design
Context-file + A2A-inbound fence ✅ Operator-editable context files (REYN.md/AGENTS.md) and untrusted inbound A2A peer messages are fenced + scanned on arrival — router_host_adapter.py (EP3) / inter_agent_messaging.py (S4b) Design
Compaction secret redaction ✅ Secret-looking content is stripped from compaction input before summaries are persisted — security/secret_redaction.py Design

Differentiation vs general agents: Reyn places content-layer scanning at the OS seams — the same content boundaries where secret interpolation already sits — as a security-domain transform that keeps OS decision logic free of skill strings (P7). Structural redundancy means checks already enforced by the sandbox / permission layer (e.g. absolute-path or pipe-to-shell writes) are not re-implemented as ad-hoc per-call scans.


Budget & Cost

Feature Description Documentation
Per-agent caps Token + USD hard limits with warn_ratio Budget config
Per-chain caps Skill spawn count + token total per chain Budget config
Rate limits Per-model calls-per-minute sliding window Budget config
Daily quotas Persistent JSONL ledger, resets at local midnight Budget config
Monthly quotas Persistent JSONL ledger, resets at month boundary Budget config
Crash-durable cap counters Every cap counter (daily / monthly / per-agent token+USD / per-chain spawn count) is reconstructed on startup from the fsync-per-append ledger — a crash inside the throttled budget_state.json save window cannot under-count a cap and re-allow over-budget calls or spawns. The state file is a best-effort cache; the ledger wins on recovery Budget config · state-dir
extension_calls (+ safety.on_limit.mode) Budget-extension flow on hard cap hit; extension_calls > 0 opts the dimension into the unified safety.on_limit policy (ask / auto-extend / deny). The per-dimension ask_on_exceed bool was removed. Budget config
High-cost model warn (cost_warn) cost_warn.enabled (default true) emits a model_cost_warn event + inline conv-pane marker when the resolved model's input cost per 1M tokens exceeds model_threshold_per_1m_input_usd (default 5.0); fires at /model switch and session startup, de-duped once per model per session reyn.yaml § cost_warn

Differentiation vs general agents: token + USD caps per agent / chain / model with refuse-on-exceed and a safety.on_limit-driven extension flow, plus a pre-selection high-cost model warning — runaway spend is structurally bounded, not merely observed after the fact.


Memory & RAG

Feature Description Documentation
LiteLLM embedding backend Any provider via named model class config RAG concepts
Local embedding backend sentence-transformers via pip install 'reyn[local-embed]'local-mini / local-e5 classes, credential-free, GPU-optional via REYN_EMBED_DEVICE RAG concepts § Local embedding backend · Guide
Provider-prefix routing sentence-transformers/ → local backend; anything else → LiteLLM RAG concepts § Embedding configuration
Batch embed Configurable batch_size with concurrency semaphore RAG concepts
Dimension table Static lookup for OpenAI / Voyage / Cohere RAG concepts
SQLite index per source .reyn/index/<source>/index.db with WAL mode RAG concepts
Chunk dedup content_hash upsert prevents re-indexing RAG concepts
recall op embed → index_query per source → merge top-K globally Control IR
Action embedding index ActionEmbeddingIndex (SQLite-WAL, class-swap detection, cross-process build lock) — backs the search_actions tool the chat LLM uses Universal catalog § search_actions · reyn embeddings
Memory CRUD list / read / remember_shared / remember_agent / forget Memory concepts · reyn memory CLI

Differentiation vs general agents: beyond chat memory, Reyn ships a RAG framework — a safe-mode Python step calls embed_and_index() directly (you own the chunking logic) over a pluggable IndexBackend, with a credential-free local-embedding option. A foundation to build on, not a fixed memory feature.


MCP

Feature Description Documentation
stdio transport Subprocess StdioServerParameters — implemented Concepts: MCP
HTTP transport Streamable HTTP with request headers — implemented Concepts: MCP
SSE transport Reserved — raises NotImplementedError Concepts: MCP
mcp serve Expose Reyn agents as an MCP server over stdio JSON-RPC 2.0 reyn mcp CLI
mcp install Fetch from registry, gate permissions, write config, store secrets. Three chat verbs: mcp__install_registry (official registry), mcp__install_package (npm/pypi/docker/github URL), mcp__install_local (direct command). CLI: reyn mcp install <SERVER_ID> or --source <SPEC>. Concepts: MCP · reyn mcp CLI
Secret management Per-server env vars in ~/.reyn/secrets.env reyn secret CLI
Tool dispatch Lazy-load and cache MCPClient per server connection Concepts: MCP

Differentiation vs general agents: Reyn is both an MCP client (consumes external servers) and an MCP server (exposes its own agents) — standard-protocol interop in both directions, with stdio MCP servers subprocess-sandboxed under Seatbelt.


Skills

Feature Description Documentation
SKILL.md registry Explicit skills.entries declarations (no directory scan) — same registration model as mcp.servers Concepts: Skills
Three-layer exposure L1 system-prompt ## Skills menu (name — description [path]) → L2 on-demand SKILL.md read → L3 bundled-asset file-read, all via the ordinary file-read op Concepts: Skills
Config cascade ~/.reyn/config.yamlreyn.yamlreyn.local.yaml ⊕ dynamic .reyn/config/skills.yaml, later tier wins on name collision Reference: reyn.yaml
Hot-reload .reyn/config/skills.yaml edits apply at the next turn boundary via the "skills" reload seam Concepts: Config hot-reload
Session visibility toggle set_capability_visible("skill", name, visible) — restrict-only, cannot re-grant beyond the registered set Concepts: Skills
skill_management__install_local Register a local skill directory into .reyn/config/skills.yaml; threat-scanned, permission-gated, config-generation recorded for crash-recovery Concepts: Skills
skill_management__install_source Fetch + shallow-clone a skill from a git/GitHub URL into .reyn/skills/<name>/; same threat-scan/gate/recovery pipeline, plus path-traversal-hardened name sanitization and containment checks Concepts: Skills

Differentiation vs general agents: skills are instructions the model chooses to read, not programs the OS executes — the same layered-disclosure shape (menu → on-demand load) as MCP tool discovery, applied to task-specific technique instead of external APIs.


Web & Protocol

Feature Description Documentation
FastAPI gateway REST + WebSocket server on localhost:8080 reyn web CLI
WebSocket chat /ws/chat for interactive browser sessions reyn web CLI
A2A Agent Card Per-agent /.well-known/agent-card.json capability declaration reyn web CLI
A2A message/send Synchronous JSON-RPC 2.0 single-turn endpoint per agent reyn web CLI
A2A agent discovery GET /a2a/agents server-level listing reyn web CLI
A2A async tasks async_modeTask envelope; GET /a2a/tasks/{run_id} poll, …/events SSE stream, …/cancel; mid-run ask_user surfaces as input-required A2A concepts
Webhook push Status-transition POSTs to params.webhook_url for async tasks (reyn.web.notifications) A2A concepts
MCP-over-SSE /mcp/sse + /mcp/messages for MCP client connections reyn web CLI · reyn mcp CLI
REST API /api/* for agents / skills / runs / topologies / budget / permissions reyn web CLI

Differentiation vs general agents: competitors specialise in broad, deep connectivity to the messaging apps you already use. Reyn keeps connectivity to standard protocols — MCP (client + server), A2A (sync + async tasks with webhook push), and a REST / WebSocket gateway — rather than per-app integrations.


TUI

The Textual terminal interface for reyn chat (src/reyn/interfaces/tui/).

Feature Description Documentation
Conversation view Streaming conversation with inline thinking rows and tool-call rendering
Right Panel tabs Live side panels: Agents / Cost / Docs / Events / Keys / Memory / Pending
Tool-result viewer registry ✅ register_viewer seam replaces inline content-type dispatch; register_content_type_viewer(content_types, viewer, *, match="exact"\|"prefix"\|"substring") provides the ergonomic MIME shorthand — delegates to register_viewer so name/position behave identically Tool-result viewers reference
LLM-generated template fallback ✅ On registry miss, _generate_template async-generates a TemplateSchema (label/value rows + caption) via LLM call; _apply_template renders it with label escape and row/caption caps (_MAX_TEMPLATE_ROWS=8, _MAX_CAPTION_CHARS=40) Tool-result viewers reference · FP-0051 proposal
Email-diff viewer ✅ Concrete viewers for message/rfc822 (email from/subject card) and text/x-diff / text/x-patch (syntax-highlighted patch); registered before the generic JSON viewer so declared content-type takes priority Tool-result viewers reference
Input + command palette Input bar with slash commands (/plan, /compact, /find, /help, /clear) via a command palette
Intervention widget In-TUI ask_user prompt rendering
Chainlit web chat (⚗ PoC) Alternative browser chat UI sharing the same agent — reyn chainlit + chainlit_app/ (agent picker, settings, uploads, slash routing); coexists with the TUI

Differentiation vs general agents: Reyn's chat surface is a local, inspectable TUI with live audit panels (events / cost / permissions) beside the conversation — the operator sees what the agent is doing and spending in real time.


Intervention

Cross-surface ask_user and permission routing — the same prompt reaches the operator over whichever surface is active (chat/services/intervention_registry.py).

Feature Description Documentation
InterventionBus family ChatInterventionBus (TUI) / StdinInterventionBus (CLI) / A2AInterventionBus (web) / _MCPInterventionBus (MCP) Permission model
InterventionRegistry Tracks pending interventions and pairs each answer back to the waiting run
ask_user lifecycle Pause run → surface prompt → resume on answer; async wait works across surfaces Control IR — ask_user

Differentiation vs general agents: human-in-the-loop is a first-class, surface-agnostic primitive — a permission ask or ask_user routes to the operator identically whether the agent runs in the TUI, CLI, web / A2A, or MCP.


Sessions and identity

Feature Description Documentation
Two-level model Agent (identity) → Session (conversation) Concepts: Sessions
Multiple Sessions per Agent One identity, many parallel conversations; AgentRegistry maps name → {sid → Session} with a shared Agent identity Concepts: Sessions
Identity vs conversation scope Memory / permissions / workspace / peer-addressing live on the Agent; history / inbox-outbox / current task stay per-Session Concepts: Sessions
Per-session persistence Each Session is snapshotted and restored independently (WAL-backed; snapshot re-keyed per Session) Concepts: Sessions
Global-cut time-travel /rewind moves every Session and Agent to the target checkpoint atomically (one global single-seq WAL) — per-Session granularity is in persistence, not the rewind Concepts: time-travel
Multi-session crash recovery On restart the full name → {sid → Session} structure is reconstructed from event log + snapshots, not just one conversation Concepts: time-travel
Transport routing-key Default: native conversation-id → Session (namespaced, auto-spawn/resume). Explicit: join an existing Session by id (non-existent = error). Scoped within one Agent Concepts: Sessions

Differentiation vs general agents: the Agent / Session / runtime split is the mainstream agent-platform shape (cf. Assistant / Thread / Run); Reyn's distinction is what sits beneath it — every Session is event-sourced, permission-gated, and independently persisted, so one identity can hold many isolated conversations, with a single global consistent-cut rewind across them all.


Multi-Agent

Feature Description Documentation
Agent registry Named agents with role profiles + history.jsonl reyn agent CLI
network topology Full mesh — any member to any member reyn topology CLI
team topology Star around leader — member-to-member forbidden
pipeline topology Ordered — each member sends only to next
_default topology Auto-synthesized full mesh for unassigned agents Multi-agent config
MessageBus Quiescence-based coordination with reply_to correlation Multi-agent config
delegate_to_agent Async-dispatch to peer with topology permission gate Multi-agent concepts
Agent hops cap Max delegation depth via safety.loop.max_agent_hops reyn-yaml § safety
chain_id propagation Trace multi-hop chains in P6 events Events reference

Differentiation vs general agents: delegation is topology-gated (network / team / pipeline) with a hop-depth cap and chain_id audit propagation — multi-agent reach is bounded and traceable, not free-form.


LLM org-design (runtime spawn primitives)

Three router-only tools the LLM uses to build a live organisation at runtime — distinct from the operator CLI / Topology YAML surface (which defines structure up front in configuration).

Feature Description Documentation
agent_spawn Create a new agent (name + role) under the calling agent's authority; capabilities capped at ⊆ the spawner's by construction; spawn lineage is OS-set / identity-keyed (forge-guarded) Concepts: LLM org-design tools
session_spawn Start a fresh-context sub-session under the calling agent to run a task in isolation; mode=ephemeral auto-vanishes after the task, mode=persistent stays; optional narrowing (restrict-only) at spawn time Concepts: LLM org-design tools
topology_create Wire agents in the caller's spawn subtree into a named topology (network / team / pipeline) and optionally bind members to capability profiles (narrowing within the ⊆-parent envelope); subtree-restriction gate enforced by OS Concepts: LLM org-design tools
⊆-parent capability model Spawned agent effective capability = parent's live effective ∩ assigned profile; recursive no-escalation-via-spawn; closed across four stale-lineage axes (live, rewind-drop, absent-parent, name-reuse) Concepts: permission model § LLM spawn
Operator spawn-tree bounds safety.spawn.max_depth (chain depth) + safety.spawn.max_children (fan-out + topology member count) — DoS guard; exceeding either fires the safety.on_limit checkpoint (interactive=operator-prompt / unattended=reject / auto_extend); depth and children carry separate per-spawner extension keys; LLM cannot self-raise the base limit reyn-yaml § safety.spawn

Differentiation vs general agents: the LLM designs the org structure at runtime — not free-form (every spawned agent is capability-capped at ⊆ the spawner, recursively), not pre-wired (the org emerges from the task), and fully rewind-safe (lineage is WAL-tracked; spawn and topology events survive crash recovery).


Task system

The dynamic work-unit model: small composable ops the LLM reaches for as structure emerges, instead of an upfront plan.

Feature Description Documentation
Dynamic task ops 11 composable work-unit ops (task__create / update_status / get / list / add_dependency / remove_dependency / repoint_dependency / abort / heartbeat / register_unblock_predicate / comment) the LLM reaches for when structure emerges Concepts: Tasks · Control IR — Task ops
Requester / assignee model Requester (creator, notify-target) vs a single immutable assignee (worker); a non-self assignee delegates cross-session; a task created while executing a task is automatically owned (requester) by it — OS-derived, no parent_id op field (§16) Concepts: Tasks
Single-writer CAS gate Only the assignee session may write a task's status — fixed-equality assignee == caller session_id in the backend; topology writes (deps / abort) are owned by the requester Concepts: Tasks
Dual-path, no bypass The same assignee CAS is enforced whether ops arrive from a phase's control-IR or the chat router (invoke_action); the bridge refuses a session-less context rather than mask the gate Concepts: Tasks
Dependency DAG deps are depends-on edges; a task with unmet deps is OS-derived blocked, readiness recomputed (never written); edges are existence- + cycle-checked; repoint swaps a dep to a substitute Concepts: Tasks
Cross-session WAKES A born-startable delegated task — and a dependent promoted to ready — wakes its assignee session to execute it, with the OS execute-framing as the trusted instruction Concepts: Tasks
Content-fenced task text The free-text description / name / result fields are structurally fenced as untrusted data on the query path (task.get / list) and in the execution-path wake message; OS-generated structural fields stay unfenced Security: what gets structurally fenced
/tasks view List running tasks + per-task status + kill, spanning skill runs and dynamic tasks chat CLI
Single-source ToolDefinitions The LLM-facing tool schemas are derived from the IROp models (model_json_schema() minus the kind discriminator), so the catalog never drifts from the runtime contract Control IR — Task ops

Differentiation vs general agents: rather than a forced upfront plan, the task model is small composable ops the LLM reaches for as structure emerges — with a single-writer compare-and-set on the immutable assignee session (no hand-off, no bypass across the phase / chat paths), a cycle-checked dependency DAG, and cross-session WAKES that let one agent hand a durable, crash-recoverable work-unit to a peer.


Sandbox

Feature Description Documentation
SeatbeltBackend macOS sandbox-exec SBPL profile generation Concepts: Sandbox
LandlockBackend Linux 5.13+ Landlock LSM + seccomp-BPF stacking Concepts: Sandbox
NoopBackend Fallback audit-only with one-time WARN log Concepts: Sandbox
SandboxPolicy network / read_paths / write_paths / subprocess / env_passthrough / timeout Control IR — sandboxed_exec
Auto-selection Platform detection + on_unsupported: warn\|error\|ignore reyn-yaml § sandbox · Concepts: Sandbox

Differentiation vs general agents: tool / code execution runs under an OS-level sandbox (Seatbelt / Landlock + seccomp-BPF) with an explicit SandboxPolicy, rather than unsandboxed tool calls. Stdio MCP servers are also subprocess-wrapped under Seatbelt.


Environment — ⚗ Stage 2 (experimental MVP)

Repo-filesystem mechanism abstraction decoupling the workspace from where the repo FS lives. The host backend is production; the container backend is an exec-per-op MVP. See src/reyn/environment/.

Feature Description Documentation
EnvironmentBackend protocol Abstracts repo-FS read / write / exec away from the OS + permission layer
HostBackend Default — identity over the local filesystem (production)
DockerEnvironmentBackend ⚗ Stage 2 MVP — repo FS + exec inside a Docker container (--container attach); exec-per-op
Mount-mode launcher ⚗ container launch with the repo mounted + devcontainer.json awareness / build-on-demand

Differentiation vs general agents: Reyn adopts the container-exec pattern those agents popularised (e.g. Hermes docker-exec), but keeps the OS + permission + audit layer on the host while only the repo FS lives in the container — sandboxed execution without surrendering governance. (⚗ Stage 2 / experimental.)