# Namespace and Paths

Orca stores all on-disk state under a single **namespace root**
directory. The v0.9 re-architecture introduced a multi-namespace
layout (R-002) where each namespace is a self-contained directory tree
with its own database, jobs, allocs, env, and secrets. A `cluster/`
directory holds cluster-wide artifacts shared across namespaces.

> **v0.9 layout (canonical)**: This document describes the v0.9
> multi-namespace layout. The v0.8 flat layout (`orca.db`, `ca.crt`,
> `server.crt` at the root) is deprecated and removed in v0.12
> (REQ-138).

## Namespace root resolution

The namespace root is resolved in this order:

1. If `--system` flag is passed → root is `/root/.orca` (errors if
   `ORCA_HOME` is set to a conflicting value).
2. Else if `ORCA_HOME` is set → root is `$ORCA_HOME`.
3. Else → root is `~/.orca` (`$HOME/.orca`).

### `ORCA_HOME` (REQ-041)

Set the `ORCA_HOME` environment variable to change the namespace root
for all orca components:

```bash
export ORCA_HOME=/var/lib/orca
orca init          # creates /var/lib/orca/
orca ns create prod
```

### `--system` (REQ-042)

The `--system` persistent flag selects the system-level namespace root
`/root/.orca`:

```bash
sudo orca --system init          # creates /root/.orca/
sudo orca --system ns list
```

If `ORCA_HOME` is already set to a different value, `--system` returns
an error (to avoid silent namespace mismatches).

## v0.9 multi-namespace layout (R-002)

```
$ORCA_HOME/
├── cluster/                  # cluster-wide (NOT a workload namespace)
│   ├── ca.crt, ca.key        # step-ca root (R-006, D-101)
│   ├── master.key            # AES-256-GCM root (R-011, mode 0600)
│   ├── master.key.sealed     # sealed master key (REQ-147, mode 0600)
│   ├── config.md             # Markdown frontmatter config (R-014)
│   ├── known_hosts           # SSH known_hosts (D-035)
│   ├── orca_ssh_key          # orca SSH private key (D-037)
│   ├── orca_ssh_key.pub      # orca SSH public key
│   ├── peers/<host>/         # per-peer directory
│   ├── txns/                 # cluster transaction log (R-016)
│   ├── acl.json              # ACL state (mode 0600)
│   ├── oidc-client-secret    # OIDC client secret (mode 0600, C-36)
│   ├── webauthn-credentials.db # WebAuthn public keys (mode 0600)
│   └── state/                # cluster state
├── _defaults/                # implicit root namespace (always exists)
│   ├── ns.md                 # namespace frontmatter (kind: Namespace)
│   ├── .env                  # per-namespace env
│   ├── .env.secrets          # encrypted secrets
│   ├── db/orca.db            # per-namespace SQLite database
│   ├── jobs/                 # submitted jobspecs
│   └── alloc/                # allocation state
├── <explicit-namespace>/     # operator-created (e.g., prod, staging)
│   ├── ns.md
│   ├── .env, .env.secrets
│   ├── db/orca.db
│   ├── jobs/, alloc/
│   └── syncthing/            # Syncthing config (if replicated volumes)
└── orca_cache.db             # CLI-side cache (R-008)
```

### Key points

- **`_defaults/`** is the implicit root namespace (D-159). It always
  exists. Every namespace inherits from `_defaults` and cannot opt out
  (D-185, D-187).
- **`cluster/`** is NOT a workload namespace — it holds cluster-wide
  artifacts (CA, master key, SSH keys, known_hosts, peers, txns, ACL,
  OIDC secrets, WebAuthn credentials).
- **Per-namespace DBs**: each namespace has its own
  `db/orca.db` (R-002). No namespace column in SQLite.
- **Namespace inheritance**: child namespaces inherit env and
  constraints from parents (via `ns.md` frontmatter `parents:` field).
  `_defaults` is always appended last in the inheritance chain.
- **`orca ns` subcommands**: `list`, `create`, `delete`, `inspect`,
  `validate`, `inherit`, `set-constraint` — see below and
  [docs/cli.md](cli.md#orca-ns).

### Path reference (`internal/paths/`)

| Function | Path | Contents |
|----------|------|----------|
| `Root()` | `$ORCA_HOME` | Namespace root |
| `ClusterDir()` | `Root()/cluster` | Cluster-wide artifacts |
| `NamespaceDir(ns)` | `Root()/ns` | Per-namespace directory |
| `NSDb(ns)` | `Root()/ns/db/orca.db` | Per-namespace SQLite DB |
| `NSEnv(ns)` | `Root()/ns/.env` | Per-namespace env |
| `NSSecrets(ns)` | `Root()/ns/.env.secrets` | Encrypted secrets |
| `NSJobs(ns)` | `Root()/ns/jobs` | Jobs dir |
| `NSAlloc(ns)` | `Root()/ns/alloc` | Alloc dir |
| `NSMd(ns)` | `Root()/ns/ns.md` | Namespace frontmatter |
| `DefaultNamespace()` | `_defaults` | Implicit root (D-159) |
| `CACertPath()` | `ClusterDir()/ca.crt` | step-ca root (D-101) |
| `MasterKeyPath()` | `ClusterDir()/master.key` | AES-256-GCM root key |
| `KnownHostsPath()` | `ClusterDir()/known_hosts` | SSH known_hosts |
| `SSHKeyPath()` | `ClusterDir()/orca_ssh_key` | orca SSH private key |
| `ConfigPath()` | `ClusterDir()/config.md` | Markdown config (R-014) |
| `CacheDB()` | `Root()/orca_cache.db` | CLI-side cache (R-008) |
| `PeersDir()` | `ClusterDir()/peers` | Peers directory |
| `TxnDir()` | `ClusterDir()/txns` | Transaction log (R-016) |

## Creating and managing namespaces

```bash
# List all namespaces
orca ns list

# Create a namespace (inherits from _defaults)
orca ns create prod

# Create a namespace with an explicit parent
orca ns create staging --parent prod

# Inspect the effective inheritance chain + merged env
orca ns inspect prod

# Validate a namespace's inheritance chain
orca ns validate prod

# Delete an empty namespace (refuses if jobs/ or alloc/ non-empty)
orca ns delete staging
```

### `orca ns inherit` — set parent namespace (R-002)

Set the parent namespace for a namespace. Updates `ns.md` frontmatter
(`parents` field) and validates the new chain has no cycles. The
implicit root `_defaults` is always appended last (D-185).

```bash
orca ns inherit <name> --parent <parent-namespace>
```

**Example**:
```bash
# Make staging inherit from prod (chain: staging -> prod -> _defaults)
orca ns inherit staging --parent prod
```

The child cannot inherit from itself transitively — the resolver
validates the chain before writing. If a cycle is detected, the
command exits 1 with an error.

### `orca ns set-constraint` — set a constraint (R-002)

Set a constraint on a namespace. Constraints are `key=value` strings
(e.g., `max-allocs=10`) stored in `ns.md` frontmatter and unioned
across the inheritance chain by the resolver.

```bash
orca ns set-constraint <name> <key>=<value>
```

**Example**:
```bash
# Limit prod to 10 concurrent allocations
orca ns set-constraint prod max-allocs=10

# Set a required node affinity
orca ns set-constraint prod require-label=ssd
```

Constraints are unioned (not overridden) across the inheritance chain:
if `_defaults` sets `max-allocs=50` and `prod` sets `max-allocs=10`,
the effective constraint is the most restrictive one (CEL evaluation
determines precedence per constraint key).

See [docs/cli.md](cli.md#orca-ns) for the full `orca ns` reference.

## `ORCA_DB` override

For finer-grained control, `ORCA_DB` overrides only the database path
(not the cert/namespace paths). This is primarily a testing affordance.

```bash
export ORCA_DB=/tmp/test.db
orca init   # uses /tmp/test.db for the DB, ~/.orca/ for everything else
```

## Deprecated: v0.8 flat layout

> **Removed in v0.12** (REQ-138): The v0.8 flat layout (`orca.db`,
> `ca.crt`, `ca.key`, `server.crt`, `server.key` at the namespace root)
> is superseded by the v0.9 multi-namespace layout (R-002) and the
> dual-write window is closed.

The v0.8 flat layout stored all state at the namespace root:

| Path | Contents |
|------|----------|
| `~/.orca/orca.db` | SQLite database |
| `~/.orca/ca.crt` | CA certificate |
| `~/.orca/ca.key` | CA private key |
| `~/.orca/server.crt` | Server certificate |
| `~/.orca/server.key` | Server private key |

The v0.9 re-architecture moved these to `cluster/` (CA, SSH keys) and
per-namespace `db/` (SQLite) to support multi-tenancy (R-002). The
`internal/certpaths` shim that supported the dual-write window is
removed in v0.12.

## See also

- [Install Guide](install.md) — 1-liner install with `install.sh`.
- [Docker Guide](docker.md) — running orca in a container.
- [CLI Reference](cli.md#orca-ns) — `orca ns` subcommands.
- [Jobspec Reference](jobspec.md) — markdown frontmatter schema.
