Skip to content

Architecture

Where feedbai is going, decided on 2026-11-08: one simple architecture, the same for everyone, from one person to an organisation with hundreds of repositories. It builds on an agent in the loop. It is a plan: what exists today is in the status issue.

  1. Security first, always. No process ever holds untrusted text, secrets and the power to act together. Every token is scoped to one project and one job, and can be revoked. Nothing merges without a human.
  2. The same for everyone. One program, one pipeline, the same tools. Only who runs it changes: us, you, or your organisation.
  3. Free software, self-hostable. Everything we run is the open-source stack. Anyone can run it on their own domain, and nothing we host is required.
  4. Inclusive. A person who has never used a terminal can set it up in one click. An organisation can run all of it itself.
  5. No setup by hand at scale, and no agent deciding what it touches. Enrolling 300 repositories is one choice by a human; plain code does the setup; agents only ever see one project at a time.

One program, the feedbai runner (the hub, grown up), runs for every enrolled project, each in its own sandbox, the same fixed pipeline:

Stage Sees untrusted text Holds Can Is
Read yes, it fetches it a read-only channel token nothing else feedbai (plain code)
Triage yes no secrets, no tools only output JSON, checked against a schema (kind, title, summary, message links) one model, chosen per account
Act only the validated JSON an issues-write token, the agent’s channel token file issues (feedbai file), react ✅ (feedbai react), post fixed replies plain code, no model
Code (off by default) only issues a human accepted a token that can open pull requests, never merge change code in a throwaway sandbox Claude Code or Codex, chosen per account
Reply no the agent’s channel token “🤖 This is fixed: …” when a pull request closes the issue plain code, a fixed template

Whoever writes a message can only influence the triage model, which can’t do anything but produce JSON. The stages that act are plain code. Tokens are injected by the runner (at best, added to outgoing requests by a proxy, so no stage ever sees them), short-lived where the platform allows (GitHub App tokens last an hour), and each stage may only reach the hosts it needs.

Copying tokens into settings is a chore and a risk. Projects get identities that platforms already provide:

  • GitHub: the workflow’s own token (issues), automatic.
  • The triage model: the one thing that may need a key (OpenRouter, a provider), unless you triage in your own agent session or run a local model. There is no free model inside GitHub Actions anymore (GitHub Models was retired in July 2026).
  • Matrix and Bluesky: the runner’s bots act for a project that proves which repository it is, a short-lived token signed by its CI (GitHub Actions OIDC), in rooms whose admins tied them to it (the repository in the room topic). Nothing is created, copied or stored.

Only people running everything themselves create accounts, with one guided command (feedbai agent setup, to come), never by copying tokens.

Enrolling projects: one click, not one setup per repository

Section titled “Enrolling projects: one click, not one setup per repository”
  • Install the feedbai App on your account or organisation and choose all repositories, or a selection. The runner works on exactly what the App was given. Uninstalling stops everything.
  • Where each project talks (Matrix room, Bluesky handle…) is found by plain code, from links in the repository as feedbai already does, and proposed as one pull request per repository. A human merges it, or approves them in bulk.
  • Pausing one project: a .feedbai/pause file in it.

Configuration: one place per account, overrides where needed

Section titled “Configuration: one place per account, overrides where needed”

A .feedbai repository per account or organisation (like GitHub’s .github) holds:

  • defaults: which model triages, whether the code stage is on, labels;
  • guidelines (#63): how your projects want feedback turned into issues, which every triage reads;
  • the AI key’s location (never the key itself).

A feedbai.config.json in a repository only says what differs: its channels, its own guidelines, turning the code stage on.

Identities: one agent per project, created by the runner

Section titled “Identities: one agent per project, created by the runner”

People see, and room admins can kick or mute, one agent per project, never a person’s own account and never one shared bot:

  • Matrix: the runner has its own Matrix server with an application service (the Matrix mechanism for bots and bridges). It creates @<project>:feedbai.internet4000.com (or @<project>:your.org when you run it) the moment a project is enrolled, and issues one revocable token per agent. The master key stays in a small isolated service; each project’s run only gets its own agent’s token.
  • Bluesky: handles under the same domain (<project>.feedbai.internet4000.com), with accounts on the runner’s own Bluesky host (PDS), created the same way.
  • Forges: the App’s installation token, scoped to the repository, issues only (plus pull requests when the code stage is on).

Accounts created by hand don’t scale to hundreds of projects; created by the runner, they’re automatic and isolated.

One key per account or organisation, used for all its projects: Anthropic, OpenAI, or OpenRouter (many models behind one key). A small, cheap model triages; a strong coding agent writes code; replies need no model. On our hosted runner, people without a key can pay for usage instead. We never train on anything, and the triage only sees what a project’s channels say.

The same stack (the runner, a Matrix server, a Bluesky host), packaged to run as one docker compose:

Runs it Agent identities Pays
A person, a small project our hosted instance at feedbai.internet4000.com: sign in, choose repositories, done @project:feedbai.internet4000.com prepaid credits or a subscription, or their own AI key (no free credits)
Someone with many projects (or friends) our instance, or their own box ours, or on their domain their AI key; compute if hosted by us
An organisation itself, on its own domain, with its own models and sign-in @project:their.org nothing to us

Payments exist only on our hosted instance, through Stripe (we never see card details), for compute and optionally AI usage.

The privacy trade-offs we accept, and their limits

Section titled “The privacy trade-offs we accept, and their limits”
  • A Matrix server keeps a copy of the rooms it joins (that’s how Matrix works). So on our hosted instance, agents join public rooms only, history is kept short and encrypted at rest, and the privacy notes say so. Private rooms need a self-hosted runner: your server, your data.
  • Our hosted instance holds state (enrolled projects, encrypted secrets, schedules): a deliberate exception to “feedbai stores nothing”, only there, never required, and absent when you run it yourself.
  • The master key of a runner’s Matrix application service is its most valuable secret: isolated, minimal code, rotated, audited.

The hosted tier: one small box, many projects, sealed from each other

Section titled “The hosted tier: one small box, many projects, sealed from each other”

For people who arrive with nothing: they sign in with their forge (GitHub first), pick repositories (the App), and agents run for them. They pay as they go (prepaid credits) or by subscription, or bring their own AI key. No free credits: free usage invites abuse and costs us real money. Only our own projects run on our tab.

Small enough to run on one machine (a Hetzner server or a Raspberry Pi 5), and sealed per project:

Piece What Why it’s safe
Front door a Cloudflare Tunnel to the box: no open ports the box is never reachable directly; our Worker and its rate limits sit in front
Sign-in “Sign in with GitHub” (the App’s user sign-in) no passwords of ours; org membership comes from the forge
The runner the same open-source code as everywhere one program to audit
Each run a throwaway rootless container per project per run: read-only filesystem, no Linux capabilities, CPU and memory limits, its own network that can only reach the hosts its stage needs (through an egress proxy) a run can’t see other projects, the host, or the internet at large
Tokens minted per run, scoped to one repository, short-lived (GitHub App: 1 hour); Matrix and Bluesky actions through the runner’s bots, only in rooms the project’s admins tied to it nothing long-lived to steal from a run
Data one SQLite file: accounts, projects, credits, run log (30 days); settings and any user’s own AI key encrypted per project (envelope encryption: a key per project, itself encrypted by the box’s master key held by systemd credentials, TPM-backed where the hardware has one) one leaked project key opens one project
Payments Stripe Checkout and signed webhooks card details never touch us; credits are spent per run and shown per project
Models our provider account (billed back as credits), or the user’s own key the triage stage never gets tools or secrets either way
Backups the SQLite file, encrypted, off the box losing the box loses no one’s data
Updates signed releases, automatic security updates for the OS a small surface kept current

What it holds is exactly what the privacy notes will list, and each project can export or delete its data. Organisations that need more isolation (their own models, sign-in, servers) run the same stack themselves.

  • The shared @feedbai:matrix.org bot filing every mention: replaced by per-project agents and a triage step (#70). Until then it stays in public rooms only, with fixed texts (SECURITY.md).
  • Per-repository CI workflows (on your own): still possible for one project, but not the way to run many.

Each step is used on real projects before the next one starts.

  1. The runner on our own repositories: today’s hub plus the triage and act stages, with feedbai and radio4000 as the first projects, using their own agent accounts.
  2. Agent handles under our domain: cheap, our Worker already proves handles.
  3. Our Matrix server and application service: per-project agents created automatically, public rooms only.
  4. The .feedbai configuration repository and the bulk setup pull requests: enrolling many repositories at once, for us and for friends.
  5. The hosted tier on one box (above): sign in with GitHub, pick repos, our model, a dashboard, for us and a few friends first; then prepaid credits and subscriptions (no free credits).
  6. The self-hostable package (one docker compose), the same as our box, for organisations.
  • What the hosted tier costs (credits per run, a subscription), and which sandbox runtime on a Raspberry Pi (rootless Podman, gVisor)? To verify on the hardware before building.
  • Forgejo, Codeberg and GitLab have no GitHub-style Apps: what’s the one-click enrolment there?
  • End-to-end encrypted Matrix rooms: the runner would need full Matrix encryption support.