Agent index (llms.txt) — fetch this first, then the page it names.
Development setup
How to build and test Orama from a checkout. Everything lives in one repository.
Repository layout
| Path | What | Language |
|---|---|---|
core/ | Node software: gateway, CLI (orama), supervisor, install, monitor | Go 1.27.2+ |
chain/ | The Orama chain (oramad, orama-global). Its own Go module; core/ does not import it | Go |
caddy/ | The Caddy modules built into every node's Caddy | Go |
sdk/ | @debros/orama, the TypeScript SDK | TypeScript |
sdk-vault/ | @debros/orama-vault, the vault client | TypeScript |
vault/ | The guardian daemon | Zig |
os/ | OramaOS: agent and Buildroot image | Go, Buildroot |
website/ | The website and these docs | TypeScript (pnpm) |
e2e/ | The fleet end-to-end suite | Go |
docs/ | The whitepaper and the technical reference (docs/whitepaper/); every other doc is in website/src/docs/ | Markdown |
contracts/ | Request and response fixtures shared by Go and TypeScript tests | JSON |
Prerequisites
| Tool | Version | Needed for |
|---|---|---|
| Go | 1.27.2 or newer | Everything in Go |
| Node.js | 22.12 or newer (the repo pins 24 in .nvmrc) | The SDK and the website |
| pnpm | Current | TypeScript packages |
| Zig | 0.15.x (the minor release vault/build.zig.zon names; ORAMA_ZIG overrides) | orama maint build (it cross-compiles the vault, and the gateway with cgo through zig cc, static musl), the vault |
| git, make | Current | Version stamps, the Makefiles |
# macOS brew install go node pnpm git make # Zig 0.15.x from https://ziglang.org/download/ (the build checks the minor release) go version # 1.27.2 or newer zig version # 0.15.x
Zig is needed for orama maint build, not for running the unit tests: the gateway links mattn/go-sqlite3 for namespace SQLite databases, which does not work in a CGO_ENABLED=0 build. macOS or Linux works.
RootWallet and the deploy commands
The RootWallet desktop app, open and unlocked, is required by every command in Release and rollout that reaches a node.
There are no SSH keys on disk. Every command that reaches a node (orama maint push, orama maint rollout, orama node setup, orama status report, orama ssh) asks the RootWallet desktop app's agent for a wallet-derived key over a Unix socket at ~/.rootwallet/agent.sock, writes it to a 0600 temp file for the length of the command, and wipes it afterwards. RW_AGENT_SOCK overrides the path.
Before a rollout: open the app and unlock it. Then expect this:
- +First run after a rebuild, one approval prompt. Approval is keyed on the hash of the calling binary, so every
make buildproduces a neworamathat RootWallet has not seen before and asks about once. - +One unlock for the whole run. The agent locks itself after 30 minutes of no traffic, and a six-node rolling upgrade spends far longer than that in SSH sessions the agent never sees. The CLI touches the agent every five minutes for as long as it holds keys, so the window stays open until the command finishes and closes immediately after.
- +A command that seems to hang is usually a prompt. Look at the desktop app. A first run against a locked wallet waits up to two minutes for approval and two more for the unlock before it gives up.
If a command fails with a RootWallet error, the message says what to do; the codes are listed in Troubleshooting. For a real cluster you also need RootWallet installed.
Every command and flag the CLI defines is in the CLI overview and its generated pages, which are rendered from the command tree and checked by a test, so they cannot drift from the code. This page covers the workflows.
Build and test
The Go module for the node is core/, not the repository root. The root Makefile delegates to it.
cd core make deps make build # binaries in core/bin/: orama, orama-node, gateway, identity, sfu, turn, orama-sni-router, ... make test # go test ./... make lint
| Task | Command |
|---|---|
| All unit tests | make -C core test. The root make test is the full local gate: core, Caddy modules, the SDK unit tests (make sdk-test; cd sdk && pnpm install --frozen-lockfile first), the fleet-e2e lint and coverage gate, and the whitepaper checks |
| One package | cd core && go test ./pkg/path/to/package/... |
| One test | go test ./pkg/path/... -run TestName |
| Race detector | go test -race ./pkg/path/... |
| Regenerate the CLI reference | make -C core docs (a test fails if whitepaper appendix D, docs/whitepaper/technical-reference/appendices/d-cli-reference.md, drifts from the command tree) |
| The chain | cd chain && make build && make test (see Running a chain node) |
| The SDK | cd sdk && pnpm install && pnpm build && pnpm test |
| The vault | cd vault && zig build && zig build test |
| This website | cd website && pnpm install && pnpm dev (build: pnpm build; docs check: node scripts/check-docs.mjs) |
make build writes an orama into core/bin/. A signed archive for a cluster is orama maint build from core/ (Build and sign); it builds Caddy from the repository's caddy/ module, so no xcaddy is needed. The archive also carries the chain node (oramad, its verifier, orama-global, cosmovisor), which needs rustup with the x86_64-unknown-linux-musl target, cargo, make and rsync; --skip-global-layer leaves it out. Set SOURCE_DATE_EPOCH to get a reproducible archive (Release and rollout). Maintainers cut a build into the release repository with orama maint release (Cutting a release).
Run against a cluster
There is no local single-process mode that skips systemd. To exercise node code, use a sandbox (Sandbox clusters) or the one-VPS evaluation path (One-VPS evaluation).
orama network add dev https://cluster.example.com orama network use dev orama auth login
The explorer against a made-up chain
To work on the explorer's pages without a network, start the dev server with the dev gateway:
cd website ORAMA_EXPLORER_DEV_GATEWAY=1 pnpm dev --host 127.0.0.1
It serves a small invented chain (the fixtures of the explorer's own tests, extended so that every page has data) at /v1/chain/ on the dev server. Open /explorer/custom?gateway=http%3A%2F%2Flocalhost%3A5173 (the port is the dev server's) and confirm the gateway when the explorer asks. The host in the address picks the behaviour: localhost is a node with the chain indexer, http://127.0.0.1:5173 is a node without one (every index/… route answers 503 "runs no chain indexer"), which shows the explorer's no-indexer states; a gateway address nothing listens on (http://127.0.0.1:1) shows the unreachable-gateway error. The head moves every four seconds so the live parts can be watched.
It is a development tool and nothing else. The plugin (website/src/explorer/dev/vite-plugin.ts) applies to vite dev only, is added to the configuration only when the variable is 1, refuses to start in production mode, and nothing under src/ imports src/explorer/dev, so the built site cannot contain it; a test builds the explorer and checks.
IDE
VS Code with the Go extension, or GoLand. core/, chain/ and e2e/ are separate Go modules; open each as its own module.
The rules of the codebase
Read Code style and Testing before your first change. In short:
- +Code is the source of truth, docs describe what the code does today, and a change ends with a check that no doc now lies.
- +Every change ships unit tests; every user-visible change (a CLI command, gateway route, chain message or query, systemd unit, documented guarantee) ships a fleet e2e test and lists it under
covers:ine2e/features/<x>/feature.yaml.make testfails the coverage gate otherwise. - +Fix root causes. No fallbacks, no retries that mask flakiness, no catch-and-continue.
- +Rolling upgrades only: never restart several RQLite voters at once.