Scraper

Putting my /skills to use

From first question to a system that runs every morning.

bokeh

A while back I published a Claude skill called Socratic Agentic Workflow. The idea: before you write any code for an AI-driven system, the skill interviews you. Thirty minutes of questions across eight themes, and you walk away with five linked Markdown files covering mission, roles, file structure, system logic, and a handover brief a coding agent can pick up cold.

Publishing a method is one thing. Trusting it with your own project is another. So when I had an idea I actually wanted built, I became the skill's first real user: answered its questions, took the documents it produced, handed them to a coding agent, and shipped the result.


The project

I follow too many sources: blogs, newsletters, research feeds. Most days I either skim them badly or skip them entirely. I wanted a small system that checks a curated list of about 80 sources every morning, scores every new piece against a profile of my interests, and sends me a digest over email and Slack that takes five minutes to read. Every item linked directly to the source. No read-it-later graveyard, no algorithm deciding for me.

The interesting part isn't the crawling. It's the judgement. A keyword filter can find articles about AI workflows. It cannot find the essay about orchestral conducting that turns out to be the best thing I'll read about leadership all year. That fuzzy call is where a language model earns its place, and where plain code doesn't.


The stack

Python — the whole pipeline is a Python script. Straightforward choice: good scraping libraries, easy to schedule, easy to read back six months later.

LM Studio runs a local language model (Meta's Llama 3.1, 8 billion parameters) for scoring. I could have called a cloud API, but my reading profile is personal — I didn't want it leaving my machine. Local inference is slower and less capable than a frontier model, but for a relevance judgement against a known profile, a smaller model is plenty.

Gmail SMTP + App Password handles email delivery. No OAuth, no Google Cloud project, no token refresh logic. An app password is a credential you generate once in your Google account settings and paste into your password manager. Simple enough to still be working in two years.

Slack Incoming Webhook sends the Slack message. Same philosophy: one URL, one POST request, done. No bot setup, no API scopes.

1Password CLI injects credentials at runtime via op run. The script never sees a raw password — it only sees a reference like op://vault/item/field, and the CLI swaps in the real value when the script starts. Nothing sensitive ever touches the repo.

macOS LaunchAgent runs the pipeline automatically on login, once per day. A small state file records the date of the last run so a restart doesn't trigger a double send. This is the macOS-native equivalent of a cron job — no extra tooling required.

Cursor was the coding agent that built the implementation. It received the five Markdown files from the skill session as its brief and worked within the structure they defined.



What the interview caught

The skill's core rule is "always ask, never assume". In practice, it refused to let me get away with hand-waving. Three moments stand out.

It forced a real out-of-scope list. Asked what the system should not do, my instinct was to skip ahead. The skill didn't move on until I'd named hard boundaries. Those boundaries ended up shaping the build: no auto-saving into another reading backlog, and no endless link-following. The crawler runs exactly two passes — my curated sources first, then one hop into links found in pieces that scored well. New sources discovered along the way land in a pending file for me to review, never added automatically. That single rule is the difference between a tool and a runaway scraper.

It made my fuzziest idea concrete. I kept saying I wanted "things I wouldn't have found myself". The interview reflected that back and pushed until it became a named category in a five-point scoring scale — with the fifth slot reserved for pieces that have no obvious overlap with my profile, but that the model still judges I'll want. That category is the reason the system exists. Before the interview it was a feeling. After, it was a spec.

It said its assumptions out loud. Where I stayed vague, the skill stated an assumption, flagged it, and wrote it into the output files. One decision — how to pre-screen the second crawl pass so it didn't flood the scorer — was explicitly deferred to build time. Because it was visible in the docs the whole way through, it didn't catch anyone off guard when it came due.


The documents are the prompt

If you've read anything else on this site, you know where I stand on this: in AI-assisted work, documents aren't a record of decisions, they are the decisions. A well-structured Markdown file is an instruction set. The skill is built on that premise, so I won't pretend it surprised me. What this project gave me was the cleanest end-to-end proof of it I've had so far.

The handover file the skill produces ends with a ready-to-paste first prompt for a coding agent: read the mission and structure files first, build this component first, don't create anything outside the defined folders, ask before deciding anything the docs don't cover. I pasted it into Cursor. The agent built inside the lines.

The role definitions read like job descriptions because that's what they are: one part fetches, one part scores and filters, one part deduplicates and delivers. The logic file declared — before a single line of code existed — that if scoring fails, the run halts and sends an alert, because a digest without judgement is worse than no digest at all. Decided in conversation, written into a Markdown file, built exactly as specified. No drift between what was agreed and what was made.

That last part is the point. The gap between intent and implementation is where most product work goes to die. When the planning document and the build instruction are the same file, that gap has nowhere to live.


Reflections on v0.2 of the skill

Honest friction, because a write-up without it is just marketing.

The "no implementation details" rule leaked — and that was fine. The skill instructs itself to stay at logic and intent, no implementation details. But the constraints theme asks where the system runs and what tools it must use, and honest answers to those questions are implementation. The docs were better for containing them. The rule in v0.2 should be "no code", not "no implementation".

Deferred assumptions are IOUs with a due date. The one decision we postponed explicitly still cost a rework loop mid-build. A future version of the skill should distinguish between decisions that are safe to defer and ones that sit on the critical path — and refuse to defer the latter.

The 30-minute frame held because I knew the idea cold. I'd been thinking about this project for weeks before I ran the interview, so my answers came fast. With a fuzzier idea, the frame would burst. The skill needs a graceful "park it and return in a second session" move, rather than compressing themes when time runs short.

None of that changes the headline result. My own skill interviewed me, caught what I would have glossed over, and produced documents strong enough that a coding agent built a working system inside them. The interview was the architecture review — it just happened before the architecture existed.


The skill is MIT-licensed and lives at github.com/Kimotep/skills

skillAI
TJ

TJ

Lead designer and technical writer focused on the intersection of human psychology and digital craftsmanship.

Writing index