Use Getting started for the macOS build, Architecture for the picture, and the contracts for what each primitive guarantees.
| Path | What lives there |
|---|---|
| crates/ | The kernel and its generic hosts. Nothing here knows a provider, a channel, or a tool by name. |
| registry/interface/ | Every interface descriptor, every worker pin, and each interface's own driver code. |
| registry/worker_environment_kind/ | Room descriptors with their executors and tool binaries. |
| registry/tool/ | Tool descriptors pointing at a room's executables. |
| registry/ee_template/ | Goals and their policy. |
| registry/artifact/ | Declared context artifacts: roles, grounding, skills. |
| registry/mark/, registry/verifier/ | Outcome vocabulary and check packages. |
| schemas/ | JSON Schemas for run records, movements, grants, verdicts, marks, verifiers. |
| app/src/, app/electron/ | The desktop client: React presentation and Electron host operations. |
| app/cli/ | Terminal presentation over the shared client projections, authoring, setup, and artifact transports. |
| app/distribution/ | The baseline registry, local application packs, generated-output declarations. |
| app/schemas/ | Client-side JSON contracts: setup, packages, surfaces, extensions. |
| Crate | Role |
|---|---|
octopus-app |
The octopus binary: up, down, doctor. Boots a Home and runs the arrival loop. |
octopus-app-server |
The composition root: registry snapshot, artifact arrival handling, and the worker-policy wiring. |
octopus-runtime |
Grant formation per arrival, admission, outbound transfers, run records, and the run-records index. |
octopus-policy |
Policy shapes and their reduction: worker-interface ceilings and interface policy declarations. |
octopus-ee |
EE templates, instances, and the EE tree. |
octopus-interfaces |
Interface descriptors and worker-pin policy loading. |
octopus-interface-transport |
Interface life processes, hand-in, activation, and live reconciliation. |
octopus-interface-projection |
What an interface is handed: binding, affordance, metadata, and registry projections. |
octopus-descriptors |
The one strict JSON gate every descriptor crosses, and descriptor hashing. |
octopus-tool-registry |
Tool descriptor loading and argument validation. |
octopus-tool-handlers |
The passive tool-call and tool-result contract. No executable family lives here. |
octopus-worker-env |
Room descriptors, leasing, and the authorization gate. Room behavior lives in kind packages. |
octopus-marks |
Mark descriptors and the verification input and verdict types. |
octopus-verifiers |
The blind verifier runner: pins a package and executes its script. |
octopus-ledger, octopus-ledger-store |
Movement types and the append-only log. |
octopus-ledger-index |
The in-memory arrival index and the disposable SQLite index. |
octopus-schemas |
The published JSON Schemas. |
Adding a capability over an existing driver or room is descriptors and
bindings. A genuinely new execution family is code inside its concrete owner
folder under registry/. Do not put provider names, artifact semantics, or
product behavior into the crates' decision paths. See
Extending Octopus.
The file observer example
demonstrates selected files becoming immutable input artifacts, a checkpoint
waiting for two independently verified snapshots, and catch-up after repairing
an exact interface binding. Its --read-root argument grants an explicit
existing directory; the command prints the proposed files and steps without
installing them. The observer is an interface package, while waiting and
replay use existing runtime mechanisms. Use ./octopus inspect <run-id> --json
to inspect the resulting checkpoint and movement evidence.
JSON is part of the program here. A worker ceiling or interface binding can change behavior as much as a source edit, so a commit alone does not describe what a user's installation is running.
The diagram separates running code from persistent files. Repository packages reach Home through the distribution and installation path; client preferences and provider credentials have the separate locations below.
| Location | Owner and purpose |
|---|---|
registry/, app/distribution/, schemas |
Versioned source: reusable code, descriptors, package definitions, and validation rules. |
Octopus.app |
A built snapshot: client, runtime, startup baseline, and optional local packages. |
<home>/registry/ |
Installed, active descriptors and package code, including local configuration and authorized mutations. |
| Other Home files | Machine roots, runs, EEs, ledger, blobs, installation receipts, and private interface state. |
<home>/client/ / provider state |
The client profile of that Home, including preferences and Extensions / provider-owned credentials, which OCTOPUS_HOME does not isolate. |
The normal loop is edit the owning source or descriptor → run focused checks → build the changed distribution → exercise it against an explicitly selected test Home → inspect the run and movement evidence. For client presentation, the renderer preview is the shorter loop described below. An edit in the checkout does not automatically update a packaged app or an already-installed package in a Home.
Octopus is a research preview. Incompatible persisted formats require a fresh Home through normal setup. There are no schema migrations, predecessor tables, automatic package adoption, or startup repairs of missing fields in old state. The bundled registry initializes a new Home once; later starts use the installed registry. Explicit package installation and recovery of interrupted operations in the current format remain supported. Preserve sign-in credentials when resetting a disposable Home; do not transplant old runs, checkpoints or ledgers.
Authorized local changes to descriptors, role artifacts and package code do not invalidate an installed package. Doctor validates active contracts and runs declared probes; it does not compare installed bytes with the bundle.
A reusable fix belongs in the source package and its checks. A user's token, machine path, run, or personal context belongs in private state. Reproduce a bug with the smallest relevant package/configuration and recorded evidence; do not turn a user's Home into a source fixture. See Troubleshooting for collecting diagnostics and the client guide for the installation path.
- Fix the contract, not the symptom. Failures here are almost always architectural - the wrong data shown to the model, a missing descriptor field - not a capability gap. Hardcoding around one hides a problem in the system behind a workaround for the model.
- No branch on identity. Not on a worker pin, a provider, a model string, or an artifact label.
- Fail closed. A clear error beats a fallback that almost works. No silent semantic fallback, no placeholder success.
- Leave evidence. A new side effect produces an artifact and a movement.
- Tests follow the framework. Add a contract test when a primitive is stable. Keep test code well under half of a change, and do not pin implementation details.
- Comments describe documented architecture or nothing. No promises, no migration notes, no explanations of why a change is correct.
Install dependencies and use the Node/Rust toolchains in the build guide. From the repository root, run the checks relevant to a change:
cargo check --locked --workspace --all-targets
cargo test --locked -p octopus-policy --lib
cargo test --locked -p octopus-runtime --lib
cargo test --locked -p octopus-ledger-index --libFor client setup and presentation contracts:
cd app
npx tsc --noEmit --incremental false
npm run check:design-system
npm run test:workspace-setup
npm run test:client-setup
npm run test:chat-trace-contractsThe quality workflow lists the broader checks
and platform dependencies. It runs Rust contracts through cargo nextest, one
process per test; .config/nextest.toml runs the
Code Mode, process session and file publication tests one at a time.
Source/type checks and contract tests do not prove a
fresh packaged setup, a real model reply, or physical device permissions.
For the terminal client, npm --prefix app run test:cli checks transcript,
interaction, transport, packaging, and setup contracts. npm --prefix app run build:cli builds its release distribution; build:cli-client rebuilds only the
shared TypeScript client functions. Exercise the resulting CLI with an explicit
test Home for real task and tool acceptance. The terminal imports the existing
client libraries and installed chat interface; it does not create a second task
index or runtime control API.
Run the Doomsday latency budget separately in release mode:
cargo test --locked --release -p octopus-app-server --test doomsday -- --ignored --nocaptureThe budget is 1,000 ms of framework overhead for a reference 5,000 ms model response. It measures 20 artifact round trips per scenario through policy, durable storage and verified marks: one project EE, then 1,000 project EEs and background run records with a maximum depth of 30. Cold and warm exchanges must both fit. Provider replies are boundary fixtures; model latency, client work and initial setup are outside the timed exchange. No user Home or live provider is used.
quality runs when a pull request is opened, updated with new commits,
reopened, or marked ready for review. It also runs on pushes, except changes
limited to docs/ and the root README.md, and supports Run workflow.
A newer run cancels an older quality run for the same pull request, branch or
tag. Pull request jobs use read-only repository permissions; GitHub may require
maintainer approval before running a fork's contribution. doomsday is manual
only. release runs for a pushed v* tag and on Run workflow; see
Releases. None of them has a schedule or an automatic retry loop.
Local checks use no GitHub-hosted runner minutes. When publishing a local commit status, name the checks actually run, attach it to the exact tested commit, and retain the command results. A local check does not establish that the Linux and macOS hosted jobs passed. Billing-blocked jobs have not tested the code and must not be relabeled as successful tests.
From the repository root, check publication inputs with:
node app/scripts/check-public-source.cjsThat check reads the selected Git blobs and declared package inputs. Required
public files must be selected, and the publication controls must match the
checked files. Use it before publishing a checkout; --worktree skips the
staged-file inventory. It does not establish asset provenance or runtime acceptance.
A release is the packaged app as a disk image,
Octopus-<version>-macos-<arch>.dmg, with install.sh and checksums.txt.
The version is version in app/package.json; the packager writes it into
the bundle, and the release tag is v<version>.
After npm --prefix app run package:mac, build the release assets locally with:
node app/scripts/release-macos.cjsThe script checks the bundle (version, identifier, minimum macOS,
architecture, managed Codex receipt, code signature), then builds the disk
image on an APFS sparse image in which byte-identical files are clones of one
copy. The bundle carries the same executables in several package owners, and
the clones keep the compressed image close to the size of the unique content.
It mounts the result, compares every path, mode, and SHA-256 with the bundle,
verifies the signature inside the image, and writes app/build/release/ and
app/build/release-notes.md from app/release. Nothing is
uploaded.
The release workflow does the same on a hosted macOS runner. Run workflow
is a dry run whose assets stay on the run for seven days. Pushing a tag that
matches app/package.json builds the assets and creates a draft GitHub
release; it becomes public only when a maintainer publishes the draft. Asset
digests reported by GitHub are checked against checksums.txt.
Quit the client and runtime before replacing the release. If the release changes persisted contracts, initialize a fresh Home and retain only sign-in credentials. Existing runs and ledgers are not upgraded.
For a browser renderer preview, from the repository root:
npm --prefix app run devVite serves the renderer on the local address it prints. Electron-only operations and runtime-backed flows require the desktop app; the browser preview cannot stand in for their acceptance.
Test the built app/build/Octopus.app with its bundled release runtime and
capability executables. Use a dedicated test Home and the actual onboarding
flow. Keep real user Homes, credentials, and accepted UI behavior intact. An
integration needing login or macOS permissions must be exercised separately;
missing credentials are an explicit limit on the result.
The fresh packaged onboarding runner documents its modes with:
npm --prefix app run dev:onboarding -- --helpAfter preparing the build prerequisites, run both modes from the repository root:
OCTOPUS_NATIVE_NODE_HEADERS="$PWD/app/build/node-v24.15.0/include/node" \
npm --prefix app run dev:onboarding -- --mode unauthenticated
npm --prefix app run dev:onboarding -- --mode reused-auth \
--auth-file /absolute/path/auth.json --target task --no-buildEach run creates empty, isolated client, runtime, and provider Homes. The first mode builds and signs the app, walks welcome, opens browser sign-in, and cancels it. It does not claim a completed login. The second copies only the selected credential, completes setup, and requires rendered replies in Home and a new task. It removes the credential copy afterward.
--no-build requires a previous successful harness build whose source and bundle
hashes still match. Reports and screenshots stay in ignored
.private/onboarding/. Read the report's requested boundary and result before
calling onboarding verified; the runner does not certify every capability or
macOS permission.
Change schema-owned data explicitly and validate it at its owner. Do not hide malformed old data behind startup migrations, fallback models, or a degraded success path. Report any source/documentation mismatch and what remains unverified in the change description.
