Runtime

TinyRustLM Offline Release, Service-Worker Update, and Last-Known-Good Rollback Architecture

Report summary

The research topic is reliable publication and offline lifecycle management for TinyRustLM.com , as specified in the supplied engineering brief. The governing objective is to ensure that every browser session runs one cryptographically identified application generation, that an explicitly supported

Status
Research archive item
Category
Runtime
Length
6,604 words
Reading time
31 minutes
Report type
architecture

Key topics

  • Runtime
  • AI
  • Rust
  • Privacy
  • Semantic Systems
  • Research Archive
  • Strategy
  • Audit

Research provenance

Archive status
Research archive item
Content identity
sha256:5c997803c3aebeb67e2d8f8a890e97a94323a6881d31127d7f0bedf76584217a

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

Source availability: 36 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 summary

The research topic is reliable publication and offline lifecycle management for TinyRustLM.com, as specified in the supplied engineering brief. The governing objective is to ensure that every browser session runs one cryptographically identified application generation, that an explicitly supported offline shell remains usable, and that interrupted or defective releases can be rolled back without combining HTML, JavaScript, workers, WebAssembly, styles, manifests, icons, schemas, or security policies from different releases.

[PUBLIC-OBSERVED] Publicly indexed TinyRustLM pages describe browser-local inference, local or peer-provided model files, an optional loopback companion, catalog and peer metadata, and optional MemoryEndpoints connectivity. The public interface also states that prompts are not sent to a project server. These are public product claims, not proof of the deployed implementation or network behavior. A recent crawl showed the root application reporting a ready browser-local runtime, while another recent search snapshot reported a missing WASM runtime; this inconsistency is itself evidence that deployment success must be established through versioned public readback and real-browser receipts rather than screenshots, uploads, or search-engine snapshots.

[RECOMMENDATION] TinyRustLM should use a two-plane lifecycle:

PlanePurposeUpdate frequencyAuthoritative identity
Supervisor planeMinimal root bootstrap, stable /sw.js, release verification, cache selection, rollback, update coordinationRareSupervisor manifest hash and exact public hashes
Application-release planeImmutable app HTML, JavaScript, CSS, WASM, workers, icons, web manifest, schemas and public metadata descriptorsEvery releaseSigned canonical release-manifest hash, RID

The central design is a mutable, non-cacheable release pointer—for example /release.json—that names an immutable, signed release manifest under /releases/<RID>/release-manifest.json. Every executable and style resource lives under that immutable release path and uses a content-hashed filename. The pointer is the only normal release commit artifact. Existing clients remain pinned to their currently admitted release until the candidate is completely downloaded, byte-hashed, validated and voluntarily activated; fresh clients may admit the newly committed release. This eliminates the need to pretend that a static host provides whole-site atomic deployment.

[RECOMMENDATION] Do not use query strings as the primary version identity. Do not make a service-worker precache list authoritative merely because it contains expected filenames. Do not treat SRI as complete graph verification. The authoritative release identity should be the SHA-256 digest of a canonical release manifest, authenticated by an offline-held deployment signing key. Content-hashed filenames provide dependency immutability; SRI adds browser enforcement for eligible <script> and <link> resources; the service worker must independently hash the actual response bytes before admitting them to a release cache. SRI currently applies principally to scripts and links, requires appropriate CORS handling for cross-origin resources, and does not by itself cover generic worker creation, arbitrary fetch() responses, or an entire transitive WASM application graph.

[RECOMMENDATION] The service worker must never call skipWaiting() during installation as a default policy, and it must not call clients.claim() merely because installation succeeded. Browser lifecycle rules intentionally keep an installed replacement waiting while old controlled clients exist; immediate activation can cause an old page to have later requests processed by new service-worker logic. Chrome’s official PWA guidance explicitly warns about this mixed-version condition.

[RECOMMENDATION] Keep two locally verified application releases—active and lastKnownGood—plus at most one candidate. Rollback should switch a small local release-selection record, not copy files into an unversioned “current” cache. Server-side rollback should repoint /release.json to a prior immutable manifest and issue a signed rollback receipt. A defective application release can therefore be rolled back offline by the stable supervisor. A catastrophically defective supervisor service worker cannot be fully repaired offline; it requires a normal browser service-worker update from the origin, which is why supervisor code must be small, infrequently changed and tested separately.

[RECOMMENDATION] The initial production gate should require all of the following: canonical build identity; clean source state; immutable graph validation; staged-object public hash readback; release-pointer commit; Chromium, Firefox and WebKit execution; offline admission and restart; interrupted-update recovery; old-tab/new-tab coordination; local last-known-good rollback; exact security-header verification; model-byte absence checks; network-policy tests; and privacy scanning of source maps, caches, storage, traces, screenshots and deployment receipts. Upload completion is not a release receipt.

The workstreams rank as follows:

WorkstreamRelevanceDelivery feasibilityFailure impactPriority
Release identity and immutable graphCriticalHighCriticalImmediate
Candidate staging and service-worker lifecycleCriticalMediumCriticalImmediate
Public publication and readback state machineCriticalMediumCriticalImmediate
Privacy, CSP and cross-origin isolationCriticalMediumCriticalImmediate
Browser update, multi-tab and rollback testsCriticalMediumHighImmediate
Remote cleanup and model-absence proofHighMediumHighBefore production
Receipt graph and reproducibilityHighHighHighBefore production
Performance optimization and navigation preloadMediumHighMediumAfter correctness

Evidence, scope, and architectural conclusions

The report distinguishes six evidence classes:

LabelMeaning
[STANDARD]Behavior required or described by a web standard or Internet Standard
[VENDOR]Documented browser-vendor behavior or guidance
[PUBLIC-OBSERVED]Information visible through publicly indexed TinyRustLM pages
[INFERENCE]A conclusion drawn from cited evidence, not a direct observation
[RECOMMENDATION]Proposed engineering design
[VERIFY]Requires source access, hosting credentials, browser profiles, logs or authorized deployment

Definition and scope. The release system includes the root bootstrap, application HTML, JavaScript modules, CSS, Rust-generated WASM, dedicated or shared workers, service worker, icons, web app manifest, schema files, public catalog descriptors, hosting policy, security headers, deployment manifest, public readback receipts, and client-side release state. It excludes model bytes from project hosting and excludes private prompts, credentials, pairing codes, MemoryEndpoints keys, enrollment URLs and other user secrets from service-worker caches and deployment evidence.

Why it matters. A PWA has several independently retained state layers: open documents, installed windows, active and waiting service workers, Cache Storage, the HTTP cache, back-forward cache, OPFS or IndexedDB, and browser-managed installed-app metadata. HTTP caching rules do not force a browser history entry or application object to update, and a service-worker update does not automatically remove prior Cache Storage entries. Consequently, “all files uploaded” does not imply that a user sees one release.

The main stakeholders and impacts are:

StakeholderPrimary riskRequired control
Users running local inferenceLost generation state, broken offline startup, prompt disclosureVoluntary activation, explicit state checkpointing, no diagnostic exfiltration
Release operatorsPartial upload, false success, unsafe cleanupDependency-first staging, public readback, bounded deletion
Security reviewersXSS, supply-chain substitution, isolation failureCSP, immutable identities, response hashing, COOP/COEP/CORP
Browser/PWA usersStale tabs and installed-app divergenceController handshake, release coordination and truthful UI
Companion, peer and memory operatorsOverbroad network access or credential leakageExact endpoint classes, network-only handling, redacted receipts
MaintainersIrreproducible rollback and test ambiguityVersioned receipt graph and deterministic release manifest

Current public context. The indexed public interface contains local-file import, direct peer and loopback-companion concepts, user-entered catalog or peer URLs, MemoryEndpoints fields, run-history controls, and browser-local inference claims. That implies that the application’s legitimate network surface is more complex than a conventional fully static PWA. It also creates a policy conflict: a static CSP can allow exact predeclared origins, but it cannot safely convert arbitrary user-entered peer origins into a new per-session connect-src allowlist. The project must therefore choose between a closed, signed peer-origin registry; a fixed loopback companion that performs peer communication; or a deliberately broader CSP on a segregated, reduced-privilege page. Allowing arbitrary https: or wss: origins in the main application would not satisfy exact network closure.

Research conclusion. The highest-priority architectural choice is not a caching algorithm; it is the trust and commitment model. TinyRustLM should define:

  1. A canonical manifest whose digest is the application release ID.
  2. Immutable release URLs that never change after publication.
  3. One mutable release pointer whose update is the publication commit.
  4. A stable supervisor that verifies candidate bytes before local admission.
  5. An explicit client-side active-release record.
  6. A separate browser service-worker lifecycle for rare supervisor changes.
  7. A receipt graph proving what was built, published, retrieved, executed, cached, updated and rolled back.

Without these elements, cache-first versus network-first decisions merely relocate version-mixing risk.

Standards and browser-behavior baseline

The W3C Service Workers Editor’s Draft dated July 23, 2026 defines the worker lifecycle, fetch interception and the Cache-like response store. An updated worker is installed separately from the active worker and normally waits until the prior worker no longer controls clients. The browser performs update detection on the service-worker script and relevant dependencies; explicit skipWaiting() and clients.claim() can override the normal separation, but can cause a replacement worker to control pages that loaded under a different generation.

The principal standards and implementation observations are:

AreaCurrent referenceStandardized or documented guaranteeTinyRustLM implication
Service workerW3C Editor’s Draft, July 23, 2026Separate installing, waiting and active workers; fetch interception and Cache APIUse waiting as a compatibility barrier; do not equate install with activation
Cache APIService Workers specificationRequest URLs are cache keys; query searches are considered unless ignoreSearch is deliberately enabledNever use ignoreSearch: true for application assets or secret-bearing URLs
Navigation preloadBroad browser availability since approximately April 2022 in MDN baseline dataCan begin network navigation while a service worker startsOptional optimization only; it must not bypass release selection
HTTP cachingRFC 9111, Internet Standard, June 2022Freshness, validation, no-store, no-cache, Vary, ETag and cache-key semanticsUse immutable long caching only for content-addressed resources
Immutable responsesRFC 8246, September 2017Cache-Control: immutable indicates that a fresh response will not changeAppropriate for content-hashed release assets, not pointers or root state
Web App ManifestW3C Working Draft, May 7, 2026Defines id, scope, start_url, icons and installed-app metadataKeep a stable app id; hash icon URLs so installed metadata can observe changes
CSPW3C Working Draft, July 29, 2026Controls resource loading, workers, connections, framing, base URLs and WASM compilationDeliver CSP as a response header and eliminate inline/event-handler dependencies
SRIW3C Working Draft, July 10, 2025Browser verifies eligible resource bytes against integrity metadataUse for scripts and styles, but not as whole-release proof
COOP/COEPWHATWG HTML living standardCOOP: same-origin plus compatible COEP can create cross-origin isolationRequired when WASM threads use shared memory
CORPFetch integrationResource response can restrict no-cors cross-origin useSet same-origin on project-owned executable and style resources
StorageWHATWG Storage Standard, March 15, 2026Quotas and persistence are implementation-defined estimatesCache admission must handle quota failure and storage eviction
OPFSBrowser implementation baselineOrigin-private, quota-governed storage; cleared with site dataSuitable for admitted user model artifacts, not as part of app-release cache

Sources:

Browser behavior observations. COEP is documented in the current WHATWG HTML developer edition as supported in current Chromium, Firefox and WebKit-derived engines, with historical entry points of Chrome 83, Firefox 79 and Safari 15.2. Navigation preload, Cache Storage, service-worker registration and controller APIs are broadly available in evergreen browsers. Those historical support thresholds are not substitutes for testing the exact stable versions used at release time. Each browser receipt must record browser name, full version, OS, architecture, installation mode, viewport, feature probes, navigator.userAgent or user-agent client hints where available, and self.crossOriginIsolated.

[RECOMMENDATION] Treat the following as interoperability-sensitive rather than assumed identical: service-worker update timing; storage eviction; installed-manifest refresh; background-tab throttling; back-forward cache restoration; mobile PWA restart; loopback and private-network restrictions; CSP reporting; and worker/WASM error surfaces. Web standards define the model, but quotas are explicitly implementation-defined and user agents retain discretion over installed-manifest application and storage persistence.

[RECOMMENDATION] Use navigation preload only after the correctness model is complete. If enabled, its response must flow through the same release-pointer and expected-hash checks as a normal fetch; it must never cause the active release to consume a newly published root or app HTML before local admission. Navigation preload improves startup latency but is not a consistency primitive.

Release identity, immutable graph, and publication state machine

Canonical identity. Define a deterministic canonical JSON serialization called release-manifest.v1. Its SHA-256 digest is the authoritative release identifier:

RID = "trm-" + lowercase_hex(SHA256(canonical_release_manifest_bytes))

A human-readable build label such as 2026.08.01+git.ab12cd34 may accompany the RID but must never replace it as the identity. Timestamps, signatures and deployment-environment data that would make the manifest nondeterministic should be stored in separate attestations or excluded from the hashed canonical payload.

A minimum manifest should include:

{
  "kind": "tinyrustlm.release-manifest.v1",
  "release_id": "trm-<sha256>",
  "source": {
    "repository": "<repository-id>",
    "revision": "<full-commit>",
    "tree_state": "clean",
    "submodules": {},
    "source_date_epoch": 0
  },
  "toolchain": {
    "rustc": "<exact-version>",
    "cargo": "<exact-version>",
    "wasm_bindgen": "<exact-version>",
    "wasm_opt": "<exact-version>",
    "node": "<exact-version>",
    "package_manager": "<exact-version>",
    "lockfile_sha256": "<sha256>"
  },
  "protocols": {
    "supervisor": 1,
    "page_worker": 1,
    "wasm_abi": 1,
    "storage_schema": 1
  },
  "artifacts": [
    {
      "logical_role": "app-html",
      "url": "/releases/<RID>/app.<sha256>.html",
      "sha256": "<sha256>",
      "size": 1234,
      "media_type": "text/html; charset=utf-8",
      "encoding_policy": "identity-hash",
      "cache_policy": "public,max-age=31536000,immutable",
      "dependencies": [
        "bootstrap-js",
        "app-css"
      ]
    }
  ],
  "security_contract": {
    "csp_profile": "isolated-local-inference-v1",
    "coop": "same-origin",
    "coep": "require-corp",
    "corp": "same-origin",
    "permissions_policy_profile": "minimal-v1"
  },
  "network_contract": {
    "application_origins": ["https://tinyrustlm.com"],
    "catalog_origins": [],
    "memory_origins": [],
    "loopback_origins": [],
    "peer_policy": "signed-registry-only"
  }
}

[RECOMMENDATION] Every artifact record must specify exact URL, SHA-256, decoded byte size, expected media type, allowed Content-Encoding, cache policy and dependency edges. Hash the actual file bytes before HTTP content encoding. Public verification should retrieve with Accept-Encoding: identity to compare those build bytes directly, then separately test compressed delivery, Content-Encoding, Vary: Accept-Encoding and decoded behavior.

Immutable graph. Use immutable release paths and content-hashed filenames:

/releases/<RID>/app.<hash>.html
/releases/<RID>/bootstrap.<hash>.mjs
/releases/<RID>/app.<hash>.css
/releases/<RID>/runtime.<hash>.wasm
/releases/<RID>/inference-worker.<hash>.mjs
/releases/<RID>/manifest.<hash>.webmanifest
/releases/<RID>/icon-192.<hash>.png
/releases/<RID>/icon-512.<hash>.png
/releases/<RID>/schemas/<name>.<hash>.json
/releases/<RID>/release-manifest.json
/releases/<RID>/release-manifest.sig

The URLs /, /sw.js, /release.json and optional human-readable status pages are mutable supervisor endpoints and must not receive immutable caching. All executable imports from an admitted app HTML document must resolve to the same /releases/<RID>/ subtree. Workers must be created using exact release URLs rather than unversioned /worker.js; WASM must be fetched from the exact release path; the web manifest must use content-hashed icon URLs. The Web App Manifest specification notes that browsers may consider an icon updated when its src changes, reinforcing the value of immutable icon names.

Identity-mechanism comparison.

MechanismStrengthLimitationRole
Content-hashed filenameURL identity changes whenever bytes change; works for imports, workers and WASM URLsDoes not independently prove that the server returned matching bytesPrimary dependency identity
SHA query parameterCreates a distinct URL in normal cache matchingUnderlying path remains mutable; operators and middleware may ignore or normalize queriesDo not use as authoritative identity
SRIBrowser blocks eligible script/style bytes that do not matchCoverage is incomplete; cross-origin use requires CORS; does not define the whole graphDefense-in-depth for scripts and styles
Signed release manifestAuthenticates the complete expected graph and operator intentRequires protected signing key and a trusted verification key; first-load trust remains rooted in HTTPS/bootstrapAuthoritative graph and deployment attestation
Service-worker cache manifestConvenient install inputA filename/hash declaration proves nothing until actual response bytes are hashedDerived implementation data only
HTTP ETagEfficient conditional validationETag semantics are server-controlled and need not be a cryptographic content hashPointer/bootstrap revalidation, not identity

SRI requires the response bytes to match the supplied digest and treats a failed check as a network error; cross-origin integrity checking relies on CORS. RFC 9111 defines cache validation and ETag behavior, while RFC 8246 supports long-lived immutable caching for version-specific URLs.

Signed manifest model. Sign the canonical manifest digest with an offline or hardware-protected release key. The signature should be verified by deployment tooling and public-readback tooling. Browser-side signature verification is useful only if the verification key is pinned in the supervisor and key rotation is separately authenticated. A signature does not verify a response unless the client first hashes the received bytes and verifies that digest against the signed manifest. It also does not protect a first-time user from simultaneous compromise of the origin-delivered bootstrap and its embedded trust key; it principally protects the release process, caches, mirrors and post-build mutation.

Per-artifact atomic publication. The host is assumed to make individual object replacement atomic but not the whole release. The publication sequence is therefore dependency-first and pointer-last:

stateDiagram-v2
    [*] --> Preflight
    Preflight --> Inventory: clean source, locks, toolchain, policy
    Inventory --> StageImmutable: bounded remote inventory accepted
    StageImmutable --> StageReadback: upload all /releases/RID/ objects
    StageReadback --> ManifestPublish: every staged byte/hash/header valid
    StageReadback --> Failed: any mismatch or unknown redirect
    ManifestPublish --> CandidateBrowser: manifest and signature publicly valid
    CandidateBrowser --> CommitPointer: staging browser and policy tests pass
    CandidateBrowser --> Failed: execution or isolation failure
    CommitPointer --> PublicReadback: atomically replace /release.json
    PublicReadback --> ProductionBrowser: pointer and full graph re-read publicly
    ProductionBrowser --> SuccessReceipt: update, offline and smoke gates pass
    ProductionBrowser --> Rollback: any production gate fails
    Rollback --> RollbackReadback: repoint to prior immutable RID
    RollbackReadback --> FailedReceipt
    SuccessReceipt --> DeferredCleanup
    Failed --> FailedReceipt
    DeferredCleanup --> [*]
    FailedReceipt --> [*]

The unavoidable mixed-visibility window exists while immutable candidate objects are appearing on the host. It is harmless because no committed pointer references them. After pointer replacement, some caches may still hold the old pointer or old documents, but those clients remain pinned to an old immutable RID. New clients that observe the new pointer can resolve every dependency because all immutable objects were read back before commitment.

The pointer should resemble:

{
  "kind": "tinyrustlm.release-pointer.v1",
  "sequence": 42,
  "release_id": "trm-<sha256>",
  "manifest_url": "/releases/trm-<sha256>/release-manifest.json",
  "manifest_sha256": "<sha256>",
  "not_before": "2026-08-01T00:00:00Z",
  "rollback_of": null
}

Serve the pointer with Cache-Control: no-store, or at minimum no-cache, max-age=0, must-revalidate, and a strong ETag. no-store instructs HTTP caches not to retain the response, although RFC 9111 warns that it is not by itself a complete privacy mechanism.

Failure and rollback rules. Before pointer commit, failure leaves only unreachable candidate objects. After commit, any failed production validation immediately repoints the pointer to the previous RID; the candidate remains available for forensic comparison but is no longer selected. Do not delete the failed release in the rollback transaction. Cleanup is a later, bounded and separately receipted operation.

Service worker, caching, coherent startup, updates, rollback, and offline behavior

Two lifecycle planes. Application updates and supervisor service-worker updates should not be conflated.

The application-release lifecycle operates inside a stable active supervisor:

DISCOVERED → DOWNLOADING → VERIFYING → CANDIDATE_READY
           → USER_WAITING → COMMITTING_LOCAL → ACTIVE
           → LAST_KNOWN_GOOD or REJECTED

The browser service-worker lifecycle applies when /sw.js itself changes:

installing → installed/waiting → activating → activated

The W3C lifecycle and Chrome’s official guidance support keeping a replacement service worker in waiting while existing controlled pages are active. Immediate takeover is specifically hazardous where an old page cannot predict new worker behavior.

Registration and scope. Register one service worker at /sw.js with scope / and updateViaCache: "none" or the most conservative supported equivalent. The response for /sw.js should use Cache-Control: no-cache, max-age=0, must-revalidate, an exact JavaScript media type and X-Content-Type-Options: nosniff. Keep the script self-contained or use immutable imports whose hashes are supervisor-manifested. A stable script URL is necessary so existing pages continue checking the same registration for updates. The service-worker update mechanism compares fetched script bytes and supports explicit registration.update() checks.

Supervisor installation. A new supervisor’s install event must:

  1. Parse its embedded supervisor manifest and version.
  2. Retrieve and hash every required supervisor resource.
  3. Confirm status, final URL, media type, size and security expectations.
  4. Populate a new supervisor:<SID> cache.
  5. Confirm that the active application RID and last-known-good RID remain readable.
  6. Complete installation without calling skipWaiting().

A rejected fetch, digest mismatch, quota error or missing prerequisite must reject the install promise, preventing the worker from reaching waiting.

Activation. Activation occurs only after client agreement or when no prior controlled clients remain. The new supervisor should not automatically claim existing pages. On activation it should migrate only versioned control metadata, retain the current and prior verified application caches, and delete caches only if they match an exact recognized namespace and retention rule. New documents become controlled naturally on navigation. clients.claim() is permissible only for a protocol-compatible supervisor change whose page/worker handshake is proven safe; it should not be the default.

Cache namespaces.

Namespace or storePermitted contentRetentionService-worker handling
trm-supervisor:<SID>Root bootstrap and supervisor static resourcesCurrent plus previous during migrationExact cache-only after verification
trm-release:<RID>App HTML, JS, CSS, WASM, app workers, icons, web manifest, schemasActive, last-known-good, candidateExact cache-only after admission
trm-public-metadata:<schema>Non-secret signed catalog metadataSize/age boundedNetwork-first; visibly stale fallback
IndexedDB release-controlActive RID, previous RID, candidate status, protocol versionsPersistentSmall transactional records
OPFS models/User-admitted model artifacts and derived indexesUser-managed, quota-awareNever entered into Cache Storage
IndexedDB/OPFS conversation statePrompts or local history only when explicitly enabledUser-controlledNever read, copied or cached by SW
MemoryEndpoints dataLocal synchronized records if product requires themExplicit policyNever placed in Cache Storage
DiagnosticsRedacted in-memory ring buffer; explicit export onlySession-bounded by defaultNo remote transmission by default

Cache API matching normally includes the query portion of a URL unless ignoreSearch is set. TinyRustLM should never set ignoreSearch: true for executable assets, metadata with identity parameters or any request that might include credentials, pairing codes, invitations or user identifiers.

Resource fetch policies.

Resource classPolicyCorrectness rationale
Active app navigationCache-only pinned app.html for activeRID; repair screen on missing entryA controlled client never sees server HTML from another generation
Immutable release assetsCache-only after release admissionPrevents opportunistic substitution or partial online repair
Candidate assetsNetwork fetch, full byte verification, then candidate cacheNothing executes before admission
Release pointerNetwork-only/no-store; cached value may be displayed only as stale statusAvoid stale pointer becoming an activation instruction
Signed public catalog metadataNetwork-first with bounded, labeled stale copyAvailability without pretending freshness
User model files and OPFS modelsFile/OPFS access, not HTTP cachePrevents model bytes entering service-worker caches
Peer model transfersNetwork-only pass-through; no body inspection, cloning or cachingPreserves privacy and storage boundary
Loopback companionNetwork-only; exact allowed origin; no cacheA local live service must not be simulated offline
MemoryEndpointsNetwork-only for authorized operations; no cacheAvoids token and private-data retention in Cache Storage
Favicons, app icons and manifestImmutable release cacheKeeps installed presentation tied to the RID
Source mapsNot publicly deployedAvoids source, path and secret leakage
Diagnostics and CSP reportsDisabled remotely by default or explicitly privacy-reviewedReports can contain URLs and execution context

Byte verification. cache.addAll() is insufficient as the trust decision because it does not compare each body with the application’s expected canonical digest. The installer should fetch() with redirect: "error" where supported, validate status and metadata, read or stream the complete response, compute SHA-256, compare length and digest, and only then write a newly constructed or safely cloned response to the candidate cache. A service worker can enforce integrity only by checking actual bytes; a manifest hash declaration alone proves nothing.

For WASM, WebAssembly.instantiateStreaming() is ideal for performance but conflicts with a simple pre-execution whole-body digest unless the stream is duplicated and one path is completely verified before execution. Because SubtleCrypto’s common digest interface consumes a complete buffer rather than providing a standardized incremental streaming hash, the safest admission path is to download the relatively small runtime WASM into an ArrayBuffer, verify it, cache it, and compile only the verified bytes. Model weights are excluded from the application release and should not be routed through this mechanism.

Coherent startup. Model activation remains disabled until all of the following match:

app HTML RID
bootstrap module RID
controller-reported active RID
inference-worker RID and protocol
WASM exported build/RID identifier
storage schema version
security isolation requirement

The page sends a HELLO message containing its RID and protocol version to the controller. The controller returns activeRID, supervisorVersion, candidate state and whether rollback is available. The page then launches the immutable worker URL and requires the worker to return the same RID before transferring model handles. The WASM module should export a compile-time release identifier or expose an immutable custom-section digest validated by the JavaScript loader.

If any value differs, the application shows a non-destructive Version repair required state, blocks new generation, preserves locally held input, and offers one of three actions: finish the pending update, return to last-known-good, or reload from the currently active release. A generic “network error” is inadequate.

A pageshow event with persisted === true must re-run this handshake because back-forward cache can restore a document whose controller or active-release state changed while it was frozen. Browser history is not governed solely by HTTP cache freshness.

Multi-tab coordination. Use BroadcastChannel("tinyrustlm-release") plus service-worker postMessage() for advisory coordination. Each tab reports RID, activity state, whether a generation is running, whether local input is dirty and whether it can reload. The supervisor announces CANDIDATE_READY; tabs acknowledge SAFE_TO_SWITCH, BUSY, or INCOMPATIBLE.

A second tab opened during deployment behaves coherently:

  • If controlled by the old supervisor state, it receives the old pinned shell.
  • If it is a fresh uncontrolled client after pointer commitment, it may verify and admit the new release.
  • It must not cause existing tabs to switch.
  • Once the candidate is selected locally, all tabs either reload into the selected RID or remain blocked from model activation until they do.

A browser does not provide a reliable general mechanism for a service worker to forcibly close arbitrary controlled tabs. “Stale tab closure” should therefore mean disabling sensitive or incompatible actions and requesting reload, not claiming the tab was closed.

Forced security updates. Forceful transition is justified only for narrowly defined conditions: a known exploitable application vulnerability, a revoked release-signing key, a privacy-boundary failure, a compromised dependency, or a network policy that can send prompts or model bytes unexpectedly. Even then, the page should stop accepting new prompts, request a generation checkpoint or cancellation, preserve editable input, and move to a blocking update screen. It should not destroy an active generation without a documented state policy.

Last-known-good rollback. Store:

activeRID
lastKnownGoodRID
candidateRID
activationSequence
supervisorProtocol
rollbackReasonCode

The local activation transaction changes only activeRID after the candidate cache and release manifest are fully verified. The prior activeRID becomes lastKnownGoodRID. On startup failure, repeated worker crash, failed isolation check or explicit user request, the supervisor atomically selects lastKnownGoodRID, marks the candidate rejected and reloads clients into the prior immutable shell.

Server-authorized rollback repoints /release.json to the previous RID and includes rollback_of, reason code, operator signature and sequence. Security rollback must not restore a release revoked for privacy or remote-code-execution reasons. It must never recreate retired model routes or weaker headers.

Offline capability matrix.

CapabilityOffline statusRequired local stateTruthful UI
Open admitted application shellSupportedVerified active release cache“Offline — application ready”
Load previously admitted local modelSupported, subject to quota and browser supportFile handle or OPFS model and matching schema“Offline — local model available”
Continue local generationSupported if runtime and model remain resident/availableActive matching RID, worker and model“Running locally”
Import a user-selected local fileSupportedBrowser file picker permission“Local file selected”
Retrieve catalog metadataUnavailable; stale snapshot may be shownOptional signed snapshot“Offline — catalog may be stale”
Contact direct peerNot generally available; LAN may still be reachableApproved peer and reachable networkDistinguish “Internet offline” from “Peer unreachable”
Contact loopback companionAvailable only if companion is runningExact local endpoint and consent“Companion unavailable,” not “offline model unavailable”
MemoryEndpoints operationsUnavailable unless network endpoint is reachableCredentials and endpoint“Hosted memory unavailable”
Download a new modelUnavailable without a reachable approved sourceNone“No model available offline”
Recover defective candidateSupported through local last-known-goodPrior verified release retained“Recovered to previous verified version”
Repair defective supervisorNot guaranteed offlineOrigin connectivity and valid /sw.js“Application repair requires network”

OPFS is origin-private, quota-governed and removed when the user clears site data, so offline availability must never be described as permanent backup.

Security, privacy, network closure, and cleanup

Cross-origin isolation. WASM threads that use shared memory depend on SharedArrayBuffer-style capabilities. Current platform guidance requires cross-origin isolation, normally produced by:

Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corp

The application must then verify self.crossOriginIsolated === true in both window and worker contexts before selecting a threaded runtime. Cross-origin resources must opt in through CORS or suitable CORP behavior.

Use require-corp rather than credentialless initially because its explicit opt-in model is easier to audit. Any cross-origin catalog, peer or MemoryEndpoints response loaded into an isolated application must satisfy the relevant CORS/COEP conditions. Third-party JavaScript, styles, fonts and frames should be eliminated.

Recommended document-header baseline.

Content-Security-Policy:
  default-src 'none';
  script-src 'self' 'wasm-unsafe-eval';
  script-src-attr 'none';
  style-src 'self';
  img-src 'self';
  font-src 'none';
  object-src 'none';
  base-uri 'none';
  frame-src 'none';
  frame-ancestors 'none';
  worker-src 'self';
  manifest-src 'self';
  connect-src 'self' https://<approved-catalog> https://<approved-memory> http://127.0.0.1:<fixed-port>;
  form-action 'none';
  upgrade-insecure-requests

Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corp
Cross-Origin-Resource-Policy: same-origin
Permissions-Policy:
  camera=(), microphone=(), geolocation=(), payment=(), usb=(),
  serial=(), bluetooth=(), display-capture=(),
  cross-origin-isolated=(self)
Referrer-Policy: no-referrer
X-Content-Type-Options: nosniff
Strict-Transport-Security: max-age=63072000; includeSubDomains

The exact Permissions Policy token set must be validated against current browser behavior before enforcement. HSTS includeSubDomains and preload enrollment should be used only after every relevant subdomain is permanently HTTPS-capable. CSP should be response-header delivered because some directives, including frame-ancestors, cannot be fully expressed through a CSP meta element. CSP Level 3 also defines specific integration with WebAssembly byte compilation and worker loading.

'wasm-unsafe-eval' should be included only if the selected runtime requires dynamic WASM compilation under CSP; do not add general 'unsafe-eval'. Remove inline scripts, inline event handlers and mutable third-party dependencies rather than compensating with permissive CSP. If a static host cannot generate per-response nonces, external content-hashed scripts plus SRI and a strict 'self' policy are preferable.

SRI limitations. Apply SHA-384 or SHA-512 SRI to the root app module and stylesheet when loaded through eligible HTML elements. Cross-origin SRI requires CORS. Redirects, CORS mode and the final response influence whether the integrity check can succeed. SRI failure prevents execution, but SRI on one module does not automatically provide a simple universal guarantee over every dynamic import, worker, fetched WASM body and metadata response. The service worker also occupies a privileged interception position: a malicious active service worker can synthesize responses, while a correctly designed service worker can enforce a stronger release-manifest check. The integrity trust boundary must therefore include the service worker itself.

Network closure. Define request classes in the release manifest and enforce them independently in the page and service worker:

ClassAllow ruleCredential ruleCache/log rule
Application assetsExact same-origin release URLs and hashesOmitCache only after verification; log RID only
Public catalogExact configured origin and schema pathOmitBounded signed metadata cache
Direct peerSigned-registry exact origin or companion-mediatedExplicitly omit unless protocol requires otherwiseNever cache body or full sensitive URL
Loopback companionFixed scheme, host and port; user initiationProtocol-specific local authorizationNever Cache Storage; redact identifiers
MemoryEndpointsExact production origin and operation pathsExplicit token headerNever cache; never log token, workspace or agent identifiers
CSP reportingDisabled by default, or same-origin privacy-reviewed endpointOmitStrip full URLs and samples
Analytics/error reportingNone by defaultNoneProhibited unless separately approved
Browser-originated update trafficOutside page controlBrowser-controlledDocument as residual browser behavior

A static CSP can constrain origins but generally cannot constrain exact URL paths with the same precision as an application-layer allowlist. CSP source matching supports path concepts, but redirect and matching semantics require careful treatment and should not be the sole network-policy control.

Arbitrary peer conflict. A user-entered arbitrary peer URL cannot simultaneously be unrestricted and covered by a strict predeclared connect-src. The recommended resolution is one of:

OptionSecurityUsabilityRecommendation
Signed, release-approved peer-origin registryHighMediumPreferred for browser-direct peers
Fixed loopback companion handles arbitrary peersHigh if companion is trustedHigh after installationPreferred for open-ended P2P
Separate reduced-privilege peer-import origin/pageMediumMediumAcceptable with strict data separation
Main app allows connect-src https: wss:Low closureHighReject

The project domain must not proxy model bytes. A local companion may broker user-authorized P2P traffic without violating that constraint, provided the browser clearly identifies the companion as a live local service and never simulates it while unavailable.

Prompt and model privacy. Service-worker code must not clone, inspect, hash for diagnostics, cache or report model-transfer bodies. It must not cache requests containing Authorization, cookies, invitation tokens, pairing codes, workspace identifiers or non-public query parameters. Prompts and local conversation history belong in page-owned local storage only when the user enables persistence; they must never be copied into release receipts, CSP reports, screenshots or remote diagnostics.

Cache-Control: no-store is useful on sensitive HTTP responses but is not a complete privacy guarantee, so application code and the service worker must also avoid explicit persistence.

Remote cleanup. Cleanup must operate from an exact allowlist generated from:

  • the newly committed release,
  • retained active and last-known-good releases,
  • a finite list of known retired unpublished paths,
  • canonical supervisor files, and
  • explicitly approved non-release public files.

The cleanup tool must retrieve a bounded remote inventory from the deployment root. Any unknown name, unexpected nested directory, symlink, reparse point, alias, redirect object or unrecognized storage type causes a visible stop. It must not recursively delete the site root or follow links. It may delete only exact names listed in a signed cleanup plan, and it must record pre-delete and post-delete inventory hashes.

Model-byte absence proof. Public testing can show only that known routes do not expose models; complete proof requires authorized host inventory. The strongest practical proof combines:

  1. Deployment manifest allowlisting every permitted object.
  2. Authorized recursive object-store or filesystem inventory without following links.
  3. Rejection of unknown objects.
  4. Scanning filenames, media types, magic bytes and unusually large files.
  5. Negative public probes for known retired model routes and extensions.
  6. Verification that redirects do not lead to a project-hosted model location.
  7. Confirmation that project access logs show no model-serving routes during tests.

Public negative probes alone cannot prove global absence because unguessable paths may exist.

Verification, receipts, TDD, and release roadmap

Public HTTPS readback. Verification must run from an external network context that does not share the deployment host’s filesystem, CDN control plane or authenticated operator session. For each public object, record:

FieldRequired check
Requested and final URLCanonical HTTPS origin, no unexpected redirects
StatusExact expected status; no soft-404 HTML
Entity hashSHA-256 of full response with Accept-Encoding: identity
SizeExact decoded byte count and, where relevant, encoded content length
Media typeExact allowlisted type and charset
Content encodingIdentity test plus separately approved compression
Cache policyImmutable for release objects; no-store/revalidate for pointers
ETag and Last-ModifiedRecorded, but not substituted for content hash
CSP and isolationExact contract on HTML and relevant worker responses
CORP and CORSCorrect for same-origin and approved cross-origin use
Redirect policyNo host aliases or downgrade
Route concealmentRetired app and model routes return expected negative result
Release identityHTML, manifest, pointer and headers agree on RID/SID

Verification must read complete response bodies. HEAD, object-store metadata and upload checksums are useful preconditions but do not prove what public HTTPS clients receive after CDN transformation or routing.

Browser matrix.

ScenarioChromiumFirefoxWebKitMobile viewportInstalled PWA
Fresh first online loadRequiredRequiredRequiredRequiredWhere supported
Warm controlled loadRequiredRequiredRequiredRequiredRequired
Offline restartRequiredRequiredRequiredRequiredRequired
Interrupted candidate downloadRequiredRequiredRequiredRequiredRequired
Storage quota or cache write failureRequiredRequiredRequiredRequiredRequired
Stale active supervisorRequiredRequiredRequiredRequiredRequired
Old tab plus candidate waitingRequiredRequiredRequiredRequiredRequired
Second tab during pointer commitRequiredRequiredRequiredRequiredRequired
Update while generatingRequiredRequiredRequiredRequiredRequired
Browser restart during stagingRequiredRequiredRequiredRequiredRequired
Last-known-good rollbackRequiredRequiredRequiredRequiredRequired
Corrupted cache entryRequiredRequiredRequiredRequiredRequired
Network loss at each state transitionRequiredRequiredRequiredRequiredRequired
Back-forward cache restoreRequiredRequiredRequiredRequiredWhere applicable
Reduced motion and keyboard-only useRequiredRequiredRequiredRequiredRequired
No duplicate assistant renderingRequiredRequiredRequiredRequiredRequired
crossOriginIsolated and threaded WASMRequiredRequiredRequiredRequiredRequired

Each test must capture exact browser and OS versions, RID, SID, service-worker registration state, controller script URL, cache names, active/last-known-good records, console errors, network request destinations, screenshots with sensitive fields masked, and pass/fail assertions.

Privacy and secret scanning. Scan source and built artifacts for credentials, tokens, private origins, invitation URLs, local paths, home-directory names, workspace IDs, source-map comments, embedded .env values and private repository references. Scan public JavaScript, WASM strings, manifests, maps, HTML, headers, browser storage, Cache Storage keys, OPFS names, traces, HAR files, screenshots, receipts and authorized hosting logs. Large files and model-format signatures should be separately flagged. Test fixtures must use unmistakably fake secrets, and the scanner must prove that its own fixture detections work.

Receipt graph.

flowchart LR
    S[Source receipt] --> B[Build receipt]
    T[Toolchain receipt] --> B
    B --> P[Package and graph receipt]
    P --> D[Deployment receipt]
    H[Hosting-policy receipt] --> D
    D --> R[Public readback receipt]
    R --> X[Browser execution receipt]
    X --> O[Offline receipt]
    X --> U[Update receipt]
    O --> K[Rollback receipt]
    U --> K
    D --> C[Cleanup receipt]
    R --> C
    Q[Test-suite receipt] --> X
    Q --> O
    Q --> U
    Q --> K

Receipt IDs should be hashes of canonical receipt content. The dependency model controls invalidation:

ChangeRebuild assetsRedeployRepeat public readbackRepeat browser/offline/update tests
Source or dependency changeYesYesYesYes
Rust/WASM or frontend toolchain changeYesYesYesYes
Security-header contract changeNo, unless embeddedYesYesYes
Hosting configuration changeNoYesYesUsually yes
Browser test implementation onlyNoNoNoYes
Test browser version changeNoNoNoYes
Documentation-only change outside releaseNoNoNoNo
Candidate cleanup rule changeNoCleanup-onlyCleanup verificationNo, unless live paths affected
Release-pointer rollbackNoPointer onlyYesRollback smoke required

This separation prevents a changed browser test from falsely creating a new application build while ensuring that any asset-byte change invalidates deployment and public-readback evidence.

TDD backlog and stop rules.

PhaseTests written firstExit criterionMandatory stop
IdentityCanonical JSON, deterministic RID, graph closure, media types, clean-tree checksSame source and tools produce identical manifest and hashesNondeterminism, unlocked dependency or missing artifact
Local serverExact headers, immutable routes, pointer semantics, redirects, MIME and isolationLocal browser passes fresh and offline loadMissing header, route alias or MIME mismatch
Service-worker fixturesInstall failure, waiting behavior, no premature activation, cache corruption, quota failureCandidate never becomes active until verifiedAny unverified response is served
Mixed generationOld page/new candidate, new tab during commit, bfcache restore, worker mismatchModel activation always fails closed on RID mismatchAny old page invokes incompatible new worker
Offline and rollbackRestart, last-known-good, missing model, stale metadataTruthful status and deterministic recoveryLive service is simulated or data is silently discarded
Validate-only deploymentInventory, planned uploads, planned pointer change, no mutationSigned plan matches build manifestUnknown remote object or unbounded delete
Authenticated stagingFull upload, readback and browser suiteAll receipts completeHash, header, privacy or network failure
Production commitPointer-only commit followed by public checksExternal readback and core browser smoke passAny redirect, identity or isolation discrepancy
CleanupExact retired-path plan and model absence inventoryOnly approved paths removedSymlink/reparse point or unknown name
Final publicationRemove all superseded unpublished shells, routes, registrations and aliasesOne documented canonical lifecycle remainsLegacy path remains reachable without explicit approval

A proposed implementation roadmap is:

gantt
    title TinyRustLM release-lifecycle implementation roadmap
    dateFormat  YYYY-MM-DD
    axisFormat  %b %d

    section Identity and local proof
    Canonical release manifest and graph tests :a1, 2026-08-03, 10d
    Immutable build output and local server    :a2, after a1, 10d

    section Supervisor and recovery
    Candidate admission and byte hashing       :b1, after a2, 14d
    Multi-tab coordination and startup handshake :b2, after b1, 12d
    Last-known-good and interrupted-update tests :b3, after b2, 10d

    section Security and deployment
    CSP isolation and network closure          :c1, after a2, 18d
    Validate-only deployment and public readback :c2, after b1, 14d
    Secret scanning and bounded cleanup        :c3, after c2, 10d

    section Browser qualification
    Chromium Firefox WebKit matrix              :d1, after b3, 14d
    Staged release and rollback rehearsal       :d2, after d1, 7d

Dates are a proposed sequence, not a delivery claim. Work should stop immediately on release-graph nondeterminism, a public hash mismatch, unknown remote inventory, missing isolation, unexpected third-party network traffic, model bytes on a project origin, a privacy-secret finding, premature activation, inability to return to last-known-good, or inconsistent root and www canonicalization.

Unknowns requiring authorization and prioritized sources

The following facts cannot be established from public pages or standards and require source access, hosting credentials, controlled browser profiles or an authorized staging deployment:

UnknownEvidence required
Current source revision and clean worktreeRepository access and signed source receipt
Exact build toolchains and dependency locksBuild environment and lockfiles
Existing service-worker code, scope and registrationsSource plus controlled browser-profile inspection
Current cache names and retained generationsDevTools or automated browser storage inspection
Actual public headers and CDN transformationsExternal full-response readback
Whole-site or per-object hosting atomicityHosting-provider contract and controlled publication experiment
Root versus www canonical behaviorDNS, redirect, certificate and header checks
Current public asset graph and hashesBuild artifacts and public byte reads
Whether source maps or private metadata are deployedAuthorized inventory and public probes
Whether model bytes exist anywhere under project domainsComplete authorized inventory plus public negative tests
Current CSP, CORS, COOP, COEP and CORP compatibility with peersStaging deployment and endpoint response inspection
Loopback companion origin, ports and private-network behaviorCompanion protocol documentation and browser tests
MemoryEndpoints authorization and URL structureAuthorized integration specification
Whether local model data uses OPFS, IndexedDB or handlesSource and browser storage inspection
Existing prompt/history persistenceSource, storage and privacy review
Hosting logs and diagnostic destinationsAuthorized configuration and log review
Safe set of retired unpublished pathsHistorical deployment inventory
Current browser defects affecting the appExact-version cross-engine test matrix

No statement in this report should be read as validation of TinyRustLM’s private source, hosting configuration, deployed headers, service-worker state, browser storage or production privacy behavior.

Prioritized authoritative sources, retrieved August 1, 2026:

  1. W3C, Service Workers Editor’s Draft, July 23, 2026. Primary lifecycle, registration, update, fetch interception, Cache API and client-control reference. Most important for install/wait/activate semantics and failure behavior.
  1. W3C, Content Security Policy Level 3, Working Draft, July 29, 2026. Primary definition of script-src, worker-src, connect-src, manifest-src, object-src, base-uri, frame-ancestors, reporting and WebAssembly integration.
  1. WHATWG, HTML Standard — Browsing and Cross-Origin Policies. Primary living-standard reference for COOP, COEP, browsing-context isolation and the conditions that support cross-origin-isolated execution.
  1. W3C, Web Application Manifest, Working Draft, May 7, 2026. Primary source for stable app identity, scope, start URL, installed presentation, icons and manifest update semantics.
  1. W3C, Subresource Integrity, Working Draft, July 10, 2025. Primary source for browser-enforced hash metadata, CORS requirements, integrity failure and current scope limitations.
  1. IETF, RFC 9111: HTTP Caching, Internet Standard, June 2022. Authoritative definition of freshness, cache keys, validation, no-store, no-cache, Vary and cache/application distinctions.
  1. IETF, RFC 8246: HTTP Immutable Responses, Proposed Standard, September 2017. Primary basis for long-lived immutable caching of content-addressed release assets and discussion of corruption risks.
  1. WHATWG, Storage Standard, Living Standard updated March 15, 2026. Primary definition of origin storage architecture, persistence, usage and implementation-defined quota behavior.
  1. Chrome for Developers, Handling Service Worker Updates with Immediacy. Vendor guidance illustrating waiting-worker notification, user-controlled activation and the risks of immediate takeover. Its examples should be adapted to TinyRustLM’s stricter release protocol rather than copied as the architecture.
  1. W3C, Permissions Policy, Working Draft, October 6, 2025. Primary source for reducing access to browser capabilities and constraining cross-origin-isolated capabilities to intended contexts.