bastion v0.5.0 — self-hosted life os
✓ runtime local · ✓ keys yours · ✓ memory contestable · ✓ authority explicit
THE AGENT THAT CAN'T BETRAY YOU. LIFE OS // trustworthy by design

# One agent for your whole life — health, work, money, projects — that stays useful for years without becoming unreviewable, irreversible, or owned by a vendor. # Most agents ask for the keys. Bastion never needs them.

$ curl -fsSL bastion.run | sh ▶ PRESS START
1:scan ── WHY LONG-LIVED AGENTS FAIL
$ agent-doctor
$ agent-doctor --scan typical_assistant
✗ memory.provenance ............ MISSING — hidden profile silently becomes behavior; no source, no removal
✗ ingress.trust_classification . MISSING — any web page or email can act with YOUR authority
✗ sender.owner_mapping ......... MISSING — anyone who reaches the bot gets a session
✗ egress.privacy_gate .......... MISSING — data leaves as a side effect of tool calls
✗ state.export ................. LOCKED — years of context die with the subscription
▲ 5 critical failures — this agent accumulates power it was never granted.

$ agent-doctor --scan bastion
✓ memory.provenance ............ OK — every fact has source, validity, lifecycle
✓ ingress.trust_classification . OK — content is never permission
✓ sender.owner_mapping ......... OK — unknown senders rejected
✓ egress.privacy_gate .......... OK — leaving data is a first-class decision
✓ state.export ................. OK — bastion export → identity, memories, goals: yours
■ all checks passed — 0 implicit grants.
2:workspace ── SIX GUARANTEES, ENFORCED BY THE RUNTIME — NOT BY A POLITE SYSTEM PROMPT
0: memory
Memory you can disagree with.

Every fact has provenance, validity, and a lifecycle. Inspect where it came from, correct it, or revoke it — chat history is not unquestionable truth, and a "profile" never silently becomes policy.

❯ /memory challenge #1205
· provenance shown · fact flagged for review
1: authority
Context is not permission.

Incoming content is classified by trust. Public messages and email are untrusted; WhatsApp is signature-checked; unknown senders rejected. No "the model saw it, therefore do it" path.

❯ /authority list
· 2 grants active · 0 implicit · all revocable
2: exit-path
Your Bastion. In any place.

Sessions, memory, personas, companion and secrets live in your deployment — one directory holds all of it. Move the whole instance to a new machine, or just back it up, without a migration project. Your providers, your subscriptions — credentials never enter agent memory.

❯ bastion export
· identity, memories, goals, personas → yours
3: life-os
One life, many domains — without one giant messy chat.

Work priorities shouldn't erase health goals. Personas, goals and memories stay distinct per life area while informing one person-level assistant. Context without collapse.

❯ /goals
· health · work · money · projects — separate, linked
4: cabinet
Hard trade-offs get a council, not a coin flip.

Cabinet mode convenes named personas to deliberate, preserves dissent, and returns a synthesized recommendation. Priorities made explicit and revisable — never flattened into one agreeable voice.

❯ /cabinet "push the launch or protect recovery?"
· 3 perspectives · dissent preserved · synthesis returned
5: extensions
No blank checks. Ever.

Declarative, WASM and subprocess extensions plug into a capability-bounded host — installing one grants nothing by default. Self-improvement is approval-gated: skill candidates queue for your sign-off.

⚠ skill candidate ready — awaiting owner approval
· nothing rewrites itself without oversight
7: floorplan.svg
Every power has a door. Every door has an owner.

Not an illustration — the runtime's real architecture. External content enters through quarantine and gains authority only with your signature. One gate.

ROOM 01 MEMORY (contestable) ROOM 02 AUTHORITY (explicit) ROOM 03 CHANNELS QUARANTINE external content SINGLE GATE UNDER YOUR DOMAIN
6: companion

The Keeper lives in the TUI — pixel art on Kitty, WezTerm, Ghostty, iTerm2. /pet game on turns healthy breaks and finished work into cosmetic progression.

8: est. 2025
██████╗  █████╗ ███████╗████████╗██╗ ██████╗ ███╗   ██╗
██╔══██╗██╔══██╗██╔════╝╚══██╔══╝██║██╔═══██╗████╗  ██║
██████╔╝███████║███████╗   ██║   ██║██║   ██║██╔██╗ ██║
██╔══██╗██╔══██║╚════██║   ██║   ██║██║   ██║██║╚██╗██║
██████╔╝██║  ██║███████║   ██║   ██║╚██████╔╝██║ ╚████║
╚═════╝ ╚═╝  ╚═╝╚══════╝   ╚═╝   ╚═╝ ╚═════╝ ╚═╝  ╚═══╝
FORTRESS CLASS · SELF-HOSTED · MIT · A ShinAI PROJECT
3:bastion mode ── YOUR CLAUDE CODE, BECOMES YOUR BASTION NEW IN 0.5
0: bastion-mode
Your Claude Code becomes your Bastion.

Install the plugin and the coding agent you already use gets your persona, memory, goals and companion. Claude Code keeps running the model and the tools; Bastion supplies who it is and what it may do. Local-only memory never leaves the machine — it fails the same egress check as everything else. If the daemon isn't running, the hooks stay silent and Claude Code behaves as if the plugin weren't there.

❯ session start
· persona, core memory, goals injected · local_only beliefs withheld
1: tool-rules
Your rules for every tool call.
allowruns without a promptdenyblocked, rule shown as the reasonaskthe host asks you, as usualremoteapprove from another surface
❯ tool = "Bash" · input = "git push*"
· decision = "remote" → waits for your answer
2: approve-anywhere
Approve a risky call from your phone. Or the terminal. Or a desk device.

A remote rule opens an approval on every surface at once and waits. Approved means allow, denied means deny, and no answer falls back to the host's own prompt — silence never approves.

$ bastion mode — two lines · new in 0.5
$ claude plugin marketplace add ./integrations/claude-code
$ claude plugin install bastion@bastion

Run the first line from a clone of the repo. This connects Claude Code to your running Bastion. No Bastion running? See the Bastionizer below.

BASTIONIZER ── THE BASTION WAY OF WORKING, NO DAEMON NEW IN 0.5
0: bastionizer
Any agent acts as Bastion. Nothing to run.

Six skills and one standard-library Python script make Claude Code, Codex or any agent that reads skills work the Bastion way: personas per life area, local SQLite memory (FTS5 and a knowledge graph), search over past conversations, reminders, skills the agent writes and improves itself, the Cabinet, and a status-line companion. Everything stays in ~/.bastion. No server, no background process, no network.

❯ prompt
· routed to a persona · matching memories and due reminders added · local-only memories never reach hooks
1: which-one
Use one or the other.
modeconnects Claude Code to your running BastionbastionizerBastion's way of working, without running Bastion
❯ daemon plugin enabled
· Bastionizer hooks stay quiet
$ bastionizer — two lines · new in 0.5
$ claude plugin marketplace add ./extras/bastionizer
$ claude plugin install bastionizer@bastionizer

Run the first line from a clone of the repo. Other agents: copy the skills folders into their skills directory.

PRESENCE EVERYWHERE ── ONE EVENT SYSTEM, MANY SURFACES NEW IN 0.5
a: web

Web app. Sessions, approvals with a countdown, persona switch, paired devices.

b: mobile

Mobile app. The same buddy view in your pocket — approve or deny where you are.

c: tui

Terminal UI. Ctrl+Y approves, Ctrl+N denies, /agents shows who is doing what. The Keeper raises its hand.

d: desktop

Desktop tray. Notifications and approve / deny from the tray, with no one-click approve unless the call is shown whole.

e: cli

CLI. bastion presence status | approve | deny — scriptable, and the same contract as the rest.

f: desk device

GeekMagic SmallTV Ultra / Pro. Reference firmware shows persona, sessions and approvals. The Pro approves by touch (off by default).

NO SURFACE APPROVES A CALL IT CANNOT SHOW WHOLE.
4:vs ── CHOOSE YOUR AGENT

BASTION VS TYPICAL AGENT

EVERY STAT ENFORCED BY THE RUNTIME — NOT A ROADMAP PROMISE
◈ BASTION
CLASS: FORTRESS · SELF-HOSTED · MIT · RUST
MEMORY INTEGRITY10/10
██████████
Provenance + temporal validity — inspect, contest, correct, revoke
INJECTION RESISTANCE10/10
██████████
Trust-classified ingress — content is never permission; capability boundary in the runtime
PRIVACY9/10
██████████
Privacy-aware egress + owner mapping per channel; strangers rejected
OWNERSHIP10/10
██████████
Self-hosted, local-first; export/import full agent state; your models, your keys
EXTENSIBILITY9/10
██████████
WASM / subprocess / declarative under a capability-bounded host; approval-gated self-improvement
SURFACES10/10
██████████
CLI/TUI · Telegram · WhatsApp · Discord · Slack · email · voice · MCP — one identity everywhere
APPROVE FROM ANYWHERENEW IN 0.5
██████████
Web, mobile, terminal, tray, CLI or a desk device — and no surface approves a call it can't show whole
WORKS INSIDE OTHER AGENTSNEW IN 0.5
██████████
Bastion mode for Claude Code — your persona, memory and tool rules in the agent you already use
▢ TYPICAL AI ASSISTANT
CLASS: CHAT WINDOW · VENDOR-HOSTED · SUBSCRIPTION
MEMORY INTEGRITY2/10
██████████
Hidden profile; silently becomes behavior; no source, no removal
INJECTION RESISTANCE3/10
██████████
A web page saying "do X" can execute with your authority
PRIVACY3/10
██████████
Egress is a side effect of whatever tool ran; anyone who reaches the bot gets a session
OWNERSHIP1/10
██████████
Lives on the vendor's servers; years of context die with the subscription
EXTENSIBILITY4/10
██████████
Install = full ambient access to files, network, identity; opaque updates
SURFACES3/10
██████████
One app, one UI
FLAWLESS VICTORY — SELF-HOST YOUR CHAMPION ↓
5:install ── YOUR MACHINE, YOUR KEYS

INSERT COIN? NO. IT'S MIT.

TWO MINUTES · NO SUBSCRIPTION · NO VENDOR
$ quick — one line
$ curl -fsSL bastion.run | sh 

Bootstraps the full stack. Inspect the script first if that's your style — it preserves an existing .env and never prints generated credentials.

$ from source — inspect everything
$ git clone \
    https://github.com/thewaifucorp/bastion-agent.git
$ cd bastion-agent && ./installer.sh
$ bastion   # opens the TUI

bastion finds or starts the local Compose runtime and opens the TUI — Keeper included.