Changelog — page 11
New features, improvements, and fixes in the Fluxzero SDK.
Sep 1, 2026 · 1.248.0
Section titled “Sep 1, 2026 · 1.248.0”GitHub
Sep 1, 2026 · 1.248.0
Section titled “Sep 1, 2026 · 1.248.0”Aug 31, 2026 · 2.0.0-RC3
Section titled “Aug 31, 2026 · 2.0.0-RC3”GitHub
Aug 31, 2026 · 2.0.0-RC3
Section titled “Aug 31, 2026 · 2.0.0-RC3”Symmetric document-based Models
RC3 is a focused correctness release on top of RC2. Document-authoritative Models now use the configured DocumentSerializer for both storage and reconstruction, so the Model repository obeys the same complete-document contract as ordinary Document Store reads.
What changed
For @Model(eventSourced = false), every repository read now passes the complete SerializedDocument to DocumentSerializer.fromDocument(...). This applies consistently to direct and current loads, batched loads, cache refresh after a miss or restart, Graph reconstruction, and namespaced repositories.
That makes document-level transformations truly round-trip capable:
- encryption and decryption;
- compression;
- signing and integrity verification;
- custom envelopes;
- transformations that depend on document ID, collection, timestamps, or metadata.
Fluxzero.builder()
.replaceDocumentSerializer(myDocumentSerializer)
.build();
Compatibility
There is no persisted- or wire-format change. The default document serializer produces the same result as before, and event-sourced Model reconstruction is untouched. Existing custom serializers only gain the missing symmetric read callback.
Use SDK and Runtime 2.0.0-RC3 as a matching pair.
Full comparison: 2.0.0-RC2...2.0.0-RC3
Aug 31, 2026 · 2.0.0-RC2
Section titled “Aug 31, 2026 · 2.0.0-RC2”GitHub
Aug 31, 2026 · 2.0.0-RC2
Section titled “Aug 31, 2026 · 2.0.0-RC2”Fluxzero 2.0.0-RC2 — Sharper Models, Reliable Dev Startup
Fluxzero 2.0 is about modeling independent domain lifecycles directly: every independently living object is a @Model, durable @Parent relationships connect those Models, and Graph<T> restores coherent context only where an application needs it.
RC2 keeps that Model/Graph foundation intact and makes the release considerably easier to adopt. The embedded Dev Server can now retain a wider startup window for brand-new consumers, while the human guides, public Javadocs and Java/Kotlin agent manuals have been brought onto the same current API and design language.
Model the lifecycle, then choose storage
The central 2.0 rule is now expressed consistently throughout the documentation:
@Model(materializeGraph = true)
record Project(
@EntityId ProjectId projectId,
ProjectDetails details) {
}
@Model
record Task(
@EntityId TaskId taskId,
@Parent(pathInParent = "tasks") ProjectId projectId,
TaskDetails details) {
}
Task is independent because it has its own identity and lifecycle—not because it is large, searchable or awkward to embed. It can have its own history, retention, deletion and concurrency while still appearing naturally below a Project:
Graph<Project> project = Fluxzero.loadGraph(projectId);
List<Task> tasks = project.childModels("tasks", Task.class);
List<Graph<Project>> activeProjects = Fluxzero.searchGraph(Project.class)
.whereDescendant(Task.class, MatchConstraint.match(false, "completed"))
.fetchAll();
The revised guides cover the complete current contract: typed Model and Graph search, lazy and historical Graph loading, pinned state boundaries, polymorphic and recursive relationships, Graph context and derived properties, direct Model search versus Graph materialization, event publication, event sourcing and the forward-only Aggregate-to-Model migration path.
The bundled Java and Kotlin project files now teach exactly the same capabilities and use the same public type catalogue as the human documentation.
Reliable startup commands in the Dev Server
An embedded Test Server previously started a new consumer one second before the current end of its log. That default is safe and remains unchanged, but it was too narrow for development tools that may publish startup commands before application handlers finish registering.
Embedded owners can now choose the initial look-back explicitly:
Server server = TestServer.startServer(0, Duration.ofSeconds(10));
The duration applies only when a consumer has no stored or client-controlled position. Existing durable positions are never moved backwards, and every existing startServer(port) and local-client entry point retains the one-second default. Embedded tooling can also observe typed consumer readiness instead of confusing an open connection with a registered message handler.
Compatibility and RC status
- RC2 introduces no new Model persisted or wire format compared with RC1.
- Existing Aggregate, messaging, search, scheduling and web applications remain supported.
- Runtime 2.0 remains compatible with 1.x SDK clients.
- SDK 2.0 can use a 1.x Runtime for existing non-Model capabilities; new Model persistence requires Runtime 2.0.
- RC2 artefacts are immutable prereleases. Stable
latestimages, stable Javadocs and stable site signals remain untouched.
| Component | Release |
|---|---|
| Maven BOM | io.fluxzero:fluxzero-bom:2.0.0-RC2 |
| Test Server image | ghcr.io/fluxzero-io/fluxzero-sdk-java/fluxzero-test:2.0.0-RC2 |
| Proxy image | ghcr.io/fluxzero-io/fluxzero-sdk-java/fluxzero-proxy:2.0.0-RC2 |
| Javadocs | 2.0.0-RC2 |
Explore the current 2.0 API
Aug 31, 2026 · 1.247.0
Section titled “Aug 31, 2026 · 1.247.0”GitHub
Aug 31, 2026 · 1.247.0
Section titled “Aug 31, 2026 · 1.247.0”Aug 28, 2026 · 1.246.0
Section titled “Aug 28, 2026 · 1.246.0”GitHub
Aug 28, 2026 · 1.246.0
Section titled “Aug 28, 2026 · 1.246.0”Aug 28, 2026 · 1.245.0
Section titled “Aug 28, 2026 · 1.245.0”GitHub
Aug 28, 2026 · 1.245.0
Section titled “Aug 28, 2026 · 1.245.0”Aug 27, 2026 · 2.0.0-RC1
Section titled “Aug 27, 2026 · 2.0.0-RC1”GitHub
Aug 27, 2026 · 2.0.0-RC1
Section titled “Aug 27, 2026 · 2.0.0-RC1”Fluxzero 2.0.0-RC1 — Independent Models and Graphs
Fluxzero 2.0 introduces a new foundation for persisted domain state: independent Models connected by durable relationships and exposed as coherent Graphs.
In Fluxzero 1.x, an Aggregate root was often forced to own much more than the business domain required. Identity, persistence, history, caching, concurrency and deletion of independently living children all ended up behind one root and usually in one ever-growing stream.
Fluxzero 2.0 separates those concerns:
- every domain object with its own lifecycle becomes an independent
@Model; @Parentrecords relationships without embedding or duplicating child state in the parent;Graph<T>reconstructs the coherent domain view when code actually needs the surrounding context;- one command can assert and change multiple Models in one atomic commit;
- event sourcing, document loading, caching, snapshots, direct search and Graph materialization become storage choices made after the domain boundary is correct.
The familiar Fluxzero programming model remains: immutable messages, annotated handlers, automatic dependency injection, event publication, upcasting and the TestFixture. The major change is that storage shape no longer has to dictate domain shape.
Model the lifecycle, not the container
If a Task can be created, changed, retained or deleted independently, it is a Model—even when users normally see it inside a Project:
@Model(materializeGraph = true)
public record Project(
@EntityId ProjectId projectId,
ProjectDetails details) {
}
@Model
public record Task(
@EntityId TaskId taskId,
@Parent(pathInParent = "tasks") ProjectId projectId,
TaskDetails details,
boolean completed) {
}
ProjectId and TaskId carry their Model type, so Fluxzero can resolve command targets, loads and relationships without class arguments or casts.
Project and Task now have separate streams, histories, caches and lifecycles. Moving a Task only changes its projectId; Fluxzero updates the durable relationship without loading or rewriting either Project. Because ProjectId is typed, @Parent infers Project.class. Parent-scoped IDs, recursive relationships such as Folder → Folder, polymorphic parents, aliases and configurable cascade deletion are supported.
Use @Member only when a nested value deliberately shares all creation, change, history, retention and deletion with its root.
Commands become atomic Model transitions
Commands can carry their assertions and state transition directly:
public record CompleteTask(TaskId taskId) {
@AssertLegal
void assertOpen(Task task) {
if (task.completed()) {
throw new IllegalStateException("Task is already complete");
}
}
@Apply
Task apply(Task task) {
return new Task(
task.taskId(), task.projectId(),
task.details(), true);
}
}
Publishing CompleteTask is enough. Fluxzero resolves the target, runs interceptors and assertions, applies the transition and durably commits the result. No boilerplate command handler or aggregate lookup is required.
One payload may read, create, update, move or delete several independent Models in the same atomic commit. Payload-side handlers run first; Model-side @InterceptApply, @AssertLegal and @Apply methods then add reusable domain-wide behavior against the intermediate state. Conflict retries, replay and live handling use that same deterministic reducer. Commands in one ordered batch also get read-your-writes without making unrelated Model chains wait for each other.
Graphs restore context without restoring coupling
Graph<T> is a typed, lazy view over one Model and its relationships:
ProjectId projectId = new ProjectId("1");
Graph<Project> project = Fluxzero.loadGraph(projectId);
List<Task> tasks = project.childModels("tasks", Task.class);
Graph<Project> before = project.previous();
The root Model is loaded only when its value is requested; parents, children, descendants and history are resolved lazily at one pinned state boundary. A Graph can:
- navigate parents, children and descendants;
- expose the complete state before a change;
- load an exact historical boundary or play back to an event;
- stage updates and deletions;
- serialize as a nested response through explicit
pathInParentrelationships; - filter or select response branches without copying Model values;
- add derived
@GraphPropertyvalues; - be injected directly into command, query, event, document and web handlers.
A sole Graph<Project> parameter on an event or notification handler subscribes to durable changes anywhere below that root. Fluxzero supplies the exact before and after Graph and also handles child moves and root deletion coherently.
Search live or materialized Graphs
Graph search uses the regular typed Search API:
List<Graph<Project>> projects = Fluxzero.searchGraph(Project.class)
.whereDescendant(
Task.class,
MatchConstraint.match(false, "completed"))
.fetchAll();
Fluxzero uses a configured materialized projection when available and otherwise composes the Graph live. A materialized Graph is a derived search document; the independent Models and their relationships remain authoritative. Direct Model search is configured separately.
Current point reads always use the committed Model state, even while asynchronous Graph materialization is catching up. Materialized Graphs retain the concrete type and revision of every node, so the ordinary serializer can upcast each Model independently. @HandleDocument(modelGraph = ...) can persist evolved node schemas back into the derived projection without rewriting authoritative Model history.
Event sourcing without giant root streams
Models are event-sourced by default. Because every independently living Model has its own stream, a short-lived Task no longer inflates the lifetime history of its Organisation or Project. Snapshotting and bounded reconstruction remain available for genuinely long streams.
Document-based loading is also supported for Models that should read their current state directly. This changes the load strategy—not whether their updates can be stored and published as events. Search documents, cache retention, snapshots, event publication and Graph materialization are independently configurable.
Model and Graph injection into event handlers is pinned to the exact durable Model commit that produced the event. Historical relations therefore cannot accidentally observe a newer cached parent or child.
A gradual path from Aggregates to Models
Changing @Aggregate to @Model is deliberately not treated as a persistence migration. Fluxzero 2.0 instead provides a controlled, forward-only migration path:
- replay published legacy events into shadow Models;
- catch up continuously while the legacy application remains the only write owner;
- validate and adopt the reconstructed state;
- move queries and read-only listeners to Models and Graphs incrementally;
- transfer command ownership per Model boundary only after every check reports
GO.
The migration runner preserves the link between a legacy global event and the Model state created from it. Converted event handlers can therefore inject the exact new Model or Graph state for that old event. Multiple migration instances use one durable single-tracker consumer for safe failover, and document-backed state is staged outside normal reads until adoption. Legacy STORE_ONLY events are outside this global-log replay source.
This lets applications validate the new representation under real event traffic without committing to a big-bang cutover.
Built as a production path, not an adapter layer
Models use a dedicated high-throughput SDK/Runtime commit protocol with bounded batching, compact binary framing, durable receipts, conflict-aware retries, cache coherence and restart-safe projection processing. Direct Model changes, atomic multi-Model actions, Graph reads and asynchronous materialization all share the same authoritative commit boundary.
The complete command → result, command → Model and command → Model → Graph routes were characterized throughout development, alongside the existing non-Model routes. The design keeps unrelated Models parallel and avoids rebuilding or serializing a complete Graph when only one Model changes.
Compatibility and RC status
- Existing messaging, handler, Aggregate, search, scheduling and web APIs remain available for 1.x applications.
- New persisted state should use
@Model; the legacy Aggregate API remains for existing applications and deliberate migrations. - Runtime 2.0 remains compatible with 1.x SDK clients.
- SDK 2.0 can continue to use a 1.x Runtime for existing non-Model capabilities; new Model persistence requires Runtime 2.0.
- This is the first release candidate. It is intended for realistic application migration, performance and deployment validation before 2.0 GA.
Use the matching immutable RC for SDK and Runtime:
| Component | Release |
|---|---|
| Maven BOM | io.fluxzero:fluxzero-bom:2.0.0-RC1 |
| Runtime image | ghcr.io/fluxzero-io/fluxzero-runtime/fluxzero-runtime:2.0.0-RC1 |
| Test Server image | ghcr.io/fluxzero-io/fluxzero-sdk-java/fluxzero-test:2.0.0-RC1 |
| Proxy image | ghcr.io/fluxzero-io/fluxzero-sdk-java/fluxzero-proxy:2.0.0-RC1 |
Start exploring
- Model-first overview and migration guide
- Build the first Model application
- Model loading, relationships and Graphs
- Complete 1.244.0 → 2.0.0-RC1 change history
Fluxzero 2.0 is the point where the code can finally say what the domain already knew: an entity is independent because it has its own life—not because it happens to fit inside somebody else's list.
Aug 27, 2026 · 1.244.0
Section titled “Aug 27, 2026 · 1.244.0”GitHub
Aug 27, 2026 · 1.244.0
Section titled “Aug 27, 2026 · 1.244.0”Aug 27, 2026 · 1.243.0
Section titled “Aug 27, 2026 · 1.243.0”GitHub
Aug 27, 2026 · 1.243.0
Section titled “Aug 27, 2026 · 1.243.0”Aug 26, 2026 · 1.242.0
Section titled “Aug 26, 2026 · 1.242.0”GitHub
Aug 26, 2026 · 1.242.0
Section titled “Aug 26, 2026 · 1.242.0”Aug 26, 2026 · 1.241.0
Section titled “Aug 26, 2026 · 1.241.0”GitHub
Aug 26, 2026 · 1.241.0
Section titled “Aug 26, 2026 · 1.241.0”Aug 26, 2026 · 1.240.1
Section titled “Aug 26, 2026 · 1.240.1”GitHub
Aug 26, 2026 · 1.240.1
Section titled “Aug 26, 2026 · 1.240.1”Aug 25, 2026 · 1.240.0
Section titled “Aug 25, 2026 · 1.240.0”GitHub
Aug 25, 2026 · 1.240.0
Section titled “Aug 25, 2026 · 1.240.0”Aug 24, 2026 · 1.239.12
Section titled “Aug 24, 2026 · 1.239.12”GitHub
Aug 24, 2026 · 1.239.12
Section titled “Aug 24, 2026 · 1.239.12”Aug 22, 2026 · 1.239.11
Section titled “Aug 22, 2026 · 1.239.11”GitHub
Aug 22, 2026 · 1.239.11
Section titled “Aug 22, 2026 · 1.239.11”Aug 22, 2026 · 1.239.10
Section titled “Aug 22, 2026 · 1.239.10”GitHub
Aug 22, 2026 · 1.239.10
Section titled “Aug 22, 2026 · 1.239.10”Aug 20, 2026 · 1.239.9
Section titled “Aug 20, 2026 · 1.239.9”GitHub
Aug 20, 2026 · 1.239.9
Section titled “Aug 20, 2026 · 1.239.9”Aug 20, 2026 · 1.239.8
Section titled “Aug 20, 2026 · 1.239.8”GitHub
Aug 20, 2026 · 1.239.8
Section titled “Aug 20, 2026 · 1.239.8”Aug 18, 2026 · 1.239.7
Section titled “Aug 18, 2026 · 1.239.7”GitHub
Aug 18, 2026 · 1.239.7
Section titled “Aug 18, 2026 · 1.239.7”Aug 17, 2026 · 1.239.6
Section titled “Aug 17, 2026 · 1.239.6”GitHub
Aug 17, 2026 · 1.239.6
Section titled “Aug 17, 2026 · 1.239.6”© 2026 Fluxzero