Repository navigation
Phase 2.3 — ActionStatus compensation enums + engine wiring #698
Description
Followup from workflow#640 Phase 2 + Phase 2.5 cascade closeouts. Phase 2 PR #694 (sha b09bced) reserved proto tags 4+5 with comment 'Phase 2.3 compensation (COMPENSATED + COMPENSATION_FAILED)'. Phase 2.5 added tag 6 candidate for SKIPPED. Now actually define these + wire compensation semantics.
Scope (5 sub-items per Phase 2 design)
- Define ACTION_STATUS_COMPENSATED (tag 4) + ACTION_STATUS_COMPENSATION_FAILED (tag 5) + ACTION_STATUS_SKIPPED (tag 6) enum values in plugin/external/proto/iac.proto
- Wire compensation logic in engine (iac/wfctlhelpers/apply.go) — when wfctl-side hook (OnResourceApplied / OnResourceDeleted) fails AFTER per-action driver succeeded, attempt to compensate
- Distinguish dispatch-fail (current ActionStatusError) from post-hook-fail (new ActionStatusCompensated/Failed) per cycle-1+2+3 Copilot findings on PR feat: workflow#640 Phase 2 — v2 hooks-over-gRPC contract (ApplyResult.Actions + ActionStatus + engine populate + decoder) #694 (apply.go:313/316/235/354 conflations — all deferred to Phase 2.3)
- Distinguish skipped-due-to-cancel from dispatch-fail per ctx-cancel deferral (apply.go:235 finding)
- Per-plugin opt-in via existing IaCProviderFinalizer (Phase 2.5) or new IaCProviderCompensator RPC
Design questions
- What triggers compensation? wfctl-side hook failure (engine knows). Plugin-side post-driver-success errors (plugin emits via FinalizeApplyResponse?).
- What does compensation DO? Engine could call plugin's Delete RPC for created resources. Risk: re-entrant delete during apply mid-flight.
- Per-resource-type opt-in? Some resources are not compensable (e.g., DB writes already happened).
- Test coverage strategy?
Approach
Full superpowers pipeline (brainstorm → design → plan → implement). Compensation semantics warrant dedicated design (saga-style rollback, per-resource-type opt-in, hook-failure-vs-driver-failure differentiation).
Deferred from Phase 2.5+ Cleanup Bundle (docs/plans/2026-05-17-phase2.5-cleanup-bundle-design.md in workflow repo) because: 'compensation semantics require dedicated design that warrants its own pipeline. Mixing it into a mechanical-cleanup bundle would dilute focus and force compromises.'
References
- workflow#640 (Phase 2 cascade — main feat: workflow#640 Phase 2 — v2 hooks-over-gRPC contract (ApplyResult.Actions + ActionStatus + engine populate + decoder) #694)
- workflow#695 (Phase 2.5 cascade — main feat(iac): IaCProviderFinalizer + OnPlanComplete hook (#695 Phase 2.5) #697 + DO feat: decompose V1 CRUD routes into pipeline primitives (#86) #123)
- decisions/0024-iac-typed-force-cutover.md
- decisions/0040-v2-action-lifecycle-provider-compatibility.md
- Phase 2.5+ Cleanup Bundle design (in feat/phase2.5-cleanup-design branch)
Activity
feat(iac): ActionStatus compensation enums + mapping fix (#698 Phase …
intel352 commentedon May 17, 2026
Shipped via PR #700 (squash sha 7a85593). Workflow v0.56.0 published (18 assets, latest).
Cascade summary
Out of scope