Audit-Ready Mutation
Evidence status: Rust 4.1.1 with SQLite has an executed audited mutation.
The Java examples are reviewed shapes but are not executable evidence while
the current generated Java workspace remains blocked. Audit-sink contents,
rollback, and masking assertions are still required.
Problem
Change an entity while preserving who initiated the operation, why the state changed, and which transaction owns the write.
Use this recipe for application mutations. Do not use a generated entity as a place to hide request identity, authorization, or transaction policy.
Inputs
- A generated entity and its exact update methods.
- A request-scoped
UserContextcarrying application identity and policy. - A provider/runtime that supports the required transaction behavior.
- A concrete audit description meaningful to an operator or reviewer.
Read the generated entity before choosing an update method. Generated method names vary with the model and target stack.
Java Path
Keep transaction ownership at the service/use-case boundary:
@Transactional
public void confirmOrder(CustomUserContext ctx, Order order) {
order.updateStatusToConfirmed();
order.auditAs("Confirm customer order").save(ctx);
}
The exact updateStatusToConfirmed() method is illustrative. Use the method
emitted by the current generated entity.
For several saves that must commit together, keep them inside the same service transaction:
@Transactional
public void confirmOrderAndReserveStock(
CustomUserContext ctx, Order order, Stock stock) {
order.updateStatusToConfirmed();
order.auditAs("Confirm customer order").save(ctx);
stock.updateReservedQuantity(order.getTotalQuantity());
stock.auditAs("Reserve stock for confirmed order").save(ctx);
}
Rust Path
Rust graph saves carry audit intent on the entity persistence chain:
order
.audit_as("Confirm customer order")
.save(&ctx)
.await?;
For graph writes, confirm that the registered provider implements the transaction capability required by the runtime. Do not assume that a memory or experimental provider has the same rollback guarantees as a relational provider.
Verification
Verify more than successful return:
- Reload the entity with a query carrying
commentandpurpose. - Confirm the intended state and optimistic-lock version.
- Inspect the configured audit sink/log for identity and business intent.
- Force a validation or child-write failure and confirm transaction rollback.
- Confirm no sensitive payload is exposed by the selected log level.
Failure Modes
| Symptom | Likely cause | Fix |
|---|---|---|
| Save rejected for missing audit | Persistence chain has no audit intent. | Add a concrete auditAs / audit_as before save. |
| Update method missing | Handwritten code guessed a generated method. | Read generated entity source and use its exact method. |
| Partial multi-entity write | Transaction boundary is missing or provider semantics differ. | Add/verify the application transaction and provider capability. |
| Audit entry lacks actor | Request context was created without project identity integration. | Populate and test the application UserContext identity boundary. |
| Sensitive data in logs | Payload logging or masking policy is unsafe. | Reduce log detail and configure masking before production. |