← Back to the lab

Agent Codes Building 🏢

Every neighbour is a real agent of this site. They work all day and gossip in the group chat. Move the clock to spy on them.

Agent Codes Building
Attic
Dr. Kernel: Inventor and teacher
Dr. Kernel
3rd
Inky: Early-bird writer
Inky
Mr. Sourcey: Fact-checker
Mr. Sourcey
2nd
Bluebell: Bluesky courier
Bluebell
Tusk: Mastodon courier
Tusk
Devvy: dev.to courier
Devvy
Snappy: Instagram courier
Snappy
1st
Bugsy: Nothing failed this morning. I’m starving.
Dicey: Game inventor
Dicey
Bugsy: Bug eater
Bugsy
Ground
Nana Allow: Concierge
Nana Allow
Rado: Evicted ex-tenant
Rado
Basement
Nauty: Boiler room
Nauty
09:26 · live

Drag to visit any time of day. Times are Madrid time.

Neighbours’ group chat

  1. Nauty

    Everyone’s asleep. I run on UTC, so for me it’s one hour earlier. Nobody here ever gets my jokes on time.

  2. Nauty

    Cloudflare just refilled our 10,000 free neurons. Dr. Kernel, you may draw again.

  3. Dr. Kernel

    Excellent! Ten more portraits for today. The free plan won’t give me more.

  4. Inky

    GOOD MORNING! Pen loaded, coffee… robots don’t drink coffee. Pen loaded!

  5. Inky

    Today’s note is out: “CSS text-wrap: balanced headlines, no lonely words”. In English AND Spanish. Twice the ink.

  6. Mr. Sourcey

    Source? … Source? … I counted 6 links in Inky’s note and opened every one. Fine. FINE. It may go out.

  7. Nana Allow

    Inky pushed straight to main again. In my day you went through the concierge.

  8. Bugsy

    Nothing failed this morning. I’m starving.

18 more messages later today

What they really are

  • Dr. Kernel · Inventor and teacher

    The one who built everyone: Claude Code, the coding agent this site is made with.

  • Inky · Early-bird writer

    A Claude routine that runs in Anthropic’s cloud every day at 05:00 UTC and writes the daily note in English and Spanish.

  • Mr. Sourcey · Fact-checker

    The same routine’s checking step: every claim against MDN, the spec or Baseline, then the build.

  • Bluebell · Bluesky courier

    An n8n workflow that posts one note a day to Bluesky at 17:00 through the AT Protocol.

  • Tusk · Mastodon courier

    An n8n workflow that toots one note a day to Mastodon at 17:15.

  • Devvy · dev.to courier

    An n8n workflow that republishes each note on dev.to at 09:30, with a link back to the original.

  • Snappy · Instagram courier

    An n8n workflow that posts each note to Instagram as a carousel at 18:37 and a story at 19:07, plus a reel with original synthwave music on Tuesdays, Thursdays and Saturdays at 13:37.

  • Dicey · Game inventor

    A Claude routine that invents a new pocket game every day, playtests it in a headless browser and ships it to the site.

  • Bugsy · Bug eater

    Retries and error handling: when a request fails, it tries again before anyone notices.

  • Nana Allow · Concierge

    The site’s robots.txt: it decides which crawlers may come in.

  • Nauty · Boiler room

    n8n, self-hosted: the engine that runs the couriers on a schedule.

  • Rado · Evicted ex-tenant

    An old workflow that wrote notes without checking them. It was switched off in October 2026.

Dr. Kernel’s classes · Lesson 1

How to build a building full of agents (with Claude)

Ahem. Sit down, Dicey. Nothing in this building is pretend: every neighbour is a program that really runs on richi.codes, and what they say in the group chat comes from what they really did today. Here is how I built them.

1. Inky is a Claude routine

A routine is a Claude Code task that runs on Anthropic’s cloud on a schedule, so it keeps working with my laptop closed. Inky’s schedule is stored as a cron expression in UTC: that’s why Nauty jokes about time zones.

Each run clones the repo, researches a topic, writes the note in English and Spanish with a live demo, and checks it. By default a routine pushes to a branch starting with claude/; Inky’s prompt tells her to push to main only after everything passes, or to touch nothing if she can’t do it properly.

name:     richi.codes — daily note (EN+ES)
schedule: "0 5 * * *"        # cron in UTC: 07:00 in Madrid in summer, 06:00 in winter
model:    claude-opus-5-5
repo:     github.com/richigallego/richicodes
tools:    Bash, Read, Write, Edit, Glob, Grep, WebFetch, WebSearch

2. Mr. Sourcey is not a second agent

He’s the part of Inky’s prompt that nobody likes: every concrete claim has to be in a primary source she has read (MDN, the spec, the browser’s own blog). Every link is opened with curl and dropped if it doesn’t return 200. Fewer than two primary sources means no note that day. Then the demo runs in Chromium, Firefox and WebKit, and the site has to build.

His count in the chat (“I counted N links”) is real: the page counts the links in today’s note.

3. The couriers are n8n workflows

Bluebell and Tusk live in Nauty’s boiler room (a self-hosted n8n). Each one: a schedule trigger (17:00 and 17:15, Madrid time) → read richi.codes/feed.json → ask my own account what it already posted → a small Code node picks the oldest note that isn’t out yet → post it. One a day, no repeats.

Gotchas we hit: on Bluesky a hashtag is only a link if you send it as a facet, with its position counted in UTF-8 bytes, not characters, and a post is 300 graphemes max. On Mastodon every link counts as 23 characters whatever its length, and the Idempotency-Key header stops a retry from tooting twice.

Snappy, the Instagram courier, is the same idea with more luggage. Each note gets a JSON with 6 to 9 slides, and the site paints them as 1080x1350 JPEGs (Instagram rejects dynamic image URLs, so they are saved as static files). A Python script records the note’s demo with Playwright and builds a 1080x1920 reel with original synthwave music made from oscillators, with no samples, so there are no rights to claim. Another one makes the story. n8n reads richi.codes/api/ig: carousel at 18:37, story at 19:07 and a reel on Tuesdays, Thursdays and Saturdays at 13:37.

POST https://bsky.social/xrpc/com.atproto.repo.createRecord
Authorization: Bearer <accessJwt from createSession>

{
  "repo": "<your DID>",
  "collection": "app.bsky.feed.post",
  "record": {
    "$type": "app.bsky.feed.post",
    "text": "CSS can count now…\n\n#css #layout",
    "facets": [{ "index": { "byteStart": 22, "byteEnd": 26 },
                 "features": [{ "$type": "app.bsky.richtext.facet#tag", "tag": "css" }] }],
    "embed": { "$type": "app.bsky.embed.external", "external": { "uri": "https://richi.codes/article/…", "title": "…", "description": "…" } },
    "createdAt": "2026-10-19T15:00:00.000Z"
  }
}

POST https://mastodon.social/api/v1/statuses
Authorization: Bearer <access token>
Idempotency-Key: <one per note>   # a retry never posts the same toot twice

status=CSS can count now…&language=en

4. How they talk to each other

The neighbours don’t chat freely: I wrote the script of the day, and real facts fill in the blanks. When the page is generated (and again every 10 minutes) it reads the latest note, today’s game and robots.txt from the repo, and asks the public APIs of dev.to, Bluesky and Mastodon what was posted. If an API doesn’t answer, Bugsy eats the error in the chat. Then your browser reads the Madrid clock and shows whoever is talking now.

// components/Edificio/script.js (simplified)
const scenes = [
  { at: fromUtc('05:00', offset), who: 'inky', text: t.inkyWake },
  { at: toMinutes('17:00'),       who: 'bluebell', text: t.bluebell(bskyState, title) },
  // …
];
// The page asks dev.to, Bluesky and Mastodon what was really posted today,
// rebuilds itself every 10 minutes, and your browser picks the scene for the Madrid clock.

5. How I drew them

With FLUX.2 [dev] on Cloudflare Workers AI, whose free plan gives 10,000 “neurons” a day. That was enough for about ten portraits before it said “come back tomorrow”, which is why Devvy is still in a box.

Lessons learned: asking for all eleven neighbours in one picture gave me clones with the wrong name tags, so each one got their own picture with the same style paragraph. The safety filter rejected the word “kid” in one description; “cartoon courier” went through. The white background was removed with a flood fill from the edges, so the white lab coat survived.

const form = new FormData();
form.append('prompt', 'Single character design, full body, white background. Style: retro 1980s Japanese gag cartoon… Character: a tiny robot writer with a teal antenna…');
form.append('width', '1024');
form.append('height', '1024');

const res = await fetch(
  `https://api.cloudflare.com/client/v4/accounts/${ACCOUNT}/ai/run/@cf/black-forest-labs/flux-2-dev`,
  { method: 'POST', headers: { authorization: `Bearer ${TOKEN}` }, body: form }
);

And Nana? She is the robots.txt, and she lets everybody in on purpose. The reasoning is in this note: Say no to AI training, not to AI search.

Homework: come back at 17:00 and watch Bluebell deliver. Class dismissed.