diff --git a/README.md b/README.md index 986054d97..0fe2019c5 100644 --- a/README.md +++ b/README.md @@ -37,8 +37,9 @@ Built with love, with the prayer that these maps bless the nations. **A blessing for you.** These maps and posters are given to bless the people who bless the nations. We love you, and we are thankful for your work. We bless you in Jesus' name. -Every poster is in Posterverse (`plugin-designs/posterverse/`): UPG100 Posters, Country Posters, -Poster Design and Wall of People Groups. They are all in the Plugin Studio (`bun run dev`) too. +Posterverse (`plugin-designs/posterverse/`) brings the six poster plugins together: UPG100 Posters, Country +Posters, Poster Design, Wall of People Groups, Bible Posters and Bless India Posters. They are all in the +Plugin Studio (`bun run dev`) too. # dx-maps โ€” one build, maps that embed everywhere @@ -60,7 +61,7 @@ capabilities, three outputs, one shared library, one build. | ๐Ÿ”— **Maps that talk to each other** | Maps share props and events, so one app can nest them and a click in one can move another. | | ๐Ÿชถ **Small bundles** | Each map's file carries only the parts of the shared library it uses (tree-shaken). | | โš™๏ธ **One build step** | `bun run build` makes every map at once. | -| ๐Ÿ“ฆ **Three outputs** | A web folder (iframe, script embed), a mobile app, a desktop app โ€” [the 3 outputs](#what-the-build-makes--3-outputs). | +| ๐Ÿ“ฆ **Three outputs** | A web folder (iframe, script embed), a mobile app, and a desktop app built from the same code you run in the browser โ€” [the 3 outputs](#what-the-build-makes--3-outputs). | | What dx-maps set out to do | Proof | |---|---| @@ -70,7 +71,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 merge at a time** | [agent swarm](#build-it-with-an-agent-swarm) | +| **One agent per plugin, the repo agent reads 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 @@ -125,9 +126,9 @@ people groups of the world. When you work here, the goal is one of these: library and the checks. - **One plugin per folder** in `plugin-designs/`; shared code goes in `library/` only if it stays reusable for every other plugin. -- **Land on `development`**, one change at a time through the lock, with `bun run gates:pre` passing. `main` is +- **Join `development`** (the pilot), one change at a time through the lock, with `gates:pre`, `gates:post` and the landing checks passing. `main` is production and moves only on a publish. -- These 8 maps are in production: the 7 in the gallery, plus the country map for DX Life's country pages. The +- These 8 maps are in production: the 7 production maps in the gallery, plus the country map for DX Life's country pages. The other maps are experimental: leave them as they are unless your task is one of them. @@ -135,11 +136,12 @@ people groups of the world. When you work here, the goal is one of these: --- -## The 7 production maps +## The production maps -**Seven maps DX uses today** โ€” each one a plugin you can embed on its own, and all seven together in -the Research Gallery, which DX Life publishes as **Deep Research**. An eighth production map, the country map -(`country-map`), draws DX Life's country pages; it isn't in the gallery. +**Seven production maps DX uses today, all together in the Research Gallery**, which DX Life publishes +as **Deep Research**; each one is also a plugin you can embed on its own. The gallery also carries two +poster plugins still marked experimental, Country Posters and Poster Design (see Posterverse). An eighth +production map, the country map (`country-map`), draws DX Life's country pages; it isn't in the gallery. @@ -152,7 +154,7 @@ the Research Gallery, which DX Life publishes as **Deep Research**. An eighth pr - +
UPG100 Posters
UPG100 Posters
prayer lists of 100 people groups, with posters to print
Cities with Internet
Cities with Internet
internet access where unreached people groups live
Gospel Resources
Gospel Resources
which people groups have scripture, film or audio โ€” and which have nothing
Research Gallery
Research Gallery
all seven in one app โ€” capability 5
Research Gallery
Research Gallery
all nine in one app โ€” capability 5
@@ -259,10 +261,9 @@ If you build with AI agents, this repo is made for you: updating the moment you save. - **Speak instead of typing.** Rudder, an offline voice-to-text tool, sits as a corner widget in the Studio: look at a plugin, say what you see, and hand the text to your agent. Nothing leaves your - computer (Linux today). -- **One plugin, several outputs.** The same plugin ships as a web embed or a mobile app, and a plugin - can target the desktop: Rudder is the desktop example, a corner widget in the Studio and its own - desktop app (`bun run desktop:build rudder-voice`, see [HOWTO-build-the-desktop-app](./documentation/HOWTO-build-the-desktop-app.md)). + computer. It also runs as its own desktop app. +- **One plugin, several outputs.** The same code ships as a web embed, a mobile app or a desktop app + ([the desktop app](#output-3--the-desktop-app--works-today)). - **Build together.** [Run it in the cloud](#run-it-in-the-cloud) gives a whole team one shared dev server. @@ -326,7 +327,7 @@ improvement on the next build.
-What the Research Gallery is made of โ€” seven production maps, an Experimental shelf, all five capabilities in one plugin +What the Research Gallery is made of โ€” seven production maps, two poster plugins, an Experimental shelf, all five capabilities in one plugin ```text Research Gallery capability 5 @@ -341,10 +342,12 @@ Research Gallery capability 5 โ”‚ โ”œโ”€ regions list regions-list capability 1 โ”‚ โ””โ”€ region dashboards region-dashboards capability 1 โ”œโ”€ Prayer Mobilization +โ”‚ โ”œโ”€ Prayer Progress doxa-simple-map capability 2 โ”‚ โ”œโ”€ UPG100 Posters upg-100-mfe capability 4 โ”‚ โ”‚ โ”œโ”€ zoned map upg-100-list capability 1 โ”‚ โ”‚ โ””โ”€ poster wall poster-wall capability 1 -โ”‚ โ””โ”€ Prayer Progress doxa-simple-map capability 2 +โ”‚ โ”œโ”€ Country Posters country-posters-mfe capability 4 +โ”‚ โ””โ”€ Poster Design poster-design-mfe capability 4 โ”œโ”€ Gospel Research โ”‚ โ”œโ”€ Cities with Internet connectivity-map capability 1 โ”‚ โ””โ”€ Gospel Resources resources-map capability 1 @@ -352,7 +355,6 @@ Research Gallery capability 5 โ”œโ”€ prayer walk planner prayer-walk-planner capability 1 โ”œโ”€ UPG neighbor upg-neighbor capability 3 โ”œโ”€ all people groups all-people-groups capability 1 - โ”œโ”€ country posters country-posters capability 4 โ”œโ”€ vision card doxa-vision-card capability 2 โ”œโ”€ PPLR data maps pplr-data-maps capability 3 โ””โ”€ Wall of People Groups wall-of-people-groups capability 3 @@ -498,7 +500,7 @@ files in the repo. The `Dockerfile` and `compose.yaml` sit at the repo root; rec **Plugin Studio: the public Studio, with PocketBase.** The highest route: the same container with `ACCESS=public`, on your research subdomain. -- The Plugin Studio follows `development` and is open to everyone, so what agents land shows up live. +- The Plugin Studio follows `development` and is open to everyone, so what agents add to the pilot shows up live. - Its `/cdn`, built from `main`, serves your site's production maps. - Publishing and PocketBase's dashboard ask for a password you set when you deploy; OIDC stays available. @@ -615,21 +617,38 @@ bun run phone # builds the app and installs it on a phone or emulator ### Output 3 โ€” the desktop app โœ… works today -**We got the JAMstack map app running as a desktop app.** - -![Desktop app (Tauri), working](documentation/readme-images/deploy5-desktop.png) - -**Rudder, the voice-to-text plugin, runs as its own desktop app too**, built with -`bun run desktop:build rudder-voice` ([HOWTO-build-the-desktop-app](./documentation/HOWTO-build-the-desktop-app.md)). +**Run it in your browser, then ship the same code as a desktop app.** [Tauri](https://tauri.app) wraps +it in a small Rust program that runs on your computer. Rudder, the offline voice-to-text plugin, is the +proof: its Linux desktop app works and is used to dictate the work on many of these maps. Its goal is +private voice-to-text that you own: offline, no telemetry, no cloud. ![Rudder, the offline voice-to-text desktop app, running](documentation/readme-images/deploy5-desktop-rudder.png)
-More about the desktop app +More: how it works, Rudder's goal, and what isn't run yet -[Tauri](https://tauri.app) wraps the same built folder into a desktop program: it produced a Linux -app and a `.deb` installer. It isn't in the dx bundler for production yet โ€” and the Research Gallery -could become a strong desktop app. +**How it works.** What you build and try on the development server (`bun run dev`) is what ships to +the desktop; there is no second code base. Rudder runs as a corner widget in the Plugin Studio and as +its own desktop app, built with `bun run desktop:build rudder-voice` +([HOWTO-build-the-desktop-app](./documentation/HOWTO-build-the-desktop-app.md)): look at a plugin, say +what you see, and hand the text to an agent. The map app runs as a desktop app the same way. + +**Rudder's goal, from the start: private voice-to-text that you own.** + +- **Offline, with no telemetry and no cloud.** Your own code and your own self-hosted speech model + (NVIDIA's open NeMo-Speech.cpp runtime and a small speech model, about 742 MB) run on a modest amount + of your computer's CPU. After a one-time download of the runtime and the model, nothing needs the + network; a trace of the speech runtime showed zero sockets and zero DNS lookups. The aim is that it + works out of the box: today the first-run download is still a manual step. +- **Be careful who commits to Rudder.** A voice-to-text tool hears everything said near it, so one + bad change could turn it into spyware. Take changes to `plugin-designs/rudder-voice/` and + `backend/rudder-engine/` only from people you trust, and have a second person read every one. +- **Planned: an egress monitor** that shows you, as it runs, that Rudder sends no data out to anyone. + +**What isn't run yet.** Tauri builds a Linux app and a `.deb` installer today. The macOS and Windows +builds are set up but have not been run ([the HOWTO](./documentation/HOWTO-build-the-desktop-app.md) +says which steps are proven). The desktop build runs on demand with the commands below; the automatic +production build doesn't make it yet. The Research Gallery could become a strong desktop app too. ```bash bun run check:tauri # checks the desktop setup โ€” needs no Rust tools @@ -725,8 +744,9 @@ has one agent that owns it, and the work moves through three kinds of branch: with hot reload follows it, so each change that joins can be seen there within about 15 seconds. - **The landing branch (`main`)** is what ships. It moves only when a person approves a publish, and the landing server rebuilds from it. -- **PR branches** hold one plugin or feature each. They start from the landing branch and join the - pilot branch, one at a time, after the checks pass and a second reader has read the change. +- **PR branches** hold one plugin or feature each. They start from the pilot branch, take in the latest + pilot by merging (never rebasing), and join it one at a time, after the checks pass and a second agent, + usually the repository's agent, has read the change. **It scales by adding PR branches, not by sharing one.** Many people, each with several agents, can work on many plugins at the same time: every plugin or feature gets its own PR branch, and each one @@ -734,10 +754,12 @@ can be seen on the pilot server as soon as it joins the pilot. **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 merges onto the pilot in order, or a -gate-keeper that reads each change before it joins the pilot, are jobs your harness gives to its agents. +Studio; it does not ship a harness. There are three roles: one agent per repository, which handles its +branches and watches the work being done in it; one agent per plugin; and one shepherd agent that all the +other agents talk to, which keeps order and puts the merges onto the pilot in order. Your harness gives +these jobs to its agents. -![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 joins the pilot and then reaches the landing branch, in four steps, the three outputs, and how it scales: one PR branch per plugin, a self-hosted git service, and publishing to a public host only from the landing branch](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 shepherd and a repo agent over the plugin agents; below, how a change joins the pilot and then reaches the landing branch, in four steps, the three outputs, and how it scales: one PR branch per plugin, a self-hosted git service, and publishing to a public host only from the landing branch](documentation/readme-images/delegation-model.png) [Open the diagram full size](documentation/readme-images/delegation-model.png): on a phone its small text needs it. @@ -748,11 +770,11 @@ gate-keeper that reads each change before it joins the pilot, are jobs your harn ```bash git fetch origin && git switch -c development origin/main && git push -u origin development ``` -3. **One PR branch and worktree per feature**, each started from the landing branch, then install +3. **One PR branch and worktree per feature**, each started from the pilot branch, then install once in each: ```bash - git worktree add -b regions/work ../dx-maps-regions origin/main - git worktree add -b upg100/work ../dx-maps-upg100 origin/main + git worktree add -b regions/work ../dx-maps-regions origin/development + git worktree add -b upg100/work ../dx-maps-upg100 origin/development cd ../dx-maps-regions && bun install --frozen-lockfile ``` 4. **One preview server per agent on your own machine, each on its own port** (in the cloud, the one @@ -760,35 +782,43 @@ gate-keeper that reads each change before it joins the pilot, are jobs your harn ```bash bun x vite --port 5301 --strictPort # the next agent uses 5302, and so on ``` -5. **Join the pilot one at a time, through a lock that works like a merge queue.** Inside the lock, merge your PR branch into a - throwaway copy of the pilot branch, run the checks, and push that merge only if nothing fails - (`gates:pre` exits non-zero when a check fails, so the push never runs then). Your PR branch itself - stays one feature on the landing branch; only the pilot gets the merge: +5. **Join the pilot one at a time, through a lock that works like a merge queue.** First merge the + latest pilot into your PR branch (merge, never rebase) and fix any clash there. A second agent reads + the change, and looks at it on screen where it shows. Then, inside the lock, merge the pilot once more + in case it moved, run the checks (`gates:pre`, `gates:post`) and the landing checks (fresh bundles, + the tree, the integrity hashes, no conflict markers), and push only if nothing fails: ```bash + git fetch origin && git merge --no-edit origin/development # on your PR branch: the latest pilot flock /tmp/dx-maps-development.lock sh -c ' - git fetch origin && git switch --detach origin/development && - git merge --no-edit regions/work && - bun run gates:pre && git push origin HEAD:development - git switch regions/work' + git fetch origin && git merge --no-edit origin/development && + bun run gates:pre && bun run gates:post && + node internal/landing-preconditions.mjs && + git push origin HEAD:development' ``` If the merge stops on a conflict, run `git merge --abort`, fix the clash on your PR branch and join again. `flock` guards one machine. Agents on several machines need a shared lock, such as one your harness provides. -6. **One agent owns the full build**; the others build only their own plugin: +6. **Each change rebuilds what it touches.** There is no single build owner: rebuild every bundle your + change reaches, then the tree and the integrity hashes, and commit them with the change. The landing + checks refuse a change whose bundles are stale: ```bash - BUILD_ALLOW=1 bun run build # the build owner: every plugin - BUNDLE= bun x vite build && bun run tree && bun run fix:sri # everyone else: one plugin + BUNDLE= bun x vite build # each bundle your change reaches + bun run tree && bun run fix:sri # then the tree and the integrity hashes ``` -7. **Publish, when a person approves it:** fast-forward the landing branch to a pilot commit that - passed the checks, tag it, and deploy from the tag: + Only a change to the build itself (its config or its dependencies) reaches every bundle: + `BUILD_ALLOW=1 bun run build`. +7. **Publish, when a person approves it:** make sure the release the landing branch is on now has its + own version tag (that tag is the rollback point), fast-forward the landing branch to a pilot commit + that passed the checks, tag it, and deploy from the tag: ```bash git fetch origin && git switch main && git merge --ff-only origin/main + git tag -a v0.2.0 -m "Release v0.2.0" && git push origin v0.2.0 # the outgoing release, if untagged git merge --ff-only # a commit that passed the checks - bun run gates:pre # the checks must pass on exactly this commit + bun run gates:pre && bun run gates:post # the checks must pass on exactly this commit git tag -a v1.0.0 -m "Release v1.0.0" && git push origin main v1.0.0 ``` - The tag's `public/dx-maps/` folder is the built site: deploy that - ([how to deploy](./documentation/DEPLOY.md)). Publish to a public host, such as GitHub, only from + The tag's `public/dx-maps/` folder is the built site: deploy that, and build the landing demo from + the same tag ([how to deploy](./documentation/DEPLOY.md)). To go back, deploy the previous release's tag. Publish to a public host, such as GitHub, only from the landing branch and only when it is ready. ### Developing in the cloud with a swarm @@ -826,8 +856,9 @@ So the project works like a busy kitchen: 2. **Only one change joins the pilot 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 merges onto the pilot in order, and a gate-keeper can read - each change by its content before it joins the pilot. Your harness gives these jobs to its agents. +3. **Someone keeps order.** One shepherd agent, which all the other agents talk to, keeps order and puts + the merges onto the pilot in order; one agent per repository handles its branches and watches the work + being done in it. Your harness gives these jobs to its agents. 4. **The landing branch moves only when a person approves a publish**, after the checks pass on that exact version. The pilot server follows the pilot branch; the landing server rebuilds from the landing branch. @@ -845,7 +876,7 @@ That's how many plugins get built at the same time, in one project, without the | **main** (the landing) | the version that ships: it moves only when a person approves publishing `development` | | **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 | -| **merge** | combining your branch with everyone else's latest work; here it happens inside the pilot lock, in a throwaway copy of the pilot | +| **merge** | taking everyone else's latest work into your branch: the latest pilot goes into your PR branch (never a rebase), before joining and once more inside the pilot lock | | **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 | @@ -929,7 +960,7 @@ The studio is a plugin like any other: `plugin-designs/plugin-studio/plugin-stud ### Run it in the cloud **One shared dev server for the whole team, no laptop setup.** A container clones the repo, follows -`development`, and hot-reloads every change an agent lands, so everyone sees the Plugin Studio update in +`development`, and hot-reloads every change that joins the pilot, so everyone sees the Plugin Studio update in their browser within seconds, with no rebuild. Add OIDC settings and it puts a "Sign in with *your provider*" page in front of everything, open only to the groups you allow. Recipe and settings: [deployment/cloud/](./deployment/cloud/README.md). @@ -940,7 +971,7 @@ The three ways dx-maps ships (a drop-in into your own site, the container on its ### Cloud development environment -**Your laptop can follow what agents land somewhere else.** By default `bun run dev` is fully local: no +**Your laptop can follow what agents add to the pilot somewhere else.** By default `bun run dev` is fully local: no settings, nothing fetched, and only your own edits hot-reload. To also see what agents push to a shared branch (an agent on a server, or the whole team), add two lines to `.env.local` (gitignored): diff --git a/documentation/HOWTO-build-the-desktop-app.md b/documentation/HOWTO-build-the-desktop-app.md index 33360ce45..0fb8f8936 100644 --- a/documentation/HOWTO-build-the-desktop-app.md +++ b/documentation/HOWTO-build-the-desktop-app.md @@ -4,8 +4,9 @@ Rudder (`plugin-designs/rudder-voice`) is voice-to-text that runs on your own co local engine (`backend/rudder-engine`, Go) that drives NVIDIA's NeMo-Speech.cpp speech server. The desktop app is a Tauri window around the built web tree, with the engine started as a **sidecar**. -This page is written for an agent following it cold. **Read "What is proven" first**: most of the -desktop path has never been run by anyone, and the steps say so where that is the case. +This page is written for an agent following it cold. **Read "What is proven" first**: the Linux app is +proven and in use; the macOS and Windows path has not been run yet, and the steps say so where that is +the case. ## What is proven, and what is not @@ -18,8 +19,8 @@ desktop path has never been run by anyone, and the steps say so where that is th | The engine **compiling** for macOS (arm64, x86_64) and Windows (x86_64) | Proven by cross-compiling. It has **never been run** on either. | | The engine accepting a WebSocket from the Tauri webview (`tauri://localhost`, `http://tauri.localhost`) | Proven against a running engine; another site's origin is refused. | | NeMo-Speech.cpp runtime for macOS / Windows | Published by NVIDIA (release v0.1.0: `macos-aarch64-cpu`, `macos-aarch64-metal`, `macos-x86_64-cpu`, `windows-x86_64-cpu` / `-cuda` / `-vulkan`). **Never run here.** | -| `bun run desktop:build rudder-voice` on **Linux** | Proven: produced `Rudder_0.1.0_amd64.deb` (8.8 MB) holding the app and the `rudder-engine` sidecar side by side. The app has **not been launched** from it yet (no display on the build box). | -| The shell starting and stopping the engine sidecar | Built (`deployment/src-tauri/src/main.rs`), compiled into that installer; not yet run. | +| `bun run desktop:build rudder-voice` on **Linux** | Proven: produced `Rudder_0.1.0_amd64.deb` (8.8 MB) holding the app and the `rudder-engine` sidecar side by side. The installed Linux app has since been launched and is in use: it is used to dictate the work on these maps. | +| The shell starting and stopping the engine sidecar | Built (`deployment/src-tauri/src/main.rs`), compiled into that installer. The installed Linux app works (the row above); not yet run on macOS or Windows. | | First-run model download | **Not built.** Run `setup-runtime.sh` into the app's data folder by hand (step 7). | ## 1. Prerequisites diff --git a/documentation/readme-images/delegation-model.png b/documentation/readme-images/delegation-model.png index 63217aa59..6780b539b 100644 Binary files a/documentation/readme-images/delegation-model.png and b/documentation/readme-images/delegation-model.png differ diff --git a/documentation/readme-images/deploy5-desktop.png b/documentation/readme-images/deploy5-desktop.png deleted file mode 100644 index f670797ef..000000000 Binary files a/documentation/readme-images/deploy5-desktop.png and /dev/null differ diff --git a/documentation/readme-images/src/delegation-model.svg b/documentation/readme-images/src/delegation-model.svg index 5edefe17c..b4e420bbf 100644 --- a/documentation/readme-images/src/delegation-model.svg +++ b/documentation/readme-images/src/delegation-model.svg @@ -116,15 +116,15 @@ Experimental shelf ยท 5 plugins -roaming -agent +an agent +per plugin -coordinator +shepherd -gate-keeper -a coordinator puts the merges in order; -a gate-keeper checks each one by its content -one owner per plugin, in its own branch ยท a second reader for every change +repo agent +one shepherd: every agent talks to it; it orders the merges; +a repo agent per repo runs its branches and watches the work +one agent per plugin, in its own branch ยท the repo agent reads every change pilot branch (development) @@ -139,9 +139,9 @@ agent โ€” owns one plugin -coordinator โ€” orders merges +shepherd โ€” orders merges -gate-keeper โ€” checks each merge +repo agent โ€” one per repo How a change joins the pilot โ€” one at a time, so many plugins can be built at once @@ -155,8 +155,8 @@ 2 -Second reader -another agent reads every +Repo agent reads +the repo agent reads every change by its content before it may join โ†’ diff --git a/documentation/readme-images/src/deploy5-desktop.svg b/documentation/readme-images/src/deploy5-desktop.svg deleted file mode 100644 index 7f4c4baae..000000000 --- a/documentation/readme-images/src/deploy5-desktop.svg +++ /dev/null @@ -1,12 +0,0 @@ - - - - -Desktop app (Tauri) -We got the JAMstack map app running -as a desktop app. - -PROVEN ยท NOT YET LIVE -Proven, not yet in production. The Research -Gallery could become a strong desktop app. - \ No newline at end of file