Case Study · Product Design · AI Engineering · AI Builders Challenge with IBM Bob · 2026

Openhall

Ten artworks and one sentence in, a walkable exhibition out — AI-curated rooms, wall labels, a guided tour with spoken narration, and a one-click export that gives the artist a gallery they actually own.

IBM watsonx.ai · Llama vision + text models · Three.js · Zod validation · BYOK · Static-site export

First-person view inside an Openhall-generated gallery: wood floor, white walls with track lighting, framed paintings on both sides, and a doorway opening into the next room
The demo exhibition — eight public-domain works, curated, hung, and lit without a human touching a 3D editor.

Openhall, 2026

TypeScript, Three.js, watsonx.ai, and one Cloudflare Worker · Open source · Artist-owned edition

Problem
Exhibiting is gatekept. Physical space costs hundreds to thousands of dollars, and the online fallbacks — Instagram grids, PDF portfolios — flatten artwork into a scrolling feed, losing the spatial, curated experience that gives a show its impact.
Built
A browser tool that analyses an artist's uploaded works, curates them into themed rooms, writes every label and docent narration, builds a walkable 3D gallery — and exports it all as a self-contained static site with no account, platform, or fee attached.
My Role
I defined the product, the visitor experience, and the ownership principle, then directed a three-tool AI build workflow — IBM Bob for architecture and implementation, Codex for auditing and hardening, Claude Code for live-failure debugging — owning every accept/reject decision along the way.
10Artworks per exhibition, one sentence of curatorial direction
16AI requests per generation — every one validated
2Llama models, each sized to its task
0Accounts, databases, or servers holding the artist's work

Good work, no room to hang it.

Independent artists and art students make work worth exhibiting, but exhibitions stay gatekept. A physical show means renting a space, and the usual online alternatives treat artwork as content: a square in a feed, a page in a PDF. What disappears is exactly the thing a show is for — walking through rooms someone composed, seeing works in deliberate company, reading a label written with intent.

Virtual-gallery platforms exist, but they mostly hand the artist a 3D editor and a subscription: hours of manual placement, then a gallery that lives on someone else's servers for a monthly fee. The two questions behind Openhall were simple: what if curation took one sentence instead of one editor — and what if the result belonged to the artist, full stop?


What a visitor gets.

The two-minute pitch shows the whole arc — upload, one-sentence brief, generation, and the walkable result.

The generated exhibition behaves like a real one. You walk it in first person (WASD and mouse), click any work to step close and inspect it, or press Tour and let the gallery guide you piece by piece — with an opt-in audio guide that speaks each narration aloud. An "About the Artist" wall, generated from the artist's name, statement, and links, greets visitors the way a title wall does in a physical show.

Openhall tour mode inspecting a Pissarro painting up close, with the generated About-the-Artist wall and tour controls: autoplay, audio guide, previous, next, and exit
Tour mode — the docent card, audio guide, and the artist wall the AI assembles from three fields.

And then the part that defines the product: Export. One click produces a zip that is a complete, self-contained static website — viewer, tour, narration, everything. Drop it on any free static host and the exhibition is live at the artist's own URL, with no Openhall account, dependency, or fee. The tool forgets you; the show is yours.


AI has taste. Code has a tape measure.

The generation pipeline is a six-station line. The core idea: language models are good at judgment and terrible at geometry, so every station does only what its worker is reliably good at — AI decides what belongs together and what to say; deterministic code decides where every wall, doorway, and picture hook goes.

The pipeline — who does what

  1. Code

    Upload

    Up to ten works, resized in the browser. Nothing leaves the artist's machine except the AI calls they configure.

  2. AI · vision

    Read each work

    A vision model notes every piece's style, palette, subject, and mood — the curator walking the studio, taking notes.

  3. AI · language

    Curate the show

    A language model reads all the notes plus the artist's one-sentence brief, then decides rooms, groupings, hanging walls, and the visitor's route. It chooses; it never measures.

  4. Zod validation gate — wrong ids, missing works, broken tour order? One retry with the errors attached, then fail loudly. Never silently repaired.
  5. Code

    Build the rooms

    A deterministic assembler turns the plan into geometry — room dimensions, doorways, exact placements, collision bounds. Pure math, correct every time.

  6. AI · language

    Write the words

    Placard labels and a spoken docent narration for every work, in the voice the artist's brief set. Validated batch by batch.

  7. Code

    Render & export

    Three.js renders the walkable gallery; the exporter packs it into a static site that runs anywhere, forever.

Why the gate matters: an AI answer is "probably right", never "guaranteed right". A model can format perfect JSON and still assign eight artworks out of ten, or invent ids that don't exist. Every structured AI response is checked against what was actually asked for — before anything downstream trusts it.


What I chose — and what I rejected.

AI curates; deterministic code builds

Early versions let the model emit gallery geometry freeform. The result was walkable but incoherent — tour paths through walls, backtracking routes. Splitting judgment from geometry fixed it permanently: the model was never asked to do math again.

Fail loudly over patching quietly

When validation fails, the pipeline retries once with the errors attached, then stops and tells the artist. I rejected auto-repairing bad AI output — a gallery silently missing three works is worse than an honest error screen that keeps the artist's inputs intact.

No backend, no account, no lock-in

API keys live in the artist's browser; the export is a complete site with zero Openhall dependency. I rejected the standard SaaS shape — hosting users' galleries — because ownership was the point. The one exception is a tiny stateless relay the IBM route needs.

Two models, each sized to its task

An 11B vision model reads one artwork at a time — an easy task, done sixteen times cheaply. Curation, which must track ten ids across rooms, placements, and tour order without dropping one, gets a 70B model. Right-sizing beat using one big model for everything.


Three things that broke, and what they taught.

Every fix below is visible in the repo's history — the project keeps its debugging honest instead of pretending the pipeline worked on the first try.

  1. The gallery that arrived cut off mid-sentence

    Symptom: generation failed at the same JSON position on every retry. Root cause: the model was asked to emit the entire gallery — geometry, labels, everything — and hit its output-length ceiling; retrying couldn't fix truncation. Fix: this failure produced the architecture — the deterministic assembler took geometry away from the model entirely, and output shrank to what a model can reliably say.

  2. The model that failed the same exam twice

    Symptom: with ten artworks, curation failed validation on every run — ids dropped, duplicated, or invented. Root cause: exact bookkeeping across a long answer is precisely what small models are worst at, and near-zero temperature meant the retry repeated the same mistake. Fix: swapped the 8B curation model for a 70B one and verified it against the exact failing scenario — first-attempt pass, twice in a row.

  3. The API that wouldn't talk to a browser

    Symptom: watsonx calls that worked in scripts died in the browser. Root cause: IBM's auth and ML endpoints send no CORS headers — they assume you have a backend, and Openhall deliberately has none. Fix: a minimal stateless Cloudflare Worker that exchanges the token and relays the calls — the smallest possible backend, built only because the browser wasn't allowed to do it alone.


How this was actually made.

Openhall was built in collaboration with AI; the design decisions, content, and direction are mine. I did not write this project line by line — and being precise about that split is part of the work I want to show.

  • AI did — the architecture and feature implementation (IBM Bob, directed through written session prompts that are committed to the repo); a commit-by-commit audit of Bob's work that surfaced nine integration gaps, the fixes, and sixteen regression tests, plus feature refinements delivered as reviewed pull requests (Codex); and live-failure debugging and real-browser verification, including diagnosing why curation kept failing validation and proving the model swap against the exact failing case (Claude Code).
  • I did — the concept and the ownership principle, the visitor experience, the visual presets, the honesty rules for every failure state, the per-session direction of all three tools, and the final call on everything that shipped.
  • What I learned — treat AI output as a proposal, not a fact. The pipeline validates every structured answer; my workflow validates every AI-written change the same way — run it for real, in a real browser, against the exact case that failed. "Looks correct" and "runs correct" are different claims.
The deeper lesson: capability is task-shaped

The most useful thing this project taught me about AI engineering is that a model isn't "good" or "bad" — it's good at a shape of task. The same 8B model that analysed artworks flawlessly failed curation every single time, because analysing one image is easy and tracking ten ids through an interlocking plan is hard. Once I saw capability as task-shaped, the design followed: shrink each AI task until it fits the model reliably, give everything else to deterministic code, and put a validator at every seam. That principle — not any single feature — is what I'd carry to the next product.

Exit through the gallery.

Walk the live demo gallery, watch the pitch, or read the source — the repo includes the full build history, the AI session prompts that directed it, and the debugging notes.