Inspiration
There's a running joke in the AI community — Simon Willison's "pelican benchmark," where every new model is asked to draw a pelican riding a bicycle. We wanted our Build Week entry to earn a place in that lineage: put a pelican at the center, and let the newest model prove itself through character rather than a static drawing.
The other half of the inspiration was a real, unglamorous problem. Every developer has inherited a website and wondered, what is this thing even running? Tech-stack detectors exist, but they're dry — a list of logos, no judgment, no priorities. We asked: what if the tool that tells you what you're running also told you, with brutal honesty, what to fix first — and made you laugh while it did it?
So we built Dr. Gordon Pelican: a pompous, over-credentialed academic pelican who insists on being called "Dr." ("I didn't spend all those years at Bird University to be called professor"). Paste a URL, and he detects your real stack, scores it, roasts it down his beak — then, begrudgingly, hands you the modernization and security fixes that actually matter. Fun hook, useful tail. The roast earns the share; the fixes earn the "real product" respect.
What it does
- You paste a URL.
- The app fetches the page and runs a clean-room stack detector — 120 original signatures reading HTML, headers, script sources, meta/generator tags, and cookies to identify the CMS, framework, server, CDN, and analytics behind the site.
- A transparent heuristic scores the stack's health and modernity, mapping it to one of five mood bands.
- GPT‑5.6 writes the roast — in Dr. Pelican's voice, savagery scaled to the score — plus a prioritized list of real fixes.
- The pelican reacts. His pixel-art face and tone shift with the band: from a grudging nod at 100 to monocle-popping devastation at 0.
- You get a shareable OG card to post the verdict.
His five moods, driven by the score [0, 100]:
| Score | Band | Tone |
|---|---|---|
| 85–100 | Impressed | "Hmph. Adequate." Backhanded respect. |
| 65–84 | Smug | Mild condescension, a few jabs. |
| 40–64 | Concerned | Genuine concern, sharper jabs. |
| 20–39 | Horrified | Theatrical dismay. |
| 0–19 | Ashes | Total academic devastation. |
The score itself is a deliberately transparent heuristic — no black box, just penalties applied to detected signals (deprecated/EOL tech, known-insecure versions, age proxies, missing security headers):
$$ s = \max!\left(0,\; 100 - \sum_{i} w_i \cdot \text{penalty}_i\right) $$
Keeping scoring legible mattered: Dr. Pelican can only be fair if his verdict traces back to something real.
How we built it
The whole thing was built through OpenAI Codex in a WSL2 harness, on the all-OpenAI toolkit, and deployed to the Apify platform as a single Standby actor (a persistent HTTP server) exposing three routes:
GET /— the pixel-styled single-page app.POST /roast { url }— runs the pipeline, returns{ detected[], score, band, spriteId, roast, fixes[], shareId }.GET /card/:shareId— a server-rendered 1200×630 share card.
The stack is TypeScript ESM, the Apify SDK, cheerio for parsing, and the OpenAI SDK calling GPT‑5.6 with structured output. The share card is rendered server-side to PNG with Satori/Resvg. The five pixel-art pelican sprites were generated with OpenAI image generation — so every generative surface in the product, wit and art, runs on the same toolkit.
Two design decisions did the heavy lifting:
- Clean-room detection. Rather than vendor an existing signature engine (and inherit its license), we had Codex author the detector from scratch — 120 original rules for the highest-signal, roast-worthy tech. Public detection facts (WordPress serves
/wp-content/, React leavesdata-reactroot) are written clean. That kept the project MIT-licensed and made the detector itself a showcase of Codex's spec-driven build. - Grounding as code, not just a prompt. GPT‑5.6 is fed only the detected stack, and the roast layer enforces it in code — any "fix" that doesn't name a genuinely detected technology is dropped, and the call fails if fewer than three grounded fixes survive. Dr. Pelican physically cannot hallucinate a problem you don't have.
We also ran a small model-tiering experiment on the live roast path and logged it: the Sol tier (gpt-5.6) landed the character's voice best; the Terra tier was ~2.5× faster and slightly stronger on security fixes but less funny; Luna was gated. Verdict: keep Sol for the character hook, Terra as the fast fallback.
Challenges we ran into
- JS-heavy sites with thin HTML. Single-page apps hand a crawler almost nothing. Instead of failing, we turned it into a feature: when there's insufficient evidence, Dr. Pelican refuses to guess and roasts the lack of detectable signal — in character. No hallucinated stack, and it's one of the best beats in the demo.
- The deploy that passed every test and still 502'd. Local tests were green (the OpenAI client is mocked via dependency injection), but the live actor returned 502 on every real roast. Root cause was a three-layer trap: an invalid production key, an env-var name mismatch (the app read
OPENAI_API_KEYwhile only a second secret had been updated), and — the sneaky one — a warm Apify Standby run kept serving the old build even after a new one shipped. The fix was to align the secret and abort the running Standby run so a fresh container cold-started on the new build. A humbling reminder that "all tests pass" and "it works in production" are different claims. - Keeping scope honest under a 4-day clock. We tiered the build so every stage was independently submittable, and validated the Apify deploy continuously from Tier 1 rather than saving integration for the end.
What we learned
- Character is a product feature, not decoration. The mood-reactive pelican is what makes people paste a second URL — and the fixes are what make them come back. The joke and the utility reinforce each other instead of competing.
- Codex is strong at spec-driven, task-decomposed builds. Handed a clear spec and a tiered plan, it built the detector, scoring, roast layer, UI, and share renderer as coherent modules with production-grade guardrails (body-size caps, HTML-escaped OG meta, URL validation, DI throughout) — not glue code.
- Ground your model in code. The most reliable way to stop a creative model from making things up isn't a sterner prompt; it's a code gate that drops any output not tied to real evidence.
- The same GPT‑5.6 call can carry both the wit and the security correctness — one model, two jobs, which is the whole "fun hook, useful tail" thesis in one API call.
What's next
- A "pick your roaster" cast of characters beyond Dr. Pelican.
- An MCP wrapper so ChatGPT or Codex can call the roaster as a tool.
- Broader detector coverage past the initial roast-worthy set.
Built With
- ai
- apify
- cheerio
- codex
- css
- docker
- gpt-5.6
- html
- javascript
- llm
- node.js
- openai
- openai-api
- openai-image-generation
- pixel-art
- rest-api
- resvg
- satori
- serverless
- typescript
- vitest
- web-scraping
Log in or sign up for Devpost to join the conversation.