Releases: adz/Axial
Release list
v0.9.3
Axial 0.9.3
Fix
Axial's diagnostics and outcome types no longer depend on F#'s reflection-based structured printer, which NativeAOT
and trimming remove. Under NativeAOT, FiberRegistry.DumpAt, FiberDump.renderAt, telemetry fiber-status tags,
Exit.toResult failure messages, and process error rendering could throw or print the wrong text. So could any
application code calling ToString() on an Exit, Cause, or FiberStatus.
Public unions now have hand-written ToString() overrides:
Exit,Cause,FiberStatus,FiberId,FiberDump,LogLevel,StreamStep, andAttributeValueProcessError,ProcessEvent,InputSource, andOutputTarget;ProcessResultrenders a one-line summaryHttpError,Method, andRequestBody;HttpResponserenders a one-line summaryFileSystemError,EnvironmentVariableError, andBaseRuntimeError
Error types use their existing describe text. Payloads inside Exit and Cause render with their own ToString,
so application error types should override it too.
New
AXG006 (ReflectionFormatting) in Axial.Guardrails reports formatting that needs the structured printer.
It covers ToString(), string, interpolation holes, %A, and boxed arguments to String.Format and similar
methods, applied to F# unions, records, FSharp.Core collections and options, and type parameters. It runs in
application and library projects. See the Guardrails notes for the rule and the axial-allow-reflection-format
directive.
The NativeAOT probe (scripts/run-aot-probe.sh) now renders these types, dumps a fiber registry, and runs a deep
synchronous loop, so a regression fails the release checks.
v0.9.2
Axial 0.9.2
Fix
Flows are now stack safe when their steps complete synchronously. Each bind, map, loop iteration, traversal
element, stream pull, and schedule recurrence previously nested further into the stack, so long chains
overflowed it and terminated the process. On a 1MB thread stack (the Windows default) that took only a few
thousand steps: a flow { for ... } over a large sequence of cached or already-known values was enough.
Affected shapes, all covered by tests/Axial.Tests/StackSafetyTests.fs on a 1MB-stack thread:
forandwhileloops inflow { }Flow.traverseandFlow.sequence- long left-nested
Flow.bind,Flow.map, andFlow.orElsechains - recursive flows deferred with
Flow.delayor theflow { }builder FlowStreampipelines (for examplefilterskipping long runs) andSchedule.repeat/Schedule.retry
Flow invocation and synchronous fold continuations now count nesting depth per thread; past a fixed depth,
execution continues on a fresh thread-pool stack via Task.Run, which preserves AsyncLocal runtime state and
cannot deadlock a caller that blocks under a SynchronizationContext. Already-completed executions also skip
the task state machine, so each step costs fewer frames. Fable's Async already trampolines and is unchanged.
Flow values built by eager F# recursion (let rec f n = f (n - 1) |> Flow.map g) still recurse in F# before
Axial runs; defer the recursive call with Flow.delay.
v0.9.1
Axial 0.9.1
Fix
scripts/pack.sh omitted src/Axial.Layers/Axial.Layers.fsproj, so 0.9.0's headline addition
(Layer.pool/Pool<'resource>, see dev-docs/releases/0.9.0.md) was never actually published to
NuGet despite the project being fully configured for packing (PackageId, description, tags).
Axial.Layers is now packed and published like every other add-on.
scripts/check-source-inventory.sh now also verifies every src project declaring <PackageId>
is included in scripts/pack.sh's project list, so a project can no longer be silently left out of
a release.
v0.9.0
Axial 0.9.0
Axial.Layers
Layer.pool provisions a fixed-size set of resource instances and hands them out round-robin through a new
Pool<'resource> type.
let checkerPool =
Layer.pool 4 (fun _ -> Layer.succeed (FSharpChecker.Create(keepAssemblyContents = true)))Instances are acquired sequentially, in index order, inside the layer's scope; acquireRelease inside the
acquire function releases each instance in the reverse of that order when the scope closes, same as every other
layer combinator. Pool<'resource>.Next() is a thread-safe round-robin accessor; Pool<'resource>.Count and
Pool<'resource>.Instances expose the provisioned set directly.
This targets expensive, non-thread-safe-per-call resources — compiler services, pinned HTTP clients, and similar —
that were previously hand-rolled per consumer with Interlocked.Increment and a manually sized array.
Prompted by FsLiveDocs adopting Axial for its compile/check pipeline; see
dev-docs/current-ideas/fsharp-compiler-adapter.md.
v0.8.0
Axial 0.8.0
Breaking changes
Process.run is now the command-line host runner: it starts a Flow with live process services and returns a host
exit code. The equivalent DSL form is workflow |> run.
Process.runWith environment workflow starts a process Flow with an application's existing environment. The
environment supplies IConsole for typed failure reporting and may contain any other application services.
The former lazy Process.run is renamed to Process.toFlow. It converts a ProcessSpec into a Flow that runs only
when its enclosing Flow runs. Axial.Process.Script is removed; use Process.run, Process.runWith, or their DSL
forms instead.
Process.console is added as the full API equivalent of DSL console. It creates a lazy Flow that forwards both
output channels to the host console. captureParallel now explicitly applies complete capture to every command.
Process.command now accepts an interpolated command template, such as Process.command $"git status", with each
hole preserved as one native argument. The previous executable-and-list form is renamed to Process.commandArgs.
Documentation and release workflow
The documentation site now separates Axial Core, Axial.Process, and Axial.HttpClient into focused documentation
sets, with a package catalogue linking each set. The homepage logo scales to the available viewport on small screens
and is larger on wider displays.
The Getting Started and Why Flow guides now introduce Flow<'env, 'error, 'value> as capabilities, expected failure,
and successful value. They explain why Axial manages effects through one composable runtime model, rather than treating
the type signature as a substitute for cancellation and resource ownership. The Flow type diagram has light and dark
variants.
The Axial.Process landing page now starts with a compact script and links to focused guides for command composition,
output capture, streaming, failures, scripts, worked examples, and application Flow integration. The guides link DSL
names to their API reference entries and distinguish command construction, lazy conversion to Flow, and host execution.
The Task-versus-Flow comparison now links each scenario to its complete GitHub source and the tests that verify the
claimed behavior.
Release documentation is now recorded as an immutable, committed history. The site renders that history on every
deployment, so its version switcher reflects the published Axial releases. The release workflow verifies a candidate
capsule against that history before publication, records the published capsule after publication, and waits for the
Pages deployment before publishing NuGet packages.
FsLiveDocs is updated to 0.6.1, which fixes Markdown and cross-references immediately following rendered F# code
fences.
v0.7.1
Axial 0.7.1
No API changes. This release re-cuts 0.7.0 under a new version number after the resumable-release
mechanism submitted duplicate NuGet symbol package uploads for 0.7.0, one of which nuget.org's
async validator flagged as failed even though the package itself published correctly. 0.7.0's
package and symbol IDs are already immutable on NuGet, so this release exists to give a clean,
unambiguous symbol package for the same content.
The publish-nuget job is now idempotent: it checks nuget.org before pushing each package and
skips anything already published, instead of re-running the full push loop (and re-submitting
symbol packages) on every retry.
v0.7.0
Axial 0.7.0
Axial 0.7.0 is the first release under the Axial name.
Axial continues the workflow foundation previously developed in the FsFlow repository, now with a narrower focus: typed workflows, explicit dependencies, structured failure, concurrency, and operational services for F# applications.
The core API is Flow<'env, 'error, 'value>. Packages use the Axial and Axial.* names. Because the project is still pre-1.0, this release does not retain compatibility aliases for earlier package names or APIs.