# Deployment Porting Guide ## Purpose Use this guide when updating boilerplate deployment and CI documentation. It keeps deployment prose aligned with the current static evidence without overstating live proof, registry state, or production runtime behavior. This document is a documentation entrypoint only. It does not authorize runtime workflow changes, secret creation, live registry pushes, Coolify deployments, browser checks, Playwright runs, Cypress runs, or other E2E execution from Auto-Mode. ## Source Evidence Use these sources as the deployment-porting baseline: - `README.md` for the active Gitea CI summary, Corepack/pnpm setup, Docker smoke description, and manual E2E policy. - `docs/porting-guide.md` section `Deployment and CI docs` for wording rules that distinguish Gitea CI, local Docker smoke validation, static verification, and manual browser/E2E review. - `docs/deployment.md` for the current deploy workflow contract, Gitea Package Registry placeholder slots, Coolify runner-side triggering, and health/readiness inspection guidance. - `.tc/baselines/porting-docs/baseline-health.md` for the Porting Docs baseline gate evidence and documentation inventory scope. When a later document claims stronger proof than these sources, it must name the later human-approved run or slice evidence that provided that proof. ## CI Terminology Describe the active pipeline as Gitea CI on the self-hosted `toolctrl-ci` runner. The baseline CI contract starts with Corepack and the pinned pnpm version, installs dependencies with `pnpm install --frozen-lockfile`, then runs static/package gates for quality, API, worker, database, and Docker smoke validation. Use these safe local verification references for CI documentation updates: ```sh pnpm run verify:ci-baseline pnpm run verify:gitea-ci-workflow pnpm run verify:production-seed-artifact ``` Do not describe baseline CI as publishing images, pushing to a registry, triggering Coolify, running browser automation, or proving live deployment. Those claims require separate focused evidence. ## Docker Smoke Boundaries Document Docker smoke as local build and configuration validation. It may prove that Dockerfile targets and Docker Compose configuration are shaped correctly, but it is not proof of a live runtime, registry publish, artifact upload, production rollout, or browser/E2E behavior. Safe static/package verifier references include focused scripts and tests such as: ```sh node scripts/verify-docker-baseline.mjs pnpm exec vitest run scripts/verify-docker-baseline.test.mjs ``` If a human later performs a live Docker build/run smoke check, record it as manual evidence and keep secrets out of commands, logs, screenshots, and summaries. ## Deploy Workflow Verification The deploy workflow contract is static unless a later human-approved run proves otherwise. Use this command as the supported shorthand when documenting the deploy workflow verifier: ```sh pnpm run verify:deploy-workflow ``` Focused verifier references may also include: ```sh node scripts/verify-gitea-deploy-workflow.mjs pnpm exec vitest run scripts/verify-gitea-deploy-workflow.test.mjs ``` The static deploy workflow may document versioned image targets for `web`, `api`, and `worker`, immutable full-SHA tags, stage-and-promote alias behavior, and required placeholder configuration slots. Do not turn this into a claim that a registry login, image push, artifact publication, or production deployment actually happened unless the corresponding Gitea run evidence is attached separately. ## Placeholder-Only Secret Handling Deployment docs must use placeholder names only. These names identify required CI variable or secret slots; they are not example values: - `REGISTRY_USER` - `REGISTRY_PAT` - `COOLIFY_API_URL` - `COOLIFY_RESOURCE_UUIDS` - `COOLIFY_TOKEN` - `COOLIFY_STAGING_API_URL` - `COOLIFY_STAGING_RESOURCE_UUIDS` - `COOLIFY_STAGING_TOKEN` Do not include real registry hosts, namespaces, usernames, passwords, Coolify URLs, UUIDs, tokens, webhook query strings, deploy endpoints, database URLs, Redis URLs, Supabase keys, mail provider keys, or secret-shaped sample values. Use the image placeholder form `{registry}/{namespace}/{web|api|worker}:{tag}` when explaining image naming. ## Coolify Runner Trigger Coolify triggering is runner-side after image publication. Document staging as the push-to-`main` path and production as the `workflow_dispatch` `promote` path. Promotion must require `staged_sha` as a full 40-character staged commit SHA, require `backup_confirmed=true` after backup or restore-point readiness is confirmed, verify the requested SHA image set against the current `staging` alias, and then move production `main` aliases without rebuilding. The workflow must read endpoint and resource data only from configured CI variables and secrets. Documentation must not imply Coolify triggers from pull requests, schedules, or release tags unless a later approved workflow change and verifier evidence explicitly establish that behavior. ## Health and Readiness Inspection Health/readiness inspection is separate from deployment proof. Static verification can document repository contracts for `GET /healthz`, `GET /readyz`, API health/readiness responses, and worker health reporting, while live runtime inspection remains manual. Safe verifier references include: ```sh node scripts/verify-health-baseline.mjs pnpm exec vitest run scripts/verify-health-baseline.test.mjs ``` Manual runtime inspection may check web or API health/readiness endpoints, compare request IDs, or inspect worker health output. It must not record database connection strings, Redis URLs, stack traces, tokens, passwords, provider secrets, or other deployment-only values. ## Auto-Mode Exclusions Auto-Mode-safe proof for deployment documentation is limited to static and package-level commands. Auto-Mode must not run live Docker builds, live Docker containers, registry pushes, Coolify dispatches, browser automation, Playwright, Cypress, or E2E commands unless a human explicitly approves that exact focused run in the current session. When porting deployment docs, write manual-only language for those excluded checks. If a document needs to mention a future live deployment, phrase it as a manual verification step and keep the current static contract clear. ## Negative Verification Terms Deployment documentation must fail review when it introduces any of these contract breaks: - Real deploy endpoints, real registry hosts, real Coolify URLs, UUIDs, tokens, passwords, or secret-shaped examples. - Claims that baseline CI, pull requests, schedules, or static verifiers prove production deployment. - Claims that Coolify triggers before all deployable images are published. - Browser, Playwright, Cypress, or E2E commands presented as Auto-Mode defaults. - Unresolved marker words from the common task-note vocabulary. ## Forking To A Different Infra When a fork runs the boilerplate on its own Gitea/registry/runner, the literal infra strings in `.gitea/workflows/*.yml` must change but the verify gates (`scripts/verify-gitea-ci-workflow.mjs`, `scripts/verify-gitea-deploy-workflow.mjs`) keep enforcing structural correctness. Both gates read their expected infra strings from `scripts/infra-config.mjs`, which honours the following optional env vars (fallback values shown in parentheses): | Env var | Default | Used for | | --- | --- | --- | | `TOOLCTRL_CI_RUNNER` | `toolctrl-ci` | `runs-on:` label asserted in every job | | `TOOLCTRL_IMAGE_PREFIX` | `toolctrl` | Docker smoke tags `-{web,api,worker}:smoke` | | `TOOLCTRL_GIT_HOST` | `git.tool-ctrl.de` | `REGISTRY:` and `docker login` host pattern + `/etc/hosts` override | | `TOOLCTRL_REGISTRY_NAMESPACE` | `toolctrl-labs` | Gitea Package Registry namespace expectations | | `TOOLCTRL_DB_USER` | `toolctrl` | Preflight `DATABASE_URL` user component | | `TOOLCTRL_DB_NAME` | `toolctrl` | Preflight `DATABASE_URL` database name | Fork procedure: 1. `sed`-replace the literal `toolctrl-ci`, `toolctrl-{web,api,worker}:smoke`, `git.tool-ctrl.de`, `toolctrl-labs`, and DB credentials in `.gitea/workflows/*.yml` to match the fork's infra. 2. Export the matching `TOOLCTRL_*` env vars in CI so the verify gates assert against the new strings instead of the ToolCTRL defaults. 3. Run `pnpm run verify:gitea-ci-workflow` and `pnpm run verify:deploy-workflow` locally to confirm the fork's workflow shape still satisfies the contract. No verify-gate assertions change. Forks inherit the same structural guarantees without rewriting the Gitea verification scripts. ## Static Verification After editing this guide, use non-E2E checks only: ```sh test -s docs/deployment-porting.md grep -Eq "Gitea|Docker smoke|verify:ci-baseline|verify:gitea-ci-workflow|verify:deploy-workflow|REGISTRY_PAT|COOLIFY_TOKEN|workflow_dispatch|promote|staging|main" docs/deployment-porting.md pnpm run verify:production-docs pnpm run verify:docs-links ``` These checks confirm the guide exists, keeps required deployment contract terms visible, and stays covered by the active docs gates. They do not prove live deployment.