Approval Workflows

Approval is the separation-of-duties gate between authorship and execution. It ties a human sign-off to the SQL that was reviewed (changing it returns the script to pending), enforces four-eyes review when Allow Self-Approval is off, supports revise-and-resubmit, and records every transition in the tamper-evident audit log. The Decision Flight Recorder adds point-in-time schema evidence.

Statuses

A script's approval status and an approval request's status are separate: a script can be approved directly by an Approver, or through an approval request that collects the required signatures.

Script statusMeaningNext
PendingNew, edited, resubmitted or revoked; not yet approved.Approved | Rejected
ApprovedReviewed; can be run and can join a release.Pending (its SQL or rollback SQL changes, or its approval is revoked)
RejectedReviewed and refused, with the reviewer's reason.Pending (Resubmit)
Request statusMeaningNext
PendingWaiting for signatures.Approved (enough signatures) | Rejected | withdrawn by the requester
ApprovedSigned by enough people; a script request approves the script, a release request opens that environment.Pending (revoked)
RejectedRefused, with who rejected it, when and why.Final: request approval again

Running is recorded in executions and release runs, not as an approval status.

Requesting Approval

From a pending script, Request Approval asks how many approvals the script needs (a whole number from 1 to 10, starting at the default required approvers) and creates the request for the script's own environment; the toast names the script, its environment and the approvals it needs. The button is hidden while a pending request exists for the script's current SQL. A release is put up for approval per environment from its detail, after it is signed off.

Review

Approvers, Release Managers and admins act on pending requests, looking at the SQL, its revision, the blast radius and any shadow run, then Sign Approval or Reject with a reason. Substantive review dimensions:

AI Review

When an AI provider is set up and the script review mode is manual, a pending script request has AI Review. The review shows the risk (Low, Medium, High or Critical), a summary, and each finding with its severity, what kind of finding it is (for example No WHERE clause or Destructive change), its line and a suggestion. A review that cannot finish, such as an answer from the AI model that is not in the review format, says so with the reason instead of guessing a risk, and Review Again runs it again. Dismiss clears the review.

Revise and Resubmit

A rejected script shows the reviewer's reason. The author edits it (a change to the SQL or the rollback SQL moves the script to its next revision) and chooses Resubmit, which returns it to Pending on the server, clears the rejection, and records the resubmission in the audit log; approval can then be requested again. Only a rejected script can be resubmitted. Cycles are unbounded until approval or abandonment.

Revocation

Approvers, Release Managers and admins can revoke an approved request from the Approvals view. Its signatures are cleared and it returns to Pending; for a script request the script returns to Pending too, and so does any signed-off release that contains it. Use when a requirement changes, a defect surfaces, the target schema drifts after approval, or approval was granted in error.

Working in the Approvals View

Sign Approval, Reject and Revoke are shown to Approvers and above, and each takes effect only after the server confirms it. Every decision names the request it changed (for example Signed "add index": 1 of 2 approvals or Approved "Spring" in Production), and a refused action names the request and gives the server's reason. You can sign a request once, and only while it is pending. Each card and the request detail name the environment and show how many approvals the request has of how many it needs, and who requested it and when. A request for a release is titled with the release name, shows the release version and the environment it is for, and has no script actions. A script, or a release in one environment, has at most one pending request at a time; a release can be put up for approval only after it is signed off, because only an approval made after the sign-off opens the environment. Everyone who can sign is notified of a new request.

Search the list by script or release name, environment or requester, and filter it by status or by script and release requests. A script request's detail shows the blast radius chip and the Shadow Run control beside Snapshots, so the reviewer can check the impact before signing. Each signature shows when it was made, in your time zone, and any comment the approver left; while a request is pending you can Withdraw your own signature (an admin can withdraw anyone's).

Rejecting needs a reason: Reject asks for it, and an empty reason changes nothing. The request then shows who rejected it, when and why, and an approved request shows when it was approved. Revoke says what revoking does before it does it. While a request is pending, the person who requested it (or an admin) can Withdraw Request; approved and rejected requests stay, because they are part of the approval record.

Approval Settings

Under Settings, Approval Settings holds two server-side settings that admins change with Edit: Default Required Approvers (a whole number from 1 to 10; any other value is refused and nothing is saved), the number of signatures a new request needs when the requester does not choose one (Request Approval starts at it), and Allow Self-Approval. The panel also lists the environments that require approval; that is set on each environment, under Environments.

Approval Resets When the SQL Changes

Every script has a revision number that increases whenever its SQL changes, whether in the editor or from a repository pull, and whenever its rollback SQL is edited; the script detail shows it. An approval request records the revision and a SHA-256 of the SQL and of the rollback SQL it was made for. If either changes while the request is pending, the request can no longer be signed: the Approvals view says which revision it was for and which is current, and approval can be requested again for the current version. The audit entries for requesting, signing, rejecting and revoking a script approval name the revision and both hashes, so the record shows exactly which SQL and rollback each decision was about.

Editing the SQL or rollback SQL of an approved script, or pulling a changed version of it from a repository source, returns it to Pending, and every signed-off release that contains it returns to Pending as well. A release sign-off also records the SHA-256 of each script's SQL; a run whose scripts no longer match is refused, so a release never runs SQL other than what was signed off.

Approval Audit Trail

Every action is appended to the tamper-evident audit log: requesting, signing (with the comment), rejecting (with the reason), withdrawing a signature, revoking, resubmitting and withdrawing a request. Each entry records who acted and when; entries about a script request also record the script revision and the SHA-256 of its SQL, so the record shows exactly which SQL each decision was about.

Decision Flight Recorder

The Decision Flight Recorder captures point-in-time, read-only evidence of the target's structure at the moments that define an approval, so reviewers and auditors can see exactly what the database looked like at request and at sign-off. Snapshots record schema and statistics only, never row data or credentials.

Capture Triggers

Capture runs in the background after the approval action commits and never blocks or fails it; an incomplete collector yields a partial or failed snapshot with a reason rather than a lost record.

Snapshot Contents

SectionContent
SchemaIntrospected tables, views, materialized views, functions, procedures, sequences per schema.
Data ShapeFor each object the script changes: its size in the engine's own unit (rows, or documents on MongoDB and Elasticsearch, nodes on Neo4j, keys on Redis), its size on disk or in memory, and per column, field or property the share of empty values and the number of distinct values, as far as the engine keeps them. Read on every engine from its own statistics: pg_class and pg_stats on PostgreSQL and TimescaleDB, SHOW STATISTICS and the table's ranges on CockroachDB, information_schema and column histograms on MySQL (index cardinality on MariaDB), partition counts and statistics histograms on SQL Server, the dictionary statistics on Oracle, exact counts on SQLite, $collStats on MongoDB, size estimates on Cassandra (an exact count while a new table has none), label counts on Neo4j, index statistics and field aggregations on Elasticsearch, and matching keys with their memory on Redis. MongoDB fields, Neo4j properties and Redis hash fields are read from a sample of up to 1,000 documents, 1,000 nodes or 50 keys, counted in the database; the card says how large the sample was. Values themselves are never stored, except the most common values PostgreSQL keeps in its statistics. Statistics an engine has not gathered yet show as a dash.
Dependency ImpactCount of dependent objects and relationships around the change, from the same dependency graph as the blast radius, read on every engine.
Capture StatusComplete, Partial (collector skipped), or Failed, with the specific collector and message.

Viewing & Diffing

Approvals with evidence show a Snapshots badge (its tooltip flags partial/failed captures); opening the Flight Recorder panel lists every capture with metadata, issues, touched objects, data shape, dependency impact, and a per-schema summary. Any two captures for the same approval can be diffed: the panel computes a schema diff reporting added / removed / altered per object class, e.g. a column that appeared between request and signature, always ordered oldest-to-newest. Two captures of the same connection can be compared on every engine, with the same object classes as a shadow run's comparison.