pro/works discipline/version 1.1, in development, source not yet published

leanwerk Process management for model-driven projects Your process, executed rather than re-interpreted

leanwerk is process management for a project that is run, in part or in whole, by a language model. It puts the process into typed state and a small set of commands, and drives a person and an attached model through exactly the same surface. The problem it answers is ordinary and expensive: a process that lives in prose is read again and derived again by every session, slightly differently each time and at a price per token. leanwerk turns that into state and commands. The decisions, the rough path, the checklist, the tickets, the attached models and the forge each become a small, near-deterministic command over a typed per-project ledger, and a person and an attached model reach the project through exactly the same surface. What the industry now calls graph engineering is what falls out of that: a run built as a graph of small steps with tools at the nodes, rather than a loop.

Builds for

  • FreeBSD
  • Linux
  • macOS

Built with

  • Rust
  • GBLN
  • BSD-3-Clause

Delegates to

  • cargo
  • claude
  • gh
  • git
  • ssh
The leanwerk mark: a blocky L drawn as a mason's square, both strokes three cells thick, with a cross cut into the angle, extruded
Kind
A command-line control system over a project's own state
Version
1.1, stage Dev
Host
Rust, 2024 edition, from 1.85
Source
7,823 lines
Tests
324, in 7,536 lines of their own
Dependencies
Three, all pure Rust
Network
None. No socket, no TLS, no client
State
GBLN, one typed ledger per project
Doctrine
Embedded in the binary, byte for byte
Command groups
Fourteen, object then verb
Gate
Every state change waits for a person
Council
Seven voices: one gate, five vetoes, one debater
Install
Never machine-global. It lives in the project
Binary
1.18 MB on macOS arm64, stripped
Licence
BSD-3-Clause

01prose is re-derived

A process written in prose is re-invented every morning

Ask a session to follow a project's discipline and it does what a person would: it reads the documents and works out what they mean. That derivation happens again at the next session, and the next, from the same words, and it lands in a slightly different place each time. It is also the single most expensive thing in the session, because the whole discipline has to be in the window before the first line of work is done.

leanwerk moves the discipline out of interpretation and into the substrate. Each step of the process becomes a small command with parameters, and the state those commands operate on is a set of typed files rather than a shelf of Markdown. The knowledge ledger, the rough path, the checklist, the tickets, the attached models and the forge binding each have their own group of commands, fourteen groups in all, and the grammar is the same everywhere: object, then verb.

    leanwerk [-qv] [-m model] <group> <action> [operands]
    lw …                              a hard link with the identical surface

    lw knowledge create               a decision, recorded at the moment it is made
    lw roadmap list                   the rough path
    lw ticket close 0042              refused unless validation and Council are recorded
        

Each command runs both ways: a short interactive form that asks for what it needs, and a fully flagged form for scripts and for a machine. The flags follow getopt, clusters and attached values included, because a tool that behaves like a Unix tool needs explaining once rather than every time.

If the process is commands, what are the commands operating on?

02the state is typed

A ledger with types, not a directory of notes

The state behind the commands is written in GBLN, the typed record format from the same house: the type travels with the value and every string carries its own bound. A project's ledger is a handful of these files, one per concern, and they are the project rather than a description of it.

    major<u8>(1)
    minor<u8>(1)
    push<s16>(2607031319)
    stage<s16>(Dev)
    managed<s8>(yes)
        

The important word is schema-owned. A write does not edit the file; it rebuilds every field with its canonical type and then persists it, so a malformed record or a value past its bound is refused at the door instead of being stored and discovered later. The same form is the message the core checks between its own parts, which means the tool's data format and its internal bus are one thing and there is no second representation to keep in step.

Because the state is data rather than prose, the questions a project asks constantly are answered by reading rather than by deduction: what was decided and why, what is next, what is open, which model is attached, whether this push is stamped. A session that needs the state loads the state, not the eight documents the state was previously inferred from.

Data and commands, then. Who is allowed to drive them?

03one surface

The model gets no privileged path, because there is only one path

This is the part the rest of the design hangs from. There are two ways to run leanwerk and they use the same commands.

In the first, a person or an agent session drives the tool command by command. That is what runs today, including the session that builds leanwerk itself. In the second, leanwerk holds the loop: it composes the minimal context for one step out of the ledger, drives an attached model through that same command surface, and takes the result back through the same layer.

The tool's own note for this is that the second is a dress around the first. Nothing is built twice; every command written for the hand-driven mode is the command the loop uses, and neither mode is the fallback. The consequence is the point: a model attached to a project cannot reach past the commands on offer, not because it is watched, but because there is nothing else there. The fence stops being a fence and becomes the shape of the room.

Every model spawn is denied its own tools, so an attached model acts through leanwerk's surface and no other. How the tool reaches each model is itself a versioned record rather than compiled-in knowledge, but the tool-denial floor stays in code, where a per-machine override cannot reach it.

There is a fashionable name for the shape of this now. The industry calls it graph engineering: a run laid out as a graph of small, well-defined steps with tools at the nodes, instead of a model looping over a prompt until something usable falls out. leanwerk arrived at it from the other end, and earlier, by asking a duller question. What is a project's process, actually? Written down as state and commands rather than as prose, it is already a graph, and the loop was never the shape of the work; it was the shape of not having written the work down.

So the graph builds itself, and the shape of it is worth following because it is where the efficiency comes from. The roadmap is the plan and stays where it is. What moves is underneath it: an open question is put with three options and a marked recommendation, the owner answers, and the answer arrives as items on the checklist, or is refused with the reason recorded so that it is not asked again. Each item is then sorted by what it actually is. One narrowly bounded step becomes a short branch and is done. Anything wider, or anything carrying a signal, becomes a ticket with the full ceremony behind it, and in doubt it escalates rather than slips through.

The signals are the interesting part, because they are the specialists reaching back into the planning. A step becomes a ticket when a decision has to be recorded, when the acceptance criteria have to be agreed before the work rather than after it, or when the change has depth in security, architecture or a public interface, which is another way of saying that the review would have something to say about it. The project therefore sorts its own work by the standard it will be judged against, which is the part a person usually has to do by hand and usually does not.

Each step is composed from the ledger as it stands, driven through a near-deterministic command with a real tool behind it, and the result goes back into the state the next step is composed from. The reward is the ordinary one: fewer tokens per step, because the context is the minimum that step needs rather than everything that might matter; less time, because the steps do not wander; and an answer that holds, because each step was small enough to be checked when it was made. The project states the aim it holds itself to, and it is the fair one to quote: to beat the same project run free-hand on token cost, by determinism and planning rather than by improvisation.

Driven from prose

A session driven from prose A vertical loop. A few documents at the top feed a cycle: read everything again, work out what it means again, do the work, and hope it matched. An arrow runs from the bottom of the cycle back to the top, because the next session starts in the same place with the same documents and nothing else. a few documents Read it all again the whole discipline, every time Work out what it means a fresh derivation each time Do the work with the process held in the head Hope it matched nothing recorded for the next one and again next session, from the same place
Four documents and a habit. The discipline is read and re-derived at every session start, which is the most expensive thing in the window and the least repeatable: the same words land somewhere slightly different each time, and nothing the session worked out survives it.

A project that organises itself

A project that organises itself A vertical chain. The roadmap is the plan path and is rarely moved. Where something is genuinely open it is put as a question with three options and one marked recommendation; the answer becomes items on the checklist, or is refused with the reason recorded. Each item is then either a short branch, when it is one narrowly bounded step, or a ticket, when it spans several checkpoints or carries a signal: a decision to record, stated acceptance criteria, or depth in security, architecture or a public interface. Both go through the same validation and the same specialists before the merge, and the roadmap advances. Beside the chain a rail holds the drivers, which bind the work, and the knowledge ledger, which is read before the first line and written at the moment each decision is made. Roadmap the plan path, rarely moved A real question three options, one starred Checklist the answer becomes items Short branch one step Ticket a wider goal Validation the same gate for both The specialists seven voices on finished work Merge and the trace is complete or refused, and the reason recorded Drivers the binding rules Knowledge every decision and the plan advances, carrying its state
The same work as a graph the project builds for itself. The roadmap is the plan and is rarely moved; what an answered question produces is items on the checklist, and each item is then one of two things. One narrowly bounded step becomes a short branch, light on ceremony. Anything that spans several checkpoints, or that carries a signal, becomes a ticket: a decision that has to be recorded, acceptance criteria stated in advance, or depth in security, architecture or a public interface, which is to say anything the specialists will want to look at. In doubt it escalates. Both paths meet the same gate.

If a model can drive the commands, what stops it driving the dangerous ones?

04nothing changes without you

Read freely. The first write stops and waits

In the autonomous loop the model proposes one command per step on a plain line of text. A read-only command runs and its result feeds back. The first command that would change, delete or execute anything is prepared with its payload, recorded as a pending action, and held. It is not run. The loop waits for you.

    lw amode run  < task              drives the model; holds at the first write
    lw amode approve 0007             runs the held command, then resumes the loop
    lw amode reject  0007             resolves the hold, runs nothing, stops
        

The approve path is exactly once. leanwerk writes a marker before it runs the held command, so a crash in the middle leaves the action for a person to resolve by hand rather than leaving a machine free to run it twice. Approving resumes the loop from where it held, with the task, the history and the command's own payload replayed out of the record.

Four more fences sit around the same loop, and they are ordinary rather than clever: the step and token budgets in the project's own configuration, a stop file whose mere existence ends the run before the next step, an append-only record per step carrying that step's real token cost, and the allowlist that decides what counts as read-only in the first place. A budget left unset is no budget, and the tool says so rather than inventing a number on your behalf.

That is the loop fenced from outside. What fences the binary from inside?

05power is a handle

A module reaches what it was handed, and nothing else

Inside, leanwerk is built the way a microkernel is: a small core that mediates and implements nothing, and single-job modules behind one trait with one method. The core dispatches, supervises, validates and brokers; the work happens in the module that owns that one job.

What the core brokers is capability. A module does not ask for permission to touch the workspace, the clock, a subprocess or the ticket store; it is handed typed handles at construction, and only the core can make one. The absence of a handle is the absence of the power, which is a cheaper thing to reason about than a list of rules about who may do what.

The same instinct governs what leanwerk refuses to contain. It has no network stack, no TLS of its own and no HTTP client: three dependencies, all pure Rust, and its network surface is deliberately zero. Where a system already has a well-built tool for a job, leanwerk drives that tool instead of growing its own version of it, and keeps the skeleton for itself.

The jobWhat leanwerk does
Version controlDrives git, and installs its own hooks into it
Build and testRuns the project's own chain, each command directly, no shell
ForgeDrives the platform's own CLI; the token goes by reference, never on the command line
ModelsDrives the installed agent CLI, locally or over ssh
TransportNothing. There is no socket in the binary to secure

A tidy machine room. How would anyone know the discipline was actually followed?

06the specialists and the trace

Eighteen obligations, and no pass without evidence

Every piece of work carries a process trace: an enumerated list of obligations recorded in its own ticket. The ticket opened with its scope declared, the branch, the reading logged before the first line, the open questions routed rather than improvised, each decision recorded at the moment it was made, the steps in order, the validation green throughout, the roadmap and checklist updated, the merge and the history extended rather than tidied. An incomplete trace is not a warning; it means the review does not sit.

The seven who sit on it

The review is a council of specialists, and they are not a convention somebody remembers: they ship as data. A versioned record inside the binary carries each one's office, its rank in the order of precedence, a short brief, and the full instruction it is bound by, and each sits in its own context with reading tools and no writing ones. They are convened only on finished work that has already passed the gate, because a verdict on unbuilt or untested material is a rubber stamp by construction.

VoiceGuardsWeight
the ChairThe trace, the order of the steps, and mediation when two requirements collide. Walks the eighteen obligations first, from the artefacts rather than from memoryGates the session
the AuditorSecurity and provenance: input validation, memory safety, capability boundaries, error paths, secret handling, the supply chain, the licence allowlistBeats everything
the GuardianProduct scope, from outside the codebase: the operator, the buyer, the standard. Contracts, conformance, documentation that matches behaviour, and no quiet driftBeats the three below
the ArchitectArchitecture and elimination, and whether the change is coherent from every position that observes it: other actors, concurrency, retries, time, scale, a hostile callerBeats style and speed
the EditorThe written word: naming against a closed vocabulary, the register, the headers, the documentation, and every line a user will read in a terminalBeats speed
the ProfilerPerformance, measured rather than assumed: hot paths, allocations, locks, binary size, start-up costOptimises what survives
the N3rdBloat, in the code and in the process alike. Asks whether a leaner cut does the job the orthodox one misses, and puts it to the othersNo veto. Argues

They have names as well as offices, because a reviewer with a temperament argues differently from a checklist. The Chair is a master of the lodge, calm and exact and never assuming. The Auditor reads like a saga chronicler and trusts nothing he has not traced to its source. The Editor grooms relentlessly and lets nothing ship half-licked. The Profiler measures before she touches. The N3rd is a demoscene hacker who judges by cleverness rather than by the textbook, holds no veto at all, and is listened to anyway.

The order between them is stated rather than negotiated, which is what makes the review finish. Security beats everything. Scope beats architecture. Architecture beats style, because a system that is coherent from every side beats one that is merely tidy. Style beats speed. And speed optimises whatever survived the five above it. The one who did the work does not chair its review.

Three rules against a rubber stamp

A review that always passes is a cost with no product, so three rules stand in the way of one. A pass without named evidence is invalid: every verdict cites what was checked and where, down to the line. Every member has to answer what a hostile reviewer would attack first, and show it defended. And a claim about behaviour or performance has to point at a test, a profile or a conformance vector, because speculation is a fail rather than a caveat.

The same shape governs the questions asked along the way, which is the other half of what keeps a session from wandering. An open question is not improvised: it is stated in one sentence, put with three options and their costs, one of them marked as the honest recommendation with its reasoning, and then the work waits. When the answer comes it becomes a numbered entry in the ledger at that moment rather than at the end, so the next session inherits the decision and not the argument. Questions that the state can answer are not asked at all.

The effect is that the discipline can be checked by somebody who was not there, including somebody who would rather it failed. That is a different property from a project that was run carefully, and it is the one that survives the person who ran it.

A demanding standard to set. Does the tool meet it itself?

07its own first customer

The tool submits to its own discipline

leanwerk's repository carries a works directory of exactly the shape it generates for anybody else: the ledger, the rough path, the checklist, the tickets, the gate. It is not a demonstration tree kept tidy for visitors. It is the state the tool was built through.

measured7,823Lines of Rust
measured324Tests, in 7,536 lines
measured164Decisions in its ledger
measured3Dependencies

Counted from the tree rather than from the README: the sources and the test files as they stand, the ledger entries as separate records, the dependency list from the manifest. Tests live in their own directory, never beside the code they exercise, and they reach it only through its public surface.

The code doctrine it carries is stricter than most people would volunteer for, and it is the part that makes the rest legible. Nine verbs are permitted and they have no synonyms: read, write, create, delete, update, find, check, parse, render. The words that conceal what happens are banned outright, so nothing in the tree is called handle, process, manage or do. There are no framework suffixes, no abbreviations outside a declared allowlist, and every file opens with one sentence stating the single thing it is responsible for.

All of it traces to one axiom, which is worth quoting exactly because it explains why the rules look the way they do rather than merely being rules: preserve the developer's cognitive capacity for logic. Everything else is that applied recursively. Every unit does one thing, is sized by its scope, is named from a closed vocabulary, is readable where it stands, and is separated by concern. It holds for a function, a file, a module and a system alike, so a codebase that grows does not need new principles.

Convincing on its own ground. What happened on somebody else's?

Fielda stranger's codebase

What happened when it met a project it had never seen

The beta was run against a read-only clone of ripgrep at 15.1.0, a large and well-kept Rust project with a discipline of its own. The rule for the run was that only the shipped surface counted: the binary, its embedded doctrine, the manual and the man page. Anything the conductor knew from having built the tool counted as a documentation defect rather than as knowledge. Nothing was routed to the ripgrep project, no issue and no pull request, and the bed's push URL was mechanically disabled so that it could not be.

Five phases ran to the end. What worked, worked in the way you would want: the scaffold never overwrote an existing file, the whole ripgrep workspace built, formatted and tested through leanwerk's own validation chain in twenty-six seconds, and the exit codes were honest about every refusal.

What did not work is the part worth printing. leanwerk seized the project's version. It onboarded at 0.0 while the project carried 15.1.0, then instructed the operator to stamp, and the stamp overwrote the real version in the manifest and ate a trailing marker the project's own release tooling depends on. Worse, the reader and the writer disagreed about which line the version was on, so the check reported a dependency's version while the write went somewhere else entirely.

That is a high-severity design defect found by running the thing rather than by reading it, and it was fixed by changing the design rather than the symptom. An existing version is now detected at onboarding and the project's own scheme is left alone; the stamp refuses, naming what it found and the one command that opts in; and adoption takes the existing major rather than inventing one. The re-run walked the same path cold: the refusal taught, the opt-in worked, and the trailing marker survived byte for byte.

The next production run, on a different pair of repositories, came back with zero defects and two cosmetic observations. That is the shape of an honest beta, and it is the reason this chapter is on the page rather than in a drawer.

Edgeswhere it stops

Where it stops, and what that leaves you

  • It is not a build system, and not a continuous-integration service. It runs the chain your project already has and reports the first red honestly. What that chain contains is your business.
  • The autonomous loop is deliberately not autonomous where it counts. Every action that would change something waits for a person. If what you want is a machine that finishes the job overnight without asking, this is the wrong tool and says so at the gate.
  • The judgement parts need an agent. The binary supplies the doctrine, the generation and the loop; surveying a strange project and conducting its interview is work for a model or a person following the embedded protocol. It makes the discipline portable rather than making the thinking unnecessary.
  • It assumes git. The project root is found by walking up to the nearest repository, and the hooks it installs are git hooks.
  • A prebuilt binary exists for macOS on Apple silicon. Everywhere else it is a cargo build --release away, and it is never installed machine-wide: its home is inside the project it steers.
  • In development at 1.1, and parked while the work it steers is elsewhere. The tool is used daily on other projects; sessions on the tool itself open when the field sends something back.
  • The discipline is opinionated and does not apologise for it. Nine verbs, a ticket per piece of work, a council on finished work only. It suits a project meant to outlive the memory of the person who wrote it, and it is heavier than a weekend needs.

What it is, then, in the one line that has to survive the rest of the page: process management for a project run by a model, built so that the process lives in the state rather than in the prompt. That is where the efficiency comes from, and the efficiency is the point. A step composed from a ledger costs the tokens the step needs instead of the tokens the whole discipline needs; a step that is written down does not have to be worked out again tomorrow; and a change that waits for a person is a change nobody has to undo.