# State Hub Onboarding

This guide turns a new machine into a usable State Hub operator or collaborator
environment. It covers local credentials, SSH reachability, Gitea access, and
Claude Code MCP registration.

State Hub remains a coordination read/cache layer. Repo permissions, SSH
access, and controlled tunnels are the first access boundary. OpenBao is the
runtime secret authority for platform and workload secrets once its bootstrap
ceremony is complete.

## Quick Start

Clone the repo, then run the bootstrap script:

```bash
git clone https://forgejo.coulomb.social/coulomb/state-hub.git ~/state-hub
cd ~/state-hub
make bootstrap-env
```

The bootstrap enables `sandbox_workspace_write.network_access` in the
operator's Codex `config.toml`, removes any default `dev-hub` Codex MCP
registration, then checks whether a Codex sandbox can reach
`http://127.0.0.1:8000/state/health`. Use `--skip-codex` to omit this step, or
run it independently:

```bash
make configure-codex
```

If verification still reports isolated networking, a managed Codex permission
profile is overriding user configuration. Retry State Hub REST/CLI commands with
escalated execution or change that managed profile; do not infer that the API is
down until the same health check has been run outside the sandbox.

The slim six-tool Codex MCP server remains available for explicit testing, but
is not recommended while the Codex MCP bridge adds substantial call latency:

```bash
make configure-codex WITH_MCP=1
```

On a clean Ubuntu 24.04 machine, allow package installation explicitly:

```bash
make bootstrap-env ARGS="--install-missing"
```

For a remote machine that reaches State Hub through ops-bridge:

```bash
make bridges
make register-mcp MCP_URL=http://127.0.0.1:18001/sse API_BASE=http://127.0.0.1:18000
```

Restart Claude Code after MCP registration.

## Primary Operator: New Machine

1. Install minimal host prerequisites:

   ```bash
   sudo apt-get update
   sudo apt-get install -y git curl openssh-client make python3
   ```

2. Clone `state-hub` and any domain repo you expect to operate:

   ```bash
   git clone https://forgejo.coulomb.social/coulomb/state-hub.git ~/state-hub
   git clone https://forgejo.coulomb.social/coulomb/the-custodian.git ~/the-custodian
   ```

3. Run the bootstrap:

   ```bash
   cd ~/state-hub
   make bootstrap-env ARGS="--install-missing"
   ```

   The script will:

   - check required tools
   - configure `git credential.helper`
   - create `~/.ssh/id_ed25519` when missing
   - print the public key for managed hosts
   - create `~/.railiance_gitea.conf` when you provide a Gitea token
   - register the State Hub MCP server for Claude Code
   - check State Hub API reachability

4. Authorize the SSH key on managed hosts. If password or existing key access
   is available, rerun:

   ```bash
   make bootstrap-env ARGS="--authorize-ssh --skip-gitea --skip-mcp"
   ```

   Default targets:

   - `tegwick@92.205.62.239` for Railiance01
   - `tegwick@92.205.130.254` for CoulombCore

5. Connect to State Hub:

   Primary operators reach the cluster deployment on port `8000` through
   ops-bridge (`state-hub-primary`). Verify before starting a local API:

   ```bash
   curl -fsS http://127.0.0.1:8000/state/health || make api
   make mcp-http
   ```

   Remote machines use the tunnel mesh:

   ```bash
   make bridges
   ```

   Operating model: [`docs/cluster-operating-model.md`](cluster-operating-model.md)

6. Restart Claude Code and verify that `state-hub` appears in the MCP server
   list. In the first session, call `get_state_summary()` when MCP tools are
   available. If not, use:

   ```bash
   cat .custodian-brief.md
   curl -s "http://127.0.0.1:8000/workplans/?status=active" | python3 -m json.tool
   ```

## Domain Collaborator: New Person

1. Get a Gitea account with write access to the relevant domain repo.
2. Clone this repo and the domain repo:

   ```bash
   git clone https://forgejo.coulomb.social/coulomb/state-hub.git ~/state-hub
   git clone https://forgejo.coulomb.social/coulomb/<domain-repo>.git ~/<domain-repo>
   ```

3. Run the bootstrap:

   ```bash
   cd ~/state-hub
   make bootstrap-env
   ```

4. Send the printed SSH public key to the operator, or authorize it yourself if
   you already have host access:

   ```bash
   ssh-copy-id -i ~/.ssh/id_ed25519.pub tegwick@92.205.62.239
   ```

5. Bring up the State Hub tunnel when direct local access is unavailable:

   ```bash
   make bridges
   make register-mcp MCP_URL=http://127.0.0.1:18001/sse API_BASE=http://127.0.0.1:18000
   ```

6. Restart Claude Code, open the domain repo, and orient from the repo brief:

   ```bash
   cat .custodian-brief.md
   ```

7. Contribute work through repo-backed workplans. A new workplan lives under
   `workplans/` and follows ADR-001. The hub indexes files; the files remain
   authoritative.

## Credential Helper Choices

`make bootstrap-env` configures Git credentials only when no global helper is
already set.

Default behavior:

- use `libsecret` when the helper exists
- otherwise use `credential.helper=cache --timeout=3600`

For headless hosts where a persistent plaintext helper is acceptable:

```bash
make bootstrap-env ARGS="--git-helper store --allow-plaintext-store"
```

Prefer SSH remotes or a keyring-backed helper for normal operator machines.

## Gitea Token File

Some Railiance scripts read `~/.railiance_gitea.conf`:

```bash
GITEA_URL="http://92.205.130.254:32166"
GITEA_USER="<user>"
GITEA_TOKEN="<token>"
```

Required token capabilities depend on the action:

- repo creation needs `read:user` and repository write/admin scope
- package publishing needs package write scope
- inventory reads need repository read scope

The bootstrap script writes this file with mode `0600` and does not print the
token.

## MCP Registration

Local registration:

```bash
make register-mcp
```

Tunnel registration:

```bash
make register-mcp MCP_URL=http://127.0.0.1:18001/sse API_BASE=http://127.0.0.1:18000
```

The current State Hub MCP transport is SSE. The old `.mcp.json`/stdio flow is
legacy; use `make mcp-http` to run the SSE service on `127.0.0.1:8001`.

## Verification Checklist

Run these checks after bootstrap:

```bash
git config --global --get credential.helper
test -f ~/.ssh/id_ed25519.pub
test -f ~/.railiance_gitea.conf
curl -fsS http://127.0.0.1:8000/state/health || curl -fsS http://127.0.0.1:18000/state/health
make register-mcp DRY_RUN=1
```

Then restart Claude Code and confirm that the `state-hub` MCP server is
available.
