Repository navigation
Consolidation plan: every service's code and deploy definition in trios, driven by topology.t27 #1758
Description
The owner, 2026-10-10 (translated): move everything into one repository and one service managed through .t27, based on trios.
This issue is that plan. It is the consolidation that #1756 deferred: #1756 slice 2 needs it, and so does phase 2 of the disaster-recovery epic gHashTag/t27#8675. Nothing moves under this issue yet.
The plan is driven by specs/hosting/topology.t27 (gHashTag/t27#8699, PR gHashTag/t27#8708). That spec holds every Railway service, its source, build, volumes, tier and restore phase, and it is generated from the inventory of 2026-10-10. Every figure below comes from it. Costs are the inventory's 30-day run-rate estimates.
1. Where the code is today
| Code lives in | Visibility | Rows | Run-rate per 30 days | Services |
|---|---|---|---|---|
| gHashTag/999-multibots-telegraf | private | 15 (2 stopped) | $310.56 | the bot, vibee-render, vibee-editor, supabase-gateway, queen-watch, ci-bridge, check-runner. Also, from deployment/: gigaam, parakeet, mouth, voice-clone, voice-clone-qwen, browser-pod, telegram-bot-api, remote-browser |
| gHashTag/trios | public | 3 | $462.08 | trios-agent-server (branch queen), trios-bee-runner-1 and -2 (branch queen-runners) |
| gHashTag/t27 | public | 3 | $268.96 | t27b-lab, t27b-lab-2 (contrib/railway/t27b-lab), t27c-lab (infra/t27c-lab) |
| gHashTag/trinity | public | 2 (1 stopped) | $1.26 | queen-proxy (apps/queen-proxy), queen-web (apps/queen-web) |
| gHashTag/igla-coder-gpu | private | 2 | $0.25 | igla-judge board, loop |
| gHashTag/t27-github-collab | private | 1 | $0.02 | t27-github-collab |
| gHashTag/leela, woody-weed-bot, turbobaby-user-bot, trios-railway, BrowserOS | public | 6 | $1.51 | one or two services each. turbobaby-bot is crashed and browseros never ran |
| registry images, no code of ours | n/a | 14 (2 stopped) | $339.41 | Postgres x5, pgvector, Redis, postgrest, supabase-storage, whisper, vision, zep, zep-nlp, inngest |
| Railway templates | public | 4 (2 stopped) | $14.26 | minio Bucket x2, minio Console x2 |
| Railway functions | inline in Railway | 3 (2 stopped) | $39.54 | agents-acceptance-once, crm-door-once, todo-api. Copies were recovered off GitHub |
| only inside Railway | unknown | 3 | $12.97 | skills-site, jobsearch-cron, project-brain's overlay |
| no deployment | n/a | 3 | $4.81 | dayo64-xcheck build, both igla-judge judge |
Two facts change the plan:
- trios's deployed Queen does not share history with trios
main.queenandqueen-runnershave no common ancestor withmain(gh api repos/gHashTag/trios/compare/main...queenanswers "No common ancestor"). "Into trios" therefore also means bringing those trees undermain, or naming the branch in every definition. - 18 rows run private code, and 15 of them are in one repo. 999-multibots-telegraf already works as a private monorepo for nearly everything private.
2. What may move into trios
trios is public. Private code and its git history never go into it.
- May move, code and history: the public code: trios-railway, leela, woody-weed-bot, turbobaby-user-bot, the two trinity apps, the t27 labs, and the Queen branches into trios
main. - May move, definitions only:
- the definitions of all 59 rows. They are already public, in topology.t27;
- images and templates, which have no code of ours.
- Never moves into a public repo:
- 999-multibots-telegraf, igla-coder-gpu and t27-github-collab, and their history;
- the three Railway-only sources until someone has read them. They go to a private repo first;
- the recovered function copies. crm-door-once names CRM clients.
3. Options for the private code (the owner chooses)
| Option | What it is | For | Against |
|---|---|---|---|
| A. Private monorepo | One private repo holds all private service code. It could be 999-multibots-telegraf itself (15 of the 18 private rows are there already), or a new trios-private |
Nothing private is exposed. The smallest code move: igla-coder-gpu's two folders and t27-github-collab join it | Two repos, not one. CI is split. The deploy plane needs a read token for the private repo, so it is owner-tier only |
| B. Private submodules in trios | trios/deploy/private is a submodule pointing at a private repo |
The owner's clone --recursive gives one tree |
The public repo publishes the private repo's name and every pinned commit id. Public CI, contributors and public-tier hosts get a broken checkout. Railway building trios with a private submodule is untested: test it before relying on it. Every change needs a second commit to bump the pointer |
| C. Public definitions, private code | trios/deploy/ holds a generated definition for every row. A private row's definition names its repo, path and commit; the code stays private |
One place to see and deploy everything, with no private code moved. Small, reversible steps, and no history rewrite | The code is not literally in one repo. The definitions name private repos and commits, which topology.t27 already does publicly |
| D. Make trios private | Everything moves into trios, history included | Literally one repo | It ends trios as an open project. #1756 needs public hosts to fetch the host agent and its jobs, so a public distribution is needed anyway. Actions minutes are metered for private repos. Links from public repos to trios issues, which the swarm uses as ledgers (#1729, #1751), stop opening for anyone outside the org. All eggs go into the GitHub account that #8675 names as at risk. Undoing it later re-exposes everything that moved in |
Recommendation: C now, with A for the private code. Make 999-multibots-telegraf, or a new private repo, the one private home, and move igla-coder-gpu's board/remote/loop and t27-github-collab into it. D is the only option that satisfies "one repository" literally, and it gives up the most.
4. Target layout
trios already has deploy/docker, deploy/launchd and deploy/systemd, so the per-service tree goes beside them:
trios/
deploy/
services/
<project>/<service>/
service.t27 generated from topology.t27's row: never hand-edited
railway.json generated from service.t27 (plumbing a resolver parses), only for rows Railway builds
src/ only for public code that moved here (the Dockerfile and the app)
docker/ launchd/ systemd/ as today
topology.t27 keeps one home. Either t27 stays canonical and trios vendors it byte for byte under a sha gate, or the canonical copy moves to trios and t27 vendors it. Both repos must not edit it.
A generated service.t27 for one row, from the values topology.t27 holds:
// SPDX-License-Identifier: Apache-2.0
; deploy/services/999/gigaam/service.t27 -- generated from specs/hosting/topology.t27 row 999/gigaam; do not edit
; phi^2 + 1/phi^2 = 3 | TRINITY
module deploy_999_gigaam;
pub const KEY : str = "999/gigaam";
pub const SOURCE_REPO : str = "gHashTag/999-multibots-telegraf"; // private: the code stays there (option C)
pub const SOURCE_PATH : str = "deployment/gigaam";
pub const SOURCE_COMMIT : str = "cfa6deab446c";
pub const IMAGE_DIGEST : str = "sha256:9cf09c0a04bb4b82581114b1649ddd9cb1ff2d42124b106879dd42b42f373666";
pub const BUILD : str = "dockerfile";
pub const DOCKERFILE : str = "/Dockerfile";
pub const START : str = "";
pub const VOLUMES : [0]str = [];
pub const CUSTOM_DOMAINS : [0]str = [];
pub const HOLDS_SECRETS : bool = true; // values come from the owner's encrypted export, never from git
pub const TIER : str = "trusted"; // stateless; voice passes through; no path to data at rest
pub const RESTORE_PHASE : u32 = 1;
pub const DEPENDS_ON : [0]str = [];
test the_card_is_its_row {
assert SOURCE_COMMIT.len > 0 or IMAGE_DIGEST.len > 0;
assert RESTORE_PHASE == 1;
}
Gen gap. t27c has no backend that writes one file per table row, whether a service.t27 or a railway.json. Under the "only t27" rule that is a compiler gap, to be filed on gHashTag/t27#5980 with a repro, not filled with a hand script. Until it closes, the definitions are not generated, and step 1 below waits.
5. Order of moves
Each step is small. Each Railway change is one service at a time, with the owner's approval.
- Before anything moves:
- land topology.t27 (specs/hosting/topology.t27: the deployment in .t27, the source of truth for what runs where t27#8699);
- the owner runs
railway loginso skills-site, jobsearch-cron and project-brain can be copied out of their containers (t27#8675). The copies and the three function copies go to a private repo, after gitleaks; - the data backups of t27#8675 phase 1.
- Definitions, no Railway change. Generate
deploy/services/**for all 59 rows. A trios check holds them byte-identical to what topology.t27 generates. This waits on the gen gap above. - A read-only control plane.
plancompares each row with Railway's live config and prints the drift. It changes nothing. - Public code, smallest first, one PR and one service each. Move it with history (
git subtree), re-point that service's Railway source, watch one deploy and its health check, then leave a pointer in the old place:- trios-railway ($0.04);
- leela ($1.14);
- woody-weed-bot ($0.29);
- turbobaby-user-bot (crashed now);
- queen-proxy ($0.58).
Whether the t27 labs leave t27 is a separate question, because the lab health check compareslab.py's sha against t27 master.
- The Queen. Bring
queenandqueen-runnersunder triosmain; together they run at $462 per 30 days. Follow the drain rule: a Queen deploy must not stop the swarm. - Private code, by the option chosen in section 3.
- Images and templates get definitions only:
- mirror
ghcr.io/ghashtag/inngest:mcp-authto a registry outside the at-risk GitHub account; - pin the
:latestimages by digest (zep, zep-nlp, pgvector, llama.cpp, the neko base).
- mirror
6. What breaks, and how to keep it from breaking
CI
- Railway redeploys a repo service only when its watch patterns match, for example
apps/vibee-editor/render/**orsrc/**. Re-pointing a service resets them. - ci-bridge and check-runner run 999's PR checks. Moving them breaks those checks until they are wired again.
- Public trios CI never sees private code, and fork PRs never see secrets.
Railway source links
- Every re-point is a Railway change and triggers a deploy.
- The manifest shows supabase-gateway and queen-watch building from the repo root, while their code is in
apps/supabase-gatewayanddeployment/queen-watch. Both also have a deployment waiting for approval. Find out how they really build before touching them. - 20 services were deployed with
railway upand have no source link at all. Moving one means switching it to a git build, which changes behaviour. The digests in topology.t27 identify what runs now; a rebuild will not reproduce them byte for byte.
Secrets
- Values never travel with code. They stay in Railway and in the owner's encrypted export (t27#8675, item 6).
- Credentials bound to a repo do break when it moves:
- GitHub App installations and webhooks (the t27-bees app, ci-bridge's app);
- OAuth callbacks (t27-github-collab);
- deploy keys (project-brain);
- Railway's GitHub app access to the repo.
Hostnames
- Both recovered one-shot functions call vibee-render by its railway.app hostname.
- Railway's own
RAILWAY_SERVICE_*_URLreferences survive a repo move, but not a move to a new account.
History
- Run gitleaks on any subtree before it lands in public trios.
- Never merge private history into it.
This Mac
- trios is about 1.8 GB and 999-multibots-telegraf about 0.9 GB.
- Use
--filter=blob:noneand sparse checkouts; do not clone either repo fully.
7. What "one service managed through .t27" can sanely mean
It means one control plane: a Queen job card plus thin glue that reads topology.t27 and reconciles every provider to it.
- Plan: a diff against the provider's live config.
- Apply: one service at a time, in restore order, each judged by its health check.
- Restore: apply against an empty account, then restore the data volumes in the same order.
- Later: place trusted-tier and public-tier rows on Self-hosting MVP: services on users' computers, verified by agreement, credited in TRI (off-chain first), everything decided in .t27 #1756 hosts.
It does not mean one process or one container running Postgres, minio, Redis, Python STT and the Node bots together:
- Failure domains: one OOM would take the databases down with the speech models. vision alone holds about 15 GB of RAM.
- Deploys: every deploy would be a full outage.
- Tiers: owner-only data stores would be packed with the trusted-tier STT pods that Self-hosting MVP: services on users' computers, verified by agreement, credited in TRI (off-chain first), everything decided in .t27 #1756 wants to move off.
- Restore order: the order would be lost.
Several services may share one owner-tier machine, as separate processes that the plane starts.
The smallest useful first step: plan for project 999, read-only.
Decisions for the owner
- Choose an option from section 3. The recommendation is C with A.
- Choose where topology.t27 lives: t27 stays canonical, or trios becomes canonical.
- Approve each Railway re-point in step 3 one service at a time, starting with trios-railway.
Activity