README + diagram: the pilot lock and one merge at a time, so "landing" means only the landing branch

The lock guards the pilot, so it is the pilot lock, and the act is a merge onto the pilot: the
README's summary row, the harness paragraph, the kitchen list, the glossary and the alt text, and the
diagram's title, the lock ring, the coordinator line and the legend. "Publish to landing" and
"landing (main)" keep the word for the landing branch. Also: about 15 seconds to see a landed change;
a "merge" glossary row instead of "rebase", with pilot and landing beside development and main; the
cloud paragraph names BRANCH=development and PRODUCTION_BRANCH=main. The PNG is re-rendered at 2x.
This commit is contained in:
Doxa Maps 2026-10-02 05:38:20 +00:00
parent bf140e38c9
commit cb74b60009
3 changed files with 19 additions and 19 deletions

View file

@ -70,7 +70,7 @@ capabilities, three outputs, one shared library, one build.
| **One app nests every map** — and each stays embeddable on its own | [capability 5](#capability-5--app-shell-the-research-gallery) · `bun run check:composite-reg` |
| **5 capabilities, every one shippable in every output** | `bun run verify:5-caps` |
| **Shared library, private plugins** — reuse without breaking each other | `bun run check:library-index` |
| **One owner per plugin, a second reader for every change, one landing at a time** | [agent swarm](#build-it-with-an-agent-swarm) |
| **One owner per plugin, a second reader for every change, one merge at a time** | [agent swarm](#build-it-with-an-agent-swarm) |
## For vibe coders: build, open the Studio, embed a map
@ -698,7 +698,7 @@ your own page, set `"locale"` in its `profile-config`. Arabic reads right to lef
has one agent that owns it, and the work moves through three kinds of branch:
- **The pilot branch (`development`)** is the shared working version. A development server with hot
reload follows it, so each change that lands can be seen there within seconds.
reload follows it, so each change that lands can be seen there within about 15 seconds.
- **The landing branch (`main`)** is production. It moves only when you publish, and the production
server rebuilds from it.
- **PR branches** hold one feature each. They start from the landing branch and land on the pilot
@ -706,10 +706,10 @@ has one agent that owns it, and the work moves through three kinds of branch:
**Bring your own harness.** dx-maps works with whatever AI coding agent or agent harness you already
use. The repo gives you the branch strategy below, the checks (`bun run gates:pre`) and the Plugin
Studio; it does not ship a harness. Roles such as a coordinator that puts the landings in order, or a
Studio; it does not ship a harness. Roles such as a coordinator that puts the merges onto the pilot in order, or a
gate-keeper that reads each change before it lands, are jobs your harness gives to its agents.
![The delegation model: the pilot branch (development) at the centre behind a landing lock, the landing branch (main) below it, inside the Plugin Studio; eight plugins around it, each owned by one agent; a coordinator and a gate-keeper over the agents; below, how a change lands in four steps, and the three outputs](documentation/readme-images/delegation-model.png)
![The delegation model: the pilot branch (development) at the centre behind the pilot lock; publishing to the landing branch (main) and its outputs below it; inside the Plugin Studio; eight plugins around it, each owned by one agent; a coordinator and a gate-keeper over the agents; below, how a change lands in four steps, and the three outputs](documentation/readme-images/delegation-model.png)
<sub>[Open the diagram full size](documentation/readme-images/delegation-model.png): on a phone its small text needs it.</sub>
@ -767,8 +767,8 @@ gate-keeper that reads each change before it lands, are jobs your harness gives
Keep the repository on a forge you host yourself: a swarm pushes often, and on a public host one wrong
push publishes work you did not mean to share. Give each app two servers: a **pilot server** that
follows the pilot branch with hot reload, and a **landing server** that rebuilds from the landing
branch. The cloud container in `deployment/cloud/` runs both today (set its `BRANCH` to `development`
for the pilot server; the default is `main`). One pilot server per app, rather
branch. The cloud container in `deployment/cloud/` runs both today (`BRANCH=development` for the pilot server,
`PRODUCTION_BRANCH=main` for the landing server; `BRANCH` defaults to `main`). One pilot server per app, rather
than one per pull request, keeps the memory the same however many pull requests are open. Each
developer can still build on their own machine with the Plugin Studio and push their branch.
@ -793,10 +793,10 @@ So the project works like a busy kitchen:
1. **Each agent works in its own branch and copy of the project** — its own counter, so nobody bumps
anybody. One owner per plugin, and one per shared file.
2. **Only one change lands at a time.** Whoever holds the *landing lock* first catches up with
2. **Only one change lands at a time.** Whoever holds the *pilot lock* first catches up with
everyone else's latest work, fixes any clash itself and runs every check; the change goes into the
pilot branch only if nothing fails. The pilot branch always works.
3. **Someone keeps order.** A coordinator can put the landings in order, and a gate-keeper can read
3. **Someone keeps order.** A coordinator can put the merges onto the pilot in order, and a gate-keeper can read
each change by its content before it lands. Your harness gives these jobs to its agents.
4. **The landing branch moves only when you publish**, after the checks pass on that exact version.
The pilot server follows the pilot branch; the production server rebuilds from the landing branch.
@ -811,12 +811,12 @@ That's how many plugins get built at the same time, in one project, without the
| Word | In plain terms |
|---|---|
| **repo** | the project folder, with its full history |
| **development** | the shared working version: every agent's change is added here, one at a time |
| **main** | the production version: it moves only when `development` is published |
| **development** (the pilot) | the shared working version: every agent's change is added here, one at a time |
| **main** (the landing) | the production version: it moves only when `development` is published |
| **worktree** | a private copy of the project for one agent to work in |
| **merge conflict** | two changes touched the same lines; someone has to decide how to combine them |
| **rebase** | catching your work up with everyone else's latest before adding it |
| **landing lock** | only one change lands on `development` at a time; its holder catches up and runs every check first |
| **merge** | combining your branch with everyone else's latest work; here it happens inside the pilot lock, in a throwaway copy of the pilot |
| **pilot lock** | only one change merges onto `development` at a time; its holder catches up and runs every check first |
| **tag** | a fixed name for one release commit, such as `v1.0.0`, so you can always deploy exactly it |
</details>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 769 KiB

After

Width:  |  Height:  |  Size: 767 KiB

View file

@ -10,7 +10,7 @@
<path id="mqL" d="M 679,884 A 71,71 0 0 0 821,884"/>
</defs>
<rect width="1500" height="2086" fill="#ffffff"/>
<text x="750" y="54" text-anchor="middle" font-size="34" font-weight="800" fill="#0f172a">How dx-maps is built: one owner per plugin, one landing at a time</text>
<text x="750" y="54" text-anchor="middle" font-size="34" font-weight="800" fill="#0f172a">How dx-maps is built: one owner per plugin, one merge at a time</text>
<circle cx="750" cy="850" r="540" fill="none" stroke="#2563eb" stroke-width="1.6" stroke-dasharray="3 7" opacity=".75"/>
<circle cx="750" cy="850" r="355" fill="none" stroke="#15803d" stroke-width="2.2" opacity=".85"/>
<circle cx="750" cy="850" r="606" fill="none" stroke="#7c3aed" stroke-width="2" stroke-dasharray="8 7" opacity=".6"/>
@ -29,8 +29,8 @@
<circle cx="750" cy="850" r="120" fill="#fef2f2" stroke="#dc2626" stroke-width="3" stroke-dasharray="10 6"/>
<path id="mqT" d="M 646,850 A 104,104 0 0 1 854,850" fill="none"/>
<path id="mqB" d="M 644,850 A 106,106 0 0 0 856,850" fill="none"/>
<text font-size="13" font-weight="800" fill="#b91c1c" letter-spacing="1.6"><textPath href="#mqT" startOffset="50%" text-anchor="middle">LANDING LOCK</textPath></text>
<text font-size="12" font-weight="700" fill="#b91c1c" letter-spacing="1.2"><textPath href="#mqB" startOffset="50%" text-anchor="middle">ONE LANDING AT A TIME</textPath></text>
<text font-size="13" font-weight="800" fill="#b91c1c" letter-spacing="1.6"><textPath href="#mqT" startOffset="50%" text-anchor="middle">PILOT LOCK</textPath></text>
<text font-size="12" font-weight="700" fill="#b91c1c" letter-spacing="1.2"><textPath href="#mqB" startOffset="50%" text-anchor="middle">ONE MERGE AT A TIME</textPath></text>
<rect x="617" y="846" width="26" height="20" rx="4" fill="#dc2626"/>
<path d="M 622,846 v -6 a 8,8 0 0 1 16,0 v 6" fill="none" stroke="#dc2626" stroke-width="3.5"/>
<circle cx="630" cy="856" r="3" fill="#fff"/>
@ -122,14 +122,14 @@
<text x="690" y="254" text-anchor="middle" font-size="14" font-weight="800" fill="#4c1d95">coordinator</text>
<circle cx="812" cy="248" r="56" fill="#f1f5f9" stroke="#334155" stroke-width="3.5"/>
<text x="812" y="254" text-anchor="middle" font-size="14" font-weight="800" fill="#1e293b">gate-keeper</text>
<text x="884" y="192" font-size="17" fill="#4c1d95">a coordinator puts the landings in order;</text>
<text x="884" y="192" font-size="17" fill="#4c1d95">a coordinator puts the merges in order;</text>
<text x="884" y="216" font-size="17" fill="#1e293b">a gate-keeper checks each one by its content</text>
<text x="750" y="1502" text-anchor="middle" font-size="20" font-weight="800" fill="#1e3a8a">one owner per plugin, in its own branch · a second reader for every change</text>
<rect x="36" y="110" width="304" height="280" rx="14" fill="#f8fafc" stroke="#e2e8f0" stroke-width="2"/>
<circle cx="64" cy="142" r="11" fill="#166534" stroke="#14532d" stroke-width="2.5"/>
<text x="88" y="147" font-size="15" fill="#334155">pilot branch (development)</text>
<circle cx="64" cy="174" r="11" fill="#fef2f2" stroke="#dc2626" stroke-width="2.5"/>
<text x="88" y="179" font-size="15" fill="#334155">landing lock — one at a time</text>
<text x="88" y="179" font-size="15" fill="#334155">pilot lock — one at a time</text>
<circle cx="64" cy="206" r="11" fill="#fffbeb" stroke="#d97706" stroke-width="2.5"/>
<text x="88" y="211" font-size="15" fill="#334155">Plugin Studio — the one repo</text>
<circle cx="64" cy="238" r="11" fill="#f0fdf4" stroke="#15803d" stroke-width="2.5"/>
@ -139,9 +139,9 @@
<circle cx="64" cy="302" r="11" fill="#eff6ff" stroke="#2563eb" stroke-width="2.5"/>
<text x="88" y="307" font-size="15" fill="#334155">agent — owns one plugin</text>
<circle cx="64" cy="334" r="11" fill="#f5f3ff" stroke="#7c3aed" stroke-width="2.5"/>
<text x="88" y="339" font-size="15" fill="#334155">coordinator — orders landings</text>
<text x="88" y="339" font-size="15" fill="#334155">coordinator — orders merges</text>
<circle cx="64" cy="366" r="11" fill="#f1f5f9" stroke="#334155" stroke-width="2.5"/>
<text x="88" y="371" font-size="15" fill="#334155">gate-keeper — checks landings</text>
<text x="88" y="371" font-size="15" fill="#334155">gate-keeper — checks each merge</text>
<rect x="60" y="1536" width="1380" height="232" rx="20" fill="#fef2f2" stroke="#fca5a5" stroke-width="2"/>
<text x="750" y="1578" text-anchor="middle" font-size="22" font-weight="800" fill="#7f1d1d">How a change lands — one at a time, so many plugins can be built at once</text>
<rect x="80.0" y="1600" width="305" height="148" rx="14" fill="#fff" stroke="#dc2626" stroke-width="2"/>

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 20 KiB