Files
harmony/fleet/harmony-fleet-deploy
Jean-Gabriel Gill-Couture 1e898a7328
All checks were successful
Run Check Script / check (pull_request) Successful in 2m33s
feat(fleet-deploy): smoke-test contract as a Score companion
Phase 0 of the smoke-test contract from ADR-023 P4 ("deploy returns
only after smoke-test success"). Lands inside harmony-fleet-deploy
under companion/smoke/ so the shape can be validated against a real
consumer before promoting to a top-level crate.

Three small types + a wrapper, zero edits to the Score / Interpret /
Maestro public API:

  Probe         single-attempt unit; classifies its own observation
                as Ok / Retry / Fatal via ProbeAttempt.
  SmokeSuite    ordered list of (probe, RetryPolicy) stages; sequential
                by design.
  SmokeTest     companion trait paired with a Score by associated type
                — `SM: SmokeTest<T, Score = S>` is the compile-time
                lock (ADR-024 §2 / JG's compile-time-feedback principle).
  deploy /      free functions binding Score::interpret to an optional
  deploy_with_  SmokeTest. The smoke variant returns only after the
  smoke         suite passes; a failed probe is DeployError::SmokeFailed
                with the full report attached.

Cardinality choices follow JG's *For the Love of Compilers* talk:
ProbeName is a validated newtype (rejected: empty / control-chars /
>128 bytes), ProbeAttempt is a three-arm sum because "not ready yet"
and "definitively no" drive different orchestration paths, ProbeFailure
splits Timeout from Rejected because the operator actions are different.
RetryPolicy::polling panics on a zero interval at construction rather
than spinning the executor in production.

One concrete probe ships in this PR — TcpReachable — to validate the
trait shape against real network I/O. Run_probe orchestrates retry +
timeout outside the probe itself so each probe stays single-attempt
and unit-testable.

Stage progress is emitted via tracing::info_span! / info! today.
Adding HarmonyEvent::SmokeStage* variants is deferred to Phase 1
(Score / Interpret stay untouched in Phase 0).

Phase 1 follow-ups: HttpHealthy, K8sPodReady, NatsKvKeyExists probes;
a real FleetOperatorSmokeTest composed of those; optional dashboard
event variants. None of those touch the contract — that's the point
of locking the shape here.

Tests: 21 new (4 in tcp::tests, 8 in probe::tests, 3 in suite::tests,
4 in deploy::tests). Full crate: 39 / 39 passing. No regressions.
build/check.sh equivalents: cargo check --all-targets --all-features
clean, cargo fmt --check clean, cargo clippy with zero findings on
the new module.
2026-05-23 16:29:35 -04:00
..