Front and back
A ships; B and C are ideas
The hosted board is option A: the kanban calls the board server, which writes the chosen store. Deploy a hosted board sets it up. B and C stay TODO.
The kanban is static files. A hosted board needs something that turns a browser edit into a commit. There are three shapes for that.
| How the shapes compare | A. Front and back | B. Front only | C. Both |
|---|---|---|---|
| Nothing to runB needs a small sign-in function | — | ~ | |
| The GitHub token stays off the browser | — | ~ | |
| Each commit under the user's own nameA needs sign-in with GitHub | ~ | ||
| One implementation of the board logicB and C need the core in WebAssembly | ~ | ~ | |
| Works without GitHub | — |
A. Front and back: ships
The page calls the board API, and the API writes to Git or SQLite. This is the local mode with the loopback limit lifted, signed in with a GitHub App.
- The GitHub token stays on the server and never reaches the browser.
- Every write goes through the same validation and commit builders as the CLI.
- Someone has to run the server: a process, TLS and a secret. Render’s free
plan runs it from this repository’s
render.yaml.
Sign-in, sources and storage are independent
| Contract | Responsibility | Implementations |
|---|---|---|
| Authentication | Identify the person and keep credentials on the server. | GitHub sign-in; explicit local or HTTPS workspace bearer. |
| Source provider | Discover sources, expose configuration fields and check current access. | GitHub repositories; configured SQLite databases with reader/writer policies. |
| Board service | Validate cards, create and apply operations, check hashes and revisions. | One implementation for every source. |
| BoardStore | Read snapshots and commit atomic changes. | Local Git, pushed Git and SQLite. |
/v1/sources returns provider-neutral references and descriptors. The client
renders each provider’s fields, opens the source through /v1/sources/open,
and uses the same board routes afterward. References contain selectors, never
credentials. Database permissions use stable provider subjects; Git source
identities include the repository id, so names do not define access. A source-bound session cannot open
another account’s data. Every request rechecks source permissions.
Signing in with GitHub does not put database contents in a repository. Git permissions govern Git sources; database policies govern SQLite. A failed provider can report its own warning while other sources remain available. SQLite shows a mixed-source configuration.
TODO: B. Front only, straight to GitHub
The page calls the GitHub API with the signed-in user’s token. There is no board server.
- Nothing to run: the site stays on GitHub Pages.
- Each commit carries the user’s own identity, and GitHub enforces who may write. That was always the real authority: anyone with push access can edit the board with git anyway.
createCommitOnBranchwith an expected head gives the same compare-and-swap the server does today.- The board logic (parsing cards,
board check, one line per commit) runs in the browser. Compiling the Rust core to WebAssembly would keep one implementation instead of two. - The token lives in the browser. Card descriptions render Markdown, so a script injection would expose a token that can write to the repository. This needs strict sanitising, a content security policy, and either a separate board repository or rulesets that protect every other branch.
- Signing in still needs a small token exchange: see Authentication.
- GitHub only: no local store, no other forge.
TODO: C. Both, behind one client
The page talks to one client interface with two implementations: the board API or GitHub directly. The most flexible, and two paths to maintain.
TODO: Ways to run it, whichever shape wins
Once there is one API, the same contract can be served several ways:
| Command | What runs | For |
|---|---|---|
TODO: serve | The kanban and the API, one origin | Self-hosting with one process |
TODO: serve --api-only | The API alone | The CLI and agents talking to a remote board |
| TODO: behind a proxy | Plain HTTP behind Caddy, nginx, Traefik or a tunnel | TLS and routing left to the proxy |
The design rule: one server, one API, several clients. The kanban is one client among them; self-hosting is one binary or one container image.