Repository navigation
Phase 2: the single-host cutover, prepared (do not merge before Access steps A to E) - #112
Merged
Merged
Conversation
…e composer Worker, behind Access) Under the owner's single-host amendment, the invite-only beta is the existing Composer: composer.aesthetic-function.com and its Worker, dspack-studio-composer, behind Cloudflare Access. This change retargets the experimental deploy path at that Worker and hardens the default config. It deploys nothing by itself: its merge redeploys only the block-free default artifact through Workers Builds, and the owner merges it at step F.1 of the cutover order, after Access is configured and verified (A to E). - wrangler.jsonc: workers_dev false, preview_urls false, keep_vars true, and no vars; HOSTED_AI moves to the dashboard (absent means on). - wrangler.composer-beta.jsonc -> wrangler.composer-experimental.jsonc: the same Worker, route, runtime, bindings and rate-limit namespace as wrangler.jsonc, serving apps/composer/out-experimental. - deploy-composer-beta.yml -> deploy-composer-experimental.yml: dispatch-only from main through the protected composer-experimental environment, with its own token (CLOUDFLARE_API_TOKEN_EXPERIMENTAL). Before every deploy it checks that anonymous GET and POST requests already go to the Access login, and it records the rollback anchor or refuses. There is no first deploy. - check-beta-deploy.mjs -> check-experimental-deploy.mjs: both configs are the one composer Worker with one custom-domain route and no custom-domain Preview URLs, equal apart from the artifact. The Access check adds an empty-body POST to /api/propose, and refuses any failure to reach the hostname. - Tests: experimental-deploy.test.mjs, written fail-first (59 assertions failed against the old guard, configs and workflow), and the operator-log config check. - Docs: deployment.md's single-host runbook replaces the superseded beta section. BLOCKS.md, BETA-DEPLOY-PLAN.md, BETA-OPERATIONS.md, the decision record, the plan's status note and backlog rows O2, O10 and O12 are updated. No application, Worker code, block code or request builder changes. No new hostname, subdomain or Worker is created or named. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01R6Ax8qvfN3gYUC85oSGnoi
Deploying with
|
| Status | Name | Latest Commit | Updated (UTC) |
|---|---|---|---|
| ✅ Deployment successful! View logs |
dspack-studio-composer | 9908313 | Oct 17 2026, 07:15 PM |
…loys, guard, tests) An independent review of 3164245 found no material defect and seven minor ones. This commit fixes six, written fail-first: - The anchor is read as JSON. `wrangler deployments status --json` is parsed by the guard's new --active-version mode, and only the one version the latest deployment serves at 100% is accepted. A gradual split or a listing refuses, and the summary records "anchor: <id>". - A partial deploy is still checked. wrangler makes the new version live before it publishes the custom domain's settings, so the deploy step has an id, and the record and post-deploy Access check run whenever it ran, even when it failed. - readConfig refuses a "__proto__" key at any depth, escaped or not. The parser turns one into a prototype that Object.keys never shows and wrangler still reads. - Both configs set previews_enabled false on the custom-domain route, so every deploy turns the custom domain's own Preview URLs off. wrangler 4.146.0 and 4.151.1 read both configs offline with no warning. - The workflow tests now fail on each regression the review showed passing: if: always(), || true, a workflow-level token, an extra --var or --route, a softened step condition, and a dropped persist-credentials. - The --access and --active-version modes load nothing from node_modules. The seventh, the job split that would make the token boundary real, is recorded as backlog O14. The same holds for Workers Builds' own build and deploy. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01R6Ax8qvfN3gYUC85oSGnoi
…klog rows The reviewer's verification of 721242c resolved five of the seven findings and confirmed the deferral of the sixth. Its one material item, NEW-1, was conditional: Workers Builds' own wrangler must accept previews_enabled on the route. It does: the Workers Builds branch build of 721242c, which reads this same wrangler.jsonc, succeeded. This commit closes NEW-2, the two test gaps it found. Both mutations now fail a test, and the seven earlier ones still do: - exactly one step may deploy, and after the guard only the two post-deploy steps may carry a condition, so a retry step with if: failure() fails; - a workflow-level env written in flow style fails like a block one. Backlog: O14 now names the repository's own guard script among what build code could rewrite. New row O15 pins the wrangler Workers Builds runs. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01R6Ax8qvfN3gYUC85oSGnoi
There was a problem hiding this comment.
🔵 Needs a closer look
The production-host cutover requires the owner to verify and record Access steps A–E before merging.
No open issues 🎉
What changed in this PR
Prepares the invite-only experimental build for the existing Composer Worker behind Cloudflare Access, without changing application code or creating another host.
Changes:
- Hardens both deployment configs while preserving the block-free default artifact.
- Replaces the separate-beta workflow with mandatory Access checks and rollback-version recording.
- Updates regression tests and single-host operational documentation.
| File | Description |
|---|---|
wrangler.jsonc |
Disables alternate URLs and preserves dashboard variables. |
wrangler.composer-experimental.jsonc |
Targets the existing Worker with experimental assets. |
wrangler.composer-beta.jsonc |
Removes the separate-Worker config. |
docs/deployment.md |
Documents single-host deployment, switches and rollback. |
docs/blocks/RELEASE-REVIEW.md |
Updates test references. |
docs/blocks/POST-BETA-BACKLOG.md |
Records completed safeguards and deferred hardening. |
docs/blocks/PHASE-2-RELEASE-PLAN.md |
Updates deployment-path status. |
docs/blocks/PHASE-2-DECISION-RECORD.md |
Records replacement of the separate-beta path. |
docs/blocks/BETA-OPERATIONS.md |
Clarifies variable persistence and rollback behavior. |
docs/blocks/BETA-DEPLOY-PLAN.md |
Updates cutover checks and deployment safeguards. |
docs/BLOCKS.md |
Describes single-host block-delivery controls. |
apps/composer/worker/operator-log.test.mjs |
Checks both configs preserve dashboard variables. |
apps/composer/scripts/check-experimental-deploy.mjs |
Validates configs, artifacts, Access and active versions. |
apps/composer/scripts/check-beta-deploy.mjs |
Removes the superseded guard. |
apps/composer/lib/experimental-deploy.test.mjs |
Tests the single-host deployment safeguards. |
apps/composer/lib/beta-deploy.test.mjs |
Removes the superseded tests. |
.github/workflows/deploy-composer-experimental.yml |
Adds guarded deployment to the existing Worker. |
.github/workflows/deploy-composer-beta.yml |
Removes the separate-beta workflow. |
Review effort: Balanced
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What this is
The single-host cutover change, prepared for review. Under the owner's single-host amendment, the experimental artifact deploys to the existing composer Worker,
dspack-studio-composer, oncomposer.aesthetic-function.com, behind Cloudflare Access (docs/blocks/BETA-DEPLOY-PLAN.md). No new hostname, subdomain or Worker is created or named.Do not merge before steps A to E of the cutover order are done and recorded:
The owner merges it at step F.1. This PR deploys nothing by itself. Its merge redeploys only the block-free default artifact, through Workers Builds, with the hardened config. The release candidate's application code is unchanged, so that deployment is the rollback anchor.
What changes
wrangler.jsonc(Workers Builds,deploy-composer). It still serves the block-freeapps/composer/outon the same Worker and route, and gains:workers_dev: false,preview_urls: falseandkeep_vars: true, andpreviews_enabled: falseon its one custom-domain route, so every deploy turns the custom domain's own Preview URLs off;vars:HOSTED_AImoves to the dashboard. Absent means on, and the value already set there is kept.wrangler.composer-beta.jsonc→wrangler.composer-experimental.jsonc. The same Worker (dspack-studio-composer), route (composer.aesthetic-function.com), runtime, AI binding and rate-limit namespace (1001) aswrangler.jsonc, servingapps/composer/out-experimental. The two configs differ only in the assets directory.deploy-composer-beta.yml→deploy-composer-experimental.yml.main, through the protectedcomposer-experimentalenvironment.CLOUDFLARE_API_TOKEN_EXPERIMENTAL, never the repository's productionCLOUDFLARE_API_TOKEN. A dispatch to an environment that does not exist yet would create it unprotected, so the run then refuses for want of the secret instead of reaching the production token./api/models, static assets) and an anonymous POST to/api/proposeall go to the Cloudflare Access login.wrangler deployments status --json. It refuses otherwise, a gradual split included. There is nofirst_deploy.check-beta-deploy.mjs→check-experimental-deploy.mjs.previews_enabled: false.__proto__key anywhere in either config is refused. The parser would turn it into a prototype that every key check misses and wrangler still reads.keep_varson, and neither config may declare vars or env.--accessand--active-versionmodes load nothing fromnode_modules.beta-deploy.test.mjs→experimental-deploy.test.mjs, written fail-first: 59 of its assertions failed against the old guard, configs and workflow.if: always(),|| true, a workflow-level token, an extra--varor--route, a softened step condition, and a droppedpersist-credentials.operator-log.test.mjs: neither config declares vars.docs/deployment.mdgets "The invite-only beta" runbook, replacing the superseded beta section. It covers the switches, the rollback, which restores the target version's variables, the stop conditions, and what now meets the Access login.docs/BLOCKS.mdlayer 2,BETA-DEPLOY-PLAN.md(step C's command, the cutover-change section),BETA-OPERATIONS.md, the decision record, the plan's status note and backlog rows O2, O10 and O12 are updated to match.Nothing in the application, the Worker's code, the block code or the request builders changes.
Safeguards
apps/composer/out. Its branch builds runwrangler versions upload, which only reads the Worker's subdomain settings and never changes them (wrangler 4.146.0).maindeploys the block-free default artifact, an automatic rollback, until the workflow is dispatched again.HOSTED_AI,BLOCKS_BETAandBETA_OPERATOR_LOGagain after every rollback.Review
One independent adversarial review of 3164245 found:
0 material findings;
7 minor findings. 721242c fixes six:
__proto__guard;previews_enabled: false;The seventh, splitting the workflow into a build job and a deploy job so the token boundary is real, is backlog O14. Workers Builds' own build and deploy share one container the same way.
The same reviewer then verified 721242c:
previews_enabledon the route, since an unknown route key is a hard error. Cleared: the Workers Builds branch build of 721242c, which reads this samewrangler.jsonc, succeeded. Pinning that wrangler is recorded as backlog O15.if: failure()and a flow-styleenv:. 9908313 closes both: exactly one step may deploy, only the two post-deploy steps may carry a condition after the guard, and any workflow-levelenvfails.Checks
Fail-first: 59 failing, then 123 of 123 in
experimental-deploy.test.mjsandoperator-log.test.mjs. The review round's tests: 8 failing, then 136 of 136; now 137 of 137. Each of 9 workflow mutations fails a test: the review's seven and the verification's two.Locally,
pnpm typecheckexited 0, andpnpm testpassed in every workspace:The composer suite was re-run on the final tree after rebasing onto the merged docs (510 of 510), and after the review's fixes (523 of 523, typecheck exit 0, then 524 of 524).
wrangler 4.146.0 and 4.151.1 read both configs offline with no warning, with
previews_enabled: falseon the route and empty vars. Workers Builds' own branch builds of 3164245 and of 721242c, which has the route key, succeeded.Every relative link resolves. No new em-dash: the one in an added line of
wrangler.jsoncis the existing comment's, re-wrapped.🤖 Generated with Claude Code
https://claude.ai/code/session_01R6Ax8qvfN3gYUC85oSGnoi