Appearance
AI Provider-Backed Preview Hermetic Proof
Date: 2026-07-15
Scope
This proof covers provider-backed, no-write generation, explanation, and essay grade previews owned by ai-classifier-service. It uses an in-process OpenAI-compatible HTTP server and a configured provider fixture, so it is deterministic and makes no billable provider request.
Evidence
bash
GOTOOLCHAIN=go1.25.11 go test ./services/ai-classifier-service/... -count=1
GOTOOLCHAIN=go1.25.11 go test -race \
./services/ai-classifier-service/internal/provider \
./services/ai-classifier-service/internal/usecase \
-run 'Test(OpenAITaskProviderGeneratesExplainsAndGradesPreviewPayloads|ParseEssayGradeRejectsProviderRubricDrift|ClassifierService.*Grade)' \
-count=1Both commands passed on 2026-07-15.
| Check | Result |
|---|---|
| OpenAI-compatible request | Sends model, bearer authorization, JSON-object response format, and task-specific prompts to /chat/completions. |
| Internal HTTP workflow | The provider-backed /v1/ai/essay-grade/preview handler returns a PREVIEW envelope with the selected provider and preserves attempt-service as the stored-grade handoff owner. |
| Generation result | Parses generated question data and returns status=PREVIEW; Question Bank receives no write. |
| Explanation result | Parses solution and ordered steps and returns status=PREVIEW; Question Bank receives no write. |
| Essay grade result | Rejects provider rubric drift, preserves every caller criterion/max score, and returns only an advisory attempt-grade payload. |
| Scope and handoff | Similar references are still loaded through the tenant-scoped Question Bank context boundary. Provider candidates carry previewOnly=true, providerBacked=true, and handoffService=question-service. |
| Telemetry | Success records provider/model/tokens/latency; failure records a FAILED provider usage event. Provider-backed preview envelopes now report the provider operation and token estimates rather than stale mock estimates. |
| Charge boundary | Essay-grade stays preview_only_no_consume: it records AI-owned telemetry but makes no Usage quota consume or Wallet debit. |
| Local behavior | AI_CLASSIFIER_PROVIDER=mock remains the deterministic, no-network default. |
Boundary And Rollback
The default Gateway table remains unchanged and broad AI routes stay legacy_proxy. Provider-backed results remain editor previews until a versioned, idempotent Question Bank apply API plus usage/wallet preflight is implemented and proven. Docker Compose forwards AI_CLASSIFIER_API_KEY, AI_CLASSIFIER_BASE_URL, and AI_CLASSIFIER_MODEL only when the operator sets them. Roll back by setting AI_CLASSIFIER_PROVIDER=mock or using the default Gateway route table.
Not Proven
This is not evidence of a live Mistral or other provider credential, provider network execution, credit consumption, quota enforcement, canonical Question Bank or attempt write, browser behavior, or public route promotion.