lmjtfy.git / apps / lmjtfy / wrangler.toml
1name = "lmjtfy"
2main = "build/index.js"
3compatibility_date = "2026-09-01"

The site is https://lmjtfy.fun, bare (the owner's domain, on Cloudflare, 2026-10-03). It began at https://lmjtfy.deizel.workers.dev, which stays on, and www.lmjtfy.fun is attached, only so the Worker can send their visitors, link previews and clones on with a permanent redirect (gate in src/host.rs). No per-version preview addresses beside them.

code.lmjtfy.fun is where the code is cloned from and read (https://code.lmjtfy.fun/<repo>.git, the owner, 2026-10-05): the same Worker, which gives that host the repositories and a front page listing them and nothing else (src/host.rs), and sends every repository's path on lmjtfy.fun, www and workers.dev there with a 308.

15workers_dev = true
16preview_urls = false
17routes = [
18  { pattern = "lmjtfy.fun", custom_domain = true },
19  { pattern = "www.lmjtfy.fun", custom_domain = true },
20  { pattern = "code.lmjtfy.fun", custom_domain = true },
21]
23[build]
24command = "worker-build --release"
25
26[vars]

Whether lmjtfy.fun, www and workers.dev send a repository's path to code.lmjtfy.fun with a 308 ("on"), or serve the clone themselves as before the code host ("off"). Exactly "on" or "off" (src/host.rs GitRedirect): anything else is logged as an error and runs as "off". It is "on" since the code host was checked (2026-10-05). To roll back, deploy once with --var GIT_REDIRECT:off: the 308s are cached for a day (max-age=86400), so a client that already followed one may keep going to the code host.

34GIT_REDIRECT = "on"

A pinned model: jev-protocol refuses aliases, because the answers behind an alias change without a change here.

37JEV_MODEL = "jev-1.13.0"

The LLM that writes Jev's questions: the cheapest candidate that passed every case of tools/eval (2026-10-02: 14/14, about 16 neurons a call; the one cheaper model, granite-4.0-h-micro, passed 11). Rerun the eval before changing it.

42LLM_MODEL = "@cf/qwen/qwen3-30b-a3b-fp8"

The most all visitors together may spend on Jev in a UTC day, in dollars. The LLM's own budget is not set here: it is Workers AI's free allocation (llm::FREE_NEURONS_PER_DAY). A dollar is about 25,000 requests at $0.00004 each (the owner, 2026-10-02: "they will never hit it anyway").

47JEV_DOLLARS_PER_DAY = "1"

Workers AI. There is no local emulation: wrangler dev calls the real models on the real account, so it needs the account's token (lmjtfy-wrangler, from the devshell).

52[ai]
53binding = "AI"

The day's budgets, shared by every visitor (src/meter.rs).

56[[durable_objects.bindings]]
57name = "BUDGET"
58class_name = "Budget"

Every request that was answered, and what people asked (src/archive.rs). It also makes the calls, so the same request is never sent twice.

62[[durable_objects.bindings]]
63name = "ARCHIVE"
64class_name = "Archive"
66[[migrations]]
67tag = "v1"
68new_sqlite_classes = ["Budget"]
69
70[[migrations]]
71tag = "v2"
72new_sqlite_classes = ["Archive"]

The key is a secret, not a var. Declaring it makes wrangler dev read it from the process environment (op-env-run puts it there) and makes wrangler deploy refuse if the deployed Worker lacks it.

77[secrets]
78required = [
79  "LMJTFY_TYPESAFE_API_KEY",
80  # For the account's real Workers AI usage (src/meter.rs): a token that can
81  # read analytics and nothing else, and the account it reads. A dev server
82  # without them counts only itself, and says so on the page.
83  "CLOUDFLARE_ANALYTICS_TOKEN",
84  "CLOUDFLARE_ACCOUNT_ID",
85  # For `git clone <site>/lmjtfy.git` (src/clone.rs): a GitHub fine-grained
86  # token with Contents: read on deizel/lmjtfy and deizel/jevcrates and no
87  # other permission. A dev server without it answers clones with 503.
88  "LMJTFY_GITHUB_TOKEN",
89]

Cloudflare's own record of what the Worker did (the owner, 2026-10-02): every invocation logged, with what it logged, and every request traced (fetches, Durable Object calls, the handler). Kept in the account's dashboard: logs 3 days (Workers Free: 200,000 events a day), traces 7 days. Traces count towards Cloudflare Observability billing from 2026-12-01; lower head_sampling_rate before then if they would.

97[observability]
98enabled = true
100[observability.logs]
101enabled = true
102invocation_logs = true
103head_sampling_rate = 1
104
105[observability.traces]
106enabled = true
107head_sampling_rate = 1

Staging: the same code as its own Worker, lmjtfy-staging, with its own archive and budgets, where a change is tried before it reaches visitors (the owner, 2026-10-04: "a preview environment so we aren't pushing straight to prod"). lmjtfy-wrangler apps/lmjtfy deploy --env staging.

Only at staging.lmjtfy.fun, where Cloudflare Access admits the owner and the agents' service token (nixos-config, access.nix). No workers.dev address and no preview addresses: either would be a way round Access, and every ask here spends real money. For the same reason there is no code host here: a second address is a second way round Access, and nothing in nixos-config's access.nix covers one. Staging serves the repositories itself, where it is (src/host.rs, Host::Other), so the clone proxy and the code pages are tried there; the code host's own routes are tried under wrangler dev with a Host: code.lmjtfy.fun header (README, "The code pages"). An environment inherits no bindings or variables, so each is said again.

127[env.staging]
128name = "lmjtfy-staging"
129workers_dev = false
130preview_urls = false
131routes = [{ pattern = "staging.lmjtfy.fun", custom_domain = true }]
133[env.staging.vars]
134JEV_MODEL = "jev-1.13.0"
135LLM_MODEL = "@cf/qwen/qwen3-30b-a3b-fp8"

A tenth of production's: enough to try a change, not enough to matter.

137JEV_DOLLARS_PER_DAY = "0.10"
139[env.staging.ai]
140binding = "AI"
141
142[[env.staging.durable_objects.bindings]]
143name = "BUDGET"
144class_name = "Budget"
145
146[[env.staging.durable_objects.bindings]]
147name = "ARCHIVE"
148class_name = "Archive"
149
150[[env.staging.migrations]]
151tag = "v1"
152new_sqlite_classes = ["Budget", "Archive"]
153
154[env.staging.secrets]
155required = ["LMJTFY_TYPESAFE_API_KEY", "CLOUDFLARE_ANALYTICS_TOKEN", "CLOUDFLARE_ACCOUNT_ID", "LMJTFY_GITHUB_TOKEN"]
156
157[env.staging.observability]
158enabled = true
159
160[env.staging.observability.logs]
161enabled = true
162invocation_logs = true
163head_sampling_rate = 1