tooling
The Loop Is the Skill
Skills are most useful when they are wired into a repeatable loop: plan the work, write it to durable task state, execute one task in a fresh context, and let a monitor keep the workflow moving.
I've got a question for those on the internet viewing this, what do you think the best way to utilize agents are now that there are so many tools out there?
You could say its having a self hosted containerized always on agent that does it all automated tasks for you, others would argue that its running multi-agent orchestrations and whole teams and companies being simulated across your projects.
I think all of those are valid and still pushing the bounds of agentic usage. For me I keep coming back to the fundamental use-case of agentic coding:
How do we create a loop.
More specifically, it is the loop you can actually seamlessly with minimal supervision.
I think that is highlighed in my current agent skills repo. I have a small general set of skills that I reuse across projects, and the main value is not that each skill is individually clever. The value is that they fit together into a workflow that turns a vague idea into scoped work, scoped work into JSON task state, and JSON task state into clean one-task agent runs.
The best way I have found to use skills is to make them part of a looped workflow where one skill could invoke another in the process
That sounds simple because it is simple. That is also why it works.
The shape of it
The core loop in my setup is built around three skills from my shared skills repo:
project-planstart-taskralphloop
There are supporting skills around the edges, mostly query-workboard and edit-workboard, but the main flow is this:
idea from me
-> project-plan
-> clarifying questions
-> documentation proposal
-> workboard tasks
-> start-task
-> one task claimed
-> relevant docs and files loaded
-> implementation
-> verification
-> docs updated
-> commit
-> ralphloop
-> monitor agent stays alive
-> fresh worker agent per cycle
-> worker runs start-task
-> worker reports summary
-> monitor decides whether to continue or stop
Makes sense and pretty simple right?
There is no grand distributed agent corporation living in my terminal. There is no always-on department of synthetic staff members waiting for a quarterly planning doc. It is a pretty small workflow that depends on written state, short-lived workers, and a monitor that can stop when something gets weird.
And that matters because I am a solo dev and I can't afford to be 'doing allat'.
I only have my free time outside my 9-5 and I especally do not have the capital to be running up API costs. I have the paid consumer plans I can justify, where I still hit usage limits, and I usually cannot generate enough parallel work to fully use some giant swarm setup anyway.
So my workflow is optimized around a different constraint: make each agent run count.
Start by planning, not implementing
I almost always start with project-plan.
That skill is intentionally annoying in the right way. It does not immediately jump into implementation. It reads the project instructions, infers the relevant docs, gathers only the context it needs, then asks clarification questions before proposing a documentation direction.
The planning step gives me a place to talk through the idea with the agent before the repo changes. I can say, “I want to add this feature,” and the agent can push back on scope, identify affected surfaces, call out missing constraints, and turn the fuzzy shape into something the repo can actually absorb.
For me, the important part is that project-plan creates the pipeline into the workboard. It starts with questions, then moves into docs, then writes tasks only after the direction is accepted.
That sequence is doing more work than it looks like:
| Phase | What it protects |
|---|---|
| Questions | Stops the agent from guessing product intent and pins direction |
| Docs proposal | Locks in behavior before code and stays as something known for future agents |
| Workboard tasks | Turns the plan into durable, queryable work |
This is where the workboard becomes more than a TODO list. It is the agent’s kanban board, but it is also the boundary around the next context window.
I wrote about the bigger doc side of this in [[documentation-is-agent-infrastructure]]. The short version is that agents need repo-native structure. They need maps, constraints, routing rules, and a place to write down what work exists. If every new session starts with a private briefing from me, the workflow is already losing.
Why JSON works so well here
My workboard is a set of JSON task objects. I typically boast about the effectiveness of 'md' files with agentic usage but here we want a different outcome.
One major reason for that but first allow me to explain,
A task has a predictable shape:
{
"id": "GROUP-01",
"title": "Implement the thing",
"description": "One implementation-ready paragraph with clear boundaries.",
"status": "todo",
"priority": "medium",
"group_id": "GROUP",
"depends_on": [],
"blocked_by": [],
"acceptance_criteria": [
"Observable outcome the agent can verify"
],
"docs": [
"docs/ARCHITECTURE.md"
],
"files": [
"src/lib/server/example.ts"
],
"commands": [
"npm run test:run",
"npm run lint"
]
}
The exact fields are less important than the contract. The task tells the agent what it is, why it exists, what has to be true when it is done, what docs and files are likely relevant, and what commands prove the work.
That brings me to my biggest point and the reason why JSON is chosen,
JSON objects are queryable.
I do not want an agent dumping the whole workboard into context every time it needs a task. That is how you turn a useful task file into context sludge.
Instead, the agent uses targeted queries:
jq '.tasks[] | select(.id == "TASK-ID")' docs/workboard.json
Or it asks for the next startable item by filtering for todo, empty blockers, and completed dependencies. The agent gets the slice it needs, not the entire board.
That matches the argument in [[against-infinite-context]]. More context is not automatically better. A task runner does not need the full mythology of the project. It needs the right task, the relevant docs, the expected files, and the acceptance criteria. Everything else should stay on disk until it is needed.
One task, one worker
Once the workboard exists, start-task is the skill that keeps execution disciplined.
Its job is not to be fancy. It executes exactly one task from the workboard. It checks dependency rules, claims the task, reads the task’s docs and files, implements only what the task describes, runs the verification commands, updates docs, marks the task done only after checks pass, then commits.
start-task keeps the agent within the guardrails and focused on the planned implementation.
Remember, docs are the source of truth
It should go something like:
select one startable task
claim it
load only the relevant context
implement the requested behavior
run the listed checks
update the docs that changed
mark the task done
commit
summarize
This is also why I care so much about the task schema. If the task is vague, the worker is vague. If the task has crisp acceptance criteria and real verification commands, the worker has something to push against.
The loop does not remove judgment. It moves judgment earlier, into planning and task design, where I can actually shape the work before a worker starts touching files.
And with that the loop is complete
The end-to-end workflow is wrapped by ralphloop. The main reason all of these skills come together so seamlessly.
This skill is directly inspired by Geoffrey Huntley’s Ralph loop: run a coding agent in a loop, give each iteration fresh context, make it do one task, persist state to disk, then start again. The part I like is the brutality of it. Fresh context, one item, written plan, repeat.
My version combines that with the part of Steve Yegge’s Gas Town that clicked for me: an orchestrator should be able to oversee workers instead of every worker becoming a long-lived conversation that I have to babysit manually.
So in my setup, the agent I invoke ralphloop on becomes the monitor. It does not implement tasks directly. It creates one worker per cycle, points that worker at start-task, waits for the worker summary, then closes that worker and decides whether to continue.
A typical invocation looks like this:
ralphloop start-task iterations:3
That tells the monitor to run up to three cycles. Each cycle gets a fresh worker, and each worker is expected to finish with a summary block like this:
RALPH-SUMMARY-START
STATUS: SUCCESS|FAILURE|BLOCKED
TASK_ID: <task id or n/a>
TASK_TITLE: <task title or one-line summary>
DOCS: UPDATED|N/A|MISSING (<brief detail>)
TESTS: PASS|FAIL|SKIP (<brief detail>)
FILES_CHANGED: <comma-separated paths, max 5>
COMMIT_MSG: <one-line commit message, max 72 chars>
PUSHED: YES|NO (<sha or reason>)
FAILURE_REASON: <reason or none>
WORK_DONE: <brief summary of completed work before stop, or none>
PRESERVED_CHANGES: YES|NO (<brief worktree state or reason>)
RALPH-SUMMARY-END
This output block is simply meant for the orchestrator. It needs the status, the task, whether docs and tests passed, what changed, whether there is a commit, and what went wrong if the worker stopped.
What we keep out is the actual work implemented.
That keeps the monitor context clean. It has enough surface-level context for me to interact with it if something breaks, but it is not slowly drowning in every worker’s full transcript.
Why not go bigger?
There are bigger systems out there. Agent swarms, always-on agent departments, worker-manager hierarchies, OpenClaw-style setups, Hermes-style systems, Gas Town itself. I get the appeal. I also think a lot of that work is genuinely interesting and wish to experiement with soem of those in the future.
There are still two underlying blockers for me that I've breifly touched on.
First, I am a solo dev. I do not have a constant backlog of work or tasks large enough to justify a massive agent department. Some weeks I have a few focused tasks. Some weeks I have one weird bug and a half-written blog post. Building a whole synthetic org chart around that would be funny, but also kind of ridiculous and not useful.
Second, usage limits are real. I pay for the plans I use, and I still hit the ceiling often enough that I feel it. A workflow that assumes I can casually burn dozens of concurrent agents for every change is not my world right now.
So my setup is intentionally smaller:
- durable tasks instead of long memory
- fresh workers instead of one bloated conversation
- a monitor instead of fully headless automation
- targeted queries instead of giant context dumps
- commits and summaries instead of vibes
That last one matters. I do not want a loop that silently runs away from me. I want a loop that can make progress while still giving me good control points.
The monitor agent is the compromise I like. If a worker fails, blocks, or needs clarification, I can talk to the monitor. The monitor has the rough shape of what happened, the worker summary, and the current loop state. That is enough to steer for debugging or diagnostics or even review if I so choose.
The skills are small on purpose
The funny thing is that none of these skills are magical by themselves.
project-plan is a planning workflow. start-task is a disciplined task executor. ralphloop is a monitor loop. query-workboard and edit-workboard are careful ways to read and mutate task state without torching the context window or rewriting the whole file.
The useful part is the combination.
project-plan creates the board
query-workboard finds the next safe task
start-task completes one task
edit-workboard keeps the board accurate
ralphloop repeats the cycle with fresh workers
That is the pattern I keep reaching for across projects. It is small enough that I can understand it, strict enough that agents can follow it, and flexible enough that every repo can still have its own docs, commands, and weird local rules.
For now, I have not found anything more useful or efficient for how I actually work.
Maybe that changes. Maybe the bigger orchestrators get cheap enough and simple enough that I start using them every day. I am open to that.
But right now, the thing that works is a modest loop built around durable state and fresh context. Plan the work. Write it down. Run one task. Verify it. Commit it. Start fresh.
Nothing flashy just the essentials.