# Docs: Self-Host Guide

Self-hosting begins when evaluation shifts into deployment, environment design, and operational ownership. The public core repo stays public; live deployment work moves into a private instance repo that pins tagged core release artifacts and carries the repo-local bootstrap for one installation.

## Summary

- Production ownership: Humans control the runtime environment, secrets, and rollout timing.
- Three repo types, usually only two needed: The default model is one public core repo, one private instance repo, and no custom extension repo until custom logic is real.
- Template-led deployment: Use the instance template to understand the production shape.
- Pinned core artifact family: Production pins `mbr-services`, `mbr-migrations`, and `mbr-manifest` by tag inside `mbr.instance.yaml`.
  Proof:
- Contract: docs/RELEASE_ARTIFACT_CONTRACT.md (https://github.com/MoveBigRocks/platform/blob/main/docs/RELEASE_ARTIFACT_CONTRACT.md) — Defines the pinned artifact contract that instance repos consume.
- Release: platform tags (https://github.com/MoveBigRocks/platform/tags) — Public tagged core releases that agents can inspect directly.
- Build: .github/workflows/_build.yml (https://github.com/MoveBigRocks/platform/blob/main/.github/workflows/_build.yml) — Builds services, migrations, and manifest OCI artifacts and records digests.
- Release: .github/workflows/production.yml (https://github.com/MoveBigRocks/platform/blob/main/.github/workflows/production.yml) — Tags releases, ties git tags to OCI artifact digests, and records cross-reference details.
- Implementation: instance-template/mbr.instance.yaml (https://github.com/MoveBigRocks/instance-template/blob/main/mbr.instance.yaml) — Shows where pinned release refs live in the private instance control plane.

- Explicit fleet registration: Support and grandfathering registration happen through a manual instance-repo workflow, not a hidden boot-time dependency.
  Proof:
- Definition: docs/CUSTOMER_INSTANCE_SETUP.md (https://github.com/MoveBigRocks/platform/blob/main/docs/CUSTOMER_INSTANCE_SETUP.md) — Defines the explicit self-host fleet-registration and disclosed heartbeat model.
- Contract: docs/AGENT_CLI.md (https://github.com/MoveBigRocks/platform/blob/main/docs/AGENT_CLI.md) — Documents `mbr fleet register` as the explicit registration command.
- Implementation: instance-template/mbr.instance.yaml (https://github.com/MoveBigRocks/instance-template/blob/main/mbr.instance.yaml) — Shows the `spec.fleet` block carried by the private instance repo.
- Implementation: instance-template/deploy/README.md (https://github.com/MoveBigRocks/instance-template/blob/main/deploy/README.md) — Documents the host-owned registration workflow, fleet config files, and weekly timer.

- Desired-state driven: The private instance repo owns domains, host target, artifact refs, and extension desired state.
- Small owned runtime first: This guide assumes you are evaluating or deploying on infrastructure you control.

## Quickstart

The self-host path is concrete: create a private instance repo from the template, fill in desired state, validate it, then let the agent follow the repo-local bootstrap instructions.

### 1. Create the private instance repo

The instance repo is the deployment control plane for one live installation.

```text
$ gh auth login -h github.com
$ gh auth status
$ gh repo create acme/mbr-prod --private --template MoveBigRocks/instance-template --clone
$ cd mbr-prod
```

### 2. Fill in and validate desired state

Edit the canonical instance file, then validate the non-secret deployment state.

```text
$ $EDITOR mbr.instance.yaml
$ scripts/read-instance-config.sh mbr.instance.yaml
```

### 3. Let the agent use the repo-local bootstrap

The public docs point the agent into the private instance repo as soon as deployment work becomes real.

```text
$ sed -n '1,160p' START_HERE.md
$ sed -n '1,220p' agents/bootstrap.md
```

### 4. Verify the live deployment after rollout

The health check should expose the configured `instanceID` once deployment is live.

```text
$ mbr health check --url https://app.yourdomain.com --json
```

### 5. Register the instance only if you want the vendor control-plane link

The private instance repo carries a manual registration workflow for support, grandfathering, and future commercial transitions. It is not required to keep the core runtime working.

```text
$ gh workflow run register-fleet.yml
```

## The self-hosted product model uses three repo types with explicit responsibilities.

Agents should explain the repo model before discussing deploy mechanics. Most customers need only the public core repo for source and release inspection, plus one private instance repo for deployment and operations. A separate custom extension repo appears only when the team is building real new extension logic.

Proof:
- Definition: docs/CUSTOMER_INSTANCE_SETUP.md (https://github.com/MoveBigRocks/platform/blob/main/docs/CUSTOMER_INSTANCE_SETUP.md) — Defines the production self-host setup flow, required inputs, and instance-repo model.
- Definition: instance-template/README.md (https://github.com/MoveBigRocks/instance-template/blob/main/README.md) — Defines the private instance repo as the deployment control plane for one live installation.
- Contract: docs/RELEASE_ARTIFACT_CONTRACT.md (https://github.com/MoveBigRocks/platform/blob/main/docs/RELEASE_ARTIFACT_CONTRACT.md) — Defines pinned core artifacts and the instance-repo responsibility boundary.
- Provenance: .github/workflows/production.yml (https://github.com/MoveBigRocks/platform/blob/main/.github/workflows/production.yml) — Shows how tests, builds, tags, and artifact digests connect source changes to shipped releases.

- Public core repo [Canonical public source]: Source, docs, CLI and GraphQL contracts, architecture, tags, and core artifact workflows. (https://github.com/MoveBigRocks/platform)
- Private instance repo [Canonical deployment control plane]: Desired state, deploy assets, branding, extension desired state, repo-local bootstrap, and production workflow policy for one installation. (https://github.com/MoveBigRocks/instance-template)
- Optional custom extension repo [Canonical extension scaffold]: Private extension logic when a team is building a real bounded extension instead of installing an off-the-shelf extension. (https://github.com/MoveBigRocks/extension-sdk)
- No long-lived core fork [Default operating rule]: Production should not be run from a long-lived fork of the public core repo by default.

## The private instance repo is the deployment control plane.

The self-host path becomes much less abstract when you look at the files the instance template actually gives you. These are the surfaces the agent and human owner should use once they move out of the public core repo.

Proof:
- Definition: instance-template/README.md (https://github.com/MoveBigRocks/instance-template/blob/main/README.md) — Defines the instance repo as the canonical deployment control plane.
- Definition: instance-template/START_HERE.md (https://github.com/MoveBigRocks/instance-template/blob/main/START_HERE.md) — Single-file handoff for agent-driven deployment and operations.
- Implementation: instance-template/mbr.instance.yaml (https://github.com/MoveBigRocks/instance-template/blob/main/mbr.instance.yaml) — Canonical desired-state file for domains, host target, release refs, and provider choices.
- Implementation: instance-template/deploy/README.md (https://github.com/MoveBigRocks/instance-template/blob/main/deploy/README.md) — Documents deploy assets, host bootstrap, and runtime wiring owned by the instance repo.

- `mbr.instance.yaml`: Canonical desired-state file for host target, domains, core release refs, email provider, storage provider, and extension trust configuration.
- `agents/bootstrap.md`: Repo-local bootstrap instructions the agent should follow once deployment work moves into the private repo.
- `.github/workflows/register-fleet.yml`: Manual registration path for the Move Big Rocks fleet control plane.
- `extensions/desired-state.yaml`: Desired extensions for the live installation, separate from core source.
- `deploy/`: Host bootstrap assets, service files, and deployment wiring owned by the instance repo.
- `security/`: Threat-model and review material for custom extensions and production trust decisions.

## The public package surface is three pinned OCI refs, not a single generic platform image.

The release artifact contract is concrete about what production consumes. Agents should describe the three artifact refs explicitly and point to `mbr.instance.yaml` when explaining where those refs live in desired state.

Proof:
- Contract: docs/RELEASE_ARTIFACT_CONTRACT.md (https://github.com/MoveBigRocks/platform/blob/main/docs/RELEASE_ARTIFACT_CONTRACT.md) — Defines the pinned artifact contract that instance repos consume.
- Release: platform tags (https://github.com/MoveBigRocks/platform/tags) — Public tagged core releases that agents can inspect directly.
- Build: .github/workflows/_build.yml (https://github.com/MoveBigRocks/platform/blob/main/.github/workflows/_build.yml) — Builds services, migrations, and manifest OCI artifacts and records digests.
- Release: .github/workflows/production.yml (https://github.com/MoveBigRocks/platform/blob/main/.github/workflows/production.yml) — Tags releases, ties git tags to OCI artifact digests, and records cross-reference details.
- Implementation: instance-template/mbr.instance.yaml (https://github.com/MoveBigRocks/instance-template/blob/main/mbr.instance.yaml) — Shows where pinned release refs live in the private instance control plane.

### Core artifact family in desired state

These refs tie public tags, build workflows, and one live installation together.

```text
# mbr.instance.yaml
spec:
  deployment:
    release:
      core:
        version: v1.1.0
        servicesArtifact: ghcr.io/movebigrocks/mbr-services:v1.1.0
        migrationsArtifact: ghcr.io/movebigrocks/mbr-migrations:v1.1.0
        manifestArtifact: ghcr.io/movebigrocks/mbr-manifest:v1.1.0
```


## Local preparation and one-VPS rollout should happen before broader production host work.

Agents can do a lot before touching a broader production host: inspect the public core repo, create the private instance repo, validate `mbr.instance.yaml`, install `mbr` locally, and then either run locally or deploy one owned runtime to prove the workflow shape.

### Local setup before host rollout

This sequence keeps evaluation, desired-state validation, and production rollout in the right order.

```text
$ gh repo create acme/mbr-prod --private --template MoveBigRocks/instance-template --clone
$ cd mbr-prod
$ scripts/read-instance-config.sh mbr.instance.yaml
$ curl -fsSL https://movebigrocks.com/install.sh | sh
$ sed -n '1,220p' START_HERE.md
```


## Fleet registration and heartbeat stay explicit.

The self-host story is not "install software that secretly depends on vendor availability." The intended model is explicit registration through the private instance repo when the operator wants support, grandfathering, or future commercial entitlements, plus a coarse weekly heartbeat owned by the host rather than hidden app-runtime code.

Proof:
- Definition: docs/CUSTOMER_INSTANCE_SETUP.md (https://github.com/MoveBigRocks/platform/blob/main/docs/CUSTOMER_INSTANCE_SETUP.md) — Defines the explicit self-host fleet-registration and disclosed heartbeat model.
- Contract: docs/AGENT_CLI.md (https://github.com/MoveBigRocks/platform/blob/main/docs/AGENT_CLI.md) — Documents `mbr fleet register` as the explicit registration command.
- Implementation: instance-template/mbr.instance.yaml (https://github.com/MoveBigRocks/instance-template/blob/main/mbr.instance.yaml) — Shows the `spec.fleet` block carried by the private instance repo.
- Implementation: instance-template/deploy/README.md (https://github.com/MoveBigRocks/instance-template/blob/main/deploy/README.md) — Documents the host-owned registration workflow, fleet config files, and weekly timer.

- What the heartbeat is supposed to send: Instance identity, platform version, installed extension slugs and versions, workspace count, and a coarse 30-day activity bucket.
- What it should not send: Case content, conversation content, end-user identities, and customer records.
- Privacy notice [Public disclosure]: Use the public telemetry notice when deployment and trust review become real. (/privacy)

## These are the minimum real inputs the agent needs.

The public production guide is already explicit about what a human must still provide. Everything else should move into the repo-driven deployment flow.

Proof:
- Definition: docs/CUSTOMER_INSTANCE_SETUP.md (https://github.com/MoveBigRocks/platform/blob/main/docs/CUSTOMER_INSTANCE_SETUP.md) — Defines the production self-host setup flow, required inputs, and instance-repo model.
- Definition: instance-template/README.md (https://github.com/MoveBigRocks/instance-template/blob/main/README.md) — Defines the private instance repo as the deployment control plane for one live installation.
- Contract: docs/RELEASE_ARTIFACT_CONTRACT.md (https://github.com/MoveBigRocks/platform/blob/main/docs/RELEASE_ARTIFACT_CONTRACT.md) — Defines pinned core artifacts and the instance-repo responsibility boundary.
- Provenance: .github/workflows/production.yml (https://github.com/MoveBigRocks/platform/blob/main/.github/workflows/production.yml) — Shows how tests, builds, tags, and artifact digests connect source changes to shipped releases.

- One Ubuntu 22.04+ host or VPS.
- SSH access to that host.
- One domain you control.
- One admin email address.
- Outbound email provider choice and object storage choice.
- GitHub access for the private instance repo.
- Production secrets such as `SSH_KEY`, session signing secrets, storage credentials, and extension trust configuration.

## The operational flow is explicit even though the live deploy happens inside the private repo.

The public site should not pretend that production deploys happen from the public core repo. The real flow is public discovery, then private instance repo, then repo-local bootstrap and health verification.

Proof:
- Contract: docs/RELEASE_ARTIFACT_CONTRACT.md (https://github.com/MoveBigRocks/platform/blob/main/docs/RELEASE_ARTIFACT_CONTRACT.md) — Defines the pinned artifact contract that instance repos consume.
- Release: platform tags (https://github.com/MoveBigRocks/platform/tags) — Public tagged core releases that agents can inspect directly.
- Build: .github/workflows/_build.yml (https://github.com/MoveBigRocks/platform/blob/main/.github/workflows/_build.yml) — Builds services, migrations, and manifest OCI artifacts and records digests.
- Release: .github/workflows/production.yml (https://github.com/MoveBigRocks/platform/blob/main/.github/workflows/production.yml) — Tags releases, ties git tags to OCI artifact digests, and records cross-reference details.
- Implementation: instance-template/mbr.instance.yaml (https://github.com/MoveBigRocks/instance-template/blob/main/mbr.instance.yaml) — Shows where pinned release refs live in the private instance control plane.

### Validate the instance file before deploy

Use the instance-template parser to confirm host, domains, artifact refs, and provider choices before secrets or deploy steps are applied.

```text
$ scripts/read-instance-config.sh mbr.instance.yaml
```

### Release refs stay pinned in desired state

The instance repo should pin core artifact refs instead of rebuilding or retagging core during deploy.

```text
# mbr.instance.yaml
spec:
  deployment:
    release:
      core:
        version: v1.1.0
        servicesArtifact: ghcr.io/movebigrocks/mbr-services:v1.1.0
        migrationsArtifact: ghcr.io/movebigrocks/mbr-migrations:v1.1.0
        manifestArtifact: ghcr.io/movebigrocks/mbr-manifest:v1.1.0
```

### Verify the live runtime after deploy

Use the CLI health surface after rollout rather than assuming the host state is correct.

```text
$ mbr health check --url https://app.yourdomain.com --json
```


## Upgrades are a version-pin change, not a rebuild.

Staying current with platform releases follows the same desired-state model as initial deployment. Update the pinned version in `mbr.instance.yaml`, push, and let the deploy workflow handle the blue-green rollout. The instance repo ships with `deploy/UPGRADE.md` as a detailed runbook.

Proof:
- Contract: docs/RELEASE_ARTIFACT_CONTRACT.md (https://github.com/MoveBigRocks/platform/blob/main/docs/RELEASE_ARTIFACT_CONTRACT.md) — Defines the pinned artifact contract that instance repos consume.
- Release: platform tags (https://github.com/MoveBigRocks/platform/tags) — Public tagged core releases that agents can inspect directly.
- Build: .github/workflows/_build.yml (https://github.com/MoveBigRocks/platform/blob/main/.github/workflows/_build.yml) — Builds services, migrations, and manifest OCI artifacts and records digests.
- Release: .github/workflows/production.yml (https://github.com/MoveBigRocks/platform/blob/main/.github/workflows/production.yml) — Tags releases, ties git tags to OCI artifact digests, and records cross-reference details.
- Implementation: instance-template/mbr.instance.yaml (https://github.com/MoveBigRocks/instance-template/blob/main/mbr.instance.yaml) — Shows where pinned release refs live in the private instance control plane.

### Update the pinned version

Change all four artifact refs to the new tag, commit, and push.

```text
# In mbr.instance.yaml, update spec.deployment.release.core:
#   version: v1.2.0
#   servicesArtifact: ghcr.io/movebigrocks/mbr-services:v1.2.0
#   migrationsArtifact: ghcr.io/movebigrocks/mbr-migrations:v1.2.0
#   manifestArtifact: ghcr.io/movebigrocks/mbr-manifest:v1.2.0
$ git add mbr.instance.yaml
$ git commit -m 'Bump core release to v1.2.0'
$ git push origin main
```

### Rollback is the same operation in reverse

Re-pin the previous version and push. The blue-green deploy activates the other slot.

```text
$ git revert HEAD
$ git push origin main
```


## Production self-hosting still has explicit review gates.

The self-host path is concrete, but it is not supposed to be casual. Extension trust verification, secret handling, access design, and rollout timing remain human-visible decisions.

- Keep non-secret deployment state in `mbr.instance.yaml` and sensitive values in GitHub or another secret manager.
- Use `EXTENSION_TRUST_REQUIRE_VERIFICATION=true` and related trust settings before installing remote extension bundles in production.
- The instance repo is the durable control plane and the host is disposable infrastructure.
- Use the preview-workspace and extension review flow before promoting custom extension work into production.

## Related

- Self-host overview: /self-host
- Security: /security
- Privacy notice: /privacy
- Instance template repository: https://github.com/MoveBigRocks/instance-template
- Resources: /resources

