Unreleased
1.8.1 — 2026-11-12
Fixed
- Respect the first allowed cron time for
delayandstart_at, including exact minute boundaries and the Unix epoch. - Reconcile repeated schedule declarations against durable Engine state after cancellation through the Dashboard or Elixir API. Preserve the existing timer when the durable declaration is unchanged.
- Restore Python task arguments correctly when ordinary parameters precede
*args, including defaults, positional-only and keyword-only parameters. - Encode HTTP worker queue names as URL path segments and decode them on the server, supporting slashes, spaces, reserved characters and Unicode.
Changed
- Release
tay-client1.4.4 with the argument-binding and HTTP queue fixes.
1.8.0 — 2026-11-02
Changed
- Promote the 1.8 release-candidate feature set to the stable version: durable schedules over both transports, overlap policies, execution rate limits, shared state-memory accounting, bounded results and worker diagnostics. See the rc1–rc3 entries below for implementation and compatibility details.
- Release
tay-client1.4.3 with updated scheduling and transport documentation.
Added
- Add a disposable Docker soak with Python HTTP/Unix workers, retries, persistent/volatile jobs, durable schedules, alternating crash/graceful restarts, catalogued cold backup/restore and terminal-history compaction. Preserve resource measurements and run status for long operational trials.
- Add a cross-version public-API upgrade fixture covering completed/delayed jobs, durable schedules, compaction and restart after cold restore.
Fixed
- Require Phoenix.HTML 4.4 or later to address the attribute-name injection advisory CVE-2026-117645.
- Align SDK, protocol and operations documentation with durable schedules over HTTP and Unix sockets, persistent results, remote HTTP workers and automatic retention/compaction.
1.8.0-rc3 — 2026-10-29
Added
- Enforce schedule
allow,skipandqueuepolicies against the preceding nonterminal occurrences, including policy changes. Persist the active job link and reconcile interrupted delivery with the unchanged deterministic occurrence ID. - Add HTTP schedule registration, listing, inspection and cancellation, with the same producer methods and handles in both Python transports. HTTP worker decorators can reconcile durable startup schedules.
- Add bounded Engine-local queue/task execution rate limits and standalone
TAY_RATE_LIMITSJSON configuration. Only committed starts consume credit; monotonic fixed windows reset with the Engine generation. - Export oldest ready-job age, schedule lag, last checkpoint timestamp and capacity-refusal reasons, with example Prometheus alerts.
- Add schema-2 semantic types 11 (schedule delivery), 12 (historical schedule state/checkpoint), and 13 (complete occurrence membership checkpoints). Checkpoints preserve logical schedule revisions and overlap links, including while replaying concurrent compaction tails. Earlier binaries refuse these events; downgrade after writing them requires restoring a prior backup.
Changed
- Release
tay-client1.4.2. Share schedule payload construction and validation between decorators, Unix producers and HTTP producers. Keep cancelled startup declarations withdrawn during automatic reconnect. - Cache native compiler outputs by source, flags, compiler identity, OTP headers, platform and Mix environment. Rebuild missing artifacts, publish outputs atomically, and preserve the production/test-helper boundary on cached builds.
- Remove the obsolete non-Store-v2 live persistence and execution paths while retaining historical Event decoding.
- Require full qualification and a passing performance regression gate for the exact release candidate commit. Enable the comparison gate by default and enforce a successful full qualification gate before container/PyPI publication. Balance baseline/candidate trials in ABBA order with fresh VMs and retain individual reports to separate filesystem drift from code regressions.
- Bound the release benchmark to eight in-flight jobs, exclude a warmup store, and qualify two independent replicas per platform with eight trials and 10,000 measured jobs each. Refuse noisy cohorts above 10% relative MAD in addition to the unchanged 20% regression threshold.
Fixed
Use an explicit CA-verifying Python TLS probe for HTTPS qualification on macOS and Linux. Check trusted-client acceptance, missing/untrusted-client rejection, server CA trust and hostname validation independently of curl's platform TLS backend. Generate fixture CA extensions from a private config and verify the chain offline, avoiding duplicate extensions from OpenSSL 1.1.1 machine defaults.
Wait for HTTP listener readiness and asynchronous post-compaction status publication in integration tests instead of racing their startup/snapshot.
Share
max_state_bytesbetween jobs, schedules, retained results and admitted operations. Reserve result and lifecycle headroom before accepting work; keep cancellation and settlement available at capacity and preserve recovery limits.Bound schedule operation admission, page schedule lists and directly fetch one declaration. Automatically paginate SDK lists and bound Dashboard/metrics reads.
Preserve every active occurrence across policy changes and checkpoints; refuse unsafe tightening of historical allow declarations with incomplete membership.
Centralize schedule field validation, public projections and auxiliary event classification.
Remove the obsolete missing recovery-test path from qualification; retain Store-v2 large recovery and large-segment coverage.
Bound schedule intervals, timestamps, timer waits and UTF-8 declaration IDs.
Classify proven online headroom refusals as deferred, preserving unknown publication outcomes. Clean up test reservations even when allocation fails.
Monitor coordinator operations so a failed asynchronous call cannot leave the schedule operation queue permanently occupied.
Added
- Add
JobHandle.wait_resultandHTTPJobHandle.wait_resultwith one bounded deadline, terminal errors, and cooperative local cancellation. - Run HTTP and Unix-socket workers through the same
tay workerCLI, preservingtay-worker module:instance. Add read-onlytay doctordiagnostics, exact socket-discovery origin, mTLS checks and a bounded HTTP readiness endpoint. - Compare candidate and previous-release throughput, enqueue/callback p95, sampled RSS/BEAM memory and compaction time using the same public-API harness. Qualification retains JSON/Markdown artifacts and supports an optional regression gate with metadata/sample validation.
Fixed
- Distinguish actual JSON null results, missing retained values, cancelled jobs and unavailable Core reads. Expose typed missing-result/cancellation SDK errors.
- Freeze the full job-options contract across Python and Elixir, rejecting unsupported options, conflicting aliases, invalid limits and rounded-zero timeouts before submission.
- Fence completions to their original HTTP token or Unix connection. Retire stale async work and wait for synchronous HTTP work before session replacement, preserving local capacity across Tay restart.
1.8.0-rc2 — 2026-10-28
Changed
- Discover the shared
/run/tay/tay.sockautomatically in the Engine and Python SDK, including before the listener creates it. Docker workers retain a shared socket volume but no longer needTAY_SOCKET_PATHfor the standard layout. - Use one transport-selection policy for embedded and standalone hosts. Enabling HTTP disables the implicit Unix socket; an explicit socket path enables both. Preserve the resolved endpoint and directory permissions when starting Engine.
- Extract Engine state and execution operations, Native Port framing and metadata codecs, and explicit compaction-publication stages without changing wire or storage formats. Clarify CRC32C implementation and native descriptor ownership.
- Update
tay-clientto 1.4.1 with shared task invocation, producer option validation, and error formatting. Reject malformed false-like argument/options values and duplicate decorated-task submission options consistently. - Isolate Lifecycle command delivery and explicit state/operation structures. Derive in-flight command counts from active permits and preserve FIFO, drain, and stale-acknowledgement behavior within the same owner process.
- Define lifecycle operation transitions and model-check timeout/late-event traces. Classify opaque driver failures after effects begin as unknown outcomes, and cancel an expired policy drain consistently.
- Freeze requests and replies for all Native Port opcodes, including the production/fault-helper capability boundary and malformed message handling.
- Avoid looking up the Unix UID for disabled, explicit, environment-selected, and shared-runtime sockets.
Fixed
- Retry HTTP worker registration after connection loss, both at startup and after session expiry, without replaying execution outcomes.
- Safely serialize task exceptions with invalid Unicode or failing
__str__. Apply finite positive transport timeouts and the same registration/retry validation to HTTP and Unix-socket clients. - Clear completed administrative phases from lifecycle status. Separate operation coordination from command admission and Writer session/bootstrap I/O from pure state construction. Remove the unused operation force field.
- Add successful Native Port payload contracts for reads, directory entries, identities, write receipts, owner facts and filesystem space, exercised against both the Native APIs and the production helper.
- Require Bandit 1.14.1 to address the HTTP/2 memory-amplification advisory CVE-2026-116078.
- Keep result-delivery failures separate from user task failures; a lost success notification no longer causes a contradictory failure notification.
- Allow remote cancellation after a synchronous task returns a loop-owned awaitable, while keeping running synchronous thread work protected.
- Stop the HTTP worker claim loop and cancel/await its execution wrappers during shutdown, preventing late completions after session revocation.
- Enforce error byte limits even for long Unicode exception class names, and ensure text truncation terminates. Avoid repeated result normalization.
- Share HTTP/TLS validation, report socket startup failures with their path, and reuse native cold-copy cleanup while preserving descriptor close order.
- Refresh strict-filesystem tests and TLS fixtures, and discover supported Python interpreters consistently in integration tests.
1.8.0-rc1 — 2026-10-27
Changed
- Updated Bandit to 1.14.
- Updated Plug.Crypto to 2.2.1 to address CVE-2026-105963.
- Accelerated CRC32C with a portable C NIF, retaining the original Elixir implementation for historical comparisons, with no runtime fallback. Large updates run on dirty CPU schedulers; checksum values, incremental registers and storage formats are unchanged.
- Compute Record header and full-record CRC32C in one NIF call during encoding, continuing the payload checksum from the header register without concatenation.
- Generate native editor metadata with
mix tay.native.editor, independently from native compilation and production builds.
1.7.0 — 2026-10-20
Changed
- Returned to one complete
tayHex package and onetayOCI image. HTTP and Dashboard remain bundled, while the standalone Dashboard stays disabled by default and starts only whenTAY_ENABLE_DASHBOARD=true. - Retained the transport-independent Protocol v1 and execution-boundary improvements developed during the 1.6 series.
Fixed
- Avoided redefining the native Mix compiler task when Tay is loaded more than once as a path or Hex dependency.
- Preserved JSON
nullworker results across Unix-socket and HTTP transports by canonicalizing them to Elixirnilat the protocol boundary.
1.6.x — Experimental, withdrawn
- The
tay_core/tay_http/taypackage split was an unsuccessful experiment: its operational and release complexity outweighed the small RAM reduction. The 1.6 series is not recommended for production use. Stay on 1.5.3 until 1.7.0 is released, then upgrade directly to 1.7.x.
1.5.3 — 2026-10-18
Fixed
- Applied terminal-retention compaction to finished volatile jobs in the live ETS projection, keeping dashboard history and in-memory accounting in sync.
1.5.2 — 2026-10-17
Changed
- Clarified the top-level source-of-truth contract for persistent Store-v2 jobs and RAM-only volatile jobs.
Fixed
- Updated the standalone release smoke test to verify the Store-v2
STORE-V2authority marker andCURRENTpointer across restart instead of expecting the removed Store-v1STOREmarker. - Removed a 100-ms timing assumption from the blocked-recovery lifecycle test so slower Store-v2 startup still exercises the same synchronization boundary.
1.5.1 — 2026-10-17
Added
- Added immutable per-job
:persistentand:volatiledurability with job-over-worker-over-global precedence. Volatile jobs share execution and accounting machinery but remain entirely in the live ETS projection. - Added global persistent-journal group commit with bounded event-count and interval thresholds while retaining post-fsync acknowledgements.
- Updated
tay-clientto 1.4.0 with validated per-enqueue and decorated-task durability options for both Unix-socket and HTTP producers.
1.5.0 — 2026-10-17
Changed
- Removed Store-v1 startup, recovery, migration, adoption, rollback, and native helper support. Tay 1.5.0 opens Store-v2 storage only; upgrade older stores with a 1.4.x release before installing 1.5.0.
- Initialized new storage directly with an empty Store-v2 generation and no
transient Store-v1
STOREmarker or root segment directory. - Reworked online compaction to reconstruct its checkpoint from the sealed immutable Store-v2 generation at an exact durable frontier instead of copying Engine ETS and terminal projections.
- Allowed Store-v2 automatic retention compaction to run with active execution.
- Centralized catch-up limits, capped the in-memory online delta at 65,536 events and 64 MB, and exposed peak-delta, preparation, total, and net-reclamation measurements.
Fixed
- Aligned the 10,000-job automatic-retention qualification with the online compaction policy so active scheduled and available jobs cannot indefinitely starve expired-history reclamation.
1.4.8 — 2026-10-17
Security
- Updated Bandit to 1.13.1 for the HTTP/1 authority-validation and HTTP/2 blocked-send fixes, removed the obsolete advisory exception, and restored HTTP/2 support.
Changed
- Updated the Python client package to 1.3.2, corrected its public task-owner typing, and made unsupported schedule operations fail explicitly.
- Added dependency auditing, Python 3.11–3.14 testing, Python static type checking, and complete standalone workflow path triggers to CI.
- Kept production container examples on immutable version tags and separated published-image usage from local image builds.
1.4.7 — 2026-10-16
Fixed
- Reclaimed transient startup and recovery heaps in the Engine, lifecycle guardian, and executor server after readiness is published.
1.4.6 — 2026-10-15
Added
- Added live BEAM CPU utilization, online scheduler capacity, and run-queue pressure to the Dashboard Overview with an explicit shared-runtime boundary.
Changed
- Replaced native reply-header offsets, field widths, and packet-allocation growth values with named protocol constants and a shared big-endian encoder.
1.4.5 — 2026-10-15
Added
- Added human-readable, on-demand Dashboard details for storage records, including explanations for encoded enum values and execution tokens.
- Added offset-cursor pagination for large segment inspections.
Changed
- Moved storage-record decoding out of the Engine command loop and added a bounded preview cache so inspection work cannot delay job processing.
- Bounded decoded field and raw-payload rendering to keep Dashboard pages responsive for large records.
Fixed
- Made the fault-injection lock-loss cleanup unambiguous so strict GCC builds
pass with
-Werror=misleading-indentation. - Removed the synchronous schedule-operation cycle between the Engine and Executor Server. Registrations, advancements, and cancellations now retain request order without blocking executor capacity polling, acknowledge only durable commits, and report unknown outcomes without automatic retries.
1.4.4 — 2026-10-15
Changed
- Accelerated CRC32C with a table-driven implementation and added bounded sequential read-ahead with direct reads for large records across recovery, Store-v2 validation, and publication.
- Reduced native-helper allocation pressure with chunked write verification, streamed reply bodies, reusable request storage, and geometrically grown descriptor chains while preserving readback and durability checks.
- Combined append paths and avoided re-encoding records during segment rotation; compaction estimates now measure snapshot payloads without materializing them.
- Computed sealed-segment SHA-256 during the validation pass instead of reading each source segment a second time.
- Bounded Dashboard segment inspection to the requested record limit, using sealed footers or active Writer state for the total count.
- Standardized displayed and configured binary byte units as KB, MB, GB, and
TB, where every step is 1,024; standalone configuration no longer accepts
the
KiB,MiB, orGiBsuffixes. - Updated the Python client package to 1.3.1 for its matching terminology change and release artifact.
- Replaced native protocol and fault-injection magic numbers with named, wire-stable constants and documented their meanings.
1.4.3 — 2026-10-15
Changed
- Dashboard storage-record inspection now identifies the related job or schedule, revision, timestamp, and event summary. Decoded payload details can be expanded inline, and job identifiers link to their job page.
1.4.2 — 2026-10-15
Security
- Disabled Bandit's HTTP/2 listener while a Hex release containing the fix for GHSA-69m6-wcv4-rwcf is pending. The acknowledged advisory is not reachable by Tay; HTTP/1.1 remains available.
Fixed
- Added the missing
telemetry_metricsproduction dependency to the standalone release lockfile.
1.4.1 — 2026-10-15
Added
- Added low-cardinality
Telemetry.Metricsdefinitions for command latency, durable transitions, group commits, engine resources, schedules, and queues. - Added a supervised bounded poller for engine/queue gauge snapshots and an
optional
opentelemetry_telemetrybridge for public-command spans.
Changed
- Public Tay commands now emit standard Telemetry
start,stop, andexceptionspan events with bounded operation/outcome metadata. - Updated transitive dependencies, including
phoenix_pubsubto 2.4.1 andmakeupto 1.2.3.
1.4.0 — 2026-10-15
Added
- Enabled Event-v2 schema-2 schedule registration, advancement, cancellation, and successful-result records across live persistence, Store-v1 recovery, Store-v2 checkpoints, compaction, and restart recovery.
- Added durable schedule inspection/cancellation APIs and a Dashboard Schedules page showing expression, next/last run, and lifecycle state.
- Added bounded physical record inspection for Dashboard storage segments, including sequence, offset, semantic type, schema, and payload size.
Changed
- Successful remote-worker results now remain available after restart and are removed when compaction removes their completed job.
- Schedule declarations no longer depend on a connected client replaying them after an Engine or listener restart.
1.3.6 — 2026-10-14
Fixed
- Deferred the Engine and Writer full-GC pass until both active and running work have drained, cancelled a pending idle reclaim when new work arrives, and avoided repeatedly collecting an unchanged idle engine.
- Allowed a fenced offline checkpoint to finish after legitimate mutations advance its source sequence while retaining the source-epoch fence, so an actual epoch replacement is still rejected.
- Kept online-checkpoint ETS snapshot cleanup within its map-shaped reference contract, eliminating an opaque table-identifier Dialyzer warning.
- Kept the live blocked-job count exact across retry and cancellation transitions instead of repairing it only on restart.
Changed
- Added Dialyzer to continuous integration and the release qualification checklist.
- Removed duplicate retained-definition byte accounting from Engine state; the status metric now uses the compaction estimate's equivalent counter.
1.3.5 — 2026-10-11
Fixed
- Preserved the
:ets.table()type across online-checkpoint snapshot creation, ingestion, and cleanup so named tables and opaque table identifiers both satisfy the ETS contract without ElixirLS/Dialyzer warnings.
Changed
- Reduced the Writer GenServer to API and callback routing by extracting its configuration, state/fail-closed handling, recovery/activation lifecycle, group-commit state, offline and online compaction orchestration, and physical segment operations while retaining a single serialized native-port owner and the existing durability/fault boundaries.
- Decomposed the Engine command owner into focused command, group-commit, persistence, projection/accounting, and online-checkpoint modules. The Engine remains the sole GenServer and ETS/runtime-state owner, preserving command ordering, durability acknowledgements, and fail-closed generation fencing.
1.3.4 — 2026-10-11
Changed
- Made online Store-v2 checkpoints converge through bounded multi-round tail catch-up while admission remains open. The final fence is requested only for a small residual tail, and an overloaded builder abandons its candidate without replacing or poisoning the live source epoch.
- Removed full ETS list/map duplication from live checkpoint ingestion and kept
full candidate replay outside the online publication fence. The fenced path
now syncs the bounded final delta, atomically publishes
CURRENT, and performs bounded authority validation; restart retains full canonical replay. - Kept standalone container health green during normal online checkpoint
preparingandswitchingphases while still probing the configured transport.
Fixed
- Reopened the previous active segment and released queued enqueue calls after a
known pre-
CURRENTcandidate failure. AmbiguousCURRENToutcomes remain fail-closed. - Added bounded checkpoint catch-up and final-delta measurements, and made compaction log messages identify their normalized event and reason.
1.3.3 — 2026-10-11
Fixed
- Changed periodic Store-v2 checkpoints to capture the live active and terminal projections at an exact durable sequence frontier instead of replaying every old journal segment. Checkpoints can now run with active jobs, preserve concurrent mutations in the ordered tail, release their temporary ETS copy after ingestion, and retain the existing verified atomic publication path.
1.3.2 — 2026-10-10
Fixed
- Made segment rollover constant-time with respect to retained history by replacing foreground semantic replay with pinned identity, exact-size, CRC, and successor-header validation. Durable file and directory sync barriers remain unchanged.
1.3.1 — 2026-10-10
Added
- Added configurable strict-durability group commit for concurrent enqueue
requests via
group_commit_interval_msand standaloneTAY_GROUP_COMMIT_INTERVAL_MS, including batch telemetry, fault/shutdown coverage, and a seven-interval throughput/latency benchmark recipe. - Added standalone
TAY_DEFAULT_QUEUE_CONCURRENCYconfiguration instead of a hard-coded execution limit of 10 for thedefaultqueue. - Added standalone
TAY_CALLER_TIMEOUT_MSconfiguration and preserved a bounded reason in HTTPunknown_outcomeresponses for diagnosis. - Added optional periodic Store-v2 semantic checkpoints through
compaction: [checkpoint_interval: ...]and standaloneTAY_CHECKPOINT_INTERVAL_MS. Checkpoints publish a verified snapshot plus ordered tail without blocking normal preparation-time admission, skip unchanged state, defer while active jobs exist, and recover from the durable sequence frontier. Standalone enables them every 60 seconds by default;0explicitly disables them. - Made every Overview job-status card navigate to the Jobs page with its state filter selected, including keyboard focus and visible hover/focus feedback.
- Released
tay-client1.3.0 withretriesandbackoffsupport onTayHTTPWorker.task; decorator retry settings now also act as defaults forTask.enqueueand can be overridden per submission.
Changed
- Split Engine configuration validation into named, thematic validators and replaced unexplained numeric limits with documented module attributes.
- Defined zero Dashboard/API terminal retention as a one-shot full terminal-history compaction; active jobs remain protected and the durable future retention is clamped to the one-hour minimum.
- Decoupled
tay-clientreleases from Tay versions. The release helper and PyPI workflow now skip an unchanged Python client and require its independent version to increase only whenclients/python/changes.
Fixed
- Kept the live active-memory charge ledger across online checkpoint adoption, made retained-byte charging stable across Event-v1 and Store-v2 projection fields, and fail closed on negative or divergent active accounting.
- Made enqueue wait through the short fenced checkpoint switch instead of
returning
unavailable, bounded by the configured caller timeout. - Added an idle full-GC pass for the Engine and Writer after the active workload drains, releasing transient process heaps and binary references retained by a large burst.
- Included the HTTP error code in Python
ServerErrormessages when Tay does not provide a human-readable reason, while retaining the structuredcodeanddetailsattributes. - Aligned the OCI health-check startup grace period with Tay's 15-minute recovery deadline so large valid histories are not declared unhealthy while replay is still in progress.
- Kept the selected Dashboard theme stable across LiveView refreshes and made status cards use the complete dark palette during system-theme fallback.
1.3.0 — 2026-10-09
Changed
- Made Event v2 the production semantic implementation while preserving all six frozen Event-v1 lifecycle schemas and literal bytes. The obsolete Event v1 facade has been removed; runtime replay works entirely through Event v2.
- Reserved and validated Event-v2 schema-2 types 7 through 10 for future durable schedule registration, advancement, cancellation, and successful result recording. Runtime emission and recovery projection are not enabled in this release.
- Added pull-request and main-branch CI for the Elixir and Python suites, and made unsafe symlinked test data roots fail fast.
- Corrected the operations documentation for online compaction.
1.2.0 — 2026-10-08
Added
- Allowed
TAY_MAX_STATE_BYTESto use integer decimal or binary size suffixes, such as5GBor5GiB, while preserving plain-byte values.
1.1.1 — 2026-10-08
Fixed
- Restored spacing between Dashboard card grids and the explanatory text that follows them.
1.1.0 — 2026-10-08
Changed
- Made Dashboard terminology and inline explanations understandable without prior Erlang/BEAM knowledge, including job states, runtime memory, active-job safeguards, and durable storage.
- Replaced the separate active-state byte and value-node limits with one
max_state_bytesbudget. The estimate now uses the job's flat BEAM heap shape, machine word size, retained canonical encoding, and binary payload bytes; the formermax_state_nodesoption remains accepted but ignored for 1.x configuration compatibility. - Displayed byte values in the most readable binary unit, including KB for sub-MB values and GB for large limits.
Fixed
- Preserved the expanded Storage files section across live data refreshes.
1.0.0 — 2026-09-30
Added
- Released the stable Tay 1.0 engine, Python client, standalone OCI image, and optional LiveView dashboard.
- Stabilized the versioned storage formats, executor protocol, recovery behavior, and documented compatibility contracts established during the 1.0.0 release-candidate series.
Changed
- Promoted the validated 1.0 operating profile from release candidate to the stable 1.x release line.
1.0.0-rc.9 — 2026-09-30
Changed
- Removed active-job and terminal-history count limits. Both Dashboard counters now show current counts without a maximum, and neither count can reject admission or trigger pressure compaction.
- Kept terminal cleanup governed exclusively by the configured time retention; active payload byte and value-node safeguards remain in place.
- Made a successful Dashboard compaction persist its selected terminal retention in Store-v2 and override the startup environment on later restarts.
- Ran Dashboard-triggered compaction asynchronously so the LiveView remains responsive while jobs continue to be accepted and executed.
- Buffered source-segment inspection during compaction preparation to avoid a native storage round trip for every record.
Fixed
- Kept automatic compaction estimates available when persisted terminal retention is infinite.
1.0.0-rc.8 — 2026-09-30
Fixed
- Preserved the durable availability-order frontier across online compaction so concurrent inserts can be replayed after expired terminal jobs are removed.
- Kept Store-v2 manifests backward-compatible while authenticating the allocator frontier for newly compacted epochs.
1.0.0-rc.7 — 2026-09-30
Fixed
- Allowed online compaction to replay epochs containing multiple valid
post-manifest source rotations instead of rejecting them as
source_segments_missing. - Made compaction retries publish successfully after an earlier preparation failure rotated the live tail while preserving the authoritative epoch.
1.0.0-rc.6 — 2026-09-30
Fixed
- Synchronized Engine's physical segment frontier with Writer's source rotation before background compaction admits further mutations.
- Prevented valid post-rotation receipts from being rejected as
invalid_writer_receipt, which previously revoked the live generation while compaction was preparing its candidate. - Preserved fail-open behavior after a preparation failure even when online compaction had first rotated a non-empty active tail.
1.0.0-rc.5 — 2026-09-30
Fixed
- Replayed Store-v2 segments through a bounded chunk cache instead of issuing native-owner calls for every record, keeping Writer admission responsive while online compaction prepares its candidate.
- Aborted failed pre-switch candidates without poisoning the authoritative Writer or retiring the live Engine generation.
- Preserved the existing generation and returned lifecycle state to
readywhen a background compaction builder fails before the atomic switch.
1.0.0-rc.4 — 2026-09-30
Fixed
- Moved online-compaction source recovery out of the Engine mailbox loop so large terminal histories no longer block job admission and execution during the preparing phase.
- Replayed immutable Store-v2 segments directly in the background compaction builder instead of first materializing and copying the complete job map in Engine at the start of preparation.
- Released transient recovery and compaction heaps in the processes that own them, preventing terminal-history recovery memory from remaining allocated after activation or compaction.
- Supported online compaction when the current Store-v2 tail is empty without racing concurrent appends.
1.0.0-rc.3 — 2026-09-29
Fixed
- Kept terminal job payloads in the disk-backed projection while serving job pages through a compact ordered inspection index.
- Loaded only the terminal jobs selected for the current cursor page instead of folding and repeatedly sorting the complete terminal history.
- Released the temporary recovery heap before the Engine enters its steady-state loop.
- Clarified that Dashboard state-capacity counters describe active-job admission limits rather than measured runtime memory.
1.0.0-rc.2 — 2026-09-29
Fixed
- Throttled and coalesced Dashboard refreshes under transition-heavy workloads.
- Kept Dashboard filter controls and cursor pagination stable during live refreshes.
- Preserved HTTP enqueue rejection diagnostics, including capacity reasons.
1.0.0-rc.1 — 2026-09-29
Added
- Added ergonomic Python task decorators with stable automatic or explicit
public names, local registry lookup, argument serialization through
task.enqueue(), duplicate-name protection, and synchronous/asynchronous handler execution. - Added a production idempotency guide for at-least-once jobs and financial operations.
- Added a repeatable Tay 1.0 readiness audit harness with explicit PASS/FAIL/SKIP/UNKNOWN classification and isolated release artifacts.
Fixed
- Passed the parent test build's complete dependency code path to independent BEAM VMs so whole-VM crash tests can start every Tay application dependency.
- Corrected the Python dependency audit to inspect the fully resolved input without misclassifying command-line or environment failures as vulnerabilities.
Changed
- Declared the documented single-node, single-writer contracts as the Tay 1.0 release-candidate surface. Record v1, STORE v1, Segment v1, Event v1, and the existing fail-closed recovery policy remain unchanged.
0.15.2 — 2026-09-27
Changed
- Renamed the HTTP worker lifecycle methods to
register()andserve_forever()to make explicit that registration alone does not process jobs. Keptstart()andrun()as deprecated compatibility aliases.
0.15.1 — 2026-09-27
Fixed
- Make the HTTP-only health test probe a listening TCP port without starting a
production-durability Store on the CI runner's unsupported
/tmpfilesystem. Production standalone durability remains strict:sync.
0.15.0 — 2026-09-27
Changed
- Added mTLS-capable remote HTTP workers with long polling, execution acknowledgements, bounded results, cancellation events, and session expiry.
- Allow standalone HTTP-only operation with
TAY_SOCKET_PATH=off; the local Unix socket remains available when local workers are desired. - Added Python
TayHTTPWorkerfor remote task execution and kept the local socket client available. Named the Python HTTP response and worker limits. - Merged the dashboard into the single
tayHex package and moved its release host understandalone/; removed the separate dashboard package.
0.14.0 — 2026-09-27
Changed
- Replaced the gRPC/Go gateway with an optional Bandit HTTP/JSON producer API in the Elixir Engine; Cowboy and cowlib are not dependencies.
- Added the Python HTTP/JSON producer client with mTLS support and consolidated the container examples into one Compose file.
0.13.1 — 2026-09-26
Fixed
- Corrected Python client import ordering and formatting so the tagged source passes its PyPI publication checks.
- Made optional gRPC and PKCS#12 dependency checks explicit at module scope.
0.13.0 — 2026-09-26
Added
- Added an opt-in gRPC producer API for enqueue, status, cancellation, and result retrieval.
- Added direct mTLS support for non-loopback gRPC listeners and Python clients, including a single PKCS#12 bundle option in the Python SDK.
Fixed
- Enabled the dashboard endpoint in its HTTP test configuration and refreshed nested dependency locks for the new Tay gRPC dependencies.
0.12.0 — 2026-09-25
Added
- Added online Store-v2 compaction with explicit
compacting/preparingandcompacting/switchinglifecycle phases. - Added regression coverage proving admission and job execution continue while a replacement epoch is built in the background.
- Added
TAY_TERMINAL_RETENTIONduration configuration for the standalone runtime, including minute, hour, and day forms such as30m,24h, and7d. - Bundled the optional dashboard into the single
tayOCI image, enabled withTAY_ENABLE_DASHBOARD=true.
Changed
- Store-v2 compaction now rotates to a frozen frontier, builds its candidate in a monitored background process, journals concurrent durable mutations, and catches them up behind an atomic publication fence without restarting the Engine.
- The first Store-v1 to Store-v2 adoption remains an explicit draining
migratingoperation because the frozen v1 format has no safe online catch-up boundary. - The dashboard reports compaction and migration as storage-maintenance states instead of presenting normal compaction as crash recovery.
- Container publication now produces only
ghcr.io/andriisydorenko1904/tay; the separatetay-dashboardimage is retired.
0.11.3 — 2026-09-25
Changed
- Added a sustained-ingress regression test proving that a capacity-16 external executor refills a queue to its concurrency limit of 10 while producers continuously enqueue without pauses.
- Added one-command local benchmark profiles for lifecycle throughput, schedule lag under load, cold recovery, storage rotation and replay.
Fixed
- Prevented sustained enqueue traffic from filling the Engine mailbox ahead of executor completions and queue demand. Client admission remains unchanged, while a guardian-owned FIFO now delivers one mutation at a time to the already-serialized durable Writer and yields between append boundaries.
- Fixed benchmark JSON output for tuple-valued status fields such as terminal
retention and canonicalized macOS
/tmppaths for native storage safety.
0.11.2 — 2026-09-25
Changed
- Python clients now retain successful schedule declarations and replay them during every listener reconnect before advertising worker capacity or reporting the connection as ready.
- Scheduled occurrences now use deterministic job IDs and remain pending while admission is unavailable instead of being silently dropped under pressure.
Fixed
- Restored cron and interval declarations automatically after compaction or an Engine restart while the declaring Python client remains alive.
- Prevented one-shot schedule ticks from disappearing when active-state capacity is temporarily exhausted.
0.11.1 — 2026-09-25
Changed
- Automatic compaction now defers while active jobs exist, keeping ordinary admission available during sustained workloads.
- Terminal-count pressure now compacts to an 80% low-water mark instead of the exact configured maximum, preventing restart churn after each completion.
- The dashboard now explains a busy lifecycle-operation slot, displays unknown capacity instead of false zeroes during recovery, and refreshes automatically when the Engine becomes ready again.
Fixed
- Prevented terminal-history pressure from repeatedly taking Tay unavailable while a large active workload was still being processed.
- Prevented a freshly loaded dashboard from remaining permanently empty after mounting during the compaction restart window.
0.11.0 — 2026-09-25
Added
- Added a configurable
max_terminal_jobssafety bound and standaloneTAY_MAX_JOBS,TAY_MAX_STATE_BYTES,TAY_MAX_STATE_NODES, andTAY_MAX_TERMINAL_JOBSsettings. - Added dashboard runtime-memory and active/terminal capacity diagnostics.
Changed
- Split runtime state into a hot private-ETS projection for active jobs and a disposable disk-backed projection for terminal inspection history.
- Made active admission limits apply only to actionable work; completed, cancelled, and discarded jobs no longer consume hot job/byte/node capacity, including after recovery.
- Kept filtered statistics, queues, job lookup, retry, and bidirectional pagination available across both projections.
Fixed
- Prevented large completed/discarded histories from permanently rejecting new
jobs with
retained_nodesorretained_jobs. - Added pressure-triggered compaction that retains the newest bounded terminal history without waiting for normal age, size, ratio, or cooldown gates.
0.10.0 — 2026-09-24
Added
- Added a bounded catalog of the 128 newest canonical storage segments to the Engine status snapshot.
- Added a collapsible dashboard table with each segment's canonical filename, active/sealed state, size, record count, and sequence range.
- Added bounded
free,claimed,reserved, andsubmittedclient-slot counts to the Engine status snapshot. - Added a backward-compatible machine-readable capacity reason to Protocol v1
error responses and preserved it in Python
ServerError.details. - Added
deploy-helper.shto publish the version-matched container images and Python client through their GitHub Actions workflows.
Changed
- Moved normal command replies to the lifecycle Guardian so it releases the exact submitted permit before making success or error visible to the caller.
- Expanded the project README with clearer architecture, installation, and deployment guidance.
Fixed
- Fixed fast sequential producers transiently exhausting
client_slotsbecause successful replies could previously race ahead of permit release.
0.9.9 — 2026-09-24
Added
- Added canonical history size in MB, segment count, and configured terminal retention to the dashboard Overview page.
- Added an explicit retention-hours control to manual dashboard compaction.
- Exposed the configured compaction terminal retention in the bounded Engine status snapshot.
Changed
- Manual dashboard compaction now reports the selected retention alongside the number of removed and retained jobs and reclaimed bytes.
- Clarified that retention is time-based rather than a disk quota and that the displayed canonical history excludes temporary compaction headroom.
0.9.8 — 2026-09-24
Added
- Added a light/dark dashboard theme that follows the operating-system setting by default and can be overridden with a persistent theme control.
- Added state-specific colors throughout job, queue, and overview displays.
- Added a confirmation-protected manual compaction action on the Overview page with a human-readable completion summary.
Changed
- Replaced raw diagnostic maps with readable outcome titles and explanations; compact version/code data remains available under Technical details.
- Removed the redundant Apply filters button because LiveView applies state, queue, and partial worker filters as they change.
0.9.7 — 2026-09-24
Added
- Added exact filtered job totals and opaque previous/next/last cursors to the public inspection response.
- Added complete dashboard navigation for first, previous, next, and last pages, including current/total page and visible/total job counts.
Changed
- Made filtered cursor pages contain matching jobs up to the requested limit, including sparse partial-worker matches.
- Kept version-one job cursors readable while emitting the bidirectional version-two cursor format.
Fixed
- Fixed the dashboard's one-way pagination, which previously provided no way to return to earlier pages or jump to the final page.
0.9.6 — 2026-09-23
Changed
- Gave dashboard package publication its own committed lock file so switching from the local Tay checkout to the Hex dependency no longer mutates the development lock.
- Required Tay 0.9.5 or newer for dashboard partial worker-key filtering while allowing dashboard releases to version independently from the core package.
0.9.5 — 2026-09-23
Added
- Added partial worker-key filtering to the inspection API and dashboard while preserving cursor/filter binding.
Fixed
- Made stable schedule declarations idempotent so periodic reconciliation no longer resets interval timers or triggers a job on every reconciliation pass.
0.9.4 — 2026-09-23
Fixed
- Included the JSON codec required by Phoenix LiveView in the standalone dashboard release, preventing WebSocket joins from crashing after upgrade.
- Parsed URL-encoded query parameters in the standalone endpoint so filters and cursor links also work during static and non-JavaScript navigation.
0.9.3 — 2026-09-23
Added
- Added dashboard version, lifecycle context, attempt semantics, and readable diagnostic-code descriptions to job details.
Fixed
- Fixed LiveView origin validation behind Docker port publishing and reverse proxies while retaining same-origin protection.
- Made job filters usable with both live events and ordinary GET submission, restored no-JavaScript cursor navigation, and exposed page position.
- Prevented executor connection send failures from being misclassified as protocol error codes and crashing the connection process.
0.9.2 — 2026-09-23
Fixed
- Fixed standalone dashboard LiveView connections when accessed through local
loopback aliases such as
127.0.0.1, restoring interactive job filters. - Changed job cursor pagination to use LiveView patch navigation and added regression coverage for distinct pages and filtered results.
0.9.1 — 2026-09-23
Added
- Added the dashboard-enabled OCI distribution with one Tay Engine, the Executor Protocol Unix socket, and a self-contained Phoenix LiveView UI.
- Added a Compose example, non-root/read-only runtime hardening, Engine and HTTP smoke coverage, multi-architecture GHCR publishing, and complete deployment documentation.
- Kept built-in HTTP Basic authentication optional and disabled by default; deployments may enable it with a paired username/password or rely on their private network, loopback binding, VPN, or trusted ingress boundary.
0.9.0 — 2026-09-23
Added
- Added an official minimal standalone OTP release and Debian-slim production image for non-Elixir Executor Protocol v1 clients, without changing the Hex package or embedded startup contract.
- Added strict runtime environment parsing, Engine-plus-UDS readiness checks, non-root/read-only container support, a generic Python worker Compose example, release/container lifecycle tests, and stable/prerelease-aware GHCR publishing.
0.8.1 — 2026-09-22
Added
- Added the opt-in Engine option
initialize: :if_missingfor embedding applications that need first-start creation of a genuinely missing store. - Kept the default existing-only startup model and fail-closed recovery: an existing, corrupt, partial, unsupported, inaccessible, or busy store is never reinitialized, repaired, replaced, truncated, or used as a bootstrap signal.
- Added an atomic native ownership operation that creates the owner lock only when it creates the final storage root, preventing Engine-level TOCTOU checks.
0.8.0 — 2026-09-22
Added
- Added the stable, bounded public inspection API: cursor-paginated job listing, incremental state statistics, and public queue runtime snapshots.
- Added generic payload-bounded job-transition and queue-control telemetry.
- Added the separately published optional
tay_dashboardPhoenix LiveView package with overview, job filtering/details, retry/cancel, queue controls, live refreshes, host-router integration, and explicit authentication guidance. - Preserved all frozen durable storage formats and kept Phoenix, LiveView, Plug,
HTML, and JavaScript dependencies out of the core
taypackage.
0.7.1 — 2026-09-22
Fixed
- Fixed a circular
GenServer.calldeadlock between executor dispatch and completion on connections with capacity greater than one. Outbound delivery is now mailbox-ordered without synchronously blocking the executor server; durable-start ordering, completion acknowledgements, disconnect recovery, reservation cleanup and at-least-once execution semantics are preserved. - Added a deterministic capacity-two dispatch/completion overlap regression test and a concurrent multi-capacity stress test.
0.7.0 — 2026-09-21
Added
- Executor Protocol v1 now has automatic, cross-language local socket discovery:
explicit path,
TAY_SOCKET_PATH, XDG runtime,TMPDIR, then per-UID/tmp. Normal Engines andTay()therefore connect without socket configuration; automatic directories are private andexecutor_socket: nilis the explicit listener opt-out. Stale cleanup now verifies the Unix socket file type before unlinking and refuses arbitrary filesystem objects. - Added an opt-in, Unix-domain-socket-only Executor Protocol v1 listener with bounded framed JSON, explicit hello/register/capacity lifecycle, per-task dispatch selection, durable enqueue/status/cancel bridging, timeout fencing, disconnect recovery and bounded live-generation result retention.
- Added the separately packaged, stdlib-only
clients/pythonSDK. It supports producer, embedded and dedicated worker modes, task decorators, reconnecting task registration, JSON validation, bounded result/error reporting and thetay-workerentry point. - Preserved the frozen Record/Segment/Event v1 format. Result values are not
invented as Event-v1 fields: only completion is durable, while successful
values are retained up to
executor_max_resultsin the current listener generation. Durable periodic scheduling and custom retry policies remain deferred. - Centralized the immutable Event-v1 retry delay/jitter constants so all retry producers and interval checks use the same frozen policy.
0.5.0 — first public preview
Added
- Durable single-node job core: frozen Record v1 and Segment/STORE v1 framing, canonical Event v1 semantics, an authoritative append-only log, bounded admission, same-ID insertion reconciliation and disposable ETS projections.
- Supervised execution lifecycle: scheduling, automatic bounded retries, revision-checked cancellation/manual retry, queue pause/resume, drain and explicit fresh-generation stop/restart. Worker effects are at-least-once; neither exactly-once external effects nor multi-node execution is supported.
- Fail-closed recovery: complete contiguous understood events replay even when prior caller acknowledgements are unknown. Torn, corrupt or unsupported history preserves evidence and refuses writable activation; no automatic tail repair, truncation or partial-state publication is provided.
- Qualification: unchanged binary/Event fixtures, macOS development and validated Linux/Btrfs strict-sync ordinary suites, ASan/UBSan, independent crash/race and cold-restore tests, detached consumer releases, 10,000-job reconstruction, 1 GB physical recovery, 300-segment tests and the measured benchmark scenarios. The R5 profile is finite and target validation is required; see compatibility and limits.
- Limitations: no hardware-independent power-loss certification, automatic repair, live backup, retention/compaction, distributed execution or arbitrary workload/OS/filesystem support. Phase 11 snapshots/retention/compaction and Phase 12 orchestration/uniqueness remain deferred.
Earlier v0.1.0–v0.4.0 Git tags mark development milestones, not prior public
Hex releases. See compatibility and
operations for the supported release boundary.