This is a submission for the Hacktoberfest Open-Source AI Challenge Week 3: Slow and Steady In the last 8 years, I've been collecting a ton of bookmarks on different apps on interesting projects, tools and topics. At some point, the numbers of saved links have increased a lot that it turned impossible to review them by myself. Hacktoberfest 2026 Week 3 challenge theme inspired me to prototype a small swarm of agents that help me automate the curation of this huge amount of bookmarks sitting next to me, and build at the same time a personal skunkworks division that generates knowledge, help prototyping ideas and build a portfolio of skills. I took a sample of bookmarks from my Google Chrome (which currently holds ~8,130 bookmarks). One folder, Reading List: since March 2025 I have saved 1,017 links to it, every one of them "to learn by building". I have built nothing from it (so lazy).
That folder is the prototype's test bed: 1,017 of 8,130 bookmarks, about 12.5% of the pile. The other 7,113 are next.
Skunkworks Sloth is three small agents that do the part I kept putting off:
Each agent has its own Discord channel. My part of running it is three replies a day: tap a card, say go, say approve. The rest of my time goes into what the sloth can't do for me: reading the daily link and reviewing the code before I approve it.
Who gets to be lazier: anyone with a bookmark folder full of good intentions. I'm the first user.
All three agents are deployed with their independent profile in an Hermes instance, and communicate their work on specific channels within my personal Discord server.
The curator agent is in charge of processing batches of bookmark sources. Once it finished, it provides a summary reports, and highlights any links that needs a review from me
Above, the curator reports an odd link that I can check and either keep it or send it to valhalla.
A specific channel reports all links that were sent to valhalla for a final human triage. Here, I can confirm which ones to pick and the ones to dispose based on their status
The coordinator agent then turns the curator’s curated links into a skunkworks backlog. It uses Github projects to build a Kanban board that I can checkout from time to time
Moreover, the coordinator also builds a second brain using the Open Knowledge Format (OKF) format for keeping a knowledge base that can be used by me or other agents.
Every week, the coordinator will ask me for my preference around the topic of focus. He proposed a few based the knowledge and skunkworks kanban status.
Then, every day I get to pick a topic-specific project/idea to explore and communicate my decision to the coordinator. It then, forwards it to a worker agent that will assist me in the initial prototyping.
Additionally, the coordinator suggest me a daily reading post from those bookmarked links that are not touching any code.
Once the worker agent receives the ticket information from the coordinator, it awaits for my command to start a building session. I can tell it which model to use, either an open weights served by OpenRouter or a Anthropic model in case of more complex tasks.
Finally, the worker reports its works and verify that testing passes. I review the code and docs, make adjustments, and approve the prototype to be published as a repository on Github. The skunkworks kanban board and second brain update through the process.
Monorepo for my Hacktoberfest 2026 challenge entries and the knowledge base behind them.
Hacktoberfest 2026 is run by MLH and DEV, presented by DigitalOcean. The theme is "AI belongs to everyone": build with open-weight models and open-source AI. Pull requests no longer count. Rewards come from virtual stickers (see STICKERS.md), and the DEV Challenges carry cash prizes.
Each challenge lives in its own folder under challenges/. I'm starting with the weekend challenge and adding the others as they open.
| # | Challenge | Window (UTC) | Status |
|---|---|---|---|
| 01 | Weekend: Build for a Friend : RC Pit Companion | Oct 2 02:00 → Oct 5 06:59 | ✅ Published |
| 02 | Week 1: Touch Grass : Idea Leash | Oct 5 18:00 → Oct 12 06:59 | ✅ Published 2026-10-11 23:30 local |
| 03 | Week 2: Side Hustle : PartsPaddock | Oct 12 19:00 → Oct 19 06:59 | ✅ Published 2026-10-18 23:21 local |
| 04 |
The project lives in challenges/04-week3-slow-and-steady, MIT licensed. The three agents ship as Hermes profile distributions, so scripts/install.sh sets them up on another Hermes host in one step (or next to agents you already run).
The green zone is my laptop, and everything that reads my links lives there:
sloth`` curator, board, builder and core.
The blue zone is hosted: the Worker's coding models, Postgres on Tiger Data, and GitHub. The purple zone is Discord, where I talk to the agents.
The rule I kept all week: models do language, code does rules. No agent decides what gets deleted, built or pushed; it runs a command, and the command checks.
Crons post first: at 07:00 the Curator triages anything new, at 08:00 the Coordinator posts today's reading, and at 09:00 it posts three or four cards weighted by my weekly focus. I tap one and say go in #sk-worker. The Worker builds for up to two hours, posts a summary with the test result and the cost, and waits. approve N pushes a private repo and moves the card to Built.
Valhalla is a proposal, never a deletion. I reply empty or restore 3, 7, and the sloth writes a removal list. It never edits Chrome's bookmark file.
The Coordinator clustered the build pile into 58 cards, each with a learning goal, a hypothesis, a done-means and kill criteria. Every arrow except the box timeout is one of my replies. A run that finishes waits in Building until I approve it, and a box that ends without meeting its done-means is Killed, with honest notes.
Each agent is a Hermes profile with one job: its own model, skills, crons and channel. Deny rules block sudo, Docker and keychain commands, risky commands need my approval, and computer use is off. That's a command policy, not a sandbox: the agents still run as my user.
The Worker has two providers. By default it codes with Gemma 4 26B A4B, an open-weight model, through OpenRouter. When a card needs more, I say go deep and the same box runs on Anthropic Claude Sonnet 5.5. Every message about those runs says "(closed model)", and the cost is tracked either way. I can also name a model, go with qwen3-coder-next, from a short allowlist in the config. The desk refuses anything else, so a typo can't start an expensive run.
links is the hub. Triage keeps its history (1,098 rows for 969 links), so a page the browser reads later can change its verdict. events mirrors the #sk-logs channel, which is where every number in this post comes from.
Gemma
Browserbase (Stagehand)
extract() with a custom LLM callback pointed at the local Gemma, one browser session per batch, and a drain step after every timeout (see below). It read 197 pages, including 37 of 40 X posts in its last pass.
Tiger Data
sloth apply-schema, triage history kept as rows, and a partial unique index for "one main reading per day".
My reading list is a diary of what I was curious about for a year and a half. With Gemma running locally, none of the 969 pages left my Mac to be judged. Triage, the browser step and the models behind the Curator and the Coordinator all run on the laptop; only their chat messages travel through Discord.
Local also means re-running is free. I re-ran triage on parts of the list several times this week as the prompt improved. With a hosted model each pass would be another bill; with Ollama it's electricity and a few minutes.
Open weights keep the Worker honest. Its default coder is Gemma 4 26B: hosted on OpenRouter and paid per run, but an open-weight model I could move home. When I choose go deep, I trade that for a stronger closed model, and the run says so.
The harness is open too. Hermes let me harden each profile and package all three agents as distributions, so the setup is scripts/install.sh on any other Hermes host instead of a page of instructions.
The coordinator session, curated and scrubbed: from the first idea to three parallel lanes, the failures above, and the measured run.
| Before | After | |
|---|---|---|
| Bookmarks waiting | 8,130 in Chrome, 1,017 of them in the Reading List | the Reading List fully triaged: 969 links, a reason each; 7,113 bookmarks still to go |
| Prototypes built from the list | 0 | 1 on open weights, approved and pushed (plus 1 labelled closed-model test) |
| From "what should I build?" to a tested repo | never happened | about 20 minutes: pick, go , a 4.9-minute build,approve |
| Cost of that build | n/a | $0.11 on Gemma 4 26B A4B (OpenRouter) |
| My time per day | (not doing it) | a few replies to run the loop; 30-120 minutes in total including reading and reviewing the generated code before approve |
| Reading | a pile of 609 | one link a day, picked for this week's focus |
The first open-weights build was the card I picked on Sunday evening, Private Aztec Sandbox Smart Contract. The Worker wrote a Noir counter contract with private state, two tests and a demo in 4.9 minutes. My first look said it failed: the runner checked make test without the Aztec toolchain on its PATH. With the same PATH the Worker had, both tests passed. They run in Aztec's test environment (TXE), not against a live Sandbox node, which is less than the Worker's own notes claimed. That gap is why the runner checks every build itself instead of trusting the agent's report.
My saved links don't only live in Chrome. The next sources are the bookmark piles on X and Facebook, flowing into the same links table (it already has a source column), so everything downstream stays the same.
GET /2/users/:id/bookmarks, OAuth 2.0 with the bookmark.read scope, the 800 most recent). The fallback needs nothing new: Stagehand already reads X posts, so it can scroll x.com/i/bookmarks in my own logged-in local Chrome and extract each post.facebook.com/saved in the local browser.
Either way, the browser stays on my machine, the model stays local, and the agents don't change.