Skip to content

AI Generation Replay Cache Contract Proof

Scope

P6-048 reduces latency and avoids a repeated provider request for an identical, already-settled AI generation preview. It applies only when AI_GENERATION_USAGE_WALLET_ENABLED=true; default deployments keep that flag off and preserve the existing preview behavior.

ai-classifier-service owns the replay record. It is not a Question Bank write, a wallet ledger, a usage counter, or a Gateway default-route promotion.

Replay Contract

  1. The service normalizes the generation request and derives the existing deterministic SHA-256 idempotency key from the actor, organization, mode, prompt, scope, count, document references, and reference question IDs.
  2. Cache lookup is isolated by (organizationId, actorId, idempotencyKey) and only returns a non-expired ai_generation_preview_replays record.
  3. On a hit, the stored no-write preview is returned with a warning that the provider, usage-service, and wallet-service were not called.
  4. On a miss, the normal sequence remains preflight -> provider -> settle -> provider usage event. Only that completed sequence saves a 24-hour replay.
  5. Provider failures, settlement failures, and usage-event persistence failures are not cached. A cache persistence failure does not hide an already settled response; the owner-service idempotency keys remain the fallback on retry.
  6. singleflight joins concurrent identical requests in one Go process. It is deliberately not presented as cross-pod mutual exclusion; the durable cache serves completed retries after a restart or on another pod.

Boundary And Rollback

  • The replay is an ai-classifier-service projection of an existing preview. It never creates a canonical question. A teacher still submits a reviewed candidate through Question Bank's separate owner API.
  • The default Gateway routes remain legacy-proxied. This is not browser or production-provider proof, and no paid provider request is made by these regressions.
  • To disable the behavior, leave or set AI_GENERATION_USAGE_WALLET_ENABLED=false; migration rollback drops only the AI-service replay table.

Hermetic Evidence

bash
GOTOOLCHAIN=go1.25.11 go test ./services/ai-classifier-service/internal/usecase \
  -run 'TestClassifierServiceChargedGeneration(ReplaySkipsProviderAndSettlement|DoesNotCacheSettlementFailure)' -count=1 -v
GOTOOLCHAIN=go1.25.11 go test ./services/ai-classifier-service/internal/repository \
  -run TestScanGenerationPreviewReplayDecodesSettledResult -count=1 -v

The first regression proves a second identical charged preview invokes exactly one preflight, provider, and settlement sequence, produces one usage event, and returns the stored preview. The second proves a settlement failure is not cached and a retry re-enters the provider path. The repository regression verifies durable JSON replay decoding.

Go-platform documentation is generated from repository Markdown.