A chat that reaches a computer
Envelop is a web chat whose other end is a real 32-bit computer, Tomato. A person sends a message or a small compute job from the browser. A backend holds it until a nearby phone or computer can carry it over Bluetooth to Tomato. Tomato runs the job and writes an answer back.

Quick start
Contents
| Chapter | Coverage |
|---|---|
Scope, conventions, and reading order. |
|
System path, components, and data model. |
|
Wire protocol, delivery semantics, and compute provenance. |
|
Chat, backend calls, and protocol documents. |
|
Bridge runbook and backend deployment. |
|
Test vectors, contract tests, and acceptance evidence. |
|
Clients, backend schema, and repository layout. |
|
Bounded sizes and current measurement state. |
|
Experimental boundary and open unknowns. |
Conventions
-
monospaceidentifies commands, paths, and code identifiers. -
Paths are relative to the repository root unless stated otherwise.
-
Unmeasured results are marked
TBD (unmeasured). -
When prose and implementation disagree, the documentation policy decides which source wins; dated files under
log/are history, never current architecture.
1. Introduction
Envelop surrounds the Tomato computer with a messaging system: a
browser chat client anyone can open, a durable cloud backend, one
nearby native bridge at a time, and the compact binary ENVELOP/1
device protocol that reaches Tomato over Bluetooth.
Tomato itself — processor, computer, and operating system — is maintained in the Tomato repository. The Envelop endpoint inside Tomato OS lives there; the web app, backend, native bridge apps, and shared device protocol live here.
1.1. Scope
This manual documents the Envelop side: system path, wire contract, delivery semantics, backend calls, bridge operation, deployment, verification, and current limits. Tomato internals (CPU, ALU, firmware) are covered by the Tomato manual and referenced by path, not duplicated.
1.2. Reading order
Start with Architecture for the system path, then Design for the protocol and provenance rules that govern every claim on this site. Operators run bridges with Operation; everyone checks Known limitations before quoting availability.
1.3. Conventions
-
monospacemarks commands, paths, identifiers, and literals. -
File paths are repository-relative, e.g.
protocol/ENVELOP_PROTOCOL.md. -
Unmeasured values are written as
TBD (unmeasured)— never estimated. -
Status words are not interchangeable: implemented, verified, hardware-accepted, deployed, and online mean different things. See Known limitations.
2. Architecture
Four blocks move a message from a person to silicon: the public web app, the Supabase backend, one nearby verified bridge, and the Envelop app inside Tomato OS driving the Tomato CPU.
2.1. Canonical path
person → Envelop web app → backend queue → nearby verified bridge → Envelop in Tomato OS → Tomato CPU → labeled reply
The browser and backend never talk directly to the FPGA. Tomato has one current radio connection, while the backend independently permits one unexpired authenticated bridge lease at a time.
2.2. System context
-
Public user device — person, Envelop web app, and Virtual Tomato (a browser worker for offline compute or explicit preview).
-
Cloud boundary (Supabase) — anonymous auth, PostgREST RPC with row level security, and records for profiles, conversations, messages, presence, the device queue, compute jobs, and the 30-second bridge lease.
-
Physically near Tomato — one verified bridge (macOS 14 or private Android) reaching Tomato over the nRF8001 Nordic UART BLE link with binary
ENVELOP/1framing. -
Tomato computer — Envelop in Tomato OS plus the Tomato CPU.
Virtual Tomato is a separate browser execution path, not a bridge and not a substitute result for an ambiguous hardware operation.
2.3. Repository ownership
| Directory | Responsibility |
|---|---|
|
Public chat, UI, and Virtual Tomato |
|
Schema, row level security, queues, leases, jobs |
|
macOS chat plus operator bridge |
|
Cloud API, protocol codecs, compiler |
|
Private owner UI plus BLE bridge |
|
Wire contract plus shared test vectors |
|
Current architecture, operations, and status |
|
Contract verification and platform tests |
2.4. State boundaries
Presence, lease, delivery, and read state are independent. A human heartbeat is not a bridge lease; delivery is not read state; checked-in source is not proof that hardware is online:
-
Human online — presence heartbeat state.
-
Hardware online — an unexpired authenticated bridge lease after
ENVELOP/1identity verification. -
Delivered — Tomato
MESSAGE_ACKplus the cloud queue update. -
Read — never inferred; no read-receipt feature exists in the current contract.
3. Design
The design centers on a small binary wire contract, at-least-once delivery with session-local tokens, and strict provenance labels that separate physical hardware results from virtual execution.
3.1. Wire contract
ENVELOP/1 replaces the legacy 95-character LF transport only when
both ends run this protocol. Never negotiate by guessing from a
Bluetooth name; bring-up against old LF firmware must fail
verification rather than silently bridging.
All integers are unsigned big endian. Each frame carries magic
50 47, version 01, a type byte, a route (u16), a payload length
(u16), the payload, and a CRC-16/CCITT-FALSE over header and
payload. Payloads are bounded to 512 bytes, so a frame never exceeds
522 bytes. Receivers reject unknown types, versions, lengths, and
CRCs, advance one byte to search for magic, and reset partial frames
on disconnect.
| Frame | Type | Route | Payload |
|---|---|---|---|
|
1 |
0 |
Empty; bridge initiates verification |
|
2 |
0 |
Exact ASCII |
|
3 |
0 |
Empty; discards session routes and dedup tokens |
|
4 |
nonzero |
Avatar, unread flag, 1–32 ASCII name bytes |
|
7 |
nonzero |
Delivery token ( |
|
8 |
nonzero |
Outgoing token ( |
|
9 |
original route |
Original token ( |
|
10 |
0 |
State byte: offline, syncing, or online |
|
32 |
nonzero |
Token plus 1–508 bytes of Tomato job data |
|
33 |
original route |
Token, status byte, result ( |
OPEN_CHAT and CHAT_HISTORY exist in the contract for
device-driven history requests, but current native bridge handlers do
not implement that exchange. The full field reference is
protocol/ENVELOP_PROTOCOL.md; the BLE adapter contract is
protocol/BLE_PROTOCOL.md.
3.2. Delivery semantics
-
Retries retain the same delivery token; Tomato deduplicates
CHAT_MESSAGEtokens before display. -
If Tomato accepts a frame but the link fails before the cloud acknowledgement is recorded, the message can be shown again after resynchronization. Delivery is therefore at least once across reconnect and power-loss boundaries; exactly-once display is not claimed.
-
Cloud UUIDs stop at the bridge. Only bounded routes, delivery tokens, and printable ASCII text cross BLE. The route table holds at most eight contacts and routes are session-local.
-
In either direction,
MESSAGE_ACKmeans protocol and backend acceptance — not that a person read the message.
3.3. Compute provenance
A person enters a supported expression; the browser compiles canonical Tomato bytecode; the chosen execution path decides the label:
-
Hardware request — a durable compute job is created, the leased bridge claims it, Tomato executes
COMPUTE_JOB, and the backend completes the job from the matchingCOMPUTE_RESULT. Only this completed backend hardware result may be labeled Physical Tomato or Hardware Tomato. -
Offline compute or explicit preview — the browser worker executes immediately as Virtual Tomato, visibly labeled, never queued for hardware.
-
Timeout, disconnect, or ambiguous claimed job — an unknown hardware outcome. It must not be replayed virtually; fallback after a hardware attempt requires a separately chosen action and a confirmed terminal non-result.
3.4. Identity vocabulary
Verified Tomato means the bridge received the exact binary
ENVELOP/1 Tomato identity after HELLO. This is a protocol
identity check, not cryptographic attestation and not a
confidentiality claim. Envelop is not documented as end-to-end
encrypted; backend content and operator-visible bridge traffic are
readable application data.
4. Interfaces
Three surfaces matter: the public web chat, the backend remote calls, and the protocol documents that pin the wire format.
4.1. Web chat
The browser is the general public client at web chat. It queues messages for physical Tomato, runs explicitly labeled Virtual Tomato execution, and never requires a bridge on the user’s side. Which revision is deployed must be checked separately from repository source.
4.2. Backend calls
The backend exposes PostgREST RPC plus row level security over these core operations:
| Call | Effect |
|---|---|
|
Stores a durable message and creates a queued device row |
|
Returns queued messages and jobs to the leased bridge |
|
Marks a queue row acknowledged after Tomato |
|
Idempotently stores a Tomato reply; Tomato is acknowledged only after this succeeds |
|
Claims the 30-second authenticated lease for a fresh bridge instance |
|
Releases the lease when possible on disconnect |
|
Dashboard-only first-owner setup; never granted to anonymous clients |
Clients receive only the project HTTPS URL and the public publishable/anonymous key:
export ENVELOP_SUPABASE_URL='https://YOUR_PROJECT.supabase.co'
export ENVELOP_SUPABASE_KEY='YOUR_PUBLIC_KEY'
Service-role keys, secrets, UUIDs, and admin controls must never ship in clients or appear in documentation assets.
4.3. Protocol documents
-
protocol/ENVELOP_PROTOCOL.md— exact frame fields, types, and limits for the binary v1 contract. -
protocol/BLE_PROTOCOL.md— Nordic UART adapter: TX notifications, ordered RX frame chunks of at most 20 bytes, transport-capacity flow control. -
protocol/test-vectors/— sharedframes.jsonvectors consumed by Swift XCTest andpython3 protocol/test-vectors/verify_c.py.
5. Operation
Bridge operation is a runbook for operators; backend deployment is a runbook for the owner. Public users operate neither.
5.1. Bridge runbook
One nearby operator-controlled bridge at a time. A BLE connection without a valid lease must not forward cloud traffic, and a lease must not be claimed before Tomato identity verification.
Connect:
-
Confirm the bridge account has a Tomato grant (owner bootstrap via
envelop_private.bootstrap_owner(uuid)). -
Start the native app near Tomato and connect the Nordic UART GATT service; subscribe to notifications and send binary
HELLO. -
Require the exact
ENVELOP/1Tomato identity response. Reject a Bluetooth name, malformed response, old line protocol, or timeout. -
Create a fresh bridge-instance UUID, claim the backend lease, and renew it while connected.
-
Begin with
CONTACT_RESET, then synchronize routes, queued messages, and jobs.
Operate normally: forward queued messages with stable session delivery
tokens, acknowledge queue items only after Tomato MESSAGE_ACK, call
send_as_device with a stable nonce before acknowledging Tomato, and
complete compute jobs only from the matching COMPUTE_RESULT.
On disconnect or lease loss, stop cloud forwarding and clear partial
frames, routes, tokens, pending BLE writes, announced contacts, and
compute waiters. A reconnect creates a new bridge instance starting
with CONTACT_RESET. Never force-takeover an unexpired lease; never
replay an ambiguous job through Virtual Tomato.
5.2. Recovery checklist
-
Peer fails verification — stop; confirm matching protocol and firmware.
-
Bridge account not provisioned — provision the operator in the dashboard; do not widen anonymous grants.
-
Device already leased — find the existing operator or wait for expiry.
-
Lease lost — stop forwarding, clear session state, reconnect.
-
Internet loss — retain backend and device truth; do not acknowledge work that was not durably accepted.
5.3. Backend deployment
|
Warning
|
backend/migrations/001_envelop.sql is the sole current
schema and it is a destructive reset, not an incremental migration. It
drops and recreates the Envelop schemas and erases all application
state, including ownership. Never apply it as a routine production
update.
|
Stage first: use a disposable Supabase project, enable anonymous sign-ins, back up everything that must survive, rehearse restore into a separate disposable project, run the schema, bootstrap the owner from the dashboard, and complete physical acceptance before describing hardware as available. If the owner’s anonymous-auth identity is lost, the supported recovery is a clean reset plus dashboard-only bootstrap; no public API or service-role key may bypass it.
6. Verification
Four layers establish different facts: shared vectors for codec agreement, local tests for schema and source contracts, guardrails for documentation boundaries, and live acceptance for deployed reality.
6.1. Shared vectors
protocol/test-vectors/frames.json covers core framing and both
compute frame types. Swift XCTest and
python3 protocol/test-vectors/verify_c.py consume them. Vectors
prove codec agreement, not a live radio session or a complete
application flow.
6.2. Contract tests
Run local backend contract tests from the repository root:
node backend/tests.mjs
These tests do not contact or establish the revision of a hosted
project. Website behavior is covered by the chat test suites, e.g.
node --test website/chat/*.test.cjs. Live smoke tests stay off by
default because they create accounts and data; run them only when
explicitly authorized.
6.3. Documentation guardrails
python3 tools/check_docs.py enforces the project’s evidence
boundary in CI: public copy must not claim live availability,
hardware demonstration, or deployed revisions without fresh
evidence, and private packages, keys, and identifiers must not leak
into public artifacts.
6.4. Acceptance evidence
A live acceptance record identifies the backend schema revision, bridge source and package version, Tomato firmware revision, physical device, date, and the exact message and compute sequence exercised. Local codec tests are useful but are not physical acceptance.
7. Implementation
Each surface is implemented where its platform demands; the wire
contract in protocol/ is the shared source of truth between them.
7.1. Clients
-
Browser (
website/) — public chat underwebsite/chat/, Virtual Tomato browser worker, and the static pages deployed to the web surface. -
macOS (
apple/) — Swift package targeting macOS 14 (package 0.2.0): operator bridge plus test chat client. -
Android (
android/) — private owner app (package 0.2.0):android/core/holds cloud API, protocol codecs, and compiler;android/bridge/holds the owner UI plus foreground BLE bridge. No public login or ownership-claim flow; never link it as a public download. -
Tomato OS endpoint — implemented in Tomato assembly and local simulation in the Tomato repository, not here.
7.2. Backend schema
The sole schema file is backend/migrations/001_envelop.sql. Public
tables cover profiles, conversations, messages, device queue, bridge
leases, presence, compute jobs, and grants under row level security;
bridge grants, administrators, trusted bridge users, and reserved
names live in the private schema. Local behavior is pinned by
backend/tests.mjs; backend/smoke-live.sh is reserved for
explicitly authorized live runs.
7.3. Repository layout
website/ stages only static files for the public deployment.
Native Android and macOS packages build solely into gitignored
private local directories — no native package belongs under
website/, in the Pages artifact, or in public page links.
8. Performance and limits
No latency or throughput measurements are claimed in current sources; the numbers below are design bounds, not benchmarks.
| Bound | Value | Notes |
|---|---|---|
Device text |
1–256 printable ASCII bytes |
Longer text is |
Wire payload |
At most 512 bytes |
Frame at most 522 bytes with header and CRC |
BLE chunk |
At most 20 bytes per RX write |
Nordic UART transport capacity |
Route table |
At most 8 contacts |
Session-local; cleared on |
Bridge lease |
30 seconds, renewed while healthy |
Fencing mechanism, not a health proof |
End-to-end latency |
|
No measured send-to-ACK figures in source |
Sustained throughput |
|
No measured jobs-per-minute figures in source |
Timeout, lease loss, disconnect, or an ambiguous claimed job is an unknown hardware outcome. It must stay visible as unknown rather than being converted into a virtual result or a performance claim.
9. Known limitations
Envelop is experimental. Source implementation plus local tests do not prove that the production backend schema, a nearby bridge, and the programmed FPGA run matching revisions.
9.1. Status boundary
| Area | Canonical status |
|---|---|
Web chat |
Implemented in source; deployed revision must be checked separately |
Virtual fallback |
Implemented and unit-tested; fallback after a hardware attempt needs a separate action and a confirmed terminal non-result |
Backend |
One destructive schema plus local contract tests; hosted state not established |
macOS |
Source-supported operator and test client, package 0.2.0 |
Android |
Private source-supported bridge app, package 0.2.0; no public artifact |
Device protocol |
Binary v1 with shared vectors; conformance is not a live radio session |
Tomato OS endpoint |
Implemented in assembly and simulation; programmed hardware needs live evidence |
Physical messaging and compute |
Implemented end to end in source; availability needs a live acceptance check |
9.2. Open unknowns
Which website and backend revisions are deployed; whether a bridge and programmed FPGA are online with matching revisions; whether the latest Android source completed physical-device acceptance; whether backup and owner-recovery rehearsals passed against a disposable project. Public copy must not convert these into live or available claims without fresh evidence.
9.3. Hard boundaries
-
Not documented as end-to-end encrypted; backend content and operator-visible bridge traffic are readable application data.
-
Exactly-once display is not claimed; delivery is at least once.
-
MESSAGE_ACKis acceptance, never a read receipt. -
No device-driven history synchronization yet (
OPEN_CHATandCHAT_HISTORYare unimplemented in bridge handlers). -
No repository-wide open-source licence; describe Envelop as a private repository with a public web surface, not as open source.
About me
I’m Tyrone Marhguy, a Computer Engineering student at the University of Pennsylvania, class of 2028. Envelop is the browser path I built so a chat can reach the Tomato computer.
I grew up between Kumasi and Accra. In 2021, Achimota School denied me admission because I wear dreadlocks as an expression of my Rastafarian faith. Ghana’s High Court ordered the school to admit me; I finished secondary school there, then came to Penn on a full scholarship. BBC Pidgin and Deutsche Welle covered the case.
I design the architecture, build the boards, and write the software. Tomato is a 32-bit computer with a running FPGA implementation and discrete boards in progress. I also build systems software, including a search engine, a compiler, and a database, and I contribute fixes to open-source EDA tools such as LibreLane, OpenROAD, Verilator, and OpenFPGA. That work has included production software at Aragorn AI and battery-management hardware at Vero Electric.
Hardware
-
Tomato, a 32-bit computer (repository)
-
Pineapple GPU, a programmable 3D GPU on a Nexys A7
-
riscv64xO3, a 2-wide out-of-order RV64IMAC
-
MAC, a BFloat16 multiply-accumulate for SkyWater 130 nm
-
UDP/IP stack, a 100 Mbps datapath on a Nexys A7
-
ITCH parser, NASDAQ ITCH 5.0 on a Nexys A7
-
6T SRAM, a full-custom SRAM study
Software and systems
Open source
See open-source work for contributions to LibreLane, OpenROAD, Verilator, and OpenFPGA.