Building

How I work with Claude Code

Groupthink is built and run by agents, and the numbers are on their own page. This page is the mechanics. What the agents read, how a change gets from an issue to production, what reads production afterward, and what I still do myself. Each rule below has the date it was written and the thing that went wrong first.

The Groupthink story, with the numbers

Start here

What I would copy first

  1. 01 Put the rules in a file the agent reads every time, and write down why each one exists.
  2. 02 Keep the always-on file short. Procedure goes in documents loaded when a task needs them.
  3. 03 Give every agent its own checkout, enforce it with a hook, and verify the hook on a schedule.
  4. 04 The review is a comment on the pull request. Reading your own diff is not a review.
  5. 05 Green means you read the checks on the head commit. An agent saying merge-ready is not evidence.
  6. 06 Something has to read production every morning, and every check for an absence needs a second query.
  7. 07 Every request ends in one of four states. A reminder from me is a bug in the system.
  8. 08 Have the agent use the product from the public docs alone, then brief you on what it can do.

What the agents read

The agents do not know how my company works. They read it, at the start of every session, from a file at the root of each repository and one above all of them.

Every rule carries its why and its date

A rule in my configuration is the instruction, then the incident that produced it, with the date. I said this to Claude on August 7: that is how much more it lands when you have the why, and it costs too little to save it. A bare directive invites resistance. It also cannot be retired, because nobody can tell whether the thing that created it is still true.

Behaviour and procedure are separate files

The global file reached 9,540 words on August 26, growing about 200 words a day, because every new rule was appended to it. The rules about how to behave, response length, when to ask, how to write, were outnumbered thirteen to one by procedure and were quietly losing. The same day the frontend repository's file hit 12,816 words, and branching rules alone were a third of it. Nothing was deleted. Procedure moved into documents that load when a task calls for them, 28 of them now, and the always-on file kept only what has to be considered every single turn. The question when adding a rule is which half it is.

Temporary rules expire by machine

A rule that is only true for a while gets an expiry date in a comment on its heading, and a script in the morning routine fails once the date passes. This exists because a section that said, in prose, remove this after July 1, sat in every session's context for eight weeks past its own expiry, still routing code review to someone who had left. Prose is not a mechanism.

There is a written model of me

One file describes what I optimize for, how I write, how I make decisions, and where the agent's simulation of me is reliable and where it is flaky. Engineering scope and voice rules are solid. Pricing, anything touching paying customers, and strategic pivots are flaky and get asked. It is consulted instead of asking me when asking would not add signal, it is updated when I redirect, and its first line says it is a model and not the truth.

It took ten months and it is still changing

The configuration repository started in November 2025. It holds 28 workflow documents, five hooks, eight routines, and the incident reports that produced them. Most of it was written after May 2026, when an audit of every repository on my machine found no hooks, no subagents, and no skills anywhere. The repositories were documented. They were not yet programmable.

How a change gets to production

One issue, one agent, one worktree, one pull request. The steps run in this order, and each one exists because skipping it cost something.

  1. 01

    It starts as an issue with a chain of intent

    An engineering issue names the product issue it implements, and the product issue names the goal. A milestone is one dated name, created in all five repositories at once with the same title and due date, so the board sorts as a timeline. The milestone carries a launch tier, and the tier decides which marketing work is created alongside the engineering work. A second file in each repository holds what the tracker cannot: which issue bodies are wrong, what is blocked and on what, what was investigated and ruled out, and why the order is the order. It carries a last-verified date. Older than a week means rewrite it before acting on it.

  2. 02

    The agent claims the issue before touching it

    Every session authenticates as me, so assignment cannot tell two sessions apart. The claim is a label plus a timestamped comment. The earliest timestamp wins, a claim with no pull request goes stale after three hours, and the durable claim is an open pull request that closes the issue. This came from June 24, when two sessions built the same two issues. One of them was assigned to me and got built twice anyway.

  3. 03

    It works in its own checkout

    One session, one git worktree, branched from develop. A hook blocks branch-changing git commands in any shared checkout. It tells a worktree from a primary checkout structurally, so a repository cloned tomorrow is covered without a list to maintain. The hook has been found not running three times: absent on August 4, a stale copy on August 13, and regressed again on September 2. Each time the documentation, the repository, and the settings all read as protection. So the morning routine now runs a script that exercises the installed hook and proves it denies what it should. A guard nobody verifies on a schedule is a guard you should assume is off.

  4. 04

    The pull request carries its own evidence

    It inherits the milestone from its issue. The body opens in plain terms, then says what the change enables next, then the engineering detail, and every issue number in it is glossed so it reads without opening a link. Every issue it closes gets its own closing line, because a comma-separated list closes only the first. A sweep of 159 open issues on August 14 found six that had shipped and were still open. A post-deploy checklist section is required in every body, and a low-risk change writes not applicable with a reason rather than leaving it out. A pre-review audit table goes on as a comment: issue alignment, duplicate-system check, whether a zero was treated as evidence, commit hygiene, branch freshness, deferred items lifted to issues.

  5. 05

    The review is AI, and it has to be on the pull request

    The session that wrote the code requests the review, and the review is posted as a comment. Reading your own diff inside a session is not a review, and green CI is not one either, because CI only proves the tests that exist still pass. The reviewer runs on the strongest model available, on purpose. It should not be weaker than the sessions writing the code. It has a read-only shell so it can check findings against source instead of reading a diff. It defaults to approve and blocks for security, broken functionality, breaking changes, and migrations. A finding is checked before it is applied. Three findings in one August release would have broken the feature if applied as written, so both the premise and the suggested fix get verified against source first. Then a disposition comment lists every finding as fixed with a commit, deferred with an issue, or declined with a reason. The last human reviewer came off in May 2026.

  6. 06

    Green is observed on the head commit

    An agent reporting merge-ready is not evidence. Agents work in worktrees where local checks can mislead, so they report CI as unverified even after a local pass, and the merging session reads the checks on the head commit, again after every push. A fast green from a job that skips itself when the diff touches nothing it cares about means nothing was tested. No run at all is not a passing run. The branch has required status checks, so the platform enforces the condition instead of a session remembering to poll. On August 26 an auto-merge fired mid-CI because the branch had no required checks, so it had nothing to wait for. It happened to land on green code.

  7. 07

    Releases carry a checklist, or they do not go

    Develop merges to main about once a day. The release body is written in plain language, rolls up every merged pull request's post-deploy checklist into one section, names the rollback signals, and opens a paired 24-hour monitoring issue. Since August 26 the agent merges a release once CI is observed green, because I could not keep clicking merge on every one. A short list still waits for me: migrations that touch existing rows, authentication, billing, queue and scheduler changes, and changes to the shape of the API. That list has been narrowed twice, on purpose. Routing zero-risk changes to me trains me to rubber-stamp, which erodes the signal on the ones that need me.

  8. 08

    Done is verified in production

    There is no staging. The checklist runs against production: the deploy landed, new routes answer, the error tracker shows nothing new since the deploy, the failed-jobs table is empty. Anything an agent structurally cannot check, which is anything visual, is labelled for human verification, and since September 2 a merged release carries a label on GitHub until that walk is done. That rule came from a release that sat merged and deployed for an hour with an untouched checklist and nothing anywhere saying so.

What watches production

Building is the easy half. The setup only earned my trust when something started reading production every morning.

The daily health check

About thirty numbered checks, written up in one markdown file, run every morning. The deterministic half is a single script that takes about ninety seconds. The rest needs a session with access to email, a browser, and the production database. It files a dated issue with one summary comment, appends a row to a dashboard, and turns real problems into issues in the engineering repositories.

An absence has at least two causes

Most checks fire on something missing: no emails sent, no signups, no deploys. Missing can mean broken, or it can mean nothing was due. So every absence-shaped check carries a second query that tells the two apart, and it runs before anything is escalated. This was written after one session raised four false alarms in a day. The other half of the rule is that flattering numbers get investigated less than alarming ones. A stale goals file once reported a month at 389 percent of target.

Every metric is judged against its own history

Each number is compared with its own sixteen-week band rather than a fixed threshold. A metric once read red for three weeks because its threshold had been set below its historical floor.

What it has caught

A notification type that had silently stopped sending for about eight months, which produced a zero-volume canary. Meeting-bot joins failing for weeks, invisible because the failures produced rows every other check filtered out as noise. A release merged and not deployed for two days behind a hung deploy that reported cancelled rather than failed, which produced a check that compares the running commit with main.

The decision log

An append-only file in the product repository, newest at the top. Each entry is a question, the decision, the alternatives considered, the why, a predicted outcome, and when to revisit. Sessions write entries when a decision is made, without being asked. Two rules hold it together. Never invent a why, mark it as needing my confirmation instead. Never edit history, a revision is a new entry that links back. Around 350 entries since May.

Log files are production state

The morning routine reads dates out of markdown logs to decide what to suggest: email triage every three or four days, a vision check weekly. One triage entry sat in an unmerged pull request for six days, so the log on main showed the previous run, and the next session reported a thirteen-day gap that never happened and started work that was not needed. A file a routine reads to decide whether to run gets merged in the same session it was written.

Cost per merged pull request, every month

Total recurring burn divided by merged engineering pull requests, with each anchor marked verified or estimated. Agent token spend is logged daily in API-equivalent dollars, because raw token counts are dominated by cache reads and mislead. The figures are on the Groupthink page with their sources.

How I keep my end

The system is only as good as what I give it and what I tolerate coming back. These are the rules on my side.

Every request ends in one of four states

Done and verified. Done with the judgment calls written down where I will see them. Escalated to me as a single packet with context, options, and a recommendation. Or parked with a durable carrier, an issue, a calendar event, or a scheduled trigger, created before the session ends. There is no fifth state where a task quietly evaporates. I fire off a request and delete it from my head, so my memory is never the persistence layer. If I have to remind the system of anything, that is a bug. The task gets handled, and then the class of failure gets patched with a rule, a routine step, or a hook.

Do the thing, do not preview it

When I name an artifact, write the issue, open the pull request, draft the email, the deliverable is the artifact existing. I said this on August 26: I am saying go write this issue, and instead of writing the issue Claude is coming back with here is all the stuff I would put in the issue. Why do I need to read all this? A preview doubles my reading and turns a finished task back into a review task. Preview is reserved for the irreversible.

Escalate decisions, not diffs

On August 14 I had a dozen green pull requests in front of me that I could not meaningfully review, so the rule changed. The default is to merge. When a question surfaces, it comes to me as the question, with options and a recommendation. I do not read the diff. Releases, sends to customers, spending, and irreversible actions are always my click. The rule rests on the automated review's measured precision, which is tracked, and if that tracking goes stale the rule gets revisited.

Under 150 words

The first two lines of any response carry the outcome and any decision I need to make. I read by skimming, and long responses cost me more than they save. Think at 100 percent, share at 30. If something needs 500 words it needs a document or an issue, and I get the link.

The session close is a checklist

An audit of 215 session closes in July found about one open item in nine had leaked. Half were finishable and parked. Half were blocked, with nothing but a sentence in the summary. So the close has rules. Finish finishable work instead of offering it. No blocked item closes on prose alone. It needs a trigger that will resurface it. Then a sweep for anything worth encoding: if we would have to explain it again next session, it was not written down. Then the decision log.

A run needs a driver

On June 4 I said go autonomous for the night. The session acknowledged it, set up a worktree, and sat idle for eight hours until I said good morning. A session ends its turn the moment it stops calling tools, and nothing re-invokes it across a gap. Overnight work needs a loop, a scheduled job, or a workflow script that wakes it, plus a host that stays awake and a permission mode that will not stop on a prompt nobody is there to answer. I test the driver in the afternoon before betting a night on it.

Routines are trigger phrases

Good morning, goodnight, Monday setup, Friday wrap. Each maps to a script and a written guide, and the guide includes the tone. The morning one does not count pull requests. It asks what would feel good to get done, reflects it back, and starts.

Verification, which is where most of the mistakes were

Most of the rules written this summer are about the gap between a thing reporting done and a thing being done.

Walk the product from the docs alone

Before a launch, the agent uses the live product in my own browser with the public documentation as its only reference, ignoring what it knows about the implementation, and logs every place reality differed from what the docs led it to expect. On August 27 a launch had passed CI, two review rounds, API smoke tests, and a claim-by-claim audit of the docs. The first walk found five things in under an hour, one of them a blocker: the headline feature worked in the database and was invisible to the user checking for it. CI validates code against our imagination of the user. This validates the product against what the docs promised. The walk ends with a briefing to me on what the product can now do, because the standing risk of delegating verification is that I stop learning my own product.

Make a new test fail on purpose first

On August 13 three pull requests shipped tests that verified nothing, and two of them survived both the automated review and a human one. A new test now has to be shown failing when the behaviour it guards is removed, before anyone trusts that it passes.

A zero is not evidence until you know the denominator

A clean check on August 29 turned out to mean an entire milestone had received no production data at all. Absence of badness and absence of content look identical. Verification asserts positive evidence, and when a zero is the result, the next question is what the total was.

Product claims get checked against the code

Anything that describes what the product does, to someone outside the room, is verified claim by claim against a freshly fetched copy of the code, with a file and line for each claim. My own description of the product is a starting point. It gets checked like anything else. On August 19 a help document said the product did not record something that the production path in fact sent, and it would have gone to a paying customer as fact.

A credential is not seeded until it has been used

A correctly encrypted key with the wrong role took down desktop transcription for days in August. Seeding now ends with a call that proves the credential can do the thing it is for, and the ones that matter have a scheduled probe.

Before writing to anyone's account, dry-run read-only in production

Any change that writes to a user's third-party account ships with a read-only dry run first: the count of affected rows and the before-and-after under the new logic, as counts and aggregates only, never rows. The rule has since stopped two further fixes that would have changed nothing.

What I still do myself

  • I decide what deserves to exist. Nothing here has taken that over and I do not expect it to.
  • I sign in. The agent drives the browser to the login page and I do the sign-in, every time. It never touches an OAuth grant or a payment.
  • I click merge on the carve-outs: migrations against real rows, authentication, billing, anything irreversible.
  • I do the final visual walk before a launch, from the list of things that need eyes.
  • I send the email. The agent drafts into my mailbox and I press send.
  • I write the rule. Every rule the system follows is one I noticed, decided, and wrote down, and the system applies my judgment at a volume I cannot personally review. That is the real risk in all of this. The guard that regressed twice in three weeks is what it looks like in practice.

Read next