# 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](/docs/deployment/deploy) 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.

## 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](/docs/deployment/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.
- `createCommitOnBranch` with 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](/docs/deployment/auth).
- 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.
