Skip to content

Releases: runcycles/cycles-server

v0.1.25.59 — authoritative reservation TTL

Choose a tag to compare

@amavashev amavashev released this 28 Jul 15:58
1407364

Authoritative reservation TTL

  • Emit remaining_ttl_ms on reservation create and extend responses.
  • Recompute the field on idempotent replays; finalized reservations report zero.
  • Keep the timing hint outside signed evidence payloads.
  • Stabilize replay assertions for the documented dynamic-field carve-out.
  • Align generated and runtime schemas on a non-negative TTL.

v0.1.25.58 — direct-event replay metrics

Choose a tag to compare

@amavashev amavashev released this 14 Jul 20:10
4ad4567

Direct-event replay metrics

This release closes the remaining replay-observability asymmetry: successful keyed direct-event replays now appear in the domain request counter without double-counting mutation-only effects.

Observability

  • Records successful keyed POST /v1/events replays as cycles_events_total{decision="APPLIED",reason="IDEMPOTENT_REPLAY"}.
  • Keeps fresh event applications tagged reason="OK".
  • Preserves exactly-once cycles_overdraft_incurred_total accounting when an event replay follows an original debt-incurring mutation.
  • Clarifies that domain event counters cover repository-handled outcomes and documents the operations that expose replay tags.

Compatibility and validation

  • Metrics-only behavior change: no protocol schema, HTTP body/status, Redis command, Lua script, ledger state, idempotency storage, evidence, or runtime-event behavior changed.
  • Production and full-stack Compose files pin ghcr.io/runcycles/cycles-server:0.1.25.58.
  • Targeted repository tests passed: 30/30.
  • Real-Redis metrics integration tests passed: 14/14.
  • Full integration-profile reactor discovered 1,207 tests with zero failures or errors.
  • Protocol operation coverage remains 11/11.
  • JaCoCo line coverage: data 95.14%, API 95.56%.
  • All merge CI, integration, CodeQL, container, and supply-chain checks passed.
  • [benchmark-skip]: the replay path adds one in-memory Micrometer counter increment; foreground Redis and ledger paths are unchanged.

Full details: CHANGELOG.md [0.1.25.58], AUDIT.md, BENCHMARKS.md, and PR #249.

v0.1.25.57 — Redis recovery and rolling-upgrade matrices

Choose a tag to compare

@amavashev amavashev released this 14 Jul 19:32
ad1a6b7

Redis recovery and rolling-upgrade matrices

This test/documentation-only release makes Redis lost-response recovery and supported rolling-upgrade storage compatibility executable in CI, without changing production behavior.

Recovery coverage

  • Adds deterministic lost-response tests for reserve, commit, release, direct event, dry-run, and decide.
  • Retries every discarded successful response and asserts byte-identical bodies plus exactly-once ledger, evidence, runtime-event, reservation, event, and TTL-index side effects.
  • Uses a FIFO executor barrier for deterministic asynchronous event draining rather than timing sleeps.

Upgrade compatibility

  • Adds frozen legacy Redis fixtures for lifecycle fast-body rows, pre-snapshot rows, pre-v0.1.25.52 event storage, the pre-v0.1.25.51 dry-run namespace, and reservations created before the optional created-at index.
  • Pins replay, mismatch, snapshot-backfill, no-second-debit, and index-backfill behavior against the current reader.
  • Strengthens fixtures so storage-field drift cannot make compatibility tests pass vacuously.

Compatibility and validation

  • No production source, protocol wire shape, Redis layout, or foreground command path changed.
  • Production and full-stack Compose files pin ghcr.io/runcycles/cycles-server:0.1.25.57.
  • 1,206 tests passed: 31 model, 575 data, 600 API; zero failures, errors, or skips.
  • Protocol operation coverage 11/11.
  • JaCoCo line coverage: data 95.14%, API 95.56%.
  • All merge CI, integration, CodeQL, container, and supply-chain checks passed.
  • [benchmark-skip]: this release changes tests and documentation only.

Full details: CHANGELOG.md [0.1.25.57], AUDIT.md, BENCHMARKS.md, issue #247, and PR #248.

v0.1.25.56 — leased scheduled Redis maintenance

Choose a tag to compare

@amavashev amavashev released this 14 Jul 18:35
14efc2f

Leased scheduled Redis maintenance

This release coordinates all five Redis-backed scheduled maintenance jobs across runtime replicas without changing protocol behavior, ledger semantics, job cadence, or foreground request paths.

Reliability and operations

  • Adds per-job Redis SET NX PX leases for reservation expiry, audit retention, event retention, created-at index repair, and created-at index sweeping.
  • Renews and releases leases only when the owner token still matches, preventing an old process from extending or deleting a successor lease.
  • Uses a bounded heartbeat executor plus local overlap guards; abandoned leases recover automatically after TTL.
  • Keeps every maintenance job idempotent and isolates action, Redis, renewal, release, and metrics failures from the scheduler.
  • Adds cycles_maintenance_runs_total{job,outcome} and cycles_maintenance_duration_seconds{job,outcome} with structurally bounded tags.
  • Warns at startup when the renewal interval exceeds one-third of the lease TTL and documents renewal head-of-line timeout margin.

Compatibility

  • No protocol schema, HTTP request/response, ledger Lua, authoritative Redis row, maintenance cadence, or foreground request-path change.
  • New cycles:maintenance:lease:* keys are short-lived internal coordination state.
  • Mixed fleets remain idempotent but do not provide single-run guarantees until every runtime pod is upgraded.
  • Production and full-stack Compose files pin ghcr.io/runcycles/cycles-server:0.1.25.56.

Validation

  • 1,195 tests passed: 31 model, 575 data, 589 API; zero failures, errors, or skips.
  • Protocol operation coverage 11/11.
  • JaCoCo line coverage: data 95.14%, API 95.56%.
  • Real-Redis tests cover two-runner exclusion, heartbeat renewal, stale-owner release protection, abandoned-lease recovery, Redis/type/action/metrics failures, and all five scheduler delegations.
  • All PR CI, integration, CodeQL, Trivy, and container checks passed.
  • [benchmark-skip]: production changes are confined to background maintenance and bounded metrics; no HTTP or ledger hot path changed.

Full details: CHANGELOG.md [0.1.25.56], AUDIT.md, BENCHMARKS.md, issue #245, and PR #246.

v0.1.25.55 — typed reservation-query boundary

Choose a tag to compare

@amavashev amavashev released this 14 Jul 17:39
bf972c5

Typed reservation-query boundary

This release reduces the highest remaining change-risk concentration in cycles-server without changing protocol, Redis, cursor, filtering, ordering, or performance behavior.

Internal architecture

  • Introduces immutable ReservationListQuery groups for scope filters, inclusive time windows, sort state, cursors, limits, and optional projections.
  • Moves SCAN pagination, sorted fallback, and completeness-gated created-at traversal into RedisReservationQueryRepository.
  • Centralizes Redis hash projections, filter matching, finalized-time resolution, and detail/list hydration in ReservationHashMapper.
  • Retains both public RedisReservationRepository.listReservations(...) signatures as the compatibility facade.
  • Shares exact scope-segment matching between reservation and balance queries while preserving the existing first-occurrence behavior.

Correctness safeguards

  • Adds a real-Redis query matrix that executes through both a READY created-at index and the authoritative SCAN fallback.
  • Asserts identical rows, stable ordering, page boundaries, exact cursor bytes, and error code/status/message across both paths.
  • Pins the tenant, reservation_id, and created_at consistency fields in listing projections.
  • Preserves the established filter-hash argument order so in-flight sorted cursors remain valid across the upgrade.

Compatibility

  • No protocol schema, HTTP signature, response shape, Redis key, Lua script, Redis command sequence, cursor encoding, filter, ordering, index readiness, or feature-flag change.
  • Production and full-stack Compose files pin ghcr.io/runcycles/cycles-server:0.1.25.55.

Validation

  • 1,182 tests passed: 31 model, 562 data, 589 API; zero failures, errors, or skips.
  • Protocol operation coverage 11/11.
  • JaCoCo line coverage: data 95.22%, API 95.56%.
  • Real-Redis created-at index suite 24/24, including explicit INDEX and SCAN_DISABLED parity coverage.
  • Three paired candidate and three v0.1.25.54 baseline benchmark trials completed all 17 cases with zero errors.
  • Sorted-list p50 remained 17.0 ms at 1,000 rows and moved from 16.9 ms to 17.6 ms (+4.1%) at 10,000 rows, classified as performance-neutral.
  • All PR CI, integration, CodeQL, Trivy, and container checks passed.

Full details: CHANGELOG.md [0.1.25.55], AUDIT.md, BENCHMARKS.md, issue #243, and PR #244.

v0.1.25.54 — bounded created-at reservation listing

Choose a tag to compare

@amavashev amavashev released this 14 Jul 15:57
182ea05

Bounded created-at reservation listing

This release makes the default created_at_ms reservation listing population-independent while preserving reservation hashes as the authority and retaining the complete full-SCAN fallback whenever index completeness is uncertain.

Performance

  • Adds a per-tenant created_at_ms ZSET, atomically dual-written by reservation creation.
  • Serves the default sorted query in bounded, tie-safe candidate batches only after READY/count validation succeeds.
  • Reduces same-host p50 from 22.5 ms to 10.7 ms at 1,000 rows and from 164.9 ms to 11.1 ms at 10,000 rows.
  • Leaves the other six sort keys on the authoritative full-SCAN implementation.

Reliability and rollout

  • Uses restartable backfill, expected-count validation before and after hydration, lazy stale cleanup, and a nightly authoritative sweep.
  • Invalidates readiness on malformed authoritative rows and repairs exclusively owned wrong-type index keys without creating complete-looking omissions.
  • Isolates scheduled maintenance on a bounded four-thread pool and backs off deterministic malformed-row reconciliation failures for one hour.
  • Validates sorted cursor boundaries before Redis work so indexed and fallback paths return the same 400 INVALID_REQUEST.
  • Defaults the read/backfill switch off in the application and both production Compose files; enable RESERVATION_CREATED_AT_INDEX_ENABLED only after every writer runs v0.1.25.54 or newer.

Compatibility

  • No protocol schema, response body, filtering, ordering, or cursor-format change.
  • Disabling the feature flag immediately restores the previous full-SCAN read path.
  • Production and full-stack Compose files pin ghcr.io/runcycles/cycles-server:0.1.25.54.

Validation

  • 1,181 tests passed: 31 model, 561 data, 589 API; zero failures, errors, or skips.
  • Protocol operation coverage 11/11.
  • JaCoCo line coverage: data 95.10%, API 95.56%.
  • Real-Redis coverage includes 10,000-row traversal, 300-way timestamp ties, rollout/readiness races, malformed cursors, corruption fallback, wrong-type repair, sweep isolation, and repair backoff.
  • Three local benchmark trials completed all 17 cases with zero errors; the release workflow will independently enforce the rolling 25% regression gate.
  • Production Compose configurations render successfully.

Full details: CHANGELOG.md [0.1.25.54], AUDIT.md, BENCHMARKS.md, and PR #242.

v0.1.25.53 — sorted reservation scaling baseline

Choose a tag to compare

@amavashev amavashev released this 14 Jul 13:42
23e4176

Sorted reservation scaling baseline

This benchmark-only release establishes the pre-index comparison point for cycles-server#240 without changing production request, Lua, Redis-storage, or wire behavior.

Added

  • end-to-end GET /v1/reservations sorted-list benchmarks at 1,000 and 10,000 total reservation hashes
  • a 50/50 authenticated-tenant/unrelated-tenant fixture that exposes the current global SCAN and hydration cost
  • list_sorted_1k_p50_ms and list_sorted_10k_p50_ms in benchmark parsing, three-trial medians, nightly history, and release regression gating
  • a revised completeness-safe Phase B design: one default-sort index, explicit post-rollout readiness, expected-count validation, restartable backfill, stale cleanup, stable tie pagination, and full-SCAN fallback

Baseline

Three same-host medians against the unchanged v0.1.25.52 runtime:

  • 1,000 total / 500 tenant rows: 22.5 ms p50, 40.9 ms p95, 48.3 ms p99
  • 10,000 total / 5,000 tenant rows: 164.9 ms p50, 210.2 ms p95, 232.0 ms p99

Validation

  • 1,144 tests; zero failures, errors, or skips
  • protocol operation coverage 11/11
  • JaCoCo line coverage: data 95.12%, API 95.56%
  • release benchmark profile 17/17 with all nine headline metrics parsed
  • production Compose configurations validated

v0.1.25.52 — event replay storage and ledger helper cleanup

Choose a tag to compare

@amavashev amavashev released this 14 Jul 13:15
b0db4fc

This release removes keyed-event replay storage amplification and consolidates the protocol's per-scope over-limit rule without changing public behavior.

Event replay storage

  • Stores one canonical response body for new idempotent events in the 30-day event hash instead of duplicating it in a seven-day fast-response key.
  • Reads the immutable snapshot directly on normal replay, preserving one body lookup while removing one response-sized write, expiring key, and memory copy per keyed event.
  • Retains byte-identical replay for pre-v0.1.25.52 rows through the legacy fast-key fallback and opportunistic HSETNX snapshot backfill.
  • Uses a protected hash read so an incompatible legacy event-key type does not prevent replay while the canonical legacy response still exists.

Ledger maintainability

  • Replaces four hand-synchronized commit/event over-limit marking loops with one shared mark_uncovered_scopes implementation.
  • Keeps exact signed-int64 arithmetic side-effect-free in int64-helpers.lua; Redis mutations live in the separate ledger-helpers.lua prelude.
  • Adds composition tests that enforce one helper definition per loaded ledger script and prevent Redis writes from returning to the arithmetic prelude.

Compatibility

  • No request, response, or successful replay shape changes.
  • Pre-v0.1.25.52 event rows remain replayable while their legacy response key exists; missing event hashes are not recreated and existing snapshots are never overwritten.
  • Production and full-stack compose defaults pin ghcr.io/runcycles/cycles-server:0.1.25.52.

Validation

  • 1,144 tests passed: 31 model, 534 data, 579 API; zero failures, errors, or skips.
  • Protocol contract coverage 11/11; JaCoCo line coverage 95.12% data and 95.56% API.
  • Real-Redis coverage includes snapshot-only replay, legacy backfill, wrong-type legacy fallback, and both capped-charge policies' hierarchical scope marking.
  • Three benchmark-profile trials passed all 15 cases with zero concurrency errors; every headline delta remained below the 25% regression threshold.

Full details: CHANGELOG.md [0.1.25.52], AUDIT.md, BENCHMARKS.md, and PR #239.

v0.1.25.51 — protocol idempotency and replay hardening

Choose a tag to compare

@amavashev amavashev released this 14 Jul 12:25
7060eda

This release hardens protocol idempotency, replay integrity, hierarchical budget attribution, and corrupt-expiry observability without changing the public schema.

Protocol correctness

  • Shares the reserve endpoint idempotency namespace between live and dry-run requests, returning 409 IDEMPOTENCY_MISMATCH when the same key changes request form or payload.
  • Makes slow, uncontested non-persisting evaluations publish safely after claim expiry while preventing overwrite by a newer winner.
  • Preserves pre-upgrade dry-run results through the legacy namespace bridge and detects independently lost companion hashes by value shape.
  • Marks only scopes that individually fail to cover capped commit/event charges as over-limit.

Replay and expiry hardening

  • Stores immutable event response snapshots and repairs missing fast response caches without re-dispatching webhooks or synthesizing changed bodies.
  • Opportunistically backfills pre-snapshot event rows while their canonical response remains available.
  • Quarantines malformed expiry rows with durable reason/timestamp metadata, WARN logging, and bounded cycles.reservations.quarantined metrics.
  • Normalizes missing/non-textual quarantine tenants to the existing UNKNOWN metric tag.

Compatibility

  • No request or successful-response schema changes.
  • Mixed-version deployments may return a transient retriable 500 from an older pod while a new dry-run marker is live (at most 60 seconds); the documented production topology remains single-instance.
  • Production and full-stack compose defaults pin ghcr.io/runcycles/cycles-server:0.1.25.51.

Validation

  • 1,140 tests passed: 31 model, 531 data, 578 API; zero failures, errors, or skips.
  • Protocol contract coverage 11/11; JaCoCo line coverage 95.11% data and 95.56% API.
  • Focused adversarial Redis suite 64/64, including three-state CAS and bidirectional value-shape mismatch cases.
  • Three benchmark-profile trials completed with zero concurrent errors and no measurable regression.

Full details: CHANGELOG.md [0.1.25.51], AUDIT.md, BENCHMARKS.md, and PR #238.

v0.1.25.50 — runtime correctness, replay integrity, and int64 fidelity

Choose a tag to compare

@amavashev amavashev released this 13 Jul 14:00
fbbf790

Rolls up the v0.1.25.49 runtime hardening and the v0.1.25.50 replay/int64 follow-up. This release keeps the public protocol schema unchanged while closing correctness, liveness, and scaling gaps in reservation lifecycle processing.

Correctness and replay integrity

  • Stores immutable reserve/commit/release response snapshots inside their atomic Redis mutations and repairs missing fast caches without synthesizing a potentially different response.
  • Uses a PENDING → BASE/EVIDENCE state machine so concurrent replay repair cannot overwrite a canonical evidence-bearing response.
  • Preserves exact signed-int64 ledger arithmetic and response values across reserve, commit, release, expiry, direct events, and extend through one shared Lua decimal helper.
  • Saturates only the commit-level debt observability aggregate at Long.MAX_VALUE; per-scope debts and balances remain exact.
  • Restores commit/release replay metrics with IDEMPOTENT_REPLAY while avoiding overdraft double-counting.

Expiry and audit hardening

  • Emits expiry events only for a true status=EXPIRED transition and hydrates the correct timestamp fields.
  • Quarantines reservations with missing, malformed, or negative estimate data outside the bounded TTL sweep index, leaving state and budgets untouched for operator reconciliation and logging a WARN.
  • Makes admin-release audit persistence part of the same Lua transaction and centralizes audit-entry preparation with fail-closed tenant validation.

Performance and operations

  • Releases Redis connections before BCrypt verification.
  • Replaces hot reservation HGETALL calls with explicit HMGET projections, shares name-keyed projection mapping, and hoists projection arrays.
  • Adds resilient event/delivery pointer retention cleanup and fixes jqwik configuration discovery.
  • Updates production and full-stack compose defaults to ghcr.io/runcycles/cycles-server:0.1.25.50.

Compatibility

  • No public schema or successful-response shape changes.
  • Finalized reservations created before immutable snapshots existed still replay through their canonical body cache; if both that cache and a snapshot are absent, the server returns the existing retriable 500 rather than a non-identical reconstruction.

Validation

  • 1,111 tests: 31 model, 525 data, 555 API; zero failures, errors, or skips.
  • Contract coverage 11/11; JaCoCo line coverage 95.09% data and 95.56% API.
  • Real-Redis regressions cover 2^53 + 1, 10^14 + 1, and Long.MAX_VALUE ledger/refund/replay cases.
  • Same-host benchmark medians: reserve/commit/release p50 14.5/13.7/14.3 ms and 698.2 ops/s at 32 threads, with no regression signal versus v0.1.25.49.

Full details: CHANGELOG.md [0.1.25.49] and [0.1.25.50], AUDIT.md 2026-07-12/13 entries, PRs #235 and #237, issue #236.