Files
zemion 2ffdb23f69
Dependency Audit / dependency-audit (push) Successful in 1m45s
Deployment Installer / deployment-installer (push) Successful in 6s
Security Audit / security-audit (push) Successful in 11m30s
feat(devkit): add resumable workspace automation and UI review tooling
Verified with the coordinated workspace changes by devkit full run
2026-09-08T225814-186389-0000-3e3ed7cd (all seven phases passed).
This shared UI pass does not mark the individual module reviews complete.
2026-09-09 02:03:17 +02:00

7.4 KiB
Executable File

Headless durable releases

The devkit release commands use the same release application, request validation, run store and bounded executors as the release console. They invoke its ASGI application inside the current process, with an ephemeral internal token. No listening socket, background server, browser session or externally supplied console URL is used. The development environment's FastAPI/HTTPX dependencies load only when a release command runs; ordinary devkit help does not import them.

This is a GovOPlaN-specific provider. Repository and origin authority still comes from the release service's registered catalog. --project is explicitly rejected for release commands; a portable project configuration must not silently override that authority. A different workspace path does not authorize arbitrary release repositories, remotes, commands, signing policies or source bindings.

The default compact output includes the overall status, selected repository states and versions, source-preflight readiness, bounded gate findings and the recommended next action. Run inspection also shows step-state counts and the first outstanding steps. These are projections of the service response, not new readiness checks. Use --json for the complete existing plan or receipt; compact output deliberately omits executor commands, arguments and source bindings.

Commands and boundaries

Command Purpose Effect boundary
release status Current release dashboard Offline by default; explicit remote/catalog flags enable their checks
release plan Selective repository/version plan Inspection only; does not create a run
release list Bounded run history, with --limit and --cursor Existing workspace-scoped store
release show RUN_ID Exact verified run, steps, receipts and required confirmations No release execution
release create Freeze a selected repository/version plan Preview by default; --apply persists a run
release preview RUN_ID STEP_ID Frozen step and its current constraints No step claim; catalog publication additionally uses the existing validated-candidate preview
release execute RUN_ID STEP_ID One available durable step Preview by default; --apply, explicit request ID and the step's exact confirmation are required
release resume RUN_ID Mark persisted running attempts interrupted Requires --apply; never assumes an effect succeeded
release retry RUN_ID STEP_ID Prepare an eligible failed/read-only-interrupted step Requires --apply; does not execute it
release reconcile RUN_ID STEP_ID Record a proven uncertain-write outcome Requires --apply, --confirm RECONCILE and an explicit outcome

Create and transition commands require caller-chosen --request-id values. Retain the same ID for an uncertain replay of the same command; changing inputs under an existing ID fails closed. No command automatically retries a mutation. These commands perform one explicit transition, not an implicit "release everything" loop.

Read commands do not commit, tag, push, publish or apply database migrations. The existing private run store can initialize its lock directory or upgrade a legacy record while inspecting it; this does not advance release steps. --include-migrations requests the existing audits, never migration application. --online, --remote-tags and --public-catalog are explicit network-check choices. A generic step preview describes frozen intent; it is not a claim that live preflight, remote identity or release acceptance has passed.

Example: review, freeze and execute one step

Run the devkit through the workspace ./devkit entrypoint. These examples put global options before release:

./devkit --workspace-root /path/to/workspace --format json release plan \
  --repo-version govoplan-files=0.1.9

./devkit --workspace-root /path/to/workspace release create \
  --repo-version govoplan-files=0.1.9 --request-id files-release-create-0001

./devkit --workspace-root /path/to/workspace release create \
  --repo-version govoplan-files=0.1.9 --request-id files-release-create-0001 --apply

./devkit --workspace-root /path/to/workspace release show RUN_ID
./devkit --workspace-root /path/to/workspace release preview RUN_ID STEP_ID
./devkit --workspace-root /path/to/workspace release execute RUN_ID STEP_ID \
  --request-id files-release-step-0001 --confirm REQUIRED_CONFIRMATION --apply

RUN_ID, STEP_ID and REQUIRED_CONFIRMATION stand for the actual values returned by the frozen run. For read-only preflight/alignment/install-verification steps, omit --confirm when the service reports an empty confirmation. Metadata, commit, release-lock, source-tag, source-push, candidate-generation and catalog publication steps keep the existing UPDATE, COMMIT, LOCK, TAG, PUBLISH, GENERATE and PUSH confirmations respectively. Prerequisite ordering is enforced by the same store; a later step cannot be forced through this adapter.

Version selection supports repeated --repo-version REPO=VERSION, or repeated --repo REPO with --target-version VERSION. Every created run needs explicit versions for all selected repositories. Conflicting version assignments are rejected. Planning is selective; repositories are never silently selected merely because their worktrees are dirty.

Candidate publication and recovery

Use the frozen run's catalog:selective-generator and catalog:validate-sign-publish steps, not the disabled legacy mutation endpoints. Generation accepts repeated --signing-key KEY_ID=PRIVATE_KEY_FILE; these are operator-owned key-file references, never inline key material. Signing arguments are not emitted in devkit JSON or persisted by the adapter. Publication consumes the candidate receipt created by that run, not an arbitrary candidate directory. The existing source/runtime trust, immutable tag/remote identity, private candidate checks and exact commit-delta checks remain authoritative.

After an interrupted write, inspect the run and the actual local/remote effect. Use resume --apply if an attempt was left running. Then use reconcile with effect_absent, effect_succeeded or unresolved, --confirm RECONCILE, a new reconciliation request ID and --apply. Successful reconciliation still performs the service's independent receipt checks. An unresolved effect must not be retried or papered over by generating a new request ID. A failed/read-only attempt may use retry --apply and a new explicit execute attempt only when the existing lifecycle makes that safe.

State and limitations

Every successful response exposes state_location and candidate_location. Without --state-dir, the adapter uses the console's existing default private, workspace-fingerprinted state directory. With --state-dir PATH, it uses PATH/release-console/workspace-<fingerprint>/release-runs. Workspaces cannot read or resume one another's runs. Existing ownership, symlink, permission, retention and record-integrity checks are unchanged.

Release preparation can commit only the recognized, receipt-bound metadata changes its executors produced. This command does not stage arbitrary source changes, use git add -A, force-push, retarget tags or enable the disabled generic prepare/sync/push endpoints. Normal selected-path maintenance requires its own explicit reviewed-change workflow; it is not silently folded into release.