aos-setup · diff
git:20260913.a6dac4f to git:20260913.9ff238a
71 added, 9 removed. Audit B to B.
---
name: aos-setup
description: >-
Bring a machine to a complete, verified AOS installation: the skills pack,
MCP servers, gate hooks, memB (engine, MCP, ambient hook, WebUI), OpenWiki
(CLI, auth, harness integrations, refresh daemon) and Synapse. Run once on a
new computer, and again whenever something in the ecosystem stopped working.
category: bdb-core
risk: low
source: bdb
date_added: "2026-09-13"
---
# AOS Setup — Machine Level
Installing the AOS npm package is the easy half. The half that quietly fails is
everything around it: memB has no venv, the ambient memory hook was never
wired, OpenWiki has a CLI but no provider credentials, Synapse's binary is not
on `PATH`. The result is a machine where most skills work and the memory,
documentation and visualization layers silently do nothing.
This skill closes that gap: **measure first, then fix only what is broken.**
- For per-project wiring — a new project folder, its `AGENTS.md`, its memB
- project binding, its wiki — use `/aos-project-init` after this one.
+ This is also where a **new agent harness** gets wired: adding Codex or
+ Antigravity to a machine that already runs Claude Code is this skill's job, not
+ a reinstall.
+ For per-project wiring — a folder's slug, its wiki, its memB binding — use
+ `/aos-project-init` after this one.
+
+ ### What each harness can actually do
+
+ Portability is not uniform, and pretending otherwise is how people end up
+ believing memory works everywhere:
+
+ | | Skills | MCP | Hooks |
+ |---|---|---|---|
+ | Claude Code | `~/.claude/skills` | `~/.claude.json` | **yes** |
+ | Antigravity | `~/.gemini/config/skills` | `mcp_config.json` | no |
+ | Codex | `~/.codex/skills` | `config.toml` | no |
+ | OpenCode | — | `opencode.jsonc` | no |
+ | Cursor / Roo | `bdb-skills` | `mcp.json` | no |
+
+ Only Claude Code has hooks, so only there can memB inject per prompt. Elsewhere
+ the same context arrives through the rule files that harness loads at start —
+ see section 5 — which means it is as fresh as the last write, not as fresh as
+ the prompt. Say so plainly rather than letting someone assume parity.
+
---
## 1. Measure
Run the doctor. It is read-only; it installs and edits nothing.
```bash
node skills/global_config/aos-setup/scripts/aos-doctor.mjs # from the AOS repo
node ~/.claude/skills/aos-setup/scripts/aos-doctor.mjs # from an installed copy
```
Flags: `--json` for machine-readable output, `--net` to also compare the
installed AOS version against npm.
It reports up to 26 checks across six areas, each with the exact fix command.
The exact number varies by machine: the LaunchAgent rows are macOS-only, the
OpenWiki integrations row needs the CLI on `PATH`, the npm-version row needs
`--net`, and the optional-module rows appear only for modules the manifest
claims are installed.
| Area | What is verified |
|---|---|
| `prereq` | Node ≥ 22, `python3`, `git`, `uv`, `gh` |
| `aos` | `~/.agents/.bdb-manifest.json`, skills synced into each harness's skill directory |
| `hooks` | `go-gate.mjs`, `graph-gate.mjs`, `memb-inject.mjs` — present **and** wired in `~/.claude/settings.json` |
| `memB` | module, venv, `~/.MemBDB/memb.db`, WebUI on `:8088`, autostart, `memb-mcp` venv, MCP registration |
| `openwiki` | CLI, `~/.openwiki/.env` credentials, harness integrations, 2-hourly refresh daemon |
| `synapse` | binary on `PATH`, daemon on `:7781` |
Exit code is `0` only when every check passes. **Report the failing rows to the
user before changing anything**, then work the sections below in order — each
one covers a block the doctor can flag.
---
- ## 2. Install or update AOS itself
+ ## 2. Machine configuration
+ Two things are machine-specific and ship with **no** value, because AOS is a
+ public package: one person's `web, media, infra` means nothing on someone
+ else's disk.
+
```bash
+ aos-config propose # read this machine's layout, suggest nothing more
+ aos-config show # what is configured now
+ ```
+
+ `propose` looks for a workspace root (`~/dev`, `~/Projects`, `~/src`, `~/code`)
+ and offers its immediate subdirectories as the domain vocabulary. **Present the
+ proposal, do not apply it** — the user decides which of those are real domains
+ and which are just folders. Then ask for the memB `user_id`, which must never
+ be invented either.
+
+ ```bash
+ aos-config set workspaceRoot ~/dev
+ aos-config set domains bdb-core,web,media,agents,infra
+ aos-config set userId <the user's memB id>
+ ```
+
+ The result lands in `~/.agents/aos-config.json`. `/aos-project-init` reads it
+ to offer a domain per project and refuses to guess when it is missing.
+
+ ---
+
+ ## 3. Install or update AOS itself
+
+ ```bash
npx -y @hybridlabor-api/aos@latest
```
The interactive installer asks which harnesses to target (Claude Code, Gemini /
Antigravity, Codex, OpenCode, Claude Desktop, …), which MCP servers to wire,
and which optional modules to pull. Non-interactive variants:
```bash
npx -y @hybridlabor-api/aos -y --platforms=2 # unattended, one platform
npx -y @hybridlabor-api/aos --dry-run # show what it would do
```
Two things worth insisting on when the installer asks:
- **Pick every harness the user actually runs.** A harness left unselected gets
no skills at all, which is the single most common "AOS doesn't work here".
- **Enable the optional modules** — memB, Synapse, OS Remote, Creator
Extension, Tool Installer. They are what the doctor's memB and Synapse
sections check for.
The installer writes `~/.agents/.bdb-manifest.json`. If that file is absent,
nothing was ever installed globally, no matter how many skills happen to sit in
a harness directory.
---
- ## 3. memB — memory that actually retains
+ ## 4. memB — memory that actually retains
memB is three separate pieces, and a machine can have any subset:
| Piece | Lives at | Doctor row |
|---|---|---|
| Engine + WebUI | `~/.agents/memB` (venv, `:8088` daemon) | `module`, `python venv`, `WebUI :8088`, `autostart` |
| MCP server | `~/.gemini/config/mcps/memb-mcp` (venv + `run.py`) | `memb-mcp server`, `memb_mcp registered` |
| Ambient hook | `~/.claude/hooks/memb-inject.mjs` | `memb-inject.mjs`, `memb-inject.mjs wired` |
The engine and the MCP come from the installer. If the venv is missing, repair
it in place rather than reinstalling everything:
```bash
cd ~/.agents/memB
uv venv --seed .venv
uv pip install --python .venv/bin/python -r requirements.txt
```
`uv venv --seed` has been observed to create a venv without `pip`; that is why
`uv pip install --python <venv>` is the command above and not `python -m pip`.
The store lives in `~/.MemBDB/memb.db`. An empty store is normal on a fresh
machine — `/aos-project-init` seeds it per project.
---
- ## 4. The ambient memory hook
+ ## 5. The ambient memory hook
The hook is what makes memB *ambient* rather than something an agent has to
remember to query. On every prompt it reads the SQLite store directly and
injects the relevant memories as context. It fails open: any error exits `0`
and the prompt proceeds untouched.
Since v4.4.0 the installer ships `memb-inject.mjs` into `~/.claude/hooks/` and
wires it as a `UserPromptSubmit` hook. **v4.4.0's Quick Update did not** — it
refreshes skills and submodules, and hooks are harness plumbing rather than
skills, so a machine that already had AOS updated to 4.4.0 without ever
receiving the hook. Fixed in v4.4.1; a machine that took that update needs one
more run:
```bash
npx -y @hybridlabor-api/aos@latest
```
The wiring is merged into `~/.claude/settings.json`, never written over it:
user keys and foreign hook entries survive, and a re-run replaces the BDB entry
rather than adding a second copy.
The hook carries an `aos-hook-version:` line on its second line, and the doctor
compares it against what the installed release expects. That is why the row can
read *stale* rather than simply passing: a hook file that exists and is wired
can still be an old copy carrying a bug this version fixed. When you change the
hook in a way machines must pick up, bump that line and the expected value in
`aos-doctor.mjs` in the same commit — the test suite fails if the two disagree.
Unlike the two gate hooks, this one stays `$HOME`-anchored even in a project
harness — the memB store is machine-global, and pointing it at
`$CLAUDE_PROJECT_DIR` would make it fail on every prompt in any project the
harness was never installed into.
+ **On a harness without hooks** — everything except Claude Code — the same
+ context is written into the rule files that harness loads instead:
+
+ ```bash
+ python3 ~/.agents/memB/memb_auto_inject.py --global # GEMINI.md, CODEX.md, …
+ python3 ~/.agents/memB/memb_auto_inject.py --dir <repo> # a project's AGENTS.md
+ ```
+
+ It merges into a delimited block and leaves everything outside it alone. The
+ block carries the time it was written, because this path is only ever as fresh
+ as its last run.
+
Standing facts that should reach every prompt — persona, brand rules, house
style — go one per line into `~/.MemBDB/ambient-persona.txt`. Lines starting
with `#` are ignored. This file is deliberately *not* shipped: ask the user
what belongs there rather than inventing it, and never copy another machine's.
Verify by starting a session and checking that the first prompt carries a
`[memB Ambient Memory Context]` block.
---
- ## 5. OpenWiki
+ ## 6. OpenWiki
```bash
npm install -g openwiki@latest # CLI, needs Node >= 22
openwiki auth <provider> # google | openai | groq | openrouter | ollama | …
openwiki integrations list # per-harness host integration status
openwiki integrations install claude # repeat for codex / cursor / opencode
```
Credentials land in `~/.openwiki/.env`. Without them every wiki run fails at
auth — the CLI being on `PATH` proves nothing on its own.
The 2-hourly refresh daemon comes from the AOS installer when an OpenWiki API
key is supplied. To install it separately:
```bash
bash ~/.claude/skills/openwiki-skill/scripts/install_daemon.sh # macOS / Linux
powershell -ExecutionPolicy Bypass -File install_daemon.ps1 # Windows
```
Wikis themselves are per-repository (`.openwiki/` in each project) — that is
`/aos-project-init`'s job, not this one's.
---
- ## 6. Synapse
+ ## 7. Synapse
The installer downloads the module, symlinks the binary to
`~/.local/bin/synapse` and registers a daemon on port `7781`. Two failure modes
the doctor separates deliberately:
- **Binary not found** — usually `~/.local/bin` missing from `PATH`. Add it to
the shell profile; do not copy the binary somewhere else.
- **Port closed** — the daemon is not running. On macOS:
`launchctl load -w ~/Library/LaunchAgents/com.bdb.synapse.plist`.
If no pre-built binary exists for the platform, build it:
`cd ~/.agents/bdb-synapse && go build -o synapse ./cmd/synapse/`.
---
- ## 7. The dashboard
+ ## 8. The dashboard
`aos-dashboard` serves one page on `http://127.0.0.1:7900` showing every BDB
service live — memB, Synapse, the OpenWiki daemon, AO Orchestrator and RemoteOS
— with its version, port, LaunchAgent state, start/stop/restart, and its log
files inline. It polls every five seconds.
```bash
aos-dashboard # opens the browser
aos-dashboard --no-open # just serve
aos-dashboard --port 7901 # if 7900 is taken
```
It binds to `127.0.0.1` only, and every control action is matched against a
fixed service table — an id or action the table does not contain is refused,
and no value from the request ever reaches a shell or a file path.
It also surfaces causes a port probe cannot see. The AO Orchestrator card
checks the code signature of `~/.local/bin/ao`: a binary rebuilt and copied
into place unsigned is SIGKILLed by AMFI at launch (exit 137), which otherwise
looks like a daemon that is simply down, with nothing in the log. The fix it
names is `codesign -s - -f ~/.local/bin/ao`.
Use it when the user asks what is running, or when a doctor row says a port is
closed and the question is why.
---
- ## 8. Confirm
+ ## 9. Confirm
Re-run the doctor. Do not report success from the fact that commands ran —
report the doctor's own count:
```bash
node skills/global_config/aos-setup/scripts/aos-doctor.mjs
# 26/26 checks pass. AOS is fully wired.
```
Anything still failing that the user deliberately does not want (no Synapse on
a headless server, no OpenWiki daemon on a laptop) is fine — say so explicitly
instead of leaving it looking broken.
Then hand off: **the machine is ready; per-project setup runs through
`/aos-project-init` in each repository.**
---
## Red flags
- Reporting "AOS installed" on the strength of a successful `npx` run. The
installer succeeds happily with memB skipped and no hook wired.
- Overwriting `~/.claude/settings.json` instead of merging into its `hooks`
object — that silently removes the go-gate.
- Treating an empty `~/.MemBDB` as a defect. It is the expected state until
something is ingested.
- Copying the reference machine's persona file verbatim onto someone else's
computer. Ask what their standing facts are.