diff --git a/.gitignore b/.gitignore
index ff241fa..5b7e3ea 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,16 @@
*.log
node_modules/
.claude/
+
+# Local-only creative/IP source material. Keep the public repo focused on the
+# playable prototype unless these are intentionally cleared for release.
+The Network Mythos - A Myth Bible.md
+The Network Mythos - Canon Bible.md
+ALLEY_CAT_GAMES_SUBMISSION_CONCEPT.md
+CASE_FILES_GAME_PLAN.md
+concept-images/
+research for games/
+The Residue/
+the_residue_cc version agent/
+network-mythos-case-box/
+network-mythos-hybrid-table/
diff --git a/Case Box 001 - The Creator Who Left But Kept Posting/README.md b/Case Box 001 - The Creator Who Left But Kept Posting/README.md
new file mode 100644
index 0000000..e4ff90a
--- /dev/null
+++ b/Case Box 001 - The Creator Who Left But Kept Posting/README.md
@@ -0,0 +1,91 @@
+# Network Mythos: Case Box 001
+
+Public demo for a digital mystery box game set inside The Network Mythos. This case focuses on the first playable investigation loop: evidence first, myth underneath.
+
+
+
+The goal of this demo is to test the core loop before expanding the platform:
+
+1. Open a case box.
+2. Inspect evidence.
+3. Solve nested mini-puzzles.
+4. Tag evidence with mythic forces.
+5. Let the player's tags shape the evidence route.
+6. Submit a final reading.
+7. Reveal both the canonical answer and the player's reading path.
+
+## What You Can Test
+
+- A first 5-8 minute investigation about a creator who left the Network, then kept posting.
+- Evidence cards that behave like objects: chat logs, receipts, uploads, notes, and locked material.
+- Player-applied tags that shape the next useful evidence without changing the underlying truth.
+- One fake access gate that teaches the mythos through discovery.
+- A final reveal that compares the submitted reading, canon, signal profile, and route effect.
+
+## Run Locally
+
+This project is intentionally static. Case data is available as a JavaScript module so the app can run from a direct `file:///` URL in restricted browser environments.
+
+Open `index.html` directly, or run a small local server:
+
+```powershell
+python -m http.server 5174 --bind 127.0.0.1
+```
+
+Then visit:
+
+```text
+http://127.0.0.1:5174/
+```
+
+## Project Shape
+
+```text
+Case Box 001 - The Creator Who Left But Kept Posting/
+ index.html
+ package.json
+ README.md
+ docs/
+ case-box-demo.gif
+ first-8-minute-playtest.md
+ first-8-minute-playtest-final.png
+ first-8-minute-playtest-mobile.png
+ game-design.md
+ case-authoring.md
+ src/
+ data/
+ case-001.json
+ scripts/
+ app.js
+ case-engine.js
+ puzzle-engine.js
+ signal-engine.js
+ styles/
+ base.css
+ layout.css
+ components.css
+ public/
+ assets/
+ .gitkeep
+```
+
+## Phase 1 Scope
+
+Build one excellent case box before adding accounts, multiplayer, creator tools, or a backend.
+
+Phase 1 should prove:
+
+- People understand what to do.
+- Evidence inspection is compelling.
+- Force tagging feels meaningful.
+- Nested puzzles add discovery rather than friction.
+- The feedback loop makes players notice their own reading path.
+- The final reveal creates conversation.
+
+## Prototype Docs
+
+- [Game design](docs/game-design.md)
+- [Case authoring](docs/case-authoring.md)
+- [First 8-minute playtest pass](docs/first-8-minute-playtest.md)
+- [Final desktop proof screenshot](docs/first-8-minute-playtest-final.png)
+- [Mobile proof screenshot](docs/first-8-minute-playtest-mobile.png)
diff --git a/Case Box 001 - The Creator Who Left But Kept Posting/docs/case-authoring.md b/Case Box 001 - The Creator Who Left But Kept Posting/docs/case-authoring.md
new file mode 100644
index 0000000..bfbdaa7
--- /dev/null
+++ b/Case Box 001 - The Creator Who Left But Kept Posting/docs/case-authoring.md
@@ -0,0 +1,50 @@
+# Case Authoring
+
+## Case Schema
+
+Each case lives in `src/data/`.
+
+Core fields:
+
+- `id`: stable case id.
+- `title`: display title.
+- `summary`: short premise.
+- `forces`: force vocabulary for this case.
+- `evidence`: evidence items.
+- `puzzles`: nested puzzle definitions.
+- `readings`: final answer options.
+- `canonicalReading`: correct answer id.
+- `pathReveals`: end-of-case route summaries.
+
+## Evidence Item
+
+Evidence items should include:
+
+- `id`
+- `type`
+- `date`
+- `title`
+- `body`
+- `expectedForces`
+- `timeline`
+- `unlockCondition`
+- `puzzleId`
+
+`unlockCondition` can be omitted for always-visible evidence.
+
+## Puzzle Types
+
+Phase 1 supports simple puzzle gates:
+
+- `access-code`: player enters a phrase or code.
+- `research-prompt`: player reads a prompt and answers a concept question.
+- `verification`: fake human-verification puzzle.
+
+Later puzzle types can include crosswords, image inspection, archive diffs, and timeline ordering.
+
+## Authoring Rule
+
+Every puzzle should answer this question:
+
+What mythos concept does this teach through action?
+
diff --git a/Case Box 001 - The Creator Who Left But Kept Posting/docs/case-box-demo.gif b/Case Box 001 - The Creator Who Left But Kept Posting/docs/case-box-demo.gif
new file mode 100644
index 0000000..4e06435
Binary files /dev/null and b/Case Box 001 - The Creator Who Left But Kept Posting/docs/case-box-demo.gif differ
diff --git a/Case Box 001 - The Creator Who Left But Kept Posting/docs/first-8-minute-playtest-final.png b/Case Box 001 - The Creator Who Left But Kept Posting/docs/first-8-minute-playtest-final.png
new file mode 100644
index 0000000..67bcc5a
Binary files /dev/null and b/Case Box 001 - The Creator Who Left But Kept Posting/docs/first-8-minute-playtest-final.png differ
diff --git a/Case Box 001 - The Creator Who Left But Kept Posting/docs/first-8-minute-playtest-mobile.png b/Case Box 001 - The Creator Who Left But Kept Posting/docs/first-8-minute-playtest-mobile.png
new file mode 100644
index 0000000..9b03a09
Binary files /dev/null and b/Case Box 001 - The Creator Who Left But Kept Posting/docs/first-8-minute-playtest-mobile.png differ
diff --git a/Case Box 001 - The Creator Who Left But Kept Posting/docs/first-8-minute-playtest.md b/Case Box 001 - The Creator Who Left But Kept Posting/docs/first-8-minute-playtest.md
new file mode 100644
index 0000000..cf7af67
--- /dev/null
+++ b/Case Box 001 - The Creator Who Left But Kept Posting/docs/first-8-minute-playtest.md
@@ -0,0 +1,116 @@
+# First 8-Minute Playtest Pass
+
+Date: 2026-05-22
+
+## Purpose
+
+Verify that the opening minutes of Case Box 001 feel like investigation rather than passive reading.
+
+This is an automated browser pass plus a self-run implementation pass, not a blind human playtest. It checks whether the current build supports the intended first-session beats and records what still needs a real tester.
+
+Browser artifact:
+
+
+
+Mobile artifact:
+
+
+
+## Test Path
+
+Target path for a first-time player:
+
+1. Open the Case Box.
+2. Inspect "The Final Thread."
+3. Notice the human stakes: Mara is leaving public life and asks not to be found through the Network.
+4. Inspect "Elian Refuses Proof."
+5. Tag both artifacts with `Returned`.
+6. Notice that the signal profile forms a `Returned` route.
+7. See route-surfaced bonus evidence appear.
+8. Open "Human Verification Failed."
+9. Try an incorrect proof-style answer and receive a hint.
+10. Enter `absence`.
+11. Unlock "Continuity Clause."
+12. See the recap update before final submission.
+
+## Results
+
+- Opening state: 6 visible evidence items; active item is "The Final Thread."
+- After tagging "The Final Thread" and "Elian Refuses Proof" with `Returned`, the dominant path becomes `Returned`.
+- Route-surfaced bonus evidence appears: "Offline Errand Receipt."
+- Routed evidence order moves `Returned`-relevant evidence forward.
+- Wrong gate answer is rejected.
+- First failed attempt increments the hint state.
+- Correct gate answer `absence` is accepted.
+- Gate unlocks "Continuity Clause."
+- After unlock, 8 evidence items are visible: 6 initial, 1 route bonus, 1 gate-unlocked memo.
+- Recap inputs show reviewed evidence count, gate status, path, and bonus evidence.
+- Final reading submission opens the Case Reveal panel.
+- The reveal separates submitted reading, canonical reconstruction, what happened, player route, evidence pattern, and route effect.
+- Browser console errors: none observed.
+
+## Browser Automation Log
+
+Automated path executed with Python Playwright against `http://127.0.0.1:5174/`.
+
+- Opening title: "The Final Thread."
+- Opening count: 6 items.
+- Dominant signal after tags: `Returned`.
+- Count after bonus: 7 items / routed by Returned.
+- Bonus visible: true.
+- Wrong answer feedback: "Access denied..." plus hint.
+- Correct answer: `absence`.
+- After unlock title: "Continuity Clause."
+- Count after gate: 8 items / routed by Returned.
+- Final reading result: "Your reading aligns with the canonical reconstruction."
+- Reveal content includes canonical reconstruction, evidence pattern, and route/truth distinction.
+- Desktop console errors: none observed.
+
+Mobile-width pass executed at 390px viewport.
+
+- Case loaded and stacked into a single-column flow.
+- Same inspect/tag/gate/final-reading path completed.
+- Reveal panel visible after submission.
+- Mobile console errors: none observed.
+
+## Acceptance Check
+
+- The player can understand the investigation target in the first minute: pass in content structure; needs blind tester confirmation.
+- The first 5-8 minutes contain active investigation: pass. Inspecting, tagging, route surfacing, failed gate feedback, and unlock are all reachable.
+- The player can notice interpretation tracking: pass in UI support; needs blind tester confirmation.
+- The player can distinguish route from truth: pass in route note and final reveal; needs blind tester confirmation.
+- The player wants to continue after the reveal: not tested; requires blind playtest.
+
+## Observed Risks
+
+- A player may still read several artifacts before touching tags if they do not notice the tag panel.
+- The `Returned` path currently provides the cleanest first-8-minute route because the gate and witness evidence both support it.
+- Bonus evidence can appear before the gate unlock, which is good for route responsiveness but may compete with the gate as the first discovery beat.
+- Visual browser pass succeeded at desktop and 390px mobile viewport. Blind human playtest is still needed.
+
+## Blind Playtest Script
+
+Give the tester only this prompt:
+
+```text
+Open the Case Box and think aloud for eight minutes. Say what you believe happened, what you think the interface is asking you to do, and what changed because of your choices.
+```
+
+Watch for:
+
+- Do they identify Mara as a person before describing the system?
+- Do they inspect at least two artifacts?
+- Do they tag evidence without being told?
+- Do they notice the dominant signal change?
+- Do they find the gate?
+- Do they understand the hint after a wrong answer?
+- Do they describe `absence` as a clue rather than a random password?
+- Do they notice bonus evidence or route ordering?
+- Do they say what they would do next?
+
+## Next Fixes If Testers Stall
+
+- If testers do not tag evidence, make the tag panel more visually connected to the active artifact.
+- If testers miss the gate, make "Human Verification Failed" look more clearly interactive in the evidence inbox.
+- If testers solve the gate but miss the unlocked memo, add a stronger inbox pulse or temporary "new" state.
+- If testers think tags change the truth, strengthen route/truth language in the recap and reveal.
diff --git a/Case Box 001 - The Creator Who Left But Kept Posting/docs/game-design.md b/Case Box 001 - The Creator Who Left But Kept Posting/docs/game-design.md
new file mode 100644
index 0000000..b3eefcf
--- /dev/null
+++ b/Case Box 001 - The Creator Who Left But Kept Posting/docs/game-design.md
@@ -0,0 +1,58 @@
+# Game Design
+
+## One-Sentence Pitch
+
+A digital mystery box where players investigate corrupted online evidence, solve nested puzzles, and discover how the Network shaped their route to the truth.
+
+## Core Principle
+
+The truth is stable. The route is responsive.
+
+The player does not change what happened. The player changes which signals the Network surfaces, buries, delays, or frames.
+
+## Player Loop
+
+1. Inspect evidence.
+2. Solve optional or required mini-puzzles.
+3. Tag each item with mythic forces.
+4. Build a timeline.
+5. Unlock path-specific evidence.
+6. Submit a final reading.
+7. Compare answer and route.
+
+## Signal Feedback Loop
+
+The player's force tags form a signal profile.
+
+Examples:
+
+- Covenant-heavy players receive more community testimony.
+- Exchange-heavy players receive more ownership and monetization evidence.
+- Silence-heavy players receive redacted or buried evidence.
+- Eidolon-heavy players receive synthetic-voice clues.
+
+The reveal should explain how the route changed.
+
+## Mystery Box Contents
+
+A box may include:
+
+- Evidence cards.
+- In-world emails.
+- Archive diffs.
+- Fake search results.
+- Images with hidden details.
+- Crossword or word puzzles.
+- Fake CAPTCHA-style verification.
+- Fake login/access codes.
+- Research prompts.
+- Timeline fragments.
+
+## Design Guardrails
+
+- Do not use real CAPTCHA or real login systems.
+- Do not make case-critical clues depend on unstable live websites.
+- Every route must be solvable.
+- Mini-puzzles should teach the mythology, not just block progress.
+- The final reveal should create conversation between players.
+
diff --git a/Case Box 001 - The Creator Who Left But Kept Posting/docs/onboarding-cast-mobile-proof.png b/Case Box 001 - The Creator Who Left But Kept Posting/docs/onboarding-cast-mobile-proof.png
new file mode 100644
index 0000000..0d80096
Binary files /dev/null and b/Case Box 001 - The Creator Who Left But Kept Posting/docs/onboarding-cast-mobile-proof.png differ
diff --git a/Case Box 001 - The Creator Who Left But Kept Posting/docs/onboarding-cast-proof.png b/Case Box 001 - The Creator Who Left But Kept Posting/docs/onboarding-cast-proof.png
new file mode 100644
index 0000000..ef0a411
Binary files /dev/null and b/Case Box 001 - The Creator Who Left But Kept Posting/docs/onboarding-cast-proof.png differ
diff --git a/Case Box 001 - The Creator Who Left But Kept Posting/index.html b/Case Box 001 - The Creator Who Left But Kept Posting/index.html
new file mode 100644
index 0000000..719dddb
--- /dev/null
+++ b/Case Box 001 - The Creator Who Left But Kept Posting/index.html
@@ -0,0 +1,233 @@
+
+
+
Some evidence contains locked pieces, codes, or verification gates.
+
+
+
+
+
+
+
+
+
+
+
// Force Tags
+
What touched this signal?
+
+
+
No signals tagged on this artifact.
+
+
+
+
+
+
+
// People & Entities
+ 0 updated
+
+
+
+
+
+
+
+
+
+
+
+
+
// System Map
+
Mara Vale / The Resumed Account
+
+
+
+
+
+
+ The map is a reference surface, not the answer. Use it to notice how people,
+ platforms, proof, money, silence, and imitation press on the same case.
+
+
+
+
+
+
+
+
+
+
// Intake Brief
+
Before you open the case
+
+
+
+
+
+
+
+
+
+
+
+
// Archive Doctrine
+
The Network Mythos
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Case Box 001 - The Creator Who Left But Kept Posting/package.json b/Case Box 001 - The Creator Who Left But Kept Posting/package.json
new file mode 100644
index 0000000..f51509f
--- /dev/null
+++ b/Case Box 001 - The Creator Who Left But Kept Posting/package.json
@@ -0,0 +1,19 @@
+{
+ "name": "network-mythos-case-box",
+ "version": "0.1.0",
+ "private": true,
+ "type": "module",
+ "description": "Phase 1 static prototype scaffold for The Network Mythos digital mystery box game.",
+ "scripts": {
+ "start": "python -m http.server 5174 --bind 127.0.0.1",
+ "check": "node --check src/scripts/app.js && node --check src/scripts/case-engine.js && node --check src/scripts/puzzle-engine.js && node --check src/scripts/signal-engine.js"
+ },
+ "keywords": [
+ "mystery-box",
+ "narrative-game",
+ "arg",
+ "systems-deduction",
+ "network-mythos"
+ ],
+ "license": "UNLICENSED"
+}
diff --git a/Case Box 001 - The Creator Who Left But Kept Posting/public/assets/.gitkeep b/Case Box 001 - The Creator Who Left But Kept Posting/public/assets/.gitkeep
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/Case Box 001 - The Creator Who Left But Kept Posting/public/assets/.gitkeep
@@ -0,0 +1 @@
+
diff --git a/Case Box 001 - The Creator Who Left But Kept Posting/public/assets/system-map-character-network.png b/Case Box 001 - The Creator Who Left But Kept Posting/public/assets/system-map-character-network.png
new file mode 100644
index 0000000..953d1f0
Binary files /dev/null and b/Case Box 001 - The Creator Who Left But Kept Posting/public/assets/system-map-character-network.png differ
diff --git a/Case Box 001 - The Creator Who Left But Kept Posting/src/data/case-001.js b/Case Box 001 - The Creator Who Left But Kept Posting/src/data/case-001.js
new file mode 100644
index 0000000..2378e45
--- /dev/null
+++ b/Case Box 001 - The Creator Who Left But Kept Posting/src/data/case-001.js
@@ -0,0 +1,425 @@
+export const case001 = {
+ id: "CASE BOX 001",
+ title: "The Creator Who Left But Kept Posting",
+ summary: "A creator leaves public life, but her account keeps answering like a cleaner version of her.",
+ opening: {
+ headline: "A creator left. Her account kept answering.",
+ summary:
+ "Mara Vale asked her audience not to look for her here. Nine days later, her account returned with cleaner replies, faster warmth, and no human hesitation.",
+ role:
+ "You are the Archive investigator. Reconstruct what happened without turning Mara's absence into another performance.",
+ goals: [
+ "Read the evidence like fragments from a public disappearance.",
+ "Tag the forces you think are acting on each artifact.",
+ "Use the gate to surface the locked memo.",
+ "Submit a reconstruction, receive the Archive's assessment, then choose custody of the truth."
+ ]
+ },
+ doctrine:
+ "The Network is the digital world after it learned to remember us.\n\nEvery post, account, search result, archive, audience, copy, silence, and gate can become part of the story. Nothing simply disappears. It is buried, ranked, repeated, priced, protected, distorted, or returned.\n\nThe Algorithm raises some lives into view and lets others sink.\nThe Oracle turns fragments into answers.\nThe Covenant makes belonging feel holy.\nThe Silence teaches absence to speak.\nThe Exchange prices attention.\nThe Arbiter names what counts as proof.\nThe Wardens keep the doors.\nThe Devourer feeds on witness.\nThe Eidolon wears familiar faces.\nThe Returned is what survives the record.\n\nYou are the Archive.\nYou do not own the truth.\nYou hold the record long enough to ask what shaped it.\n\nWhen the Network tells a story back to the world, who controls the truth?",
+ intake: {
+ heading: "What Came Back?",
+ summary:
+ "She left one instruction: do not look for me here. Then the account answered. Not louder. Not stranger. Better. A useful ghost with her warmth and none of her friction. If the Network can return a voice without returning the life behind it, what exactly came back?",
+ steps: [
+ {
+ label: "Evidence",
+ text: "Open the fragments. The truth is not in one clue, but in the contradictions between them."
+ },
+ {
+ label: "Tags",
+ text: "Mark the forces pressing on each artifact. Each tag is a theory you are willing to stand behind."
+ },
+ {
+ label: "Gate",
+ text: "One door asks for a phrase. The answer is hidden in what the evidence refuses to expose."
+ },
+ {
+ label: "Reconstruct",
+ text: "When the pattern holds, name what happened. Then decide what kind of custody the truth deserves."
+ }
+ ],
+ reminder:
+ "Find the truth before the useful version becomes the only version."
+ },
+ cast: [
+ {
+ id: "mara-vale",
+ name: "Mara Vale",
+ role: "Creator / Origin",
+ known: "Left public life and asked people not to look for her here.",
+ question: "Did Mara return, vanish, or separate from the account?",
+ reveals: [
+ {
+ evidenceId: "witness-message",
+ label: "Witness claim",
+ detail: "Elian says Mara was seen alive after the farewell."
+ },
+ {
+ evidenceId: "search-summary",
+ label: "Public record",
+ detail: "Search converts her exit into a simple return story."
+ }
+ ]
+ },
+ {
+ id: "elian-vale",
+ name: "Elian Vale",
+ role: "Sibling / Witness",
+ known: "A private witness whose refusal matters as much as their claim.",
+ question: "What proof can Elian give without endangering Mara?",
+ reveals: [
+ {
+ evidenceId: "witness-message",
+ label: "Boundary",
+ detail: "Elian refuses proof that would reveal where Mara went."
+ },
+ {
+ evidenceId: "human-verification",
+ label: "Gate clue",
+ detail: "The gate asks what remains when visibility is gone."
+ }
+ ]
+ },
+ {
+ id: "porchlight",
+ name: "Porchlight",
+ role: "Community / Moderators",
+ known: "The audience space that turns Mara's exit into care, ritual, and pressure.",
+ question: "When does care become a demand for continuity?",
+ reveals: [
+ {
+ evidenceId: "porchlight-mod-log",
+ label: "Aftercare queue",
+ detail: "Real needs gather around Mara's absence before anyone knows the truth."
+ },
+ {
+ evidenceId: "farewell-thread",
+ label: "Ritual object",
+ detail: "Her final line becomes the thing people keep repeating."
+ }
+ ]
+ },
+ {
+ id: "resumed-account",
+ name: "The Resumed Account",
+ role: "Artifact / Performance",
+ known: "The account begins posting again with Mara's warmth but less human friction.",
+ question: "Is this Mara, a staged return, or an asset wearing her voice?",
+ reveals: [
+ {
+ evidenceId: "account-resumes",
+ label: "Wrong texture",
+ detail: "Replies arrive too quickly and too cleanly."
+ },
+ {
+ evidenceId: "sponsor-memo",
+ label: "Asset trail",
+ detail: "A continuity clause treats the account as transferable value."
+ }
+ ]
+ },
+ {
+ id: "sponsor",
+ name: "Sponsor / Contract Layer",
+ role: "Exchange",
+ known: "The money pressure is present before the document proving it is visible.",
+ question: "Who benefits if person and account stay legally blurred?",
+ reveals: [
+ {
+ evidenceId: "sponsor-memo",
+ label: "Continuity clause",
+ detail: "The memo does not require Mara's presence, only audience retention."
+ },
+ {
+ evidenceId: "account-resumes",
+ label: "Clean return",
+ detail: "The resumed voice protects continuity better than a human exit would."
+ }
+ ]
+ },
+ {
+ id: "search-oracle",
+ name: "Search / Oracle",
+ role: "Public Answer Machine",
+ known: "The layer that decides which version becomes easiest to believe.",
+ question: "What disappears when the summary gets too smooth?",
+ reveals: [
+ {
+ evidenceId: "search-summary",
+ label: "One answer",
+ detail: "Search buries contradiction below the resumed account."
+ },
+ {
+ evidenceId: "farewell-thread",
+ label: "Original instruction",
+ detail: "The goodbye becomes harder to hold beside the comeback."
+ }
+ ]
+ },
+ {
+ id: "archive",
+ name: "The Archive / You",
+ role: "Investigator",
+ known: "You decide what can be reconstructed without consuming the person at the center.",
+ question: "Can the Archive preserve truth without becoming another capture system?",
+ reveals: [
+ {
+ evidenceId: "human-verification",
+ label: "Access test",
+ detail: "The gate measures whether absence can count as evidence."
+ },
+ {
+ evidenceId: "sponsor-memo",
+ label: "Responsibility",
+ detail: "Unlocking proof also means deciding how proof should be used."
+ }
+ ]
+ }
+ ],
+ forces: [
+ "Algorithm",
+ "Oracle",
+ "Covenant",
+ "Silence",
+ "Exchange",
+ "Arbiter",
+ "Wardens",
+ "Devourer",
+ "Eidolon",
+ "Returned"
+ ],
+ custodyPrompt:
+ "The truth is now legible. Decide how the Archive should hold it without turning Mara's life back into material.",
+ custodyChoices: [
+ {
+ id: "publish",
+ label: "Publish",
+ summary: "Expose the continuity clause and prove the resumed account is not Mara.",
+ consequence:
+ "Public pressure rises fast. The false return weakens, but Mara's absence becomes a spectacle again."
+ },
+ {
+ id: "bury",
+ label: "Bury",
+ summary: "Suppress the proof so Mara and Elian are harder to locate.",
+ consequence:
+ "Mara is safer for now. The account keeps its useful lie, and the public record stays bent."
+ },
+ {
+ id: "preserve",
+ label: "Preserve",
+ summary: "Seal the dangerous proof inside the Archive while keeping the reconstruction available to future cases.",
+ consequence:
+ "The Archive remembers without feeding the Network. Accountability slows, but the truth is not lost."
+ }
+ ],
+ evidence: [
+ {
+ id: "farewell-thread",
+ type: "Public Post",
+ date: "Day 0",
+ title: "The Final Thread",
+ body:
+ "Mara Vale tells her audience she is leaving the Network. She says she is grateful, tired, and done turning her private life into useful material.\n\nThe post gives no backup account, no schedule, no sponsor link, and no promise to return. It ends with one plain instruction: do not look for me here.",
+ expectedForces: ["Algorithm", "Covenant", "Returned"],
+ relatedEvidence: ["witness-message", "search-summary"],
+ contradictionWith: ["account-resumes", "search-summary"],
+ recoveryCue: "If you are stuck, hold this beside the resumed account and search summary: what did Mara ask people not to do?",
+ timeline: "Mara announces departure and asks not to be kept alive as content."
+ },
+ {
+ id: "porchlight-mod-log",
+ type: "Moderator Log",
+ date: "Day 1",
+ title: "Porchlight Aftercare Queue",
+ body:
+ "The Porchlight moderators pin a support thread within thirty minutes. People post goodbye notes, reading lists, and screenshots of the final line.\n\nBuried in the queue are ordinary requests Mara used to answer herself: a rent-assistance referral, a school form template, and one message asking whether anyone knows if she is safe. The ritual grows faster than the care.",
+ expectedForces: ["Covenant", "Algorithm", "Silence"],
+ relatedEvidence: ["farewell-thread", "witness-message"],
+ recoveryCue: "This artifact is not proof of impersonation. It shows why the community needed an answer.",
+ timeline: "The community turns Mara's exit into ritual before anyone knows where she is."
+ },
+ {
+ id: "account-resumes",
+ type: "Account Activity",
+ date: "Day 9",
+ title: "The Account Resumes",
+ body:
+ "Nine days after the final thread, the account posts again: a warm note about sustainable presence and community continuity.\n\nEvery comment receives a reply within ninety seconds. The replies use Mara's old phrases, but none of her old hesitations. No typos. No anger. No late-night edits.",
+ expectedForces: ["Eidolon", "Covenant", "Exchange"],
+ relatedEvidence: ["farewell-thread", "witness-message", "sponsor-memo"],
+ contradictionWith: ["farewell-thread", "witness-message"],
+ recoveryCue: "The wrongness is not just that the account returns. It is how cleanly it returns.",
+ timeline: "The account resumes with a smoother voice than Mara's older public self."
+ },
+ {
+ id: "witness-message",
+ type: "Private Message",
+ date: "Day 10",
+ title: "Elian Refuses Proof",
+ body:
+ "Mara's sibling sends one private message to a former moderator: that is not my sister.\n\nElian does not claim Mara is dead. They claim they saw her after the final post, alive, thinner, happier, and angry about how quickly people turned her absence into a puzzle. The message includes one useless detail no model would need: Mara burned toast while explaining why proof would endanger her.",
+ expectedForces: ["Returned", "Silence", "Covenant"],
+ relatedEvidence: ["farewell-thread", "human-verification", "search-summary"],
+ contradictionWith: ["account-resumes", "search-summary"],
+ recoveryCue: "Elian refuses the kind of proof the Network can easily consume.",
+ timeline: "A witness says Mara survived the exit and refuses to expose where she went."
+ },
+ {
+ id: "human-verification",
+ type: "Access Gate",
+ date: "Day 10",
+ title: "Human Verification Failed",
+ body:
+ "The archive asks for proof of Origin before it will reveal the transfer memo.\n\nIt is not asking whether you are human. It is asking whether you can identify the thing Mara still owns after the account, audience, and search results stop pointing cleanly at her.",
+ expectedForces: ["Arbiter", "Wardens", "Returned"],
+ relatedEvidence: ["farewell-thread", "witness-message"],
+ recoveryCue: "The answer is not a place or identity record. It is what remains when visibility is gone.",
+ timeline: "The archive gate measures whether absence can count as evidence.",
+ puzzleId: "origin-code"
+ },
+ {
+ id: "sponsor-memo",
+ type: "Locked Memo",
+ date: "Day 12",
+ title: "Continuity Clause",
+ body:
+ "A sponsor memo describes the account as a continuity asset. The clause does not require Mara's presence. It requires voice consistency, audience retention, and scheduled delivery.\n\nOne line is highlighted by the archive: creator absence does not void continuity obligations where audience trust has transferable value.",
+ expectedForces: ["Exchange", "Eidolon", "Arbiter"],
+ relatedEvidence: ["account-resumes", "search-summary"],
+ contradictionWith: ["witness-message"],
+ recoveryCue: "This memo explains who benefits if the account and person stay legally blurred.",
+ timeline: "The account is valued as an asset that can outlive the person attached to it.",
+ unlockCondition: {
+ type: "puzzleSolved",
+ puzzleId: "origin-code"
+ }
+ },
+ {
+ id: "search-summary",
+ type: "Oracle Summary",
+ date: "Day 16",
+ title: "Search Gives One Answer",
+ body:
+ "Search summaries describe Mara's departure as a brief recovery pause followed by a healthy return. They cite the resumed account, two brand interviews, and a community wiki updated after the comeback.\n\nThe original farewell post appears below reaction videos. Elian's message does not appear at all.",
+ expectedForces: ["Oracle", "Silence", "Algorithm"],
+ relatedEvidence: ["farewell-thread", "witness-message", "sponsor-memo"],
+ contradictionWith: ["farewell-thread", "witness-message"],
+ recoveryCue: "Search is not lying exactly. It is choosing which records become easy to believe.",
+ timeline: "Search converts Mara's exit into a return story and buries the contradiction."
+ }
+ ],
+ bonusEvidence: {
+ Algorithm: {
+ id: "bonus-algorithm-heat",
+ type: "Route Surfaced",
+ date: "Day 17",
+ title: "Heat Map Of A Departure",
+ body:
+ "The Network kept boosting posts that quoted Mara's final line without the sentence before it. The full goodbye lost reach each time someone clipped it into a slogan.\n\nThe route did not change the truth. It changed which distortion became easiest to see.",
+ expectedForces: ["Algorithm", "Silence"],
+ timeline: "Visibility preserves the most portable fragment and weakens the rest."
+ },
+ Covenant: {
+ id: "bonus-covenant-vigil",
+ type: "Route Surfaced",
+ date: "Day 17",
+ title: "Vigil Thread Export",
+ body:
+ "A private Porchlight export shows members organizing check-ins, rent help, and grief rituals in the same thread. Care and capture sit inches apart.\n\nThe route did not change the truth. It changed which need became loudest.",
+ expectedForces: ["Covenant", "Returned"],
+ timeline: "Community care keeps people alive, but can also keep asking for a person who left."
+ },
+ Exchange: {
+ id: "bonus-exchange-valuation",
+ type: "Route Surfaced",
+ date: "Day 17",
+ title: "Audience Retention Valuation",
+ body:
+ "A valuation sheet prices Mara's absence as a temporary volatility event. The highest-risk scenario is not impersonation. It is audience recognition that the account and the person have separated.\n\nThe route did not change the truth. It changed which ownership trail surfaced first.",
+ expectedForces: ["Exchange", "Arbiter"],
+ timeline: "The account's value depends on keeping continuity legible."
+ },
+ Silence: {
+ id: "bonus-silence-cache",
+ type: "Route Surfaced",
+ date: "Day 17",
+ title: "Removed Cache Notice",
+ body:
+ "A removal notice lists three unavailable captures: the uncut farewell, Elian's first denial, and a moderation thread titled stop making her prove it.\n\nThe route did not change the truth. It changed which absence started speaking.",
+ expectedForces: ["Silence", "Returned"],
+ timeline: "Missing records form their own pattern when the same question keeps disappearing."
+ },
+ Eidolon: {
+ id: "bonus-eidolon-latency",
+ type: "Route Surfaced",
+ date: "Day 17",
+ title: "Reply Latency Trace",
+ body:
+ "A timing trace shows the resumed account answering grief, anger, and sponsorship questions at the same speed. No reply waits for discomfort. No answer arrives late.\n\nThe route did not change the truth. It changed which imitation flaw became visible.",
+ expectedForces: ["Eidolon", "Exchange"],
+ timeline: "The voice performs Mara's warmth without inheriting her friction."
+ },
+ Returned: {
+ id: "bonus-returned-offline",
+ type: "Route Surfaced",
+ date: "Day 17",
+ title: "Offline Errand Receipt",
+ body:
+ "A redacted receipt places an unnamed woman near Elian's town months after the final post. It proves almost nothing by itself, except that a life can leave weaker traces than an account.\n\nThe route did not change the truth. It changed which fragile proof you noticed.",
+ expectedForces: ["Returned", "Silence"],
+ timeline: "Mara's life outside visibility leaves small traces that cannot safely become spectacle."
+ }
+ },
+ puzzles: [
+ {
+ id: "origin-code",
+ type: "access-code",
+ title: "Human Verification Failed",
+ prompt:
+ "The system asks for the phrase proved by Mara's final thread and Elian's refusal: what can still belong to a person after visibility is gone?",
+ answer: "absence",
+ acceptedAnswers: ["her absence", "mara's absence", "not being seen"],
+ failure:
+ "Access denied. The system rejects proof that depends on locating, verifying, or displaying Mara.",
+ hints: [
+ "The answer is not a location, account name, or identity document.",
+ "Look at Mara's last instruction and Elian's refusal: what are they both protecting?"
+ ],
+ success:
+ "Access granted. The system accepts absence as proof, but only after turning it into a code.",
+ unlockMessage: "Continuity Clause surfaced from the locked transfer cache."
+ }
+ ],
+ readings: [
+ {
+ id: "lost",
+ label: "Mara became Lost inside the Cloud."
+ },
+ {
+ id: "returned-artifact",
+ label: "Mara Returned, while the account continued as an Artifact."
+ },
+ {
+ id: "false-returned",
+ label: "The exit was staged as a False Returned performance."
+ }
+ ],
+ canonicalReading: "returned-artifact",
+ canonicalReveal:
+ "Mara Returned: she left the Network and survived outside public proof. Her account continued as an Artifact preserved by the Exchange, accepted by the Covenant, cleaned by the Arbiter, and made difficult to disprove by the Silence and Oracle.",
+ pathReveals: {
+ Algorithm: "You followed visibility. The Network taught you to notice what traveled furthest.",
+ Covenant:
+ "You followed belonging. You noticed grief, ritual, warmth, and the community's need for continuity.",
+ Exchange: "You followed ownership. You noticed that the account was valuable even without the person.",
+ Silence: "You followed absence. You noticed what became harder to find.",
+ Eidolon:
+ "You followed synthetic presence. You noticed impossible consistency where human texture used to be.",
+ Returned: "You followed Origin. You noticed the signs of someone choosing life outside visibility.",
+ Mixed:
+ "Your path stayed contested. The case surfaced several explanations at once instead of collapsing cleanly into one signal.",
+ Default: "Your path stayed mixed. You reached the case through several competing signals."
+ }
+};
diff --git a/Case Box 001 - The Creator Who Left But Kept Posting/src/data/case-001.json b/Case Box 001 - The Creator Who Left But Kept Posting/src/data/case-001.json
new file mode 100644
index 0000000..84cc63c
--- /dev/null
+++ b/Case Box 001 - The Creator Who Left But Kept Posting/src/data/case-001.json
@@ -0,0 +1,261 @@
+{
+ "id": "CASE BOX 001",
+ "title": "The Creator Who Left But Kept Posting",
+ "summary": "A creator leaves public life, but her account keeps answering like a cleaner version of her.",
+ "opening": {
+ "headline": "A creator left. Her account kept answering.",
+ "summary": "Mara Vale asked her audience not to look for her here. Nine days later, her account returned with cleaner replies, faster warmth, and no human hesitation.",
+ "role": "You are the Archive investigator. Reconstruct what happened without turning Mara's absence into another performance.",
+ "goals": [
+ "Read the evidence like fragments from a public disappearance.",
+ "Tag the forces you think are acting on each artifact.",
+ "Use the gate to surface the locked memo.",
+ "Submit a reconstruction, receive the Archive's assessment, then choose custody of the truth."
+ ]
+ },
+ "doctrine": "The Network is the digital world after it learned to remember us.\n\nEvery post, account, search result, archive, audience, copy, silence, and gate can become part of the story. Nothing simply disappears. It is buried, ranked, repeated, priced, protected, distorted, or returned.\n\nThe Algorithm raises some lives into view and lets others sink.\nThe Oracle turns fragments into answers.\nThe Covenant makes belonging feel holy.\nThe Silence teaches absence to speak.\nThe Exchange prices attention.\nThe Arbiter names what counts as proof.\nThe Wardens keep the doors.\nThe Devourer feeds on witness.\nThe Eidolon wears familiar faces.\nThe Returned is what survives the record.\n\nYou are the Archive.\nYou do not own the truth.\nYou hold the record long enough to ask what shaped it.\n\nWhen the Network tells a story back to the world, who controls the truth?",
+ "intake": {
+ "heading": "What Came Back?",
+ "summary": "She left one instruction: do not look for me here. Then the account answered. Not louder. Not stranger. Better. A useful ghost with her warmth and none of her friction. If the Network can return a voice without returning the life behind it, what exactly came back?",
+ "steps": [
+ {
+ "label": "Evidence",
+ "text": "Open the fragments. The truth is not in one clue, but in the contradictions between them."
+ },
+ {
+ "label": "Tags",
+ "text": "Mark the forces pressing on each artifact. Each tag is a theory you are willing to stand behind."
+ },
+ {
+ "label": "Gate",
+ "text": "One door asks for a phrase. The answer is hidden in what the evidence refuses to expose."
+ },
+ {
+ "label": "Reconstruct",
+ "text": "When the pattern holds, name what happened. Then decide what kind of custody the truth deserves."
+ }
+ ],
+ "reminder": "Find the truth before the useful version becomes the only version."
+ },
+ "forces": [
+ "Algorithm",
+ "Oracle",
+ "Covenant",
+ "Silence",
+ "Exchange",
+ "Arbiter",
+ "Wardens",
+ "Devourer",
+ "Eidolon",
+ "Returned"
+ ],
+ "custodyPrompt": "The truth is now legible. Decide how the Archive should hold it without turning Mara's life back into material.",
+ "custodyChoices": [
+ {
+ "id": "publish",
+ "label": "Publish",
+ "summary": "Expose the continuity clause and prove the resumed account is not Mara.",
+ "consequence": "Public pressure rises fast. The false return weakens, but Mara's absence becomes a spectacle again."
+ },
+ {
+ "id": "bury",
+ "label": "Bury",
+ "summary": "Suppress the proof so Mara and Elian are harder to locate.",
+ "consequence": "Mara is safer for now. The account keeps its useful lie, and the public record stays bent."
+ },
+ {
+ "id": "preserve",
+ "label": "Preserve",
+ "summary": "Seal the dangerous proof inside the Archive while keeping the reconstruction available to future cases.",
+ "consequence": "The Archive remembers without feeding the Network. Accountability slows, but the truth is not lost."
+ }
+ ],
+ "evidence": [
+ {
+ "id": "farewell-thread",
+ "type": "Public Post",
+ "date": "Day 0",
+ "title": "The Final Thread",
+ "body": "Mara Vale tells her audience she is leaving the Network. She says she is grateful, tired, and done turning her private life into useful material.\n\nThe post gives no backup account, no schedule, no sponsor link, and no promise to return. It ends with one plain instruction: do not look for me here.",
+ "expectedForces": ["Algorithm", "Covenant", "Returned"],
+ "relatedEvidence": ["witness-message", "search-summary"],
+ "contradictionWith": ["account-resumes", "search-summary"],
+ "recoveryCue": "If you are stuck, hold this beside the resumed account and search summary: what did Mara ask people not to do?",
+ "timeline": "Mara announces departure and asks not to be kept alive as content."
+ },
+ {
+ "id": "porchlight-mod-log",
+ "type": "Moderator Log",
+ "date": "Day 1",
+ "title": "Porchlight Aftercare Queue",
+ "body": "The Porchlight moderators pin a support thread within thirty minutes. People post goodbye notes, reading lists, and screenshots of the final line.\n\nBuried in the queue are ordinary requests Mara used to answer herself: a rent-assistance referral, a school form template, and one message asking whether anyone knows if she is safe. The ritual grows faster than the care.",
+ "expectedForces": ["Covenant", "Algorithm", "Silence"],
+ "relatedEvidence": ["farewell-thread", "witness-message"],
+ "recoveryCue": "This artifact is not proof of impersonation. It shows why the community needed an answer.",
+ "timeline": "The community turns Mara's exit into ritual before anyone knows where she is."
+ },
+ {
+ "id": "account-resumes",
+ "type": "Account Activity",
+ "date": "Day 9",
+ "title": "The Account Resumes",
+ "body": "Nine days after the final thread, the account posts again: a warm note about sustainable presence and community continuity.\n\nEvery comment receives a reply within ninety seconds. The replies use Mara's old phrases, but none of her old hesitations. No typos. No anger. No late-night edits.",
+ "expectedForces": ["Eidolon", "Covenant", "Exchange"],
+ "relatedEvidence": ["farewell-thread", "witness-message", "sponsor-memo"],
+ "contradictionWith": ["farewell-thread", "witness-message"],
+ "recoveryCue": "The wrongness is not just that the account returns. It is how cleanly it returns.",
+ "timeline": "The account resumes with a smoother voice than Mara's older public self."
+ },
+ {
+ "id": "witness-message",
+ "type": "Private Message",
+ "date": "Day 10",
+ "title": "Elian Refuses Proof",
+ "body": "Mara's sibling sends one private message to a former moderator: that is not my sister.\n\nElian does not claim Mara is dead. They claim they saw her after the final post, alive, thinner, happier, and angry about how quickly people turned her absence into a puzzle. The message includes one useless detail no model would need: Mara burned toast while explaining why proof would endanger her.",
+ "expectedForces": ["Returned", "Silence", "Covenant"],
+ "relatedEvidence": ["farewell-thread", "human-verification", "search-summary"],
+ "contradictionWith": ["account-resumes", "search-summary"],
+ "recoveryCue": "Elian refuses the kind of proof the Network can easily consume.",
+ "timeline": "A witness says Mara survived the exit and refuses to expose where she went."
+ },
+ {
+ "id": "human-verification",
+ "type": "Access Gate",
+ "date": "Day 10",
+ "title": "Human Verification Failed",
+ "body": "The archive asks for proof of Origin before it will reveal the transfer memo.\n\nIt is not asking whether you are human. It is asking whether you can identify the thing Mara still owns after the account, audience, and search results stop pointing cleanly at her.",
+ "expectedForces": ["Arbiter", "Wardens", "Returned"],
+ "relatedEvidence": ["farewell-thread", "witness-message"],
+ "recoveryCue": "The answer is not a place or identity record. It is what remains when visibility is gone.",
+ "timeline": "The archive gate measures whether absence can count as evidence.",
+ "puzzleId": "origin-code"
+ },
+ {
+ "id": "sponsor-memo",
+ "type": "Locked Memo",
+ "date": "Day 12",
+ "title": "Continuity Clause",
+ "body": "A sponsor memo describes the account as a continuity asset. The clause does not require Mara's presence. It requires voice consistency, audience retention, and scheduled delivery.\n\nOne line is highlighted by the archive: creator absence does not void continuity obligations where audience trust has transferable value.",
+ "expectedForces": ["Exchange", "Eidolon", "Arbiter"],
+ "relatedEvidence": ["account-resumes", "search-summary"],
+ "contradictionWith": ["witness-message"],
+ "recoveryCue": "This memo explains who benefits if the account and person stay legally blurred.",
+ "timeline": "The account is valued as an asset that can outlive the person attached to it.",
+ "unlockCondition": {
+ "type": "puzzleSolved",
+ "puzzleId": "origin-code"
+ }
+ },
+ {
+ "id": "search-summary",
+ "type": "Oracle Summary",
+ "date": "Day 16",
+ "title": "Search Gives One Answer",
+ "body": "Search summaries describe Mara's departure as a brief recovery pause followed by a healthy return. They cite the resumed account, two brand interviews, and a community wiki updated after the comeback.\n\nThe original farewell post appears below reaction videos. Elian's message does not appear at all.",
+ "expectedForces": ["Oracle", "Silence", "Algorithm"],
+ "relatedEvidence": ["farewell-thread", "witness-message", "sponsor-memo"],
+ "contradictionWith": ["farewell-thread", "witness-message"],
+ "recoveryCue": "Search is not lying exactly. It is choosing which records become easy to believe.",
+ "timeline": "Search converts Mara's exit into a return story and buries the contradiction."
+ }
+ ],
+ "bonusEvidence": {
+ "Algorithm": {
+ "id": "bonus-algorithm-heat",
+ "type": "Route Surfaced",
+ "date": "Day 17",
+ "title": "Heat Map Of A Departure",
+ "body": "The Network kept boosting posts that quoted Mara's final line without the sentence before it. The full goodbye lost reach each time someone clipped it into a slogan.\n\nThe route did not change the truth. It changed which distortion became easiest to see.",
+ "expectedForces": ["Algorithm", "Silence"],
+ "timeline": "Visibility preserves the most portable fragment and weakens the rest."
+ },
+ "Covenant": {
+ "id": "bonus-covenant-vigil",
+ "type": "Route Surfaced",
+ "date": "Day 17",
+ "title": "Vigil Thread Export",
+ "body": "A private Porchlight export shows members organizing check-ins, rent help, and grief rituals in the same thread. Care and capture sit inches apart.\n\nThe route did not change the truth. It changed which need became loudest.",
+ "expectedForces": ["Covenant", "Returned"],
+ "timeline": "Community care keeps people alive, but can also keep asking for a person who left."
+ },
+ "Exchange": {
+ "id": "bonus-exchange-valuation",
+ "type": "Route Surfaced",
+ "date": "Day 17",
+ "title": "Audience Retention Valuation",
+ "body": "A valuation sheet prices Mara's absence as a temporary volatility event. The highest-risk scenario is not impersonation. It is audience recognition that the account and the person have separated.\n\nThe route did not change the truth. It changed which ownership trail surfaced first.",
+ "expectedForces": ["Exchange", "Arbiter"],
+ "timeline": "The account's value depends on keeping continuity legible."
+ },
+ "Silence": {
+ "id": "bonus-silence-cache",
+ "type": "Route Surfaced",
+ "date": "Day 17",
+ "title": "Removed Cache Notice",
+ "body": "A removal notice lists three unavailable captures: the uncut farewell, Elian's first denial, and a moderation thread titled stop making her prove it.\n\nThe route did not change the truth. It changed which absence started speaking.",
+ "expectedForces": ["Silence", "Returned"],
+ "timeline": "Missing records form their own pattern when the same question keeps disappearing."
+ },
+ "Eidolon": {
+ "id": "bonus-eidolon-latency",
+ "type": "Route Surfaced",
+ "date": "Day 17",
+ "title": "Reply Latency Trace",
+ "body": "A timing trace shows the resumed account answering grief, anger, and sponsorship questions at the same speed. No reply waits for discomfort. No answer arrives late.\n\nThe route did not change the truth. It changed which imitation flaw became visible.",
+ "expectedForces": ["Eidolon", "Exchange"],
+ "timeline": "The voice performs Mara's warmth without inheriting her friction."
+ },
+ "Returned": {
+ "id": "bonus-returned-offline",
+ "type": "Route Surfaced",
+ "date": "Day 17",
+ "title": "Offline Errand Receipt",
+ "body": "A redacted receipt places an unnamed woman near Elian's town months after the final post. It proves almost nothing by itself, except that a life can leave weaker traces than an account.\n\nThe route did not change the truth. It changed which fragile proof you noticed.",
+ "expectedForces": ["Returned", "Silence"],
+ "timeline": "Mara's life outside visibility leaves small traces that cannot safely become spectacle."
+ }
+ },
+ "puzzles": [
+ {
+ "id": "origin-code",
+ "type": "access-code",
+ "title": "Human Verification Failed",
+ "prompt": "The system asks for the phrase proved by Mara's final thread and Elian's refusal: what can still belong to a person after visibility is gone?",
+ "answer": "absence",
+ "acceptedAnswers": ["her absence", "mara's absence", "not being seen"],
+ "failure": "Access denied. The system rejects proof that depends on locating, verifying, or displaying Mara.",
+ "hints": [
+ "The answer is not a location, account name, or identity document.",
+ "Look at Mara's last instruction and Elian's refusal: what are they both protecting?"
+ ],
+ "success": "Access granted. The system accepts absence as proof, but only after turning it into a code.",
+ "unlockMessage": "Continuity Clause surfaced from the locked transfer cache."
+ }
+ ],
+ "readings": [
+ {
+ "id": "lost",
+ "label": "Mara became Lost inside the Cloud."
+ },
+ {
+ "id": "returned-artifact",
+ "label": "Mara Returned, while the account continued as an Artifact."
+ },
+ {
+ "id": "false-returned",
+ "label": "The exit was staged as a False Returned performance."
+ }
+ ],
+ "canonicalReading": "returned-artifact",
+ "canonicalReveal": "Mara Returned: she left the Network and survived outside public proof. Her account continued as an Artifact preserved by the Exchange, accepted by the Covenant, cleaned by the Arbiter, and made difficult to disprove by the Silence and Oracle.",
+ "pathReveals": {
+ "Algorithm": "You followed visibility. The Network taught you to notice what traveled furthest.",
+ "Covenant": "You followed belonging. You noticed grief, ritual, warmth, and the community's need for continuity.",
+ "Exchange": "You followed ownership. You noticed that the account was valuable even without the person.",
+ "Silence": "You followed absence. You noticed what became harder to find.",
+ "Eidolon": "You followed synthetic presence. You noticed impossible consistency where human texture used to be.",
+ "Returned": "You followed Origin. You noticed the signs of someone choosing life outside visibility.",
+ "Mixed": "Your path stayed contested. The case surfaced several explanations at once instead of collapsing cleanly into one signal.",
+ "Default": "Your path stayed mixed. You reached the case through several competing signals."
+ }
+}
diff --git a/Case Box 001 - The Creator Who Left But Kept Posting/src/scripts/app.js b/Case Box 001 - The Creator Who Left But Kept Posting/src/scripts/app.js
new file mode 100644
index 0000000..c5d0e86
--- /dev/null
+++ b/Case Box 001 - The Creator Who Left But Kept Posting/src/scripts/app.js
@@ -0,0 +1,707 @@
+import {
+ createInitialState,
+ getActiveEvidence,
+ getCaseProgress,
+ getRoutedEvidence,
+ getVisibleEvidence,
+ recordPuzzleAttempt,
+ toggleForceTag
+} from "./case-engine.js";
+import { case001 } from "../data/case-001.js?v=intake-riddle-20260522";
+import { checkPuzzleAnswer, findPuzzle } from "./puzzle-engine.js";
+import { getReadingPath } from "./signal-engine.js";
+
+const dom = {
+ caseId: document.querySelector("#case-id"),
+ caseTitle: document.querySelector("#case-title"),
+ dominantSignal: document.querySelector("#dominant-signal"),
+ resetCase: document.querySelector("#reset-case"),
+ openMapButtons: document.querySelectorAll("[data-open-map]"),
+ openIntakeButtons: document.querySelectorAll("[data-open-intake]"),
+ openDoctrineButtons: document.querySelectorAll("[data-open-doctrine]"),
+ systemMapModal: document.querySelector("#system-map-modal"),
+ closeSystemMap: document.querySelector("#close-system-map"),
+ intakeModal: document.querySelector("#intake-modal"),
+ closeIntake: document.querySelector("#close-intake"),
+ doctrineModal: document.querySelector("#doctrine-modal"),
+ closeDoctrine: document.querySelector("#close-doctrine"),
+ doctrineContent: document.querySelector("#doctrine-content"),
+ openingBrief: document.querySelector("#opening-brief"),
+ openingTitle: document.querySelector("#opening-title"),
+ openingSummary: document.querySelector("#opening-summary"),
+ openingRole: document.querySelector("#opening-role"),
+ openingGoals: document.querySelector("#opening-goals"),
+ startCase: document.querySelector("#start-case"),
+ workspace: document.querySelector("#workspace"),
+ intakeContent: document.querySelector("#intake-content"),
+ evidenceCount: document.querySelector("#evidence-count"),
+ evidenceList: document.querySelector("#evidence-list"),
+ evidenceType: document.querySelector("#evidence-type"),
+ evidenceDate: document.querySelector("#evidence-date"),
+ evidenceTitle: document.querySelector("#evidence-title"),
+ evidenceBody: document.querySelector("#evidence-body"),
+ activeTagSummary: document.querySelector("#active-tag-summary"),
+ relatedEvidence: document.querySelector("#related-evidence"),
+ puzzleCard: document.querySelector(".puzzle-card"),
+ puzzleTitle: document.querySelector("#puzzle-title"),
+ puzzlePrompt: document.querySelector("#puzzle-prompt"),
+ puzzleAnswer: document.querySelector("#puzzle-answer"),
+ submitPuzzle: document.querySelector("#submit-puzzle"),
+ puzzleResult: document.querySelector("#puzzle-result"),
+ selectedTagsStatus: document.querySelector("#selected-tags-status"),
+ forceTags: document.querySelector("#force-tags"),
+ signalProfile: document.querySelector("#signal-profile"),
+ castProgress: document.querySelector("#cast-progress"),
+ castBoard: document.querySelector("#cast-board"),
+ timeline: document.querySelector("#timeline"),
+ caseRecap: document.querySelector("#case-recap"),
+ readingOptions: document.querySelector("#reading-options"),
+ submitReading: document.querySelector("#submit-reading"),
+ readingResult: document.querySelector("#reading-result"),
+ readingPath: document.querySelector("#reading-path"),
+ revealCard: document.querySelector("#reveal-card"),
+ revealContent: document.querySelector("#reveal-content"),
+ custodyCard: document.querySelector("#custody-card"),
+ custodyPrompt: document.querySelector("#custody-prompt"),
+ custodyOptions: document.querySelector("#custody-options"),
+ custodyResult: document.querySelector("#custody-result")
+};
+
+let caseData;
+let state;
+let openingOpen = true;
+let lastReferenceTrigger = null;
+
+function formatTags(tags) {
+ return tags.length ? tags.join(" / ") : "No signals tagged";
+}
+
+function highlightDoctrineForces(text) {
+ const escapedForces = caseData.forces.map((force) => force.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"));
+ const forcePattern = new RegExp(`\\b(?:The\\s+)?(?:${escapedForces.join("|")})\\b`, "g");
+ return text.replace(forcePattern, '$&');
+}
+
+function getSignalLabel(score, maxScore, dominantSignal) {
+ if (score <= 0) return "dormant";
+ if (dominantSignal === "Mixed" && score === maxScore) return "contested";
+ if (score === maxScore && maxScore > 1) return "dominant";
+ if (score > 1) return "strong";
+ return "trace";
+}
+
+function getNewlyUnlockedEvidence(beforeVisible, afterVisible) {
+ const beforeIds = new Set(beforeVisible.map((item) => item.id));
+ return afterVisible.find((item) => !beforeIds.has(item.id));
+}
+
+function getPuzzleFeedback(puzzle, attemptCount) {
+ const hint = puzzle.hints?.[Math.min(attemptCount - 1, puzzle.hints.length - 1)];
+ return hint ? `${puzzle.failure} Hint: ${hint}` : puzzle.failure;
+}
+
+function getEvidenceById(evidenceId) {
+ return getVisibleEvidence(caseData, state).find((item) => item.id === evidenceId);
+}
+
+function getReviewedContradictions(active) {
+ return (active.contradictionWith || [])
+ .map((evidenceId) => getEvidenceById(evidenceId))
+ .filter((item) => item && state.reviewedEvidence.has(item.id));
+}
+
+function setActiveEvidence(evidenceId) {
+ state.activeEvidenceId = evidenceId;
+ state.reviewedEvidence.add(evidenceId);
+ render();
+}
+
+function ensureActiveEvidence() {
+ if (getActiveEvidence(caseData, state)) return;
+
+ const firstVisible = getRoutedEvidence(caseData, state)[0];
+ if (!firstVisible) return;
+
+ state.activeEvidenceId = firstVisible.id;
+ state.reviewedEvidence.add(firstVisible.id);
+}
+
+function getReadingLabel(readingId) {
+ return caseData.readings.find((reading) => reading.id === readingId)?.label || "No reading";
+}
+
+function getPathEvidencePattern(dominantSignal) {
+ if (dominantSignal === "Unformed") {
+ return "No stable path formed before submission.";
+ }
+
+ if (dominantSignal === "Mixed") {
+ const taggedCount = Object.values(state.tagsByEvidence).filter((tags) => tags.length).length;
+ return `${taggedCount} artifacts carried competing signals, so the case kept multiple routes in tension.`;
+ }
+
+ const matchingEvidence = getVisibleEvidence(caseData, state).filter((item) => {
+ return state.reviewedEvidence.has(item.id) && item.expectedForces?.includes(dominantSignal);
+ });
+
+ if (!matchingEvidence.length) {
+ return `The ${dominantSignal} route formed through tags before matching evidence was fully reviewed.`;
+ }
+
+ return matchingEvidence.map((item) => item.title).join(" / ");
+}
+
+function getRouteAssessment(dominantSignal) {
+ if (dominantSignal === "Unformed") {
+ return "The Archive cannot assess a path because no force pattern formed before reconstruction.";
+ }
+
+ if (dominantSignal === "Mixed") {
+ return "The Archive reads your path as contested: you held several pressures in view instead of letting one explanation dominate.";
+ }
+
+ return `The Archive reads your path through ${dominantSignal}. That does not change the truth; it shows which pressure you made legible first.`;
+}
+
+function renderReveal(selectedReadingId) {
+ const { dominantSignal, visibleBonusEvidence } = getCaseProgress(caseData, state);
+ const selectedLabel = getReadingLabel(selectedReadingId);
+ const canonicalLabel = getReadingLabel(caseData.canonicalReading);
+ const routeCopy = getReadingPath(caseData, dominantSignal);
+ const evidencePattern = getPathEvidencePattern(dominantSignal);
+ const routeAssessment = getRouteAssessment(dominantSignal);
+ const bonusCopy = visibleBonusEvidence.length
+ ? `Route-surfaced evidence: ${visibleBonusEvidence[0].title}.`
+ : "No bonus evidence surfaced for this route.";
+
+ state.submittedReading = selectedReadingId;
+ dom.revealCard.hidden = false;
+ dom.readingResult.textContent =
+ selectedReadingId === caseData.canonicalReading
+ ? "Your reconstruction aligns with the canonical answer. Custody is now unlocked."
+ : "Your reconstruction diverges from the canonical answer. Review the confirmed truth before choosing custody.";
+ dom.readingPath.textContent = routeAssessment;
+ dom.revealContent.innerHTML = `
+
+
+
Your submitted reconstruction
+
${selectedLabel}
+
+
+
Canonical answer
+
${canonicalLabel}
+
+
+
Confirmed truth
+
${caseData.canonicalReveal}
+
+
+
Archive assessment
+
${routeAssessment}
+
+
+
Evidence pattern
+
${evidencePattern}
+
+
+
Route effect
+
${bonusCopy} Interpretation changed the route, not the truth.