Files
ironclaw/crates
Illia Polosukhin e88236ab08 refactor(events): replace JobResult.status String with JobResultStatus enum (#2678)
* refactor(events): replace JobResult.status String with JobResultStatus enum

Producers at 7 sites and consumers at 3 sites previously agreed by
convention only. Promotes the status field to a typed enum with
snake_case serde — wire format preserved.

Maps to bug pattern from #2570, #2531, #2517 where status transitions
drifted between producer and consumer.

Tests cover snake_case serialization, wire-format round-trip, and the
is_success() predicate used at consumer sites.

* refactor(events): add Stuck variant, accept "error" alias, case-insensitive parse

JobResultStatus now covers the full set of wire values producers emit:
- New `Stuck` variant for worker/job.rs `mark_stuck` path (was coerced
  to Failed + warn log, losing the distinction that job monitor and
  recovery logic care about).
- `FromStr` accepts `"error"` as a legacy alias for `Failed` so
  claude_bridge and acp_bridge wire payloads deserialize cleanly
  instead of hitting the default-on-unknown branch.
- `FromStr` trims whitespace and uses `eq_ignore_ascii_case`, so
  `"  COMPLETED  "` and `"Failed"` parse rather than falling back.
- Empty / whitespace-only input now returns `Err` (distinct from
  "unknown value") so callers can log it separately.

Producer migration: worker/job.rs emits `JobResultStatus::Stuck`
directly via `serde_json::json!` so the wire string stays pinned to
`as_str()`. claude_bridge and acp_bridge keep emitting `"error"` on
the wire; the FromStr alias covers them without churn on those call
sites.

Added unit tests for each variant, the `"error"` alias, case
insensitivity, whitespace trimming, empty-string error, and
preservation of the original input in `JobResultStatusParseError`.

---------

Co-authored-by: Henry Park <henrypark133@gmail.com>
2026-04-20 12:39:42 +09:00
..