Skip to content

v0.4.1-beta

Choose a tag to compare

@nishujangra nishujangra released this 31 Jul 04:30
· 286 commits to master since this release
54e6e30

Spooky 0.4.1-beta — Staged Activation & Rollback

Patch release covering all changes since 0.4.0-beta.

Added

  • Staged runtime activationPOST /admin/runtime/validate, /preview, and /activate split config changes into plan-then-commit. Validate and preview read, validate, compatibility-gate, and produce a per-domain diff without touching the running runtime; activate commits it as an explicit transaction returning the diff, structured rejections, and a history entry.
  • Rollback by generation idPOST /admin/runtime/rollback restores a previously retained runtime generation. Rollback moves forward to a new generation number while restoring the target's content and its original config source.
  • Runtime generation historyGET /admin/runtime/history and /history/{generation} expose the operation log alongside retained-generation records (status, rollback_candidate, has_bundle, and a note explaining failed staged prepares), so operators can discover which generations are valid rollback targets.
  • Alternate config source activation — activation accepts a config_path in the request body, enabling canary workflows that switch between config files without a restart.
  • Optimistic concurrencyexpected_generation on activate and expected_active_generation on rollback reject with 409 when the runtime has moved underneath the caller.
  • Runtime activation observability, and canonical rejection reasons normalized across operator surfaces.

Fixed

  • Activating an alternate config_path now makes that file the active runtime source. Previously the runtime kept advertising the startup path, so a later reload-without-body silently re-read the wrong file and the control-plane view misreported the active config source.
  • Generation history records only the operation actually requested. Previously every staged call wrote both a validate and a synthetic preview entry, so a single activation consumed three history slots and the audit trail claimed preview activity that never occurred.
  • Retained-generation state is now surfaced by the history API. Failed staged prepares were tracked internally but never exposed, leaving operators unable to see why a candidate never committed.

Changed

  • Operator conflicts are now classified instead of collapsing into 500. Stale-generation and restart-required conflicts return 409; an unknown rollback target returns 404; an invalid config returns 400. Genuine runtime faults — resource preparation failure, or a failed runtime swap — still return 500.
  • POST /admin/runtime/reload now defaults to the currently active runtime config source rather than always re-reading the startup path. It remains supported as a shortcut over the same staged pipeline as /activate.
  • Config defaults co-located with the types they belong to, and serde default patterns normalized.
  • Test suite restructured by behavioral domain, with shared integration harnesses for the request path, bootstrap/QUIC parity, runtime swap, and backend lifecycle.
  • Documentation updated for the staged control-plane surface: control API reference, API overview, production readiness, migration guide, and roadmap.

Upgrade Notes

⚠️ Behavioral change for automation matching on HTTP status codes. Recoverable control-plane conflicts that previously returned 500 Internal Server Error now return 409 Conflict or 404 Not Found. Tooling that treats any non-2xx from /admin/runtime/reload as an infrastructure failure should be updated to distinguish retryable operator conflicts from genuine faults.

Note that validate and preview return 200 even when a candidate is rejected — the status code reflects the planning request, not the verdict. Read candidate_status and rejected_changes.

Known Limitations

  • No dynamic backend discovery (static config only)
  • Listener bind address and protocol changes still require a restart
  • Retained generations are capped at a fixed bound; rollback reaches recent generations, not arbitrarily old ones
  • Retention is not yet configurable, and there is no automatic rollback on post-activation health regression
  • Pre-GA — extended soak testing recommended before broad production rollout