The hosted sandbox is built in three layers:Documentation Index
Fetch the complete documentation index at: https://docs.enfinitos.com/llms.txt
Use this file to discover all available pages before exploring further.
sandbox-core
The foundational TypeScript library. Edge-runtime-compatible: uses only Web APIs (TextEncoder, btoa/atob, crypto.subtle via
@noble/hashes, crypto.randomUUID, crypto.getRandomValues). No
node:fs, no node:crypto, no Buffer.
| Module | Responsibility |
|---|---|
canonical.ts | Field-ordered + sort-keys canonical JSON. Byte-exact with platform + auditor SDK. |
crypto.ts | Ed25519 (via @noble/ed25519), SHA-256 (via @noble/hashes), base64url, sandbox keypair derivation. |
proofPack.ts | signProofRecord, issueProofPack, buildReceiptPayload. Produces envelope.v1 packs. |
metering.ts | Per-substrate projection rules — DOOH dwell seconds, CTV impressions, etc. |
settlement.ts | Banker’s-rounded reconciliation across TENANT / VENUE / PLATFORM splits. |
tenantState.ts | The full rights bounded context: basis, right (issue/suspend/resume/revoke), offer (propose/accept/reject/counter/withdraw), challenge (open/resolve/withdraw), expiry sweeps, provenance walks. |
constraints.ts | Pre-render gate: messaging opt-out + quiet hours, automotive speed, drone Remote ID + BVLOS waiver, audio attention. |
syntheticFactory.ts | Generates plausible delivery events with substrate-realistic dwell. |
types.ts | All wire shapes. Mirrors platform shapes exactly. |
__tests__/conformance.test.ts — every
sandbox-issued pack is fed through @enfinitos/sdk-auditor’s
verifyAll. A drift in any encoder, signature, chain, metering, or
settlement primitive will fail the suite. CI gates the sandbox
release on it.
HTTP API
Each route underapps/web/app/api/sandbox/ is a tiny adapter
between the HTTP boundary and the sandbox-core state machines.
Common scaffolding lives in _lib/wrapHandler.ts:
- Parses cookies + HMAC validation
- Per-IP rate limiting
- JSON body parsing
- Persists the mutated tenant state back to the store
- Wraps errors into the standard envelope
Storage
The tenant store is aMap<tenantId, TenantState> keyed under a
global Symbol so all routes share one view per Worker isolate. The
interface (apps/web/app/sandbox/_lib/store.ts) is intentionally
small — get, set, delete — so a future swap to Cloudflare
KV / D1 / Durable Objects requires no route-handler changes.
Why module-level memory works for sandbox
Sandbox traffic is single-visitor, short-session, low-stakes. A typical visitor finishes the seven-step flow in 5–20 minutes. Cloudflare Workers keep their isolates warm for tens of minutes under continuous traffic; the eviction case is detectable and recoverable (the API returns 410 TENANT_EVICTED; the UI prompts the user to hit Reset).Upgrading to persistent storage
When sandbox traffic is high enough that eviction is common, the upgrade is:- Create a Cloudflare KV namespace bound to the Pages project.
- Replace
memoryStorein_lib/store.tswith a KV-backed implementation matching the same interface. - KV reads are eventually consistent (~60s globally) — sandbox tenants are per-visitor so consistency isn’t a concern.
- Set an explicit TTL (24h matches the cookie max-age).
In-browser verifier
apps/web/app/sandbox/_components/SandboxConsole.tsx runs the
seven-step audit roundtrip client-side using sandbox-core
primitives:
- Envelope version is
envelope.v1. canonicaliseProofPayloadre-encodes each record byte-identically.sha256HexOfString(payloadCanonical)reproducesafterHash.- The hash chain is intact end-to-end.
- Every Ed25519 signature verifies against the published key.
- Metering records re-project from receipts.
- Settlement lines reconcile per-meter to gross.
Cross-environment story
A sandbox-issued pack verifies under any auditor pointed at the sandbox key directory. A production-issued pack verifies under any auditor pointed at the production key directory. Cross-pointing fails asUNKNOWN_KEY_ID — there is no environment-conditional
code path on the auditor side. The same library handles both.
This is the property that makes the sandbox useful for compliance
review: anything that verifies under sandbox will verify under
production once a real tenant exists.
Trust model summary
| Question | Answer |
|---|---|
| Are sandbox signatures real? | Yes — Ed25519 over canonical JSON, identical algorithm to production. |
| Is the sandbox key kept secret? | No, deliberately — derived from a published seed string so anyone can re-derive. The keyId is unambiguously labelled as a sandbox key. |
| Can a sandbox pack impersonate a production pack? | No. Sandbox packs carry a sandbox keyId; production auditors don’t know this key. Verification fails as UNKNOWN_KEY_ID. |
| Can a malicious user forge sandbox packs? | Yes — by design. The sandbox is a demonstration environment, not a trust boundary. Forging packs that pass sandbox verification is the same as running the demo. |
| Where does tenant data live? | Module-level Map in the Worker isolate. Per-visitor, ephemeral, no cross-visitor leakage. |
| Is the cookie tamper-resistant? | HMAC-SHA256 over the tenantId with a server secret. Tampering breaks the HMAC. |
| What about rate limiting? | 10 req/10s burst + 200 req/hour sustained per IP. Cloudflare’s bind-time rate-limit primitive is the production upgrade path. |