## 1. Project Overview & Quickstart (unicity-astrid/LICENSE-MIT) # LICENSE-MIT Open-source repository unicity-astrid/LICENSE-MIT ### Repository Details - **Repository:** [unicity-astrid/LICENSE-MIT](https://github.com/unicity-astrid/LICENSE-MIT) - **Primary Language:** Code *Note: High-volume repository documentation is actively indexed and synchronized by YakaAI.* ## 2. Official Technical Reference & Guides (unicity-astrid/unicity-astrid.github.io) ## File: README.md # Unicity AOS website Product website and developer documentation for **Unicity AOS**, the modular Agent Operating System from Unicity. The site explains the product distribution while preserving the boundary to [Astrid Runtime](https://github.com/astrid-runtime/astrid), the open operating-system engine beneath it. The production hostname is [aos.unicity.ai](https://aos.unicity.ai/). Until the first signed AOS product release is published, the install surface visibly marks stable, dev, nightly, Homebrew, and AOS Oracle channels as staged and keeps every copy action disabled. ## Repository layout | Path | Purpose | | --- | --- | | `site/` | Astro website, developer guide, local docs lens, and product pages | | `kernel-web/` | Browser bridge for the real Astrid kernel used by interactive explanations | | `site-capsules/` | WebAssembly components used only by the in-browser experience | | `kernel-smoke/` and `spike/` | Runtime portability and component-model probes | | `notes/` and `DESIGN.md` | Implementation notes and the current product-site contract | ## Develop The website requires Node.js 22.12.0 or newer. ```sh cd site npm ci npm run check npm run build npm run dev ``` Both `check` and `build` are release gates. The product release integration is centralized in `site/src/lib/release.ts`; `available` may become `true` only after matching AOS artifacts, checksums, signatures, and installer assets exist. The default installer channel is stable. Development and nightly channels are always explicit (`--channel dev` and `--channel nightly`) and never fall back to stable. The commands are documentation only while their channel metadata is unavailable. `site/public/install.sh` is a byte-for-byte mirror of the canonical `aos-ce` installer. Pages CI records the exact source commit in `AOS_INSTALLER_SOURCE_COMMIT` and compares both source and built copies. Update that commit and the mirror together only after the canonical installer contract has landed. Community Edition source lives in [unicity-aos/aos-ce](https://github.com/unicity-aos/aos-ce). --- ## File: site/src/content/developers/architecture.md --- title: Product and runtime architecture part: Orientation order: 20 --- Unicity AOS is the agent operating system people install. Astrid is the secure engine included inside it, and capsules are the isolated abilities that turn the engine into a useful agent. The layers keep product behavior replaceable without weakening the part that enforces permissions. ## The stack | Layer | Role | Examples | | --- | --- | --- | | Product | Unicity AOS | `aos`, installers, editions, updates, customer HTTP edge, host integrations | | Distribution | AOS CE or Enterprise | `Distro.toml`, selected capsules, defaults, onboarding, product policy | | Components | AOS capsule workspace | model providers, ReAct loop, memory, tools, uplinks | | Engine | Astrid Runtime | kernel, daemon, sandbox, IPC, capability store, generic gateway | | Contracts | Astrid Runtime project | `astrid:*` WIT packages, SDKs, capsule artifact format | The kernel deliberately contains no agent loop, model choice, memory strategy, or product workflow. It routes typed events, checks capabilities, runs WebAssembly components, meters resources, and maintains runtime records. Intelligence lives in capsules. ## How a turn moves 1. An uplink publishes a user prompt on the event bus. 2. The coordinator loads the session and asks the prompt builder for context. 3. Hook capsules contribute identity, project rules, memory, and other context. 4. A provider capsule calls the selected model. 5. Tool calls pass through the router and capability checks. 6. Results return over typed topics and the uplink renders the response. Every step crosses an explicit contract. Capsules do not call one another by linking Rust libraries together, and a prompt cannot grant a host capability. ## Decide where a change belongs Put a change in AOS when it defines the product composition, customer behavior, edition policy, a first-party capsule, an integration, or a product API. Put it in Astrid Runtime when every distribution needs the same generic primitive: a WIT contract, sandbox rule, capability type, scheduler behavior, or daemon API. If an AOS capsule needs a missing host function, design the smallest generic contract upstream. Release the WIT and SDK change, then consume that release in AOS. Do not fork the engine or add an AOS-only escape hatch to the kernel. ## Compatibility is part of the architecture Crate names, `astrid:*` WIT namespaces, `@unicity-astrid` package identities, ABI names, signed artifacts, and release URLs are versioned compatibility surfaces. AOS can change its product composition without rewriting the contracts existing capsules were built against. --- ## File: site/src/content/developers/build-package.md --- title: Build and package part: Ship and release order: 70 --- There are two different build outputs. A raw WebAssembly file proves the Rust component compiles. An installable `.capsule` bundles the component, manifest, metadata, and verification material expected by the runtime. ## Compile the component Run from the capsule directory so `.cargo/config.toml` selects `wasm32-unknown-unknown` and the repository's `getrandom` backend configuration. ```sh cargo build --release ``` Do not install the `.wasm` directly and do not rename it by hand to `.capsule`. That skips component packaging and verification. ## Build the artifact Use the released Astrid build tooling through the product's pinned development environment: ```sh aos capsule build ``` The supported build produces an artifact under `dist/`. The exact filename is derived from the package identity and version; automation should discover it from the build output or a manifest, not guess it. Before release, verify: - every `[[component]].file` exists in the package; - the component imports only declared WIT contracts; - manifest and component versions agree; - the runtime compatibility range covers the pinned AOS runtime; - no source maps, local paths, secrets, or test fixtures leaked into the bundle; - a clean checkout produces the same content digest. ## Reproducibility Use the committed `Cargo.lock`, pinned toolchain, released SDK, and a clean working tree. Do not package with an unpublished path dependency. ```sh cargo build --locked --release git diff --exit-code ``` Record the source commit, toolchain, artifact digest, and dependency lock in the release attestation. Signing identifies what was published; reproducibility lets another developer prove how it was produced. ## Smoke installation Create a temporary product home, install the artifact through the normal runtime surface, invoke one success path, and exercise at least one denied capability. Do not reuse a developer's live `~/.aos` in CI. The product release should stage every capsule artifact first, verify all digests, then compose the distro lock. Never resolve Community Edition from mutable repository branches during end-user installation. --- ## File: site/src/content/developers/capsule-anatomy.md --- title: Capsule anatomy part: Build capsules order: 35 --- A capsule is an installable WebAssembly component plus a declarative manifest. It is not a daemon plugin and it is not a Rust library loaded into the kernel. The runtime instantiates it inside a sandbox and exposes only the WIT imports and capabilities approved at installation. ## Create the package First-party capsules live at `capsules/capsule-` in the AOS CE workspace. A minimal layout is: ```text capsules/capsule-greeter/ ├── .cargo/config.toml ├── Cargo.toml ├── Capsule.toml ├── README.md └── src/lib.rs ``` Use the workspace SDK and compile as a `cdylib`. ```toml [package] name = "astrid-capsule-greeter" version = "0.1.0" edition = "2024" license = "MIT OR Apache-2.0" [lib] crate-type = ["cdylib"] [dependencies] astrid-sdk = { workspace = true } serde = { workspace = true, features = ["derive"] } serde_json = { workspace = true } ``` The published package name can retain the `astrid-capsule-*` compatibility identity while its description and documentation correctly place it in AOS. The checked-in target configuration makes a plain capsule build produce the component input expected by the packaging tool: ```toml [build] target = "wasm32-unknown-unknown" [target.wasm32-unknown-unknown] rustflags = ["--cfg=getrandom_backend=\"custom\""] ``` That custom random backend routes entropy through the audited `astrid:sys` host import. Do not switch the capsule to WASI to make an undeclared host call work. ## Implement one handler The SDK macros generate the component export surface. Keep the handler small and move deterministic logic into ordinary Rust functions that host tests can call. ```rust #![deny(unsafe_code)] use astrid_sdk::prelude::*; #[derive(Default)] pub struct Greeter; #[capsule] impl Greeter { #[astrid::interceptor("handle_greet")] pub fn handle_greet(&self, payload: serde_json::Value) -> Result<(), SysError> { let name = payload.get("name").and_then(serde_json::Value::as_str).unwrap_or("agent"); ipc::publish_json( "greeter.v1.response.greet", &serde_json::json!({ "message": format!("Hello, {name}") }), ) } } ``` Never trust a caller identity supplied inside `payload`. The runtime-stamped envelope is the authority for the current invocation. Validate size, required fields, enum values, and paths before touching a host import. ## Declare the same contract `Capsule.toml` is the runtime's installation boundary. The subscribe handler must match the exported macro name, and every response topic must be allowed by `[publish]`. ```toml [package] name = "astrid-capsule-greeter" version = "0.1.0" description = "Greeting example for Unicity AOS" astrid-version = ">=0.9.4" [[component]] id = "greeter" file = "astrid_capsule_greeter.wasm" type = "executable" [subscribe] "greeter.v1.request.greet" = { wit = "@example/greeter/greet-request", handler = "handle_greet" } [publish] "greeter.v1.response.greet" = { wit = "@example/greeter/greet-response" } ``` Only one trailing wildcard is accepted for normal subtree subscriptions. Prefer concrete publish topics when the capsule can enumerate them. A handler return value is not a bus response; publish the response explicitly. ## First validation loop ```sh cd capsules/capsule-greeter cargo fmt -- --check cargo build cd ../.. cargo test --locked -p astrid-capsule-greeter ``` Plain `cargo build` verifies the WebAssembly compilation configured by the capsule. Run host tests from the workspace root so the member's WebAssembly target configuration does not try to execute a browserless `.wasm` test binary. The build does not produce an installable `.capsule`; packaging is a separate step covered in [Build and package](/developers/build-package/). --- ## File: site/src/content/developers/capsules.md --- title: Compose capsules into AOS part: Build capsules order: 30 --- A capsule is one isolated ability in AOS. Community Edition selects a tested set of capsules and grants each one the capabilities it needs. The Astrid SDK, WIT contracts, sandbox, and artifact format provide the common runtime surface. ## Add the workspace member Create `capsules/capsule-` and add it to root `workspace.members`. Reuse root dependency versions wherever possible. Every capsule has its own `Cargo.toml`, `Capsule.toml`, source, tests, and README, while the workspace has one committed dependency lock. ```sh cargo check --locked --workspace ``` Finish the component itself using the chapters on [capsule anatomy](/developers/capsule-anatomy/), [manifest authority](/developers/manifest/), and [IPC contracts](/developers/ipc/). ## Add the distro entry Community Edition composition lives in `distros/community/unicity-ce/Distro.toml`. The first product release packages verified `.capsule` artifacts beside the distro under `capsules/`; pin the artifact version and reference that release-local path. ```toml [[capsule]] name = "astrid-capsule-example" source = "capsules/astrid-capsule-example.capsule" version = "0.1.0" ``` Add `role = "uplink"` for a frontend. Use a named `group` for mutually selected providers. Supply product defaults through `env` placeholders rather than hard-coding credentials in the capsule. ```toml [variables] example_endpoint = { description = "Example service base URL", default = "https://example.invalid" } [[capsule]] name = "astrid-capsule-example" source = "capsules/astrid-capsule-example.capsule" version = "0.1.0" env = { endpoint = "{{ example_endpoint }}" } ``` The public capsule registry is not live yet. Do not put a registry namespace in the CE manifest until that namespace resolves to signed, immutable artifacts. ## Validate the composition The distro is a graph. Installing a capsule is insufficient if its subscribed topics have no publisher, its WIT requirements are unsatisfied, or its provider group has no selected member. Check: - package version matches the built artifact; - all required WIT packages fall within distro compatibility; - publish and subscribe topics have intended peers; - requested host capabilities are explainable during onboarding; - environment variables resolve without exposing secrets; - clean initialization installs the complete CE set; - removing the capsule leaves the remaining distro coherent. ## Keep runtime contracts generic Add product behavior through capsules and distro policy. If the change needs a generic WIT contract, SDK capability, kernel operation, or sandbox behavior, design it upstream in Astrid Runtime and consume a released version. Published crate names, `astrid:*` namespaces, `@unicity-astrid` WIT identities, and signed artifact names remain compatibility contracts. Product prose and descriptions say AOS; identifiers change only through a deliberate compatible protocol migration. --- ## File: site/src/content/developers/ci.md --- title: Continuous integration part: Ship and release order: 80 --- CI should fail at the earliest useful boundary and still prove the final artifact. Separate fast workspace feedback from packaging and end-to-end release jobs. ## Pull-request gates Run for every Rust change: ```sh cargo fmt --all -- --check cargo check --locked --workspace cargo test --locked --workspace cargo clippy --locked --workspace --all-targets --all-features -- -D warnings ``` Also build each capsule with its checked-in target configuration. A host-only workspace pass does not prove the WebAssembly component compiles. ## Contract gates When SDK or WIT inputs change: - verify generated WIT mirrors are current; - build every consuming capsule; - compare the public API and WIT contract surface; - reject an unversioned incompatible change; - test both the oldest and newest supported runtime where the range spans them. ## Artifact gates For each release candidate: 1. build from a clean checkout with `--locked`; 2. produce the `.capsule`, not only raw `.wasm`; 3. inspect the package manifest; 4. calculate and record its digest; 5. install into an isolated AOS home; 6. execute success and denial smoke tests; 7. upload only after every capsule passes. Run matrix jobs for Linux and macOS when host tooling differs. Do not claim Windows support from a Rust cross-compile alone; the product needs state paths, IPC, services, installer, and end-to-end tests on Windows. ## Product-site gates The website is part of the release contract. It must pass both: ```sh npm run check npm run build ``` Validate that installer metadata names the same AOS version as release assets, that the command downloads the product rather than a standalone runtime, and that the developer-guide index contains working `/developers/...` URLs. ## Secrets and logs Use least-privilege workflow tokens, pin third-party actions to reviewed revisions according to repository policy, and never echo signing material. Keep release jobs protected from untrusted fork code. --- ## File: site/src/content/developers/cli.md --- title: Product CLI part: Operate AOS order: 100 --- `aos` is the product command. It owns the product home, Community Edition composition, health projection, version identity, and update policy. Lower-level operator commands use the Astrid engine bundled in the same AOS release, so the complete runtime command set remains available through one CLI. ## Product-owned commands | Command | Behavior | | --- | --- | | `aos --help` | product help and delegation boundary | | `aos --version` | AOS calendar-SemVer version, such as `2026.1.1` | | `aos status [--json]` | read typed local runtime status without invoking the runtime CLI | | `aos serve-health` | bind the narrow loopback health endpoint | | `aos update` | update the AOS product and bundled runtime together from a signed channel or exact version | `aos self-update` remains an alias for `aos update`. `aos distro` is also product-owned and refuses replacement of the Unicity CE composition. The public installer applies the embedded Community Edition composition and wires the selected host plugins. There is no separate activation step. A developer who deliberately wants another distribution uses standalone Astrid Runtime outside the product installation. ## Delegated commands Every other command is executed by `~/.aos/runtime/bin/astrid` with `ASTRID_HOME=~/.aos/runtime` and the product workspace state directory set only in the child process. This includes runtime/operator surfaces such as daemon operation, capsule inspection, diagnostics, and agent execution. The product-owned `aos status` remains the supported local status projection; it is not delegated to the runtime command of the same name. ```sh aos doctor aos start aos logs aos capsule list aos run ``` The exact delegated command set is the command set of the Astrid Runtime version pinned into that AOS release. `aos` does not copy the implementation and should not maintain a second parser for every runtime flag. ## Product home override Use `AOS_HOME` to isolate a development or CI installation: ```sh export AOS_HOME=/absolute/path/to/aos-home aos status ``` Do not export `ASTRID_HOME` globally as an AOS setup step. The wrapper owns that child-process setting, which prevents product state from colliding with a standalone runtime. ## Exit codes and automation Product commands return zero on success and nonzero on validation, health-service, update, or child-runtime failure. Automation should consume the exit code and structured HTTP contracts rather than matching human help text. `aos serve-health` binds only `127.0.0.1:8765`. It is a long-running service, not a one-shot health check; probe it with `GET /v1/runtime/health`. --- ## File: site/src/content/developers/get-started.md --- title: Get started with AOS CE part: Orientation order: 10 --- Unicity AOS Community Edition is the public product distribution. Its command is `aos`; its product home is `~/.aos`; its private bundled runtime lives at `~/.aos/runtime`. ## Install AOS Stable is the installer default. Development and nightly are always explicit: ```sh # Stable curl -fsSL https://aos.unicity.ai/install.sh | sh # Explicit prerelease channels curl -fsSL https://aos.unicity.ai/install.sh | sh -s -- --channel dev curl -fsSL https://aos.unicity.ai/install.sh | sh -s -- --channel nightly ``` An unavailable channel must stop without installing or falling back to another channel. ```sh git clone https://github.com/unicity-aos/aos-ce.git cd aos-ce cargo check --locked --workspace cargo test --locked -p unicity-aos-bootstrap ``` Do not use `cargo install astrid` as an AOS installation. That installs a standalone runtime CLI and does not provide the AOS product wrapper, embedded Community Edition manifest, product home, or coordinated update policy. ## Product release layout The signed release archive contains: ```text bin/aos runtime/bin/astrid runtime/bin/astrid-daemon runtime/bin/astrid-build runtime/bin/astrid-emit Distro.toml capsule-assets.txt capsules/*.capsule ``` The installer selects a platform archive named `unicity-aos-.tar.gz`, verifies the signed release identity and archive, and installs the product, pinned runtime, and Community Edition capsule set together. Verification passes the archive itself to `cosign verify-blob`, binding the downloaded bytes to the AOS release workflow identity and immutable calendar version tag before extraction. The release publishes `BLAKE3SUMS.txt` as its primary digest inventory and `SHA256SUMS.txt` for compatibility with external tooling such as Homebrew. The archive's schema-2 `release-manifest.json` records the Astrid Runtime input as `runtime.digest = "blake3:<64 lowercase hex>"`. The installer does not substitute a detached checksum comparison for direct Sigstore archive verification. ## Start a host plugin No manual post-install activation command is required for Claude Code, Codex, or Grok Build. Start a selected host after installation. Its plugin provisions only that host's named principal and Oracle pack. The release also publishes the Homebrew formula: ```sh brew install unicity-aos/tap/aos ``` The tap repository and formula automation can exist before the formula itself. The command works only after the stable release publishes and verifies it. The installer applies the Unicity CE manifest from the same signed product release. It does not fetch a mutable manifest from `main`. The wrapper keeps the product runtime home separate from standalone Astrid state. ## Verify the installation ```sh aos --version aos status aos doctor aos capsule list ``` If the health service is enabled: ```sh curl --fail http://127.0.0.1:8765/v1/runtime/health ``` A ready response proves the local product runtime is reachable. It does not prove that every provider credential, external service, or optional capsule is ready; use delegated runtime readiness and product diagnostics for those. ## A clean product home AOS creates `~/.aos` and provisions Community Edition from scratch. It does not import, rename, rewrite, or delete a standalone `~/.astrid` installation. The two homes can coexist, which makes a first AOS install safe to evaluate and remove without changing an existing Astrid setup. --- ## File: site/src/content/developers/http.md --- title: HTTP API status and conventions part: HTTP API order: 130 --- Unicity AOS exposes a narrow local health service and a broader authenticated product gateway. The health service answers one readiness question; the gateway provides the customer and integration API documented in the remaining chapters. ## Implementation status | Surface | Status | Ownership | | --- | --- | --- | | `GET /v1/runtime/health` on `127.0.0.1:8765` | implemented in AOS CE | AOS product health projection | | `/api/*`, `/healthz`, and `/metrics` gateway | release-coupled AOS API | product gateway | | `GET /api/openapi.json` | generated by the gateway implementation | authoritative only for the running release that serves it | The remaining chapters map the complete gateway surface. The running release's generated OpenAPI document remains authoritative when website copy and a deployed version differ. ## Product health ```http GET /v1/runtime/health HTTP/1.1 Host: 127.0.0.1:8765 ``` The loopback service returns `200 {"ready":true}` when the bundled runtime is ready and `503 {"ready":false}` otherwise. It accepts no query parameters, no implicit `HEAD`, no CORS, and no caller-selected principal, socket, or IPC topic. It does not expose diagnostics, keys, audit records, or arbitrary bus access. ## Gateway base and discovery Examples use `http://127.0.0.1:2787`. Operators may bind the product gateway elsewhere, but public exposure requires TLS, reverse-proxy policy, and an explicit CORS allowlist. ```sh curl --fail http://127.0.0.1:2787/api/openapi.json ``` Unauthenticated routes are limited to discovery, onboarding, redemption, and operations probes: | Method | Path | Purpose | | --- | --- | --- | | `GET` | `/api/distribution` | distribution identity and metadata | | `GET` | `/api/distribution/onboarding` | fields required by onboarding | | `POST` | `/api/auth/redeem` | exchange a one-time invite for a session | | `POST` | `/api/auth/pair-device/redeem` | redeem a device-pairing code | | `GET` | `/healthz` | process liveness for operators | | `GET` | `/metrics` | Prometheus metrics; restrict by network policy | | `GET` | `/api/openapi.json` | generated contract for this running build | All other routes require `Authorization: Bearer `. ## Wire conventions - JSON requests send `Content-Type: application/json`. - Ordinary responses are JSON unless the OpenAPI content type says otherwise. - Streaming routes use Server-Sent Events and reconnect semantics documented in [Agent and event streams](/developers/http-streams/). - Unknown fields, invalid identifiers, and out-of-range pagination values are client errors; clients must not rely on silent coercion. - Error bodies and status codes in the deployed OpenAPI document are authoritative for that release. - CORS is off by default. An empty origin allowlist emits no CORS headers. - Security headers apply to public, authenticated, preflight, and error responses. ## Client rule Generate clients from the OpenAPI document shipped by the same AOS release you deploy. Do not copy schemas from `main`, and do not assume a route documented here exists until the running product release advertises it. --- ## File: site/src/content/developers/http-admin.md --- title: Administration API part: HTTP API order: 145 --- Administration routes require a bearer session and then apply capability checks for the requested operation. Authentication alone does not make a caller an administrator. ## Principals | Method | Path | Purpose | | --- | --- | --- | | `GET` | `/api/sys/principals` | list principal summaries | | `POST` | `/api/sys/principals` | create a principal from `CreatePrincipalRequest` | | `GET` | `/api/sys/principals/{id}` | read one principal | | `PATCH` | `/api/sys/principals/{id}` | apply `ModifyPrincipalRequest` | | `DELETE` | `/api/sys/principals/{id}` | delete a principal according to runtime policy | | `POST` | `/api/sys/principals/{id}/enable` | enable execution | | `POST` | `/api/sys/principals/{id}/disable` | disable execution | IDs are path parameters validated by the server. A disabled principal remains an identity and can retain records; clients should not present disable as delete. ## Capabilities and quotas | Method | Path | Body or response | | --- | --- | --- | | `POST` | `/api/sys/principals/{id}/caps` | `GrantRequest` | | `DELETE` | `/api/sys/principals/{id}/caps` | `RevokeRequest` | | `GET` | `/api/sys/principals/{id}/quotas` | current limits | | `PUT` | `/api/sys/principals/{id}/quotas` | replace supported quota values | | `GET` | `/api/sys/principals/{id}/usage` | current metered usage | | `GET` | `/api/sys/capabilities` | `CapabilityCatalogResponse` | Capability grants narrow authority; they do not alter capsule code. Build administrative UIs from the capability catalog instead of hard-coding labels. Quota and usage are different: setting a limit does not reset consumed usage. ## Groups and invites | Method | Path | Purpose | | --- | --- | --- | | `GET` | `/api/sys/groups` | `GroupListResponse` | | `POST` | `/api/sys/groups` | create with `CreateGroupRequest` | | `PATCH` | `/api/sys/groups/{name}` | modify with `ModifyGroupRequest` | | `DELETE` | `/api/sys/groups/{name}` | delete a group | | `GET` | `/api/sys/invites` | list invite summaries | | `POST` | `/api/sys/invites` | issue from `IssueRequest` | | `DELETE` | `/api/sys/invites/{fingerprint}` | revoke an unused invite | Invite list responses expose fingerprints and safe metadata, not reusable secret material. Show a newly issued code once, then store only what the schema permits. ## Capsules and environment | Method | Path | Purpose | | --- | --- | --- | | `GET` | `/api/capsules` | installed capsule summaries | | `POST` | `/api/capsules` | install from `InstallRequest` | | `GET` | `/api/capsules/{id}` | `CapsuleDetail` | | `GET` | `/api/capsules/{id}/topics` | declared publish and subscribe topics | | `GET` | `/api/capsules/{id}/env` | typed `EnvSchemaResponse` | | `POST` | `/api/capsules/{id}/env/{field}` | write one field with `EnvWriteRequest` | Install accepts only sources allowed by product policy and verification. Do not build a UI that turns an arbitrary URL into a trusted capsule. Environment schemas mark request text, types, defaults, and secret handling; never echo a secret value after writing it. ## Models and runtime | Method | Path | Purpose | | --- | --- | --- | | `GET` | `/api/models` | list models discovered through the active provider registry | | `GET` | `/api/models/active` | current model selection | | `PUT` | `/api/models/active` | select with `SetActiveModelRequest` | | `GET` | `/api/sys/status` | runtime status summary | | `GET` | `/api/sys/readiness` | readiness and dependency checks | | `POST` | `/api/sys/capsules/reload` | reload the install-time capsule set | Model selection is a product operation delegated to capsules; the kernel does not contain model policy. A reload is an administrative mutation and should be followed by readiness checks before traffic resumes. ## Operations probes `GET /healthz` and `GET /metrics` are public to support load balancers and Prometheus. “Public” means no bearer middleware, not safe for the open internet. Restrict them with the reverse proxy or firewall. The separate AOS `/v1/runtime/health` loopback projection remains intentionally narrower.