Files

6.8 KiB

KithMoot for Archipelago — preview candidate

Not release-qualified. UX/UI review, independent review, coordinated node installation, lifecycle acceptance and physical Companion acceptance are pending. Do not publish this candidate or replace a signed catalog to make it visible.

Included

  • The upstream browser workspace at /j/, not the marketing site or a redirect.
  • Upstream 0.5.4, commit 408c7b8e00caa3c968926fa7c3c9cd4ac58c76b9.
  • Rootless UID 101 nginx, read-only root, no capabilities, bounded scratch.
  • Gate-fronted UI on port 8189 (check collisions again when integrating).
  • Canonical host NIP-07 provider copied by an idempotent install hook to a persistent bridge directory; explicit application identity and no automatic NIP-98 flow. Provider is outside the app service-worker scope and not cached.
  • Host identity selection feeding the ordinary upstream account-adoption flow, one initial chooser after restoration, manual retry/account switching and an alternate signer action. The packaged picker excludes raw secret-key entry.
  • Normalized upstream symbol, with the platform's standard margins. Artwork source: art/brand/2026-09-29/kithmoot-symbol-gradient.svg at the commit above. See LICENSE.upstream; the container also includes the upstream MIT notice.
  • Embedded launch and a video PiP control using the existing remote video element. The user selects a remote video; this is not a composite meeting/gallery PiP.

Required platform changes

This package deliberately does not fall back to tab-only installation. The accompanying isolated platform proposal adds verified manifest-controlled iframe permissions and a mediated archipelago-video-v1 protocol. The dashboard grants only an allowlisted set to the iframe's source origin; it does not grant *. The signed policy must match the installed app identity/version. Disk manifests alone do not authorize this integration.

requires_host_frame: true is for video mediation, not for NIP-07. The app uses ordinary browser video PiP where available. On Companion, the dashboard mediates the existing main-frame-only native channel after the app fullscreens its actual video in the initiating user gesture. Origins, source windows, nonces, installed version, opt-in, dimensions and fullscreen ownership are checked. No URL, cookie, media track or private key crosses that protocol.

The retained dashboard media slot keeps the same iframe when its panel closes. A return/close notice makes a retained call discoverable. Closing PiP returns to the call; it does not silently hang up or mute outgoing media. Close app and stop call disposes the frame. Opening another retained media app replaces the slot, ending this frame; concurrent retained audio/video apps are not promised.

HTTPS (with the node CA trusted) is required for normal-address browser capture. Permission delegation cannot bypass browser/system consent or an ancestor's restrictive Permissions-Policy. Plain HTTP must show truthful limitations. Companion support is not qualified until tested on a physical device.

Explicit service and data boundaries

This first package is a browser client. It does not deploy a relay, keeper, TURN server, meeting-code server, Blossom server, agent, AI model or wallet.

  • Relays, peers and configured storage are contacted by the browser, not nginx. The package retains upstream network defaults; inspect network settings before real use. Tests must block public relay publication and use synthetic fixtures.
  • Same-origin TURN credential fetching is disabled: no missing /turn service is presented as working. Direct peer calls can fail behind restrictive NAT. TURN/forwarder deployment needs a separate network/service integration.
  • Meeting-code creation is disabled and explained; use full invitation links. Existing code lookup has no bundled server and is not a supported package feature. Do not advertise meeting codes in the catalog.
  • Shared-file uploads require an explicitly selected compatible Blossom server and upstream disclosure/consent. File sharing is not an included local backend.
  • Ordinary room device keys/history are browser-origin state (localStorage and related stores), not node volume backups. Scheme/hostname/port/profile changes can make that state unavailable. Preserve origin through updates; do not claim the bridge volume backs up rooms. Clearing site data can lose local state.
  • /bridge contains only the public host provider. Provider-copy failure must fail its verification hook and blocks qualification, even if nginx is healthy. The health endpoint proves static serving, not login, call or relay readiness.

Build and checks

Build in disposable, secret-free isolation with CPU/memory limits. Never mount credentials, host networking, container sockets or user data into a build.

podman build --memory=3g --cpu-period=100000 --cpu-quota=100000 \
  --security-opt=no-new-privileges \
  -t localhost/archipelago-kithmoot:0.5.4-archy.1 docker/kithmoot
bash scripts/validate-app-manifest.sh apps/kithmoot/manifest.yml
node --test docker/kithmoot/archipelago-video.test.mjs

integrate.py refuses changed upstream source anchors. Build output includes the upstream pinned WASM checks and no-telemetry check. Base images are digest-pinned; review dependency/base advisories before release. Build success is not a review or a runtime acceptance receipt. Run canonical Rust manifest validation through the project's isolated backend runner when qualifying the integration.

Generate catalogs using scripts/generate-app-catalog.py, then run the normal drift checks in the integrating branch. Never manually add generated fields or forge a signed/node-only catalog. Stage the build context, manifest and icon through the normal runtime payload only in the coordinated deployment window.

Acceptance checklist (open unless separately recorded)

  • Independent source/dependency/integration review.
  • Real My Apps/installing tile/icon/detail/launch paths.
  • Canonical signer allow/deny/remembered identity and account switching; no duplicate chooser; no fresh-browser second node login.
  • Actual HTTP limitations and trusted HTTPS iframe, tab fallback and Companion.
  • Private fixture room create/join/chat/files, invitation fragments preserved.
  • Camera/microphone consent, denied permissions, screen sharing, reconnect.
  • Browser PiP entry/return/close, same stream, no duplicate audio.
  • Physical Companion PiP, disabled system PiP, background/resume, rotation, close/return, session expiry and connectivity interruption.
  • Retained iframe while navigating dashboard; visible return/stop controls; switching media app, logout and node switch stop the old call.
  • Install/stop/start/restart/backend restart/host reboot/preserve/reinstall.
  • Operator UX/UI review before release, followed by the affected re-tests.