Start here
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
- Name and home.
botgumi(ボット組, "the bot crew"), atgithub.com/xieweizhi/botgumi. The CLI isbotgumi new <app>. Renamed fromapp-studiobefore v1: the@app-studionpm scope belongs to another active project, and "App Studio" is a crowded name. Swift modules use theBotgumiprefix. - License. MIT. The copyright line names "botgumi contributors", not a person.
- 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.
- 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).
- 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.
- One provider config per app.
botgumi.config.tsnames the provider for each concern. The generator installs only those adapters. Event names and flag keys live in the app's tracking plan. - Multilingual from day 0. UI locales
enandzh-Hansin v1. Every user-facing string is authored in both. Content language is per item. No CJK-only logic. - 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.
- One Swift package at the repo root. SwiftPM only resolves a package by URL when
Package.swiftis at the repository root, so the manifest lives there and the sources live underpackages/swift/. Each module is its own library product. - CI. TS checks run on GitHub. Swift and iOS run locally only (
scripts/verify.sh, each app'sios/scripts/ci.sh). No macOS runners. - Agent runtimes. Agents run behind an
AgentRuntimeinterface with two v1 runtimes:claude(Claude Code / Agent SDK) andcodex(Codex CLI). Each role picks a runtime and model inbotgumi.config.ts, with per-track overrides. Role files carry no model. - 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. - Instructions written once.
AGENTS.mdis the source;CLAUDE.mdcontains only@AGENTS.md. - 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. - Task intake. Every task is a GitHub issue. Issues with the
botgumilabel or an@botgumimention, chat, andbotgumi task "…"are the ways in. Human gates are issues labelledgate. 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. - 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 throughghat start and every few minutes. No inbound port on the user's machine. - Trust. Issue and comment text counts as instructions only from allowlisted authors (default: the repo owner). Everyone else's text is data.
- 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). - Merge policy. The orchestrator, never the author, may merge when the tier is in
merge.auto(defaultlow), all required statuses pass (includingios-ciandbotgumi/review), no protected path is touched, the diff is undermerge.maxLines, and the PR is not a gate. A failed smoke check or a Sentry spike withinmerge.watchMinutestriggers 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 stayprivateand unpublished.