Perseusโ„ข ๐Ÿชž

July 5, 2026 ยท View on GitHub

Perseus โ€” Live Context Engine. One command. Zero orientation.

Perseusโ„ข ๐Ÿชž โ€” One command. Zero orientation.

smithery badge pip install perseus-ctx && cd your-project && perseus quickstart

Perseus demo โ€” before/after cold-start

CI PyPI MCP Registry License: MIT Status: Patent Pending perseus.observer โ†’


๐Ÿ›ก๏ธ Product Family

Perseus is the live context engine. Seven specialized products extend it:

ProductDescriptionPage
Perseus Vault55 MCP tools (exposed under 3 name aliases: perseus_vault_*/mimir_*/mneme_*) โ€” persistent memory with FTS5, entities, layers, confidence decay/perseus-vault/
MCTS31 security analyzers for MCP servers โ€” tool poisoning, prompt injection, credential leaks/mcts/
PR Pilot5-agent autonomous PR review pipeline โ€” graduated autonomy L1โ†’L3/pr-pilot/
Blast RadiusGitLab-native dependency impact analysis โ€” 1 mention, instant risk report/blast-radius/
Rapid AgentDual-backend memory agent (Elastic โ†” Engram-rs) โ€” Google Cloud Hackathon/rapid-agent/
Qwen MemoryAgent that gets smarter every session โ€” Qwen Cloud Hackathon/qwen-memory/
CrewAI MemoryPersistent cross-session memory backend for CrewAI (54K stars) โ€” community PR #6208/crewai/

Perseus Vault โ€” Persistent Memory (MCP)

Perseus Vault is the persistent memory backend for Perseus โ€” a lightweight Rust MCP server with SQLite + FTS5. Zero network calls, no API keys. As of v2.7.0, offline dense/hybrid embeddings are bundled by default (the model is compiled into the binary), so semantic recall works zero-config with no external model download. v2.14.0 provides 55 distinct MCP tools (each exposed under perseus_vault_*, mimir_*, and mneme_* aliases, so a raw tools/list handshake reports ~165) across structured entities, hybrid vector search, RAG, connectors, confidence decay, journal events, and state management: perseus_vault_remember, perseus_vault_recall, perseus_vault_context, perseus_vault_traverse, perseus_vault_decay, perseus_vault_stats, perseus_vault_health, and more.

๐Ÿ“„ Product page โ†’ | โญ GitHub โ†’

Install (prebuilt binary โ€” Linux / macOS):

curl -sSf https://raw.githubusercontent.com/Perseus-Computing-LLC/perseus-vault/main/scripts/install.sh | sh

Windows / Intel-macOS (build from source): cargo install --git https://github.com/Perseus-Computing-LLC/perseus-vault. Then run perseus doctor to confirm Perseus can reach it.

Hermes Agent โ€” add to ~/.hermes/config.yaml:

mcp_servers:
  perseus_vault:
    command: "perseus-vault"
    args: ["serve"]

Claude Desktop / Cursor โ€” add to your MCP settings:

{
  "mcpServers": {
    "perseus_vault": {
      "command": "perseus-vault",
      "args": ["serve"]
    }
  }
}

Perseus integration โ€” add to .perseus/config.yaml:

perseus_vault:
  enabled: true
  command: ["perseus-vault", "serve"]

The perseus-vault binary self-resolves its canonical default DB path, so no --db argument is needed (its default is ~/.mimir/data/perseus-vault.db). The legacy mimir: key is still accepted for back-compat, so existing configs keep working. Then add @memory mode=search query="your terms" to .perseus/context.md and Perseus resolves live recall at render time.

Works with any MCP-compatible assistant.

๐Ÿ† Hackathons โ€” 3 Entries Submitted

Google Cloud Rapid Agent (Elastic Partner Track)

Status: Submitted | Deadline: June 11, 2026 | Devpost: perseus-cmzeu9 ๐Ÿ“„ Product page โ†’

Perseus is entered in the Google Cloud Rapid Agent Hackathon (Elastic Partner Track). The submission demonstrates persistent agent memory across three consecutive sessions, with live backend swap from Elastic Cloud to Engram-rs (self-hosted).

Qwen Cloud Hackathon (MemoryAgent Track)

Status: Submitted | ๐Ÿ“„ Product page โ†’

Agent that gets smarter every session. Persistent memory, confidence decay, cross-session compounding. Track requirements checklist with contradiction demo beat.

GitLab Transcend Hackathon (Showcase Track)

Status: Submitted | ๐Ÿ“„ Product page โ†’

Blast Radius โ€” GitLab-native dependency impact analysis via Orbit knowledge graph. One @mention, instant risk report.

Build with Gemini XPRIZE

Status: Submitted | ๐Ÿ“„ Product page โ†’

PR Pilot โ€” 5-agent autonomous PR review pipeline. Gemini API, Google Cloud Run, Stripe integration.

Wire Perseus to Your Assistant (MCP)

Perseus implements the Model Context Protocol (MCP), exposing tools over stdio or SSE transport. Every tool resolves live workspace state at invocation time โ€” no stale cache, no pre-computed snapshots.

โš ๏ธ Security Gate: Shell-executing directives (@query, @agent, @services command:) require export PERSEUS_ALLOW_DANGEROUS=1. Without it, shell directives are silently skipped.

Quick Start (MCP Server)

pip install perseus-ctx
perseus mcp serve                          # stdio (Claude Desktop, Claude Code, Cursor, Codex)
perseus mcp serve --transport sse --port 8420  # SSE (remote agents, multi-machine)

Assistant-Specific Wiring

Pick your assistant and add the config block shown:

Hermes Agent (~/.hermes/config.yaml):

mcp_servers:
  perseus:
    command: perseus
    args: ["mcp", "serve", "--workspace", "/path/to/workspace"]

Then verify with hermes mcp test perseus. Tools appear as mcp_perseus_* in your session.

Use an absolute path for --workspace. Perseus's non-interactive shell context has a limited PATH โ€” a bare perseus command works in the Hermes MCP config because Hermes resolves it from the user's environment, but the workspace path must be absolute.

Claude Desktop (claude_desktop_config.json):

{
  "mcpServers": {
    "perseus": {
      "command": "perseus",
      "args": ["mcp", "serve", "--workspace", "/path/to/workspace"]
    }
  }
}

Claude Code (.mcp.json in your project root):

{
  "mcpServers": {
    "perseus": {
      "command": "perseus",
      "args": ["mcp", "serve"]
    }
  }
}

Cursor (.cursor/mcp.json):

{
  "mcpServers": {
    "perseus": {
      "command": "perseus",
      "args": ["mcp", "serve"]
    }
  }
}

Codex (~/.codex/config.toml or per-project .mcp.json):

{
  "mcpServers": {
    "perseus": {
      "command": "perseus",
      "args": ["mcp", "serve"]
    }
  }
}

Rovo Dev (.mcp.json in repo root):

{
  "mcpServers": {
    "perseus": {
      "command": "perseus",
      "args": ["mcp", "serve"]
    }
  }
}

Rovo Dev also reads AGENTS.md at session start โ€” pair MCP tools with rendered context for a complete setup.

Docker

docker build -t perseus .
docker run --rm -v /path/to/workspace:/workspace perseus mcp serve

See Container Runtime for full Docker and compose deployment.

MCP Registry

Published as io.github.Perseus-Computing-LLC/perseus on the official MCP Registry (search "perseus"). Includes server.json for zero-config discovery.


MCP Tools

30 MCP tools resolve live state at invocation time (including the legacy aliases perseus_get_context/perseus_get_health). Two additional sensitive tools โ€” perseus_query (run a shell command) and perseus_agent (execute a local agent subprocess) โ€” are not part of this default set: they require explicit mcp.tool_allowlist opt-in because they execute commands in the user's local shell (not sandboxed, full user permissions apply).

ToolDescription
perseus_servicesHealth-check running services
perseus_readRead file contents
perseus_listList directory or structured data
perseus_treeTree view of directory
perseus_envRead environment variables
perseus_dateCurrent date/time
perseus_waypointLatest checkpoint summary
perseus_sessionRecent session digests
perseus_healthContext maintenance report
perseus_driftOracle drift report
perseus_memoryLocal narrative recall + persistent Perseus Vault store
perseus_mimirRecall persistent memories via BM25 (legacy name of perseus_mneme)
perseus_mnemeRecall persistent memories from the external Mneme server via BM25
perseus_skillsList available skills with staleness flags
perseus_includeInclude and render another file
perseus_agoraTask board from tasks/*.md
perseus_inboxAgent message inbox
perseus_promptSystem prompt block
perseus_validateValidate rendered block against schema
perseus_toolRun allowlisted external tool
perseus_perseusFetch context from remote Perseus instance
perseus_auto_skillInstruct the agent to load a specific skill before starting work
perseus_profileResolve a per-model context profile (context target + memory posture)
perseus_masonQuery the Mason code architecture concept map
perseus_researchPer-paper Methods/Results blocks from an external paper-search MCP server (external server is opt-in via config)
perseus_tokensEmbed token budget for rendered context
perseus_budgetDeclare a token budget enforced by perseus prompt-size
perseus_tooltrimFiltered toolset metadata and usage statistics
perseus_get_contextFull rendered workspace context (legacy alias)
perseus_get_healthDaedalus context-maintenance heuristics (legacy alias)

Opt-in only (excluded from the default set until added to mcp.tool_allowlist):

ToolDescription
perseus_queryRun a shell command and return stdout
perseus_agentExecute local agent subprocess

The Problem

Every AI assistant session starts cold. Before useful work begins, the assistant burns turns on orientation โ€” checking which services are running, reading stale config files, rediscovering where you left off. Static markdown files (.cursorrules, CLAUDE.md) rot immediately. The port you wrote down has changed. The container that was "always running" hasn't been started since Tuesday.

Stale context isn't neutral. It's drag.


The Fix: Resolve Before Context

Perseus is a pre-processor. You write directives in a source document โ€” @query, @services, @waypoint โ€” and Perseus resolves them at render time, then outputs plain markdown. The assistant reads verified facts, not instructions to go find facts.

Without Perseus                     With Perseus
โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€    โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
"Port is 3001 (check .env)"    โ†’   Port: 3001
"47 tests (may be stale)"      โ†’   Tests: all passing (run 8s ago)
"Check docker ps first"        โ†’   mongo-dev: Up 4h 12m
"Where did we leave off?"      โ†’   Checkpoint: webhook handler written,
                                              pending test run

Perseus replaces your assistant's context file โ€” CLAUDE.md, .cursorrules, AGENTS.md, .hermes.md โ€” with rendered live context. If you already have a hand-written context file, migrate its static content into .perseus/context.md first. Perseus overwrites the output file on every render. Add @perseus to line 1 of your source and it becomes live. The assistant never sees directive syntax. It sees a document that was already true.


Quick Start (30 Seconds to Live Context)

perseus quickstart          # auto-detects project, scaffolds context, renders

Smart init detects your stack and tailors the setup:

  • Python โ†’ @memory queries for test patterns, type annotations
  • Rust โ†’ trait bounds, lifetime annotations, cargo config
  • Node.js/TS โ†’ npm scripts, ESLint config, component patterns
  • Go, Java, C/C++, Docker โ€” all detected automatically
  • Falls back to a sensible generic query when unknown

The output file name is the only assistant-specific detail:

AssistantOutput file
Claude CodeCLAUDE.md
Hermes Agent.hermes.md (top priority) or AGENTS.md
Cursor.cursorrules or .cursor/context.md
CodexAGENTS.md
Rovo DevAGENTS.md
Any otherWhatever your assistant reads at session start

Hermes priority order: .hermes.md โ†’ AGENTS.md โ†’ CLAUDE.md. Render to .hermes.md for highest priority.

Keep it fresh with cron, launchd, systemd, or perseus watch:

# Linux systemd (auto-refresh every 5 minutes)
perseus systemd .perseus/context.md --output AGENTS.md --interval 5m --install --enable

# macOS launchd
perseus launchd .perseus/context.md --output AGENTS.md

# Cron (any POSIX host)
perseus cron .perseus/context.md --output AGENTS.md --every 5 --install

See the Integration Guide for Hermes-specific auto-refresh setups and spec/integration.md for full adapter patterns.


Why Perseus? (Proof, Hardening, and Enterprise Value)

Perseus delivers verified, up-to-date context, eliminating the need for AI assistants to spend turns orienting themselves. Here's how it stands up:

Performance & Efficiency

  • 1,190ร— coldโ†’warm gap โ€” Real-world scenario using the Perseus repo itself as the benchmark target. At the 1,408 directive scale, the cold render took 578.7s, while the warm render took 0.486s. Raw data โ†’
  • Mnฤ“mฤ“ persistent memory โ€” In-process BM25 recall, zero daemon. 37ms search P50 at 10,000 docs, flat across all scales. Perseus @mimir renders: 51ร— coldโ†’warm speedup with @cache. 2,700 docs/sec write throughput, 0.4ms P50 saves. v1.0.7 adds Mimir (Project Synapse) โ€” MCP-based remote memory with Ebbinghaus time-decay and FTS5 + LIKE hybrid search, circuit-breaker protected. Local Mnฤ“mฤ“ remains the default. Full results โ†’
  • 94% token reduction, 0ms overhead โ€” live 200-request A/B harness: 488 โ†’ 27 avg prompt tokens per request. P99 latency overhead: 0ms โ€” Perseus adds nothing to response time. Full harness results โ†’
  • Enterprise Ready โ€” Cost analysis shows that for a 500-developer team, Perseus can save significant token costs per year. Cost analysis โ†’
  • Extreme Enterprise Benchmark โ€” 10-phase suite (reps=10, 50 devs, 250 concurrent agents): 10/10 hard gates ยท 6/6 soft gates ยท 0 errors at 250 concurrent ยท 90% enterprise ROI ยท fleet P99 1,169ms. The benchmark is designed to surface regressions, not hide them. Full methodology โ†’ ยท Raw results โ†’

Perseus v1.0.6 โ€” Performance Benchmarks

Reliability & Security

Perseus is tested against edge cases that challenge the "resolve before context" claim. v1.0.6 completed a deep-dive architectural review (O(nยฒ)โ†’O(n), regex parser, shell hardening, retry classification) and a full security review against the MCP transport and foreign resolver surface (Phase 26):

  • MCP SSE bearer-token auth โ€” POST /message requires Bearer token via mcp.sse_bearer_token config key (falls back to serve.auth_token for backward compat). Unauthenticated requests receive 401.
  • Platform-portable MCP timeout โ€” _call_tool() uses ThreadPoolExecutor + Future.result(timeout=...) instead of Unix-only SIGALRM. Works on Windows, macOS, and Linux.

Platform support: Perseus is developed and CI-tested on Linux (Ubuntu, Python 3.10โ€“3.12). macOS is supported but not in CI. Windows is supported with caveats: the MCP transport and core render pipeline work cross-platform, but approximately 8% of the test suite currently fails on Windows due to POSIX-specific shell assumptions, path handling differences, and missing select support in the LSP module. Native Windows scheduling (Task Scheduler) is deferred โ€” use WSL cron or invoke perseus render from your own scheduler. Windows improvements are tracked but not the primary target.

  • Foreign resolver SSRF protection โ€” URL allowlist via foreign_resolver.url_allowlist, private-IP blocking (block_private_ips, default true), HMAC signature verification (verify_signatures now defaults to true, minimum 32-char secret). Redirects re-check destination IPs. Localhost (127.0.0.1, ::1) explicitly allowed for local testing.

  • 16/16 hard gates passed โ€” Gauntlet v2: 100.0/100 โ€” Full 10-phase enterprise torture test on Perseus v1.0.8: cold/warm renders, memory retrieval, single/multi-agent tasks, 5-day enterprise week, 12 adversarial scenarios, 2-hour sustained torture, and token efficiency. All 16 gates passed with zero failures. Full results โ†’

  • Semantic Equivalence: 1.0 โ€” A live Gemini 2.5 Flash judge found 20/20 A/B test pairs to be semantically equivalent, confirming that Perseus changes what the assistant knows, not what it says.

  • Workspace boundaries โ€” Symlink escapes (direct, relative, chained, to /etc) are all blocked. The trust-gate resolves symlinks to their real target before checking boundaries.

  • Context overflow protection โ€” @read and @include warn and truncate when files exceed max_read_bytes / max_include_bytes (512 KB default, None for unlimited).

  • Transitive resolution โ€” @include on .md files recursively renders directives up to max_include_depth (default 5), with cycle detection.

  • Integrity drift โ€” Optional integrity_check captures file mtimes before render and warns if any file changed mid-resolution.

  • Plugin sandboxing โ€” Plugin directives with executes_shell=True are gated behind allow_query_shell, same as built-ins. Plugin errors are caught and surfaced as inline warnings โ€” a broken plugin never breaks a render.

Edge-case tests cover circular dependencies, race conditions, symlink escapes, and context overflow. These four config knobs live under render: in ~/.perseus/config.yaml.

Perseus reads from a live filesystem โ€” there is no snapshot isolation unless you enable integrity_check. Files can change between directive resolutions. The render output reflects whatever was on disk at the moment each directive resolved, not a single atomic point-in-time. This is the right tradeoff for a zero-dependency pre-processor (zero overhead by default, check when it matters), but it is not a database transaction.

The O_CREAT | O_EXCL checkpoint locking is atomic on local POSIX filesystems. Network filesystems (NFS < v4, SMB, cloud mounts) may not honor these semantics โ€” if you run a multi-agent relay across machines, use a local disk or a filesystem with verified atomic-create support.

perseus.py is a compiled build artifact produced by scripts/build.py from the modular src/perseus/ tree. It is not hand-maintained as a single file. The source modules are the canonical form.


How Perseus Works

You write this:

@perseus v1.0.8

# Context โ€” @date format="YYYY-MM-DD HH:mm z"

## What's Running
@query "docker ps --format 'table {{.Names}}\t{{.Status}}'"

## Last Session
@waypoint ttl=86400

## Ports
@read .env key="API_PORT" fallback="3001"

## Active Tasks
@agora status=open,in_progress

## Skills Available
@skills flag_stale=true category=devops,github

## Project Memory
@memory focus="recent"

Perseus renders this:

# Context โ€” 2026-05-27 08:33 CDT

## What's Running
mongo-dev    Up 4 hours
redis-dev    Up 4 hours

## Last Session
Checkpoint written: 2026-05-27T08:28
Task: webhook handler โ€” written, pending test run
Next: run pytest tests/test_webhook.py

## Ports
3001

## Active Tasks
| ID | Title | Status | Scope |
|---|---|---|---|
| task-08 | List and Tree Directives | Complete | medium |
| task-12 | Mnฤ“mฤ“ Narrative Memory | Complete | large |

## Skills Available
| Skill | Category | Updated |
|---|---|---|
| hermes-agent | autonomous-ai-agents | 2026-05-20 |
| github-pr-workflow | github | 2026-05-15 |
| docker-stack-auditing โš  | devops | 2026-03-01 |
| documentation-audit | software-development | 2026-05-26 |

## Project Memory
### Recent
- 2026-06-05: Deep-dive code review โ€” O(nยฒ)โ†’O(n) macro expansion, regex parser, webhook retry classification, shell injection hardening. Test suite at 894 tests (Linux, Python 3.10โ€“3.12), all passing.
- 2026-05-27: Shipped MCP deep integration (Phase 25). 24 directives exposed as MCP tools by default.
- 2026-05-26: Deployed Perseus v1.0.6 to PyPI. Test suite at 894 tests โ€” all passing (Linux, Python 3.10โ€“3.12).
- 2026-05-24: Completed Hephaestus extensibility โ€” plugin directives, macros, hooks, pipes.

The assistant never sees a directive. It sees a document that was already true โ€” including which skills are available, which tasks are open, and what decisions were recently made.

Extensibility in Practice

Macros reduce repetition. Pipes compose. Aliases keep things short:

@macro health-check %service%
@query "curl -s http://%service%:8080/health"
@services
  - name: %service%
    url: http://%service%:8080/health
@endmacro

@q "git log --oneline -5" | @cache ttl=300
@health-check my-api

The assistant sees resolved output โ€” never a directive.

Full directive reference: docs/DIRECTIVES.md.


Session Waypoints

If an agent session crashes or a connection drops, Waypoints preserve the execution state.

perseus checkpoint \
  --task "Implementing webhook integration" \
  --status "handler written, pending test run" \
  --next "run pytest tests/test_webhook.py" \
  --workspace /workspace/myproject

The next session recovers immediately with perseus recover โ€” workspace-aware, freshness-gated, no re-orientation.


Multi-Agent Coordination

120-agent swarm demo โ€” 120 agents claiming tasks via atomic sidecar locks, zero collisions

Because Perseus outputs flat files and writes checkpoints to disk, downstream systems can build coordination on top of it without Perseus itself being an orchestration platform. The checkpoint store is namespaced and lock-protected โ€” agents read each other's latest state from the filesystem rather than a message bus. Teams have extended this pattern to multi-agent relay, shared inboxes, and agora task boards.

dev-01: [architect โ†’ implementer โ†’ reviewer โ†’ tester]  โ”€โ”
dev-02: [architect โ†’ implementer โ†’ reviewer โ†’ tester]  โ”€โ”ค
...                                                      โ”œโ”€ shared checkpoint store
dev-30: [architect โ†’ implementer โ†’ reviewer โ†’ tester]  โ”€โ”˜     (namespaced + lock-protected)

Proven at enterprise scale โ€” see Multi-Agent Relay.


Architecture

  Plugins:  ~/.perseus/plugins/        โ”€โ”  Discovered at render time.
            ~/.perseus/validators/       โ”‚  Macros, hooks, webhooks,
            ~/.perseus/formats/          โ”˜  and aliases load from config.

Source document (.perseus/context.md)
  @perseus v1.0.8
  @query "git log --oneline -5"          โ”
  @read .env key="PORT"                  โ”‚  Directives resolved
  @waypoint ttl=86400                    โ”‚  before context window.
  @services                              โ”‚  Cache layer avoids
    - name: My App                       โ”‚  re-running slow queries.
      url: http://localhost:3001/health  โ”˜
          โ”‚
          โ–ผ perseus render
  Resolved markdown (facts, not instructions)
          โ”‚
          โ–ผ
  .hermes.md  โ†โ”€โ”€ cron watchdog keeps this โ‰ค5 min fresh
          โ”‚
          โ–ผ
  AI context window โ€” complete, accurate, zero pre-flight tax

  Waypoints: ~/.perseus/checkpoints/
  Plugins:   ~/.perseus/plugins/
  Validators:~/.perseus/validators/
  Formats:   ~/.perseus/formats/
  Cache:     ~/.perseus/cache/
  Config:    ~/.perseus/config.yaml

Extensibility (Hephaestus)

Perseus is extensible without source patching. Drop Python files into ~/.perseus/ and the renderer discovers them at startup.

Plugins

# ~/.perseus/plugins/my_plugin.py
from perseus.registry import DirectiveSpec

def _resolve_service_status(args, cfg, workspace):
    import urllib.request
    try:
        resp = urllib.request.urlopen(args.strip(), timeout=5)
        return f"Status: {resp}"
    except Exception as e:
        return f"Error: {e}"

REGISTER = {
    "@service-status": DirectiveSpec(
        name="@service-status",
        resolver=_resolve_service_status,
        args=["url"],
        kind="inline",
        call_sig="acw",
        executes_shell=False,
        safe_for_hover=True,
        cacheable=True,
        summary="Check HTTP status of a URL",
    )
}

Use it in context files: @service-status https://api.example.com/health

Built-in directives always win collisions. Plugins respect the same permission profile as built-ins (executes_shell gates behind allow_query_shell).

Macros

Reusable directive compositions โ€” no Python needed:

@macro deploy %env% %version%
@query "kubectl rollout status deploy/app -n %env%"
@services
  - name: app-%env%
    url: https://%env%.example.com/health
@endmacro

@deploy production 2.3.1

Macros expand before directive resolution. Chaining supported up to depth 5 with cycle detection. Define them in your context file or at .perseus/macros.md.

Render Pipeline Hooks

Shell scripts or Python callbacks fire at render lifecycle points โ€” on_render_start, on_directive_resolved, on_cache_hit, on_cache_miss, on_render_complete, on_directive_error:

# ~/.perseus/config.yaml
hooks:
  enabled: true
  on_render_complete:
    - cmd: "notify-send 'Context refreshed'"
  on_directive_error:
    - plugin: "my_error_handler"

Pipe Syntax

Chain directives with | for lightweight composition (max 3 stages):

@query "ls services/" | @cache ttl=300
@read config.yaml path="endpoints" | @validate schema="endpoint-list"

Output of each stage becomes the first positional argument to the next.

Tiered Context (Progressive Disclosure)

Not every question needs the full environment injected. A "what's 2+2?" shouldn't pull in Docker health checks, skill listings, and session digests. Perseus now ships tiered context rendering โ€” the agent is the RAG.

perseus render .perseus/context.md --tier 1    # core context (~12 directives, lean)
perseus render .perseus/context.md --tier 2    # + services, skills, sessions
perseus render .perseus/context.md              # everything (backward compatible)

Three tiers, assigned per directive in the registry:

TierNameWhat goes here
1AlwaysCore context โ€” lightweight, always needed (@date, @memory, @waypoint, @health, @env)
2ConditionalTask-specific, heavier (@services, @skills, @session, @agora, @inbox)
3On-DemandBulky/expensive โ€” the agent pulls it if needed (@query, @read, @include, @tree, @list)

Directives above the tier limit are skipped and reported in a Context Manifest:

> ๐Ÿ“‹ Context Manifest โ€” Tier limit: 1
>
> โ€ข @services (Tier 2 / Conditional) โ€” Health-check listed services
> โ€ข @skills (Tier 2 / Conditional) โ€” List available skills
> โ€ข @query (Tier 3 / On-Demand) โ€” Run a shell command and embed stdout
>
> Re-run with `perseus render --tier 2` for conditional context,
> or `--tier 3` for full context on demand.

Template authors can override per-instance with @tier:N:

@services @tier:1    # Always resolve this block, even though @services defaults to Tier 2
docker
nginx
@end

Set render.default_tier: 1 in ~/.perseus/config.yaml to make lean context the default for all renders. No embedding model, no LLM routing โ€” one integer comparison per directive gates resolution. The agent sees what's available and can pull it on demand.

Prompt-Size Forensics (perseus prompt-size + @budget)

Context is the scarcest resource in agent systems โ€” and it's usually spent blind. perseus prompt-size renders a context and shows exactly where every byte went, attributed per directive, with a static-vs-dynamic split:

perseus prompt-size .perseus/context.md          # human table, largest offenders first
perseus prompt-size .perseus/context.md --json   # stable, deterministic JSON for CI diffing
perseus prompt-size .perseus/context.md --since HEAD~5   # per-directive budget delta vs a git ref
perseus prompt-size: context.md (tier 3)
total: 5950 bytes, 2270 tokens [tiktoken:cl100k_base โ€” exact]
split: static 43 B / cacheable 45 B / volatile 5862 B (attributed 5907 + static 43 = 5950 โ€” exact)

Per directive (largest first):
      5862 B     2249 tok   98.52%  [ volatile]  @env PATH  line 7
        45 B        9 tok    0.76%  [cacheable]  @include "sub.md"  line 8
  • Byte-exact accounting โ€” per-directive bytes + static template bytes sum to the rendered total with no unattributed remainder (the accounting.exact field asserts this in --json).
  • Tokenizer-aware โ€” real BPE counts via tiktoken (cl100k_base) when it happens to be installed (labeled exact); otherwise a deterministic offline heuristic clearly labeled estimate. Never a network call.
  • Static vs. dynamic split โ€” see how much of the render is a cacheable prefix vs. per-render volatility (@env, @date, @query).
  • --since <git-ref> diff mode โ€” renders the file's content at the ref (via git show, offline) and reports which directive's contribution grew, so "someone added an @include that doubled the prompt" is caught in review.

Pair it with a @budget declaration in the source to gate context bloat in CI:

@perseus
@budget max=8000 strict forensic
...

perseus prompt-size checks every @budget after the render: under budget passes silently; over budget warns with the per-directive offender breakdown โ€” or exits non-zero when the declaration says strict (or the CLI is invoked with --strict). forensic expands the overflow report to the full per-directive table plus the static/cacheable/volatile split. The directive itself renders as empty text, so it costs nothing in the context it guards.

Scope contract: @budget declarations are read from the top-level source text before conditionals are evaluated โ€” top-level only. A @budget inside an @include'd file is not enforced (prompt-size warns and reports it under included_budgets in --json); a @budget inside a false @if branch is still enforced, because the scan is text-level. In --json output, static.tokens is derived (total โˆ’ ฮฃ per-directive tokens, clamped at 0 and flagged tokens_derived) โ€” the byte accounting is the measured, exact invariant.

Directive Aliases

Config-driven shorthand โ€” single-pass, no recursive expansion:

# ~/.perseus/config.yaml
directives:
  aliases:
    "@q": "@query"
    "@svc": "@services"
    "@stale-skills": "@skills flag_stale=true category=all"

Pre-defined aliases: @qโ†’@query, @rโ†’@read, @svcโ†’@services, @mbโ†’@memory, @agโ†’@agora, @wpโ†’@waypoint, @sessโ†’@session. Config aliases override them.

Custom Schema Validators

Plugin validators for domain-specific schemas:

@query "cat endpoints.yaml" schema="plugin:endpoint_list"

Validator modules in ~/.perseus/validators/ export a validate(value, schema_def) function returning (valid: bool, message: str).

Event Webhooks

POST render lifecycle events to an external URL with optional HMAC-SHA256 signing:

webhooks:
  enabled: true
  url: "https://hooks.example.com/perseus-events"
  secret: "your-hmac-key"
  events:
    - on_render_start
    - on_render_complete
    - on_directive_error

Speculative Prefetch (@speculate)

Speculative execution for context assembly (#607): a transparent Markov / frequency predictor over your recorded waypoint (checkpoint) transitions predicts the next task, and Perseus pre-warms that task's context after the current render completes โ€” so the first render of the next turn is already hot. No ML dependencies; the predictor interface is pluggable for a future LLM backend.

Off by default. Enable it in config and opt a source in with the pragma:

# ~/.perseus/config.yaml
speculate:
  enabled: true              # master gate โ€” default false (zero behavior change)
  k: 3                       # top-k predicted next intents to consider
  budget_tokens: 2000        # cumulative token budget per speculation pass
  confidence_threshold: 0.30 # only warm predictions at/above this probability
  intents:                   # intent pattern (fnmatch) โ†’ prefetch directive line(s)
    "deploy*":
      - '@read "runbook.md" @cache ttl=300'
    "review*":
      - '@query "git log --oneline -10" @cache ttl=120'
@perseus v1

Your context here...
@speculate k=3 budget=2000

The @speculate pragma never appears in rendered output; k= / budget= override the config for that source. Speculation is synchronous-after-render: it can never delay or interleave with the live render, and a failure inside speculation never breaks a render.

Cache safety: speculative warms run through the same prefetch executor and use the exact key derivation the renderer reads (workspace-scoped base key + dependency fingerprint), so a speculative entry is just an early warm โ€” it can never shadow or poison real reads. On the real turn the renderer re-derives the fingerprint and TTL as usual, so a wrong prediction costs nothing.

Observability:

$ perseus explain --speculate
Speculate: enabled=true backend=markov k=3 threshold=0.30
History: 42 intent(s); current: review PR
Predicted next intents:
  1. deploy staging  p=0.67  [1 candidate(s), 1 warm]
     - warm: @read "runbook.md" @cache ttl=300
Past speculation: hits=12 misses=4 hit_rate=0.75 (settled=16)

Prediction outcomes (hit/miss per settled prediction, budget spend, warm results) persist to a workspace-keyed stats file (<cache_dir>/speculate_stats-<workspace_hash>.json, atomic writes) with a documented shape โ€” a future @bandit ledger integration can consume it as a value signal.


Context Profiles & Recall-First Memory (@profile)

A context engine should retrieve, not pre-load. As of v1.0.14, Perseus is recall-first by default: the automatic long-term-memory dump that used to be stapled into every rendered context is replaced by a short, static retrieval pointer plus the recall tools. On a 200k-context model, a fixed memory blob on every turn is a permanent token tax that poisons prefix-cache stability the moment any fact changes โ€” Perseus already has the retrieval layer (@memory, @mimir, perseus_mneme), so the default context now spends the budget on the task.

Per-model context profiles make the posture first-class and model-aware:

# ~/.perseus/config.yaml
profiles:
  default:            { context_target: 200000,  memory: on_demand }
  claude-sonnet-4-6:  { context_target: 200000,  memory: on_demand }
  claude-opus-4-8:    { context_target: 1000000, memory: on_demand }   # big window is not an excuse to bloat
  legacy-dump:        { context_target: 200000,  memory: always, inject_limit: 5 }

Select a profile per document with the @profile directive (unknown names fall back to default deterministically):

@profile claude-sonnet-4-6

Three memory postures:

PostureBehavior
on_demand (default)Inject a static retrieval pointer + tools. No pre-materialized memory dump. The fixed prompt prefix stays byte-stable across vault writes (prefix-cache friendly).
relevantInject only entities whose recall_when triggers match the current render context (via the vault's trigger matching). No match โ†’ no dump.
alwaysLegacy opt-in. The pre-v1.0.14 unconditional dump on every render. Kept for back-compat; documented as an anti-pattern. always_inject: true is accepted as an alias.

Injection hygiene (all postures that inject content):

  • De-duplicated โ€” if the rendered document already contains a memory section (an explicit @memory directive, a template section, or a previous injection pass), the automatic block is skipped. The same memory content can never appear twice in one context.
  • Workspace-scoped โ€” recall calls that support it receive the active workspace hash, so personal and project memories don't share one undifferentiated pool at the render layer.
  • Budgeted per profile โ€” a 200k-class profile admits at most a handful of entities (inject_limit, default 5; 10 for larger windows).
  • Advisory framing โ€” injected memory carries a note that it may be stale or tangential and that live workspace state wins on conflict, instead of asserting authority.

To suppress the automatic section entirely (pointer included) set mimir.auto_inject: false; to restore the old behavior globally set profiles.default.memory: always.


Project Memory (Mnฤ“mฤ“)

Mnฤ“mฤ“ (ฮœฮฝฮฎฮผฮท) is Perseus's narrative project memory. It distills checkpoints and Pythia recommendations into a per-workspace narrative โ€” so your assistant knows not just what's running, but how you got here.

# Update the narrative from latest checkpoints
perseus memory update

# Query the narrative
perseus memory query "what was the auth decision?"

# Render it inline
perseus render .perseus/context.md --output CLAUDE.md

In your context file:

@memory                    # full narrative
@memory focus="decisions"  # decisions section only
@memory focus="recent"     # recent activity

Mnฤ“mฤ“ is LLM-optional: deterministic assembly works zero-dependency; an optional memory.llm_provider enables richer distillation. Full docs: spec/components.md ยง 4.


Full Documentation

DocumentWhat it covers
CLI ReferenceEvery command and flag
Setup & Config GuideThe definitive setup, config, automation, and troubleshooting guide
Directives ReferenceAll directives with modifiers and examples
Integration GuideWire Perseus to Hermes via LLM routing
Adapter PatternsWire Perseus to any AI assistant
Container RuntimeDocker and compose deployment
Quickstart5-minute setup walkthrough
Product ContractGuarantees, trust model, permissions
ContributingDev setup, test suite, commit conventions
ExamplesEnd-to-end workflow recipes
Use CasesReal-world usage patterns
PerformanceBenchmark methodology and results
Agent SurfacesJSON contracts for agent consumption
DeploymentSystemd, launchd, cron, Docker, CI
SecurityTrust model, workspace boundaries, secrets
RoadmapLiving roadmap (live @perseus source)

Government & Federal Procurement

Perseus is built for government deployment from the ground up.

CapabilityStatus
LicenseMIT โ€” no copyleft, no GPL/AGPL
SBOMPublished โ€” NTIA minimum elements
Air-gappedZero cloud dependencies
EncryptionN/A (read-only context engine)
TelemetryNone โ€” no phoning home, no tracking
Supply chainSLSA attestation in progress

For federal buyers: See docs/federal-buyers.md for procurement information, compliance status, and deployment models (air-gapped, on-premises, classified environments).

Perseus Computing LLC is a US-owned small business. SAM.gov registration in progress. NAICS: 541715, 541511, 541512.


Patent Pending. A provisional patent application covering Perseus's resolve-before-context pipeline architecture is on file with the USPTO. See docs/ip/ for the public IP portfolio, including technical disclosures and evidence exhibits.

PERSEUSโ„ข is a trademark of Thomas Connally. Internal subsystem names (Pythia, Daedalus, Agora, Mnฤ“mฤ“) are not independently trademarked and are covered under the PERSEUS mark.

Privacy Policy

Perseus is a local-first context engine โ€” it runs entirely on your machine.

Data Collection

  • No data collection. Perseus does not collect, transmit, or phone home any user data, usage statistics, or telemetry.
  • All context resolution happens locally on your filesystem.

Data Usage & Storage

  • Perseus reads project files, git state, and environment variables to resolve context directives.
  • No project data leaves your machine. Perseus does not cache or store file contents beyond the render pipeline.
  • When paired with Mimir for persistent memory, memory data is stored locally per Mimir's privacy policy.

Third-Party Sharing

  • None. Perseus is fully offline by default โ€” no API calls, no cloud services, no external network requests.
  • Optional MCP server connections (e.g., to remote services) are explicitly configured by the user and only made when that server is declared in your configuration.

Data Retention

  • Perseus does not retain data independently. Rendered context is ephemeral and regenerated on each invocation.
  • For persistent memory, see Perseus Vault's privacy policy.

Contact

License

License: MIT โ€” see LICENSE. This license does not include a patent grant; patent rights are reserved separately.

Third-party notices: see NOTICE.