Trunk-Based Development (TBD) Workflow
Core Principles
mainis Production: Themainbranch is the strict source of truth. If code is inmain, it is actively deployed to the Hetzner Swarm production cluster.- Deployments ≠ Releases: Code is deployed continuously (multiple times a day). Features are released to users asynchronously via Feature Flags.
- Ephemeral Branches: Feature branches (
feat/,fix/) must be short-lived (merged within 24–48 hours). - Forward-Only History: Force pushing to
mainis strictly prohibited. Mistakes are fixed by rolling forward usinggit revertor automated Docker Swarm rollbacks.
The Agentic Daily Workflow
1. Planning & Branching
- Checkout a new, short-lived branch from
main. - Use Google Antigravity (IDE Agent) to architect the feature, generating markdown implementation plans and database schema designs. Antigravity stores artifacts internally in its own data directory.
2. Execution & Local Validation
- Use ECC / Claude Code CLI to execute the generated plans, generating boilerplate, Nest.js workers, and Hasura migrations.
- Validate the Vue.js UI and backend services locally using Docker Compose before committing.
3. AI-Gated CI/CD (Pull Requests)
- Open a PR against
main. This triggers the GitHub Actions pipeline. - The CI/CD pipeline enforces passing unit tests and initiates a headless AI code review, validating changes against
.ai/rules/(specifically checking Swarm configs and secret management). - A live preview Swarm environment is automatically spun up via Traefik dynamic routing for visual QA.
4. Continuous Deployment
- Upon human and AI approval, merge the PR to
main. The feature branch is automatically deleted. - GitHub Actions builds the new container images, pushes them to the registry, and triggers a rolling deployment to the Hetzner Swarm Manager.
Production Safety Mechanisms
To safely merge unfinished or risky code into main without impacting enterprise customers, the following patterns are mandatory:
Feature Flags
- Intent: Hide incomplete functionality while keeping the codebase unified and preventing merge conflicts.
- Implementation: Manage flags via a dedicated PostgreSQL/Hasura table. The Vue.js frontend and Nest.js API must evaluate these flags before rendering UI components or processing restricted mutations.
- Modifying Existing Features: Use "Branch by Abstraction." Build the new logic alongside the old logic, using the feature flag as a router. Remove the old logic only when the new feature is verified in production.
- Lifecycle: Feature flags must be removed within 2 weeks of full production rollout. A periodic audit (e.g., monthly) should identify and clean up stale flags to prevent configuration drift.
Expand and Contract Migrations
- Intent: Prevent database locks and API crashes during schema changes (zero-downtime database updates).
- Implementation: Never execute destructive SQL (drops, renames) in a single PR.
- Expand: Add the new schema element and update the application to write to both old and new.
- Migrate: Backfill historical data via a background worker.
- Contract: Only after the backfill worker reports 100% completion and the old column/table has had zero application reads for ≥ 48 hours, remove the old schema element and legacy code paths in a final, separate PR.
Database Migration Rollbacks
- Intent: Ensure every schema change can be safely reversed without manual intervention.
- Mandatory Down Migrations: Every Hasura migration must include a corresponding down migration. PRs missing a down migration must be rejected.
- Regular Testing: Down migrations should be exercised regularly in CI to verify they execute cleanly against a representative dataset.
- Code Review Gate: Both the AI code review and human reviewer must explicitly verify the presence and correctness of the down migration before approving a PR.
Automated Swarm Rollbacks
- Intent: Protect against fatal application crashes (e.g., syntax errors) that bypass the CI/CD pipeline.
- Implementation: Rely on Docker Swarm's native orchestration. Swarm is configured to start new containers before stopping old ones (
start-first). It monitors strict container health checks upon boot. If a new deployment fails its health check, Swarm automatically executes a rollback, keeping the previous stable container active and ensuring zero downtime.