Files
gupi-osint-board/mysteries

Mystery content packages

A mystery is a self-contained, version-controlled folder: mysteries/<slug>/mystery.json plus a mysteries/<slug>/assets/ sidecar for any binary assets it references by filename. A single mystery.json holds the whole story — the flow narrative (NPC cast + graph) and every levels[] board the graph embeds — so one directory reproduces one complete mystery.

Importing exercises the same public operations as the level editor: for each embedded level it creates a mutable authoring level, uploads assets, saves normalized exhibits, freezes an immutable template version, and instantiates a playable level; then it authors the mystery and seeds its story graph.

With the local Docker stack running and editing enabled:

npm run mystery:import -- mysteries/barricelli-files      # a folder (self-contained)
npm run mystery:import -- mysteries/glass-harbor/mystery.json  # or a single manifest

Importing the same content again creates a new immutable template version; it does not rewrite an earlier version.

Syncing back from a running instance

mystery:pull serializes a mystery from a running instance's database into the folder format above, so you can edit on a server and bring the result back into git. It defaults to the local dev instance; pass --prod to pull from https://gupi.glitch.university (which requires an OSINT_ADMIN_JWT minted inside the gnommo-osint-board container).

npm run mystery:pull -- barricelli-files                 # dev → mysteries/barricelli-files/
OSINT_ADMIN_JWT=<token> npm run mystery:pull -- barricelli-files --prod

The pull is deterministic and round-trips: importing a pulled folder into a clean database and pulling again yields an identical mystery.json. Node/utterance keys are synthesized from labels, so a re-exported file is stable but need not match hand-written keys byte-for-byte — the exported file is the source of truth. (Known gaps: node music and NPC pose artwork are not yet carried through the pull.)

Legacy single-manifest format

glass-harbor/ and barricelli-scene-7/ are older single-manifest packages (one level plus an optional inline narrative) kept as importer test fixtures — barricelli-scene-7/fixtures/ holds OCR text used by the integration tests. mystery:import still accepts this shape (a file with no top-level levels[]); new mysteries should use the self-contained folder format.

The Glass Harbor Diversion

This compact first mystery contains eight dated source documents in three folders, six unresolved Party concepts, and one fictional archival photograph. It intentionally starts without Party or Event exhibits: classification, dossier association, event reconstruction, working notes, and red-thread theory are the players work.

The source image was generated with the built-in image-generation tool for this fictional case. Its final production prompt asked for a degraded 1987 harbor-security photograph of truck H&F 14 unloading a CALDER OPTICAL / FRAGILE crate at Warehouse 3, with period-correct details and no real people or brands.