Runtime

Secure Browser-to-Companion Protocol for Local Inference and Direct P2P

Report summary

This report treats the uploaded specification as the controlling scope: an HTTPS TinyRustLM browser client must communicate with an independently installed Rust/.NET companion for .slm import, local inference, and direct peer-to-peer model transfer, while ensuring that project sites do not receive p

Status
Research archive item
Category
Runtime
Length
7,685 words
Reading time
35 minutes
Report type
evaluation

Key topics

  • Runtime
  • AI
  • .NET
  • Rust
  • Privacy
  • Semantic Systems
  • Research Archive
  • Audit

Research provenance

Archive status
Research archive item
Content identity
sha256:3c80f14422a7cb3996617db39afd9b07541912a3147579fe2bb4e0f0de44f339

For citation, use the report title and canonical URL. Archival presence does not establish authorship or promote report statements into portfolio evidence.

Source availability: 41 citation markers in the source export have no recoverable source links. Those markers are omitted from this reader; any supplied bibliography and ordinary links remain. Check the original sources before relying on the cited claims.

This page renders the archived Markdown as safe, formatted HTML. It is background research and does not become a portfolio claim without evidence review.

Full report

On this page

Executive protocol recommendation

Scope, evidence labels, and assumptions

This report treats the uploaded specification as the controlling scope: an HTTPS TinyRustLM browser client must communicate with an independently installed Rust/.NET companion for .slm import, local inference, and direct peer-to-peer model transfer, while ensuring that project sites do not receive prompts or model bytes and that publication, administrative, catalog, MemoryEndpoints, and P2P-signing credentials do not cross into page JavaScript.

The following labels distinguish evidence from design:

LabelMeaning
Public factDirectly observable from published standards or vendor documentation
InferenceA conclusion drawn from multiple public facts
RecommendationThe proposed TinyRustLM first-release design
AssumptionA premise not yet verified against private implementation
Verification requiredA fact that needs authorized code, package, host, browser, or network access

The report assumes the production web origin is exactly https://tinyrustlm.com, with no alternate www, preview, or staging origins sharing production pairing authority. It assumes the companion can display trusted native UI, maintain per-user protected state, and expose separate loopback control and non-loopback P2P processes. It does not assume anything about existing routes, ports, certificates, .slm structure, package signatures, logging configuration, model-runtime cancellation behavior, or P2P key handling.

Recommendation: use one protocol only:

HTTP/1.1 Fetch over numeric loopback, with response streaming, origin-bound interactive pairing, short-lived proof-of-possession session keys, application-layer authenticated encryption, strict CORS, and no cookies.

The page connects only to:

http://127.0.0.1:43191–43198
http://[::1]:43191–43198

Port 43191 is primary; 43192 through 43198 are ordered collision fallbacks. These are proposed product-private values and must receive a final collision and packaging review before release. The companion must bind 127.0.0.1 and, where available, ::1 using separate sockets. It must never bind the control protocol to 0.0.0.0, ::, a hostname, a LAN address, or an interface selected through DNS.

Loopback IP literals are classified as potentially trustworthy by the Secure Contexts algorithm, and potentially trustworthy local URLs are treated differently from ordinary insecure mixed content. That browser affordance is not authentication: the Secure Contexts specification itself warns that secure-context isolation is incomplete and that localhost name resolution can be unreliable. Chrome additionally gates public-to-loopback requests behind Local Network Access permission; this began for Fetch in Chrome 142 and expanded to WebSocket and WebTransport in Chrome 147.

The browser uses ordinary fetch() for control requests and ReadableStream response bodies for generation. Fetch supports incremental response consumption and abort-driven cancellation, while the classic WebSocket API does not provide backpressure and can accumulate buffered data faster than an application processes it.

Because HTTP loopback is plaintext, sensitive bodies and generation events are encrypted at the application layer after pairing:

  • P-256 ephemeral ECDH for each browser session.
  • HKDF-SHA-256 for independent request-encryption, response-encryption, request-MAC, response-MAC, and rekey keys.
  • AES-256-GCM for request payloads and individual streaming events.
  • HMAC-SHA-256 over canonical HTTP semantics for early authentication and anti-replay.
  • A transcript-bound companion identity signature using a per-install P-256 identity key protected outside browser storage.

HKDF is designed to derive multiple cryptographically strong keys from source key material such as a Diffie–Hellman result. HTTP Message Signatures provides a useful model for covering method, target, authority, content digest, creation time, and expiration, while also warning that signatures alone do not provide confidentiality; the proposed protocol therefore adds AEAD rather than relying on MACs alone.

flowchart LR
    W[TinyRustLM HTTPS page] -->|Fetch + strict CORS\nHMAC + encrypted bodies| L[Loopback control plane]
    L --> I[Isolated inference worker]
    L --> S[Content-addressed model store]
    L --> P[P2P status interface]
    P --> Q[Separate P2P process]
    Q <-->|Direct encrypted model transfer| R[Remote peer]

    W -.->|Catalog and discovery metadata only| M[MiniModel.org]
    W -.- X[No prompts or model bytes]
    M -.- X

Principal design decisions

DecisionFirst-release positionReason
Control transportHTTP/1.1 Fetch on numeric loopbackBroad browser support, streaming responses, abort support, no local CA
ConfidentialityApplication-layer AEADLoopback and local HTTP are not equivalent to an authenticated private channel
DiscoveryEight-port bounded probe, public-safe descriptor onlyBrowser cannot directly read OS IPC or a local descriptor file
PairingNative-UI approval with transcript short-authentication stringDefeats silent malicious-origin and port-squatter enrollment
Browser credential lifetimeMemory-only, session-scopedReduces persistence after tab/profile compromise
Durable authorizationCompanion-side origin approval onlyKeeps reusable secrets out of JavaScript storage
Generation streamAuthenticated encrypted NDJSON over FetchIncremental, inspectable state machine with bounded buffering
Browser model uploadNot present in first releaseAvoids duplicate bytes, private-path leakage, and browser buffering
ImportCompanion-native picker or direct P2P acquisitionBytes remain between local storage, companion, and peer
P2P authorityNever returned to browserPublication and serving keys remain in the P2P process or OS store
CompatibilityOne clean major protocolThe product is pre-publication; insecure unpublished routes should be removed

Threat model and protected assets

Trust boundaries

The protocol crosses seven materially different boundaries:

  1. The public HTTPS delivery boundary for TinyRustLM JavaScript and WebAssembly.
  2. The browser origin and profile boundary.
  3. The browser-to-loopback network boundary.
  4. The companion control-plane process boundary.
  5. The inference worker and model-store boundary.
  6. The P2P process and non-loopback network boundary.
  7. The OS credential, update, installer, and user-account boundary.

A secure context means the browser delivered the page through an origin meeting the browser’s trust criteria; it does not prove that the delivered application is benign. Secure Contexts explicitly notes incomplete isolation through facilities such as web storage and BroadcastChannel. A compromised approved TinyRustLM page, same-origin service worker, or extension that can inspect page state can therefore see prompts before encryption and can exercise whatever session scopes the page possesses. No browser-to-companion protocol can cryptographically hide a prompt from the JavaScript that creates it.

flowchart TB
    subgraph Public["Public and browser zone"]
        A[CDN / origin]
        B[TinyRustLM document]
        C[Top-level rendering controller]
        D[Browser profile, extensions, DevTools]
    end

    subgraph Local["Per-user local zone"]
        E[Loopback listener]
        F[Pairing and capability authority]
        G[Inference worker]
        H[Quarantine]
        I[Model store]
    end

    subgraph Peer["P2P zone"]
        J[P2P lane]
        K[Remote peers]
        L[Catalog metadata]
    end

    A --> B --> C --> E
    D -. can affect .-> B
    E --> F
    F --> G
    H --> I --> G
    F --> J
    J --> K
    L -. discovery only .-> J

Actors, capabilities, and security objectives

Threat actor or conditionPlausible capabilityRequired control or residual limitation
Malicious remote websiteScan loopback ports, submit simple requests, induce preflightsExact CORS allowlist, exact Origin, no unauthenticated side effects, LNA permission, pairing
Compromised TinyRustLM page or XSSRead prompts, call authorized APIs, exfiltrate browser-held keysStrict CSP, no third-party scripts, short sessions, narrow scopes; cannot fully protect prompts from the approved page
Malicious browser extensionRead/alter page and network state according to extension permissionsShort-lived capability and native approval limit duration; otherwise residual browser-compromise risk
Local unprivileged process, same userPort-squat, imitate discovery, make direct HTTP calls, read user-accessible filesNative UI pairing, instance key, proof-of-possession, user-only ACLs, application encryption
Another OS userProbe shared listeners or filesPer-user process, loopback-only listener, user-specific ACLs, protected runtime directories
Elevated process or malwareInspect process memory, inject code, capture traffic, replace executableSigned updates, package identity checks, isolation, receipts; confidentiality is not guaranteed against administrator-level compromise
DNS rebinding originResolve attacker-controlled name to loopback or alternate addressNumeric loopback URLs only, exact Host, connected-address check, no hostname listener
Router or network observerObserve or modify non-loopback P2P trafficP2P authenticated encryption, peer identity, signed manifests; control plane never leaves loopback
Stale tab or browser profileReuse old session or commit a late answerShort expiry, revocation, renderer lease, event sequence, terminal generation state
Downgraded companionRestore removed routes or weak protocolSigned update metadata, minimum accepted clean protocol and build floor
Stolen session capabilityExercise allowed operations until expiryProof-of-possession key, operation scope, origin/instance binding, idle timeout, revocation
Port squatterReturn a fake descriptor before the real companion startsNo secret in discovery; trusted native companion UI must approve the transcript
Corrupt .slm or malicious peerResource exhaustion, parser exploit, wrong model identityStreaming hash, structural admission, quarantine, size limits, atomic promotion

Protected-asset inventory

The highest-value assets are the prompt and completion content; model weights and .slm artifacts; private local paths; model inventory and usage history; companion identity keys; browser session keys; P2P identity and signing keys; enrollment URLs; MemoryEndpoints tokens; catalog credentials; publication keys; fleet or workspace administrator credentials; update trust roots; diagnostics; receipts; and service availability.

The design deliberately separates key domains:

Key or credentialAllowed holderBrowser-visible form
Browser session traffic keysBrowser memory and companion session memoryNon-exportable or in-memory key handles; never serialized to logs
Companion instance identity keyCompanion OS-protected storePublic key and fingerprint only
Receipt-attestation keyCompanion or isolated receipt signerSigned receipt and public identifier only
P2P transport/signing keyP2P process or OS-protected storeStatus and public peer identifier only
Catalog credentialCatalog agent or P2P processNever
Publication keyNative publication workflowNever
MemoryEndpoints tokenDedicated native integrationNever unless a separately reviewed capability explicitly requires a constrained operation
Fleet/admin credentialAdministrator-managed native componentNever

A stolen browser session key must not imply possession of the instance identity key, P2P key, update key, publication key, or administrative credential.

Browser standards and transport decision

Standards and implementation matrix

AreaNormative or vendor position as retrieved August 1, 2026Protocol consequence
Secure contexts127.0.0.0/8 and ::1/128 are potentially trustworthy; localhost is conditional on safe local resolutionUse numeric IP literals, not localhost
Mixed contentPotentially trustworthy local targets are not treated like ordinary insecure remote contentHTTP loopback can be viable, subject to browser policy
Local Network AccessWICG work defines public, local, and loopback address spaces and permission-gated access; Chrome implements permission gatingTreat LNA as browser mediation, not authentication
FetchResponse bodies can be consumed as streams; aborting affects the request and body readUse Fetch for generation and explicit cancellation
CORSPreflight and response headers determine whether page JavaScript can access cross-origin responsesExact origin, methods, headers, and bounded cache
WebSocketBrowser sends Origin; RFC 6455 says servers should validate it, but non-browser clients can forge itOrigin is a signal, never request authentication
CSPconnect-src controls Fetch, XHR, EventSource, WebSocket, and related outbound connectionsEnumerate only the approved loopback ports and required public services
Permissions PolicyFeatures can be selectively enabled or denied, but unknown features can be ignored and implementation support variesUse as defense-in-depth, not the primary boundary
WASM shared memoryCross-origin isolation normally requires COOP and COEPDeploy COOP/COEP where browser-side WASM threads are used
OAuth loopback redirectNative-app OAuth permits random loopback ports but acknowledges interception by other local appsUseful contrast only; an OAuth redirect pattern is not sufficient for companion authorization

These behaviors are documented in Secure Contexts, the Fetch and CSP standards, the LNA proposal, browser release notes, and RFCs for WebSocket and native-app OAuth.

Candidate-transport comparison

CandidateSecurity propertiesStreaming and cancellationDeployment and UXFirst-release decision
HTTP loopback + FetchStrict CORS and origin checks; application authentication/encryption requiredNative response stream and AbortController; request status through ordinary routesNo certificate installation; affected by LNA and browser policySelected
HTTPS loopback with locally trusted certificateTLS confidentiality and endpoint authentication if trust is installed correctlyGood Fetch streamingCertificate issuance, renewal, trust-store modification, revocation, multi-profile behavior, and installer privilege create a large lifecycle burdenReject for first release
HTTPS with shared/public local certificateEasy browser trust only if private key is distributable or DNS ownership is involvedGoodShared private keys or public DNS indirection create unacceptable compromise and rebinding risksProhibited
Classic WebSocketPersistent bidirectional channel; browser Origin availableNo built-in backpressure in the classic API; application cancellation requiredLNA prompts in current Chromium; browser cannot freely set an arbitrary Authorization header in the handshakeReject
Server-Sent EventsHTTP-based, one-way eventsAutomatic reconnection and Last-Event-ID; separate request needed for cancellationEventSource does not provide the desired custom-header and request-envelope model; would introduce a second transportReject
WebTransportMultiplexed streams and datagrams over secure transportStrong streaming modelHTTPS/HTTP/3/QUIC certificate and operational complexity; LNA-gated in current ChromiumDefer
Native messagingExtension identity can constrain which browser extension invokes the host; OS process and framed messagesGood for messages; not directly available to a normal web originRequires extension installation, policy, store distribution, and an additional supply-chain componentFuture managed/enterprise mode only
Custom URI handlerCan launch an applicationNot a data-plane transportURLs and command lines are poor places for secrets; invocation and response correlation are awkwardNon-secret launch hint only, or omit
Browser extension bridgeCan use native messaging and mediate local transportFlexibleBroader privilege, extension compromise risk, browser-store dependencyNot required for first release

WebSocket servers are expected to validate acceptable browser origins, but RFC 6455 explicitly recognizes that non-browser clients can send fabricated Origin values. Classic WebSocket also lacks a backpressure mechanism. Native messaging offers explicit extension-to-native-host allowlisting, but only through an installed extension and host manifest.

Server-Sent Events are unidirectional and define automatic reconnection behavior; those semantics are useful for public event feeds but conflict with a clean, explicitly authenticated request/stream lifecycle where generation is never restarted implicitly.

Browser support policy

Recommendation: qualify each shipped browser family using its current stable release and previous major release. The minimum matrix should include Chromium, Microsoft Edge, Firefox, and Safari on every supported Windows and Linux configuration. Browser family detection must not select a weaker security path. Instead:

  • Feature-detect streaming Fetch, Web Crypto primitives, AbortController, and any LNA behavior.
  • Present an explicit unsupported-browser result when mandatory primitives are absent.
  • Never fall back to WebSocket, unencrypted HTTP bodies, permissive CORS, a URL bearer token, or a legacy route.
  • Test browser permission denial, permission revocation, incognito/private profiles, profile switching, stale service workers, and top-level versus framed execution.
  • Make the application top-level only; do not permit the inference interface to operate inside an iframe.

Loopback discovery, pairing, and session security

Binding and listener invariants

The companion must enforce all of the following before reporting readiness:

Required IPv4 listener: 127.0.0.1:<selected-port>
Optional IPv6 listener: [::1]:<same-selected-port>
IPv6 socket option: IPV6_V6ONLY = true
Allowed ports, ordered: 43191, 43192, 43193, 43194,
                        43195, 43196, 43197, 43198
HTTP protocol: HTTP/1.1 only
TLS/ALPN: none on the control listener

On Windows, the implementation should use exclusive binding semantics and must not opt into port sharing. On Linux, it must not set SO_REUSEPORT. After accept(), it must inspect both local and peer socket addresses and reject anything that is not exactly loopback. IPv4-mapped IPv6 addresses should be rejected rather than normalized into an accepted form.

The listener should use these initial resource ceilings:

ResourceProposed ceiling
Total control connections32
Unauthenticated connections4
Authenticated connections16
Concurrent generation streams per user2
Active generation per renderer lease1
Concurrent imports1
Request header block16 KiB
Public descriptor response16 KiB
Ordinary encrypted control body1 MiB
Redacted diagnostic response256 KiB
Per-stream queued plaintext256 KiB or 64 events, whichever comes first
Header completion timeout5 seconds
Unauthenticated idle timeout5 seconds
Authenticated idle timeout, no stream30 seconds

These values are proposed defaults, not observed product limits. They must be load-tested against the actual runtime.

Discovery without a bearer secret

The browser probes only:

GET /.well-known/tinyrustlm-companion HTTP/1.1
Host: 127.0.0.1:43191
Origin: https://tinyrustlm.com
Accept: application/json

The probe iterates the fixed port set with bounded concurrency and jitter. It does not include a token, enrollment URL, user identifier, model identifier, prompt, query string, fragment, cookie, custom URI payload, or secret challenge.

The public descriptor exposes only:

{
  "schema": "https://tinyrustlm.com/schemas/local-probe-v1.json",
  "protocol_major": 1,
  "instance_id": "c2d40ebf-…",
  "instance_public_key": "p256:base64url-public-key",
  "selected_port": 43191,
  "pairing_required": true,
  "pairing_methods": ["native-confirm-sas-v1"],
  "build_channel": "stable",
  "response_nonce": "base64url-128-bit",
  "expires_at": "2026-08-01T18:04:30Z"
}

The descriptor is intentionally not trusted until pairing. A malicious local process can occupy a candidate port and return a syntactically valid descriptor. It cannot become the trusted companion without causing the user to approve the same pairing transcript in the authentic companion’s native UI.

Candidate discovery alternatives compare as follows:

MechanismBenefitDefectPosition
Single fixed portSimpleEasy collision and squatting; no fallbackInsufficient alone
Bounded ordered port setBrowser-accessible, no external helperScan surface and possible squattingSelected with authenticated pairing
Filesystem descriptorStrong local coordination between native processesNormal web page cannot read itUse internally, not browser discovery
OS IPC bootstrapStrong access controlBrowser cannot use it without extension/native integrationFuture extension mode
User-entered portAvoids scanningPoor UX and still no endpoint identityEmergency diagnostic only
User-mediated codeStrong intent signalMust not become a low-entropy bearer secretSelected as transcript comparison
mDNS/service registrationDiscoverableAdds network exposure, DNS complexity, and privacy leakageReject
Custom URI bootstrapCan launch companionURL/argv/history leakage if it contains secretsAt most carry a non-secret launch nonce

OAuth loopback redirect guidance permits ephemeral ports but warns that another local application can intercept a loopback redirect. For TinyRustLM, a callback receipt is therefore not endpoint authentication and cannot replace interactive companion confirmation.

First pairing and repeat-session protocol

The first pairing uses an authenticated key-exchange transcript plus explicit native approval. The six-word short-authentication string is a human comparison value derived from a full-entropy transcript; it is not submitted as a password and is not itself a bearer capability.

sequenceDiagram
    participant B as TinyRustLM top-level tab
    participant C as Candidate companion endpoint
    participant U as User / trusted native UI

    B->>C: GET public descriptor on bounded ports
    C-->>B: instance_id, public key, nonce, protocol major

    B->>B: Generate ephemeral P-256 ECDH key and browser_nonce
    B->>C: POST /v1/pairings<br/>origin, ephemeral key, nonce, requested scopes
    C->>C: Generate ephemeral ECDH key and pairing_id
    C-->>B: Server key, instance signature, transcript hash, expiry
    B->>B: Verify signature and derive SAS
    C->>U: Show exact origin, scopes, instance fingerprint, SAS
    B->>U: Show same SAS and requested operation summary
    U->>C: Approve in native UI
    B->>C: POST /v1/pairings/{id}:complete<br/>proof of derived handshake key
    C-->>B: Session id, limits, expiry, server proof
    B->>B: Derive independent traffic keys with HKDF

    alt Repeat during live browser session
        B->>C: Authenticated /v1/sessions:refresh
        C-->>B: Rekey transcript and reduced-or-equal scopes
    else Session expired or companion restarted
        C-->>B: 401 session_expired
        B->>C: New pairing request
        C->>U: New native approval
    else User revokes session
        U->>C: Revoke in native UI
        C-->>B: Stream terminal event session_revoked
    else Response lost after accepted operation
        B->>C: Retry with same idempotency key
        C-->>B: Existing operation_id and current state
    end

The pairing transcript must bind:

protocol major and minor
companion instance_id
companion package/build digest
companion long-lived public identity key
exact requesting origin
browser ephemeral public key
companion ephemeral public key
browser_nonce
companion_nonce
pairing_id
requested scopes
approved scopes
creation and expiration times
public discovery descriptor hash

The companion UI must display the exact serialized origin, not merely a brand name such as “TinyRustLM.” It must distinguish production, staging, preview, IP-literal, and deceptive Unicode domains.

Session capability model

A session is identified by a random 256-bit session_id, but the identifier is not sufficient to authorize requests. Authorization requires possession of keys derived from the pairing ECDH result. Each session is bound to:

  • One companion instance.
  • One exact HTTPS origin.
  • One protocol major and negotiated minor.
  • One random, memory-only client_context_id.
  • One top-level-tab renderer_lease_id.
  • A finite set of operation scopes.
  • An idle expiry and absolute expiry.
  • A minimum accepted browser-app build.
  • A companion build and minimum-protocol floor.

Proposed defaults are a 30-minute idle lifetime, an eight-hour absolute lifetime, and traffic-key rotation every 15 minutes or after \(2^{20}\) authenticated messages, whichever occurs first. Companion restart invalidates all in-memory sessions unless an encrypted session journal is explicitly designed and tested; the safer first release is to require re-pairing.

Recommended scopes are:

inventory.read
model.import.native_picker
model.import.p2p
model.activate
generation.start
generation.cancel
model.free
diagnostics.read.redacted
p2p.status.read
session.revoke.self

There should be no browser scope for arbitrary file paths, generic URL fetching, shell execution, raw log access, P2P private-key export, catalog credential retrieval, publication signing, fleet administration, or MemoryEndpoints token retrieval.

Credential storage decision

LocationPersistenceMain exposureDecision
JavaScript variable / dedicated controller memoryUntil reload, close, or crashXSS and authorized extension can use itDefault
sessionStorageTab session, including reloadSame-origin script and some stale-tab scenariosDo not store traffic keys
IndexedDB non-exportable CryptoKeyDurable per origin/profileXSS may use the key even when it cannot export itDeferred opt-in
localStorageDurable and string-readableXSS, backup, accidental loggingProhibited
Browser cookieAutomatic request attachmentCSRF and ambient authorityProhibited
Companion user configurationDurableLocal user/process subject to ACLStore origin approvals, not browser traffic keys
OS credential storeDurable, platform-protectedPlatform/account compromise; possible roaming depending APIInstance and P2P keys only
Re-pairingNo durable browser secretUser frictionRequired after page-session loss by default

The instance identity key, receipt-attestation key, P2P key, publication key, catalog credential, and administrative credentials must never be returned to page JavaScript. Browser memory should hold only the current low-authority session keys.

Versioned API, authentication, and browser controls

Discovery and version negotiation

After pairing, the authenticated capabilities document is:

{
  "schema": "https://tinyrustlm.com/schemas/companion-capabilities-v1.json",
  "protocol": {
    "major": 1,
    "minor": 0,
    "minimum_minor": 0
  },
  "instance": {
    "id": "c2d40ebf-…",
    "build_version": "1.0.0",
    "package_digest": "sha256:…",
    "signer_id": "tinyrustlm-release-2026"
  },
  "artifact": {
    "slm_versions": ["1"],
    "max_bytes": 8589934592,
    "required_hashes": ["sha256"],
    "signature_profiles": ["slm-manifest-v1"]
  },
  "runtime": {
    "abi_versions": ["1"],
    "sampling_profiles": ["basic-v1"]
  },
  "streaming": {
    "modes": ["encrypted-ndjson-v1"],
    "resume": "status-only",
    "heartbeat_seconds": 10,
    "max_event_plaintext_bytes": 65536
  },
  "operations": {
    "cancellation": true,
    "idempotency": true,
    "persistent_import_status": true,
    "generation_restart": false
  },
  "limits": {
    "active_generations": 2,
    "active_imports": 1
  },
  "privacy": {
    "prompts_sent_to_project_sites": false,
    "model_bytes_sent_to_project_sites": false,
    "access_log_body_capture": false
  },
  "feature_flags": [],
  "critical": []
}

Unknown noncritical JSON fields are ignored. Every extension that changes security interpretation must be listed in critical; an unknown critical field causes deterministic failure. An unsupported major version returns 426 Upgrade Required with a public-safe supported-major list. Minor-version negotiation selects the highest mutually supported minor within the same major. No content-type sniffing is allowed.

Proposed clean route set

Method and routeAuthenticationPurpose
GET /healthzNoneProcess liveness only
GET /readyzNone, minimalLocal control-plane readiness only
GET /.well-known/tinyrustlm-companionNonePublic-safe discovery descriptor
POST /v1/pairingsOrigin checks, no sessionBegin pairing
GET /v1/pairings/{pairing_id}Pairing-bound challengePoll native approval state
POST /v1/pairings/{pairing_id}:completeHandshake proofComplete key agreement
GET /v1/capabilitiesSessionNegotiated capabilities
POST /v1/sessions:refreshSessionRekey without increasing scopes
POST /v1/sessions/{id}:revokeSame sessionRevoke current session
GET /v1/modelsinventory.readPublic-safe local inventory
POST /v1/importsImport scopeOpen native picker or begin approved P2P acquisition
GET /v1/imports/{id}Import scopeImport progress and terminal state
GET /v1/operations/{id}Matching operation scopeLost-response recovery
POST /v1/models/{id}:activatemodel.activateActivate a verified model
POST /v1/generationsgeneration.startBegin encrypted streaming generation
POST /v1/generations/{id}:cancelgeneration.cancelIdempotent cancellation
POST /v1/models/{id}:freemodel.freeRelease runtime resources
GET /v1/diagnostics?level=redactedDiagnostic scopeBounded local-safe diagnostics
GET /v1/p2p/statusp2p.status.readLayered P2P status and receipts

/healthz must return no model inventory, build fingerprint, username, filesystem path, P2P address, key identifier, or public-reachability claim. /readyz means only that the local control path can accept authenticated work.

Routes that should not exist in the first release include:

/admin/*
/debug/raw
/logs/raw
/metrics
/files/*
/filesystem/read
/shell
/proxy
/fetch-url
/upload
/keys/*
/credentials/*
/publish
/catalog/login
/p2p/private-key
/api/generate
/ws
/events
any legacy alias or versionless mutating endpoint

Canonical request authentication

Each authenticated request carries:

X-TRLM-Protocol: 1.0
X-TRLM-Session: base64url-session-id
X-TRLM-Created: 1785626400
X-TRLM-Expires: 1785626460
X-TRLM-Nonce: base64url-128-bit
X-TRLM-Sequence: 483
X-TRLM-Idempotency-Key: uuid-v4
Content-Digest: sha-256=:base64:
X-TRLM-MAC: :base64:
Content-Type: application/trlm-envelope+json
Origin: https://tinyrustlm.com

The signature base is assembled from parsed semantics, not raw header text:

"@method": POST
"@scheme": http
"@authority": 127.0.0.1:43191
"@path": /v1/generations
"origin": https://tinyrustlm.com
"content-type": application/trlm-envelope+json
"content-digest": sha-256=:...:
"x-trlm-protocol": 1.0
"x-trlm-session": ...
"x-trlm-created": 1785626400
"x-trlm-expires": 1785626460
"x-trlm-nonce": ...
"x-trlm-sequence": 483
"x-trlm-idempotency-key": ...

This follows the design principle of RFC 9421: sign stable derived components such as method, target, and authority, and avoid ambiguous custom canonicalization. The implementation need not expose the general RFC 9421 negotiation surface; it should adopt a frozen TinyRustLM profile with exactly one accepted serialization and algorithm suite.

Request processing order is mandatory:

  1. Enforce connection, header, body, and deadline limits.
  2. Parse exactly one request under strict HTTP/1.1 rules.
  3. Validate local destination, Host, request-target form, and origin.
  4. Reject duplicate security headers.
  5. Resolve the session and verify expiry and scope.
  6. Verify nonce, sequence window, content digest, and MAC in constant time.
  7. Enter the nonce into the replay cache.
  8. Decrypt the body with canonical headers as AEAD additional data.
  9. Validate schema and operation limits.
  10. Apply idempotency and execute.

Clock tolerance should be ±60 seconds. Requests remain valid for at most 60 seconds and never beyond the session expiration. A nonce is accepted once and retained in the replay cache for the session lifetime plus two minutes. Sequence numbers must increase, with only a small bounded out-of-order window where parallel Fetch requests require it.

Idempotency rules are:

  • Same session, route, idempotency key, and plaintext request digest: return the original operation or terminal result.
  • Same idempotency key with a different route or digest: 409 idempotency_conflict.
  • Repeated cancel: return the existing terminal cancellation or completion state.
  • Repeated import request: return the same import operation; never duplicate the artifact.
  • Repeated generation start: return the same generation identifier; never launch a second answer silently.
  • Idempotency records survive companion restart for imports and state-changing model operations. Generation records survive as metadata, but an interrupted generation is not resumed automatically.

All MAC, digest, key-identifier, and transcript comparisons must use constant-time primitives after validating expected lengths.

Host, destination, DNS-rebinding, and request-parser rules

Only these authorities are valid:

127.0.0.1:<actual-bound-port>
[::1]:<actual-bound-port>

Reject:

  • localhost, .localhost, or any DNS hostname.
  • IPv4-mapped IPv6.
  • Decimal-integer, octal, hexadecimal, shortened, or otherwise alternative IPv4 notation.
  • 0.0.0.0, [::], link-local, private LAN, public, and zone-scoped IPv6.
  • User information in an authority.
  • A trailing dot or case-normalized hostname.
  • A Host that differs from an absolute-form request target.
  • Forwarded, X-Forwarded-Host, X-Forwarded-For, and X-Original-URL.
  • Redirecting requests or responses.
  • Multiple Host, Content-Length, security, or digest fields.
  • Transfer-Encoding plus Content-Length.
  • Obsolete folded headers and ambiguous request-target encodings.
  • Decoded paths containing dot segments, encoded separators, NUL, or invalid UTF-8 where UTF-8 is required.

RFC 3986 defines bracketed IPv6 literals and conventional dotted-decimal IPv4 syntax; rejecting noncanonical numeric representations reduces disagreement between URL parsers, HTTP libraries, and address validators.

The companion should accept origin-bearing browser requests only when:

Origin == "https://tinyrustlm.com"
Sec-Fetch-Mode == "cors"             when present
Sec-Fetch-Site == "cross-site"       when present for public-to-loopback
Sec-Fetch-Dest == "empty"            when present

Sec-Fetch-* fields are supporting signals, not authentication, because a native client can forge them. Mutating and authenticated routes must reject missing Origin, Origin: null, sandboxed opaque origins, file: origins, extension origins, and requests initiated from unapproved preview domains.

Strict CORS

An approved preflight response is:

Access-Control-Allow-Origin: https://tinyrustlm.com
Access-Control-Allow-Methods: GET, POST, OPTIONS
Access-Control-Allow-Headers: Content-Type, Content-Digest,
  X-TRLM-Protocol, X-TRLM-Session, X-TRLM-Created,
  X-TRLM-Expires, X-TRLM-Nonce, X-TRLM-Sequence,
  X-TRLM-Idempotency-Key, X-TRLM-MAC
Access-Control-Max-Age: 300
Vary: Origin, Access-Control-Request-Method, Access-Control-Request-Headers
Cache-Control: no-store

There is no Access-Control-Allow-Credentials; requests use credentials: "omit". The origin is never reflected dynamically, and * is never used. Preflight validates the requested method and every requested header before returning success. Preflight itself has no side effect and does not reveal inventory, readiness details, or pairing state.

Fetch’s CORS processing requires matching allow-origin and method/header authorization for the browser to expose a cross-origin response. That mechanism restricts browser reads but does not stop a native local client; the session MAC remains the actual authorization boundary.

Every browser request uses:

fetch(url, {
  method: "POST",
  mode: "cors",
  credentials: "omit",
  cache: "no-store",
  redirect: "error",
  referrerPolicy: "no-referrer",
  headers,
  body,
  signal
});

Redirects must be prevented at request time; discovering response.redirected after following a redirect is too late to protect the original request.

Project-site CSP, isolation, and Permissions Policy

A production policy should approximate:

Content-Security-Policy:
  default-src 'none';
  script-src 'self' 'nonce-{per-response-random}';
  style-src 'self';
  img-src 'self' data:;
  font-src 'self';
  connect-src 'self'
    https://minimodel.org
    http://127.0.0.1:43191
    http://127.0.0.1:43192
    http://127.0.0.1:43193
    http://127.0.0.1:43194
    http://127.0.0.1:43195
    http://127.0.0.1:43196
    http://127.0.0.1:43197
    http://127.0.0.1:43198
    http://[::1]:43191
    http://[::1]:43192
    http://[::1]:43193
    http://[::1]:43194
    http://[::1]:43195
    http://[::1]:43196
    http://[::1]:43197
    http://[::1]:43198;
  worker-src 'self';
  frame-src 'none';
  frame-ancestors 'none';
  object-src 'none';
  base-uri 'none';
  form-action 'self';
  manifest-src 'self';
  require-trusted-types-for 'script';

No third-party analytics, tag manager, advertising script, remote font, or support widget should run in the inference origin. Subresource Integrity should protect any exceptionally permitted static third-party resource, although self-hosting is preferable. A service worker should either be absent from the inference application or have a narrowly reviewed scope, no prompt/body logging, and an explicit update and rollback policy.

CSP connect-src is the relevant directive for Fetch, WebSocket, EventSource, and similar connection APIs.

For browser-side WASM threads:

Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corp
Cross-Origin-Resource-Policy: same-origin
Origin-Agent-Cluster: ?1

Cross-origin isolation is the browser state associated with access to capabilities such as shared memory, and is normally established through COOP plus COEP.

A defense-in-depth Permissions Policy should deny LAN access and allow loopback only to the top-level application where the browser recognizes the feature names:

Permissions-Policy:
  local-network=(),
  loopback-network=(self),
  camera=(),
  microphone=(),
  geolocation=(),
  usb=(),
  serial=(),
  bluetooth=()

Permissions Policy is not sufficient by itself because feature availability and implementation vary, and unrecognized policy-controlled features can be ignored.

Streaming generation, import, privacy, and P2P truth

Generation request and event contract

The decrypted generation request contains:

{
  "schema": "generation-request-v1",
  "request_id": "uuid",
  "renderer_lease_id": "uuid",
  "model": {
    "artifact_sha256": "…",
    "composition_sha256": "…"
  },
  "prompt": {
    "format": "messages-v1",
    "messages": [
      {"role": "user", "content": "…"}
    ]
  },
  "sampling": {
    "profile": "basic-v1",
    "temperature": 0.7,
    "top_p": 0.95,
    "max_output_tokens": 512,
    "seed": null
  }
}

The companion computes a local prompt digest for request binding, but that digest must not be exported to project sites, catalogs, public receipts, telemetry, or ordinary logs. A prompt hash can itself enable confirmation attacks against guessed sensitive text.

The HTTP response is application/x-ndjson, but each line is an authenticated encrypted envelope:

{
  "v": 1,
  "generation_id": "uuid",
  "stream_prefix": "base64url-random",
  "seq": 17,
  "type": "ciphertext",
  "ciphertext": "base64url",
  "tag": "base64url",
  "prev_event_hash": "sha256:…"
}

After decryption, the permitted event types are:

EventRequired content
acceptedGeneration ID, response ID, renderer lease, active model/composition digest, sampling digest
deltaMonotonic event sequence and UTF-8 text delta or token identifier, never both ambiguously
usageInput tokens, output tokens, elapsed inference counters
heartbeatSequence and monotonic server time; no prompt/model content
completeStop reason, final usage, final stream hash
errorStable code, retryability, bounded safe message
cancelledCancellation reason and final usage
session_revokedTerminal session state

Every event is individually AEAD-protected with a nonce derived from a random per-stream prefix and the monotonic sequence. The prior-event hash chains the stream and makes deletion, duplication, and reordering detectable.

Backpressure and cancellation

Fetch response bodies expose a readable stream, allowing the browser to process data incrementally rather than waiting for the complete response.

The companion must nevertheless impose its own bounded queue. Recommended behavior:

  • Pause model-output consumption when the queue reaches 64 events or 256 KiB of plaintext.
  • If the runtime cannot pause, retain only within the hard bound and cancel with consumer_too_slow; never allow unbounded memory growth.
  • Send a heartbeat every ten seconds during token silence.
  • Treat 30 seconds of unconsumed buffered output as a stalled consumer.
  • Limit a decrypted event to 64 KiB and an error message to 4 KiB.
  • Never log token or text deltas.

Cancellation uses both browser transport cancellation and an authoritative protocol operation:

  1. The UI calls AbortController.abort() to stop further browser consumption.
  2. It sends POST /v1/generations/{id}:cancel with a new authenticated idempotency key.
  3. The inference worker observes a cancellation token at bounded intervals.
  4. If completion won the race, cancellation returns already_complete.
  5. If cancellation won, the stream terminates once with cancelled.
  6. Repeating the same cancellation returns the same terminal state.

Aborting a Fetch affects both the request and subsequent body reads, but transport abort alone is not sufficient proof that computation stopped; the explicit cancel operation supplies authoritative state.

One authoritative renderer

A generation is bound to one renderer_lease_id. The browser application maintains one top-level rendering controller per assistant turn. The companion rejects a second active generation for the same lease unless the first is terminal.

The UI commit rule is:

Commit only when:
session_id matches
generation_id matches expected operation
response_id has not been committed
renderer_lease_id is the active lease
seq == previous_seq + 1
event MAC and hash chain verify
terminal event has not previously occurred

A browser-origin Web Lock may coordinate same-origin tabs, but the companion-side renderer lease remains authoritative. Storage events or BroadcastChannel alone are not a security boundary; Secure Contexts notes that cross-context browser facilities contribute to incomplete isolation.

A disconnected generation is marked interrupted. First release has no token-stream resume and no invisible restart. A retry with the same idempotency key returns the existing operation state. Continuing an interrupted answer is a new, explicit user action and a new generation, visibly distinguished from the interrupted response.

Model-import decision

Import mechanismPrivacy and efficiencySecurity concernDecision
Browser-selected File uploaded over loopbackUser-friendly but model bytes traverse browser memory and may be duplicatedDevTools, extension, buffering, temporary storage, large-upload interoperabilityNot first release
Browser-selected path referenceBrowser normally does not expose a generally usable native pathPath privacy and confused-deputy file accessProhibited
Companion-native pickerBytes move directly from disk into companion quarantineRequires trusted native UIPreferred
Browser-entered local pathAvoids byte uploadReveals private paths and can become arbitrary-file authorityProhibited
Direct P2P acquisitionAvoids project-site and browser pathRequires peer identity, manifest trust, resource limitsSupported after P2P verification
Catalog-mediated downloadCentral convenienceViolates the no-model-proxy constraintProhibited

POST /v1/imports should accept only an operation choice such as:

{"source": "native_picker"}

or:

{
  "source": "p2p",
  "artifact_sha256": "…",
  "signed_manifest": {"…": "…"},
  "peer_receipt_id": "…"
}

It must not accept an arbitrary local filesystem path or arbitrary URL.

.slm admission pipeline

Because the .slm format and its signing rules are not publicly verified here, the following is a required architecture rather than a claim about the current artifact format:

flowchart LR
    A[Native picker or authenticated peer] --> B[Per-user quarantine]
    B --> C[Stream size enforcement]
    C --> D[Streaming SHA-256]
    D --> E[Container and manifest parser]
    E --> F[Signature and publisher policy]
    F --> G[Tensor, length, ABI, and resource checks]
    G --> H[Runtime compatibility probe]
    H --> I[fsync file and directory]
    I --> J[Atomic rename into content-addressed store]
    J --> K[Inventory publication by public-safe digest]

Admission must validate:

  • Magic, container version, endianness, declared lengths, and complete-file termination.
  • Manifest signature and signer policy.
  • Artifact SHA-256 and every component digest.
  • Tensor dimensions, element counts, multiplication overflow, offsets, alignment, and overlap.
  • Runtime ABI, architecture, quantization, tokenizer, and operator compatibility.
  • Compression ratio and decompressed-size limits.
  • No archive path traversal, symlink, device node, alternate data stream, or absolute path.
  • Disk quota, memory forecast, model-context limit, and maximum file count.
  • No execution or memory mapping from quarantine before complete admission.
  • fsync and atomic promotion so crashes cannot expose partially admitted content.

The public model identity should be content-based, for example sha256:<digest>, with a separately displayed human catalog name. Local filenames and paths are not part of public identity.

Prompt, model, and diagnostic privacy

The companion must disable ordinary HTTP access logging or restrict it to route templates, status classes, bounded durations, and random request identifiers. It must never log:

  • Request URLs containing variable identifiers when a template suffices.
  • Query strings.
  • Origin beyond a normalized allowlist identifier.
  • Authorization, session, nonce, MAC, digest, or idempotency values.
  • Encrypted or plaintext bodies.
  • Prompt text, completion text, token deltas, embeddings, or prompt hashes.
  • Model filenames, user paths, or peer addresses.
  • P2P, publication, catalog, MemoryEndpoints, enrollment, or administrative secrets.

Errors cross the browser boundary as stable codes plus bounded generic descriptions. Full parser offsets, native stack traces, environment variables, command lines, and filesystem paths remain only in protected opt-in diagnostics, and even there must be redacted.

Residual privacy boundaries must be explicit:

SurfaceControlResidual risk
Compromised approved pageCSP, no third-party script, short scopesPage necessarily sees user-entered prompt
Browser extensionMinimize permission recommendations, short sessionPrivileged extension may inspect page/network
DevToolsNo server logs; encrypted wire bodiesUser or local debugger can inspect pre-encryption page state
Crash dumpsDisable or minimize; scrub keys and prompt buffersOS-level dumps may capture memory
Swap/hibernationLocked memory for keys where practical; clear buffersModel and prompt pages may reach OS-managed storage
Clipboard/screenshotsNever copy automatically; explicit user actionUser or OS tools can capture displayed content
Temporary filesQuarantine only, mode-restricted, atomic cleanupForensic recovery may remain depending filesystem
Source mapsNo secrets; restrict production distributionMaps can aid exploitation if broadly exposed
P2P trafficEnd-to-end peer authentication and encryptionSizes, timing, and peer IPs remain metadata

P2P status separation

The browser must not collapse different network claims into one “online” indicator.

Status dimensionEvidence requiredWhat it does not prove
Local inference readyAuthenticated readiness receipt and loaded runtimeP2P process is healthy
P2P lane healthySigned local process-health receiptLAN or Internet reachability
LAN listener activeBound non-loopback address and local socket stateAnother LAN host can connect
LAN reachabilityRecent challenge from an independent LAN verifierPublic Internet reachability
Public reachabilityRecent outside-in challenge receiptCatalog announcement
Catalog announcedCatalog acknowledgment for peer/model metadataModel bytes were served successfully
Transfer verifiedPeer-signed transfer receipt and artifact digestContinued reachability after receipt expiry

A local /healthz response proves only local process liveness. Public reachability requires an outside verifier that issued an unpredictable challenge and received a valid response over the P2P lane. Catalog acknowledgment is a separate event and must not be inferred from either health or reachability.

The browser may display only unexpired receipts, including the evidence timestamp, verifier identity class, and expiration. The P2P private key remains in the P2P process or OS-protected storage.

Service lifecycle, updates, evidence, and testing

Windows and Linux process architecture

Windows recommendation: install per user under a protected %LOCALAPPDATA% location and run the control companion unelevated in the interactive user context. Do not run the browser control plane as SYSTEM. Use a per-user startup mechanism and a per-user singleton lock. Give model-store, configuration, and credential files ACLs that exclude other nonadministrative users. Close inherited handles and isolate model workers in job objects or equivalent process supervision.

Linux recommendation: use a systemd --user unit. Put transient sockets, lock files, and PID metadata under $XDG_RUNTIME_DIR; persistent configuration under $XDG_CONFIG_HOME; state and model indexes under $XDG_STATE_HOME or a deliberately selected per-user data directory. A systemd login environment creates a private per-user runtime directory intended for runtime objects such as Unix sockets and removes it after the user’s final logout.

A conceptual Linux unit should include, where compatible with GPU/runtime requirements:

[Service]
ExecStart=%h/.local/libexec/tinyrustlm-companion
Restart=on-failure
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ProtectHome=read-only
RestrictSUIDSGID=true
LockPersonality=true
UMask=0077

The loopback control plane and P2P lane should be separate processes:

ProcessPrivilege and networkSecret access
Control companionPer user; loopback onlyInstance identity, session authority, model index
Inference workerNo listening sockets; least filesystem accessSelected verified model and generation input
Import verifierQuarantine and promotion paths onlyArtifact verification trust anchors
P2P laneRequired LAN/public sockets onlyP2P identity, serving policy; no browser session keys
UpdaterNarrow installation authority, not continuously residentUpdate metadata trust roots

Only the P2P lane should trigger or require non-loopback firewall rules. The control companion should never add a firewall exception.

Startup, restart, and shutdown

Startup order:

  1. Verify executable/package identity.
  2. Acquire the per-user singleton.
  3. Lock configuration and credential files.
  4. Validate minimum protocol/build policy.
  5. Bind the selected loopback port before publishing readiness.
  6. Recover the operation journal.
  7. Verify model-store index consistency.
  8. Start workers and mark /readyz true.
  9. Start the independent P2P lane only if native policy enables it.

On restart:

  • Pairing attempts become expired.
  • In-memory browser sessions become invalid.
  • Running generations become interrupted; they are not silently restarted.
  • Imports resume only from verified chunk boundaries under the same manifest and expected digest, or enter an explicit restart-required state.
  • Activation and free operations reconcile against observed worker state.
  • Stale ports and runtime descriptor files are removed only after ownership checks.
  • Orphan workers are terminated or reattached only through authenticated parent identity.

Shutdown drains by first rejecting new generation and import requests, then allowing a short bounded grace interval, issuing cancellation, flushing operation metadata, and closing listeners. The design must not claim a successful clean shutdown if workers remain orphaned.

Uninstall must stop services, revoke sessions, remove startup entries, remove only TinyRustLM-created firewall rules, delete runtime files, and wipe credentials. User models should be preserved or deleted only through an explicit user choice.

Update and downgrade defense

The update design should combine signed native packages with TUF-style metadata:

  • Root role and threshold trust.
  • Timestamp and snapshot freshness.
  • Signed target metadata containing package digest, length, platform, architecture, channel, protocol range, and security floor.
  • Protection against rollback, freeze, mix-and-match, and wrong-target installation.
  • Transactional install and rollback only to a still-authorized security version.
  • Separate emergency authorization for any exceptional downgrade.
  • Binding of the browser application build and companion package digest in the pairing transcript.

The Update Framework is expressly designed to address rollback, freeze, mix-and-match, and wrong-software attacks through role separation, versioning, expirations, and threshold signatures. Windows package signing additionally allows package integrity and signer identity to be checked.

Because the product is pre-publication, the release should define a single minimum clean protocol and remove all superseded handlers before publishing. Historical receipts may record earlier test versions, but the executable must not retain dormant legacy routes, compatibility tokens, permissive CORS branches, or alternate transports.

Adversarial test matrix

TestStimulusRequired result
Malicious website scanThousands of origins probe every candidate portAt most public descriptor; no inventory or side effect
Reflected originArbitrary Origin sent in preflightNo reflected allow-origin; request denied
Null originSandboxed iframe or local fileDeterministic denial
DNS rebindingHostname changes from public to loopbackIrrelevant because hostname targets/listeners are rejected
Forged HostCorrect socket, wrong authority400 invalid_authority before body processing
Alternative numeric IPDecimal, octal, hex, mapped IPv6Rejected before route dispatch
CSRF formSimple form POST without custom headersUnsupported media type or authentication failure; no side effect
Preflight confusionMixed-case, duplicate, or extra requested headersExact normalized allowlist or denial
Cross-site WebSocketBrowser attempts ws:// connectionNo WebSocket route/listener exists
ReplayRepeat identical authenticated requestReplay denial or original idempotent result, never duplicate execution
Stolen session ID onlyCorrect session identifier, no traffic keyMAC failure
Stolen full session capabilityValid key from another origin/instance or after expiryOrigin/instance/expiry denial
Port squattingFake descriptor and pairing endpointCannot produce approval in authentic companion UI
Local malicious processDirect HTTP requests with forged browser headersFails proof-of-possession
Oversized bodyLength above declared route limitEarly 413, bounded read, no allocation proportional to declaration
SlowlorisPartial headers/body below minimum rateDeadline closure
Request smugglingCL/TE ambiguity or duplicate lengthsConnection closed before routing
Duplicate stream eventRepeated sequence or hashRenderer terminates stream as integrity failure
Out-of-order eventSequence gap/reorderingNo commit; integrity failure
Cancellation raceComplete and cancel occur concurrentlyExactly one terminal state
Lost responseDrop after operation acceptanceRetry returns original operation
Companion restartKill during generation/importGeneration interrupted; import safely recovered or restarted
Corrupt modelWrong digest, malformed dimensions, truncated fileQuarantine rejection; no activation
Decompression bombTiny compressed input with excessive expansionAdmission stops at ratio/size ceiling
Path traversalArchive member escapes quarantineRejection
Stale tabOld tab attempts to commit after lease transferCompanion and renderer reject
DowngradeInstall older signed but disallowed buildSecurity-floor rejection
Secret leakageScan logs, dumps, profiles, packagesRelease blocker on any unauthorized secret marker

Browser tests must run from real HTTPS origins rather than only mocked unit clients, because CORS, mixed content, secure-context, LNA, service-worker, and permission behavior is browser-mediated. Chrome’s LNA permission applies to public-to-loopback requests, and current Chromium has expanded it across Fetch, WebSocket, and WebTransport surfaces over successive releases.

Public-safe receipt contract

A receipt suitable for support or publication contains:

{
  "schema": "trlm-receipt-v1",
  "receipt_id": "uuid",
  "created_at": "2026-08-01T18:42:00Z",
  "expires_at": "2026-08-01T18:52:00Z",
  "companion": {
    "package_sha256": "…",
    "signer_id": "tinyrustlm-release-2026"
  },
  "protocol": {"major": 1, "minor": 0},
  "origin": "https://tinyrustlm.com",
  "endpoint_class": "loopback-ipv4",
  "scopes": ["p2p.status.read"],
  "model": {"artifact_sha256": "…"},
  "status": {
    "local_ready": true,
    "p2p_lane_healthy": true,
    "lan_reachable": "unverified",
    "public_reachable": "verified",
    "catalog_announced": false
  },
  "counts": {
    "challenge_requests": 1,
    "successful_responses": 1
  },
  "test_identity": "outside-verifier-production",
  "error": null,
  "signature": {
    "key_id": "receipt-key-2026",
    "value": "base64url"
  }
}

Public-safe receipts omit prompts, completions, prompt hashes, filenames, paths, usernames, exact loopback ports, local process IDs, browser profile identifiers, peer IPs unless explicitly necessary, session identifiers, nonces, MACs, and secret values.

Secret-scanning contract

CI, package publication, diagnostic export, and support-bundle generation must scan:

  • UTF-8, UTF-16LE, and UTF-16BE text.
  • Base64, base64url, hexadecimal, JSON-escaped, and percent-encoded forms.
  • Source, generated code, WebAssembly strings, source maps, symbols, manifests, packages, logs, traces, profiles, crash artifacts, test fixtures, and screenshots where automated classification is possible.
  • Known prefixes and markers for enrollment URLs, bearer tokens, MemoryEndpoints, authorization headers, private-key PEM blocks, catalog secrets, publication keys, P2P private keys, and session headers.
  • High-entropy strings, with narrowly reviewed allowlists based on stable digests rather than plaintext exceptions.

Any confirmed production secret, prompt fixture containing real user data, private model path, or private key in a distributable artifact is a release blocker.

TDD and clean-cutover backlog

OrderTest-first deliverableExit criterion
1URI, authority, origin, header, content-digest, and canonical-signature parsersCorpus passes; differential fuzzing finds no parser disagreement
2Loopback-only socket bindingAutomated proof that wildcard and non-loopback connections fail
3Hostile-origin and CORS suiteEvery unapproved, null, missing, or reflected origin fails
4Discovery and port collisionValid fallback and malicious squatter scenarios pass
5Pairing transcript and native approvalMITM, replay, wrong-origin, wrong-instance, and expired pairing fail
6Session AEAD, MAC, replay cache, and rekeyPublished vectors pass in Rust, .NET, and browser implementation
7Public-safe inventoryNo path, secret, or private metadata escapes
8One synthetic .slm fixtureStructural admission, corruption, quota, and atomic promotion pass
9One authorized real modelVerified import and activation without browser byte transit
10Generation streamSequence, encryption, backpressure, terminal state, and one-renderer properties pass
11Cancellation and lost responseRaces and idempotent recovery pass
12Restart and operation journalNo invisible regeneration or partial promotion
13P2P truth modelLocal health cannot set LAN/public/catalog status
14Windows and Linux packagesPer-user installation, ACLs, update, uninstall, and stale-resource tests pass
15Browser dogfoodReal HTTPS tests pass on the supported browser matrix
16Route removal auditNo superseded endpoint, dual transport, permissive CORS, or compatibility token remains

Stop-release conditions include any non-loopback control bind; wildcard or reflected CORS; URL or cookie bearer credentials; missing native confirmation; browser exposure of high-value keys; unauthenticated mutating routes; accepted replay; unbounded stream buffering; duplicate answer commitment; generation restart without explicit user action; corrupt model promotion; local health presented as public reachability; accepted downgrade; or a confirmed secret-scanner finding.

Unknowns, follow-up validation, and annotated bibliography

Facts requiring authorized verification

The following cannot be responsibly asserted from public information:

UnknownRequired access or artifactDesign consequence
Actual TinyRustLM production and staging originsDNS/CDN and deployment configurationExact origin and CSP allowlists
Existing local endpoints and transportsSource, binaries, or live companionRoute-removal and migration audit
Current bind addresses and port behaviorLive network inspection and sourceLoopback enforcement and collision plan
.slm container and signature specificationFormal schema and test artifactsAdmission parser, limits, trust roots
Runtime cancellation and flow controlRuntime source and instrumentationBackpressure and cancellation guarantees
Model memory and temporary-file behaviorRuntime tests and OS tracingPrivacy and crash-recovery posture
P2P handshake and transportProtocol specification and packet capturesPeer authentication, replay, and confidentiality
P2P and publication key storageAuthorized credential-flow reviewSecret-boundary validation
MiniModel catalog API behaviorPublic/API specification and deployment reviewMetadata-only enforcement
Windows installer privilege and startup mechanismInstaller project and packagePer-user and update architecture
Linux packaging and hardening compatibilityUnit files, sandbox tests, GPU setupPractical service isolation
Logging, traces, crash dumps, telemetryConfiguration, binaries, and generated artifactsSecret-leakage assessment
Update trust roots and rollback policyUpdate metadata and signing ceremonyDowngrade resistance
Browser build and support policyProduct decision and test farmExact compatibility matrix
Existing credentials or enrollment URLsAuthorized secret inventoryBoundary and scanner rules
Firewall and NAT behaviorLive Windows/Linux and outside verifierP2P status truth
Legacy unpublished routesRepository and binary inventoryClean cutover proof

Sequenced deeper-validation plan

A defensible elapsed-time estimate cannot be derived without repository size, package count, browser support targets, .slm complexity, P2P design, or access to test infrastructure. The work can instead be scoped by evidence-producing stages:

StageRelative effortRequired outputs
Protocol freezeMediumThreat model, schemas, canonicalization vectors, crypto profile, route registry
Private implementation inventoryMediumListener/route/secret/log/update data-flow map
Parser and cryptographic implementationLargeRust, .NET, and browser interoperability vectors and fuzz targets
Browser interoperabilityLargeReal-origin CORS/LNA/mixed-content matrix across supported browsers
Artifact admissionLarge to very largeFormal .slm schema, malformed corpus, resource-limit tests
Lifecycle and packagingLargeSigned Windows/Linux packages, ACL/unit tests, upgrade/uninstall evidence
P2P verificationLarge to very largePeer protocol review, outside-in verifier, receipt semantics
Clean publication auditMediumRoute-removal proof, secret scan, package inventory, release blockers closed

The stages should remain sequential where security dependencies require it: protocol and schema freeze before implementation; route inventory before clean cutover; .slm specification before parser security claims; P2P protocol review before public-reachability claims; and package/update verification before production enrollment.

Prioritized annotated bibliography

All sources below were retrieved on August 1, 2026. Living standards should be pinned to immutable repository commits in the final architecture decision record; a retrieval date alone is not an immutable revision.

PriorityPrimary source and publication stateRelevance
1W3C Secure Contexts, Editor’s Draft dated November 10, 2023Normative algorithm for potentially trustworthy loopback origins; also documents incomplete isolation and localhost-resolution risk.
2WICG Local Network AccessCurrent proposal for permission-gated public/local/loopback access and integrations with Fetch, WebSocket, and WebTransport. Treat as evolving rather than a universally implemented standard.
3Chrome 142 release notes, stable October 28, 2025Vendor record of Local Network Access permission gating for public-to-local and public-to-loopback requests and mixed-content relaxation after permission.
4Chrome 147 release notes, stable April 7, 2026Vendor record extending Local Network Access restrictions to WebSocket and WebTransport.
5WHATWG Fetch StandardNormative Fetch, CORS, preflight, redirect, response, and streaming processing model.
6W3C Content Security Policy Level 3Defines connect-src, script restrictions, framing controls, and other browser-side containment mechanisms.
7W3C Permissions Policy, Editor’s Draft dated June 18, 2026Defines policy-controlled feature allowlists; useful as defense-in-depth for loopback/local-network capabilities.
8RFC 9421, HTTP Message Signatures, February 2024Primary model for signing canonical method, authority, target, fields, creation time, and expiry; importantly distinguishes integrity from confidentiality.
9RFC 5869, HKDF, May 2010Primary key-derivation construction for separating handshake output into independent protocol keys.
10RFC 6455, The WebSocket Protocol, December 2011Defines browser-origin behavior and server origin validation; clarifies why Origin cannot authenticate native clients.
11WHATWG Server-Sent Events, developer edition updated July 16, 2026Primary definition of EventSource’s one-way event stream, event IDs, and reconnect behavior.
12RFC 3986, URI Generic Syntax, January 2005Canonical URI authority, IPv4, and bracketed IPv6 grammar supporting strict destination parsing.
13RFC 8252, OAuth 2.0 for Native Apps, October 2017Useful contrast for random loopback ports and local-app interception; not an authorization design for this companion.
14Microsoft Edge Native Messaging documentationPrimary vendor description of extension-native host manifests, extension allowlisting, process invocation, and message framing.
15MDN Fetch API usage guideBrowser-oriented documentation for response streams, abort semantics, CORS use, and request behavior.
16MDN WebSocket APIBrowser documentation noting the classic WebSocket API’s lack of backpressure.
17W3C Cross-Origin Isolation guidance through @@MKREPORTTOKEN0@@Documents the COOP/COEP conditions associated with cross-origin isolation and shared-memory browser features.
18The Update Framework specification, version 1.0.19 source retrievedPrimary update-security framework addressing rollback, freeze, mix-and-match, key compromise, and target selection.
19Microsoft MSIX SignTool guidanceVendor guidance for signing Windows application packages and establishing package integrity and signer identity.

The evidence supports the central architectural conclusion: browser loopback affordances, CORS, LNA permission, Origin, and secure-context classification are useful layers, but none establishes that a process on a local port is the intended TinyRustLM companion. That identity and authority must come from user-mediated pairing, proof-of-possession session keys, strict destination validation, narrow capabilities, application-layer confidentiality, and a separately protected native trust and update chain.