Records the tenet revision and its shape: instance registry and instance keys in ~/.werkator.yml (one instance per OS user), optional repo defaults in an explicit defaults: block merged below every repo's own layers, repo config unchanged in each repository, registry-wins precedence, basename repo names. Rejected: a federation dashboard over single-repo instances (keeps N services), and the status quo. Konzept/AGENTS architecture wording changes only when the implementation lands; the decision list carries 0009 now. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
61 lines
4.2 KiB
Markdown
61 lines
4.2 KiB
Markdown
# One Werkator Instance Serves a Set of Repositories
|
||
|
||
**Status:**
|
||
- proposed: 2026-09-01
|
||
- accepted: 2026-09-01
|
||
- rejected: -
|
||
- superseded: -
|
||
|
||
**Decision [accepted]:** The founding tenet "one instance per repository" is revised to "one instance per repository *set*": a Werkator instance aggregates self-contained repositories listed in an instance registry, sharing one service, one port, one UI, one watcher schedule, and one global executor cap.
|
||
Implementation is planned as `docs/plan/22-multi-repo.md`; this ADR records the decision and its shape, not the code.
|
||
|
||
## Context and Problem Statement
|
||
|
||
"One instance per repository" (docs/Werkator-Konzept.md) does not scale even to two repositories on a Hostsharing Managed Webspace: building Werkbaum next to Werkator on mih34 would need a second service, a second assigned port, a second tunnel or domain, a second UI and metrics page.
|
||
Every repository multiplies operations while the instance-level resources could be shared.
|
||
|
||
### Technical Background
|
||
|
||
Everything repository-specific already lives inside the repository or is keyed by it: machine config with secrets, build results, auto-build slots, worktrees, and buildenvs under `.git/werkator/`; the artifact store under a per-repo key.
|
||
An instance can therefore aggregate repositories without absorbing their state — adding or removing a repository is a registry entry, never a data migration, and single-repo mode stays the degenerate case (a registry of one, implicitly the current working directory).
|
||
|
||
## Considered Options
|
||
|
||
* One instance per repository set (registry + aggregation) — chosen
|
||
* A federation dashboard proxying several single-repo instances
|
||
* Status quo: one instance, one repository
|
||
|
||
### One Instance per Repository Set
|
||
|
||
Good:
|
||
|
||
- One service, port, UI, tunnel/domain, metrics page for any number of repositories.
|
||
- Repositories stay self-contained; per-repo secrets, history, and pinning semantics are untouched.
|
||
- Global concurrency control across all repositories.
|
||
|
||
Bad:
|
||
|
||
- The repo dimension must be threaded through executor pools, watcher cycle, routes, and UI — the largest refactor since the rewrite (mitigated by a behavior-preserving `RepoContext` session first).
|
||
- Instance-level and repo-level configuration must be split cleanly (see below).
|
||
|
||
### Federation Dashboard over Single-Repo Instances
|
||
|
||
Rejected: less invasive, but it keeps N services, N ports, and N tunnels — it solves only the UI aggregation, not the operations burden that motivated the change.
|
||
|
||
### Status Quo
|
||
|
||
Rejected: on a webspace, ports and domains are the scarce, manually assigned resource; per-repository services do not scale there.
|
||
|
||
## Decision Outcome
|
||
|
||
One instance per repository set, with the configuration split decided 2026-09-01:
|
||
|
||
- **Instance config** lives in `~/.werkator.yml` in the home directory of the user running the instance — one instance per OS user, matching the platform model. It carries `server.*` (port, domain/public base URL, nginx), the repository registry, the control token, the global `executor.maxConcurrent`, and the watcher schedule. The file name stays `.werkator.yml` in all three locations; the location carries the meaning.
|
||
- **Repo defaults** may live in the home file, but only in an explicit `defaults:` block, merged *below* every repository's own layers (home defaults → committed project config → repo machine config → branch layer); pinning semantics are unchanged. Accepted cost: secrets may then live in two places.
|
||
- **Repo config** stays in each repository: the committed `.werkator.yml` and the machine config in its `.git/werkator/`.
|
||
- Instance keys found in a repo's machine config are ignored with a warning naming both files once a home config exists — never merged silently.
|
||
- When a home config with a registry exists, `werkator server` serves the registry regardless of the current directory; without one it serves the current directory exactly as before.
|
||
- Repository names (routes, UI) default to the directory basename, are overridable per registry entry, and duplicates abort the start loudly.
|
||
|
||
Consequences: `docs/Werkator-Konzept.md` and AGENTS.md change their wording when the implementation lands (plan step 22 sessions B–D); until then this ADR documents the target and the existing behavior remains accurate.
|