Skip to content
379 linesCodeBlameRaw

Pick any line to see why it is the way it is: the commit, the pull request and issue it came from, and what the agent was thinking.

Deploys as code: a manifest of every Worker, a deploy tool that ships only what changed in parallel stages, and a g1t Actions workflow1// Everything g1t deploys to Cloudflare, in one place. Read by
2// scripts/deploy.mjs (plan, deploy), deploy/self-host/configs.mjs (what a
3// self-hosted installation runs) and the tests in scripts/deploy/.
The docs folder is gone, and what it held lives where people read it: how a self-hosted g1t runs and how to deploy g1t to Cloudflare are pages on docs.g1t.sh under Run g1t yourself, and speed, rate limits and operating g1t.sh are sections of CONTRIBUTING.md; code that cited a file in docs/ now points to the page or section that covers it, or says what it means itself, and applied migrations and the runner images are left as they were.4// docs.g1t.sh/guides/deploy-to-cloudflare/ explains each field and how to
5// add a unit.
Deploys as code: a manifest of every Worker, a deploy tool that ships only what changed in parallel stages, and a g1t Actions workflow6//
7// What is written here is what the Wrangler configs cannot say. The rest is
8// read from each unit's wrangler.jsonc, never copied: its D1 databases and
9// migrations, the services it binds to, its KV, R2, queues and routes. The
10// shared crates and packages a unit is built from are read from Cargo's and
11// npm's workspace metadata. `worker` and `d1` are written here too, so the
12// file reads as an inventory, and a test checks they match the configs.
13{
14 // Deployed in this order. A stage starts only when the one before it
15 // succeeded. A unit binds only to units in its own stage or an earlier
16 // one (a test checks it), so new code never calls a service that has
17 // not shipped yet. Within a stage, units go out in parallel.
18 //
19 // migrations: every pending D1 migration, before any code.
20 // core: the services, reached through service bindings.
Chat and workspace agents: channels, DMs and named agents you talk to21 // edge: public endpoints other than the site: API, MCP, g1t.page, status
22 // (models is public too, but in core: agents binds to it).
Deploys as code: a manifest of every Worker, a deploy tool that ships only what changed in parallel stages, and a g1t Actions workflow23 // front: the site, sudo and the docs.
24 "stages": ["migrations", "core", "edge", "front"],
25
26 // Names for the resources the configs refer to by id, for setup
27 // commands and the docs. A test checks every KV id in a config is here.
28 "resources": {
29 "kv": {
30 "16a4232cb746418db53782aa068be693": "g1t-actions-blobs",
31 "e627b571f07047e187c03e1fc2b3bbdd": "g1t-avatars",
32 "14bc5c233d4c46a5bbf23b5367cce5fd": "g1t-domains",
33 "be765052d0124c2a935b3db4dff99f1f": "g1t-repos-git-cache"
34 }
35 },
36
37 // Each deployable unit, by short name (`--only events,web`).
38 //
39 // kind: rust-worker (worker-build), ts-worker (Wrangler bundles it),
40 // react-router (vite build first), astro (astro build first).
41 // secrets: names only; set with `npx wrangler secret put NAME` in its folder.
42 // setup: one-time steps no config can say, for a first deploy.
43 // self_host: what deploy/self-host does with it: "run" (in the one
44 // workerd), "off" (bound to the off Worker), "separate" (a
45 // process of its own), or "none".
46 // inputs: files outside its folder it is built from that no workspace
47 // metadata names (a test finds such imports).
The docs folder is gone, and what it held lives where people read it: how a self-hosted g1t runs and how to deploy g1t to Cloudflare are pages on docs.g1t.sh under Run g1t yourself, and speed, rate limits and operating g1t.sh are sections of CONTRIBUTING.md; code that cited a file in docs/ now points to the page or section that covers it, or says what it means itself, and applied migrations and the runner images are left as they were.48 // image: a Containers image (the guide's "The runner's images"):
Fast pages, required checks on the branch, self-hosted runners, honest incidents49 // dockerfile the image a deploy ships: the base plus the binary
50 // crate the crate that binary is built from (and what it uses)
51 // base { context: the base's folder, lock: the file that
52 // records the base that was pushed }; the base is
53 // rebuilt only when its folder changes
54 // repository where both are pushed in Cloudflare's registry
Deploys as code: a manifest of every Worker, a deploy tool that ships only what changed in parallel stages, and a g1t Actions workflow55 "units": {
56 "events": {
57 "path": "services/events",
58 "kind": "rust-worker",
59 "worker": "g1t-events",
60 "d1": { "database": "g1t-events", "migrations": "migrations" },
61 "stage": "core",
62 "secrets": [],
Merge branch 'worktree-agent-ad8a36dfcd4176015' into spend-guardrails63 "setup": [
64 "The dead-letter queue every queue consumer sends what it gave up on to, before any unit that names it deploys: npx wrangler queues create g1t-events-dlq"
65 ],
Deploys as code: a manifest of every Worker, a deploy tool that ships only what changed in parallel stages, and a g1t Actions workflow66 "self_host": "run"
67 },
68 "identity": {
69 "path": "services/identity",
70 "kind": "rust-worker",
71 "worker": "g1t-identity",
72 "d1": { "database": "g1t", "migrations": "migrations" },
73 "stage": "core",
74 "secrets": ["GITHUB_APP_CLIENT_SECRET", "IDENTITY_KEY"],
75 "setup": ["Email Sending on g1t.sh (the EMAIL binding)"],
76 "self_host": "run"
77 },
78 "repos": {
79 "path": "services/repos",
80 "kind": "rust-worker",
81 "worker": "g1t-repos",
82 "d1": { "database": "g1t-repos", "migrations": "migrations" },
83 "stage": "core",
84 "secrets": ["REPOS_KEY"],
Merge branch 'worktree-agent-a1b995daa94e4e1b7'85 "setup": [
86 "The Artifacts namespace `g1t` (the ARTIFACTS binding)",
Merge branch 'worktree-agent-ac5b181a013e54348'87 "The R2 bucket `g1t-git-packs` (GIT_PACKS) with its lifecycle rule: `npx wrangler r2 bucket create g1t-git-packs`, then `npx wrangler r2 bucket lifecycle add g1t-git-packs expire-packs packs/ --expire-days 7 --abort-multipart-days 1`",
88 "The R2 bucket for nightly backups: npx wrangler r2 bucket create g1t-backups"
Merge branch 'worktree-agent-a1b995daa94e4e1b7'89 ],
Deploys as code: a manifest of every Worker, a deploy tool that ships only what changed in parallel stages, and a g1t Actions workflow90 "self_host": "run"
91 },
92 "work": {
93 "path": "services/work",
94 "kind": "rust-worker",
95 "worker": "g1t-work",
96 "d1": { "database": "g1t-work", "migrations": "migrations" },
97 "stage": "core",
98 "secrets": [],
99 "self_host": "run"
100 },
101 "search": {
102 "path": "services/search",
103 "kind": "rust-worker",
104 "worker": "g1t-search",
105 "d1": { "database": "g1t-search", "migrations": "migrations" },
106 "stage": "core",
107 "secrets": [],
108 "self_host": "run"
109 },
110 "projects": {
111 "path": "services/projects",
112 "kind": "ts-worker",
113 "worker": "g1t-projects",
114 "d1": { "database": "g1t-projects", "migrations": "migrations" },
115 "stage": "core",
116 "secrets": [],
117 "self_host": "run"
118 },
Chat and workspace agents: channels, DMs and named agents you talk to119 "chat": {
120 "path": "services/chat",
121 "kind": "ts-worker",
122 "worker": "g1t-chat",
123 "d1": { "database": "g1t-chat", "migrations": "migrations" },
124 "stage": "core",
125 "secrets": [],
126 "setup": [
127 "The D1 database, before the first deploy: npx wrangler d1 create g1t-chat, then put its id in services/chat/wrangler.jsonc"
128 ],
129 "self_host": "run"
130 },
The artifacts service is services/artifacts, the Worker g1t-artifacts, bound as ARTIFACTS by the API, the site and the agents; its live rooms move to it with a Durable Object transfer from g1t-docs-service, and its database, bucket, indexes and queue keep their names. The git store's binding and settings are GITSTORE, its ops scripts gitstore-*, and workflow run artifacts keep their compatible API under run_artifacts modules. The deploy tool puts a Worker that has never deployed before the Workers in its stage that bind to it, and the deploy guide gives the cutover runbook.131 // Artifacts: docs (a doc is one kind of artifact), their spaces,
132 // sharing and live rooms. It was g1t-docs-service (services/docs)
133 // until 2026-10; its resources kept their g1t-docs names. g1t-docs
134 // is the documentation site (apps/docs).
135 "artifacts": {
136 "path": "services/artifacts",
Docs: a workspace knowledge base people and agents write together137 "kind": "ts-worker",
The artifacts service is services/artifacts, the Worker g1t-artifacts, bound as ARTIFACTS by the API, the site and the agents; its live rooms move to it with a Durable Object transfer from g1t-docs-service, and its database, bucket, indexes and queue keep their names. The git store's binding and settings are GITSTORE, its ops scripts gitstore-*, and workflow run artifacts keep their compatible API under run_artifacts modules. The deploy tool puts a Worker that has never deployed before the Workers in its stage that bind to it, and the deploy guide gives the cutover runbook.138 "worker": "g1t-artifacts",
Docs: a workspace knowledge base people and agents write together139 "d1": { "database": "g1t-docs", "migrations": "migrations" },
140 "stage": "core",
141 "secrets": [],
142 "setup": [
The artifacts service is services/artifacts, the Worker g1t-artifacts, bound as ARTIFACTS by the API, the site and the agents; its live rooms move to it with a Durable Object transfer from g1t-docs-service, and its database, bucket, indexes and queue keep their names. The git store's binding and settings are GITSTORE, its ops scripts gitstore-*, and workflow run artifacts keep their compatible API under run_artifacts modules. The deploy tool puts a Worker that has never deployed before the Workers in its stage that bind to it, and the deploy guide gives the cutover runbook.143 "An installation that ran g1t-docs-service: move to g1t-artifacts as \"Renaming a Worker\" in docs.g1t.sh/guides/deploy-to-cloudflare/ says (its queue consumer first, then this Worker, which takes the old Worker's live rooms)",
144 "The D1 database, before the first deploy: npx wrangler d1 create g1t-docs, then put its id in services/artifacts/wrangler.jsonc",
Docs know what code they describe; a project's docs folder in Docs; Docs events; files on any S3 store145 "The R2 bucket for files in pages: npx wrangler r2 bucket create g1t-docs-files",
Docs index by meaning: passages of every page and project doc, embedded on save and recalled for agents; hybrid search for people146 "The queue the events service sends it merges and pushes on (pages whose cited code changed, projects' docs): npx wrangler queues create g1t-events-docs. The service also sends its own backfill jobs to it (JOBS)",
The artifacts plan records what Phase 1 decided, self-hosting and the deploy list name the g1t-folios index and the trash cron, and folio events are listed as published but never offered to webhooks.147 "The Vectorize index agents recall Docs from: npx wrangler vectorize create g1t-docs --dimensions=768 --metric=cosine, with string metadata indexes on workspace_id and space_id (npx wrangler vectorize create-metadata-index g1t-docs --property-name=<name> --type=string)",
148 "The Vectorize index for artifacts (folios), before the first deploy with FOLIO_VECTORS: npx wrangler vectorize create g1t-folios --dimensions=768 --metric=cosine, with string metadata indexes on workspace_id, scope and kind (npx wrangler vectorize create-metadata-index g1t-folios --property-name=<name> --type=string). Without it, artifacts are searched and recalled by words"
Docs: a workspace knowledge base people and agents write together149 ],
150 "self_host": "run"
151 },
Merge the workspace shell: navigation and phone shell, g1t as orchestrator, agents in roles with audience-checked reads, reactions and custom emoji, live notifications and browser push, the homepage tour (agents 0002, chat 0002)152 "notify": {
153 "path": "services/notify",
154 "kind": "ts-worker",
155 "worker": "g1t-notify",
156 // No D1: each person's feed keeps its own state in its Durable
157 // Object's SQLite storage.
158 "stage": "core",
159 // The private half of the VAPID key pair browser pushes are signed
160 // with; without it, notifications are live in open tabs only.
161 "secrets": ["VAPID_PRIVATE_KEY"],
162 "setup": [
163 "The VAPID key pair for browser push: `node scripts/ops/vapid-keys.mjs` prints both halves and stores nothing. Put the public half in VAPID_PUBLIC_KEY in services/notify/wrangler.jsonc, and the private half with `npx wrangler secret put VAPID_PRIVATE_KEY` in services/notify"
164 ],
165 "self_host": "run"
166 },
Chat and workspace agents: channels, DMs and named agents you talk to167 "agents": {
168 "path": "services/agents",
169 "kind": "ts-worker",
170 "worker": "g1t-agents",
171 "d1": { "database": "g1t-agents", "migrations": "migrations" },
172 "stage": "core",
173 "secrets": [],
174 "setup": [
175 "The D1 database, before the first deploy: npx wrangler d1 create g1t-agents, then put its id in services/agents/wrangler.jsonc"
176 ],
177 // Replies route and gate model work exactly as runs do, with the
178 // runner's own modules: its routing policy and who may use hosted models.
179 "inputs": ["services/runner/src/model-env.ts", "services/runner/src/hosted.ts"],
180 "self_host": "run"
181 },
Deploys as code: a manifest of every Worker, a deploy tool that ships only what changed in parallel stages, and a g1t Actions workflow182 "billing": {
183 "path": "services/billing",
184 "kind": "rust-worker",
185 "worker": "g1t-billing",
186 "d1": { "database": "g1t-billing", "migrations": "migrations" },
187 "stage": "core",
Stripe's webhook secret is a Worker secret, STRIPE_WEBHOOK_SECRET, from a destination made in Stripe's dashboard188 "secrets": ["STRIPE_SECRET_KEY", "STRIPE_WEBHOOK_SECRET", "CLOUDFLARE_USAGE_TOKEN"],
Deploys as code: a manifest of every Worker, a deploy tool that ships only what changed in parallel stages, and a g1t Actions workflow189 "self_host": "run"
190 },
191 "integrations": {
192 "path": "services/integrations",
193 "kind": "rust-worker",
194 "worker": "g1t-integrations",
195 "d1": { "database": "g1t-integrations", "migrations": "migrations" },
196 "stage": "core",
197 "secrets": ["INTEGRATIONS_KEY", "GITHUB_APP_PRIVATE_KEY", "GITHUB_APP_WEBHOOK_SECRET"],
198 "self_host": "run"
199 },
200 "webhooks": {
201 "path": "services/webhooks",
202 "kind": "rust-worker",
203 "worker": "g1t-webhooks",
204 "d1": { "database": "g1t-webhooks", "migrations": "migrations" },
205 "stage": "core",
206 "secrets": ["WEBHOOKS_KEY"],
207 "self_host": "run"
208 },
209 "actions": {
210 "path": "services/actions",
211 "kind": "rust-worker",
212 "worker": "g1t-actions",
213 "d1": { "database": "g1t-actions", "migrations": "migrations" },
214 "stage": "core",
215 "secrets": ["ACTIONS_KEY"],
216 "self_host": "run"
217 },
Packages, with a container registry on g1t.sh; workspaces deleted whole and kept 30 days; Members for every member218 "packages": {
219 "path": "services/packages",
220 "kind": "rust-worker",
221 "worker": "g1t-packages",
222 "d1": { "database": "g1t-packages", "migrations": "migrations" },
223 "stage": "core",
224 "secrets": ["PACKAGES_TOKEN_SECRET", "R2_ACCESS_KEY_ID", "R2_SECRET_ACCESS_KEY"],
225 "setup": [
226 "The D1 database: npx wrangler d1 create g1t-packages, its id in services/packages/wrangler.jsonc",
227 "The R2 bucket for packages' files: npx wrangler r2 bucket create g1t-packages",
228 "The events queue: npx wrangler queues create g1t-events-packages",
229 "For signed downloads: an R2 API token with read access to g1t-packages, as R2_ACCESS_KEY_ID and R2_SECRET_ACCESS_KEY"
230 ],
231 "self_host": "run"
232 },
Deploys as code: a manifest of every Worker, a deploy tool that ships only what changed in parallel stages, and a g1t Actions workflow233 "security": {
234 "path": "services/security",
235 "kind": "rust-worker",
236 "worker": "g1t-security",
237 "d1": { "database": "g1t-security", "migrations": "migrations" },
238 "stage": "core",
239 "secrets": [],
240 "self_host": "run"
241 },
242 "deployments": {
243 "path": "services/deployments",
244 "kind": "ts-worker",
245 "worker": "g1t-deployments",
246 "d1": { "database": "g1t-deployments", "migrations": "migrations" },
247 "stage": "core",
248 "secrets": ["CLOUDFLARE_API_TOKEN"],
249 "setup": [
250 "Workers for Platforms, and the dispatch namespace: scripts/setup-deployments.sh",
251 "Custom domains (Cloudflare for SaaS on g1t.page): scripts/setup-custom-domains.sh"
252 ],
253 "self_host": "run"
254 },
255 "runner": {
256 "path": "services/runner",
257 "kind": "ts-worker",
258 "worker": "g1t-runner",
259 "stage": "core",
260 "secrets": ["AI_GATEWAY_TOKEN"],
Fast pages, required checks on the branch, self-hosted runners, honest incidents261 "setup": [
262 "Containers on the account; Docker on the machine that builds a new image",
263 "The base image, once: node scripts/deploy.mjs build-base"
264 ],
Deploys as code: a manifest of every Worker, a deploy tool that ships only what changed in parallel stages, and a g1t Actions workflow265 "image": {
266 "dockerfile": "services/runner/Dockerfile",
Fast pages, required checks on the branch, self-hosted runners, honest incidents267 // The binary the image adds to its base (scripts/build-runner.mjs).
268 "crate": "g1t-runner",
269 "base": { "context": "services/runner/base", "lock": "services/runner/base.json" },
270 "repository": "g1t-runner"
Deploys as code: a manifest of every Worker, a deploy tool that ships only what changed in parallel stages, and a g1t Actions workflow271 },
272 "self_host": "off"
273 },
274 "context": {
275 "path": "services/context",
276 "kind": "ts-worker",
277 "worker": "g1t-context",
278 "d1": { "database": "g1t-context", "migrations": "migrations" },
279 "stage": "core",
280 "secrets": [],
281 "setup": [
282 "The Vectorize index: npx wrangler vectorize create g1t-context --dimensions=768 --metric=cosine, with metadata indexes on workspace, kind, project and private"
283 ],
284 "self_host": "off"
285 },
286 "og": {
287 "path": "services/og",
288 "kind": "ts-worker",
289 "worker": "g1t-og",
290 "stage": "core",
291 "secrets": [],
292 "setup": ["Browser Rendering on the account (the BROWSER binding)"],
293 // The roadmap cards read the site's roadmap.
294 "inputs": ["apps/web/app/lib/roadmap.ts"],
295 "self_host": "none"
296 },
297 "api": {
298 "path": "apps/api",
299 "kind": "rust-worker",
300 "worker": "g1t-api",
301 "stage": "edge",
Actions: OIDC tokens, the toolkit's cache and artifact services, and artifacts in R2302 // ACTIONS_OIDC_KEY signs workflow jobs' OIDC tokens; without it the
303 // issuer answers 404 and jobs are not offered tokens.
The docs folder is gone, and what it held lives where people read it: how a self-hosted g1t runs and how to deploy g1t to Cloudflare are pages on docs.g1t.sh under Run g1t yourself, and speed, rate limits and operating g1t.sh are sections of CONTRIBUTING.md; code that cited a file in docs/ now points to the page or section that covers it, or says what it means itself, and applied migrations and the runner images are left as they were.304 // ACTIONS_OIDC_KEY_PREVIOUS only while rotating (the guide's "OIDC
305 // tokens for workflow jobs").
Actions: OIDC tokens, the toolkit's cache and artifact services, and artifacts in R2306 "secrets": ["ACTIONS_OIDC_KEY"],
307 "setup": [
The docs folder is gone, and what it held lives where people read it: how a self-hosted g1t runs and how to deploy g1t to Cloudflare are pages on docs.g1t.sh under Run g1t yourself, and speed, rate limits and operating g1t.sh are sections of CONTRIBUTING.md; code that cited a file in docs/ now points to the page or section that covers it, or says what it means itself, and applied migrations and the runner images are left as they were.308 "The OIDC signing key for workflow jobs: an RSA key made with `openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:2048`, stored with `npx wrangler secret put ACTIONS_OIDC_KEY` (docs.g1t.sh/guides/deploy-to-cloudflare/#oidc-tokens-for-workflow-jobs)",
309 "The actions cache bucket's lifecycle rule limited to `c/`, so artifacts under `a/` are kept their retention-days (docs.g1t.sh/guides/deploy-to-cloudflare/#a-first-deploy-to-a-new-account)"
Actions: OIDC tokens, the toolkit's cache and artifact services, and artifacts in R2310 ],
Merge branch 'worktree-agent-aaf03bdceac799c89'311 "self_host": "separate"
Deploys as code: a manifest of every Worker, a deploy tool that ships only what changed in parallel stages, and a g1t Actions workflow312 },
313 "models": {
314 "path": "services/models",
315 "kind": "ts-worker",
316 "worker": "g1t-models",
Chat and workspace agents: channels, DMs and named agents you talk to317 // Core, though it is public at models.g1t.sh: the agents service
318 // reaches it by service binding for chat replies. It binds only to
319 // core services itself.
320 "stage": "core",
Deploys as code: a manifest of every Worker, a deploy tool that ships only what changed in parallel stages, and a g1t Actions workflow321 "secrets": ["AI_GATEWAY_TOKEN"],
322 "setup": ["The AI Gateway `g1t`"],
Chat and workspace agents: channels, DMs and named agents you talk to323 // Not run self-hosted, but bound to the off Worker: agents binds to it.
324 "self_host": "off"
Deploys as code: a manifest of every Worker, a deploy tool that ships only what changed in parallel stages, and a g1t Actions workflow325 },
326 "pages": {
327 "path": "services/pages",
328 "kind": "ts-worker",
329 "worker": "g1t-pages",
330 "stage": "edge",
331 "secrets": [],
332 "setup": ["A proxied wildcard DNS record on g1t.page (`*`, AAAA 100::): scripts/setup-deployments.sh"],
333 "self_host": "none"
334 },
335 "status": {
336 "path": "apps/status",
337 "kind": "ts-worker",
338 "worker": "g1t-status",
339 "d1": { "database": "g1t-status", "migrations": "migrations" },
340 "stage": "edge",
341 "secrets": ["STATUS_SECRET"],
342 "setup": ["Email Sending on g1t.sh (the EMAIL binding)"],
343 "self_host": "separate"
344 },
345 "web": {
346 "path": "apps/web",
347 "kind": "react-router",
348 "worker": "g1t",
349 "stage": "front",
Merge g1tusercontent.com: registry answers run nothing in a browser, the site's pages run only their own scripts, repository files and avatars on their own origin, raw files rate limited per address350 // USERCONTENT_KEY signs the short-lived addresses of private
351 // repositories' files on g1tusercontent.com; without it they are
352 // served from g1t.sh instead.
353 "secrets": ["USERCONTENT_KEY"],
354 "setup": [
355 "The R2 bucket g1t-downloads, for the self-hosted runner's releases: npx wrangler r2 bucket create g1t-downloads",
356 "The zone g1tusercontent.com on the account; the Worker's custom domain on it is made by the deploy",
357 "The key for private files' addresses: `node -e \"console.log(require('crypto').randomBytes(32).toString('hex'))\" | npx wrangler secret put USERCONTENT_KEY` in apps/web"
358 ],
Deploys as code: a manifest of every Worker, a deploy tool that ships only what changed in parallel stages, and a g1t Actions workflow359 "self_host": "run"
360 },
361 "sudo": {
362 "path": "apps/sudo",
363 "kind": "react-router",
364 "worker": "g1t-sudo",
365 "stage": "front",
366 "secrets": [],
367 "setup": ["A Cloudflare Access application on sudo.g1t.sh; its AUD tag is ACCESS_AUD"],
368 "self_host": "none"
369 },
370 "docs": {
371 "path": "apps/docs",
372 "kind": "astro",
373 "worker": "g1t-docs",
374 "stage": "front",
375 "secrets": [],
376 "self_host": "none"
377 }
378 }
379}

This file's history is long; its oldest lines are credited to the oldest commit read.