01 Operation
This is a COPY for the operator's reading room. The original (above) is the authority — if they ever disagree, the original wins and this file is regenerated. Generated 2026-10-12 18:27 by mira.
SolOS V3 — Production Documentation
SolOSV3 is the A2A-native agent fleet. One registry, everything derived from it,
cost-first model routing, and every control falsifiable by design. V2
(/home/lab/solos2) is reference only.
Suite: 457 passed · 2 skipped · 2 xfailed at 751286d — the state this document
describes.
1. What it is, in one paragraph
Eleven agents across three planes, all declared in one YAML file. The Heart (5
agents) runs tasks; the Brain (3) orchestrates and reports; Pulse (3, another
host) is the human-facing plane. A task arrives → the router picks the cheapest
capable model (free first, paid last) → the executor runs it through the opencode
CLI → every attempt is priced into a cost ledger → a stuck task escalates without a
human. Nothing restated: the registry is the one source and every projection
derives from it. Each module names the V2 defect it exists to close.
2. Where everything lives
| Path | Contents |
|---|---|
/home/lab/.solos/ | the code root — private git repo, origin = youngframeworks/solos-v3 |
core/protocol/ | seam.py (wire validation) · wire.py · card.py (Agent Card) · dialect.py |
core/config/ | models.py/models.yaml (derived model list) · ladder.py (tier ladder + retention blocklist) · router.py |
core/harness/ | definition.py (run-scoped env, no provider keys) · probe.py · wiring.py (built-never-wired detector) · readout.py (Stage 8 readout) |
cortex/registry/ | agents.yaml — THE one source · projections.py · 24 tests |
cortex/tasks/ | states.yaml (9 wire states / 14 local) · stuck.py (the 300s rule) |
cortex/memory/, cortex/skills/ | two-tier memory · skills store, plane-filtered |
operation/runtime/ | worker.py · serve.py · a2a_server.py · loop.py · store.py · invoke.py · observe.py · wire_route.py |
operation/state/ | disposable run state (task .db files) — gitignored |
etc/systemd/ | solos-v3-worker.service (the unit that runs the Heart) |
tests/ | 457 tests; every control has a MUST-FAIL case |
| Vault | /home/lab/SolOS/vault/Docs/SolOSV3/ — plans, rulings, the model sheet |
3. The agents — from the registry, at 751286d
| Plane | Agent | Endpoint | Model | Instrument |
|---|---|---|---|---|
| heart | ace | http://127.0.0.1:8301 | longcat-2.5-preview-free | none (free) |
| heart | alpha | http://127.0.0.1:8302 | longcat-2.5-preview-free | none (free) |
| heart | atlas | http://127.0.0.1:8303 | longcat-2.5-preview-free | none (free) |
| heart | echo | http://127.0.0.1:8304 | longcat-2.5-preview-free | none (free) |
| heart | nova | http://127.0.0.1:8305 | longcat-2.5-preview-free | none (free) |
| brain | min | http://127.0.0.1:8311 | longcat-2.5-preview-free | none (free) |
| brain | mira | http://127.0.0.1:8312 | longcat-2.5-preview-free | none (free) |
| brain | sol | http://127.0.0.1:8313 | longcat-2.5-preview-free | none (free) |
| pulse | eva | http://192.168.4.34:8441 | longcat-2.5-preview-free | none (free) |
| pulse | eve | http://192.168.4.34:8442 | longcat-2.5-preview-free | none (free) |
| pulse | tam | http://192.168.4.34:8443 | longcat-2.5-preview-free | none (free) |
The rule: a task is classified first (cortex/classification.py). A confidential
task routes only to a confirmed zero-retention model — with none confirmed, it is
refused outright rather than assumed safe. RETENTION_BLOCKLIST additionally
refuses muse-spark (trains on request data) even if someone confirms it.
4. How a task flows
submit --> TaskStore
|
classify (cortex/classification.py)
| confidential? -> confirmed zero-retention only, else REFUSED
v
route (core/config/router.py)
| ladder: GO free -> ZEN free -> GO paid -> ZEN paid
| per (endpoint, model_id); cost rung beats instrument rung
v
invoke (operation/runtime/invoke.py, OpencodeInvoker)
| opencode CLI; output-classified (rc==0 is NOT success)
| E5 boundary: no provider key reaches the child process
v
record (core/config/cost_ledger.py)
| every attempt priced; unknown is never summed as zero
v
stuck rule (cortex/tasks/stuck.py)
| 300s without progress -> escalate, no human decides
v
observe (operation/runtime/observe.py)
state counts · per-model ledger · cost · heartbeat
5. Operating commands
Environment (every command):
SOLOS_V3_HOME=/home/lab/.solos
Run the whole test suite (the health check):
cd /home/lab/.solos && SOLOS_V3_HOME=$PWD python3 -m pytest tests/ -q
Run one Heart worker (what the systemd unit does):
python3 operation/runtime/worker.py ace --poll-interval 5 --sweep-interval 30
Flags: --max-parallel N · --once (one cycle, for smoke tests) · --db PATH.
Serve one agent's A2A endpoint:
python3 operation/runtime/serve.py --agent ace # port from the registry
python3 operation/runtime/serve.py --agent ace --port 8320 --log-level DEBUG
Install the systemd unit:
mkdir -p ~/.config/systemd/user && cp etc/systemd/solos-v3-worker.service ~/.config/systemd/user/
systemctl --user daemon-reload
systemctl --user enable --now solos-v3-worker
journalctl --user -u solos-v3-worker -f
Submit a task (via A2A, the supported path):
json {"jsonrpc":"2.0","id":1,"method":"SendMessage",
"params":{"message":{"role":"user","parts":[{"text":"<goal>"}]}}}
Observe a running fleet:
python3 operation/runtime/observe.py # state counts, ledger, heartbeats
Probe the model catalogue live:
SOLOS_V3_HOME=$PWD python3 -c "from core.config import models; [print(p.declaration.address, p.reachable) for p in models.probe()]"
Backup and restore rehearsal (--no-agent, zero tokens):
hermes cron list # solos-backup-github 03:00 daily
bash ~/.hermes/profiles/mira/scripts/restore-proof.sh
6. Design rules, and the defect each one closes
| Rule | Source | The V2 defect it closes |
|---|---|---|
| One registry, everything derived | cortex/registry/ | the same fact restated in 2 places, drifting |
A model's identity is (endpoint, id) | core/config/models.py | a model listed under the wrong endpoint failed at call time |
| Cost rung beats instrument rung | core/config/ladder.py | paid GO called on attempt 3 while free ZEN sat untried |
| Unknown cost is never summed as zero | core/config/cost_ledger.py | 30,721 attempts at $0.00000 read as free |
Every paid call carries why_paid | cost_ledger.py | $11.17 with no recorded reason |
rc == 0 is not success | router.py | a polite refusal, exit 0, recorded as completed |
| Refuse > assume on retention | classification.py + ladder.py | an unconfirmed "probably zero-retention" is a disclosure |
| A control must be falsifiable | every module | V2 built six controls nobody called |
| Restore, don't document, the backup | restore-proof.sh | "a backup nobody has restored is a belief" |
7. Modules — what each one is for
| Module | Purpose |
|---|---|
cortex/registry/ | the 11 agents: ids, planes, ports, models, cost/retention fields |
cortex/registry/projections.py | derived views (ports, addresses, drift tests) |
cortex/tasks/ | the task contract: states, wire mapping, the stuck rule |
cortex/classification.py | is this task confidential? keyword+path, never an LLM |
cortex/memory/ | short/long memory, two capture paths |
cortex/skills/ | the skill store: declared by plane, loaded on demand |
core/protocol/ | the A2A v1.0 seam: validates the wire, derives states from the contract |
core/config/models.py + .yaml | the live model list, probed, never hardcoded |
core/config/ladder.py | the four-rung ladder + RETENTION_BLOCKLIST |
core/config/router.py | picks a rung, switches on failure, reports every attempt |
core/config/cost_ledger.py | append-only pricing of every attempt |
core/harness/definition.py | run-scoped, credential-free child environment |
core/harness/wiring.py | the built-never-wired detector |
operation/runtime/store.py | sqlite task store (the 14 local states) |
operation/runtime/invoke.py | one model call → (rc, stdout, stderr) |
operation/runtime/loop.py | the cycle: claim → route → invoke → record |
operation/runtime/worker.py | the wheel: poll, claim, parallel, sweep |
operation/runtime/serve.py + a2a_server.py | one agent's A2A listener |
operation/runtime/observe.py | the live readout |
8. Cost model — the numbers an operator needs
| Instrument | Definition | Consequence |
|---|---|---|
| GO | $10 package, per-model allowance | enters GO free first; paid is drawn only deliberately |
| ZEN | $40/mth credit | last rung — the only one that costs real money |
| 5-hour window | 20% of a model's monthly limit | the binding constraint, not the month |
| Model | Input | Output | Cached read | Monthly | 5-hour |
|---|---|---|---|---|---|
| MiMo-V2.6-Flash | $0.14 | $0.28 | $0.0028 | $60 | $12.00 |
| GLM-5.3-Flash | $0.15 | $0.50 | $0.03 | $60 | $12.00 |
| Muse Spark 1.2 | $0.10 | $0.20 | $0.002 | $60 | $12.00 |
| Qwen3.8 Flash | $0.15 | $0.47 | $0.016 | $30 | $6.00 |
| GPT 6 Luna | $0.10 | $0.50 | $0.01 | $15 | $3.00 |
| Claude Haiku 5.5 | $0.10 | $0.50 | $0.01 | $15 | $3.00 |
A free model on ZEN still costs $0.00; a paid GO model still costs money — which is why ZEN free outranks GO paid.
Measured posture (7 days to 2026-10-11): spend $11.60, down from $19.49; free
models did 4.8b tokens at $0.00; one paid model carried everything. Live figures
at any time: opencode stats --days 7 --cost --models.
9. Production status — honest, and dated
| Component | State |
|---|---|
| Registry, projections, drift tests | ✅ 24 tests, 0 drift |
| A2A seam + Agent Card | ✅ built, 8/8 conformance states |
| Task contract + stuck rule | ✅ 300s, fires unaided |
| Skills, tools, memory | ✅ plane-filtered, no cross-plane leakage |
| Cost/retention stack | ✅ ledger + ladder + router + blocklist, all falsified |
| Executor + worker + observer | ✅ 429-switch proven end to end |
| Backup & restore | ✅ daily cadence and restore proven into an empty root |
| The Heart listening | ◻️ ports 8301–8305 are not open — serve --agent ace starts one, and the systemd unit exists but was not installed at writing time |
So: every capability V3 defines is built and tested. What production adds is the operator action in §5 — installing the unit and binding the ports. That is a morning's work, not a build phase, and it is the one line in this document that ages first.
10. Known constraints
operation/state/is disposable by design — task.dbfiles do not survive to the backup. The cost ledger gets a second copy on each backup run.- Pulse planes 3 agents on
192.168.4.34— a different host; not reachable from LAB's loopback. provider_routing/data_collection: denysolves retention only via OpenRouter, and no model is on OpenRouter today. The blocklist is the control until then.operation/state/is disposable by design — task.dbfiles are not backed up; the cost ledger is copied out on each backup run.- The model sheet (
05-operations/) is a 2026-10-11 snapshot — prices are quoted, not probed.core/config/models.py::probe()answers it live. - Batch processing (
batch_runner.py) is out of scope — training-data generation, not fleet operation.

