---
title: "Foundations"
source: "docs/decisions/ADR-0001-foundations.md"
---

> Part of [botgumi docs](https://botgumi.com/docs/llms.txt). Every page: [llms.txt](https://botgumi.com/llms.txt).

# ADR-0001: botgumi foundations

Status: accepted · 2026-10-18

## Context

botgumi turns a working app-development process into a versioned template and a set of shared
packages. It comes from the lessons of one shipped app; nothing specific to that app belongs here.

## Decisions

1. **Name and home.** `botgumi` (ボット組, "the bot crew"), at `github.com/xieweizhi/botgumi`. The CLI is
   `botgumi new <app>`. Renamed from `app-studio` before v1: the `@app-studio` npm scope belongs to another
   active project, and "App Studio" is a crowded name. Swift modules use the `Botgumi` prefix.
2. **License.** MIT. The copyright line names "botgumi contributors", not a person.
3. **Visibility.** Private until v1, then public. Before going public: scan the full git history for
   secrets (for example with gitleaks) and remove anything specific to one app.
4. **Swappable providers.** Each third-party tool sits behind an interface with a no-op adapter and a
   contract test suite that every adapter must pass. App code imports interfaces only; a lint rule enforces it.
   Defaults: Amplitude (analytics and flags), Sentry (crash), RevenueCat (purchases), Cloudflare (email, domain lookup).
5. **Opinionated core (not swappable).** Cloudflare backend (Workers, D1, R2, KV, Access);
   TanStack Start + Cloudflare Pages for web; native iOS with XcodeGen; the asc CLI for App Store tooling.
   Amended by ADR-0002: native Android (Kotlin, Compose, Gradle, Google Play) joins the core, and an app picks
   its platforms.
   Amended by ADR-0003: the operator dashboard is by default a private Claude artifact fed by a morning
   collector; TanStack Start stays the web stack for the landing page and the optional web dashboard.
6. **One provider config per app.** `botgumi.config.ts` names the provider for each concern.
   The generator installs only those adapters. Event names and flag keys live in the app's tracking plan.
7. **Multilingual from day 0.** UI locales `en` and `zh-Hans` in v1. Every user-facing string is authored
   in both. Content language is per item. No CJK-only logic.
8. **Versioning.** Semver with Changesets. Each app records the template version it was generated from;
   an upgrade bot opens a PR in each app when a new version ships.
9. **One Swift package at the repo root.** SwiftPM only resolves a package by URL when `Package.swift`
   is at the repository root, so the manifest lives there and the sources live under `packages/swift/`.
   Each module is its own library product.
10. **CI.** TS checks run on GitHub. Swift and iOS run locally only (`scripts/verify.sh`, each app's
    `ios/scripts/ci.sh`). No macOS runners.
11. **Agent runtimes.** Agents run behind an `AgentRuntime` interface with two v1 runtimes: `claude`
    (Claude Code / Agent SDK) and `codex` (Codex CLI). Each role picks a runtime and model in
    `botgumi.config.ts`, with per-track overrides. Role files carry no model.
12. **Model policy (defaults).** Orchestrator on Fable 5.1, falling back to Opus 5.5 when tokens run low.
    Workers on Opus 5.5 for the high tier and Sonnet 5.5 for mid and low, chosen per task by the orchestrator.
    See `agents/model-policy.md`.
13. **Instructions written once.** `AGENTS.md` is the source; `CLAUDE.md` contains only `@AGENTS.md`.
14. **PR review.** One agent writes, another reviews, against fixed rules (`agents/review-rules.md`). The
    reviewer is never the author and by default runs on a different runtime. High-risk PRs get both
    reviewers. After 2 rounds with blocking findings open, the orchestrator escalates to a human.
    The author never merges its own PR.
15. **Task intake.** Every task is a GitHub issue. Issues with the `botgumi` label or an `@botgumi`
    mention, chat, and `botgumi task "…"` are the ways in. Human gates are issues labelled `gate`.
    Amended by ADR-0004: the brand, design system, lo-fi, hi-fi and screenshot gates close the five design
    stages in that order, and no app screen is built before its hi-fi gate.
16. **Event delivery.** GitHub webhooks go to a Cloudflare Worker (`botgumi-relay`) that queues them in a
    Durable Object; the local runner reads them over an outbound WebSocket and does a catch-up poll through
    `gh` at start and every few minutes. No inbound port on the user's machine.
17. **Trust.** Issue and comment text counts as instructions only from allowlisted authors (default: the repo
    owner). Everyone else's text is data.
18. **Bot identity.** Agents act as a GitHub App (`botgumi[bot]`) with issues, pull requests, contents,
    commit statuses and projects permissions, installed only on chosen repos (`docs/github-app-setup.md`).
19. **Merge policy.** The orchestrator, never the author, may merge when the tier is in `merge.auto`
    (default `low`), all required statuses pass (including `ios-ci` and `botgumi/review`), no protected path
    is touched, the diff is under `merge.maxLines`, and the PR is not a gate. A failed smoke check or a Sentry
    spike within `merge.watchMinutes` triggers a revert PR. In the botgumi repo itself, a human merges.

## Consequences

- Vendor SDK dependencies in the Swift package are resolved by every app that depends on botgumi,
  even when it links only the interfaces. When the first vendor SDK is added, decide between SwiftPM
  traits and splitting adapters into their own repositories.
- TS packages export source (`.ts`) until a build step exists, so they stay `private` and unpublished.
