| 1 | { |
| 2 | "$schema": "../../node_modules/wrangler/config-schema.json", |
| 3 | "name": "g1t-billing", |
| 4 | "account_id": "1e6f2cffa3f445920836e8ebe446bb58", |
| 5 | "compatibility_date": "2026-09-26", |
| 6 | // Runs next to its database: a request makes several queries in turn, |
| 7 | // and each would otherwise cross the distance to it. |
| 8 | "placement": { "mode": "off" }, |
| 9 | "main": "build/index.js", |
| 10 | "build": { "command": "node ../../scripts/build-rust-worker.mjs" }, |
| 11 | // Reached only through service bindings. |
| 12 | "workers_dev": false, |
| 13 | "d1_databases": [ |
| 14 | { |
| 15 | "binding": "DB", |
| 16 | "database_name": "g1t-billing", |
| 17 | "database_id": "695a6979-fd07-4850-bc97-904a6b4b7a04", |
| 18 | "migrations_dir": "migrations" |
| 19 | } |
| 20 | ], |
| 21 | // Identity emails owners as their workspace nears its usage limit. |
| 22 | // Repos says which repositories are public (the open-source pool pays |
| 23 | // for work on those) and what private ones hold (the storage meter). |
| 24 | "services": [ |
| 25 | { "binding": "IDENTITY", "service": "g1t-identity" }, |
| 26 | { "binding": "REPOS", "service": "g1t-repos" } |
| 27 | ], |
| 28 | // Margin alerts to staff (src/margin.rs), through Cloudflare Email |
| 29 | // Sending like identity's and the status page's mail. |
| 30 | "send_email": [{ "name": "EMAIL", "remote": true }], |
| 31 | // Events from the bus: a workspace renamed moves its billing to the |
| 32 | // new slug (src/rename.rs). |
| 33 | "queues": { |
| 34 | "consumers": [{ "queue": "g1t-events-billing", "max_batch_size": 20, "max_batch_timeout": 1 }] |
| 35 | }, |
| 36 | "vars": { |
| 37 | // What is added to a model run's cost, in percent: g1t's overhead for |
| 38 | // running and building it. The price book's markups are the same. |
| 39 | "MARGIN_PERCENT": "20", |
| 40 | // While g1t is being built out, workspaces pay nothing: runs are |
| 41 | // recorded with what they cost, and nothing is charged. Set to |
| 42 | // "false" when pricing starts. |
| 43 | // Off: workspaces are charged as their account's terms say. g1t's own |
| 44 | // (flagon-io, Flagon, Inc.'s) is comped in sudo.g1t.sh, not by this switch. |
| 45 | "FREE_WHILE_BUILDING": "false", |
| 46 | // The g1t plan (src/features.rs): $20 a month per workspace, never |
| 47 | // per person. It includes $10 of usage a month at cost plus 20%, used |
| 48 | // first and not rolled over; the other $10 pays for running g1t, the |
| 49 | // free forge for everyone, and the people building it. No quotas: |
| 50 | // builds, requests, CPU, custom domains, storage and git operations |
| 51 | // are all metered at cost plus 20% and drawn from the $10 first; only |
| 52 | // the workspace's spend limit stops it. Projects are not metered. |
| 53 | "PLAN_MONTHLY_CENTS": "2000", |
| 54 | "PLAN_INCLUDED_MICROS": "10000000", |
| 55 | // 1 GB of private storage free for every workspace: past it, the plan |
| 56 | // pays at cost plus the margin, and a free workspace's pushes to |
| 57 | // private repositories stop. The audit log is kept 90 days on every plan. |
| 58 | "FREE_PRIVATE_STORAGE_BYTES": "1000000000", |
| 59 | "AUDIT_RETENTION_DAYS": "90", |
| 60 | // The trial (src/credits.rs, src/cards.rs): $5 of usage once per new |
| 61 | // workspace, granted after a card check (one per card), out of a pool |
| 62 | // for everyone ($100) that resets each calendar month (UTC). Either at |
| 63 | // 0 turns new trials off. Never for deployments. |
| 64 | "TRIAL_WORKSPACE_MICROS": "5000000", |
| 65 | "TRIAL_MONTHLY_POOL_MICROS": "100000000", |
| 66 | // g1t's open-source pool: checks, workflows and the merge queue on |
| 67 | // public repositories, for any workspace with a card check, up to $25 |
| 68 | // a month in all and $2 a month for any one repository. |
| 69 | "OSS_POOL_MICROS": "25000000", |
| 70 | "OSS_REPO_MICROS": "2000000", |
| 71 | // Ceilings on usage not yet paid for (src/limits.rs): $3 for a free |
| 72 | // workspace (it has no on-demand compute), $100 for a paid one's first |
| 73 | // month, then twice what it has paid as payments clear, between the |
| 74 | // start and $1,000 (Established: its monthly spend, up to $10,000). |
| 75 | "LIMIT_NEW_MICROS": "3000000", |
| 76 | "LIMIT_PAID_START_MICROS": "100000000", |
| 77 | "LIMIT_PAID_MIN_MICROS": "25000000", |
| 78 | "LIMIT_PAID_MAX_MICROS": "1000000000", |
| 79 | // Caps on agents (src/compute.rs): what the agents on one issue may |
| 80 | // spend in all. One run's spend cap is DEFAULT_RUN_CAP_MICROS in |
| 81 | // crates/contracts (guardrails.rs), shared with the guardrails' cost |
| 82 | // per run; RUN_CAP_MICROS here would override it. Owners and staff |
| 83 | // can change both. |
| 84 | "ISSUE_CAP_MICROS": "10000000", |
| 85 | // A spike: an hour's spend above 5 times the usual hour over the last |
| 86 | // week, and at least $5, pauses new compute until an owner confirms. |
| 87 | "SPIKE_FACTOR": "5", |
| 88 | "SPIKE_FLOOR_MICROS": "5000000", |
| 89 | // The most of an overage's real cost a one-click goodwill credit |
| 90 | // covers (src/overages.rs); it always gives back the margin too. |
| 91 | "OVERAGE_FORGIVE_COST_MICROS": "50000000", |
| 92 | // Git operations through g1t (src/storage.rs): 50,000 a month free for |
| 93 | // every workspace; past it the plan pays at cost plus 20% and is never |
| 94 | // slowed, and a free workspace is slowed down by the repos service |
| 95 | // (its GIT_OPERATIONS_FREE_CAP, the same number), never charged. |
| 96 | "GIT_OPERATIONS_INCLUDED": "50000", |
| 97 | // A month's close charges no less than $5, so a payment's fee is never |
| 98 | // most of it: smaller amounts carry over. Charges at a limit always go |
| 99 | // through. |
| 100 | "MIN_CHARGE_MICROS": "5000000", |
| 101 | // Where the keeper reads what g1t pays (src/keeper.rs). Its token, |
| 102 | // CLOUDFLARE_USAGE_TOKEN, is a secret: Billing, Account Analytics |
| 103 | // and AI Gateway, read only. The daily cost reconciliation |
| 104 | // (src/costs.rs, src/margin.rs) reads the bill with |
| 105 | // CLOUDFLARE_BILLING_TOKEN (Account: Billing Read, Account Analytics |
| 106 | // Read) when it is set, else with the usage token. With neither it |
| 107 | // reconciles only what g1t counted itself. See |
| 108 | // docs/BILLING_OPERATIONS.md. |
| 109 | "CLOUDFLARE_ACCOUNT_ID": "1e6f2cffa3f445920836e8ebe446bb58", |
| 110 | "AI_GATEWAY_ID": "g1t", |
| 111 | // Where margin alerts go: a product or all of g1t under the margin |
| 112 | // floor, leaks, drift. Empty sends none (sudo still shows them). |
| 113 | "COSTS_ALERT_EMAIL": "hey@flagon.io", |
| 114 | // What g1t pays for itself, capped (src/budget.rs), at cost: |
| 115 | // a comped account's (flagon-io's) work, $150 a month, unless its |
| 116 | // terms in sudo set its own limit; alerts at 50, 75, 90 and 100% to |
| 117 | // COSTS_ALERT_EMAIL, and at 100% new work on it is refused. |
| 118 | "COMPED_MONTHLY_CEILING_MICROS": "150000000", |
| 119 | // All of g1t's own spend in a day (comped, the trial and open-source |
| 120 | // pools, free overruns, anything charged without real money): at |
| 121 | // $75, new agent runs on hosted models that g1t pays for pause until |
| 122 | // 00:00 UTC; staff are emailed and can lift it in sudo. Workspaces |
| 123 | // paying with real money are never paused. 0 turns either cap off. |
| 124 | "PLATFORM_DAILY_SPEND_CAP_MICROS": "75000000", |
| 125 | // Cloudflare's fixed subscriptions a month, for sudo's figures only: |
| 126 | // Workers Paid ($5) and Workers for Platforms ($25). |
| 127 | "CLOUDFLARE_FIXED_MONTHLY_MICROS": "30000000" |
| 128 | }, |
| 129 | // Settling runs every 15 minutes; checking costs daily (keeper::DAILY). |
| 130 | "triggers": { "crons": ["*/15 * * * *", "17 4 * * *"] }, |
| 131 | // Secrets: STRIPE_SECRET_KEY. Without it nothing is charged and the |
| 132 | // runner decides who may start agents some other way. |
| 133 | // STRIPE_WEBHOOK_SECRET: the signing secret (whsec_…) of the destination |
| 134 | // made in Stripe's dashboard for https://api.g1t.sh/stripe/webhook. |
| 135 | // Without it every event is refused (the replay still reads them). |
| 136 | "observability": { "enabled": true } |
| 137 | } |