# Deployment Preflight Acceleration

## Status

Design contract for the first mergeable release-speed slice. This document is
the deployment-flow source of truth until the implementation is linked to an
issue or PR.

## Scope Guard

The objective is to fail a staging or production release before its reset,
pack apply, frontend build, target process start, or nginx cutover when
read-only facts already prove it cannot succeed.

This slice adds a `release-preflight.json` gate. Prod keys it by the exact
staging release tag and tag target commit; staging keys it by the exact main
commit selected in the prepared runtime env. Production records the candidate
final-pack hash/tree, runner commands, read-only TiDB connectivity, selected
installed-pack state, and duplicate groups for candidate unique fields.
Staging records candidate identity plus runner and deploy-input admission; its
candidate preflight uses `--admission-only` and does not query the staging
database or installed packs. After the candidate backend starts and its HubSpot
secret is provisioned, both environments also prove signed admission against
that inactive backend before nginx can switch. Production retains HubSpot
read-capacity and Connected Work runtime checks. Staging skips database-dependent
read, runtime, fixture, and matrix validation because its database is a
non-authoritative production replica.

The release preflight is deliberately read-only: no pack install, source
convergence, database reset, admission change, service restart, or nginx
change is permitted. The later signed-admission probe also performs no
mutation; it runs only after the existing candidate startup and secret
provisioning steps have completed.

## Non-Goals

- Do not run normal/clean/materialized 800 pressure gates in staging or prod
  as part of this preflight.
- Do not make `RepairLegacyUniqueDuplicates` an escape hatch.
- Do not claim source convergence can be simulated faithfully here; upstream
  only exposes a mutating `apply-source-convergence` command. This slice
  detects existing `installing` state before that command is reached.
- Do not expose the candidate publicly to test HubSpot admission. The signed
  probe keeps the public URL in its signature but connects directly to the
  inactive candidate port.
- Do not let a deploy mutate the global HubSpot workflow-action definition.
  Deploy-time verification is read-only; an action-definition repair needs a
  separately authorized operator workflow with an explicit rollback contract.

## Design Options

1. Keep all checks after deploy: cheap to maintain but wastes the longest
   stage and can fail after cutover. Rejected.
2. Rebuild and apply the full candidate in a separate preflight: stronger but
   doubles the normal release cost and mutates shared production state.
   Rejected.
3. Read exact candidate metadata from the emitted release tag and compare it
   with read-only production state before expensive deploy stages. Chosen.

## Acceptance

- Prod runs the gate after exact release-tag runtime preparation and before
  backup branch reset; staging runs it after runtime preparation and before
  the expensive blue-green deploy stage.
- The signed HubSpot secret gate runs against the inactive candidate backend
  before nginx/current changes. It signs the public URL but connects directly
  to the candidate port, so it proves the restored runtime secret without
  exposing the candidate publicly.
- Production `hubspot-read` blocks before any backup reset, build, or pack apply.
- Production Connected Work `runtime` blocks against the inactive candidate
  port before nginx/current changes. Staging does not run a post-cutover
  Connected Work matrix.
- HubSpot workflow-action options use `--verify-only` before deploy. A drifted
  external definition blocks before deployment rather than being repaired after
  cutover. After the candidate adapter starts, the same definition is probed
  directly through its inactive options-adapter port before nginx/current
  changes.
- It writes a secret-free JSON artifact and exits non-zero on a blocked check.
- A candidate unique field with a live duplicate group blocks before deploy.
- A selected installed pack left in `installing` blocks before deploy.
- The workflow uploads the artifact on both PASS and BLOCK.

## Follow-Up Slice

Define an explicit, separately authorized HubSpot workflow-action repair
operation with a rollback contract. It must not become a hidden deployment
side effect.
