Discord-first AI companion runtime built in Rust
Warning
Active development. APIs and behavior can change between commits.
Tip
For the conceptual story — why this runtime is shaped the way it is — see the docs site: https://haru0416-dev.github.io/AsteronIris/. Japanese docs are available at https://haru0416-dev.github.io/AsteronIris/ja/. This README is the "how"; the site is the "why".
AsteronIris is in active development. The companion conversational core (memory, persona, turn enrichment, verifier harness) and gateway are stable. Discord text is the only channel with end-to-end product coverage today; non-Discord adapters compile and load but are extension-level alpha surfaces.
AsteronIris is a text-first AI companion runtime built for durable conversation quality on Discord. It is open about being an AI, keeps relationship memory across sessions, and calibrates tone and distance for public rooms, threads, and DMs without becoming noisy.
Primary loop: Channel Input -> Pickup Policy -> Turn Enrichment -> Response Assembly -> Pre-send Verification -> Reply Delivery -> Post-turn Update.
Desktop and other channels are secondary operator/adapter surfaces around this loop, not separate product centers.
Status legend: Stable (production-ready) · Beta (feature-complete, API may move) · Alpha (works on the happy path).
| Capability | Status | Summary |
|---|---|---|
| Companion | Stable | Discord-first text companion with relationship continuity and public/private calibration |
| Channels (Discord) | Beta | Primary delivery surface with end-to-end coverage from gateway through turn pipeline |
| Channels (others) | Alpha | Secondary adapters (Telegram/Slack/Matrix/etc.); not primary product proof surface |
| Memory | Stable | Backends: postgres, markdown, none; autosave, recall, GraphRAG, ingestion pipeline |
| Persona | Stable | Rapport, affect, continuity, and companion posture shaping |
| Runtime Harness | Stable | Shared turn loop, pre-send verification, pickup controls, and safety/governance hooks |
| Gateway | Stable | Axum HTTP/WS gateway with pairing, A2A messaging, webhook ingress, companion surface routes, and admin API |
| Daemon | Stable | Long-running runtime: gateway + channels + scheduler + heartbeat |
| Turn Enrichment | Stable | Shared pre/post-turn pipeline: affect detection, memory recall, persona context, prompt composition, relationship update |
| Skills | Beta | Install/manage skill packs with trust-tier evaluation |
| Desktop | Alpha | Secondary operator console for governance, diagnostics, and memory/admin workflows |
| Subagents | Beta | Multi-agent orchestration: inline/spawned execution, cancellation, status tracking |
| Eval | Stable | Behavioral, replay, reliance, persona-consistency, and memory-bench harnesses |
| Security | Stable | Command allowlist, path policy, pairing flow, encrypted vault, secret scrubbing, writeback guards |
| Tunnel | Alpha | Expose local services externally |
| MCP Bridge | Beta | Connect to external MCP servers |
- Rust stable (
rust-toolchain.toml) protocv29+- Git
- A model provider credential, or a local provider configured during onboarding
- PostgreSQL for the recommended memory backend. Markdown and
nonememory modes exist for constrained or offline setups, but PostgreSQL is the production recommendation.
git clone https://github.com/haru0416-dev/AsteronIris.git
cd AsteronIris
cargo build --releaseFirst-run steps are ordered. onboard --interactive is required before agent can start; it
writes ~/.asteroniris/config.toml and initializes the workspace.
# Interactive onboarding wizard (run first on a fresh install)
cargo run -- onboard --interactive
# Start interactive agent (requires completed onboarding)
cargo run -- agent
# One-shot message (requires completed onboarding)
cargo run -- agent --message "Summarize my open tasks"Every accepted companion turn converges on the same enrichment pipeline. Discord text is the product-proven channel; CLI, gateway, desktop/operator surfaces, and secondary channel adapters reuse the same turn contract where they create or replay companion turns, but they are not all equally mature product surfaces.
Pre-turn: affect detection → memory recall → persona context → system prompt composition
Post-turn: relationship update → message autosave → memory consolidation
The transport-facing path is centralized in src/runtime/services/companion_turn.rs, while
src/core/agent/turn_enrichment.rs remains the canonical owner of pre/post-turn enrichment.
The desktop/ directory contains a Tauri 2 + React 19 + Tailwind 4 operator console.
- Session review and transcript inspection
- Channel and runtime health visibility
- Companion admin surfaces and secondary tooling
- Multimodal attachment authoring (images, voice notes)
Run the desktop app against a local daemon:
cargo run -- daemon --host 127.0.0.1 --port 3000
# then in desktop/
pnpm tauri devcargo run -- gateway --host 127.0.0.1 --port 3000Public routes:
GET /health,GET /healthzGET /ready,GET /readyzGET /openapi/v1.jsonGET /.well-known/agent.jsonPOST /pairPOST /a2a/v1/messagesGET /a2a/v1/tasksGET /a2a/v1/tasks/{task_id}POST /a2a/v1/tasks/{task_id}/cancelPOST /webhookPOST /companion/context/ingestPOST /companion/multimodal/ingestGET /ws
Companion surface routes:
POST /companion/surface/captionPOST /companion/surface/widgetPOST /companion/surface/request-window/openGET /companion/surface/request-window/{window_id}POST /companion/surface/request-window/{window_id}/confirmPOST /companion/surface/request-window/{window_id}/cancel
Admin API (/admin/v1/*):
GET /admin/v1/openapi.json- Runtime, usage, mood, activity timeline, agent list
- Session CRUD and message history
- Governance, memory review, and companion approval windows
- Auth profile management
- Channel management
- Skill management
- Cron management
- Companion admin
- Tenant management
Note
Admin routes are not public. In practice, pair first via POST /pair, then send
Authorization: Bearer <token> and X-Asteroniris-Tenant: <tenant-id> on /admin/v1/*
requests.
Some routes are feature/config dependent (for example WhatsApp routes).
Optional trust-signal headers for external ingress (POST /webhook, POST /a2a/v1/messages):
X-Signature-Verified(true/1)X-Signature-StatusX-Webhook-Signature-StatusX-Source-Url/X-External-Source-UrlX-Forwarded-Proto,Origin,Referer
These headers influence trust-scoring only when injected by a trusted edge verifier or reverse proxy. Untrusted clients should not set them directly.
Top-level commands:
onboard— initialize workspace and configurationagent— run assistant loopgateway— start HTTP/WebSocket gatewaydaemon— start long-running runtimeservice— manage launchd/systemd user servicedoctor— run diagnostics (--repairfor safe local repairs)config— validate configurationstatus— show runtime/system statuseval— run evaluation suites (baseline, replay, memory-bench)model— update default model/providercron— manage scheduled taskschannel— list/start/doctor/add/remove channelsintegrations— inspect integrationsauth— manage auth profiles and OAuth import/statusskills— manage installed skills
Default paths:
~/.asteroniris/config.toml
~/.asteroniris/workspace
Common environment overrides:
| Variable | Purpose |
|---|---|
ASTERONIRIS_API_KEY |
Provider API key |
ASTERONIRIS_PROVIDER |
Default provider |
ASTERONIRIS_MODEL |
Default model |
ASTERONIRIS_TEMPERATURE |
Sampling temperature |
ASTERONIRIS_WORKSPACE |
Workspace path override |
ASTERONIRIS_GATEWAY_HOST |
Gateway host override |
ASTERONIRIS_GATEWAY_PORT |
Gateway port override |
ASTERONIRIS_GATEWAY_MAX_BODY_SIZE_BYTES |
Max request body size for the gateway |
Reference template: .env.example
Security/ingress tuning example (~/.asteroniris/config.toml):
[channels_config]
# Removes per-channel autonomy/tool restrictions.
# Global security policy is still enforced.
high_freedom_all_channels = true
[security.perimeter]
enforce_uniform_inner_freedom = true
supported_targets = ["host", "docker", "kubernetes"]
[security.external_knowledge_trust]
enabled = true
default_score = 0.60
min_allow_score = 0.70
min_sanitize_score = 0.30
[security.external_knowledge_trust.source_overrides]
# Explicitly trusted signed ingress.
"gateway:webhook:signature=verified" = 0.90
# Explicitly untrusted/anonymous relay ingress.
"gateway:webhook:anonymous:relay" = 0.15Built-in source profiles are applied for common prefixes (gateway:*, channel:*, tool:web*,
etc.) when no explicit override matches.
src/
├── cli/ # CLI command surface
├── config/ # TOML schema + env overrides
├── contracts/ # Cross-boundary types and shared contracts
├── core/
│ ├── affect/ # Rule-based affect detection, empathy signals
│ ├── agent/ # Turn executor, turn enrichment, tool loop
│ ├── eval/ # Evaluation harnesses and baseline/replay/memory suites
│ ├── experience/ # Experience capture and recall
│ ├── memory/ # Memory backends, ingestion, GraphRAG
│ ├── persona/ # Relationship, empathy, user model, embodied state, continuity
│ ├── providers/ # LLM provider abstraction + reliability
│ ├── sessions/ # Session state and history
│ ├── subagents/ # Multi-agent orchestration
│ ├── taste/ # Preference and taste modeling
│ └── tools/ # Tool registry, middleware, built-in tools
├── media/ # Media processing and speech config
├── onboard/ # Setup wizard and scaffolding
├── platform/ # Daemon, service, cron
├── plugins/
│ ├── companion/ # Companion surface, context, multimodal, rhythm
│ ├── extensions/ # Extension loader
│ ├── integrations/ # External service integrations
│ ├── mcp/ # MCP bridge
│ └── skills/ # Skill loading, catalog, trust tiers
├── runtime/
│ ├── diagnostics/ # Runtime diagnostics
│ ├── environment/ # Environment detection
│ ├── observability/ # Metrics, tracing, logs
│ ├── services/ # Shared runtime services (composition root)
│ ├── tunnel/ # Tunnel management
│ └── usage/ # Usage accounting
├── security/ # Policy, pairing, auth, secrets, guards
├── transport/
│ ├── channels/ # Channel adapters + shared message handler
│ └── gateway/ # HTTP/WS gateway + admin API
├── ui/ # Terminal UI building blocks
└── utils/ # Shared utilities
desktop/ # Tauri/React companion operator console
tests/ # Integration tests by domain
migrations/ # PostgreSQL schema migrations
AsteronIris is designed for a single-operator workspace — one person, or a small trusted team, running the daemon on a machine they control. It is not a multi-tenant SaaS, a public RAG endpoint, or a shared inference gateway. The threat model assumes the operator is trusted and focuses on three containment boundaries: (1) the LLM and its tools execute under a deny-by-default command allowlist and path policy; (2) externally reachable surfaces (webhooks, A2A) trust only edge-verified ingress signals; (3) secrets the runtime must hold live in an encrypted local vault with scrubbing on all outbound surfaces.
Highlights:
- Command allowlist + path policy enforcement (deny-by-default)
- Workspace-scoped execution; writeback guard on paths outside workspace
- Gateway pairing flow with token hashing and lockout handling
- Encrypted local secret vault (ChaCha20-Poly1305)
- Secret scrubbing on all outbound surfaces
- Trust-scored external ingress via edge-verifier headers (see Gateway section above)
Full threat model and disclosure policy: SECURITY.md.
cargo fmt -- --check
cargo clippy -- -D warnings
cargo check-all
cargo testStrict release gate (quality + fuzz + audit + perf compare):
./scripts/release/human_like_release_gate.shcargo test-dev
cargo test-dev-tests
cargo build-minimal
cargo check-all
cargo coverage
cargo coverage-tarpaulin
cargo ntest
cargo ntest-cigit config core.hooksPath .githooksPre-push runs:
cargo fmt -- --checkcargo clippy -- -D warningscargo check-allcargo test
- Public docs site: https://haru0416-dev.github.io/AsteronIris/
- Japanese public docs: https://haru0416-dev.github.io/AsteronIris/ja/
- Contribution guide:
CONTRIBUTING.md - Agent/repo operating rules:
AGENTS.md - Internal docs index:
internal-docs/README.md - Architecture placement canon:
internal-docs/design/src-architecture-realignment.md - Product differentiation plan:
internal-docs/design/differentiation-strategy.md - Rust clean-code policy (2026 baseline):
RUST_BASE_POLICY_STRICT_2026.md