The woodpecker-deployer-rbac.yaml was in kustomization.yaml but
release.sh only applied rdev-api.yaml directly. This caused CI
deploy steps to fail with RBAC forbidden errors.
Now release.sh --deploy applies both manifests.
- Initial K8s deployment auto-creation during project creation
- DNS record upsert support (create or update existing records)
- Ingress host management for domain aliases (AddIngressHost/RemoveIngressHost)
- Woodpecker deployer RBAC manifest for CI deploy steps
- Single-commit template seeding via Gitea bulk file API
Closes automation gaps exposed during www.threesix.ai launch:
- Projects now auto-create K8s Deployment/Service/Ingress on creation
- Domain aliases automatically update both DNS and K8s ingress
- CI deploy steps work without manual RBAC setup
- Template seeding triggers only one CI pipeline (not per-file)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The deployer was using cert-manager.io/issuer (namespace-scoped)
referencing letsencrypt-threesix which only exists in the threesix
namespace. Projects deploy to the projects namespace, so changed to
cert-manager.io/cluster-issuer with letsencrypt-prod.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The destinations format caused Kaniko to push images with the full
registry URL as part of the repo path (registry.threesix.ai/name
instead of just name). Using registry + repo + tags format pushes
to the correct path.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The templates referenced zot.orchard9.ai which has no DNS record.
The actual zot registry is at registry.threesix.ai. Also updated
static templates to use Kaniko plugin instead of docker:24-dind.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The deployer was blindly calling Namespaces().Create() which triggered
cluster-scope RBAC checks even when the namespace already existed.
Now checks with Get() first and only creates if NotFound.
Also adds namespace get/create and secrets create/update/patch
permissions to the rdev-api-deployer ClusterRole.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Switch from raw gcr.io/kaniko-project/executor:debug to
woodpeckerci/plugin-kaniko with destinations setting. Also use
npm install instead of npm ci (no lock file in templates) and
skip-tls-verify for self-signed registry certs.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Zot is configured without authentication, so remove the auth
configuration step from templates. Added --insecure flag for
internal registry access.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Replace Docker-in-Docker (privileged mode) with Kaniko for container
builds. This allows CI pipelines to run without requiring trusted
repo status in Woodpecker.
- astro-landing: Use Kaniko with from_secret for registry auth
- go-api: Use Kaniko with from_secret for registry auth
- default: Use Kaniko with from_secret for registry auth
Kaniko builds and pushes images without requiring privileged mode,
making it compatible with Woodpecker's default security settings.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add PipelineErrorResponse struct to handler
- Add Errors field to PipelineResponse struct
- Add mapPipelineErrors helper function
- Include errors in both ListPipelines and GetPipeline responses
Root cause of CI failures: Woodpecker trust level doesn't allow privileged mode
for docker steps. Errors were being returned by Woodpecker but not exposed.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add CIPipelineError struct to domain with Type, Message, IsWarning fields
- Map Woodpecker Pipeline.Errors to domain.CIPipeline.Errors
- Fix migration 013: UUID type for project_id, cast id to text for MD5
- Remove invalid domain data migration (columns don't exist)
- Update release.sh with --deploy flag and migration support
- Fix test nil pointer: check errors in TestAPIKeyRepository_ProjectIDArrayHandling
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add --deploy flag documentation to quick reference
- Update platform status with Multi-Domain Support (Done)
- Add current version indicator
- Add new implementation entries to cookbook
- Mark cookbook ready for E2E testing
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Landing page cookbook implementation (Weeks 1-4):
Domain Infrastructure:
- Add project_domains table with migration (013_project_domains.sql)
- Add ProjectDomain model with domain types (primary_auto, primary_custom, alias)
- Add SlugGenerator and ProjectDomainRepository interfaces
- Implement postgres adapters for domain and slug management
Service Layer:
- Add domain CRUD methods to ProjectInfraService
- Generate 8-char random slugs for auto-domains
- Support custom subdomains during project creation
- Add site_live health check to project status
- Trigger CI build after template seeding
Handler Updates:
- Add DomainService interface and adapter pattern
- Rewrite domain handlers to use database-backed service
- Add proper error handling for duplicate/missing domains
CI Integration:
- Add TriggerBuild to CIProvider interface
- Implement TriggerBuild in Woodpecker adapter
- Manually trigger initial build after template seed
Cookbook & Scripts:
- Add landing-test.sh script for E2E testing
- Add release.sh for version releases
- Add logs.sh for quick log access
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add Gitea, Cloudflare DNS, and Kubernetes deployer adapters following
hexagonal architecture. These enable automated project provisioning:
- Git repository creation/management via Gitea
- DNS record management via Cloudflare
- Container deployment to Kubernetes
Includes domain models, ports, handlers, and Woodpecker CI webhook
integration for automated deployments on push.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- docker-compose.yaml: Local PostgreSQL on port 5433
- .env.local.example: Environment template for local dev
- Makefile: Dev commands (run, test, db-up, db-reset, etc.)
- QUICKSTART.md: Developer setup guide
- .gitignore: Exclude .env.local
Verified workflow:
1. make setup (creates .env.local)
2. make db-up (starts postgres)
3. make run (auto-migrates and serves on :8080)
All endpoints tested and working.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Documents the complete API key authentication system:
- Key format, hashing, and scopes
- Database schema and migrations
- Auth middleware and endpoints
- Build/deploy instructions
- Fixes for chi middleware ordering and Colima cross-compilation
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Chi requires middleware to be defined before routes. Moved
setupHealthEndpoints() from New() to Run() to allow callers to
add middleware before routes are registered.
Also:
- Updated rdev-api.yaml with DB env vars, RBAC, ServiceAccount
- Added Dockerfile.api.simple for pre-built binary deployment
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
v0.2 - Real Workspaces:
- Project-specific claudebox StatefulSets (pantheon, aeries)
- Init containers for git clone via SSH
- Deploy key secrets template
- Project ConfigMaps for CLAUDE.md
v0.3 - Git Integration:
- Dockerfile with rdev-bot git identity
- openssh-client for SSH operations
- Image version bump to v0.3.0
v0.4 - API Server:
- Go REST API with chi router
- Endpoints: /projects, /claude, /shell, /git, /events
- SSE streaming for real-time output
- OpenAPI docs via Scalar at /docs
- Kubernetes RBAC for pod exec
- Executor and project registry packages
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Implements a fully documented API server following the aeries chassis pattern:
- pkg/api: Simplified chassis with App, Response helpers, and OpenAPI builder
- cmd/rdev-api: Entry point with full OpenAPI spec for all v0.4 endpoints
- internal/handlers: Stubbed project handlers (list, get, claude, shell, git, events)
Endpoints:
- GET /health, /ready - Health checks
- GET /docs, /openapi.json - Scalar API docs
- GET /projects - List projects
- GET /projects/{id} - Get project
- POST /projects/{id}/claude, shell, git - Run commands
- GET /projects/{id}/events - SSE streaming
Uses Scalar for dark-mode API documentation at /docs.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
PLAN.md covers:
- v0.1: Base case (complete)
- v0.2: Real workspaces with init container clone
- v0.3: Git integration with deploy keys
- v0.4: Go REST API for controlling claudebox pods
- v0.5: SSE streaming for real-time output
- v0.6: Production hardening (auth, rate limits, audit)
Architecture: External clients (Discord, Slack, CLI) connect to
rdev-api which kubectl exec's into claudebox pods.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Created history/v0.1.0.md with full deployment notes
- Added k3s implementation section to reference.md
- Fixed auth command: `claude` not `claude /login`
- Documented issues encountered and solutions
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Switch from GCP Artifact Registry to GitHub Container Registry
- Build images for linux/amd64 (k3s node architecture)
- Use PVC for Claude config instead of secret (auth persists across restarts)
- Remove credential secret dependency
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Dockerfile for claudebox with Claude Code CLI
- Kustomize manifests for k3s deployment
- Scripts for credentials, deploy, and verify
- README with quick start guide
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>