Skip to content

Parity ledger — route → status·

Generated from ~/tinyai-id @ 72244113 and worker submodule @ fffcf20. Status values: todo · ported (code compiles in template) · tested (source tests pass in template) · n/a (deliberately excluded, reason given).

Parity: 64 / 64 web routes ported (32 with source tests green) · 121 / 121 worker endpoints ported (+ oauth.ts unmounted — DRIFT #11) · 100%

R2 skeleton (not counted): GET /api/health (web, edge) and GET /health (worker) exist only to prove the monorepo builds; neither is a source route.

apps/web — app/api/* (64 route files)·

Route Methods Source lines Source tests Status
/api/account-voice GET,POST 66 account-voice-write.test.ts tested (account-voice-write)
/api/archives GET,POST,DELETE 85 — ported (session-archive lib tested)
/api/auth/cli POST 64 cli-token.test.ts tested (cli-token)
/api/auth/cli/token POST 53 cli-token.test.ts tested (cli-token)
/api/auth GET 138 oauth-csrf.test.ts tested (auth, oauth-csrf)
/api/auth/webauthn/login GET,POST 122 webauthn-login.test.ts tested (webauthn-login)
/api/auth/webauthn/register GET,POST 130 — ported (no source unit test; verification logic verbatim)
/api/chain/join GET 80 chain-join-doc.test.ts chain-join.test.ts tested (gated PAYMENTS_ENABLED; source suites green, DRIFT #28)
/api/chain/status GET 62 chain-status.test.ts tested (gated PAYMENTS_ENABLED; source suites green, DRIFT #28)
/api/chat POST 2106 chat-route.test.ts flipper-tools.test.ts limit-message.test.ts nicla-tools.test.ts nicla-voice-tools.test.ts page-code-trust.test.ts prompt.test.ts spawn-tree-states.test.ts wearables-android.test.ts wearables-ios.test.ts tested (chat-route; page-code-trust wiring its now active)
/api/chat/tool-result POST 50 — ported
/api/control POST 146 control-limit-order.test.ts limit-message.test.ts write-routes.test.ts tested (write-routes, control-limit-order)
/api/delete DELETE 47 write-routes.test.ts tested (write-routes)
/api/devices/adopt POST 68 adopt-route.test.ts ios-adopt-failure.test.ts nicla-android-parity.test.ts ported
/api/devices/ask POST 102 device-ask-route.test.ts device-ask-universe.test.ts tested (device-ask-universe)
/api/devices/endpoint/chat POST 77 endpoint-chat-route.test.ts ported
/api/devices/endpoint GET 123 devices-camera-panel.test.ts ported
/api/devices/event POST 53 nicla-android-parity.test.ts ported
/api/devices/heartbeat POST 63 devices-route.test.ts ported
/api/devices/messages POST 50 — ported
/api/devices/relay POST,GET,PUT,PATCH 149 relay-poll-verdict.test.ts relay-route.test.ts relay-send.test.ts ported
/api/devices GET,POST,DELETE 151 devices-route.test.ts enroll-outcome.test.ts revoke-message.test.ts ported
/api/devices/task-result POST 55 — ported
/api/devices/transcript POST,GET 113 android-transcripts-readback.test.ts transcript-route.test.ts ported
/api/erc8004/registration/[slug] GET 203 erc8004-registration.test.ts x402-facilitator.test.ts x402-network-parity.test.ts x402-tiny-network.test.ts tested (gated PAYMENTS_ENABLED; source suites green, DRIFT #28)
/api/events GET 51 — ported
/api/firmware/manifest POST,GET,PUT 146 firmware-channel.test.ts tested (firmware-channel)
/api/follow GET,POST 63 — ported
/api/graph GET,POST 113 graph-query.test.ts memory-list.test.ts ported
/api/job-run POST 246 flipper-ble.test.ts flipper-tools.test.ts job-run.test.ts nicla-tools.test.ts nicla-voice-tools.test.ts tested (job-run)
/api/jobs GET,POST,DELETE 101 write-routes.test.ts tested (write-routes)
/api/learnings GET,POST,DELETE 143 learnings-delete-scope.test.ts memory-list.test.ts unlearn-scope.test.ts tested (memory-list, learnings-delete-scope, unlearn-scope — 13 census its skip until MemoryPanel/tools/memory/messages/voice land)
/api/location GET,POST,DELETE 97 — ported (worker SQL tested: locations-sql)
/api/login POST 81 — ported (rate-limit tested; login route test lands with tiny CRUD in R5)
/api/logout POST,GET 16 — ported (no source unit test; 16 lines verbatim)
/api/manifest/[slug] GET 64 — ported (tiny-record tested)
/api/me GET 49 standing.test.ts ported (free-tier tested; standing test waits for rate-limit.ts in the next slice)
/api/media POST 67 media-route.test.ts ported
/api/messages GET,POST,DELETE 131 dm-length-parity.test.ts ios-messages-load-reason.test.ts load-failure-caption.test.ts memory-list.test.ts ported
/api/model-config GET,POST 74 — tested (settings-routes)
/api/model-providers GET,POST,DELETE 107 — tested (settings-routes)
/api/prefs GET,POST 57 — tested (settings-routes)
/api/push GET,POST,DELETE 85 — ported
/api/run-tool POST 44 — tested (user-tools via lib)
/api/share POST,GET,DELETE 164 share-route.test.ts write-routes.test.ts tested (share-route, write-routes)
/api/telegram GET,POST,DELETE 77 — tested (worker telegram-poll + telegram-authz)
/api/tiny POST 132 tiny-read-degrade.test.ts ported (no source unit test; worker get tested via tiny-read-degrade later)
/api/tools/install POST 161 — ported
/api/tools GET,POST,DELETE 108 — tested (user-tools via lib)
/api/tools/run POST 71 — ported
/api/tools/trust GET,POST,DELETE 97 write-routes.test.ts tested (write-routes)
/api/udid GET,POST 169 udid-route.test.ts tested (udid-route, 16; owner default inverted — DRIFT #10)
/api/visit POST 68 limit-cost-routes.test.ts ported (limit-cost-routes waits for /api/worker)
/api/voice/recording-status/[id] GET 70 voice-playback-refusal.test.ts voice-recording-status-route.test.ts tested (voice-recording-status-route)
/api/voice/replay/[id] GET 42 — ported
/api/voice/session POST 142 flipper-ble.test.ts ported
/api/voice/sessions GET 25 call-recordings-load.test.ts ported
/api/voice/tool POST 122 flipper-ble.test.ts flipper-tools.test.ts graph-query.test.ts nicla-tools.test.ts nicla-voice-tools.test.ts unlearn-scope.test.ts ported (voice-tools)
/api/wallet/faucet POST 164 dev-keys.test.ts faucet-mint-not-a-deposit.test.ts faucet-no-answer.test.ts pay-deadline-above-route.test.ts x402-pay-route.test.ts tested (gated PAYMENTS_ENABLED; source suites green, DRIFT #28)
/api/wallet GET,POST 168 — tested (gated PAYMENTS_ENABLED; source suites green, DRIFT #28)
/api/wallet/withdraw POST 318 deadlines.test.ts dev-keys.test.ts pay-deadline-above-route.test.ts withdraw-settle-network.test.ts x402-pay-route.test.ts x402-settle-unknown.test.ts tested (gated PAYMENTS_ENABLED; source suites green, DRIFT #28)
/api/worker POST 74 limit-cost-routes.test.ts tested (limit-cost-routes)
/api/x402/chat/[slug] POST,GET 697 x402-credit-counterparty.test.ts x402-durability.test.ts x402-facilitator.test.ts x402-network-parity.test.ts x402-settle-unknown-record.test.ts x402-settle-unknown.test.ts x402-tiny-network.test.ts tested (gated PAYMENTS_ENABLED; source suites green, DRIFT #28)
/api/x402/pay POST,PUT 880 pay-deadline-above-route.test.ts x402-pay-route.test.ts x402-payer.test.ts x402-settle-unknown.test.ts x402-spend-reconcile.test.ts x402-spend-reverse-sent.test.ts tested (gated PAYMENTS_ENABLED; source suites green, DRIFT #28)

apps/worker — router endpoints (chatgpt-plugin-tinyai/src/index.ts)·

Method Path Handler Source module Status
POST /upsert UpsertCall upsert.ts ported (upsert-merge tested)
DELETE /tiny TinyDeleteCall delete.ts ported (delete-cascade test waits for retrieve.ts)
GET /get GetCall get.ts ported
GET /retrieve RetrieveCall retrieve.ts ported (tiny-delete-cascade tested)
POST /turns TurnStoreCall turns.ts tested (turns-memory)
GET /list ListCall list.ts ported
GET /legal LegalCall legal.ts tested (worker legal.test — brand from APP_URL, placeholder text)
GET /community CommunityCall community.ts ported
GET /profile ProfileCall profile.ts ported
POST /share ShareCreateCall share.ts ported
GET /share ShareGetCall share.ts ported
DELETE /share ShareDeleteCall share.ts ported
GET /share/list ShareListCall share.ts ported
POST /archive ArchiveCreateCall archives.ts ported
GET /archive/list ArchiveListCall archives.ts ported
GET /archive ArchiveGetCall archives.ts ported
DELETE /archive ArchiveDeleteCall archives.ts ported
GET /learnings LearningsListCall learnings.ts ported
POST /learnings LearningsAddCall learnings.ts ported
DELETE /learnings LearningsDeleteCall learnings.ts ported
GET /graph/neighbors GraphNeighborsCall learnings.ts ported (memory-graph tested)
GET /graph/all GraphAllCall learnings.ts ported (memory-graph tested)
GET /graph/conflicts GraphConflictsCall learnings.ts ported (memory-graph tested)
POST /graph/resolve GraphResolveCall learnings.ts ported (memory-graph tested)
POST /graph/social SocialRecordCall learnings.ts ported
GET /graph/social SocialGraphCall learnings.ts ported
POST /follow FollowCall learnings.ts ported
GET /graph/feed FeedCall learnings.ts ported
GET /reputation ReputationGetCall reputation.ts ported (reputation test waits for withdrawals.ts, R7)
POST /events EventsEmitCall events.ts ported
GET /events EventsListCall events.ts ported
POST /jobs JobsCreateCall scheduler.ts tested (scheduler, scheduler-cas, scheduler-ownership, job-cadence, job-abandoned, worker scheduler-callback)
GET /jobs JobsListCall scheduler.ts tested (scheduler, scheduler-cas, scheduler-ownership, job-cadence, job-abandoned, worker scheduler-callback)
DELETE /jobs JobsDeleteCall scheduler.ts tested (scheduler, scheduler-cas, scheduler-ownership, job-cadence, job-abandoned, worker scheduler-callback)
GET /push/key PushKeyCall push.ts ported (push-crypto tested)
POST /push/subscribe PushSubscribeCall push.ts ported
DELETE /push/subscribe PushUnsubscribeCall push.ts ported
POST /push/send PushSendCall push.ts ported (push-crypto, relay-notify tested)
GET /tools/browse ToolsBrowseCall tools.ts tested (worker tools-marketplace)
GET /tools ToolsListCall tools.ts tested (worker tools-marketplace)
POST /tools ToolsUpsertCall tools.ts tested (worker tools-marketplace)
DELETE /tools ToolsDeleteCall tools.ts tested (worker tools-marketplace)
POST /telegram/api TelegramApiCall telegram-api.ts ported
POST /telegram TelegramConfigCall telegram.ts ported
GET /telegram TelegramGetCall telegram.ts ported
DELETE /telegram TelegramDeleteCall telegram.ts ported
GET /prefs PrefsGetCall prefs.ts ported
POST /prefs PrefsSetCall prefs.ts ported
GET /model-config ModelConfigGetCall model-config.ts tested (worker model-keys)
POST /model-config ModelConfigSetCall model-config.ts tested (worker model-keys)
GET /model-providers ModelProvidersGetCall model-providers.ts tested (worker model-keys)
POST /model-providers ModelProvidersSetCall model-providers.ts tested (worker model-keys)
DELETE /model-providers ModelProvidersDeleteCall model-providers.ts tested (worker model-keys)
GET /account-voice AccountVoiceGetCall account-voice.ts tested (account-voice-write)
POST /account-voice AccountVoiceSetCall account-voice.ts tested (account-voice-write)
POST /device/enroll DeviceEnrollCall devices.ts tested (16 source test files)
POST /device/heartbeat DeviceHeartbeatCall devices.ts tested (16 source test files)
GET /device/list DevicesListCall devices.ts tested (16 source test files)
DELETE /device DeviceRevokeCall devices.ts tested (16 source test files)
POST /device/rotate-token DeviceRotateTokenCall devices.ts tested (16 source test files)
POST /device/event DeviceEventCall devices.ts tested (16 source test files)
POST /device/ask DeviceAskCall ask.ts tested (16 source test files)
POST /device/endpoint/call DeviceEndpointCallRoute devices.ts tested (16 source test files)
POST /firmware/publish FirmwarePublishCall firmware.ts tested
GET /firmware/current FirmwareCurrentCall firmware.ts tested
POST /firmware/device-current FirmwareDeviceCurrentCall firmware.ts tested
POST /transcript TranscriptAddCall transcripts.ts tested (transcripts-sql)
GET /transcript/list TranscriptListCall transcripts.ts tested (transcripts-sql)
GET /transcript TranscriptGetCall transcripts.ts tested (transcripts-sql)
POST /location/heartbeat LocationBeatCall locations.ts tested (locations-sql)
GET /location/list LocationsListCall locations.ts tested (locations-sql)
DELETE /location LocationDeleteCall locations.ts tested (locations-sql)
POST /device/relay/send RelaySendCall relay.ts tested (16 source test files)
POST /device/relay/poll RelayPollCall relay.ts tested (16 source test files)
POST /device/relay/reply RelayReplyCall relay.ts tested (16 source test files)
GET /device/relay/recv RelayRecvCall relay.ts tested (16 source test files)
POST /device/relay/deposit RelayDepositCall relay.ts tested (16 source test files)
POST /device/task-result RelayTaskResultCall relay.ts tested (16 source test files)
GET /pay/balance PayBalanceCall payments.ts tested (gated PAYMENTS_ENABLED; 12 source suites + payments-gate)
POST /pay/invoke PayInvokeCall payments.ts tested (gated PAYMENTS_ENABLED; 12 source suites + payments-gate)
POST /pay/transfer PayTransferCall payments.ts tested (gated PAYMENTS_ENABLED; 12 source suites + payments-gate)
POST /pay/refund PayRefundCall payments.ts tested (gated PAYMENTS_ENABLED; 12 source suites + payments-gate)
POST /pay/price PayPriceSetCall payments.ts tested (gated PAYMENTS_ENABLED; 12 source suites + payments-gate)
GET /pay/pricing PayPricingCall payments.ts tested (gated PAYMENTS_ENABLED; 12 source suites + payments-gate)
POST /pay/credit PayCreditCall payments.ts tested (gated PAYMENTS_ENABLED; 12 source suites + payments-gate)
POST /pay/spend PaySpendCall payments.ts tested (gated PAYMENTS_ENABLED; 12 source suites + payments-gate)
POST /pay/spend-sent PaySpendSentCall payments.ts tested (gated PAYMENTS_ENABLED; 12 source suites + payments-gate)
POST /pay/spend-reverse PaySpendReverseCall payments.ts tested (gated PAYMENTS_ENABLED; 12 source suites + payments-gate)
POST /pay/settle-unknown PaySettleUnknownCall payments.ts tested (gated PAYMENTS_ENABLED; 12 source suites + payments-gate)
GET /pay/reconcile-status PayReconcileStatusCall payments.ts tested (gated PAYMENTS_ENABLED; 12 source suites + payments-gate)
POST /pay/link-address PayLinkAddressCall deposits.ts tested (gated PAYMENTS_ENABLED; 12 source suites + payments-gate)
POST /pay/claim PayClaimCall deposits.ts tested (gated PAYMENTS_ENABLED; 12 source suites + payments-gate)
GET /pay/deposit-info PayDepositInfoCall deposits.ts tested (gated PAYMENTS_ENABLED; 12 source suites + payments-gate)
POST /pay/faucet PayFaucetCall deposits.ts tested (gated PAYMENTS_ENABLED; 12 source suites + payments-gate)
POST /pay/withdraw-request WithdrawRequestCall withdrawals.ts tested (gated PAYMENTS_ENABLED; 12 source suites + payments-gate)
POST /pay/withdraw-complete WithdrawCompleteCall withdrawals.ts tested (gated PAYMENTS_ENABLED; 12 source suites + payments-gate)
POST /pay/withdraw-fail WithdrawFailCall withdrawals.ts tested (gated PAYMENTS_ENABLED; 12 source suites + payments-gate)
GET /ring RingGetCall ring.ts ported
POST /ring RingAddCall ring.ts ported
POST /visit VisitCall visit.ts ported
POST /media/upload MediaUploadCall media.ts tested (16 source test files)
GET /media/:key MediaGetCall media.ts tested (16 source test files)
POST /device/tool-result ToolResultPostCall media.ts tested (16 source test files)
GET /device/tool-result ToolResultGetCall media.ts tested (16 source test files)
POST /voice/session (inline → voice.ts) voice.ts tested (voice-recording-range/gaps, voice-teardown-monotonic, media-retention-manifest)
GET /voice/connect/:id (inline → voice.ts) voice.ts tested (voice-recording-range/gaps, voice-teardown-monotonic, media-retention-manifest)
POST /voice/reap/:id (inline → voice.ts) voice.ts tested (voice-recording-range/gaps, voice-teardown-monotonic, media-retention-manifest)
GET /voice/recording/:id (inline → voice.ts) voice.ts tested (voice-recording-range/gaps, voice-teardown-monotonic, media-retention-manifest)
GET /voice/sessions VoiceSessionsListCall voice.ts tested (voice-recording-range/gaps, voice-teardown-monotonic, media-retention-manifest)
GET /voice/session VoiceSessionGetCall voice.ts tested (voice-recording-range/gaps, voice-teardown-monotonic, media-retention-manifest)
GET /voice/replay/:id/:file (inline → voice.ts) voice.ts tested (voice-recording-range/gaps, voice-teardown-monotonic, media-retention-manifest)
POST /message MessageSendCall messages.ts tested (16 source test files)
POST /device/messages DeviceMessagesCall messages.ts tested (16 source test files)
GET /messages MessagesListCall messages.ts tested (16 source test files)
GET /message/unread MessagesUnreadCall messages.ts tested (16 source test files)
DELETE /message MessageDeleteCall messages.ts tested (16 source test files)
POST /user/upsert UserUpsertCall users.ts ported (users.ts verbatim; credential-binding tested)
GET /user/get UserGetCall users.ts ported (users.ts verbatim; credential-binding tested)
POST /credential/add CredentialAddCall users.ts ported (users.ts verbatim; credential-binding tested)
GET /credential/list CredentialListCall users.ts ported (users.ts verbatim; credential-binding tested)
POST /credential/signcount CredentialSignCountCall users.ts ported (users.ts verbatim; credential-binding tested)

apps/worker — non-HTTP entry points·

Entry What Status
scheduled (cron * * * * *) runDueJobs, pollTelegramBots, sweepToolUpdates, LOCATION_SWEEP_SQL, reconcileSentSpends, reconcileSettleUnknown, sweepReconcileAlarm ported — runDueJobs, LOCATION_SWEEP, pollTelegramBots, sweepToolUpdates + (PAYMENTS_ENABLED) reconcileSentSpends, reconcileSettleUnknown, sweepReconcileAlarm; was: partial — runDueJobs + location sweep + pollTelegramBots + sweepToolUpdates wired; payments reconciler lands with R8
email Email Routing: forwards <slug>@ to the tiny's customer email; hardcoded CF account id + owner fallback address → must become env tested — src/email.ts, EMAIL_OWNER_FORWARD / CLOUDFLARE_ACCOUNT_ID+TOKEN (DRIFT #30), 9 tests
Durable Object VoiceSession live voice call relay (OpenAI Realtime ⇄ client), journals to R2 + D1 ported (voice.ts verbatim; placeholder class removed; wrangler dry-run bundles)

Skipped census tests (self-activating)·

Some source tests are cross-surface censuses: they read other files' source text. Where the file is not ported yet, the it is it.skipIf(!has('<path>')) and turns on by itself when the path appears. its that read ios/ or android/ are dropped — this template has no mobile apps. Current skips: 23 (voice-teardown-monotonic 3 [mobile + app/calls page], memory-list 5, learnings-delete-scope 2, unlearn-scope 6, dm-send 1, graph-query 1, page-code-trust 5, relay-send 3 (censused by it.skipIf; see npx vitest run --reporter=verbose | grep skipped for the live list), job-cadence 3) waiting on components/chat/MemoryPanel.tsx, components/chat/JobsPanel.tsx, lib/chat/slash-commands.ts, app/api/voice/tool/route.ts (R7/R9).

Chat runtime libs (R5)·

lib status
lib/bedrock-edge.ts, lib/chat/model.ts ported verbatim; tests bedrock-eventstream, chat-helpers (additional-fields waits on components/chat/ModelSettings)
lib/chat/helpers.ts, events.ts, tool-filter.ts, page-code-trust.ts, graph-query.ts ported verbatim; tests green (page-code-trust/graph-query wiring its skip until chat route, Chat.tsx, strands-events, voice/tool land)
lib/chat/relay-send.ts, dm-send.ts, dm-attachments.ts ported; MEDIA_ORIGINS = TINY_WORKER_URL only (tinyai-id also pinned its production host); relay-send caller census skips until nicla/flipper/platform/devices-relay land
lib/chat/prompt.ts ported; site host via APP_URL (siteHostName()); Android-app sentence dropped
lib/chat/tools/universe.ts, messages.ts, memory.ts, client-side.ts ported; worker URL via lib/config (lazy WORKER()); tests universe-tools, dm-media-tools, dm-send, graph-query, unlearn-scope
lib/utils.ts (full), tools/http.ts ported; parseOpenAPI default worker from TINY_WORKER_URL; tests utils, parse-openapi, http-tool
lib/chat/tools/platform.ts, spawn.ts, nicla.ts, nicla-voice.ts, flipper.ts ported; WORKER = workerUrlOrPlaceholder() (module-scope, build-safe); run-tool proxy needs NEXT_PUBLIC_APP_URL; tests device-media, platform-tools, spawn-async, nicla-tools, use-device-endpoint (worker relay/devices census skips until R6)
lib/deadlines.ts, lib/x402/* (8 files: tiny-chain, facilitator, payer, top-up, wallet-client, explorer, faucet-countdown, use-faucet-countdown), lib/chain/* (5: rpc, status, join, calldata, explorer-core) ported verbatim (env-only config: TINY_CHAIN_ID/RPC_URL/USDC_ADDRESS/EXPLORER_URL, PAYMENTS_NETWORK); tests top-up, chain-explorer, explorer, faucet-countdown, wallet-client, x402-quote-copy green (109); deadlines/chain-calldata/chain-identity/x402-facilitator/x402-payer/x402-tiny-network wait for the web money routes + chain/ + app/chain pages
app/api/chat/route.ts, app/api/chat/tool-result ported; 44 worker URLs → ${WORKER}, prompt links → APP_URL/request origin, install_tool allowlist → TOOL_REPO_ALLOWLIST env; lib/x402/tiny-chain.ts (env-only) ported for paymentsNetwork

Dependency layout note: the web app needs zod 4 + openai 6 (peer of @strands-agents/sdk) while the worker's itty-router-openapi needs zod 3 + openai 4. Root devDependencies pin zod@4 / openai@6 so npm hoists those and nests the worker's versions under apps/worker/node_modules — verified by a local wrangler dev smoke (/health, /list, /community, /events, /push/key) after d1 migrations apply --local (all 34 apply clean).

| lib/voice/* (live, outcome, platform, playback, realtime, tools, tts, vad) + components/chat/voice.ts | ported verbatim; tests tts-chunk, vad, voice-platform, voice-tools green |

UI surface (R9)·

slice files status
R9a shell tailwind.config.js, postcss.config.js, app/globals.css, app/layout.tsx (+ lib/site.ts), components/{theme-provider,TinyLogo,SiteHeader,MapToggle,GlobalMapBackdrop,MapBackground,Analytics}.tsx, lib/{theme,map-pref,geo,relative-time,relative-tick,use-relative-tick}.ts, lib/chat/{whoami,session-expiry,auth-events}.ts, app/{loading,error,global-error}.tsx, app/{manifest,robots,sitemap}.ts, app/icon.png, public icons ported; constants → env (DRIFT #31, #32); next build + next start verified (title/og/robots/sitemap/manifest from env, CSS 200); tests theme, geo, relative-*, session-expiry, auth-events (chat censuses self-activate)
R9b chat surface components/chat/* (Chat.tsx closure: 73 files incl. lib/chat client libs, lib/{community,file-attachments,model-pricing,model-registry,sse,webllm}, lib/public-config.ts), app/page.tsx (real home + A2HS QR), app/not-found.tsx ported verbatim; 8 browser-side worker/host constants → env (DRIFT #33); 69 upstream test files added (2849 pass / 10 skip); iOS/Android parity blocks dropped (render-ui-fallback, spawn-tree-states, tiny-read-degrade), R9c censuses self-activate (wallet/[slug]/Universe sinks); next build + headless Chrome render of / (desktop + 390px): onboarding, hero, composer, header, 0 page errors
R9c pages app/[slug] (+loading), about, auth/cli, calls, chain (+ui, lookup, address/[addr], tx/[hash]), devices, map, og/[slug], universe (+loading, opengraph-image), vcard/[slug], voice, wallet, wearables (+handoff); components/{Community,FollowButton,Profile,ProfileToolCard,ProfileTools,UniverseDirectory}; lib/devices/revoke-message ported verbatim (30 files); ~60 brand/origin/worker constants → env (DRIFT #34); 11 upstream test files added (native-client cases dropped, DRIFT #35); R9b's dormant censuses (wallet/[slug]/Universe sinks) now active: 189 files, 2936 pass / 5 skip; next build 24 static + all dynamic pages; next start curl of 15 routes 200 (vcard of an unknown tiny 404) with zero tiny.technology/@tinyaid/say.jpeg leakage; headless Chrome /about /universe /wallet /devices /chain /[slug]: 0 page errors

R10 — fresh-deploy proof (in progress)·

Step Status
Cloudflare storage under tiny-vercel-* via scripts/bootstrap-cloudflare.mjs DONE 2026-09-15 08:21Z — 3 KV, D1, 2 Vectorize (+2 metadata indexes), R2; idempotent re-run reuses all 7; ledger docs/PROVISIONED.md
D1 schema DONE — all 36 migrations applied remotely (39 tables)
Worker deployed DONE — https://tiny-vercel-worker.cagatay.workers.dev (version ee095c84); smoke: /health ok, /get not-exists sentinel, /community empty, /pay/* 404 payments-disabled JSON, /upsert schema-validates
Scratch Vercel project (D-004) DONE 2026-09-15 08:33Z — tiny-vercel-scratch (team cagataycali-s-team, rootDirectory apps/web, 10 production env vars, deployed from the CLI in 2m). https://tiny-vercel-scratch.vercel.app: all pages 200, /api/health workerConfigured+appUrlConfigured, /api/events 401, payments 404-off, unknown slug renders "Create an AI named …" exactly like production, anonymous /api/chat streams a full SSE agent turn through the fresh worker (pong, 14 events, [DONE]). Worker APP_URL re-pointed at the scratch origin and redeployed (version a9cee71b)
GitHub OAuth App (sign-in path) BLOCKED on owner — D-010; anonymous surface proven, authenticated surface (create tiny, passkey, devices, memory) waits for the OAuth app
docs/DEPLOY.md walkthrough, README Deploy button, docs/VERCEL_TEMPLATE.md checklist DONE 2026-09-15 09:02Z — README button (root-directory=apps/web, 10 env keys, envLink→DEPLOY.md, demo card), apps/web/vercel.json (monorepo install/build + maxDuration 300 for /api/chat) proven by a fresh CLI production deploy (f37eoobja, ready in 1m, cd ../.. && npm ci 926 pkgs), VERCEL_TEMPLATE.md against the live submit form + deploy-button docs (charter URL 404s, noted)
Sample endpoint device (charter rule 8) DONE 2026-09-15 09:40Z — examples/echo-device (zero-dep server.mjs + enroll.mjs + 7 node:test cases, in root npm test). PROVEN live against the scratch deployment through a Cloudflare quick tunnel: enroll → device 6d5d1ded listed as endpoint with url; /api/devices/endpoint telemetry 200 + snapshot 200 image/png 89B; /api/devices/endpoint/chat 200; and a real /api/chat agent turn used use_device and answered with the device's actual uptime + Node version. Session for the proof was an operator-minted CLI-shaped JWT (own AUTH_JWT_SECRET) since GitHub OAuth is D-010; the browser consent path in enroll.mjs is untested until then
Teardown rehearsal DONE 2026-09-15 10:35Z — run TWICE: teardown 9s (exactly the 8 prefixed rows; 6 production KV ids and the Vercel project verified untouched by before/after listings), bootstrap+migrate 19s, secrets+deploy 14s = 33s to a serving worker at the same name-based URL; app needed no change. Fresh D1 proven (ids restart at 1), Vectorize recall after ~20s, full /api/chat turn recalled the new memory. Found+fixed: first run left the worker in the ledger although it was gone → teardown now re-lists on non-zero exit and logs every delete to .cloudflare-teardown.log. docs/DEPLOY.md “Rehearsed” section
R1–R9 re-verification on the REBUILT stack (charter rule 10) DONE 2026-09-15 11:30Z — local: web 2936 passed/5 skipped, worker 122, echo-device 7, exit 0. Live against fresh D1/KV/Vectorize: R3 /api/me 401→200 with JWT, cli/token bad code 401, passkey login validation, logout; R5 chat turn (math) + tool use; R6 devices: echo device enrolled through a quick tunnel → telemetry 200, snapshot image/png, agent use_device ×3 answered real uptime, events/messages/jobs/push 200, revoke ok; R7 user row via /user/upsert (what the OAuth callback does — D-010 still means no browser sign-in) → create tiny via /api/control → /api/me lists it, public config read active:true, chat honours its system prompt ("REHEARSAL Hi there!"), /community lists owner+tiny, /retrieve (Vectorize) finds it with scratch-app URLs, share create/read/revoke, graph social, archives, voice sessions, /api/delete → active:false; R8 every payments route answers the 404 "payments disabled" hint; R9 /, /devices, /<tiny>, /tiny?share= 200. One inherited footgun found → D-011.

cli — apps/cli (npx tiny-vercel, ported from tiny-tech@0.13.7 @ b8b9397)·

Inventory: docs/CLI.md. Rungs per the charter's CLI addition; status values as above plus proven (exercised against the live scratch deployment).

Rung Scope Status
C1 inventory commands, 72 modules / 28,579 lines, 54 tiny.technology refs with file:line, 72 env vars, 61 test files, web-vs-worker reach (27 web routes all present; 3 public worker reads + 1 media allowlist) DONE 2026-09-15 18:05Z — docs/CLI.md; DRIFT #36 (/api/wallet/balance)
C2 skeleton + verbatim port apps/cli in the repo, tsc build, 61 test suites green, root CI runs it DONE 2026-09-15 18:05Z — 152 files copied verbatim (src, test, menubar, tsconfig); tsc clean in 2.3s; node --test 1432/1432 pass in 17s; root npm test/typecheck call it via --prefix apps/cli; CI installs both lockfiles. NOT a hoisted workspace member: the web app pins React 18.2.0 and Ink 7 needs React ≥19 — hoisting put Ink next to React 18 and import('ink') failed at runtime (useEffectEvent missing), so the CLI keeps its own package-lock.json (D-012). gitleaks: 4 secret-shaped test fixtures (scrubber + OpenAPI auth tests) allowlisted by exact value/file
C3 one config --api → TINY_API_URL → ~/.tiny/config.json → prompt; tiny-vercel init <url>; worker URL derived from <app>/api/health; 54 refs → 0; gitleaks clean DONE 2026-09-15 18:27Z — src/config.ts (resolution, init, /api/health probe, worker discovery + cache, ConfigRequiredError off-TTY), 12 new tests; apps/cli now has 0 tiny.technology refs in src/test/menubar/README (from 54+29+3+7); launchd label technology.tiny.daemon → dev.tiny-vercel.daemon; bin/prose tiny-tech → tiny-vercel; the ONE web change: /api/health adds siteName + workerUrl (public origin the browser bundle already ships; null when unset) + 3 tests; tray status gains webUrl so the menu bar opens the configured app; server tests run against a loopback fake deployment instead of the operator's prod worker. 1445/1445 CLI tests, Swift suite green, gitleaks clean
C4 live proof init https://tiny-vercel-scratch.vercel.app → CLI-token login (operator JWT, D-010) → enroll this Mac → heartbeat on /devices → use_device round-trip from the scratch web agent answering a real shell question; recorded in docs/EVIDENCE.md DONE 2026-09-15 18:42Z — scratch redeployed with the health change; init derived the worker; login ran the REAL loopback + code-exchange path (the consent click reproduced with an operator session because D-010 leaves no browser sign-in) → credentials.json + device.json; daemon heartbeat → /api/devices shows online:true with 18 capabilities; web agent use_device invoke → this Mac ran cat /tmp/tv-proof-335ad3a4.txt && uname -m && sw_vers -productVersion → tiny-vercel-proof-335ad3a4 / arm64 / 26.4.1 came back in the chat (22 s). Device revoked, temp home + JWT deleted. docs/EVIDENCE.md
C5 packaging npm pack listing, npm publish --dry-run, startup time + size in docs/EVIDENCE.md; owner asked ONCE about publishing tiny-vercel@0.1.0 DONE 2026-09-15 18:50Z — tarball 425.5 kB / 1.4 MB / 75 files (dist + package.json + README), gitleaks clean, 0 brand refs; fresh install 3.1 s → working tiny-vercel bin; help 0.08 s, init 0.21 s, MCP initialize 744 ms. npm publish --dry-run OK; name free (404). Owner asked once via dialog (240 s) — no answer → publish DEFERRED (D-013). Also: this Mac has no npm login (E401), so publishing needs the owner's npm login anyway
C6 docs README + docs-site page "CLI: npx tiny-vercel"; this section at 100% DONE 2026-09-15 19:05Z — README § "CLI — npx tiny-vercel" + apps/cli row in Shape + Devices table repointed; docs site start/cli.md (nav under Get started, card on the start page), ledgers CLI.md + EVIDENCE.md linked from Reference; every user-facing npx tiny-tech in README/docs → npx tiny-vercel; mkdocs build --strict clean

cli parity: 13 / 13 commands ported · 61 / 61 source test files green (+ config.test.mjs) · 54 / 54 constants removed · 100%

Commands (13)·

Command Source Status
login / logout / whoami / devices cli.ts, auth.ts, api.ts proven live (EVIDENCE § C4 steps 3–4); auth/api/device suites tested
init <url> (NEW — the one config) config.ts proven live (step 1); 12 tests
connect [app] / onboard [status] / sync integrations.ts, onboard.ts, tui/onboard-app.tsx tested (integrations, integrations-store, onboard suites); login printed the onboard hint live
serve (MCP stdio) server.ts tested (server, server-device suites against a loopback deployment; initialize 744 ms measured)
tui / repl / one-shot / (none) agent/, tui/ tested (agent, tui, conversations, layout, components, voice-call, realtime, speech, human-type, markdown suites); interactive TUI not driven in this lane
daemon install\|show\|status\|logs\|restart\|uninstall daemon.ts tested (daemon suite: unit/plist rendering with the new label); not installed on the proof machine (it already runs the owner's production daemon)
mesh [peers\|send\|broadcast] (enroll + heartbeat + relay) mesh/*, device.ts proven live (steps 5–7: heartbeat online, use_device round-trip); mesh, mesh-registry, relay-poller, device suites tested
tray <action> + menubar/ Swift client tray.ts, menubar/ proven live (step 8: tray status + webUrl on the socket); tray, tray-notify suites + swift test green