# URLCode > A portable runtime for programmable URL behavior, and the framework that grows > from it: routes in YAML, functions and middleware, then accounts, data, MCP tools and > stored links as operator-installed extensions. Stable project format > `version: "1"`. Core is Apache-2.0; this revision is `0.6.6`. `function`/`middleware` > routes are trusted by default with `sandbox: true` as the per-route opt-in. The > auth, store and mcp extensions are add-ons released with core and pinned by > it; a site adds them with `urlcode extensions add `. Only core is published to npm. Use the schema and docs from the runtime revision you run. Do not assume Node, fetch or database access inside a `sandbox: true` function, regex routes, global middleware, YAML interpolation, or packages named in YAML. Secrets need external revision-pinned grants. Unsupported features fail with the route named; nothing degrades silently. ## Start here (read only this section for a first attempt) 1. Before writing anything, run `npx --no --package @jimhoyd/urlcode urlcode bootstrap DIR --capabilities NAME,... --json` (MCP `get_context` with `bootstrap: true`): site and route-project roots, entry and host file, pinned/installed runtime against this one, exact commands to run from the site root, the site/project path mapping and this runtime's schema fragments for the capabilities you name. It creates nothing unless you add `--create` with an explicit DIR ([local agent bootstrap][docs/TOOLING.md#local-agent-bootstrap]). If DIR already holds your files (a built `frontend/`, say), add `--adopt` too: the site is written around them, nothing is moved or overwritten, and any collision is refused with the paths listed. Then copy or build the frontend into `app/`. Then run `npx --no --package @jimhoyd/urlcode urlcode context --project DIR` (MCP `get_context`). For redirect-only work run `npx --no --package @jimhoyd/urlcode urlcode context --project DIR --task redirects`: supported shapes with exact YAML, gaps with their exact validation error, a paste-ready `starter`, and this project's own redirects. For a goal that spans routes, persistence or extensions, `urlcode plan-feature "goal" --project DIR --json` (MCP `plan_feature`) names the matching recipes and the extension authoring surfaces the goal asks for (store ownership, transitions, membership and readers; auth route protection), from installed or catalog descriptors; its `commands` end with `urlcode recipes add NAME --project app`, which merges a recipe into the site's `app/` (routes, includes, extension config, fixtures, seed and the audit count; any clash refuses it all, named) instead of copying its files (MCP `merge_recipe` with `--allow-authoring`, for the served project only). With `--host-file`, `explain`, `plan-feature`, `context` and `review` read the registrations without a revision pin; anything that activates (`validate`, `test`, `dev`, `serve`) still needs the reviewed pin, which `urlcode permissions --project app` prints. The site's check scripts and the authoring MCP runners review each edit without a new pin; serving still needs one ([the local review loop][docs/EXTENSIONS.md#the-local-review-loop]). The audit's expected route count is committed once in `app/tests/audit.json`. Such a hermetic run refuses an extension built for extension contract 1 and any registration `composeHost` did not compose on the run's own data directory (`hermetic-host-unconfirmed`), and removes its `urlcode-hermetic--*` directory even when interrupted ([hermetic runs][docs/EXTENSIONS.md#hermetic-runs-and-test-seeds]). 2. After installing `@jimhoyd/urlcode`, run `npx --no --package @jimhoyd/urlcode urlcode init .` (it works in a directory holding only `package.json`, `package-lock.json`, `node_modules`, `.git`, a pre-registered `.mcp.json` (see next paragraph) or a coding-agent client's own `.claude/` or `.codex/` state, which init never writes into or changes, and preserves existing package metadata). It writes a bare agent-ready site: the route project `app/` (`urlcode.yaml` with no routes), `host.mjs` (the operator host), `package.json` with an exact runtime pin and npm scripts, `AGENTS.md`, local `.mcp.json` (kept as-is if one is already there), and project CI. Then run `npx --no --package @jimhoyd/urlcode urlcode validate --local` and `npx --no --package @jimhoyd/urlcode urlcode test` from the site; `--project` defaults to `app` there. `--no` refuses a registry fetch, so it always uses the installed scoped runtime. `.mcp.json` only exists once `init` writes it, so Claude Code, which loads a project's `.mcp.json` at session start, sees no `urlcode` tools on the very first turn that creates a project. To have MCP `get_context` and friends available from that first turn, register `.mcp.json` *before* starting the agent session: `npx --no --package @jimhoyd/urlcode urlcode mcp print-config > .mcp.json` in the target directory, then start the session there. The server answers normally against the still-empty directory (a project-reading tool such as `get_context` returns the same `run urlcode init there to create a project` guidance the CLI prints); once `init` runs, the same session's next MCP call succeeds — no restart needed. Codex does not read `.mcp.json`: register the same pinned command under `[mcp_servers.urlcode]` in `~/.codex/config.toml` or a trusted project `.codex/config.toml`, with the site root as `cwd`, or with `codex mcp add` ([registering the server][docs/TOOLING.md#registering-the-server]). If a client cannot be bootstrapped that way, run `init` as a plain CLI call for the first turn instead, then continue with MCP registered. Where a sandbox forbids writing client configuration (`init-write-denied` naming `.mcp.json`), use `init . --no-mcp`: the same site without `.mcp.json`, reported as `mcpRegistration: skipped`; do not work around the policy. 3. Do not read or grep [llms-full.txt](llms-full.txt) (about 60k tokens) for a routine task; `get_context`, `capabilities`/`get_capability`, `search_docs` and `search_recipes` answer it. It is the deliberate fallback when those do not: only then, locate the one matching heading (never the whole file) — a source checkout also has the matching page directly under `docs/`. 4. Hosted reference and skills are optional: connect a compatible HTTP MCP client to `https://urlcode.ai/mcp`, which needs no key and runs no model of its own. Keep `urlcode mcp` registered for project-aware inspection and validation. Start with the hosted [agent guide](https://urlcode.ai/llms.txt), then see [hosted AI MCP setup][docs/TOOLING.md#optional-hosted-ai-mcp]. Only when the user asks for it, the authoring skill's [hosted-assisted mode][docs/AI-AUTHORING.md#hosted-assisted-authoring-opt-in] calls `urlcode_task_plan` before writing YAML, then verifies locally. | Shape | Supported? | Use | |---|---|---| | Fixed redirect, 301/302/303/307/308 (302 default) | Yes | `redirect: {url, status}` | | Parameterized path (`/users/{id}` to `/profiles/{id}`) | Yes | `{name}` in `redirect.url`, naming a declared path parameter | | Root-relative destination (`/users/{id}` to `/profiles/{id}`) | Yes | `redirect.url: /profiles/{id}`: one leading slash, path only | | Wildcard suffix (`/legacy/**` to `/modern/{**}`, any depth) | Yes | terminal `/**` key with a literal prefix; `{**}` is the remaining segments (redirect only; not static or Cloudflare) | | Query-string preservation | Yes, opt-in | `redirect.query.pass` / `query.map` | | Method-preserving redirect | Yes | `methods` plus `status: 307` or `308` | | 404 for unmatched paths | Yes | `site.notFound` (project-relative `.html`) | | SPA fallback (client routes answer `index.html`) | Recipe, not native | [recipe `spa-shell`][recipes/spa-shell/README.md]: root `/*` static mount plus an operator plugin in `--host-file`; self-hosted only | | Host or scheme chosen from the request | No | destination is a literal absolute `https://` URL or a root-relative path; report the gap | ## Declarative-first Use the highest-level declarative feature before writing a function or middleware. Custom code only when the framework cannot express the requirement; then report the gap. Never invent fields or bypass target limits or operator grants ([design principle][docs/PROJECT-DIRECTION.md#design-principle-declarative-first]). | I need | Use | |---|---| | Security headers | `policies.security` ([security][docs/policies/security.md]) | | Cache headers / cache strategy | `cacheControl` / `policies.cache` ([assets][docs/yaml/assets.md], [cache][docs/policies/cache.md]) | | Body size, content type, JSON check, per method | `request.body.` ([HTTP][docs/HTTP.md]) | | One JSON Schema for a route body, an MCP tool and a store collection, or a standalone schema file with local `$ref`s | top-level `schemas:` (inline, or `{file: schemas/x.json}` read offline, remote refs refused), named as `request.body.POST.schema: x`, mcp `inputSchema: x` and a store collection's `schema: x` (a flat record; its `defaults` and `readOnlyProperties` stay on the collection); the OpenAPI export emits it once as a component ([named schemas][docs/HTTP.md#named-schemas]) | | Restrict HTTP methods | `methods` (default GET/HEAD; 405 with `Allow`, before any extension `authorize()`, so an undeclared method on an `auth: true` route is 405, not 401/403) | | Rate limiting, bot/AI-crawler blocking, compression | `policies.throttle`, `policies.agents`, `policies.compression` ([policies][docs/POLICIES.md]) | | Fixed JSON/text/headers | `respond` and `response.headers` | | robots.txt, sitemap, favicon, security.txt | top-level `site` ([site][docs/SITE.md]) | | Sign-in, sign-out, protected routes | `extensions.auth: {version: "1", config: {}}` (a thin Better Auth adapter; `urlcode extensions add auth`, then `npx urlcode-auth migrate` for the bundled SQLite file, or the owner's own Better Auth database as `auth({database, testDatabase})` in host.mjs), an `/api/auth/*` mount with `extension: auth` and `methods: [GET, POST]`, then `auth: true` on each protected route (its function reads `context.capabilities.auth.identity.userId`; there is no role, permission or CSRF key); browsers sign in with `createAuthClient({basePath: '/api/auth'})` from `better-auth/client`; roles and permissions are application data ([auth][packages/auth/README.md], [the `auth` short form][docs/EXTENSIONS.md#protecting-a-route-the-auth-short-form]) | | Application rules needing the signed-in caller | with the bundled store installed, first its declarations: owned collections, declared transitions and membership gates (end-to-end example with no application code: [proofs/private-requests][proofs/private-requests/README.md]); otherwise ordinary YAML function routes with `auth: true`, explicit methods and bounded request bodies, where the trusted function reads the verified user id from `context.capabilities.auth.identity.userId` (not available to `sandbox: true` routes) ([request-bound capabilities][docs/EXTENSIONS.md#request-bound-capabilities], recipe `authenticated-json-api`) | | Audit log | `audit: true` on a store collection: its writes are recorded in the store's own database, in the same transaction, kept to `auditRetention`, read with `urlcode-store audit`, and forwarded to any sink through the tap `StoreExports.audit` (core's `AuditTap`: `peek`, then `ack`; `status()` counts events pruned before any sink peeked them) ([audited writes][docs/STORE.md#audited-writes]) | | Persistence | the owner's choice: the bundled store is a default, and a trusted function may call any database library directly instead (end-to-end with `node:sqlite`, `auth: true` and no store extension: [proofs/native-storage][proofs/native-storage/README.md]; store declarations without the store extension are refused, not emulated). The operator-installed store extension: recipes `store-crud`, `store-booking`, `store-credits` and `store-approval`, each collection's record `schema` a JSON Schema 2020-12 object schema in the request body profile, inline or a named project schema, with store behavior (`defaults`, `readOnlyProperties`) beside it on the collection (422 with the body-schema issues; [record schema][docs/STORE.md#record-schema]), described by `urlcode openapi --host-file`, per-record ownership (`ownership: owner` on a collection behind `auth: true`, [store ownership][docs/STORE.md#per-record-ownership]), declared single-record `transitions` and `Idempotency-Key` replay ([transitions][docs/STORE.md#conditional-transitions-and-result-aware-retries]), permissions as data: a `membership: true` collection of principal ids gating a transition or a create (`members`, `create.members`) and named read-only cross-owner `readers` mounts, each with its own gate and optionally a projection of listed properties (`readers..properties`, a directory that hides balances beside a members-only full view) ([membership gates][docs/STORE.md#membership-gates-and-cross-owner-reads]), a declared non-overlap `intervals` constraint for scheduling, with fixed-length aligned slots (`length`, `step`, and `origin` for a fixed-offset local grid) (`409 interval_conflict`, [intervals][docs/STORE.md#non-overlapping-intervals]), declared `transfers` moving a whole amount between two records' balances with the sum conserved (`409 insufficient_balance`, [transfers][docs/STORE.md#declared-transfers]), `editable`/`deletable` states outside which `PUT`/`PATCH`/increments/`DELETE` answer `409 record_locked` ([edit and delete states][docs/STORE.md#edit-and-delete-states]), `unique` string properties across owners (`409 value_taken`, [unique handle][docs/STORE.md#a-directory-by-a-unique-handle]) and retry-safe host transactions (`StoreExports.transaction(work, {idempotencyKey})`); one serving process per database on local disk, a second one refused by an OS lock ([one serving process][docs/STORE.md#one-serving-process-per-database]); holds and filtering beyond equality are gaps | | A form: validate a submission, email it, rate-limit it | a frontend posting JSON to a route whose `request.body.POST.schema` validates it before code runs (`format: email` and the other standard formats); `respond` answers and `signals` notifies a hook with no project code (recipe `contact-form`); to email it, a trusted `function` calls the provider's SDK, HTTP API or nodemailer with its credentials in granted `secrets`; `policies.throttle` limits the route | | A frontend over store collections | the application's own code: `fetch` to the JSON mounts, reading a list's `etags` (send `If-Match`) and `may` (offer only allowed transitions); URLCode ships no component kit or screens. Reference: [proofs/private-requests/client][proofs/private-requests/client/main.js]; for shadcn/ui use the official tooling and `urlcode artifacts stage` | | Frontend at the site root beside `/api/...` extension mounts | a root `/*` `static` mount (`index: index.html`) plus the extension mounts: the longest mount prefix wins, so each extension keeps its whole mount; a route inside an extension's mount, or an extension mount enclosing another, fails `urlcode validate` naming both routes ([site-root frontend][docs/ROUTING.md#a-site-root-frontend-beside-api-extension-mounts]) | | Stored short links (create, redirect, click count) | operator-installed store extension's `shortLinks` capability: a collection `key`, a `format: uri` `destination` property (HTTP(S) only), one `increments` counter, and a public `/go`-style redirect mount; no function needed (`urlcode docs search "shortLinks"`, MCP `search_docs`) | When only code can do it, one function serves one or more routes: ```yaml /hello/{name}: function: functions/hello.mjs # binds args.name; context.route.pattern is "/hello/{name}" ``` ```js export default (request, { args, route }) => Response.json({ hello: args.name }); ``` Function handler shape: a module whose `export default` is `(request, { args, env, route, requestId })` and returns a `Response` (or a promise of one). `args` holds the route's declared path inputs; the string form `function: functions/hello.mjs` and the long form `function: {source: ...}` both bind every declared path input (write `args: {}` to bind none). `sandbox: true` is a separate route option. `route.pattern` is the matched pattern; `env` holds route-scoped values only; `requestId` is the response's `X-Request-Id`. Search the docs with bounded output using `npx --no --package @jimhoyd/urlcode urlcode docs search "TEXT" --project app` (MCP `search_docs`) rather than grepping llms-full.txt. It covers the core agent docs plus the guides and `urlcode.json` schemas of add-ons installed and verified in the site (core-pinned, or independent with lock integrity and recorded files), reports which sources it did and did not search, and names one section or config path to read next; no match means no match in those sources, not an unsupported feature. Draft `tests/requests.json` from `urlcode fixtures suggest --json` (MCP `suggest_fixtures`): it reads urlcode.yaml and its includes, covers only routes the YAML alone determines and lists function, middleware, proxy, extension, pattern and binding routes as `gaps` to test by hand. For write-capable or streaming function/middleware routes it adds `verificationGaps`: the stateful handler verification matrix (`urlcode docs search "stateful handler verification"`) as untested application-supplied expectations, never coverage; rows a fixture cannot express need an ordinary test. An `auth: true` route is covered by a `steps` fixture that signs in through the provider's own endpoint, with `"origin": "{{origin}}"` on unsafe requests, and its accounts and memberships are declared in `tests/seed.json` (each test and audit run starts from a fresh database holding exactly that seed); the auth mount is a route too, covered by an `expectJson` on each sign-in (`/user/id`) and a `GET /api/auth/get-session` case, as the `auth: true` recipes' fixtures do, which run unchanged in a site with `urlcode extensions add auth`; `expectJson` asserts chosen values of a JSON body by JSON Pointer; a passing case counts only with `expectBody`, `expectJson` or `expectHeaders`, a covered GET implies HEAD, `expectSignals` asserts the signals a request emits (`urlcode test` and `audit` record them and deliver none; `urlcode dev --signal-sink stdout` prints them), and `audit`'s `coverageNotes` names what is missing ([authenticated routes][docs/READINESS.md#authenticated-routes-auth-true]). `urlcode diff BEFORE --json` (a YAML file, or a directory to compare includes too; MCP `summarize_yaml_change`) names the routes, code seams and operator grants a change adds; `urlcode report BEFORE > report.html` renders it, the review findings and each route's request path as a read-only page for a person; `urlcode studio BEFORE` serves that page on localhost and rebuilds it on every reload. The default `urlcode mcp` tools never execute project code: run fixtures with `urlcode test`. MCP `run_tests` executes the project's trusted functions, middleware and extensions, so it exists only when the operator adds `--allow-authoring`. Handler for the response: fixed text or JSON is `respond`; one HTML file is `page`; a directory is `static`; an attachment is `download`; a short HTML snippet is `respond` `text` with a `Content-Type: text/html; charset=utf-8` header. Functions are trusted by default; add `sandbox: true` to opt a route in ([function security][docs/FUNCTION-SECURITY.md]). After a real attempt, draft feedback only for a capability gap, repeated workaround, documentation gap or suspected defect, with sanitized YAML and validation evidence. Search existing issues first; never publish or comment without the user's approval. ## Reference (load one only when needed) - Authoring: [AI authoring contract][docs/AI-AUTHORING.md], [YAML guide][docs/YAML-GUIDE.md], [field reference][docs/YAML-REFERENCE.md], [JSON Schema](schemas/urlcode.schema.json), [semantics][docs/SPECIFICATION.md], [cookbook](examples/cookbook/README.md), [recipes][docs/RECIPES.md]. - Skills (MCP `list_skills` returns all three with their own descriptions): [authoring loop](skills/urlcode/SKILL.md), [authoring](.claude/skills/urlcode-authoring/SKILL.md), [operations](.claude/skills/urlcode-operations/SKILL.md). - Routes and handlers: [routing][docs/ROUTING.md], [HTTP][docs/HTTP.md], [middleware][docs/MIDDLEWARE.md], [assets][docs/ASSETS.md], [conditions][docs/CONDITIONS.md], [egress][docs/EGRESS.md], [prerender][docs/PRERENDER.md], [site][docs/SITE.md], [organization][docs/ORGANIZATION.md]. - Extension keys: core's field reference stops at `extensions..config`; every first-party extension's configuration, route-policy and hook fields are in its package README's generated field reference, indexed with a capability-to-keys map in [extension field references][docs/EXTENSION-REFERENCE.md]. For an installed add-on, `urlcode docs search "" --project app` (MCP `search_docs`) reaches the same section. - Extensions: [extensions][docs/EXTENSIONS.md] (including [add-ons: extensions and artifacts][docs/EXTENSIONS.md#add-ons-extensions-and-artifacts]; MCP `get_extension_artifacts` and `inspect_extension_artifact`, CLI `urlcode artifacts inspect`, installed files checked offline against `addon-files.lock.json` by `list --strict` and `urlcode extensions|artifacts verify` ([the installed file record][docs/EXTENSIONS.md#the-installed-file-record]), re-running `add ` upgrades an independent package and `outdated` reports newer registry versions ([upgrading an independent package][docs/EXTENSIONS.md#upgrading-an-independent-package]), [independent artifact packages][docs/EXTENSIONS.md#independent-artifact-packages]; every released add-on's agent references: MCP `get_release_addon_catalog`, [release-wide discovery][docs/EXTENSIONS.md#the-release-wide-agent-catalog], not evidence of installation; writing one: [generic add-on authoring rules][docs/EXTENSIONS.md#generic-add-on-authoring-rules]), [the composition contract][docs/FRAMEWORK.md#the-composition-contract], [package and channel alignment][docs/VERSION-ALIGNMENT.md]. Add an extension with `urlcode extensions add ` (it installs the tarball core pins, writes its YAML and routes, and wires `host.mjs`); it writes the capability only, and `--example` also writes that extension's demo (store's `/api/todos`); use that managed installer for first-party add-ons. Inspect the installed stack first; first-party extensions are defaults, not requirements, and a trusted function may use any npm library directly ([owner choice][docs/EXTENSIONS.md#native-independent-integration-or-bundled-default]); external/private extensions are allowed and installed separately, then explicitly wired into the operator host. Follow the [external-extension workflow][docs/EXTENSIONS.md#external-extensions-and-ai-tooling], including host-aware discovery and validation. [urlcode-auth][packages/auth/], [urlcode-store][packages/store/], and [urlcode-mcp][packages/mcp/] are the extension sources; an independent package may take one of their names (the name is the role) while the first-party one is not installed. An `extension:` mount may declare route `env` under the same operator grant as a function route; it reaches the extension as `ExtensionRequest.env`, and hooks/handlers are called as `(input, {requestId, env, ...})` ([request context][docs/EXTENSIONS.md#request-context-route-env-and-request-id]). A site served on several origins keeps one canonical `--origin` and lists the others with the operator's repeatable `--alias-origin` (never YAML); every extension's same-origin check admits them through core's one rule, `isSameOriginRequest` ([site origins][docs/EXTENSIONS.md#site-origins-and-same-origin-checks]). Per-route middleware is native core (`middleware:` array), not a retired extension; core has no native `link` handler, but the store extension's `shortLinks` capability covers create, invalid-destination, redirect, missing-code and click-count for stored short links without a function — declare it under `extensions.store.config.shortLinks` (`urlcode docs search "shortLinks"`, MCP `search_docs`). Only report a gap for stored-link needs beyond that (custom redirect status, non-HTTP(S) destinations, per-record ownership). - Tooling: [tooling and MCP][docs/TOOLING.md], [TypeScript][docs/TYPESCRIPT.md], [capabilities][docs/CAPABILITIES.md], [plugins][docs/PLUGINS.md], [bulk import][docs/BULK.md]. - Operations: [operations][docs/OPERATIONS.md], [hosting inside another framework][docs/OPERATIONS.md#hosting-urlcode-inside-another-framework] (`createEmbeddedHandler`), [install][docs/INSTALL.md], [deployment checks][docs/DEPLOYMENT-CHECKS.md], [readiness][docs/READINESS.md], [capacity][docs/CAPACITY.md], [resilience][docs/RESILIENCE.md], [observability][docs/OBSERVABILITY.md], [Vercel][docs/VERCEL.md], [AWS][docs/AWS.md], [Cloudflare][docs/CLOUDFLARE.md], [static hosting][docs/STATIC.md], [production readiness][docs/RELEASE-OPERATIONS.md#production-readiness], [roadmap][ROADMAP.md]. [docs/TOOLING.md#local-agent-bootstrap]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/TOOLING.md#local-agent-bootstrap [docs/TOOLING.md#registering-the-server]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/TOOLING.md#registering-the-server [docs/TOOLING.md#optional-hosted-ai-mcp]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/TOOLING.md#optional-hosted-ai-mcp [docs/AI-AUTHORING.md#hosted-assisted-authoring-opt-in]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/AI-AUTHORING.md#hosted-assisted-authoring-opt-in [recipes/spa-shell/README.md]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/recipes/spa-shell/README.md [docs/PROJECT-DIRECTION.md#design-principle-declarative-first]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/PROJECT-DIRECTION.md#design-principle-declarative-first [docs/policies/security.md]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/policies/security.md [docs/yaml/assets.md]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/yaml/assets.md [docs/policies/cache.md]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/policies/cache.md [docs/HTTP.md]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/HTTP.md [docs/HTTP.md#named-schemas]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/HTTP.md#named-schemas [docs/POLICIES.md]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/POLICIES.md [docs/SITE.md]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/SITE.md [packages/auth/README.md]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/packages/auth/README.md [docs/EXTENSIONS.md#protecting-a-route-the-auth-short-form]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/EXTENSIONS.md#protecting-a-route-the-auth-short-form [proofs/private-requests/README.md]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/proofs/private-requests/README.md [docs/EXTENSIONS.md#request-bound-capabilities]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/EXTENSIONS.md#request-bound-capabilities [docs/STORE.md#audited-writes]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/STORE.md#audited-writes [proofs/native-storage/README.md]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/proofs/native-storage/README.md [docs/STORE.md#record-schema]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/STORE.md#record-schema [docs/STORE.md#per-record-ownership]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/STORE.md#per-record-ownership [docs/STORE.md#conditional-transitions-and-result-aware-retries]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/STORE.md#conditional-transitions-and-result-aware-retries [docs/STORE.md#membership-gates-and-cross-owner-reads]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/STORE.md#membership-gates-and-cross-owner-reads [docs/STORE.md#non-overlapping-intervals]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/STORE.md#non-overlapping-intervals [docs/STORE.md#declared-transfers]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/STORE.md#declared-transfers [docs/STORE.md#edit-and-delete-states]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/STORE.md#edit-and-delete-states [docs/STORE.md#a-directory-by-a-unique-handle]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/STORE.md#a-directory-by-a-unique-handle [docs/STORE.md#one-serving-process-per-database]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/STORE.md#one-serving-process-per-database [proofs/private-requests/client/main.js]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/proofs/private-requests/client/main.js [docs/ROUTING.md#a-site-root-frontend-beside-api-extension-mounts]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/ROUTING.md#a-site-root-frontend-beside-api-extension-mounts [docs/READINESS.md#authenticated-routes-auth-true]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/READINESS.md#authenticated-routes-auth-true [docs/FUNCTION-SECURITY.md]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/FUNCTION-SECURITY.md [docs/AI-AUTHORING.md]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/AI-AUTHORING.md [docs/YAML-GUIDE.md]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/YAML-GUIDE.md [docs/YAML-REFERENCE.md]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/YAML-REFERENCE.md [docs/SPECIFICATION.md]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/SPECIFICATION.md [docs/RECIPES.md]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/RECIPES.md [docs/ROUTING.md]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/ROUTING.md [docs/MIDDLEWARE.md]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/MIDDLEWARE.md [docs/ASSETS.md]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/ASSETS.md [docs/CONDITIONS.md]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/CONDITIONS.md [docs/EGRESS.md]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/EGRESS.md [docs/PRERENDER.md]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/PRERENDER.md [docs/ORGANIZATION.md]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/ORGANIZATION.md [docs/EXTENSION-REFERENCE.md]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/EXTENSION-REFERENCE.md [docs/EXTENSIONS.md]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/EXTENSIONS.md [docs/EXTENSIONS.md#add-ons-extensions-and-artifacts]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/EXTENSIONS.md#add-ons-extensions-and-artifacts [docs/EXTENSIONS.md#the-installed-file-record]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/EXTENSIONS.md#the-installed-file-record [docs/EXTENSIONS.md#upgrading-an-independent-package]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/EXTENSIONS.md#upgrading-an-independent-package [docs/EXTENSIONS.md#independent-artifact-packages]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/EXTENSIONS.md#independent-artifact-packages [docs/EXTENSIONS.md#the-release-wide-agent-catalog]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/EXTENSIONS.md#the-release-wide-agent-catalog [docs/EXTENSIONS.md#generic-add-on-authoring-rules]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/EXTENSIONS.md#generic-add-on-authoring-rules [docs/FRAMEWORK.md#the-composition-contract]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/FRAMEWORK.md#the-composition-contract [docs/VERSION-ALIGNMENT.md]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/VERSION-ALIGNMENT.md [docs/EXTENSIONS.md#external-extensions-and-ai-tooling]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/EXTENSIONS.md#external-extensions-and-ai-tooling [docs/EXTENSIONS.md#native-independent-integration-or-bundled-default]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/EXTENSIONS.md#native-independent-integration-or-bundled-default [packages/auth/]: https://github.com/jimhoyd-com/urlcode/tree/v0.6.6/packages/auth [packages/store/]: https://github.com/jimhoyd-com/urlcode/tree/v0.6.6/packages/store [packages/mcp/]: https://github.com/jimhoyd-com/urlcode/tree/v0.6.6/packages/mcp [docs/EXTENSIONS.md#request-context-route-env-and-request-id]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/EXTENSIONS.md#request-context-route-env-and-request-id [docs/EXTENSIONS.md#site-origins-and-same-origin-checks]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/EXTENSIONS.md#site-origins-and-same-origin-checks [docs/TOOLING.md]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/TOOLING.md [docs/TYPESCRIPT.md]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/TYPESCRIPT.md [docs/CAPABILITIES.md]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/CAPABILITIES.md [docs/PLUGINS.md]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/PLUGINS.md [docs/BULK.md]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/BULK.md [docs/OPERATIONS.md]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/OPERATIONS.md [docs/OPERATIONS.md#hosting-urlcode-inside-another-framework]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/OPERATIONS.md#hosting-urlcode-inside-another-framework [docs/INSTALL.md]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/INSTALL.md [docs/DEPLOYMENT-CHECKS.md]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/DEPLOYMENT-CHECKS.md [docs/READINESS.md]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/READINESS.md [docs/CAPACITY.md]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/CAPACITY.md [docs/RESILIENCE.md]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/RESILIENCE.md [docs/OBSERVABILITY.md]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/OBSERVABILITY.md [docs/VERCEL.md]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/VERCEL.md [docs/AWS.md]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/AWS.md [docs/CLOUDFLARE.md]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/CLOUDFLARE.md [docs/STATIC.md]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/STATIC.md [docs/RELEASE-OPERATIONS.md#production-readiness]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/RELEASE-OPERATIONS.md#production-readiness [ROADMAP.md]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/ROADMAP.md [docs/EXTENSIONS.md#the-local-review-loop]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/EXTENSIONS.md#the-local-review-loop [docs/EXTENSIONS.md#hermetic-runs-and-test-seeds]: https://github.com/jimhoyd-com/urlcode/blob/v0.6.6/docs/EXTENSIONS.md#hermetic-runs-and-test-seeds