Quickstart
Cubby Quickstart
From a fresh clone to a signed change against a real device in ~30 minutes.
0. Prerequisites
- Python 3.9+
- Docker runtime — Docker Desktop, OrbStack, or Colima (+ docker CLI). Colima is the lightest zero-license option on macOS: ```sh brew install colima docker docker-compose colima start --cpu 4 --memory 8 --arch aarch64 ```
1. Clone and install
git clone <repo-url> cubby
cd cubby
python3 -m venv .venv
source .venv/bin/activate
pip install -e ".[api,agents,dev]"
cp .env.example .env
Edit .env to taste. Everything has sensible dev defaults; the only fields most operators touch on a fresh install:
ANTHROPIC_API_KEY— when set,ClaudeAgentRuntimeis used as the default agent backend (preferred over OpenAI).NETOPS_EVIDENCE_HMAC_SECRET— production evidence-signing key. Leave empty to use the auto-generated dev key undervar/keys/.NETOPS_APPROVAL_HMAC_SECRET— production approval-signing key. Distinct from the evidence key by design.
2. Verify the install
cubby smoke
pytest -q # 790+ unit tests should pass; devicelab tests skip
smoke exercises the full workflow against SimulatedTransport. If it reports ok, your install is functionally correct.
3. Stand up a lab (Nokia SR Linux, free & public)
docker pull ghcr.io/nokia/srlinux:latest
docker run -d --rm --privileged --name cubby-srl1 -h srl1 -p 2221:22 \
ghcr.io/nokia/srlinux:latest sudo bash /opt/srlinux/bin/sr_linux
docker run -d --rm --privileged --name cubby-srl2 -h srl2 -p 2222:22 \
ghcr.io/nokia/srlinux:latest sudo bash /opt/srlinux/bin/sr_linux
until nc -z localhost 2221 && nc -z localhost 2222; do sleep 2; done
First boot of each container takes ~60s to initialise the SR Linux CLI.
4. Point Cubby at the lab
cp tests/devicelab/lab.nokia_srl.yml.example tests/devicelab/lab.yml
export LAB_SRL_USER=admin LAB_SRL_PASSWORD='NokiaSrl1!'
5. Exercise the full pipeline
Read-only snapshot (safe against any lab, even shared sandboxes):
python -m tests.devicelab.run snapshot
CAB-signed change (requires smoke.allow_write: true + smoke.change_path: true in lab.yml):
python -m tests.devicelab.run change --device srl1 --interface mgmt0 --vlan 42
Evidence chain audit (run after any session):
python -m tests.devicelab.run verify-chain
6. What to expect
snapshotreturns{"ok": true, ...}with real hostname + vendor + os_family + interface list parsed from each device.changeruns the complete Cubby path:- Normalise
ChangeRequest→TypedIntent - Policy + validator pass
- Sign CAB approval bound to the canonical plan hash
- Precheck + execute forward commands on the real device
- Re-snapshot + verify
- On verification failure → rollback + mark
ROLLED_BACK - Write signed evidence bundle; advance
chain.tipworkflow_state: CLOSEDis full success.ROLLED_BACKis also expected when the intent's verification invariant doesn't hold on the target device (e.g. Nokia SR Linux'smgmt0doesn't have anaccess_vlanthe way Cisco/Arista access ports do — the spine correctly rolls back when the verification check fails).
- Normalise
verify-chainreturnsok: truewith total bundle count and any legacy-signature / chain-reset counts. Anychain_errors≠ [] means the evidence chain broke — investigate before proceeding.
7. Tear down
docker rm -f cubby-srl1 cubby-srl2
colima stop # optional — keeps the Linux VM around for next session
8. Next steps
- Add more devices to
lab.yml— Arista cEOS, Cisco IOS-XE, real hardware. Seetests/devicelab/README.mdfor per-platform setup. - Read
docs/OPERATOR_GUIDE.md— the deep-dive for anyone going past lab use: env-var matrix, demo vs production posture, how to wire real adapters, per-approver Ed25519 CAB keys, API auth upgrade path, secrets custody, and the "ready for a second human" checklist. - Wire production signing keys — rotate from the dev keys under
var/keys/to real secrets managed by your secret store. SeeSECURITY.md§ "Signing-key custody". - Stand up OIDC or HMAC API auth — the default
devmode is for local work only. SetNETOPS_API_AUTH_MODE=hmacor=oidc+ the matching env vars. - Read
SOUL.md+AGENTS.md— the workspace convention primes the agent's system prompt. EditingUSER.md+TOOLS.mdteaches Cubby about your fleet.
Troubleshooting
no device in lab.yml has resolvable credentials — the credentials_env prefix on each lab device resolves to <PREFIX>_USER + <PREFIX>_PASSWORD env vars. Default expects LAB_SRL_USER / LAB_SRL_PASSWORD.
Permission denied for user svc-cubby-network-jit — the demo execution engine issues a short-lived service-account lease that real devices don't know about. The lab harness ignores this and uses the lab credentials directly. If you see this from the CLI, you're not going through tests.devicelab.run — use the CLI wrapper.
Validators reject the plan (workflow only supports access-mode interfaces / target VLAN not in allowed set) — the lab harness seeds lab devices into the state repository with access-port metadata so the validators accept the plan. If you hit this, rebuild the harness through build_lab_harness(); don't use build_demo_harness() directly for live-lab work.
asyncssh.misc.PermissionDenied on an exec command — usually SR Linux hasn't finished booting. Wait 60-90 seconds after docker run before running the first snapshot.