# AWP I1 dogfood deployment

The I1 dogfood instance runs persistently on `debian3` while AgentRun workspaces are created on demand in the existing three-node K3s cluster.

## Owner URL

From the Tailscale-connected workstation, open the authenticated HTTPS entrypoint:

```text
https://debian3.taild2daa0.ts.net/
```

The loopback web listener (`127.0.0.1:4173`) is an implementation detail behind Tailscale Serve, not the owner URL.

## Persistent services

User-systemd services on `debian3`:

```text
awp-dogfood-postgres.service
awp-dogfood-control-plane.service
awp-dogfood-web.service
```

User lingering is enabled so the services survive logout and start with the user service manager after reboot.

PostgreSQL data is retained in the rootless Podman volume `awp-dogfood-postgres`.

## Execution plane

`infra/k8s/execution-base.yaml` provisions `awp-system` and `awp-workspaces` plus the restricted `awp-workspace-controller` RBAC boundary. AgentRun pods/PVCs/NetworkPolicies are created only when the owner starts Factory work; the deployment script does not start a FactoryRun.

## Deploy/update

Use the current deploy script and name the exact canonical-main SHA you intend to deploy:

```bash
git fetch origin main
AWP_DOGFOOD_SOURCE_SHA="$(git rev-parse origin/main)" bash infra/dogfood/deploy-debian3.sh
```

The deploy script does **not** trust the invoking checkout as product source. It fetches `origin/main` into the service-owned source seed, refuses the deployment if `origin/main` no longer equals `AWP_DOGFOOD_SOURCE_SHA`, archives that exact commit into `repo.next`, builds there, imports authoritative runtime configuration, then swaps the source only after the old web/control services are stopped.

Deployments are serialized by `$AWP_DOGFOOD_ROOT/.deploy.lock` for the entire build/apply/swap/verify transaction. Concurrent operator sessions wait (900 seconds by default, configurable with `AWP_DOGFOOD_DEPLOY_LOCK_WAIT_SEC`) instead of stopping or replacing another deployment mid-verification.

A successful cutover requires `/health` to report the exact deployed Git commit/tree and zero migration drift. Only then is `~/.config/awp-dogfood/deployment-receipt.json` replaced with the verified source SHA/tree and immutable execution-image identities. A failed or raced deployment does not create a success receipt.

## Verify

```bash
systemctl --user is-active \
  awp-dogfood-postgres.service \
  awp-dogfood-control-plane.service \
  awp-dogfood-web.service

curl -fsS http://127.0.0.1:8787/health | jq .
curl -fsS http://127.0.0.1:4173/ >/dev/null
cat ~/.config/awp-dogfood/deployment-receipt.json | jq .
```

Expected control-plane health includes PostgreSQL status `ok`, zero pending migrations, no migration drift, and `source.sha` / `source.tree` equal to the retained deployment receipt.

## Repository-scoped GitHub publication authority

I1 trusted publication supports two mutually exclusive server-side credential modes. Prefer a GitHub App installation for dogfood because it mints short-lived repository-scoped tokens and avoids retaining a long-lived publication token.

### Preferred: GitHub App installation

Create or use a GitHub App whose repository permissions are limited to the operations AWP requires:

- **Contents: Read and write** — publish the exact candidate ref/commit and perform the trusted merge mutation/readback.
- **Administration: Read-only** — read required branch-protection checks.
- **Checks: Read-only** — read check-run state for the exact candidate revision.
- **Commit statuses: Read-only** — read commit-status state for the exact candidate revision.

Install the App on **only** `platform-modules/awp`. Do not grant all-repositories access. On `debian3`, provision these files under `~/.config/awp-dogfood/`:

```text
github-app-id                 numeric App ID only
github-app-installation-id    numeric installation ID only
github-app-private-key        PEM private key, mode 600
```

Do not store an installation access token. At runtime AWP signs a bounded App JWT, asks GitHub for a short-lived installation token narrowed to repository name `awp` and the permissions above, then verifies `/installation/repositories` exposes exactly `platform-modules/awp` before any provider operation may use the lease. A token that exposes zero, multiple, or a different repository fails closed.

The dogfood deploy emits only file/reference metadata into `control-plane.env`:

```text
AWP_GITHUB_PUBLICATION_APP_ID
AWP_GITHUB_PUBLICATION_INSTALLATION_ID
AWP_GITHUB_PUBLICATION_APP_PRIVATE_KEY_FILE
AWP_GITHUB_PUBLICATION_REPOSITORY=platform-modules/awp
```

The private-key **value** is never written into the environment file, PostgreSQL, deployment receipt, workspace or AgentRun.

### Alternative: fine-grained token file

The existing `~/.config/awp-dogfood/github-publication-token` mode remains supported for a repository-scoped fine-grained token. Do not use a broad classic PAT or the ambient `gh auth` token as AWP runtime publication authority.

The deploy fails closed if both credential modes are configured or if the GitHub App file set is partial. Merely provisioning credentials does not authorize a FactoryRun or advance `GOLIVE.md`; the owner journey remains a separate explicit boundary.
