Unreleased#
- Public try page (
router/http/public.mjs,panel/try/, opt-inELYRA_PUBLIC_TRY=1): signed-out visitors of the admin hostname get a real streamed chat on the node's local model, never a peer, hosted key or simulated answer; per-client hourly limit, daily cap, concurrency cap, strict CSP. Tests:router/test/public.test.mjs. - Wallet connect (Reown AppKit,
ELYRA_REOWN_PROJECT_ID): fund the escrow from your own wallet (depositForthe node address). Bundle built bytools/wallet/. Tests:router/test/fund.test.mjs. - Control panel restyled as a plain product dashboard; sign-in page and sign-out button for remote admin.
- Routing fix: a live listing now always beats the simulated market within a request (
plan()). Before, after connecting Ollamamodel: autowas still answered by a simulated peer with canned text. Seedocs/DECISIONS.md. Tests:router/test/market.test.mjs. - Opt-in remote admin (
router/http/remote.mjs,ELYRA_ADMIN_HOST+ELYRA_ADMIN_TOKEN): the real panel,/apiand/v1on one named host behind a login (signed cookie, rate limits, CSRF check, proxied traffic never gets the localhost path,/metricsnever). Off by default; loopback rules otherwise unchanged. Tests:router/test/remote.test.mjs(11). Docs:docs/REMOTE-ADMIN.md. - Remote admin login page:
Referrer-Policy: same-origin(wasno-referrer, which made Chrome sendOrigin: nulland the login was refused). Regression test added (12 tests inremote.test.mjs). - Panel UX: next-step banner on Overview (connect a real model / hide the simulated market), one-click Ollama detection from Overview, "connected" card in Connect, live models first in the Playground with an honest empty state and a wait indicator for cold model loads, tidier result badges. Mobile: fixed grid minimum widths that pushed every card past the screen (0 overflowing elements in all 8 views at 390 px), topology graph scrolls inside its box.
- Test
router/test/panel.test.mjs: every panel module must parse and every relative import must resolve to an export (the panel has no build step, so nothing else catches this). - Open-source readiness:
LICENSE(MIT, matching the contract SPDX headers),SECURITY.md,CONTRIBUTING.md, rewrittenREADME.md; new docsINSTALL,OLLAMA,USAGE,CONFIGURATION,DEPLOY-CLOUDFLARE, and a docs index. - Cloudflare Pages:
tools/pages/renders the landing + docs intodist/;wrangler.toml;.github/workflows/deploy-pages.yml./app/*redirects to the install guide because the panel needs a local router. - Static demo removed.
/app/on the website redirects to the live node at app.elyrainference.com. - New docs:
PANEL,API(control API reference),PROVIDER,FAQ,GLOSSARY. - Pages bundle ships a
404.html(otherwise Pages answers unknown paths with 200 and the landing). First live deploy:elyra-5cg.pages.dev. - Tests: node boot wait raised from 5 s to 30 s (router, TEE) and the encryption-at-rest test now stops each child once the boot banner is printed instead of after a fixed 4 s. On a loaded host boot took 4.5 s and tests failed spuriously. No runtime change.
0.2.0 — 2026-11-04#
Architecture (2026-11-06)#
- Repo restructured:
vpr/→router/,app/→panel/, landing mirror →site/. URLs unchanged (/,/app/). router/node.mjs(920 lines) split intorouter/core/(+consumer/,provider/),router/http/(route table per surface),router/lib/;router.mjsrenamedpolicy.mjs. No wire, API or on-disk format change; the 47 tests are unchanged.- Panel
app.js(735 lines) split into ES modules (lib/,components/,views/,css/); more remote strings escaped; dead code removed. - Added
docs/LANDSCAPE.md(competitors and reusable repos),docs/VPS.md(seller node on a VPS),docs/HANDOFF.md(agent onboarding) anddocs/REGISTRY.md(discovery design, not built).
Rename (2026-11-06)#
- New logo: supplied "E" mark everywhere (app, favicon, landing header/footer) and the 3D hero + token models regenerated from it (
tools/brand/). - Solais → Elyra everywhere (see docs/STATUS.md → Naming). Wire-breaking: PROTOCOL 3,
ElyraEscrowredeployed + verified on Robinhood testnet,ELYRA_*env vars,.elyradata dir (legacy.solaisadopted).
TEE (2026-11-05)#
- Real attestation verification for Google Confidential Space (
router/tee.mjs), buyer-pinned image digests,VERIFIEDvsCLAIMED, stricterteeOnly, TEE-mode seller (attestation in hello, local upstreams only), payout sweep, boot env config, redeem on shutdown,deploy/tee/kit,docs/TEE.md. Breaking for routing: self-declared and demo TEE no longer count as private.
Roles (2026-11-05)#
- Overview onboarding for buyers and sellers, seller Earnings panel (
earnDailyin/api/ledgerstats), app talks to its own origin on any port, no-store for app assets, landing marks 600+/150+ as a launch target.
Security review fixes (2026-11-05)#
- Found while testing live: vouchers are bound to the escrow they were signed for; the voucher baseline is
max(local cumulative, on-chain claimed) + amount(provider mirrors it). Mainnet-fork rehearsal script (npm run rehearse:mainnet) and its report. - Receipts are validated strictly and the amount is derived locally; vouchers must be canonical 65-byte signatures; provider credit is keyed by wallet with a fail-closed on-chain deposit check, worst-case admission control (
max_tokenscapped at 8192) and auto-redeem; requests are ed25519-authenticated with replay protection; wallet control is proven (EIP-191); voucher pushes are sealed; settlement is per-wallet and fault tolerant. Escrow v2: withdraw requests are single-use and expire (7 days). Seedocs/STATUS.mdfor the finding table.
Operations#
- Protocol version negotiation (
PROTOCOL = 2, mismatch refused with a clear error,x-elyra-protocolheader), Prometheus/metrics,/healthz, structured JSON logs, GitHub Actions CI. Tests: metrics never contain prompt text; old-protocol peers are refused.
USDG settlement (supersedes the ETH design below)#
- Deployed and exercised on Robinhood Chain Testnet: MockUSDG + ElyraEscrow verified on Blockscout; two-node paid trade settled on chain (addresses and tx hashes in
docs/STATUS.md). ElyraEscrow(token)is ERC-20:deposit(amount)/depositFor, balance-delta check, safe transfers;MockUSDGfor testnet/local (open mint, labelled). Amounts are token units (USDG 6 decimals) = dollars × 1e6: no oracle, nousdPerEth. Receipts carryamountUnits.router/net.mjs: DoH resolver so Robinhood hosts work behind DNS-hijacking ISPs; chain ids verified live.- Deploy:
npm run chain:deploy:testnet(uses the node wallet). Panel: token/balances, mint (mock only), approve+deposit.
Added#
- On-chain settlement for Robinhood Chain (Arbitrum Orbit, ETH gas):
contracts/ElyraEscrow.sol(deposit, cumulative EIP-712 vouchers, redeem, delayed withdraw; 12 hardhat tests),router/chain.mjsadapter, consumer vouchers after every verified receipt, provider credit limit and escrow-funding check,/api/chain*, Payments → Escrow panel, explorer links. Verified end to end against a local EVM (router/test/chain.test.mjs). Not yet exercised on the live Robinhood testnet (RPC unreachable from the dev machine). - Sealed transport (protocol v2): prompts and completions encrypted to the provider's X25519 key; unsealed requests refused.
- Token-inflation audit: receipts claiming far more output tokens than the received text are rejected.
- SSRF guard for gossip-learned peers, per-consumer rate limit, deny list, startup re-contact of remembered peers, wallet/box-key binding in hello.
- Landing: legal pages, removed agency trackers/socials, honest TEE wording.
Network view#
- Rebuilt: ring topology (live / bridge / community), vendor logos on bridge nodes, animated packets on recent routes, hover tooltip, click-for-detail with per-peer model table and TRY, filters, stat tiles.
Fixed#
- Hosted upstreams (OpenRouter, OpenAI, …) are no longer labelled LOCAL/private: they show
HOSTED · CLEAR, score 0 on privacy, and are excluded byteeOnly/auto:private. Only localhost/LAN upstreams count as local.
Security#
- Optional encryption at rest via
ELYRA_PASSPHRASE(router/vault.mjs), tested (encrypted files, same identity across restarts, refuses without/with wrong passphrase).
Blockscout#
contracts/verify.mjs(+artifacts/standard-input.jsonfrom the build), explorer address links and a verified-source badge in Payments. Tip: if the primary RPC is down, a Blockscout instance may serve JSON-RPC at<explorer>/api/eth-rpc; paste it as the RPC override.
Changed#
- Receipts now carry
amountWei/providerWalletin chain mode./p2p/inferbody is{from, sealed}. - Node address is now the real secp256k1 wallet (was a derived placeholder). Runtime dependency:
ethers. - Client hang-ups no longer count as peer failures.
0.1.0 — 2026-11-04#
Added#
router/: Virtual Private Router daemon. OpenAI-compatible endpoint, policy ranking, failover, ed25519 signed receipts, peer gossip, provider mode, ledger + simulated-testnet settlement, loopback-only control API, static hosting of site and panel.panel/: control panel rewritten in the landing's visual language (indigo gradient, paper surface, NB Architekt, bracketed cards). Views: Overview, Playground, Models, Routing, Network, Payments, Provide, Connect. Provider/model logos fromassets/logos.- Simulated demo market (labelled) so routing works on a fresh install.
npm test: ranking rules + two-node integration (billing equals receipt, streaming, price-bait refusal, TEE-only, local-only API).AGENTS.md,PRD.md,ROADMAP.md,docs/.
Changed#
- Landing copy, meta, 3D labels and dashboard image rewritten from "AI visibility analytics" to "peer-to-peer AI inference".
Removed#
server.mjsandstart-mirror.bat(superseded byrouter/server.mjs,start.bat).