Getting Started
Two actors are involved in onboarding: an admin who provisions your GCP access once, and you (the developer) who runs the rest. The admin steps must happen before you begin.
Admin Steps
① Create the developer config
Create terraform/config/developers/<handle>.tfvars. Replace alice with the developer’s chosen handle and their actual email:
developer_id = "alice"
developer_email = "alice@horizon.ai"
Commit and push this file to main.
Add the developer’s email to the developer_emails list in terraform/config/environments/foundation.tfvars, then apply:
./scripts/tf foundation apply
This grants the developer serviceAccountTokenCreator on the dev platform SA — the permission they need to apply their own sandbox in step ⑥. Without this step, ./scripts/dev-setup will fail.
Foundation only needs to be applied once per developer. Re-running it for subsequent developers is safe — it is idempotent.
Developer Steps
③ Clone the repo
git clone <repo-url>
cd v0-shokunin-ai-platform
④ Open the dev container
Open the repo in VS Code. When prompted, click Reopen in Container.
The container provides Node.js 24, Bun, Docker-in-Docker, Terraform, gcloud CLI, and Python 3.12. The first build takes 3–5 minutes.
GitHub Codespaces alternative: Open the repo on GitHub → Code → Codespaces → Create codespace on main. No local Docker required.
⑤ Authenticate with GCP
In the container terminal, run both commands:
gcloud auth login
gcloud auth application-default login
The first authenticates your gcloud CLI. The second sets up Application Default Credentials (ADC) — required by dev-setup and env-sync to read from Secret Manager.
⑥ Run dev-setup
./scripts/dev-setup <your-handle> <your-email>
Example:
./scripts/dev-setup alice alice@horizon.ai
This single script handles everything:
| Step | What it does |
|---|
| Verify prereqs | Checks gcloud, terraform, bun are available and authenticated |
| Create tfvars | Creates config/developers/<handle>.tfvars if not already committed |
| Apply sandbox | Runs ./scripts/tf dev <handle> apply — creates your Firestore database and grants Secret Manager read access |
| Sync secrets | Runs ./scripts/env-sync — pulls all platform secrets from GCP Secret Manager into your .env |
| Health check | Installs dependencies and verifies the build |
The admin must complete step ② before you run dev-setup. Without it, the terraform apply will fail with a permission denied error on SA impersonation.
⑦ Authenticate OpenCode
OpenCode requires an API key to run. If you are part of the Horizon organisation, request a Zen API key from an admin.
Once you have the key, log in:
Select Zen as the provider and paste your API key when prompted. This is a one-time step per machine — credentials are stored locally.
⑧ Start OpenCode and local services
In separate terminals:
# Terminal 1 — AI coding assistant
opencode
# Terminal 2 — local platform services
docker-compose up -d
The platform is now running at http://localhost:3000.
Verify the Setup
docker-compose ps # all containers: Up (healthy)
bd status # Beads CLI: connected
gcloud auth list # your account: ACTIVE
Development Commands
| Command | Description |
|---|
bun run dev | Next.js dev server with hot reload (faster than Docker for active development) |
bun run build | Production build with type checking |
bun run lint | ESLint |
docker-compose up -d | Start all local services |
docker-compose ps | Check service health |
./scripts/env-sync | Re-sync secrets from GCP (safe to re-run at any time) |
Troubleshooting
dev-setup fails: Could not obtain an access token
The admin has not applied foundation yet (step ②), or the wrong email was added to foundation.tfvars. Ask your admin to check terraform/config/environments/foundation.tfvars and re-apply.
env-sync fails: secret not found or permission denied
Your sandbox terraform hasn’t been applied yet, or the apply failed partway. Re-run ./scripts/dev-setup — it is safe to run multiple times.
bd fails with CGO errors
Ensure CGO_ENABLED=1 is set in .env. It is included in .env.example — if missing from your .env, add it manually.
Port conflicts
lsof -ti:3000 | xargs kill -9 # free port 3000
lsof -ti:3307 | xargs kill -9 # free port 3307 (Dolt)