Skip to main content
Version: v5.6.1

opschain approval-policies convert-step-gates

packs:change-governance

opschain approval-policies convert-step-gates [--dry-run]

Inventories every step-level requires_approval_from: wait gate in the stored workflow catalog and, on request, creates the equivalent approval policy (ChangeGovernanceService.ConvertStepApprovalGates). The step gate is the in-YAML approval: a wait step naming user_names/ldap_groups parks the run mid-flow until any one named approver releases it. It stays supported and enforced — but governance-grade approval lives in approval policies on the estate paths, not in workflow YAML, so this verb is the operator path from one to the other: it scans every stored workflow version, reports every gate by name and converts the current ones into policies through the same store the policy write verbs use.

Converting never edits or removes workflow YAML. The step gate keeps enforcing exactly as before — a converted workflow holds twice (the policy before the run starts, the gate at the step) until the workflow's authors delete the requires_approval_from: keys from their own repositories at their own pace. The report ends with that reminder.

Each converted gate becomes a policy shaped for the workflow's runs:

  • the policy's scope and path pattern are the owning project's path, and its action pattern is the workflow's code — exactly the identity a workflow run is matched on, so the policy holds that workflow's runs for approval before they start;
  • the gate's user_names and ldap_groups become the policy's named approvers, with quorum 1 and self-approval allowed — the step gate is satisfied by any one named approver, the run's creator included when named;
  • two steps gated on the same approver set propose one policy (the second reports already_converted against it), and a different approver set converts under its own deterministic name.

The report names every gate (project/workflow v<version> step "<name>", approvers included):

  • converted — the policy was created (name, id and shape in the row);
  • already converted — a re-run creates nothing twice: a policy with the converted shape already exists, whatever it has since been renamed to;
  • superseded — the gate sits on a draft or on a version a newer published version supersedes; only the latest published version converts, and the gate keeps enforcing if that older version is run explicitly;
  • unconvertible — left to recreate by hand: property-placeholder approver names ({{ … }}, resolved per run against project properties) and gates on archived workflows.

The verb requires a PostgreSQL-backed server holding the packs:change-governance entitlement, the change-governance determination (updatable on /governance/change, the root scope — the conversion writes policies across the whole estate) and a stepped-up session. A writing run is audited as api:step_approval_gates:converted; --dry-run produces the same report without writing anything and is not audited.

Estate usage is also visible without running the verb: whenever a stored workflow version carrying the gate is composed for a run or a plan, the server records one throttled warn:workflows:deprecated_approval_gate event naming the workflow, version and gate-carrying steps (at most one per version per day), so opschain events answers where the key is still in use.

Flags​

FlagMeaning
--dry-runReport what would convert without writing any policy.

-o json / -o yaml emit the typed report in its protojson wire shape.

Exit codes​

CodeMeaning
0Report produced (a writing run may have created policies; no step-level requires_approval_from gates found in the stored workflow catalog when no stored version carries the key).
1The conversion failed — the error names the server's Connect code and message, including the packs:change-governance funnel refusal, the missing governance determination and the step-up refusal.
2Usage error, including a missing server target.

Examples​

$ opschain approval-policies convert-step-gates --dry-run
[would convert] /projects/web/release v3 step "approve" approvers=alice, dba -> policy "Converted step approval gate /projects/web/release 1a2b3c4d" (path /projects/web, actions release)
[superseded] /projects/web/release v2 step "approve" approvers=old-approver — version 2 is superseded by a newer published version — only the latest published version converts; the gate keeps enforcing when this version runs
1 convertible, 0 already converted, 1 superseded, 0 unconvertible
the step gates stay enforced: converting never edits workflow YAML — delete requires_approval_from keys at your own pace

$ opschain approval-policies convert-step-gates
[converted] /projects/web/release v3 step "approve" approvers=alice, dba -> policy "Converted step approval gate /projects/web/release 1a2b3c4d" (01993…, path /projects/web, actions release)
...