Oracle Regen Consistency

SPEC_ORACLE_REGEN_CONSISTENCY.md · 2026-04-20

SPEC_ORACLE_REGEN_CONSISTENCY — Gemini Non-Determinism Handling

Version: 1.0 | Status: AUTHORIZED | Authority: α.13 | Date: 2026-04-16


PURPOSE

When the Oracle result page (/oracle/result?session_id=...) is loaded and the verdict cache

(oracle_toll.pyGET /cache/{session_id}) returns 404 (cache miss), the verdict route

(app/api/verdict/route.ts) calls Gemini again using the identical prompt template used by the

original webhook-triggered generation.

The problem: Gemini is a stochastic model. Temperature > 0 means the regenerated verdict may

differ from the original verdict that was already emailed to the customer. A customer who paid $5

CAD for a Full Breakdown may see GREEN on their result page and RED in their email — or vice versa.

This is a trust and correctness failure.

This specification defines: how regen requests must be configured to maximize determinism, how to

detect and log divergence between the original (emailed) verdict and the regenerated verdict, what

divergence thresholds are acceptable, and what the customer notification path looks like when

significant divergence is detected.

This spec does NOT eliminate Gemini non-determinism — that is impossible at the API level. It

defines a regime that minimizes it and handles it explicitly when it occurs.

Source gap: SPEC_ORACLE_VERDICT_PIPELINE.md GAP-08.


INPUTS

Primary: Cache Miss Signal

Session Context (required for regen)

Original Verdict Reference (optional but required for divergence check)

that the result may differ from email. [GAP — original verdict recovery currently has no mechanism

when oracle_log.jsonl does not exist; see GAP-01 of SPEC_ORACLE_VERDICT_PIPELINE.md]

Gemini API Configuration for Regen Requests

All regen calls MUST use the following parameters (not optional):


{
  "model": "gemini-2.5-flash",
  "generationConfig": {
    "temperature": 0.0,
    "topP": 1.0,
    "topK": 1,
    "candidateCount": 1
  }
}

Rationale: temperature=0.0, topK=1 selects the greedy-decode (argmax) path, which is maximally

deterministic for a given prompt. This does not guarantee identical outputs across all API calls

(model infrastructure variance, quantization differences across serving replicas are possible), but

eliminates sampling randomness as a source of divergence.

Note: The original webhook call MAY have used default temperature (not 0.0). [GAP — original

webhook generation config is not explicitly specified in current code; review needed.]


OUTPUTS

Primary Output: Regenerated Verdict JSON

Structurally identical to the originally cached verdict:


{
  "tier": "quick" | "full" | "strategy",
  "query": "<original customer query>",
  "verdict": { ... },
  "cached_at": "<ISO timestamp of regen>",
  "regen": true,
  "regen_reason": "cache_miss"
}

The regen: true flag marks this as a regenerated result (not from original cache).

The regen_reason field is for audit trail purposes.

Secondary Output: Divergence Log Entry

Appended to oracle_log.jsonl (requires GAP-01 fix):


{
  "event": "regen_divergence_check",
  "session_id": "<stripe_session_id>",
  "tier": "quick" | "full" | "strategy",
  "original_verdict": "GREEN" | "AMBER" | "RED" | "NULL" | "UNKNOWN",
  "regen_verdict": "GREEN" | "AMBER" | "RED" | "NULL",
  "top_level_match": true | false,
  "divergence_level": "none" | "minor" | "significant",
  "timestamp": "<ISO>"
}

Tertiary Output: Customer Notification (conditional — significant divergence only)

If divergence level is "significant" (see INVARIANTS), a notification email is dispatched via

oracle_email_service.py using a new endpoint or the existing /send-verdict-email with an

appended disclaimer:


NOTE: Due to a technical condition, the verdict on your results page may differ slightly from
the one you received by email. Both represent a valid coherence reading of your submission.
If you have questions, reply to this email and we will provide clarification.

INVARIANTS

  1. Regen configuration lock — All regen calls MUST set temperature=0.0, topK=1. No regen

call may use default or elevated temperature settings. This is enforced at the call site in

app/api/verdict/route.ts. Violation means sampling variance contaminates the result.

  1. Regen always re-caches — After a successful regen, the result MUST be written back to the

cache via POST /cache/{session_id}. Subsequent requests for the same session_id will hit cache.

A regen that does not write to cache means every page load triggers a new Gemini call —

unnecessary cost and a new divergence opportunity on every load.

  1. Divergence check is non-blocking — Divergence detection logic MUST NOT delay or block

the verdict delivery to the customer. The result page renders the regen verdict immediately.

Divergence check and notification happen asynchronously (fire-and-forget IIFE or equivalent).

  1. Original verdict is authoritative — If divergence is detected, the emailed verdict is

considered authoritative (the customer received it first, paid for it, and may have acted on it).

The result page displays the regen verdict WITH a divergence disclaimer appended. It does NOT

silently replace the emailed verdict.

  1. Divergence thresholds (applied to top-level verdict field comparison):

- "none" — top-level verdict identical (both GREEN, both AMBER, etc.) → no action

- "minor" — adjacent color shift (GREEN↔AMBER, AMBER↔RED) → log only; no customer notification

- "significant" — non-adjacent shift (GREEN↔RED, any↔NULL) → log + customer notification email

  1. Regen is only triggered by cache miss — Regen MUST NOT be triggered for any other reason

(e.g., customer request, retry, admin action) without NOUS authorization. Regen is the

automatic fallback path, not a manual "regenerate" feature.

  1. Prompt identity — The prompt template sent to Gemini on regen MUST be identical (byte-for-byte)

to the prompt template used in the original webhook generation. Any deviation in prompt structure

can introduce divergence independent of temperature settings.

  1. [GAP — needs design] Regen rate limiting — No mechanism currently prevents a customer from

triggering repeated regen calls (by not caching, or by cache expiry). A rate limit of 1 regen

per session_id per 5 minutes should be implemented. Currently unspecified.


VERIFICATION CRITERIA

Σ.✓ conditions — regen consistency is operating correctly when:

  1. Temperature enforcement — A test call to the regen code path verifies that the Gemini API

request body contains temperature=0.0 and topK=1. This can be verified via mock/intercept

in the test suite. Failure to find these params = spec violation.

  1. Cache write after regen — After a regen, GET /cache/{session_id} returns 200 with the

regen payload. The regen: true flag is present. Verified by: integration test that deletes

cache entry, loads result page, then checks cache.

  1. Divergence log entry — When a regen occurs, oracle_log.jsonl receives a

regen_divergence_check entry within 5 seconds. Verified by: integration test with oracle_log

tail check. [GAP — requires oracle_log.jsonl to exist (GAP-01)]

  1. Non-blocking render — Result page returns HTTP 200 with verdict JSON within 30 seconds of

cache miss, regardless of whether divergence was detected. Divergence processing must not add to

render latency. Verified by: load test with cache miss and timing assertion.

  1. Significant divergence notification — When a GREEN→RED or RED→GREEN divergence is induced

in test (by seeding original verdict in log and mocking Gemini to return opposite), the customer

email with divergence disclaimer is sent within 60 seconds. Verified by: email service mock +

log assertion.

  1. Prompt identity check — A unit test compares the prompt string passed to Gemini in both the

webhook path and the regen path for all three tiers. String equality must hold. Verified by:

extracting prompt construction to a shared utility function (buildVerdictPrompt(tier, query))

and testing that function in isolation.


FAILURE MODES

  1. Σ.⊠ Temperature not enforced — Regen call uses default Gemini temperature (non-zero).

Result: verdict varies on every page load. Customer sees different verdict each refresh.

Detection: no current instrumentation. Mitigation: code review + test enforcement (VC-1).

  1. Σ.⊠ Cache not written after regen — Regen succeeds but cacheVerdict() silently fails

(GAP-06 — empty catch in verdictCache.ts). Every page load triggers a new Gemini call.

Detection: cache hit rate metric (not currently tracked). Mitigation: fix GAP-06 (alerting on

cache service health); also fix empty catch in cacheVerdict.

  1. Σ.⊠ Original verdict not recoverable — oracle_log.jsonl does not exist (GAP-01 not fixed).

Divergence check cannot compare to original. Result: divergence check skipped; customer may

receive no notification of a real divergence. Mitigation: implement GAP-01 (oracle_log.jsonl).

  1. Σ.⊠ Divergence notification email fails — Graph API is down at the moment a significant

divergence is detected. Notification email not sent. Customer is not informed.

Detection: email service 502 response in async path. Mitigation: log the failure; retry once

after 60 seconds (fire-and-forget second attempt). [GAP — retry logic for async divergence

notification not specified]

  1. Σ.⊠ Prompt divergence between webhook and regen path — A code change modifies the prompt

construction in one path but not the other. Regen divergence increases structurally.

Detection: VC-6 (prompt identity test) catches this on deploy. Mitigation: consolidate prompt

construction into buildVerdictPrompt() utility function used by both paths.

  1. Σ.⊠ Gemini infrastructure variance — Even at temperature=0.0, different serving replicas

may return different token streams for identical inputs. This is an external model behavior gap.

Detection: divergence log (GAP entry). Mitigation: none automatic — log and notify.

[GAP — needs design: if infrastructure variance frequency > 5% of regen events, escalate to

NOUS for consideration of caching original verdict in a redundant store]

  1. Σ.⊠ Regen loop — Customer repeatedly reloads result page after cache write fails.

Each reload triggers a new Gemini call and a new regen. Cost accumulates.

Detection: no rate limit currently in place. Mitigation: implement regen rate limiting (INVARIANT 8).


DEPENDENCIES

| Dependency | Role |

|-----------|------|

| app/api/verdict/route.ts | Regen trigger point — cache miss path |

| app/lib/verdictCache.ts | cacheVerdict() — must be called after regen |

| oracle_toll.py (port 8889) | Provides /cache/{session_id} GET/POST |

| Gemini API (gemini-2.5-flash) | Regen generation target |

| oracle_log.jsonl | Divergence event log (GAP-01 of SPEC_ORACLE_VERDICT_PIPELINE) |

| oracle_email_service.py (port 8006) | Divergence notification delivery |

| SPEC_ORACLE_VERDICT_PIPELINE.md | Parent pipeline spec |


DEPENDENTS

| Dependent | Dependency |

|-----------|-----------|

| Customer trust | Consistency between email and result page |

| Revenue reputation | A GREEN→RED divergence on result page for a paid customer is a brand event |

| oracle_log.jsonl audit trail | Regen events must be logged for forensics |

| SPEC_ORACLE_SMOKE_TEST.md | Smoke test must include a cache-miss regen path validation |


GAPS IDENTIFIED DURING SPECIFICATION

| Gap ID | Description | Impact |

|--------|-------------|--------|

| REGEN-GAP-01 | Original webhook generation config (temperature setting) unspecified — may not match regen config | Unknown divergence baseline |

| REGEN-GAP-02 | Original verdict not recoverable without oracle_log.jsonl (PIPELINE GAP-01) | Divergence check blind |

| REGEN-GAP-03 | No rate limiting on regen calls per session_id | Cost exposure on repeated page loads |

| REGEN-GAP-04 | Retry logic for divergence notification email not specified | Silent failure on notification path |

| REGEN-GAP-05 | No metric tracking cache hit vs. regen frequency | Operational visibility gap |

| REGEN-GAP-06 | Gemini infrastructure variance (temperature=0 does not guarantee bit-identical output) | Residual divergence rate unknown |


REFERENCES

| File | Role |

|------|------|

| /home/nous/Aether/app/app/api/verdict/route.ts | Regen trigger — cache miss path |

| /home/nous/Aether/app/app/lib/verdictCache.ts | Cache R/W |

| /home/nous/oracle_toll.py | Cache service |

| /home/nous/oracle_email_service.py | Divergence notification delivery |

| /home/nous/memories/SPEC_ORACLE_VERDICT_PIPELINE.md | Parent pipeline spec (GAP-08 source) |


Φζ.⊤. The regen path must be held as tight as the original.


Jeremy Zlabis

Chronogeometer · Visionary · Disruptor · Chief

42 Sisters AI · East York, Toronto

🍁 Φ 0.042