From the free book Delta: Closing the Specification Gap (Dhuri, 2026). The PDF is the canonical edition — figures, tables, and code formatting are simplified online.
Domain-correct output from HIPAA services to flash-sale inventory systems
“AI writes the code. You write the specification. The specification is the hard part. The rest takes a few seconds.” — A developer, after using Recipe 4.3 for the first time In This Chapter
No float for money. No exceptions. No ‘it’s fine for this use case.’ No. IEEE 754 double cannot represent 0.10 exactly. The actual value is 0.1000000000000000055511151231257827021… Across hundreds of thousands of transactions, this error accumulated to a four- figure discrepancy (see Chapter 1 and the Preface). The type is Money<TCurrency> (C#) or Money (Java). For every financial calculation. Every time. (One clarification for the pedantic reader: decimal in C# and BigDecimal in Java are not floats — they are base-10 fixed-precision types, which is precisely why the Money type uses them internally. The Law forbids float and double directly; it does not forbid the underlying base-10 types that Money wraps.)
4.1 The Quality Equation Code Generation Quality = Role × Context × Task × Constraints Each factor multiplies the others. A zero in any dimension produces zero-quality output regardless of the other three. A perfect role + perfect context + zero constraints produces code that looks correct and violates your domain invariants in production.
68% of AI-generated code changes typically require at least one domain-specific correction before merging, in teams without structured prompt practices. Teams that adopt a structured prompt frame consistently report a substantially lower revision rate — observed in the 15–25% range. Illustrative figure. The directional claim — that prompt specificity reduces post-generation revision overhead — is supported by published research; see Sajid et al. (2023), “Testing LLMs on Code Generation with Varying Levels of Prompt Specificity”, arXiv:2311.07599. See Research & Statistics Notes (see Appendix J)
39 BEFORE — Tier 1 (What most developers type) "Write a Java patient contact update service" AFTER — Tier 3 (Specification Frame) "<role>Senior Java engineer on HIPAA EHR. Java 21, Spring Boot 3.3, ,→ @AuditLog AOP, Result<Void> returns.</role><existing_interface> ,→ public interface PatientDemographicsService { Result<Void> ,→ updateContactInfo(UpdateContactInfoCommand cmd); }</ ,→ existing_interface><task>Validate patient is active (not ,→ deceased, not merged), partial-update contact fields, publish ,→ ContactInfoUpdatedEvent after transaction commit.</task>< ,→ constraints>@AuditLog(action=UPDATE_CONTACT, resource=Patient) ,→ REQUIRED. PHI NEVER in logs; ALWAYS log patientId (UUID) only. ,→ No @Autowired; ALWAYS @RequiredArgsConstructor. Events AFTER ,→ commit; NEVER inside @Transactional. Deceased=Failure( ,→ PATIENT_DECEASED). Merged=Failure(PATIENT_MERGED).</constraints ,→ ><output_specification>Complete compilable class. Package + all ,→ imports. ONE implementation. If ambiguous: ASSUMPTION: [what]
,→ before code.</output_specification>" Result: Tier 1: functional Java with no @AuditLog, PHI in log ,→ statements, no deceased/merged guard. Passes code review by ,→ engineers without HIPAA training. Tier 3: compilable, HIPAA,→ compliant, all guards present — approved by compliance on first ,→
submission.
Java 21 — HIPAA PatientDemographicsServiceImpl (Compilable) // File: src/main/java/com/yourcompany/patients/ ,→ PatientDemographicsServiceImpl.java package com.yourcompany.patients; import com.yourcompany.common.Result; import com.yourcompany.audit.AuditLog; import com.yourcompany.patients.commands.UpdateContactInfoCommand; import com.yourcompany.patients.domain.Patient; import com.yourcompany.patients.events.ContactInfoUpdatedEvent; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.context.ApplicationEventPublisher; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @Slf4j @Service @RequiredArgsConstructor public class PatientDemographicsServiceImpl implements ,→ PatientDemographicsService { private final PatientRepository patientRepository; private final ApplicationEventPublisher eventPublisher; @Override @Transactional @AuditLog(action = "UPDATE_CONTACT", resource = "Patient") public Result<Void> updateContactInfo(UpdateContactInfoCommand ,→ cmd) { return patientRepository.findById(cmd.patientId()) .map(patient -> applyUpdate(patient, cmd)) .orElse(Result.failure("PATIENT_NOT_FOUND", "Patient not ,→ found: " + cmd.patientId())); } private Result<Void> applyUpdate(Patient patient, ,→ UpdateContactInfoCommand cmd) { // Guards: check lifecycle state before any modification if (patient.isDeceased()) return Result.failure("PATIENT_DECEASED", "Cannot update ,→ a deceased patient"); if (patient.isMerged()) return Result.failure("PATIENT_MERGED", "Cannot update a ,→ merged patient record"); patient.updateContactInfo(cmd.phone(), cmd.email(), cmd.addressLine1(), cmd.city(), cmd.postalCode()); patientRepository.save(patient); // Publish AFTER transaction commit — not inside the ,→ transaction eventPublisher.publishEvent(new ContactInfoUpdatedEvent( ,→ patient.getId()));
41 // NO PHI in logs — only correlation ID (patientId UUID) log.info("Contact info updated: patientId={}", cmd.patientId() ,→ ); return Result.success(null); } }
4.3 Recipe 2 — Idempotent Payment Handler (.NET 9 / MediatR 12) PATTERN — The Hundreds of Double Charges
A SaaS payments team deployed a Stripe webhook handler. The handler processed events and returned 200 OK within the 30-second timeout. On a Tuesday morning, Stripe’s infrastructure experienced a 34-second delay spike. Hundreds of webhooks were automatically retried. Each ran twice. 340 business customers were charged twice for their monthly subscription. The refund and reconciliation process ran for four days. Three customers churned.
C# — Idempotent Payment Handler (.NET 9, MediatR 12) (Compilable) // File: src/Application/Payments/ProcessPaymentCommandHandler.cs using MediatR; using YourCompany.Application.Common; using YourCompany.Domain.ValueObjects; using Microsoft.Extensions.Logging; namespace YourCompany.Application.Payments; public sealed record ProcessPaymentCommand( Guid CustomerId, Money<USD> Amount, // Money<USD> — never decimal directly
string CardToken,
// PCI: NEVER log string PaymentReference
// Idempotency key from caller
) : IRequest<Result<PaymentConfirmation>>; public sealed class ProcessPaymentCommandHandler : IRequestHandler<ProcessPaymentCommand, Result< ,→ PaymentConfirmation>> { private readonly IPaymentRepository _payments; private readonly IPaymentGateway _gateway; private readonly IIdempotencyStore _idempotency; private readonly IDomainEventDispatcher _events; private readonly ILogger<ProcessPaymentCommandHandler> _logger; public ProcessPaymentCommandHandler( IPaymentRepository payments, IPaymentGateway gateway, IIdempotencyStore idempotency, IDomainEventDispatcher events, ILogger<ProcessPaymentCommandHandler> logger) { (_payments, _gateway, _idempotency, _events, _logger) = (payments, gateway, idempotency, events, logger); } public async Task<Result<PaymentConfirmation>> Handle( ProcessPaymentCommand request, CancellationToken ,→ cancellationToken) { // STEP 1: Idempotency check FIRST — before any side effects var cached = await _idempotency .GetAsync<PaymentConfirmation>(request.PaymentReference, ,→ cancellationToken); if (cached is not null) { _logger.LogInformation( "Duplicate reference {Ref} — returning cached result", ,→ request.PaymentReference); return Result<PaymentConfirmation>.Success(cached); } // STEP 2: Charge via payment gateway var gatewayResult = await _gateway.ChargeAsync( request.Amount, request.CardToken, request.PaymentReference, cancellationToken); if (!gatewayResult.Succeeded) return Result<PaymentConfirmation>.Failure( "GATEWAY_DECLINED", gatewayResult.DeclineReason ?? " ,→ Declined"); // STEP 3: Persist the aggregate var payment = Payment.Create( request.CustomerId, request.Amount, gatewayResult.TransactionId, request.PaymentReference); await _payments.AddAsync(payment, cancellationToken); var confirmation = new PaymentConfirmation( payment.Id, gatewayResult.TransactionId, DateTimeOffset. ,→ UtcNow); // STEP 4: Store idempotency AFTER successful persistence await _idempotency.StoreAsync( request.PaymentReference, confirmation, cancellationToken) ,→ ; // STEP 5: Dispatch domain event AFTER save — NEVER inside ,→ transaction await _events.DispatchAsync( new PaymentProcessedEvent(payment.Id, request.Amount), ,→ cancellationToken); // CardToken MUST NOT appear in logs — only correlation IDs _logger.LogInformation( "Payment processed: paymentId={PaymentId} ref={Ref}", payment.Id, request.PaymentReference); return Result<PaymentConfirmation>.Success(confirmation); } }
AVOID: ”Write a Java service that checks stock and reserves units for an order” USE: Add: ”<constraints>@Version on Product entity for optimistic locking. @Retryable(retryFor=OptimisticLockingFailureException. class, maxAttempts=3, backoff=@Backoff(delay=50, multiplier= 2)). InsufficientStockException MUST NOT be caught or swallowed. </constraints>” Why: Without @Version, 10,000 concurrent flash-sale requests produce 847 oversells in 12 seconds (Chapter 1, Incident 3). @Version adds one database column and one retry annotation. The production incident costs orders of magnitude more. Java 21 — Thread-Safe Inventory (Spring Boot 3.3, Compilable) // File: src/main/java/com/yourcompany/inventory/InventoryService. ,→ java package com.yourcompany.inventory; import com.yourcompany.inventory.exceptions. ,→ InsufficientStockException; import com.yourcompany.inventory.events.StockReservedEvent; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.dao.OptimisticLockingFailureException; import org.springframework.kafka.core.KafkaTemplate; import org.springframework.retry.annotation.Backoff; import org.springframework.retry.annotation.Retryable; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.data.redis.core.StringRedisTemplate; import java.time.Duration; import java.util.UUID; @Slf4j @Service @RequiredArgsConstructor public class InventoryService {
45 private static final Duration RESERVATION_TTL = Duration. ,→ ofSeconds(900); private final ProductRepository productRepository; private final StringRedisTemplate redisTemplate; private final KafkaTemplate<String, StockReservedEvent> ,→ kafkaTemplate; @Transactional @Retryable( retryFor = OptimisticLockingFailureException.class, maxAttempts = 3, backoff = @Backoff(delay = 50, multiplier = 2)) public UUID reserve(UUID productId, int quantity, UUID customerId) ,→
{ var product = productRepository.findById(productId) .orElseThrow(() -> new ProductNotFoundException(productId)
,→ ); if (!product.canReserve(quantity)) // P0: MUST NOT be swallowed or converted to Result. ,→ failure() throw new InsufficientStockException(productId, quantity, ,→
product.getAvailableStock()); product.incrementReserved(quantity); // saveAndFlush triggers the @Version check — throws on
,→ conflict productRepository.saveAndFlush(product); UUID token = UUID.randomUUID(); redisTemplate.opsForValue().set( "reservation:" + token, productId + ":" + quantity, RESERVATION_TTL); // Publish AFTER transaction commits — not inside kafkaTemplate.send("inventory.reserved", productId.toString(), ,→
specification quality. The model can’t infer Money<T>, idempotency patterns, or HIPAA audit requirements. + Law 5: No float for money. No exceptions. The constraint is one sentence. The production incident is three weeks of reconciliation. + Three most expensive AI generation mistakes: no idempotency order (double charges), no optimistic locking (oversells), no PHI log constraint (HIPAA violations). Each has a one-sentence prevention. + All ten recipes follow the same pattern: Specification Frame with domain constraint block. The domain constraint block is the entire difference between a tutorial example and production code.
UP NEXT — Chapter 5: Code Review That Actually Finds Problems
A generic code review prompt produces generic feedback. A domain review prompt produces findings like ‘[Line 47] patient.getName() in log.info() is a Definite HIPAA Violation per 45 CFR 164.312(b).’ Chapter 5 shows you exactly how to get from the first to the second.
48