Hayate ecosystem: Start here · Deployment model · Tested compatibility
This is the public, executable reference for the
Hayate ecosystem. It is generated from
create-hayate==0.14.0 and contains one application core that runs unchanged
on ASGI with SQLite and Cloudflare Python Workers with D1.
The app intentionally uses a generic TODO model. It contains no FolioMCP source, data model, credentials, tenant policy, or product-specific behavior.
After cloning the repository, run:
uv sync --locked
npm ci --ignore-scripts
cp .dev.vars.example .dev.vars
uv run pytest
uv run python scripts/check_sql_contracts.pyEvery executable command block in this README runs in CI. The direct test suite covers identity-scoped CRUD, bounded typed multipart uploads, OpenAPI, MCP, production middleware, explicit operational admin, SQL contracts, persistent redacted audit history, and restart-safe local database bootstrap.
Run the complete ASGI path:
bash scripts/check_asgi.shRun the complete local workerd path with Node.js 24:
bash scripts/check_workerd.sh class
bash scripts/check_workerd.sh globalBoth paths run deterministic Schemathesis coverage and positive fuzzing against
the live OpenAPI endpoint, create a TODO, and digest a bounded upload through
authenticated HTTP. They then read the same identity-scoped data through a
stateless MCP 2026-07-28 tools/call.
| Boundary | Verified behavior |
|---|---|
| Application | One src/app.py, WHATWG Request/Response, identity-scoped CRUD |
| API contract | Typed UUID and binary-file validation, bounded multipart parsing, OpenAPI 3.1.1, real-server Schemathesis gate, hardened Scalar, first-party zero-runtime TypeScript client |
| Agent protocol | MCP 2026-07-28 discovery and structured complete result; 2025-11-25 compatibility |
| Identity | Explicit local identity; fail-closed Cloudflare Access JWT/JWKS in production |
| Data | Checked SQL contracts; SQLite on ASGI, D1 binding on Workers |
| Operations | Explicit TODO admin; operator allowlist, owner scope, exact Origin, cursor paging, saved views, bounded CSV, redacted localized history, safe branding |
| Observability | Validated request IDs, bounded application/Worker release identity, and compact query-free JSON access events across ASGI and Workers |
| Production | Exact-origin CORS, security headers, 1 MiB body limit, native rate limiting, deployment-identifiable responses |
| Supply chain | Locked dependencies, dependency audit, workflow audit, pinned actions |
Regenerate and verify the checked artifacts:
uv run python scripts/export_compatibility.py --check
npm run api:check
npm run client:interopThe generated compatibility table and
machine-readable JSON come from uv.lock,
golden-app.toml, and wrangler.toml; CI fails when they drift.
client/api-client.ts is generated from the same OpenAPI document as
client/api-types.ts. It imports only the generated paths type and uses
platform Fetch at runtime. The interoperability gate strictly compiles that
client, then executes authenticated JSON, query/path, multipart, and delete
operations against a real golden ASGI process.
The reference uses Hayate's default WorkerEntrypoint class. This is the
feature-complete mode for HTTP plus named RPC methods and class handlers such
as scheduled.
Hayate also exposes an explicit global-handler compatibility mode. It has
slightly less dispatch overhead but is HTTP-only: it must not be presented as
supporting RPC methods or scheduled class handlers. Generate that shape with
create-hayate --workers-entrypoint global only when the service contract is
strictly HTTP.
GET /health— public liveness.GET /canonicalize— a WHATWG URL/IDNA contract.GET /whoami— the current request principal.GET|POST /todos,GET|DELETE /todos/:id— identity-scoped data.POST /uploads— bounded multipart file streaming with a typed digest response.GET /openapi.json,GET /docs— authenticated schema and docs.POST /mcp— MCP Streamable HTTP.GET|POST /admin/*— separately allowlisted operational TODO administration.
The reference enables create-hayate's opt-in admin profile. Local requests
to /admin require the developer@example.com Cloudflare Access identity;
production uses the placeholder operator@example.com until the deployment
owner replaces it. There is no anonymous mode, default superuser, reflected
table access, or generic SQL endpoint.
Records and audit history are scoped to the Access subject. List controls use
bounded checked-SQL search/sort/cursor contracts, static saved views, and a
separately authorized CSV export with hard row and byte ceilings. Mutations
require an exact configured Origin, and persistent audit rows deliberately
omit submitted values. Branding is escaped plain text with contrast-checked
theme tokens and a hashed style CSP; the page includes semantic landmarks,
visible focus, reduced-motion handling, and application-scoped localization.
The reviewed vendored source commits and MIT licenses live under admin/.
Run the optional real-browser gate after installing Chromium:
uv run playwright install chromium
HAYATE_ADMIN_BROWSER_TESTS=1 uv run pytest -m browser -qThis repository is a reference, not a deploy-with-placeholders artifact. Complete every item in PRODUCTION.md, including replacing the Access audience/domain, D1 IDs, CORS origins, rate-limit namespaces, observability policy, and rollout ownership.
The design and trust boundaries are explained in ARCHITECTURE.md. Report vulnerabilities according to SECURITY.md.