# Pathrule Pattern: Cloudflare Workers (1.0.0)
# ::pathrule:package:cloudflare-workers

### [RULE] Reach every service through a binding, with generated types  (path: /src)
<!-- scope: folder | priority: high | strict -->

A binding is an in-process reference to another resource: no network hop, no credential to manage, no signing. Calling the same resource over its public API is slower, costs more, and adds a secret you did not need.

- Access resources as `env.MY_KV`, `env.MY_BUCKET`, `env.DB`, `env.MY_QUEUE`, and other Workers through service bindings. Use the REST API only for control-plane work that has no binding.
- Never hand-write the `Env` interface. Generate it (`wrangler types`) from the configuration so a renamed or missing binding is a compile error rather than a runtime `undefined`.
- Pass `env` explicitly through your code instead of reading a module-level copy. It is per-request state, and capturing it in module scope is how a preview binding ends up serving production traffic.
- Keep secrets as secrets (`wrangler secret put`), read them from `env`, and never inline them in source or in the config file.
- Test against real bindings with the Workers test pool, which runs tests inside the runtime rather than in Node, so KV, D1, and Durable Object behaviour is the actual behaviour.

---

### [RULE] Write for the isolate: no shared request state, stream, and stay inside CPU time  (path: /src)
<!-- scope: folder | priority: high | strict -->

Many requests share one isolate, and the runtime bills CPU time, not the time you spend waiting on I/O. Both facts change how code should be written.

- Keep no mutable request state at module scope. Caching an immutable, non-user-specific value (a parsed config, a compiled regex) is fine; storing anything about the current user is a cross-request leak.
- Waiting on `fetch`, KV, or D1 does not consume CPU budget, so parallel I/O is cheap: fire independent requests together with `Promise.all` rather than sequentially. What does consume the budget is computation, so avoid parsing or transforming large payloads in the Worker.
- Stream bodies through rather than buffering: pass the response body along, or use `TransformStream` and `pipeTo`. Reading a large response into a string is how a Worker hits its memory ceiling.
- Return the response first and do follow-up work in `ctx.waitUntil(...)` (analytics, cache writes, logging). Work started without `waitUntil` after the response may be cancelled.
- Handle failure explicitly at the edge: a subrequest limit, a timeout, or a downstream error should produce a deliberate response, not an unhandled rejection.

---

### [MEMORY] Wrangler configuration keeps the runtime current  (path: /)

The Worker's behaviour is pinned by its configuration, and stale settings are the most common cause of "it works locally but not on deploy".

- Use `wrangler.jsonc` for new projects (some newer features are JSON-config only) and keep it in the repo as the source of truth for bindings, routes, and limits.
- Set `compatibility_date` explicitly and move it forward deliberately when you have tested the change. It is the runtime's version pin, not a timestamp to ignore.
- Enable `nodejs_compat` when your code or a dependency imports Node built-ins, and prefer web-standard APIs where you have the choice. A missing flag shows up as a module resolution failure at deploy.
- Define environments for staging and production with their own bindings and routes, so a promotion is a deploy of the same code with different resources rather than an edited config.
- Turn on observability and use `wrangler tail` while debugging. Structured logging plus a request id is what makes an edge deployment debuggable at all.

See /src for the binding and isolate rules this configuration exposes.

---

### [MEMORY] Choosing storage: KV, D1, Durable Objects, R2, Queues  (path: /src)

Each store has one job, and picking the wrong one is the most expensive mistake in a Workers architecture because it shapes the data model.

- KV: read constantly, write rarely, and tolerate eventual consistency. Feature flags, configuration, session lookups. Do not use it as a counter or a write-heavy store; writes propagate globally and reads can be briefly stale.
- D1: relational application data with SQL. Great for the long tail of app queries; treat it like a small database (index what you filter, keep queries narrow) and remember reads have regional characteristics.
- Durable Objects: a single addressable instance that serialises access to its own state. This is the only way to get strong consistency and coordination (rate limiters, real-time rooms, per-entity locks, WebSocket hibernation).
- R2: object storage for blobs, with no egress fee to Workers. Stream to and from it rather than loading objects into memory.
- Queues for asynchronous work and buffering, and the Cache API (or cache headers) in front of expensive computed responses. If a value is expensive to compute and identical for many requests, cache it before reaching for a store.

See /src for the isolate rules and the redis-caching pattern for cache invalidation strategy.

---

### [SKILL] workers-deploy-review  (path: /)

---
name: workers-deploy-review
description: Review checklist for Cloudflare Workers changes covering bindings and generated types, isolate safety, CPU and memory limits, storage selection, and wrangler configuration. Run before deploying.
---

# Workers deploy review

## Bindings
- [ ] Every Cloudflare resource is reached through a binding, not its REST API.
- [ ] `Env` types are generated, not hand-written, and the build fails on a missing binding.
- [ ] Secrets come from `env`; nothing sensitive is in source or config.
- [ ] `env` is passed explicitly, never captured at module scope.

## Isolate safety
- [ ] No mutable module-scope state carries request or user data.
- [ ] Independent I/O runs in parallel; nothing sequential without a reason.
- [ ] Bodies are streamed, not buffered, for anything large.
- [ ] Post-response work runs inside `ctx.waitUntil`.

## Limits
- [ ] Computation in the request path is bounded and cheap.
- [ ] Script size is within limits after bundling; no accidental large dependency.
- [ ] Subrequest and downstream failures produce a deliberate response.

## Storage
- [ ] The store matches the access pattern (KV read-heavy, D1 relational, Durable Object for consistency, R2 for blobs).
- [ ] Nothing write-heavy or counter-like is in KV.
- [ ] Expensive identical responses are cached.

## Configuration
- [ ] `wrangler.jsonc` in the repo, `compatibility_date` explicit and current.
- [ ] `nodejs_compat` set if Node built-ins are used.
- [ ] Staging and production environments have their own bindings and routes.
- [ ] Observability enabled; logs carry a request id.
