Owner's guide

The work-loop

The work-loop is your name for the run from a sentence you say to a change you can see. Every piece of it is tracked as an issue on GitHub. This page is what each step means, what your Claude does at it, and which parts of the loop are still undecided.

GitHubThe queue is GitHub Issues and the LifeOps project board

Every piece of work is an issue on your LifeOps repository on GitHub, under its Issues tab. Each issue has a number, written like #42. That number is how your Claude finds an issue and cites it in every commit. In its reply to you it leads with the issue's title, since the title tells you what the work is.

The LifeOps board, under the repository's Projects tab, shows the same issues as columns, one per status. A sync script copies each issue's labels onto the board, so the labels are the record and the board is a view of them. When the two disagree, the labels are right.

Each of these questions has a quick answer on GitHub. What waits on you is GitHub's own Assigned view: open Issues at the top of any GitHub page, then Assigned to me. What is being built right now is every issue with the status:in-progress label; click that label on any issue to list them. What your Claude saw at the start of its session is the briefing described under How a build runs.

The queue spent twelve days in Linear, another issue tracker, from Sep 3 2026, and came back to GitHub on Sep 15. An issue from those days had an identifier like COG-42 or LC-217, and its GitHub issue names the identifier it came from.

Your Claude acts on GitHub as you. Since Oct 11 2026 the issues it files, the comments it writes and the commits it makes appear under your name. Before then it had a second account, which made it look as if you did no work. Older work shows that account, zg-claude. Each commit your Claude makes ends with a Claude co-author line. A commit without that line is your own edit, and your Claude reads it as a ruling.

FilingEvery change you name becomes an issue before anything else happens

A sentence of yours that names a change to the product becomes an issue before anything else happens in that exchange. Filing is the first thing your Claude does with your words.

The rule holds while you are watching a build. A change you name while looking at the screen gets filed like any other, and iterating on what is in front of you does not stand in for filing it. A correction that contradicts an issue's title becomes its own issue. One change per issue.

Everything filed is real work, and the only decision left is the order it gets done in.

Your Claude files with one command, bin/file-issue.sh in its operating folder (outside this repository), which creates the issue and adds it to the board straight away. Without it, a new issue reaches the board only at the sync script's next run. When the board step fails, the issue still exists and the command prints a warning saying it is not on the board, with the reason and the fix, so your Claude can say so instead of reporting a clean filing.

The reply you get names the issue it filed, by title. A reply that names no issue means the filing did not happen, and saying so is enough to get it filed. Before the exchange ends, your Claude goes back over what you asked for and points at the issue for each change you named.

Why that check exists. A change you asked for mid-build on Sep 3 2026 never became an issue, and you said so the next day: “that means you are failing to file issues i tell you to file … This is constantly a gap and prevents all work from getting done”.

A title is the app, a colon, and the change, said the way a person would say it. “Money: split a transaction on its own screen” is the shape. The body leads with your quote, then the context someone needs months later, then the parts of the app the change touches. A screenshot you gave goes right under your quote. Each issue also gets a module: label, which places it on the roadmap, the in-app map of every issue by part of the product.

StatusesA status label says where a piece of work stands

You read the queue by status. Each status is a label on the issue that starts with status:, and each one means a single thing.

Backlog status:backlog. Parked, one issue at a time. You are the only one who parks an issue here, and your Claude never takes work out of it.
Open status:open, or an issue with no status label. The queue itself. New issues arrive here, and your Claude plans from it. Issues from the Linear days may say status:todo, which means the same.
Planned status:planned. The plan comment is on the issue. It is ready to build.
In progress status:in-progress. Being built. Your Claude claims an issue with this label and a comment saying it is working on it.
Web done status:web-done. The web half is deployed and the issue stays open, usually for the phone.
iOS done status:ios-done. The phone half is finished as well.
Waiting on you status:waiting-on-you. Only you can unblock it, and the question is on the issue. The issue is assigned to you as well.
Done The issue is closed, with a plain note of what changed. Every closed issue on the board reads Done.

The assignee has one meaning. Your avatar on an issue means it waits on you: your Claude has asked you something on it and assigned it to you. You answer with a comment on the issue or in a session, and your Claude takes you off it once you have. Your Claude acts as you, so it never assigns itself. An issue labelled waiting on you with nobody assigned is a slip, and your Claude fixes it when it meets one.

Two more labels say what the assignee cannot show. soft-block means your Claude is going ahead and your word would steer it. deferred parks a whole piece of work, an umbrella issue and everything under it, until you pick it back up; the umbrella's body starts with Status: DEFERRED.

PlanningAn issue gets planned before it gets built, on a stronger model

Planning and building run on different models. Fable plans and Opus builds, two Claude models with Fable the stronger of the pair. Planning is the judgment step, and a bad plan misdirects every builder working from it.

A planning pass starts when an issue is marked Priority on the roadmap, when you name one, or when you ask for every issue in Open to be planned.

The pass reads each issue's title and body once, with no code open, and sorts the issues by the part of the app they touch. One planner takes each part, and the parts are planned at the same time, so logic that several issues share gets named once. An issue you wrote by hand has its title rewritten as an app and a change here. Then the planner reads what the work touches: the code in the web app and in the phone app, and the guide pages describing that surface.

The plan is posted as a comment on the issue, under four headings every time.

Touches The files, listed for the web app and for the phone app.
Shared Logic both apps need, named as a function and a file, and which app gets it written first. The other app copies it exactly, and a check keeps the two copies identical.
Order The sequence to work in when other issues touch the same files, and which app each builder owns. Two issues on one surface are sequenced, never built side by side.
Needs you Anything only you can answer.

Anything under Needs you sends the issue to Waiting on you: the question goes on the issue and the issue is assigned to you. An empty Needs you sends it to Planned, ready for a builder who never has to open the code to understand it.

BuildingDevelopment covers both apps, and the phone follows at a stopping point you name

Development is the web app and the phone app. Guides are pre-release work instead. Your words: “guides are not part of development”, and “ios is not pre-release, ios is development”.

The phone does not ship in step with the web. You argue a design out on the web while its shape settles, and rebuilding the phone for every rejected layout spends the work twice. You said it after three rejected layouts for one row: “this is a perfect example of why we dont implement ios lock step with web. We will implement ios when we get to a better stopping point.”

So an issue can finish its web work with the phone still owed. The phone half is picked up as its own pass, at a stopping point you name. Your Claude does not build it by default.

LabelsTwo labels say which app has a change, and shipped means live

Which app has a change is a pair of labels on the issue, one starting web: and one starting ios:. Each takes one of four values.

Needed web:needed, ios:needed. That app is owed the change. An issue with no label for an app has not been sorted yet, and reads the same way.
Built web:built, ios:built. The code is finished and merged into the main line of code, and nobody has it yet. A change to the installed phone app waits at ios:built until you authorize a TestFlight build.
Shipped web:shipped means the web change is deployed, and someone has looked at it on the live site. ios:shipped means your phone can have it. Most phone changes arrive over the air, with no new install; a change to the installed app itself arrives as a TestFlight build you tap Update on.
N/A web:n-a, ios:n-a. That app has no part in the change.

Issues from the Linear days also have server: and docs: labels with the same four values, for the backend and the guides, and a kind: label saying bug, feature or improvement.

The labels said “complete” for an hour on Sep 4 2026, and you read that as done and in your hands: “Wait this is confusing. Web Complete & IOS Complete, yet only Web has it live and deployed.” Shipped now means live everywhere the word appears, never code that has merely been merged.

The built value came from your ask the same day: “You need a new label that distinguishes ios built and ios deployed”. Labels stay few on purpose, since your standing word on them is “I hate clutter”.

AgentsIssues are built in parallel, and one session lands them all

One builder takes one issue, in its own copy of the repository. The web half and the phone half can run at the same time. Builders never push their work up and never deploy it.

Two issues touching the same screen collide when their changes come together. One integrating session takes them one at a time in a set order, folds each onto the current code, re-runs the checks, then pushes once and deploys once. One unverified push is in flight at a time.

While you are watching, that order changes. The change is deployed first and reaches the live site in a little over a minute, so you see it. The deploy runs that app's own test suite on the way, and the rest follows after you have looked: the check on web-and-phone parity, the commit, and the push. Anything set aside to get there is written on the issue as a comment at the moment it is set aside.

A run with you away goes in phases, in your words: “Plan out first. Build web second. Build ios last, but do not push testflight. You can deploy ota. Finally update all docs and remaining to close out any issues you can.” Every open issue gets planned and moves to status:planned, or to Waiting on you if its plan has a question for you. Web gets built and deployed for every planned one, which moves it to status:web-done. Then one phone pass covers everything that owes the phone, published over the air. Then the guides, then a close-out pass that closes whatever is finished. A TestFlight upload waits for your explicit word, and a change to the installed app itself stops at ios:built until you give it.

Every session starts with a briefing, printed by scripts/orient_github.sh when the session opens, that names these phases and lists the open issues by status, the ones waiting on you first. Anything filed in the last hour comes ahead of the rest of the queue, since it is usually about something you are looking at right now.

ProjectsA run of related issues gets a project of its own

Issues that belong to one effort share a project: label, which the board shows in its Project column. The board itself is also called a project on GitHub; the label is the grouping inside it. Project is your word for that grouping: “I think all of these issues need to be in a higher level proejct”. Money, Apps, Extensions, Obsidian, Notes and Events MVP are the projects so far.

A larger effort also gets an umbrella issue, which holds the idea in your words and states the rules binding the whole run, so a rule like the phone not shipping in lockstep is settled once instead of argued on every issue underneath. Its pieces of work are its sub-issues, and parking the umbrella parks all of them.

Sub-issues are for separate work. The steps of the process never become sub-issues.

UndecidedThree parts of the loop have no definition yet

The loop is written down as far as you and your Claude have decided it. These three are still blank.

The pre-release checklist What has to be true between built and closed, beyond both app labels reading Shipped or N/A, is unagreed. An issue gets no checklist on it until you settle it.
Deploy state The web:shipped label records that a deploy went out. How anything more about the deploy gets recorded on the issue is unsettled.
Client delivery A client instance takes the work as a merge on its own cadence, worked out from the code that changed. How that gets tracked is unsettled.