Documentation portal operations
This guide owns the infrastructure lifecycle for https://guildcontrol.lasers.app. The release runbook owns version publication and treats a healthy, exact documentation deployment as a precondition. It does not duplicate hosting setup here.
Deployment contract
Section titled “Deployment contract”GuildControl publishes an assets-only Cloudflare Worker from site/wrangler.jsonc. The canonical site is a deterministic Astro build with no runtime origin, server function, secret, or Discord access. The stable workers.dev route remains available for bootstrap and provider-level diagnosis, while per-version preview URLs are disabled and canonical metadata remains bound to guildcontrol.lasers.app. The tracked Worker configuration also disables Wrangler telemetry for this project.
The CI workflow separates verification from authority:
- The
Documentation portaljob installs locked dependencies, generates the site from the checked-out source, runs static, unit, browser, accessibility, and link checks, dry-runs the Worker deployment, and uploadssite/distas the genericdocumentation-portalartifact. - The
CI gaterequires the documentation job and every other release-quality job to pass. - The
Publish documentation portaljob runs only for protectedmainpushes or an explicitdeploy-documentationdispatch atmain. It downloads the verified artifact from the same workflow run, receives the deployment credential only from the protecteddocumentationenvironment, uploads those exact files, and checks the public manifest over HTTPS.
Pull requests, scheduled checks, build steps, browser tests, and artifact uploads never receive a Cloudflare credential. CI has no DNS or custom-domain authority.
One-time Cloudflare and GitHub setup
Section titled “One-time Cloudflare and GitHub setup”Use Cloudflare Workers Static Assets for the site and keep the Worker name guildcontrol.
- Create a GitHub Actions environment named
documentationand restrict its deployment branches to protectedmain. A required reviewer is unnecessary for this public static site because the protected branch and complete CI gate already define the reviewed content boundary. - Set the environment variable
CLOUDFLARE_ACCOUNT_IDto the deployment account identifier. This identifier is routing metadata, not a credential. - Create a dedicated account-owned Cloudflare API token named
j-256/guildcontrol Worker deploy token. Limit its account resource to the deployment account and grant only Workers Scripts Write. - Capture the returned-once token directly into the maintainer password manager and the environment secret
CLOUDFLARE_WORKERS_DEPLOY_TOKEN. Never print it, place it in shell history, write it to a repository or temporary file, or reuse a broader operator token. - Build and dry-run the exact site before the first upload:
npm run deps:lockednpm run buildnpm --prefix site run deps:lockednpm --prefix site run browser:installnpm --prefix site run verifynpm --prefix site run deploy:dry-run- Bootstrap the Worker with the dedicated token available only in the process environment, then discard the process-local value. The tracked deployment command is
npm --prefix site run deploy; do not add an alternate dashboard build configuration.
The Workers Scripts Write token can upload Worker code and assets. It cannot edit DNS or attach a custom domain. Keep those authorities with a maintainer credential used only during deliberate infrastructure operations.
Custom-domain cutover
Section titled “Custom-domain cutover”Cloudflare cannot attach a Workers Custom Domain while a conflicting DNS record exists. Follow the official Pages-to-Workers migration and Custom Domain procedures in this order:
- Confirm the Worker upload completed and the exact local
site/dist/generated/docs-manifest.jsonis retained for verification. - Remove the custom-domain binding from the old GitHub Pages site.
- Delete only the exact DNS record for
guildcontrol.lasers.app. Do not change the wildcard*.j-256.devrepository redirect or unrelatedlasers.apprecords. - Attach
guildcontrol.lasers.appto theguildcontrolWorker as a Custom Domain. Let Cloudflare create and manage its DNS record and certificate. - Require a valid HTTPS response and run:
node scripts/check-public-documentation.mjs \ --manifest site/dist/generated/docs-manifest.json \ --attempts 6 \ --delay-ms 10000- Merge the prepared deployment change, or explicitly redeploy the exact
maincommit withgh workflow run ci.yml --ref main -f operation=deploy-documentation, then requirePublish documentation portalto upload the same verified artifact and pass its independent public check. - Set the GitHub repository homepage to
https://guildcontrol.lasers.app, disable the obsolete GitHub Pages site, and confirm that no Pages deployment action or Pages-specific repository authority remains.
Do not delete the old Pages configuration before the Worker and rollback inputs are ready. If the custom-domain verification fails during cutover, detach the Worker domain and restore the exact prior Pages binding and DNS record while diagnosing the Worker separately.
Routine deployment and recovery
Section titled “Routine deployment and recovery”A protected main push deploys automatically after the full CI gate. An explicit deploy-documentation workflow dispatch at main provides a credential-rotation or same-commit recovery path without changing source. The default verify dispatch runs the high-cost external evidence checks without deploying. No path rebuilds inside the privileged job.
For a content or configuration regression, revert the responsible commit through the normal protected pull-request path. Avoid dashboard edits because they create unreviewed state that the source manifest cannot explain. For a suspected credential leak, revoke the token first, create a replacement with the same narrow policy, update the password-manager entry and environment secret, and dispatch the workflow at main to prove the replacement.
The public verifier compares the deployed documentation manifest and every declared output with the verified local artifact. It proves exact publication of those bytes at the canonical origin. It does not prove that Cloudflare, DNS, GitHub, dependencies, or the documented product behavior are free of vulnerabilities.
Canonical source: docs/documentation-portal.md
Documentation generated for guildcontrol@0.0.0. Canonical source and edit history remain in the public repository. GuildControl is an independent project and is not affiliated with or endorsed by Discord Inc. Discord is used only to identify the platform that GuildControl connects to.