# Deployment verification Both binaries embed their Git revision, UTC build time, and dirty flag. The coordinator is deployed as a Docker Compose image — see "For the Docker coordinator deployment" below for the build that carries provenance. (The old `deploy/redeploy.sh` + `orchestra.service` path was deleted on 2026-07-31; `orchestra-worker.service` is a different, still-current unit.) ## Browser operator login The browser UI requires `ORCHESTRA_WEB_USERNAME` and `ORCHESTRA_WEB_PASSWORD_HASH`. Generate a bcrypt hash without putting the password in shell history: ```sh go run ./cmd/orchestra-password ``` Set the emitted hash in the service environment along with the chosen username, then restart the coordinator. `ORCHESTRA_WEB_TOKEN` is not used by the browser UI anymore. Build a worker for staging on workpc with: ```sh revision=$(git rev-parse HEAD) build_time=$(date -u +%Y-%m-%dT%H:%M:%SZ) dirty=false; test -z "$(git status --porcelain)" || dirty=true go build -ldflags "-X orchestra/internal/buildinfo.Revision=$revision -X orchestra/internal/buildinfo.Time=$build_time -X orchestra/internal/buildinfo.Dirty=$dirty" -o orchestra-worker ./cmd/orchestra-worker scp orchestra-worker workpc:~/orchestra-deploy/orchestra-worker ssh workpc 'sha256sum ~/orchestra-deploy/orchestra-worker' ``` The worker receives only the path to a normal project configuration file: `ORCHESTRA_WORKER_PROJECT_CONFIG_FILE=/etc/orchestra/worker-projects.json`. That file contains a JSON object whose project entries contain `repo`, `worktree_root`, and `remote`; mount or provision it like any other worker configuration. The legacy single-checkout `ORCHESTRA_WORKER_PROJECTS` comma list remains supported for one existing checkout. An absent project is ineligible for routing. Verify the coordinator at `GET /v1/admin/diagnostics` with the normal admin credential: its `build` object is the coordinator provenance. `GET /v1/federation/workers` shows every worker's `build`, supported projects, and worker-local health without SSH. Build both binaries with `deploy/build.sh`, which stamps them from one commit and refuses a dirty tree. A burn-in run must never pair a new coordinator with an old worker, and matching revisions are how that is checked rather than assumed. For the Docker coordinator deployment, provide the same provenance as build arguments (the Dockerfile intentionally cannot read `.git` from its build context): ```sh revision=$(git rev-parse HEAD) build_time=$(date -u +%Y-%m-%dT%H:%M:%SZ) dirty=false; test -z "$(git status --porcelain)" || dirty=true docker compose build \ --build-arg BUILD_REVISION="$revision" \ --build-arg BUILD_TIME="$build_time" \ --build-arg BUILD_DIRTY="$dirty" \ orchestra-api docker compose up -d --no-deps orchestra-api ``` If a pre-v2 event log has the historical repeated-`seq=1` prefix, the current coordinator intentionally refuses to replay it. Stop every coordinator using the data directory and run the explicit, backup-preserving migration before deploying the current image: ```sh orchestra-migrate -data /var/lib/orchestra/data -confirm ```