# Project export: WrongWorlds

This document was generated by HackStack to give an AI agent context about a hackathon project. Sections are labeled with their provenance; content marked as truncated was cut to keep this document small.

## Project metadata

- Hackathon: OpenAI Build Week
- Tagline: Your wrong answer becomes a world you must investigate, fracture, rebuild, and escape.
- Devpost: https://devpost.com/software/wrongworlds
- GitHub: https://github.com/jpablortiz96/wrongworlds
- Demo: https://wrongworlds.vercel.app/?mode=judge
- Video: https://www.youtube.com/embed/_PB8YzG987s?enablejsapi=1&hl=en_US&rel=0&start=&version=3&wmode=transparent
- Team: 1 GitHub contributor(s) — Juan Pablo Enriquez Ortiz (1 commits)

## Devpost submission (written by the team)

### Overview

Your wrong answer becomes a world you must investigate, fracture, rebuild, and escape. 🎮 Play Judge Mode • 🌐 Live Website • 💻 GitHub • 🔬 Evidence Archive 💡

### Inspiration

Most educational AI systems respond to a misconception by explaining why the learner is wrong. That helps—but it does not always change the mental model that produced the mistake. A learner may repeat the corrected answer while continuing to reason in exactly the same way. WrongWorlds began with a different question: What if a learner could enter a world where their wrong answer was actually true? Instead of immediately correcting the learner, WrongWorlds transforms the misconception into an explorable reality. Inside that reality, the learner must: 🔍 Investigate the world. 🧩 Collect contradictory evidence. 💥 Fracture its false laws. 🌠 Rebuild a stronger explanation. 🚪 Prove that the new reasoning transfers to another context. The result is the Museum of Possible Realities: an educational game concept where every misconception can become a world with its own rules, evidence, experiments, and escape condition. 🎮 What It Does WrongWorlds is a five-act illustrated reasoning game. A learner begins with a belief: “The marketing campaign caused the sales increase.” GPT-5.6 interprets the learner’s language and converts it into a structured belief model. The learner then enters Signal City—a world governed by that explanation. Rather than receiving the correct answer immediately, the learner must explore what their belief predicts, test competing explanations, and reconstruct the causal model using evidence. 🧭 The Five-Act Experience 📊 The Central Causal Reveal $$ +70 = +10_{\text{campaign}} + 40_{\text{festival}} + 20_{\text{district}} $$ The campaign contributed to the increase—but it was not the only cause. ✨ Why It Is Different WrongWorlds does not treat a misconception as a sentence to correct. It treats the misconception as a world to test. The learner must: 🌍 Enter the reality created by the belief. 👁️ Observe what that belief predicts. 🧪 Run controlled comparisons. 🧩 Collect evidence. 💥 Watch the false reality fracture. 🌠 Rebuild a stronger causal model. 🚉 Transfer the reasoning to another world. The learner does not escape by receiving the answer. The learner escapes by demonstrating better reasoning. 🏗️ How We Built It WrongWorlds was built with Codex and GPT-5.6, using a strict separation between: 🤖 Generative interpretation ⚙️ Deterministic educational authority This separation allows the system to understand flexible learner language without allowing the model to invent evidence, change simulation outcomes, or manipulate scores. 🤖 GPT-5.6 Interprets Learner Language GPT-5.6 converts free-form learner language into a structured belief model. It identifies elements such as: The proposed cause. The claimed effect. The learner’s reasoning patterns. Relevant variables. Confidence levels. GPT-5.6 is responsible for understanding what the learner believes—not for deciding whether that belief succeeds inside the simulation. ⚙️ Deterministic Engines Govern the World GPT-5.6 does not determine: Evidence. Simulation results. State transitions. Fracture eligibility. Scores. Transfer outcomes. Those responsibilities remain with deterministic TypeScript domain engines controlling: 🏙️ Signal City experiments. 🧩 Evidence generation. 💥 Fracture eligibility. 📊 Causal contribution values. 🌌 The Reasoning Change Map. 🚉 Bloom Station transfer. 🏁 Completion and scoring. 🧱 System Architecture 🔐 Core Design Principle GPT-5.6 interprets the learner. Deterministic systems retain authority over the world. 🤝 Built With Codex Codex was the primary development partner throughout the project. It supported: 🏛️ Architecture and domain modeling. 💻 Implementation. 🧪 Automated testing. 🔁 Deterministic replay. ♿ Accessibility. 🎨 Visual integration. 🖼️ Asset validation. 📝 Documentation. 🚀 GitHub and Vercel release workflows. 🔐 Evidence integrity checks. 📦 The Final Application Includes A complete five-act illustrated Gamefront. English and Spanish localization. Keyboard navigation. Reduced-motion support. Accessible 2D parity. Responsive mobile layouts. Deterministic replay. Reproducible judge-facing screenshots. A public Evidence Archive. 🧱 Challenges We Ran Into 1. 🧠 Separating Interpretation From Authority The hardest architectural decision was determining exactly where GPT-5.6 should stop. We wanted the model to understand natural learner language, but we did not want it to: Invent evidence. Alter simulation outcomes. Influence scoring. Change state transitions. Solving this required explicit contracts between the belief interpreter and the deterministic domain engines. 2. 🎮 Turning an Editorial Prototype Into a Game The first Judge Mode was technically complete, but it felt more like an educational website than a world a learner could truly enter. We rebuilt the experience around: 👤 A recurring protagonist named Echo. 🌍 Two visually distinct worlds. 🌀 Portals. 🧩 Evidence objects. 📍 Causal hotspots. 💥 A cinematic reality-fracture moment. 🌌 A puzzle-driven rebuilding sequence. 🚪 A final escape state. The visual transformation changed how the experience felt without modifying the underlying causal engine or frozen evaluation artifacts. 3. 🔁 Maintaining Deterministic Replay The same replay needed to produce the same: State. Evidence. Visuals. Screenshots. Final result. Every single time. The final screenshot pipeline generated byte-identical public assets across repeated runs. 4. 🎨 Cleaning and Integrating Generated Assets The original game assets contained chroma-key edge contamination. We created a deterministic cleanup process that: Preserved image dimensions. Preserved alpha transparency. Removed green spill. Retained fine hair details. Preserved crystals and energy glows. Regenerated the public visual package from the real product. 5. ♿ Preserving Accessibility Without Losing the Game Feeling WrongWorlds supports: ⌨️ Keyboard interaction. 🧘 Reduced motion. 🗺️ Accessible 2D mode. 🌎 English and Spanish. 🎯 Visible focus states. 📱 Mobile layouts. The challenge was preserving the causal revelation for learners who cannot—or prefer not to—use cinematic motion. 🏆 Accomplishments We Are Proud Of ✅ Built a complete five-act educational game experience. ✅ Created two visually distinct reasoning worlds. ✅ Preserved deterministic authority over evidence and scoring. ✅ Implemented three real causal experiments in Signal City. ✅ Added transfer assessment through Bloom Station. ✅ Built deterministic replay with zero application POST requests. ✅ Deployed a Git-backed production release on Vercel. ✅ Published a public GitHub repository. ✅ Published a public Evidence Archive. ✅ Added English and Spanish localization. ✅ Added mobile, keyboard, and reduced-motion support. ✅ Added Accessible 2D parity. ✅ Generated reproducible README, Devpost, Open Graph, and video assets. 🧪 Final Verification 📚 What We Learned 🧠 A Correction Is Not the Same as a Changed Mental Model A learner can remember the right answer without understanding why the original reasoning failed. WrongWorlds makes the misconception: Visible. Testable. Explorable. Breakable. Rebuildable. 🔄 Transfer Matters A learner has not fully learned a reasoning pattern if they can only repeat it in the original example. Bloom Station exists to test whether controlled-comparison reasoning transfers to a completely different context. 🔐 AI Becomes Stronger When Its Authority Is Bounded GPT-5.6 is valuable because it can interpret the many ways a learner may express a belief. The deterministic engine is valuable because it guarantees that: Evidence remains stable. Scores remain reproducible. Simulations remain auditable. Evaluation remains trustworthy. The strength of the system comes from giving each component a clearly defined responsibility. 🎨 Visual Design Changes How Technical Work Is Understood The original implementation already contained the causal engine, but the illustrated Gamefront made the educational concept immediately understandable. The fracture scene became the clearest expression of the product: One apparent cause breaking into multiple contributions. 🚀 What Is Next WrongWorlds currently contains: 🏙️ One primary exhibit: Signal City. 🚉 One transfer world: Bloom Station. The Museum of Possible Realities could expand into new exhibits covering: 🔬 Science misconceptions. ➗ Mathematical reasoning. 💰 Economics. 📜 History. 📊 Statistics. ⚙️ Systems thinking. 📰 Media literacy. 🔮 Future Work Could Include Teacher-authored WrongWorlds. Classroom cohorts. Learner progress histories. Adaptive transfer worlds. Controlled educational studies. Long-term learning and retention measurement. ⚠️ Current Limitation The current Evidence Archive is exploratory and is not presented as proof of educational efficacy. Larger learner studies would be required to measure: Long-term learning. Retention. Reasoning improvement. Transfer across contexts. 🎮 Try WrongWorlds 🛠️ Built With Codex · GPT-5.6 · TypeScript · React · Next.js · Node.js · Playwright · Vitest · Vercel · GitHub · CSS Modules · HTML5 · WebP · Accessibility · Internationalization · Deterministic Simulation 🌌 Enter the wrong world. Test its laws. Rebuild the truth. Escape with better reasoning.

## README (from the GitHub repository)

<div align="center">

# WrongWorlds

### Your wrong answer becomes a world you must investigate, fracture, rebuild, and escape.

**A Museum of Possible Realities for causal reasoning.**

<p>
  <a href="https://wrongworlds.vercel.app/?mode=judge"><strong>Play Judge Mode</strong></a>
  · <a href="https://wrongworlds.vercel.app">Live Website</a>
  · <a href="https://wrongworlds.vercel.app/evidence">Evidence Archive</a>
  · <a href="#technical-architecture">Technical Architecture</a>
  · <a href="#run-locally">Run Locally</a>
</p>

</div>

<p align="center">
  <img
    src="./public/submission/v1/wrongworlds-hero-fracture.webp"
    alt="WrongWorlds reality fracture showing an apparent sales increase of seventy separating into campaign, festival, and district contributions"
    width="100%"
  />
</p>

## The thesis

> Most educational AI explains why a learner is wrong. WrongWorlds lets the learner enter a reality where the wrong explanation appears to be true—and escape only after reconstructing the reasoning.

WrongWorlds is a narrative educational game and misconception-reconstruction system. A learner commits to a causal explanation, enters a simulated world governed by that belief, investigates contradictory evidence, rebuilds the explanation, and tests the same reasoning in a new context.

> **GPT-5.6 interprets learner language. Deterministic engines retain authority over evidence, simulation, state transitions, and scoring.**

## Experience WrongWorlds in 90 seconds

1. Enter the **Portal of Belief**.
2. Investigate the three **Signal City** hotspots.
3. Collect three evidence fragments.
4. Watch the apparent `+70` result fracture.
5. Rebuild the causal explanation.
6. Transfer the reasoning in **Bloom Station**.
7. Reach **WORLD ESCAPED**.

<p align="center">
  <a href="https://wrongworlds.vercel.app/?mode=judge"><strong>Enter the verified Judge Mode replay →</strong></a>
</p>

No account, credentials, or API key are required. The public Judge Mode is a deterministic replay designed to preserve the same evidence, transitions, and result without network variance.

## From misconception to transfer

<p align="center">
  <img
    src="./public/submission/v1/wrongworlds-journey.webp"
    alt="Three-part WrongWorlds journey from entering a misconception-driven world, through causal fracture, to transfer and escape"
    width="100%"
  />
</p>

### Enter the WrongWorld

The learner's causal belief becomes the governing law of a simulated reality.

### Break its false laws

Controlled comparisons reveal evidence the original explanation cannot account for.

### Escape with better reasoning

The learner must apply the reconstructed reasoning in a different world.

## The educational loop

WrongWorlds is designed around four mechanisms: externalizing a learner's mental model, generating cognitive conflict through evidence, reconstructing the causal explanation, and testing transfer in a new context.

```mermaid
flowchart LR
    A["Learner misconception"] --> B["Belief becomes a world"]
    B --> C["Learner predicts what the world should do"]
    C --> D["Controlled comparisons"]
    D --> E["Contradictory evidence"]
    E --> F["Reality fracture"]
    F --> G["Causal model reconstruction"]
    G --> H["Transfer in a new world"]
    H --> I{"Reasoning transfers?"}
    I -- Yes --> J["WORLD ESCAPED"]
    I -- No --> G
```

1. **Externalization** — A misconception becomes inspectable instead of remaining hidden in language.
2. **Evidence-driven conflict** — The learner experiences a mismatch between the initial explanation and controlled comparisons.
3. **Reconstruction** — The learner builds a more defensible causal model instead of receiving a correction to memorize.
4. **Transfer** — Bloom Station checks whether the comparison strategy can be applied outside the original scenario.

This is an educational design hypothesis supported by an exploratory engineering evaluation—not proof of educational efficacy.

<a id="technical-architecture"></a>

## GPT-5.6 is an interpreter—not the authority

The optional live path sends free-form English or Spanish learner language through the server-only OpenAI Responses API. GPT-5.6 returns a Structured Output, and the application validates it again with Zod as `BeliefModel@2.0.0` before it can enter the experience.

The current contract is derived directly from `src/core/ai/schemas.ts`:

```ts
type BeliefModel = {
  schemaVersion: "2.0.0";
  language: "en" | "es";
  primaryClaim: string;
  claimedCause: "campaign" | "festival" | "district" | "multiple" | "unclear";
  claimedEffect: "sales";
  causalStrength: "certain" | "probable" | "possible" | "unclear";
  mentionedExplanatoryVariables: ("campaign" | "festival" | "district" | "time")[];
  omittedRelevantVariables: ("campaign" | "festival" | "district" | "time")[];
  reasoningPatterns: ReasoningPattern[];
  uncertaintyLanguage: string[];
  conciseMirror: string;
};
```

`causalStrength` records linguistic confidence, not evidential validity. `claimedEffect` is always `sales`, while explanatory variables are limited to explicitly mentioned `campaign`, `festival`, `district`, or `time`.

| Versioned boundary | Frozen value |
|---|---|
| Model | `gpt-5.6-sol` |
| Belief contract | `BeliefModel@2.0.0` |
| Prompt | `belief-model.v2.2` |
| Runtime | `belief-runtime.v2` — 15 seconds, zero automatic retries |
| Metrics | `belief-metrics.v2.1` |

| Responsibility | GPT-5.6 | Deterministic / validated system |
|---|:---:|:---:|
| Interpret learner language | Yes | No |
| Produce a structured belief representation | Yes | Validates the contract |
| Generate experiment outcomes | No | Yes |
| Decide what evidence was produced | No | Yes |
| Determine fracture eligibility | No | Yes |
| Control world state | No | Yes |
| Evaluate Bloom transfer | No | Yes |
| Open the exit portal | No | Yes |

```mermaid
flowchart LR
    subgraph Modes["Two execution modes"]
      Live["New learner language"] --> Action["interpretBeliefAction"]
      Action --> Interpreter["interpretBelief"]
      Interpreter --> GPT["GPT-5.6 Sol<br/>Structured Output"]
      GPT --> Schema["BeliefModel@2.0.0<br/>Zod validation"]
      Replay["Verified Judge replay"] --> Frozen["getJudgeReplay<br/>frozen interpretations"]
    end

    Schema --> Store["useLearningStore"]
    Frozen --> Store
    Store --> Learning["Learning Engine<br/>transitionLearningSession"]
    Manifest["ScenarioManifest@1.0.0"] --> Simulation["Simulation Engine<br/>pure comparisons"]
    Simulation --> Learning
    Learning --> Evidence["Evidence + fracture eligibility"]
    Evidence --> ChangeMap["ReasoningChangeMap@1.0.0"]
    ChangeMap --> Bloom["BloomTransferSession<br/>pure transfer rubric"]
    Bloom --> Exit{"WORLD ESCAPED?"}
```

> **The model may interpret what the learner believes. It cannot change what the evidence means.**

### Two execution modes, one authority model

**Live interpretation path.** When explicitly enabled with server-only configuration, GPT-5.6 converts new learner language into the versioned belief contract. Requests use `store: false`; invalid output or provider failure remains a visible, recoverable error.

**Deterministic Judge Mode.** The public replay uses exact frozen interpretations from `ai-live-20260720T192203945Z-33656`. It labels that provenance as a verified replay and does not pretend a live request occurred. The replay exists so every judge can encounter the same evidence and state transitions without credentials.

Both modes feed the same deterministic simulation, learning rules, reconciliation, and transfer rubric. The public release keeps live interpretation disabled with `WRONGWORLDS_DISABLE_LIVE=1`.

## What happens after the learner enters a belief

The runtime sequence below uses implemented functions and state holders—not hypothetical services.

```mermaid
sequenceDiagram
    actor Learner
    participant UI as SignalCityExperience
    participant Store as useLearningStore
    participant L

[README truncated for size]

## Detected evidence (automated analysis)

Indexed codebase: 182 recognized source files, 1004 KB.
- CSS (language) — detected in the code
- Next.js (technology) — detected in the code
- OpenAI (technology) — detected in the code
- React (technology) — detected in the code
- TypeScript (language) — detected in the code
- Vercel (technology) — claimed on Devpost, not found in the code
- AI coding agent: Codex — evidence: config files committed to the repository

## Codebase structure (from repository index)

### Files (120 of 241)

```
.env.example
.gitattributes
.gitignore
ACCESSIBILITY.md
AGENTS.md
ARCHITECTURE.md
BUILD_LOG.md
CODEX_COLLABORATION.md
DECISIONS.md
DESIGN_PRINCIPLES.md
docs/AI_ROLE.md
docs/DEMO_RUNBOOK.md
docs/DEPLOYMENT_VERIFICATION.md
docs/domain-model.md
docs/golden-path.md
docs/integration-strategy.md
docs/PROMPT_CONTRACTS.md
docs/signal-city-spec.md
eslint.config.mjs
EVIDENCE_PLAN.md
evidence/ai/fixtures/belief-ambiguous-es.json
evidence/ai/fixtures/belief-initial-en.json
evidence/ai/fixtures/belief-initial-es.json
evidence/ai/fixtures/belief-revised-en.json
evidence/ai/README.md
evidence/archive-manifest.json
evidence/datasets/belief-benchmark.v1.jsonl
evidence/datasets/belief-benchmark.v2.jsonl
evidence/datasets/DATASET_CARD.md
evidence/datasets/transfer-benchmark.v1.jsonl
evidence/final/final-evaluation.v1.json
evidence/final/final-evaluation.v1.md
evidence/pilot/ANALYSIS_PLAN.md
evidence/pilot/CONSENT_AND_PRIVACY.md
evidence/pilot/PILOT_PROTOCOL.md
evidence/pilot/RESPONSE_TEMPLATE.csv
evidence/plots/.gitkeep
evidence/pricing/pricing.v1.json
evidence/README.md
evidence/replays/session-replays.v1.jsonl
evidence/reports/.gitkeep
evidence/reports/ai-fixture-baseline-v1.csv
evidence/reports/ai-fixture-baseline-v1.json
evidence/reports/ai-fixture-baseline-v1.md
evidence/reports/ai-fixture-contract-v2.csv
evidence/reports/ai-fixture-contract-v2.json
evidence/reports/ai-fixture-contract-v2.md
evidence/reports/ai-live-20260719T015829469Z-22428.csv
evidence/reports/ai-live-20260719T015829469Z-22428.json
evidence/reports/ai-live-20260719T015829469Z-22428.md
evidence/reports/ai-live-20260719T195109823Z-24680.csv
evidence/reports/ai-live-20260719T195109823Z-24680.json
evidence/reports/ai-live-20260719T195109823Z-24680.md
evidence/reports/ai-live-20260720T162933063Z-24792.csv
evidence/reports/ai-live-20260720T162933063Z-24792.json
evidence/reports/ai-live-20260720T162933063Z-24792.md
evidence/reports/ai-live-20260720T190213232Z-19152.csv
evidence/reports/ai-live-20260720T190213232Z-19152.json
evidence/reports/ai-live-20260720T190213232Z-19152.md
evidence/reports/ai-live-20260720T192203945Z-33656.csv
evidence/reports/ai-live-20260720T192203945Z-33656.json
evidence/reports/ai-live-20260720T192203945Z-33656.md
evidence/reports/ai-live-20260720T195247731Z-11704.csv
evidence/reports/ai-live-20260720T195247731Z-11704.json
evidence/reports/ai-live-20260720T195247731Z-11704.md
evidence/reports/session-replays-v1.json
evidence/reports/transfer-baseline-v1.csv
evidence/reports/transfer-baseline-v1.json
evidence/reports/transfer-baseline-v1.md
evidence/runs/.gitkeep
evidence/runs/ai-fixture-baseline-v1.json
evidence/runs/ai-fixture-contract-v2.json
evidence/runs/ai-live-20260718T212113029Z-34988.json
evidence/runs/ai-live-20260718T220029707Z-12948.json
evidence/runs/ai-live-20260718T221430948Z-14512.json
evidence/runs/ai-live-20260719T015829469Z-22428.json
evidence/runs/ai-live-20260719T195109823Z-24680.json
evidence/runs/ai-live-20260720T162933063Z-24792.json
evidence/runs/ai-live-20260720T190213232Z-19152.json
evidence/runs/ai-live-20260720T192203945Z-33656.json
evidence/runs/ai-live-20260720T195247731Z-11704.json
evidence/runs/transfer-baseline-v1.json
evidence/schemas/evidence-benchmark.v1.schema.json
evidence/schemas/evidence-benchmark.v2.schema.json
evidence/schemas/evidence-report.v2.1.schema.json
evidence/schemas/README.md
evidence/scripts/analyze-pilot.ts
evidence/scripts/build-final-evaluation.ts
evidence/scripts/build-report.ts
evidence/scripts/generate-plots.ts
evidence/scripts/lib.ts
evidence/scripts/migrate-belief-dataset-v2.ts
evidence/scripts/run-ai-benchmark.ts
evidence/scripts/run-replays.ts
evidence/scripts/run-transfer-benchmark.ts
evidence/scripts/validate-evidence.ts
evidence/selections/balanced-development-20.v1.json
JUDGES_START_HERE.md
LIMITATIONS.md
next.config.ts
package.json
playwright.config.ts
PRODUCT_CONSTITUTION.md
public/submission/v1/manifest.json
README.md
SCOPE_LOCK.md
scripts/build-presentation-polish-review.ts
scripts/build-visual-cleanup-review.ts
scripts/capture-submission-assets.ts
scripts/clean-gamefront-alpha-edges.ts
scripts/submission-assets.ts
scripts/validate-ai-fixtures.mjs
scripts/validate-gamefront-assets.ts
scripts/validate-submission-assets.ts
src/app/actions/interpret-belief.ts
src/app/evidence/artifacts/[...path]/route.ts
src/app/evidence/page.tsx
src/app/globals.css
src/app/layout.tsx
src/app/page.tsx
[121 more files omitted for size]
```

### Dependencies

- package.json: @axe-core/playwright@4.12.1, @playwright/test@1.61.1, @react-three/drei@10.7.7, @react-three/fiber@9.6.1, @types/node@26.1.1, @types/react@19.2.17, @types/react-dom@19.2.3, @vitest/coverage-v8@4.1.10, eslint@9.39.5, eslint-config-next@16.2.10, next@16.2.10, openai@6.46.0, react@19.2.7, react-dom@19.2.7, three@0.185.1, tsx@4.23.1, typescript@6.0.3, vitest@4.1.10, zod@4.4.3, zustand@5.0.14

### Recent commits (newest first)

- docs: expand WrongWorlds technical and educational architecture
- Merge illustrated WrongWorlds gamefront
- feat: transform WrongWorlds into an illustrated gamefront
- docs: publish WrongWorlds release URLs
- feat: prepare WrongWorlds museum release
- feat: make WrongWorlds judge thesis impossible to miss
- evidence: close final evaluation ledger
- evidence: preserve single authorized holdout evaluation
- evidence: report final full development evaluation
- evidence: preserve final full development evaluation
- evidence: report final v2.2 semantic freeze check
- evidence: preserve final v2.2 semantic freeze check
- fix: freeze final belief prompt semantics
- evidence: preserve frozen bilingual development evaluation
- test: freeze balanced development evaluation
- fix: harden evidence report typography
- evidence: preserve calibrated bilingual v2.1 live run
- fix: harden benchmark calibration integrity
- evidence: preserve critical bilingual v2 live run
- feat: clarify versioned belief measurement

## Key source files (fetched from GitHub, selected and truncated for size)

### PRODUCT_CONSTITUTION.md

```markdown
# WrongWorlds Product Constitution

Status: **binding for the Build Week MVP**. Last reviewed: 2026-07-13.

## Mission

WrongWorlds helps learners revise misconceptions by letting them investigate a coherent world in which their initial explanation appears plausible, then encounter decisive evidence and rebuild their reasoning.

Product thesis: **“Don’t tell learners why they’re wrong. Let them explore a world where their wrong answer is right.”**

The initial audience is university students, bootcamp learners, and professionals building Data & AI Literacy. Grades 9–11 are a possible later audience, not an MVP audience.

## Non-negotiable product invariants

1. The learner commits to an explanation before receiving corrective evidence.
2. The world initially makes that explanation plausible without lying about the underlying data.
3. The learner can manipulate variables, compare scenarios, and inspect evidence.
4. A deterministic simulation owns mathematical truth, causal relationships, scenario outputs, and correctness constraints.
5. AI may interpret language, choose among pre-authorized revelations, and provide formative feedback. It may not alter simulation truth, fabricate evidence, or independently declare a conclusion correct.
6. Every consequential AI output is schema-constrained, logged with provenance, and validated against deterministic state.
7. The immersive and accessible views expose equivalent learning state, controls, evidence, and completion paths.
8. The product never invents educational efficacy claims, assessment validity, or learning scores.
9. The Build Week deliverable prioritizes one complete world—Signal City—over breadth.
10. A completed run must be reproducible from versioned inputs, deterministic engine version, reveal policy version, and relevant model metadata.

## Authority boundaries

| Concern | Authority | AI allowed role |
|---|---|---|
| Causal graph and equations | Versioned Signal City specification and simulation engine | None |
| Scenario outputs | Deterministic simulation engine | Explain an output already computed |
| Allowed evidence/revelations | Versioned reveal catalog and prerequisite rules | Select from currently eligible IDs |
| Natural-language interpretation | Learning Engine | Produce schema-bound labels with confidence and rationale |
| Correctness | Deterministic rubric over claims and inspected evidence | Suggest feedback; never override rubric |
| Product scope | Human maintainers and `SCOPE_LOCK.md` | Recommend only |
| Releases and public claims | Human maintainers | Draft only |

## Change protocol

- A change to a non-negotiable invariant, MVP in/out list, causal truth, target audience, or core technology is a **locked decision change**. It requires a new ADR in `DECISIONS.md`, explicit human approval recorded there, and updates to every affected document before implementation.
- A reversible implementation choice may proceed if it remains inside the locked boundaries, is documented in 
[truncated — 592 more characters]
```

### SCOPE_LOCK.md

```markdown
# MVP Scope Lock

Status: **locked for OpenAI Build Week 2026**. Scope changes require the protocol in `PRODUCT_CONSTITUTION.md`.

## Required MVP outcomes

The MVP is one installable bilingual PWA containing one finished learning world and the minimum integration/evidence surface needed to demonstrate it.

### In scope

- One complete world: **Signal City**.
- English and Spanish learner experience.
- Immersive React Three Fiber view.
- Accessible equivalent 2D view.
- Belief Mapper.
- Pure, deterministic simulation engine.
- Reality Controls for valid interventions and comparisons.
- Fracture Engine using a fixed reveal catalog and deterministic eligibility.
- Reflection Mirror.
- One Transfer Challenge.
- Learning Evidence Card based on recorded actions.
- Installable PWA.
- Embeddable route.
- Versioned REST API.
- Basic read-only MCP server.
- Reproducible evidence pack.
- WCAG 2.2 AA design and test target.

### Explicitly out of scope

- A second complete world.
- Marketplace, social network, multiplayer, payments, or leaderboards.
- Native mobile or desktop applications.
- Complex teacher dashboard.
- Universal course generator.
- Fully AI-generated worlds or a persistent chatbot.
- Decorative multi-agent architecture.
- Full LMS integrations, including production xAPI or LTI 1.3 implementations.
- Invented educational scores or unsupported efficacy claims.
- Grades 9–11 product adaptation during the MVP.

## Acceptance boundary

“Done” means the golden path in `docs/golden-path.md` works in English and Spanish, in immersive and accessible modes; deterministic truth is tested; keyboard and screen-reader paths are viable; the embed, REST, and read-only MCP surfaces expose their documented minimum; and the evidence pack can reproduce every reported metric from raw artifacts.

Polish, content, or infrastructure work that does not directly support this boundary must not delay completion.

## Locked decisions

- Audience, thesis, and single-world strategy.
- Signal City question and competencies.
- Four-layer separation: Simulation Engine, Learning Engine, Experience UI, Integration Layer.
- Next.js, TypeScript, React, Tailwind CSS, React Three Fiber/Three.js, Zustand, Supabase PostgreSQL, Vitest, Playwright, axe-core, OpenAI Responses API, structured outputs, REST, TypeScript MCP, PWA, and English/Spanish localization.
- Deterministic engine as sole authority for mathematical truth.
- AI authority boundary defined in `PRODUCT_CONSTITUTION.md`.
- WCAG 2.2 AA target and equivalent accessible view.

## Reversible decisions

These may be refined without changing scope, provided the change is logged and tested:

- Component boundaries, file layout, naming, and styling tokens.
- Exact 3D art direction and asset pipeline within performance/accessibility budgets.
- Supabase table normalization and caching strategy.
- Hosting region/provider configuration supported by the selected stack.
- Prompt wording, model temperature, and reveal selection heuris
[truncated — 854 more characters]
```

### package.json

```
{
  "name": "wrongworlds",
  "version": "0.1.0",
  "private": true,
  "engines": {
    "node": ">=24.0.0"
  },
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start",
    "lint": "eslint .",
    "typecheck": "tsc --noEmit",
    "test": "vitest run",
    "test:coverage": "vitest run --coverage",
    "test:e2e": "playwright test",
    "validate:ai-fixtures": "node scripts/validate-ai-fixtures.mjs",
    "gamefront:assets": "tsx scripts/validate-gamefront-assets.ts",
    "submission:capture": "tsx scripts/capture-submission-assets.ts",
    "submission:verify": "tsx scripts/validate-submission-assets.ts",
    "benchmark:ai": "tsx evidence/scripts/run-ai-benchmark.ts",
    "benchmark:report": "tsx evidence/scripts/build-report.ts",
    "benchmark:transfer": "tsx evidence/scripts/run-transfer-benchmark.ts",
    "evidence:report": "tsx evidence/scripts/build-report.ts",
    "evidence:replays": "tsx evidence/scripts/run-replays.ts",
    "evidence:verify": "tsx evidence/scripts/validate-evidence.ts",
    "pilot:analyze": "tsx evidence/scripts/analyze-pilot.ts",
    "verify": "npm run lint && npm run typecheck && npm run validate:ai-fixtures && npm run evidence:verify && npm test && npm run build && npm run test:e2e"
  },
  "dependencies": {
    "@react-three/drei": "10.7.7",
    "@react-three/fiber": "9.6.1",
    "next": "16.2.10",
    "openai": "6.46.0",
    "react": "19.2.7",
    "react-dom": "19.2.7",
    "three": "0.185.1",
    "zod": "4.4.3",
    "zustand": "5.0.14"
  },
  "devDependencies": {
    "@axe-core/playwright": "4.12.1",
    "@playwright/test": "1.61.1",
    "@types/node": "26.1.1",
    "@types/react": "19.2.17",
    "@types/react-dom": "19.2.3",
    "@vitest/coverage-v8": "4.1.10",
    "eslint": "9.39.5",
    "eslint-config-next": "16.2.10",
    "tsx": "4.23.1",
    "typescript": "6.0.3",
    "vitest": "4.1.10"
  }
}

```

### src/app/layout.tsx

```typescript
import type { Metadata, Viewport } from "next";
import type { ReactNode } from "react";
import "./globals.css";
import { siteMetadata } from "./site-metadata";

export const metadata: Metadata = siteMetadata;

export const viewport: Viewport = {
  width: "device-width",
  initialScale: 1,
  colorScheme: "dark",
  themeColor: "#08111b",
};

export default function RootLayout({ children }: Readonly<{ children: ReactNode }>) {
  return (
    <html lang="en" suppressHydrationWarning>
      <body>{children}</body>
    </html>
  );
}

```

### src/app/page.tsx

```typescript
import { SignalCityExperience } from "@/experience/signal-city-experience";
import { loadFinalEvaluationSummary } from "@/integrations/evidence/load-final-evaluation-summary";
import { loadAvailableGamefrontAssets } from "@/integrations/gamefront/load-gamefront-assets";
import { resolveAiRuntimeConfig } from "@/integrations/openai/belief-interpreter";
import { resolveInteractiveModeStatus } from "@/integrations/openai/interactive-policy";
import { isDeterministicE2eMode } from "@/integrations/testing/deterministic-e2e-mode";

interface HomePageProps {
  readonly searchParams: Promise<{ readonly mode?: string }>;
}

export default async function HomePage({ searchParams }: HomePageProps) {
  const deterministicE2e = isDeterministicE2eMode(process.env);
  const liveModeStatus = resolveInteractiveModeStatus(
    resolveAiRuntimeConfig(process.env),
    process.env.WRONGWORLDS_DISABLE_LIVE === "1",
  );
  const [params, evidenceSummary, availableGamefrontAssets] = await Promise.all([
    searchParams,
    loadFinalEvaluationSummary(),
    loadAvailableGamefrontAssets(),
  ]);
  return (
    <SignalCityExperience
      deterministicE2e={deterministicE2e}
      initialJudgeMode={params.mode === "judge"}
      evidenceSummary={evidenceSummary}
      liveModeStatus={liveModeStatus}
      availableGamefrontAssets={availableGamefrontAssets}
    />
  );
}

```

### src/core/evidence/index.ts

```typescript
export * from "./projector";
export type * from "./types";

```

### src/core/simulation/index.ts

```typescript
export * from "./engine";
export * from "./errors";
export * from "./manifest-validator";
export type * from "./types";

```

### src/core/learning/index.ts

```typescript
export * from "./errors";
export * from "./evidence-rules";
export * from "./state-machine";
export type * from "./types";

```

### src/core/ai/index.ts

```typescript
export * from "./fixture-interpreter";
export * from "./meaningful-text";
export * from "./reconcile-reasoning";
export * from "./schemas";

```

### src/app/evidence/page.tsx

```typescript
import type { Metadata } from "next";
import Link from "next/link";
import { loadEvidenceArchive } from "../../integrations/evidence/load-archive";

export const metadata: Metadata = {
  title: "Evidence Archive — WrongWorlds",
  description: "Verified, reproducible evidence artifacts for WrongWorlds.",
};

function artifactHref(relativePath: string): string {
  return `/evidence/artifacts/${relativePath.replace(/^evidence\//u, "").split("/").map(encodeURIComponent).join("/")}`;
}

function displayValue(value: number, locale: "en" | "es"): string {
  if (value > 0 && value < 1) return new Intl.NumberFormat(locale, { style: "percent", maximumFractionDigits: 1 }).format(value);
  return new Intl.NumberFormat(locale).format(value);
}

const copy = {
  en: {
    eyebrow: "Museum record · Exhibit archive", title: "Evidence Archive",
    lead: "Every visible result below resolves to a committed raw artifact and a reproducible report. Evidence Mode is closed with the failed holdout gate visible.",
    skip: "Skip to evidence", home: "Return to Signal City", tested: "What was tested",
    dataset: "Dataset", examples: "examples", split: "development / holdout", frozen: "frozen holdout",
    verified: "Verified", pending: "Pending", source: "Source artifacts", raw: "Raw run", report: "Machine report", readable: "Readable report", plot: "Plot",
    method: "Reproduce", methodText: "Validate schemas, recalculate metrics, regenerate reports and verify every public reference offline:",
    live: "Final deterministic closeout (the holdout must not be rerun):",
    finalJson: "Final evaluation (JSON)", finalReadable: "Final evaluation (Markdown)",
    limits: "Interpretation limits", limitText: "Human labels are the language reference. Deterministic engines are the simulation and transfer reference. These artifacts do not establish mastery, durable learning, fairness, or efficacy.",
  },
  es: {
    eyebrow: "Registro del museo · Archivo de exhibiciones", title: "Archivo de evidencia",
    lead: "Cada resultado visible se vincula con un artefacto raw confirmado y un informe reproducible. Evidence Mode está cerrado y el gate fallido del holdout permanece visible.",
    skip: "Ir a la evidencia", home: "Volver a Signal City", tested: "Qué se evaluó",
    dataset: "Dataset", examples: "ejemplos", split: "desarrollo / holdout", frozen: "holdout congelado",
    verified: "Verificado", pending: "Pendiente", source: "Artefactos fuente", raw: "Ejecución raw", report: "Informe máquina", readable: "Informe legible", plot: "Gráfica",
    method: "Reproducir", methodText: "Valida esquemas, recalcula métricas, regenera informes y verifica cada referencia pública sin red:",
    live: "Cierre determinista final (el holdout no debe volver a ejecutarse):",
    finalJson: "Evaluación final (JSON)", finalReadable: "Evaluación final (Markdown)",
    limits: "Límites de interpretación", limitText: "Las etiquetas humanas son la referencia lingüística. Los motores deterministas son la referencia de simulación y transferencia. Estos artefactos no establecen dominio, aprendizaje duradero, equidad ni eficacia.",
  },
} as const;

export default async function EvidencePage({ searchParams }: { searchParams: Promise<{ lang?: string }> }) {
  const params = await searchParams;
  const locale = params.lang === "es" ? "es" : "en";
  const text = copy[locale];
  const archive = await loadEvidenceArchive();
  return (
    <div className="archiveShell">
      <a className="skipLink" href="#archive-content">{text.skip}</a>
      <header className="archiveHeader">
        <div>
          <p className="kicker">{text.eyebrow}</p>
          <Link href="/" className="archiveBrand">WrongWorlds</Link>
        </div>
        <nav aria-label="Language / Idioma" className="archiveLanguages">
          <Link aria-current={locale === "en" ? "page" : undefined} href="/evidence?lang=en">EN</Link>
          <Link aria-current={locale === "es" ? "page" : undefined} href="/evidence?lang=es">ES</Link>
        </nav>
      </header>
      <main id="archive-content" className="archiveMain" tabIndex={-1}>
        <section className="archiveHero" aria-labelledby="archive-title">
          <p className="archiveIndex">E / 04</p>
          <div><h1 id="archive-title">{text.title}</h1><p>{text.lead}</p></div>
        </section>

        <section className="archiveSection" aria-labelledby="datasets-title">
          <div className="archiveSectionHeading"><span>01</span><h2 id="datasets-title">{text.tested}</h2></div>
          <div className="datasetGrid">
            {archive.datasets.map((dataset) => (
              <article className="archiveDataset" key={dataset.id}>
                <p>{text.dataset}</p><h3>{dataset.id}</h3>
                <strong>{dataset.examples} {text.examples}</strong>
                {dataset.en !== undefined && <p>{dataset.en} EN · {dataset.es} ES<br />{dataset.development} / {dataset.holdout} {text.split}</p>}
                {dataset.holdoutStatus && <span className="archiveTag">{text.frozen}</span>}
                <a href={artifactHref(dataset.path)}>{dataset.path}</a>
              </article>
            ))}
          </div>
        </section>

        <section className="archiveSection" aria-labelledby="records-title">
          <div className="archiveSectionHeading"><span>02</span><h2 id="records-title">Records</h2></div>
          <div className="archiveRecords">
            {archive.collections.map((collection) => (
              <article className={`archiveRecord archiveRecord--${collection.verificationStatus}`} key={collection.id}>
                <div className="archiveRecordTop">
                  <div><p>{collection.mode}{collection.model ? ` · ${collection.model}` : ""}</p><h3>{collection.title}</h3></div>
                  <span className="archiveStatus">{collection.verificationStatus === "verified" ? text.verified : text.pending}</span>
                </div>
                {collection.runId && <p className="archiveRu
[truncated — 1896 more characters]
```

[166 more indexed source files omitted to keep this export small. The full file list is in the Codebase structure section above.]