← Browse Dives
Full screen
Screenshot of The Goblin Containment Unit Has Failed
Loading Interactive Dive...

The Goblin Containment Unit Has Failed

How a tiny "goblin" tic in OpenAI's models snowballed into a leaked system prompt, a reinforcement-learning argument, and a full-blown meme. Six acts of evidence from Hacker News, Reddit, GitHub, the press, Google Trends, and OpenAI's own postmortem. Styled like terminal folklore.

TalkAIShowcase
Author: Joel Van Veluwen  ·  June 21, 2026    Region: us-west-2

AI Prompts Used

1Prompt 1
Build one MotherDuck Dive (a single default-exported React component) called
"The Goblin Containment Unit Has Failed" — a six-act data investigation, styled like
terminal folklore, into how a weird "goblin" tic in OpenAI's models became a leaked
system prompt, a reinforcement-learning argument, and an internet meme.

Explore each table with the MCP `query` tool before charting; only show what the data
supports. Build to preview live, then stop for my review before saving.

══════════════════════════════════════════════════════════════
THE STORY (the spine every act hangs off)
══════════════════════════════════════════════════════════════
Codex/ChatGPT users kept noticing the model reaching for "goblin" (and gremlin, raccoon,
troll, ogre, pigeon, frog) in normal answers. People found a Codex system-prompt clause
telling it NOT to mention goblins. OpenAI then published a postmortem: a "Nerdy"
personality reward had accidentally scored creature-words highly, creating a positive
feedback loop in reinforcement learning. The suppression attempt leaked, the internet
found it funny, and a wave of goblin-themed repos/posts/articles followed. The arc is:
sighting → discovery → mechanism → spread → ecosystem → meaning.

══════════════════════════════════════════════════════════════
DATA — all tables live in "goblins_dive"."main" (use `const DB = `"goblins_dive"."main"``)
Most platform tables share creature-count columns: goblin_count, gremlin_count,
raccoon_count, troll_count, ogre_count, pigeon_count, frog_count, plus topic counts
openai_count, codex_count, chatgpt_count, gpt_count, model_count, ai_count, rl_count,
sft_count, reward_count.
══════════════════════════════════════════════════════════════
goblin_creature_examples  — reported_by, model_version, creature, quote, context,
   source_thread. Real user-captured lines where the model said a creature word.
goblin_platform_mentions  — platform, creature, items. Counts of items naming each creature.
goblin_gh_models          — slug, name, family, instruction_word_count,
   contains_creature_suppression (bool), source_url. The Codex model definitions; exactly
   one (gpt-5.5) carries the creature-suppression clause and has the longest instructions.
goblin_commits            — committed_at, message, file, anti_creature_phrase_count,
   phrase_count_delta, html_url. Count holds at 0 through April, jumps to 4 at one commit
   on 2026-04-24 — datable BEFORE OpenAI's 2026-04-29 post.
goblin_claims             — claim, metric, value, unit, source_url. Headline stats from the
   OpenAI postmortem (e.g. goblin/gremlin increases, nerdy/reward shares).
goblin_words              — rank, word, count. Word frequency in the postmortem.
goblin_arena              — model_version, mode ('no thinking' / 'high thinking'),
   creature_word_pct. Independent measure; creature-word rate ~tripled gpt-5.2 → gpt-5.5,
   worst when not thinking.
goblin_gh_repos           — full_name, name, owner, url, description, stars, created_at,
   ai_goblin_relevance_label ('high'/'medium'/...). Goblin-themed repositories.
goblin_repo_engagement    — repo, url, description, stars, contributors_observed,
   commits_observed. Depth-of-engagement for the standout repos.
goblin_hn                 — hn_id, type ('story'/...), title, url, points, num_comments.
   Hacker News threads.
goblin_reddit_threads     — subreddit, title, url, upvotes, num_comments, body_excerpt.
goblin_reddit             — subreddit, title, url, association_type, notes (broader set).
goblin_reddit_comments    — thread_id, author, upvotes, category, comment_excerpt.
goblin_media              — source, title, url, published, source_type, angle. Press coverage
   (Ars Technica, PC Gamer, Decrypt, Tom's Guide, TechRadar, VentureBeat, OpenAI, etc.).
goblin_gh_issues          — number, title, url, state, comments, author, body_excerpt.
   openai/codex issues.
goblin_timeline2          — sort_order, date_label, phase, label, detail, source, engagement.
goblin_trends_multi       — week, goblin_openai, gremlin_gpt, codex_goblin,
   nerdy_personality, gpt55_goblin. Google-Trends-style weekly interest.
goblin_pre_memo           — date, platform, source, title, url, quote_excerpt, notes.
   Evidence that sightings predate the memo.

══════════════════════════════════════════════════════════════
SECTIONS (each its own component, separated by a faint <Divider/>)
══════════════════════════════════════════════════════════════
HERO
  - Eyebrow status line: "● CONTAINMENT STATUS: FAILED".
  - Huge headline (title). One-sentence lede summarizing the arc (sighting → leak →
    reinforcement-learning argument → meme).
  - 3–4 floating stat numbers (NO card borders) from SUM/COUNT over goblin_platform_mentions
    (items mentioning goblin), goblin_gh_repos (repo count), goblin_reddit/distinct subreddits.
  - A small playful aside (a themed external link). A sticky right sidebar "goblin companion".

ACT 1 · The sightings — H2: "One goblin is a joke. Hundreds are a signal."
  - 4 quote cards from goblin_creature_examples (quote, @reported_by, context). Pick lines
    clearly from coding contexts (Codex/ChatGPT), e.g. config/refactor/networking goblins.
  - Interactive creature picker driving a mutation view off goblin_platform_mentions
    (useDiveState "creature"). Note many sightings predate the memo (goblin_pre_memo).

ACT 2 · The prompt archaeology — H2: "Then someone actually read the system prompt."
  - A styled terminal code block showing the leaked anti-creature instruction fragment.
  - Callout "the goblin suppression clause": of the Codex model defs in goblin_gh_models,
    exactly one (gpt-5.5) has contains_creature_suppression=TRUE and the longest
    instruction_word_count.
  - Bar chart from goblin_commits: anti_creature_phrase_count by commit date; highlight the
    commit where it jumps to 4 (2026-04-24), before the 2026-04-29 post.
  - Bar chart from goblin_gh_models: instruction_word_count per model, the suppressing one
    colored differently.

ACT 3 · The reinforcement loop — H2: "The reward model made a monster."
  - A hand-built flow diagram (boxes + arrows, last arrow loops ↺): User asks → Model adds
    goblin flavor → "Nerdy" reward scores it high → Behavior reinforced via reinforcement
    learning → Goblins everywhere.
  - KPI stats from goblin_claims (value+unit+claim). Word-frequency bar chart from goblin_words.
  - One real attributed quote about the feedback loop in reinforcement learning (Hacker News).
  - Line chart from goblin_arena: creature_word_pct by model_version, two lines for
    'no thinking' vs 'high thinking'; note it ~tripled gpt-5.2 → gpt-5.5.

ACT 4 · It spreads — show adoption over time.
  - Bar chart: goblin repos created per week from goblin_gh_repos (date_trunc week on created_at).
  - Optionally a small interest-over-time view from goblin_trends_multi.

ACT 5 · The goblin ecosystem — H2: "From bug report to banner."
  - A d3 force-directed network (hand-coded SVG, d3-force for layout): central "GOBLIN" hub,
    five category hubs (GitHub, Reddit, Media, Hacker News, Codex issues), and REAL leaf nodes:
      · GitHub  → goblin_gh_repos (high/medium relevance), sized by stars, tooltip stars+owner,
                  click opens url; dashed ring if created_at after the memo ("second wave").
      · Hacker News → goblin_hn stories, sized by points, tooltip points, click opens item.
      · Reddit  → goblin_reddit_threads, sized by upvotes, tooltip ▲upvotes·comments·subreddit +
                  a body_excerpt quote, click opens thread.
      · Media   → goblin_media articles, tooltip source·published + angle, click opens article.
      · Codex issues → goblin_gh_issues, tooltip state·comments + body_excerpt, click opens issue.
    Filter chips per category (useDiveState) toggle node visibility.
  - "Notable goblins" list from goblin_repo_engagement (stars, commits_observed, description),
    flag the ones whose description roasts OpenAI/Codex/ChatGPT.
  - Closing callout: the sequel — people re-creating the behavior on purpose ("How to Train
    Your Goblin"), tying it back to the reinforcement-learning loop.

ACT 6 · The takeaway — H2: "What the goblin means."
  - A creature "mutation" table from goblin_platform_mentions (creature, total items), reacting
    to the Act-1 creature selection.
  - ONE punchy closing line. Concrete, a little funny, not grandiose.

FOOTER — sources (OpenAI postmortem; the named outlets; Hacker News; Reddit; GitHub; Google
Trends) + "A MotherDuck Dive." Then a CTA line linking Hurdle.ai.

══════════════════════════════════════════════════════════════
VOICE  (the part that keeps it from sounding like AI)
══════════════════════════════════════════════════════════════
Journalistic and dryly funny. Specific numbers, no hype words. Every quote/node/stat is a
REAL row from the data — never fabricate. Ban clichés ("say the quiet part out loud," "rode
in with the verbosity," "learned to bite," "kept it alive on purpose"). Cut filler sentences.
Headlines short and concrete. Expand "RL" to "reinforcement learning" in body text.

══════════════════════════════════════════════════════════════
VISUAL SYSTEM — terminal folklore
══════════════════════════════════════════════════════════════
Dark bg (~#0b0f0a), monospace accents, panel #11170f. Palette: toxic #b6ff4d,
goblin #72d572, blood #c8321e, orange #ff9f1c, purple #8e6cff, bone #e8e2d0,
parchment #b7aa88, HN blue #638CAD. Reusable: Eyebrow, H2, Lede, ChartBlock (labeled
wrapper), Skel (skeleton), Divider (faint gradient rule). Consistent dark Recharts
tooltip/grid. Hand-coded SVG ONLY for the force network and the flow diagram; all other
charts are Recharts.

══════════════════════════════════════════════════════════════
TECHNICAL (MotherDuck Dive rules)
══════════════════════════════════════════════════════════════
- export default function; named exports allowed.
- Libraries only: react, @motherduck/react-sql-query (useSQLQuery, useDiveState), recharts,
  d3 (force/geo only), lucide-react.
- One useSQLQuery per visual. data IS the row array — guard Array.isArray(data)?data:[].
- const N = v => v!=null ? Number(v) : 0; wrap EVERY numeric value. Format dates in SQL (strftime).
- Fully qualified, double-quoted names via the DB const: ${DB}."table".
- Progressive loading: render layout immediately, per-section skeletons, no full-page spinner.
- useDiveState for the creature filter and the network category toggles.
- For public sharing, after building: copy referenced tables into a clean DB, create an
  UNRESTRICTED share, and export:
    export const REQUIRED_DATABASES = [
      { type: "share", path: "md:_share/<share>/<uuid>", alias: "goblins_dive" }
    ];

OUTPUT: the complete component, ready to save as a Dive.

Comments

Log in to leave a comment.

No comments yet. Be the first!