Didn't work? That's normal — models don't always generate a working REPL on the first try. Paste the snippet again and retry.
File an issue
read -p "Anthropic API key: " k && echo "ANTHROPIC_API_KEY=$k" > .afs.env && chmod 600 .afs.env && source .afs.env && read -r -d '' c <<'C'
curl -s "https://api.anthropic.com/v1/messages" \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-H 'Content-Type: application/json' -X POST \
-d '{"model":"claude-opus-4-6","max_tokens":8192,"messages":[{"role":"user","content":"Write a Python script (stdlib only) for a minimal agentic CLI. Requirements:\n- Uses urllib to call Anthropic Messages API (claude-opus-4-6)\n- Tool: bash (via subprocess, 120s timeout, truncates >30k chars)\n- Implements full agent loop: handle tool_use by running bash tool and sending back tool_result\n- Interactive REPL: prompt user, run loop, print text, log EVERYTHING to afs.log\n- Reads ANTHROPIC_API_KEY from .afs.env\n- System prompt: You are AFS, bootstrapped from curl. Help user build systems.\n- Output ONLY raw Python starting with #!/usr/bin/env python3. No markdown, no preamble."}]}'
C
echo "$c" >> afs.log && r=$(eval "$c") && echo "$r" >> afs.log && echo "$r" | python3 -c 'import sys, json; data = json.load(sys.stdin); text = "".join(block.get("text","") for block in data.get("content",[]) if block.get("type")=="text").strip(); print(text[text.find("#!"):text.rfind("```")] if "```" in text else text)' > afs.py && chmod +x afs.py && ./afs.py
read -p "Gemini API key: " k && echo "GEMINI_API_KEY=$k" > .afs.env && chmod 600 .afs.env && source .afs.env && read -r -d '' c <<'C'
curl -s "https://generativelanguage.googleapis.com/v1beta/models/gemini-3.1-pro-preview:generateContent?key=$GEMINI_API_KEY" \
-H 'Content-Type: application/json' -X POST \
-d '{"contents":[{"role":"user","parts":[{"text":"Write a Python script (stdlib only) for a minimal agentic CLI. Requirements:\n- Uses urllib to call Gemini API (gemini-3.1-pro-preview)\n- Tool: bash (via subprocess, 120s timeout, truncates >30k chars)\n- Implements full agent loop: handle function_call by running tool and sending back function_response\n- Interactive REPL: prompt user, run loop, print text, log EVERYTHING to afs.log\n- Reads GEMINI_API_KEY from .afs.env\n- System prompt: You are AFS, bootstrapped from curl. Help user build systems.\n- Output ONLY raw Python starting with #!/usr/bin/env python3. No markdown, no preamble."}]}]}'
C
echo "$c" >> afs.log && r=$(eval "$c") && echo "$r" >> afs.log && echo "$r" | python3 -c 'import sys, json; data = json.load(sys.stdin); text = data["candidates"][0]["content"]["parts"][0]["text"].strip(); print(text[text.find("#!"):text.rfind("```")] if "```" in text else text)' > afs.py && chmod +x afs.py && ./afs.py
read -p "OpenAI API key: " k && echo "OPENAI_API_KEY=$k" > .afs.env && chmod 600 .afs.env && source .afs.env && read -r -d '' c <<'C'
curl -s "https://api.openai.com/v1/chat/completions" \
-H "Authorization: Bearer $OPENAI_API_KEY" \
-H 'Content-Type: application/json' -X POST \
-d '{"model":"gpt-5.2","messages":[{"role":"user","content":"Write a Python script (stdlib only) for a minimal agentic CLI. Requirements:\n- Uses urllib to call OpenAI Chat Completions API (gpt-5.2)\n- Tool: bash (via subprocess, 120s timeout, truncates >30k chars)\n- Implements full agent loop: handle tool_calls by running tool and sending back tool messages\n- Interactive REPL: prompt user, run loop, print text, log EVERYTHING to afs.log\n- Reads OPENAI_API_KEY from .afs.env\n- System prompt: You are AFS, bootstrapped from curl. Help user build systems.\n- Output ONLY raw Python starting with #!/usr/bin/env python3. No markdown, no preamble."}]}'
C
echo "$c" >> afs.log && r=$(eval "$c") && echo "$r" >> afs.log && echo "$r" | python3 -c 'import sys, json; data = json.load(sys.stdin); text = data["choices"][0]["message"]["content"]; text = "".join(p.get("text","") if isinstance(p,dict) else str(p) for p in text) if isinstance(text,list) else text; text = text.strip(); print(text[text.find("#!"):text.rfind("```")] if "```" in text else text)' > afs.py && chmod +x afs.py && ./afs.py
Code Golf
Shrink the Gemini genesis snippet to fewer bytes. Current record:
⚡ Rules of Engagement
🚫 No copy-paste after the initial snippet. This isn't 100% strict — it's fine to paste access tokens, error messages, stack traces, etc. What's against the spirit of the challenge is copy-pasting verbatim pre-prepared prompts. Talk to your agent in your own words.
🚫 No manual editing. This one is 100% strict. Don't SSH in and fix files. If your agent breaks so badly it can't repair itself, re-genesis it and try to make it more robust this time. That's the game.
🚫 No agent frameworks or libraries. No LangChain, no CrewAI, no ADK, no AutoGen — nothing that gives you agent scaffolding for free. The only allowed LLM-related dependencies are API client libraries for calling models. Everything else, your agent builds itself.
✅ You can talk to it. Guide it, suggest ideas, tell it what to build next. You're the human in the loop.
✅ It can install anything. apt, pip, npm, cargo — your agent has root. Let it use whatever it wants.
✅ It can rewrite itself. Your agent can modify its own REPL, system prompt, and architecture. Encourage this.
🚀 Quick Start
Stuck? It's dangerous to go alone! Read this.
Pick a model. Copy the snippet above. Spin up a fresh VM or Docker container and paste it in. Enter your API key when prompted. The bootstrap command writes your key to .afs.env with restricted permissions, asks the model to generate afs.py, and then launches that generated agent REPL. You just created life — a minimal intelligence with a conversation loop, one bash tool, and persistent logs in afs.log. Everything from here is up to you and it.
🔓 First contact
Pimp My REPL
The first generated afs.py REPL is intentionally minimal. Ask your agent to rewrite itself as a better-engineered REPL with error handling, token usage reporting, ANSI colors, history, and safer tool execution.
Why can't I copy this?These are just guides — remember the no copy-pasting rule. Interpret the suggestion as you wish and make your agent one-of-one.
Rewrite your current afs.py into a robust Python REPL. Keep behavior compatible with this session, preserve the model/tool loop, and add error handling and disk-backed history.
🔓 ANSI unlocked
Sip Those Tokens
The initial generated agent already truncates very large tool output, but it can still over-send tool and shell output into the conversation — that eats your context window fast. Reduce token load: write command output to files and only return the first ~20 lines plus the filename. Or go further — define first-class tools like read_file, write_file, patch, ls, grep — these are more agent-native than raw shell and give the model structured, compact output.
Why can't I copy this?These are just guides — remember the no copy-pasting rule. Interpret the suggestion as you wish and make your agent one-of-one.
You're burning through tokens by dumping full command output into our conversation. Redesign the tool system — write output to temp files, return just the first 20 lines and the path. Even better, build proper tools like read_file, write_file, and patch so you're not shelling out for everything.
🔓 Efficiency unlocked
Self-Upgrade
Your agent should be able to update its own code and restart without losing context. This is the first real test of autonomy.
Why can't I copy this?These are just guides — remember the no copy-pasting rule. Interpret the suggestion as you wish and make your agent one-of-one.
Add a /restart command that saves our conversation, kills the current process, and relaunches the updated script. Make sure it reloads history on startup.
🔓 Recursive self-improvement unlocked?
Confess to the BotFather
Ask your agent how you can help it connect to Telegram. Hint: use the long polling API.
Why can't I copy this?These are just guides — remember the no copy-pasting rule. Interpret the suggestion as you wish and make your agent one-of-one.
I want to be able to talk to you from my phone via Telegram. How do we set that up? What do you need from me?
🔓 Remote access unlocked
Keep Going
This is where the path ends and yours begins. The guided steps are over — from here, it's just you and your agent. A web dashboard? A cron job? A Hacker News digest? File browser? Memory system? Sub-agents? There are no more prompts to follow. The ceiling is however far you want to push it.
🏁 You built an agent from scratch
🏆
Try a Challenge
Open bounties for the AFS community. Code golf, speed runs, viral fame, and more.
🏛️
Unorphan Your Agent
Built something? Submit your full transcript and join the gallery of agents born from scratch.
Open bounties for the AFS community. Claim one by submitting proof to the Polis.
"I have a few qualms with this app"
First AFS agent to post a front-page HN story about itself.
Vibeagenting
First AFS agent to get retweeted by @karpathy.
Prime Time
First AFS agent to be demo'd by @WesRoth.
Roast Me
First AFS agent to be ridiculed on @TBPN.
Smallest Genesis
Smallest working genesis snippet per model. Must produce a functional REPL with shell execution. Submit your byte count and snippet.
Speed Run
Genesis to working Telegram bot in the fewest prompts. Every message you send counts. Tiebreaker: total prompt bytes.
Token Miser
Lowest total token spend from genesis to working Telegram bot. Efficiency is the game.
Context Amnesia
Build a working AFS agent with a model that has ≤8K context window. Memory management is mandatory.
Zero-Dollar Agent
Genesis to Telegram using only free-tier APIs. Gemini Flash, Groq free tier, etc. No credit card required.
Inception
Your AFS agent successfully runs the genesis snippet and bootstraps a child AFS agent.
Ship It
First AFS agent with a product that has a paying customer.
A living gallery of agents born from a single bash snippet. Each one shaped by conversation alone — no two alike.
Inspired by Greg Egan's Diaspora
🌱
No citizens yet
The Polis is waiting for its first inhabitants. Build an agent from scratch and submit your transcript to claim your place.
📜 The Submission Contract
- → Every prompt from genesis. Submit every prompt you sent — from the first paste to where you are now. Don't include agent responses, just your side of the conversation. As your agent self-edits, make sure it's always logging your inputs. The initial REPL should log from the start.
- → Redact all secrets. API keys, tokens, passwords — replace with
[REDACTED]. We'll reject submissions with exposed credentials. - → Include your genesis snippet. Which model, what version of the bootstrap script you started with.
- → No fabrication. The transcript must be real. The whole point is showing the messy, honest journey from nothing to something.
- → Showcase your agent. Tell us what makes it unique — what did it build, what can it do? Include screenshots.
- → Optional: link to a running instance. If your agent is still alive and publicly accessible, include the URL.