{"protocol":"clank-doc/1","frameworkVersion":"0.24.0","slug":"release-windows","title":"Scheduled release windows","description":"Schedule an exact current release channel pin for a bounded maintenance window. The controller retains the reviewed source artifact, target binding, active target release, dependency configuration and initiating credential identity. It atte","group":{"id":"deploy","title":"Deploy and operate"},"url":"https://docs.clank.run/docs/release-windows","source":"docs/release-windows.md","headings":["Review and queue","Current authority and readiness","Cancellation and recovery","Bounds, retention and compatibility","HTTP and types"],"tableOfContents":[{"id":"review-and-queue","title":"Review and queue","level":2},{"id":"current-authority-and-readiness","title":"Current authority and readiness","level":2},{"id":"cancellation-and-recovery","title":"Cancellation and recovery","level":2},{"id":"bounds-retention-and-compatibility","title":"Bounds, retention and compatibility","level":2},{"id":"http-and-types","title":"HTTP and types","level":2}],"markdown":"# Scheduled release windows\n\nSchedule an exact current [release channel](release-channels.md) pin for a bounded maintenance\nwindow. The controller retains the reviewed source artifact, target binding, active target release,\ndependency configuration and initiating credential identity. It attempts activation no earlier\nthan the start and publishes acceptance only before expiry. Scheduling does not reserve a clock\ninstant or guarantee delivery: controller downtime, work already running and provider latency can\nconsume the window. Expired work cannot publish a release.\n\n## Review and queue\n\nUse **Project → Environments → Release channels → Schedule current pin**, or `clank release-window`\nin a directory linked to the environment family root. Inspect the current channel, environment,\nactive target release and target dependency configuration before preparing a data-only request.\nThe following illustrative JSON requires your actual IDs, versions and future timestamps:\n\n```json\n{\n  \"channel\": \"stable\",\n  \"expectedVersion\": 1,\n  \"targetEnvironment\": \"staging\",\n  \"expectedEnvironmentVersion\": 1,\n  \"expectedActiveReleaseId\": \"EXACT_ACTIVE_TARGET_RELEASE\",\n  \"expectedDependencyVersion\": 0,\n  \"idempotencyKey\": \"reviewed_release_window_0001\",\n  \"startsAt\": \"2026-11-01T01:30:00-05:00\",\n  \"expiresAt\": \"2026-11-01T01:45:00-05:00\",\n  \"timeZone\": \"America/Chicago\"\n}\n```\n\n```sh\nclank release-window queue --request=release-window.json --json\nclank release-window list --json\nclank release-window show EXACT_WINDOW_ID --json\n```\n\nTimes require a valid ISO calendar date, seconds and an explicit `Z` or UTC offset. Bare local\ntimes are rejected. The window starts in the future, ends within the next 30 days and lasts at\nmost 24 hours. `timeZone` selects the IANA timezone for a review preview; it does not reinterpret\nthe supplied instants. During the repeated autumn hour, `01:30:00-05:00` and `01:30:00-06:00`\nare different instants, which the UTC fields and offset-bearing preview distinguish. The API\nnormalizes accepted instants to UTC.\n\nThe dashboard reviews the artifact digest, source entry, target identity, binding version,\nexpected active release, migration policy, dependency version, UTC instants and selected timezone.\nEditing fields invalidates approval. A lost queue response retains the exact request and key;\n**Retry exact channel request** inspects or returns the original schedule, without queueing another\nactivation. CLI retries reuse the unchanged JSON and attestation. Changing any approved field or\ninitiating credential under the same key returns `RELEASE_WINDOW_RETRY_CHANGED`, including after\nacceptance or expiry. A new attempt requires a fresh review and new key.\n\nSigned-release installations require `--attestation=target-attestation.json`, or the same bounded\nfile in the dashboard. The target-bound signature is checked when queued and again through the\nnormal activation path. Scheduling stores credential IDs and original scope, never raw bearer\ncredentials, session cookies or CSRF tokens. Public observations exclude those IDs and attestations.\n\n## Current authority and readiness\n\nQueueing and execution require current family-root deploy permission, source read permission,\ntarget deploy permission and independent projects in the same workspace. Production additionally\nrequires a current workspace owner/admin. Revoking the initiating token, signing out its browser\nsession, changing its original scope or removing required authority prevents acceptance even if\nthe work was already staged. Impersonation cannot schedule releases.\n\nExecution rechecks the approved current channel, source binding, target binding, expected active\ntarget and dependency configuration. A newer pin or changed target makes the old schedule fail.\nRequired services are checked at execution and acceptance; a queue-time health check is never\nstored as authority. Schedules cannot carry a human readiness override. Normal artifact retention,\nmigration, current secrets, quotas and [provider host certification](environment-promotions.md)\ncontinue to apply. A provider target must meet the existing co-located `code-only` promotion\ncontract; scheduling does not permit new provider migrations.\n\n## Cancellation and recovery\n\n```sh\nclank release-window cancel EXACT_WINDOW_ID --expected-version=1 --json\nclank release-window recover EXACT_WINDOW_ID --expected-version=3 \\\n  --confirm='recover-release-window FAMILY_ROOT_SLUG EXACT_WINDOW_ID' --json\n```\n\nRead the current schedule before either operation. Exact-version cancellation can stop pending\nwork or mark running work `cancelling`, including while health checks are waiting. It prevents\nacceptance and verifies compensation before reporting a terminal result. The initiating user may\ncancel while still authorized; cancelling another user's work requires workspace administration.\nAn accepted schedule is terminal and cannot be cancelled or executed again.\n\nStates are `pending`, `running`, `cancelling`, `accepted`, `failed`, `cancelled`, `expired` and\n`recovery-required`. Failed health, cancellation, expiry or lost authority restore the prior writer\nthrough the existing promotion path. Local `apply-safe` recovery restores its pre-operation database.\nProvider `code-only` recovery preserves already committed application writes, including writes by\nan unpublished healthy candidate; cancellation is not a data rollback. Uncommitted provider data\napplication is recovered through its journal. An interrupted migration or unverifiable cleanup\nremains visibly fenced. The dashboard shows the exact recovery phrase; recovery requires current\nworkspace administration, target rollback authority and any configured recent-authentication\npolicy. It finishes only after the underlying exact promotion is verified as failed and its prior\nwriter can safely return. Failed, cancelled and expired schedules never silently retry; review a\nnew request after recovery.\n\nDurable claims use the existing transactional control store and project leases. Restarts resume\npending work and exact provider generations; acceptance commits the schedule, channel action,\nenvironment promotion and dependency receipt in the same transaction. A controller crash after\nacceptance cannot reactivate the artifact. These contracts do not establish replicated-controller\nleadership, multi-region failover or a cross-store scheduler.\n\n## Bounds, retention and compatibility\n\nEach family retains at most 100 unresolved schedules and 1,000 schedules total. History is not\nsilently pruned: exact request fingerprints remain reserved and the total bound can be exhausted.\n`RELEASE_WINDOW_CAPACITY` or `RELEASE_WINDOW_HISTORY_CAPACITY` requires operator inspection, not\nreuse of an old key. Lists show the newest 100 currently authorized schedules; an exact ID reads\nany authorized retained row. Current access to root, source and target filters inspection.\n\nUnresolved schedules protect their channel from retirement and referenced projects from deletion.\nTheir source uploads are protected by the retained channel pin. Keep control metadata and uploads\ntogether in recovery backups. The schema is additive and existing immediate promotion fingerprints\nremain unchanged. Before downgrading to a controller without scheduling support, cancel pending\nwork and finish or recover every unresolved schedule using the compatible controller. Older\ncontrollers cannot enforce these schedule pins or execute their durable work. Configuring\n`releaseWindows: { intervalMs: false }` pauses automatic execution for an owned maintenance period;\nit does not extend approved windows. The default interval is 1,000 ms, with supported intervals\nfrom 100 to 60,000 ms.\n\n## HTTP and types\n\nRoutes are under `/api/projects/:root/release-windows`. Browser writes require the existing\nsession and CSRF checks; bearer requests retain their original credential scope.\n\n| Method and suffix | Contract |\n| --- | --- |\n| `GET /` | Newest 100 currently authorized retained schedules. |\n| `POST /` | Exact JSON fields above; optional `x-clank-release-attestation`; returns `schedule` with status 201. |\n| `GET /:id` | One exact currently authorized schedule. |\n| `POST /:id/cancel` | `expectedVersion`; returns the current cancellation result. |\n| `POST /:id/recover` | `expectedVersion`, exact `confirmation`; finishes verified prior-writer recovery. |\n\nImport `PlatformReleaseWindowRequest`, `PlatformReleaseWindow`, `PlatformReleaseWindowCancelRequest`\nand `PlatformReleaseWindowRecoveryRequest` from `@clank.run/framework/platform`. The dependency\nversion, nullable expected active release and explicit instants are required. Observation fields\nare readonly. Readiness overrides and queue-time check IDs are excluded from the request type.\n"}