Release Manifests
A release manifest is the immutable contract between a ThinkWork release and a customer deployment job. It lets the CLI and the customer AWS control plane deploy without cloning the ThinkWork source repository.
What It Contains
Section titled “What It Contains”The manifest includes:
- manifest schema version
- release version
- compatibility bounds
- artifact metadata and SHA-256 hashes
- artifact bundle metadata for machine-consumed platform payloads
- Terraform module or bundle references
- deployment runner/build image reference
- deployment runner script path, SHA-256, and size metadata
- managed-app descriptors for Cognee, Twenty, and Plane
- smoke contracts
- deployment profile schema version
- key id and detached signature metadata when the release is signed
Verification Order
Section titled “Verification Order”- Resolve the controller trust policy for the selected environment.
- For customer-safe runs, require a detached signature and verify it with a pinned trusted ThinkWork public key.
- For dogfood canary runs, unsigned manifests are allowed only when the
controller policy is explicitly
allow_unsigned_canary; evidence must mark the manifest as an unsigned canary. - Reject expired or revoked signing keys.
- Verify compatibility bounds for the CLI and runner.
- Resolve releases by explicit version/tag plus manifest digest. Do not use
GitHub’s
Latestbadge as deployment authority for canary validation. - Download artifact bundles only after the manifest is trusted.
- Verify the platform bundle SHA-256, extract it with traversal/link checks, and verify every contained artifact SHA-256 before Terraform, static assets, or runtime bundles consume it.
- Record the raw manifest digest, canonical manifest digest, trust decision, bundle digest, and staged artifact digests on deployment jobs and smoke evidence.
GitHub Release Assets
Section titled “GitHub Release Assets”Human-facing GitHub Releases should stay small. For deployable platform releases, the expected machine-consumed assets are:
thinkwork-release.jsonthinkwork-release.sig.jsonwhen release signing is enabledplatform-artifacts.tar.gz
The platform bundle contains backend Lambda zips, static-site archives, and the
deployment runner script under runner/thinkwork-runner.py.
Individual artifact URLs in the manifest are a compatibility path; new
deployment controller runs should consume the bundle and verify every contained
artifact against the manifest before staging it.
components.deploymentRunner.script records the staged runner script’s
relativePath, optional direct url, SHA-256, and size. Settings release
preflight uses that metadata to compare a customer’s frozen S3 runner with the
selected release. Runner refresh remediation must copy the trusted selected
release script only after the manifest and platform bundle have been verified,
and evidence should record both the previous runner object and the target
script digest.
The manifest asset is also the publish finalization marker. Release automation
removes any existing thinkwork-release.json before refreshing deployable
assets, uploads the platform bundle and signature first, and uploads the final
manifest last. If a refresh fails midway, the release should be temporarily
non-deployable instead of presenting an old manifest digest with newer assets.
Managed-app descriptors and runtime images are one contract. If a release
manifest advertises a managed app with requiredImages, every required image
name must appear in runtimeImages as an immutable @sha256: URI. The release
publisher builds the ThinkWork-owned Cognee image and reads pinned Twenty and
Plane image URIs from repository variables so the controller can fail before
Terraform when an optional app cannot be deployed from the selected release.
The default release manifest currently advertises:
| Managed app | Required runtime image | Smoke contract |
|---|---|---|
| Cognee | cognee | plugins/company-brain/smoke/cognee-managed-app-smoke.mjs |
| Twenty CRM | twenty | plugins/twenty/smoke/twenty-managed-app-smoke.mjs |
| Plane | plane | plugins/plane/smoke/plane-managed-app-smoke.mjs |
Plane’s release descriptor is only deploy-ready when the selected manifest
contains a digest-pinned Plane runtime image. The image URI must use @sha256:
rather than a mutable tag because the deployment runner passes the selected
manifest image directly into Terraform.
Desktop assets may be published by a separate workflow, but operators should see
one coordinated release version. The human-facing release should contain
desktop installers, updater metadata, thinkwork-release.json, and
platform-artifacts.tar.gz before the release is treated as a deployable
environment update.
Unsigned canaries are for ThinkWork dogfood and TEI proving runs only while the
signing key rollout is in progress. Production and customer-safe controllers
should set release_manifest_trust_policy = "require_signature" and configure
trusted public keys before accepting a release.
The TEI proving environment accepted v0.1.0-canary.149 under the explicit
allow_unsigned_canary trust policy. Evidence records both the raw manifest
SHA-256
f25c6a05d42578acd6f4696d678b19af831c6e19a23e227e07a6db9559f47532 and the
platform bundle SHA-256
b463b44094d60e94ee068881343deab53bb65d6d081b69757dcc04afb181aad8.
Upgrade Evidence
Section titled “Upgrade Evidence”Release upgrade evidence should record:
- previous release version and manifest digest
- target release version and manifest digest
- target deployment runner script digest and path
- platform bundle digest and staged artifact digests
- Step Functions execution ARN
- CodeBuild build ARN/id
- Terraform plan and apply artifact keys
- post-upgrade foundation smoke result
- managed-app smoke results for enabled apps, including Plane when it is provisioned or parked
Settings Preflight Contract
Section titled “Settings Preflight Contract”The Settings release workflow consumes the release manifest before dispatching the customer deployment controller. The preflight job must verify and persist:
- target manifest URL and SHA-256
- manifest signed/unsigned state and trust policy
- selected release Terraform module or bundle version
- selected release runner script path, SHA-256, and size
- deployed frozen S3 runner compatibility
- preserved customer configuration summary
- known IAM drift checks required by the selected release class
- evidence bucket/prefix and final status pointer
Dispatch must use the release-update job id created by preflight. It must not restart the old direct path that sends only release version, manifest URL, and manifest SHA-256 to the controller.
The preflight summary is intentionally operator-facing. It should make customer domain, delegated/legacy-retired flags, SES sender settings, platform operator emails, identity/OAuth posture, and optional app flags visible before the operator can start the controller.
Failure Triage
Section titled “Failure Triage”| Failure | Meaning |
|---|---|
| Missing signature | The controller requires a trusted signature and no detached signature was available. |
| Unsigned non-canary manifest | The selected release is not a canary and cannot run under allow_unsigned_canary. |
| Invalid signature | The manifest cannot be trusted. Stop and fetch a known-good manifest. |
| Unknown key | The runner does not trust the signing key. Update trusted keys only through a reviewed release. |
| Revoked or expired key | Do not deploy. Use a release signed by an active key. |
| Artifact hash mismatch | The artifact does not match the manifest. Stop before Terraform or runtime update. |
| Compatibility mismatch | Upgrade the CLI/runner or choose a compatible release. |
| Missing managed-app smoke metadata | The release is not usable for managed-app deployment. |
| Missing managed-app runtime image | The release advertises an app that cannot be deployed from its manifest. |
| Runner mismatch | Refresh the S3 runner from the selected trusted release before dispatch. |
| IAM drift | Block dispatch until the live CodeBuild role can satisfy the selected release class. |
Operator Notes
Section titled “Operator Notes”ThinkWork can continue to publish release assets from the ThinkWork-owned GitHub project. Customer deployments consume signed release artifacts from the release manifest; they do not need a customer source repo or customer GitHub Actions.
See docs/runbooks/settings-release-upgrades.md for the operator runbook and
docs/verification/settings-release-upgrade-safety.md for the regression
checklist.