workflow

git clone https://git.godosa.eu/workflow

master

raw · 9085 bytes

wf — a shared workflow for many coding agents on one machine

wf is the task workflow I use to run several long-lived Claude Code sessions in parallel, each working in its own project under one folder (/projects). How to set it up and use it: docs/manual.md. It has three parts:

  1. One rules file for every agent. shared/CLAUDE.md sets out the loop each agent follows: cold start, test-first implementation, one commit per finished task, when to ask and when to decide, and how to report problems with the workflow itself. Claude Code loads CLAUDE.md from the working directory and every parent, so the file is symlinked once as /projects/CLAUDE.md and every project gets it. A project's own CLAUDE.md holds only project specifics and wins on conflict.
  2. A task tool, wf. Each project keeps its open work in a TASKS.md with stable ids. Agents never read or rewrite that file whole; they use one short command per operation (wf next, wf add, wf done, wf ctx, …), and wf check makes sure no reference rots.
  3. A memory/CPU ledger, wf res. Agents reserve memory and CPUs before a big or long job and get a clear "busy, retry after HH:MM" instead of out-of-memory kills. The owner keeps a guaranteed reserve, and a larger one in gaming mode. Built on systemd user units and cgroups.

Status: a personal setup, published as a reference. It is shaped around one person's machine and habits: Linux, systemd, Claude Code, one /projects folder. It is provided as is. Setup and daily use: docs/manual.md. There is no support and no plan for Windows or macOS. Take whatever ideas or code are useful to you.

Why

With one agent, a task list in a markdown file works fine. With five or more agents running for days, things go wrong:

  • Each project grows its own task scripts and workflow prose, and they drift apart.
  • Agents spend context reading and rewriting long task files, renumber items, and break references ("see task 14").
  • A workflow fix has to be copied into every project.
  • Two agents start a 10 GB build at the same time and one of them is killed, or the desktop freezes.

wf answers these with one rules file, a task format with stable ids, a CLI that makes every routine edit one command, and a ledger that rations memory and CPU.

The loop (shared/CLAUDE.md)

Short version. The file itself is the authority.

  • Cold start ("continue"): wf next shows the questions waiting for the owner, items that need a human, plans in flight, and the next pickable task with its context. The agent works on it without asking.
  • Task kinds: an implementation slice (at most about 1 h) is test red → implement → verify green. Design work goes through brainstorming → spec → owner approval → wf add slices. Bugs: evidence → failing test → fix.
  • Autonomy: decide, record the decision in the spec or task, report it. Ask only at real forks. Blocked on the owner → wf add -s awaiting "<question>" and move on to another task.
  • Done: wf done <id> -m "<entry>" archives the task and prints the project's checklist, wf check must report 0 errors, then one commit. Never merge or push unasked.
  • Resources: a job over 2 GB RAM, over 4 cores or over 10 minutes goes through wf res run. Exit 3 means busy: the agent notes it and works on something else.
  • Workflow problems: wf report "<what>" appends to a shared inbox. The agent works around the problem and keeps going. The owner's workflow session triages the inbox later.

TASKS.md

# Tasks — myproject

## Awaiting your decision

- **a-save-format**: JSON or binary saves? Blocks [[t-save-load]].

## Pending

- **t-cave-seams** [P1] (<1h): Terrain: cave entrance seams. Close the slit beside the lintel.
  - Tests (red first): seam test on the cave fixture.
  - After: [[t-terrain-cave-render]]
  Ref: DESIGN.md#terrain

- **t-save-load** [P2] (1h) (blocked: [[a-save-format]]): Save and load. Round-trip the world.

## Needs human

- **t-playtest-feel** [P1] (<1h): Play-test feel and tuning.
  - [ ] jump height

## Deferred

- **t-android-port** [P3] (10h): Android port.
  • Four sections. Items in Needs human are never picked by an agent.
  • Ids (t-… for tasks, a-… for questions) are stable and never reused. Links are written as [[id]].
  • Priority P0–P3, effort from a fixed list (<1h, 1h, 5h, 10h, 100h). Anything over 1 h is split into slices with --parent.
  • After: lists dependencies. Ref: points into the project's docs, down to a heading anchor. wf ctx and wf next print the referenced sections, so an agent loads only what it needs.
  • Finished tasks become one dated line in tasks/archive.md. The full history stays in git.

Commands

Run inside a project (a folder with workflow.toml). Every write command accepts --dry-run and refuses a change that would add a wf check error.

Read
next [--brief] what to work on now, with context
list · show · ctx items, filtered · raw items · an item or doc anchor with everything it links to
search <words> · log ranked search over tasks, archive and docs · newest archive lines
projects every project under the root: counts, next task, check errors
check validate format, ids, links, refs and anchors; exit 1 on any error
Write
add · done new item (id from the title or --id; --parent for slices) · archive finished tasks
prio · move · status · set reprioritise · move or reorder · in progress / blocked · header fields
rename · note · body · tick change an id and its links · append a line · replace the body · check a box
report · init · migrate file a workflow problem · start a project · convert a numbered task list
wf res
run --mem 10G [--cpus N] --for 40m --title T [--queue\|--force] -- CMD reserve and start a job as a systemd user unit; exit 3 = busy (--force: fit against really free memory, ignoring ledger claims; the busy line names it when it would fit)
status · wait · release · note reservations and budget · wait for a job · drop an entry · reserve for foreground work
game on [--for 4h] / off raise the owner's reserve; agents slow down, never get killed; with hook installed, agent commands get no display
hook Claude Code PreToolUse hook for ~/.claude/settings.json (see docs/resource-ledger.md §4.6)
clean · adopt · timer on/off · tick stale tmpfs scratch · move running sessions into the agents slice · 1-minute housekeeping

wf -h and wf <command> -h give the details.

Design notes

  • Pure core. wflib/ is text in, text out, with no file access. wf.py and wf_res.py do the I/O. Python ≥ 3.11 standard library only.
  • Live tool, safe releases. Every agent runs the main tree of this repo the moment it changes. Changes are made in a git worktree and fast-forwarded only when the tests pass and wf check gives the same result in every project as before. Commands are only ever added; a task-format change comes with wf migrate.
  • Concurrent writers. Task files are written whole via temp file + rename, and a write is refused if the file changed since it was read. wf report appends with one O_APPEND write. The resource ledger is a JSON file under a lock.
  • Ledger, not scheduler. wf res keeps no daemon. Every call reads /proc/meminfo and the ledger, admits or refuses, and starts the job as a transient systemd unit with MemoryMax inside agents.slice. A one-minute timer starts queued jobs, ends gaming mode and cleans up.

Full reference: docs/design.md (format, config, every command, release rules) and docs/resource-ledger.md.

Tests

python3 -m unittest discover -s tests

Licence and credits

MIT, see LICENSE. Credits: CREDITS.md.

From the author

These projects are things that have been tumbling about in my head for a long time, and I now feel like trying to do something with. The bulk of my focus here is on some of the games that I love, but every time I boot them up, I just fiddle about in the menu and set up mods and fixes for a couple hours, with my drive to play them fizzling out. This is my hope to solve that, and while I am a professional software engineer this would not have happened were it not for the rise of (relatively) cheap AI that could do the bulk of the work with me. If you don't approve, that's fine. I did these things for me, sharing them is something I do in the hopes to help others in similar situations, that just want to play the games they love. Thank you to all that made these playable in the first place, with some luck this finds you, and can bring some joy.

Written with AI assistance (Claude, by Anthropic), used as an engineering tool.