Known gaps and differences

What doesn't exist, what's rough, and what's still unfinished.

This guide describes Crisptastic as built. Specifications, plans and older pages describe the intended system or earlier versions, and they disagree with the code in places. This chapter lists the differences so that you do not waste time on features that do not exist.

When this guide and another document disagree, trust this guide.

Features described elsewhere that do not exist

If you see these in a specification or an older page, they are not available.

Pages and routing

  • @header, @cache, @telemetry directives. (They print as text.)
  • Options on directives: @redirect "...", status: 301, &#64;cookie ..., path:, max_age_seconds:<code>. Redirects are always</code>303; cookie attributes are fixed.
  • Nested session assignment (@session a.b = 1).
  • Folders _errors/, _triggers/, and error handlers default, 403, 405, 413, 429. Error pages are top-level files named 400, 404, 500 or error.
  • A folder name making files private. Only a file name starting with _ does.
  • Catch-all ([...rest]) routes, optional segments, a 308 redirect to the trailing-slash URL.
  • A per-route auth policy. ([routes."/x"] does declare methods, body type and size, capabilities and rate limits; see Configuration.)
  • The {{{{ escape for a literal {{.
  • language.* error codes, the language.non_scalar_output error, and a protection of request, context and data from being reassigned.
  • Custom helper functions defined in a page (@code).
  • Request fields request.id, request.client.*; context fields context.application, .origin, .authority, .values, .capabilities, .now; error context fields code and correlation_id.

Configuration

  • [deploy], authorities, health_route, [limits], [runtime] (including minimum_version and language_profile), [session], [secrets], [capabilities.*], app_id. The deployment key is [deployment] domains. Unknown top-level keys, and unknown keys inside the sections that are read, are refused with config.unknown_key.
  • Configurable execution limits. They are fixed constants.
  • Reading crisptastic.toml from the site folder when you name the folder on the command line. It is read from the current directory (or --config).

Development

  • Local fakes for capabilities.
  • crisptastic.toml reloading in dev.
  • A dev that is identical to production: secure cookies and sealed [env] values apply only on a host.
  • Serving assets under /assets/. They are served at the site root.

Integrations

  • auth, payments, files, images and messaging as @call capabilities; auth.start/logout/require, Stripe webhooks and refunds, idempotency keys, file size limits.
  • A data capability with general queries. It has get, list, create, replace and delete.
  • Circuit breakers, retries and per-operation timeouts.
  • Replicated sessions, or any session expiry.

SDA

  • The jq-style syntax (.items | sort_by(...) | take(5) | { id, total }) shown in older pages. Only a small subset is implemented (Fetching and shaping data).

Deployment and hosting

  • crisptastic status, apps, deployments, logs, secrets, rollback, server add, host init, keys authorize and a host.toml file.
  • The challenge-authenticated deployment protocol and its rollback, retire and log endpoints. The real control plane is one call: mutual-TLS POST /v1/deployments/activate.
  • An operations listener with /metrics; deployment history; health checks before a switch; an audit log.
  • Node-to-node secret transfer and replicated sessions in the cluster.
  • An operator export/restore command for a lost cluster.
  • Signed official releases and a public installation channel. (Private builds install through Gritpack; see the Quickstart.)
  • Embedded [data] on a Fabric cluster, or telemetry on a deployed host. (A single host does open [data] stores; see Running a host.)

Things that work differently from what pages say

Claim in older materialReality
"run / serve serve without watching."run watches by default (--no-watch); serve is a different command that ignores the config file.
"context.env.KEY holds [env] values."Only in dev/run/serve. Empty on a deployed host.
"Archived Capsules are free of usable credentials."A Capsule contains the secret values, encrypted to the host recipients.
"build signs and wraps the site in a Capsule."build capsule makes an unsigned, unencrypted artifact that cannot be hosted. deploy makes the deployable Capsule.
"deploy runs the deterministic build."deploy ships your sources and the host compiles them at activation, unless [asset_publication] is configured.
"Two builds produce identical bytes."True only for Site Artifacts; deployment Capsules are encrypted with randomness.
"Indexing null gives null."It is an error. A missing key is null.
"@for (x of y); use of, not in."in is current; of is legacy; both work.
"ASCII only; the lexer crashes on other characters."UTF-8 text works. Only identifiers must be ASCII.
"Arrays and objects need json(...) or raise an error."They print as JSON.
"{{ x }} is identical to {{= x }}."{{ x }} takes only a dotted path or a pipe expression.
"Public asset URLs are served from /assets/...."Assets are served from the site root (assets/logo.svg is /logo.svg).
"Error pages get a quarter of the render budget."They get the same limits but cannot mutate.
"With --proxy-mode none (default, loopback)".Under the production profile, the default rejects all site traffic.
"--host-root with --development-process-profile."The two options conflict.
"A cluster supplies secrets to a restarted node from another node."Not wired in; each node decrypts the Capsule itself.
[[peers]] with only boot_id, address and credential fieldsAlso needs certificate_fingerprint_blake3, not_before_unix, not_after_unix.

Security notes for integrations

The code behind the helper endpoints (Stripe, S3, Cloudflare Images and Auth0) has the properties listed in Security model, in particular unauthenticated access and the unencoded session_id in the Stripe lookup. They are documented here rather than hidden so you can decide how to expose them.

Bugs and rough edges worth knowing

  • @include( anywhere in a file, including comments and prose, is processed.
  • A stray } in text inside a block closes that block.
  • Arithmetic beyond 2^53 loses precision silently (9223372036854775807 + 1 prints 9223372036854776000); there is no overflow error.
  • Dev-server pages cannot @fetch http://localhost APIs (outbound policy).
  • Production hosting requires Linux. The macOS build is for writing sites.
  • A bare true or false as the value of @let or @session becomes null. !false and 1 = 1 work.
  • [fetch] cache_ttl_ms caches a failed fetch too, so an upstream error is served again until the time runs out.
  • A data write during a GET gives a 500 page rather than a failed result you can branch on.
  • Run a trial host from outside the site folder, or give it a --deployments-root outside it. Unpacked .crisp files inside the site count as routes.

What remains unfinished (from the project's own status)

Certification for production use of the whole system; failure-race and cold-start testing; independent security review; backup and restore for a lost cluster; clustered stateful sites; untrusted-tenant isolation; and release signing.