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

  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.