A tongue-in-cheek out-of-office experience. Colleagues submit "witness statements" about sightings; Claude extracts entities and plots them on a live knowledge graph and map.
Built by: Cameron Stiller · Nuix
Graph library: Ogma by Linkurious
- Colleagues visit the live site and see a real-time investigation board tracking the missing person's movements
- Staff can submit witness statements (e.g. "I saw Cameron at the airport with a suspicious amount of sunscreen")
- Claude API moderates each statement and extracts entities (locations, activities, associates) and relationships
- A background GitHub poller imports pre-planned sightings from a public JSON feed at a scheduled time — so the board updates itself while you're actually on holiday
- Everything lands on an interactive Ogma knowledge graph and Leaflet map that updates in real time via WebSockets
| Layer | Tech |
|---|---|
| Frontend | React 18 + TypeScript + Vite |
| Graph viz | Ogma (Linkurious) — commercial licence required |
| Map | Leaflet + OpenStreetMap |
| Backend | Node.js + Express + Socket.io |
| AI | None — staff form submits structured fields directly |
| Geocoding | Nominatim (OpenStreetMap) — rate-limited at 1 req/s |
| Database | PostgreSQL |
| Deployment | Docker Compose (local) · Helm + k3s (production) |
| Real-time | Socket.io (WebSocket broadcast on new sightings) |
cp .env.example .env
# Fill in: TARGET_NAME, LAST_SEEN_DATE, POLL_URL
# Optionally set: DB_USER, DB_PASSWORD, DB_NAME (defaults are fine for local dev)
docker-compose up -d
# Frontend → http://localhost:3000
# Backend → http://localhost:3001Ogma is a commercial graph library. You need a licence from Linkurious.
Once you have the .zip, extract the JS files into frontend/public/ogma/ (the path vite.config.ts expects).
Copy .env.example and fill in:
| Variable | Description |
|---|---|
TARGET_NAME |
Name of the "missing" person (e.g. Cameron Stiller) |
LAST_SEEN_DATE |
Display date in the header (e.g. 2026-06-26) |
POLL_URL |
URL to a JSON array of pre-planned sightings (see below) |
POLL_INTERVAL_MS |
How often to check POLL_URL (default 300000 = 5 min) |
DB_USER / DB_PASSWORD / DB_NAME |
PostgreSQL credentials (defaults fine for local) |
The poller fetches a JSON file from POLL_URL every POLL_INTERVAL_MS. Format:
[
{
"time": "2026-06-27T09:20:00",
"location": "Sydney Airport Terminal 1, Mascot NSW 2020",
"activity": "Checking in at the departure gate",
"associate": "Optional — person or thing they were with"
}
]timeis treated as AEST (UTC+10) and is also the dedup key — duplicate times are skipped- Future-dated entries are ignored until their time arrives, so you can commit the whole trip upfront
- Geocoding is done via Nominatim; no coordinates needed in the feed
A good workflow: keep sightings in a separate public GitHub raw URL so you can edit them from your phone while you're away.
The helm/operation-find-cameron/ chart deploys frontend, backend, PostgreSQL (Bitnami subchart), and Traefik ingress with a /demo subpath.
helm upgrade --install operation-find-cameron ./helm/operation-find-cameron \
-n your-namespace \
--set backend.env.TARGET_NAME="Your Name" \
--set backend.env.POLL_URL="https://raw.githubusercontent.com/..." \
--set postgresql.auth.password=changemeImages are expected to be pre-built and imported on the node (imagePullPolicy: Never) — see DEPLOYMENT.md for the full build-and-import workflow.
├── backend/
│ ├── src/
│ │ ├── index.ts Express + Socket.io server
│ │ ├── routes/witness.ts API endpoints
│ │ └── services/
│ │ ├── database.ts PostgreSQL operations
│ │ ├── geo.ts Nominatim geocoding + reverse geocoding
│ │ └── poller.ts GitHub sightings feed poller
│ └── Dockerfile
├── frontend/
│ ├── src/
│ │ ├── App.tsx Shell, timeline playback, header stats
│ │ └── components/
│ │ ├── GraphVisualization.tsx Ogma knowledge graph
│ │ ├── MapView.tsx Leaflet map with suburb clustering
│ │ ├── WitnessForm.tsx Statement submission (staff only)
│ │ └── LocationAutocomplete.tsx Nominatim address search
│ └── Dockerfile
├── helm/operation-find-cameron/ Helm chart for Kubernetes
├── docker-compose.yml Local dev / demo
└── .env.example Environment variable template
The main site is read-only for most visitors. But if you know the URL, you can submit sightings yourself:
https://your-domain/demo/staff
The /staff route unlocks a witness statement form. Type what you saw and Claude will extract the entities and add them to the graph in real time. Keep it work-appropriate — the API moderates submissions.
This path is intentionally undocumented in the UI. Share it only with people you want contributing to the investigation.
- Fork this repo
- Set
TARGET_NAMEto your name - Create a public GitHub repo with your sightings JSON (see format above)
- Set
POLL_URLto the raw URL of that file - Deploy with Docker Compose or Helm
- Put the URL in your out-of-office email
Source code: MIT
Ogma graph library: commercial licence required from Linkurious — not included in this repo.