Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
1ab9e5a
Preserve framework corrections and durable JDBC batch candidate
Oct 23, 2026
45533ab
Index durable batch under business coordination
Oct 23, 2026
0a772ad
Verify asynchronous callbacks by thread identity across scheduler modes
Oct 23, 2026
48fcca1
Validate initialized Batch executors before admitting durable work
Oct 23, 2026
f0d75c7
Require header bearer authority and retain native CSRF protection
Oct 23, 2026
72544b9
Quote Batch fixture role data without leaking credentials
Oct 23, 2026
8d6a6e1
Avoid eager bean initialization during application metadata discovery
Oct 23, 2026
a8e99ce
Protect client security diagnostics and checked buffer allocation
Oct 23, 2026
978a53b
Preserve long precision in condition report counters
Oct 24, 2026
95601cc
Preserve enum criteria types for configured R2DBC converters
Oct 24, 2026
f909721
Use cryptographic randomness for generated account numbers
Oct 24, 2026
b079ed1
Project configured validated JWT tenants into authenticated principals
Oct 24, 2026
134f4fb
Provide opt-in UTC auditing for mixed modern temporal models
Oct 24, 2026
ef2a5e6
Keep database driver details out of generic error responses
Oct 24, 2026
5296bca
Preserve generated AES key material across configuration and rotation
Oct 24, 2026
119b74f
Require literal boolean grants from OPA and OpenFGA
Oct 25, 2026
2bea932
Preserve typed SDK variants through opt-in generation
Oct 25, 2026
490cbce
Preserve Instant semantics through opt-in OpenAPI scalar generation
Oct 25, 2026
3ee0168
Restore production OAuth2 client registration on Boot 4
Oct 25, 2026
f6e3cc2
Protect temporary outputs and remove empty credential defaults
Oct 25, 2026
bbefea0
Escape provider log fields without exposing error payloads
Oct 25, 2026
78d185b
Keep data-processing logs free of untrusted payloads
Oct 25, 2026
13219db
Keep R2DBC filter diagnostics free of request payloads
Oct 26, 2026
6f035c4
Keep cache diagnostics free of keys and provider payloads
Oct 26, 2026
71d4d84
Escape webhook metric diagnostics without changing telemetry
Oct 26, 2026
6f1e1f7
Keep orchestration diagnostics on one log line
Oct 26, 2026
313c35d
Escape line separators in orchestration EDA diagnostics
Oct 26, 2026
49a28d8
Escape line separators in webhook processing diagnostics
Oct 26, 2026
abc1d9c
Escape provider fields in webhook controller diagnostics
Oct 26, 2026
4ec8801
Add opt-in bounded R2DBC root transactions with owned cleanup
Oct 27, 2026
5da837f
Expose budget intersections for pre-acquisition owner bounds
Oct 27, 2026
5cd8ec4
Escape webhook guard diagnostic fields without changing request behavior
Oct 27, 2026
a387cdb
Escape job and enrichment diagnostic fields without changing payloads
Oct 27, 2026
e4a13ca
Escape String diagnostics in global data controllers
Oct 27, 2026
7665c0a
Escape remaining starter-data diagnostic fields
Oct 27, 2026
a1bb5bd
Escape orchestration diagnostic fields without changing workflow beha…
Oct 27, 2026
dbaf8f4
Bound persistence diagnostic fields without changing stored workflow …
Oct 27, 2026
24f9abf
Preserve indexed auto-configuration exclusions during observability s…
Oct 27, 2026
494db72
Honor the orchestration REST switch for workflow management
Oct 27, 2026
a2469ed
Project the authenticated issuer into OPA policy subjects
Oct 27, 2026
3503f25
Add bounded audit evidence with exact principal tenant keys
Oct 28, 2026
85f5f95
Append immutable audit evidence in the owning R2DBC transaction
Oct 28, 2026
b5934a9
Accept monthly patch counters beyond two digits
Oct 29, 2026
eaa499b
Bind Batch publication plans to explicit namespace intent
Oct 29, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
4 changes: 4 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ jobs:
- name: Compile, test, and install framework libraries
if: steps.changes.outputs.java == 'true'
run: ./mvnw -B -ntp -Dtest.serialization.protobuf=true -Dtest.serialization.avro=true clean install
- name: Check generator and gRPC runtime alignment
if: steps.changes.outputs.java == 'true'
run: python3 scripts/verify_grpc_alignment.py --maven "$GITHUB_WORKSPACE/mvnw" --report target/grpc-alignment.json
- name: Test all maintained standalone examples
if: steps.changes.outputs.java == 'true'
run: bash scripts/verify_examples.sh
Expand All @@ -61,5 +64,6 @@ jobs:
path: |
**/target/surefire-reports/
**/target/failsafe-reports/
target/grpc-alignment.json
if-no-files-found: warn
retention-days: 14
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ Use the framework parent when you want its build and dependency management:
<parent>
<groupId>org.fireflyframework</groupId>
<artifactId>fireflyframework-parent</artifactId>
<version>26.10.21-SNAPSHOT</version>
<version>26.10.22</version>
<relativePath/>
</parent>
```
Expand All @@ -124,7 +124,7 @@ Or retain your existing parent and import the independent BOM:
<dependency>
<groupId>org.fireflyframework</groupId>
<artifactId>fireflyframework-bom</artifactId>
<version>26.10.21-SNAPSHOT</version>
<version>26.10.22</version>
<type>pom</type>
<scope>import</scope>
</dependency>
Expand Down
2 changes: 1 addition & 1 deletion build/bom/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ A team that already has a corporate Maven parent can import this BOM into the on
<dependency>
<groupId>org.fireflyframework</groupId>
<artifactId>fireflyframework-bom</artifactId>
<version>26.10.21-SNAPSHOT</version>
<version>26.10.22</version>
<type>pom</type>
<scope>import</scope>
</dependency>
Expand Down
9 changes: 7 additions & 2 deletions build/bom/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

<groupId>org.fireflyframework</groupId>
<artifactId>fireflyframework-bom</artifactId>
<version>26.10.21-SNAPSHOT</version>
<version>26.10.22</version>
<packaging>pom</packaging>

<name>Firefly Framework - BOM</name>
Expand Down Expand Up @@ -35,7 +35,7 @@
</scm>

<properties>
<fireflyframework.version>26.10.21-SNAPSHOT</fireflyframework.version>
<fireflyframework.version>26.10.22</fireflyframework.version>
<!-- Security patches beyond the selected platform BOMs. -->
<jackson2-bom.version>2.21.7</jackson2-bom.version>
<jackson-bom.version>3.1.7</jackson-bom.version>
Expand Down Expand Up @@ -295,6 +295,11 @@
<artifactId>fireflyframework-backoffice</artifactId>
<version>${fireflyframework.version}</version>
</dependency>
<dependency>
<groupId>org.fireflyframework</groupId>
<artifactId>fireflyframework-batch</artifactId>
<version>${fireflyframework.version}</version>
</dependency>

<!-- ECM -->
<dependency>
Expand Down
15 changes: 14 additions & 1 deletion build/parent/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ The onboarding example inherits this parent and keeps its own application versio
<parent>
<groupId>org.fireflyframework</groupId>
<artifactId>fireflyframework-parent</artifactId>
<version>26.10.21-SNAPSHOT</version>
<version>26.10.22</version>
<relativePath/>
</parent>
```
Expand All @@ -29,6 +29,19 @@ The onboarding example inherits this parent and keeps its own application versio

This POM has no runtime configuration namespace. Configure the selected child libraries in the application that uses them.

### Generated Java SDK variants

The managed OpenAPI Generator plugin exposes two opt-in build properties for object variants described with `oneOf`:

```xml
<properties>
<openapi.use.oneof.interfaces>true</openapi.use.oneof.interfaces>
<openapi.use.oneof.deduction>true</openapi.use.oneof.deduction>
</properties>
```

Both properties default to `false`, preserving the existing generator behavior. For the qualified Java WebClient configuration, the interface option generates separate typed variants and the deduction option uses their JSON field shapes during Jackson deserialization. Qualify serialization, deserialization, ambiguous payloads, and compatibility with the owning API before enabling them in a consumer. Keep the API schema and normal generator lifecycle authoritative for SDK output. These properties do not change a service's business admission rules or publish an updated SDK.

## Continue the application

Use the [CQRS guide](../../docs/site/modules/cqrs.md) for the next part of this integration.
Expand Down
25 changes: 22 additions & 3 deletions build/parent/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

<groupId>org.fireflyframework</groupId>
<artifactId>fireflyframework-parent</artifactId>
<version>26.10.21-SNAPSHOT</version>
<version>26.10.22</version>
<packaging>pom</packaging>

<name>Firefly Framework - Parent POM</name>
Expand Down Expand Up @@ -35,7 +35,7 @@
</scm>

<properties>
<fireflyframework.version>26.10.21-SNAPSHOT</fireflyframework.version>
<fireflyframework.version>26.10.22</fireflyframework.version>
<!-- Java -->
<java.version>25</java.version>
<maven.compiler.release>${java.version}</maven.compiler.release>
Expand All @@ -53,6 +53,8 @@
<openapi.use.tags>true</openapi.use.tags>
<openapi.use.optional>true</openapi.use.optional>
<openapi.date.library>java8</openapi.date.library>
<openapi.use.oneof.interfaces>false</openapi.use.oneof.interfaces>
<openapi.use.oneof.deduction>false</openapi.use.oneof.deduction>

<!-- Spring Boot and Cloud -->
<spring-boot.version>4.1.1</spring-boot.version>
Expand Down Expand Up @@ -88,11 +90,12 @@
<resilience4j.version>2.4.0</resilience4j.version>

<!-- gRPC -->
<grpc.version>1.79.0</grpc.version>
<grpc.version>1.83.1</grpc.version>
<protobuf.version>4.33.5</protobuf.version>

<!-- Serialization -->
<avro.version>1.12.1</avro.version>
<jackson-databind-nullable.version>0.2.8</jackson-databind-nullable.version>

<!-- Logging -->
<janino.version>3.1.12</janino.version>
Expand Down Expand Up @@ -473,6 +476,11 @@
</dependency>

<!-- Serialization -->
<dependency>
<groupId>org.openapitools</groupId>
<artifactId>jackson-databind-nullable</artifactId>
<version>${jackson-databind-nullable.version}</version>
</dependency>
<dependency>
<groupId>org.apache.avro</groupId>
<artifactId>avro</artifactId>
Expand Down Expand Up @@ -808,6 +816,11 @@
<artifactId>fireflyframework-backoffice</artifactId>
<version>${fireflyframework.version}</version>
</dependency>
<dependency>
<groupId>org.fireflyframework</groupId>
<artifactId>fireflyframework-batch</artifactId>
<version>${fireflyframework.version}</version>
</dependency>
<dependency>
<groupId>org.fireflyframework</groupId>
<artifactId>fireflyframework-ecm</artifactId>
Expand Down Expand Up @@ -1115,6 +1128,12 @@
<groupId>org.openapitools</groupId>
<artifactId>openapi-generator-maven-plugin</artifactId>
<version>${openapi-generator.version}</version>
<configuration>
<configOptions>
<useOneOfInterfaces>${openapi.use.oneof.interfaces}</useOneOfInterfaces>
<useDeductionForOneOfInterfaces>${openapi.use.oneof.deduction}</useDeductionForOneOfInterfaces>
</configOptions>
</configuration>
</plugin>

<!-- Maven Source Plugin -->
Expand Down
2 changes: 1 addition & 1 deletion docs/examples/getting-started/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<parent>
<groupId>org.fireflyframework</groupId>
<artifactId>fireflyframework-parent</artifactId>
<version>26.10.21-SNAPSHOT</version>
<version>26.10.22</version>
<relativePath/>
</parent>
<groupId>com.example</groupId>
Expand Down
2 changes: 1 addition & 1 deletion docs/examples/onboarding-coordination/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<parent>
<groupId>org.fireflyframework</groupId>
<artifactId>fireflyframework-parent</artifactId>
<version>26.10.21-SNAPSHOT</version>
<version>26.10.22</version>
<relativePath/>
</parent>
<groupId>com.example</groupId>
Expand Down
2 changes: 1 addition & 1 deletion docs/examples/onboarding-event-store/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<parent>
<groupId>org.fireflyframework</groupId>
<artifactId>fireflyframework-parent</artifactId>
<version>26.10.21-SNAPSHOT</version>
<version>26.10.22</version>
<relativePath/>
</parent>
<groupId>com.example</groupId>
Expand Down
37 changes: 37 additions & 0 deletions docs/immutable-local-audit.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Local transactional immutable audit and permanent export intent

This opt-in capability appends canonical kernel audit values and a permanent outbox intent inside the owning command's existing local R2DBC transaction. It creates no Spring bean, transaction, connection pool, default schema, security grant or background subscriber. The best-effort security audit logging SPI remains unchanged.

## Construct on the owning resource graph

The owner constructs one stable `OwnedLeaseConnectionFactory`, `DatabaseClient`, `R2dbcEntityTemplate` and `R2dbcTransactionManager`, verifies them with `BoundedR2dbcResources.verify`, and uses the existing `DefaultBoundedRootTransaction`. Pass those exact objects to `SpringDataTransactionalAuditAppender`, together with a mandatory genuine `AuditAppendAuthority` and the **same Clock and LongSupplier instances used for the original operation budget**. Do not wrap or replace a caller's client/template, converters or statement filters.

The appender's `append(scope, event)` must be composed into the owning root work publisher, before that publisher completes. It proves the private active invocation and exact RootTransactionScope/resource graph before admission, then uses the transaction-bound same connection. It never invokes a second root or generic joining TransactionalOperator. Ordinary ambient transactions, stale/foreign scopes and mismatched graphs refuse. Narrowing the genuine original scope preserves its identity.

The authority port must resolve the authenticated current actor, authorize the resource and action, and verify the event's outcome, process, evidence digest and policy facts. Kernel values are claims, not authentication. The appender compares the complete actor and stream against the permit at admission and again before native completion. There is no default or successful unavailable provider. The actor's platform tenant key is an exact String namespace; the resource tenant remains a separate UUID. Do not invent a UUID mapping or equate those tenants.

## Persistence and replay

Every public `LocalAuditRepository` operation also requires the genuine RootTransactionScope and the same verified factory/client/template/manager graph; it cannot fall back to an ordinary ambient transaction. It exposes no inherited general CRUD API. Its mapped statement helpers are private.

`SpringDataLocalAuditRepository` uses the owning template's genuine mapping strategy/converter and StatementMapper for ordinary inserts and head CAS. Every insert/update must observe exactly one actual affected row. Zero, multiple and missing observations refuse. It stores every canonical kernel field, including separate Instant seconds/nanos, with no serializer-dependent JSON. Event uniqueness is `(resource_tenant_id,event_id)` across all streams in that tenant. The stream head CAS includes the whole scope, expected sequence and previous hash.

The immutable event and its immutable `AUDIT_EXPORT` intent are inserted in the same local transaction as the head and business work. The next append links the prior hash. Exact replay reads the original full event, verifies its canonical record hash and full permanent outbox, and returns the original record without changing its timestamp or sequence. Different content under the same event ID refuses. A duplicate database error propagates without reading or continuing in the aborted transaction. A mandatory append failure marks the genuine owner transaction rollback-only, so catching a logical append refusal cannot commit the business effect. Marking performs no SQL and never clears rollback-only.

The API returns `ProvisionalAppend`, which is not a durability receipt. The owner must independently inspect its original RootCompletion: acknowledged commit, completed boundary and complete cleanup are separate required facts. A caught refusal can yield a completed rollback boundary with **no commit**; returning a work value does not change that fact. RootTransactionException can also retain acknowledged-commit facts despite withholding a value or incomplete cleanup. Do not infer no-effect or replay a business effect from an exception alone.

The library cannot detect an owner that omits the mandatory audit call. Explicit owner integration and native business/audit effect capture remain adoption gates. External export/delivery, mutable retry leases and ACK state must be separate from permanent event/outbox rows; no delivery worker is supplied here.

## Explicit PostgreSQL contract

`modules/r2dbc/src/main/resources/db/optional/immutable-audit/postgresql.sql` is a standalone explicit transaction, outside default Flyway locations and versioned naming. It must be deliberately installed once by a separately delegated installer. It neither baselines/repairs history nor assumes any owning business table. There is no automatic Flyway bean. Provision exact NOINHERIT/NOSUPERUSER/NOBYPASSRLS/NOCREATEDB/NOCREATEROLE/NOREPLICATION roles beforehand: non-login `firefly_audit_guard`; login `firefly_audit_writer` and `firefly_audit_reader`. The installer must be able to SET the guard and hold public CREATE WITH GRANT OPTION. The script removes its temporary guard public CREATE grant before commit.

The owning business pool uses `firefly_audit_writer`; the deployment must deliberately grant that role its own core's required business privileges. The script grants no business-table permission. The writer cannot own audit tables or use the private schema. Ordinary reader grants cannot mutate originals; reader RLS is denied by default until a separately admitted export/read adapter is implemented. No general read API is supplied.

The concrete native repository calls fixed technical functions on the same transaction. Enter binds actual session/xid/backend, nonce, event, whole resource scope and full admitted actor, serializes scoped event/stream mechanics, and returns the real database recording clock and a cap at most five seconds. The appender narrows its original paired budget with a one-millisecond completion margin; no new deadline is granted. Native completion and a deferred constraint require the immutable event, complete permanent intent, current head and native-time linkage. Multiple sequential append contexts can exist within one owner transaction, each completed separately and still checked at the original boundary. The fixed native clock/functions do not authenticate their actor parameters or establish a genuine owner permit.

Database primary/foreign keys enforce tenant-scoped identity, unique stream sequence, immutable predecessor links and current head linkage. UPDATE/DELETE triggers and grants protect originals for ordinary runtime roles. The adapter computes/rechecks canonical kernel hashes; this SQL contract does not independently reimplement the canonical hash protocol. Privileged storage administrators remain outside ordinary-role protection. Actual PostgreSQL mapping, constraints, privileges, rollback and restart behavior require the separately approved native fixture; source tests are not that evidence.

## Remaining operational and compliance work

No checkpoint custody, authenticated signing, WORM storage, retention/hold/disposition engine, trusted reference-clock operations, external export acknowledgment or restore evidence is supplied. There is no invented global DORA retention period and no compliance certification. Full framework CQRS/saga/TCC/batch lifecycle integration and explicit per-core/process adoption remain separate gates. Existing owner journals must retain their current contracts until a real integration is qualified.
2 changes: 1 addition & 1 deletion docs/migration/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ The organization inventory contained 93 repositories. The Java migration include

`pom.xml` is an aggregation POM. `build/parent/pom.xml` supplies consumer build/dependency management; `build/bom/pom.xml` is independent. The parent does not import its own BOM, avoiding a model-resolution cycle. Framework dependency versions in the public parent use `fireflyframework.version`, so an application version such as `1.0.0` does not accidentally change its framework dependencies. The BOM now includes the previously omitted `fireflyframework-security-bff`.

A single concrete `26.10.21-SNAPSHOT` version identifies development. The version updater validates the monthly CalVer train (`YY.MM.PP`, with `PP` as the release counter) and all input XML before writing, updates framework project/parent/dependency properties, preserves external dependency versions, and ignores generated `target` directories. Existing release versions are never overwritten.
A single concrete `26.10.22` version identifies development. The version updater validates the monthly CalVer train (`YY.MM.PP`, with `PP` as the release counter) and all input XML before writing, updates framework project/parent/dependency properties, preserves external dependency versions, and ignores generated `target` directories. Existing release versions are never overwritten.

## Boot 4 compatibility

Expand Down
2 changes: 2 additions & 0 deletions docs/migration/boot4-application-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ Testcontainers. Version 2 changes Maven module names. Keep Docker available and

Provider integrations. Cloud SDK starters, Springdoc, resilience, and security integrations move with the Boot 4 generation. Verify authentication, connection configuration, and failure handling against your actual providers.

gRPC generation and transport. Keep the generator's `grpc.version` aligned with every resolved `io.grpc` runtime artifact. A consumer can compile while a mixed Netty/core train fails with `AbstractMethodError` during server creation. The parent exposes the same gRPC version selected by its Boot platform. Run `python3 scripts/verify_grpc_alignment.py` from the framework checkout to resolve a real consumer graph. The script also accepts `--maven`, `--settings`, `--repository` and `--report` for an isolated build. Use `protoc` from the selected `protobuf.version`, inspect native generator architecture on the build host, and exercise a generated client over an actual owned transport. A classifier name alone does not establish that the downloaded binary runs on that architecture.

## Suggested application verification

- Compile with JDK 25 and inspect the effective dependency tree.
Expand Down
Loading
Loading