Development Playbook

A shared process for every developer — from first-timers using AI to experienced engineers. One standard, all repos.

🏗
See also
Infrastructure & Container Architecture
Komodo stacks · test/prod separation · game containers · Multi-Zones frontend model

How we work

01 Every feature starts with a GitHub issue
02 Every issue gets a feature document
03 Code lives in a branch, never directly on main
04 The pre-push gate protects everyone — run it locally
05 CI is the final arbiter — if CI is red, nothing ships
06 Small commits, clear messages — future you will be grateful
07 AI is a tool, not a reviewer — always read what it writes

The development flow

📋
Issue
Create GitHub issue + feature doc
🌿
Branch
feat/<name> from main
💻
Code
Write code + tests (AI or manual)
🛡
Pre-push gate
Format · Lint · Types · Tests
🔀
Pull Request
Link issue + feature doc
⚙️
CI
Full validation + Docker build
🚀
Deploy
Auto on merge to main

What runs where

Pre-commit Local

  • Passes immediately (fast)
  • No blocking checks

Pre-push Local

  • Prettier format check
  • ESLint
  • TypeScript type-check
  • Unit tests
  • Integration tests
  • Architecture verify
  • Dockerfile syntax (if Docker installed)

CI — Pull Request GitHub Actions

  • All pre-push checks
  • Full Next.js build
  • Smoke tests (Playwright)
  • Coverage upload

CI — Push to main GitHub Actions

  • All PR checks
  • Semantic version tag
  • Docker build + push → GHCR
  • Komodo redeploy

Every PR must meet these standards

🎨
Code Formatting
All code formatted with Prettier. No formatting discussions — the tool decides. Run pnpm format before committing.
pre-push CI
🔍
Linting
ESLint must pass with zero errors. Includes rules for React hooks, import order, no unused variables, and architecture boundaries (no server imports in client components).
pre-push CI
🔷
Type Safety
TypeScript strict mode. Zero type errors. No any — use unknown and narrow. AI often introduces any — always check.
pre-push CI
🧪
Tests
Unit tests for all logic. Integration tests for data flows. New features require tests — AI should write them alongside the implementation. Smoke tests run in CI on PRs.
pre-push CI (smoke)
📡
Structured Logging
All containers send structured logs to OpenObserve via OTLP. No console.log in production code — use the logger. Every request should produce a trace with service name, level, and correlation ID.
ESLint rule runtime
🔑
No Secrets in Code
All secrets via environment variables. Never committed to the repo. .env files are gitignored. Secrets stored in Komodo or GitHub Actions secrets — not in .env.example.
pre-push CI scan
📝
Conventional Commits
Commit message format: type(scope): subject. Valid types: feat fix docs ci chore refactor test. Drives semantic versioning automatically.
CI
📄
Feature Document
Every feat/* branch must have a feature doc at docs/features/<name>.md before implementation starts. PR must link to it. AI agents read this as context.
PR checklist

Branch naming

Branch Purpose Notes
main Production ⬤ Protected — CI required, no direct push
feat/<name> New feature Branch from main, PR back to main
fix/<name> Bug fix Branch from main
chore/<name> Maintenance, deps, docs No feature doc required
ci/<name> CI/CD changes No feature doc required

From idea to shipped feature

1

Create a GitHub Issue

Describe what you want to build: what problem it solves, what it looks like when done. Add acceptance criteria. gh issue create

2

Create the feature document

Copy docs/features/TEMPLATE.mddocs/features/<feature-name>.md. Fill in context, scope, and design decisions. Commit it to the branch.

3

Create branch and start coding

Branch name matches the feature: feat/live-scoreboard. Use AI freely — but read every line it writes before committing.

4

Write tests alongside the code

Unit tests for logic. Integration tests for data flow. The pre-push gate will run them — better to know now than in CI.

5

Commit with conventional messages

Format: feat(scope): subject. Keep commits small and focused. Reference the issue: Refs: #42

6

Push — the gate runs automatically

Husky runs format → lint → type-check → unit → integration. If it fails, fix locally. Never use --no-verify.

7

Open a PR linking issue + feature doc

PR description: what changed, why, how to test it. Link: Closes #42. Link to docs/features/<name>.md.

8

CI passes → merge → auto-deploy

Once CI is green and reviewed, merge to main. GitHub Actions builds the Docker image and Komodo redeploys.

What we use and why

sanity-web

Main Platform

Next.js 15 TypeScript Tailwind CSS Sanity CMS Clerk Auth Vitest Playwright
cs-web

CS2 Frontend

Next.js 15 TypeScript Tailwind CSS Clerk Auth Vitest Playwright
dedikert

CS2 Backend

FastAPI Python PostgreSQL Redis Celery SQLAlchemy Alembic
core-infrastructure

Infrastructure

Komodo Docker Compose Ubuntu Nginx GHCR
all services

Observability

OpenObserve OTLP/HTTP Structured logs Traces Dashboards

Using AI effectively

✓ Do

  • Read every line of AI-generated code before committing
  • Give the AI the feature doc and CLAUDE.md as context
  • Ask the AI to write tests alongside the code
  • Tell the AI which skill documents apply to the task
  • Use AI to explain code you don't understand before submitting
  • Commit small — one logical change per commit
  • Ask the AI to check security before submitting API routes

✗ Don't

  • Commit AI output without reading it
  • Use --no-verify to skip the pre-push gate
  • Paste entire file rewrites as single commits
  • Let AI push directly to main
  • Trust AI on security-sensitive code — always verify
  • Skip the feature document because "it's a small change"
  • Ignore CI failures — red CI means nothing ships