Work tracking: assume the session ends in 30 minutes
Plan as if this session can stop at any moment. Token budgets run out about every 30 minutes, workstations crash,
and disks get reformatted. Anything that exists only in this session's context, in an uncommitted file, in a scratch
or /tmp directory, on one machine's disk or in an agent's private memory is lost when that happens. GitHub is
the record. A fresh agent on another computer must be able to continue from the issue, the branch and the PR
alone.
The loop
- Find or open the issue first. Search before opening:
gh issue list --state all --search "<words>". Open one per piece of work that will take more than a few minutes:gh issue create --title "<outcome, not activity>" --body-file <file>. Write the body with the template below. A large job gets a tracking issue that links smaller ones. Then check who holds it and claim it. Several agents on different tools and machines work the same repos. Read the issue's latest work-claim comments: if another agent holds an unexpired claim, pick other work or claim a separate scope. Otherwise post aclaimbefore changing anything. - Branch from the integration branch and push it at once. Follow the repo's AGENTS.md / CONTRIBUTING.md: in
cad-agent that is a
feat/<topic>worktree fromorigin/dev; in a product repo, oftendev. Push before you have much to push (git push -u origin <branch>), so the branch exists remotely from the start. - Open a draft PR early with
Closes #<issue>in the body:gh pr create --draft --base <base>. List in it what is still missing. CI on a draft may fail; say why in the PR. - Commit and push in clean chunks. One coherent change per commit (it builds, its message says what and why), pushed right away. Never batch an hour of work into one local commit. Generated files are committed only when they are regenerated by the committed sources (no hand-edited exports, no stale evidence).
- Checkpoint about every 30 minutes, and before anything long or risky. A checkpoint is:
- commit and push everything worth keeping (WIP commits on your branch are fine; say
WIPin the subject); - tick the issue checklist and add a short comment: what changed, what is running, the exact next step;
- for each run in flight, the host, command, log path and how to collect its results (see
cad-remote-runs). Ask yourself: "if this session ended now, could someone else continue from GitHub without asking me?" If not, checkpoint. Post it as a work-claimcheckpointso it renews your lease (at least once a day).
- commit and push everything worth keeping (WIP commits on your branch are fine; say
- Close out as you go. When a PR merges, its
Closes #Ncloses the issue; check that it did, tick the tracking issue and comment with the merge commit. Close issues that turned out to be unnecessary, with the reason. Delete your own merged branches and remove your own worktrees (after checking no virtualenv imports from them); never touch another session's branch or worktree. End your claim withdone(PR, commit, evidence), orreleasewith resume notes if you stop before the end.
Work claims: sharing issues between agents
A claim is an issue comment whose first line the tools parse. No host names, user names or private infrastructure: agents are named by a stable pseudonymous tag. Always post a new comment; never edit an earlier one.
<!-- work v1 claim agent=a-7kq2m4xw lease=2026-11-01T19:00Z -->
**Claimed** by agent `a-7kq2m4xw` until 2026-11-01T19:00Z UTC.
Scope: <what this agent is doing on this issue>
Branch: <branch or PR>
The first lines of the other actions:
<!-- work v1 checkpoint agent=a-7kq2m4xw lease=2026-11-02T08:30Z -->
<!-- work v1 release agent=a-7kq2m4xw -->
<!-- work v1 done agent=a-7kq2m4xw -->
A checkpoint goes on with what was done and the next step, a release with resume notes, and done with the PR, commit or evidence.
| Action | When | Lease |
|---|---|---|
claim |
before starting | until lease=, at most 24 h after the comment |
checkpoint |
progress; at least once per lease | renews lease= |
release |
stopping before the end, with resume notes | none: the claim ends |
done |
PR merged or evidence posted | none: the claim ends |
- Format. The tag is
a-plus eight characters of[a-z2-7].lease=is UTC to the minute,YYYY-MM-DDTHH:MMZ(no seconds), and is at most 24 h after the comment's own timestamp. - A claim not refreshed within its lease has expired: the issue is open for anyone. Daily checkpoints are the price of holding work.
- Who holds a contested issue. Each agent's run of claims starts with its first
claimand continues while every followingclaimorcheckpointis posted before the previous lease runs out. A gap ends the run; the next comment starts a new one. Of the agents whose latest comment is an unexpiredclaimorcheckpoint, the one whose current run started first holds the issue. A later agent backs off, or claims a non-overlapping scope and says so. Re-read the comments after posting a claim: if an earlier run is still active, postrelease. - A claim coordinates; it is not a lock, a permission or proof of progress. Before continuing someone's expired claim, read its last checkpoint and re-check the branch, PR, runs and side effects.
- A tag names a harness on one machine, not a session. Parallel sessions on the same machine and tool share a tag, so a claim with your own tag may be another session's. Read its latest checkpoint before acting on it.
- Pick any stable tag of the right form and write the comments by hand. Valpatel agents have a helper that derives the tag and posts the comments.
What must never live only locally
- Decisions and their reasons: put them in the issue, the PR description or a doc in the repo.
- Measurements and observations from the user (a photo, "the fan blows up", "it measured 68 mm"): record them in the repo (parameters with a note, or a doc) and in the issue, with the date.
- Run configurations and results: the command line belongs in the issue; result files belong in the repo if the project tracks them, otherwise attached to the issue or the release.
- Lessons: the repo's
lessons/(cad-agent) or the product's notes folder, not only an agent's memory file.
Large or licensed inputs (vendor CAD, datasheets) stay out of git; the repo records where they come from and how to fetch them (a sources list plus a fetch script) so a reformatted machine can rebuild.
Resuming
At the start of a session, or after a crash, rebuild the state from GitHub before touching anything:
gh issue list --state open --assignee @me ; gh issue list --state open --limit 30
gh issue list --state open --search '"work v1" in:comments' # issues with claims: read who holds what
gh pr list --state open --author @me
git fetch --all --prune && git status -sb
git log --oneline --branches --not --remotes # commits on no remote: push them first
git stash list
Read the tracking issue's latest comment for the next step and the runs in flight; check each run's log on its host
before starting it again (it may have finished). The cad-resume agent does this and reports a plan. If local commits
exist that are not on the remote, push them first.
Issue template
<one paragraph: the outcome wanted and why; who asked and when>
**Done**
- [x] <step> (<commit or PR>)
**Next**
- [ ] <step, specific enough to start without asking>
**Running**
- <host>: `<command>`, log `<path>`; done when `<marker>`; collect with `<command>`
**Resume:** branch `<branch>`, PR #<n>. <anything a fresh agent must know first>
Rules that go with it
- Follow the repo's own branch rules: never push to protected branches, never force-push a branch you did not create, merge only when the repo's rules allow (CI green, review done, threads resolved, the user's go-ahead where the repo requires it).
- Write issue and PR text for a reader who was not in the session: no "as discussed", no chat references.
- Do not post private infrastructure details (host names, addresses, credentials) in public repos. Name a run host by role ("the CFD host") and keep its address in the private notes the team already uses.