Skip to content
377 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 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.131 // Docs mode's service, which also hosts artifacts (folios). Its
132 // Worker is g1t-docs-service: g1t-docs is the documentation site
133 // (apps/docs).
Docs: a workspace knowledge base people and agents write together134 "docs-service": {
135 "path": "services/docs",
136 "kind": "ts-worker",
137 "worker": "g1t-docs-service",
138 "d1": { "database": "g1t-docs", "migrations": "migrations" },
139 "stage": "core",
140 "secrets": [],
141 "setup": [
142 "The D1 database, before the first deploy: npx wrangler d1 create g1t-docs, then put its id in services/docs/wrangler.jsonc",
Docs know what code they describe; a project's docs folder in Docs; Docs events; files on any S3 store143 "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 people144 "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.145 "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)",
146 "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 together147 ],
148 "self_host": "run"
149 },
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)150 "notify": {
151 "path": "services/notify",
152 "kind": "ts-worker",
153 "worker": "g1t-notify",
154 // No D1: each person's feed keeps its own state in its Durable
155 // Object's SQLite storage.
156 "stage": "core",
157 // The private half of the VAPID key pair browser pushes are signed
158 // with; without it, notifications are live in open tabs only.
159 "secrets": ["VAPID_PRIVATE_KEY"],
160 "setup": [
161 "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"
162 ],
163 "self_host": "run"
164 },
Chat and workspace agents: channels, DMs and named agents you talk to165 "agents": {
166 "path": "services/agents",
167 "kind": "ts-worker",
168 "worker": "g1t-agents",
169 "d1": { "database": "g1t-agents", "migrations": "migrations" },
170 "stage": "core",
171 "secrets": [],
172 "setup": [
173 "The D1 database, before the first deploy: npx wrangler d1 create g1t-agents, then put its id in services/agents/wrangler.jsonc"
174 ],
175 // Replies route and gate model work exactly as runs do, with the
176 // runner's own modules: its routing policy and who may use hosted models.
177 "inputs": ["services/runner/src/model-env.ts", "services/runner/src/hosted.ts"],
178 "self_host": "run"
179 },
Deploys as code: a manifest of every Worker, a deploy tool that ships only what changed in parallel stages, and a g1t Actions workflow180 "billing": {
181 "path": "services/billing",
182 "kind": "rust-worker",
183 "worker": "g1t-billing",
184 "d1": { "database": "g1t-billing", "migrations": "migrations" },
185 "stage": "core",
Stripe's webhook secret is a Worker secret, STRIPE_WEBHOOK_SECRET, from a destination made in Stripe's dashboard186 "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 workflow187 "self_host": "run"
188 },
189 "integrations": {
190 "path": "services/integrations",
191 "kind": "rust-worker",
192 "worker": "g1t-integrations",
193 "d1": { "database": "g1t-integrations", "migrations": "migrations" },
194 "stage": "core",
195 "secrets": ["INTEGRATIONS_KEY", "GITHUB_APP_PRIVATE_KEY", "GITHUB_APP_WEBHOOK_SECRET"],
196 "self_host": "run"
197 },
198 "webhooks": {
199 "path": "services/webhooks",
200 "kind": "rust-worker",
201 "worker": "g1t-webhooks",
202 "d1": { "database": "g1t-webhooks", "migrations": "migrations" },
203 "stage": "core",
204 "secrets": ["WEBHOOKS_KEY"],
205 "self_host": "run"
206 },
207 "actions": {
208 "path": "services/actions",
209 "kind": "rust-worker",
210 "worker": "g1t-actions",
211 "d1": { "database": "g1t-actions", "migrations": "migrations" },
212 "stage": "core",
213 "secrets": ["ACTIONS_KEY"],
214 "self_host": "run"
215 },
Packages, with a container registry on g1t.sh; workspaces deleted whole and kept 30 days; Members for every member216 "packages": {
217 "path": "services/packages",
218 "kind": "rust-worker",
219 "worker": "g1t-packages",
220 "d1": { "database": "g1t-packages", "migrations": "migrations" },
221 "stage": "core",
222 "secrets": ["PACKAGES_TOKEN_SECRET", "R2_ACCESS_KEY_ID", "R2_SECRET_ACCESS_KEY"],
223 "setup": [
224 "The D1 database: npx wrangler d1 create g1t-packages, its id in services/packages/wrangler.jsonc",
225 "The R2 bucket for packages' files: npx wrangler r2 bucket create g1t-packages",
226 "The events queue: npx wrangler queues create g1t-events-packages",
227 "For signed downloads: an R2 API token with read access to g1t-packages, as R2_ACCESS_KEY_ID and R2_SECRET_ACCESS_KEY"
228 ],
229 "self_host": "run"
230 },
Deploys as code: a manifest of every Worker, a deploy tool that ships only what changed in parallel stages, and a g1t Actions workflow231 "security": {
232 "path": "services/security",
233 "kind": "rust-worker",
234 "worker": "g1t-security",
235 "d1": { "database": "g1t-security", "migrations": "migrations" },
236 "stage": "core",
237 "secrets": [],
238 "self_host": "run"
239 },
240 "deployments": {
241 "path": "services/deployments",
242 "kind": "ts-worker",
243 "worker": "g1t-deployments",
244 "d1": { "database": "g1t-deployments", "migrations": "migrations" },
245 "stage": "core",
246 "secrets": ["CLOUDFLARE_API_TOKEN"],
247 "setup": [
248 "Workers for Platforms, and the dispatch namespace: scripts/setup-deployments.sh",
249 "Custom domains (Cloudflare for SaaS on g1t.page): scripts/setup-custom-domains.sh"
250 ],
251 "self_host": "run"
252 },
253 "runner": {
254 "path": "services/runner",
255 "kind": "ts-worker",
256 "worker": "g1t-runner",
257 "stage": "core",
258 "secrets": ["AI_GATEWAY_TOKEN"],
Fast pages, required checks on the branch, self-hosted runners, honest incidents259 "setup": [
260 "Containers on the account; Docker on the machine that builds a new image",
261 "The base image, once: node scripts/deploy.mjs build-base"
262 ],
Deploys as code: a manifest of every Worker, a deploy tool that ships only what changed in parallel stages, and a g1t Actions workflow263 "image": {
264 "dockerfile": "services/runner/Dockerfile",
Fast pages, required checks on the branch, self-hosted runners, honest incidents265 // The binary the image adds to its base (scripts/build-runner.mjs).
266 "crate": "g1t-runner",
267 "base": { "context": "services/runner/base", "lock": "services/runner/base.json" },
268 "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 workflow269 },
270 "self_host": "off"
271 },
272 "context": {
273 "path": "services/context",
274 "kind": "ts-worker",
275 "worker": "g1t-context",
276 "d1": { "database": "g1t-context", "migrations": "migrations" },
277 "stage": "core",
278 "secrets": [],
279 "setup": [
280 "The Vectorize index: npx wrangler vectorize create g1t-context --dimensions=768 --metric=cosine, with metadata indexes on workspace, kind, project and private"
281 ],
282 "self_host": "off"
283 },
284 "og": {
285 "path": "services/og",
286 "kind": "ts-worker",
287 "worker": "g1t-og",
288 "stage": "core",
289 "secrets": [],
290 "setup": ["Browser Rendering on the account (the BROWSER binding)"],
291 // The roadmap cards read the site's roadmap.
292 "inputs": ["apps/web/app/lib/roadmap.ts"],
293 "self_host": "none"
294 },
295 "api": {
296 "path": "apps/api",
297 "kind": "rust-worker",
298 "worker": "g1t-api",
299 "stage": "edge",
Actions: OIDC tokens, the toolkit's cache and artifact services, and artifacts in R2300 // ACTIONS_OIDC_KEY signs workflow jobs' OIDC tokens; without it the
301 // 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.302 // ACTIONS_OIDC_KEY_PREVIOUS only while rotating (the guide's "OIDC
303 // tokens for workflow jobs").
Actions: OIDC tokens, the toolkit's cache and artifact services, and artifacts in R2304 "secrets": ["ACTIONS_OIDC_KEY"],
305 "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.306 "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)",
307 "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 R2308 ],
Merge branch 'worktree-agent-aaf03bdceac799c89'309 "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 workflow310 },
311 "models": {
312 "path": "services/models",
313 "kind": "ts-worker",
314 "worker": "g1t-models",
Chat and workspace agents: channels, DMs and named agents you talk to315 // Core, though it is public at models.g1t.sh: the agents service
316 // reaches it by service binding for chat replies. It binds only to
317 // core services itself.
318 "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 workflow319 "secrets": ["AI_GATEWAY_TOKEN"],
320 "setup": ["The AI Gateway `g1t`"],
Chat and workspace agents: channels, DMs and named agents you talk to321 // Not run self-hosted, but bound to the off Worker: agents binds to it.
322 "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 workflow323 },
324 "pages": {
325 "path": "services/pages",
326 "kind": "ts-worker",
327 "worker": "g1t-pages",
328 "stage": "edge",
329 "secrets": [],
330 "setup": ["A proxied wildcard DNS record on g1t.page (`*`, AAAA 100::): scripts/setup-deployments.sh"],
331 "self_host": "none"
332 },
333 "status": {
334 "path": "apps/status",
335 "kind": "ts-worker",
336 "worker": "g1t-status",
337 "d1": { "database": "g1t-status", "migrations": "migrations" },
338 "stage": "edge",
339 "secrets": ["STATUS_SECRET"],
340 "setup": ["Email Sending on g1t.sh (the EMAIL binding)"],
341 "self_host": "separate"
342 },
343 "web": {
344 "path": "apps/web",
345 "kind": "react-router",
346 "worker": "g1t",
347 "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 address348 // USERCONTENT_KEY signs the short-lived addresses of private
349 // repositories' files on g1tusercontent.com; without it they are
350 // served from g1t.sh instead.
351 "secrets": ["USERCONTENT_KEY"],
352 "setup": [
353 "The R2 bucket g1t-downloads, for the self-hosted runner's releases: npx wrangler r2 bucket create g1t-downloads",
354 "The zone g1tusercontent.com on the account; the Worker's custom domain on it is made by the deploy",
355 "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"
356 ],
Deploys as code: a manifest of every Worker, a deploy tool that ships only what changed in parallel stages, and a g1t Actions workflow357 "self_host": "run"
358 },
359 "sudo": {
360 "path": "apps/sudo",
361 "kind": "react-router",
362 "worker": "g1t-sudo",
363 "stage": "front",
364 "secrets": [],
365 "setup": ["A Cloudflare Access application on sudo.g1t.sh; its AUD tag is ACCESS_AUD"],
366 "self_host": "none"
367 },
368 "docs": {
369 "path": "apps/docs",
370 "kind": "astro",
371 "worker": "g1t-docs",
372 "stage": "front",
373 "secrets": [],
374 "self_host": "none"
375 }
376 }
377}

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