You came here from the screen you left, and it is still open behind you. Back to the screen you left
Using it · page 11 of 17
The loop, step by step
One requirement, from a sentence to a sealed record. This is the whole product in one pass, with what you see at each step.
The example is small on purpose, and real: a litre total on a phone app's home screen.
1. You write the ask
Show the litre total with its unit on the home screen. The home screen shows a number with no unit, and a reader has to know it is litres. Show the unit. Acceptance criteria 1. the home screen's total reads "12 345 L" with a space as thousands separator and a space before the unit 2. a test named
home total > shows the unit after a space
Two things make this a DoneMark requirement rather than a ticket. The criteria are things a machine can be asked about. And the second one names a check by the exact string the test run will report, so there is no argument later about whether it passed.
You do not have to write the lines yourself. On A new feature, type what it should do in one line and press Draft the "done when" lines. DoneMark drafts three to six lines from your sentence and the project's brief, each labelled Drafted by DoneMark · yours to change. A line that cannot be tested as written comes back as a question with a testable wording to take. Edit any of them, or + Add a line of your own.
Each line says how it will be seen — by a check (an automated test), a picture (a screenshot a person looks at), a journey (a path through the running app, see Seeing it running) or a record entry. A line that does not say yet reads Not said yet, and cannot be approved until it does. Under More…, you can add up to three sketches of what you mean.
Three other ways in. Start from a plan — A website people sign in to — which asks four questions and drafts five features and a security baseline in your words. Bring your GitHub backlog in: Read the backlog drafts each open issue, says which are ready and which need an answer first, and you take the ready ones together. Or write it by hand, as above.
What you see: the requirement, in draft, or Approve 4 lines if you are its judge.
2. You approve it
The words freeze — Approve as judge: "These are the rules I will judge by." From here, agents and evidence refer to these words, and nobody — including you — can move the target. On the requirements list, a judge can tick several drafts and Approve 3 features at once, each by name; only a draft whose every line says how it will be seen can be ticked.
Its envelope freezes with it: what an attempt may spend, how long it may run, which files it may touch.
What you see: approved, and a Dispatch control.
3. You dispatch
DoneMark queues the work. The runner in your repository — on GitHub's machines or your own — asks DoneMark whether there is anything, takes it, and runs your agent with your key.
DoneMark is not running anything. It wrote down what was asked and is waiting.
What you see: building.
4. The agent works, and pushes twice
A good attempt pushes the check failing first, with no implementation behind it, and lets CI record it red. Then it writes the code and pushes again.
That is not ceremony. It is the only way the record can ever show the check failing. A check written and implemented in one push is only ever seen passing, and on the record that reads as passed, but unproven — indistinguishable from a check that could never have caught the bug it claims to catch.
What you see: commits appearing, CI runs starting.
An attempt does not say it is done while the checks on its last commit are still running. It waits, and the run page says it is waiting. That is why a door does not open the moment an agent stops working — what it pushed has not been read yet, and a verdict given before the evidence arrives is a verdict on the commit before it. If the checks never start at all, the attempt reports anyway and names the commit it never saw a run for.
5. Your CI runs, and publishes
Your tests run on your machines, as they always did. The workflow publishes the per-check report, the same report from before the change, and the coverage.
DoneMark did not run a thing.
6. DoneMark looks
It reads the runs, the artifacts, the diff and the pull request, with a token minted for that repository alone, and writes down what it observed — each piece with its source.
For each criterion it asks a ladder of questions: was a check named, did it run, what did it say, was it ever seen failing before the code existed, does it touch the lines that changed, does it notice when they break.
What you see: evidence arriving.
7. The door opens
When the attempt's own evidence has settled, DoneMark opens the door and tells the judges — in what waits for you, by email, and in Slack if you set it up.
What you see: validating, and the run page, which leads with what a careful judge weighs first:
- the criteria and how far each one's evidence goes
- anything red beyond your criteria, named, with its first error line
- for each check run, whose fault it is — the code's, the machine's, or superseded
- the agent's own claims, in a column of their own
- a reason already drafted from what DoneMark saw, for you to edit
8. You decide
Sign off or Not quite, with a reason. DoneMark never writes either for you; it puts the button order behind the facts and leaves the choice. The reason starts as a draft from what DoneMark saw, for you to edit or replace, and both buttons refuse while it is empty: a verdict without one is not a record.
Beside the reason, What I tried holds what you checked yourself on your own device, and one screenshot — marked as your own observation, never as something CI witnessed. When you say not quite, you can mark the screen where it is wrong; the next attempt is given your marks with the photograph.
Sign off and a DoneMark is sealed: numbered, dated, naming you as the person who accepted it and saying you are outside the harness that built it. If you are also the author, it says that too.
Under your reason on the sealed record, Make this reason a decision turns what you wrote into a rule every later attempt is told (The brief and the decisions).
Not quite — a refusal — is recorded just as fully, with your reason and the evidence you read, and the next attempt starts from this one's branch with your words in its instruction. It takes no number: a DoneMark number means a person accepted, so a refusal never carries one and never stands in a list of sealed work. Its record has a page of its own, reached from the requirement and from the attempt it judged.
9. It goes live
An accepted requirement queues a release. DoneMark merges it, your deploy runs, and DoneMark watches for the application answering at that commit before it says live. Live is observed. On Vercel, the release waits for Vercel's own production deployment of that commit, and needs no token of Vercel's.
In a release, one press seals every requirement that looks right and puts the release live together.
What you see: verified, and the release moving from queued to live.
10. The record stays
The sealed DoneMark does not change. Link it, show it to a client, read it in a year. It says what was asked, what CI saw, what the agent claimed, who accepted it and when.
The standing queue
You do not have to press Run. An approved requirement stands in a queue, and a runner asking for work is handed the first one in it. The order is yours, set by dragging on the requirements list; a refused requirement stands ahead of an approved one, because somebody is waiting on a fix.
approved requirements, in your order
┌──────┬──────┬──────┬───────────────┐
│ 1 │ 2 │ 3 │ … │
└──┬───┴──────┴──────┴───────────────┘
│ a runner asks for work every 30 s
▼
one attempt per lane, one attempt per requirement
A project has lanes: how many attempts it may run at once. Two agents on one requirement would race each other's branches, so a requirement gets one attempt at a time whatever the lanes allow.
Releases come first
A release that has not landed holds the queue. An attempt started underneath it would be built on a default branch the project is in the middle of leaving, and a door would open on work that was never standing on today's code. So the queue waits, and the wake takes the releases first.
The reverse is also true: a release pressed while an attempt is running is kept, not refused, and takes itself the moment the ground is free.
What leaves the queue, and what comes back
Two attempts that end with nothing for a judge to read take a requirement out of the queue. Nothing about the requirement changes — it stays exactly as you left it, and you can still dispatch it by hand. The queue simply stops spending attempts on something that is failing for a reason no attempt is going to fix.
When many attempts fail the same way at once — an account out of quota, a provider down — that is one fault repeating, not the backlog failing. The queue stops where it stands and names the error that stopped it, rather than walking down the backlog spending an attempt on each.
Letting the queue go again forgives those failures: attempts that ended before you let it go no longer count against the requirements they landed on, and the ones they took out come back. The queue says how many it put back.
Migration numbers
Two attempts off the same default branch would otherwise both write the next migration number and collide at release. A number is taken when an attempt claims it and released when that attempt ends, so the second attempt is told the number is gone and takes the one after it.
The same loop, without DoneMark's runner
If your team already runs Devin, Copilot, Cursor or your own scripts, you do not need DoneMark's runner at all. Open a pull request whose branch or title names the requirement, and DoneMark records it as an attempt on that requirement: your author, your branch, your pull request. Steps 5 to 10 are identical.