5.1 KiB
Plugin Transition Preflight And Delivery Acceptance Design
Context
P2-D8e2g made approval evidence independent and single-use, but the Plugin page still decided whether to enter approval flow from the Registry-wide realExecutorConfigured flag. In a mixed route configuration, one installed real Executor made every Transition look approval-sensitive even when that Transition resolved only to dry-run:v1. The browser also reconstructed effective retry and compensation identity from stale list fields.
P2-D8e2h moves that decision to a Transition-scoped server preflight and adds one operational delivery acceptance report. The execute endpoint remains the final authority and repeats all checks; preflight is an exact preview, not a capability token.
Transition Preflight
GET /generator/plugin/{pluginId}/transitions/{transitionId}/preflight?executionMode=... accepts the requested action mode (APPLY, RETRY, or COMPENSATE). It uses the same service, Transition lock, immutable plan verifier, nextMode state machine, trusted contribution resolver, and routing policy as execution.
The response freezes:
- requested and effective mode, including failed compensation retry resolving back to
COMPENSATE; - current Transition fingerprint;
- environment, routing fingerprint, and summary Executor;
- ordered execution steps with direction, contribution identity, target, selected Executor, and real-side-effect marker;
- whether any step is real and whether the effective route requires approval;
- only currently executable approval records.
Preflight has three states:
READY: dry-run, real execution with approval disabled, or real execution with at least one exact approved record;APPROVAL_REQUIRED: the actual route requires approval but no executable evidence exists;NO_ACTION: the requested action is already an idempotent terminal/no-op according to the execution state machine.
Invalid requested transitions still fail with the same service errors as execution rather than returning a misleading ready state.
Approval Eligibility
An approval is returned as executable only when all of the following remain true:
- status is
APPROVEDandexpires_atis in the future; - effective mode, Transition fingerprint, routing fingerprint, environment, and summary Executor exactly match;
- requester account, requester roles, request reason/time/expiry, approver account, approver roles, approval reason/time/expiry are all present;
- requester and approver still satisfy the configured separation rule.
Execution repeats those checks after locking the selected approval. The preflight result can therefore become stale safely: a concurrent expiry, revocation, configuration change, or consumption causes execution to fail before Outbox work is created.
Frontend Flow
Every execute, retry, and compensate action now starts with server preflight:
NO_ACTIONreports the current no-op state.APPROVAL_REQUIREDopens the approval workspace and disables request submission until the current preflight identity is loaded.READY + approvalRequiredconsumes the newest executable approval returned by the server after explicit confirmation.READY + realExecutionwithout an approval requirement displays an explicit real-side-effect warning.READYdry-run retains the normal queue confirmation.
The execution body copies fingerprints and environment only from the preflight response. The approval workspace refreshes preflight and approval history together and displays the exact ordered route before a request or decision.
Delivery Acceptance
PluginDeliveryAcceptanceService owns the delivery verification response. It returns seven explicit checks:
- the SQL, permission, and menu baseline Plugins are installed;
- the active built-in or database Plugin release catalog is ready;
- all three mixed routes explicitly select
sql-jdbc:v1,permission-jdbc:v1, andmenu-jdbc:v1; - control-plane and JDBC target environment codes match exactly;
- real execution approval and separation are enabled;
- the isolated JDBC target configuration is complete;
- target receipt, permission ownership, and menu ownership ledgers are queryable.
The report is READY only when every check passes. The delivery page renders each check as passed or blocked, then shows the non-secret routing, approval, Registry, and JDBC snapshots.
Security And Boundaries
- Preflight requires execute or approve permission and never returns JDBC URL, username, password, driver errors, SQLState, or raw target exceptions.
- The acceptance probe uses zero-row SELECT statements only. It does not run Plugin contributions or modify the target.
- Preflight performs lazy approval expiry under the Transition lock, matching the existing approval-list behavior; it does not create execution, receipt, or Outbox rows.
- No schema migration is required for this stage.
- No external MySQL instance was connected or modified during implementation. Target adapter tests continue to use H2 in MySQL mode; an explicitly authorized isolated MySQL rehearsal remains separate.
- Plaintext development credentials and TLS verification remain deferred by explicit user decision.